import React, { useState, useEffect } from 'react'; import { X, Plus, Minus, User, ShoppingCart, FileText, Calculator, Package } from 'lucide-react'; import { Button, Input, Select, Card, Badge } from '../../ui'; import { EditViewModal } from '../../ui/EditViewModal'; import type { StatusModalSection } from '../../ui/EditViewModal'; import { OrderCreate, OrderItemCreate, CustomerResponse, OrderType, PriorityLevel, DeliveryMethod, PaymentMethod, PaymentTerms, OrderSource, SalesChannel, CustomerCreate, CustomerType, CustomerSegment } from '../../../api/types/orders'; import { useCustomers, useCreateCustomer } from '../../../api/hooks/orders'; import { useIngredients } from '../../../api/hooks/inventory'; import { ProductType, ProductCategory } from '../../../api/types/inventory'; import { useCurrentTenant } from '../../../stores/tenant.store'; import { useAuthUser } from '../../../stores/auth.store'; import { useTranslation } from 'react-i18next'; interface OrderFormModalProps { isOpen: boolean; onClose: () => void; onSave: (orderData: OrderCreate) => Promise; } export const OrderFormModal: React.FC = ({ isOpen, onClose, onSave }) => { const currentTenant = useCurrentTenant(); const user = useAuthUser(); const tenantId = currentTenant?.id || user?.tenant_id || ''; const { t } = useTranslation(['orders', 'common']); // Create enum options using direct i18n const orderTypeOptions = Object.values(OrderType).map(value => ({ value, label: t(`orders:order_types.${value}`) })); const priorityLevelOptions = Object.values(PriorityLevel).map(value => ({ value, label: t(`orders:priority_levels.${value}`) })); const deliveryMethodOptions = Object.values(DeliveryMethod).map(value => ({ value, label: t(`orders:delivery_methods.${value}`) })); const customerTypeOptions = Object.values(CustomerType).map(value => ({ value, label: t(`orders:customer_types.${value}`) })); // Form state const [selectedCustomer, setSelectedCustomer] = useState(null); const [orderItems, setOrderItems] = useState([]); const [orderData, setOrderData] = useState>({ order_type: OrderType.STANDARD, priority: PriorityLevel.NORMAL, delivery_method: DeliveryMethod.PICKUP, discount_percentage: 0, delivery_fee: 0, payment_terms: PaymentTerms.IMMEDIATE, order_source: OrderSource.MANUAL, sales_channel: SalesChannel.DIRECT }); // Customer modals const [showCustomerForm, setShowCustomerForm] = useState(false); const [showCustomerSelector, setShowCustomerSelector] = useState(false); const [newCustomerData, setNewCustomerData] = useState>({ customer_type: CustomerType.INDIVIDUAL, country: 'España', is_active: true, preferred_delivery_method: DeliveryMethod.PICKUP, payment_terms: PaymentTerms.IMMEDIATE, discount_percentage: 0, customer_segment: CustomerSegment.REGULAR, priority_level: PriorityLevel.NORMAL }); // Simple product selection const [selectedProductId, setSelectedProductId] = useState(''); const [selectedQuantity, setSelectedQuantity] = useState(1); // API hooks const { data: customers = [] } = useCustomers({ tenant_id: tenantId, active_only: true, limit: 100 }); // Fetch finished products from inventory const { data: finishedProducts = [], isLoading: productsLoading } = useIngredients( tenantId, { product_type: ProductType.FINISHED_PRODUCT, is_active: true } ); const createCustomerMutation = useCreateCustomer(); // Calculate totals const subtotal = orderItems.reduce((sum, item) => sum + (item.quantity * item.unit_price), 0); const discountAmount = subtotal * (orderData.discount_percentage || 0) / 100; const taxAmount = (subtotal - discountAmount) * 0.21; // 21% VAT const total = subtotal - discountAmount + taxAmount + (orderData.delivery_fee || 0); useEffect(() => { if (!isOpen) { // Reset form when modal closes setSelectedCustomer(null); setOrderItems([]); setSelectedProductId(''); setSelectedQuantity(1); setOrderData({ order_type: OrderType.STANDARD, priority: PriorityLevel.NORMAL, delivery_method: DeliveryMethod.PICKUP, discount_percentage: 0, delivery_fee: 0, payment_terms: PaymentTerms.IMMEDIATE, order_source: OrderSource.MANUAL, sales_channel: SalesChannel.DIRECT }); } }, [isOpen]); const handleAddSelectedProduct = () => { if (!selectedProductId || selectedQuantity <= 0) return; const product = finishedProducts.find(p => p.id === selectedProductId); if (!product) return; const existingItem = orderItems.find(item => item.product_id === selectedProductId); if (existingItem) { setOrderItems(items => items.map(item => item.product_id === selectedProductId ? { ...item, quantity: item.quantity + selectedQuantity } : item )); } else { const newItem: OrderItemCreate = { product_id: product.id, product_name: product.name, product_sku: product.sku || undefined, product_category: product.category || undefined, quantity: selectedQuantity, unit_of_measure: product.unit_of_measure || 'unidad', unit_price: product.average_cost || product.standard_cost || 0, line_discount: 0 }; setOrderItems(items => [...items, newItem]); } // Reset selection setSelectedProductId(''); setSelectedQuantity(1); }; const handleUpdateItemQuantity = (productId: string, quantity: number) => { if (quantity <= 0) { setOrderItems(items => items.filter(item => item.product_id !== productId)); } else { setOrderItems(items => items.map(item => item.product_id === productId ? { ...item, quantity } : item )); } }; const handleCreateCustomer = async () => { if (!newCustomerData.name || !tenantId) return; try { const customerData: CustomerCreate = { ...newCustomerData, tenant_id: tenantId, customer_code: `CUST-${Date.now()}` // Generate simple code } as CustomerCreate; const newCustomer = await createCustomerMutation.mutateAsync(customerData); setSelectedCustomer(newCustomer); setShowCustomerForm(false); setNewCustomerData({ customer_type: CustomerType.INDIVIDUAL, country: 'España', is_active: true, preferred_delivery_method: DeliveryMethod.PICKUP, payment_terms: PaymentTerms.IMMEDIATE, discount_percentage: 0, customer_segment: CustomerSegment.REGULAR, priority_level: PriorityLevel.NORMAL }); } catch (error) { console.error('Error creating customer:', error); } }; const handleSaveOrder = async () => { if (!selectedCustomer || orderItems.length === 0 || !tenantId) return; const finalOrderData: OrderCreate = { tenant_id: tenantId, customer_id: selectedCustomer.id, order_type: orderData.order_type || OrderType.STANDARD, priority: orderData.priority || PriorityLevel.NORMAL, requested_delivery_date: orderData.requested_delivery_date || new Date().toISOString(), delivery_method: orderData.delivery_method || DeliveryMethod.PICKUP, delivery_fee: orderData.delivery_fee || 0, discount_percentage: orderData.discount_percentage || 0, payment_terms: orderData.payment_terms || PaymentTerms.IMMEDIATE, order_source: orderData.order_source || OrderSource.MANUAL, sales_channel: orderData.sales_channel || SalesChannel.DIRECT, items: orderItems, special_instructions: orderData.special_instructions }; await onSave(finalOrderData); onClose(); }; // Convert form data to StatusModal sections const modalSections: StatusModalSection[] = [ { title: 'Cliente', icon: User, fields: [ { label: 'Cliente Seleccionado', value: selectedCustomer ? selectedCustomer.id : '', type: 'select', editable: true, placeholder: 'Seleccionar cliente...', options: customers.map(customer => ({ value: customer.id, label: `${customer.name} (${customer.customer_code})` })), span: 1 }, { label: 'Nuevo Cliente', value: ( ), span: 1 } ] }, { title: 'Detalles del Pedido', icon: FileText, fields: [ { label: 'Tipo de Pedido', value: orderData.order_type || OrderType.STANDARD, type: 'select', editable: true, options: orderTypeOptions }, { label: 'Prioridad', value: orderData.priority || PriorityLevel.NORMAL, type: 'select', editable: true, options: priorityLevelOptions }, { label: 'Método de Entrega', value: orderData.delivery_method || DeliveryMethod.PICKUP, type: 'select', editable: true, options: deliveryMethodOptions }, { label: 'Fecha de Entrega', value: orderData.requested_delivery_date?.split('T')[0] || '', type: 'date', editable: true } ] }, { title: 'Productos', icon: Package, fields: [ { label: 'Agregar Producto', value: (
setSelectedQuantity(Number(e.target.value))} placeholder="Cant." />
), span: 2 }, ...(orderItems.length > 0 ? [{ label: 'Productos en el Pedido', value: (
{orderItems.map((item, index) => (

{item.product_name}

€{item.unit_price.toFixed(2)} × {item.quantity} = €{(item.unit_price * item.quantity).toFixed(2)}

{item.quantity}
))}
), span: 2 }] : []) ] }, { title: 'Resumen Financiero', icon: Calculator, fields: [ { label: 'Subtotal', value: subtotal, type: 'currency', highlight: true }, { label: 'Descuento', value: -discountAmount, type: 'currency' }, { label: 'IVA (21%)', value: taxAmount, type: 'currency' }, { label: 'Gastos de Envío', value: orderData.delivery_fee || 0, type: 'currency', editable: true }, { label: 'Total', value: total, type: 'currency', highlight: true, span: 2 } ] } ]; const handleFieldChange = (sectionIndex: number, fieldIndex: number, value: string | number) => { const section = modalSections[sectionIndex]; const field = section.fields[fieldIndex]; // Update order data based on field changes if (section.title === 'Cliente') { if (field.label === 'Cliente Seleccionado') { const customer = customers.find(c => c.id === value); setSelectedCustomer(customer || null); } } else if (section.title === 'Detalles del Pedido') { if (field.label === 'Tipo de Pedido') { setOrderData(prev => ({ ...prev, order_type: value as OrderType })); } else if (field.label === 'Prioridad') { setOrderData(prev => ({ ...prev, priority: value as PriorityLevel })); } else if (field.label === 'Método de Entrega') { setOrderData(prev => ({ ...prev, delivery_method: value as DeliveryMethod })); } else if (field.label === 'Fecha de Entrega') { setOrderData(prev => ({ ...prev, requested_delivery_date: value ? `${value}T12:00:00Z` : undefined })); } } else if (section.title === 'Resumen Financiero' && field.label === 'Gastos de Envío') { setOrderData(prev => ({ ...prev, delivery_fee: Number(value) })); } }; return ( <> {/* Legacy content for sections that need custom UI */}
{/* New Customer Modal - Using StatusModal for consistency */} setShowCustomerForm(false)} mode="edit" title="Nuevo Cliente" subtitle="Complete la información del cliente" size="lg" showDefaultActions={false} sections={[ { title: 'Información Personal', icon: User, fields: [ { label: 'Nombre *', value: newCustomerData.name || '', type: 'text', editable: true, required: true, placeholder: 'Nombre del cliente' }, { label: 'Teléfono', value: newCustomerData.phone || '', type: 'tel', editable: true, placeholder: 'Número de teléfono' }, { label: 'Email', value: newCustomerData.email || '', type: 'email', editable: true, placeholder: 'Correo electrónico', span: 2 }, { label: 'Tipo de Cliente', value: newCustomerData.customer_type || CustomerType.INDIVIDUAL, type: 'select', editable: true, options: customerTypeOptions }, { label: 'Método de Entrega Preferido', value: newCustomerData.preferred_delivery_method || DeliveryMethod.PICKUP, type: 'select', editable: true, options: deliveryMethodOptions } ] } ]} actions={[ { label: 'Cancelar', variant: 'outline', onClick: () => setShowCustomerForm(false) }, { label: 'Crear Cliente', variant: 'primary', onClick: handleCreateCustomer, disabled: !newCustomerData.name } ]} onFieldChange={(sectionIndex, fieldIndex, value) => { // Get the customer modal sections instead of the order modal sections const customerModalSections = [ { title: 'Información Personal', icon: User, fields: [ { label: 'Nombre *' }, { label: 'Teléfono' }, { label: 'Email' }, { label: 'Tipo de Cliente' }, { label: 'Método de Entrega Preferido' } ] } ]; const field = customerModalSections[sectionIndex]?.fields[fieldIndex]; if (!field) return; if (field.label === 'Nombre *') { setNewCustomerData(prev => ({ ...prev, name: String(value) })); } else if (field.label === 'Teléfono') { setNewCustomerData(prev => ({ ...prev, phone: String(value) })); } else if (field.label === 'Email') { setNewCustomerData(prev => ({ ...prev, email: String(value) })); } else if (field.label === 'Tipo de Cliente') { setNewCustomerData(prev => ({ ...prev, customer_type: value as CustomerType })); } else if (field.label === 'Método de Entrega Preferido') { setNewCustomerData(prev => ({ ...prev, preferred_delivery_method: value as DeliveryMethod })); } }} /> {/* Customer Selector Modal */} setShowCustomerSelector(false)} mode="view" title="Seleccionar Cliente" subtitle="Elija un cliente existente o cree uno nuevo" size="lg" showDefaultActions={false} sections={[ { title: 'Clientes Disponibles', icon: User, fields: [ { label: 'Lista de clientes', value: (
{customers.length === 0 ? (

No hay clientes disponibles

) : ( customers.map(customer => (

{customer.name}

Código: {customer.customer_code}

{customer.email &&
📧 {customer.email}
} {customer.phone &&
📞 {customer.phone}
}
)) )}
), span: 2 } ] } ]} actions={[ { label: 'Nuevo Cliente', variant: 'outline', onClick: () => { setShowCustomerSelector(false); setShowCustomerForm(true); } }, { label: 'Cerrar', variant: 'primary', onClick: () => setShowCustomerSelector(false) } ]} /> ); }; export default OrderFormModal;