import React, { useState, useEffect } from 'react'; import { WizardStep, WizardStepProps } from '../../../ui/WizardModal/WizardModal'; import { Edit3, Upload, CheckCircle2, AlertCircle, Download, FileSpreadsheet, Calendar, DollarSign, Package, CreditCard, Loader2, X, } from 'lucide-react'; import { useTenant } from '../../../../stores/tenant.store'; import { salesService } from '../../../../api/services/sales'; import { inventoryService } from '../../../../api/services/inventory'; import { showToast } from '../../../../utils/toast'; // ======================================== // STEP 1: Entry Method Selection // ======================================== interface EntryMethodStepProps extends WizardStepProps { data: Record; onDataChange: (data: Record) => void; } const EntryMethodStep: React.FC = ({ data, onDataChange, onNext }) => { const [selectedMethod, setSelectedMethod] = useState<'manual' | 'upload'>( data.entryMethod || 'manual' ); const handleSelect = (method: 'manual' | 'upload') => { setSelectedMethod(method); onDataChange({ ...data, entryMethod: method }); }; const handleContinue = () => { onDataChange({ ...data, entryMethod: selectedMethod }); onNext(); }; return (

¿Cómo deseas registrar las ventas?

Elige el método que mejor se adapte a tus necesidades

{/* Manual Entry Option */} {/* File Upload Option */}
{/* Continue Button */}
); }; // ======================================== // STEP 2a: Manual Entry Form // ======================================== const ManualEntryStep: React.FC = ({ data, onDataChange, onNext }) => { const { currentTenant } = useTenant(); const [salesItems, setSalesItems] = useState(data.salesItems || []); const [saleDate, setSaleDate] = useState( data.saleDate || new Date().toISOString().split('T')[0] ); const [paymentMethod, setPaymentMethod] = useState(data.paymentMethod || 'cash'); const [notes, setNotes] = useState(data.notes || ''); const [products, setProducts] = useState([]); const [loadingProducts, setLoadingProducts] = useState(true); const [error, setError] = useState(null); useEffect(() => { fetchProducts(); }, []); const fetchProducts = async () => { if (!currentTenant?.id) return; setLoadingProducts(true); try { const result = await inventoryService.getIngredients(currentTenant.id); // Filter for finished products only const finishedProducts = result.filter((p: any) => p.category === 'finished_product'); setProducts(finishedProducts); } catch (err: any) { console.error('Error fetching products:', err); setError('Error al cargar los productos'); } finally { setLoadingProducts(false); } }; const handleAddItem = () => { setSalesItems([ ...salesItems, { id: Date.now(), productId: '', product: '', quantity: 1, unitPrice: 0, subtotal: 0 }, ]); }; const handleUpdateItem = (index: number, field: string, value: any) => { const updated = salesItems.map((item: any, i: number) => { if (i === index) { const newItem = { ...item, [field]: value }; // If product is selected, auto-fill price if (field === 'productId') { const selectedProduct = products.find((p: any) => p.id === value); if (selectedProduct) { newItem.product = selectedProduct.name; newItem.unitPrice = selectedProduct.average_cost || selectedProduct.last_purchase_price || 0; } } // Auto-calculate subtotal if (field === 'quantity' || field === 'unitPrice' || field === 'productId') { newItem.subtotal = (newItem.quantity || 0) * (newItem.unitPrice || 0); } return newItem; } return item; }); setSalesItems(updated); }; const handleRemoveItem = (index: number) => { setSalesItems(salesItems.filter((_: any, i: number) => i !== index)); }; const calculateTotal = () => { return salesItems.reduce((sum: number, item: any) => sum + (item.subtotal || 0), 0); }; const handleSave = () => { onDataChange({ ...data, salesItems, saleDate, paymentMethod, notes, totalAmount: calculateTotal(), }); onNext(); }; return (

Registrar Venta Manual

Ingresa los detalles de la venta

{/* Date and Payment Method */}
setSaleDate(e.target.value)} className="w-full px-3 py-2 border border-[var(--border-secondary)] rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] bg-[var(--bg-primary)] text-[var(--text-primary)]" />
{error && (
{error}
)} {/* Sales Items */}
{loadingProducts ? (
Cargando productos...
) : products.length === 0 ? (

No hay productos terminados disponibles

Agrega productos al inventario primero

) : salesItems.length === 0 ? (

No hay productos agregados

Haz clic en "Agregar Producto" para comenzar

) : (
{salesItems.map((item: any, index: number) => (
handleUpdateItem(index, 'quantity', parseFloat(e.target.value) || 0) } className="w-full px-2 py-1.5 text-sm border border-[var(--border-secondary)] rounded focus:outline-none focus:ring-1 focus:ring-[var(--color-primary)]" min="0" step="1" />
handleUpdateItem(index, 'unitPrice', parseFloat(e.target.value) || 0) } className="w-full px-2 py-1.5 text-sm border border-[var(--border-secondary)] rounded focus:outline-none focus:ring-1 focus:ring-[var(--color-primary)]" min="0" step="0.01" />
€{item.subtotal.toFixed(2)}
))}
)} {/* Total */} {salesItems.length > 0 && (
Total: €{calculateTotal().toFixed(2)}
)}
{/* Notes */}