vibe
This commit is contained in:
parent
837cfb6d43
commit
939840a3ac
76 changed files with 6636 additions and 83 deletions
124
src/Service/StockAdjustmentService.php
Normal file
124
src/Service/StockAdjustmentService.php
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Entity\DrinkType;
|
||||
use App\Enum\SystemSettingKey;
|
||||
use App\Repository\DrinkTypeRepository;
|
||||
use App\Repository\InventoryRecordRepository;
|
||||
use App\Repository\OrderRepository;
|
||||
use App\Repository\SystemConfigRepository;
|
||||
use App\ValueObject\StockAdjustmentProposal;
|
||||
|
||||
readonly class StockAdjustmentService
|
||||
{
|
||||
public function __construct(
|
||||
private DrinkTypeRepository $drinkTypeRepository,
|
||||
private InventoryRecordRepository $inventoryRecordRepository,
|
||||
private OrderRepository $orderRepository,
|
||||
private SystemConfigRepository $systemConfigRepository,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Proposes adjusted stock levels for all drink types
|
||||
*
|
||||
* @return array<int, StockAdjustmentProposal> Array of stock adjustment proposals
|
||||
*/
|
||||
public function proposeStockAdjustments(): array
|
||||
{
|
||||
$drinkTypes = $this->drinkTypeRepository->findAll();
|
||||
$proposals = [];
|
||||
|
||||
foreach ($drinkTypes as $drinkType) {
|
||||
$proposals[] = $this->proposeStockAdjustmentForDrinkType($drinkType);
|
||||
}
|
||||
|
||||
return $proposals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proposes an adjusted stock level for a specific drink type
|
||||
*/
|
||||
public function proposeStockAdjustmentForDrinkType(DrinkType $drinkType): StockAdjustmentProposal
|
||||
{
|
||||
$currentDesiredStock = $drinkType->getDesiredStock();
|
||||
$lookbackOrders =
|
||||
(int) $this->systemConfigRepository->getValue(SystemSettingKey::STOCK_ADJUSTMENT_LOOKBACK_ORDERS);
|
||||
$increaseAmount = (int) $this->systemConfigRepository->getValue(SystemSettingKey::STOCK_INCREASE_AMOUNT);
|
||||
$decreaseAmount = (int) $this->systemConfigRepository->getValue(SystemSettingKey::STOCK_DECREASE_AMOUNT);
|
||||
|
||||
// Get the last N orders for this drink type
|
||||
$lastOrders = $this->orderRepository->findLastOrdersForDrinkType($drinkType, $lookbackOrders);
|
||||
|
||||
// If there are no orders, return the current desired stock
|
||||
if ($lastOrders === []) {
|
||||
return new StockAdjustmentProposal($drinkType, $currentDesiredStock);
|
||||
}
|
||||
|
||||
// Check if stock was 0 in the last order
|
||||
$lastOrder = $lastOrders[0];
|
||||
$lastOrderItems = $lastOrder->getOrderItems();
|
||||
$stockWasZeroInLastOrder = false;
|
||||
|
||||
foreach ($lastOrderItems as $orderItem) {
|
||||
if ($orderItem->getDrinkType()->getId() === $drinkType->getId()) {
|
||||
// Find the inventory record closest to the order creation date
|
||||
$inventoryRecords = $this->inventoryRecordRepository->findByDrinkType($drinkType);
|
||||
foreach ($inventoryRecords as $record) {
|
||||
if ($record->getTimestamp() <= $lastOrder->getCreatedAt()) {
|
||||
if ($record->getQuantity() === 0) {
|
||||
$stockWasZeroInLastOrder = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If stock was 0 in the last order, increase desired stock
|
||||
if ($stockWasZeroInLastOrder) {
|
||||
return new StockAdjustmentProposal($drinkType, $currentDesiredStock + $increaseAmount);
|
||||
}
|
||||
|
||||
// Check if stock was above zero in all lookback orders
|
||||
$stockWasAboveZeroInAllOrders = true;
|
||||
$ordersToCheck = min(count($lastOrders), $lookbackOrders);
|
||||
|
||||
for ($i = 0; $i < $ordersToCheck; $i++) {
|
||||
$order = $lastOrders[$i];
|
||||
$orderItems = $order->getOrderItems();
|
||||
|
||||
foreach ($orderItems as $orderItem) {
|
||||
if ($orderItem->getDrinkType()->getId() === $drinkType->getId()) {
|
||||
// Find the inventory record closest to the order creation date
|
||||
$inventoryRecords = $this->inventoryRecordRepository->findByDrinkType($drinkType);
|
||||
foreach ($inventoryRecords as $record) {
|
||||
if ($record->getTimestamp() <= $order->getCreatedAt()) {
|
||||
if ($record->getQuantity() === 0) {
|
||||
$stockWasAboveZeroInAllOrders = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$stockWasAboveZeroInAllOrders) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If stock was above zero in all lookback orders, decrease desired stock
|
||||
if ($stockWasAboveZeroInAllOrders && $ordersToCheck === $lookbackOrders) {
|
||||
$proposedStock = max(0, $currentDesiredStock - $decreaseAmount);
|
||||
return new StockAdjustmentProposal($drinkType, $proposedStock);
|
||||
}
|
||||
|
||||
// Otherwise, keep the current desired stock
|
||||
return new StockAdjustmentProposal($drinkType, $currentDesiredStock);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue