user(); return $user !== null && $user->tenant_id !== null && $user->department_id !== null; } /** @return array */ public function rules(): array { return [ 'operation_key' => 'nullable|uuid', 'process_version' => 'nullable|integer|min:1', 'cost_center_id' => ['required', 'integer', Rule::exists('cost_centers', 'id')->where('tenant_id', $this->user()?->tenant_id)->where('department_id', $this->user()?->department_id)], 'priority' => ['required', Rule::in(['normal', 'high', 'urgent'])], 'needed_by' => ['required', 'date_format:Y-m-d', 'after_or_equal:today'], 'justification' => ['required', 'string', 'min:10', 'max:5000'], 'items' => ['required', 'array', 'min:1', 'max:50'], 'items.*.catalogue_entry_id' => 'nullable|integer|min:1', 'items.*.catalogue_version' => 'nullable|required_with:items.*.catalogue_entry_id|integer|min:1', 'items.*.source_line_id' => 'nullable|integer|min:1', 'items.*.description' => ['required_without:items.*.catalogue_entry_id', 'string', 'max:255'], 'items.*.category' => ['required_without:items.*.catalogue_entry_id', 'string', 'max:100'], 'items.*.purchase_type' => ['required_without:items.*.catalogue_entry_id', Rule::in(['consumable', 'service', 'other', 'equipment', 'spare_part'])], 'items.*.equipment_id' => ['exclude_unless:items.*.purchase_type,spare_part', 'required', 'integer', Rule::exists('equipment', 'id')->where('tenant_id', $this->user()?->tenant_id)->where('department_id', $this->user()?->department_id)], 'items.*.spare_part_id' => ['exclude_unless:items.*.purchase_type,spare_part', 'required', 'integer', Rule::exists('spare_parts', 'id')->where('tenant_id', $this->user()?->tenant_id)], 'items.*.production_area' => 'exclude_unless:items.*.purchase_type,equipment|required|string|max:200', 'items.*.downtime_started_at' => 'exclude_unless:items.*.purchase_type,spare_part|nullable|date_format:Y-m-d\TH:i|before_or_equal:now', 'items.*.quantity' => ['required', 'numeric', 'min:0.001', 'max:1000000', 'regex:/^\d+(\.\d{1,3})?$/'], 'items.*.unit' => ['required_without:items.*.catalogue_entry_id', 'string', 'max:30'], 'items.*.unit_price' => ['required', 'numeric', 'min:0.01', 'max:100000000', 'regex:/^\d+(\.\d{1,2})?$/'], 'items.*.tax_rate' => ['required', 'numeric', 'between:0,100', 'regex:/^\d+(\.\d{1,2})?$/'], ]; } /** @return array */ public function messages(): array { return [ 'cost_center_id.exists' => 'Seleccione um centro de custo do seu departamento.', 'needed_by.after_or_equal' => 'A entrega pretendida deve ser hoje ou numa data futura.', 'justification.min' => 'Descreva a necessidade da compra com pelo menos 10 caracteres.', 'items.*.quantity.regex' => 'Use até três casas decimais na quantidade.', 'items.*.unit_price.regex' => 'Use até duas casas decimais no preço.', 'items.*.tax_rate.regex' => 'Use até duas casas decimais na taxa de IVA.', ]; } }