import { defineStore } from "pinia"; import { ref, computed } from "vue"; import InvoiceService, { Invoice, CreateInvoicePayload, UpdateInvoicePayload, } from "@/services/invoice"; export const useInvoiceStore = defineStore("invoice", () => { // State const invoices = ref([]); const currentInvoice = ref(null); const loading = ref(false); const error = ref(null); // Pagination state const pagination = ref({ current_page: 1, last_page: 1, per_page: 10, total: 0, }); // Getters const allInvoices = computed(() => invoices.value); const isLoading = computed(() => loading.value); const hasError = computed(() => error.value !== null); const getError = computed(() => error.value); const getInvoiceById = computed(() => (id: number) => invoices.value.find((invoice) => invoice.id === id) ); const getPagination = computed(() => pagination.value); // Actions const setLoading = (isLoading: boolean) => { loading.value = isLoading; }; const setError = (err: string | null) => { error.value = err; }; const setInvoices = (newInvoices: Invoice[]) => { invoices.value = newInvoices; }; const setCurrentInvoice = (invoice: Invoice | null) => { currentInvoice.value = invoice; }; const setPagination = (meta: any) => { if (meta) { pagination.value = { current_page: meta.current_page || 1, last_page: meta.last_page || 1, per_page: meta.per_page || 10, total: meta.total || 0, }; } }; /** * Fetch all invoices with optional pagination and filters */ const fetchInvoices = async (params?: { page?: number; per_page?: number; search?: string; status?: string; client_id?: number; }) => { setLoading(true); setError(null); try { const response = await InvoiceService.getAllInvoices(params); setInvoices(response.data); if (response.meta) { setPagination(response.meta); } return response; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to fetch invoices"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Fetch a single invoice by ID */ const fetchInvoice = async (id: number) => { setLoading(true); setError(null); try { const response = await InvoiceService.getInvoice(id); setCurrentInvoice(response.data); return response.data; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to fetch invoice"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Create a new invoice */ const createInvoice = async (payload: CreateInvoicePayload) => { setLoading(true); setError(null); try { const response = await InvoiceService.createInvoice(payload); invoices.value.push(response.data); setCurrentInvoice(response.data); return response.data; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to create invoice"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Create an invoice from a quote */ const createFromQuote = async (quoteId: number) => { setLoading(true); setError(null); try { const response = await InvoiceService.createFromQuote(quoteId); invoices.value.push(response.data); setCurrentInvoice(response.data); return response.data; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to create invoice from quote"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Update an existing invoice */ const updateInvoice = async (payload: UpdateInvoicePayload) => { setLoading(true); setError(null); try { const response = await InvoiceService.updateInvoice(payload); const updatedInvoice = response.data; // Update in the invoices list const index = invoices.value.findIndex( (invoice) => invoice.id === updatedInvoice.id ); if (index !== -1) { invoices.value[index] = updatedInvoice; } // Update current invoice if it's the one being edited if (currentInvoice.value && currentInvoice.value.id === updatedInvoice.id) { setCurrentInvoice(updatedInvoice); } return updatedInvoice; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to update invoice"; setError(errorMessage); throw err; } finally { setLoading(false); } }; /** * Delete an invoice */ const deleteInvoice = async (id: number) => { setLoading(true); setError(null); try { const response = await InvoiceService.deleteInvoice(id); // Remove from the invoices list invoices.value = invoices.value.filter((invoice) => invoice.id !== id); // Clear current invoice if it's the one being deleted if (currentInvoice.value && currentInvoice.value.id === id) { setCurrentInvoice(null); } return response; } catch (err: any) { const errorMessage = err.response?.data?.message || err.message || "Failed to delete invoice"; setError(errorMessage); throw err; } finally { setLoading(false); } }; return { // State invoices, currentInvoice, loading, error, pagination, // Getters allInvoices, isLoading, hasError, getError, getInvoiceById, getPagination, // Actions fetchInvoices, fetchInvoice, createInvoice, createFromQuote, updateInvoice, deleteInvoice, }; });