payservedb 8.0.1 → 8.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payservedb",
3
- "version": "8.0.1",
3
+ "version": "8.0.3",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -120,6 +120,27 @@ const invoiceSchema = new mongoose.Schema(
120
120
  type: Number,
121
121
  default: 0,
122
122
  },
123
+ // NEW FIELD 1: Year-Month for easy filtering
124
+ yearMonth: {
125
+ type: String,
126
+ match: /^\d{4}-\d{2}$/, // Validates format like "2025-08"
127
+ index: true
128
+ },
129
+ // NEW FIELD 2: Simple notification tracking
130
+ notificationsSent: {
131
+ sms: {
132
+ type: Boolean,
133
+ default: false
134
+ },
135
+ email: {
136
+ type: Boolean,
137
+ default: false
138
+ },
139
+ attempts: {
140
+ type: Number,
141
+ default: 0
142
+ }
143
+ },
123
144
  voidMetadata: {
124
145
  voidedBy: {
125
146
  userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
@@ -237,6 +258,11 @@ invoiceSchema.index({ 'viewStatus.openedBy.facilityId': 1 }); // Add index for f
237
258
  // Add index for double entry accounts
238
259
  invoiceSchema.index({ invoiceDoubleEntryAccount: 1 });
239
260
  invoiceSchema.index({ paymentDoubleEntryAccount: 1 });
261
+ // NEW INDEXES for new fields
262
+ invoiceSchema.index({ yearMonth: 1 }); // For filtering by year-month
263
+ invoiceSchema.index({ yearMonth: 1, status: 1 }); // Combined index for monthly reports
264
+ invoiceSchema.index({ 'notificationsSent.sms': 1 }); // For finding SMS sent/not sent
265
+ invoiceSchema.index({ 'notificationsSent.email': 1 }); // For finding email sent/not sent
240
266
 
241
267
  // Add virtual field for calculating balance
242
268
  invoiceSchema.virtual('calculatedBalance').get(function () {
@@ -321,6 +347,24 @@ invoiceSchema.statics.findUnviewedInvoices = function (facilityId) {
321
347
  });
322
348
  };
323
349
 
350
+ // NEW STATIC METHODS for new fields
351
+ // Find invoices by year-month
352
+ invoiceSchema.statics.findByYearMonth = function (yearMonth) {
353
+ return this.find({ yearMonth: yearMonth });
354
+ };
355
+
356
+ // Find invoices where notifications haven't been sent
357
+ invoiceSchema.statics.findPendingNotifications = function (facilityId) {
358
+ return this.find({
359
+ 'facility.id': facilityId,
360
+ status: { $in: ['Unpaid', 'Overdue'] },
361
+ $or: [
362
+ { 'notificationsSent.sms': false },
363
+ { 'notificationsSent.email': false }
364
+ ]
365
+ });
366
+ };
367
+
324
368
  // Pre-save middleware to ensure overpay and balanceBroughtForward stay in sync during transition
325
369
  invoiceSchema.pre('save', function (next) {
326
370
  // If balanceBroughtForward is negative (credit), sync with overpay for backwards compatibility
@@ -329,6 +373,14 @@ invoiceSchema.pre('save', function (next) {
329
373
  } else {
330
374
  this.overpay = 0; // No overpay if there's no negative balance
331
375
  }
376
+
377
+ // NEW: Auto-generate yearMonth from issueDate if not provided
378
+ if (!this.yearMonth && this.issueDate) {
379
+ const year = this.issueDate.getFullYear();
380
+ const month = String(this.issueDate.getMonth() + 1).padStart(2, '0');
381
+ this.yearMonth = `${year}-${month}`;
382
+ }
383
+
332
384
  next();
333
385
  });
334
386