app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/attribute-type-list'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response); /** @var \Modules\Attribute\Models\AttributeType[] $attributes */ $attributes = ItemAttributeTypeMapper::getAll() ->with('l11n') ->where('l11n/language', $response->header->l11n->language) ->execute(); $view->data['attributes'] = $attributes; return $view; } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementAttributeValues(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/attribute-value-list'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response); /** @var \Modules\Attribute\Models\AttributeValue[] $attributes */ $attributes = ItemAttributeValueMapper::getAll() ->with('l11n') ->where('l11n/language', $response->header->l11n->language) ->execute(); $view->data['attributes'] = $attributes; return $view; } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementAttributeType(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/attribute-type'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response); /** @var \Modules\Attribute\Models\AttributeType $attribute */ $attribute = ItemAttributeTypeMapper::get() ->with('l11n') ->where('id', (int) $request->getData('id')) ->where('l11n/language', $response->header->l11n->language) ->execute(); $l11ns = ItemAttributeTypeL11nMapper::getAll() ->where('ref', $attribute->id) ->execute(); $view->data['attribute'] = $attribute; $view->data['l11ns'] = $l11ns; return $view; } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementAttributeValue(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/attribute-value'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response); /** @var \Modules\Attribute\Models\AttributeValue $attribute */ $attribute = ItemAttributeValueMapper::get() ->with('l11n') ->where('id', (int) $request->getData('id')) ->where('l11n/language', $response->header->l11n->language) ->execute(); $view->data['attribute'] = $attribute; return $view; } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementItemList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/item-list'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004801001, $request, $response); /** @var \Modules\ItemManagement\Models\Item[] $items */ $items = ItemMapper::getAll() ->with('l11n') ->with('l11n/type') ->with('files') ->with('files/types') ->where('l11n/language', $response->header->l11n->language) ->where('l11n/type/title', ['name1', 'name2', 'name3'], 'IN') ->where('files/types/name', 'item_profile_image') ->limit(50) ->execute(); $view->data['items'] = $items; return $view; } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementSalesList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { return $this->viewItemManagementItemList($request, $response, $data); } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementPurchaseList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { return $this->viewItemManagementItemList($request, $response, $data); } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementItemCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { return $this->viewItemManagementItem($request, $response, $data); } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementWarehousingList(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { return $this->viewItemManagementItemList($request, $response, $data); } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementSalesCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/item-create'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004805001, $request, $response); return $view; } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementPurchaseCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/item-create'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004806001, $request, $response); return $view; } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementWarehousingCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/item-create'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004807001, $request, $response); return $view; } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return View * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementItem(RequestAbstract $request, ResponseAbstract $response, $data = null) : View { $head = $response->data['Content']->head; $nonce = $this->app->appSettings->getOption('script-nonce'); $head->addAsset(AssetType::CSS, 'Resources/chartjs/chart.css'); $head->addAsset(AssetType::JSLATE, 'Resources/chartjs/chart.js', ['nonce' => $nonce]); $head->addAsset(AssetType::JSLATE, 'Modules/ItemManagement/Controller.js', ['nonce' => $nonce, 'type' => 'module']); $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/item-profile'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1004803001, $request, $response); /** @var \Modules\ItemManagement\Models\Item $item */ $item = ItemMapper::get() ->with('l11n') ->with('l11n/type') ->with('files') ->with('files/types') ->with('attributes') ->with('attributes/type') ->with('attributes/type/l11n') ->with('attributes/value') ->with('notes') ->where('id', (int) $request->getData('id')) ->where('l11n/language', $response->header->l11n->language) ->where('l11n/type/title', ['name1', 'name2', 'name3'], 'IN') ->where('attributes/type/l11n/language', $response->header->l11n->language) ->limit(5, 'files')->sort('files/id', OrderType::DESC) ->limit(5, 'notes')->sort('notes/id', OrderType::DESC) ->execute(); $view->data['item'] = $item; // 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 $query = new Builder($this->app->dbPool->get()); $results = $query->selectAs(ItemMapper::HAS_MANY['files']['external'], 'file') ->from(ItemMapper::TABLE) ->leftJoin(ItemMapper::HAS_MANY['files']['table']) ->on(ItemMapper::HAS_MANY['files']['table'] . '.' . ItemMapper::HAS_MANY['files']['self'], '=', ItemMapper::TABLE . '.' . ItemMapper::PRIMARYFIELD) ->leftJoin(MediaMapper::TABLE) ->on(ItemMapper::HAS_MANY['files']['table'] . '.' . ItemMapper::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(ItemMapper::HAS_MANY['files']['self'], '=', $item->id) ->where(MediaTypeMapper::TABLE . '.' . MediaTypeMapper::getColumnByMember('name'), '=', 'item_profile_image'); /** @var \Modules\Media\Models\Media $itemImage */ $itemImage = MediaMapper::get() ->with('types') ->where('id', $results) ->limit(1) ->execute(); $view->data['itemImage'] = $itemImage; $businessStart = UnitAttributeMapper::get() ->with('type') ->with('value') ->where('ref', $this->app->unitId) ->where('type/name', 'business_year_start') ->execute(); $view->data['business_start'] = $businessStart->id === 0 ? 1 : $businessStart->value->getValue(); // @todo this one should already be loaded in the backend application no????????? /** @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['defaultlocalization'] = LocalizationMapper::get()->where('id', (int) $settings->id)->execute(); $view->data['l11nView'] = new \Web\Backend\Views\L11nView($this->app->l11nManager, $request, $response); /** @var \phpOMS\Localization\BaseStringL11nType[] $l11nTypes */ $l11nTypes = ItemL11nTypeMapper::getAll() ->execute(); $view->data['l11nTypes'] = $l11nTypes; /** @var \phpOMS\Localization\BaseStringL11n[] $l11nValues */ $l11nValues = ItemL11nMapper::getAll() ->with('type') ->where('ref', $item->id) ->execute(); $view->data['l11nValues'] = $l11nValues; /** @var \Modules\Attribute\Models\AttributeType[] $attributeTypes */ $attributeTypes = ItemAttributeTypeMapper::getAll() ->with('l11n') ->where('l11n/language', $response->header->l11n->language) ->execute(); $view->data['attributeTypes'] = $attributeTypes; /** @var \Modules\Organization\Models\Unit[] $units */ $units = UnitMapper::getAll() ->execute(); $view->data['units'] = $units; /** @var \Modules\Billing\Models\Price\Price[] $prices */ $prices = PriceMapper::getAll() ->where('item', $item->id) ->where('type', PriceType::SALES) ->where('client', null) ->execute(); $view->data['prices'] = $prices; /** @var \Modules\Auditor\Models\Audit[] $audits */ $audits = AuditMapper::getAll() ->where('type', StringUtils::intHash(ItemMapper::class)) ->where('module', 'ItemManagement') ->where('ref', (string) $item->id) ->execute(); // @todo join audit with files, attributes, localization, prices, notes, ... $view->data['audits'] = $audits; /** @var \Modules\Media\Models\Media[] $files */ $files = MediaMapper::getAll() ->with('types') ->join('id', ItemMapper::class, 'files') // id = media id, files = item relations ->on('id', $item->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['hasBilling'] = $this->app->moduleManager->isActive('Billing'); return $view; } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return View * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementSalesItem(RequestAbstract $request, ResponseAbstract $response, $data = null) : View { return $this->viewItemManagementItem($request, $response, $data); } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementPurchaseItem(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { return $this->viewItemManagementItem($request, $response, $data); } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemManagementWarehouseItem(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { return $this->viewItemManagementItem($request, $response, $data); } /** * Routing end-point for application behavior. * * @param RequestAbstract $request Request * @param ResponseAbstract $response Response * @param array $data Generic data * * @return RenderableInterface * * @since 1.0.0 * @codeCoverageIgnore */ public function viewItemPurchaseAnalysis(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface { $head = $response->data['Content']->head; $nonce = $this->app->appSettings->getOption('script-nonce'); $head->addAsset(AssetType::CSS, 'Resources/chartjs/chart.css'); $head->addAsset(AssetType::JSLATE, 'Resources/chartjs/chart.js', ['nonce' => $nonce]); $head->addAsset(AssetType::JSLATE, 'Modules/Sales/Controller/Controller.js', ['nonce' => $nonce, 'type' => 'module']); $view = new View($this->app->l11nManager, $request, $response); $view->setTemplate('/Modules/ItemManagement/Theme/Backend/item-analysis'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1001602001, $request, $response); $monthlySalesCosts = []; for ($i = 1; $i < 13; ++$i) { $monthlySalesCosts[] = [ 'net_sales' => $sales = \mt_rand(1200000000, 2000000000), 'net_costs' => (int) ($sales * \mt_rand(25, 55) / 100), 'year' => 2020, 'month' => $i, ]; } $view->data['monthlySalesCosts'] = $monthlySalesCosts; ///// $monthlySalesCustomer = []; for ($i = 1; $i < 13; ++$i) { $monthlySalesCustomer[] = [ 'net_sales' => $sales = \mt_rand(1200000000, 2000000000), 'customers' => \mt_rand(200, 400), 'year' => 2020, 'month' => $i, ]; } $view->data['monthlySalesCustomer'] = $monthlySalesCustomer; $annualSalesCustomer = []; for ($i = 1; $i < 11; ++$i) { $annualSalesCustomer[] = [ 'net_sales' => $sales = \mt_rand(1200000000, 2000000000) * 12, 'customers' => \mt_rand(200, 400) * 6, 'year' => 2020 - 10 + $i, ]; } $view->data['annualSalesCustomer'] = $annualSalesCustomer; ///// $monthlyCustomerRetention = []; for ($i = 1; $i < 10; ++$i) { $monthlyCustomerRetention[] = [ 'customers' => \mt_rand(200, 400), 'year' => \date('y') - 9 + $i, ]; } $view->data['monthlyCustomerRetention'] = $monthlyCustomerRetention; ///// $currentCustomerRegion = [ 'Europe' => (int) (\mt_rand(200, 400) / 4), 'America' => (int) (\mt_rand(200, 400) / 4), 'Asia' => (int) (\mt_rand(200, 400) / 4), 'Africa' => (int) (\mt_rand(200, 400) / 4), 'CIS' => (int) (\mt_rand(200, 400) / 4), 'Other' => (int) (\mt_rand(200, 400) / 4), ]; $view->data['currentCustomerRegion'] = $currentCustomerRegion; $annualCustomerRegion = []; for ($i = 1; $i < 11; ++$i) { $annualCustomerRegion[] = [ 'year' => 2020 - 10 + $i, 'Europe' => $a = (int) (\mt_rand(200, 400) / 4), 'America' => $b = (int) (\mt_rand(200, 400) / 4), 'Asia' => $c = (int) (\mt_rand(200, 400) / 4), 'Africa' => $d = (int) (\mt_rand(200, 400) / 4), 'CIS' => $e = (int) (\mt_rand(200, 400) / 4), 'Other' => $f = (int) (\mt_rand(200, 400) / 4), 'Total' => $a + $b + $c + $d + $e + $f, ]; } $view->data['annualCustomerRegion'] = $annualCustomerRegion; ///// $currentCustomersRep = []; for ($i = 1; $i < 13; ++$i) { $currentCustomersRep['Rep ' . $i] = [ 'customers' => (int) (\mt_rand(200, 400) / 12), ]; } \uasort($currentCustomersRep, function($a, $b) { return $b['customers'] <=> $a['customers']; }); $view->data['currentCustomersRep'] = $currentCustomersRep; $annualCustomersRep = []; for ($i = 1; $i < 13; ++$i) { $annualCustomersRep['Rep ' . $i] = []; for ($j = 1; $j < 11; ++$j) { $annualCustomersRep['Rep ' . $i][] = [ 'customers' => (int) (\mt_rand(200, 400) / 12), 'year' => 2020 - 10 + $j, ]; } } $view->data['annualCustomersRep'] = $annualCustomersRep; ///// $currentCustomersCountry = []; for ($i = 1; $i < 51; ++$i) { $country = (string) ISO3166NameEnum::getRandom(); $currentCustomersCountry[\substr($country, 0, 20)] = [ 'customers' => (int) (\mt_rand(200, 400) / 12), ]; } \uasort($currentCustomersCountry, function($a, $b) { return $b['customers'] <=> $a['customers']; }); $view->data['currentCustomersCountry'] = $currentCustomersCountry; $annualCustomersCountry = []; for ($i = 1; $i < 51; ++$i) { $countryCode = ISO3166CharEnum::getRandom(); $countryName = (string) ISO3166NameEnum::getByName('_' . $countryCode); $annualCustomersCountry[\substr($countryName, 0, 20)] = []; for ($j = 1; $j < 11; ++$j) { $annualCustomersCountry[\substr($countryName, 0, 20)][] = [ 'customers' => (int) (\mt_rand(200, 400) / 12), 'year' => 2020 - 10 + $j, 'name' => $countryName, 'code' => $countryCode, ]; } } $view->data['annualCustomersCountry'] = $annualCustomersCountry; ///// $customerGroups = []; for ($i = 1; $i < 7; ++$i) { $customerGroups['Group ' . $i] = [ 'customers' => (int) (\mt_rand(200, 400) / 12), ]; } $view->data['customerGroups'] = $customerGroups; return $view; } }