Skip to content

Commit 74f9470

Browse files
committed
Implemented that chores can be assigned to users (closes grocy#253)
1 parent 3dcd513 commit 74f9470

File tree

65 files changed

+987
-75
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+987
-75
lines changed

.tx/config

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
[main]
22
host = https://www.transifex.com
33

4-
[grocy.chore_types]
5-
file_filter = localization/<lang>/chore_types.po
6-
source_file = localization/chore_types.pot
4+
[grocy.chore_period_types]
5+
file_filter = localization/<lang>/chore_period_types.po
6+
source_file = localization/chore_period_types.pot
7+
source_lang = en
8+
type = PO
9+
10+
[grocy.chore_assignment_types]
11+
file_filter = localization/<lang>/chore_assignment_types.po
12+
source_file = localization/chore_assignment_types.pot
713
source_lang = en
814
type = PO
915

changelog/52_UNRELEASED_2019-xx-xx.md

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
- Recipe improvements
1313
- Based on the new linked quantity units, recipe ingredients can now use any product related unit, the amount is calculated according to the cnoversion factor of the unit relation
1414
- Chores improvements
15+
- Chores can now be assigned to users
16+
- Option per chore, different "assignment types" like "Random", "Who least did first", etc.
17+
- On the chores overview page the list can be filterd to only show chores assigned to the currently logged in user
1518
- New option "Due date rollover" per chore which means the chore can never be overdue, the due date will shift forward each day when due
1619
- Equipment improvements/fixes
1720
- Fixed that the delete button not always deleted the currently selected equipment item

controllers/ChoresApiController.php

+33
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,37 @@ public function UndoChoreExecution(\Slim\Http\Request $request, \Slim\Http\Respo
7070
return $this->GenericErrorResponse($response, $ex->getMessage());
7171
}
7272
}
73+
74+
public function CalculateNextExecutionAssignments(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
75+
{
76+
try
77+
{
78+
$requestBody = $request->getParsedBody();
79+
80+
$choreId = null;
81+
if (array_key_exists('chore_id', $requestBody) && !empty($requestBody['chore_id']) && is_numeric($requestBody['chore_id']))
82+
{
83+
$choreId = intval($requestBody['chore_id']);
84+
}
85+
86+
if ($choreId === null)
87+
{
88+
$chores = $this->Database->chores();
89+
foreach ($chores as $chore)
90+
{
91+
$this->ChoresService->CalculateNextExecutionAssignment($chore->id);
92+
}
93+
}
94+
else
95+
{
96+
$this->ChoresService->CalculateNextExecutionAssignment($choreId);
97+
}
98+
99+
return $this->EmptyApiResponse($response);
100+
}
101+
catch (\Exception $ex)
102+
{
103+
return $this->GenericErrorResponse($response, $ex->getMessage());
104+
}
105+
}
73106
}

controllers/ChoresController.php

+13-5
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $respo
2828
'currentChores' => $this->ChoresService->GetCurrent(),
2929
'nextXDays' => $nextXDays,
3030
'userfields' => $this->UserfieldsService->GetFields('chores'),
31-
'userfieldValues' => $this->UserfieldsService->GetAllValues('chores')
31+
'userfieldValues' => $this->UserfieldsService->GetAllValues('chores'),
32+
'users' => $usersService->GetUsersAsDto()
3233
]);
3334
}
3435

@@ -60,21 +61,28 @@ public function Journal(\Slim\Http\Request $request, \Slim\Http\Response $respon
6061

6162
public function ChoreEditForm(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
6263
{
64+
$usersService = new UsersService();
65+
$users = $usersService->GetUsersAsDto();
66+
6367
if ($args['choreId'] == 'new')
6468
{
6569
return $this->AppContainer->view->render($response, 'choreform', [
66-
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService'),
70+
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_PERIOD_TYPE_'),
6771
'mode' => 'create',
68-
'userfields' => $this->UserfieldsService->GetFields('chores')
72+
'userfields' => $this->UserfieldsService->GetFields('chores'),
73+
'assignmentTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_ASSIGNMENT_TYPE_'),
74+
'users' => $users
6975
]);
7076
}
7177
else
7278
{
7379
return $this->AppContainer->view->render($response, 'choreform', [
7480
'chore' => $this->Database->chores($args['choreId']),
75-
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService'),
81+
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_PERIOD_TYPE_'),
7682
'mode' => 'edit',
77-
'userfields' => $this->UserfieldsService->GetFields('chores')
83+
'userfields' => $this->UserfieldsService->GetFields('chores'),
84+
'assignmentTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_ASSIGNMENT_TYPE_'),
85+
'users' => $users
7886
]);
7987
}
8088
}

grocy.openapi.json

+70-1
Original file line numberDiff line numberDiff line change
@@ -2100,6 +2100,48 @@
21002100
}
21012101
}
21022102
},
2103+
"/chores/executions/calculate-next-assignments": {
2104+
"post": {
2105+
"summary": "(Re)calculates all next user assignments of all chores",
2106+
"tags": [
2107+
"Chores"
2108+
],
2109+
"requestBody": {
2110+
"required": false,
2111+
"content": {
2112+
"application/json": {
2113+
"schema": {
2114+
"type": "object",
2115+
"properties": {
2116+
"chore_id": {
2117+
"type": "integer",
2118+
"description": "The chore id of the chore which next user assignment should be (re)calculated, when omitted, the next user assignments of all chores will (re)caluclated"
2119+
}
2120+
},
2121+
"example": {
2122+
"chore_id": 1
2123+
}
2124+
}
2125+
}
2126+
}
2127+
},
2128+
"responses": {
2129+
"204": {
2130+
"description": "The operation was successful"
2131+
},
2132+
"400": {
2133+
"description": "The operation was not successful",
2134+
"content": {
2135+
"application/json": {
2136+
"schema": {
2137+
"$ref": "#/components/schemas/GenericErrorResponse"
2138+
}
2139+
}
2140+
}
2141+
}
2142+
}
2143+
}
2144+
},
21032145
"/batteries": {
21042146
"get": {
21052147
"summary": "Returns all batteries incl. the next estimated charge time per battery",
@@ -2853,6 +2895,9 @@
28532895
"next_estimated_execution_time": {
28542896
"type": "string",
28552897
"format": "date-time"
2898+
},
2899+
"next_execution_assigned_user": {
2900+
"$ref": "#/components/schemas/UserDto"
28562901
}
28572902
},
28582903
"example": {
@@ -3091,15 +3136,39 @@
30913136
"type": "string",
30923137
"enum": [
30933138
"manually",
3094-
"dynamic-regular"
3139+
"dynamic-regular",
3140+
"daily",
3141+
"weekly",
3142+
"monthly"
30953143
]
30963144
},
3145+
"period_config": {
3146+
"type": "string"
3147+
},
30973148
"period_days": {
30983149
"type": "integer"
30993150
},
31003151
"track_date_only": {
31013152
"type": "boolean"
31023153
},
3154+
"rollover": {
3155+
"type": "boolean"
3156+
},
3157+
"assignment_type": {
3158+
"type": "string",
3159+
"enum": [
3160+
"no-assignment",
3161+
"who-least-did-first",
3162+
"random",
3163+
"in-alphabetical-order"
3164+
]
3165+
},
3166+
"assignment_config": {
3167+
"type": "string"
3168+
},
3169+
"next_execution_assigned_to_user_id": {
3170+
"type": "integer"
3171+
},
31033172
"row_created_timestamp": {
31043173
"type": "string",
31053174
"format": "date-time"

helpers/extensions.php

+12-2
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,20 @@ function SumArrayValue($array, $propertyName)
8888
return $sum;
8989
}
9090

91-
function GetClassConstants($className)
91+
function GetClassConstants($className, $prefix = null)
9292
{
9393
$r = new ReflectionClass($className);
94-
return $r->getConstants();
94+
$constants = $r->getConstants();
95+
96+
if ($prefix === null)
97+
{
98+
return $constants;
99+
}
100+
else
101+
{
102+
$matchingKeys = preg_grep('!^' . $prefix . '!', array_keys($constants));
103+
return array_intersect_key($constants, array_flip($matchingKeys));
104+
}
95105
}
96106

97107
function RandomString($length, $allowedChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
msgid ""
2+
msgstr ""
3+
"Project-Id-Version: \n"
4+
"Report-Msgid-Bugs-To: \n"
5+
"Last-Translator: Translation migration from old PHP array files\n"
6+
"Language-Team: http://www.transifex.com/grocy/grocy/language/en\n"
7+
"MIME-Version: 1.0\n"
8+
"Content-Type: text/plain; charset=UTF-8\n"
9+
"Content-Transfer-Encoding: 8bit\n"
10+
"POT-Creation-Date: 2019-05-01T17:59:17+00:00\n"
11+
"PO-Revision-Date: 2019-05-01T17:59:17+00:00\n"
12+
"Language: en\n"
13+
"X-Domain: grocy/chore_assignment_types\n"
14+
15+
msgid "no-assignment"
16+
msgstr ""
17+
18+
msgid "who-least-did-first"
19+
msgstr ""
20+
21+
msgid "random"
22+
msgstr ""
23+
24+
msgid "in-alphabetical-order"
25+
msgstr ""
File renamed without changes.

localization/component_translations.pot

+3
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ msgstr ""
2929

3030
msgid "fullcalendar_locale"
3131
msgstr ""
32+
33+
msgid "bootstrap-select_locale"
34+
msgstr ""
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#
2+
msgid ""
3+
msgstr ""
4+
"Project-Id-Version: \n"
5+
"Report-Msgid-Bugs-To: \n"
6+
"POT-Creation-Date: 2019-05-01T17:59:17+00:00\n"
7+
"PO-Revision-Date: 2019-09-17 10:45+0000\n"
8+
"Language-Team: Danish (https://www.transifex.com/grocy/teams/93189/da/)\n"
9+
"MIME-Version: 1.0\n"
10+
"Content-Type: text/plain; charset=UTF-8\n"
11+
"Content-Transfer-Encoding: 8bit\n"
12+
"Language: da\n"
13+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
14+
"X-Domain: grocy/chore_assignment_types\n"
15+
16+
msgid "no-assignment"
17+
msgstr ""
18+
19+
msgid "who-least-did-first"
20+
msgstr ""
21+
22+
msgid "random"
23+
msgstr ""
24+
25+
msgid "in-alphabetical-order"
26+
msgstr ""
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# Translators:
2-
# Bernd Bestel <[email protected]>, 2019
2+
# Troels Siggaard <[email protected]>, 2019
33
#
44
msgid ""
55
msgstr ""
66
"Project-Id-Version: \n"
77
"Report-Msgid-Bugs-To: \n"
88
"POT-Creation-Date: 2019-05-01T17:59:17+00:00\n"
99
"PO-Revision-Date: 2019-05-01 17:42+0000\n"
10-
"Last-Translator: Bernd Bestel <[email protected]>, 2019\n"
10+
"Last-Translator: Troels Siggaard <[email protected]>, 2019\n"
1111
"Language-Team: Danish (https://www.transifex.com/grocy/teams/93189/da/)\n"
1212
"MIME-Version: 1.0\n"
1313
"Content-Type: text/plain; charset=UTF-8\n"
@@ -17,16 +17,16 @@ msgstr ""
1717
"X-Domain: grocy/chore_types\n"
1818

1919
msgid "manually"
20-
msgstr "Manuelt"
20+
msgstr "manuelt"
2121

2222
msgid "dynamic-regular"
23-
msgstr ""
23+
msgstr "gentagende-dynamisk"
2424

2525
msgid "daily"
26-
msgstr ""
26+
msgstr "daglig"
2727

2828
msgid "weekly"
29-
msgstr ""
29+
msgstr "ugentlig"
3030

3131
msgid "monthly"
32-
msgstr ""
32+
msgstr "månedlig"
+13-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
# Translators:
2+
# Troels Siggaard <[email protected]>, 2019
3+
# Bernd Bestel <[email protected]>, 2019
14
#
25
msgid ""
36
msgstr ""
47
"Project-Id-Version: \n"
58
"Report-Msgid-Bugs-To: \n"
69
"POT-Creation-Date: 2019-05-01T17:59:17+00:00\n"
710
"PO-Revision-Date: 2019-05-01 17:42+0000\n"
11+
"Last-Translator: Bernd Bestel <[email protected]>, 2019\n"
812
"Language-Team: Danish (https://www.transifex.com/grocy/teams/93189/da/)\n"
913
"MIME-Version: 1.0\n"
1014
"Content-Type: text/plain; charset=UTF-8\n"
@@ -14,19 +18,22 @@ msgstr ""
1418
"X-Domain: grocy/component_translations\n"
1519

1620
msgid "timeago_locale"
17-
msgstr ""
21+
msgstr "timdsiden_lokal"
1822

1923
msgid "timeago_nan"
20-
msgstr ""
24+
msgstr "tidsiden_ien"
2125

2226
msgid "moment_locale"
23-
msgstr ""
27+
msgstr "tidspunkt_lokal"
2428

2529
msgid "datatables_localization"
26-
msgstr ""
30+
msgstr "datatabeller_lokalisering"
2731

2832
msgid "summernote_locale"
29-
msgstr ""
33+
msgstr "summernote_lokal"
3034

3135
msgid "fullcalendar_locale"
32-
msgstr ""
36+
msgstr "fuldkalender_lokal"
37+
38+
msgid "bootstrap-select_locale"
39+
msgstr "da_DK"

0 commit comments

Comments
 (0)