many fixes and expands and module expansions

This commit is contained in:
Dennis Eichhorn 2021-04-04 17:10:52 +02:00
parent 6fd3f145d4
commit af797be07c
14 changed files with 425 additions and 46 deletions

View File

@ -1,4 +1,66 @@
[
{
"id": 1004801001,
"pid": "/",
"type": 2,
"subtype": 0,
"name": "ItemManagement",
"uri": null,
"target": "self",
"icon": "fa fa-usd",
"order": 20,
"from": "ItemManagement",
"permission": { "permission": 2, "type": null, "element": null },
"parent": 0,
"children": [
{
"id": 1004802001,
"pid": "/",
"type": 2,
"subtype": 1,
"name": "Attributes",
"uri": "{/prefix}item/attribute/type?{?}",
"target": "self",
"icon": null,
"order": 15,
"from": "Sales",
"permission": { "permission": 2, "type": null, "element": null },
"parent": 1004801001,
"children": [
{
"id": 1004802002,
"pid": "/item",
"type": 3,
"subtype": 1,
"name": "Types",
"uri": "{/prefix}item/attribute/type?{?}",
"target": "self",
"icon": null,
"order": 15,
"from": "Sales",
"permission": { "permission": 2, "type": null, "element": null },
"parent": 1004802001,
"children": []
},
{
"id": 1004802003,
"pid": "/item",
"type": 3,
"subtype": 1,
"name": "Values",
"uri": "{/prefix}item/attribute/value?{?}",
"target": "self",
"icon": null,
"order": 15,
"from": "Sales",
"permission": { "permission": 2, "type": null, "element": null },
"parent": 1004802001,
"children": []
}
]
}
]
},
{
"id": 1004805001,
"pid": "/",
@ -246,5 +308,20 @@
"children": []
}
]
},
{
"id": 1004809001,
"pid": "/sales/analysis",
"type": 3,
"subtype": 1,
"name": "Article",
"uri": "{/prefix}sales/analysis/item",
"target": "self",
"icon": null,
"order": 4,
"from": "ItemManagement",
"permission": { "permission": 2, "type": null, "element": null },
"parent": 1001602001,
"children": []
}
]

View File

@ -114,6 +114,18 @@
"name": "itemmgmt_attr_type_custom",
"type": "TINYINT(1)",
"null": false
},
"itemmgmt_attr_type_required": {
"description": "Every item must have this attribute type if set to true.",
"name": "itemmgmt_attr_type_required",
"type": "TINYINT(1)",
"null": false
},
"itemmgmt_attr_type_pattern": {
"description": "This is a regex validation pattern.",
"name": "itemmgmt_attr_type_pattern",
"type": "VARCHAR(255)",
"null": false
}
}
},

View File

@ -6,6 +6,50 @@ use phpOMS\Account\PermissionType;
use phpOMS\Router\RouteVerb;
return [
'^.*/item/attribute/type.*$' => [
[
'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementAttributeTypes',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
'type' => PermissionType::READ,
'state' => PermissionState::ATTRIBUTE,
],
],
],
'^.*/item/attribute/value.*$' => [
[
'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementAttributeValues',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
'type' => PermissionType::READ,
'state' => PermissionState::ATTRIBUTE,
],
],
],
'^.*/item/attribute/type.*$' => [
[
'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementAttributeTypes',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
'type' => PermissionType::READ,
'state' => PermissionState::ATTRIBUTE,
],
],
],
'^.*/item/attribute/value.*$' => [
[
'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementAttributeValues',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
'type' => PermissionType::READ,
'state' => PermissionState::ATTRIBUTE,
],
],
],
'^.*/sales/item/list.*$' => [
[
'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementSalesList',
@ -105,4 +149,15 @@ return [
],
],
],
'^.*/sales/analysis/item(\?.*|$)$' => [
[
'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemAnalysis',
'verb' => RouteVerb::GET,
'permission' => [
'module' => BackendController::MODULE_NAME,
'type' => PermissionType::READ,
'state' => PermissionState::SALES_ITEM,
],
],
],
];

View File

@ -15,11 +15,14 @@ declare(strict_types=1);
namespace Modules\ItemManagement\Controller;
use Model\SettingsEnum;
use Modules\Media\Models\Media;
use Modules\Admin\Models\LocalizationMapper;
use Modules\Billing\Models\BillTypeL11n;
use Modules\Billing\Models\SalesBillMapper;
use Modules\ItemManagement\Models\ItemAttributeMapper;
use Modules\ItemManagement\Models\ItemAttributeTypeMapper;
use Modules\ItemManagement\Models\ItemL11nMapper;
use Modules\ItemManagement\Models\ItemL11nType;
use Modules\ItemManagement\Models\ItemMapper;
use phpOMS\Asset\AssetType;
use phpOMS\Contract\RenderableInterface;
@ -28,6 +31,7 @@ use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Stdlib\Base\SmartDateTime;
use phpOMS\Views\View;
use Modules\ItemManagement\Models\ItemAttributeValueMapper;
/**
* ItemManagement controller class.
@ -39,6 +43,111 @@ use phpOMS\Views\View;
*/
final class BackendController extends Controller
{
/**
* Routing end-point for application behaviour.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return RenderableInterface
*
* @since 1.0.0
* @codeCoverageIgnore
*/
public function viewItemManagementAttributeTypes(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/ItemManagement/Theme/Backend/attribute-type-list');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response));
$attributes = ItemAttributeTypeMapper::with('language', $response->getLanguage())
::getAll();
$view->addData('attributes', $attributes);
return $view;
}
/**
* Routing end-point for application behaviour.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return RenderableInterface
*
* @since 1.0.0
* @codeCoverageIgnore
*/
public function viewItemManagementAttributeValues(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/ItemManagement/Theme/Backend/attribute-value-list');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response));
$attributes = ItemAttributeValueMapper::with('language', $response->getLanguage())
::getAll();
$view->addData('attributes', $attributes);
return $view;
}
/**
* Routing end-point for application behaviour.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return RenderableInterface
*
* @since 1.0.0
* @codeCoverageIgnore
*/
public function viewItemManagementAttributeType(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/ItemManagement/Theme/Backend/attribute-type');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response));
$attribute = ItemAttributeTypeMapper::with('language', $response->getLanguage())
::get((int) $request->getData('id'));
$view->addData('attribute', $attribute);
return $view;
}
/**
* Routing end-point for application behaviour.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return RenderableInterface
*
* @since 1.0.0
* @codeCoverageIgnore
*/
public function viewItemManagementAttributeValue(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/ItemManagement/Theme/Backend/attribute-value');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response));
$attribute = ItemAttributeValueMapper::with('language', $response->getLanguage())
::get((int) $request->getData('id'));
$view->addData('attribute', $attribute);
return $view;
}
/**
* Routing end-point for application behaviour.
*
@ -57,7 +166,13 @@ final class BackendController extends Controller
$view->setTemplate('/Modules/ItemManagement/Theme/Backend/sales-item-list');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004805001, $request, $response));
$items = ItemMapper::with('language', $response->getLanguage())::getAfterPivot(0, null, 25);
$items = ItemMapper::with('language', $response->getLanguage())
::with('type', 'backend_image', models: [Media::class]) // @todo: it would be nicer if I coult say files:type or files/type and remove the models parameter?
::with('notes', models: null)
::with('attributes', models: null)
::with('title', ['name1', 'name2', 'name3'], comparison: 'in', models: [ItemL11nType::class]) // @todo: profile, why does this have almost no impact on the sql performance?
::getAfterPivot(0, null, 25);
$view->addData('items', $items);
return $view;
@ -181,12 +296,12 @@ final class BackendController extends Controller
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return RenderableInterface
* @return View
*
* @since 1.0.0
* @codeCoverageIgnore
*/
public function viewItemManagementSalesItem(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface
public function viewItemManagementSalesItem(RequestAbstract $request, ResponseAbstract $response, $data = null) : View
{
$head = $response->get('Content')->getData('head');
$head->addAsset(AssetType::CSS, 'Resources/chartjs/Chartjs/chart.css');
@ -226,6 +341,7 @@ final class BackendController extends Controller
// @todo: why is the conditional array necessary, shouldn't the mapper realize when it mustn't use the conditional (when the field doesn't exist in the mapper)
$newestInvoices = SalesBillMapper::with('language', $response->getLanguage(), [BillTypeL11n::class])::getNewestItemInvoices($item->getId(), 5);
$topCustomers = SalesBillMapper::getItemTopCustomers($item->getId(), new SmartDateTime('Y-01-01'), new SmartDateTime('now'), 5);
$allInvoices = SalesBillMapper::getItemBills($item->getId(), new SmartDateTime('Y-01-01'), new SmartDateTime('now'));
$regionSales = SalesBillMapper::getItemRegionSales($item->getId(), new SmartDateTime('Y-01-01'), new SmartDateTime('now'));
$countrySales = SalesBillMapper::getItemCountrySales($item->getId(), new SmartDateTime('Y-01-01'), new SmartDateTime('now'), 5);
$monthlySalesCosts = SalesBillMapper::getItemMonthlySalesCosts($item->getId(), (new SmartDateTime('now'))->createModify(-1), new SmartDateTime('now'));
@ -235,6 +351,7 @@ final class BackendController extends Controller
$avg = new Money();
$lastOrder = null;
$newestInvoices = [];
$allInvoices = [];
$topCustomers = [];
$regionSales = [];
$countrySales = [];
@ -246,6 +363,7 @@ final class BackendController extends Controller
$view->addData('avg', $avg);
$view->addData('lastOrder', $lastOrder);
$view->addData('newestInvoices', $newestInvoices);
$view->addData('allInvoices', $allInvoices);
$view->addData('topCustomers', $topCustomers);
$view->addData('regionSales', $regionSales);
$view->addData('countrySales', $countrySales);

View File

@ -41,7 +41,7 @@ class ItemAttributeType implements \JsonSerializable, ArrayableInterface
* @var string
* @since 1.0.0
*/
protected string $name = ''; // @todo: currently not filled, should be used as identifier or if not required removed (at the moment it seems like it is useless?!)
public string $name = ''; // @todo: currently not filled, should be used as identifier or if not required removed (at the moment it seems like it is useless?!)
/**
* Which field data type is required (string, int, ...) in the value
@ -59,12 +59,16 @@ class ItemAttributeType implements \JsonSerializable, ArrayableInterface
*/
protected bool $custom = false;
public string $validationPattern = '';
public bool $isRequired = false;
/**
* Localization
*
* @var int|int[]|ItemAttributeTypeL11n|ItemAttributeTypeL11n[]
* @var ItemAttributeTypeL11n
*/
protected $l11n = 0;
protected string | ItemAttributeTypeL11n $l11n;
/**
* Possible default attribute values

View File

@ -38,12 +38,12 @@ class ItemAttributeTypeL11n implements \JsonSerializable, ArrayableInterface
/**
* Item ID.
*
* @var int|ItemL11nType
* @var int|ItemAttributeType
* @since 1.0.0
*/
protected int |
ItemL11nType $type = 0;
ItemAttributeType $type = 0;
/**
* Language.
@ -64,13 +64,13 @@ ItemL11nType $type = 0;
/**
* Constructor.
*
* @param int|ItemL11nType $type Attribute type
* @param int|ItemAttributeType $type Attribute type
* @param string $title Localized title
* @param string $language Language
*
* @since 1.0.0
*/
public function __construct(int | ItemL11nType $type = 0, string $title = '', string $language = ISO639x1Enum::_EN)
public function __construct(int | ItemAttributeType $type = 0, string $title = '', string $language = ISO639x1Enum::_EN)
{
$this->type = $type;
$this->title = $title;
@ -92,11 +92,11 @@ ItemL11nType $type = 0;
/**
* Get attribute type
*
* @return int|ItemL11nType
* @return int|ItemAttributeType
*
* @since 1.0.0
*/
public function getType()
public function getType() : int | ItemAttributeType
{
return $this->type;
}

View File

@ -37,6 +37,8 @@ final class ItemAttributeTypeMapper extends DataMapperAbstract
'itemmgmt_attr_type_name' => ['name' => 'itemmgmt_attr_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true],
'itemmgmt_attr_type_fields' => ['name' => 'itemmgmt_attr_type_fields', 'type' => 'int', 'internal' => 'fields'],
'itemmgmt_attr_type_custom' => ['name' => 'itemmgmt_attr_type_custom', 'type' => 'bool', 'internal' => 'custom'],
'itemmgmt_attr_type_pattern' => ['name' => 'itemmgmt_attr_type_pattern', 'type' => 'bool', 'internal' => 'validationPattern'],
'itemmgmt_attr_type_required' => ['name' => 'itemmgmt_attr_type_required', 'type' => 'bool', 'internal' => 'isRequired'],
];
/**

View File

@ -31,4 +31,6 @@ abstract class PermissionState extends Enum
public const PURCHASE_ITEM = 2;
public const STOCK_ITEM = 3;
public const ATTRIBUTE = 4;
}

View File

@ -14,6 +14,10 @@ declare(strict_types=1);
return ['Navigation' => [
'Analyze' => 'Analyze',
'Attributes' => 'Attributes',
'Types' => 'Types',
'Values' => 'Values',
'Create' => 'Create',
'List' => 'List',
'ItemManagement' => 'Item Management',
]];

View File

@ -0,0 +1,70 @@
<?php
/**
* Orange Management
*
* PHP Version 8.0
*
* @package Modules\ItemManagement
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
use Modules\Media\Models\NullMedia;
use phpOMS\Uri\UriFactory;
/** @var \phpOMS\Views\View $this */
$attributes = $this->getData('attributes');
echo $this->getData('nav')->render(); ?>
<div class="row">
<div class="col-xs-12">
<section class="portlet">
<div class="portlet-head"><?= $this->getHtml('AttributeTypes'); ?><i class="fa fa-download floatRight download btn"></i></div>
<table id="iAttributeTypeList" class="default">
<thead>
<tr>
<td><?= $this->getHtml('ID', '0', '0'); ?>
<label for="iAttributeTypeList-sort-1">
<input type="radio" name="iAttributeTypeList-sort" id="iAttributeTypeList-sort-1">
<i class="sort-asc fa fa-chevron-up"></i>
</label>
<label for="iAttributeTypeList-sort-2">
<input type="radio" name="iAttributeTypeList-sort" id="iAttributeTypeList-sort-2">
<i class="sort-desc fa fa-chevron-down"></i>
</label>
<label>
<i class="filter fa fa-filter"></i>
</label>
<td class="wf-100"><?= $this->getHtml('Name'); ?>
<label for="iAttributeTypeList-sort-2">
<input type="radio" name="iAttributeTypeList-sort" id="iAttributeTypeList-sort-2">
<i class="sort-asc fa fa-chevron-up"></i>
</label>
<label for="iAttributeTypeList-sort-3">
<input type="radio" name="iAttributeTypeList-sort" id="iAttributeTypeList-sort-3">
<i class="sort-desc fa fa-chevron-down"></i>
</label>
<label>
<i class="filter fa fa-filter"></i>
</label>
<tbody>
<?php
$count = 0;
foreach ($attributes as $key => $value) : ++$count;
$url = UriFactory::build('{/prefix}item/attribute/type?{?}&id=' . $value->getId());
?>
<tr data-href="<?= $url; ?>">
<td><a href="<?= $url; ?>"><?= $value->getId(); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($value->getL11n()); ?></a>
<?php endforeach; ?>
<?php if ($count === 0) : ?>
<tr><td colspan="2" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
</section>
</div>
</div>

View File

View File

View File

@ -29,6 +29,7 @@ $notes = $item->getNotes();
$files = $item->getFiles();
$newestInvoices = $this->getData('newestInvoices') ?? [];
$allInvoices = $this->getData('allInvoices') ?? [];
$topCustomers = $this->getData('topCustomers') ?? [];
$regionSales = $this->getData('regionSales') ?? [];
$countrySales = $this->getData('countrySales') ?? [];
@ -56,7 +57,8 @@ echo $this->getData('nav')->render();
<li><label for="c-tab-10"><?= $this->getHtml('Stock'); ?></label></li>
<li><label for="c-tab-11"><?= $this->getHtml('Disposal'); ?></label></li>
<li><label for="c-tab-12"><?= $this->getHtml('Media'); ?></label></li>
<li><label for="c-tab-13"><?= $this->getHtml('Logs'); ?></label></li>
<li><label for="c-tab-13"><?= $this->getHtml('SalesInvoices'); ?></label></li>
<li><label for="c-tab-14"><?= $this->getHtml('Logs'); ?></label></li>
</ul>
</div>
<div class="tab-content">
@ -168,8 +170,8 @@ echo $this->getData('nav')->render();
$url = UriFactory::build('{/prefix}editor/single?{?}&id=' . $note->getId());
?>
<tr data-href="<?= $url; ?>">
<td><a href="<?= $url; ?>"><?= $note->title; ?></a>
<td><a href="<?= $url; ?>"><?= $note->createdAt->format('Y-m-d'); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($note->title); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($note->createdAt->format('Y-m-d')); ?></a>
<?php endforeach; ?>
</table>
</section>
@ -189,9 +191,9 @@ echo $this->getData('nav')->render();
$url = UriFactory::build('{/prefix}media/single?{?}&id=' . $file->getId());
?>
<tr data-href="<?= $url; ?>">
<td><a href="<?= $url; ?>"><?= $file->name; ?></a>
<td><a href="<?= $url; ?>"><?= $file->extension; ?></a>
<td><a href="<?= $url; ?>"><?= $file->createdAt->format('Y-m-d'); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($file->name); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($file->extension); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($file->createdAt->format('Y-m-d')); ?></a>
<?php endforeach; ?>
</table>
</section>
@ -215,11 +217,11 @@ echo $this->getData('nav')->render();
$url = UriFactory::build('{/prefix}sales/bill?{?}&id=' . $invoice->getId());
?>
<tr data-href="<?= $url; ?>">
<td><a href="<?= $url; ?>"><?= $invoice->getNumber(); ?></a>
<td><a href="<?= $url; ?>"><?= $invoice->type->getL11n(); ?></a>
<td><a href="<?= $url; ?>"><?= $invoice->billTo; ?></a>
<td><a href="<?= $url; ?>"><?= $invoice->net->getCurrency(); ?></a>
<td><a href="<?= $url; ?>"><?= $invoice->createdAt->format('Y-m-d'); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($invoice->getNumber()); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($invoice->type->getL11n()); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($invoice->billTo); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($invoice->net->getCurrency()); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($invoice->createdAt->format('Y-m-d')); ?></a>
<?php endforeach; ?>
</table>
</section>
@ -513,7 +515,7 @@ echo $this->getData('nav')->render();
<tr>
<td><label for="iText1"><?= $this->getHtml('Value'); ?></label>
<tr>
<td><input id="iName5" name="name5" type="text" value="<?= $this->printHtml('$item->getName1()'); ?>">
<td><input id="iName5" name="name5" type="text" value="<?= $this->printHtml($item->getL11n('name1')->description); ?>">
<tr>
<td><input type="submit" value="<?= $this->getHtml('Add', '0', '0'); ?>">
</table>
@ -557,7 +559,7 @@ echo $this->getData('nav')->render();
<div class="col-xs-12 col-md-6">
<section class="box wf-100">
<header>
<h1><?= $this->getHtml('Customer'); ?></h1>
<h1><?= $this->getHtml('Pricing'); ?></h1>
</header>
<div class="inner">
<form id="item-edit" action="<?= UriFactory::build('{/api}itemmgmt/item'); ?>" method="post">
@ -605,28 +607,30 @@ echo $this->getData('nav')->render();
</div>
<div class="col-xs-12 col-md-6">
<table id="groupTable" class="box table default">
<caption><?= $this->getHtml('Prices'); ?><i class="fa fa-download floatRight download btn"></i></caption>
<thead>
<tr>
<td>
<td><?= $this->getHtml('ID', '0', '0'); ?><i class="sort-asc fa fa-chevron-up"></i><i class="sort-desc fa fa-chevron-down"></i>
<td class="wf-100"><?= $this->getHtml('Name'); ?><i class="sort-asc fa fa-chevron-up"></i><i class="sort-desc fa fa-chevron-down"></i>
<tbody>
<?php $c = 0;
$l11ns = [];
foreach ($l11ns as $key => $value) : ++$c;
$url = UriFactory::build('{/prefix}admin/group/settings?{?}&id=' . $value->getId()); ?>
<tr data-href="<?= $url; ?>">
<td><a href="#"><i class="fa fa-times"></i></a>
<td><a href="<?= $url; ?>"><?= $value->getId(); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($value->name); ?></a>
<?php endforeach; ?>
<?php if ($c === 0) : ?>
<section class="portlet">
<div class="portlet-head"><?= $this->getHtml('Prices'); ?><i class="fa fa-download floatRight download btn"></i></div>
<table id="iSalesItemList" class="default">
<thead>
<tr>
<td colspan="5" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
<td>
<td><?= $this->getHtml('ID', '0', '0'); ?><i class="sort-asc fa fa-chevron-up"></i><i class="sort-desc fa fa-chevron-down"></i>
<td class="wf-100"><?= $this->getHtml('Name'); ?><i class="sort-asc fa fa-chevron-up"></i><i class="sort-desc fa fa-chevron-down"></i>
<tbody>
<?php $c = 0;
$l11ns = [];
foreach ($l11ns as $key => $value) : ++$c;
$url = UriFactory::build('{/prefix}admin/group/settings?{?}&id=' . $value->getId()); ?>
<tr data-href="<?= $url; ?>">
<td><a href="#"><i class="fa fa-times"></i></a>
<td><a href="<?= $url; ?>"><?= $value->getId(); ?></a>
<td><a href="<?= $url; ?>"><?= $this->printHtml($value->name); ?></a>
<?php endforeach; ?>
<?php if ($c === 0) : ?>
<tr>
<td colspan="5" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
</section>
</div>
</div>
</div>
@ -900,6 +904,37 @@ echo $this->getData('nav')->render();
</div>
<input type="radio" id="c-tab-13" name="tabular-2" checked>
<div class="tab">
<div class="row">
<div class="col-xs-12">
<section class="portlet">
<div class="portlet-head"><?= $this->getHtml('RecentInvoices'); ?></div>
<table id="iSalesItemList" class="default">
<thead>
<tr>
<td><?= $this->getHtml('Number'); ?>
<td><?= $this->getHtml('Type'); ?>
<td class="wf-100"><?= $this->getHtml('Name'); ?>
<td><?= $this->getHtml('Net'); ?>
<td><?= $this->getHtml('Date'); ?>
<tbody>
<?php foreach ($allInvoices as $invoice) :
$url = UriFactory::build('{/prefix}sales/bill?{?}&id=' . $invoice->getId());
?>
<tr data-href="<?= $url; ?>">
<td><a href="<?= $url; ?>"><?= $invoice->getNumber(); ?></a>
<td><a href="<?= $url; ?>"><?= $invoice->type->getL11n(); ?></a>
<td><a href="<?= $url; ?>"><?= $invoice->billTo; ?></a>
<td><a href="<?= $url; ?>"><?= $invoice->net->getCurrency(); ?></a>
<td><a href="<?= $url; ?>"><?= $invoice->createdAt->format('Y-m-d'); ?></a>
<?php endforeach; ?>
</table>
</section>
</div>
</div>
</div>
<input type="radio" id="c-tab-14" name="tabular-2" checked>
<div class="tab">
<div class="row">
<div class="col-xs-12">