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'; import { CatalogueSearch } from '@/components/requisition-catalogue'; import type { CatalogueOptions } from '@/components/requisition-catalogue'; type Line = { source_line_id: string; catalogue_entry_id: string; catalogue_version: string; catalogue_code: string; 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 = (taxRate: string): Line => ({ source_line_id: '', catalogue_entry_id: '', catalogue_version: '', catalogue_code: '', key: crypto.randomUUID(), description: '', category: '', purchase_type: 'consumable', quantity: '1', unit: 'un', unit_price: '', tax_rate: taxRate, 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 = [], defaultTaxRate = '16.00', catalogue, }: { 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 }[]; defaultTaxRate?: string; catalogue?: CatalogueOptions; }) { 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) => ({ source_line_id: i.id ? String(i.id) : '', catalogue_entry_id: i.catalogue_entry_id ? String(i.catalogue_entry_id) : '', catalogue_version: i.catalogue_snapshot ? String(i.catalogue_snapshot.version) : '', catalogue_code: i.catalogue_snapshot?.code ?? '', 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(defaultTaxRate)], }); 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, ) } />