mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-09-08 08:04:10 +00:00
feat(payments): add customer ledgers and allocations (#744)
This commit is contained in:
@@ -35,6 +35,7 @@ export const API = {
|
||||
CUSTOMERS: '/api/v1/customers',
|
||||
CUSTOMERS_DELETE: '/api/v1/customers/delete',
|
||||
CUSTOMER_STATS: '/api/v1/customers', // append /{id}/stats
|
||||
CUSTOMER_STATEMENT: '/api/v1/customers', // append /{id}/statement
|
||||
|
||||
// Items & Units
|
||||
ITEMS: '/api/v1/items',
|
||||
|
||||
@@ -6,6 +6,79 @@ import type {
|
||||
ListParams,
|
||||
DeletePayload,
|
||||
} from '@/scripts/types/api'
|
||||
import type { Currency } from '@/scripts/types/domain/currency'
|
||||
|
||||
export type CustomerStatementType = 'activity' | 'outstanding'
|
||||
|
||||
export interface CustomerStatementEntry {
|
||||
id: string | number
|
||||
date: string
|
||||
entry_type: 'invoice' | 'credit_note' | 'payment'
|
||||
reference: string
|
||||
description?: string | null
|
||||
debit_amount: number
|
||||
credit_amount: number
|
||||
balance?: number
|
||||
}
|
||||
|
||||
export interface CustomerStatementOutstandingInvoice {
|
||||
id: number
|
||||
invoice_number: string
|
||||
invoice_date: string
|
||||
due_date: string | null
|
||||
original_amount: number
|
||||
applied_amount: number
|
||||
remaining_amount: number
|
||||
}
|
||||
|
||||
export interface CustomerStatementCredit {
|
||||
id: number
|
||||
payment_number: string
|
||||
payment_date: string
|
||||
amount: number
|
||||
allocated_amount: number
|
||||
available_amount: number
|
||||
}
|
||||
|
||||
export interface CustomerStatement {
|
||||
type: CustomerStatementType
|
||||
customer: Customer
|
||||
currency?: Currency
|
||||
opening_balance?: number
|
||||
closing_balance?: number
|
||||
invoice_due_amount?: number
|
||||
available_credit?: number
|
||||
account_balance?: number
|
||||
entries?: CustomerStatementEntry[]
|
||||
meta?: {
|
||||
current_page: number
|
||||
last_page: number
|
||||
per_page: number
|
||||
total: number
|
||||
}
|
||||
invoices?: CustomerStatementOutstandingInvoice[]
|
||||
credits?: CustomerStatementCredit[]
|
||||
}
|
||||
|
||||
export interface CustomerStatementParams {
|
||||
type: CustomerStatementType
|
||||
from_date?: string
|
||||
to_date?: string
|
||||
as_of?: string
|
||||
page?: number
|
||||
}
|
||||
|
||||
export interface SendCustomerStatementPayload {
|
||||
type: CustomerStatementType
|
||||
from_date?: string
|
||||
to_date?: string
|
||||
as_of?: string
|
||||
to?: string
|
||||
cc?: string
|
||||
bcc?: string
|
||||
subject?: string
|
||||
body?: string
|
||||
}
|
||||
|
||||
export interface CustomerListParams extends ListParams {
|
||||
display_name?: string
|
||||
@@ -81,4 +154,40 @@ export const customerService = {
|
||||
const { data } = await client.get(`${API.CUSTOMER_STATS}/${id}/stats`, { params })
|
||||
return data
|
||||
},
|
||||
|
||||
async getStatement(
|
||||
id: number,
|
||||
params: CustomerStatementParams,
|
||||
): Promise<ApiResponse<CustomerStatement>> {
|
||||
const { data } = await client.get(`${API.CUSTOMER_STATEMENT}/${id}/statement`, { params })
|
||||
return data
|
||||
},
|
||||
|
||||
statementPdfUrl(id: number, params: CustomerStatementParams): string {
|
||||
const query = new URLSearchParams(
|
||||
Object.entries(params).reduce<Record<string, string>>((result, [key, value]) => {
|
||||
if (value !== undefined && value !== null) result[key] = String(value)
|
||||
return result
|
||||
}, {}),
|
||||
)
|
||||
query.set('download', '1')
|
||||
|
||||
return `/reports/customers/${id}/statement?${query.toString()}`
|
||||
},
|
||||
|
||||
async sendStatement(
|
||||
id: number,
|
||||
payload: SendCustomerStatementPayload,
|
||||
): Promise<{ success: boolean }> {
|
||||
const { data } = await client.post(`${API.CUSTOMER_STATEMENT}/${id}/statement/send`, payload)
|
||||
return data
|
||||
},
|
||||
|
||||
async allocateCredit(
|
||||
id: number,
|
||||
allocations: Array<{ payment_id: number; invoice_id: number; amount: number }>,
|
||||
): Promise<{ success: boolean }> {
|
||||
const { data } = await client.post(`${API.CUSTOMER_STATEMENT}/${id}/credit-allocations`, { allocations })
|
||||
return data
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user