diff --git a/Admin/Install/Search.php b/Admin/Install/Search.php new file mode 100644 index 0000000..31a2a40 --- /dev/null +++ b/Admin/Install/Search.php @@ -0,0 +1,43 @@ + __DIR__ . '/SearchCommands.php']); + } +} diff --git a/Admin/Install/SearchCommands.php b/Admin/Install/SearchCommands.php new file mode 100644 index 0000000..76563e9 --- /dev/null +++ b/Admin/Install/SearchCommands.php @@ -0,0 +1,32 @@ + [ + [ + 'dest' => '\Modules\ClientManagement\Controller\SearchController:searchGeneral', + 'verb' => RouteVerb::ANY, + 'permission' => [ + 'module' => SearchController::NAME, + 'type' => PermissionType::READ, + 'state' => PermissionCategory::CLIENT, + ], + ], + ], +]; diff --git a/Admin/Install/attributes.json b/Admin/Install/attributes.json index ba63a1f..6cc8544 100755 --- a/Admin/Install/attributes.json +++ b/Admin/Install/attributes.json @@ -6,7 +6,7 @@ "de": "Bewertung" }, "value_type": 2, - "is_custom_allowed": true, + "is_custom_allowed": false, "validation_pattern": "", "is_required": false, "default_value": "", @@ -55,23 +55,40 @@ } ] }, + { + "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": { "en": "Send bills as emails", "de": "Sende Rechnungen als Email" }, - "value_type": 1, + "value_type": 5, "is_custom_allowed": false, "validation_pattern": "", "is_required": false, "default_value": 1, "values": [ { - "value": 0 + "value": false }, { - "value": 1 + "value": true } ] }, @@ -88,6 +105,39 @@ "default_value": "", "values": [] }, + { + "name": "support_emails", + "l11n": { + "en": "Send support as emails", + "de": "Sende Support als Email" + }, + "value_type": 5, + "is_custom_allowed": false, + "validation_pattern": "", + "is_required": false, + "default_value": true, + "values": [ + { + "value": false + }, + { + "value": true + } + ] + }, + { + "name": "support_email_address", + "l11n": { + "en": "Email address for support", + "de": "Emailadresse für Support" + }, + "value_type": 2, + "is_custom_allowed": true, + "validation_pattern": "", + "is_required": false, + "default_value": "", + "values": [] + }, { "name": "segment", "l11n": { diff --git a/Admin/Install/db.json b/Admin/Install/db.json index d613024..ec5e8f9 100755 --- a/Admin/Install/db.json +++ b/Admin/Install/db.json @@ -12,8 +12,7 @@ "clientmgmt_client_no": { "name": "clientmgmt_client_no", "type": "VARCHAR(255)", - "null": false, - "unique": true + "null": false }, "clientmgmt_client_no_reverse": { "name": "clientmgmt_client_no_reverse", diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 1891cb9..0fede79 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -283,6 +283,9 @@ final class ApiController extends Controller $account = new NullAccount((int) $request->getData('account')); } + // @feature Create a way to let admins create a default account format for clients/suppliers + // https://github.com/Karaka-Management/oms-ClientManagement/issues/19 + $client = new Client(); $client->number = $request->getDataString('number') ?? ''; $client->account = $account; @@ -537,7 +540,7 @@ final class ApiController extends Controller return; } - $uploaded = $this->app->moduleManager->get('Media')->uploadFiles( + $uploaded = $this->app->moduleManager->get('Media', 'Api')->uploadFiles( names: $request->getDataList('names'), fileNames: $request->getDataList('filenames'), files: $uploadedFiles, diff --git a/Controller/BackendController.php b/Controller/BackendController.php index d312b2a..de84772 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -257,10 +257,8 @@ final class BackendController extends Controller ->execute(); // 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. - // ItemManagement::getRelations()->with('types')->where(...); - // This should return the relations and NOT the model itself + // @feature Create a new read mapper function that returns relation models instead of its own model + // https://github.com/Karaka-Management/phpOMS/issues/320 $query = new Builder($this->app->dbPool->get()); $results = $query->selectAs(ClientMapper::HAS_MANY['files']['external'], 'file') ->from(ClientMapper::TABLE) @@ -276,7 +274,6 @@ final class BackendController extends Controller ->where(MediaTypeMapper::TABLE . '.' . MediaTypeMapper::getColumnByMember('name'), '=', 'client_profile_image'); $view->data['clientImage'] = MediaMapper::get() - ->with('types') ->where('id', $results) ->limit(1) ->execute(); diff --git a/Controller/SearchController.php b/Controller/SearchController.php new file mode 100644 index 0000000..40d6e25 --- /dev/null +++ b/Controller/SearchController.php @@ -0,0 +1,111 @@ +getDataString('search') ?? '')); + $names[] = ($request->getDataString('search') ?? ''); + + $mapper = ClientMapper::getAll() + ->with('account') + ->with('mainAddress') + ->with('account/contacts') + ->limit(8); + + foreach ($names as $name) { + $mapper->where('account/login', '%' . $name . '%', 'LIKE', 'OR') + ->where('account/name1', '%' . $name . '%', 'LIKE', 'OR') + ->where('account/name2', '%' . $name . '%', 'LIKE', 'OR') + ->where('account/name3', '%' . $name . '%', 'LIKE', 'OR'); + } + + /** @var \Modules\ClientManagement\Models\Client[] $accounts */ + $accounts = $mapper->execute(); + + $results = []; + foreach ($accounts as $account) { + // Get item profile image + // @feature Create a new read mapper function that returns relation models instead of its own model + // https://github.com/Karaka-Management/phpOMS/issues/320 + $query = new Builder($this->app->dbPool->get()); + $iResults = $query->selectAs(ClientMapper::HAS_MANY['files']['external'], 'file') + ->from(ClientMapper::TABLE) + ->leftJoin(ClientMapper::HAS_MANY['files']['table']) + ->on(ClientMapper::HAS_MANY['files']['table'] . '.' . ClientMapper::HAS_MANY['files']['self'], '=', ClientMapper::TABLE . '.' . ClientMapper::PRIMARYFIELD) + ->leftJoin(MediaMapper::TABLE) + ->on(ClientMapper::HAS_MANY['files']['table'] . '.' . ClientMapper::HAS_MANY['files']['external'], '=', MediaMapper::TABLE . '.' . MediaMapper::PRIMARYFIELD) + ->leftJoin(MediaMapper::HAS_MANY['types']['table']) + ->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'], '=', $account->id) + ->where(MediaTypeMapper::TABLE . '.' . MediaTypeMapper::getColumnByMember('name'), '=', 'client_profile_image'); + + $image = MediaMapper::get() + ->where('id', $iResults) + ->limit(1) + ->execute(); + + $results[] = [ + 'title' => $account->account->name1 . ' ' . $account->account->name2, + 'link' => '{/base}/sales/client/view?id=' . $account->id, + 'email' => $account->account->getContactByType(ContactType::EMAIL)->content, + 'phone' => $account->account->getContactByType(ContactType::PHONE)->content, + 'city' => $account->mainAddress?->city, + 'image' => $image->id === 0 + ? 'Web/Backend/img/logo_grey.png' + : $image->getPath(), + 'type' => 'list_accounts', + 'module' => 'Client Management', + ]; + } + + $response->header->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true); + $response->add($request->uri->__toString(), $results); + } +} diff --git a/Theme/Backend/client-view.tpl.php b/Theme/Backend/client-view.tpl.php index f789c33..1bbc0fb 100644 --- a/Theme/Backend/client-view.tpl.php +++ b/Theme/Backend/client-view.tpl.php @@ -13,6 +13,7 @@ declare(strict_types=1); use Modules\Admin\Models\ContactType; +use Modules\Billing\Models\BillMapper; use Modules\Billing\Models\Price\PriceType; use Modules\Billing\Models\SalesBillMapper; use Modules\Media\Models\NullMedia; @@ -928,7 +929,14 @@ echo $this->data['nav']->render(); getHtml('Date'); ?> id, SmartDateTime::startOfYear($this->data['business_start']), new SmartDateTime('now')); + $allInvoices = BillMapper::getAll() + ->with('type') + ->with('type/l11n') + ->where('client', $client->id) + ->where('type/l11n/language', $this->response->header->l11n->language) + ->where('billDate', SmartDateTime::startOfYear($this->data['business_start']), '>=') + ->where('billDate', new \DateTime('now'), '<=') + ->execute(); $count = 0; /** @var \Modules\Billing\Models\Bill $invoice */ diff --git a/info.json b/info.json index 6274b14..efcff81 100755 --- a/info.json +++ b/info.json @@ -25,7 +25,8 @@ "Navigation": "*", "Editor": "*", "Media": "*", - "Admin": "*" + "Admin": "*", + "Search": "*" }, "load": [ {