gateway = $gateway; $this->db = $database; } /** * @param int $articleId * @param int|float $quantity * * @throws InvalidArgumentException|ArticleNotFoundException * * @return float */ public function calculateCalculatedPurchasePrice($articleId, $quantity) { $quantity = (float)$quantity; $articleId = $this->ensureArticleId($articleId); if ($quantity <= 0.0) { throw new InvalidArgumentException(sprintf('Quantity must be greater than 0. Actual: %s', $quantity)); } $calculatedPurchasePrice = $this->db->fetchValue( 'SELECT a.berechneterek FROM artikel AS a WHERE a.id = :article_id AND a.verwendeberechneterek = 1', ['article_id' => $articleId] ); $calculatedPurchasePrice = (float)$calculatedPurchasePrice * $quantity; if ($calculatedPurchasePrice > 0) { return $calculatedPurchasePrice; } if (!$this->gateway->isPartsListArticle($articleId)) { return 0; } $calculatedPurchasePrice = 0; $partsListArticles = $this->db->fetchAll( 'SELECT s.artikel, s.menge FROM stueckliste AS s WHERE s.stuecklistevonartikel = :article_id', ['article_id' => $articleId] ); foreach($partsListArticles as $articles=>$article){ $calculatedPurchasePrice += $this->calculateCalculatedPurchasePrice($article['artikel'], $article['menge']); } return $calculatedPurchasePrice; } /** * @param int $articleId * * @throws InvalidArgumentException * * @return int */ private function ensureArticleId($articleId) { if (empty($articleId) || (int)$articleId < 1) { throw new InvalidArgumentException('Required argument "articleId" is empty or invalid.'); } return (int)$articleId; } /** * @param int $articleId * @param int $addressId * @param float $price * @param string $currencyCode * @param float $quantityFrom * @param string $purchaseNumber * @param string $purchaseName * * @return int */ public function setPurchasePrice($articleId, $addressId, $price, $currencyCode = 'EUR', $quantityFrom = 1.0, $purchaseNumber = '', $purchaseName = '') { $this->ensureArticleId($articleId); if(empty($currencyCode)) { $currencyCode = 'EUR'; } if($quantityFrom <= 0) { $quantityFrom = 1.0; } $select = $this->db->select(); $select ->cols(['pp.id', 'pp.preis as price','IF(pp.waehrung <> \'\', pp.waehrung, \'EUR\') AS currency_code', 'pp.artikel AS article_id','pp.ab_menge AS quantity_from','pp.bestellnummer AS purchase_number', 'pp.bezeichnunglieferant AS purcase_name' ]) ->from('einkaufspreise AS pp') ->where("ab_menge=:quantity_from AND adresse=:address_id AND artikel=:article_id AND waehrung = :currency_code AND (IFNULL(gueltig_bis='0000-00-00','0000-00-00') OR gueltig_bis >= NOW()) AND geloescht!=1") ->bindValue('quantity_from', (float)$quantityFrom) ->bindValue('address_id', (int)$addressId) ->bindValue('article_id', (int)$articleId) ->bindValue('currency_code', $currencyCode); $oldPrice = $this->db->fetchRow( $select->getStatement(), $select->getBindValues() ); if(!empty($oldPrice)) { $isPriceDifferent = round($oldPrice['price'],8) !== round($price,8); $isNumberOrNameDiffernt = (String)$oldPrice['purchase_number'] !== (String)$purchaseNumber || (String)$oldPrice['purcase_name'] !== (String)$purchaseName; if(!$isPriceDifferent && !$isNumberOrNameDiffernt) { return $oldPrice['id']; } if(!$isPriceDifferent) { return $oldPrice['id']; } $this->db->perform( 'UPDATE einkaufspreise SET gueltig_bis = DATE_SUB(CURDATE(), INTERVAL 1 DAY) WHERE id = :id', ['id'=>$oldPrice['id']] ); } $this->db->perform('INSERT INTO einkaufspreise (artikel, adresse, objekt, projekt, preis, waehrung, ab_menge, bestellnummer, bezeichnunglieferant, nichtberechnet) VALUES (:article_id, :address_id, :object, :project_id, :price, :currency, :quantity_from, :purchase_number,:purchase_name, 1)', [ 'article_id' => (int)$articleId, 'address_id' => (int)$addressId, 'object' => '', 'project_id' => 0, 'price' => (float)$price, 'currency' => $currencyCode, 'quantity_from' => (float)$quantityFrom, 'purchase_number' => (String)$purchaseNumber, 'purchase_name' => (String)$purchaseName ] ); return $this->db->lastInsertId(); } /** * @param array $purchasePriceArray [article_id, address_id, price, quantity_from, currency_code,purchase_number,purchase_name] */ public function setPurchasePriceByArray($purchasePriceArray) { if(empty($purchasePriceArray)) { return; } $articleIds = []; $addressIds = []; foreach($purchasePriceArray as $purchasePrice) { if(!in_array($purchasePrice['article_id'], $articleIds)) { $articleIds[] = $purchasePrice['article_id']; } if(!in_array($purchasePrice['address_id'], $addressIds)) { $addressIds[] = $purchasePrice['address_id']; } } $select = $this->db->select(); $select ->cols( [ 'pp.id', 'pp.preis as price', 'IF(pp.waehrung <> \'\', pp.waehrung, \'EUR\') AS currency_code', 'pp.artikel AS article_id', 'pp.adresse AS address_id', 'pp.ab_menge AS quantity_from', 'pp.bestellnummer AS purchase_number', 'pp.bezeichnunglieferant AS purcase_name' ] ) ->from('einkaufspreise AS pp') ->where("adresse IN (:address) AND artikel IN (:article) AND (IFNULL(pp.gueltig_bis,'0000-00-00')='0000-00-00' OR pp.gueltig_bis >= CURDATE()) AND pp.geloescht!=1") ->bindValue('address', $addressIds) ->bindValue('article', $articleIds); $oldPrices = $this->db->fetchAll( $select->getStatement(), $select->getBindValues() ); $priceTree = []; foreach($oldPrices as $oldPrice) { $articleId = (int)$oldPrice['article_id']; $addressId = (int)$oldPrice['address_id']; $currencyCode = $oldPrice['currency_code']; $quantityFrom = round($oldPrice['quantity_from'],8); $priceTree[$articleId][$addressId][$currencyCode][$quantityFrom] = $oldPrice['price']; } unset($oldPrices); foreach($purchasePriceArray as $purchasePrice) { $articleId = (int)$purchasePrice['article_id']; $addressId = (int)$purchasePrice['address_id']; $currencyCode = $purchasePrice['currency_code']; $quantityFrom = round($purchasePrice['quantity_from'],8); $price = round($purchasePrice['price'], 8); $purchaseNumber = !empty($purchasePrice['purchase_number'])?$purchasePrice['purchase_number']:''; $purchaseName = !empty($purchasePrice['purchase_name'])?$purchasePrice['purchase_name']:''; $aricleExists = !empty($priceTree[$articleId]); $addressExists = $aricleExists && !empty($priceTree[$articleId][$addressId]); $currencyExists = $addressExists && !empty($priceTree[$articleId][$addressId][$currencyCode]); $quantityFromExists = $currencyExists && !empty($priceTree[$articleId][$addressId][$currencyCode][$quantityFrom]); if(!$quantityFromExists || round($oldPrice['price'],8) !== $price) { $this->setPurchasePrice( $articleId, $addressId, $price, $currencyCode, $quantityFrom, $purchaseNumber, $purchaseName ); } } } }