Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
85.00% covered (warning)
85.00%
17 / 20
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
PickingOrderProductSyncService
85.00% covered (warning)
85.00%
17 / 20
50.00% covered (danger)
50.00%
1 / 2
4.05
0.00% covered (danger)
0.00%
0 / 1
 sync
81.25% covered (warning)
81.25%
13 / 16
0.00% covered (danger)
0.00%
0 / 1
3.06
 getStockIOProductAmount
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Domain\PickingOrder\Services;
4
5use function implode;
6
7use Illuminate\Support\Facades\DB;
8
9use App\Events\ServiceProcessed;
10use App\Models\PickingOrder\PickingOrder;
11use App\Models\StockIO\StockIOProduct;
12use App\Models\User;
13
14use Domain\PickingOrder\Exception\PickingOrderException;
15use Domain\PickingOrder\Enums\PickingOrderStatusEnum;
16
17readonly class PickingOrderProductSyncService
18{
19
20    /**
21     * @param array $stockIOProducts
22     * @param PickingOrder $pickingOrder
23     * @param User $user
24     * @return void
25     */
26    public function sync(array $stockIOProducts, PickingOrder $pickingOrder, User $user): void
27    {
28        foreach ($stockIOProducts as $stockIOProduct) {
29            $existingStockIOProducts = DB::table('picking_order_products')
30                ->where('stock_io_product_id', $stockIOProduct['id'])
31                ->pluck('stock_io_product_id')
32                ->intersect($stockIOProduct['id']);
33
34            if ($existingStockIOProducts->isNotEmpty()) {
35                throw new PickingOrderException(__('The products [:products] have already been added to the order', [
36                    'products' => implode(', ', $existingStockIOProducts->toArray())
37                ]));
38            }
39
40            $syncData[$stockIOProduct['id']] = [
41                'type' => $stockIOProduct['type'],
42                'status' => PickingOrderStatusEnum::PENDING->value,
43                'amount' => $this->getStockIOProductAmount($stockIOProduct['id']),
44            ];
45        }
46
47        $pickingOrder->stockIOProducts()->sync($syncData);
48        ServiceProcessed::dispatch(self::class, $user);
49    }
50
51    /**
52     * @param int $stockIOProductId
53     * @return float
54     */
55    private function getStockIOProductAmount(int $stockIOProductId): float
56    {
57        return (StockIOProduct::query()
58            ->where('id', $stockIOProductId)
59            ->select('amount')
60            ->first())->amount;
61    }
62}