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 { StatusModal } from '../../ui/StatusModal'; import type { StatusModalSection } from '../../ui/StatusModal'; 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 { useOrderEnums } from '../../../utils/enumHelpers'; 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 orderEnums = useOrderEnums(); // 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 }); // Product selection const [showProductModal, setShowProductModal] = useState(false); const [productSearch, setProductSearch] = useState(''); const [selectedCategory, setSelectedCategory] = useState(''); // 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([]); setProductSearch(''); setSelectedCategory(''); 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 handleAddProduct = (product: any) => { const existingItem = orderItems.find(item => item.product_id === product.id); if (existingItem) { setOrderItems(items => items.map(item => item.product_id === product.id ? { ...item, quantity: item.quantity + 1 } : item )); } else { const newItem: OrderItemCreate = { product_id: product.id, product_name: product.name, product_sku: product.sku || undefined, product_category: product.category || undefined, quantity: 1, unit_of_measure: product.unit_of_measure || 'unidad', unit_price: product.average_cost || product.standard_cost || 0, line_discount: 0 }; setOrderItems(items => [...items, newItem]); } setShowProductModal(false); }; 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(); }; // Get unique categories for filtering const uniqueCategories = Array.from(new Set( finishedProducts .map(product => product.category) .filter(Boolean) )).sort(); const filteredProducts = finishedProducts.filter(product => { const matchesSearch = product.name.toLowerCase().includes(productSearch.toLowerCase()) || (product.category && product.category.toLowerCase().includes(productSearch.toLowerCase())) || (product.description && product.description.toLowerCase().includes(productSearch.toLowerCase())); const matchesCategory = !selectedCategory || product.category === selectedCategory; return matchesSearch && matchesCategory; }); // Convert form data to StatusModal sections const modalSections: StatusModalSection[] = [ { title: 'Cliente', icon: User, fields: [ { label: 'Cliente Seleccionado', value: selectedCustomer ? `${selectedCustomer.name} (${selectedCustomer.customer_code})` : 'Ninguno', span: 2 } ] }, { title: 'Detalles del Pedido', icon: FileText, fields: [ { label: 'Tipo de Pedido', value: orderData.order_type || OrderType.STANDARD, type: 'select', editable: true, options: orderEnums.getOrderTypeOptions() }, { label: 'Prioridad', value: orderData.priority || PriorityLevel.NORMAL, type: 'select', editable: true, options: orderEnums.getPriorityLevelOptions() }, { label: 'Método de Entrega', value: orderData.delivery_method || DeliveryMethod.PICKUP, type: 'select', editable: true, options: orderEnums.getDeliveryMethodOptions() }, { label: 'Fecha de Entrega', value: orderData.requested_delivery_date?.split('T')[0] || '', type: 'date', editable: true } ] }, { title: 'Productos', icon: Package, fields: [ { label: 'Total de Productos', value: orderItems.length, highlight: true }, { label: 'Lista de Productos', value: orderItems.length > 0 ? orderItems.map(item => `${item.product_name} (x${item.quantity})`).join(', ') : 'Sin productos', 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 === '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 ( <> setShowCustomerSelector(true) }, { label: 'Agregar Productos', variant: 'outline', onClick: () => setShowProductModal(true), icon: Plus }, { label: 'Cancelar', variant: 'outline', onClick: onClose }, { label: 'Crear Pedido', variant: 'primary', onClick: handleSaveOrder, disabled: !selectedCustomer || orderItems.length === 0 } ]} onFieldChange={handleFieldChange} /> {/* Legacy content for sections that need custom UI */}
{/* Product Selection Modal - Using StatusModal for consistency */} setShowProductModal(false)} mode="view" title="Seleccionar Productos" subtitle="Elija productos terminados para agregar al pedido" size="2xl" showDefaultActions={false} sections={[ { title: 'Filtros', icon: Package, fields: [ { label: 'Buscar productos', value: productSearch, type: 'text', editable: true, placeholder: 'Buscar productos...', span: 1 }, { label: 'Categoría', value: selectedCategory, type: 'select', editable: true, placeholder: 'Todas las categorías', options: [ { value: '', label: 'Todas las categorías' }, ...uniqueCategories.map(category => ({ value: category, label: category })) ], span: 1 } ] }, { title: 'Productos Disponibles', icon: ShoppingCart, fields: [ { label: 'Lista de productos', value: (
{productsLoading ? (

Cargando productos...

) : filteredProducts.length === 0 ? (

{productSearch ? 'No se encontraron productos que coincidan con la búsqueda' : 'No hay productos finalizados disponibles'}

) : ( filteredProducts.map(product => (

{product.name}

{product.description && (

{product.description}

)}
{product.category && ( {product.category} )} €{(product.average_cost || product.standard_cost || 0).toFixed(2)}
Stock: {product.total_quantity || 0} {product.unit_of_measure} {product.sku && SKU: {product.sku}}
)) )}
), span: 2 } ] } ]} onFieldChange={(sectionIndex, fieldIndex, value) => { if (sectionIndex === 0) { if (fieldIndex === 0) { setProductSearch(String(value)); } else if (fieldIndex === 1) { setSelectedCategory(String(value)); } } }} /> {/* 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: orderEnums.getCustomerTypeOptions() }, { label: 'Método de Entrega Preferido', value: newCustomerData.preferred_delivery_method || DeliveryMethod.PICKUP, type: 'select', editable: true, options: orderEnums.getDeliveryMethodOptions() } ] } ]} 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;