import { Head, Link, useForm } from '@inertiajs/react'; import { Plus, Save, Trash2 } from 'lucide-react'; import { FormErrors, PageTitle, Panel, controlClass, } from '@/components/procurement'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { money } from '@/types/procurement'; import type { CostCenter, Requisition } from '@/types/procurement'; type Line = { key: string; description: string; category: string; purchase_type: string; quantity: string; unit: string; unit_price: string; tax_rate: string; equipment_id: string; spare_part_id: string; production_area: string; downtime_started_at: string; }; const emptyLine = (): Line => ({ key: crypto.randomUUID(), description: '', category: '', purchase_type: 'consumable', quantity: '1', unit: 'un', unit_price: '', tax_rate: '0', equipment_id: '', spare_part_id: '', production_area: '', downtime_started_at: '', }); const lineFields = [ { key: 'description', label: 'Descrição', type: 'text', maxLength: 255 }, { key: 'category', label: 'Categoria', type: 'text', maxLength: 100 }, { key: 'quantity', label: 'Quantidade', type: 'number', min: '0.001', max: '1000000', step: '0.001', }, { key: 'unit', label: 'Unidade', type: 'text', maxLength: 30 }, { key: 'unit_price', label: 'Preço unitário sem IVA (MZN)', type: 'number', min: '0.01', max: '100000000', step: '0.01', }, { key: 'tax_rate', label: 'Taxa de IVA (%)', type: 'number', min: '0', max: '100', step: '0.01', }, ] as const; export default function RequisitionForm({ costCenters, requisition, equipment = [], spareParts = [], stockItems = [], }: { costCenters: CostCenter[]; requisition: Requisition | null; equipment?: { id: number; code: string; description: string }[]; spareParts?: { id: number; stock_item_id: number }[]; stockItems?: { id: number; code: string; name: string; unit: string }[]; }) { const form = useForm({ cost_center_id: requisition ? String(requisition.cost_center_id) : '', priority: requisition?.priority ?? 'normal', needed_by: requisition?.needed_by ?? '', justification: requisition?.justification ?? '', items: requisition?.items.map((i) => ({ key: String(i.id), description: i.description, category: i.category, purchase_type: i.purchase_type, quantity: String(i.quantity), unit: i.unit, unit_price: (i.unit_price_minor / 100).toFixed(2), tax_rate: String(i.tax_rate), equipment_id: i.equipment_id ? String(i.equipment_id) : '', spare_part_id: i.spare_part_id ? String(i.spare_part_id) : '', production_area: i.production_area ?? '', downtime_started_at: i.downtime_started_at?.slice(0, 16) ?? '', })) ?? [emptyLine()], }); const changeLine = (index: number, field: keyof Line, value: string) => form.setData( 'items', form.data.items.map((item, i) => i === index ? { ...item, [field]: value } : item, ), ); const estimate = form.data.items.reduce( (sum, i) => sum + Math.round( Math.round(Number(i.quantity) * Number(i.unit_price) * 100) * (1 + Number(i.tax_rate) / 100), ), 0, ); return ( <>
{ e.preventDefault(); if (requisition) form.put(`/requisicoes/${requisition.id}`); else form.post('/requisicoes'); }} > {costCenters.length === 0 && (
O seu departamento ainda não tem centros de custo. Peça ao administrador para criar um antes de registar pedidos.
)}
form.setData( 'needed_by', e.target.value, ) } />