payservedb 8.7.0 → 8.7.2

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 (186) hide show
  1. package/.env +2 -2
  2. package/ZOHO_INTEGRATION_SCHEMA.md +644 -644
  3. package/index.js +319 -319
  4. package/package.json +17 -17
  5. package/src/models/account.js +52 -52
  6. package/src/models/agent_departments.js +59 -59
  7. package/src/models/agent_notifications.js +53 -53
  8. package/src/models/agent_performance.js +127 -127
  9. package/src/models/agent_roles.js +77 -77
  10. package/src/models/agents.js +154 -154
  11. package/src/models/apilog.js +18 -18
  12. package/src/models/approvalsWorkflows.js +49 -49
  13. package/src/models/archivedapilog.js +18 -18
  14. package/src/models/asset.js +92 -92
  15. package/src/models/assetsAssignment.js +64 -64
  16. package/src/models/auditTrail.js +346 -346
  17. package/src/models/bankdetails.js +47 -47
  18. package/src/models/billerAddress.js +124 -124
  19. package/src/models/booking_invoice.js +165 -165
  20. package/src/models/bookinganalytics.js +63 -63
  21. package/src/models/bookingconfig.js +45 -45
  22. package/src/models/bookingproperty.js +179 -179
  23. package/src/models/bookingreservation.js +239 -239
  24. package/src/models/bookingrevenuerecord.js +84 -84
  25. package/src/models/budget.js +95 -95
  26. package/src/models/budgetCategory.js +19 -19
  27. package/src/models/campaigns.js +108 -108
  28. package/src/models/cashpayment.js +291 -291
  29. package/src/models/combinedUnits.js +62 -62
  30. package/src/models/combined_invoice.js +424 -424
  31. package/src/models/common_area_electricity.js +38 -38
  32. package/src/models/common_area_generator.js +41 -41
  33. package/src/models/common_area_utility_alert.js +37 -37
  34. package/src/models/common_area_water.js +39 -39
  35. package/src/models/communication_status.js +33 -33
  36. package/src/models/communication_user_opt.js +32 -32
  37. package/src/models/community_guidelines.js +35 -35
  38. package/src/models/company.js +53 -53
  39. package/src/models/coreBaseSettings.js +16 -16
  40. package/src/models/coreInvoiceSettings.js +100 -100
  41. package/src/models/counter_schema.js +21 -21
  42. package/src/models/country_tax.js +42 -42
  43. package/src/models/currency_settings.js +39 -39
  44. package/src/models/customer.js +214 -214
  45. package/src/models/customer_satisfaction_survey.js +278 -278
  46. package/src/models/customer_surveys.js +139 -139
  47. package/src/models/customer_tickets.js +239 -239
  48. package/src/models/dailyChecklist.js +312 -312
  49. package/src/models/default_payment_details.js +17 -17
  50. package/src/models/deliveryTimeMarks.js +18 -18
  51. package/src/models/document_type.js +19 -19
  52. package/src/models/dutyRosterChecklist.js +250 -250
  53. package/src/models/dutyroster.js +136 -136
  54. package/src/models/email.js +37 -37
  55. package/src/models/email_sms_queue.js +61 -61
  56. package/src/models/entry_exit.js +53 -53
  57. package/src/models/expense.js +99 -99
  58. package/src/models/expense_category.js +45 -45
  59. package/src/models/facility.js +71 -71
  60. package/src/models/facilityBillingPrices.js +29 -29
  61. package/src/models/facilityInvoice.js +240 -240
  62. package/src/models/facilityInvoicePayment.js +52 -52
  63. package/src/models/facilityInvoiceRecipient.js +32 -32
  64. package/src/models/facilityWalletTransactionsMetadata.js +236 -236
  65. package/src/models/facility_departements.js +20 -20
  66. package/src/models/facility_payment_details.js +20 -20
  67. package/src/models/facility_rating.js +78 -78
  68. package/src/models/facilityasset.js +25 -25
  69. package/src/models/faq.js +14 -14
  70. package/src/models/gl_account_double_entries.js +25 -25
  71. package/src/models/gl_accounts.js +56 -56
  72. package/src/models/gl_entries.js +49 -49
  73. package/src/models/goodsReceivedNotes.js +115 -115
  74. package/src/models/guard.js +47 -47
  75. package/src/models/handover.js +258 -258
  76. package/src/models/inspection_category.js +38 -38
  77. package/src/models/invoice.js +480 -480
  78. package/src/models/invoice_generation_approval.js +86 -86
  79. package/src/models/invoicing_schedule.js +40 -40
  80. package/src/models/item_inspection.js +96 -96
  81. package/src/models/knowledge_base.js +109 -109
  82. package/src/models/knowledge_base_rating.js +44 -44
  83. package/src/models/leaseagreement.js +237 -237
  84. package/src/models/leasetemplate.js +17 -17
  85. package/src/models/levy.js +223 -223
  86. package/src/models/levy_invoice_settings.js +26 -26
  87. package/src/models/levycontract.js +210 -210
  88. package/src/models/levytype.js +23 -23
  89. package/src/models/maintenance_service_vendor.js +38 -38
  90. package/src/models/maintenance_services.js +17 -17
  91. package/src/models/maintenancerequisition.js +31 -31
  92. package/src/models/master_workplan.js +32 -32
  93. package/src/models/master_workplan_child.js +34 -34
  94. package/src/models/message.js +38 -38
  95. package/src/models/module.js +21 -21
  96. package/src/models/notification.js +44 -44
  97. package/src/models/paymentTermsMarks.js +19 -19
  98. package/src/models/penalty.js +76 -76
  99. package/src/models/pendingCredentials.js +32 -32
  100. package/src/models/powerMeterCommunicationProtocol.js +17 -17
  101. package/src/models/powerMeterCustomerAccount.js +78 -78
  102. package/src/models/powerMeterCustomerBand.js +14 -14
  103. package/src/models/powerMeterDailyReading.js +30 -30
  104. package/src/models/powerMeterGateways.js +40 -40
  105. package/src/models/powerMeterMonthlyReading.js +34 -34
  106. package/src/models/powerMeterPowerCharges.js +85 -85
  107. package/src/models/powerMeterSettings.js +159 -159
  108. package/src/models/powerMeterSingleDayReading.js +32 -32
  109. package/src/models/powerMeters.js +116 -116
  110. package/src/models/powerMetersManufacturer.js +14 -14
  111. package/src/models/power_meter_account.js +81 -81
  112. package/src/models/power_meter_command_logs.js +30 -30
  113. package/src/models/power_meter_command_queue.js +33 -33
  114. package/src/models/power_meter_negative_balance.js +44 -44
  115. package/src/models/power_prepaid_credits.js +47 -47
  116. package/src/models/power_prepaid_debits.js +53 -53
  117. package/src/models/power_prepaid_orders.js +78 -78
  118. package/src/models/power_sms_notification.js +26 -26
  119. package/src/models/privacy_policy.js +19 -19
  120. package/src/models/propertyManagerContract.js +556 -556
  121. package/src/models/propertyManagerRevenue.js +195 -195
  122. package/src/models/purchaseOrderInvoice.js +74 -74
  123. package/src/models/purchase_order.js +213 -213
  124. package/src/models/purchase_request.js +110 -110
  125. package/src/models/quickbooks_config.js +52 -41
  126. package/src/models/refresh_token.js +23 -23
  127. package/src/models/reminder.js +197 -197
  128. package/src/models/report.js +13 -13
  129. package/src/models/resident.js +121 -121
  130. package/src/models/rfq_details.js +131 -131
  131. package/src/models/rfq_response.js +153 -153
  132. package/src/models/service_charge_invoice_upload.js +42 -42
  133. package/src/models/service_charge_payments.js +27 -27
  134. package/src/models/servicerequest.js +55 -55
  135. package/src/models/settings.js +62 -62
  136. package/src/models/short_urls.js +21 -21
  137. package/src/models/smart_meter_daily_consumption.js +44 -44
  138. package/src/models/sms_africastalking.js +20 -20
  139. package/src/models/sms_balance_notification.js +26 -26
  140. package/src/models/sms_meliora.js +20 -20
  141. package/src/models/staff.js +36 -36
  142. package/src/models/stocksandspare.js +161 -161
  143. package/src/models/suppliers.js +74 -74
  144. package/src/models/terms_and_conditions.js +19 -19
  145. package/src/models/tickets.js +186 -186
  146. package/src/models/tickets_category.js +72 -72
  147. package/src/models/unitManagementTemplate.js +44 -44
  148. package/src/models/unitasset.js +25 -25
  149. package/src/models/units.js +118 -118
  150. package/src/models/user.js +185 -185
  151. package/src/models/valueaddedservices.js +50 -79
  152. package/src/models/vas_invoices_upload.js +50 -50
  153. package/src/models/vas_payments.js +24 -24
  154. package/src/models/vasinvoice.js +192 -192
  155. package/src/models/vasvendor.js +57 -57
  156. package/src/models/visitLog.js +95 -95
  157. package/src/models/visitor.js +67 -67
  158. package/src/models/waitlist.js +45 -45
  159. package/src/models/wallet.js +44 -44
  160. package/src/models/wallet_transactions.js +50 -50
  161. package/src/models/water_invoice.js +351 -351
  162. package/src/models/water_meter_Command_Queue.js +33 -33
  163. package/src/models/water_meter_account.js +86 -86
  164. package/src/models/water_meter_billing.js +58 -58
  165. package/src/models/water_meter_combined_accounts.js +92 -92
  166. package/src/models/water_meter_communication.js +17 -17
  167. package/src/models/water_meter_communication_logs.js +39 -39
  168. package/src/models/water_meter_concentrator.js +70 -70
  169. package/src/models/water_meter_daily_history.js +32 -32
  170. package/src/models/water_meter_high_risk.js +36 -36
  171. package/src/models/water_meter_iot_cards.js +34 -34
  172. package/src/models/water_meter_loan_deduction.js +134 -134
  173. package/src/models/water_meter_manufacturer.js +35 -35
  174. package/src/models/water_meter_monthly_history.js +36 -36
  175. package/src/models/water_meter_negative_amounts.js +44 -44
  176. package/src/models/water_meter_settings.js +290 -290
  177. package/src/models/water_meter_single_day_history.js +34 -34
  178. package/src/models/water_meter_size.js +15 -15
  179. package/src/models/water_meters.js +133 -133
  180. package/src/models/water_meters_delivery.js +76 -76
  181. package/src/models/water_prepaid_credit.js +47 -47
  182. package/src/models/water_prepaid_debit.js +50 -50
  183. package/src/models/workorder.js +49 -49
  184. package/src/models/zohoAccount.js +453 -453
  185. package/src/models/zohoIntegration.js +262 -262
  186. package/src/models/zohoItem.js +504 -504
@@ -1,291 +1,291 @@
1
- const mongoose = require('mongoose');
2
-
3
- const cashPaymentSchema = new mongoose.Schema(
4
- {
5
- paymentReference: {
6
- type: String,
7
- required: true,
8
- unique: true,
9
- trim: true
10
- },
11
- receiptNumber: {
12
- type: String,
13
- required: true,
14
- unique: true,
15
- trim: true
16
- },
17
- invoice: {
18
- invoiceId: {
19
- type: mongoose.Schema.Types.ObjectId,
20
- ref: "Invoice",
21
- required: true
22
- },
23
- invoiceNumber: {
24
- type: String,
25
- required: true,
26
- trim: true
27
- },
28
- accountNumber: {
29
- type: String,
30
- trim: true
31
- },
32
- invoiceType: {
33
- type: String,
34
- trim: true
35
- }
36
- },
37
- client: {
38
- clientId: {
39
- type: mongoose.Schema.Types.ObjectId,
40
- ref: "Customer",
41
- required: true
42
- },
43
- firstName: {
44
- type: String,
45
- required: true,
46
- trim: true
47
- },
48
- lastName: {
49
- type: String,
50
- required: true,
51
- trim: true
52
- }
53
- },
54
- facility: {
55
- id: {
56
- type: mongoose.Schema.Types.ObjectId,
57
- ref: "Facility",
58
- required: true
59
- },
60
- name: {
61
- type: String,
62
- required: true,
63
- trim: true
64
- }
65
- },
66
- currency: {
67
- id: {
68
- type: mongoose.Schema.Types.ObjectId,
69
- ref: "Currency",
70
- required: true
71
- },
72
- name: {
73
- type: String,
74
- required: true,
75
- trim: true
76
- },
77
- code: {
78
- type: String,
79
- required: true,
80
- uppercase: true,
81
- minlength: 3,
82
- maxlength: 3
83
- }
84
- },
85
- paymentAmount: {
86
- type: Number,
87
- required: true,
88
- min: 0
89
- },
90
- paymentDate: {
91
- type: Date,
92
- required: true,
93
- default: Date.now
94
- },
95
- paymentMethod: {
96
- type: String,
97
- enum: ['cash', 'bank-transfer', 'cheque','mpesa'],
98
- default: 'cash'
99
- },
100
- exchangeRate: {
101
- rate: {
102
- type: Number,
103
- default: 1
104
- },
105
- sourceCurrency: {
106
- type: String,
107
- uppercase: true,
108
- minlength: 3,
109
- maxlength: 3
110
- },
111
- targetCurrency: {
112
- type: String,
113
- uppercase: true,
114
- minlength: 3,
115
- maxlength: 3
116
- },
117
- conversionDate: Date
118
- },
119
- approvalStatus: {
120
- type: String,
121
- enum: ['Pending', 'Approved', 'Rejected'],
122
- default: 'Pending'
123
- },
124
- approvedBy: {
125
- userId: mongoose.Schema.Types.ObjectId,
126
- name: String,
127
- approvalDate: Date,
128
- comments: String
129
- },
130
- rejectedBy: {
131
- userId: mongoose.Schema.Types.ObjectId,
132
- name: String,
133
- rejectionDate: Date,
134
- reason: String
135
- },
136
- isVoided: {
137
- type: Boolean,
138
- default: false
139
- },
140
- voidedBy: {
141
- userId: mongoose.Schema.Types.ObjectId,
142
- name: String,
143
- voidDate: Date,
144
- reason: String
145
- },
146
- reconciliationStatus: {
147
- type: String,
148
- enum: ['Pending', 'Matched', 'Partial', 'Overpaid', 'Error'],
149
- default: 'Pending'
150
- },
151
- reconciliationDetails: {
152
- appliedAmount: Number,
153
- overpayAmount: {
154
- type: Number,
155
- default: 0
156
- },
157
- reconciliationDate: Date,
158
- reconciledBy: mongoose.Schema.Types.ObjectId,
159
- paymentMethod: String, // To store the payment method used during reconciliation
160
- notes: String
161
- },
162
- paymentNotes: String,
163
- isRefund: {
164
- type: Boolean,
165
- default: false
166
- },
167
- refundDetails: {
168
- reservationId: {
169
- type: mongoose.Schema.Types.ObjectId,
170
- ref: "BookingReservation",
171
- default: null
172
- },
173
- bookingReservationId: {
174
- type: String,
175
- default: null
176
- },
177
- bookingInvoiceId: {
178
- type: mongoose.Schema.Types.ObjectId,
179
- ref: "BookingInvoice",
180
- default: null
181
- },
182
- reason: String
183
- },
184
- attachments: [
185
- {
186
- fileId: mongoose.Schema.Types.ObjectId,
187
- fileName: String,
188
- fileType: String,
189
- filePath: String,
190
- uploadDate: Date,
191
- uploadedBy: mongoose.Schema.Types.ObjectId,
192
- size: Number,
193
- originalName: String
194
- }
195
- ],
196
- metadata: {
197
- createdBy: {
198
- type: mongoose.Schema.Types.ObjectId,
199
- required: true
200
- },
201
- source: {
202
- type: String,
203
- enum: ['manual', 'api', 'import', 'mobile'],
204
- default: 'manual'
205
- },
206
- deviceInfo: {
207
- deviceId: String,
208
- deviceType: String,
209
- ipAddress: String
210
- }
211
- }
212
- },
213
- {
214
- timestamps: true
215
- }
216
- );
217
-
218
- // Add indexes for frequently queried fields
219
- cashPaymentSchema.index({ 'paymentReference': 1 });
220
- cashPaymentSchema.index({ 'receiptNumber': 1 });
221
- cashPaymentSchema.index({ 'approvalStatus': 1 });
222
- cashPaymentSchema.index({ 'isVoided': 1 });
223
- cashPaymentSchema.index({ 'client.clientId': 1 });
224
- cashPaymentSchema.index({ 'invoice.invoiceId': 1 });
225
- cashPaymentSchema.index({ 'facility.id': 1 });
226
- cashPaymentSchema.index({ 'reconciliationStatus': 1 });
227
- cashPaymentSchema.index({ 'paymentDate': -1 });
228
- cashPaymentSchema.index({ 'currency.code': 1 });
229
- cashPaymentSchema.index({ 'paymentMethod': 1 });
230
- cashPaymentSchema.index({ 'paymentDate': -1, 'approvalStatus': 1 });
231
- cashPaymentSchema.index({ 'client.clientId': 1, 'approvalStatus': 1 });
232
-
233
- // // Add virtual properties
234
- // cashPaymentSchema.virtual('clientFullName').get(function () {
235
- // return ${ this.client.firstName } ${ this.client.lastName };
236
- // });
237
- // Add instance methods
238
- cashPaymentSchema.methods.convertCurrency = function (targetCurrencyCode, exchangeRate) {
239
- if (this.currency.code === targetCurrencyCode) {
240
- return this.paymentAmount;
241
- }
242
- return this.paymentAmount * exchangeRate;
243
- };
244
-
245
- // Static methods
246
- cashPaymentSchema.statics.findByClientId = function (clientId) {
247
- return this.find({ 'client.clientId': clientId }).sort({ paymentDate: -1 });
248
- };
249
-
250
- cashPaymentSchema.statics.findByInvoiceId = function (invoiceId) {
251
- return this.find({ 'invoice.invoiceId': invoiceId }).sort({ paymentDate: -1 });
252
- };
253
-
254
- cashPaymentSchema.statics.findPendingPayments = function (facilityId) {
255
- return this.find({
256
- 'facility.id': facilityId,
257
- 'approvalStatus': 'Pending',
258
- 'isVoided': false
259
- }).sort({ paymentDate: -1 });
260
- };
261
-
262
- cashPaymentSchema.statics.findOverpaidPayments = function (facilityId) {
263
- return this.find({
264
- 'facility.id': facilityId,
265
- 'approvalStatus': 'Approved',
266
- 'reconciliationStatus': 'Overpaid',
267
- 'isVoided': false
268
- }).sort({ paymentDate: -1 });
269
- };
270
-
271
- // Pre-save middleware
272
- cashPaymentSchema.pre('save', function (next) {
273
- // If the payment is approved, ensure the reconciliation status is set
274
- if (this.isModified('approvalStatus') && this.approvalStatus === 'Approved' && this.reconciliationStatus === 'Pending') {
275
- this.reconciliationStatus = 'Matched'; // Default status when approved
276
- }
277
-
278
- // If the payment is voided, clear certain fields
279
- if (this.isModified('isVoided') && this.isVoided) {
280
- this.approvalStatus = 'Pending';
281
- this.reconciliationStatus = 'Pending';
282
- }
283
-
284
- next();
285
- });
286
-
287
- // Create model (only if not already defined by getModel utility)
288
- const CashPayment = mongoose.models.CashPayment || mongoose.model('CashPayment', cashPaymentSchema);
289
-
290
- module.exports = CashPayment;
291
-
1
+ const mongoose = require('mongoose');
2
+
3
+ const cashPaymentSchema = new mongoose.Schema(
4
+ {
5
+ paymentReference: {
6
+ type: String,
7
+ required: true,
8
+ unique: true,
9
+ trim: true
10
+ },
11
+ receiptNumber: {
12
+ type: String,
13
+ required: true,
14
+ unique: true,
15
+ trim: true
16
+ },
17
+ invoice: {
18
+ invoiceId: {
19
+ type: mongoose.Schema.Types.ObjectId,
20
+ ref: "Invoice",
21
+ required: true
22
+ },
23
+ invoiceNumber: {
24
+ type: String,
25
+ required: true,
26
+ trim: true
27
+ },
28
+ accountNumber: {
29
+ type: String,
30
+ trim: true
31
+ },
32
+ invoiceType: {
33
+ type: String,
34
+ trim: true
35
+ }
36
+ },
37
+ client: {
38
+ clientId: {
39
+ type: mongoose.Schema.Types.ObjectId,
40
+ ref: "Customer",
41
+ required: true
42
+ },
43
+ firstName: {
44
+ type: String,
45
+ required: true,
46
+ trim: true
47
+ },
48
+ lastName: {
49
+ type: String,
50
+ required: true,
51
+ trim: true
52
+ }
53
+ },
54
+ facility: {
55
+ id: {
56
+ type: mongoose.Schema.Types.ObjectId,
57
+ ref: "Facility",
58
+ required: true
59
+ },
60
+ name: {
61
+ type: String,
62
+ required: true,
63
+ trim: true
64
+ }
65
+ },
66
+ currency: {
67
+ id: {
68
+ type: mongoose.Schema.Types.ObjectId,
69
+ ref: "Currency",
70
+ required: true
71
+ },
72
+ name: {
73
+ type: String,
74
+ required: true,
75
+ trim: true
76
+ },
77
+ code: {
78
+ type: String,
79
+ required: true,
80
+ uppercase: true,
81
+ minlength: 3,
82
+ maxlength: 3
83
+ }
84
+ },
85
+ paymentAmount: {
86
+ type: Number,
87
+ required: true,
88
+ min: 0
89
+ },
90
+ paymentDate: {
91
+ type: Date,
92
+ required: true,
93
+ default: Date.now
94
+ },
95
+ paymentMethod: {
96
+ type: String,
97
+ enum: ['cash', 'bank-transfer', 'cheque','mpesa'],
98
+ default: 'cash'
99
+ },
100
+ exchangeRate: {
101
+ rate: {
102
+ type: Number,
103
+ default: 1
104
+ },
105
+ sourceCurrency: {
106
+ type: String,
107
+ uppercase: true,
108
+ minlength: 3,
109
+ maxlength: 3
110
+ },
111
+ targetCurrency: {
112
+ type: String,
113
+ uppercase: true,
114
+ minlength: 3,
115
+ maxlength: 3
116
+ },
117
+ conversionDate: Date
118
+ },
119
+ approvalStatus: {
120
+ type: String,
121
+ enum: ['Pending', 'Approved', 'Rejected'],
122
+ default: 'Pending'
123
+ },
124
+ approvedBy: {
125
+ userId: mongoose.Schema.Types.ObjectId,
126
+ name: String,
127
+ approvalDate: Date,
128
+ comments: String
129
+ },
130
+ rejectedBy: {
131
+ userId: mongoose.Schema.Types.ObjectId,
132
+ name: String,
133
+ rejectionDate: Date,
134
+ reason: String
135
+ },
136
+ isVoided: {
137
+ type: Boolean,
138
+ default: false
139
+ },
140
+ voidedBy: {
141
+ userId: mongoose.Schema.Types.ObjectId,
142
+ name: String,
143
+ voidDate: Date,
144
+ reason: String
145
+ },
146
+ reconciliationStatus: {
147
+ type: String,
148
+ enum: ['Pending', 'Matched', 'Partial', 'Overpaid', 'Error'],
149
+ default: 'Pending'
150
+ },
151
+ reconciliationDetails: {
152
+ appliedAmount: Number,
153
+ overpayAmount: {
154
+ type: Number,
155
+ default: 0
156
+ },
157
+ reconciliationDate: Date,
158
+ reconciledBy: mongoose.Schema.Types.ObjectId,
159
+ paymentMethod: String, // To store the payment method used during reconciliation
160
+ notes: String
161
+ },
162
+ paymentNotes: String,
163
+ isRefund: {
164
+ type: Boolean,
165
+ default: false
166
+ },
167
+ refundDetails: {
168
+ reservationId: {
169
+ type: mongoose.Schema.Types.ObjectId,
170
+ ref: "BookingReservation",
171
+ default: null
172
+ },
173
+ bookingReservationId: {
174
+ type: String,
175
+ default: null
176
+ },
177
+ bookingInvoiceId: {
178
+ type: mongoose.Schema.Types.ObjectId,
179
+ ref: "BookingInvoice",
180
+ default: null
181
+ },
182
+ reason: String
183
+ },
184
+ attachments: [
185
+ {
186
+ fileId: mongoose.Schema.Types.ObjectId,
187
+ fileName: String,
188
+ fileType: String,
189
+ filePath: String,
190
+ uploadDate: Date,
191
+ uploadedBy: mongoose.Schema.Types.ObjectId,
192
+ size: Number,
193
+ originalName: String
194
+ }
195
+ ],
196
+ metadata: {
197
+ createdBy: {
198
+ type: mongoose.Schema.Types.ObjectId,
199
+ required: true
200
+ },
201
+ source: {
202
+ type: String,
203
+ enum: ['manual', 'api', 'import', 'mobile'],
204
+ default: 'manual'
205
+ },
206
+ deviceInfo: {
207
+ deviceId: String,
208
+ deviceType: String,
209
+ ipAddress: String
210
+ }
211
+ }
212
+ },
213
+ {
214
+ timestamps: true
215
+ }
216
+ );
217
+
218
+ // Add indexes for frequently queried fields
219
+ cashPaymentSchema.index({ 'paymentReference': 1 });
220
+ cashPaymentSchema.index({ 'receiptNumber': 1 });
221
+ cashPaymentSchema.index({ 'approvalStatus': 1 });
222
+ cashPaymentSchema.index({ 'isVoided': 1 });
223
+ cashPaymentSchema.index({ 'client.clientId': 1 });
224
+ cashPaymentSchema.index({ 'invoice.invoiceId': 1 });
225
+ cashPaymentSchema.index({ 'facility.id': 1 });
226
+ cashPaymentSchema.index({ 'reconciliationStatus': 1 });
227
+ cashPaymentSchema.index({ 'paymentDate': -1 });
228
+ cashPaymentSchema.index({ 'currency.code': 1 });
229
+ cashPaymentSchema.index({ 'paymentMethod': 1 });
230
+ cashPaymentSchema.index({ 'paymentDate': -1, 'approvalStatus': 1 });
231
+ cashPaymentSchema.index({ 'client.clientId': 1, 'approvalStatus': 1 });
232
+
233
+ // // Add virtual properties
234
+ // cashPaymentSchema.virtual('clientFullName').get(function () {
235
+ // return ${ this.client.firstName } ${ this.client.lastName };
236
+ // });
237
+ // Add instance methods
238
+ cashPaymentSchema.methods.convertCurrency = function (targetCurrencyCode, exchangeRate) {
239
+ if (this.currency.code === targetCurrencyCode) {
240
+ return this.paymentAmount;
241
+ }
242
+ return this.paymentAmount * exchangeRate;
243
+ };
244
+
245
+ // Static methods
246
+ cashPaymentSchema.statics.findByClientId = function (clientId) {
247
+ return this.find({ 'client.clientId': clientId }).sort({ paymentDate: -1 });
248
+ };
249
+
250
+ cashPaymentSchema.statics.findByInvoiceId = function (invoiceId) {
251
+ return this.find({ 'invoice.invoiceId': invoiceId }).sort({ paymentDate: -1 });
252
+ };
253
+
254
+ cashPaymentSchema.statics.findPendingPayments = function (facilityId) {
255
+ return this.find({
256
+ 'facility.id': facilityId,
257
+ 'approvalStatus': 'Pending',
258
+ 'isVoided': false
259
+ }).sort({ paymentDate: -1 });
260
+ };
261
+
262
+ cashPaymentSchema.statics.findOverpaidPayments = function (facilityId) {
263
+ return this.find({
264
+ 'facility.id': facilityId,
265
+ 'approvalStatus': 'Approved',
266
+ 'reconciliationStatus': 'Overpaid',
267
+ 'isVoided': false
268
+ }).sort({ paymentDate: -1 });
269
+ };
270
+
271
+ // Pre-save middleware
272
+ cashPaymentSchema.pre('save', function (next) {
273
+ // If the payment is approved, ensure the reconciliation status is set
274
+ if (this.isModified('approvalStatus') && this.approvalStatus === 'Approved' && this.reconciliationStatus === 'Pending') {
275
+ this.reconciliationStatus = 'Matched'; // Default status when approved
276
+ }
277
+
278
+ // If the payment is voided, clear certain fields
279
+ if (this.isModified('isVoided') && this.isVoided) {
280
+ this.approvalStatus = 'Pending';
281
+ this.reconciliationStatus = 'Pending';
282
+ }
283
+
284
+ next();
285
+ });
286
+
287
+ // Create model (only if not already defined by getModel utility)
288
+ const CashPayment = mongoose.models.CashPayment || mongoose.model('CashPayment', cashPaymentSchema);
289
+
290
+ module.exports = CashPayment;
291
+