diff --git a/Admin/Install/Admin.install.php b/Admin/Install/Admin.install.php index dac901a..bbd3467 100644 --- a/Admin/Install/Admin.install.php +++ b/Admin/Install/Admin.install.php @@ -24,4 +24,12 @@ return [ 'pattern' => '', 'module' => ApiController::NAME, ], + [ + "description" => "Default item segmentation (segment, section, sales group, product group)", + 'type' => 'setting', + 'name' => SettingsEnum::CLIENT_AREA, + 'content' => '[]', + 'pattern' => '', + 'module' => ApiController::NAME, + ], ]; diff --git a/Admin/Install/Navigation.install.json b/Admin/Install/Navigation.install.json index d12eee9..9fa0ed8 100755 --- a/Admin/Install/Navigation.install.json +++ b/Admin/Install/Navigation.install.json @@ -37,7 +37,7 @@ "uri": "{/base}/sales/client/create", "target": "self", "icon": null, - "order": 1, + "order": 5, "from": "ClientManagement", "permission": { "permission": 4, "category": null, "element": null }, "parent": 1003102001, diff --git a/Admin/Install/attributes.json b/Admin/Install/attributes.json index 6fe98d6..9abf5cd 100755 --- a/Admin/Install/attributes.json +++ b/Admin/Install/attributes.json @@ -55,23 +55,6 @@ } ] }, - { - "name": "client_area", - "l11n": { - "en": "Client area", - "de": "Kundengebiet" - }, - "value_type": 2, - "is_custom_allowed": false, - "validation_pattern": "", - "is_required": false, - "default_value": "01", - "values": [ - { - "value": "01" - } - ] - }, { "name": "bill_emails", "l11n": { diff --git a/Admin/Install/db.json b/Admin/Install/db.json index ec5e8f9..c2e413f 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -39,6 +39,14 @@ "type": "DATETIME", "null": false }, + "clientmgmt_client_rep": { + "name": "clientmgmt_client_rep", + "type": "INT", + "null": true, + "default": null, + "foreignTable": "sales_rep", + "foreignKey": "sales_rep_id" + }, "clientmgmt_client_account": { "name": "clientmgmt_client_account", "type": "INT", diff --git a/Admin/Routes/Web/Api.php b/Admin/Routes/Web/Api.php index e620faa..c452c46 100644 --- a/Admin/Routes/Web/Api.php +++ b/Admin/Routes/Web/Api.php @@ -31,7 +31,31 @@ return [ ], ], ], - '^.*/client/attribute$' => [ + '^.*/client(\?.*|$)$' => [ + [ + 'dest' => '\Modules\ClientManagement\Controller\ApiController:apiClientCreate', + 'verb' => RouteVerb::PUT, + 'csrf' => true, + 'active' => true, + 'permission' => [ + 'module' => ApiController::NAME, + 'type' => PermissionType::CREATE, + 'state' => PermissionCategory::CLIENT, + ], + ], + [ + 'dest' => '\Modules\ClientManagement\Controller\ApiController:apiClientUpdate', + 'verb' => RouteVerb::SET, + 'csrf' => true, + 'active' => true, + 'permission' => [ + 'module' => ApiController::NAME, + 'type' => PermissionType::MODIFY, + 'state' => PermissionCategory::CLIENT, + ], + ], + ], + '^.*/client/attribute(\?.*|$)$' => [ [ 'dest' => '\Modules\ClientManagement\Controller\ApiAttributeController:apiClientAttributeCreate', 'verb' => RouteVerb::PUT, @@ -39,7 +63,7 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, + 'type' => PermissionType::CREATE, 'state' => PermissionCategory::CLIENT, ], ], @@ -50,12 +74,12 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, + 'type' => PermissionType::MODIFY, 'state' => PermissionCategory::CLIENT, ], ], ], - '^.*/client/attribute/type$' => [ + '^.*/client/attribute/type(\?.*|$)$' => [ [ 'dest' => '\Modules\ClientManagement\Controller\ApiAttributeController:apiClientAttributeTypeCreate', 'verb' => RouteVerb::PUT, @@ -64,7 +88,7 @@ return [ 'permission' => [ 'module' => ApiController::NAME, 'type' => PermissionType::READ, - 'state' => PermissionCategory::CLIENT, + 'state' => PermissionCategory::ATTRIBUTE, ], ], [ @@ -75,11 +99,11 @@ return [ 'permission' => [ 'module' => ApiController::NAME, 'type' => PermissionType::READ, - 'state' => PermissionCategory::CLIENT, + 'state' => PermissionCategory::ATTRIBUTE, ], ], ], - '^.*/client/attribute/type/l11n$' => [ + '^.*/client/attribute/type/l11n(\?.*|$)$' => [ [ 'dest' => '\Modules\ClientManagement\Controller\ApiAttributeController:apiClientAttributeTypeL11nCreate', 'verb' => RouteVerb::PUT, @@ -87,8 +111,8 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, - 'state' => PermissionCategory::CLIENT, + 'type' => PermissionType::CREATE, + 'state' => PermissionCategory::ATTRIBUTE, ], ], [ @@ -98,12 +122,12 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, - 'state' => PermissionCategory::CLIENT, + 'type' => PermissionType::MODIFY, + 'state' => PermissionCategory::ATTRIBUTE, ], ], ], - '^.*/client/attribute/value$' => [ + '^.*/client/attribute/value(\?.*|$)$' => [ [ 'dest' => '\Modules\ClientManagement\Controller\ApiAttributeController:apiClientAttributeValueCreate', 'verb' => RouteVerb::PUT, @@ -111,7 +135,7 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, + 'type' => PermissionType::CREATE, 'state' => PermissionCategory::CLIENT, ], ], @@ -122,12 +146,12 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, + 'type' => PermissionType::MODIFY, 'state' => PermissionCategory::CLIENT, ], ], ], - '^.*/client/attribute/value/l11n$' => [ + '^.*/client/attribute/value/l11n(\?.*|$)$' => [ [ 'dest' => '\Modules\ClientManagement\Controller\ApiAttributeController:apiClientAttributeValueL11nCreate', 'verb' => RouteVerb::PUT, @@ -135,7 +159,7 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, + 'type' => PermissionType::CREATE, 'state' => PermissionCategory::CLIENT, ], ], @@ -146,12 +170,12 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, + 'type' => PermissionType::MODIFY, 'state' => PermissionCategory::CLIENT, ], ], ], - '^.*/client/l11n$' => [ + '^.*/client/l11n(\?.*|$)$' => [ [ 'dest' => '\Modules\ClientManagement\Controller\ApiController:apiClientL11nCreate', 'verb' => RouteVerb::PUT, @@ -159,7 +183,7 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, + 'type' => PermissionType::CREATE, 'state' => PermissionCategory::CLIENT, ], ], @@ -170,12 +194,12 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, + 'type' => PermissionType::MODIFY, 'state' => PermissionCategory::CLIENT, ], ], ], - '^.*/client/l11n/type$' => [ + '^.*/client/l11n/type(\?.*|$)$' => [ [ 'dest' => '\Modules\ClientManagement\Controller\ApiController:apiClientL11nTypeCreate', 'verb' => RouteVerb::PUT, @@ -183,7 +207,7 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, + 'type' => PermissionType::CREATE, 'state' => PermissionCategory::CLIENT, ], ], @@ -194,7 +218,7 @@ return [ 'active' => true, 'permission' => [ 'module' => ApiController::NAME, - 'type' => PermissionType::READ, + 'type' => PermissionType::MODIFY, 'state' => PermissionCategory::CLIENT, ], ], diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 1a9307b..670a463 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -31,6 +31,7 @@ use Modules\Media\Models\Collection; use Modules\Media\Models\CollectionMapper; use Modules\Media\Models\PathSettings; use Modules\Organization\Models\UnitMapper; +use Modules\Sales\Models\NullSalesRep; use phpOMS\Account\PermissionType; use phpOMS\Api\EUVAT\EUVATVies; use phpOMS\Localization\BaseStringL11n; @@ -372,6 +373,7 @@ final class ApiController extends Controller $client = new Client(); $client->number = $request->getDataString('number') ?? ''; $client->account = $account; + $client->rep = $request->hasData('rep') ? new NullSalesRep((int) $request->getData('rep')) : null; $client->unit = $request->getDataInt('unit') ?? $this->app->unitId; $request->setData('name', null, true); diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 6ecd48d..9745e80 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -30,6 +30,7 @@ use phpOMS\Asset\AssetType; use phpOMS\Contract\RenderableInterface; use phpOMS\DataStorage\Database\Query\Builder; use phpOMS\DataStorage\Database\Query\OrderType; +use phpOMS\Math\Geometry\Shape\D3\Sphere; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; use phpOMS\Utils\StringUtils; @@ -187,15 +188,27 @@ final class BackendController extends Controller $view->setTemplate('/Modules/ClientManagement/Theme/Backend/client-list'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1003102001, $request, $response); - /** @var \Modules\ClientManagement\Models\Client $client */ - $client = ClientMapper::getAll() + $mapper = ClientMapper::getAll() ->with('account') ->with('mainAddress') ->where('unit', $this->app->unitId) - ->limit(25) - ->executeGetArray(); + ->limit(25); - $view->data['client'] = $client; + if ($request->hasData('geo')) { + $geo = $request->getDataList('geo'); + + $locationBox = Sphere::boundingBox( + (float) $geo[0], (float) $geo[1], + $request->getDataFloat('radius') ?? 3000.0 + ); + + $mapper->where('lat', $locationBox['a']['lat'], '<')->where('lon', $locationBox['a']['lon'], '>') + ->where('lat', $locationBox['b']['lat'], '<')->where('lon', $locationBox['b']['lon'], '<') + ->where('lat', $locationBox['c']['lat'], '>')->where('lon', $locationBox['c']['lon'], '>') + ->where('lat', $locationBox['d']['lat'], '>')->where('lon', $locationBox['d']['lon'], '<'); + } + + $view->data['client'] = $mapper->executeGetArray(); return $view; } @@ -230,6 +243,22 @@ final class BackendController extends Controller * * @return RenderableInterface * + * @feature In the supplier and client view you should be able to select multiple bills and click print for printing + * https://github.com/Karaka-Management/oms-Billing/issues/35 + * + * @feature The send bill as email should have a global settings where you can either define a global email or + * empty = user specific email + * https://github.com/Karaka-Management/oms-Billing/issues/33 + * + * @feature Add list for top articles on profile page... important for customer calls + * https://github.com/Karaka-Management/oms-ClientManagement/issues/12 + * + * @feature Create easy way to create quick visitor reports (= maybe use notes for this with a type 'visit') + * https://github.com/Karaka-Management/oms-Sales/issues/2 + * + * @feature Allow to create visitor report on cell phone by using location matching (geolocation) + * https://github.com/Karaka-Management/oms-Sales/issues/3 + * * @since 1.0.0 * @codeCoverageIgnore */ @@ -269,11 +298,6 @@ final class BackendController extends Controller ->where($pkType, $pkValue) ->where('attributes/type/l11n/language', $response->header->l11n->language) ->where('attributes/value/l11n/language', [$response->header->l11n->language, null]) - /* - ->where('attributes/value/l11n', (new Where($this->app->dbPool->get())) - ->where(ClientAttributeValueL11nMapper::getColumnByMember('ref'), '=', null) - ->orWhere(ClientAttributeValueL11nMapper::getColumnByMember('language'), '=', $response->header->l11n->language)) - */ ->execute(); $view->data['attributeView'] = new \Modules\Attribute\Theme\Backend\Components\AttributeView($this->app->l11nManager, $request, $response); diff --git a/Models/Client.php b/Models/Client.php index d7fb2d6..14aafea 100755 --- a/Models/Client.php +++ b/Models/Client.php @@ -18,6 +18,7 @@ use Modules\Admin\Models\Account; use Modules\Editor\Models\EditorDoc; use Modules\Payment\Models\Payment; use Modules\Profile\Models\Profile; +use Modules\Sales\Models\SalesRep; use phpOMS\Stdlib\Base\Address; use phpOMS\Stdlib\Base\NullAddress; @@ -79,6 +80,8 @@ class Client */ public string $info = ''; + public ?SalesRep $rep = null; + /** * Creation date and time. * @@ -135,14 +138,6 @@ class Client */ public array $partners = []; - /** - * Sales representative. - * - * @var Profile|null - * @since 1.0.0 - */ - public ?Profile $salesRep = null; - /** * Advertisement material. * diff --git a/Models/ClientMapper.php b/Models/ClientMapper.php index 3f86a9c..42cbe67 100755 --- a/Models/ClientMapper.php +++ b/Models/ClientMapper.php @@ -20,6 +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\Sales\Models\SalesRepMapper; use phpOMS\DataStorage\Database\Mapper\DataMapperFactory; /** @@ -48,6 +49,7 @@ final class ClientMapper extends DataMapperFactory 'clientmgmt_client_status' => ['name' => 'clientmgmt_client_status', 'type' => 'int', 'internal' => 'status'], 'clientmgmt_client_type' => ['name' => 'clientmgmt_client_type', 'type' => 'int', 'internal' => 'type'], 'clientmgmt_client_info' => ['name' => 'clientmgmt_client_info', 'type' => 'string', 'internal' => 'info'], + 'clientmgmt_client_rep' => ['name' => 'clientmgmt_client_rep', 'type' => 'int', 'internal' => 'rep'], 'clientmgmt_client_created_at' => ['name' => 'clientmgmt_client_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt', 'readonly' => true], 'clientmgmt_client_account' => ['name' => 'clientmgmt_client_account', 'type' => 'int', 'internal' => 'account'], 'clientmgmt_client_address' => ['name' => 'clientmgmt_client_address', 'type' => 'int', 'internal' => 'mainAddress'], @@ -93,6 +95,10 @@ final class ClientMapper extends DataMapperFactory 'mapper' => AddressMapper::class, 'external' => 'clientmgmt_client_address', ], + 'rep' => [ + 'mapper' => SalesRepMapper::class, + 'external' => 'clientmgmt_client_rep', + ], ]; /** diff --git a/Models/SettingsEnum.php b/Models/SettingsEnum.php index d1bd935..a4a2899 100644 --- a/Models/SettingsEnum.php +++ b/Models/SettingsEnum.php @@ -27,4 +27,6 @@ use phpOMS\Stdlib\Base\Enum; abstract class SettingsEnum extends Enum { public const DEFAULT_SEGMENTATION = '1003100001'; + + public const CLIENT_AREA = '1003100002'; } diff --git a/Theme/Backend/Lang/Navigation.de.lang.php b/Theme/Backend/Lang/Navigation.de.lang.php index 34d4a37..c6ca394 100755 --- a/Theme/Backend/Lang/Navigation.de.lang.php +++ b/Theme/Backend/Lang/Navigation.de.lang.php @@ -16,4 +16,5 @@ return ['Navigation' => [ 'Client' => 'Kunde', 'Region' => 'Region', 'SalesRep' => 'Verkäufer', + 'Attributes' => 'Attribute', ]]; diff --git a/Theme/Backend/Lang/Navigation.en.lang.php b/Theme/Backend/Lang/Navigation.en.lang.php index c068a61..b8d8076 100755 --- a/Theme/Backend/Lang/Navigation.en.lang.php +++ b/Theme/Backend/Lang/Navigation.en.lang.php @@ -16,4 +16,5 @@ return ['Navigation' => [ 'Client' => 'Client', 'Region' => 'Region', 'SalesRep' => 'SalesRep', + 'Attributes' => 'Attributes', ]]; diff --git a/Theme/Backend/client-list.tpl.php b/Theme/Backend/client-list.tpl.php index cd5033c..3f644d9 100755 --- a/Theme/Backend/client-list.tpl.php +++ b/Theme/Backend/client-list.tpl.php @@ -22,7 +22,11 @@ echo $this->data['nav']->render(); ?>
-
getHtml('Clients'); ?>download
+
+ getHtml('Clients'); ?> + download + location_on +
diff --git a/Theme/Backend/client-view.tpl.php b/Theme/Backend/client-view.tpl.php index e33de14..d2c2e82 100644 --- a/Theme/Backend/client-view.tpl.php +++ b/Theme/Backend/client-view.tpl.php @@ -29,6 +29,8 @@ use phpOMS\Localization\RegionEnum; use phpOMS\Message\Http\HttpHeader; use phpOMS\Stdlib\Base\FloatInt; use phpOMS\Stdlib\Base\SmartDateTime; +use phpOMS\System\File\ExtensionType; +use phpOMS\System\File\FileUtils; use phpOMS\Uri\UriFactory; $countryCodes = ISO3166TwoEnum::getConstants(); @@ -49,6 +51,10 @@ $clientStatus = ClientStatus::getConstants(); $logs = $this->data['logs'] ?? []; +// @performance The client, supplier and item views should not use actual tabs but individual pages for better performance +// Tabs require too many models to be loaded. Implement and then use a tab navigation if it doesn't already exist. +// https://github.com/Karaka-Management/oms-ItemManagement/issues/13 + /** * @var \phpOMS\Views\View $this */ @@ -92,7 +98,10 @@ echo $this->data['nav']->render();
-
+ >
@@ -354,8 +363,10 @@ echo $this->data['nav']->render(); foreach ($client->files as $file) : ++$count; $url = UriFactory::build('{/base}/media/view?{?}&id=' . $file->id); + $extensionType = FileUtils::getExtensionType($value->extension); ?> -
+ >
name; ?> extension; ?> createdAt->format('Y-m-d'); ?> diff --git a/info.json b/info.json index efcff81..de5a9bf 100755 --- a/info.json +++ b/info.json @@ -18,6 +18,7 @@ "dependencies": { "Admin": "1.0.0", "Media": "1.0.0", + "Sales": "1.0.0", "Payment": "1.0.0", "Editor": "1.0.0" },