diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index 9ce1a86..9bc633d 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -19,7 +19,7 @@ "type": 2, "subtype": 1, "name": "Attributes", - "uri": "{/lang}/{/app}/item/attribute/type?{?}", + "uri": "{/lang}/{/app}/item/attribute/type/list?{?}", "target": "self", "icon": null, "order": 15, @@ -33,7 +33,7 @@ "type": 3, "subtype": 1, "name": "Types", - "uri": "{/lang}/{/app}/item/attribute/type?{?}", + "uri": "{/lang}/{/app}/item/attribute/type/list?{?}", "target": "self", "icon": null, "order": 15, @@ -48,7 +48,7 @@ "type": 3, "subtype": 1, "name": "Values", - "uri": "{/lang}/{/app}/item/attribute/value?{?}", + "uri": "{/lang}/{/app}/item/attribute/value/list?{?}", "target": "self", "icon": null, "order": 15, diff --git a/Admin/Install/attributes.json b/Admin/Install/attributes.json index 232cd99..ec9331a 100755 --- a/Admin/Install/attributes.json +++ b/Admin/Install/attributes.json @@ -1,28 +1,8 @@ [ - { - "name": "featured", - "l11n": { - "en": "Featured", - "de": "Featured" - }, - "value_type": 1, - "is_custom_allowed": false, - "validation_pattern": "", - "is_required": false, - "default_value": "", - "values": [ - { - "value": 0 - }, - { - "value": 1 - } - ] - }, { "name": "shop", "l11n": { - "en": "Shop Item", + "en": "Shop item", "de": "Shop Artikel" }, "value_type": 1, @@ -40,10 +20,30 @@ ] }, { - "name": "front", + "name": "shop_featured", "l11n": { - "en": "Frontpage", - "de": "Frontpage" + "en": "Shop featured", + "de": "Shop featured" + }, + "value_type": 1, + "is_custom_allowed": false, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [ + { + "value": 0 + }, + { + "value": 1 + } + ] + }, + { + "name": "shop_front", + "l11n": { + "en": "Shop frontpage", + "de": "Shop frontpage" }, "value_type": 1, "is_custom_allowed": false, @@ -144,7 +144,41 @@ ] }, { - "name": "hc-code", + "name": "bill_fees", + "description": "Used for defining special fees such as freight, insurance etc. which can be made accessible in a separate area in the bill", + "l11n": { + "en": "Bill fees", + "de": "Sonderkosten" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [ + { + "value": 0 + }, + { + "value": 1 + } + ] + }, + { + "name": "upc", + "l11n": { + "en": "UPC", + "de": "UPC" + }, + "value_type": 1, + "is_custom_allowed": false, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "hc_code", "l11n": { "en": "HC-code", "de": "Zolltarifnummer" @@ -156,6 +190,19 @@ "default_value": "", "values": [] }, + { + "name": "hazmat", + "l11n": { + "en": "Hazmat", + "de": "Gefahrgut" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, { "name": "color", "l11n": { @@ -354,5 +401,31 @@ "is_default": true } ] + }, + { + "name": "minimum_order", + "l11n": { + "en": "MOQ", + "de": "Mindestbestellmenge" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "dual_use", + "l11n": { + "en": "Dual use", + "de": "Dual use" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] } ] \ No newline at end of file diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 863e5cd..87fcf51 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -51,8 +51,8 @@ "type": "INT", "default": null, "null": true, - "foreignTable": "organization_unit", - "foreignKey": "organization_unit_id" + "foreignTable": "unit", + "foreignKey": "unit_id" } } }, @@ -288,6 +288,22 @@ "name": "itemmgmt_attr_value_unit", "type": "VARCHAR(255)", "null": false + }, + "itemmgmt_attr_value_deptype": { + "name": "itemmgmt_attr_value_deptype", + "type": "INT(11)", + "null": true, + "default": null, + "foreignTable": "itemmgmt_attr_type", + "foreignKey": "itemmgmt_attr_type_id" + }, + "itemmgmt_attr_value_depvalue": { + "name": "itemmgmt_attr_value_depvalue", + "type": "INT(11)", + "null": true, + "default": null, + "foreignTable": "itemmgmt_attr_value", + "foreignKey": "itemmgmt_attr_value_id" } } }, diff --git a/Admin/Install/items.json b/Admin/Install/items.json new file mode 100644 index 0000000..0ca5f7a --- /dev/null +++ b/Admin/Install/items.json @@ -0,0 +1,42 @@ +[ + { + "number": "1", + "l11ns": { + "name1": { + "en": "Freight", + "de": "Freight" + }, + "description_short": {} + }, + "primary_image": "", + "keywords": {}, + "attributes": [ + { + "type": "bill_fees", + "value": 1, + "custom": false + } + ], + "variants": [] + }, + { + "number": "2", + "l11ns": { + "name1": { + "en": "Insurance", + "de": "Insurance" + }, + "description_short": {} + }, + "primary_image": "", + "keywords": {}, + "attributes": [ + { + "type": "bill_fees", + "value": 1, + "custom": false + } + ], + "variants": [] + } +] \ No newline at end of file diff --git a/Admin/Install/localizations.json b/Admin/Install/localizations.json index b88f1d4..f2cec38 100755 --- a/Admin/Install/localizations.json +++ b/Admin/Install/localizations.json @@ -18,5 +18,13 @@ { "name": "description_long", "is_required": false + }, + { + "name": "shop_name1", + "is_required": true + }, + { + "name": "shop_name2", + "is_required": false } ] \ No newline at end of file diff --git a/Admin/Installer.php b/Admin/Installer.php index 0e79d76..bd859c8 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -14,6 +14,8 @@ declare(strict_types=1); namespace Modules\ItemManagement\Admin; +use Modules\ItemManagement\Models\ItemAttributeTypeMapper; +use Modules\ItemManagement\Models\ItemL11nTypeMapper; use phpOMS\Application\ApplicationAbstract; use phpOMS\Config\SettingsInterface; use phpOMS\Message\Http\HttpRequest; @@ -74,6 +76,112 @@ final class Installer extends InstallerAbstract $relations = \json_decode($fileContent, true); $l11nTypes = self::createItemRelationTypes($app, $relations); + + /* Items */ + $fileContent = \file_get_contents(__DIR__ . '/Install/items.json'); + if ($fileContent === false) { + return; + } + + $items = \json_decode($fileContent, true); + $itemArray = self::createItems($app, $items); + } + + /** + * Install default l11n types + * + * @param ApplicationAbstract $app Application + * @param array $items Attribute definition + * + * @return array + * + * @since 1.0.0 + */ + private static function createItems(ApplicationAbstract $app, array $items) : array + { + $itemArray = []; + + /** @var \Modules\ItemManagement\Controller\ApiController $module */ + $module = $app->moduleManager->getModuleInstance('ItemManagement'); + + $attributeTypes = ItemAttributeTypeMapper::getAll()->with('defaults')->execute(); + $l11nTypes = ItemL11nTypeMapper::getAll()->execute(); + + // Change indexing for easier search later on. + foreach ($attributeTypes as $e) { + $attributeTypes[$e->name] = $e; + } + + foreach ($l11nTypes as $e) { + $l11nTypes[$e->title] = $e; + } + + foreach ($items as $item) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('number', (string) $item['number']); + + $module->apiItemCreate($request, $response); + $itemId = $response->get('')['response']->getId(); + + $itemArray[] = !\is_array($response['response']) + ? $response['response']->toArray() + : $response['response']; + + foreach ($item['l11ns'] as $name => $l11ns) { + $l11nType = $l11nTypes[$name]; + + foreach ($l11ns as $language => $l11n) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('item', $itemId); + $request->setData('type', $l11nType->getId()); + $request->setData('language', (string) $language); + $request->setData('description', (string) $l11n); + + $module->apiItemL11nCreate($request, $response); + } + } + + foreach ($item['attributes'] as $attribute) { + $attrType = $attributeTypes[$attribute['type']]; + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('item', $itemId); + $request->setData('type', $attrType->getId()); + + if ($attribute['custom'] ?? true) { + $request->setData('custom', $attribute['value']); + } else { + $request->setData('value', self::findAttributeIdByValue($attrType->getDefaults(), $attribute['value'])); + } + + $module->apiItemAttributeCreate($request, $response); + } + } + + return $itemArray; + } + + private static function findAttributeIdByValue(array $defaultValues, mixed $value) + { + foreach ($defaultValues as $val) { + if ($val->valueStr === $value + || $val->valueInt === $value + || $val->valueDec === $value + ) { + return $val->getId(); + } + } + + return 0; } /** diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index b420dcd..a3b41f1 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -18,9 +18,20 @@ use phpOMS\Account\PermissionType; use phpOMS\Router\RouteVerb; return [ - '^.*/item/attribute/type.*$' => [ + '^.*/item/attribute/type/list.*$' => [ [ - 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementAttributeTypes', + 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementAttributeTypeList', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::ATTRIBUTE, + ], + ], + ], + '^.*/item/attribute/type\?.*$' => [ + [ + 'dest' => '\Modules\ItemManagement\Controller\BackendController:viewItemManagementAttributeType', 'verb' => RouteVerb::GET, 'permission' => [ 'module' => BackendController::NAME, diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 69f598f..2b27ab3 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -55,7 +55,7 @@ final class BackendController extends Controller * @since 1.0.0 * @codeCoverageIgnore */ - public function viewItemManagementAttributeTypes(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + public function viewItemManagementAttributeTypeList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/attribute-type-list'); diff --git a/Models/AttributeValueType.php b/Models/AttributeValueType.php index dae8f24..20d0f1f 100755 --- a/Models/AttributeValueType.php +++ b/Models/AttributeValueType.php @@ -33,4 +33,8 @@ abstract class AttributeValueType extends Enum public const _FLOAT = 3; public const _DATETIME = 4; + + public const _BOOL = 5; + + public const _FLOAT_INT = 6; } diff --git a/Models/ItemAttributeTypeMapper.php b/Models/ItemAttributeTypeMapper.php index 3ed099c..3a2fc9d 100755 --- a/Models/ItemAttributeTypeMapper.php +++ b/Models/ItemAttributeTypeMapper.php @@ -53,7 +53,7 @@ final class ItemAttributeTypeMapper extends DataMapperFactory 'mapper' => ItemAttributeTypeL11nMapper::class, 'table' => 'itemmgmt_attr_type_l11n', 'self' => 'itemmgmt_attr_type_l11n_type', - 'column' => 'title', + 'column' => 'content', 'external' => null, ], 'defaults' => [ diff --git a/Models/ItemAttributeValue.php b/Models/ItemAttributeValue.php index c5ace47..e39f382 100755 --- a/Models/ItemAttributeValue.php +++ b/Models/ItemAttributeValue.php @@ -37,6 +37,22 @@ class ItemAttributeValue implements \JsonSerializable */ protected int $id = 0; + /** + * Depending attribute type + * + * @var null|int + * @since 1.0.0 + */ + public ?int $dependingAttributeType = null; + + /** + * Depending attribute value + * + * @var null|int + * @since 1.0.0 + */ + public ?int $dependingAttributeValue = null; + /** * Int value * @@ -154,7 +170,10 @@ class ItemAttributeValue implements \JsonSerializable { if ($datatype === AttributeValueType::_STRING) { $this->valueStr = (string) $value; - } elseif ($datatype === AttributeValueType::_INT) { + } elseif ($datatype === AttributeValueType::_INT + || $datatype === AttributeValueType::_FLOAT_INT + || $datatype === AttributeValueType::_BOOL + ) { $this->valueInt = (int) $value; } elseif ($datatype === AttributeValueType::_FLOAT) { $this->valueDec = (float) $value; diff --git a/Models/ItemAttributeValueMapper.php b/Models/ItemAttributeValueMapper.php index de5b3ac..f03fc9e 100755 --- a/Models/ItemAttributeValueMapper.php +++ b/Models/ItemAttributeValueMapper.php @@ -40,6 +40,8 @@ final class ItemAttributeValueMapper extends DataMapperFactory '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/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index 5bfa313..3e35be0 100755 --- a/tests/Controller/ApiControllerTest.php +++ b/tests/Controller/ApiControllerTest.php @@ -55,7 +55,7 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase }; $this->app->dbPool = $GLOBALS['dbpool']; - $this->app->orgId = 1; + $this->app->unitId = 1; $this->app->accountManager = new AccountManager($GLOBALS['session']); $this->app->appSettings = new CoreSettings(); $this->app->moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../../Modules/');