diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 74c945d..6ae0163 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -16,7 +16,9 @@ namespace Modules\Support\Controller; use Modules\Admin\Models\AccountMapper; use Modules\Admin\Models\ContactType; +use Modules\Messages\Models\EmailMapper; use Modules\Support\Models\NullSupportApp; +use Modules\Support\Models\SettingsEnum; use Modules\Support\Models\SupportApp; use Modules\Support\Models\SupportAppMapper; use Modules\Support\Models\Ticket; @@ -29,8 +31,6 @@ use Modules\Tasks\Models\TaskType; use phpOMS\Message\Http\RequestStatusCode; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; -use Modules\Messages\Models\EmailMapper; -use Modules\Support\Models\SettingsEnum; /** * Api controller for the tickets module. @@ -93,6 +93,16 @@ final class ApiController extends Controller $this->createStandardCreateResponse($request, $response, $ticket); } + /** + * Create email notification regarding ticket + * + * @param Ticket $ticket Ticket the notification is for + * @param string $language Language of the email (e.g. 'en', 'de') + * + * @return void + * + * @since 1.0.0 + */ public function notifyEmail(Ticket $ticket, string $language) : void { // @todo decide what to send via email @@ -109,20 +119,16 @@ final class ApiController extends Controller ->with('attributes/types') ->with('attributes/value') ->with('account/contacts') - ->where('account', $ticket->task->for->id) + ->where('account', $ticket->task->for?->id) ->where('attributes/types/name', ['support_emails', 'support_email_address'], 'IN') ->execute(); - if ($client->getAttribute('support_emails')->value->getValue() === false) { - return; - } - // @todo should this really be a string? Shouldn't this be a contact element? Same goes for billing. - $email = $client->getAttribute('support_email_address')->value->getValue(); + $email = $client->getAttribute('support_email_address')->value->valueStr; $account = $client->account; } - if ($email === '' || $email === null) { + if (empty($email)) { $supplier = null; if ($this->app->moduleManager->isActive('SupplierManagement')) { @@ -131,36 +137,40 @@ final class ApiController extends Controller ->with('attributes/types') ->with('attributes/value') ->with('account/contacts') - ->where('account', $ticket->task->for->id) + ->where('account', $ticket->task->for?->id) ->where('attributes/types/name', ['support_emails', 'support_email_address'], 'IN') ->execute(); + + if ($supplier->getAttribute('support_emails')->value->getValue() === false) { + return; + } } - if ($supplier->getAttribute('support_emails')->value->getValue() === false) { + if ($supplier === null) { return; } // @todo should this really be a string? Shouldn't this be a contact element? Same goes for billing. - $email = $supplier->getAttribute('support_email_address')->value->getValue(); + $email = $supplier->getAttribute('support_email_address')->value->valueStr; $account = $supplier->account; } - if ($email === '' || $email === null) { + if (empty($email)) { $account = AccountMapper::get() ->with('contacts') - ->where('id', $ticket->task->for->id) + ->where('id', $ticket->task->for?->id) ->execute(); $email = $account->getContactByType(ContactType::EMAIL)->content; } - if ($email === '' || $email === null) { + if (empty($email)) { return; } $handler = $this->app->moduleManager->get('Admin', 'Api')->setUpServerMailHandler(); - /** @var \Model\Setting $billingTemplate */ + /** @var \Model\Setting $supportTemplate */ $supportTemplate = $this->app->appSettings->get( names: SettingsEnum::SUPPORT_EMAIL_TEMPLATE, module: 'Support' @@ -189,9 +199,9 @@ final class ApiController extends Controller $mail->template = \array_merge( $mail->template, [ - '{user_name}' => $account->login, - '{ticket_id}' => $ticket->id, - '{ticket_status}' => $lang['Tasks']['S' . $ticket->task->status], + '{user_name}' => $account?->login, + '{ticket_id}' => $ticket->id, + '{ticket_status}' => $lang['Tasks']['S' . $ticket->task->status], '{ticket_subject}' => $ticket->task->title, ] ); @@ -358,7 +368,7 @@ final class ApiController extends Controller $this->createModel($request->header->account, $element, TicketElementMapper::class, 'ticket_element', $request->getOrigin()); $this->updateModel($request->header->account, $old, $ticket->task, TaskMapper::class, 'ticket', $request->getOrigin()); - $ticket->task->taskElements[] = $element; + $ticket->task->taskElements[] = $element->taskElement; $this->notifyEmail($ticket, $response->header->l11n->language); diff --git a/Controller/BackendController.php b/Controller/BackendController.php index f05c74f..0e6aa08 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -16,22 +16,22 @@ namespace Modules\Support\Controller; use Model\SettingMapper; use Modules\Media\Models\MediaMapper; +use Modules\Profile\Models\SettingsEnum as ProfileSettingsEnum; use Modules\Support\Models\SupportAppMapper; use Modules\Support\Models\TicketMapper; use Modules\Support\Views\TicketView; -use phpOMS\Asset\AssetType; -use phpOMS\Contract\RenderableInterface; -use phpOMS\DataStorage\Database\Query\OrderType; -use phpOMS\Message\RequestAbstract; -use phpOMS\Message\ResponseAbstract; -use phpOMS\Views\View; -use Modules\Profile\Models\SettingsEnum as ProfileSettingsEnum; use Modules\Tasks\Models\AccountRelationMapper; use Modules\Tasks\Models\TaskElementMapper; use Modules\Tasks\Models\TaskMapper; use Modules\Tasks\Models\TaskStatus; use Modules\Tasks\Models\TaskType; +use phpOMS\Asset\AssetType; +use phpOMS\Contract\RenderableInterface; use phpOMS\DataStorage\Database\Query\Builder; +use phpOMS\DataStorage\Database\Query\OrderType; +use phpOMS\Message\RequestAbstract; +use phpOMS\Message\ResponseAbstract; +use phpOMS\Views\View; /** * Support controller class. @@ -102,7 +102,7 @@ final class BackendController extends Controller $view->data['tickets'] = $mapperQuery->execute(); - $view->data['stats'] = TicketMapper::getStatOverview($request->header->account); + $view->data['stats'] = TicketMapper::getStatOverview(); return $view; } @@ -140,7 +140,6 @@ final class BackendController extends Controller ->with('app') ->where('task/tags/title/language', $request->header->l11n->language); - /** @var \Modules\Support\Models\Ticket */ $view->data['ticket'] = $request->hasData('for') ? $mapperQuery->where('task', (int) $request->getData('for'))->execute() : $mapperQuery->where('id', (int) $request->getData('id'))->execute(); @@ -160,7 +159,7 @@ final class BackendController extends Controller $view->data['tickets'] = TicketMapper::getAll() ->with('task') - ->where('task/for', $view->data['ticket']->task->for->id) + ->where('task/for', $view->data['ticket']->task->for?->id) ->sort('createdAt', OrderType::DESC) ->offset(1) ->limit(5) @@ -171,7 +170,7 @@ final class BackendController extends Controller $view->data['hasContractManagement'] = $this->app->moduleManager->isActive('ContractManagement'); if ($view->data['hasContractManagement']) { $view->data['contracts'] = \Modules\ContractManagement\Models\ContractMapper::getAll() - ->where('account', $view->data['ticket']->task->for->id) + ->where('account', $view->data['ticket']->task->for?->id) ->where('end', $dt, '>=') // @todo consider to also allow $end === null ->sort('createdAt', OrderType::DESC) ->limit(5) diff --git a/Models/TicketMapper.php b/Models/TicketMapper.php index 9fe73c7..202592d 100755 --- a/Models/TicketMapper.php +++ b/Models/TicketMapper.php @@ -14,7 +14,6 @@ declare(strict_types=1); namespace Modules\Support\Models; -use Modules\Admin\Models\AccountMapper; use Modules\Tasks\Models\AccountRelationMapper; use Modules\Tasks\Models\TaskElementMapper; use Modules\Tasks\Models\TaskMapper; @@ -88,7 +87,7 @@ final class TicketMapper extends DataMapperFactory 'app' => [ 'mapper' => SupportAppMapper::class, 'external' => 'support_ticket_app', - ] + ], ]; /** @@ -107,7 +106,14 @@ final class TicketMapper extends DataMapperFactory */ public const PRIMARYFIELD = 'support_ticket_id'; - public static function getStatOverview(int $account) : array + /** + * Get general ticket stats + * + * @return array{total:int, unassigned:int, open:int, closed:int, inprogress:int} + * + * @since 1.0.0 + */ + public static function getStatOverview() : array { $start = SmartDateTime::startOfMonth(); diff --git a/Theme/Backend/Lang/de.lang.php b/Theme/Backend/Lang/de.lang.php index d1c2769..c2566dc 100755 --- a/Theme/Backend/Lang/de.lang.php +++ b/Theme/Backend/Lang/de.lang.php @@ -20,7 +20,7 @@ return ['Support' => [ 'AverageProcessTime' => 'Durchschn. Prozess Zeit', 'Closed' => 'Geschlossen', 'Completion' => 'Abgeschlossen', - 'Advanced' => 'Fortgeschritten', + 'Advanced' => 'Fortgeschritten', 'Created' => 'Erstellt', 'Creator' => 'Ersteller', 'Day' => 'Tag', diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index 0632b84..c224fe6 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -20,7 +20,7 @@ return ['Support' => [ 'AverageProcessTime' => 'Avg. Process Time', 'Closed' => 'Closed', 'Completion' => 'Completion', - 'Advanced' => 'Advanced', + 'Advanced' => 'Advanced', 'Created' => 'Created', 'Creator' => 'Creator', 'Day' => 'Day', diff --git a/Theme/Backend/user-support-dashboard.tpl.php b/Theme/Backend/user-support-dashboard.tpl.php index dd47fdf..9ee44b3 100755 --- a/Theme/Backend/user-support-dashboard.tpl.php +++ b/Theme/Backend/user-support-dashboard.tpl.php @@ -15,7 +15,7 @@ declare(strict_types=1); use phpOMS\Uri\UriFactory; /** - * @var \phpOMS\Views\View $this + * @var \phpOMS\Views\View $this */ echo $this->data['nav']->render(); ?>