Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 75 |
|
0.00% |
0 / 11 |
CRAP | |
0.00% |
0 / 1 |
| TransferTaskPushProductService | |
0.00% |
0 / 75 |
|
0.00% |
0 / 11 |
462 | |
0.00% |
0 / 1 |
| push | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
6 | |||
| populateItemToTransferDTO | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
| markTransferTaskProductAsPicked | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
| validateTransferTaskStatus | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
| findPickedItem | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
12 | |||
| updatePickedProductStatus | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
| transferItem | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
6 | |||
| handlePickedTransferTaskProduct | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
| validateTransferTaskProductStatus | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| validateTransferTaskProductAmount | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getExistsOtherPickedTransferTaskProductTrasferring | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace Domain\TransferTask\Services; |
| 4 | |
| 5 | use App\Models\{Address\Address, Item\Item, TransferTask\PickedTransferTaskProduct, TransferTask\TransferTask, TransferTask\TransferTaskProduct, User}; |
| 6 | use App\Helper\AppHelper; |
| 7 | use Domain\Address\Exceptions\AddressException; |
| 8 | use Domain\Item\Exceptions\ItemNotFoundException; |
| 9 | use Domain\Transaction\{Enums\TransactionOutputReasonEnum, Enums\TransactionTypeEnum}; |
| 10 | use Domain\Transferable\{DTOs\TransferItemDTO, |
| 11 | Exceptions\CantTransferItemException, |
| 12 | Services\TransferableTransferItemService}; |
| 13 | use Domain\TransferTask\{DTOs\TransferTaskPickProductDTO, Enums\PickedTransferTaskProductStatusEnum, Exceptions\PickedTransferTaskProductStatusException, Exceptions\TransferTaskStatusException}; |
| 14 | use Exception; |
| 15 | use Illuminate\{Database\Eloquent\Builder, Support\Facades\DB}; |
| 16 | use Throwable; |
| 17 | |
| 18 | readonly class TransferTaskPushProductService |
| 19 | { |
| 20 | /** |
| 21 | * @param TransferTaskPickProductDTO $transferTaskProductDTO |
| 22 | * @param Address $recipient |
| 23 | * @param User $user |
| 24 | * @return void |
| 25 | * @throws Throwable |
| 26 | */ |
| 27 | public function push(TransferTaskPickProductDTO $transferTaskProductDTO, Address $recipient, User $user): void |
| 28 | { |
| 29 | try { |
| 30 | DB::beginTransaction(); |
| 31 | |
| 32 | // $this->validateTransferTaskProductStatus($transferTaskProductDTO->transferTaskProduct); |
| 33 | // $this->validateTransferTaskStatus($transferTaskProductDTO->transferTaskProduct->transferTask); |
| 34 | |
| 35 | $pickedTransferTaskProduct = $this->findPickedItem($transferTaskProductDTO); |
| 36 | |
| 37 | $itemPickedTransferTask = $pickedTransferTaskProduct->item; |
| 38 | |
| 39 | // if ($this->validateTransferTaskProductAmount($pickedTransferTaskProduct, $transferTaskProductDTO)){ |
| 40 | // $pickedTransferTaskProduct->update(['item_id' => null]); |
| 41 | // } |
| 42 | |
| 43 | $item = $this->transferItem( |
| 44 | $itemPickedTransferTask, |
| 45 | $this->populateItemToTransferDTO($itemPickedTransferTask, $transferTaskProductDTO->amount), |
| 46 | $recipient, |
| 47 | $user, |
| 48 | $transferTaskProductDTO->observation |
| 49 | ); |
| 50 | |
| 51 | $this->handlePickedTransferTaskProduct( |
| 52 | $pickedTransferTaskProduct, |
| 53 | $transferTaskProductDTO, |
| 54 | $item, |
| 55 | $user |
| 56 | ); |
| 57 | |
| 58 | DB::commit(); |
| 59 | } catch (Throwable $throwable) { |
| 60 | DB::rollBack(); |
| 61 | throw $throwable; |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | /** |
| 66 | * @param Item $itemToTransfer |
| 67 | * @param float $amount |
| 68 | * @param array $readingLogDTOs |
| 69 | * @return TransferItemDTO |
| 70 | */ |
| 71 | private function populateItemToTransferDTO(Item $itemToTransfer, float $amount, array $readingLogDTOs = []): TransferItemDTO |
| 72 | { |
| 73 | return new TransferItemDTO([ |
| 74 | 'item' => $itemToTransfer, |
| 75 | 'amount' => $amount, |
| 76 | 'reading_logs' => $readingLogDTOs, |
| 77 | ]); |
| 78 | } |
| 79 | |
| 80 | /** |
| 81 | * @param TransferTaskProduct $transferTaskProduct |
| 82 | * @return void |
| 83 | */ |
| 84 | private function markTransferTaskProductAsPicked(TransferTaskProduct $transferTaskProduct): void |
| 85 | { |
| 86 | $transferTaskProduct->pick(); |
| 87 | $transferTaskProduct->save(); |
| 88 | } |
| 89 | |
| 90 | /** |
| 91 | * @param TransferTask $transferTask |
| 92 | * @return void |
| 93 | */ |
| 94 | private function validateTransferTaskStatus(TransferTask $transferTask): void |
| 95 | { |
| 96 | if ($transferTask->isPending()) { |
| 97 | $transferTask->start(); |
| 98 | $transferTask->save(); |
| 99 | } |
| 100 | |
| 101 | if ($transferTask->isCanceled()) { |
| 102 | throw new TransferTaskStatusException(__('Task is canceled')); |
| 103 | } |
| 104 | |
| 105 | if ($transferTask->isConcluded()) { |
| 106 | throw new TransferTaskStatusException(__('Task is concluded')); |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | /** |
| 111 | * @param TransferTaskPickProductDTO $transferTaskProductDTO |
| 112 | * @return PickedTransferTaskProduct |
| 113 | */ |
| 114 | public function findPickedItem(TransferTaskPickProductDTO $transferTaskProductDTO): PickedTransferTaskProduct |
| 115 | { |
| 116 | $pickedTransferTaskProduct = $transferTaskProductDTO->transferTaskProduct->pickedTransferTaskProduct() |
| 117 | ->whereHas('item', function (Builder $builder) use ($transferTaskProductDTO) { |
| 118 | $builder->whereHas('integration', function (Builder $builder) use ($transferTaskProductDTO) { |
| 119 | $builder->where('parameters->production_order', $transferTaskProductDTO->productionOrder); |
| 120 | }); |
| 121 | }) |
| 122 | ->get(); |
| 123 | |
| 124 | if (!$pickedTransferTaskProduct) { |
| 125 | throw new ItemNotFoundException(__('Item not found')); |
| 126 | } |
| 127 | |
| 128 | if ($pickedTransferTaskProduct->pluck('status')->doesntContain(PickedTransferTaskProductStatusEnum::TRANSFERRING)) { |
| 129 | throw new PickedTransferTaskProductStatusException(__('All items already transferred')); |
| 130 | } |
| 131 | |
| 132 | return $pickedTransferTaskProduct->where('status', PickedTransferTaskProductStatusEnum::TRANSFERRING)->first(); |
| 133 | } |
| 134 | |
| 135 | /** |
| 136 | * @param PickedTransferTaskProduct $pickedTransferTaskProduct |
| 137 | * @return void |
| 138 | */ |
| 139 | private function updatePickedProductStatus(PickedTransferTaskProduct $pickedTransferTaskProduct): void |
| 140 | { |
| 141 | $pickedTransferTaskProduct->pick(); |
| 142 | $pickedTransferTaskProduct->save(); |
| 143 | } |
| 144 | |
| 145 | /** |
| 146 | * @param PickedTransferTaskProduct $pickedTransferTaskProduct |
| 147 | * @param TransferItemDTO $itemToTransferDTO |
| 148 | * @param Address $recipient |
| 149 | * @param User $user |
| 150 | * @return Item |
| 151 | * @throws Exception |
| 152 | */ |
| 153 | private function transferItem(Item $item, TransferItemDTO $itemToTransferDTO, Address $recipient, User $user, ?string $observation = null): Item |
| 154 | { |
| 155 | $address = $item->itemable; |
| 156 | if (!$address instanceof Address) { |
| 157 | throw new AddressException(__('The sender is not an Address')); |
| 158 | } |
| 159 | |
| 160 | return (new TransferableTransferItemService())->transferOne( |
| 161 | $itemToTransferDTO, |
| 162 | $address, |
| 163 | $recipient, |
| 164 | TransactionTypeEnum::TRANSFER, |
| 165 | TransactionOutputReasonEnum::PRE_ORDER->value, |
| 166 | $user, |
| 167 | $observation, |
| 168 | $address->sector->value |
| 169 | ); |
| 170 | } |
| 171 | |
| 172 | /** |
| 173 | * @param PickedTransferTaskProduct $pickedTransferTaskProduct |
| 174 | * @param TransferTaskPickProductDTO $transferTaskProductDTO |
| 175 | * @param Item $item |
| 176 | * @param User $user |
| 177 | * @return void |
| 178 | */ |
| 179 | private function handlePickedTransferTaskProduct(PickedTransferTaskProduct $pickedTransferTaskProduct, TransferTaskPickProductDTO $transferTaskProductDTO, Item $item, User $user): void |
| 180 | { |
| 181 | if ($this->validateTransferTaskProductAmount($pickedTransferTaskProduct, $transferTaskProductDTO)) { |
| 182 | $this->updatePickedProductStatus($pickedTransferTaskProduct); |
| 183 | if ($this->getExistsOtherPickedTransferTaskProductTrasferring($transferTaskProductDTO)){ |
| 184 | $this->markTransferTaskProductAsPicked($transferTaskProductDTO->transferTaskProduct); |
| 185 | } |
| 186 | } else { |
| 187 | (new PickedTransferTaskProductStoreService())->store($transferTaskProductDTO, $item, $user, 'pick'); |
| 188 | $pickedTransferTaskProduct->setAttribute('amount', round($pickedTransferTaskProduct->getAttribute('amount') - $transferTaskProductDTO->amount, 2)); |
| 189 | $pickedTransferTaskProduct->save(); |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | /** |
| 194 | * @param TransferTaskProduct $transferTaskProduct |
| 195 | * @return void |
| 196 | */ |
| 197 | public function validateTransferTaskProductStatus(TransferTaskProduct $transferTaskProduct): void |
| 198 | { |
| 199 | if ($transferTaskProduct->isPicked()) { |
| 200 | throw new CantTransferItemException(__('Product is already picked')); |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | public function validateTransferTaskProductAmount(PickedTransferTaskProduct $pickedTransferTaskProduct, TransferTaskPickProductDTO $transferTaskProductDTO): bool |
| 205 | { |
| 206 | return $pickedTransferTaskProduct->getAttribute('amount') == $transferTaskProductDTO->amount; |
| 207 | } |
| 208 | |
| 209 | public function getExistsOtherPickedTransferTaskProductTrasferring(TransferTaskPickProductDTO $transferTaskProductDTO): bool |
| 210 | { |
| 211 | $transferTaskProducts = $transferTaskProductDTO->transferTaskProduct->pickedTransferTaskProduct() |
| 212 | ->where('status', PickedTransferTaskProductStatusEnum::TRANSFERRING) |
| 213 | ->get(); |
| 214 | |
| 215 | return $transferTaskProducts->isEmpty(); |
| 216 | } |
| 217 | } |