import React, { useState } from 'react'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Card, CardContent } from "@/components/ui/card"; import { useSupabaseEmployeeData } from "@/hooks/useSupabaseEmployeeData"; import { Currency, convert, formatCurrency, getUsdToLbpRate } from "@/lib/currency"; interface DetailedTransaction { location: string; empId: string; empName: string; collectionAmount: number; collectionDate: string; depositAmount: number; depositDate: string; difference: number; } export const DetailedEmployeePaymentReport = () => { const [displayCurrency, setDisplayCurrency] = useState("USD"); const { employees, transactions } = useSupabaseEmployeeData(displayCurrency); const [selectedEmployeeId, setSelectedEmployeeId] = useState('all'); const formatDate = (date: string) => { return new Date(date).toLocaleDateString('en-US'); }; // Process transactions with the specific business logic const processEmployeeTransactions = (employeeId: string): DetailedTransaction[] => { const employee = employees.find(emp => emp.id === employeeId); if (!employee) return []; const employeeTransactions = transactions .filter(t => t.employee_id === employeeId) .map(t => ({ ...t, collection_amount: convert(t.collection_amount, t.currency, displayCurrency), deposit_amount: convert(t.deposit_amount, t.currency, displayCurrency), })) .sort((a, b) => new Date(a.transaction_date).getTime() - new Date(b.transaction_date).getTime()); const detailedTransactions: DetailedTransaction[] = []; let pendingCollections: { amount: number; date: string }[] = []; // Group transactions by date const transactionsByDate = employeeTransactions.reduce((acc, transaction) => { const date = transaction.transaction_date; if (!acc[date]) { acc[date] = { collections: 0, deposits: 0 }; } acc[date].collections += transaction.collection_amount; acc[date].deposits += transaction.deposit_amount; return acc; }, {} as Record); // Process each date chronologically Object.entries(transactionsByDate) .sort(([a], [b]) => new Date(a).getTime() - new Date(b).getTime()) .forEach(([date, { collections, deposits }]) => { // Add collection entry if there's a collection if (collections > 0) { pendingCollections.push({ amount: collections, date }); detailedTransactions.push({ location: employee.location || 'BGRoad, Karnataka', empId: employee.emp_id.replace('EMP', ''), empName: employee.name, collectionAmount: collections, collectionDate: date, depositAmount: 0, depositDate: '', difference: 0 }); } // Process deposits if (deposits > 0) { let remainingDeposit = deposits; const depositDate = date; // First, try to clear pending collections in chronological order for (let i = 0; i < pendingCollections.length && remainingDeposit > 0; i++) { const pending = pendingCollections[i]; const amountToClear = Math.min(pending.amount, remainingDeposit); if (amountToClear > 0) { // Find the corresponding collection entry and update it const collectionEntry = detailedTransactions.find( dt => dt.collectionDate === pending.date && dt.depositAmount === 0 ); if (collectionEntry) { collectionEntry.depositAmount = amountToClear; collectionEntry.depositDate = depositDate; collectionEntry.difference = amountToClear - collectionEntry.collectionAmount; } pending.amount -= amountToClear; remainingDeposit -= amountToClear; } } // Remove fully cleared collections pendingCollections = pendingCollections.filter(p => p.amount > 0); // If there's remaining deposit after clearing collections, add separate deposit entries while (remainingDeposit > 0) { detailedTransactions.push({ location: employee.location || 'BGRoad, Karnataka', empId: employee.emp_id.replace('EMP', ''), empName: employee.name, collectionAmount: 0, collectionDate: '', depositAmount: remainingDeposit, depositDate: depositDate, difference: remainingDeposit }); remainingDeposit = 0; } } }); return detailedTransactions; }; const getTransactionsToShow = (): DetailedTransaction[] => { if (selectedEmployeeId === 'all') { return employees.flatMap(employee => processEmployeeTransactions(employee.id)); } else { return processEmployeeTransactions(selectedEmployeeId); } }; const detailedTransactions = getTransactionsToShow(); // Calculate totals (combined, in display currency) const totalCollection = detailedTransactions.reduce((sum, t) => sum + t.collectionAmount, 0); const totalDeposit = detailedTransactions.reduce((sum, t) => sum + t.depositAmount, 0); const totalDifference = totalDeposit - totalCollection; // Per-currency totals from raw transactions, filtered to current selection const filteredRawTx = selectedEmployeeId === 'all' ? transactions : transactions.filter(t => t.employee_id === selectedEmployeeId); const totalCollectionUSD = filteredRawTx.filter(t => t.currency === 'USD').reduce((s, t) => s + t.collection_amount, 0); const totalCollectionLBP = filteredRawTx.filter(t => t.currency === 'LBP').reduce((s, t) => s + t.collection_amount, 0); const totalDepositUSD = filteredRawTx.filter(t => t.currency === 'USD').reduce((s, t) => s + t.deposit_amount, 0); const totalDepositLBP = filteredRawTx.filter(t => t.currency === 'LBP').reduce((s, t) => s + t.deposit_amount, 0); const totalDifferenceUSD = totalDepositUSD - totalCollectionUSD; const totalDifferenceLBP = totalDepositLBP - totalCollectionLBP; return (
{/* Header */}

Employee Payment Report (Detailed)

Rate: 1 USD = {getUsdToLbpRate().toLocaleString()} LBP
{/* Summary Cards */}

Total Collection (MM)

USD: {formatCurrency(totalCollectionUSD, "USD")}

LBP: {formatCurrency(totalCollectionLBP, "LBP")}

≈ {formatCurrency(totalCollection, displayCurrency)}

Total Deposit Amount

USD: {formatCurrency(totalDepositUSD, "USD")}

LBP: {formatCurrency(totalDepositLBP, "LBP")}

≈ {formatCurrency(totalDeposit, displayCurrency)}

=

Net Difference

USD: = 0 ? 'text-green-600' : 'text-red-600'}`}>{formatCurrency(totalDifferenceUSD, "USD")}

LBP: = 0 ? 'text-green-600' : 'text-red-600'}`}>{formatCurrency(totalDifferenceLBP, "LBP")}

= 0 ? 'text-green-600' : 'text-red-600'}`}> ≈ {formatCurrency(totalDifference, displayCurrency)}

{/* Filter */}
{/* Data Table */}
Location Emp. ID Emp. Name Collections (MM) Date Cash Deposit Deposit Date Difference {detailedTransactions.map((transaction, index) => ( {transaction.location} {transaction.empId} {transaction.empName} {transaction.collectionAmount > 0 ? formatCurrency(transaction.collectionAmount, displayCurrency) : '-'} {transaction.collectionDate ? formatDate(transaction.collectionDate) : '-'} {transaction.depositAmount > 0 ? formatCurrency(transaction.depositAmount, displayCurrency) : '-'} {transaction.depositDate ? formatDate(transaction.depositDate) : '-'} 0 ? 'text-green-600' : 'text-red-600' }`}> {transaction.difference === 0 ? '-' : formatCurrency(transaction.difference, displayCurrency)} ))}
{detailedTransactions.length === 0 && (
No transaction data available
Use the "Insert Employee Data" button to add records
)}
); };