payservedb 9.2.8 → 9.3.0

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 (231) hide show
  1. package/.env +2 -2
  2. package/ZOHO_INTEGRATION_SCHEMA.md +644 -644
  3. package/index.js +416 -415
  4. package/package.json +17 -17
  5. package/src/models/InvoiceWithholdingTax.js +67 -67
  6. package/src/models/account.js +52 -52
  7. package/src/models/agent_departments.js +59 -59
  8. package/src/models/agent_notifications.js +53 -53
  9. package/src/models/agent_performance.js +127 -127
  10. package/src/models/agent_roles.js +77 -77
  11. package/src/models/agents.js +154 -154
  12. package/src/models/apilog.js +18 -18
  13. package/src/models/approvalsWorkflows.js +49 -49
  14. package/src/models/archivedapilog.js +18 -18
  15. package/src/models/asset.js +92 -92
  16. package/src/models/assetsAssignment.js +64 -64
  17. package/src/models/auditTrail.js +346 -346
  18. package/src/models/auto_reply_rule.js +68 -68
  19. package/src/models/bankdetails.js +47 -47
  20. package/src/models/billerAddress.js +124 -124
  21. package/src/models/booking_invoice.js +165 -165
  22. package/src/models/bookinganalytics.js +63 -63
  23. package/src/models/bookingconfig.js +45 -45
  24. package/src/models/bookingproperty.js +179 -179
  25. package/src/models/bookingreservation.js +239 -239
  26. package/src/models/bookingrevenuerecord.js +84 -84
  27. package/src/models/budget.js +95 -95
  28. package/src/models/budgetCategory.js +19 -19
  29. package/src/models/campaigns.js +108 -108
  30. package/src/models/cashpayment.js +290 -290
  31. package/src/models/combinedUnits.js +62 -62
  32. package/src/models/combined_invoice.js +424 -424
  33. package/src/models/common_area_electricity.js +38 -38
  34. package/src/models/common_area_generator.js +41 -41
  35. package/src/models/common_area_utility_alert.js +37 -37
  36. package/src/models/common_area_water.js +39 -39
  37. package/src/models/communication_status.js +33 -33
  38. package/src/models/communication_user_opt.js +32 -32
  39. package/src/models/community_guidelines.js +35 -35
  40. package/src/models/company.js +53 -53
  41. package/src/models/coreBaseSettings.js +16 -16
  42. package/src/models/coreInvoiceSettings.js +100 -100
  43. package/src/models/counter_schema.js +21 -21
  44. package/src/models/country_tax.js +42 -42
  45. package/src/models/currency_settings.js +39 -39
  46. package/src/models/customer.js +234 -234
  47. package/src/models/customer_preference.js +52 -52
  48. package/src/models/customer_satisfaction_survey.js +297 -297
  49. package/src/models/customer_surveys.js +139 -139
  50. package/src/models/customer_tickets.js +237 -237
  51. package/src/models/dailyChecklist.js +312 -312
  52. package/src/models/default_payment_details.js +17 -17
  53. package/src/models/deliveryTimeMarks.js +18 -18
  54. package/src/models/document_type.js +19 -19
  55. package/src/models/dutyRosterChecklist.js +250 -250
  56. package/src/models/dutyroster.js +136 -136
  57. package/src/models/email.js +37 -37
  58. package/src/models/email_cc_config.js +48 -48
  59. package/src/models/email_sms_queue.js +61 -61
  60. package/src/models/email_thread.js +35 -35
  61. package/src/models/entry_exit.js +53 -53
  62. package/src/models/expense.js +99 -99
  63. package/src/models/expense_category.js +45 -45
  64. package/src/models/facility.js +76 -76
  65. package/src/models/facilityBillingPrices.js +29 -29
  66. package/src/models/facilityInvoice.js +240 -240
  67. package/src/models/facilityInvoicePayment.js +52 -52
  68. package/src/models/facilityInvoiceRecipient.js +32 -32
  69. package/src/models/facilityWalletTransactionsMetadata.js +236 -236
  70. package/src/models/facility_departements.js +20 -20
  71. package/src/models/facility_etims_config.js +116 -116
  72. package/src/models/facility_payment_details.js +20 -20
  73. package/src/models/facility_rating.js +78 -78
  74. package/src/models/facilityasset.js +25 -25
  75. package/src/models/faq.js +15 -15
  76. package/src/models/gl_account_double_entries.js +25 -25
  77. package/src/models/gl_accounts.js +56 -56
  78. package/src/models/gl_entries.js +49 -49
  79. package/src/models/goodsReceivedNotes.js +115 -115
  80. package/src/models/guard.js +47 -47
  81. package/src/models/handover.js +258 -258
  82. package/src/models/inspection_category.js +38 -38
  83. package/src/models/invoice.js +528 -528
  84. package/src/models/invoiceCreditAdjustment.js +45 -45
  85. package/src/models/invoice_edit_log.js +81 -81
  86. package/src/models/invoice_generation_approval.js +86 -86
  87. package/src/models/invoicing_schedule.js +40 -40
  88. package/src/models/item_inspection.js +96 -96
  89. package/src/models/knowledge_base.js +109 -109
  90. package/src/models/knowledge_base_rating.js +44 -44
  91. package/src/models/leaseagreement.js +243 -243
  92. package/src/models/leasetemplate.js +17 -17
  93. package/src/models/levy.js +212 -212
  94. package/src/models/levy_deposits.js +126 -126
  95. package/src/models/levy_invoice_settings.js +26 -26
  96. package/src/models/levy_payment_receipt.js +156 -156
  97. package/src/models/levycontract.js +213 -226
  98. package/src/models/levytype.js +23 -23
  99. package/src/models/maintenance_service_vendor.js +38 -38
  100. package/src/models/maintenance_services.js +17 -17
  101. package/src/models/maintenancerequisition.js +31 -31
  102. package/src/models/master_workplan.js +32 -32
  103. package/src/models/master_workplan_child.js +34 -34
  104. package/src/models/message.js +38 -38
  105. package/src/models/module.js +21 -21
  106. package/src/models/movein_amenity.js +13 -13
  107. package/src/models/movein_application.js +28 -28
  108. package/src/models/movein_audit_log.js +21 -21
  109. package/src/models/movein_booking.js +33 -33
  110. package/src/models/movein_commission.js +46 -46
  111. package/src/models/movein_conversation.js +25 -25
  112. package/src/models/movein_deal.js +79 -79
  113. package/src/models/movein_disbursement.js +36 -36
  114. package/src/models/movein_email_thread.js +19 -19
  115. package/src/models/movein_enquiry.js +16 -16
  116. package/src/models/movein_featured_package.js +16 -16
  117. package/src/models/movein_handoff_token.js +16 -16
  118. package/src/models/movein_invoice.js +24 -24
  119. package/src/models/movein_landlord.js +18 -18
  120. package/src/models/movein_landlord_user.js +20 -20
  121. package/src/models/movein_lease.js +37 -37
  122. package/src/models/movein_message.js +27 -27
  123. package/src/models/movein_notification.js +27 -27
  124. package/src/models/movein_otp.js +14 -14
  125. package/src/models/movein_payment.js +46 -46
  126. package/src/models/movein_reminder.js +77 -77
  127. package/src/models/movein_reservation.js +31 -31
  128. package/src/models/movein_settings.js +25 -25
  129. package/src/models/movein_tenancy.js +55 -55
  130. package/src/models/movein_unit.js +59 -59
  131. package/src/models/movein_user.js +15 -15
  132. package/src/models/movein_viewing_slot.js +21 -21
  133. package/src/models/movein_want_unit.js +20 -20
  134. package/src/models/notification.js +44 -44
  135. package/src/models/paymentTermsMarks.js +19 -19
  136. package/src/models/penalty.js +76 -76
  137. package/src/models/pendingCredentials.js +32 -32
  138. package/src/models/powerMeterCommunicationProtocol.js +17 -17
  139. package/src/models/powerMeterCustomerAccount.js +78 -78
  140. package/src/models/powerMeterCustomerBand.js +14 -14
  141. package/src/models/powerMeterDailyReading.js +30 -30
  142. package/src/models/powerMeterGateways.js +40 -40
  143. package/src/models/powerMeterMonthlyReading.js +34 -34
  144. package/src/models/powerMeterPowerCharges.js +85 -85
  145. package/src/models/powerMeterSettings.js +211 -211
  146. package/src/models/powerMeterSingleDayReading.js +32 -32
  147. package/src/models/powerMeters.js +149 -149
  148. package/src/models/powerMetersManufacturer.js +14 -14
  149. package/src/models/power_invoice.js +371 -366
  150. package/src/models/power_meter_account.js +81 -81
  151. package/src/models/power_meter_command_logs.js +30 -30
  152. package/src/models/power_meter_command_queue.js +33 -33
  153. package/src/models/power_meter_negative_balance.js +44 -44
  154. package/src/models/power_prepaid_credits.js +47 -47
  155. package/src/models/power_prepaid_debits.js +53 -53
  156. package/src/models/power_prepaid_orders.js +78 -78
  157. package/src/models/power_sms_notification.js +26 -26
  158. package/src/models/privacy_policy.js +19 -19
  159. package/src/models/propertyManagementSettings.js +60 -0
  160. package/src/models/propertyManagerContract.js +556 -556
  161. package/src/models/propertyManagerRevenue.js +195 -195
  162. package/src/models/propertyManagerRevenueEntry.js +108 -0
  163. package/src/models/purchaseOrderInvoice.js +74 -74
  164. package/src/models/purchase_order.js +213 -213
  165. package/src/models/purchase_request.js +110 -110
  166. package/src/models/quickbooks_config.js +52 -52
  167. package/src/models/recipient_group.js +61 -61
  168. package/src/models/recipient_group_member.js +62 -62
  169. package/src/models/refresh_token.js +23 -23
  170. package/src/models/reminder.js +197 -197
  171. package/src/models/report.js +13 -13
  172. package/src/models/resident.js +121 -121
  173. package/src/models/rfq_details.js +131 -131
  174. package/src/models/rfq_response.js +153 -153
  175. package/src/models/service_charge_invoice_upload.js +42 -42
  176. package/src/models/service_charge_payments.js +27 -27
  177. package/src/models/servicerequest.js +55 -55
  178. package/src/models/settings.js +62 -62
  179. package/src/models/short_urls.js +21 -21
  180. package/src/models/smart_meter_daily_consumption.js +44 -44
  181. package/src/models/sms_africastalking.js +20 -20
  182. package/src/models/sms_balance_notification.js +26 -26
  183. package/src/models/sms_meliora.js +20 -20
  184. package/src/models/staff.js +36 -36
  185. package/src/models/stocksandspare.js +161 -161
  186. package/src/models/suppliers.js +79 -79
  187. package/src/models/terms_and_conditions.js +19 -19
  188. package/src/models/tickets.js +186 -186
  189. package/src/models/tickets_category.js +72 -72
  190. package/src/models/unitManagementTemplate.js +44 -44
  191. package/src/models/unitasset.js +25 -25
  192. package/src/models/units.js +148 -130
  193. package/src/models/user.js +186 -192
  194. package/src/models/valueaddedservices.js +50 -21
  195. package/src/models/vas_invoices_upload.js +50 -50
  196. package/src/models/vas_payments.js +24 -24
  197. package/src/models/vasinvoice.js +196 -196
  198. package/src/models/vasvendor.js +52 -52
  199. package/src/models/visitLog.js +95 -95
  200. package/src/models/visitor.js +67 -67
  201. package/src/models/waitlist.js +45 -45
  202. package/src/models/wallet.js +44 -44
  203. package/src/models/wallet_transaction.js +67 -67
  204. package/src/models/wallet_transactions.js +50 -50
  205. package/src/models/water_invoice.js +362 -396
  206. package/src/models/water_meter_Command_Queue.js +33 -33
  207. package/src/models/water_meter_account.js +86 -86
  208. package/src/models/water_meter_billing.js +58 -58
  209. package/src/models/water_meter_combined_accounts.js +92 -92
  210. package/src/models/water_meter_communication.js +17 -17
  211. package/src/models/water_meter_communication_logs.js +39 -39
  212. package/src/models/water_meter_concentrator.js +70 -70
  213. package/src/models/water_meter_daily_history.js +32 -32
  214. package/src/models/water_meter_high_risk.js +36 -36
  215. package/src/models/water_meter_iot_cards.js +34 -34
  216. package/src/models/water_meter_loan_deduction.js +134 -134
  217. package/src/models/water_meter_manufacturer.js +35 -35
  218. package/src/models/water_meter_monthly_history.js +36 -36
  219. package/src/models/water_meter_negative_amounts.js +44 -44
  220. package/src/models/water_meter_settings.js +296 -296
  221. package/src/models/water_meter_single_day_history.js +34 -34
  222. package/src/models/water_meter_size.js +15 -15
  223. package/src/models/water_meters.js +176 -176
  224. package/src/models/water_meters_delivery.js +76 -76
  225. package/src/models/water_prepaid_credit.js +47 -47
  226. package/src/models/water_prepaid_debit.js +50 -50
  227. package/src/models/whatsapp_conversation.js +23 -23
  228. package/src/models/workorder.js +49 -49
  229. package/src/models/zohoAccount.js +453 -453
  230. package/src/models/zohoIntegration.js +262 -262
  231. package/src/models/zohoItem.js +504 -504
@@ -1,258 +1,258 @@
1
- const mongoose = require('mongoose');
2
-
3
- const handoverItemSchema = new mongoose.Schema({
4
- name: {
5
- type: String,
6
- required: true,
7
- trim: true
8
- },
9
- category: {
10
- type: String,
11
- required: true,
12
- trim: true,
13
- enum: ['Furniture', 'Appliance', 'Electronics', 'Fixture', 'Utility', 'Other']
14
- },
15
- description: {
16
- type: String,
17
- trim: true
18
- },
19
- condition: {
20
- type: String,
21
- required: true,
22
- enum: ['Excellent', 'Good', 'Fair', 'Poor', 'Damaged', 'Non-functional']
23
- },
24
- quantity: {
25
- type: Number,
26
- required: true,
27
- default: 1,
28
- min: [1, 'Quantity must be at least 1']
29
- },
30
- serialNumber: {
31
- type: String,
32
- trim: true
33
- },
34
- images: [{
35
- type: String, // URLs to stored images
36
- trim: true
37
- }],
38
- notes: {
39
- type: String,
40
- trim: true
41
- }
42
- }, { _id: true });
43
-
44
- // Define the main Handover schema
45
- const handoverSchema = new mongoose.Schema({
46
- // References
47
- facilityId: {
48
- type: mongoose.Schema.Types.ObjectId,
49
- ref: 'Facility',
50
- required: true
51
- },
52
- unitId: {
53
- type: mongoose.Schema.Types.ObjectId,
54
- ref: 'Unit',
55
- required: true
56
- },
57
- // IMPORTANT: For Customer, we don't specify 'ref' since it's in a different database
58
- // This avoids the cross-database population errors
59
- customerId: {
60
- type: mongoose.Schema.Types.ObjectId,
61
- required: true
62
- },
63
-
64
- // Handover details
65
- handoverType: {
66
- type: String,
67
- required: true,
68
- enum: ['MoveIn', 'MoveOut'],
69
- trim: true
70
- },
71
- handoverDate: {
72
- type: Date,
73
- required: true,
74
- default: Date.now
75
- },
76
- status: {
77
- type: String,
78
- required: true,
79
- enum: ['Draft', 'Completed', 'Disputed', 'Resolved'],
80
- default: 'Draft'
81
- },
82
-
83
- // If this is a move-out handover, reference the original move-in handover
84
- relatedHandoverId: {
85
- type: mongoose.Schema.Types.ObjectId,
86
- ref: 'Handover',
87
- default: null // Only populated for move-out handovers
88
- },
89
-
90
- // Items included in the handover
91
- items: [handoverItemSchema],
92
-
93
- // Additional information
94
- meterReadings: {
95
- electricity: {
96
- reading: Number,
97
- imageUrl: String
98
- },
99
- water: {
100
- reading: Number,
101
- imageUrl: String
102
- },
103
- gas: {
104
- reading: Number,
105
- imageUrl: String
106
- }
107
- },
108
-
109
- // Key handover confirmation
110
- keysHandedOver: {
111
- type: Number,
112
- default: 0,
113
- min: 0
114
- },
115
-
116
- // Security deposit info (for move-out)
117
- securityDeposit: {
118
- amount: {
119
- type: Number,
120
- default: 0
121
- },
122
- deductions: [{
123
- reason: {
124
- type: String,
125
- trim: true
126
- },
127
- amount: {
128
- type: Number,
129
- min: 0
130
- },
131
- description: String,
132
- currencyId: {
133
- type: mongoose.Schema.Types.ObjectId,
134
- ref: 'Currency',
135
- default: null
136
- },
137
- currency: {
138
- type: mongoose.Schema.Types.Mixed,
139
- default: null
140
- },
141
- invoiceId: {
142
- type: mongoose.Schema.Types.ObjectId,
143
- ref: 'Invoice',
144
- default: null
145
- }
146
- }],
147
- refundAmount: {
148
- type: Number,
149
- default: 0
150
- }
151
- },
152
-
153
- // Signature and agreement info
154
- signatures: {
155
- propertyManager: {
156
- signature: String, // URL to stored signature image or digital signature data
157
- date: Date
158
- },
159
- customer: {
160
- signature: String, // URL to stored signature image or digital signature data
161
- date: Date,
162
- agreement: {
163
- type: Boolean,
164
- default: false
165
- }
166
- }
167
- },
168
-
169
- // General notes
170
- notes: {
171
- type: String,
172
- trim: true
173
- },
174
-
175
- // Any attached documents
176
- attachments: [{
177
- name: String, // Custom descriptive name (e.g., "Chair Image 23")
178
- fileName: String, // Original file name
179
- fileUrl: String,
180
- uploadDate: {
181
- type: Date,
182
- default: Date.now
183
- }
184
- }]
185
- }, {
186
- timestamps: true,
187
- toJSON: { virtuals: true }, // Enable virtuals when converting to JSON
188
- toObject: { virtuals: true } // Enable virtuals when converting to object
189
- });
190
-
191
- // Add indexes for common queries
192
- handoverSchema.index({ facilityId: 1, unitId: 1, handoverType: 1 });
193
- handoverSchema.index({ customerId: 1, handoverType: 1 });
194
- handoverSchema.index({ handoverDate: -1 });
195
-
196
- // Virtual for calculating total deductions
197
- handoverSchema.virtual('totalDeductions').get(function() {
198
- if (!this.securityDeposit.deductions || this.securityDeposit.deductions.length === 0) {
199
- return 0;
200
- }
201
- return this.securityDeposit.deductions.reduce((total, deduction) => total + (deduction.amount || 0), 0);
202
- });
203
-
204
- // Add method to compare move-in and move-out states
205
- handoverSchema.methods.compareWithMoveIn = async function() {
206
- if (this.handoverType !== 'MoveOut' || !this.relatedHandoverId) {
207
- throw new Error('This method can only be called on a move-out handover with a related move-in handover');
208
- }
209
-
210
- // Find the related move-in handover
211
- const MoveInHandover = mongoose.model('Handover');
212
- const moveInHandover = await MoveInHandover.findById(this.relatedHandoverId);
213
-
214
- if (!moveInHandover) {
215
- throw new Error('Related move-in handover not found');
216
- }
217
-
218
- // Compare items and return differences
219
- const differences = {
220
- missing: [],
221
- damaged: [],
222
- changed: []
223
- };
224
-
225
- // Check for missing or damaged items
226
- moveInHandover.items.forEach(moveInItem => {
227
- const moveOutItem = this.items.find(item =>
228
- item.name === moveInItem.name &&
229
- item.category === moveInItem.category
230
- );
231
-
232
- if (!moveOutItem) {
233
- differences.missing.push(moveInItem);
234
- } else if (moveOutItem.condition !== moveInItem.condition) {
235
- if (['Poor', 'Damaged', 'Non-functional'].includes(moveOutItem.condition)) {
236
- differences.damaged.push({
237
- item: moveOutItem,
238
- originalCondition: moveInItem.condition,
239
- currentCondition: moveOutItem.condition
240
- });
241
- } else {
242
- differences.changed.push({
243
- item: moveOutItem,
244
- originalCondition: moveInItem.condition,
245
- currentCondition: moveOutItem.condition
246
- });
247
- }
248
- }
249
- });
250
-
251
- return differences;
252
- };
253
-
254
- // Create and export the model with the standard pattern
255
- const Handover = mongoose.model('Handover', handoverSchema);
256
-
257
- module.exports = Handover;
258
-
1
+ const mongoose = require('mongoose');
2
+
3
+ const handoverItemSchema = new mongoose.Schema({
4
+ name: {
5
+ type: String,
6
+ required: true,
7
+ trim: true
8
+ },
9
+ category: {
10
+ type: String,
11
+ required: true,
12
+ trim: true,
13
+ enum: ['Furniture', 'Appliance', 'Electronics', 'Fixture', 'Utility', 'Other']
14
+ },
15
+ description: {
16
+ type: String,
17
+ trim: true
18
+ },
19
+ condition: {
20
+ type: String,
21
+ required: true,
22
+ enum: ['Excellent', 'Good', 'Fair', 'Poor', 'Damaged', 'Non-functional']
23
+ },
24
+ quantity: {
25
+ type: Number,
26
+ required: true,
27
+ default: 1,
28
+ min: [1, 'Quantity must be at least 1']
29
+ },
30
+ serialNumber: {
31
+ type: String,
32
+ trim: true
33
+ },
34
+ images: [{
35
+ type: String, // URLs to stored images
36
+ trim: true
37
+ }],
38
+ notes: {
39
+ type: String,
40
+ trim: true
41
+ }
42
+ }, { _id: true });
43
+
44
+ // Define the main Handover schema
45
+ const handoverSchema = new mongoose.Schema({
46
+ // References
47
+ facilityId: {
48
+ type: mongoose.Schema.Types.ObjectId,
49
+ ref: 'Facility',
50
+ required: true
51
+ },
52
+ unitId: {
53
+ type: mongoose.Schema.Types.ObjectId,
54
+ ref: 'Unit',
55
+ required: true
56
+ },
57
+ // IMPORTANT: For Customer, we don't specify 'ref' since it's in a different database
58
+ // This avoids the cross-database population errors
59
+ customerId: {
60
+ type: mongoose.Schema.Types.ObjectId,
61
+ required: true
62
+ },
63
+
64
+ // Handover details
65
+ handoverType: {
66
+ type: String,
67
+ required: true,
68
+ enum: ['MoveIn', 'MoveOut'],
69
+ trim: true
70
+ },
71
+ handoverDate: {
72
+ type: Date,
73
+ required: true,
74
+ default: Date.now
75
+ },
76
+ status: {
77
+ type: String,
78
+ required: true,
79
+ enum: ['Draft', 'Completed', 'Disputed', 'Resolved'],
80
+ default: 'Draft'
81
+ },
82
+
83
+ // If this is a move-out handover, reference the original move-in handover
84
+ relatedHandoverId: {
85
+ type: mongoose.Schema.Types.ObjectId,
86
+ ref: 'Handover',
87
+ default: null // Only populated for move-out handovers
88
+ },
89
+
90
+ // Items included in the handover
91
+ items: [handoverItemSchema],
92
+
93
+ // Additional information
94
+ meterReadings: {
95
+ electricity: {
96
+ reading: Number,
97
+ imageUrl: String
98
+ },
99
+ water: {
100
+ reading: Number,
101
+ imageUrl: String
102
+ },
103
+ gas: {
104
+ reading: Number,
105
+ imageUrl: String
106
+ }
107
+ },
108
+
109
+ // Key handover confirmation
110
+ keysHandedOver: {
111
+ type: Number,
112
+ default: 0,
113
+ min: 0
114
+ },
115
+
116
+ // Security deposit info (for move-out)
117
+ securityDeposit: {
118
+ amount: {
119
+ type: Number,
120
+ default: 0
121
+ },
122
+ deductions: [{
123
+ reason: {
124
+ type: String,
125
+ trim: true
126
+ },
127
+ amount: {
128
+ type: Number,
129
+ min: 0
130
+ },
131
+ description: String,
132
+ currencyId: {
133
+ type: mongoose.Schema.Types.ObjectId,
134
+ ref: 'Currency',
135
+ default: null
136
+ },
137
+ currency: {
138
+ type: mongoose.Schema.Types.Mixed,
139
+ default: null
140
+ },
141
+ invoiceId: {
142
+ type: mongoose.Schema.Types.ObjectId,
143
+ ref: 'Invoice',
144
+ default: null
145
+ }
146
+ }],
147
+ refundAmount: {
148
+ type: Number,
149
+ default: 0
150
+ }
151
+ },
152
+
153
+ // Signature and agreement info
154
+ signatures: {
155
+ propertyManager: {
156
+ signature: String, // URL to stored signature image or digital signature data
157
+ date: Date
158
+ },
159
+ customer: {
160
+ signature: String, // URL to stored signature image or digital signature data
161
+ date: Date,
162
+ agreement: {
163
+ type: Boolean,
164
+ default: false
165
+ }
166
+ }
167
+ },
168
+
169
+ // General notes
170
+ notes: {
171
+ type: String,
172
+ trim: true
173
+ },
174
+
175
+ // Any attached documents
176
+ attachments: [{
177
+ name: String, // Custom descriptive name (e.g., "Chair Image 23")
178
+ fileName: String, // Original file name
179
+ fileUrl: String,
180
+ uploadDate: {
181
+ type: Date,
182
+ default: Date.now
183
+ }
184
+ }]
185
+ }, {
186
+ timestamps: true,
187
+ toJSON: { virtuals: true }, // Enable virtuals when converting to JSON
188
+ toObject: { virtuals: true } // Enable virtuals when converting to object
189
+ });
190
+
191
+ // Add indexes for common queries
192
+ handoverSchema.index({ facilityId: 1, unitId: 1, handoverType: 1 });
193
+ handoverSchema.index({ customerId: 1, handoverType: 1 });
194
+ handoverSchema.index({ handoverDate: -1 });
195
+
196
+ // Virtual for calculating total deductions
197
+ handoverSchema.virtual('totalDeductions').get(function() {
198
+ if (!this.securityDeposit.deductions || this.securityDeposit.deductions.length === 0) {
199
+ return 0;
200
+ }
201
+ return this.securityDeposit.deductions.reduce((total, deduction) => total + (deduction.amount || 0), 0);
202
+ });
203
+
204
+ // Add method to compare move-in and move-out states
205
+ handoverSchema.methods.compareWithMoveIn = async function() {
206
+ if (this.handoverType !== 'MoveOut' || !this.relatedHandoverId) {
207
+ throw new Error('This method can only be called on a move-out handover with a related move-in handover');
208
+ }
209
+
210
+ // Find the related move-in handover
211
+ const MoveInHandover = mongoose.model('Handover');
212
+ const moveInHandover = await MoveInHandover.findById(this.relatedHandoverId);
213
+
214
+ if (!moveInHandover) {
215
+ throw new Error('Related move-in handover not found');
216
+ }
217
+
218
+ // Compare items and return differences
219
+ const differences = {
220
+ missing: [],
221
+ damaged: [],
222
+ changed: []
223
+ };
224
+
225
+ // Check for missing or damaged items
226
+ moveInHandover.items.forEach(moveInItem => {
227
+ const moveOutItem = this.items.find(item =>
228
+ item.name === moveInItem.name &&
229
+ item.category === moveInItem.category
230
+ );
231
+
232
+ if (!moveOutItem) {
233
+ differences.missing.push(moveInItem);
234
+ } else if (moveOutItem.condition !== moveInItem.condition) {
235
+ if (['Poor', 'Damaged', 'Non-functional'].includes(moveOutItem.condition)) {
236
+ differences.damaged.push({
237
+ item: moveOutItem,
238
+ originalCondition: moveInItem.condition,
239
+ currentCondition: moveOutItem.condition
240
+ });
241
+ } else {
242
+ differences.changed.push({
243
+ item: moveOutItem,
244
+ originalCondition: moveInItem.condition,
245
+ currentCondition: moveOutItem.condition
246
+ });
247
+ }
248
+ }
249
+ });
250
+
251
+ return differences;
252
+ };
253
+
254
+ // Create and export the model with the standard pattern
255
+ const Handover = mongoose.model('Handover', handoverSchema);
256
+
257
+ module.exports = Handover;
258
+
@@ -1,38 +1,38 @@
1
- const mongoose = require('mongoose');
2
-
3
- // Define the schema for inspection categories
4
- const inspectionCategorySchema = new mongoose.Schema({
5
- name: {
6
- type: String,
7
- required: [true, 'Category name is required'],
8
- trim: true,
9
- unique: false // Unique per facility, not globally
10
- },
11
- description: {
12
- type: String,
13
- trim: true,
14
- default: ''
15
- },
16
- active: {
17
- type: Boolean,
18
- default: true
19
- },
20
- facilityId: {
21
- type: mongoose.Schema.Types.ObjectId,
22
- ref: 'Facility',
23
- required: true
24
- }
25
- }, {
26
- timestamps: true
27
- });
28
-
29
- // Add compound index to ensure unique category names per facility
30
- inspectionCategorySchema.index({ facilityId: 1, name: 1 }, { unique: true });
31
-
32
- // Add index for common queries
33
- inspectionCategorySchema.index({ facilityId: 1 });
34
-
35
- // Create InspectionCategory model
36
- const InspectionCategory = mongoose.model('InspectionCategory', inspectionCategorySchema);
37
-
38
- module.exports = InspectionCategory;
1
+ const mongoose = require('mongoose');
2
+
3
+ // Define the schema for inspection categories
4
+ const inspectionCategorySchema = new mongoose.Schema({
5
+ name: {
6
+ type: String,
7
+ required: [true, 'Category name is required'],
8
+ trim: true,
9
+ unique: false // Unique per facility, not globally
10
+ },
11
+ description: {
12
+ type: String,
13
+ trim: true,
14
+ default: ''
15
+ },
16
+ active: {
17
+ type: Boolean,
18
+ default: true
19
+ },
20
+ facilityId: {
21
+ type: mongoose.Schema.Types.ObjectId,
22
+ ref: 'Facility',
23
+ required: true
24
+ }
25
+ }, {
26
+ timestamps: true
27
+ });
28
+
29
+ // Add compound index to ensure unique category names per facility
30
+ inspectionCategorySchema.index({ facilityId: 1, name: 1 }, { unique: true });
31
+
32
+ // Add index for common queries
33
+ inspectionCategorySchema.index({ facilityId: 1 });
34
+
35
+ // Create InspectionCategory model
36
+ const InspectionCategory = mongoose.model('InspectionCategory', inspectionCategorySchema);
37
+
38
+ module.exports = InspectionCategory;