payservedb 8.4.5 → 8.4.7
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.
- package/index.js +2 -0
- package/package.json +1 -1
- package/src/models/customer.js +189 -189
- package/src/models/facility.js +44 -36
- package/src/models/invoice.js +192 -100
- package/src/models/invoicing_schedule.js +6 -1
- package/src/models/zohoAccount.js +453 -0
- package/src/models/zohoItem.js +504 -0
package/src/models/invoice.js
CHANGED
|
@@ -9,7 +9,7 @@ const invoiceSchema = new mongoose.Schema(
|
|
|
9
9
|
},
|
|
10
10
|
accountNumber: {
|
|
11
11
|
type: String,
|
|
12
|
-
required: true
|
|
12
|
+
required: true,
|
|
13
13
|
},
|
|
14
14
|
client: {
|
|
15
15
|
clientId: {
|
|
@@ -19,12 +19,12 @@ const invoiceSchema = new mongoose.Schema(
|
|
|
19
19
|
},
|
|
20
20
|
firstName: {
|
|
21
21
|
type: String,
|
|
22
|
-
required: true
|
|
22
|
+
required: true,
|
|
23
23
|
},
|
|
24
24
|
lastName: {
|
|
25
25
|
type: String,
|
|
26
|
-
required: true
|
|
27
|
-
}
|
|
26
|
+
required: true,
|
|
27
|
+
},
|
|
28
28
|
},
|
|
29
29
|
facility: {
|
|
30
30
|
id: {
|
|
@@ -34,8 +34,8 @@ const invoiceSchema = new mongoose.Schema(
|
|
|
34
34
|
},
|
|
35
35
|
name: {
|
|
36
36
|
type: String,
|
|
37
|
-
required: true
|
|
38
|
-
}
|
|
37
|
+
required: true,
|
|
38
|
+
},
|
|
39
39
|
},
|
|
40
40
|
unit: {
|
|
41
41
|
id: { type: mongoose.Schema.Types.ObjectId, ref: "Unit", required: true },
|
|
@@ -45,19 +45,19 @@ const invoiceSchema = new mongoose.Schema(
|
|
|
45
45
|
id: {
|
|
46
46
|
type: mongoose.Schema.Types.ObjectId,
|
|
47
47
|
ref: "Currency",
|
|
48
|
-
required: true
|
|
48
|
+
required: true,
|
|
49
49
|
},
|
|
50
50
|
name: {
|
|
51
51
|
type: String,
|
|
52
|
-
required: true
|
|
52
|
+
required: true,
|
|
53
53
|
},
|
|
54
54
|
code: {
|
|
55
55
|
type: String,
|
|
56
56
|
required: true,
|
|
57
57
|
uppercase: true,
|
|
58
58
|
minlength: 3,
|
|
59
|
-
maxlength: 3
|
|
60
|
-
}
|
|
59
|
+
maxlength: 3,
|
|
60
|
+
},
|
|
61
61
|
},
|
|
62
62
|
items: [
|
|
63
63
|
{
|
|
@@ -88,7 +88,7 @@ const invoiceSchema = new mongoose.Schema(
|
|
|
88
88
|
type: Number,
|
|
89
89
|
default: 0,
|
|
90
90
|
min: 0,
|
|
91
|
-
deprecated: true
|
|
91
|
+
deprecated: true,
|
|
92
92
|
},
|
|
93
93
|
issueDate: {
|
|
94
94
|
type: Date,
|
|
@@ -101,7 +101,15 @@ const invoiceSchema = new mongoose.Schema(
|
|
|
101
101
|
status: {
|
|
102
102
|
type: String,
|
|
103
103
|
required: true,
|
|
104
|
-
enum: [
|
|
104
|
+
enum: [
|
|
105
|
+
"Unpaid",
|
|
106
|
+
"Pending",
|
|
107
|
+
"Paid",
|
|
108
|
+
"Overdue",
|
|
109
|
+
"Cancelled",
|
|
110
|
+
"Partially Paid",
|
|
111
|
+
"Void",
|
|
112
|
+
],
|
|
105
113
|
},
|
|
106
114
|
penalty: {
|
|
107
115
|
type: Number,
|
|
@@ -123,40 +131,40 @@ const invoiceSchema = new mongoose.Schema(
|
|
|
123
131
|
yearMonth: {
|
|
124
132
|
type: String,
|
|
125
133
|
match: /^\d{4}-\d{2}$/, // Validates format like "2025-08"
|
|
126
|
-
index: true
|
|
134
|
+
index: true,
|
|
127
135
|
},
|
|
128
136
|
// NEW FIELD 2: Simple notification tracking
|
|
129
137
|
notificationsSent: {
|
|
130
138
|
sms: {
|
|
131
139
|
type: Boolean,
|
|
132
|
-
default: false
|
|
140
|
+
default: false,
|
|
133
141
|
},
|
|
134
142
|
email: {
|
|
135
143
|
type: Boolean,
|
|
136
|
-
default: false
|
|
144
|
+
default: false,
|
|
137
145
|
},
|
|
138
146
|
attempts: {
|
|
139
147
|
type: Number,
|
|
140
|
-
default: 0
|
|
141
|
-
}
|
|
148
|
+
default: 0,
|
|
149
|
+
},
|
|
142
150
|
},
|
|
143
151
|
voidMetadata: {
|
|
144
152
|
voidedBy: {
|
|
145
153
|
userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
|
|
146
154
|
name: { type: String },
|
|
147
|
-
role: { type: String }
|
|
155
|
+
role: { type: String },
|
|
148
156
|
},
|
|
149
157
|
voidedAt: { type: Date },
|
|
150
|
-
reason: { type: String }
|
|
158
|
+
reason: { type: String },
|
|
151
159
|
},
|
|
152
160
|
cancelMetadata: {
|
|
153
161
|
cancelledBy: {
|
|
154
162
|
userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
|
|
155
163
|
name: { type: String },
|
|
156
|
-
role: { type: String }
|
|
164
|
+
role: { type: String },
|
|
157
165
|
},
|
|
158
166
|
cancelledAt: { type: Date },
|
|
159
|
-
reason: { type: String }
|
|
167
|
+
reason: { type: String },
|
|
160
168
|
},
|
|
161
169
|
lastReminderSent: Date,
|
|
162
170
|
reminderHistory: [
|
|
@@ -166,29 +174,42 @@ const invoiceSchema = new mongoose.Schema(
|
|
|
166
174
|
notificationTypes: [String],
|
|
167
175
|
},
|
|
168
176
|
],
|
|
169
|
-
reconciliationHistory: [
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
type:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
177
|
+
reconciliationHistory: [
|
|
178
|
+
{
|
|
179
|
+
date: { type: Date, required: true },
|
|
180
|
+
amount: { type: Number, required: true },
|
|
181
|
+
type: {
|
|
182
|
+
type: String,
|
|
183
|
+
enum: [
|
|
184
|
+
"payment",
|
|
185
|
+
"cash",
|
|
186
|
+
"cheque",
|
|
187
|
+
"bank-transfer",
|
|
188
|
+
"mpesa-transfer",
|
|
189
|
+
"overpay-transfer",
|
|
190
|
+
"balance-deduction",
|
|
191
|
+
"overpay-received",
|
|
192
|
+
"credit-forward",
|
|
193
|
+
"debit-forward",
|
|
194
|
+
],
|
|
195
|
+
required: true,
|
|
196
|
+
},
|
|
197
|
+
sourceInvoice: String,
|
|
198
|
+
destinationInvoice: String,
|
|
199
|
+
paymentReference: String,
|
|
200
|
+
paymentCompletion: String,
|
|
201
|
+
remainingBalance: Number,
|
|
202
|
+
notes: String,
|
|
203
|
+
exchangeRate: {
|
|
204
|
+
type: Number,
|
|
205
|
+
default: 1, // For cross-currency reconciliations
|
|
206
|
+
},
|
|
207
|
+
originalCurrency: {
|
|
208
|
+
code: String, // Original currency code if different from invoice currency
|
|
209
|
+
amount: Number, // Amount in original currency
|
|
210
|
+
},
|
|
186
211
|
},
|
|
187
|
-
|
|
188
|
-
code: String, // Original currency code if different from invoice currency
|
|
189
|
-
amount: Number // Amount in original currency
|
|
190
|
-
}
|
|
191
|
-
}],
|
|
212
|
+
],
|
|
192
213
|
paymentDetails: {
|
|
193
214
|
paymentStatus: { type: String, required: true },
|
|
194
215
|
paymentMethod: { type: String },
|
|
@@ -202,17 +223,60 @@ const invoiceSchema = new mongoose.Schema(
|
|
|
202
223
|
openedBy: {
|
|
203
224
|
facilityId: { type: mongoose.Schema.Types.ObjectId, ref: "Facility" },
|
|
204
225
|
userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
|
|
205
|
-
userRole: { type: String }
|
|
226
|
+
userRole: { type: String },
|
|
206
227
|
},
|
|
207
|
-
viewHistory: [
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
228
|
+
viewHistory: [
|
|
229
|
+
{
|
|
230
|
+
viewedAt: { type: Date, required: true },
|
|
231
|
+
facilityId: { type: mongoose.Schema.Types.ObjectId, ref: "Facility" },
|
|
232
|
+
userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
|
|
233
|
+
},
|
|
234
|
+
],
|
|
212
235
|
},
|
|
213
236
|
invoiceUrl: {
|
|
214
237
|
type: String,
|
|
215
|
-
default: null
|
|
238
|
+
default: null,
|
|
239
|
+
},
|
|
240
|
+
// eTims tax integration fields
|
|
241
|
+
ticketUrl: {
|
|
242
|
+
type: String,
|
|
243
|
+
default: null,
|
|
244
|
+
description: "QR code URL from eTims/KRA for tax invoice verification",
|
|
245
|
+
},
|
|
246
|
+
txsync: {
|
|
247
|
+
status: {
|
|
248
|
+
type: String,
|
|
249
|
+
enum: ["pending", "synced", "failed", "not-applicable"],
|
|
250
|
+
default: "not-applicable",
|
|
251
|
+
},
|
|
252
|
+
syncedAt: {
|
|
253
|
+
type: Date,
|
|
254
|
+
default: null,
|
|
255
|
+
},
|
|
256
|
+
etimsInvoiceNo: {
|
|
257
|
+
type: String,
|
|
258
|
+
default: null,
|
|
259
|
+
},
|
|
260
|
+
sdcId: {
|
|
261
|
+
type: String,
|
|
262
|
+
default: null,
|
|
263
|
+
},
|
|
264
|
+
receiptNo: {
|
|
265
|
+
type: String,
|
|
266
|
+
default: null,
|
|
267
|
+
},
|
|
268
|
+
errorMessage: {
|
|
269
|
+
type: String,
|
|
270
|
+
default: null,
|
|
271
|
+
},
|
|
272
|
+
attempts: {
|
|
273
|
+
type: Number,
|
|
274
|
+
default: 0,
|
|
275
|
+
},
|
|
276
|
+
lastAttemptAt: {
|
|
277
|
+
type: Date,
|
|
278
|
+
default: null,
|
|
279
|
+
},
|
|
216
280
|
},
|
|
217
281
|
// New fields for double entry accounts
|
|
218
282
|
invoiceDoubleEntryAccount: {
|
|
@@ -229,42 +293,45 @@ const invoiceSchema = new mongoose.Schema(
|
|
|
229
293
|
accountdebitedData: {
|
|
230
294
|
amount: { type: Number },
|
|
231
295
|
description: { type: String },
|
|
232
|
-
isActive: { type: Boolean, default: true }
|
|
296
|
+
isActive: { type: Boolean, default: true },
|
|
233
297
|
},
|
|
234
298
|
accountcreditedData: {
|
|
235
299
|
amount: { type: Number },
|
|
236
300
|
description: { type: String },
|
|
237
|
-
isActive: { type: Boolean, default: true }
|
|
238
|
-
}
|
|
301
|
+
isActive: { type: Boolean, default: true },
|
|
302
|
+
},
|
|
239
303
|
},
|
|
240
304
|
{
|
|
241
305
|
timestamps: true,
|
|
242
|
-
}
|
|
306
|
+
},
|
|
243
307
|
);
|
|
244
308
|
|
|
245
309
|
// Add indexes for frequently queried fields
|
|
246
310
|
invoiceSchema.index({ accountNumber: 1 });
|
|
247
311
|
invoiceSchema.index({ status: 1 });
|
|
248
|
-
invoiceSchema.index({
|
|
249
|
-
invoiceSchema.index({
|
|
312
|
+
invoiceSchema.index({ "client.clientId": 1, status: 1 });
|
|
313
|
+
invoiceSchema.index({ "reconciliationHistory.paymentReference": 1 });
|
|
250
314
|
invoiceSchema.index({ issueDate: -1 });
|
|
251
|
-
invoiceSchema.index({
|
|
252
|
-
invoiceSchema.index({
|
|
253
|
-
invoiceSchema.index({
|
|
254
|
-
invoiceSchema.index({
|
|
255
|
-
invoiceSchema.index({
|
|
256
|
-
invoiceSchema.index({
|
|
315
|
+
invoiceSchema.index({ "currency.code": 1 }); // Add index for currency code
|
|
316
|
+
invoiceSchema.index({ "currency.id": 1 }); // Add index for currency ID
|
|
317
|
+
invoiceSchema.index({ "currency.code": 1, "client.clientId": 1, status: 1 }); // Compound index for currency-based queries
|
|
318
|
+
invoiceSchema.index({ "client.clientId": 1, balanceBroughtForward: 1 }); // Add index for finding invoices with credit balances
|
|
319
|
+
invoiceSchema.index({ "viewStatus.isOpened": 1 }); // Add index for view status
|
|
320
|
+
invoiceSchema.index({ "viewStatus.openedBy.facilityId": 1 }); // Add index for facility view tracking
|
|
257
321
|
// Add index for double entry accounts
|
|
258
322
|
invoiceSchema.index({ invoiceDoubleEntryAccount: 1 });
|
|
259
323
|
invoiceSchema.index({ paymentDoubleEntryAccount: 1 });
|
|
260
324
|
// NEW INDEXES for new fields
|
|
261
325
|
invoiceSchema.index({ yearMonth: 1 }); // For filtering by year-month
|
|
262
326
|
invoiceSchema.index({ yearMonth: 1, status: 1 }); // Combined index for monthly reports
|
|
263
|
-
invoiceSchema.index({
|
|
264
|
-
invoiceSchema.index({
|
|
327
|
+
invoiceSchema.index({ "notificationsSent.sms": 1 }); // For finding SMS sent/not sent
|
|
328
|
+
invoiceSchema.index({ "notificationsSent.email": 1 }); // For finding email sent/not sent
|
|
329
|
+
// eTims tax sync indexes
|
|
330
|
+
invoiceSchema.index({ "txsync.status": 1 }); // For finding invoices by sync status
|
|
331
|
+
invoiceSchema.index({ "txsync.etimsInvoiceNo": 1 }); // For looking up by eTims invoice number
|
|
265
332
|
|
|
266
333
|
// Add virtual field for calculating balance
|
|
267
|
-
invoiceSchema.virtual(
|
|
334
|
+
invoiceSchema.virtual("calculatedBalance").get(function () {
|
|
268
335
|
const baseBalance = this.totalAmount - (this.amountPaid || 0);
|
|
269
336
|
|
|
270
337
|
// Add positive balanceBroughtForward (customer owes money)
|
|
@@ -277,33 +344,42 @@ invoiceSchema.virtual('calculatedBalance').get(function () {
|
|
|
277
344
|
});
|
|
278
345
|
|
|
279
346
|
// Add virtual field for credit balance
|
|
280
|
-
invoiceSchema.virtual(
|
|
281
|
-
return this.balanceBroughtForward < 0
|
|
347
|
+
invoiceSchema.virtual("creditBalance").get(function () {
|
|
348
|
+
return this.balanceBroughtForward < 0
|
|
349
|
+
? Math.abs(this.balanceBroughtForward)
|
|
350
|
+
: 0;
|
|
282
351
|
});
|
|
283
352
|
|
|
284
353
|
// Getter for compatible overpay field
|
|
285
|
-
invoiceSchema.virtual(
|
|
286
|
-
return this.balanceBroughtForward < 0
|
|
354
|
+
invoiceSchema.virtual("effectiveOverpay").get(function () {
|
|
355
|
+
return this.balanceBroughtForward < 0
|
|
356
|
+
? Math.abs(this.balanceBroughtForward)
|
|
357
|
+
: 0;
|
|
287
358
|
});
|
|
288
359
|
|
|
289
360
|
// Add virtual populate for invoice double entry account
|
|
290
|
-
invoiceSchema.virtual(
|
|
291
|
-
ref:
|
|
292
|
-
localField:
|
|
293
|
-
foreignField:
|
|
294
|
-
justOne: true
|
|
361
|
+
invoiceSchema.virtual("invoiceDoubleEntry", {
|
|
362
|
+
ref: "GLAccountDoubleEntries",
|
|
363
|
+
localField: "invoiceDoubleEntryAccount",
|
|
364
|
+
foreignField: "_id",
|
|
365
|
+
justOne: true,
|
|
295
366
|
});
|
|
296
367
|
|
|
297
368
|
// Add virtual populate for payment double entry account
|
|
298
|
-
invoiceSchema.virtual(
|
|
299
|
-
ref:
|
|
300
|
-
localField:
|
|
301
|
-
foreignField:
|
|
302
|
-
justOne: true
|
|
369
|
+
invoiceSchema.virtual("paymentDoubleEntry", {
|
|
370
|
+
ref: "GLAccountDoubleEntries",
|
|
371
|
+
localField: "paymentDoubleEntryAccount",
|
|
372
|
+
foreignField: "_id",
|
|
373
|
+
justOne: true,
|
|
303
374
|
});
|
|
304
375
|
|
|
305
376
|
// Add method for currency conversion if needed
|
|
306
|
-
invoiceSchema.methods.convertAmount = function (
|
|
377
|
+
invoiceSchema.methods.convertAmount = function (
|
|
378
|
+
amount,
|
|
379
|
+
fromCurrency,
|
|
380
|
+
toCurrency,
|
|
381
|
+
exchangeRate,
|
|
382
|
+
) {
|
|
307
383
|
if (fromCurrency === toCurrency) {
|
|
308
384
|
return amount;
|
|
309
385
|
}
|
|
@@ -312,14 +388,14 @@ invoiceSchema.methods.convertAmount = function (amount, fromCurrency, toCurrency
|
|
|
312
388
|
|
|
313
389
|
// Add static method to find invoices by currency
|
|
314
390
|
invoiceSchema.statics.findByCurrency = function (currencyCode) {
|
|
315
|
-
return this.find({
|
|
391
|
+
return this.find({ "currency.code": currencyCode.toUpperCase() });
|
|
316
392
|
};
|
|
317
393
|
|
|
318
394
|
// Add static method to find invoices with credit balance
|
|
319
395
|
invoiceSchema.statics.findWithCreditBalance = function (clientId) {
|
|
320
396
|
return this.find({
|
|
321
|
-
|
|
322
|
-
|
|
397
|
+
"client.clientId": clientId,
|
|
398
|
+
balanceBroughtForward: { $lt: 0 },
|
|
323
399
|
}).sort({ updatedAt: -1 });
|
|
324
400
|
};
|
|
325
401
|
|
|
@@ -329,20 +405,20 @@ invoiceSchema.statics.calculateTotalsByCurrency = function (query = {}) {
|
|
|
329
405
|
{ $match: query },
|
|
330
406
|
{
|
|
331
407
|
$group: {
|
|
332
|
-
_id:
|
|
333
|
-
totalAmount: { $sum:
|
|
334
|
-
totalPaid: { $sum:
|
|
335
|
-
count: { $sum: 1 }
|
|
336
|
-
}
|
|
337
|
-
}
|
|
408
|
+
_id: "$currency.code",
|
|
409
|
+
totalAmount: { $sum: "$totalAmount" },
|
|
410
|
+
totalPaid: { $sum: "$amountPaid" },
|
|
411
|
+
count: { $sum: 1 },
|
|
412
|
+
},
|
|
413
|
+
},
|
|
338
414
|
]);
|
|
339
415
|
};
|
|
340
416
|
|
|
341
417
|
// New static method to find all unviewed invoices
|
|
342
418
|
invoiceSchema.statics.findUnviewedInvoices = function (facilityId) {
|
|
343
419
|
return this.find({
|
|
344
|
-
|
|
345
|
-
|
|
420
|
+
"facility.id": facilityId,
|
|
421
|
+
"viewStatus.isOpened": false,
|
|
346
422
|
});
|
|
347
423
|
};
|
|
348
424
|
|
|
@@ -355,17 +431,33 @@ invoiceSchema.statics.findByYearMonth = function (yearMonth) {
|
|
|
355
431
|
// Find invoices where notifications haven't been sent
|
|
356
432
|
invoiceSchema.statics.findPendingNotifications = function (facilityId) {
|
|
357
433
|
return this.find({
|
|
358
|
-
|
|
359
|
-
status: { $in: [
|
|
434
|
+
"facility.id": facilityId,
|
|
435
|
+
status: { $in: ["Unpaid", "Overdue"] },
|
|
360
436
|
$or: [
|
|
361
|
-
{
|
|
362
|
-
{
|
|
363
|
-
]
|
|
437
|
+
{ "notificationsSent.sms": false },
|
|
438
|
+
{ "notificationsSent.email": false },
|
|
439
|
+
],
|
|
440
|
+
});
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
// Find invoices pending eTims sync
|
|
444
|
+
invoiceSchema.statics.findPendingTaxSync = function (facilityId) {
|
|
445
|
+
return this.find({
|
|
446
|
+
"facility.id": facilityId,
|
|
447
|
+
"txsync.status": "pending",
|
|
448
|
+
});
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
// Find invoices with failed eTims sync
|
|
452
|
+
invoiceSchema.statics.findFailedTaxSync = function (facilityId) {
|
|
453
|
+
return this.find({
|
|
454
|
+
"facility.id": facilityId,
|
|
455
|
+
"txsync.status": "failed",
|
|
364
456
|
});
|
|
365
457
|
};
|
|
366
458
|
|
|
367
459
|
// Pre-save middleware to ensure overpay and balanceBroughtForward stay in sync during transition
|
|
368
|
-
invoiceSchema.pre(
|
|
460
|
+
invoiceSchema.pre("save", function (next) {
|
|
369
461
|
// If balanceBroughtForward is negative (credit), sync with overpay for backwards compatibility
|
|
370
462
|
if (this.balanceBroughtForward < 0) {
|
|
371
463
|
this.overpay = Math.abs(this.balanceBroughtForward);
|
|
@@ -376,13 +468,13 @@ invoiceSchema.pre('save', function (next) {
|
|
|
376
468
|
// NEW: Auto-generate yearMonth from issueDate if not provided
|
|
377
469
|
if (!this.yearMonth && this.issueDate) {
|
|
378
470
|
const year = this.issueDate.getFullYear();
|
|
379
|
-
const month = String(this.issueDate.getMonth() + 1).padStart(2,
|
|
471
|
+
const month = String(this.issueDate.getMonth() + 1).padStart(2, "0");
|
|
380
472
|
this.yearMonth = `${year}-${month}`;
|
|
381
473
|
}
|
|
382
474
|
|
|
383
475
|
next();
|
|
384
476
|
});
|
|
385
477
|
|
|
386
|
-
const Invoice = mongoose.model(
|
|
478
|
+
const Invoice = mongoose.model("Invoice", invoiceSchema);
|
|
387
479
|
|
|
388
|
-
module.exports = Invoice;
|
|
480
|
+
module.exports = Invoice;
|
|
@@ -16,6 +16,11 @@ const InvoicingScheduleSchema = new mongoose.Schema({
|
|
|
16
16
|
trim: true,
|
|
17
17
|
index: true
|
|
18
18
|
},
|
|
19
|
+
isAutomatic: {
|
|
20
|
+
type: Boolean,
|
|
21
|
+
required: true,
|
|
22
|
+
default: true
|
|
23
|
+
},
|
|
19
24
|
createdAt: {
|
|
20
25
|
type: Date,
|
|
21
26
|
default: Date.now
|
|
@@ -33,4 +38,4 @@ InvoicingScheduleSchema.pre('save', function(next) {
|
|
|
33
38
|
|
|
34
39
|
const InvoicingSchedule = mongoose.model('InvoicingSchedule', InvoicingScheduleSchema);
|
|
35
40
|
|
|
36
|
-
module.exports = InvoicingSchedule;
|
|
41
|
+
module.exports = InvoicingSchedule;
|