This commit is contained in:
Dennis Eichhorn 2024-04-07 17:31:42 +00:00
parent 2e506a6313
commit 480bda2fe1
11 changed files with 774 additions and 5 deletions

View File

@ -41,6 +41,21 @@
"permission": { "permission": 2, "category": null, "element": null },
"parent": 1008502001,
"children": []
},
{
"id": 1008502003,
"pid": "/qualitymanagement",
"type": 3,
"subtype": 1,
"name": "Create",
"uri": "{/base}/qualitymanagement/report/create?{?}",
"target": "self",
"icon": null,
"order": 5,
"from": "QualityManagement",
"permission": { "permission": 2, "category": null, "element": null },
"parent": 1008502001,
"children": []
}
]
}

21
Admin/Install/db.json Normal file
View File

@ -0,0 +1,21 @@
{
"qualitymgmt_report": {
"name": "qualitymgmt_report",
"fields": {
"qualitymgmt_report_id": {
"name": "qualitymgmt_report_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"qualitymgmt_report_task": {
"name": "qualitymgmt_report_task",
"type": "INT",
"null": false,
"foreignTable": "task",
"foreignKey": "task_id"
}
}
}
}

View File

@ -22,6 +22,7 @@ return [
[
'dest' => '\Modules\QualityManagement\Controller\BackendController:viewReportDashboard',
'verb' => RouteVerb::GET,
'active' => true,
'permission' => [
'module' => BackendController::NAME,
'type' => PermissionType::READ,
@ -33,6 +34,7 @@ return [
[
'dest' => '\Modules\QualityManagement\Controller\BackendController:viewQualityReport',
'verb' => RouteVerb::GET,
'active' => true,
'permission' => [
'module' => BackendController::NAME,
'type' => PermissionType::READ,
@ -40,10 +42,23 @@ return [
],
],
],
'^/qualitymanagement/report/create(\?.*$|$)' => [
[
'dest' => '\Modules\QualityManagement\Controller\BackendController:viewQualityReportCreate',
'verb' => RouteVerb::GET,
'active' => true,
'permission' => [
'module' => BackendController::NAME,
'type' => PermissionType::CREATE,
'state' => PermissionCategory::QUALITY_REPORT,
],
],
],
'^/qualitymanagement/audit/list(\?.*$|$)' => [
[
'dest' => '\Modules\QualityManagement\Controller\BackendController:viewAuditList',
'verb' => RouteVerb::GET,
'active' => true,
'permission' => [
'module' => BackendController::NAME,
'type' => PermissionType::READ,
@ -55,6 +70,7 @@ return [
[
'dest' => '\Modules\QualityManagement\Controller\BackendController:viewQuality',
'verb' => RouteVerb::GET,
'active' => true,
'permission' => [
'module' => BackendController::NAME,
'type' => PermissionType::READ,
@ -67,6 +83,7 @@ return [
[
'dest' => '\Modules\QualityManagement\Controller\BackendController:viewPrivateReportDashboard',
'verb' => RouteVerb::GET,
'active' => true,
'permission' => [
'module' => BackendController::NAME,
'type' => PermissionType::READ,
@ -78,6 +95,7 @@ return [
[
'dest' => '\Modules\QualityManagement\Controller\BackendController:viewPrivateReport',
'verb' => RouteVerb::GET,
'active' => true,
'permission' => [
'module' => BackendController::NAME,
'type' => PermissionType::READ,

View File

@ -14,8 +14,22 @@ declare(strict_types=1);
namespace Modules\QualityManagement\Controller;
use Modules\Admin\Models\AccountMapper;
use Modules\Admin\Models\ContactType;
use Modules\Messages\Models\EmailMapper;
use Modules\QualityManagement\Models\Report;
use Modules\QualityManagement\Models\ReportMapper;
use Modules\QualityManagement\Models\SettingsEnum;
use Modules\Tasks\Models\TaskElementMapper;
use Modules\Tasks\Models\TaskMapper;
use Modules\Tasks\Models\TaskStatus;
use Modules\Tasks\Models\TaskType;
use phpOMS\Message\Http\RequestStatusCode;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
/**
* QualityManagement api controller class.
* Api controller for the QualityManagement module.
*
* @package Modules\QualityManagement
* @license OMS License 2.0
@ -24,4 +38,225 @@ namespace Modules\QualityManagement\Controller;
*/
final class ApiController extends Controller
{
/**
* Validate report create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool> Returns the validation array of the request
*
* @since 1.0.0
*/
private function validateReportCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['title'] = !$request->hasData('title'))
|| ($val['plain'] = !$request->hasData('plain'))
) {
return $val;
}
return [];
}
/**
* Api method to create a report
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiReportCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateReportCreate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidCreateResponse($request, $response, $val);
return;
}
$report = $this->createReportFromRequest($request);
$this->createModel($request->header->account, $report, ReportMapper::class, 'report', $request->getOrigin());
$this->createStandardCreateResponse($request, $response, $report);
}
/**
* Method to create report from request.
*
* @param RequestAbstract $request Request
*
* @return Report Returns the created report from the request
*
* @since 1.0.0
*/
private function createReportFromRequest(RequestAbstract $request) : Report
{
$request->setData('redirect', 'qualitymanagement/report/view?for={$id}');
$task = $this->app->moduleManager->get('Tasks')->createTaskFromRequest($request);
$task->type = TaskType::HIDDEN;
$task->unit ??= $this->app->unitId;
$report = new Report($task);
return $report;
}
/**
* Api method to get a report
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiReportGet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
/** @var \Modules\QualityManagement\Models\Report $report */
$report = ReportMapper::get()->where('id', (int) $request->getData('id'))->execute();
$this->createStandardReturnResponse($request, $response, $report);
}
/**
* Api method to update a report
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiReportSet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
/** @var \Modules\QualityManagement\Models\Report $old */
$old = ReportMapper::get()
->with('task')
->where('id', (int) $request->getData('id'))
->execute();
$new = $this->updateReportFromRequest($request, clone $old);
$this->updateModel($request->header->account, $old, $new, ReportMapper::class, 'report', $request->getOrigin());
$this->createStandardUpdateResponse($request, $response, $new);
}
/**
* Method to update an report from a request
*
* @param RequestAbstract $request Request
*
* @return Report Returns the updated report from the request
*
* @since 1.0.0
*/
private function updateReportFromRequest(RequestAbstract $request, Report $new) : Report
{
return $new;
}
/**
* Validate report element create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool> Returns the validation array of the request
*
* @since 1.0.0
*/
private function validateReportElementCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['status'] = !TaskStatus::isValidValue((int) $request->getData('status')))
|| ($val['due'] = !((bool) \strtotime((string) $request->getData('due'))))
|| ($val['report'] = !(\is_numeric($request->getData('report'))))
|| ($val['forward'] = !(\is_numeric($request->hasData('forward') ? $request->getData('forward') : $request->header->account)))
) {
return $val;
}
return [];
}
/**
* Api method to create a report element
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiReportElementCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateReportElementCreate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidCreateResponse($request, $response, $val);
return;
}
// @question Consider to use the apiTaskElementCreate() function
/** @var \Modules\QualityManagement\Models\Report $report */
$report = ReportMapper::get()
->with('task')
->where('id', (int) ($request->getData('report')))
->execute();
$element = $this->app->moduleManager->get('Tasks')->createTaskElementFromRequest($request, $report->task);
$old = clone $report->task;
$report->task->status = $element->status;
$report->task->priority = $element->priority;
$report->task->due = $element->due;
$this->createModel($request->header->account, $element, TaskElementMapper::class, 'report_element', $request->getOrigin());
$this->updateModel($request->header->account, $old, $report->task, TaskMapper::class, 'report', $request->getOrigin());
$report->task->taskElements[] = $element;
$this->createStandardCreateResponse($request, $response, $element);
}
/**
* Api method to update a report
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiReportElementSet(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
$this->app->moduleManager->get('Tasks')->apiTaskElementSet($request, $response);
$new = $response->getData($request->uri->__toString())['response'];
//$this->updateModel($request->header->account, $report, $report, ReportMapper::class, 'report', $request->getOrigin());
$this->createStandardUpdateResponse($request, $response, $new);
}
}

View File

@ -66,7 +66,11 @@ final class BackendController extends Controller
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/QualityManagement/Theme/Backend/report-dashboard');
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1002901101, $request, $response);
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1008502001, $request, $response);
$view->data['reports'] = [];
$view->data['open'] = [];
$view->data['stats'] = [];
return $view;
}

77
Models/Report.php Normal file
View File

@ -0,0 +1,77 @@
<?php
/**
* Jingga
*
* PHP Version 8.2
*
* @package Modules\QualityManagement\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\QualityManagement\Models;
use Modules\Tasks\Models\Task;
use Modules\Tasks\Models\TaskType;
/**
* Report class.
*
* @package Modules\QualityManagement\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class Report
{
/**
* ID.
*
* @var int
* @since 1.0.0
*/
public int $id = 0;
/**
* The ticket is using a task.
*
* @var Task
* @since 1.0.0
*/
public Task $task;
/**
* Constructor.
*
* @param null|Task $task Creates the ticket from a task
*
* @since 1.0.0
*/
public function __construct(?Task $task = null)
{
$this->task = $task ?? new Task();
$this->task->type = TaskType::HIDDEN;
}
/**
* {@inheritdoc}
*/
public function toArray() : array
{
return [
'id' => $this->id,
'task' => $this->task,
];
}
/**
* {@inheritdoc}
*/
public function jsonSerialize() : mixed
{
return $this->toArray();
}
}

141
Models/ReportMapper.php Normal file
View File

@ -0,0 +1,141 @@
<?php
/**
* Jingga
*
* PHP Version 8.2
*
* @package Modules\QualityManagement\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\QualityManagement\Models;
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\DataStorage\Database\Mapper\DataMapperFactory;
use phpOMS\DataStorage\Database\Mapper\ReadMapper;
use phpOMS\DataStorage\Database\Query\Builder;
use phpOMS\Stdlib\Base\SmartDateTime;
/**
* Report mapper class.
*
* @package Modules\QualityManagement\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of Report
* @extends DataMapperFactory<T>
*/
final class ReportMapper extends DataMapperFactory
{
/**
* Columns.
*
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
* @since 1.0.0
*/
public const COLUMNS = [
'qualitymgmt_report_id' => ['name' => 'qualitymgmt_report_id', 'type' => 'int', 'internal' => 'id'],
'qualitymgmt_report_task' => ['name' => 'qualitymgmt_report_task', 'type' => 'int', 'internal' => 'task'],
];
/**
* Has one relation.
*
* @var array<string, array{mapper:class-string, external:string, by?:string, column?:string, conditional?:bool}>
* @since 1.0.0
*/
public const OWNS_ONE = [
'task' => [
'mapper' => TaskMapper::class,
'external' => 'qualitymgmt_report_task',
],
];
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'qualitymgmt_report';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD = 'qualitymgmt_report_id';
/**
* 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();
return [
'total' => self::count()->with('task')->where('task/createdAt', $start, '>=')->executeCount(),
'unassigned' => self::count()->with('task')->where('for', null)->executeCount(),
'open' => self::count()->with('task')->where('task/status', TaskStatus::OPEN)->executeCount(),
'closed' => self::count()->with('task')->where('task/createdAt', $start, '>=')->where('task/status', TaskStatus::DONE)->where('task/status', TaskStatus::CANCELED, '=', 'OR')->where('task/status', TaskStatus::SUSPENDED, '=', 'OR')->executeCount(),
'inprogress' => self::count()->with('task')->where('task/status', TaskStatus::WORKING)->executeCount(),
];
}
/**
* Get tasks that have something to do with the user
*
* @param int $user User
*
* @return ReadMapper
*
* @since 1.0.0
*/
public static function getAnyRelatedToUser(int $user) : ReadMapper
{
$query = new Builder(self::$db, true);
$query->innerJoin(TaskMapper::TABLE, TaskMapper::TABLE . '_d2_task')
->on(self::TABLE . '_d1.qualitymgmt_report_task', '=', TaskMapper::TABLE . '_d2_task.task_id')
->innerJoin(TaskElementMapper::TABLE)
->on(TaskMapper::TABLE . '_d2_task.task_id', '=', TaskElementMapper::TABLE . '.task_element_task')
->on(TaskMapper::TABLE . '_d2_task.task_type', '!=', TaskType::TEMPLATE)
->innerJoin(AccountRelationMapper::TABLE)
->on(TaskElementMapper::TABLE . '.task_element_id', '=', AccountRelationMapper::TABLE . '.task_account_task_element')
->where(AccountRelationMapper::TABLE . '.task_account_account', '=', $user)
->orWhere(TaskMapper::TABLE . '_d2_task.task_created_by', '=', $user)
->groupBy(self::PRIMARYFIELD);
// @todo Improving query performance by using raw queries and result arrays for large responses like this
$sql = <<<SQL
SELECT DISTINCT task.*, account.*
FROM task
INNER JOIN task_element ON task.task_id = task_element.task_element_task
INNER JOIN task_account ON task_element.task_element_id = task_account.task_account_task_element
INNER JOIN account ON task.task_created_by = account.account_id
WHERE
task.task_status != 1
AND (
task_account.task_account_account = {$user}
OR task.task_created_by = {$user}
)
LIMIT 25;
SQL;
return self::getAll()->query($query);
}
}

View File

@ -0,0 +1,71 @@
<?php
/**
* Jingga
*
* PHP Version 8.2
*
* @package Modules\Localization
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
return ['Support' => [
'Account' => 'Konto',
'All' => 'Alle',
'Assigned' => 'Zugewiesen',
'AverageAmount' => 'Durschnittliche Menge',
'AverageProcessTime' => 'Durchschn. Prozess Zeit',
'Closed' => 'Geschlossen',
'Completion' => 'Abgeschlossen',
'Advanced' => 'Fortgeschritten',
'Created' => 'Erstellt',
'Creator' => 'Ersteller',
'Day' => 'Tag',
'Department' => 'Abteilung',
'Description' => 'Beschreibung',
'Due' => 'Fällig',
'Files' => 'Dateien',
'For' => 'Für',
'Forwarded' => 'Weitergeleitet',
'From' => 'Von',
'Group' => 'Gruppe',
'InTime' => 'Rechtzeitig',
'Interval' => 'Intervall',
'Media' => 'Medien',
'Message' => 'Nachricht',
'Month' => 'Monat',
'Name' => 'Name',
'New' => 'Neu',
'Open' => 'Offen',
'Person' => 'Person',
'Priority' => 'Priorität',
'Received' => 'Erhalten',
'Receiver' => 'Empfänger',
'Redirected' => 'Umgeleitet',
'Responsible' => 'Verantwortlich',
'Select' => 'Wählen',
'Settings' => 'Einstellungen',
'Size' => 'Größe',
'Statistics' => 'Statistiken',
'Stats' => 'Stats',
'Status' => 'Status',
'Support' => 'Unterstützung',
'Report' => 'Bericht',
'Reports' => 'Berichte',
'Title' => 'Titel',
'To' => 'Zu',
'Item' => 'Artikel',
'Today' => 'Heute',
'Topic' => 'Thema',
'Type' => 'Typ',
'Unassigned' => 'Unzugewiesen',
'Unsolved' => 'Ungelöst',
'Upload' => 'Hochladen',
'Week' => 'Woche',
'Year' => 'Jahr',
'Total' => 'Gesamt',
'InProgress' => 'In Bearbeitung',
]];

View File

@ -0,0 +1,71 @@
<?php
/**
* Jingga
*
* PHP Version 8.2
*
* @package Modules\Localization
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
return ['Support' => [
'Account' => 'Account',
'All' => 'All',
'Assigned' => 'Assigned',
'AverageAmount' => 'Average Amount',
'AverageProcessTime' => 'Avg. Process Time',
'Closed' => 'Closed',
'Completion' => 'Completion',
'Advanced' => 'Advanced',
'Created' => 'Created',
'Creator' => 'Creator',
'Day' => 'Day',
'Department' => 'Department',
'Description' => 'Description',
'Due' => 'Due',
'Files' => 'Files',
'For' => 'For',
'Forwarded' => 'Forwarded',
'From' => 'From',
'Group' => 'Group',
'InTime' => 'In Time',
'Interval' => 'Interval',
'Media' => 'Media',
'Message' => 'Message',
'Month' => 'Month',
'Name' => 'Name',
'New' => 'New',
'Open' => 'Open',
'Person' => 'Person',
'Priority' => 'Priority',
'Received' => 'Received',
'Receiver' => 'Receiver',
'Redirected' => 'Redirected',
'Responsible' => 'Responsible',
'Select' => 'Select',
'Settings' => 'Settings',
'Size' => 'Size',
'Statistics' => 'Statistics',
'Stats' => 'Stats',
'Status' => 'Status',
'Support' => 'Support',
'Report' => 'Report',
'Reports' => 'Reports',
'Title' => 'Title',
'To' => 'To',
'Item' => 'Item',
'Today' => 'Today',
'Topic' => 'Topic',
'Type' => 'Type',
'Unassigned' => 'Unassigned',
'Unsolved' => 'Unsolved',
'Upload' => 'Upload',
'Week' => 'Week',
'Year' => 'Year',
'Total' => 'Total',
'InProgress' => 'In Progress',
]];

View File

@ -1,8 +1,123 @@
<?php
/**
* Jingga
*
* PHP Version 8.2
*
* @package Modules\Support
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
use phpOMS\Uri\UriFactory;
/**
* @var \phpOMS\Views\View $this
* @var \Modules\Support\Models\Ticket[] $reports
*/
$reports = $this->data['reports'];
echo $this->data['nav']->render(); ?>
<div class="row">
<div class="col-xs-12">
<div class="col-xs-12 col-md-9">
<section class="portlet">
<div class="portlet-head"><?= $this->getHtml('Open'); ?><i class="g-icon download btn end-xs">download</i></div>
<div class="slider">
<table class="default sticky">
<thead>
<td><?= $this->getHtml('Status'); ?>
<td class="full"><?= $this->getHtml('Title'); ?>
<td><?= $this->getHtml('Creator'); ?>
<td><?= $this->getHtml('Assigned'); ?>
<td><?= $this->getHtml('For'); ?>
<td><?= $this->getHtml('Item'); ?>
<td><?= $this->getHtml('Created'); ?>
<tbody>
<?php
$c = 0;
foreach ($this->data['open'] as $key => $report) : ++$c;
$url = UriFactory::build('{/base}/qualitymanagement/report/view?{?}&id=' . $report->id);
?>
<tr data-href="<?= $url; ?>">
<td><a href="<?= $url; ?>">
<span class="tag <?= $this->printHtml('task-status-' . $report->task->status); ?>">
<?= $this->getHtml('S' . $report->task->status, 'Tasks'); ?>
</span></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($report->task->title); ?></a>
<td><a class="content" href="<?= UriFactory::build('{/base}/profile/view?for=' . $report->task->createdBy->id); ?>"><?= $this->printHtml($report->task->createdBy->name1); ?> <?= $this->printHtml($report->task->createdBy->name2); ?></a>
<td><?php $responsibles = $report->task->getResponsible();
foreach ($responsibles as $responsible) : ?>
<a class="content" href="<?= UriFactory::build('{/base}/profile/view?for=' . $responsible->id); ?>">
<?= $this->printHtml($responsible->name1); ?> <?= $this->printHtml($responsible->name2); ?>
</a>
<?php endforeach; ?>
<td><a class="content"><?= $this->printHtml($report->task->for->name1); ?> <?= $this->printHtml($report->task->for->name2); ?>
<td><a href="<?= $url; ?>"><?= $this->getHtml('P' . $report->task->priority, 'Tasks'); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($report->task->createdAt->format('Y-m-d H:i')); ?></a>
<?php endforeach; if ($c == 0) : ?>
<tr><td colspan="7" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
</div>
</section>
<section class="portlet">
<div class="portlet-head"><?= $this->getHtml('Reports'); ?><i class="g-icon download btn end-xs">download</i></div>
<div class="slider">
<table class="default sticky">
<thead>
<td><?= $this->getHtml('Status'); ?>
<td class="full"><?= $this->getHtml('Title'); ?>
<td><?= $this->getHtml('Creator'); ?>
<td><?= $this->getHtml('Assigned'); ?>
<td><?= $this->getHtml('For'); ?>
<td><?= $this->getHtml('Item'); ?>
<td><?= $this->getHtml('Created'); ?>
<tbody>
<?php
$c = 0;
foreach ($this->data['reports'] as $key => $report) : ++$c;
$url = UriFactory::build('{/base}/qualitymanagement/report/view?{?}&id=' . $report->id);
?>
<tr data-href="<?= $url; ?>">
<td><a href="<?= $url; ?>">
<span class="tag <?= $this->printHtml('task-status-' . $report->task->status); ?>">
<?= $this->getHtml('S' . $report->task->status, 'Tasks'); ?>
</span></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($report->task->title); ?></a>
<td><a class="content" href="<?= UriFactory::build('{/base}/profile/view?for=' . $report->task->createdBy->id); ?>"><?= $this->printHtml($report->task->createdBy->name1); ?> <?= $this->printHtml($report->task->createdBy->name2); ?></a>
<td><?php $responsibles = $report->task->getResponsible();
foreach ($responsibles as $responsible) : ?>
<a class="content" href="<?= UriFactory::build('{/base}/profile/view?for=' . $responsible->id); ?>">
<?= $this->printHtml($responsible->name1); ?> <?= $this->printHtml($responsible->name2); ?>
</a>
<?php endforeach; ?>
<td><a class="content"><?= $this->printHtml($report->task->for->name1); ?> <?= $this->printHtml($report->task->for->name2); ?>
<td><a href="<?= $url; ?>"><?= $this->getHtml('P' . $report->task->priority, 'Tasks'); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($report->task->createdAt->format('Y-m-d H:i')); ?></a>
<?php endforeach; if ($c == 0) : ?>
<tr><td colspan="7" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
</div>
</section>
</div>
<div class="col-xs-12 col-md-3">
<section class="portlet">
<div class="portlet-head"><?= $this->getHtml('Stats'); ?></div>
<div class="portlet-body">
<img height="100%" width="100%" src="Web/Backend/img/under_construction.svg">
<table class="list">
<tr><th><?= $this->getHtml('Unassigned'); ?><td><?= $this->data['stats']['unassigned'] ?? 0; ?>
<tr><th><?= $this->getHtml('Open'); ?><td><?= $this->data['stats']['open'] ?? 0; ?>
<tr><th><?= $this->getHtml('InProgress'); ?><td><?= $this->data['stats']['inprogress'] ?? 0; ?>
<tr><th><?= $this->getHtml('Closed'); ?><td><?= $this->data['stats']['closed'] ?? 0; ?>
<tr><th><?= $this->getHtml('Total'); ?><td><?= $this->data['stats']['total'] ?? 0; ?>
</table>
</div>
</section>
</div>

View File

@ -18,6 +18,7 @@
"dependencies": {
"Admin": "1.0.0",
"Tasks": "1.0.0",
"ItemManagement": "1.0.0",
"Tools": "1.0.0"
},
"providing": {
@ -29,7 +30,7 @@
"/qualitymanagement"
],
"type": 4,
"for": "Content",
"for": 0,
"file": "QualityManagement",
"from": "QualityManagement"
},