From f0e2ebe314fb7bcc43ce52b477dcc4ce6d5a1d8c Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 2 Jan 2024 23:34:17 +0000 Subject: [PATCH] update --- Admin/Install/db.json | 26 +++ Controller/ApiController.php | 266 ++++++++++++++++++++++++++++ Controller/BackendController.php | 33 +++- Models/Employee.php | 1 + Models/EmployeeMapper.php | 7 + Models/PermissionCategory.php | 4 +- Theme/Backend/Lang/da.lang.php | 7 +- Theme/Backend/Lang/en.lang.php | 3 +- Theme/Backend/staff-create.tpl.php | 8 +- Theme/Backend/staff-list.tpl.php | 10 +- Theme/Backend/staff-profile.tpl.php | 56 ++---- 11 files changed, 365 insertions(+), 56 deletions(-) diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 02d0216..5c254cb 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -60,6 +60,32 @@ } } }, + "hr_staff_note": { + "name": "hr_staff_note", + "fields": { + "hr_staff_note_id": { + "name": "hr_staff_note_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "hr_staff_note_staff": { + "name": "hr_staff_note_staff", + "type": "INT", + "null": false, + "foreignTable": "hr_staff", + "foreignKey": "hr_staff_id" + }, + "hr_staff_note_doc": { + "name": "hr_staff_note_doc", + "type": "INT", + "null": false, + "foreignTable": "editor_doc", + "foreignKey": "editor_doc_id" + } + } + }, "hr_staff_history": { "name": "hr_staff_history", "fields": { diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 8bacec0..1309a0b 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -23,12 +23,18 @@ use Modules\HumanResourceManagement\Models\EmployeeHistoryMapper; use Modules\HumanResourceManagement\Models\EmployeeMapper; use Modules\HumanResourceManagement\Models\EmployeeWorkHistory; use Modules\HumanResourceManagement\Models\EmployeeWorkHistoryMapper; +use Modules\HumanResourceManagement\Models\PermissionCategory; +use Modules\Media\Models\CollectionMapper; +use Modules\Media\Models\MediaMapper; +use Modules\Media\Models\PathSettings; use Modules\Organization\Models\NullDepartment; use Modules\Organization\Models\NullPosition; use Modules\Organization\Models\NullUnit; use Modules\Profile\Models\Profile; use Modules\Profile\Models\ProfileMapper; +use phpOMS\Account\PermissionType; use phpOMS\Message\Http\RequestStatusCode; +use phpOMS\Message\NotificationLevel; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; use phpOMS\Stdlib\Base\AddressType; @@ -432,4 +438,264 @@ final class ApiController extends Controller return $history; } + + /** + * Api method to create a bill + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param array $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiMediaAddToEmployee(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void + { + if (!empty($val = $this->validateMediaAddToEmployee($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidAddResponse($request, $response, $val); + + return; + } + + /** @var \Modules\HumanResourceManagement\Models\Employee $employee */ + $employee = EmployeeMapper::get()->where('id', (int) $request->getData('employee'))->execute(); + $path = $this->createEmployeeDir($employee); + + $uploaded = []; + if (!empty($uploadedFiles = $request->files)) { + $uploaded = $this->app->moduleManager->get('Media')->uploadFiles( + names: [], + fileNames: [], + files: $uploadedFiles, + account: $request->header->account, + basePath: __DIR__ . '/../../../Modules/Media/Files' . $path, + virtualPath: $path, + pathSettings: PathSettings::FILE_PATH, + hasAccountRelation: false, + readContent: $request->getDataBool('parse_content') ?? false + ); + + $collection = null; + foreach ($uploaded as $media) { + $this->createModelRelation( + $request->header->account, + $employee->id, + $media->id, + EmployeeMapper::class, + 'files', + '', + $request->getOrigin() + ); + + if ($request->hasData('type')) { + $this->createModelRelation( + $request->header->account, + $media->id, + $request->getDataInt('type'), + MediaMapper::class, + 'types', + '', + $request->getOrigin() + ); + } + + if ($collection === null) { + /** @var \Modules\Media\Models\Collection $collection */ + $collection = MediaMapper::getParentCollection($path)->limit(1)->execute(); + + if ($collection->id === 0) { + $collection = $this->app->moduleManager->get('Media')->createRecursiveMediaCollection( + $path, + $request->header->account, + __DIR__ . '/../../../Modules/Media/Files' . $path, + ); + } + } + + $this->createModelRelation( + $request->header->account, + $collection->id, + $media->id, + CollectionMapper::class, + 'sources', + '', + $request->getOrigin() + ); + } + } + + if (!empty($mediaFiles = $request->getDataJson('media'))) { + foreach ($mediaFiles as $media) { + $this->createModelRelation( + $request->header->account, + $employee->id, + (int) $media, + EmployeeMapper::class, + 'files', + '', + $request->getOrigin() + ); + } + } + + $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Media', 'Media added to employee.', [ + 'upload' => $uploaded, + 'media' => $mediaFiles, + ]); + } + + /** + * Create media directory path + * + * @param Employee $employee Employee + * + * @return string + * + * @since 1.0.0 + */ + private function createEmployeeDir(Employee $employee) : string + { + return '/Modules/HumanResourceManagement/Employee/' + . $this->app->unitId . '/' + . $employee->id; + } + + /** + * Method to validate bill creation from request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateMediaAddToEmployee(RequestAbstract $request) : array + { + $val = []; + if (($val['media'] = (!$request->hasData('media') && empty($request->files))) + || ($val['employee'] = !$request->hasData('employee')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to create notes + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param array $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiNoteCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void + { + if (!empty($val = $this->validateNoteCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + + $request->setData('virtualpath', '/Modules/HumanResourceManagement/Employee/' . $request->getData('id'), true); + $this->app->moduleManager->get('Editor', 'Api')->apiEditorCreate($request, $response, $data); + + if ($response->header->status !== RequestStatusCode::R_200) { + return; + } + + $responseData = $response->getDataArray($request->uri->__toString()); + if (!\is_array($responseData)) { + return; + } + + $model = $responseData['response']; + $this->createModelRelation($request->header->account, (int) $request->getData('id'), $model->id, EmployeeMapper::class, 'notes', '', $request->getOrigin()); + } + + /** + * Validate item note create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateNoteCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['id'] = !$request->hasData('id')) + ) { + return $val; + } + + return []; + } + + /** + * Api method to update Note + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param array $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiNoteUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void + { + $accountId = $request->header->account; + if (!$this->app->accountManager->get($accountId)->hasPermission( + PermissionType::MODIFY, $this->app->unitId, $this->app->appId, self::NAME, PermissionCategory::EMPLOYEE_NOTE, $request->getDataInt('id')) + ) { + $this->fillJsonResponse($request, $response, NotificationLevel::HIDDEN, '', '', []); + $response->header->status = RequestStatusCode::R_403; + + return; + } + + $this->app->moduleManager->get('Editor', 'Api')->apiEditorUpdate($request, $response, $data); + } + + /** + * Api method to delete Note + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param array $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiNoteDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void + { + $accountId = $request->header->account; + if (!$this->app->accountManager->get($accountId)->hasPermission( + PermissionType::DELETE, $this->app->unitId, $this->app->appId, self::NAME, PermissionCategory::EMPLOYEE_NOTE, $request->getDataInt('id')) + ) { + $this->fillJsonResponse($request, $response, NotificationLevel::HIDDEN, '', '', []); + $response->header->status = RequestStatusCode::R_403; + + return; + } + + $this->app->moduleManager->get('Editor', 'Api')->apiEditorDelete($request, $response, $data); + } } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 62a86cb..a3f0ca7 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -15,11 +15,13 @@ declare(strict_types=1); namespace Modules\HumanResourceManagement\Controller; use Modules\HumanResourceManagement\Models\EmployeeMapper; +use Modules\Media\Models\MediaMapper; use Modules\Organization\Models\DepartmentMapper; use phpOMS\Contract\RenderableInterface; use phpOMS\DataStorage\Database\Query\OrderType; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; +use Modules\Profile\Models\SettingsEnum; use phpOMS\Views\View; /** @@ -34,7 +36,7 @@ use phpOMS\Views\View; final class BackendController extends Controller { /** - * Routing end-point for application behaviour. + * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -54,15 +56,27 @@ final class BackendController extends Controller $view->data['employees'] = EmployeeMapper::getAll() ->with('profile') ->with('profile/account') + ->with('image') + ->with('profile/image') ->with('companyHistory') ->with('companyHistory/unit') ->execute(); + /** @var \Model\Setting $profileImage */ + $profileImage = $this->app->appSettings->get(names: SettingsEnum::DEFAULT_PROFILE_IMAGE, module: 'Profile'); + + /** @var \Modules\Media\Models\Media $image */ + $image = MediaMapper::get() + ->where('id', (int) $profileImage->content) + ->execute(); + + $view->data['defaultImage'] = $image; + return $view; } /** - * Routing end-point for application behaviour. + * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -86,7 +100,7 @@ final class BackendController extends Controller } /** - * Routing end-point for application behaviour. + * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -106,6 +120,10 @@ final class BackendController extends Controller $employee = EmployeeMapper::get() ->with('profile') ->with('profile/account') + ->with('image') + ->with('notes') + ->with('files') + ->with('profile/image') ->with('companyHistory') ->with('companyHistory/unit') ->with('companyHistory/department') @@ -126,11 +144,14 @@ final class BackendController extends Controller $view->data['employee'] = $employee; + $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); + $view->data['vehicle-notes'] = new \Modules\Editor\Theme\Backend\Components\Compound\BaseView($this->app->l11nManager, $request, $response); + return $view; } /** - * Routing end-point for application behaviour. + * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -153,7 +174,7 @@ final class BackendController extends Controller } /** - * Routing end-point for application behaviour. + * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response @@ -176,7 +197,7 @@ final class BackendController extends Controller } /** - * Routing end-point for application behaviour. + * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response diff --git a/Models/Employee.php b/Models/Employee.php index 53fe6b2..9f84426 100755 --- a/Models/Employee.php +++ b/Models/Employee.php @@ -332,4 +332,5 @@ class Employee implements \JsonSerializable } use \Modules\Media\Models\MediaListTrait; + use \Modules\Editor\Models\EditorDocListTrait; } diff --git a/Models/EmployeeMapper.php b/Models/EmployeeMapper.php index 708bb2b..fa4252d 100755 --- a/Models/EmployeeMapper.php +++ b/Models/EmployeeMapper.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace Modules\HumanResourceManagement\Models; +use Modules\Editor\Models\EditorDocMapper; use Modules\Media\Models\MediaMapper; use Modules\Profile\Models\ProfileMapper; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; @@ -101,6 +102,12 @@ final class EmployeeMapper extends DataMapperFactory 'self' => 'hr_staff_education_history_staff', 'external' => null, ], + 'notes' => [ + 'mapper' => EditorDocMapper::class, /* mapper of the related object */ + 'table' => 'hr_staff_note', /* table of the related object, null if no relation table is used (many->1) */ + 'external' => 'hr_staff_note_doc', + 'self' => 'hr_staff_note_staff', + ], ]; /** diff --git a/Models/PermissionCategory.php b/Models/PermissionCategory.php index 2ae5eb2..fdd96c0 100755 --- a/Models/PermissionCategory.php +++ b/Models/PermissionCategory.php @@ -17,7 +17,7 @@ namespace Modules\HumanResourceManagement\Models; use phpOMS\Stdlib\Base\Enum; /** - * Permision state enum. + * Permission category enum. * * @package Modules\HumanResourceManagement\Models * @license OMS License 2.0 @@ -31,4 +31,6 @@ abstract class PermissionCategory extends Enum public const DEPARTMENT = 2; public const POSITION = 3; + + public const EMPLOYEE_NOTE = 4; } diff --git a/Theme/Backend/Lang/da.lang.php b/Theme/Backend/Lang/da.lang.php index 72080b3..9706012 100755 --- a/Theme/Backend/Lang/da.lang.php +++ b/Theme/Backend/Lang/da.lang.php @@ -15,7 +15,7 @@ declare(strict_types=1); return ['HumanResourceManagement' => [ 'Account' => 'Konto', 'Active' => 'Aktiv', - 'Address' => '', + 'Address' => 'Addresse', 'Birthday' => 'Fødselsdag', 'Clocking' => 'Clocking.', 'Contracts' => 'Kontrakter', @@ -40,12 +40,13 @@ return ['HumanResourceManagement' => [ 'Position' => 'Position', 'ProfileImage' => 'Profilbillede.', 'Remarks' => 'Bemærkninger.', - 'Salary' => '', + 'Salary' => 'Geahlt', + 'Notes' => 'Notizen', 'Shifts' => 'Skift', 'Staff' => 'Personale', 'Start' => 'Start', 'Status' => 'Status.', - 'Title' => '', + 'Title' => 'Titel', 'Unit' => 'Enhed', 'Vacation' => 'Ferie', 'Work' => 'Arbejde', diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index 269bc12..fdbc6ea 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -40,7 +40,8 @@ return ['HumanResourceManagement' => [ 'Position' => 'Position', 'ProfileImage' => 'Profile image', 'Remarks' => 'Remarks', - 'Salary' => '', + 'Salary' => 'Salary', + 'Notes' => 'Notes', 'Shifts' => 'Shifts', 'Staff' => 'Staff', 'Start' => 'Start', diff --git a/Theme/Backend/staff-create.tpl.php b/Theme/Backend/staff-create.tpl.php index daf1e2c..84aaae2 100755 --- a/Theme/Backend/staff-create.tpl.php +++ b/Theme/Backend/staff-create.tpl.php @@ -35,11 +35,11 @@ echo $this->data['nav']->render();