From a5ce0aea7d69376a9c467abbcfa85b16731211df Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 26 Jan 2024 22:53:59 +0000 Subject: [PATCH] auto fixes + some impl. --- Admin/Install/Navigation.install.json | 10 +- Admin/Install/attributes.json | 54 ++++ Admin/Install/db.json | 15 + Admin/Installer.php | 41 ++- Admin/Routes/Web/Api.php | 2 +- Admin/Routes/Web/Backend.php | 36 +-- Controller/ApiAttributeController.php | 16 +- Controller/ApiController.php | 180 +++++------ Controller/BackendController.php | 171 ++++++----- Models/Attribute/ItemAttributeTypeMapper.php | 3 +- .../ItemAttributeValueL11nMapper.php | 8 +- Models/Attribute/ItemAttributeValueMapper.php | 18 +- Models/Container.php | 4 + Models/ContainerMapper.php | 20 +- Models/Item.php | 46 +-- Models/ItemMapper.php | 38 +-- Models/ItemPrice.php | 132 -------- Models/ItemRelation.php | 2 +- Models/ItemRelationMapper.php | 8 +- Models/ItemRelationTypeMapper.php | 4 +- Models/MaterialMapper.php | 13 +- Models/MaterialSubcategory.php | 1 - Models/MaterialTypeL11nMapper.php | 8 +- Models/MaterialTypeMapper.php | 6 +- Models/NullContainer.php | 46 +++ Theme/Backend/Lang/Navigation.de.lang.php | 2 +- Theme/Backend/Lang/Navigation.en.lang.php | 2 +- Theme/Backend/Lang/de.lang.php | 284 +++++++++--------- Theme/Backend/Lang/en.lang.php | 282 ++++++++--------- Theme/Backend/attribute-type.tpl.php | 2 +- Theme/Backend/item-list.tpl.php | 39 ++- ...item-profile.tpl.php => item-view.tpl.php} | 201 +++++++------ Theme/Backend/material-view.tpl.php | 2 +- Theme/Backend/purchase-item-list.tpl.php | 2 +- Theme/Backend/sales-item-list.tpl.php | 2 +- ...rofile.tpl.php => sales-item-view.tpl.php} | 20 +- Theme/Backend/stock-item-list.tpl.php | 2 +- tests/Autoloader.php | 4 +- tests/Bootstrap.php | 71 +++-- .../Api/ApiControllerAttributeTrait.php | 23 +- .../Controller/Api/ApiControllerItemTrait.php | 15 +- .../Controller/Api/ApiControllerL11nTrait.php | 9 +- tests/Controller/ApiControllerTest.php | 14 +- tests/Models/ItemTest.php | 32 +- 44 files changed, 952 insertions(+), 938 deletions(-) delete mode 100755 Models/ItemPrice.php create mode 100644 Models/NullContainer.php rename Theme/Backend/{item-profile.tpl.php => item-view.tpl.php} (92%) mode change 100755 => 100644 rename Theme/Backend/{sales-item-profile.tpl.php => sales-item-view.tpl.php} (99%) mode change 100755 => 100644 diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index 0ece2c3..66e2d2f 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -93,7 +93,7 @@ "type": 3, "subtype": 1, "name": "Item", - "uri": "{/base}/item/profile?{?}", + "uri": "{/base}/item/view?{?}", "target": "self", "icon": null, "order": 1, @@ -172,7 +172,7 @@ "type": 3, "subtype": 1, "name": "Item", - "uri": "{/base}/sales/item/single?{?}", + "uri": "{/base}/sales/item/view?{?}", "target": "self", "icon": null, "order": 1, @@ -234,7 +234,7 @@ "type": 3, "subtype": 1, "name": "Item", - "uri": "{/base}/purchase/item/single?{?}", + "uri": "{/base}/purchase/item/view?{?}", "target": "self", "icon": null, "order": 1, @@ -296,7 +296,7 @@ "type": 3, "subtype": 1, "name": "Item", - "uri": "{/base}/warehouse/item/single?{?}", + "uri": "{/base}/warehouse/item/view?{?}", "target": "self", "icon": null, "order": 1, @@ -358,7 +358,7 @@ "type": 3, "subtype": 1, "name": "Item", - "uri": "{/base}/production/item/single?{?}", + "uri": "{/base}/production/item/view?{?}", "target": "self", "icon": null, "order": 1, diff --git a/Admin/Install/attributes.json b/Admin/Install/attributes.json index 5a58d0c..7c0fb78 100755 --- a/Admin/Install/attributes.json +++ b/Admin/Install/attributes.json @@ -1,4 +1,30 @@ [ + { + "name": "default_sales_container", + "l11n": { + "en": "Default sales container", + "de": "Standard Verkaufsgebinde" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": true, + "default_value": "", + "values": [] + }, + { + "name": "default_purchase_container", + "l11n": { + "en": "Default purchase container", + "de": "Standard Einkaufsgebinde" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": true, + "default_value": "", + "values": [] + }, { "name": "primary_supplier", "l11n": { @@ -1373,5 +1399,33 @@ "value": "III" } ] + }, + { + "name": "costcenter", + "l11n": { + "en": "Cost Center", + "de": "Kostenstelle" + }, + "value_type": 2, + "is_custom_allowed": false, + "validation_pattern": "", + "is_required": false, + "internal": true, + "default_value": "", + "values": [] + }, + { + "name": "costobject", + "l11n": { + "en": "Cost Center", + "de": "Kostenstelle" + }, + "value_type": 2, + "is_custom_allowed": false, + "validation_pattern": "", + "is_required": false, + "internal": true, + "default_value": "", + "values": [] } ] \ No newline at end of file diff --git a/Admin/Install/db.json b/Admin/Install/db.json index b60f457..05046de 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -128,11 +128,21 @@ "type": "VARCHAR(255)", "null": false }, + "itemmgmt_item_container_unit": { + "name": "itemmgmt_item_container_unit", + "type": "VARCHAR(255)", + "null": false + }, "itemmgmt_item_container_quantity": { "name": "itemmgmt_item_container_quantity", "type": "INT", "null": false }, + "itemmgmt_item_container_decimals": { + "name": "itemmgmt_item_container_decimals", + "type": "TINYINT(1)", + "null": false + }, "itemmgmt_item_container_weight": { "name": "itemmgmt_item_container_weight", "type": "INT", @@ -362,6 +372,11 @@ "type": "TINYINT(1)", "null": false }, + "itemmgmt_attr_type_internal": { + "name": "itemmgmt_attr_type_internal", + "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", diff --git a/Admin/Installer.php b/Admin/Installer.php index 480b0c9..768ddbe 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -23,7 +23,6 @@ use phpOMS\Message\Http\HttpRequest; use phpOMS\Message\Http\HttpResponse; use phpOMS\Module\InstallerAbstract; use phpOMS\Module\ModuleInfo; -use phpOMS\Uri\HttpUri; /** * Installer class. @@ -50,8 +49,6 @@ final class Installer extends InstallerAbstract { parent::install($app, $info, $cfgHandler); - \Modules\Admin\Admin\Installer::installExternal($app, ['path' => __DIR__ . '/Install/Admin.install.json']); - /* Attributes */ $fileContent = \file_get_contents(__DIR__ . '/Install/attributes.json'); if ($fileContent === false) { @@ -63,6 +60,16 @@ final class Installer extends InstallerAbstract $attrTypes = self::createAttributeTypes($app, $attributes); $attrValues = self::createAttributeValues($app, $attrTypes, $attributes); + $data = \json_decode(\file_get_contents(__DIR__ . '/Install/Admin.install.json'), true); + $content = \json_decode($data[0]['content'], true); + + foreach ($content as $type => $_) { + $content[$type] = \reset($attrValues[$type])['id']; + } + + $data[0]['content'] = \json_encode($content); + \Modules\Admin\Admin\Installer::createSettings($app, $data[0]); + /* Localizations */ $fileContent = \file_get_contents(__DIR__ . '/Install/localizations.json'); if ($fileContent === false) { @@ -100,7 +107,7 @@ final class Installer extends InstallerAbstract } /** @var array $types */ - $types = \json_decode($fileContent, true); + $types = \json_decode($fileContent, true); $materialTypeArray = self::createMaterialTypes($app, $types); } @@ -141,7 +148,7 @@ final class Installer extends InstallerAbstract foreach ($items as $item) { $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('number', (string) $item['number']); @@ -164,13 +171,13 @@ final class Installer extends InstallerAbstract foreach ($l11ns as $language => $l11n) { $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('item', $itemId); $request->setData('type', $l11nType->id); + $request->setData('content', (string) $l11n); $request->setData('language', (string) $language); - $request->setData('description', (string) $l11n); $module->apiItemL11nCreate($request, $response); } @@ -180,7 +187,7 @@ final class Installer extends InstallerAbstract $attrType = $attributeTypes[$attribute['type']]; $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('ref', $itemId); @@ -243,7 +250,7 @@ final class Installer extends InstallerAbstract foreach ($l11ns as $l11n) { $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('title', $l11n['name']); @@ -284,7 +291,7 @@ final class Installer extends InstallerAbstract foreach ($rels as $rel) { $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('title', $rel['name']); @@ -325,12 +332,14 @@ final class Installer extends InstallerAbstract /** @var array $attribute */ foreach ($attributes as $attribute) { $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('name', $attribute['name'] ?? ''); $request->setData('title', \reset($attribute['l11n'])); $request->setData('language', \array_keys($attribute['l11n'])[0] ?? 'en'); + $request->setData('repeatable', $attribute['repeatable'] ?? false); + $request->setData('internal', $attribute['internal'] ?? false); $request->setData('is_required', $attribute['is_required'] ?? false); $request->setData('custom', $attribute['is_custom_allowed'] ?? false); $request->setData('validation_pattern', $attribute['validation_pattern'] ?? ''); @@ -355,7 +364,7 @@ final class Installer extends InstallerAbstract } $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('title', $l11n); @@ -394,7 +403,7 @@ final class Installer extends InstallerAbstract /** @var array $value */ foreach ($attribute['values'] as $value) { $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('value', $value['value'] ?? ''); @@ -428,7 +437,7 @@ final class Installer extends InstallerAbstract } $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('title', $l11n); @@ -464,7 +473,7 @@ final class Installer extends InstallerAbstract /** @var array $type */ foreach ($types as $type) { $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('name', $type['name'] ?? ''); @@ -489,7 +498,7 @@ final class Installer extends InstallerAbstract } $response = new HttpResponse(); - $request = new HttpRequest(new HttpUri('')); + $request = new HttpRequest(); $request->header->account = 1; $request->setData('title', $l11n); diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php index 185e5ee..8a7b8be 100755 --- a/Admin/Routes/Web/Api.php +++ b/Admin/Routes/Web/Api.php @@ -18,7 +18,7 @@ use phpOMS\Account\PermissionType; use phpOMS\Router\RouteVerb; return [ - '^.*/item/find.*$' => [ + '^.*/item/find(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\ApiController:apiItemFind', 'verb' => RouteVerb::GET, diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index 1e8d147..bfe7f72 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -18,7 +18,7 @@ use phpOMS\Account\PermissionType; use phpOMS\Router\RouteVerb; return [ - '^.*/item/attribute/type/list.*$' => [ + '^.*/item/attribute/type/list(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementAttributeTypeList', 'verb' => RouteVerb::GET, @@ -29,7 +29,7 @@ return [ ], ], ], - '^.*/item/attribute/type\?.*$' => [ + '^.*/item/attribute/type(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementAttributeType', 'verb' => RouteVerb::GET, @@ -40,7 +40,7 @@ return [ ], ], ], - '^.*/item/attribute/value.*$' => [ + '^.*/item/attribute/value(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementAttributeValues', 'verb' => RouteVerb::GET, @@ -51,7 +51,7 @@ return [ ], ], ], - '^/item/list.*$' => [ + '^/item/list(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementItemList', 'verb' => RouteVerb::GET, @@ -62,7 +62,7 @@ return [ ], ], ], - '^/item/create.*$' => [ + '^/item/create(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementItemCreate', 'verb' => RouteVerb::GET, @@ -73,7 +73,7 @@ return [ ], ], ], - '^/item/profile.*$' => [ + '^/item/view(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementItem', 'verb' => RouteVerb::GET, @@ -85,7 +85,7 @@ return [ ], ], - '^.*/sales/item/list.*$' => [ + '^.*/sales/item/list(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementSalesList', 'verb' => RouteVerb::GET, @@ -96,7 +96,7 @@ return [ ], ], ], - '^.*/sales/item/create.*$' => [ + '^.*/sales/item/create(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementSalesCreate', 'verb' => RouteVerb::GET, @@ -107,7 +107,7 @@ return [ ], ], ], - '^.*/sales/item/profile.*$' => [ + '^.*/sales/item/view(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementSalesItem', 'verb' => RouteVerb::GET, @@ -119,7 +119,7 @@ return [ ], ], - '^.*/purchase/item/list.*$' => [ + '^.*/purchase/item/list(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementPurchaseList', 'verb' => RouteVerb::GET, @@ -130,7 +130,7 @@ return [ ], ], ], - '^.*/purchase/item/create.*$' => [ + '^.*/purchase/item/create(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementPurchaseCreate', 'verb' => RouteVerb::GET, @@ -141,7 +141,7 @@ return [ ], ], ], - '^.*/purchase/item/profile.*$' => [ + '^.*/purchase/item/view(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementPurchaseItem', 'verb' => RouteVerb::GET, @@ -153,7 +153,7 @@ return [ ], ], - '^.*/warehouse/item/list.*$' => [ + '^.*/warehouse/item/list(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementWarehousingList', 'verb' => RouteVerb::GET, @@ -164,7 +164,7 @@ return [ ], ], ], - '.*/warehouse/item/create.*$' => [ + '.*/warehouse/item/create(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementWarehousingCreate', 'verb' => RouteVerb::GET, @@ -175,7 +175,7 @@ return [ ], ], ], - '^.*/warehouse/item/profile.*$' => [ + '^.*/warehouse/item/view(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementWarehouseItem', 'verb' => RouteVerb::GET, @@ -186,7 +186,7 @@ return [ ], ], ], - '^.*/purchase/analysis/item(\?.*|$)$' => [ + '^.*/purchase/analysis/item(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemPurchaseAnalysis', 'verb' => RouteVerb::GET, @@ -197,7 +197,7 @@ return [ ], ], ], - '^.*/item/material/list\?.*$' => [ + '^.*/item/material/list(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemMaterialList', 'verb' => RouteVerb::GET, @@ -208,7 +208,7 @@ return [ ], ], ], - '^.*/item/material/view\?.*$' => [ + '^.*/item/material/view(\?.*$|$)' => [ [ 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemMaterialView', 'verb' => RouteVerb::GET, diff --git a/Controller/ApiAttributeController.php b/Controller/ApiAttributeController.php index 4d46eba..9e8abdd 100644 --- a/Controller/ApiAttributeController.php +++ b/Controller/ApiAttributeController.php @@ -61,12 +61,15 @@ final class ApiAttributeController extends Controller return; } - $type = ItemAttributeTypeMapper::get()->with('defaults')->where('id', (int) $request->getData('type'))->execute(); + $type = ItemAttributeTypeMapper::get() + ->with('defaults') + ->where('id', (int) $request->getData('type')) + ->execute(); if (!$type->repeatable) { $attr = ItemAttributeMapper::count() ->with('type') - ->where('type/id', (int) $request->getData('type')) + ->where('type/id', $type->id) ->where('ref', (int) $request->getData('ref')) ->execute(); @@ -164,13 +167,20 @@ final class ApiAttributeController extends Controller ->where('id', $request->getDataInt('type') ?? 0) ->execute(); + if ($type->isInternal) { + $response->header->status = RequestStatusCode::R_403; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + $attrValue = $this->createAttributeValueFromRequest($request, $type); $this->createModel($request->header->account, $attrValue, ItemAttributeValueMapper::class, 'attr_value', $request->getOrigin()); if ($attrValue->isDefault) { $this->createModelRelation( $request->header->account, - (int) $request->getData('type'), + $type->id, $attrValue->id, ItemAttributeTypeMapper::class, 'defaults', '', $request->getOrigin() ); diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 2549c78..bb0fbf3 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -15,13 +15,13 @@ declare(strict_types=1); namespace Modules\ItemManagement\Controller; use Modules\Admin\Models\NullAccount; +use Modules\Billing\Models\Price\PriceType; use Modules\ItemManagement\Models\Attribute\ItemAttributeTypeMapper; +use Modules\ItemManagement\Models\Container; use Modules\ItemManagement\Models\Item; use Modules\ItemManagement\Models\ItemL11nMapper; use Modules\ItemManagement\Models\ItemL11nTypeMapper; use Modules\ItemManagement\Models\ItemMapper; -use Modules\ItemManagement\Models\ItemPrice; -use Modules\ItemManagement\Models\ItemPriceStatus; use Modules\ItemManagement\Models\ItemRelationType; use Modules\ItemManagement\Models\ItemRelationTypeMapper; use Modules\ItemManagement\Models\ItemStatus; @@ -38,7 +38,6 @@ use Modules\Media\Models\PathSettings; use phpOMS\Account\PermissionType; use phpOMS\Localization\BaseStringL11n; use phpOMS\Localization\BaseStringL11nType; -use phpOMS\Localization\ISO4217CharEnum; use phpOMS\Localization\ISO639x1Enum; use phpOMS\Localization\NullBaseStringL11nType; use phpOMS\Message\Http\HttpRequest; @@ -50,7 +49,6 @@ use phpOMS\Message\ResponseAbstract; use phpOMS\Model\Message\FormValidation; use phpOMS\Stdlib\Base\FloatInt; use phpOMS\System\MimeType; -use phpOMS\Uri\HttpUri; /** * ItemManagement class. @@ -165,22 +163,52 @@ final class ApiController extends Controller $this->createModel($request->header->account, $item, ItemMapper::class, 'item', $request->getOrigin()); $this->app->dbPool->get()->con->commit(); - if ($this->app->moduleManager->isActive('Billing')) { - $billing = $this->app->moduleManager->get('Billing'); + // Define default item containers + $types = ItemAttributeTypeMapper::getAll() + ->where('name', ['default_sales_container', 'default_purchase_container'], 'IN') + ->execute(); - $internalRequest = new HttpRequest(new HttpUri('')); + foreach ($types as $type) { + $internalResponse = clone $response; + $internalRequest = new HttpRequest(); + + $internalRequest->header->account = $request->header->account; + $internalRequest->setData('ref', $item->id); + $internalRequest->setData('type', $type->id); + $internalRequest->setData('value', \reset($item->container)->id); + + $this->app->moduleManager->get('ItemManagement', 'ApiAttribute')->apiItemAttributeCreate($internalRequest, $internalResponse); + } + + if ($this->app->moduleManager->isActive('Billing')) { + $billing = $this->app->moduleManager->get('Billing', 'ApiPrice'); + + // Sales price + $internalRequest = new HttpRequest(); $internalResponse = new HttpResponse(); $internalRequest->header->account = $request->header->account; - $internalRequest->setData('name', 'base'); + $internalRequest->setData('name', 'default'); + $internalRequest->setData('type', PriceType::SALES); $internalRequest->setData('item', $item->id); - $internalRequest->setData('price_new', $request->getDataInt('salesprice') ?? 0); + $internalRequest->setData('price_new', $request->getDataString('salesprice') ?? 0); + + $billing->apiPriceCreate($internalRequest, $internalResponse); + + // Purchase price + $internalRequest = new HttpRequest(); + $internalResponse = new HttpResponse(); + + $internalRequest->header->account = $request->header->account; + $internalRequest->setData('name', 'default'); + $internalRequest->setData('type', PriceType::PURCHASE); + $internalRequest->setData('item', $item->id); + $internalRequest->setData('price_new', $request->getDataString('purchaseprice') ?? 0); $billing->apiPriceCreate($internalRequest, $internalResponse); } $this->createMediaDirForItem($item->number, $request->header->account); - $path = $this->createItemDir($item); $uploadedFiles = $request->files['item_profile_image'] ?? []; @@ -239,13 +267,13 @@ final class ApiController extends Controller return; } - $types = ItemAttributeTypeMapper::get() + $types = ItemAttributeTypeMapper::getAll() ->where('name', \array_keys($segmentation), 'IN') ->execute(); foreach ($types as $type) { $internalResponse = clone $response; - $internalRequest = new HttpRequest(new HttpUri('')); + $internalRequest = new HttpRequest(); $internalRequest->header->account = $request->header->account; $internalRequest->setData('ref', $item->id); @@ -290,15 +318,21 @@ final class ApiController extends Controller */ private function createItemFromRequest(RequestAbstract $request) : Item { - $item = new Item(); - $item->number = $request->getDataString('number') ?? ''; - $item->stockIdentifier = $request->getDataInt('stockidentifier') ?? StockIdentifierType::NONE; - $item->salesPrice = new FloatInt($request->getDataInt('salesprice') ?? 0); - $item->purchasePrice = new FloatInt($request->getDataInt('purchaseprice') ?? 0); - $item->info = $request->getDataString('info') ?? ''; - $item->parent = $request->getDataInt('parent'); - $item->unit = $request->getDataInt('unit'); - $item->setStatus($request->getDataInt('status') ?? ItemStatus::ACTIVE); + $item = new Item(); + $item->number = $request->getDataString('number') ?? ''; + $item->stockIdentifier = $request->getDataInt('stockidentifier') ?? StockIdentifierType::NONE; + $item->salesPrice = new FloatInt($request->getDataString('salesprice') ?? 0); + $item->purchasePrice = new FloatInt($request->getDataString('purchaseprice') ?? 0); + $item->info = $request->getDataString('info') ?? ''; + $item->parent = $request->getDataInt('parent'); + $item->unit = $request->getDataInt('unit'); + $item->status = ItemStatus::tryFromValue($request->getDataInt('status')) ?? ItemStatus::ACTIVE; + + $container = new Container(); + $container->name = 'default'; + $container->quantity = \pow(10, FloatInt::MAX_DECIMALS); + + $item->container[] = $container; return $item; } @@ -322,81 +356,6 @@ final class ApiController extends Controller return []; } - /** - * Api method to create item - * - * @param RequestAbstract $request Request - * @param ResponseAbstract $response Response - * @param array $data Generic data - * - * @return void - * - * @api - * - * @since 1.0.0 - */ - public function apiItemPriceCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void - { - if (!empty($val = $this->validateItemPriceCreate($request))) { - $response->header->status = RequestStatusCode::R_400; - $this->createInvalidCreateResponse($request, $response, $val); - - return; - } - - $item = $this->createItemPriceFromRequest($request); - $this->createModel($request->header->account, $item, ItemMapper::class, 'item', $request->getOrigin()); - $this->createStandardCreateResponse($request, $response, $item); - } - - /** - * Method to create item from request. - * - * @param RequestAbstract $request Request - * - * @return ItemPrice - * - * @since 1.0.0 - */ - private function createItemPriceFromRequest(RequestAbstract $request) : ItemPrice - { - $item = new ItemPrice(); - $item->currency = $request->getDataString('currency') ?? ''; - $item->price = new FloatInt($request->getDataInt('price') ?? 0); - $item->minQuantity = $request->getDataInt('minquantity') ?? 0; - $item->relativeDiscount = $request->getDataInt('relativediscount') ?? 0; - $item->absoluteDiscount = $request->getDataInt('absolutediscount') ?? 0; - $item->relativeUnitDiscount = $request->getDataInt('relativeunitdiscount') ?? 0; - $item->absoluteUnitDiscount = $request->getDataInt('absoluteunitdiscount') ?? 0; - $item->promocode = $request->getDataString('promocode') ?? ''; - $item->start = $request->getDataDateTime('start'); - $item->end = $request->getDataDateTime('end'); - $item->setStatus($request->getDataInt('status') ?? ItemPriceStatus::ACTIVE); - - return $item; - } - - /** - * Validate item create request - * - * @param RequestAbstract $request Request - * - * @return array - * - * @since 1.0.0 - */ - private function validateItemPriceCreate(RequestAbstract $request) : array - { - $val = []; - if (($val['price_new'] = !$request->hasData('price_new')) - || ($val['currency'] = !ISO4217CharEnum::isValidValue($request->getData('currency'))) - ) { - return $val; - } - - return []; - } - /** * Api method to create item attribute * @@ -648,13 +607,11 @@ final class ApiController extends Controller */ private function createItemL11nFromRequest(RequestAbstract $request) : BaseStringL11n { - $itemL11n = new BaseStringL11n(); - $itemL11n->ref = $request->getDataInt('item') ?? 0; - $itemL11n->type = new NullBaseStringL11nType($request->getDataInt('type') ?? 0); - $itemL11n->setLanguage( - $request->getDataString('language') ?? $request->header->l11n->language - ); - $itemL11n->content = $request->getDataString('content') ?? ''; + $itemL11n = new BaseStringL11n(); + $itemL11n->ref = $request->getDataInt('item') ?? 0; + $itemL11n->type = new NullBaseStringL11nType($request->getDataInt('type') ?? 0); + $itemL11n->language = ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? $request->header->l11n->language; + $itemL11n->content = $request->getDataString('content') ?? ''; return $itemL11n; } @@ -952,8 +909,11 @@ final class ApiController extends Controller */ private function createMaterialTypeFromRequest(RequestAbstract $request) : BaseStringL11nType { - $materialType = new BaseStringL11nType($request->getDataString('name') ?? ''); - $materialType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + $materialType = new BaseStringL11nType($request->getDataString('name') ?? ''); + $materialType->setL11n( + $request->getDataString('title') ?? '', + ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? ISO639x1Enum::_EN + ); return $materialType; } @@ -1017,12 +977,10 @@ final class ApiController extends Controller */ private function createMaterialTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n { - $materialL11n = new BaseStringL11n(); - $materialL11n->ref = $request->getDataInt('type') ?? 0; - $materialL11n->setLanguage( - $request->getDataString('language') ?? $request->header->l11n->language - ); - $materialL11n->content = $request->getDataString('title') ?? ''; + $materialL11n = new BaseStringL11n(); + $materialL11n->ref = $request->getDataInt('type') ?? 0; + $materialL11n->language = ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? $request->header->l11n->language; + $materialL11n->content = $request->getDataString('title') ?? ''; return $materialL11n; } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 6a69d0d..1e1aa47 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -14,22 +14,20 @@ declare(strict_types=1); namespace Modules\ItemManagement\Controller; -use Modules\Admin\Models\LocalizationMapper; -use Modules\Admin\Models\SettingsEnum; use Modules\Auditor\Models\AuditMapper; -use Modules\Billing\Models\Price\PriceMapper; -use Modules\Billing\Models\Price\PriceType; use Modules\ClientManagement\Models\Attribute\ClientAttributeTypeMapper; use Modules\ClientManagement\Models\Attribute\ClientAttributeValueL11nMapper; use Modules\ItemManagement\Models\Attribute\ItemAttributeTypeL11nMapper; use Modules\ItemManagement\Models\Attribute\ItemAttributeTypeMapper; use Modules\ItemManagement\Models\Attribute\ItemAttributeValueL11nMapper; use Modules\ItemManagement\Models\Attribute\ItemAttributeValueMapper; +use Modules\ItemManagement\Models\Item; use Modules\ItemManagement\Models\ItemL11nMapper; use Modules\ItemManagement\Models\ItemL11nTypeMapper; use Modules\ItemManagement\Models\ItemMapper; use Modules\ItemManagement\Models\MaterialTypeL11nMapper; use Modules\ItemManagement\Models\MaterialTypeMapper; +use Modules\ItemManagement\Models\StockIdentifierType; use Modules\Media\Models\MediaMapper; use Modules\Media\Models\MediaTypeMapper; use Modules\Organization\Models\Attribute\UnitAttributeMapper; @@ -200,6 +198,7 @@ final class BackendController extends Controller /** @var \Modules\ItemManagement\Models\Item[] $items */ $items = ItemMapper::getAll() + ->with('container') // @todo change to only get the default sales container ->with('l11n') ->with('l11n/type') ->with('files') @@ -212,6 +211,73 @@ final class BackendController extends Controller $view->data['items'] = $items; + // Stock distribution + $dists = []; + $reserved = []; + $ordered = []; + if ($this->app->moduleManager->isActive('WarehouseManagement')) { + $itemIds = \array_map(function (Item $item) { return $item->id; + }, $items); + $itemIdsString = \implode(',', $itemIds); + + // @todo only select sales stock. Therefore we need a place to define the sales stock(s) + $temp = \Modules\WarehouseManagement\Models\StockDistributionMapper::getAll() + ->where('item', $itemIds, 'IN') + ->execute(); + + foreach ($temp as $t) { + if (!isset($dists[$t->item])) { + $dists[$t->item] = []; + } + + // @todo These numbers might need adjustments for delivery notes/invoices depending on + // how we implement them in the warehouse management (maybe flag them in the transaction protocol as reserved?) + // also remember the SD issue where delivery notes can be technically still in stock -> stock value still belongs to company + // solution: "just" do a soft adjust of the available numbers?! but don't change the actual stock in the db + // the SD solution where actually delivered delivery notes can be adjusted after "archiving" will not be allowed + // to allow them to see what happened with such a delivery note maybe we can implement a view shows how many of the items are + // actually still outstanding. This shouldn't be anything special since we need importing of delivery notes anyways and marking + // old delivery note elements in a way to show which line items or even sub-line items got invoiced/returned etc. + $dists[$t->item][] = $t; + } + + $stockIdentifier = StockIdentifierType::NONE; + + $sql = <<app->dbPool->get()); + $results = $query->raw($sql)->execute()->fetchAll(\PDO::FETCH_ASSOC); + + foreach ($results as $result) { + if (!isset($reserved[(int) $result['billing_bill_element_item']])) { + $reserved[$t->item] = 0; + $ordered[$t->item] = 0; + } + + if ($result['billing_type_name'] === 'sales_order_confirmation') { + $reserved[(int) $result['billing_bill_element_item']] += (int) $result['quantity']; + } else { + $ordered[(int) $result['billing_bill_element_item']] += (int) $result['quantity']; + } + } + } + + $view->data['dists'] = $dists; + $view->data['reserved'] = $reserved; + $view->data['ordered'] = $ordered; + return $view; } @@ -368,11 +434,11 @@ final class BackendController extends Controller $head->addAsset(AssetType::JSLATE, 'Modules/ItemManagement/Controller.js', ['nonce' => $nonce, 'type' => 'module']); $view = new View($this->app->l11nManager, $request, $response); - $view->setTemplate('/Modules/ItemManagement/Theme/Backend/item-profile'); + $view->setTemplate('/Modules/ItemManagement/Theme/Backend/item-view'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004803001, $request, $response); - /** @var \Modules\ItemManagement\Models\Item $item */ - $item = ItemMapper::get() + /** @var \Modules\ItemManagement\Models\Item */ + $view->data['item'] = ItemMapper::get() ->with('l11n') ->with('l11n/type') ->with('files')->limit(5, 'files')->sort('files/id', OrderType::DESC) @@ -382,14 +448,14 @@ final class BackendController extends Controller ->with('attributes/type') ->with('attributes/type/l11n') ->with('attributes/value') + //->with('attributes/value/l11n') ->where('id', (int) $request->getData('id')) ->where('l11n/language', $response->header->l11n->language) ->where('l11n/type/title', ['name1', 'name2', 'name3'], 'IN') ->where('attributes/type/l11n/language', $response->header->l11n->language) + //->where('attributes/value/l11n/language', $response->header->l11n->language) ->execute(); - $view->data['item'] = $item; - // Get item profile image // It might not be part of the 5 newest item files from above // @todo It would be nice to have something like this as a default method in the model e.g. @@ -406,18 +472,16 @@ final class BackendController extends Controller ->on(MediaMapper::TABLE . '.' . MediaMapper::PRIMARYFIELD, '=', MediaMapper::HAS_MANY['types']['table'] . '.' . MediaMapper::HAS_MANY['types']['self']) ->leftJoin(MediaTypeMapper::TABLE) ->on(MediaMapper::HAS_MANY['types']['table'] . '.' . MediaMapper::HAS_MANY['types']['external'], '=', MediaTypeMapper::TABLE . '.' . MediaTypeMapper::PRIMARYFIELD) - ->where(ItemMapper::HAS_MANY['files']['self'], '=', $item->id) + ->where(ItemMapper::HAS_MANY['files']['self'], '=', $view->data['item']->id) ->where(MediaTypeMapper::TABLE . '.' . MediaTypeMapper::getColumnByMember('name'), '=', 'item_profile_image'); - /** @var \Modules\Media\Models\Media $itemImage */ - $itemImage = MediaMapper::get() + /** @var \Modules\Media\Models\Media */ + $view->data['itemImage'] = MediaMapper::get() ->with('types') ->where('id', $results) ->limit(1) ->execute(); - $view->data['itemImage'] = $itemImage; - $businessStart = UnitAttributeMapper::get() ->with('type') ->with('value') @@ -427,61 +491,40 @@ final class BackendController extends Controller $view->data['business_start'] = $businessStart->id === 0 ? 1 : $businessStart->value->getValue(); - // @todo this one should already be loaded in the backend application no????????? - /** @var \Model\Setting $settings */ - $settings = $this->app->appSettings->get(null, SettingsEnum::DEFAULT_LOCALIZATION); - - $view->data['default_localization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); - - $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); - $view->data['attributeView']->data['default_localization'] = $view->data['default_localization']; + $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); + $view->data['attributeView']->data['default_localization'] = $this->app->l11nServer; $view->data['l11nView'] = new \Web\Backend\Views\L11nView($this->app->l11nManager, $request, $response); - /** @var \phpOMS\Localization\BaseStringL11nType[] $l11nTypes */ - $l11nTypes = ItemL11nTypeMapper::getAll() + /** @var \phpOMS\Localization\BaseStringL11nType[] */ + $view->data['l11nTypes'] = ItemL11nTypeMapper::getAll() ->execute(); - $view->data['l11nTypes'] = $l11nTypes; - - /** @var \phpOMS\Localization\BaseStringL11n[] $l11nValues */ - $l11nValues = ItemL11nMapper::getAll() + /** @var \phpOMS\Localization\BaseStringL11n[] */ + $view->data['l11nValues'] = ItemL11nMapper::getAll() ->with('type') - ->where('ref', $item->id) + ->where('ref', $view->data['item']->id) ->execute(); - $view->data['l11nValues'] = $l11nValues; - - /** @var \Modules\Attribute\Models\AttributeType[] $attributeTypes */ - $attributeTypes = ItemAttributeTypeMapper::getAll() + /** @var \Modules\Attribute\Models\AttributeType[] */ + $view->data['attributeTypes'] = ItemAttributeTypeMapper::getAll() ->with('l11n') ->where('l11n/language', $response->header->l11n->language) ->execute(); - $view->data['attributeTypes'] = $attributeTypes; - - /** @var \Modules\Organization\Models\Unit[] $units */ - $units = UnitMapper::getAll() + /** @var \Modules\Organization\Models\Unit[] */ + $view->data['units'] = UnitMapper::getAll() ->execute(); - $view->data['units'] = $units; + $view->data['hasBilling'] = $this->app->moduleManager->isActive('Billing'); - /** @var \Modules\Billing\Models\Price\Price[] $prices */ - $prices = PriceMapper::getAll() - ->where('item', $item->id) - ->where('type', PriceType::SALES) - ->where('client', null) - ->execute(); - - $view->data['prices'] = $prices; - - /** @var \Modules\Billing\Models\Price\Price[] $prices */ - $prices = PriceMapper::getAll() - ->where('item', $item->id) - ->where('type', PriceType::PURCHASE) - ->execute(); - - $view->data['purchase_prices'] = $prices; + /** @var \Modules\Billing\Models\Price\Price[] */ + $view->data['prices'] = $view->data['hasBilling'] + ? \Modules\Billing\Models\Price\PriceMapper::getAll() + ->where('item', $view->data['item']->id) + ->where('client', null) + ->execute() + : []; $tmp = ItemAttributeTypeMapper::getAll() ->with('defaults') @@ -519,30 +562,24 @@ final class BackendController extends Controller $view->data['clientSegmentationTypes'] = $clientSegmentationTypes; - /** @var \Modules\Auditor\Models\Audit[] $audits */ - $audits = AuditMapper::getAll() + /** @var \Modules\Auditor\Models\Audit[] */ + $view->data['audits'] = AuditMapper::getAll() ->where('type', StringUtils::intHash(ItemMapper::class)) ->where('module', 'ItemManagement') - ->where('ref', (string) $item->id) + ->where('ref', (string) $view->data['item']->id) ->execute(); // @todo join audit with files, attributes, localization, prices, notes, ... - $view->data['audits'] = $audits; - - /** @var \Modules\Media\Models\Media[] $files */ - $files = MediaMapper::getAll() + /** @var \Modules\Media\Models\Media[] */ + $view->data['files'] = MediaMapper::getAll() ->with('types') ->join('id', ItemMapper::class, 'files') // id = media id, files = item relations - ->on('id', $item->id, relation: 'files') // id = item id + ->on('id', $view->data['item']->id, relation: 'files') // id = item id ->execute(); - $view->data['files'] = $files; - $view->data['media-upload'] = new \Modules\Media\Theme\Backend\Components\Upload\BaseView($this->app->l11nManager, $request, $response); - $view->data['note'] = new \Modules\Editor\Theme\Backend\Components\Note\BaseView($this->app->l11nManager, $request, $response); - - $view->data['hasBilling'] = $this->app->moduleManager->isActive('Billing'); + $view->data['note'] = new \Modules\Editor\Theme\Backend\Components\Note\BaseView($this->app->l11nManager, $request, $response); return $view; } diff --git a/Models/Attribute/ItemAttributeTypeMapper.php b/Models/Attribute/ItemAttributeTypeMapper.php index fca1405..23d95e9 100644 --- a/Models/Attribute/ItemAttributeTypeMapper.php +++ b/Models/Attribute/ItemAttributeTypeMapper.php @@ -42,7 +42,8 @@ final class ItemAttributeTypeMapper extends DataMapperFactory 'itemmgmt_attr_type_datatype' => ['name' => 'itemmgmt_attr_type_datatype', 'type' => 'int', 'internal' => 'datatype'], '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_repeatable' => ['name' => 'itemmgmt_attr_type_repeatable', 'type' => 'bool', 'internal' => 'repeatable'], + 'itemmgmt_attr_type_repeatable' => ['name' => 'itemmgmt_attr_type_repeatable', 'type' => 'bool', 'internal' => 'repeatable'], + 'itemmgmt_attr_type_internal' => ['name' => 'itemmgmt_attr_type_internal', 'type' => 'bool', 'internal' => 'isInternal'], 'itemmgmt_attr_type_pattern' => ['name' => 'itemmgmt_attr_type_pattern', 'type' => 'string', 'internal' => 'validationPattern'], 'itemmgmt_attr_type_required' => ['name' => 'itemmgmt_attr_type_required', 'type' => 'bool', 'internal' => 'isRequired'], ]; diff --git a/Models/Attribute/ItemAttributeValueL11nMapper.php b/Models/Attribute/ItemAttributeValueL11nMapper.php index 02612d1..62d8fcd 100644 --- a/Models/Attribute/ItemAttributeValueL11nMapper.php +++ b/Models/Attribute/ItemAttributeValueL11nMapper.php @@ -37,10 +37,10 @@ final class ItemAttributeValueL11nMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'itemmgmt_attr_value_l11n_id' => ['name' => 'itemmgmt_attr_value_l11n_id', 'type' => 'int', 'internal' => 'id'], - 'itemmgmt_attr_value_l11n_title' => ['name' => 'itemmgmt_attr_value_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], - 'itemmgmt_attr_value_l11n_value' => ['name' => 'itemmgmt_attr_value_l11n_value', 'type' => 'int', 'internal' => 'ref'], - 'itemmgmt_attr_value_l11n_lang' => ['name' => 'itemmgmt_attr_value_l11n_lang', 'type' => 'string', 'internal' => 'language'], + 'itemmgmt_attr_value_l11n_id' => ['name' => 'itemmgmt_attr_value_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'itemmgmt_attr_value_l11n_title' => ['name' => 'itemmgmt_attr_value_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'itemmgmt_attr_value_l11n_value' => ['name' => 'itemmgmt_attr_value_l11n_value', 'type' => 'int', 'internal' => 'ref'], + 'itemmgmt_attr_value_l11n_lang' => ['name' => 'itemmgmt_attr_value_l11n_lang', 'type' => 'string', 'internal' => 'language'], ]; /** diff --git a/Models/Attribute/ItemAttributeValueMapper.php b/Models/Attribute/ItemAttributeValueMapper.php index badf99e..0994fa8 100644 --- a/Models/Attribute/ItemAttributeValueMapper.php +++ b/Models/Attribute/ItemAttributeValueMapper.php @@ -37,15 +37,15 @@ final class ItemAttributeValueMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'itemmgmt_attr_value_id' => ['name' => 'itemmgmt_attr_value_id', 'type' => 'int', 'internal' => 'id'], - 'itemmgmt_attr_value_default' => ['name' => 'itemmgmt_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'], - 'itemmgmt_attr_value_valueStr' => ['name' => 'itemmgmt_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'], - 'itemmgmt_attr_value_valueInt' => ['name' => 'itemmgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'], - 'itemmgmt_attr_value_valueDec' => ['name' => 'itemmgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'], - 'itemmgmt_attr_value_valueDat' => ['name' => 'itemmgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'], - 'itemmgmt_attr_value_unit' => ['name' => 'itemmgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'], - 'itemmgmt_attr_value_deptype' => ['name' => 'itemmgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'], - 'itemmgmt_attr_value_depvalue' => ['name' => 'itemmgmt_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'], + 'itemmgmt_attr_value_id' => ['name' => 'itemmgmt_attr_value_id', 'type' => 'int', 'internal' => 'id'], + 'itemmgmt_attr_value_default' => ['name' => 'itemmgmt_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'], + 'itemmgmt_attr_value_valueStr' => ['name' => 'itemmgmt_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'], + 'itemmgmt_attr_value_valueInt' => ['name' => 'itemmgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'], + 'itemmgmt_attr_value_valueDec' => ['name' => 'itemmgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'], + 'itemmgmt_attr_value_valueDat' => ['name' => 'itemmgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'], + 'itemmgmt_attr_value_unit' => ['name' => 'itemmgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'], + 'itemmgmt_attr_value_deptype' => ['name' => 'itemmgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'], + 'itemmgmt_attr_value_depvalue' => ['name' => 'itemmgmt_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'], ]; /** diff --git a/Models/Container.php b/Models/Container.php index a82495c..cada9db 100644 --- a/Models/Container.php +++ b/Models/Container.php @@ -34,8 +34,12 @@ class Container implements \JsonSerializable public string $name = ''; + public string $unit = 'pcs'; + public int $quantity = 0; + public int $quantityDecimals = 0; + public int $weight = 0; public int $width = 0; diff --git a/Models/ContainerMapper.php b/Models/ContainerMapper.php index 1668281..b9b85ce 100644 --- a/Models/ContainerMapper.php +++ b/Models/ContainerMapper.php @@ -36,15 +36,17 @@ final class ContainerMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'itemmgmt_item_container_id' => ['name' => 'itemmgmt_item_container_id', 'type' => 'int', 'internal' => 'id'], - 'itemmgmt_item_container_name' => ['name' => 'itemmgmt_item_container_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], - 'itemmgmt_item_container_quantity' => ['name' => 'itemmgmt_item_container_quantity', 'type' => 'int', 'internal' => 'quantity'], - 'itemmgmt_item_container_weight' => ['name' => 'itemmgmt_item_container_weight', 'type' => 'int', 'internal' => 'weight'], - 'itemmgmt_item_container_width' => ['name' => 'itemmgmt_item_container_width', 'type' => 'int', 'internal' => 'width'], - 'itemmgmt_item_container_height' => ['name' => 'itemmgmt_item_container_height', 'type' => 'int', 'internal' => 'height'], - 'itemmgmt_item_container_length' => ['name' => 'itemmgmt_item_container_length', 'type' => 'int', 'internal' => 'length'], - 'itemmgmt_item_container_volume' => ['name' => 'itemmgmt_item_container_volume', 'type' => 'int', 'internal' => 'volume'], - 'itemmgmt_item_container_item' => ['name' => 'itemmgmt_item_container_item', 'type' => 'int', 'internal' => 'item'], + 'itemmgmt_item_container_id' => ['name' => 'itemmgmt_item_container_id', 'type' => 'int', 'internal' => 'id'], + 'itemmgmt_item_container_name' => ['name' => 'itemmgmt_item_container_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'itemmgmt_item_container_unit' => ['name' => 'itemmgmt_item_container_unit', 'type' => 'string', 'internal' => 'unit'], + 'itemmgmt_item_container_quantity' => ['name' => 'itemmgmt_item_container_quantity', 'type' => 'int', 'internal' => 'quantity'], + 'itemmgmt_item_container_decimals' => ['name' => 'itemmgmt_item_container_decimals', 'type' => 'int', 'internal' => 'quantityDecimals'], + 'itemmgmt_item_container_weight' => ['name' => 'itemmgmt_item_container_weight', 'type' => 'int', 'internal' => 'weight'], + 'itemmgmt_item_container_width' => ['name' => 'itemmgmt_item_container_width', 'type' => 'int', 'internal' => 'width'], + 'itemmgmt_item_container_height' => ['name' => 'itemmgmt_item_container_height', 'type' => 'int', 'internal' => 'height'], + 'itemmgmt_item_container_length' => ['name' => 'itemmgmt_item_container_length', 'type' => 'int', 'internal' => 'length'], + 'itemmgmt_item_container_volume' => ['name' => 'itemmgmt_item_container_volume', 'type' => 'int', 'internal' => 'volume'], + 'itemmgmt_item_container_item' => ['name' => 'itemmgmt_item_container_item', 'type' => 'int', 'internal' => 'item'], ]; /** diff --git a/Models/Item.php b/Models/Item.php index 4555029..0078585 100755 --- a/Models/Item.php +++ b/Models/Item.php @@ -134,6 +134,12 @@ class Item implements \JsonSerializable */ public ?int $unit = null; + /** + * Containers + * + * @var Container[] + * @since 1.0.0 + */ public array $container = []; /** @@ -148,18 +154,6 @@ class Item implements \JsonSerializable $this->purchasePrice = new FloatInt(); } - /** - * Get id. - * - * @return int Model id - * - * @since 1.0.0 - */ - public function getId() : int - { - return $this->id; - } - /** * Add item l11n * @@ -189,7 +183,7 @@ class Item implements \JsonSerializable * * @since 1.0.0 */ - public function getL11n(string $type = null) : BaseStringL11n + public function getL11n(?string $type = null) : BaseStringL11n { foreach ($this->l11n as $l11n) { if ($l11n->type?->title === $type) { @@ -212,32 +206,6 @@ class Item implements \JsonSerializable return $this->l11n; } - /** - * Get status. - * - * @return int - * - * @since 1.0.0 - */ - public function getStatus() : int - { - return $this->status; - } - - /** - * Set status. - * - * @param int $status Status - * - * @return void - * - * @since 1.0.0 - */ - public function setStatus(int $status) : void - { - $this->status = $status; - } - /** * {@inheritdoc} */ diff --git a/Models/ItemMapper.php b/Models/ItemMapper.php index 28e9253..1ed18a3 100755 --- a/Models/ItemMapper.php +++ b/Models/ItemMapper.php @@ -43,15 +43,15 @@ final class ItemMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'itemmgmt_item_id' => ['name' => 'itemmgmt_item_id', 'type' => 'int', 'internal' => 'id'], - 'itemmgmt_item_no' => ['name' => 'itemmgmt_item_no', 'type' => 'string', 'internal' => 'number', 'autocomplete' => true], - 'itemmgmt_item_status' => ['name' => 'itemmgmt_item_status', 'type' => 'int', 'internal' => 'status'], - 'itemmgmt_item_stockidentifier' => ['name' => 'itemmgmt_item_stockidentifier', 'type' => 'int', 'internal' => 'stockIdentifier'], - 'itemmgmt_item_info' => ['name' => 'itemmgmt_item_info', 'type' => 'string', 'internal' => 'info'], - 'itemmgmt_item_salesprice' => ['name' => 'itemmgmt_item_salesprice', 'type' => 'Serializable', 'internal' => 'salesPrice'], - 'itemmgmt_item_purchaseprice' => ['name' => 'itemmgmt_item_purchaseprice', 'type' => 'Serializable', 'internal' => 'purchasePrice'], - 'itemmgmt_item_parent' => ['name' => 'itemmgmt_item_parent', 'type' => 'int', 'internal' => 'parent'], - 'itemmgmt_item_unit' => ['name' => 'itemmgmt_item_unit', 'type' => 'int', 'internal' => 'unit'], + 'itemmgmt_item_id' => ['name' => 'itemmgmt_item_id', 'type' => 'int', 'internal' => 'id'], + 'itemmgmt_item_no' => ['name' => 'itemmgmt_item_no', 'type' => 'string', 'internal' => 'number', 'autocomplete' => true], + 'itemmgmt_item_status' => ['name' => 'itemmgmt_item_status', 'type' => 'int', 'internal' => 'status'], + 'itemmgmt_item_stockidentifier' => ['name' => 'itemmgmt_item_stockidentifier', 'type' => 'int', 'internal' => 'stockIdentifier'], + 'itemmgmt_item_info' => ['name' => 'itemmgmt_item_info', 'type' => 'string', 'internal' => 'info'], + 'itemmgmt_item_salesprice' => ['name' => 'itemmgmt_item_salesprice', 'type' => 'Serializable', 'internal' => 'salesPrice'], + 'itemmgmt_item_purchaseprice' => ['name' => 'itemmgmt_item_purchaseprice', 'type' => 'Serializable', 'internal' => 'purchasePrice'], + 'itemmgmt_item_parent' => ['name' => 'itemmgmt_item_parent', 'type' => 'int', 'internal' => 'parent'], + 'itemmgmt_item_unit' => ['name' => 'itemmgmt_item_unit', 'type' => 'int', 'internal' => 'unit'], ]; /** @@ -102,10 +102,10 @@ final class ItemMapper extends DataMapperFactory 'external' => null, ], 'container' => [ - 'mapper' => ContainerMapper::class, - 'table' => 'itemmgmt_item_container', - 'self' => 'itemmgmt_item_container_item', - 'external' => null, + 'mapper' => ContainerMapper::class, + 'table' => 'itemmgmt_item_container', + 'self' => 'itemmgmt_item_container_item', + 'external' => null, ], ]; @@ -198,12 +198,12 @@ final class ItemMapper extends DataMapperFactory $l11nType->id = $res['itemmgmt_item_l11n_typeref']; $l11nType->title = $res['itemmgmt_item_l11n_type_title']; - $l11n = new BaseStringL11n(); - $l11n->id = $res['itemmgmt_item_l11n_id']; - $l11n->ref = $res['itemmgmt_item_id']; - $l11n->type = $l11nType; - $l11n->content = $res['itemmgmt_item_l11n_description']; - $l11n->setLanguage($res['itemmgmt_item_l11n_lang']); + $l11n = new BaseStringL11n(); + $l11n->id = $res['itemmgmt_item_l11n_id']; + $l11n->ref = $res['itemmgmt_item_id']; + $l11n->type = $l11nType; + $l11n->content = $res['itemmgmt_item_l11n_description']; + $l11n->language = $res['itemmgmt_item_l11n_lang']; $items[$l11n->ref]->addL11n($l11n); } diff --git a/Models/ItemPrice.php b/Models/ItemPrice.php deleted file mode 100755 index c3237d4..0000000 --- a/Models/ItemPrice.php +++ /dev/null @@ -1,132 +0,0 @@ -status; - } - - /** - * Set status - * - * @param int $status Price status - * - * @return void - * - * @throws InvalidEnumValue - * - * @since 1.0.0 - */ - public function setStatus(int $status) : void - { - if (!ItemPriceStatus::isValidValue($status)) { - throw new InvalidEnumValue((string) $status); - } - - $this->status = $status; - } - - /** - * {@inheritdoc} - */ - public function toArray() : array - { - return [ - 'id' => $this->id, - 'name' => $this->name, - 'currency' => $this->currency, - 'price' => $this->price, - 'status' => $this->status, - 'minQuantity' => $this->minQuantity, - 'relativeDiscount' => $this->relativeDiscount, - 'absoluteDiscount' => $this->absoluteDiscount, - 'relativeUnitDiscount' => $this->relativeUnitDiscount, - 'absoluteUnitDiscount' => $this->absoluteUnitDiscount, - 'promocode' => $this->promocode, - 'start' => $this->start, - 'end' => $this->end, - ]; - } - - /** - * {@inheritdoc} - */ - public function jsonSerialize() : mixed - { - return $this->toArray(); - } -} diff --git a/Models/ItemRelation.php b/Models/ItemRelation.php index a441154..653746b 100755 --- a/Models/ItemRelation.php +++ b/Models/ItemRelation.php @@ -63,7 +63,7 @@ class ItemRelation implements \JsonSerializable * * @since 1.0.0 */ - public function __construct(ItemRelationType $type = null) + public function __construct(?ItemRelationType $type = null) { $this->type = $type ?? new ItemRelationType(); } diff --git a/Models/ItemRelationMapper.php b/Models/ItemRelationMapper.php index f9e85e6..b0e3368 100755 --- a/Models/ItemRelationMapper.php +++ b/Models/ItemRelationMapper.php @@ -36,10 +36,10 @@ final class ItemRelationMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'itemmgmt_item_relation_id' => ['name' => 'itemmgmt_item_relation_id', 'type' => 'int', 'internal' => 'id'], - 'itemmgmt_item_relation_src' => ['name' => 'itemmgmt_item_relation_src', 'type' => 'int', 'internal' => 'source'], - 'itemmgmt_item_relation_dst' => ['name' => 'itemmgmt_item_relation_dst', 'type' => 'int', 'internal' => 'destination'], - 'itemmgmt_item_relation_type' => ['name' => 'itemmgmt_item_relation_type', 'type' => 'int', 'internal' => 'type'], + 'itemmgmt_item_relation_id' => ['name' => 'itemmgmt_item_relation_id', 'type' => 'int', 'internal' => 'id'], + 'itemmgmt_item_relation_src' => ['name' => 'itemmgmt_item_relation_src', 'type' => 'int', 'internal' => 'source'], + 'itemmgmt_item_relation_dst' => ['name' => 'itemmgmt_item_relation_dst', 'type' => 'int', 'internal' => 'destination'], + 'itemmgmt_item_relation_type' => ['name' => 'itemmgmt_item_relation_type', 'type' => 'int', 'internal' => 'type'], ]; /** diff --git a/Models/ItemRelationTypeMapper.php b/Models/ItemRelationTypeMapper.php index 544cd11..28d46df 100755 --- a/Models/ItemRelationTypeMapper.php +++ b/Models/ItemRelationTypeMapper.php @@ -36,8 +36,8 @@ final class ItemRelationTypeMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'itemmgmt_item_relation_type_id' => ['name' => 'itemmgmt_item_relation_type_id', 'type' => 'int', 'internal' => 'id'], - 'itemmgmt_item_relation_type_title' => ['name' => 'itemmgmt_item_relation_type_title', 'type' => 'string', 'internal' => 'title'], + 'itemmgmt_item_relation_type_id' => ['name' => 'itemmgmt_item_relation_type_id', 'type' => 'int', 'internal' => 'id'], + 'itemmgmt_item_relation_type_title' => ['name' => 'itemmgmt_item_relation_type_title', 'type' => 'string', 'internal' => 'title'], ]; /** diff --git a/Models/MaterialMapper.php b/Models/MaterialMapper.php index 1946ba9..c573a3e 100644 --- a/Models/MaterialMapper.php +++ b/Models/MaterialMapper.php @@ -15,7 +15,6 @@ declare(strict_types=1); namespace Modules\ItemManagement\Models; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; -use phpOMS\Localization\BaseStringL11nType; /** * Item mapper class. @@ -37,12 +36,12 @@ final class MaterialMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'itemmgmt_material_id' => ['name' => 'itemmgmt_material_id', 'type' => 'int', 'internal' => 'id'], - 'itemmgmt_material_category' => ['name' => 'itemmgmt_material_category', 'type' => 'int', 'internal' => 'category'], - 'itemmgmt_material_subcategory' => ['name' => 'itemmgmt_material_subcategory', 'type' => 'int', 'internal' => 'subcategory'], - 'itemmgmt_material_type' => ['name' => 'itemmgmt_material_type', 'type' => 'int', 'internal' => 'type'], - 'itemmgmt_material_unit' => ['name' => 'itemmgmt_material_unit', 'type' => 'int', 'internal' => 'unit'], - 'itemmgmt_material_item' => ['name' => 'itemmgmt_material_item', 'type' => 'int', 'internal' => 'item'], + 'itemmgmt_material_id' => ['name' => 'itemmgmt_material_id', 'type' => 'int', 'internal' => 'id'], + 'itemmgmt_material_category' => ['name' => 'itemmgmt_material_category', 'type' => 'int', 'internal' => 'category'], + 'itemmgmt_material_subcategory' => ['name' => 'itemmgmt_material_subcategory', 'type' => 'int', 'internal' => 'subcategory'], + 'itemmgmt_material_type' => ['name' => 'itemmgmt_material_type', 'type' => 'int', 'internal' => 'type'], + 'itemmgmt_material_unit' => ['name' => 'itemmgmt_material_unit', 'type' => 'int', 'internal' => 'unit'], + 'itemmgmt_material_item' => ['name' => 'itemmgmt_material_item', 'type' => 'int', 'internal' => 'item'], ]; /** diff --git a/Models/MaterialSubcategory.php b/Models/MaterialSubcategory.php index eafafd6..317df3d 100644 --- a/Models/MaterialSubcategory.php +++ b/Models/MaterialSubcategory.php @@ -42,5 +42,4 @@ abstract class MaterialSubcategory extends Enum public const AUXILIARY_MATERIAL = 101; public const SUPPLIES = 102; - } diff --git a/Models/MaterialTypeL11nMapper.php b/Models/MaterialTypeL11nMapper.php index 78d3cec..5a891be 100644 --- a/Models/MaterialTypeL11nMapper.php +++ b/Models/MaterialTypeL11nMapper.php @@ -37,10 +37,10 @@ final class MaterialTypeL11nMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'itemmgmt_material_type_l11n_id' => ['name' => 'itemmgmt_material_type_l11n_id', 'type' => 'int', 'internal' => 'id'], - 'itemmgmt_material_type_l11n_title' => ['name' => 'itemmgmt_material_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], - 'itemmgmt_material_type_l11n_type' => ['name' => 'itemmgmt_material_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], - 'itemmgmt_material_type_l11n_language' => ['name' => 'itemmgmt_material_type_l11n_language', 'type' => 'string', 'internal' => 'language'], + 'itemmgmt_material_type_l11n_id' => ['name' => 'itemmgmt_material_type_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'itemmgmt_material_type_l11n_title' => ['name' => 'itemmgmt_material_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'itemmgmt_material_type_l11n_type' => ['name' => 'itemmgmt_material_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], + 'itemmgmt_material_type_l11n_language' => ['name' => 'itemmgmt_material_type_l11n_language', 'type' => 'string', 'internal' => 'language'], ]; /** diff --git a/Models/MaterialTypeMapper.php b/Models/MaterialTypeMapper.php index cf7ccfc..ac426dc 100644 --- a/Models/MaterialTypeMapper.php +++ b/Models/MaterialTypeMapper.php @@ -37,8 +37,8 @@ final class MaterialTypeMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'itemmgmt_material_type_id' => ['name' => 'itemmgmt_material_type_id', 'type' => 'int', 'internal' => 'id'], - 'itemmgmt_material_type_name' => ['name' => 'itemmgmt_material_type_name', 'type' => 'string', 'internal' => 'title', 'autocomplete' => true], + 'itemmgmt_material_type_id' => ['name' => 'itemmgmt_material_type_id', 'type' => 'int', 'internal' => 'id'], + 'itemmgmt_material_type_name' => ['name' => 'itemmgmt_material_type_name', 'type' => 'string', 'internal' => 'title', 'autocomplete' => true], ]; /** @@ -54,7 +54,7 @@ final class MaterialTypeMapper extends DataMapperFactory 'self' => 'itemmgmt_material_type_l11n_type', 'column' => 'content', 'external' => null, - ] + ], ]; /** diff --git a/Models/NullContainer.php b/Models/NullContainer.php new file mode 100644 index 0000000..1e310ea --- /dev/null +++ b/Models/NullContainer.php @@ -0,0 +1,46 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Theme/Backend/Lang/Navigation.de.lang.php b/Theme/Backend/Lang/Navigation.de.lang.php index 3f92b90..fb8bc12 100755 --- a/Theme/Backend/Lang/Navigation.de.lang.php +++ b/Theme/Backend/Lang/Navigation.de.lang.php @@ -23,5 +23,5 @@ return ['Navigation' => [ 'List' => 'Liste', 'Types' => 'Arten', 'Values' => 'Werte', - 'Materials' => 'Materialien', + 'Materials' => 'Materialien', ]]; diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index c821a62..3730d25 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -23,5 +23,5 @@ return ['Navigation' => [ 'List' => 'List', 'Types' => 'Types', 'Values' => 'Values', - 'Materials' => 'Materials', + 'Materials' => 'Materials', ]]; diff --git a/Theme/Backend/Lang/de.lang.php b/Theme/Backend/Lang/de.lang.php index 4b4270f..b1ea51c 100755 --- a/Theme/Backend/Lang/de.lang.php +++ b/Theme/Backend/Lang/de.lang.php @@ -13,150 +13,150 @@ declare(strict_types=1); return ['ItemManagement' => [ - 'Accounting' => 'Buchhaltung', - 'Address' => 'Adresse', - 'Articlegroup' => 'ArtikelGroup.', - 'Attribute' => 'Attribut', - 'AttributeTypes' => 'Attributtypen', - 'Attributes' => 'Attribute', - 'Available' => 'Erhältlich', - 'AvgPrice' => 'Durchschn. Preis', - 'Bills' => 'Rechnungen', - 'Bonus' => 'Bonus', - 'ClientGroup' => 'Client / Gruppe.', - 'ClientSection' => 'Kundensparte', - 'ClientSegment' => 'Kundensegment', - 'ClientType' => 'Kundentyp', - 'Commission' => 'Kommission', - 'Container' => 'Container', - 'CostCenter' => 'Kostenstelle', - 'CostIndicator' => 'Kostenindikator', - 'CostObject' => 'Kostenträger', - 'Countries' => 'Länder', - 'Country' => 'Land', - 'Created' => 'Erstellt', - 'CreatedAt' => 'Erstellt', - 'CustomerGroup' => 'Kundengruppe', - 'CustomsID' => 'Zoll-ID.', - 'Date' => 'Datum', - 'Description' => 'Beschreibung', - 'Discount' => 'Rabatt', - 'DiscountP' => 'Rabatt in%', - 'Disposal' => 'Entsorgung', - 'Documents' => 'Unterlagen', - 'EarningIndicator' => 'Indikator verdienen', - 'End' => 'Ende', - 'Files' => 'Dateien', - 'General' => 'Allgemein', - 'GrossWeight' => 'Bruttogewicht', - 'Group' => 'Gruppe', - 'Groups' => 'Gruppen', - 'Height' => 'Höhe', - 'ID' => 'ID', - 'ILV' => 'ILV', - 'Info' => 'Die Info', - 'Item' => 'Artikel', - 'ItemSection' => 'Artikelsparte', - 'ItemSegment' => 'Artikelsegment', - 'ItemType' => 'Artikeltyp', - 'Items' => 'Produkte', - 'Language' => 'Sprache', - 'LastOrder' => 'Letzte Bestellung', - 'Leadtime' => 'Vorlaufzeit', - 'Length' => 'Länge', - 'Localization' => 'Lokalisierung', - 'Localizations' => 'Lokalisierungen', - 'Location' => 'Ort', - 'Log' => 'Protokoll', - 'Logs' => 'Protokoll', - 'Lot' => 'Viel', - 'MRR' => 'Mrr.', - 'MTDSales' => 'MTD-Verkäufe.', - 'Makespan' => 'Makespan', - 'Margin' => 'Rand', - 'Master' => 'Meister', - 'MaximumLevel' => 'Maximaler Lagerstand', - 'Media' => 'Medien', - 'MinimumLevel' => 'Mindestbestandstufe', - 'Modified' => 'Geändert', - 'Name' => 'Name', - 'Name1' => 'Name1.', - 'Name2' => 'Name2.', - 'Name3' => 'Name3.', - 'Net' => 'Netto', - 'NetWeight' => 'Reingewicht', - 'None' => 'Keiner', - 'Notes' => 'Anmerkungen', - 'Number' => 'Nummer', - 'Ordered' => 'Bestellt', - 'Packaging' => 'Verpackung', - 'Price' => 'Preis', - 'PriceChange' => 'Preisänderung', - 'PriceUnit' => 'Preiseinheit.', - 'Prices' => 'Preise', - 'Pricing' => 'Preise', - 'Procurement' => 'Beschaffung', - 'Productgroup' => 'Produktgruppe', - 'Production' => 'Produktion', - 'Profile' => 'Profil', - 'Properties' => 'Eigenschaften', - 'Property' => 'Eigentum', - 'Purchase' => 'Kaufen', - 'PurchasePrice' => 'Kaufpreis', - 'Purchasing' => 'Einkauf', - 'QA' => 'Qualitätssicherung', - 'QM' => 'Qualitätsmanagement', - 'Quantity' => 'Menge', - 'QuantityUnit' => 'Einheit der Menge.', - 'RecentInvoices' => 'Neuste Rechnungen', - 'ReorderLevel' => 'Neuordnungspegel', - 'Reserved' => 'Reserviert', - 'SN' => 'SN', - 'Sales' => 'Umsatz', - 'SalesPrice' => 'Verkaufspreis', - 'SalesPricing' => 'Verkaufspreise', - 'Segment' => 'Segment', - 'ShelfLife' => 'Haltbarkeit.', - 'Start' => 'Start', - 'Status' => 'Status', - 'Stock' => 'Aktie', - 'StockList' => 'Lagerliste', - 'Successor' => 'Nachfolger', - 'Supplier' => 'Anbieter', - 'Text' => 'Text', - 'TimeUnit' => 'Zeiteinheit', - 'Title' => 'Titel', - 'TopCustomers' => 'Top Kunden', - 'Tracking' => 'Verfolgung', - 'TradingUnit' => 'Handelseinheit', - 'Translation' => 'Übersetzung', - 'Type' => 'Typ', - 'Unit' => 'Einheit', - 'Value' => 'Wert', - 'Volume' => 'Volumen', - 'Warehouse' => 'Lagerhaus', - 'Width' => 'Breite', - 'YTDSales' => 'Ytd Sales', - 'ItemProductGroup' => 'Artikel Produktgruppe', - 'ItemSalesGroup' => 'Artikel Umsatzgruppe', + 'Accounting' => 'Buchhaltung', + 'Address' => 'Adresse', + 'Articlegroup' => 'ArtikelGroup.', + 'Attribute' => 'Attribut', + 'AttributeTypes' => 'Attributtypen', + 'Attributes' => 'Attribute', + 'Available' => 'Erhältlich', + 'AvgPrice' => 'Durchschn. Preis', + 'Bills' => 'Rechnungen', + 'Bonus' => 'Bonus', + 'ClientGroup' => 'Client / Gruppe.', + 'ClientSection' => 'Kundensparte', + 'ClientSegment' => 'Kundensegment', + 'ClientType' => 'Kundentyp', + 'Commission' => 'Kommission', + 'Container' => 'Container', + 'CostCenter' => 'Kostenstelle', + 'CostIndicator' => 'Kostenindikator', + 'CostObject' => 'Kostenträger', + 'Countries' => 'Länder', + 'Country' => 'Land', + 'Created' => 'Erstellt', + 'CreatedAt' => 'Erstellt', + 'CustomerGroup' => 'Kundengruppe', + 'CustomsID' => 'Zoll-ID.', + 'Date' => 'Datum', + 'Description' => 'Beschreibung', + 'Discount' => 'Rabatt', + 'DiscountP' => 'Rabatt in%', + 'Disposal' => 'Entsorgung', + 'Documents' => 'Unterlagen', + 'EarningIndicator' => 'Indikator verdienen', + 'End' => 'Ende', + 'Files' => 'Dateien', + 'General' => 'Allgemein', + 'GrossWeight' => 'Bruttogewicht', + 'Group' => 'Gruppe', + 'Groups' => 'Gruppen', + 'Height' => 'Höhe', + 'ID' => 'ID', + 'ILV' => 'ILV', + 'Info' => 'Die Info', + 'Item' => 'Artikel', + 'ItemSection' => 'Artikelsparte', + 'ItemSegment' => 'Artikelsegment', + 'ItemType' => 'Artikeltyp', + 'Items' => 'Produkte', + 'Language' => 'Sprache', + 'LastOrder' => 'Letzte Bestellung', + 'Leadtime' => 'Vorlaufzeit', + 'Length' => 'Länge', + 'Localization' => 'Lokalisierung', + 'Localizations' => 'Lokalisierungen', + 'Location' => 'Ort', + 'Log' => 'Protokoll', + 'Logs' => 'Protokoll', + 'Lot' => 'Viel', + 'MRR' => 'Mrr.', + 'MTDSales' => 'MTD-Verkäufe.', + 'Makespan' => 'Makespan', + 'Margin' => 'Rand', + 'Master' => 'Meister', + 'MaximumLevel' => 'Maximaler Lagerstand', + 'Media' => 'Medien', + 'MinimumLevel' => 'Mindestbestandstufe', + 'Modified' => 'Geändert', + 'Name' => 'Name', + 'Name1' => 'Name1.', + 'Name2' => 'Name2.', + 'Name3' => 'Name3.', + 'Net' => 'Netto', + 'NetWeight' => 'Reingewicht', + 'None' => 'Keiner', + 'Notes' => 'Anmerkungen', + 'Number' => 'Nummer', + 'Ordered' => 'Bestellt', + 'Packaging' => 'Verpackung', + 'Price' => 'Preis', + 'PriceChange' => 'Preisänderung', + 'PriceUnit' => 'Preiseinheit.', + 'Prices' => 'Preise', + 'Pricing' => 'Preise', + 'Procurement' => 'Beschaffung', + 'Productgroup' => 'Produktgruppe', + 'Production' => 'Produktion', + 'Profile' => 'Profil', + 'Properties' => 'Eigenschaften', + 'Property' => 'Eigentum', + 'Purchase' => 'Kaufen', + 'PurchasePrice' => 'Kaufpreis', + 'Purchasing' => 'Einkauf', + 'QA' => 'Qualitätssicherung', + 'QM' => 'Qualitätsmanagement', + 'Quantity' => 'Menge', + 'QuantityUnit' => 'Einheit der Menge.', + 'RecentInvoices' => 'Neuste Rechnungen', + 'ReorderLevel' => 'Neuordnungspegel', + 'Reserved' => 'Reserviert', + 'SN' => 'SN', + 'Sales' => 'Umsatz', + 'SalesPrice' => 'Verkaufspreis', + 'SalesPricing' => 'Verkaufspreise', + 'Segment' => 'Segment', + 'ShelfLife' => 'Haltbarkeit.', + 'Start' => 'Start', + 'Status' => 'Status', + 'Stock' => 'Aktie', + 'StockList' => 'Lagerliste', + 'Successor' => 'Nachfolger', + 'Supplier' => 'Anbieter', + 'Text' => 'Text', + 'TimeUnit' => 'Zeiteinheit', + 'Title' => 'Titel', + 'TopCustomers' => 'Top Kunden', + 'Tracking' => 'Verfolgung', + 'TradingUnit' => 'Handelseinheit', + 'Translation' => 'Übersetzung', + 'Type' => 'Typ', + 'Unit' => 'Einheit', + 'Value' => 'Wert', + 'Volume' => 'Volumen', + 'Warehouse' => 'Lagerhaus', + 'Width' => 'Breite', + 'YTDSales' => 'Ytd Sales', + 'ItemProductGroup' => 'Artikel Produktgruppe', + 'ItemSalesGroup' => 'Artikel Umsatzgruppe', 'Promocode' => 'Promocode', - 'Region' => 'Region', + 'Region' => 'Region', 'Materials' => 'Materialien', - 'Weight' => 'Gewicht', - 'Depth' => 'Tiefe', - 'WidthLength' => 'Breite/Länge', - 'MaximumOrderInterval' => 'Maximales Bestellintervall', - 'MinimumOrderQuantity' => 'Mindestbestellmenge', - 'PrimarySupplier' => 'Hauptlieferant', - 'LeadTime' => 'Lieferzeit', - 'UnitQuantity' => 'Einheitsmenge', + 'Weight' => 'Gewicht', + 'Depth' => 'Tiefe', + 'WidthLength' => 'Breite/Länge', + 'MaximumOrderInterval' => 'Maximales Bestellintervall', + 'MinimumOrderQuantity' => 'Mindestbestellmenge', + 'PrimarySupplier' => 'Hauptlieferant', + 'LeadTime' => 'Lieferzeit', + 'UnitQuantity' => 'Einheitsmenge', 'UnitPrice' => 'Einheitspreis', - 'Lieferanten' => 'Lieferanten', - 'CostCenter' => 'Kostenstelle', - 'CostObject' => 'Kostenträger', - 'DefaultStock' => 'Standard Lager', - 'DefaultStockLocation' => 'Standard Lagerplatz', + 'Lieferanten' => 'Lieferanten', + 'CostCenter' => 'Kostenstelle', + 'CostObject' => 'Kostenträger', + 'DefaultStock' => 'Standard Lager', + 'DefaultStockLocation' => 'Standard Lagerplatz', 'Inventory' => 'Bestandsführung', - 'Identifier' => 'Identifizierung', - 'Stocktaking' => 'Inventur', + 'Identifier' => 'Identifizierung', + 'Stocktaking' => 'Inventur', ]]; diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index b12c519..fef1626 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -13,150 +13,150 @@ declare(strict_types=1); return ['ItemManagement' => [ - 'Accounting' => 'Accounting', - 'Address' => 'Address', - 'Articlegroup' => 'Articlegroup', - 'Attribute' => 'Attribute', - 'AttributeTypes' => 'Attribute types', - 'Attributes' => 'Attributes', - 'Available' => 'Available', - 'AvgPrice' => 'Avg. Price', - 'Bills' => 'Bills', - 'Bonus' => 'Bonus', - 'ClientGroup' => 'Client Group', - 'ClientSection' => 'Client Section', - 'ClientSegment' => 'Client Segment', - 'ClientType' => 'Client Type', - 'Commission' => 'Commission', - 'Container' => 'Container', - 'CostCenter' => 'CostCenter', - 'CostIndicator' => 'Cost Indicator', - 'CostObject' => 'CostObject', - 'Countries' => 'Countries', - 'Country' => 'Country', - 'Created' => 'Created', - 'CreatedAt' => 'Created', - 'CustomerGroup' => 'Customer Group', - 'CustomsID' => 'Customs ID', - 'Date' => 'Date', - 'Description' => 'Description', - 'Discount' => 'Discount', - 'DiscountP' => 'Discount in %', - 'Disposal' => 'Disposal', - 'Documents' => 'Documents', - 'EarningIndicator' => 'Earning Indicator', - 'End' => 'End', - 'Files' => 'Files', - 'General' => 'General', - 'GrossWeight' => 'Gross Weight', - 'Group' => 'Group', - 'Groups' => 'Groups', - 'Height' => 'Height', - 'ID' => 'ID', - 'ILV' => 'ILV', - 'Info' => 'Info', - 'Item' => 'Item', - 'ItemSection' => 'Item Section', - 'ItemSegment' => 'Item Segment', - 'ItemType' => 'Item Type', - 'Items' => 'Items', - 'Language' => 'Language', - 'LastOrder' => 'Last Order', - 'Leadtime' => 'Lead time', - 'Length' => 'Length', - 'Localization' => 'Localization', - 'Localizations' => 'Localizations', - 'Location' => 'Location', - 'Log' => 'Log', - 'Logs' => 'Logs', - 'Lot' => 'Lot', - 'MRR' => 'MRR', - 'MTDSales' => 'MTD Sales', - 'Makespan' => 'Makespan', - 'Margin' => 'Margin', - 'Master' => 'Master', - 'MaximumLevel' => 'Maximum stock level', - 'Media' => 'Media', - 'MinimumLevel' => 'Minimum stock level', - 'Modified' => 'Modified', - 'Name' => 'Name', - 'Name1' => 'Name1', - 'Name2' => 'Name2', - 'Name3' => 'Name3', - 'Net' => 'Net', - 'NetWeight' => 'Net Weight', - 'None' => 'None', - 'Notes' => 'Notes', - 'Number' => 'Number', - 'Ordered' => 'Ordered', - 'Packaging' => 'Packaging', - 'Price' => 'Price', - 'PriceChange' => 'Price Change', - 'PriceUnit' => 'Unit of price', - 'Prices' => 'Prices', - 'Pricing' => 'Pricing', - 'Procurement' => 'Procurement', - 'Productgroup' => 'Productgroup', - 'Production' => 'Production', - 'Profile' => 'Profile', - 'Properties' => 'Properties', - 'Property' => 'Property', - 'Purchase' => 'Purchase', - 'PurchasePrice' => 'Purchase Price', - 'Purchasing' => 'Purchasing', - 'QA' => 'QA', - 'QM' => 'QM', - 'Quantity' => 'Quantity', - 'QuantityUnit' => 'Unit of quantity', - 'RecentInvoices' => 'Recent invoices', - 'ReorderLevel' => 'Reorder level', - 'Reserved' => 'Reserved', - 'SN' => 'SN', - 'Sales' => 'Sales', - 'SalesPrice' => 'Sales Price', - 'SalesPricing' => 'Sales Pricing', - 'Segment' => 'Segment', - 'ShelfLife' => 'Shelf life', - 'Start' => 'Start', - 'Status' => 'Status', - 'Stock' => 'Stock', - 'StockList' => 'Stock list', - 'Successor' => 'Successor', - 'Supplier' => 'Supplier', - 'Text' => 'Text', - 'TimeUnit' => 'Unit of time', - 'Title' => 'Title', - 'TopCustomers' => 'Top Customers', - 'Tracking' => 'Tracking', - 'TradingUnit' => 'Trading Unit', - 'Translation' => 'Translation', - 'Type' => 'Type', - 'Unit' => 'Unit', - 'Value' => 'Value', - 'Volume' => 'Volume', - 'Warehouse' => 'Warehouse', - 'Width' => 'Width', - 'YTDSales' => 'YTD Sales', - 'ItemProductGroup' => 'Item Product Group', - 'ItemSalesGroup' => 'Item Sales Group', + 'Accounting' => 'Accounting', + 'Address' => 'Address', + 'Articlegroup' => 'Articlegroup', + 'Attribute' => 'Attribute', + 'AttributeTypes' => 'Attribute types', + 'Attributes' => 'Attributes', + 'Available' => 'Available', + 'AvgPrice' => 'Avg. Price', + 'Bills' => 'Bills', + 'Bonus' => 'Bonus', + 'ClientGroup' => 'Client Group', + 'ClientSection' => 'Client Section', + 'ClientSegment' => 'Client Segment', + 'ClientType' => 'Client Type', + 'Commission' => 'Commission', + 'Container' => 'Container', + 'CostCenter' => 'CostCenter', + 'CostIndicator' => 'Cost Indicator', + 'CostObject' => 'CostObject', + 'Countries' => 'Countries', + 'Country' => 'Country', + 'Created' => 'Created', + 'CreatedAt' => 'Created', + 'CustomerGroup' => 'Customer Group', + 'CustomsID' => 'Customs ID', + 'Date' => 'Date', + 'Description' => 'Description', + 'Discount' => 'Discount', + 'DiscountP' => 'Discount in %', + 'Disposal' => 'Disposal', + 'Documents' => 'Documents', + 'EarningIndicator' => 'Earning Indicator', + 'End' => 'End', + 'Files' => 'Files', + 'General' => 'General', + 'GrossWeight' => 'Gross Weight', + 'Group' => 'Group', + 'Groups' => 'Groups', + 'Height' => 'Height', + 'ID' => 'ID', + 'ILV' => 'ILV', + 'Info' => 'Info', + 'Item' => 'Item', + 'ItemSection' => 'Item Section', + 'ItemSegment' => 'Item Segment', + 'ItemType' => 'Item Type', + 'Items' => 'Items', + 'Language' => 'Language', + 'LastOrder' => 'Last Order', + 'Leadtime' => 'Lead time', + 'Length' => 'Length', + 'Localization' => 'Localization', + 'Localizations' => 'Localizations', + 'Location' => 'Location', + 'Log' => 'Log', + 'Logs' => 'Logs', + 'Lot' => 'Lot', + 'MRR' => 'MRR', + 'MTDSales' => 'MTD Sales', + 'Makespan' => 'Makespan', + 'Margin' => 'Margin', + 'Master' => 'Master', + 'MaximumLevel' => 'Maximum stock level', + 'Media' => 'Media', + 'MinimumLevel' => 'Minimum stock level', + 'Modified' => 'Modified', + 'Name' => 'Name', + 'Name1' => 'Name1', + 'Name2' => 'Name2', + 'Name3' => 'Name3', + 'Net' => 'Net', + 'NetWeight' => 'Net Weight', + 'None' => 'None', + 'Notes' => 'Notes', + 'Number' => 'Number', + 'Ordered' => 'Ordered', + 'Packaging' => 'Packaging', + 'Price' => 'Price', + 'PriceChange' => 'Price Change', + 'PriceUnit' => 'Unit of price', + 'Prices' => 'Prices', + 'Pricing' => 'Pricing', + 'Procurement' => 'Procurement', + 'Productgroup' => 'Productgroup', + 'Production' => 'Production', + 'Profile' => 'Profile', + 'Properties' => 'Properties', + 'Property' => 'Property', + 'Purchase' => 'Purchase', + 'PurchasePrice' => 'Purchase Price', + 'Purchasing' => 'Purchasing', + 'QA' => 'QA', + 'QM' => 'QM', + 'Quantity' => 'Quantity', + 'QuantityUnit' => 'Unit of quantity', + 'RecentInvoices' => 'Recent invoices', + 'ReorderLevel' => 'Reorder level', + 'Reserved' => 'Reserved', + 'SN' => 'SN', + 'Sales' => 'Sales', + 'SalesPrice' => 'Sales Price', + 'SalesPricing' => 'Sales Pricing', + 'Segment' => 'Segment', + 'ShelfLife' => 'Shelf life', + 'Start' => 'Start', + 'Status' => 'Status', + 'Stock' => 'Stock', + 'StockList' => 'Stock list', + 'Successor' => 'Successor', + 'Supplier' => 'Supplier', + 'Text' => 'Text', + 'TimeUnit' => 'Unit of time', + 'Title' => 'Title', + 'TopCustomers' => 'Top Customers', + 'Tracking' => 'Tracking', + 'TradingUnit' => 'Trading Unit', + 'Translation' => 'Translation', + 'Type' => 'Type', + 'Unit' => 'Unit', + 'Value' => 'Value', + 'Volume' => 'Volume', + 'Warehouse' => 'Warehouse', + 'Width' => 'Width', + 'YTDSales' => 'YTD Sales', + 'ItemProductGroup' => 'Item Product Group', + 'ItemSalesGroup' => 'Item Sales Group', 'Promocode' => 'Promocode', - 'Region' => 'Region', + 'Region' => 'Region', 'Materials' => 'Materials', - 'Weight' => 'Weight', - 'Depth' => 'Depth', - 'WidthLength' => 'Width/Length', - 'MaximumOrderInterval' => 'Maximum Order Interval', - 'MinimumOrderQuantity' => 'Minimum Order Quantity', - 'PrimarySupplier' => 'Primary Supplier', - 'LeadTime' => 'Lead Time', - 'UnitQuantity' => 'Unit Quantity', + 'Weight' => 'Weight', + 'Depth' => 'Depth', + 'WidthLength' => 'Width/Length', + 'MaximumOrderInterval' => 'Maximum Order Interval', + 'MinimumOrderQuantity' => 'Minimum Order Quantity', + 'PrimarySupplier' => 'Primary Supplier', + 'LeadTime' => 'Lead Time', + 'UnitQuantity' => 'Unit Quantity', 'UnitPrice' => 'Unit Price', 'Suppliers' => 'Suppliers', - 'CostCenter' => 'Cost Center', - 'CostObject' => 'Cost Object', - 'DefaultStock' => 'Default stock', - 'DefaultStockLocation' => 'Default stock location', + 'CostCenter' => 'Cost Center', + 'CostObject' => 'Cost Object', + 'DefaultStock' => 'Default stock', + 'DefaultStockLocation' => 'Default stock location', 'Inventory' => 'Inventory', - 'Identifier' => 'Identifier', - 'Stocktaking' => 'Stocktaking', + 'Identifier' => 'Identifier', + 'Stocktaking' => 'Stocktaking', ]]; diff --git a/Theme/Backend/attribute-type.tpl.php b/Theme/Backend/attribute-type.tpl.php index 5f8fec5..59c9afc 100755 --- a/Theme/Backend/attribute-type.tpl.php +++ b/Theme/Backend/attribute-type.tpl.php @@ -86,7 +86,7 @@ echo $this->data['nav']->render(); ?> close settings - getLanguage())); ?> + language)); ?> content; ?> diff --git a/Theme/Backend/item-list.tpl.php b/Theme/Backend/item-list.tpl.php index e21b607..19241d3 100755 --- a/Theme/Backend/item-list.tpl.php +++ b/Theme/Backend/item-list.tpl.php @@ -12,6 +12,8 @@ */ declare(strict_types=1); +use Modules\ItemManagement\Models\StockIdentifierType; +use phpOMS\Stdlib\Base\FloatInt; use phpOMS\Uri\UriFactory; /** @var \phpOMS\Views\View $this */ @@ -128,7 +130,7 @@ echo $this->data['nav']->render(); ?> $value) : ++$count; - $url = UriFactory::build('{/base}/item/profile?{?}&id=' . $value->id); + $url = UriFactory::build('{/base}/item/view?{?}&id=' . $value->id); $image = $value->getFileByTypeName('item_profile_image'); ?> @@ -140,10 +142,37 @@ echo $this->data['nav']->render(); ?> printHtml($value->getL11n('name1')->content); ?> printHtml($value->getL11n('name2')->content); ?> printHtml($value->getL11n('name3')->content); ?> - getCurrency($value->salesPrice); ?> - - - + getCurrency($value->salesPrice, symbol: ''); ?> + stockIdentifier === StockIdentifierType::NONE) : ?> + + + + + + data['dists'][$value->id] ?? [] as $dist) { + $sum += $dist->quantity; + } + $total = new FloatInt($sum); + + echo $total->getAmount(\reset($value->container)->quantityDecimals); + ?> + + + data['reserved'][$value->id] ?? 0); + + echo $total->getAmount(\reset($value->container)->quantityDecimals); + ?> + + + data['ordered'][$value->id] ?? 0); + + echo $total->getAmount(\reset($value->container)->quantityDecimals); + ?> + getHtml('Empty', '0', '0'); ?> diff --git a/Theme/Backend/item-profile.tpl.php b/Theme/Backend/item-view.tpl.php old mode 100755 new mode 100644 similarity index 92% rename from Theme/Backend/item-profile.tpl.php rename to Theme/Backend/item-view.tpl.php index 31680ed..42f395a --- a/Theme/Backend/item-profile.tpl.php +++ b/Theme/Backend/item-view.tpl.php @@ -24,7 +24,6 @@ use phpOMS\Localization\ISO3166NameEnum; use phpOMS\Localization\ISO4217CharEnum; use phpOMS\Localization\ISO639Enum; use phpOMS\Localization\Money; -use phpOMS\Localization\NullLocalization; use phpOMS\Localization\RegionEnum; use phpOMS\Message\Http\HttpHeader; use phpOMS\Stdlib\Base\SmartDateTime; @@ -37,18 +36,15 @@ $notes = $item->notes; $files = $item->files; $itemImage = $this->getData('itemImage') ?? new NullMedia(); -$allInvoices = $this->data['allInvoices'] ?? []; -$topCustomers = $this->getData('topCustomers') ?? [[], []]; -$attributeView = $this->data['attributeView']; -$l11nView = $this->data['l11nView']; +$allInvoices = $this->data['allInvoices'] ?? []; +$topCustomers = $this->getData('topCustomers') ?? [[], []]; +$attributeView = $this->data['attributeView']; +$l11nView = $this->data['l11nView']; $languages = ISO639Enum::getConstants(); -/** @var \phpOMS\Localization\Localization $l11n */ -$l11n = $this->getData('default_localization') ?? new NullLocalization(); - -$regions = RegionEnum::getConstants(); -$countries = ISO3166CharEnum::getConstants(); +$regions = RegionEnum::getConstants(); +$countries = ISO3166CharEnum::getConstants(); $currencies = ISO4217CharEnum::getConstants(); echo $this->data['nav']->render(); @@ -94,7 +90,7 @@ echo $this->data['nav']->render();
- id); - ?> + id); + ?>
-
+
@@ -133,11 +129,11 @@ echo $this->data['nav']->render();
getHtml('YTDSales'); ?>: - getCurrency(SalesBillMapper::getItemNetSales($item->id, SmartDateTime::startOfYear($this->data['business_start']), new \DateTime('now')), format: 'medium'); ?> + getCurrency(SalesBillMapper::getItemNetSales($item->id, SmartDateTime::startOfYear($this->data['business_start']), new \DateTime('now')), symbol: '', format: 'medium'); ?>
getHtml('MTDSales'); ?>: - getCurrency(SalesBillMapper::getItemNetSales($item->id, SmartDateTime::startOfMonth(), new \DateTime('now')), format: 'medium'); ?> + getCurrency(SalesBillMapper::getItemNetSales($item->id, SmartDateTime::startOfMonth(), new \DateTime('now')), symbol: '', format: 'medium'); ?>
getHtml('ILV'); ?>: - getCurrency(SalesBillMapper::getILVHistoric($item->id), format: 'medium'); ?> + getCurrency(SalesBillMapper::getILVHistoric($item->id), symbol: '', format: 'medium'); ?>
@@ -163,9 +159,9 @@ echo $this->data['nav']->render();
- id); - ?> + id); + ?>
getHtml('SalesPrice'); ?>: - getCurrency($item->salesPrice, format: 'medium'); ?> + getCurrency($item->salesPrice, symbol: '', format: 'medium'); ?>
getHtml('PurchasePrice'); ?>: - getCurrency($item->purchasePrice, format: 'medium'); ?> + getCurrency($item->purchasePrice, symbol: '', format: 'medium'); ?>
getHtml('Margin'); ?>: getNumeric( $item->salesPrice->getInt() === 0 @@ -193,13 +189,19 @@ echo $this->data['nav']->render(); getHtml('Title'); ?> getHtml('CreatedAt'); ?>
printHtml($note->title); ?> printHtml($note->createdAt->format('Y-m-d')); ?> + +
getHtml('Empty', '0', '0'); ?> +
@@ -219,14 +221,20 @@ echo $this->data['nav']->render();
getHtml('CreatedAt'); ?>
printHtml($file->name); ?> printHtml($file->extension); ?> printHtml($file->createdAt->format('Y-m-d')); ?> + +
getHtml('Empty', '0', '0'); ?> +
@@ -258,17 +266,23 @@ echo $this->data['nav']->render(); ->limit(5) ->execute(); + $count = 0; + /** @var \Modules\Billing\Models\Bill $invoice */ foreach ($newestInvoices as $invoice) : + ++$count; $url = UriFactory::build('{/base}/sales/bill?{?}&id=' . $invoice->id); ?> printHtml($invoice->getNumber()); ?> printHtml($invoice->type->getL11n()); ?> - printHtml($invoice->billTo); ?> - getCurrency($invoice->netSales); ?> + printHtml($invoice->billTo); ?> + getCurrency($invoice->netSales, symbol: ''); ?> printHtml($invoice->createdAt->format('Y-m-d')); ?> + + getHtml('Empty', '0', '0'); ?> + @@ -293,12 +307,12 @@ echo $this->data['nav']->render(); getHtml('Net'); ?> id); + $url = UriFactory::build('{/base}/sales/client/view?id=' . $client->id); ?> printHtml($client->number); ?> printHtml($client->account->name1); ?> printHtml($client->account->name2); ?> - printHtml($client->mainAddress->getCountry()); ?> + printHtml($client->mainAddress->country); ?> getCurrency(); ?> @@ -333,7 +347,7 @@ echo $this->data['nav']->render(); @@ -394,9 +408,7 @@ echo $this->data['nav']->render(); - -
@@ -585,6 +597,7 @@ echo $this->data['nav']->render(); getHtml('ID', '0', '0'); ?>expand_lessexpand_more getHtml('Name'); ?>expand_lessexpand_more getHtml('Quantity'); ?> + getHtml('Decimals'); ?> getHtml('Weight'); ?> getHtml('WidthLength'); ?> getHtml('Height'); ?> @@ -604,6 +617,7 @@ echo $this->data['nav']->render(); + @@ -612,14 +626,14 @@ echo $this->data['nav']->render(); data['containers'] ?? []; foreach ($containers as $key => $value) : ++$c; ?> settings - name !== 'base') : ?> + name !== 'default') : ?> @@ -630,6 +644,7 @@ echo $this->data['nav']->render(); id; ?> printHtml($value->name); ?> printHtml($value->promocode); ?> + printHtml($value->promocode); ?> printHtml($value->price->getAmount()); ?> printHtml($value->currency); ?> printHtml((string) $value->quantity); ?> @@ -682,7 +697,7 @@ echo $this->data['nav']->render();
@@ -947,14 +962,17 @@ echo $this->data['nav']->render(); data['prices']; - foreach ($prices as $key => $value) : ++$c; + $c = 0; + foreach ($this->data['prices'] as $key => $value) : + if ($value->type !== PriceType::SALES) { + continue; + } + ++$c; ?> settings - name !== 'base') : ?> + name !== 'default') : ?> @@ -965,12 +983,12 @@ echo $this->data['nav']->render(); id; ?> printHtml($value->name); ?> printHtml($value->promocode); ?> - printHtml($value->price->getAmount()); ?> + printHtml($value->priceNew->getAmount()); ?> printHtml($value->currency); ?> - printHtml((string) $value->quantity); ?> - printHtml((string) $value->discount); ?> - printHtml((string) $value->discountPercentage); ?> - printHtml((string) $value->bonus); ?> + quantity->getAmount(); ?> + discount->getAmount(); ?> + getPercentage($value->discountPercentage->value / 10000 / 100); ?> + bonus->getAmount(); ?> printHtml((string) $value->itemsegment->getL11n()); ?> printHtml((string) $value->itemsection->getL11n()); ?> printHtml((string) $value->itemsalesgroup->getL11n()); ?> @@ -1084,7 +1102,7 @@ echo $this->data['nav']->render();
@@ -1196,47 +1214,40 @@ echo $this->data['nav']->render(); data['purchase_prices']; - foreach ($prices as $key => $value) : ++$c; + $c = 0; + foreach ($this->data['prices'] as $key => $value) : + if ($value->type !== PriceType::PURCHASE) { + continue; + } + ++$c; ?> - - - settings - name !== 'base') : ?> - - - - - - - - id; ?> - printHtml($value->name); ?> - printHtml($value->promocode); ?> - printHtml($value->price->getAmount()); ?> - printHtml($value->currency); ?> - printHtml((string) $value->quantity); ?> - printHtml((string) $value->discount); ?> - printHtml((string) $value->discountPercentage); ?> - printHtml((string) $value->bonus); ?> - printHtml((string) $value->itemsegment->getL11n()); ?> - printHtml((string) $value->itemsection->getL11n()); ?> - printHtml((string) $value->itemsalesgroup->getL11n()); ?> - printHtml((string) $value->itemproductgroup->getL11n()); ?> - printHtml((string) $value->itemtype->getL11n()); ?> - printHtml((string) $value->clientsegment->getL11n()); ?> - printHtml((string) $value->clientsection->getL11n()); ?> - printHtml((string) $value->clientgroup->getL11n()); ?> - printHtml((string) $value->clienttype->getL11n()); ?> - printHtml((string) $value->clientcountry); ?> - start?->format('Y-m-d'); ?> - end?->format('Y-m-d'); ?> - - - - getHtml('Empty', '0', '0'); ?> - + + + settings + name !== 'default') : ?> + + + + + + + + id; ?> + printHtml($value->name); ?> + printHtml($value->supplier->number); ?> + priceNew->getAmount(); ?> + printHtml($value->currency); ?> + quantity->getAmount(); ?> + discount->getAmount(); ?> + getPercentage($value->discountPercentage->value / 10000 / 100); ?> + bonus->getAmount(); ?> + start?->format('Y-m-d'); ?> + end?->format('Y-m-d'); ?> + + + + getHtml('Empty', '0', '0'); ?> +
@@ -1263,7 +1274,7 @@ echo $this->data['nav']->render(); data['defaultAttributeTypes']['sales_tax_code'] ?? null; foreach ($attr?->defaults ?? [] as $value) : ?> -