'title', 'text' => 'Titel', 'required' => true, 'table' => ['priority' => 9]], ['key' => 'articleNumber', 'text' => 'Nr.', 'required' => true], ['key' => 'description', 'text' => 'Beschreibung', 'required' => true, 'table' => ['sortable' => false]], ['key' => 'category_id', 'text' => 'Kategorie', 'required' => true, 'modal' => ['type' => 'select', 'items' => []], 'table' => ['filter' => 'select']], ['key' => 'unit', 'text' => 'Einheit', 'required' => true,'table' => false], ['key' => 'revenueAccount', 'text' => 'Erlöskonto', 'required' => true,'modal' => ['type' => 'select', 'items' => [['value' => 0, 'text' => 'Dienstleistungen'], ['value' => 1, 'text' => 'Handelswaren']]], 'table' => false], ['key' => 'cheapestPurchasePrice', 'text' => 'Einkauf', 'modal' => false, 'table' => ['class' => 'text-center', 'suffix' => ' €']], ['key' => 'cheapestSellPrice', 'text' => 'Verkauf', 'modal' => false, 'table' => ['class' => 'text-center', 'suffix' => ' €']], ['key' => 'warningAmount', 'text' => 'Warnmenge', 'required' => true,'modal' => ['type' => 'number'], 'table' => false], ['key' => 'criticalAmount', 'text' => 'Kritische Menge', 'required' => true,'modal' => ['type' => 'number'], 'table' => false], ['key' => 'isSerialDocumentation', 'text' => 'Seriennummern', 'required' => false,'modal' => ['type' => 'checkbox'], 'table' => false], ['key' => 'isEShop', 'text' => 'Ist E-Shop', 'required' => false,'modal' => ['type' => 'checkbox'], 'table' => false], ['key' => 'isEShopHide', 'text' => 'E-Shop Versteckt', 'required' => false,'modal' => ['type' => 'checkbox'], 'table' => false], ['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center', 'priority' => 8]] ]; protected array $autocompleteColumns = ['articleNumber', 'title', 'description']; protected array $permissionCheck = ['WarehouseUser']; protected array $additionalActions = [['key' => 'openHistory','title' => 'Historie','class' => 'fas fa-history text-secondary']]; // @formatter:on protected array $additionalJSVariables = ['WAREHOUSE_ADMIN' => true]; protected function prepareCrudConfig() { $categories = array_map(fn($category) => ['value' => $category->id, 'text' => $category->name], WarehouseCategory::getAll()); $this->columns[array_search('category_id', array_column($this->columns, 'key'))]['modal']['items'] = $categories; if ($this->user->can('WarehouseAdmin')) return; array_walk($this->columns, fn(&$col) => in_array($col['key'], ['actions', 'cheapestPurchasePrice', 'warningAmount', 'criticalAmount']) && $col['table'] = false); $this->createText = false; $this->additionalJSVariables['WAREHOUSE_ADMIN'] = false; } protected function beforeUpdate($postData): bool { (new WarehouseHistoryController)->create($postData, $this->mod); return true; } protected function afterUpdate($postData) { self::updateCheapestPurchasePrice($postData['id']); } public static function updateCheapestPurchasePrice(int $id): void { $article = WarehouseArticleModel::get($id); if (!$article instanceof WarehouseArticleModel) throw new Exception("Invalid article type"); $distributor = WarehouseArticleDistributorModel::getAll(['articleId' => $id], 1, 0, ['key' => 'purchasePrice', 'order' => 'ASC']); if (count($distributor) == 0) WarehouseArticleModel::update(array_merge(get_object_vars($article), ['cheapestPurchasePrice' => null])); else if ($article->cheapestPurchasePrice != $distributor[0]->purchasePrice) WarehouseArticleModel::update(array_merge(get_object_vars($article), ['cheapestPurchasePrice' => $distributor[0]->purchasePrice])); } protected function afterCreate($postData) { self::updateCheapestPurchasePrice($postData['id']); self::updateSellPrices($postData['id']); } public static function updateSellPrices(int $id): void { // Added return type hint $a = WarehouseArticleModel::get($id); if (!$a instanceof WarehouseArticleModel) throw new Exception("Invalid article type"); $aptsById = array_column(WarehouseArticlePriceModel::getAll(['articleId' => $id]), null, 'articlePriceTypeId'); $prices = []; $cpp = $a->cheapestPurchasePrice; foreach (WarehouseArticlePriceTypeModel::getAll() as $pt) { $apt = $aptsById[$pt->id] ?? null; $p = $apt ? ($apt->priceOverride ?? $apt->priceMultiplier * $cpp) : ($pt->defaultPriceFactor * $cpp); $prices[] = ['title' => $pt->title, 'price' => round($p, 2)]; // Add title and rounded price } usort($prices, function($x, $y) { $priorityX = 4; $titleX = isset($x['title']) ? $x['title'] : null; switch ($titleX) { case 'Verkauf': $priorityX = 1; break; case 'Partner': $priorityX = 2; break; case 'Energie Steiermark': $priorityX = 3; break; } $priorityY = 4; $titleY = isset($y['title']) ? $y['title'] : null; switch ($titleY) { case 'Verkauf': $priorityY = 1; break; case 'Partner': $priorityY = 2; break; case 'Energie Steiermark': $priorityY = 3; break; } return $priorityX <=> $priorityY; }); $a->cheapestSellPrice = json_encode($prices); WarehouseArticleModel::update(get_object_vars($a)); } public function updatePricesAction() { foreach (WarehouseArticleModel::getAll() as $article) { self::updateCheapestPurchasePrice($article->id); self::updateSellPrices($article->id); } self::returnJson(['success' => true, 'message' => 'Preise wurden aktualisiert']); } protected function getHistoryAction() { self::returnJson((new WarehouseHistoryController)->getHistory($this->request->id, $this->mod, $this->columns)); } }