user() !== null; } public function rules(): array { $base = ['phase'=>'required|in:preview,confirm', 'order_id'=>'required|integer|min:1']; if ($this->input('phase') === 'confirm') return $base + ['preview'=>'required|string|max:131072']; return $base + ['revision'=>'required|string|regex:/^[a-f0-9]{64}$/D', 'reason'=>'required|string|min:10|max:2000', 'data'=>'required|array:number,issued_on,subtotal,tax,total,items', 'data.number'=>'required|string|max:80', 'data.issued_on'=>'required|date_format:Y-m-d', 'data.subtotal'=>'required|string|regex:/^\d{1,12}\.\d{2}$/D', 'data.tax'=>'required|string|regex:/^\d{1,12}\.\d{2}$/D', 'data.total'=>'required|string|regex:/^\d{1,12}\.\d{2}$/D', 'data.items'=>'required|array|min:1|max:50', 'data.items.*'=>'required|array:purchase_order_item_id,quantity,unit,unit_price,tax_rate', 'data.items.*.purchase_order_item_id'=>'required|integer|min:1|distinct', 'data.items.*.quantity'=>'required|string|regex:/^\d{1,12}(\.\d{1,3})?$/D', 'data.items.*.unit'=>'required|string|max:20', 'data.items.*.unit_price'=>'required|string|regex:/^\d{1,12}\.\d{2}$/D', 'data.items.*.tax_rate'=>'required|string|regex:/^\d{1,3}(\.\d{1,2})?$/D']; } public function after(): array { return [function ($validator) { $allowed = $this->input('phase') === 'confirm' ? ['phase','order_id','preview'] : ['phase','order_id','revision','reason','data']; if ($this->query->count() || array_diff(array_keys($this->json()->all()), $allowed)) $validator->errors()->add('payload', 'Campos ou parâmetros não permitidos.'); if (!preg_match('/^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-8][a-fA-F0-9]{3}-[89aAbB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$/D', (string)$this->header('X-Idempotency-Key'))) $validator->errors()->add('idempotency_key', 'X-Idempotency-Key UUID obrigatório.'); }]; } }