diff --git a/Admin/Install/attributes.json b/Admin/Install/attributes.json index d92bee4..f43dcff 100755 --- a/Admin/Install/attributes.json +++ b/Admin/Install/attributes.json @@ -8,7 +8,7 @@ "value_type": "int", "is_custom_allowed": false, "validation_pattern": "", - "is_required": true, + "is_required": false, "default_value": "", "values": [ { @@ -19,5 +19,126 @@ } } ] + }, + { + "name": "item", + "l11n": { + "en": "Item", + "de": "Artikel" + }, + "value_type": "int", + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "lot_external", + "l11n": { + "en": "Lot/SN External", + "de": "Charge/SN Extern" + }, + "value_type": "int", + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "lot_internal", + "l11n": { + "en": "Lot/SN", + "de": "Charge/SN" + }, + "value_type": "int", + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "justified", + "l11n": { + "en": "Justified", + "de": "Berechtigt" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [ + { + "value": 0 + }, + { + "value": 1 + } + ] + }, + { + "name": "recall", + "l11n": { + "en": "Recall", + "de": "Rückruf" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [ + { + "value": 0 + }, + { + "value": 1 + } + ] + }, + { + "name": "measure", + "l11n": { + "en": "measure", + "de": "Maßnahme" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [ + { + "value": 1, + "l11n": { + "en": "None", + "de": "Keine" + } + }, + { + "value": 2, + "l11n": { + "en": "Other", + "de": "Sonstige" + } + }, + { + "value": 3, + "l11n": { + "en": "Replace", + "de": "Austausch" + } + }, + { + "value": 4, + "l11n": { + "en": "Discount", + "de": "Nachlass" + } + } + ] } ] \ No newline at end of file diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 32842df..1dedb34 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -109,6 +109,14 @@ "name": "task_created_at", "type": "DATETIME", "null": false + }, + "task_unit": { + "name": "task_unit", + "type": "INT", + "null": true, + "default": null, + "foreignTable": "unit", + "foreignKey": "unit_id" } } }, diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php index c42f897..8fa4ebc 100755 --- a/Admin/Routes/Web/Api.php +++ b/Admin/Routes/Web/Api.php @@ -23,6 +23,7 @@ return [ 'dest' => '\Modules\Tasks\Controller\ApiController:apiTaskCreate', 'verb' => RouteVerb::PUT, 'csrf' => true, + 'active' => true, 'permission' => [ 'module' => ApiController::NAME, 'type' => PermissionType::CREATE, @@ -33,6 +34,7 @@ return [ 'dest' => '\Modules\Tasks\Controller\ApiController:apiTaskSet', 'verb' => RouteVerb::SET, 'csrf' => true, + 'active' => true, 'permission' => [ 'module' => ApiController::NAME, 'type' => PermissionType::MODIFY, @@ -43,6 +45,7 @@ return [ 'dest' => '\Modules\Tasks\Controller\ApiController:apiTaskGet', 'verb' => RouteVerb::GET, 'csrf' => true, + 'active' => true, 'permission' => [ 'module' => ApiController::NAME, 'type' => PermissionType::READ, @@ -55,6 +58,7 @@ return [ 'dest' => '\Modules\Tasks\Controller\ApiController:apiTaskReminderCreate', 'verb' => RouteVerb::PUT, 'csrf' => true, + 'active' => true, 'permission' => [ 'module' => ApiController::NAME, 'type' => PermissionType::CREATE, @@ -67,6 +71,7 @@ return [ 'dest' => '\Modules\Tasks\Controller\ApiController:apiTaskElementCreate', 'verb' => RouteVerb::PUT, 'csrf' => true, + 'active' => true, 'permission' => [ 'module' => ApiController::NAME, 'type' => PermissionType::CREATE, @@ -77,6 +82,7 @@ return [ 'dest' => '\Modules\Tasks\Controller\ApiController:apiTaskElementSet', 'verb' => RouteVerb::SET, 'csrf' => true, + 'active' => true, 'permission' => [ 'module' => ApiController::NAME, 'type' => PermissionType::MODIFY, @@ -87,6 +93,7 @@ return [ 'dest' => '\Modules\Tasks\Controller\ApiController:apiTaskElementGet', 'verb' => RouteVerb::GET, 'csrf' => true, + 'active' => true, 'permission' => [ 'module' => ApiController::NAME, 'type' => PermissionType::READ, diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index c5de7b7..b36895a 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -22,6 +22,7 @@ return [ [ 'dest' => '\Modules\Tasks\Controller\BackendController:viewTaskDashboard', 'verb' => RouteVerb::GET, + 'active' => true, 'permission' => [ 'module' => BackendController::NAME, 'type' => PermissionType::READ, @@ -33,6 +34,7 @@ return [ [ 'dest' => '\Modules\Tasks\Controller\BackendController:viewTaskList', 'verb' => RouteVerb::GET, + 'active' => true, 'permission' => [ 'module' => BackendController::NAME, 'type' => PermissionType::READ, @@ -44,6 +46,7 @@ return [ [ 'dest' => '\Modules\Tasks\Controller\BackendController:viewTaskView', 'verb' => RouteVerb::GET, + 'active' => true, 'permission' => [ 'module' => BackendController::NAME, 'type' => PermissionType::READ, @@ -55,6 +58,7 @@ return [ [ 'dest' => '\Modules\Tasks\Controller\BackendController:viewTaskCreate', 'verb' => RouteVerb::GET, + 'active' => true, 'permission' => [ 'module' => BackendController::NAME, 'type' => PermissionType::CREATE, @@ -66,6 +70,7 @@ return [ [ 'dest' => '\Modules\Tasks\Controller\BackendController:viewTaskAnalysis', 'verb' => RouteVerb::GET, + 'active' => true, 'permission' => [ 'module' => BackendController::NAME, 'type' => PermissionType::READ, diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 0b84498..a21b9d3 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -463,6 +463,7 @@ final class ApiController extends Controller $task->status = TaskStatus::OPEN; $task->type = TaskType::tryFromValue($request->getDataInt('type')) ?? TaskType::SINGLE; $task->redirect = $request->getDataString('redirect') ?? ''; + $task->unit = $request->getDataInt('unit'); if ($request->hasData('due')) { $task->due = $request->getDataDateTime('due'); diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 1663fbb..bdb1b2d 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -18,6 +18,7 @@ use Modules\Dashboard\Models\DashboardElementInterface; use Modules\Media\Models\MediaMapper; use Modules\Profile\Models\SettingsEnum; use Modules\Tasks\Models\AccountRelationMapper; +use Modules\Tasks\Models\Attribute\TaskAttributeTypeMapper; use Modules\Tasks\Models\PermissionCategory; use Modules\Tasks\Models\TaskElementMapper; use Modules\Tasks\Models\TaskMapper; @@ -289,8 +290,15 @@ final class BackendController extends Controller implements DashboardElementInte ->with('taskElements/media') ->with('taskElements/accRelation') ->with('taskElements/accRelation/relation') + ->with('attributes') + ->with('attributes/type') + ->with('attributes/type/l11n') + ->with('attributes/value') + ->with('attributes/value/l11n') ->where('id', (int) $request->getData('id')) ->where('tags/title/language', $request->header->l11n->language) + ->where('attributes/type/l11n/language', $response->header->l11n->language) + ->where('attributes/value/l11n/language', [$response->header->l11n->language, null]) ->execute(); $accountId = $request->header->account; @@ -306,6 +314,11 @@ final class BackendController extends Controller implements DashboardElementInte return $view; } + $view->data['attributeTypes'] = TaskAttributeTypeMapper::getAll() + ->with('l11n') + ->where('l11n/language', $response->header->l11n->language) + ->executeGetArray(); + $reminderStatus = []; // Set task as seen @@ -350,11 +363,12 @@ final class BackendController extends Controller implements DashboardElementInte $view->data['task'] = $task; $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1001101001, $request, $response); - $accGrpSelector = new \Modules\Profile\Theme\Backend\Components\AccountGroupSelector\BaseView($this->app->l11nManager, $request, $response); - $view->data['accGrpSelector'] = $accGrpSelector; + $view->data['accGrpSelector'] = new \Modules\Profile\Theme\Backend\Components\AccountGroupSelector\BaseView($this->app->l11nManager, $request, $response); - $editor = new \Modules\Editor\Theme\Backend\Components\Editor\BaseView($this->app->l11nManager, $request, $response); - $view->data['editor'] = $editor; + $view->data['editor'] = new \Modules\Editor\Theme\Backend\Components\Editor\BaseView($this->app->l11nManager, $request, $response); + + $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); + $view->data['attributeView']->data['default_localization'] = $this->app->l11nServer; return $view; } diff --git a/Models/AccountRelationMapper.php b/Models/AccountRelationMapper.php index 40c8032..e15bf5c 100755 --- a/Models/AccountRelationMapper.php +++ b/Models/AccountRelationMapper.php @@ -18,7 +18,7 @@ use Modules\Admin\Models\AccountMapper; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** - * Mapper class. + * AccountRelation mapper class. * * @package Modules\Tasks\Models * @license OMS License 2.0 diff --git a/Models/GroupRelationMapper.php b/Models/GroupRelationMapper.php index c0729f3..78aabf7 100755 --- a/Models/GroupRelationMapper.php +++ b/Models/GroupRelationMapper.php @@ -18,7 +18,7 @@ use Modules\Admin\Models\GroupMapper; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** - * Mapper class. + * GroupRelation mapper class. * * @package Modules\Tasks\Models * @license OMS License 2.0 diff --git a/Models/Task.php b/Models/Task.php index 044abb5..1d7a218 100755 --- a/Models/Task.php +++ b/Models/Task.php @@ -208,6 +208,8 @@ class Task implements \JsonSerializable */ public ?Account $for = null; + public ?int $unit = null; + /** * Constructor. * diff --git a/Models/TaskElementMapper.php b/Models/TaskElementMapper.php index 3a8a263..a0ac1bb 100755 --- a/Models/TaskElementMapper.php +++ b/Models/TaskElementMapper.php @@ -19,7 +19,7 @@ use Modules\Media\Models\MediaMapper; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** - * Mapper class. + * TaskElement mapper class. * * @package Modules\Tasks\Models * @license OMS License 2.0 diff --git a/Models/TaskMapper.php b/Models/TaskMapper.php index f8c3c5d..7d4ef6d 100755 --- a/Models/TaskMapper.php +++ b/Models/TaskMapper.php @@ -25,7 +25,7 @@ use phpOMS\DataStorage\Database\Query\Builder; use phpOMS\DataStorage\Database\Query\Where; /** - * Mapper class. + * Task mapper class. * * @package Modules\Tasks\Models * @license OMS License 2.0 @@ -63,6 +63,7 @@ final class TaskMapper extends DataMapperFactory 'task_created_by' => ['name' => 'task_created_by', 'type' => 'int', 'internal' => 'createdBy', 'readonly' => true], 'task_for' => ['name' => 'task_for', 'type' => 'int', 'internal' => 'for'], 'task_created_at' => ['name' => 'task_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt', 'readonly' => true], + 'task_unit' => ['name' => 'task_unit', 'type' => 'int', 'internal' => 'unit'], ]; /** diff --git a/Theme/Backend/task-view.tpl.php b/Theme/Backend/task-view.tpl.php index b00ff99..966703c 100644 --- a/Theme/Backend/task-view.tpl.php +++ b/Theme/Backend/task-view.tpl.php @@ -27,404 +27,431 @@ $cElements = \count($elements); $color = $this->getStatus($task->status); echo $this->data['nav']->render(); ?> +
+
+ +
+
+ request->uri->fragment === 'c-tab-1' ? ' checked' : ''; ?>> +
+
+
+ data['reminder'])) : ?> +
+
getHtml('ReminderedBy'); ?> data['reminder'])->reminderBy->name1; ?>
+
+ -
-
- data['reminder'])) : ?> -
-
getHtml('ReminderedBy'); ?> data['reminder'])->reminderBy->name1; ?>
-
- - -
- isEditable) : ?> - - - -
- - <?= $this->getHtml('User', '0', '0'); ?> - - - printHtml($task->createdBy->name1); ?> - printHtml($task->createdAt->format('Y/m/d H:i')); ?> - - -
- notifications -
- - getHtml('S' . $task->status); ?> - -
-
-
- printHtml($task->title); ?> -
description; ?>
- tags as $tag) : ?> - - icon) ? '' : '' . $this->printHtml($tag->icon) . ''; ?> - printHtml($tag->getL11n()); ?> - - - -
- - - name; ?> - - -
- -
-
-
-
-
- priority === TaskPriority::NONE) : ?> - getHtml('Due'); ?>: printHtml($task->due->format('Y/m/d H:i')); ?> - - getHtml('Priority'); ?>: getHtml('P' . $task->priority); ?> - -
-
-
- isEditable && $this->request->header->account === $task->createdBy->id) : ?> -
- - - -
+
+ isEditable) : ?> + + -
-
-
-
- -
- - isEditable) : ?> - - - $element) : ++$c; ?> - status !== $previous->status) - ) : ?> -
- getHtml('status_change'), - '' . $this->printHtml( - $this->renderUserName( - '%3$s %2$s %1$s', - [$element->createdBy->name1, $element->createdBy->name2, $element->createdBy->name3, $element->createdBy->login]) - ) . '', - $element->createdAt->format('Y-m-d H:i') - ); ?> - - getHtml('S' . $element->status); ?> - -
-
- - - priority !== $previous->priority) - ) : ?> -
-
- getHtml('priority_change'), - '' . $this->printHtml( - $this->renderUserName( - '%3$s %2$s %1$s', - [$element->createdBy->name1, $element->createdBy->name2, $element->createdBy->name3, $element->createdBy->login]) - ) . '', - $element->createdAt->format('Y-m-d H:i') - ); ?> - - getHtml('P' . $element->priority); ?> - -
-
- - - description !== '') : ?> -
-
-
- - <?= $this->getHtml('User', '0', '0'); ?> - - - printHtml( - $this->renderUserName( - '%3$s %2$s %1$s', - [$element->createdBy->name1, $element->createdBy->name2, $element->createdBy->name3, $element->createdBy->login]) - ); ?> - printHtml($element->createdAt->format('Y-m-d H:i')); ?> - -
-
- - files; - if ($element->description !== '') : ?> -
-
printHtml($task->title); ?> +
description; ?>
- - + data-value="">description; ?>
+ tags as $tag) : ?> + + icon) ? '' : '' . $this->printHtml($tag->icon) . ''; ?> + printHtml($tag->getL11n()); ?> + + +
- - name; ?> + + + name; ?> +
- - isEditable - && $this->request->header->account === $element->createdBy->id - ) : ?> -
- status !== TaskStatus::CANCELED - || $element->status !== TaskStatus::DONE - || $element->status !== TaskStatus::SUSPENDED - || $c != $cElements - ) : ?> -
- priority === TaskPriority::NONE - && ($previous !== null - && $previous->due->format('Y/m/d H:i') !== $element->due->format('Y/m/d H:i') - ) - ) : ?> - getHtml('Due'); ?>: printHtml($element->due->format('Y/m/d H:i')); ?> - priority !== $element->priority) : ?> - getHtml('Priority'); ?>: getHtml('P' . $element->priority); ?> - +
+
+
+
+ priority === TaskPriority::NONE) : ?> + getHtml('Due'); ?>: printHtml($task->due->format('Y/m/d H:i')); ?> + + getHtml('Priority'); ?>: getHtml('P' . $task->priority); ?> + +
+
+
+ isEditable && $this->request->header->account === $task->createdBy->id) : ?> +
+ + + +
+ +
- - - isEditable - && $this->request->header->account === $element->createdBy->id - ) : ?> -
- - - - -
- -
- -
- - - getTo(); - if (\count($tos) > 1 - || (!empty($tos) && $tos[0]->getRelation()->id !== $element->createdBy->id) - ) : ?> -
-
- - -
-
-
-
-
-
getHtml('Message'); ?>
-
-
- data['editor']->render('task-editor'); ?> -
+
+ + isEditable) : ?> + + + $element) : ++$c; ?> + status !== $previous->status) + ) : ?> +
+
+ getHtml('status_change'), + '' . $this->printHtml( + $this->renderUserName( + '%3$s %2$s %1$s', + [$element->createdBy->name1, $element->createdBy->name2, $element->createdBy->name3, $element->createdBy->login]) + ) . '', + $element->createdAt->format('Y-m-d H:i') + ); ?> + + getHtml('S' . $element->status); ?> + +
+
+ -
-
- - + priority !== $previous->priority) + ) : ?> +
+
+ getHtml('priority_change'), + '' . $this->printHtml( + $this->renderUserName( + '%3$s %2$s %1$s', + [$element->createdBy->name1, $element->createdBy->name2, $element->createdBy->name3, $element->createdBy->login]) + ) . '', + $element->createdAt->format('Y-m-d H:i') + ); ?> + + getHtml('P' . $element->priority); ?> + +
+
+ -
- - -
+ description !== '') : ?> +
+
+
+ + <?= $this->getHtml('User', '0', '0'); ?> + + + printHtml( + $this->renderUserName( + '%3$s %2$s %1$s', + [$element->createdBy->name1, $element->createdBy->name2, $element->createdBy->name3, $element->createdBy->login]) + ); ?> - printHtml($element->createdAt->format('Y-m-d H:i')); ?> + +
+
-
- - -
+ files; + if ($element->description !== '') : ?> +
+
description; ?>
-
- - -
-
-
+ +
+ + name; ?> + +
+ +
+ + isEditable + && $this->request->header->account === $element->createdBy->id + ) : ?> +
+ status !== TaskStatus::CANCELED + || $element->status !== TaskStatus::DONE + || $element->status !== TaskStatus::SUSPENDED + || $c != $cElements + ) : ?> +
+ priority === TaskPriority::NONE + && ($previous !== null + && $previous->due->format('Y/m/d H:i') !== $element->due->format('Y/m/d H:i') + ) + ) : ?> + getHtml('Due'); ?>: printHtml($element->due->format('Y/m/d H:i')); ?> + priority !== $element->priority) : ?> + getHtml('Priority'); ?>: getHtml('P' . $element->priority); ?> + +
+ -
- -
-
-
-
-
+ isEditable + && $this->request->header->account === $element->createdBy->id + ) : ?> +
+ + + + +
+ +
+ + + -
- - + getTo(); + if (\count($tos) > 1 + || (!empty($tos) && $tos[0]->getRelation()->id !== $element->createdBy->id) + ) : ?> +
+ +
+ +
-
- - + +
+
+ +
getHtml('Message'); ?>
+
+
+ data['editor']->render('task-editor'); ?> +
+ +
+ data['editor']->getData('text')->render( + 'task-editor', + 'plain', + 'taskElementCreate', + '', '', + '/content', '{/api}task?id={?id}&csrf={$CSRF}' + ); ?> +
+ +
+ + +
+ +
+ + getData('accGrpSelector')->render('iReceiver', 'to', true); ?> +
+ +
+
+ + + +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+ +
+ +
+
+
+
+
+ +
+ + +
+
+
+ + +
+ +
- +
+ + +
+
+ data['attributeView']->render( + $task->attributes, + $this->data['attributeTypes'] ?? [], + $this->data['units'] ?? [], + '{/api}task/attribute?csrf={$CSRF}', + $task->id + ); + ?> +
+
+