import React, { useState } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { useToast } from "@/components/ui/use-toast"; import { base44 } from "@/api/base44Client"; import { useMutation, useQueryClient, useQuery } from "@tanstack/react-query"; import { format, addDays } from "date-fns"; import { Plus, Trash2, FileEdit } from "lucide-react"; import { useNavigate } from "react-router-dom"; import { createPageUrl } from "@/utils"; export default function CreateInvoiceModal({ open, onClose }) { const { toast } = useToast(); const queryClient = useQueryClient(); const { data: events = [] } = useQuery({ queryKey: ['events-for-invoice'], queryFn: () => base44.entities.Event.list(), enabled: open, }); const navigate = useNavigate(); const handleAdvancedEditor = () => { onClose(); navigate(createPageUrl('InvoiceEditor')); }; const createMutation = useMutation({ mutationFn: async (data) => { const selectedEvent = events.find(e => e.id === data.event_id); if (!selectedEvent) throw new Error("Event not found"); // Generate roles and staff entries from event const roleGroups = {}; if (selectedEvent.assigned_staff && selectedEvent.shifts) { selectedEvent.shifts.forEach(shift => { shift.roles?.forEach(role => { const assignedForRole = selectedEvent.assigned_staff.filter( s => s.role === role.role ); if (!roleGroups[role.role]) { roleGroups[role.role] = { role_name: role.role, staff_entries: [], role_subtotal: 0 }; } assignedForRole.forEach(staff => { const workedHours = role.hours || 8; const baseRate = role.cost_per_hour || role.rate_per_hour || 0; const regularHours = Math.min(workedHours, 8); const otHours = Math.max(0, Math.min(workedHours - 8, 4)); const dtHours = Math.max(0, workedHours - 12); const regularRate = baseRate; const otRate = baseRate * 1.5; const dtRate = baseRate * 2; const regularValue = regularHours * regularRate; const otValue = otHours * otRate; const dtValue = dtHours * dtRate; const total = regularValue + otValue + dtValue; const entry = { staff_name: staff.staff_name, staff_id: staff.staff_id, date: selectedEvent.date, position: role.role, check_in: role.start_time || "09:00 AM", check_out: role.end_time || "05:00 PM", worked_hours: workedHours, regular_hours: regularHours, ot_hours: otHours, dt_hours: dtHours, regular_rate: regularRate, ot_rate: otRate, dt_rate: dtRate, regular_value: regularValue, ot_value: otValue, dt_value: dtValue, rate: baseRate, total: total }; roleGroups[role.role].staff_entries.push(entry); roleGroups[role.role].role_subtotal += total; }); }); }); } const roles = Object.values(roleGroups); const subtotal = roles.reduce((sum, role) => sum + role.role_subtotal, 0); const otherCharges = parseFloat(data.other_charges) || 0; const total = subtotal + otherCharges; const invoiceNumber = `INV-${Math.floor(Math.random() * 10000)}`; const vendorInfo = { name: selectedEvent.vendor_name || "Legendary", address: "848 E Gish Rd Ste 1, San Jose, CA 95112", email: "orders@legendaryeventstaff.com", phone: "(408) 936-0180" }; const clientInfo = { name: selectedEvent.business_name || "Client Company", address: selectedEvent.event_location || "Address", email: selectedEvent.client_email || "", manager: selectedEvent.client_name || selectedEvent.manager_name || "Manager", phone: selectedEvent.client_phone || "", vendor_id: "Vendor #" }; return base44.entities.Invoice.create({ invoice_number: invoiceNumber, event_id: selectedEvent.id, event_name: selectedEvent.event_name, event_date: selectedEvent.date, po_reference: data.po_reference || selectedEvent.po_reference, from_company: vendorInfo, to_company: clientInfo, business_name: selectedEvent.business_name, manager_name: selectedEvent.client_name || selectedEvent.business_name, vendor_name: selectedEvent.vendor_name, vendor_id: selectedEvent.vendor_id, hub: selectedEvent.hub, cost_center: data.po_reference || selectedEvent.po_reference, roles: roles, subtotal: subtotal, other_charges: otherCharges, amount: total, status: "Draft", issue_date: format(new Date(), 'yyyy-MM-dd'), due_date: format(addDays(new Date(), 30), 'yyyy-MM-dd'), is_auto_generated: false, notes: data.notes, }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['invoices'] }); toast({ title: "✅ Invoice Created", description: "Invoice has been created successfully", }); onClose(); setFormData({ event_id: "", po_reference: "", other_charges: 0, notes: "" }); }, }); const handleSubmit = (e) => { e.preventDefault(); if (!formData.event_id) { toast({ title: "Error", description: "Please select an event", variant: "destructive", }); return; } createMutation.mutate(formData); }; const completedEvents = events.filter(e => e.status === "Completed"); return ( Create New Invoice

Ready to create an invoice?

Use the advanced editor to create a detailed invoice with full control.

); }