From b2b1cd4fe014d3da6f007956ec12e7544400028c Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sun, 28 Dec 2025 02:10:31 +0000 Subject: [PATCH] Enhance Invoice Model with New Payment and Acknowledgment Features - Added a "New Payment" button to the Invoice model, allowing users to initiate payments based on invoice state. - Introduced an "Acknowledge" button for invoices in the "sent" state, enabling acknowledgment actions. - Updated the invoice grouping and filtering criteria to include "orderType" and "to/from" fields. - Adjusted column definitions to improve layout and visibility of new fields, including "acknowledgedAt" and "paidAt". - Enhanced the invoice summary calculations to include acknowledged counts and totals. --- src/database/models/Invoice.js | 89 +++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 18 deletions(-) diff --git a/src/database/models/Invoice.js b/src/database/models/Invoice.js index 2522707..1c2f646 100644 --- a/src/database/models/Invoice.js +++ b/src/database/models/Invoice.js @@ -4,6 +4,7 @@ import CheckIcon from '../../components/Icons/CheckIcon' import EditIcon from '../../components/Icons/EditIcon' import XMarkIcon from '../../components/Icons/XMarkIcon' import BinIcon from '../../components/Icons/BinIcon' +import PlusIcon from '../../components/Icons/PlusIcon' export const Invoice = { name: 'invoice', @@ -71,6 +72,19 @@ export const Invoice = { } }, { type: 'divider' }, + { + name: 'newPayment', + label: 'New Payment', + type: 'button', + icon: PlusIcon, + url: (_id) => + `/dashboard/finance/invoices/info?invoiceId=${_id}&action=newPayment`, + disabled: (objectData) => { + const allowedStates = ['acknowledged', 'partiallyPaid', 'overdue'] + return !allowedStates.includes(objectData?.state?.type) + } + }, + { type: 'divider' }, { name: 'post', label: 'Post', @@ -82,6 +96,17 @@ export const Invoice = { return objectData?.state?.type == 'draft' } }, + { + name: 'acknowledge', + label: 'Acknowledge', + type: 'button', + icon: CheckIcon, + url: (_id) => + `/dashboard/finance/invoices/info?invoiceId=${_id}&action=acknowledge`, + visible: (objectData) => { + return objectData?.state?.type == 'sent' + } + }, { name: 'cancel', label: 'Cancel', @@ -91,25 +116,28 @@ export const Invoice = { url: (_id) => `/dashboard/finance/invoices/info?invoiceId=${_id}&action=cancel`, disabled: (objectData) => { - return ( - objectData?.state?.type == 'cancelled' || - objectData?.state?.type == 'paid' - ) + const allowedStates = [ + 'acknowledged', + 'partiallyPaid', + 'overdue', + 'sent' + ] + return !allowedStates.includes(objectData?.state?.type) }, visible: (objectData) => { - return objectData?.state?.type == 'sent' + return objectData?.state?.type != 'draft' } } ], - group: ['vendor', 'client', 'invoiceType'], - filters: ['vendor', 'client', 'invoiceType'], + group: ['orderType'], + filters: ['to', 'from', 'orderType'], sorters: ['createdAt', 'state', 'updatedAt', 'invoiceDate', 'dueDate'], columns: [ '_reference', 'state', - 'invoiceType', - 'vendor', - 'client', + 'orderType', + 'to', + 'from', 'invoiceDate', 'dueDate', 'totalAmount', @@ -206,12 +234,14 @@ export const Invoice = { } } }, + { - name: 'paidAt', - label: 'Paid At', + name: 'acknowledgedAt', + label: 'Acknowledged At', type: 'dateTime', readOnly: true }, + { name: 'to', label: 'To', @@ -244,6 +274,12 @@ export const Invoice = { readOnly: true, columnWidth: 175 }, + { + name: 'paidAt', + label: 'Paid At', + type: 'dateTime', + readOnly: true + }, { name: 'totalAmountWithTax', label: 'Total Amount w/ Tax', @@ -301,13 +337,15 @@ export const Invoice = { type: 'object', objectType: 'orderItem', required: true, + columnWidth: 300, showHyperlink: true }, { name: 'invoiceQuantity', label: 'Quantity', type: 'number', - required: true + required: true, + columnWidth: 175 }, { name: 'invoiceAmount', @@ -315,7 +353,8 @@ export const Invoice = { type: 'number', prefix: '£', roundNumber: 2, - required: true + required: true, + columnWidth: 150 }, { name: 'taxRate', @@ -323,7 +362,8 @@ export const Invoice = { type: 'object', objectType: 'taxRate', required: false, - showHyperlink: true + showHyperlink: true, + columnWidth: 200 }, { name: 'invoiceAmountWithTax', @@ -333,6 +373,7 @@ export const Invoice = { roundNumber: 2, required: true, readOnly: true, + columnWidth: 200, value: (objectData) => { const invoiceAmount = objectData?.invoiceAmount || 0 if (objectData?.taxRate?.rateType == 'percentage') { @@ -413,6 +454,7 @@ export const Invoice = { type: 'object', objectType: 'shipment', required: true, + columnWidth: 300, showHyperlink: true }, { @@ -421,6 +463,7 @@ export const Invoice = { type: 'number', prefix: '£', roundNumber: 2, + columnWidth: 175, required: true }, { @@ -429,7 +472,8 @@ export const Invoice = { type: 'object', objectType: 'taxRate', required: false, - showHyperlink: true + showHyperlink: true, + columnWidth: 200 }, { name: 'invoiceAmountWithTax', @@ -439,6 +483,7 @@ export const Invoice = { roundNumber: 2, required: true, readOnly: true, + columnWidth: 200, value: (objectData) => { const invoiceAmount = objectData?.invoiceAmount || 0 if (objectData?.taxRate?.rateType == 'percentage') { @@ -516,6 +561,12 @@ export const Invoice = { type: 'number', color: 'cyan' }, + { + name: 'acknowledged.acknowledgedCount.count', + label: 'Acknowledged', + type: 'number', + color: 'purple' + }, { name: 'due.dueCount.count', label: 'Due', @@ -524,7 +575,8 @@ export const Invoice = { sum: [ 'sent.sentCount.count', 'partiallyPaid.partiallyPaidCount.count', - 'overdue.overdueCount.count' + 'overdue.overdueCount.count', + 'acknowledged.acknowledgedCount.count' ] }, { @@ -537,7 +589,8 @@ export const Invoice = { sum: [ 'sent.sentGrandTotalAmount.sum', 'partiallyPaid.partiallyPaidGrandTotalAmount.sum', - 'overdue.overdueGrandTotalAmount.sum' + 'overdue.overdueGrandTotalAmount.sum', + 'acknowledged.acknowledgedGrandTotalAmount.sum' ] }, {