diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index e16cf57..48208eb 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -47,6 +47,52 @@ }, { "id": 1003203001, + "pid": "/", + "type": 2, + "subtype": 1, + "name": "Attributes", + "uri": "{/lang}/{/app}/purchase/supplier/attribute/type/list?{?}", + "target": "self", + "icon": null, + "order": 5, + "from": "SupplierManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1002101001, + "children": [ + { + "id": 1003203101, + "pid": "/purchase", + "type": 3, + "subtype": 1, + "name": "Types", + "uri": "{/lang}/{/app}/purchase/supplier/attribute/type/list?{?}", + "target": "self", + "icon": null, + "order": 15, + "from": "SupplierManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003203001, + "children": [] + }, + { + "id": 1003203201, + "pid": "/purchase", + "type": 3, + "subtype": 1, + "name": "Values", + "uri": "{/lang}/{/app}/purchase/supplier/attribute/value/list?{?}", + "target": "self", + "icon": null, + "order": 15, + "from": "SupplierManagement", + "permission": { "permission": 2, "category": null, "element": null }, + "parent": 1003203001, + "children": [] + } + ] + }, + { + "id": 1003204001, "pid": "/purchase/analysis", "type": 3, "subtype": 1, @@ -54,7 +100,7 @@ "uri": "{/lang}/{/app}/purchase/analysis/supplier?{?}", "target": "self", "icon": null, - "order": 2, + "order": 10, "from": "SupplierManagement", "permission": { "permission": 2, "category": null, "element": null }, "parent": 1002106001, diff --git a/Admin/Install/attributes.json b/Admin/Install/attributes.json new file mode 100644 index 0000000..86228cd --- /dev/null +++ b/Admin/Install/attributes.json @@ -0,0 +1,170 @@ +[ + { + "name": "abc_class", + "l11n": { + "en": "Rating", + "de": "Bewertung" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [ + { + "value": "A", + "l11n": { + "en": "A", + "de": "A" + } + }, + { + "value": "B", + "l11n": { + "en": "B", + "de": "B" + } + }, + { + "value": "C", + "l11n": { + "en": "C", + "de": "C" + } + }, + { + "value": "D", + "l11n": { + "en": "D", + "de": "D" + } + }, + { + "value": "E", + "l11n": { + "en": "E", + "de": "E" + } + }, + { + "value": "F", + "l11n": { + "en": "F", + "de": "F" + } + } + ] + }, + { + "name": "group", + "l11n": { + "en": "Group", + "de": "Gruppe" + }, + "value_type": 1, + "is_custom_allowed": false, + "validation_pattern": "", + "is_required": true, + "default_value": "", + "values": [ + { + "value": 1, + "l11n": { + "en": "Group 1", + "de": "Gruppe 1" + } + } + ] + }, + { + "name": "vat_id", + "l11n": { + "en": "VAT Id", + "de": "USt IdNr." + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "tax_id", + "l11n": { + "en": "Tax Id", + "de": "Steuernummer" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "legal_form", + "l11n": { + "en": "Legal form", + "de": "Rechtsform" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "credit_rating", + "l11n": { + "en": "Credit rating", + "de": "Bonität" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "line_of_credit", + "l11n": { + "en": "Line of credit", + "de": "Kreditlimit" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "order_limit", + "l11n": { + "en": "Order limit", + "de": "Bestelllimit" + }, + "value_type": 1, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, + { + "name": "minimum_order", + "l11n": { + "en": "MOQ", + "de": "Mindestbestellmenge" + }, + "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 c4563a0..69a5c47 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -59,8 +59,8 @@ "type": "INT", "default": null, "null": true, - "foreignTable": "organization_unit", - "foreignKey": "organization_unit_id" + "foreignTable": "unit", + "foreignKey": "unit_id" } } }, @@ -204,6 +204,27 @@ "type": "DATETIME", "null": true, "default": null + }, + "suppliermgmt_attr_value_unit": { + "name": "suppliermgmt_attr_value_unit", + "type": "VARCHAR(255)", + "null": false + }, + "suppliermgmt_attr_value_deptype": { + "name": "suppliermgmt_attr_value_deptype", + "type": "INT(11)", + "null": true, + "default": null, + "foreignTable": "suppliermgmt_attr_type", + "foreignKey": "suppliermgmt_attr_type_id" + }, + "suppliermgmt_attr_value_depvalue": { + "name": "suppliermgmt_attr_value_depvalue", + "type": "INT(11)", + "null": true, + "default": null, + "foreignTable": "suppliermgmt_attr_value", + "foreignKey": "suppliermgmt_attr_value_id" } } }, diff --git a/Admin/Install/localizations.json b/Admin/Install/localizations.json new file mode 100644 index 0000000..c44dc44 --- /dev/null +++ b/Admin/Install/localizations.json @@ -0,0 +1,3 @@ +[ + +] \ No newline at end of file diff --git a/Admin/Installer.php b/Admin/Installer.php index c13ba73..9ae3d3d 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -14,7 +14,13 @@ declare(strict_types=1); namespace Modules\SupplierManagement\Admin; +use phpOMS\Application\ApplicationAbstract; +use phpOMS\Config\SettingsInterface; +use phpOMS\Message\Http\HttpRequest; +use phpOMS\Message\Http\HttpResponse; use phpOMS\Module\InstallerAbstract; +use phpOMS\Module\ModuleInfo; +use phpOMS\Uri\HttpUri; /** * Installer class. @@ -33,4 +39,211 @@ final class Installer extends InstallerAbstract * @since 1.0.0 */ public const PATH = __DIR__; + + /** + * {@inheritdoc} + */ + public static function install(ApplicationAbstract $app, ModuleInfo $info, SettingsInterface $cfgHandler) : void + { + parent::install($app, $info, $cfgHandler); + + /* Attributes */ + $fileContent = \file_get_contents(__DIR__ . '/Install/attributes.json'); + if ($fileContent === false) { + return; + } + + $attributes = \json_decode($fileContent, true); + $attrTypes = self::createSupplierAttributeTypes($app, $attributes); + $attrValues = self::createSupplierAttributeValues($app, $attrTypes, $attributes); + + /* Localizations */ + $fileContent = \file_get_contents(__DIR__ . '/Install/localizations.json'); + if ($fileContent === false) { + return; + } + + $localizations = \json_decode($fileContent, true); + $l11nTypes = self::createSupplierL11nTypes($app, $localizations); + } + + /** + * Install default l11n types + * + * @param ApplicationAbstract $app Application + * @param array $l11ns Attribute definition + * + * @return array + * + * @since 1.0.0 + */ + private static function createSupplierL11nTypes(ApplicationAbstract $app, array $l11ns) : array + { + /** @var array $l11nTypes */ + $l11nTypes = []; + + /** @var \Modules\SupplierManagement\Controller\ApiController $module */ + $module = $app->moduleManager->getModuleInstance('SupplierManagement'); + + foreach ($l11ns as $l11n) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', $l11n['name']); + $request->setData('is_required', $l11n['is_required'] ?? false); + + $module->apiSupplierL11nTypeCreate($request, $response); + + $responseData = $response->get(''); + if (!\is_array($responseData)) { + continue; + } + + $l11nTypes[] = !\is_array($responseData['response']) + ? $responseData['response']->toArray() + : $responseData['response']; + } + + return $l11nTypes; + } + + /** + * Install default attribute types + * + * @param ApplicationAbstract $app Application + * @param array, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array}> $attributes Attribute definition + * + * @return array + * + * @since 1.0.0 + */ + private static function createSupplierAttributeTypes(ApplicationAbstract $app, array $attributes) : array + { + /** @var array $supplierAttrType */ + $supplierAttrType = []; + + /** @var \Modules\SupplierManagement\Controller\ApiController $module */ + $module = $app->moduleManager->getModuleInstance('SupplierManagement'); + + /** @var array $attribute */ + foreach ($attributes as $attribute) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $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('is_required', $attribute['is_required'] ?? false); + $request->setData('is_custom_allowed', $attribute['is_custom_allowed'] ?? false); + $request->setData('validation_pattern', $attribute['validation_pattern'] ?? ''); + $request->setData('datatype', (int) $attribute['value_type']); + + $module->apiSupplierAttributeTypeCreate($request, $response); + + $responseData = $response->get(''); + if (!\is_array($responseData)) { + continue; + } + + $supplierAttrType[$attribute['name']] = !\is_array($responseData['response']) + ? $responseData['response']->toArray() + : $responseData['response']; + + $isFirst = true; + foreach ($attribute['l11n'] as $language => $l11n) { + if ($isFirst) { + $isFirst = false; + continue; + } + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', $l11n); + $request->setData('language', $language); + $request->setData('type', $supplierAttrType[$attribute['name']]['id']); + + $module->apiSupplierAttributeTypeL11nCreate($request, $response); + } + } + + return $supplierAttrType; + } + + /** + * Create default attribute values for types + * + * @param ApplicationAbstract $app Application + * @param array $supplierAttrType Attribute types + * @param array, is_required?:bool, is_custom_allowed?:bool, validation_pattern?:string, value_type?:string, values?:array}> $attributes Attribute definition + * + * @return array + * + * @since 1.0.0 + */ + private static function createSupplierAttributeValues(ApplicationAbstract $app, array $supplierAttrType, array $attributes) : array + { + /** @var array $supplierAttrValue */ + $supplierAttrValue = []; + + /** @var \Modules\SupplierManagement\Controller\ApiController $module */ + $module = $app->moduleManager->getModuleInstance('SupplierManagement'); + + foreach ($attributes as $attribute) { + $supplierAttrValue[$attribute['name']] = []; + + /** @var array $value */ + foreach ($attribute['values'] as $value) { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('value', $value['value'] ?? ''); + $request->setData('unit', $value['unit'] ?? ''); + $request->setData('default', isset($attribute['values']) && !empty($attribute['values'])); + $request->setData('attributetype', $supplierAttrType[$attribute['name']]['id']); + + if (isset($value['l11n']) && !empty($value['l11n'])) { + $request->setData('title', \reset($value['l11n'])); + $request->setData('language', \array_keys($value['l11n'])[0] ?? 'en'); + } + + $module->apiSupplierAttributeValueCreate($request, $response); + + $responseData = $response->get(''); + if (!\is_array($responseData)) { + continue; + } + + $attrValue = !\is_array($responseData['response']) + ? $responseData['response']->toArray() + : $responseData['response']; + + $supplierAttrValue[$attribute['name']][] = $attrValue; + + $isFirst = true; + foreach (($value['l11n'] ?? []) as $language => $l11n) { + if ($isFirst) { + $isFirst = false; + continue; + } + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', $l11n); + $request->setData('language', $language); + $request->setData('value', $attrValue['id']); + + $module->apiSupplierAttributeValueL11nCreate($request, $response); + } + } + } + + return $supplierAttrValue; + } } diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index e67dddb..91dbc0e 100755 --- a/Admin/Routes/Web/Backend.php +++ b/Admin/Routes/Web/Backend.php @@ -18,6 +18,28 @@ use phpOMS\Account\PermissionType; use phpOMS\Router\RouteVerb; return [ + '^.*/purchase/supplier/attribute/type/list.*$' => [ + [ + 'dest' => '\Modules\SupplierManagement\Controller\BackendController:viewSupplierManagementAttributeTypeList', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::SUPPLIER, + ], + ], + ], + '^.*/purchase/supplier/attribute/type\?.*$' => [ + [ + 'dest' => '\Modules\SupplierManagement\Controller\BackendController:viewSupplierManagementAttributeType', + 'verb' => RouteVerb::GET, + 'permission' => [ + 'module' => BackendController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::SUPPLIER, + ], + ], + ], '^.*/purchase/supplier/list.*$' => [ [ 'dest' => '\Modules\SupplierManagement\Controller\BackendController:viewSupplierManagementSupplierList', diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 6e34f88..4f4cbbd 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -15,6 +15,8 @@ declare(strict_types=1); namespace Modules\SupplierManagement\Controller; use Modules\Billing\Models\PurchaseBillMapper; +use Modules\SupplierManagement\Models\SupplierAttributeTypeMapper; +use Modules\SupplierManagement\Models\SupplierAttributeValueMapper; use Modules\SupplierManagement\Models\SupplierMapper; use phpOMS\Asset\AssetType; use phpOMS\Contract\RenderableInterface; @@ -36,6 +38,94 @@ use phpOMS\Views\View; */ final class BackendController extends Controller { + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function SupplierManagementAttributeTypeList(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + $view->setTemplate('/Modules/SupplierManagement/Theme/Backend/attribute-type-list'); + $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response)); + + /** @var \Modules\SupplierManagement\Models\SupplierAttributeType[] $attributes */ + $attributes = SupplierAttributeTypeMapper::getAll() + ->with('l11n') + ->where('l11n/language', $response->getLanguage()) + ->execute(); + + $view->addData('attributes', $attributes); + + return $view; + } + + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function SupplierManagementAttributeValues(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + $view->setTemplate('/Modules/SupplierManagement/Theme/Backend/attribute-value-list'); + $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response)); + + /** @var \Modules\SupplierManagement\Models\SupplierAttributeValue[] $attributes */ + $attributes = SupplierAttributeValueMapper::getAll() + ->with('l11n') + ->where('l11n/language', $response->getLanguage()) + ->execute(); + + $view->addData('attributes', $attributes); + + return $view; + } + + /** + * Routing end-point for application behaviour. + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param mixed $data Generic data + * + * @return RenderableInterface + * + * @since 1.0.0 + * @codeCoverageIgnore + */ + public function SupplierManagementAttributeType(RequestAbstract $request, ResponseAbstract $response, mixed $data = null) : RenderableInterface + { + $view = new View($this->app->l11nManager, $request, $response); + $view->setTemplate('/Modules/SupplierManagement/Theme/Backend/attribute-type'); + $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response)); + + /** @var \Modules\SupplierManagement\Models\SupplierAttributeType $attribute */ + $attribute = SupplierAttributeTypeMapper::get() + ->with('l11n') + ->where('id', (int) $request->getData('id')) + ->where('l11n/language', $response->getLanguage()) + ->execute(); + + $view->addData('attribute', $attribute); + + return $view; + } + /** * Routing end-point for application behaviour. * diff --git a/Models/AttributeValueType.php b/Models/AttributeValueType.php index 731eeb0..17fe51c 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/SupplierAttributeTypeMapper.php b/Models/SupplierAttributeTypeMapper.php index 271b8e3..0447e2d 100755 --- a/Models/SupplierAttributeTypeMapper.php +++ b/Models/SupplierAttributeTypeMapper.php @@ -53,7 +53,7 @@ final class SupplierAttributeTypeMapper extends DataMapperFactory 'mapper' => SupplierAttributeTypeL11nMapper::class, 'table' => 'suppliermgmt_attr_type_l11n', 'self' => 'suppliermgmt_attr_type_l11n_type', - 'column' => 'title', + 'column' => 'content', 'external' => null, ], 'defaults' => [ diff --git a/Models/SupplierAttributeValue.php b/Models/SupplierAttributeValue.php index 8bd5f83..5fd6720 100755 --- a/Models/SupplierAttributeValue.php +++ b/Models/SupplierAttributeValue.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace Modules\SupplierManagement\Models; +use phpOMS\Localization\BaseStringL11n; use phpOMS\Localization\ISO3166TwoEnum; use phpOMS\Localization\ISO639x1Enum; @@ -37,6 +38,22 @@ class SupplierAttributeValue 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 * @@ -77,6 +94,14 @@ class SupplierAttributeValue implements \JsonSerializable */ public bool $isDefault = false; + /** + * Unit of the value + * + * @var string + * @since 1.0.0 + */ + public string $unit = ''; + /** * Localization * @@ -146,7 +171,10 @@ class SupplierAttributeValue 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; @@ -177,58 +205,6 @@ class SupplierAttributeValue implements \JsonSerializable return null; } - /** - * Set language - * - * @param string $language Language - * - * @return void - * - * @since 1.0.0 - */ - public function setLanguage(string $language) : void - { - $this->language = $language; - } - - /** - * Get language - * - * @return string - * - * @since 1.0.0 - */ - public function getLanguage() : string - { - return $this->language; - } - - /** - * Set country - * - * @param string $country Country - * - * @return void - * - * @since 1.0.0 - */ - public function setCountry(string $country) : void - { - $this->country = $country; - } - - /** - * Get country - * - * @return string - * - * @since 1.0.0 - */ - public function getCountry() : string - { - return $this->country; - } - /** * {@inheritdoc} */ diff --git a/Models/SupplierAttributeValueMapper.php b/Models/SupplierAttributeValueMapper.php index 7318213..8eaf1bf 100755 --- a/Models/SupplierAttributeValueMapper.php +++ b/Models/SupplierAttributeValueMapper.php @@ -39,6 +39,9 @@ final class SupplierAttributeValueMapper extends DataMapperFactory 'suppliermgmt_attr_value_valueInt' => ['name' => 'suppliermgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'], 'suppliermgmt_attr_value_valueDec' => ['name' => 'suppliermgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'], 'suppliermgmt_attr_value_valueDat' => ['name' => 'suppliermgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'], + 'suppliermgmt_attr_value_unit' => ['name' => 'suppliermgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'], + 'suppliermgmt_attr_value_deptype' => ['name' => 'suppliermgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'], + 'suppliermgmt_attr_value_depvalue' => ['name' => 'suppliermgmt_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'], ]; /** diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php index 7e6e786..8d8a800 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/');