Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.98% covered (success)
93.98%
78 / 83
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
StockOutputRequestResource
93.98% covered (success)
93.98%
78 / 83
75.00% covered (warning)
75.00%
3 / 4
23.12
0.00% covered (danger)
0.00%
0 / 1
 toArray
91.53% covered (success)
91.53%
54 / 59
0.00% covered (danger)
0.00%
0 / 1
12.09
 resolvePurchaseSolicitationIds
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
5
 resolveRequestObservations
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 hasSolicitationIdentifier
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace Domain\StockIO\Resources;
4
5use App\Models\CostCenter\CostCenter;
6use App\Models\User;
7use App\Models\Transferable\Transferable;
8use Domain\CostCenter\Resources\CostCenterResource;
9use Domain\CostCenter\Resources\ResourceCenterResource;
10use Domain\Integration\Resources\IntegrationResource;
11use Domain\PickingOrder\Resources\PickingOrderResource;
12use Domain\Request\Resources\RequestResource;
13use Domain\Shared\Enums\SectorEnum;
14use Domain\StockIO\Enums\StockStatusEnum;
15use Domain\StockIO\Enums\StockStatusTaskEnum;
16use Domain\StockIO\Enums\StockTypeEnum;
17use Domain\Team\Resources\TeamResource;
18use Domain\User\Resources\UserResource;
19use Illuminate\Database\Eloquent\Collection;
20use Illuminate\Http\Request;
21use Illuminate\Http\Resources\Json\JsonResource;
22use Illuminate\Validation\Rules\Exists;
23
24/**
25 * @property StockStatusEnum $status
26 * @property ?string $observation
27 * @property Collection $items
28 * @property StockTypeEnum $type
29 * @property array $data
30 * @property int $id
31 * @property Transferable|null $transferable
32 * @property string $created_at
33 * @property bool $urgent
34 * @property int $reason
35 * @property SectorEnum $sector
36 */
37class StockOutputRequestResource extends JsonResource
38{
39    public function toArray(Request $request): array
40    {
41        $applicant = null;
42        $costCenter = null;
43        $resourceCenter = null;
44        $resource = null;
45        $requester = null;
46        $purchaseSolicitationIds = $this->resolvePurchaseSolicitationIds();
47        $hasPurchaseSolicitation = count($purchaseSolicitationIds) > 0;
48        $purchaseSolicitationId = $purchaseSolicitationIds[0] ?? null;
49        $requestObservations = $this->resolveRequestObservations();
50
51        if (!is_null($this->resource->request)) {
52            $requester = $this->resource->request->requester;
53        } else if ($this->integration && isset($this->integration->parameters['request_user'])) {
54            $requester = User::whereRaw("integrations->'senior'->>'user_code' = ?", [(string) $this->integration->parameters['request_user']])->first();
55        }
56
57        if ($this->resource->request) {
58            $applicant = $this->resource->request->applicant;
59
60            $costCenter = $this->resource->request->costCenter;
61            $resourceCenter = $this->resource->request->resourceCenter;
62
63            $resource = $this->resource->request->resource;
64        }
65
66        if ($this->integration && isset($this->integration->parameters['cost_center']) && is_null($costCenter)) {
67            $costCenterCode = $this->integration->parameters['cost_center'];
68            $costCenter = CostCenter::with('resourceCenter')->whereHas('integration', function ($query) use ($costCenterCode) {
69                $query->whereRaw("parameters->>'cost_center_code' = ?", [$costCenterCode]);
70            })->first();
71        }
72
73        $hasDelivery = $this->stockIOProducts
74            ->contains(fn ($p) => $p->requestDeliveries->isNotEmpty());
75
76        return [
77            'id'                => $this->id,
78            'transferable'      => $this->whenLoaded('transferable'),
79            'urgent'            => $this->urgent,
80            'observation'       => $this->observation,
81            'request_observations' => $requestObservations,
82            'request_observation' => implode('; ', $requestObservations),
83            'status'            => $this->status->value,
84            'type'              => $this->type->value,
85            'reason'            => $this->reason,
86            'sector'            => $this->sector->value,
87            'team'              => TeamResource::make($this->whenLoaded('team')),
88            'stock_io_products' => StockIOProductResource::collection(
89                $this->whenLoaded('stockIOProducts', function() {
90                    // Carrega o produto apenas se ele ainda não foi carregado
91                    // Isso preserva a 'family' se ela já tiver sido carregada pelo Controller
92                    // não Ã© a melhor abordagem deixar fixo no resource
93                    return $this->stockIOProducts->loadMissing('product');
94                })
95            ),
96            'start_date'        => (string) $this->start_date,
97            'end_date'          => (string) $this->end_date,
98            'created_at'        => (string) $this->created_at,
99            'responsible'       => UserResource::make($this->whenLoaded('responsible')),
100            'picking_orders'    => PickingOrderResource::collection($this->whenLoaded('pickingOrders')),
101            'requests'          => RequestResource::collection($this->whenLoaded('requests')),
102            'integration'       => IntegrationResource::make($this->whenLoaded('integration')),
103            'all_items_in_task' => $this->picking_status ? StockStatusTaskEnum::from($this->picking_status) : null,
104            'applicant'         => json_decode($applicant),
105            'requester'         => $requester ? UserResource::make($requester) : null,
106            'cost_center'       => $costCenter ? CostCenterResource::make($costCenter->load('integration')) : null,
107            'resource_center'   => $resourceCenter ? ResourceCenterResource::make($resourceCenter->load('integration')) : null,
108            'resource'          => json_decode($resource),
109            'has_deliveries'    => $hasDelivery,
110            'has_purchase_solicitation' => $hasPurchaseSolicitation,
111            'purchase_solicitation_id' => $purchaseSolicitationId,
112        ];
113    }
114
115    private function resolvePurchaseSolicitationIds(): array
116    {
117        $solicitationIds = [];
118
119        $this->stockIOProducts->loadMissing('integration');
120
121        foreach ($this->stockIOProducts as $stockIOProduct) {
122            $productSolicitationId = data_get($stockIOProduct->integration?->parameters, 'purchase_solicitation_number');
123            if ($this->hasSolicitationIdentifier($productSolicitationId)) {
124                $solicitationIds[] = (string) $productSolicitationId;
125            }
126        }
127
128        if (count($solicitationIds) === 0) {
129            $this->loadMissing('integration');
130            $legacySolicitationId = data_get($this->integration?->parameters, 'solicitation_number');
131
132            if ($this->hasSolicitationIdentifier($legacySolicitationId)) {
133                $solicitationIds[] = (string) $legacySolicitationId;
134            }
135        }
136
137        return array_values(array_unique($solicitationIds));
138    }
139
140    private function resolveRequestObservations(): array
141    {
142        $this->stockIOProducts->loadMissing('integration');
143
144        return $this->stockIOProducts
145            ->map(fn ($stockIOProduct) => data_get($stockIOProduct->integration?->parameters, 'obsEme'))
146            ->map(fn ($observation) => is_null($observation) ? null : trim((string) $observation))
147            ->filter(fn ($observation) => !is_null($observation) && $observation !== '')
148            ->unique()
149            ->values()
150            ->all();
151    }
152
153    private function hasSolicitationIdentifier(mixed $value): bool
154    {
155        if (is_null($value)) {
156            return false;
157        }
158
159        $normalized = trim((string) $value);
160        return $normalized !== '' && $normalized !== '0';
161    }
162}