payservedb 8.9.8 → 9.0.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 (196) hide show
  1. package/.env +2 -2
  2. package/ZOHO_INTEGRATION_SCHEMA.md +644 -644
  3. package/index.js +330 -328
  4. package/package.json +17 -17
  5. package/src/models/InvoiceWithholdingTax.js +68 -0
  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/bankdetails.js +47 -47
  19. package/src/models/billerAddress.js +124 -124
  20. package/src/models/booking_invoice.js +165 -165
  21. package/src/models/bookinganalytics.js +63 -63
  22. package/src/models/bookingconfig.js +45 -45
  23. package/src/models/bookingproperty.js +179 -179
  24. package/src/models/bookingreservation.js +239 -239
  25. package/src/models/bookingrevenuerecord.js +84 -84
  26. package/src/models/budget.js +95 -95
  27. package/src/models/budgetCategory.js +19 -19
  28. package/src/models/campaigns.js +108 -108
  29. package/src/models/cashpayment.js +290 -290
  30. package/src/models/combinedUnits.js +62 -62
  31. package/src/models/combined_invoice.js +424 -424
  32. package/src/models/common_area_electricity.js +38 -38
  33. package/src/models/common_area_generator.js +41 -41
  34. package/src/models/common_area_utility_alert.js +37 -37
  35. package/src/models/common_area_water.js +39 -39
  36. package/src/models/communication_status.js +33 -33
  37. package/src/models/communication_user_opt.js +32 -32
  38. package/src/models/community_guidelines.js +35 -35
  39. package/src/models/company.js +53 -53
  40. package/src/models/coreBaseSettings.js +16 -16
  41. package/src/models/coreInvoiceSettings.js +100 -100
  42. package/src/models/counter_schema.js +21 -21
  43. package/src/models/country_tax.js +42 -42
  44. package/src/models/currency_settings.js +39 -39
  45. package/src/models/customer.js +214 -214
  46. package/src/models/customer_preference.js +52 -52
  47. package/src/models/customer_satisfaction_survey.js +297 -297
  48. package/src/models/customer_surveys.js +139 -139
  49. package/src/models/customer_tickets.js +237 -237
  50. package/src/models/dailyChecklist.js +312 -312
  51. package/src/models/default_payment_details.js +17 -17
  52. package/src/models/deliveryTimeMarks.js +18 -18
  53. package/src/models/document_type.js +19 -19
  54. package/src/models/dutyRosterChecklist.js +250 -250
  55. package/src/models/dutyroster.js +136 -136
  56. package/src/models/email.js +37 -37
  57. package/src/models/email_sms_queue.js +61 -61
  58. package/src/models/email_thread.js +35 -35
  59. package/src/models/entry_exit.js +53 -53
  60. package/src/models/expense.js +99 -99
  61. package/src/models/expense_category.js +45 -45
  62. package/src/models/facility.js +76 -76
  63. package/src/models/facilityBillingPrices.js +29 -29
  64. package/src/models/facilityInvoice.js +240 -240
  65. package/src/models/facilityInvoicePayment.js +52 -52
  66. package/src/models/facilityInvoiceRecipient.js +32 -32
  67. package/src/models/facilityWalletTransactionsMetadata.js +236 -236
  68. package/src/models/facility_departements.js +20 -20
  69. package/src/models/facility_etims_config.js +117 -0
  70. package/src/models/facility_payment_details.js +20 -20
  71. package/src/models/facility_rating.js +78 -78
  72. package/src/models/facilityasset.js +25 -25
  73. package/src/models/faq.js +14 -14
  74. package/src/models/gl_account_double_entries.js +25 -25
  75. package/src/models/gl_accounts.js +56 -56
  76. package/src/models/gl_entries.js +49 -49
  77. package/src/models/goodsReceivedNotes.js +115 -115
  78. package/src/models/guard.js +47 -47
  79. package/src/models/handover.js +258 -258
  80. package/src/models/inspection_category.js +38 -38
  81. package/src/models/invoice.js +514 -514
  82. package/src/models/invoice_edit_log.js +81 -81
  83. package/src/models/invoice_generation_approval.js +86 -86
  84. package/src/models/invoicing_schedule.js +40 -40
  85. package/src/models/item_inspection.js +96 -96
  86. package/src/models/knowledge_base.js +109 -109
  87. package/src/models/knowledge_base_rating.js +44 -44
  88. package/src/models/leaseagreement.js +243 -243
  89. package/src/models/leasetemplate.js +17 -17
  90. package/src/models/levy.js +212 -212
  91. package/src/models/levy_invoice_settings.js +26 -26
  92. package/src/models/levycontract.js +215 -215
  93. package/src/models/levytype.js +23 -23
  94. package/src/models/maintenance_service_vendor.js +38 -38
  95. package/src/models/maintenance_services.js +17 -17
  96. package/src/models/maintenancerequisition.js +31 -31
  97. package/src/models/master_workplan.js +32 -32
  98. package/src/models/master_workplan_child.js +34 -34
  99. package/src/models/message.js +38 -38
  100. package/src/models/module.js +21 -21
  101. package/src/models/movein_application.js +29 -29
  102. package/src/models/movein_landlord.js +18 -18
  103. package/src/models/movein_user.js +15 -15
  104. package/src/models/notification.js +44 -44
  105. package/src/models/paymentTermsMarks.js +19 -19
  106. package/src/models/penalty.js +76 -76
  107. package/src/models/pendingCredentials.js +32 -32
  108. package/src/models/powerMeterCommunicationProtocol.js +17 -17
  109. package/src/models/powerMeterCustomerAccount.js +78 -78
  110. package/src/models/powerMeterCustomerBand.js +14 -14
  111. package/src/models/powerMeterDailyReading.js +30 -30
  112. package/src/models/powerMeterGateways.js +40 -40
  113. package/src/models/powerMeterMonthlyReading.js +34 -34
  114. package/src/models/powerMeterPowerCharges.js +85 -85
  115. package/src/models/powerMeterSettings.js +159 -159
  116. package/src/models/powerMeterSingleDayReading.js +32 -32
  117. package/src/models/powerMeters.js +116 -116
  118. package/src/models/powerMetersManufacturer.js +14 -14
  119. package/src/models/power_invoice.js +470 -470
  120. package/src/models/power_meter_account.js +81 -81
  121. package/src/models/power_meter_command_logs.js +30 -30
  122. package/src/models/power_meter_command_queue.js +33 -33
  123. package/src/models/power_meter_negative_balance.js +44 -44
  124. package/src/models/power_prepaid_credits.js +47 -47
  125. package/src/models/power_prepaid_debits.js +53 -53
  126. package/src/models/power_prepaid_orders.js +78 -78
  127. package/src/models/power_sms_notification.js +26 -26
  128. package/src/models/privacy_policy.js +19 -19
  129. package/src/models/propertyManagerContract.js +556 -556
  130. package/src/models/propertyManagerRevenue.js +195 -195
  131. package/src/models/purchaseOrderInvoice.js +74 -74
  132. package/src/models/purchase_order.js +213 -213
  133. package/src/models/purchase_request.js +110 -110
  134. package/src/models/quickbooks_config.js +52 -52
  135. package/src/models/refresh_token.js +23 -23
  136. package/src/models/reminder.js +197 -197
  137. package/src/models/report.js +13 -13
  138. package/src/models/resident.js +121 -121
  139. package/src/models/rfq_details.js +131 -131
  140. package/src/models/rfq_response.js +153 -153
  141. package/src/models/service_charge_invoice_upload.js +42 -42
  142. package/src/models/service_charge_payments.js +27 -27
  143. package/src/models/servicerequest.js +55 -55
  144. package/src/models/settings.js +62 -62
  145. package/src/models/short_urls.js +21 -21
  146. package/src/models/smart_meter_daily_consumption.js +44 -44
  147. package/src/models/sms_africastalking.js +20 -20
  148. package/src/models/sms_balance_notification.js +26 -26
  149. package/src/models/sms_meliora.js +20 -20
  150. package/src/models/staff.js +36 -36
  151. package/src/models/stocksandspare.js +161 -161
  152. package/src/models/suppliers.js +74 -74
  153. package/src/models/terms_and_conditions.js +19 -19
  154. package/src/models/tickets.js +186 -186
  155. package/src/models/tickets_category.js +72 -72
  156. package/src/models/unitManagementTemplate.js +44 -44
  157. package/src/models/unitasset.js +25 -25
  158. package/src/models/units.js +130 -130
  159. package/src/models/user.js +186 -186
  160. package/src/models/valueaddedservices.js +21 -21
  161. package/src/models/vas_invoices_upload.js +50 -50
  162. package/src/models/vas_payments.js +24 -24
  163. package/src/models/vasinvoice.js +196 -192
  164. package/src/models/vasvendor.js +52 -52
  165. package/src/models/visitLog.js +95 -95
  166. package/src/models/visitor.js +67 -67
  167. package/src/models/waitlist.js +45 -45
  168. package/src/models/wallet.js +44 -44
  169. package/src/models/wallet_transactions.js +50 -50
  170. package/src/models/water_invoice.js +351 -351
  171. package/src/models/water_meter_Command_Queue.js +33 -33
  172. package/src/models/water_meter_account.js +86 -86
  173. package/src/models/water_meter_billing.js +58 -58
  174. package/src/models/water_meter_combined_accounts.js +92 -92
  175. package/src/models/water_meter_communication.js +17 -17
  176. package/src/models/water_meter_communication_logs.js +39 -39
  177. package/src/models/water_meter_concentrator.js +70 -70
  178. package/src/models/water_meter_daily_history.js +32 -32
  179. package/src/models/water_meter_high_risk.js +36 -36
  180. package/src/models/water_meter_iot_cards.js +34 -34
  181. package/src/models/water_meter_loan_deduction.js +134 -134
  182. package/src/models/water_meter_manufacturer.js +35 -35
  183. package/src/models/water_meter_monthly_history.js +36 -36
  184. package/src/models/water_meter_negative_amounts.js +44 -44
  185. package/src/models/water_meter_settings.js +290 -290
  186. package/src/models/water_meter_single_day_history.js +34 -34
  187. package/src/models/water_meter_size.js +15 -15
  188. package/src/models/water_meters.js +176 -176
  189. package/src/models/water_meters_delivery.js +76 -76
  190. package/src/models/water_prepaid_credit.js +47 -47
  191. package/src/models/water_prepaid_debit.js +50 -50
  192. package/src/models/whatsapp_conversation.js +23 -23
  193. package/src/models/workorder.js +49 -49
  194. package/src/models/zohoAccount.js +453 -453
  195. package/src/models/zohoIntegration.js +262 -262
  196. package/src/models/zohoItem.js +504 -504
@@ -1,312 +1,312 @@
1
- const mongoose = require("mongoose");
2
-
3
- // Reading entry schema - each individual reading with metadata
4
- const readingEntrySchema = new mongoose.Schema(
5
- {
6
- value: {
7
- type: mongoose.Schema.Types.Mixed, // String, Boolean, or Number
8
- required: true,
9
- },
10
- date: {
11
- type: Date,
12
- required: true,
13
- },
14
- recordedBy: {
15
- type: String,
16
- required: false, // User ID who recorded this reading
17
- },
18
- notes: {
19
- type: String,
20
- required: false, // Optional notes for this reading
21
- },
22
- isActive: {
23
- type: Boolean,
24
- default: true, // Allow soft deletion of readings
25
- },
26
- },
27
- { _id: true, timestamps: true }, // Keep _id for individual readings and timestamps
28
- );
29
-
30
- // Child property schema with historical readings
31
- const childPropertySchema = new mongoose.Schema(
32
- {
33
- name: {
34
- type: String,
35
- required: true, // Child property name (e.g., "fuel_level")
36
- },
37
- currentValue: {
38
- type: mongoose.Schema.Types.Mixed, // Latest value for quick access
39
- required: false,
40
- },
41
- currentDate: {
42
- type: Date,
43
- required: false, // Date of latest reading
44
- },
45
- unit: {
46
- type: String,
47
- required: false, // Unit of measurement (e.g., "%", "°C", "bar")
48
- },
49
- readings: {
50
- type: [readingEntrySchema], // Array of all historical readings
51
- default: [],
52
- },
53
- },
54
- { _id: true },
55
- );
56
-
57
- // Main facilities monitoring schema
58
- const dailyChecklistSchema = new mongoose.Schema(
59
- {
60
- facilityId: {
61
- type: String,
62
- required: true,
63
- },
64
- // Dynamic parent-child structure with historical readings
65
- // Parent_name -> [child_properties with readings]
66
- data: {
67
- type: Map,
68
- of: [childPropertySchema], // Array of child properties for each parent
69
- default: new Map(),
70
- },
71
- },
72
- {
73
- timestamps: true,
74
- },
75
- );
76
-
77
- // Helper methods
78
- dailyChecklistSchema.methods.addReading = function (
79
- parentName,
80
- childName,
81
- value,
82
- date = new Date(),
83
- metadata = {},
84
- ) {
85
- if (!this.data.has(parentName)) {
86
- this.data.set(parentName, []);
87
- }
88
-
89
- const parent = this.data.get(parentName);
90
- let childProperty = parent.find((child) => child.name === childName);
91
-
92
- if (!childProperty) {
93
- // Create new child property
94
- childProperty = {
95
- name: childName,
96
- currentValue: value,
97
- currentDate: date,
98
- unit: metadata.unit || null,
99
- readings: [],
100
- };
101
- parent.push(childProperty);
102
- }
103
-
104
- // Add new reading
105
- const newReading = {
106
- value: value,
107
- date: date,
108
- recordedBy: metadata.recordedBy || null,
109
- notes: metadata.notes || null,
110
- isActive: true,
111
- };
112
-
113
- childProperty.readings.push(newReading);
114
-
115
- // Update current values
116
- childProperty.currentValue = value;
117
- childProperty.currentDate = date;
118
-
119
- // Sort readings by date (newest first)
120
- childProperty.readings.sort((a, b) => new Date(b.date) - new Date(a.date));
121
-
122
- this.markModified("data");
123
- };
124
-
125
- dailyChecklistSchema.methods.getCurrentValue = function (
126
- parentName,
127
- childName,
128
- ) {
129
- const parent = this.data.get(parentName);
130
- if (parent) {
131
- const child = parent.find((c) => c.name === childName);
132
- return child ? child.currentValue : null;
133
- }
134
- return null;
135
- };
136
-
137
- dailyChecklistSchema.methods.getReadingHistory = function (
138
- parentName,
139
- childName,
140
- limit = null,
141
- ) {
142
- const parent = this.data.get(parentName);
143
- if (parent) {
144
- const child = parent.find((c) => c.name === childName);
145
- if (child) {
146
- const activeReadings = child.readings.filter((r) => r.isActive);
147
- return limit ? activeReadings.slice(0, limit) : activeReadings;
148
- }
149
- }
150
- return [];
151
- };
152
-
153
- dailyChecklistSchema.methods.getLatestReading = function (
154
- parentName,
155
- childName,
156
- ) {
157
- const parent = this.data.get(parentName);
158
- if (parent) {
159
- const child = parent.find((c) => c.name === childName);
160
- if (child && child.readings.length > 0) {
161
- return child.readings.find((r) => r.isActive) || null;
162
- }
163
- }
164
- return null;
165
- };
166
-
167
- dailyChecklistSchema.methods.updateReading = function (
168
- parentName,
169
- childName,
170
- readingId,
171
- updates,
172
- ) {
173
- const parent = this.data.get(parentName);
174
- if (parent) {
175
- const child = parent.find((c) => c.name === childName);
176
- if (child) {
177
- const reading = child.readings.id(readingId);
178
- if (reading) {
179
- Object.assign(reading, updates);
180
-
181
- // If this was the latest reading, update current values
182
- const latestReading = child.readings.find((r) => r.isActive);
183
- if (latestReading && latestReading._id.equals(readingId)) {
184
- child.currentValue = reading.value;
185
- child.currentDate = reading.date;
186
- }
187
-
188
- this.markModified("data");
189
- return true;
190
- }
191
- }
192
- }
193
- return false;
194
- };
195
-
196
- dailyChecklistSchema.methods.deleteReading = function (
197
- parentName,
198
- childName,
199
- readingId,
200
- ) {
201
- const parent = this.data.get(parentName);
202
- if (parent) {
203
- const child = parent.find((c) => c.name === childName);
204
- if (child) {
205
- const reading = child.readings.id(readingId);
206
- if (reading) {
207
- reading.isActive = false; // Soft delete
208
-
209
- // Update current values to next active reading
210
- const latestActiveReading = child.readings.find((r) => r.isActive);
211
- if (latestActiveReading) {
212
- child.currentValue = latestActiveReading.value;
213
- child.currentDate = latestActiveReading.date;
214
- } else {
215
- child.currentValue = null;
216
- child.currentDate = null;
217
- }
218
-
219
- this.markModified("data");
220
- return true;
221
- }
222
- }
223
- }
224
- return false;
225
- };
226
-
227
- dailyChecklistSchema.methods.createParent = function (parentName) {
228
- if (!this.data.has(parentName)) {
229
- this.data.set(parentName, []);
230
- this.markModified("data");
231
- }
232
- };
233
-
234
- dailyChecklistSchema.methods.hasParent = function (parentName) {
235
- return this.data.has(parentName);
236
- };
237
-
238
- dailyChecklistSchema.methods.getParentNames = function () {
239
- return Array.from(this.data.keys());
240
- };
241
-
242
- dailyChecklistSchema.methods.getChildNames = function (parentName) {
243
- const parent = this.data.get(parentName);
244
- return parent ? parent.map((child) => child.name) : [];
245
- };
246
-
247
- dailyChecklistSchema.methods.getChildProperty = function (
248
- parentName,
249
- childName,
250
- ) {
251
- const parent = this.data.get(parentName);
252
- if (parent) {
253
- return parent.find((child) => child.name === childName) || null;
254
- }
255
- return null;
256
- };
257
-
258
- // Get readings within a date range
259
- dailyChecklistSchema.methods.getReadingsByDateRange = function (
260
- parentName,
261
- childName,
262
- startDate,
263
- endDate,
264
- ) {
265
- const parent = this.data.get(parentName);
266
- if (parent) {
267
- const child = parent.find((c) => c.name === childName);
268
- if (child) {
269
- return child.readings.filter((reading) => {
270
- const readingDate = new Date(reading.date);
271
- return (
272
- reading.isActive &&
273
- readingDate >= new Date(startDate) &&
274
- readingDate <= new Date(endDate)
275
- );
276
- });
277
- }
278
- }
279
- return [];
280
- };
281
-
282
- // Get statistics for a child property
283
- dailyChecklistSchema.methods.getChildStatistics = function (
284
- parentName,
285
- childName,
286
- ) {
287
- const readings = this.getReadingHistory(parentName, childName);
288
- if (readings.length === 0) return null;
289
-
290
- const numericReadings = readings
291
- .map((r) => r.value)
292
- .filter((v) => typeof v === "number");
293
-
294
- if (numericReadings.length === 0) {
295
- return {
296
- totalReadings: readings.length,
297
- type: "non-numeric",
298
- };
299
- }
300
-
301
- return {
302
- totalReadings: readings.length,
303
- type: "numeric",
304
- min: Math.min(...numericReadings),
305
- max: Math.max(...numericReadings),
306
- average:
307
- numericReadings.reduce((a, b) => a + b, 0) / numericReadings.length,
308
- latest: readings[0].value,
309
- };
310
- };
311
-
312
- module.exports = mongoose.model("DailyChecklist", dailyChecklistSchema);
1
+ const mongoose = require("mongoose");
2
+
3
+ // Reading entry schema - each individual reading with metadata
4
+ const readingEntrySchema = new mongoose.Schema(
5
+ {
6
+ value: {
7
+ type: mongoose.Schema.Types.Mixed, // String, Boolean, or Number
8
+ required: true,
9
+ },
10
+ date: {
11
+ type: Date,
12
+ required: true,
13
+ },
14
+ recordedBy: {
15
+ type: String,
16
+ required: false, // User ID who recorded this reading
17
+ },
18
+ notes: {
19
+ type: String,
20
+ required: false, // Optional notes for this reading
21
+ },
22
+ isActive: {
23
+ type: Boolean,
24
+ default: true, // Allow soft deletion of readings
25
+ },
26
+ },
27
+ { _id: true, timestamps: true }, // Keep _id for individual readings and timestamps
28
+ );
29
+
30
+ // Child property schema with historical readings
31
+ const childPropertySchema = new mongoose.Schema(
32
+ {
33
+ name: {
34
+ type: String,
35
+ required: true, // Child property name (e.g., "fuel_level")
36
+ },
37
+ currentValue: {
38
+ type: mongoose.Schema.Types.Mixed, // Latest value for quick access
39
+ required: false,
40
+ },
41
+ currentDate: {
42
+ type: Date,
43
+ required: false, // Date of latest reading
44
+ },
45
+ unit: {
46
+ type: String,
47
+ required: false, // Unit of measurement (e.g., "%", "°C", "bar")
48
+ },
49
+ readings: {
50
+ type: [readingEntrySchema], // Array of all historical readings
51
+ default: [],
52
+ },
53
+ },
54
+ { _id: true },
55
+ );
56
+
57
+ // Main facilities monitoring schema
58
+ const dailyChecklistSchema = new mongoose.Schema(
59
+ {
60
+ facilityId: {
61
+ type: String,
62
+ required: true,
63
+ },
64
+ // Dynamic parent-child structure with historical readings
65
+ // Parent_name -> [child_properties with readings]
66
+ data: {
67
+ type: Map,
68
+ of: [childPropertySchema], // Array of child properties for each parent
69
+ default: new Map(),
70
+ },
71
+ },
72
+ {
73
+ timestamps: true,
74
+ },
75
+ );
76
+
77
+ // Helper methods
78
+ dailyChecklistSchema.methods.addReading = function (
79
+ parentName,
80
+ childName,
81
+ value,
82
+ date = new Date(),
83
+ metadata = {},
84
+ ) {
85
+ if (!this.data.has(parentName)) {
86
+ this.data.set(parentName, []);
87
+ }
88
+
89
+ const parent = this.data.get(parentName);
90
+ let childProperty = parent.find((child) => child.name === childName);
91
+
92
+ if (!childProperty) {
93
+ // Create new child property
94
+ childProperty = {
95
+ name: childName,
96
+ currentValue: value,
97
+ currentDate: date,
98
+ unit: metadata.unit || null,
99
+ readings: [],
100
+ };
101
+ parent.push(childProperty);
102
+ }
103
+
104
+ // Add new reading
105
+ const newReading = {
106
+ value: value,
107
+ date: date,
108
+ recordedBy: metadata.recordedBy || null,
109
+ notes: metadata.notes || null,
110
+ isActive: true,
111
+ };
112
+
113
+ childProperty.readings.push(newReading);
114
+
115
+ // Update current values
116
+ childProperty.currentValue = value;
117
+ childProperty.currentDate = date;
118
+
119
+ // Sort readings by date (newest first)
120
+ childProperty.readings.sort((a, b) => new Date(b.date) - new Date(a.date));
121
+
122
+ this.markModified("data");
123
+ };
124
+
125
+ dailyChecklistSchema.methods.getCurrentValue = function (
126
+ parentName,
127
+ childName,
128
+ ) {
129
+ const parent = this.data.get(parentName);
130
+ if (parent) {
131
+ const child = parent.find((c) => c.name === childName);
132
+ return child ? child.currentValue : null;
133
+ }
134
+ return null;
135
+ };
136
+
137
+ dailyChecklistSchema.methods.getReadingHistory = function (
138
+ parentName,
139
+ childName,
140
+ limit = null,
141
+ ) {
142
+ const parent = this.data.get(parentName);
143
+ if (parent) {
144
+ const child = parent.find((c) => c.name === childName);
145
+ if (child) {
146
+ const activeReadings = child.readings.filter((r) => r.isActive);
147
+ return limit ? activeReadings.slice(0, limit) : activeReadings;
148
+ }
149
+ }
150
+ return [];
151
+ };
152
+
153
+ dailyChecklistSchema.methods.getLatestReading = function (
154
+ parentName,
155
+ childName,
156
+ ) {
157
+ const parent = this.data.get(parentName);
158
+ if (parent) {
159
+ const child = parent.find((c) => c.name === childName);
160
+ if (child && child.readings.length > 0) {
161
+ return child.readings.find((r) => r.isActive) || null;
162
+ }
163
+ }
164
+ return null;
165
+ };
166
+
167
+ dailyChecklistSchema.methods.updateReading = function (
168
+ parentName,
169
+ childName,
170
+ readingId,
171
+ updates,
172
+ ) {
173
+ const parent = this.data.get(parentName);
174
+ if (parent) {
175
+ const child = parent.find((c) => c.name === childName);
176
+ if (child) {
177
+ const reading = child.readings.id(readingId);
178
+ if (reading) {
179
+ Object.assign(reading, updates);
180
+
181
+ // If this was the latest reading, update current values
182
+ const latestReading = child.readings.find((r) => r.isActive);
183
+ if (latestReading && latestReading._id.equals(readingId)) {
184
+ child.currentValue = reading.value;
185
+ child.currentDate = reading.date;
186
+ }
187
+
188
+ this.markModified("data");
189
+ return true;
190
+ }
191
+ }
192
+ }
193
+ return false;
194
+ };
195
+
196
+ dailyChecklistSchema.methods.deleteReading = function (
197
+ parentName,
198
+ childName,
199
+ readingId,
200
+ ) {
201
+ const parent = this.data.get(parentName);
202
+ if (parent) {
203
+ const child = parent.find((c) => c.name === childName);
204
+ if (child) {
205
+ const reading = child.readings.id(readingId);
206
+ if (reading) {
207
+ reading.isActive = false; // Soft delete
208
+
209
+ // Update current values to next active reading
210
+ const latestActiveReading = child.readings.find((r) => r.isActive);
211
+ if (latestActiveReading) {
212
+ child.currentValue = latestActiveReading.value;
213
+ child.currentDate = latestActiveReading.date;
214
+ } else {
215
+ child.currentValue = null;
216
+ child.currentDate = null;
217
+ }
218
+
219
+ this.markModified("data");
220
+ return true;
221
+ }
222
+ }
223
+ }
224
+ return false;
225
+ };
226
+
227
+ dailyChecklistSchema.methods.createParent = function (parentName) {
228
+ if (!this.data.has(parentName)) {
229
+ this.data.set(parentName, []);
230
+ this.markModified("data");
231
+ }
232
+ };
233
+
234
+ dailyChecklistSchema.methods.hasParent = function (parentName) {
235
+ return this.data.has(parentName);
236
+ };
237
+
238
+ dailyChecklistSchema.methods.getParentNames = function () {
239
+ return Array.from(this.data.keys());
240
+ };
241
+
242
+ dailyChecklistSchema.methods.getChildNames = function (parentName) {
243
+ const parent = this.data.get(parentName);
244
+ return parent ? parent.map((child) => child.name) : [];
245
+ };
246
+
247
+ dailyChecklistSchema.methods.getChildProperty = function (
248
+ parentName,
249
+ childName,
250
+ ) {
251
+ const parent = this.data.get(parentName);
252
+ if (parent) {
253
+ return parent.find((child) => child.name === childName) || null;
254
+ }
255
+ return null;
256
+ };
257
+
258
+ // Get readings within a date range
259
+ dailyChecklistSchema.methods.getReadingsByDateRange = function (
260
+ parentName,
261
+ childName,
262
+ startDate,
263
+ endDate,
264
+ ) {
265
+ const parent = this.data.get(parentName);
266
+ if (parent) {
267
+ const child = parent.find((c) => c.name === childName);
268
+ if (child) {
269
+ return child.readings.filter((reading) => {
270
+ const readingDate = new Date(reading.date);
271
+ return (
272
+ reading.isActive &&
273
+ readingDate >= new Date(startDate) &&
274
+ readingDate <= new Date(endDate)
275
+ );
276
+ });
277
+ }
278
+ }
279
+ return [];
280
+ };
281
+
282
+ // Get statistics for a child property
283
+ dailyChecklistSchema.methods.getChildStatistics = function (
284
+ parentName,
285
+ childName,
286
+ ) {
287
+ const readings = this.getReadingHistory(parentName, childName);
288
+ if (readings.length === 0) return null;
289
+
290
+ const numericReadings = readings
291
+ .map((r) => r.value)
292
+ .filter((v) => typeof v === "number");
293
+
294
+ if (numericReadings.length === 0) {
295
+ return {
296
+ totalReadings: readings.length,
297
+ type: "non-numeric",
298
+ };
299
+ }
300
+
301
+ return {
302
+ totalReadings: readings.length,
303
+ type: "numeric",
304
+ min: Math.min(...numericReadings),
305
+ max: Math.max(...numericReadings),
306
+ average:
307
+ numericReadings.reduce((a, b) => a + b, 0) / numericReadings.length,
308
+ latest: readings[0].value,
309
+ };
310
+ };
311
+
312
+ module.exports = mongoose.model("DailyChecklist", dailyChecklistSchema);
@@ -1,18 +1,18 @@
1
- const mongoose = require("mongoose");
2
-
3
- const defaultPaymentDetailsSchema = new mongoose.Schema({
4
- shortCode: { type: String },
5
- passkey: { type: String },
6
- authorizationKey: {
7
- type: String,
8
- },
9
- module: {
10
- type: String,
11
- enum: ["All", "Water", "Electricity", "Levy","Lease"],
12
- default: "All"
13
- },
14
- });
15
-
16
- const DefaultPaymentDetails = mongoose.model('DefaultPaymentDetails', defaultPaymentDetailsSchema);
17
-
1
+ const mongoose = require("mongoose");
2
+
3
+ const defaultPaymentDetailsSchema = new mongoose.Schema({
4
+ shortCode: { type: String },
5
+ passkey: { type: String },
6
+ authorizationKey: {
7
+ type: String,
8
+ },
9
+ module: {
10
+ type: String,
11
+ enum: ["All", "Water", "Electricity", "Levy","Lease"],
12
+ default: "All"
13
+ },
14
+ });
15
+
16
+ const DefaultPaymentDetails = mongoose.model('DefaultPaymentDetails', defaultPaymentDetailsSchema);
17
+
18
18
  module.exports = DefaultPaymentDetails;