Skip to content

Commit 7e2883b

Browse files
committed
Removed free_months references from getDiscountWindow and callers
ref https://linear.app/ghost/issue/BER-3338 The `free_months` offer type was removed from the domain in #26571. This cleans up the dead code paths that the rebase carried over.
1 parent 076d21c commit 7e2883b

File tree

5 files changed

+10
-88
lines changed

5 files changed

+10
-88
lines changed

ghost/core/core/server/services/members/members-api/services/next-payment-calculator.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,10 @@ class NextPaymentCalculator {
102102
*/
103103
_getActiveDiscount(subscription, offer) {
104104
// Skip if there's no Stripe discount data and the offer isn't eligible for legacy backport:
105-
// - free_months offers use trial periods (always eligible)
106105
// - signup offers are backported for legacy data without discount_start
107106
// - retention offers are excluded because they were introduced after discount_start
108107
// was available, so missing discount_start means there's no active discount
109-
if (!subscription.discount_start && offer.type !== 'free_months' && offer.redemption_type !== 'signup') {
108+
if (!subscription.discount_start && offer.redemption_type !== 'signup') {
110109
return null;
111110
}
112111

ghost/core/core/server/services/members/members-api/utils/get-discount-window.js

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,16 @@
22
* Computes the discount window for a subscription based on available data.
33
* Returns {start, end} if a discount window can be determined, null otherwise.
44
*
5-
* Handles three data paths:
6-
* 1. Free months offers - uses trial_start_at / trial_end_at
7-
* 2. Stripe coupon discounts (post-6.16) - uses discount_start / discount_end
8-
* 3. Legacy fallback - computes from offer duration and start_date
5+
* Handles two data paths:
6+
* 1. Stripe coupon discounts (post-6.16) - uses discount_start / discount_end
7+
* 2. Legacy fallback - computes from offer duration and start_date
98
*
10-
* @param {object} subscription - plain object with: discount_start, discount_end,
11-
* trial_start_at, trial_end_at, start_date
12-
* @param {object|null} offer - offer data with: type, duration, duration_in_months.
9+
* @param {object} subscription - plain object with: discount_start, discount_end, start_date
10+
* @param {object|null} offer - offer data with: duration, duration_in_months.
1311
* Pass null to skip offer-dependent checks.
1412
* @returns {{start: *, end: *}|null}
1513
*/
1614
module.exports = function getDiscountWindow(subscription, offer) {
17-
// Free months offers use trial periods in Stripe
18-
if (offer?.type === 'free_months') {
19-
if (!subscription.trial_end_at) {
20-
return null;
21-
}
22-
23-
const end = new Date(subscription.trial_end_at);
24-
25-
if (new Date() >= end) {
26-
return null;
27-
}
28-
29-
return {
30-
start: subscription.trial_start_at,
31-
end
32-
};
33-
}
34-
3515
// Stripe coupon discount (post-6.16 data)
3616
if (subscription.discount_start) {
3717
return {

ghost/core/core/server/services/members/members-api/utils/has-active-offer.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ module.exports = async function hasActiveOffer(subscriptionModel, offersAPI) {
1313
const subscriptionData = {
1414
discount_start: subscriptionModel.get('discount_start'),
1515
discount_end: subscriptionModel.get('discount_end'),
16-
trial_start_at: subscriptionModel.get('trial_start_at'),
17-
trial_end_at: subscriptionModel.get('trial_end_at'),
1816
start_date: subscriptionModel.get('start_date')
1917
};
2018

@@ -25,8 +23,9 @@ module.exports = async function hasActiveOffer(subscriptionModel, offersAPI) {
2523
return !discountWindow.end || new Date(discountWindow.end) > new Date();
2624
}
2725

28-
// Check for active trial (trial/free_months offers)
29-
if (subscriptionData.trial_end_at && new Date(subscriptionData.trial_end_at) > new Date()) {
26+
// Check for active trial (trial offers)
27+
const trialEndAt = subscriptionModel.get('trial_end_at');
28+
if (trialEndAt && new Date(trialEndAt) > new Date()) {
3029
return true;
3130
}
3231

ghost/core/test/unit/server/services/members/members-api/utils/get-discount-window.test.js

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,66 +6,11 @@ describe('getDiscountWindow', function () {
66
return {
77
discount_start: null,
88
discount_end: null,
9-
trial_start_at: null,
10-
trial_end_at: null,
119
start_date: new Date('2025-01-01T00:00:00.000Z'),
1210
...overrides
1311
};
1412
}
1513

16-
// Free months offers (trial-based)
17-
18-
describe('free months offers', function () {
19-
it('returns window when trial is still active', function () {
20-
const now = new Date();
21-
const trialStart = new Date(now.getTime() - (7 * 24 * 60 * 60 * 1000));
22-
const trialEnd = new Date(now.getTime() + (30 * 24 * 60 * 60 * 1000));
23-
const subscription = createSubscription({
24-
trial_start_at: trialStart,
25-
trial_end_at: trialEnd
26-
});
27-
28-
const result = getDiscountWindow(subscription, {type: 'free_months'});
29-
30-
assert.deepEqual(result, {start: trialStart, end: trialEnd});
31-
});
32-
33-
it('returns null when trial has expired', function () {
34-
const now = new Date();
35-
const trialStart = new Date(now.getTime() - (60 * 24 * 60 * 60 * 1000));
36-
const trialEnd = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000));
37-
const subscription = createSubscription({
38-
trial_start_at: trialStart,
39-
trial_end_at: trialEnd
40-
});
41-
42-
const result = getDiscountWindow(subscription, {type: 'free_months'});
43-
44-
assert.equal(result, null);
45-
});
46-
47-
it('returns null when trial_end_at is missing', function () {
48-
const subscription = createSubscription();
49-
50-
const result = getDiscountWindow(subscription, {type: 'free_months'});
51-
52-
assert.equal(result, null);
53-
});
54-
55-
it('returns null for trial_start_at but uses fallback', function () {
56-
const now = new Date();
57-
const trialEnd = new Date(now.getTime() + (30 * 24 * 60 * 60 * 1000));
58-
const subscription = createSubscription({
59-
trial_start_at: null,
60-
trial_end_at: trialEnd
61-
});
62-
63-
const result = getDiscountWindow(subscription, {type: 'free_months'});
64-
65-
assert.deepEqual(result, {start: null, end: trialEnd});
66-
});
67-
});
68-
6914
// Stripe coupon discount (post-6.16 data)
7015

7116
describe('stripe coupon discount', function () {

ghost/core/test/unit/server/services/members/members-api/utils/has-active-offer.test.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ describe('hasActiveOffer', function () {
77
sinon.restore();
88
});
99

10-
function createSubscriptionModel({discountStart = null, discountEnd = null, trialStartAt = null, trialEndAt = null, offerId = null, startDate = null} = {}) {
10+
function createSubscriptionModel({discountStart = null, discountEnd = null, trialEndAt = null, offerId = null, startDate = null} = {}) {
1111
return {
1212
get: sinon.stub().callsFake((key) => {
1313
const values = {
1414
discount_start: discountStart,
1515
discount_end: discountEnd,
16-
trial_start_at: trialStartAt,
1716
trial_end_at: trialEndAt,
1817
offer_id: offerId,
1918
start_date: startDate

0 commit comments

Comments
 (0)