Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 52 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
| PickingOrderProductSyncService | |
0.00% |
0 / 52 |
|
0.00% |
0 / 5 |
156 | |
0.00% |
0 / 1 |
| sync | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
30 | |||
| getStockIOProductAmount | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
| verifyStockProductAmountExceeded | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
| linkPickedItemsWithPickingOrderProducts | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
| processInvoiceLog | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
12 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace Domain\PickingOrder\Services\V2; |
| 4 | |
| 5 | use Illuminate\Support\Facades\DB; |
| 6 | |
| 7 | use App\Events\ServiceProcessed; |
| 8 | use App\Models\PickingOrder\PickingOrder; |
| 9 | use App\Models\StockIO\StockIO; |
| 10 | use App\Models\StockIO\StockIOProduct; |
| 11 | use App\Models\User; |
| 12 | |
| 13 | use Domain\PickingOrder\Enums\PickingOrderStatusEnum; |
| 14 | use Domain\Request\DTOs\RequestLogStoreDTO; |
| 15 | use Domain\Request\Enums\RequestLogOperationEnum; |
| 16 | use Domain\Request\Services\RequestLogStoreService; |
| 17 | use Domain\StockIO\Exceptions\StockIOProductAmountExceededException; |
| 18 | |
| 19 | readonly class PickingOrderProductSyncService |
| 20 | { |
| 21 | |
| 22 | /** |
| 23 | * @param array $stockIOProducts |
| 24 | * @param PickingOrder $pickingOrder |
| 25 | * @param User $user |
| 26 | * @param bool $syncPickedItems |
| 27 | * @return void |
| 28 | */ |
| 29 | public function sync(array $stockIOProducts, PickingOrder $pickingOrder, User $user, bool $syncPickedItems): void |
| 30 | { |
| 31 | foreach ($stockIOProducts as $stockIOProduct) { |
| 32 | $existingStockIOProducts = DB::table('picking_order_products') |
| 33 | ->where('status', '<>', PickingOrderStatusEnum::CONCLUDED->value) |
| 34 | ->where('stock_io_product_id', $stockIOProduct['id']) |
| 35 | ->get(); |
| 36 | |
| 37 | $amount = isset($stockIOProduct['amount']) && !is_null($stockIOProduct['amount']) ? |
| 38 | $stockIOProduct['amount'] : |
| 39 | $this->getStockIOProductAmount($stockIOProduct['id']); |
| 40 | |
| 41 | $this->verifyStockProductAmountExceeded($stockIOProduct, $amount + $existingStockIOProducts->sum('amount')); |
| 42 | |
| 43 | $syncData[$stockIOProduct['id']] = [ |
| 44 | 'type' => $stockIOProduct['type'], |
| 45 | 'status' => PickingOrderStatusEnum::PENDING->value, |
| 46 | 'amount' => $amount, |
| 47 | ]; |
| 48 | } |
| 49 | |
| 50 | $pickingOrder->stockIOProducts()->sync($syncData); |
| 51 | |
| 52 | if ($syncPickedItems) |
| 53 | $this->linkPickedItemsWithPickingOrderProducts($pickingOrder); |
| 54 | |
| 55 | $this->processInvoiceLog($stockIOProducts, $pickingOrder, $user); |
| 56 | |
| 57 | ServiceProcessed::dispatch(self::class, $user); |
| 58 | } |
| 59 | |
| 60 | /** |
| 61 | * @param int $stockIOProductId |
| 62 | * @return float |
| 63 | */ |
| 64 | private function getStockIOProductAmount(int $stockIOProductId): float |
| 65 | { |
| 66 | return (StockIOProduct::query() |
| 67 | ->where('id', $stockIOProductId) |
| 68 | ->select('amount') |
| 69 | ->first())->amount; |
| 70 | } |
| 71 | |
| 72 | /** |
| 73 | * @param array $stockIOProduct |
| 74 | * @param float $amount |
| 75 | */ |
| 76 | private function verifyStockProductAmountExceeded(array $stockIOProduct, float $amount): void |
| 77 | { |
| 78 | $stockProduct = StockIOProduct::find($stockIOProduct['id']); |
| 79 | |
| 80 | if ($stockProduct->getAttribute('amount') < $amount) { |
| 81 | throw new StockIOProductAmountExceededException( |
| 82 | __('The amount informed exceed the stockIO product amount :stockIOProduct', |
| 83 | ['stockIOProduct' => $stockIOProduct['id']] |
| 84 | ) |
| 85 | ); |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | /** |
| 90 | * @param PickingOrder $pickingOrder |
| 91 | */ |
| 92 | private function linkPickedItemsWithPickingOrderProducts(PickingOrder $pickingOrder): void |
| 93 | { |
| 94 | $pickingOrder->pickingOrderProduct()->each(function ($pickingOrderProduct) { |
| 95 | $pickingOrderProduct->stockIOProduct->pickedItems()->each(function ($pickedItem) use ($pickingOrderProduct) { |
| 96 | $pickedItem->pickingOrderProduct()->associate($pickingOrderProduct); |
| 97 | $pickedItem->save(); |
| 98 | }); |
| 99 | }); |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * @param array $stockIOProducts |
| 104 | * @param PickingOrder $pickingOrder |
| 105 | * @param User $user |
| 106 | */ |
| 107 | private function processInvoiceLog(array $stockIOProducts, PickingOrder $pickingOrder, User $user): void |
| 108 | { |
| 109 | $stockIOs = StockIO::query() |
| 110 | ->whereHas('stockIOProducts', function ($builder) use ($stockIOProducts){ |
| 111 | $builder->whereIn('stock_io_products.id', collect($stockIOProducts)->pluck('id')); |
| 112 | }) |
| 113 | ->get('id') |
| 114 | ->keyBy('id'); |
| 115 | |
| 116 | |
| 117 | foreach ($stockIOs as $stockIO) { |
| 118 | $requestLogStoreDTO = new RequestLogStoreDTO([ |
| 119 | 'request' => $stockIO->request ? $stockIO->request : null, |
| 120 | 'stockIO' => $stockIO, |
| 121 | 'operation' => RequestLogOperationEnum::CREATED_PICKING_ORDER, |
| 122 | 'user' => $user, |
| 123 | 'detail' => $pickingOrder->toJson(), |
| 124 | 'observation' => "Tarefa de separação inserida: ". $pickingOrder->getKey(), |
| 125 | ]); |
| 126 | |
| 127 | (new RequestLogStoreService())->store($requestLogStoreDTO, $user); |
| 128 | } |
| 129 | } |
| 130 | } |