/** * @return \Zend\Http\Response|\Zend\Stdlib\Message * @todo optimize query when fetching storage unit */ public function updateCurrentLevelAction() { $this->ensure('post'); try { /** @var Stock $stock */ $stock = $this->mapper(Stock::class)->one($this->getRequestPost('id')); $newLevel = $this->getRequestPost('new_level', 0); if (!is_numeric($newLevel)) { throw new \InvalidArgumentException('Angka yang dimasukkan tidak valid.'); } $storageUnit = $stock->getStockItem()->getStorageUnit(); $type = $this->getRequestPost('type', LevelChange::TYPE_CORRECTION); $note = $this->getRequestPost('note', ''); $levelChange = new LevelChange(); $levelChange->setCorrector($this->user()); $levelChange->setStock($stock); $levelChange->setCurrentLevel($stock->getCurrentLevel() * $storageUnit->getRatio()); $levelChange->setDelta((abs($newLevel) - $stock->getCurrentLevel()) * $storageUnit->getRatio()); $levelChange->setType($type); $levelChange->setNote($note); $levelChange->setAuto(false); $stock->setCurrentLevel(abs($newLevel) * $storageUnit->getRatio()); $stock->setLastChange(new \DateTime()); $this->persist($stock, $levelChange)->commit(); return $this->jsonOk([], 200); } catch (NoResultException $e) { return $this->jsonError([], 404); } catch (\InvalidArgumentException $e) { return $this->jsonError(['errorSummary' => $e->getMessage()], 400); } }
/** * @param Purchase $purchase * @param User $corrector * @param array $rawItems */ public function increaseStock(Purchase $purchase, User $corrector, array $rawItems) { $getStockId = function ($stock) { if ($stock instanceof Stock) { return $stock->getId(); } else { if (is_numeric($stock)) { return $stock; } else { throw new \InvalidArgumentException(); } } }; $stocks = []; $unitPrices = []; foreach ($rawItems as $item) { // todo: change $items array to object? to prevent missing keys in array. if (isset($item['stock']) && $item['stock'] && isset($item['quantity']) && $item['quantity']) { try { $stocks[$getStockId($item['stock'])] = $item['quantity']; if (isset($item['total']) && $item['total'] && $item['quantity'] > 0) { $unitPrices[$getStockId($item['stock'])] = $item['total'] / $item['quantity']; } } catch (\Exception $e) { continue; } } } /** @var Stock[] $stockEntities */ $stockEntities = $this->findStockInIds(array_keys($stocks)); foreach ($stockEntities as $stockEntity) { if (isset($stocks[$stockEntity->getId()])) { $quantity = $stocks[$stockEntity->getId()]; $ratio = $stockEntity->getStockItem()->getStorageUnit()->getRatio(); $unitQuantity = $quantity * $ratio; if ($unitQuantity) { // create level change $levelChange = new LevelChange(); $levelChange->setStock($stockEntity); $levelChange->setCorrector($corrector); $levelChange->setCurrentLevel($stockEntity->getCurrentLevel()); $levelChange->setType(LevelChange::TYPE_PURCHASE); $levelChange->setDelta($unitQuantity); $levelChange->setAuto(true); $levelChange->setNote(sprintf("#%d (+%s %s)", $purchase->getId(), $quantity, $stockEntity->getStockItem()->getStorageUnit()->getName())); // update stock $stockEntity->setCurrentLevel($stockEntity->getCurrentLevel() + $unitQuantity); $stockEntity->setLastChange(new \DateTime()); if (isset($unitPrices[$stockEntity->getId()])) { $stockEntity->setCurrentUnitPrice($unitPrices[$stockEntity->getId()]); } if ($purchase->getOrderedAt() instanceof \DateTime) { $stockEntity->setLastPurchase($purchase->getOrderedAt()); } $this->em()->persist($levelChange); $this->em()->persist($stockEntity); } } } $this->em()->flush(); }