payservedb 4.9.2 → 4.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/.env +2 -2
  2. package/index.js +171 -171
  3. package/package.json +17 -17
  4. package/src/models/account.js +35 -35
  5. package/src/models/analog_water_billing.js +58 -58
  6. package/src/models/apilog.js +18 -18
  7. package/src/models/approvalsWorkflows.js +49 -49
  8. package/src/models/archivedapilog.js +18 -18
  9. package/src/models/archivedauditlog.js +83 -83
  10. package/src/models/asset.js +34 -34
  11. package/src/models/auditlog.js +83 -83
  12. package/src/models/bankdetails.js +40 -40
  13. package/src/models/bookinganalytics.js +63 -63
  14. package/src/models/bookingconfig.js +45 -45
  15. package/src/models/bookingproperty.js +112 -112
  16. package/src/models/bookingreservation.js +192 -192
  17. package/src/models/bookingrevenuerecord.js +84 -84
  18. package/src/models/budget.js +33 -33
  19. package/src/models/budgetCategory.js +19 -19
  20. package/src/models/campaigns.js +72 -72
  21. package/src/models/cashpayment.js +262 -262
  22. package/src/models/combinedUnits.js +62 -62
  23. package/src/models/common_area_electricity.js +38 -38
  24. package/src/models/common_area_generator.js +38 -38
  25. package/src/models/common_area_utility_alert.js +37 -37
  26. package/src/models/common_area_water.js +39 -39
  27. package/src/models/company.js +53 -53
  28. package/src/models/country_tax.js +42 -42
  29. package/src/models/currency_settings.js +39 -39
  30. package/src/models/customer.js +200 -200
  31. package/src/models/default_payment_details.js +17 -17
  32. package/src/models/dutyroster.js +129 -129
  33. package/src/models/email.js +24 -24
  34. package/src/models/entry_exit.js +53 -53
  35. package/src/models/expense.js +55 -55
  36. package/src/models/facility.js +61 -61
  37. package/src/models/facility_payment_details.js +20 -20
  38. package/src/models/facilityasset.js +25 -25
  39. package/src/models/faq.js +18 -18
  40. package/src/models/gl_accounts.js +56 -52
  41. package/src/models/gl_entries.js +50 -54
  42. package/src/models/guard.js +47 -47
  43. package/src/models/handover.js +241 -241
  44. package/src/models/invoice.js +291 -276
  45. package/src/models/item_inspection.js +67 -67
  46. package/src/models/leaseagreement.js +168 -168
  47. package/src/models/leasetemplate.js +17 -17
  48. package/src/models/levy.js +84 -84
  49. package/src/models/levy_invoice_settings.js +26 -26
  50. package/src/models/levycontract.js +77 -77
  51. package/src/models/levytype.js +23 -23
  52. package/src/models/maintenance_service_vendor.js +38 -38
  53. package/src/models/maintenance_services.js +17 -17
  54. package/src/models/maintenancerequisition.js +31 -31
  55. package/src/models/message.js +38 -38
  56. package/src/models/module.js +21 -21
  57. package/src/models/notification.js +24 -24
  58. package/src/models/penalty.js +76 -76
  59. package/src/models/purchase_order.js +190 -190
  60. package/src/models/purchase_request.js +65 -65
  61. package/src/models/refresh_token.js +23 -23
  62. package/src/models/reminder.js +161 -161
  63. package/src/models/report.js +13 -13
  64. package/src/models/resident.js +121 -121
  65. package/src/models/rfq_details.js +87 -87
  66. package/src/models/rfq_response.js +109 -109
  67. package/src/models/service_charge_invoice_upload.js +42 -42
  68. package/src/models/service_charge_payments.js +27 -27
  69. package/src/models/servicerequest.js +55 -55
  70. package/src/models/settings.js +62 -62
  71. package/src/models/smart_meter_daily_consumption.js +44 -44
  72. package/src/models/sms_africastalking.js +20 -20
  73. package/src/models/sms_meliora.js +16 -16
  74. package/src/models/staff.js +36 -36
  75. package/src/models/stocksandspare.js +34 -34
  76. package/src/models/suppliers.js +68 -68
  77. package/src/models/tickets.js +109 -109
  78. package/src/models/unitasset.js +25 -25
  79. package/src/models/units.js +86 -86
  80. package/src/models/user.js +183 -183
  81. package/src/models/valueaddedservices.js +36 -36
  82. package/src/models/vas_invoices_upload.js +50 -50
  83. package/src/models/vas_payments.js +24 -24
  84. package/src/models/vasinvoice.js +159 -159
  85. package/src/models/vasvendor.js +57 -57
  86. package/src/models/visitLog.js +86 -86
  87. package/src/models/visitor.js +63 -63
  88. package/src/models/waitlist.js +45 -45
  89. package/src/models/water_invoice.js +192 -192
  90. package/src/models/water_meter_account.js +74 -74
  91. package/src/models/water_meter_communication.js +17 -17
  92. package/src/models/water_meter_concentrator.js +59 -59
  93. package/src/models/water_meter_daily_history.js +31 -31
  94. package/src/models/water_meter_iot_cards.js +34 -34
  95. package/src/models/water_meter_manufacturer.js +35 -35
  96. package/src/models/water_meter_monthly_history.js +37 -37
  97. package/src/models/water_meter_settings.js +88 -88
  98. package/src/models/water_meter_single_day_history.js +31 -31
  99. package/src/models/water_meter_size.js +15 -15
  100. package/src/models/water_meters.js +103 -103
  101. package/src/models/water_meters_delivery.js +76 -76
  102. package/src/models/workorder.js +49 -49
@@ -1,277 +1,292 @@
1
- const mongoose = require("mongoose");
2
-
3
- const invoiceSchema = new mongoose.Schema(
4
- {
5
- invoiceNumber: {
6
- type: String,
7
- required: true,
8
- unique: true,
9
- },
10
- accountNumber: {
11
- type: String,
12
- required: true,
13
- unique: true,
14
- },
15
- client: {
16
- clientId: {
17
- type: mongoose.Schema.Types.ObjectId,
18
- ref: "Customer",
19
- required: true,
20
- },
21
- firstName: {
22
- type: String,
23
- required: true
24
- },
25
- lastName: {
26
- type: String,
27
- required: true
28
- }
29
- },
30
- facility: {
31
- id: {
32
- type: mongoose.Schema.Types.ObjectId,
33
- ref: "Facility",
34
- required: true,
35
- },
36
- name: {
37
- type: String,
38
- required: true
39
- }
40
- },
41
- unit: {
42
- id: { type: mongoose.Schema.Types.ObjectId, ref: "Unit", required: true },
43
- name: { type: String, required: true },
44
- },
45
- currency: {
46
- id: {
47
- type: mongoose.Schema.Types.ObjectId,
48
- ref: "Currency",
49
- required: true
50
- },
51
- name: {
52
- type: String,
53
- required: true
54
- },
55
- code: {
56
- type: String,
57
- required: true,
58
- uppercase: true,
59
- minlength: 3,
60
- maxlength: 3
61
- }
62
- },
63
- items: [
64
- {
65
- description: { type: String, required: true },
66
- quantity: { type: Number, required: true, min: 1 },
67
- unitPrice: { type: Number, required: true, min: 0 },
68
- },
69
- ],
70
- subTotal: {
71
- type: Number,
72
- required: true,
73
- },
74
- tax: {
75
- type: Number,
76
- required: true,
77
- },
78
- totalAmount: {
79
- type: Number,
80
- required: true,
81
- },
82
- amountPaid: {
83
- type: Number,
84
- default: 0,
85
- min: 0,
86
- },
87
- // Mark as deprecated, keep for backward compatibility
88
- overpay: {
89
- type: Number,
90
- default: 0,
91
- min: 0,
92
- deprecated: true
93
- },
94
- issueDate: {
95
- type: Date,
96
- required: true,
97
- },
98
- dueDate: {
99
- type: Date,
100
- required: true,
101
- },
102
- status: {
103
- type: String,
104
- required: true,
105
- enum: ["Unpaid", "Pending", "Paid", "Overdue", "Cancelled", "Partially Paid"],
106
- },
107
- penalty: {
108
- type: Number,
109
- default: 0,
110
- },
111
- whatFor: {
112
- invoiceType: { type: String, required: true },
113
- description: { type: String },
114
- },
115
- invoiceNote: {
116
- type: String,
117
- default: null,
118
- },
119
- // Enhanced balanceBroughtForward field
120
- // Positive values = customer owes money
121
- // Negative values = credit (previously tracked in overpay field)
122
- balanceBroughtForward: {
123
- type: Number,
124
- default: 0,
125
- },
126
- lastReminderSent: Date,
127
- reminderHistory: [
128
- {
129
- sentAt: Date,
130
- reminderId: mongoose.Schema.Types.ObjectId,
131
- notificationTypes: [String],
132
- },
133
- ],
134
- reconciliationHistory: [{
135
- date: { type: Date, required: true },
136
- amount: { type: Number, required: true },
137
- type: {
138
- type: String,
139
- enum: ['payment', 'cash', 'cheque', 'bank-transfer', 'mpesa-transfer', 'overpay-transfer', 'balance-deduction', 'overpay-received', 'credit-forward', 'debit-forward'],
140
- required: true
141
- },
142
- sourceInvoice: String,
143
- destinationInvoice: String,
144
- paymentReference: String,
145
- paymentCompletion: String,
146
- remainingBalance: Number,
147
- notes: String,
148
- exchangeRate: {
149
- type: Number,
150
- default: 1 // For cross-currency reconciliations
151
- },
152
- originalCurrency: {
153
- code: String, // Original currency code if different from invoice currency
154
- amount: Number // Amount in original currency
155
- }
156
- }],
157
- paymentDetails: {
158
- paymentStatus: { type: String, required: true },
159
- paymentMethod: { type: String },
160
- paymentDate: { type: Date },
161
- transactionId: { type: String },
162
- },
163
- // New field to track when an invoice has been viewed
164
- viewStatus: {
165
- isOpened: { type: Boolean, default: false },
166
- openedAt: { type: Date, default: null },
167
- openedBy: {
168
- facilityId: { type: mongoose.Schema.Types.ObjectId, ref: "Facility" },
169
- userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
170
- userRole: { type: String }
171
- },
172
- viewHistory: [{
173
- viewedAt: { type: Date, required: true },
174
- facilityId: { type: mongoose.Schema.Types.ObjectId, ref: "Facility" },
175
- userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" }
176
- }]
177
- }
178
- },
179
- {
180
- timestamps: true,
181
- }
182
- );
183
-
184
- // Add indexes for frequently queried fields
185
- invoiceSchema.index({ accountNumber: 1 });
186
- invoiceSchema.index({ status: 1 });
187
- invoiceSchema.index({ 'client.clientId': 1, status: 1 });
188
- invoiceSchema.index({ 'reconciliationHistory.paymentReference': 1 });
189
- invoiceSchema.index({ issueDate: -1 });
190
- invoiceSchema.index({ 'currency.code': 1 }); // Add index for currency code
191
- invoiceSchema.index({ 'currency.id': 1 }); // Add index for currency ID
192
- invoiceSchema.index({ 'currency.code': 1, 'client.clientId': 1, status: 1 }); // Compound index for currency-based queries
193
- invoiceSchema.index({ 'client.clientId': 1, balanceBroughtForward: 1 }); // Add index for finding invoices with credit balances
194
- invoiceSchema.index({ 'viewStatus.isOpened': 1 }); // Add index for view status
195
- invoiceSchema.index({ 'viewStatus.openedBy.facilityId': 1 }); // Add index for facility view tracking
196
-
197
- // Add virtual field for calculating balance
198
- invoiceSchema.virtual('calculatedBalance').get(function () {
199
- const baseBalance = this.totalAmount - (this.amountPaid || 0);
200
-
201
- // Add positive balanceBroughtForward (customer owes money)
202
- if (this.balanceBroughtForward > 0) {
203
- return baseBalance + this.balanceBroughtForward;
204
- }
205
-
206
- // Subtract negative balanceBroughtForward (credit)
207
- return baseBalance;
208
- });
209
-
210
- // Add virtual field for credit balance
211
- invoiceSchema.virtual('creditBalance').get(function () {
212
- return this.balanceBroughtForward < 0 ? Math.abs(this.balanceBroughtForward) : 0;
213
- });
214
-
215
- // Getter for compatible overpay field
216
- invoiceSchema.virtual('effectiveOverpay').get(function () {
217
- return this.balanceBroughtForward < 0 ? Math.abs(this.balanceBroughtForward) : 0;
218
- });
219
-
220
- // Add method for currency conversion if needed
221
- invoiceSchema.methods.convertAmount = function (amount, fromCurrency, toCurrency, exchangeRate) {
222
- if (fromCurrency === toCurrency) {
223
- return amount;
224
- }
225
- return amount * exchangeRate;
226
- };
227
-
228
- // Add static method to find invoices by currency
229
- invoiceSchema.statics.findByCurrency = function (currencyCode) {
230
- return this.find({ 'currency.code': currencyCode.toUpperCase() });
231
- };
232
-
233
- // Add static method to find invoices with credit balance
234
- invoiceSchema.statics.findWithCreditBalance = function (clientId) {
235
- return this.find({
236
- 'client.clientId': clientId,
237
- 'balanceBroughtForward': { $lt: 0 }
238
- }).sort({ updatedAt: -1 });
239
- };
240
-
241
- // Add static method to calculate totals by currency
242
- invoiceSchema.statics.calculateTotalsByCurrency = function (query = {}) {
243
- return this.aggregate([
244
- { $match: query },
245
- {
246
- $group: {
247
- _id: '$currency.code',
248
- totalAmount: { $sum: '$totalAmount' },
249
- totalPaid: { $sum: '$amountPaid' },
250
- count: { $sum: 1 }
251
- }
252
- }
253
- ]);
254
- };
255
-
256
- // New static method to find all unviewed invoices
257
- invoiceSchema.statics.findUnviewedInvoices = function (facilityId) {
258
- return this.find({
259
- 'facility.id': facilityId,
260
- 'viewStatus.isOpened': false
261
- });
262
- };
263
-
264
- // Pre-save middleware to ensure overpay and balanceBroughtForward stay in sync during transition
265
- invoiceSchema.pre('save', function (next) {
266
- // If balanceBroughtForward is negative (credit), sync with overpay for backwards compatibility
267
- if (this.balanceBroughtForward < 0) {
268
- this.overpay = Math.abs(this.balanceBroughtForward);
269
- } else {
270
- this.overpay = 0; // No overpay if there's no negative balance
271
- }
272
- next();
273
- });
274
-
275
- const Invoice = mongoose.model('Invoice', invoiceSchema);
276
-
1
+ const mongoose = require("mongoose");
2
+
3
+ const invoiceSchema = new mongoose.Schema(
4
+ {
5
+ invoiceNumber: {
6
+ type: String,
7
+ required: true,
8
+ unique: true,
9
+ },
10
+ accountNumber: {
11
+ type: String,
12
+ required: true,
13
+ unique: true,
14
+ },
15
+ client: {
16
+ clientId: {
17
+ type: mongoose.Schema.Types.ObjectId,
18
+ ref: "Customer",
19
+ required: true,
20
+ },
21
+ firstName: {
22
+ type: String,
23
+ required: true
24
+ },
25
+ lastName: {
26
+ type: String,
27
+ required: true
28
+ }
29
+ },
30
+ facility: {
31
+ id: {
32
+ type: mongoose.Schema.Types.ObjectId,
33
+ ref: "Facility",
34
+ required: true,
35
+ },
36
+ name: {
37
+ type: String,
38
+ required: true
39
+ }
40
+ },
41
+ unit: {
42
+ id: { type: mongoose.Schema.Types.ObjectId, ref: "Unit", required: true },
43
+ name: { type: String, required: true },
44
+ },
45
+ currency: {
46
+ id: {
47
+ type: mongoose.Schema.Types.ObjectId,
48
+ ref: "Currency",
49
+ required: true
50
+ },
51
+ name: {
52
+ type: String,
53
+ required: true
54
+ },
55
+ code: {
56
+ type: String,
57
+ required: true,
58
+ uppercase: true,
59
+ minlength: 3,
60
+ maxlength: 3
61
+ }
62
+ },
63
+ items: [
64
+ {
65
+ description: { type: String, required: true },
66
+ quantity: { type: Number, required: true, min: 1 },
67
+ unitPrice: { type: Number, required: true, min: 0 },
68
+ },
69
+ ],
70
+ subTotal: {
71
+ type: Number,
72
+ required: true,
73
+ },
74
+ tax: {
75
+ type: Number,
76
+ required: true,
77
+ },
78
+ totalAmount: {
79
+ type: Number,
80
+ required: true,
81
+ },
82
+ amountPaid: {
83
+ type: Number,
84
+ default: 0,
85
+ min: 0,
86
+ },
87
+ // Mark as deprecated, keep for backward compatibility
88
+ overpay: {
89
+ type: Number,
90
+ default: 0,
91
+ min: 0,
92
+ deprecated: true
93
+ },
94
+ issueDate: {
95
+ type: Date,
96
+ required: true,
97
+ },
98
+ dueDate: {
99
+ type: Date,
100
+ required: true,
101
+ },
102
+ status: {
103
+ type: String,
104
+ required: true,
105
+ enum: ["Unpaid", "Pending", "Paid", "Overdue", "Cancelled", "Partially Paid", "Void"],
106
+ },
107
+ penalty: {
108
+ type: Number,
109
+ default: 0,
110
+ },
111
+ whatFor: {
112
+ invoiceType: { type: String, required: true },
113
+ description: { type: String },
114
+ },
115
+ invoiceNote: {
116
+ type: String,
117
+ default: null,
118
+ },
119
+ balanceBroughtForward: {
120
+ type: Number,
121
+ default: 0,
122
+ },
123
+ voidMetadata: {
124
+ voidedBy: {
125
+ userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
126
+ name: { type: String },
127
+ role: { type: String }
128
+ },
129
+ voidedAt: { type: Date },
130
+ reason: { type: String }
131
+ },
132
+ cancelMetadata: {
133
+ cancelledBy: {
134
+ userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
135
+ name: { type: String },
136
+ role: { type: String }
137
+ },
138
+ cancelledAt: { type: Date },
139
+ reason: { type: String }
140
+ },
141
+ lastReminderSent: Date,
142
+ reminderHistory: [
143
+ {
144
+ sentAt: Date,
145
+ reminderId: mongoose.Schema.Types.ObjectId,
146
+ notificationTypes: [String],
147
+ },
148
+ ],
149
+ reconciliationHistory: [{
150
+ date: { type: Date, required: true },
151
+ amount: { type: Number, required: true },
152
+ type: {
153
+ type: String,
154
+ enum: ['payment', 'cash', 'cheque', 'bank-transfer', 'mpesa-transfer', 'overpay-transfer', 'balance-deduction', 'overpay-received', 'credit-forward', 'debit-forward'],
155
+ required: true
156
+ },
157
+ sourceInvoice: String,
158
+ destinationInvoice: String,
159
+ paymentReference: String,
160
+ paymentCompletion: String,
161
+ remainingBalance: Number,
162
+ notes: String,
163
+ exchangeRate: {
164
+ type: Number,
165
+ default: 1 // For cross-currency reconciliations
166
+ },
167
+ originalCurrency: {
168
+ code: String, // Original currency code if different from invoice currency
169
+ amount: Number // Amount in original currency
170
+ }
171
+ }],
172
+ paymentDetails: {
173
+ paymentStatus: { type: String, required: true },
174
+ paymentMethod: { type: String },
175
+ paymentDate: { type: Date },
176
+ transactionId: { type: String },
177
+ },
178
+ // New field to track when an invoice has been viewed
179
+ viewStatus: {
180
+ isOpened: { type: Boolean, default: false },
181
+ openedAt: { type: Date, default: null },
182
+ openedBy: {
183
+ facilityId: { type: mongoose.Schema.Types.ObjectId, ref: "Facility" },
184
+ userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
185
+ userRole: { type: String }
186
+ },
187
+ viewHistory: [{
188
+ viewedAt: { type: Date, required: true },
189
+ facilityId: { type: mongoose.Schema.Types.ObjectId, ref: "Facility" },
190
+ userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" }
191
+ }]
192
+ }
193
+ },
194
+ {
195
+ timestamps: true,
196
+ }
197
+ );
198
+
199
+ // Add indexes for frequently queried fields
200
+ invoiceSchema.index({ accountNumber: 1 });
201
+ invoiceSchema.index({ status: 1 });
202
+ invoiceSchema.index({ 'client.clientId': 1, status: 1 });
203
+ invoiceSchema.index({ 'reconciliationHistory.paymentReference': 1 });
204
+ invoiceSchema.index({ issueDate: -1 });
205
+ invoiceSchema.index({ 'currency.code': 1 }); // Add index for currency code
206
+ invoiceSchema.index({ 'currency.id': 1 }); // Add index for currency ID
207
+ invoiceSchema.index({ 'currency.code': 1, 'client.clientId': 1, status: 1 }); // Compound index for currency-based queries
208
+ invoiceSchema.index({ 'client.clientId': 1, balanceBroughtForward: 1 }); // Add index for finding invoices with credit balances
209
+ invoiceSchema.index({ 'viewStatus.isOpened': 1 }); // Add index for view status
210
+ invoiceSchema.index({ 'viewStatus.openedBy.facilityId': 1 }); // Add index for facility view tracking
211
+
212
+ // Add virtual field for calculating balance
213
+ invoiceSchema.virtual('calculatedBalance').get(function () {
214
+ const baseBalance = this.totalAmount - (this.amountPaid || 0);
215
+
216
+ // Add positive balanceBroughtForward (customer owes money)
217
+ if (this.balanceBroughtForward > 0) {
218
+ return baseBalance + this.balanceBroughtForward;
219
+ }
220
+
221
+ // Subtract negative balanceBroughtForward (credit)
222
+ return baseBalance;
223
+ });
224
+
225
+ // Add virtual field for credit balance
226
+ invoiceSchema.virtual('creditBalance').get(function () {
227
+ return this.balanceBroughtForward < 0 ? Math.abs(this.balanceBroughtForward) : 0;
228
+ });
229
+
230
+ // Getter for compatible overpay field
231
+ invoiceSchema.virtual('effectiveOverpay').get(function () {
232
+ return this.balanceBroughtForward < 0 ? Math.abs(this.balanceBroughtForward) : 0;
233
+ });
234
+
235
+ // Add method for currency conversion if needed
236
+ invoiceSchema.methods.convertAmount = function (amount, fromCurrency, toCurrency, exchangeRate) {
237
+ if (fromCurrency === toCurrency) {
238
+ return amount;
239
+ }
240
+ return amount * exchangeRate;
241
+ };
242
+
243
+ // Add static method to find invoices by currency
244
+ invoiceSchema.statics.findByCurrency = function (currencyCode) {
245
+ return this.find({ 'currency.code': currencyCode.toUpperCase() });
246
+ };
247
+
248
+ // Add static method to find invoices with credit balance
249
+ invoiceSchema.statics.findWithCreditBalance = function (clientId) {
250
+ return this.find({
251
+ 'client.clientId': clientId,
252
+ 'balanceBroughtForward': { $lt: 0 }
253
+ }).sort({ updatedAt: -1 });
254
+ };
255
+
256
+ // Add static method to calculate totals by currency
257
+ invoiceSchema.statics.calculateTotalsByCurrency = function (query = {}) {
258
+ return this.aggregate([
259
+ { $match: query },
260
+ {
261
+ $group: {
262
+ _id: '$currency.code',
263
+ totalAmount: { $sum: '$totalAmount' },
264
+ totalPaid: { $sum: '$amountPaid' },
265
+ count: { $sum: 1 }
266
+ }
267
+ }
268
+ ]);
269
+ };
270
+
271
+ // New static method to find all unviewed invoices
272
+ invoiceSchema.statics.findUnviewedInvoices = function (facilityId) {
273
+ return this.find({
274
+ 'facility.id': facilityId,
275
+ 'viewStatus.isOpened': false
276
+ });
277
+ };
278
+
279
+ // Pre-save middleware to ensure overpay and balanceBroughtForward stay in sync during transition
280
+ invoiceSchema.pre('save', function (next) {
281
+ // If balanceBroughtForward is negative (credit), sync with overpay for backwards compatibility
282
+ if (this.balanceBroughtForward < 0) {
283
+ this.overpay = Math.abs(this.balanceBroughtForward);
284
+ } else {
285
+ this.overpay = 0; // No overpay if there's no negative balance
286
+ }
287
+ next();
288
+ });
289
+
290
+ const Invoice = mongoose.model('Invoice', invoiceSchema);
291
+
277
292
  module.exports = Invoice;