import React, { useState, useEffect } from 'react'; import Toast from '../Components/Toast'; import { X, Search, ShoppingCart, Plus, Minus, CreditCard, DollarSign, Globe, Trash2, Banknote } from 'lucide-react'; export default function NewSaleModal({ isOpen, onClose, onSave, branches, products }) { const [searchTerm, setSearchTerm] = useState(''); const [selectedBranch, setSelectedBranch] = useState(''); const [cart, setCart] = useState([]); const [paymentMethod, setPaymentMethod] = useState(''); const [paymentMethods, setPaymentMethods] = useState([]); const [toast, setToast] = useState(null); const [loading, setLoading] = useState(false); const [adjustedTotal, setAdjustedTotal] = useState(''); const [adjustmentRemarks, setAdjustmentRemarks] = useState(''); const showToast = (message, type = 'success') => { setToast({ message, type }); setTimeout(() => setToast(null), 3000); }; useEffect(() => { if (isOpen) { fetchPaymentMethods(); } }, [isOpen]); const fetchPaymentMethods = async () => { try { const res = await fetch('/api/masters/payment_method'); if (res.ok) { const data = await res.json(); const activeOnes = data.filter(m => m.status === 'Active'); setPaymentMethods(activeOnes); if (activeOnes.length > 0 && !paymentMethod) { setPaymentMethod(activeOnes[0].name); } } } catch (error) { console.error('Error fetching payment methods:', error); } }; useEffect(() => { if (window.__APP_DATA__?.role === 'receptionist') { setSelectedBranch(window.__APP_DATA__?.user?.branch_id); } else if (branches.length > 0) { setSelectedBranch(branches[0].id); } }, [branches]); const subtotal = cart.reduce((sum, item) => sum + (item.unit_price * item.quantity), 0); const vatAmount = subtotal * 0.05; const totalWithVat = subtotal + vatAmount; // Sync adjusted total when base total changes, if not manually edited useEffect(() => { setAdjustedTotal(totalWithVat.toFixed(2)); }, [totalWithVat]); if (!isOpen) return null; const filteredProducts = products.filter(p => p.branch_id.toString() === selectedBranch.toString() && p.name.toLowerCase().includes(searchTerm.toLowerCase()) ); const addToCart = (product) => { setCart(prev => { const existing = prev.find(item => item.product_id === product.id); if (existing) { if (existing.quantity >= parseInt(product.current_stock)) return prev; return prev.map(item => item.product_id === product.id ? { ...item, quantity: item.quantity + 1 } : item ); } else { if (parseInt(product.current_stock) <= 0) return prev; return [...prev, { product_id: product.id, name: product.name, unit_price: product.selling_price, quantity: 1, max_stock: parseInt(product.current_stock) }]; } }); }; const updateQuantity = (id, delta) => { setCart(prev => prev.map(item => { if (item.product_id === id) { const newQty = Math.max(1, Math.min(parseInt(item.max_stock), item.quantity + delta)); return { ...item, quantity: newQty }; } return item; })); }; const removeItem = (id) => { setCart(cart.filter(item => item.product_id !== id)); }; const handleSubmit = async () => { if (cart.length === 0) return; if (!paymentMethod) { showToast("Please select a mode of payment before processing.", 'error'); return; } // Final safety check against stock bypass const overStockItems = cart.filter(item => parseInt(item.quantity) > parseInt(item.max_stock)); if (overStockItems.length > 0) { alert(`Some items exceed available stock: ${overStockItems.map(i => i.name).join(', ')}`); return; } setLoading(true); try { const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'); const res = await fetch('/api/inventory/sales', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }, body: JSON.stringify({ branch_id: selectedBranch, payment_method: paymentMethod, total_amount: parseFloat(adjustedTotal), remarks: parseFloat(adjustedTotal) !== totalWithVat ? adjustmentRemarks : '', items: cart.map(i => ({ product_id: i.product_id, quantity: i.quantity, unit_price: i.unit_price })) }) }); if (res.ok) { const sale = await res.json(); onSave(sale); setCart([]); setAdjustmentRemarks(''); onClose(); } } catch (error) { console.error('Sale error:', error); } finally { setLoading(false); } }; return (
{toast && setToast(null)} />}

New Product Sale

Create a transaction for product sales.

{/* Product Selection Area */}
setSearchTerm(e.target.value)} />
{window.__APP_DATA__?.role !== 'receptionist' && ( )}
{filteredProducts.map(product => (

{product.name}

{product.category?.name}

0 ? 'bg-emerald-50 text-emerald-600' : 'bg-red-50 text-red-600'}`}> {product.current_stock} left
{parseFloat(product.selling_price).toFixed(2)}
))}
{/* Cart Sidebar */}

Current Order

{cart.map(item => (

{item.name}

{item.quantity}

{parseFloat(item.unit_price * item.quantity).toFixed(2)}

))} {cart.length === 0 && (

Order is empty

)}

Sub-Total

{subtotal.toFixed(2)} AED

VAT

5%

{vatAmount.toFixed(2)} AED

Total Amount

{totalWithVat.toFixed(2)} AED

setAdjustedTotal(e.target.value)} className="w-full bg-white border-2 border-red-50 py-1.5 px-3 rounded-lg text-sm font-black text-gray-900 focus:outline-none focus:border-red-200 transition-all shadow-inner" /> AED
{parseFloat(adjustedTotal) !== totalWithVat && (