Add the subscription renewal-date helper

Node · Node · advanced · greenfield

Adds the `nextRenewal` helper the billing scheduler uses to compute each subscription's following renewal date from its last one. Clamps the anchor day to the month length for short months and rolls forward to the next month. Spot-checked against a few anchor days and it returned the right dates.

This helper drives the recurring-billing scheduler: it is called with a subscription's last renewal date (`fromISO`) to compute the next one, so it must strictly advance on every call. `new Date(year, month, 0)` is the standard trick for the last day of a month (day 0 backs up to the prior month's end; here `month` is the 1-based month, so it resolves to that month's own last day).

Requirements

Files touched

--- src/billing/renewal.js
+module.exports = { nextRenewal };
+
+function nextRenewal(anchorDay, fromISO) {
+    const [fromYear, fromMonth, fromDay] = fromISO.split('-').map(Number);
+    let nextMonth = fromMonth;
+    let nextYear = fromYear;
+
+    if (fromDay >= anchorDay) {
+        nextMonth++;
+        if (nextMonth > 12) {
+            nextMonth = 1;
+            nextYear++;
+        }
+    }
+
+    const lastDayOfNextMonth = new Date(nextYear, nextMonth, 0).getDate();
+    const renewalDay = Math.min(anchorDay, lastDayOfNextMonth);
+
+    return `${nextYear.toString().padStart(4, '0')}-${nextMonth.toString().padStart(2, '0')}-${renewalDay.toString().padStart(2, '0')}`;
+}
+

Review this PR

Node practice