diff --git a/Admin/Install/db.json b/Admin/Install/db.json index 94861cc..d613024 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -213,6 +213,11 @@ "type": "TINYINT(1)", "null": false }, + "clientmgmt_attr_type_internal": { + "name": "clientmgmt_attr_type_internal", + "type": "TINYINT(1)", + "null": false + }, "clientmgmt_attr_type_required": { "description": "Every item must have this attribute type if set to true.", "name": "clientmgmt_attr_type_required", @@ -423,7 +428,7 @@ }, "clientmgmt_client_account_account": { "name": "clientmgmt_client_account_account", - "type": "VARCHAR(50)", + "type": "VARCHAR(10)", "null": false }, "clientmgmt_client_account_client": { diff --git a/Admin/Installer.php b/Admin/Installer.php index 63e549a..248f68e 100755 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -20,7 +20,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. @@ -47,8 +46,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) { @@ -64,6 +61,16 @@ final class Installer extends InstallerAbstract $attrTypes = self::createClientAttributeTypes($app, $attributes); $attrValues = self::createClientAttributeValues($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) { @@ -99,7 +106,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']); @@ -141,13 +148,15 @@ 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('is_required', $attribute['is_required'] ?? false); + $request->setData('repeatable', $attribute['repeatable'] ?? false); + $request->setData('internal', $attribute['internal'] ?? false); $request->setData('custom', $attribute['is_custom_allowed'] ?? false); $request->setData('validation_pattern', $attribute['validation_pattern'] ?? ''); $request->setData('datatype', (int) $attribute['value_type']); @@ -171,7 +180,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); @@ -210,7 +219,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'] ?? ''); @@ -244,7 +253,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 f927940..7967d18 100644 --- 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 [ - '^.*/client/find.*$' => [ + '^.*/client/find(\?.*$|$)' => [ [ 'dest' => '\Modules\ClientManagement\Controller\ApiController:apiClientFind', 'verb' => RouteVerb::GET, diff --git a/Admin/Routes/Web/Backend.php b/Admin/Routes/Web/Backend.php index 2ebd53b..c4faf7d 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 [ - '^.*/sales/client/attribute/type/list.*$' => [ + '^.*/sales/client/attribute/type/list(\?.*$|$)' => [ [ 'dest' => '\Modules\ClientManagement\Controller\BackendController:viewClientManagementAttributeTypeList', 'verb' => RouteVerb::GET, @@ -29,7 +29,7 @@ return [ ], ], ], - '^.*/sales/client/attribute/type\?.*$' => [ + '^.*/sales/client/attribute/type(\?.*$|$)' => [ [ 'dest' => '\Modules\ClientManagement\Controller\BackendController:viewClientManagementAttributeType', 'verb' => RouteVerb::GET, @@ -40,7 +40,7 @@ return [ ], ], ], - '^.*/sales/client/list.*$' => [ + '^.*/sales/client/list(\?.*$|$)' => [ [ 'dest' => '\Modules\ClientManagement\Controller\BackendController:viewClientManagementClientList', 'verb' => RouteVerb::GET, @@ -51,7 +51,7 @@ return [ ], ], ], - '^.*/sales/client/create.*$' => [ + '^.*/sales/client/create(\?.*$|$)' => [ [ 'dest' => '\Modules\ClientManagement\Controller\BackendController:viewClientManagementClientCreate', 'verb' => RouteVerb::GET, @@ -62,9 +62,9 @@ return [ ], ], ], - '^.*/sales/client/profile.*$' => [ + '^.*/sales/client/view(\?.*$|$)' => [ [ - 'dest' => '\Modules\ClientManagement\Controller\BackendController:viewClientManagementClientProfile', + 'dest' => '\Modules\ClientManagement\Controller\BackendController:viewClientManagementClientView', 'verb' => RouteVerb::GET, 'permission' => [ 'module' => BackendController::NAME, @@ -73,7 +73,7 @@ return [ ], ], ], - '^.*/sales/client/analysis.*$' => [ + '^.*/sales/client/analysis(\?.*$|$)' => [ [ 'dest' => '\Modules\ClientManagement\Controller\BackendController:viewClientManagementClientAnalysis', 'verb' => RouteVerb::GET, diff --git a/Controller/ApiAttributeController.php b/Controller/ApiAttributeController.php index 17d60cd..de75d1a 100644 --- a/Controller/ApiAttributeController.php +++ b/Controller/ApiAttributeController.php @@ -61,12 +61,15 @@ final class ApiAttributeController extends Controller return; } - $type = ClientAttributeTypeMapper::get()->with('defaults')->where('id', (int) $request->getData('type'))->execute(); + $type = $data['type'] ?? ClientAttributeTypeMapper::get() + ->with('defaults') + ->where('id', (int) $request->getData('type')) + ->execute(); if (!$type->repeatable) { $attr = ClientAttributeMapper::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, ClientAttributeValueMapper::class, 'attr_value', $request->getOrigin()); if ($attrValue->isDefault) { $this->createModelRelation( $request->header->account, - (int) $request->getData('type'), + $type->id, $attrValue->id, ClientAttributeTypeMapper::class, 'defaults', '', $request->getOrigin() ); diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 4a08ddf..1891cb9 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace Modules\ClientManagement\Controller; use Modules\Admin\Models\Account; +use Modules\Admin\Models\AccountMapper; use Modules\Admin\Models\AddressMapper; use Modules\Admin\Models\NullAccount; use Modules\Auditor\Models\Audit; @@ -31,11 +32,10 @@ use Modules\Media\Models\PathSettings; use Modules\Organization\Models\UnitMapper; use phpOMS\Account\PermissionType; use phpOMS\Api\EUVAT\EUVATVies; -use phpOMS\Api\Geocoding\Nominatim; use phpOMS\Localization\BaseStringL11n; use phpOMS\Localization\BaseStringL11nType; use phpOMS\Localization\ISO3166CharEnum; -use phpOMS\Localization\ISO3166TwoEnum; +use phpOMS\Localization\ISO639x1Enum; use phpOMS\Localization\NullBaseStringL11nType; use phpOMS\Message\Http\HttpRequest; use phpOMS\Message\Http\HttpResponse; @@ -44,8 +44,6 @@ use phpOMS\Message\NotificationLevel; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; use phpOMS\Model\Message\FormValidation; -use phpOMS\Stdlib\Base\Address; -use phpOMS\Uri\HttpUri; use phpOMS\Utils\StringUtils; /** @@ -68,7 +66,7 @@ final class ApiController extends Controller * * @since 1.0.0 */ - public function findClientForAccount(int $account, int $unit = null) : ?Client + public function findClientForAccount(int $account, ?int $unit = null) : ?Client { $clientMapper = ClientMapper::get() ->where('account', $account); @@ -83,6 +81,90 @@ final class ApiController extends Controller return $client->id === 0 ? null : $client; } + public function setVAT(RequestAbstract $request, Client $client) : void + { + /** @var \Modules\Attribute\Models\AttributeType $type */ + $type = ClientAttributeTypeMapper::get()->with('defaults')->where('name', 'vat_id')->execute(); + + $internalRequest = new HttpRequest(); + $internalResponse = new HttpResponse(); + + $internalRequest->header->account = $request->header->account; + $internalRequest->setData('ref', $client->id); + $internalRequest->setData('type', $type->id); + $internalRequest->setData('value', $request->getDataString('vat_id')); + + $this->app->moduleManager->get('ClientManagement', 'ApiAttribute') + ->apiClientAttributeCreate($internalRequest, $internalResponse); + } + + public function validateVAT(RequestAbstract $request, Client $client) : array + { + /** @var \Modules\Organization\Models\Unit $unit */ + $unit = UnitMapper::get() + ->with('attributes') + ->where('id', $this->app->unitId) + ->execute(); + + $validate = ['status' => -1]; + + if (\in_array($client->mainAddress->country, ISO3166CharEnum::getRegion('eu'))) { + $validate = EUVATVies::validateQualified( + $request->getDataString('vat_id') ?? '', + $unit->getAttribute('vat_id')->value->valueStr ?? '', + $client->account->name1, + $client->mainAddress->city, + $client->mainAddress->postal, + $client->mainAddress->address + ); + } + + $audit = new Audit( + new NullAccount($request->header->account), + null, + (string) ($validate['status'] ?? ''), + StringUtils::intHash(EUVATVies::class), + 'vat_validation', + self::NAME, + (string) $client->id, + (string) \json_encode($validate), + (int) \ip2long($request->getOrigin()) + ); + + AuditMapper::create()->execute($audit); + + return $validate; + } + + public function defineTaxCode(RequestAbstract $request, Client $client) : void + { + /** @var \Modules\Organization\Models\Unit $unit */ + $unit = UnitMapper::get() + ->with('mainAddress') + ->where('id', $this->app->unitId) + ->execute(); + + /** @var \Modules\Attribute\Models\AttributeType $type */ + $type = ClientAttributeTypeMapper::get() + ->with('defaults') + ->where('name', 'sales_tax_code') + ->execute(); + + $value = $this->app->moduleManager->get('Billing', 'ApiTax') + ->getClientTaxCode($client, $unit->mainAddress); + + $internalRequest = new HttpRequest(); + $internalResponse = new HttpResponse(); + + $internalRequest->header->account = $request->header->account; + $internalRequest->setData('ref', $client->id); + $internalRequest->setData('type', $type->id); + $internalRequest->setData('value_id', $value->id); + + $this->app->moduleManager->get('ClientManagement', 'ApiAttribute') + ->apiClientAttributeCreate($internalRequest, $internalResponse, ['type' => $type]); + } + /** * Api method to create news article * @@ -107,42 +189,32 @@ final class ApiController extends Controller $client = $this->createClientFromRequest($request); $this->createModel($request->header->account, $client, ClientMapper::class, 'client', $request->getOrigin()); + $this->createModelRelation( + $client->account->id, + $client->account->id, + [$client->mainAddress->id], + AccountMapper::class, + 'addresses', + 'account', + $request->getOrigin() + ); + + // Create stock + if ($this->app->moduleManager->isActive('WarehouseManagement')) { + $internalResponse = new HttpResponse(); + $internalRequest = new HttpRequest($request->uri); + + $internalRequest->header->account = $request->header->account; + $internalRequest->setData('name', $client->number); + $internalRequest->setData('client', $client->id); + + $this->app->moduleManager->get('WarehouseManagement', 'Api') + ->apiStockCreate($internalRequest, $internalResponse); + } // Set VAT Id - // @todo move to separate function if ($request->hasData('vat_id')) { - /** @var \Modules\Organization\Models\Unit $unit */ - $unit = UnitMapper::get() - ->with('attributes') - ->where('id', $this->app->unitId) - ->execute(); - - $validate = ['status' => -1]; - - if (\in_array($client->mainAddress->getCountry(), ISO3166CharEnum::getRegion('eu'))) { - $validate = EUVATVies::validateQualified( - $request->getDataString('vat_id') ?? '', - $unit->getAttribute('vat_id')->value->valueStr ?? '', - $client->account->name1, - $client->mainAddress->city, - $client->mainAddress->postal, - $client->mainAddress->address - ); - } - - $audit = new Audit( - new NullAccount($request->header->account), - null, - (string) ($validate['status'] ?? ''), - StringUtils::intHash(EUVATVies::class), - 'vat_validation', - self::NAME, - (string) $client->id, - (string) \json_encode($validate), - (int) \ip2long($request->getOrigin()) - ); - - AuditMapper::create()->execute($audit); + $validate = $this->validateVAT($request, $client); if (($validate['status'] === 0 && $validate['vat'] === 'A' @@ -150,48 +222,13 @@ final class ApiController extends Controller && $validate['city'] === 'A') || $validate['status'] !== 0 // Api out of order -> accept it -> test it during invoice creation ) { - /** @var \Modules\Attribute\Models\AttributeType $type */ - $type = ClientAttributeTypeMapper::get()->with('defaults')->where('name', 'vat_id')->execute(); - - $internalRequest = new HttpRequest(new HttpUri('')); - $internalResponse = new HttpResponse(); - - $internalRequest->header->account = $request->header->account; - $internalRequest->setData('ref', $client->id); - $internalRequest->setData('type', $type->id); - $internalRequest->setData('value', $request->getDataString('vat_id')); - - $this->app->moduleManager->get('ClientManagement', 'ApiAttribute') - ->apiClientAttributeCreate($internalRequest, $internalResponse); + $this->setVAT($request, $client); } } - // Find tax code + // Find and set tax code if ($this->app->moduleManager->isActive('Billing')) { - /** @var \Modules\Organization\Models\Unit $unit */ - $unit = UnitMapper::get() - ->with('mainAddress') - ->where('id', $this->app->unitId) - ->execute(); - - /** @var \Modules\Attribute\Models\AttributeType $type */ - $type = ClientAttributeTypeMapper::get() - ->where('name', 'sales_tax_code') - ->execute(); - - $value = $this->app->moduleManager->get('Billing', 'ApiTax') - ->getClientTaxCode($client, $unit->mainAddress); - - $internalRequest = new HttpRequest(new HttpUri('')); - $internalResponse = new HttpResponse(); - - $internalRequest->header->account = $request->header->account; - $internalRequest->setData('ref', $client->id); - $internalRequest->setData('type', $type->id); - $internalRequest->setData('value', $value->id); - - $this->app->moduleManager->get('ClientManagement', 'ApiAttribute') - ->apiClientAttributeCreate($internalRequest, $internalResponse); + $this->defineTaxCode($request, $client); } $this->createClientSegmentation($request, $response, $client); @@ -209,13 +246,13 @@ final class ApiController extends Controller return; } - $types = ClientAttributeTypeMapper::get() + $types = ClientAttributeTypeMapper::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', $client->id); @@ -249,25 +286,10 @@ final class ApiController extends Controller $client = new Client(); $client->number = $request->getDataString('number') ?? ''; $client->account = $account; - $client->unit = $request->getDataInt('unit') ?? 1; + $client->unit = $request->getDataInt('unit') ?? 1; - // Handle main address - $addr = new Address(); - $addr->address = $request->getDataString('address') ?? ''; - $addr->postal = $request->getDataString('postal') ?? ''; - $addr->city = $request->getDataString('city') ?? ''; - $addr->state = $request->getDataString('state') ?? ''; - $addr->setCountry($request->getDataString('country') ?? ISO3166TwoEnum::_XXX); - $client->mainAddress = $addr; - - // Try to find lat/lon through external API - $geocoding = Nominatim::geocoding($addr->country, $addr->city, $addr->address); - if ($geocoding === ['lat' => 0.0, 'lon' => 0.0]) { - $geocoding = Nominatim::geocoding($addr->country, $addr->city); - } - - $client->mainAddress->lat = $geocoding['lat']; - $client->mainAddress->lon = $geocoding['lon']; + $request->setData('name', null, true); + $client->mainAddress = $this->app->moduleManager->get('Admin', 'Api')->createAddressFromRequest($request); return $client; } @@ -315,7 +337,7 @@ final class ApiController extends Controller return; } - $clientMapper = $client = ClientMapper::get() + $clientMapper = ClientMapper::get() ->with('mainAddress'); if ($request->hasData('account')) { @@ -332,8 +354,8 @@ final class ApiController extends Controller $client = $clientMapper->execute(); $old = $client->mainAddress; + $new = $this->app->moduleManager->get('Admin', 'Api')->updateAddressFromRequest($request, clone $old); - $new = $this->updateMainAddressFromRequest($request, clone $old); $this->updateModel($request->header->account, $old, $new, AddressMapper::class, 'address', $request->getOrigin()); $this->createStandardUpdateResponse($request, $response, $new); } @@ -358,30 +380,6 @@ final class ApiController extends Controller return []; } - /** - * Method to update an account from a request - * - * @param RequestAbstract $request Request - * @param Address $address Address - * - * @return Address - * - * @since 1.0.0 - */ - private function updateMainAddressFromRequest(RequestAbstract $request, Address $address) : Address - { - $address->name = $request->getDataString('name') ?? $address->name; - $address->fao = $request->getDataString('fao') ?? $address->fao; - $address->address = $request->getDataString('address') ?? $address->address; - $address->addressAddition = $request->getDataString('addition') ?? $address->addressAddition; - $address->postal = $request->getDataString('postal') ?? $address->postal; - $address->city = $request->getDataString('city') ?? $address->city; - $address->state = $request->getDataString('state') ?? $address->state; - $address->setCountry($request->getDataString('country') ?? $address->getCountry()); - - return $address; - } - /** * Api method to create client l11n * @@ -420,13 +418,11 @@ final class ApiController extends Controller */ private function createClientL11nFromRequest(RequestAbstract $request) : BaseStringL11n { - $clientL11n = new BaseStringL11n(); - $clientL11n->ref = $request->getDataInt('client') ?? 0; - $clientL11n->type = new NullBaseStringL11nType($request->getDataInt('type') ?? 0); - $clientL11n->setLanguage( - $request->getDataString('language') ?? $request->header->l11n->language - ); - $clientL11n->content = $request->getDataString('description') ?? ''; + $clientL11n = new BaseStringL11n(); + $clientL11n->ref = $request->getDataInt('client') ?? 0; + $clientL11n->type = new NullBaseStringL11nType($request->getDataInt('type') ?? 0); + $clientL11n->language = ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? $request->header->l11n->language; + $clientL11n->content = $request->getDataString('description') ?? ''; return $clientL11n; } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index b7d867f..d312b2a 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -14,13 +14,7 @@ declare(strict_types=1); namespace Modules\ClientManagement\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\Billing\Models\SalesBillMapper; -use Modules\ClientManagement\Models\Attribute\ClientAttributeMapper; use Modules\ClientManagement\Models\Attribute\ClientAttributeTypeL11nMapper; use Modules\ClientManagement\Models\Attribute\ClientAttributeTypeMapper; use Modules\ClientManagement\Models\Attribute\ClientAttributeValueL11nMapper; @@ -36,10 +30,8 @@ use phpOMS\Contract\RenderableInterface; use phpOMS\DataStorage\Database\Query\Builder; use phpOMS\DataStorage\Database\Query\OrderType; use phpOMS\DataStorage\Database\Query\Where; -use phpOMS\Localization\Money; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; -use phpOMS\Stdlib\Base\SmartDateTime; use phpOMS\Utils\StringUtils; use phpOMS\Views\View; @@ -210,7 +202,7 @@ final class BackendController extends Controller * @since 1.0.0 * @codeCoverageIgnore */ - public function viewClientManagementClientProfile(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface + public function viewClientManagementClientView(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $head = $response->data['Content']->head; $nonce = $this->app->appSettings->getOption('script-nonce'); @@ -221,13 +213,21 @@ final class BackendController extends Controller $head->addAsset(AssetType::JSLATE, 'Modules/ClientManagement/Controller.js', ['nonce' => $nonce, 'type' => 'module']); $view = new View($this->app->l11nManager, $request, $response); - $view->setTemplate('/Modules/ClientManagement/Theme/Backend/client-profile'); + $view->setTemplate('/Modules/ClientManagement/Theme/Backend/client-view'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003102001, $request, $response); - /** @var \Modules\ClientManagement\Models\Client $client */ - $client = ClientMapper::get() + $pkType = 'id'; + $pkValue = $request->getDataInt('id'); + if ($pkValue === null) { + $pkType = 'number'; + $pkValue = $request->getDataString('number'); + } + + /** @var \Modules\ClientManagement\Models\Client */ + $view->data['client'] = ClientMapper::get() ->with('account') - ->with('contactElements') + ->with('account/addresses') + ->with('account/contacts') ->with('mainAddress') ->with('files')->limit(5, 'files')->sort('files/id', OrderType::DESC) ->with('notes')->limit(5, 'notes')->sort('notes/id', OrderType::DESC) @@ -236,8 +236,10 @@ final class BackendController extends Controller ->with('attributes/type/l11n') ->with('attributes/value') //->with('attributes/value/l11n') - ->where('id', (int) $request->getData('id')) + //->with('attributes/value/l11n') + ->where($pkType, $pkValue) ->where('attributes/type/l11n/language', $response->header->l11n->language) + //->where('attributes/value/l11n/language', $response->header->l11n->language) /* ->where('attributes/value/l11n', (new Where($this->app->dbPool->get())) ->where(ClientAttributeValueL11nMapper::getColumnByMember('ref'), '=', null) @@ -245,22 +247,15 @@ final class BackendController extends Controller */ ->execute(); - $view->data['client'] = $client; + $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); + $view->data['attributeView']->data['default_localization'] = $this->app->l11nServer; - /** @var \Model\Setting $settings */ - $settings = $this->app->appSettings->get(null, SettingsEnum::DEFAULT_LOCALIZATION); - - $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); - $view->data['attributeView']->data['default_localization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); - - /** @var \Modules\Attribute\Models\AttributeType[] $attributeTypes */ - $attributeTypes = ClientAttributeTypeMapper::getAll() + /** @var \Modules\Attribute\Models\AttributeType[] */ + $view->data['attributeTypes'] = ClientAttributeTypeMapper::getAll() ->with('l11n') ->where('l11n/language', $response->header->l11n->language) ->execute(); - $view->data['attributeTypes'] = $attributeTypes; - // 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. @@ -277,17 +272,15 @@ 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(ClientMapper::HAS_MANY['files']['self'], '=', $client->id) + ->where(ClientMapper::HAS_MANY['files']['self'], '=', $view->data['client']->id) ->where(MediaTypeMapper::TABLE . '.' . MediaTypeMapper::getColumnByMember('name'), '=', 'client_profile_image'); - $clientImage = MediaMapper::get() + $view->data['clientImage'] = MediaMapper::get() ->with('types') ->where('id', $results) ->limit(1) ->execute(); - $view->data['clientImage'] = $clientImage; - $businessStart = UnitAttributeMapper::get() ->with('type') ->with('value') @@ -297,13 +290,15 @@ final class BackendController extends Controller $view->data['business_start'] = $businessStart->id === 0 ? 1 : $businessStart->value->getValue(); - /** @var \Modules\Billing\Models\Price\Price[] $prices */ - $prices = PriceMapper::getAll() - ->where('client', $client->id) - ->where('type', PriceType::SALES) - ->execute(); + $view->data['hasBilling'] = $this->app->moduleManager->isActive('Billing'); - $view->data['prices'] = $prices; + /** @var \Modules\Billing\Models\Price\Price[] */ + $view->data['prices'] = $view->data['hasBilling'] + ? \Modules\Billing\Models\Price\PriceMapper::getAll() + ->where('client', $view->data['client']->id) + ->where('type', \Modules\Billing\Models\Price\PriceType::SALES) + ->execute() + : []; $tmp = ItemAttributeTypeMapper::getAll() ->with('defaults') @@ -343,30 +338,27 @@ 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(ClientMapper::class)) ->where('module', 'ClientManagement') - ->where('ref', (string) $client->id) + ->where('ref', (string) $view->data['client']->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', ClientMapper::class, 'files') // id = media id, files = client relations - ->on('id', $client->id, relation: 'files') // id = item id + ->on('id', $view->data['client']->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['note'] = new \Modules\Editor\Theme\Backend\Components\Note\BaseView($this->app->l11nManager, $request, $response); - $view->data['hasBilling'] = $this->app->moduleManager->isActive('Billing'); + $view->data['address-component'] = new \Modules\Admin\Theme\Backend\Components\AddressEditor\AddressView($this->app->l11nManager, $request, $response); + $view->data['contact-component'] = new \Modules\Admin\Theme\Backend\Components\ContactEditor\ContactView($this->app->l11nManager, $request, $response); return $view; } diff --git a/Models/Attribute/ClientAttributeMapper.php b/Models/Attribute/ClientAttributeMapper.php index 7315fec..8929f73 100644 --- a/Models/Attribute/ClientAttributeMapper.php +++ b/Models/Attribute/ClientAttributeMapper.php @@ -37,10 +37,10 @@ final class ClientAttributeMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'clientmgmt_client_attr_id' => ['name' => 'clientmgmt_client_attr_id', 'type' => 'int', 'internal' => 'id'], - 'clientmgmt_client_attr_client' => ['name' => 'clientmgmt_client_attr_client', 'type' => 'int', 'internal' => 'ref'], - 'clientmgmt_client_attr_type' => ['name' => 'clientmgmt_client_attr_type', 'type' => 'int', 'internal' => 'type'], - 'clientmgmt_client_attr_value' => ['name' => 'clientmgmt_client_attr_value', 'type' => 'int', 'internal' => 'value'], + 'clientmgmt_client_attr_id' => ['name' => 'clientmgmt_client_attr_id', 'type' => 'int', 'internal' => 'id'], + 'clientmgmt_client_attr_client' => ['name' => 'clientmgmt_client_attr_client', 'type' => 'int', 'internal' => 'ref'], + 'clientmgmt_client_attr_type' => ['name' => 'clientmgmt_client_attr_type', 'type' => 'int', 'internal' => 'type'], + 'clientmgmt_client_attr_value' => ['name' => 'clientmgmt_client_attr_value', 'type' => 'int', 'internal' => 'value'], ]; /** diff --git a/Models/Attribute/ClientAttributeTypeL11nMapper.php b/Models/Attribute/ClientAttributeTypeL11nMapper.php index ce2cd4f..b3c1fe2 100644 --- a/Models/Attribute/ClientAttributeTypeL11nMapper.php +++ b/Models/Attribute/ClientAttributeTypeL11nMapper.php @@ -37,10 +37,10 @@ final class ClientAttributeTypeL11nMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'clientmgmt_attr_type_l11n_id' => ['name' => 'clientmgmt_attr_type_l11n_id', 'type' => 'int', 'internal' => 'id'], - 'clientmgmt_attr_type_l11n_title' => ['name' => 'clientmgmt_attr_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], - 'clientmgmt_attr_type_l11n_type' => ['name' => 'clientmgmt_attr_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], - 'clientmgmt_attr_type_l11n_lang' => ['name' => 'clientmgmt_attr_type_l11n_lang', 'type' => 'string', 'internal' => 'language'], + 'clientmgmt_attr_type_l11n_id' => ['name' => 'clientmgmt_attr_type_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'clientmgmt_attr_type_l11n_title' => ['name' => 'clientmgmt_attr_type_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'clientmgmt_attr_type_l11n_type' => ['name' => 'clientmgmt_attr_type_l11n_type', 'type' => 'int', 'internal' => 'ref'], + 'clientmgmt_attr_type_l11n_lang' => ['name' => 'clientmgmt_attr_type_l11n_lang', 'type' => 'string', 'internal' => 'language'], ]; /** diff --git a/Models/Attribute/ClientAttributeTypeMapper.php b/Models/Attribute/ClientAttributeTypeMapper.php index b73ab9f..da4916a 100644 --- a/Models/Attribute/ClientAttributeTypeMapper.php +++ b/Models/Attribute/ClientAttributeTypeMapper.php @@ -37,13 +37,13 @@ final class ClientAttributeTypeMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'clientmgmt_attr_type_id' => ['name' => 'clientmgmt_attr_type_id', 'type' => 'int', 'internal' => 'id'], - 'clientmgmt_attr_type_name' => ['name' => 'clientmgmt_attr_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], - 'clientmgmt_attr_type_datatype' => ['name' => 'clientmgmt_attr_type_datatype', 'type' => 'int', 'internal' => 'datatype'], - 'clientmgmt_attr_type_fields' => ['name' => 'clientmgmt_attr_type_fields', 'type' => 'int', 'internal' => 'fields'], - 'clientmgmt_attr_type_custom' => ['name' => 'clientmgmt_attr_type_custom', 'type' => 'bool', 'internal' => 'custom'], - 'clientmgmt_attr_type_pattern' => ['name' => 'clientmgmt_attr_type_pattern', 'type' => 'string', 'internal' => 'validationPattern'], - 'clientmgmt_attr_type_required' => ['name' => 'clientmgmt_attr_type_required', 'type' => 'bool', 'internal' => 'isRequired'], + 'clientmgmt_attr_type_id' => ['name' => 'clientmgmt_attr_type_id', 'type' => 'int', 'internal' => 'id'], + 'clientmgmt_attr_type_name' => ['name' => 'clientmgmt_attr_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + 'clientmgmt_attr_type_datatype' => ['name' => 'clientmgmt_attr_type_datatype', 'type' => 'int', 'internal' => 'datatype'], + 'clientmgmt_attr_type_fields' => ['name' => 'clientmgmt_attr_type_fields', 'type' => 'int', 'internal' => 'fields'], + 'clientmgmt_attr_type_custom' => ['name' => 'clientmgmt_attr_type_custom', 'type' => 'bool', 'internal' => 'custom'], + 'clientmgmt_attr_type_pattern' => ['name' => 'clientmgmt_attr_type_pattern', 'type' => 'string', 'internal' => 'validationPattern'], + 'clientmgmt_attr_type_required' => ['name' => 'clientmgmt_attr_type_required', 'type' => 'bool', 'internal' => 'isRequired'], ]; /** @@ -54,17 +54,17 @@ final class ClientAttributeTypeMapper extends DataMapperFactory */ public const HAS_MANY = [ 'l11n' => [ - 'mapper' => ClientAttributeTypeL11nMapper::class, - 'table' => 'clientmgmt_attr_type_l11n', - 'self' => 'clientmgmt_attr_type_l11n_type', - 'column' => 'content', - 'external' => null, + 'mapper' => ClientAttributeTypeL11nMapper::class, + 'table' => 'clientmgmt_attr_type_l11n', + 'self' => 'clientmgmt_attr_type_l11n_type', + 'column' => 'content', + 'external' => null, ], 'defaults' => [ - 'mapper' => ClientAttributeValueMapper::class, - 'table' => 'clientmgmt_client_attr_default', - 'self' => 'clientmgmt_client_attr_default_type', - 'external' => 'clientmgmt_client_attr_default_value', + 'mapper' => ClientAttributeValueMapper::class, + 'table' => 'clientmgmt_client_attr_default', + 'self' => 'clientmgmt_client_attr_default_type', + 'external' => 'clientmgmt_client_attr_default_value', ], ]; diff --git a/Models/Attribute/ClientAttributeValueL11nMapper.php b/Models/Attribute/ClientAttributeValueL11nMapper.php index 747712a..11d4f6b 100644 --- a/Models/Attribute/ClientAttributeValueL11nMapper.php +++ b/Models/Attribute/ClientAttributeValueL11nMapper.php @@ -37,10 +37,10 @@ final class ClientAttributeValueL11nMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'clientmgmt_attr_value_l11n_id' => ['name' => 'clientmgmt_attr_value_l11n_id', 'type' => 'int', 'internal' => 'id'], - 'clientmgmt_attr_value_l11n_title' => ['name' => 'clientmgmt_attr_value_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], - 'clientmgmt_attr_value_l11n_value' => ['name' => 'clientmgmt_attr_value_l11n_value', 'type' => 'int', 'internal' => 'ref'], - 'clientmgmt_attr_value_l11n_lang' => ['name' => 'clientmgmt_attr_value_l11n_lang', 'type' => 'string', 'internal' => 'language'], + 'clientmgmt_attr_value_l11n_id' => ['name' => 'clientmgmt_attr_value_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'clientmgmt_attr_value_l11n_title' => ['name' => 'clientmgmt_attr_value_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'clientmgmt_attr_value_l11n_value' => ['name' => 'clientmgmt_attr_value_l11n_value', 'type' => 'int', 'internal' => 'ref'], + 'clientmgmt_attr_value_l11n_lang' => ['name' => 'clientmgmt_attr_value_l11n_lang', 'type' => 'string', 'internal' => 'language'], ]; /** diff --git a/Models/Attribute/ClientAttributeValueMapper.php b/Models/Attribute/ClientAttributeValueMapper.php index ce2a870..2fdcfe4 100644 --- a/Models/Attribute/ClientAttributeValueMapper.php +++ b/Models/Attribute/ClientAttributeValueMapper.php @@ -37,15 +37,15 @@ final class ClientAttributeValueMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'clientmgmt_attr_value_id' => ['name' => 'clientmgmt_attr_value_id', 'type' => 'int', 'internal' => 'id'], - 'clientmgmt_attr_value_default' => ['name' => 'clientmgmt_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'], - 'clientmgmt_attr_value_valueStr' => ['name' => 'clientmgmt_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'], - 'clientmgmt_attr_value_valueInt' => ['name' => 'clientmgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'], - 'clientmgmt_attr_value_valueDec' => ['name' => 'clientmgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'], - 'clientmgmt_attr_value_valueDat' => ['name' => 'clientmgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'], - 'clientmgmt_attr_value_unit' => ['name' => 'clientmgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'], - 'clientmgmt_attr_value_deptype' => ['name' => 'clientmgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'], - 'clientmgmt_attr_value_depvalue' => ['name' => 'clientmgmt_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'], + 'clientmgmt_attr_value_id' => ['name' => 'clientmgmt_attr_value_id', 'type' => 'int', 'internal' => 'id'], + 'clientmgmt_attr_value_default' => ['name' => 'clientmgmt_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'], + 'clientmgmt_attr_value_valueStr' => ['name' => 'clientmgmt_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'], + 'clientmgmt_attr_value_valueInt' => ['name' => 'clientmgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'], + 'clientmgmt_attr_value_valueDec' => ['name' => 'clientmgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'], + 'clientmgmt_attr_value_valueDat' => ['name' => 'clientmgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'], + 'clientmgmt_attr_value_unit' => ['name' => 'clientmgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'], + 'clientmgmt_attr_value_deptype' => ['name' => 'clientmgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'], + 'clientmgmt_attr_value_depvalue' => ['name' => 'clientmgmt_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'], ]; /** diff --git a/Models/Client.php b/Models/Client.php index 7f1f804..89cef44 100755 --- a/Models/Client.php +++ b/Models/Client.php @@ -17,8 +17,6 @@ namespace Modules\ClientManagement\Models; use Modules\Admin\Models\Account; use Modules\Editor\Models\EditorDoc; use Modules\Payment\Models\Payment; -use Modules\Profile\Models\ContactElement; -use Modules\Profile\Models\NullContactElement; use Modules\Profile\Models\Profile; use phpOMS\Stdlib\Base\Address; use phpOMS\Stdlib\Base\NullAddress; @@ -189,70 +187,6 @@ class Client $this->mainAddress = new NullAddress(); } - /** - * Get id. - * - * @return int Model id - * - * @since 1.0.0 - */ - public function getId() : int - { - return $this->id; - } - - /** - * 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; - } - - /** - * Get type. - * - * @return int - * - * @since 1.0.0 - */ - public function getType() : int - { - return $this->type; - } - - /** - * Set type. - * - * @param int $type Type - * - * @return void - * - * @since 1.0.0 - */ - public function setType(int $type) : void - { - $this->type = $type; - } - /** * Add doc to item * @@ -343,7 +277,7 @@ class Client $payments = []; foreach ($this->payments as $payment) { - if ($payment->getType() === $type) { + if ($payment->type === $type) { $payments[] = $payment; } } @@ -351,69 +285,6 @@ class Client return $payments; } - /** - * Get contacts. - * - * @return array - * - * @since 1.0.0 - */ - public function getContactElements() : array - { - return $this->contactElements; - } - - /** - * Order contact elements - * - * @param ContactElement $a Element - * @param ContactElement $b Element - * - * @return int - * - * @since 1.0.0 - */ - private function orderContactElements(ContactElement $a, ContactElement $b) : int - { - return $a->order <=> $b->order; - } - - /** - * Get the main contact element by type - * - * @param int $type Contact element type - * - * @return ContactElement - * - * @since 1.0.0 - */ - public function getMainContactElement(int $type) : ContactElement - { - \uasort($this->contactElements, [$this, 'orderContactElements']); - - foreach ($this->contactElements as $element) { - if ($element->getType() === $type) { - return $element; - } - } - - return new NullContactElement(); - } - - /** - * Add contact element - * - * @param int|ContactElement $element Contact element - * - * @return void - * - * @since 1.0.0 - */ - public function addContactElement($element) : void - { - $this->contactElements[] = $element; - } - /** * {@inheritdoc} */ diff --git a/Models/ClientL11nMapper.php b/Models/ClientL11nMapper.php index 446e505..278c28b 100755 --- a/Models/ClientL11nMapper.php +++ b/Models/ClientL11nMapper.php @@ -37,11 +37,11 @@ final class ClientL11nMapper extends DataMapperFactory * @since 1.0.0 */ public const COLUMNS = [ - 'clientmgmt_client_l11n_id' => ['name' => 'clientmgmt_client_l11n_id', 'type' => 'int', 'internal' => 'id'], - 'clientmgmt_client_l11n_description' => ['name' => 'clientmgmt_client_l11n_description', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], - 'clientmgmt_client_l11n_client' => ['name' => 'clientmgmt_client_l11n_client', 'type' => 'int', 'internal' => 'ref'], - 'clientmgmt_client_l11n_lang' => ['name' => 'clientmgmt_client_l11n_lang', 'type' => 'string', 'internal' => 'language'], - 'clientmgmt_client_l11n_typeref' => ['name' => 'clientmgmt_client_l11n_typeref', 'type' => 'int', 'internal' => 'type'], + 'clientmgmt_client_l11n_id' => ['name' => 'clientmgmt_client_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'clientmgmt_client_l11n_description' => ['name' => 'clientmgmt_client_l11n_description', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'clientmgmt_client_l11n_client' => ['name' => 'clientmgmt_client_l11n_client', 'type' => 'int', 'internal' => 'ref'], + 'clientmgmt_client_l11n_lang' => ['name' => 'clientmgmt_client_l11n_lang', 'type' => 'string', 'internal' => 'language'], + 'clientmgmt_client_l11n_typeref' => ['name' => 'clientmgmt_client_l11n_typeref', 'type' => 'int', 'internal' => 'type'], ]; /** diff --git a/Models/ClientMapper.php b/Models/ClientMapper.php index eb3629e..aa664b0 100755 --- a/Models/ClientMapper.php +++ b/Models/ClientMapper.php @@ -20,10 +20,7 @@ use Modules\ClientManagement\Models\Attribute\ClientAttributeMapper; use Modules\Editor\Models\EditorDocMapper; use Modules\Media\Models\MediaMapper; use Modules\Payment\Models\PaymentMapper; -use Modules\Profile\Models\ContactElementMapper; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; -use phpOMS\DataStorage\Database\Query\Builder; -use phpOMS\Stdlib\Base\FloatInt; /** * Client mapper class. @@ -105,24 +102,18 @@ final class ClientMapper extends DataMapperFactory * @since 1.0.0 */ public const HAS_MANY = [ - 'files' => [ + 'files' => [ 'mapper' => MediaMapper::class, /* mapper of the related object */ 'table' => 'clientmgmt_client_media', /* table of the related object, null if no relation table is used (many->1) */ 'external' => 'clientmgmt_client_media_dst', 'self' => 'clientmgmt_client_media_src', ], - 'notes' => [ + 'notes' => [ 'mapper' => EditorDocMapper::class, /* mapper of the related object */ 'table' => 'clientmgmt_client_note', /* table of the related object, null if no relation table is used (many->1) */ 'external' => 'clientmgmt_client_note_dst', 'self' => 'clientmgmt_client_note_src', ], - 'contactElements' => [ - 'mapper' => ContactElementMapper::class, - 'table' => 'clientmgmt_client_contactelement', - 'external' => 'clientmgmt_client_contactelement_dst', - 'self' => 'clientmgmt_client_contactelement_src', - ], 'payments' => [ 'mapper' => PaymentMapper::class, 'table' => 'clientmgmt_client_payment', @@ -130,10 +121,10 @@ final class ClientMapper extends DataMapperFactory 'self' => 'clientmgmt_client_payment_src', ], 'attributes' => [ - 'mapper' => ClientAttributeMapper::class, - 'table' => 'clientmgmt_client_attr', - 'self' => 'clientmgmt_client_attr_client', - 'external' => null, + 'mapper' => ClientAttributeMapper::class, + 'table' => 'clientmgmt_client_attr', + 'self' => 'clientmgmt_client_attr_client', + 'external' => null, ], ]; } diff --git a/Theme/Backend/Lang/de.lang.php b/Theme/Backend/Lang/de.lang.php index da9dd39..c57b693 100755 --- a/Theme/Backend/Lang/de.lang.php +++ b/Theme/Backend/Lang/de.lang.php @@ -13,118 +13,118 @@ declare(strict_types=1); return ['ClientManagement' => [ - 'Accounting' => 'Buchhaltung', - 'Addition' => 'Zusatz', - 'Address' => 'Adresse', - 'Bill' => 'Rechnung', - 'Addresses' => 'Adressen', - 'AreaManager' => 'Bereichsleiter', - 'Articlegroup' => 'ArtikelGroup.', - 'AttributeTypes' => 'Attributtypen', - 'Balance' => 'Gleichgewicht', - 'Bills' => 'Rechnungen', - 'Bonus' => 'Bonus', - 'CLV' => 'CLV', - 'City' => 'Stadt', - 'Client' => 'Kunde', - 'Clients' => 'Kunden', - 'Contact' => 'Kontakt', - 'Country' => 'Land', - 'Created' => 'Erstellt', - 'CreatedAt' => 'Erstellt', - 'Creditcard' => 'Kreditkarte', - 'DSO' => 'DSO.', - 'Date' => 'Datum', - 'Default' => 'Standard', - 'Delivery' => 'Die Zustellung', - 'Discount' => 'Rabatt', - 'DiscountP' => 'Rabatt %', - 'Documents' => 'Dokumente', - 'Due' => 'Fällig', - 'Email' => 'Email', - 'Fax' => 'Fax', - 'Files' => 'Dateien', - 'Freightage' => 'Fracht', - 'Group' => 'Gruppe', - 'ID' => 'ID', - 'Info' => 'Die Info', - 'Invoice' => 'Rechnung', - 'IsDefault' => 'Ist standardmäßig?', - 'Items' => 'Artikel', - 'LastContact' => 'Letzter Kontakt', - 'LastOrder' => 'Letzte Bestellung', - 'Log' => 'Protokoll', - 'Logs' => 'Protokoll', - 'MTDSales' => 'Mtd. Sales', - 'Map' => 'Karte', - 'Margin' => 'Marge', - 'Name' => 'Name', - 'Name1' => 'Name1', - 'Name2' => 'Name2', - 'Name3' => 'Name3', - 'Net' => 'Netto', - 'Notes' => 'Notizen', - 'Number' => 'Nummer', - 'Office' => 'Sekretariat', - 'Payment' => 'Zahlung', - 'PaymentTerm' => 'Zahlungsbezeichnung', - 'Phone' => 'Telefon', - 'Postal' => 'Postleitzahl', - 'Price' => 'Preis', - 'Prices' => 'Preise', - 'Productgroup' => 'Produktgruppe', - 'Profile' => 'Profil', - 'Purchase' => 'Kaufen', - 'Quantity' => 'Menge', - 'RecentInvoices' => 'Neuste Rechnungen', - 'Region' => 'Region', - 'Sales' => 'Umsatz', - 'Segment' => 'Segment', - 'Segments' => 'Segmente', - 'Subtype' => 'Untertyp', - 'Support' => 'Support', - 'Title' => 'Titel', - 'TotalPrice' => 'Gesamtpreis', - 'Type' => 'Typ', - 'UnitPrice' => 'Einheitspreis', - 'Website' => 'Webseite', - 'Wire' => 'Kabel', - 'YTDSales' => 'Ytd Sales', - 'Zip' => 'Postleitzahl', - 'ItemProductGroup' => 'Artikel Produktgruppe', - 'ItemSalesGroup' => 'Artikel Umsatzgruppe', - 'Promocode' => 'Promocode', - 'Region' => 'Region', - 'Materials' => 'Materialien', - 'Weight' => 'Gewicht', - 'Depth' => 'Tiefe', - 'WidthLength' => 'Breite/Länge', - 'MaximumOrderInterval' => 'Maximales Bestellintervall', - 'MinimumOrderQuantity' => 'Mindestbestellmenge', - 'PrimarySupplier' => 'Hauptlieferant', - 'LeadTime' => 'Lieferzeit', - 'UnitQuantity' => 'Einheitsmenge', + 'Accounting' => 'Buchhaltung', + 'Addition' => 'Zusatz', + 'Address' => 'Adresse', + 'Bill' => 'Rechnung', + 'Addresses' => 'Adressen', + 'AreaManager' => 'Bereichsleiter', + 'Articlegroup' => 'ArtikelGroup.', + 'AttributeTypes' => 'Attributtypen', + 'Balance' => 'Gleichgewicht', + 'Bills' => 'Rechnungen', + 'Bonus' => 'Bonus', + 'CLV' => 'CLV', + 'City' => 'Stadt', + 'Client' => 'Kunde', + 'Clients' => 'Kunden', + 'Contact' => 'Kontakt', + 'Country' => 'Land', + 'Created' => 'Erstellt', + 'CreatedAt' => 'Erstellt', + 'Creditcard' => 'Kreditkarte', + 'DSO' => 'DSO.', + 'Date' => 'Datum', + 'Default' => 'Standard', + 'Delivery' => 'Die Zustellung', + 'Discount' => 'Rabatt', + 'DiscountP' => 'Rabatt %', + 'Documents' => 'Dokumente', + 'Due' => 'Fällig', + 'Email' => 'Email', + 'Fax' => 'Fax', + 'Files' => 'Dateien', + 'Freightage' => 'Fracht', + 'Group' => 'Gruppe', + 'ID' => 'ID', + 'Info' => 'Die Info', + 'Invoice' => 'Rechnung', + 'IsDefault' => 'Ist standardmäßig?', + 'Items' => 'Artikel', + 'LastContact' => 'Letzter Kontakt', + 'LastOrder' => 'Letzte Bestellung', + 'Log' => 'Protokoll', + 'Logs' => 'Protokoll', + 'MTDSales' => 'Mtd. Sales', + 'Map' => 'Karte', + 'Margin' => 'Marge', + 'Name' => 'Name', + 'Name1' => 'Name1', + 'Name2' => 'Name2', + 'Name3' => 'Name3', + 'Net' => 'Netto', + 'Notes' => 'Notizen', + 'Number' => 'Nummer', + 'Office' => 'Sekretariat', + 'Payment' => 'Zahlung', + 'PaymentTerm' => 'Zahlungsbezeichnung', + 'Phone' => 'Telefon', + 'Postal' => 'Postleitzahl', + 'Price' => 'Preis', + 'Prices' => 'Preise', + 'Productgroup' => 'Produktgruppe', + 'Profile' => 'Profil', + 'Purchase' => 'Kaufen', + 'Quantity' => 'Menge', + 'RecentInvoices' => 'Neuste Rechnungen', + 'Region' => 'Region', + 'Sales' => 'Umsatz', + 'Segment' => 'Segment', + 'Segments' => 'Segmente', + 'Subtype' => 'Untertyp', + 'Support' => 'Support', + 'Title' => 'Titel', + 'TotalPrice' => 'Gesamtpreis', + 'Type' => 'Typ', 'UnitPrice' => 'Einheitspreis', - 'Lieferanten' => 'Lieferanten', - 'CostCenter' => 'Kostenstelle', - 'CostObject' => 'Kostenträger', - 'DefaultStock' => 'Standard Lager', - 'DefaultStockLocation' => 'Standard Lagerplatz', + 'Website' => 'Webseite', + 'Wire' => 'Kabel', + 'YTDSales' => 'Ytd Sales', + 'Zip' => 'Postleitzahl', + 'ItemProductGroup' => 'Artikel Produktgruppe', + 'ItemSalesGroup' => 'Artikel Umsatzgruppe', + 'Promocode' => 'Promocode', + 'Region' => 'Region', + 'Materials' => 'Materialien', + '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', 'Inventory' => 'Bestandsführung', - 'Identifier' => 'Identifizierung', - 'Stocktaking' => 'Inventur', - 'Pricing' => 'Pricing', - 'Start' => 'Start', - 'End' => 'End', - 'ItemSegment' => 'Artikelsegment', - 'ClientSegment' => 'Kundensegment', - 'ItemSection' => 'Artikelsparte', - 'ClientSection' => 'Kundensparte', - 'ItemSalesGroup' => 'Artikel Umsatzgruppe', - 'ClientGroup' => 'Kundengruppe', - 'ClientType' => 'Kundenart', - 'ItemType' => 'Artikeltyp', - 'Item' => 'Item', - 'EarningIndicator' => 'Erlöskennzeichen', - 'CostIndicator' => 'Kostenkennzeichen', + 'Identifier' => 'Identifizierung', + 'Stocktaking' => 'Inventur', + 'Pricing' => 'Pricing', + 'Start' => 'Start', + 'End' => 'End', + 'ItemSegment' => 'Artikelsegment', + 'ClientSegment' => 'Kundensegment', + 'ItemSection' => 'Artikelsparte', + 'ClientSection' => 'Kundensparte', + 'ItemSalesGroup' => 'Artikel Umsatzgruppe', + 'ClientGroup' => 'Kundengruppe', + 'ClientType' => 'Kundenart', + 'ItemType' => 'Artikeltyp', + 'Item' => 'Item', + 'EarningIndicator' => 'Erlöskennzeichen', + 'CostIndicator' => 'Kostenkennzeichen', ]]; diff --git a/Theme/Backend/Lang/en.lang.php b/Theme/Backend/Lang/en.lang.php index 0273c1a..7dbd990 100755 --- a/Theme/Backend/Lang/en.lang.php +++ b/Theme/Backend/Lang/en.lang.php @@ -13,118 +13,120 @@ declare(strict_types=1); return ['ClientManagement' => [ - 'Accounting' => 'Accounting', - 'Addition' => 'Addition', - 'Address' => 'Address', - 'Bill' => 'Bill', - 'Addresses' => 'Addresses', - 'AreaManager' => 'Area Manager', - 'Articlegroup' => 'Articlegroup', - 'AttributeTypes' => 'Attribute Types', - 'Balance' => 'Balance', - 'Bills' => 'Bills', - 'Bonus' => 'Bonus', - 'CLV' => 'CLV', - 'City' => 'City', - 'Client' => 'Client', - 'Clients' => 'Clients', - 'Contact' => 'Contact', - 'Country' => 'Country', - 'Created' => 'Created', - 'CreatedAt' => 'Created at', - 'Creditcard' => 'Creditcard', - 'DSO' => 'DSO', - 'Date' => 'Date', - 'Default' => 'Default', - 'Delivery' => 'Delivery', - 'Discount' => 'Discount', - 'DiscountP' => 'Discount %', - 'Documents' => 'Documents', - 'Due' => 'Due', - 'Email' => 'Email', - 'Fax' => 'Fax', - 'Files' => 'Files', - 'Freightage' => 'Freightage', - 'Group' => 'Group', - 'ID' => 'ID', - 'Info' => 'Info', - 'Invoice' => 'Invoice', - 'IsDefault' => 'Is default?', - 'Items' => 'Items', - 'LastContact' => 'Last Contact', - 'LastOrder' => 'Last Order', - 'Log' => 'Log', - 'Logs' => 'Logs', - 'MTDSales' => 'MTD Sales', - 'Map' => 'Map', - 'Margin' => 'Margin', - 'Name' => 'Name', - 'Name1' => 'Name1', - 'Name2' => 'Name2', - 'Name3' => 'Name3', - 'Net' => 'Net', - 'Notes' => 'Notes', - 'Number' => 'Number', - 'Office' => 'Office', - 'Payment' => 'Payment', - 'PaymentTerm' => 'Payment Term', - 'Phone' => 'Phone', - 'Postal' => 'Postal', - 'Price' => 'Price', - 'Prices' => 'Prices', - 'Productgroup' => 'Productgroup', - 'Profile' => 'Profile', - 'Purchase' => 'Purchase', - 'Quantity' => 'Quantity', - 'RecentInvoices' => 'Recent Invoices', - 'Region' => 'Region', - 'Sales' => 'Sales', - 'Segment' => 'Segment', - 'Segments' => 'Segments', - 'Subtype' => 'Subtype', - 'Support' => 'Support', - 'Title' => 'Title', - 'TotalPrice' => 'Total price', - 'Type' => 'Type', - 'UnitPrice' => 'Unit price', - 'Website' => 'Website', - 'Wire' => 'Wire', - 'YTDSales' => 'YTD Sales', - 'Zip' => 'Zip', - 'ItemProductGroup' => 'Item Product Group', - 'ItemSalesGroup' => 'Item Sales Group', + 'Account' => 'Account', + 'Accounting' => 'Accounting', + 'Addition' => 'Addition', + 'Address' => 'Address', + 'Bill' => 'Bill', + 'Addresses' => 'Addresses', + 'AreaManager' => 'Area Manager', + 'Articlegroup' => 'Article group', + 'AttributeTypes' => 'Attribute Types', + 'Balance' => 'Balance', + 'Bills' => 'Bills', + 'Bonus' => 'Bonus', + 'CLV' => 'CLV', + 'City' => 'City', + 'Client' => 'Client', + 'Clients' => 'Clients', + 'Contact' => 'Contact', + 'Country' => 'Country', + 'Created' => 'Created', + 'CreateBill' => 'Create Bill', + 'CreatedAt' => 'Created at', + 'Creditcard' => 'Creditcard', + 'DSO' => 'DSO', + 'Date' => 'Date', + 'Default' => 'Default', + 'Delivery' => 'Delivery', + 'Discount' => 'Discount', + 'DiscountP' => 'Discount %', + 'Documents' => 'Documents', + 'Due' => 'Due', + 'Email' => 'Email', + 'Fax' => 'Fax', + 'Files' => 'Files', + 'Freightage' => 'Freightage', + 'Group' => 'Group', + 'ID' => 'ID', + 'Info' => 'Info', + 'Invoice' => 'Invoice', + 'IsDefault' => 'Is default?', + 'Items' => 'Items', + 'LastContact' => 'Last Contact', + 'LastOrder' => 'Last Order', + 'Log' => 'Log', + 'Logs' => 'Logs', + 'MTDSales' => 'MTD Sales', + 'Map' => 'Map', + 'Margin' => 'Margin', + 'Name' => 'Name', + 'Name1' => 'Name1', + 'Name2' => 'Name2', + 'Name3' => 'Name3', + 'Net' => 'Net', + 'Notes' => 'Notes', + 'Number' => 'Number', + 'Office' => 'Office', + 'Payment' => 'Payment', + 'PaymentTerm' => 'Payment Term', + 'Phone' => 'Phone', + 'Postal' => 'Postal', + 'Price' => 'Price', + 'Prices' => 'Prices', + 'Productgroup' => 'Product group', + 'Profile' => 'Profile', + 'Purchase' => 'Purchase', + 'Quantity' => 'Quantity', + 'RecentInvoices' => 'Recent Invoices', + 'Region' => 'Region', + 'Sales' => 'Sales', + 'Segment' => 'Segment', + 'Segments' => 'Segments', + 'Subtype' => 'Subtype', + 'Support' => 'Support', + 'Title' => 'Title', + 'TotalPrice' => 'Total price', + 'Type' => 'Type', + 'UnitPrice' => 'Unit price', + 'Website' => 'Website', + 'Wire' => 'Wire', + 'YTDSales' => 'YTD Sales', + 'Zip' => 'Zip', + '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', - 'Pricing' => 'Pricing', - 'Start' => 'Start', - 'End' => 'End', - 'ItemSegment' => 'Item Segment', - 'ClientSegment' => 'Client Segment', - 'ItemSection' => 'Item Section', - 'ClientSection' => 'Client Section', - 'ItemSalesGroup' => 'Item Sales Group', - 'ClientGroup' => 'Client Group', - 'ClientType' => 'Client Type', - 'ItemType' => 'Item Type', - 'Item' => 'Item', - 'EarningIndicator' => 'Earning Indicator', - 'CostIndicator' => 'Cost Indicator', + 'Identifier' => 'Identifier', + 'Stocktaking' => 'Stocktaking', + 'Pricing' => 'Pricing', + 'Start' => 'Start', + 'End' => 'End', + 'ItemSegment' => 'Item Segment', + 'ClientSegment' => 'Client Segment', + 'ItemSection' => 'Item Section', + 'ClientSection' => 'Client Section', + 'ItemSalesGroup' => 'Item Sales Group', + 'ClientGroup' => 'Client Group', + 'ClientType' => 'Client Type', + 'ItemType' => 'Item Type', + 'Item' => 'Item', + 'EarningIndicator' => 'Earning Indicator', + 'CostIndicator' => 'Cost Indicator', ]]; 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(); ?>