From 2b58ecd82eaef0fc2c23b7454ba5f3602b0c3ce3 Mon Sep 17 00:00:00 2001 From: Fabien O'Carroll Date: Thu, 7 Oct 2021 17:33:26 +0200 Subject: [PATCH] Added support for creating fixed offers with currency refs https://github.com/TryGhost/Team/issues/1083 We now allow creating offers for a fixed amount, rather than a percentage. These require a currency to be passed as a fixed amount is meaningless without one. --- ghost/offers/lib/OfferRepository.js | 6 +++++- ghost/offers/lib/domain/models/Offer.js | 14 ++++++++------ .../offers/lib/domain/models/OfferCurrency.js | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 ghost/offers/lib/domain/models/OfferCurrency.js diff --git a/ghost/offers/lib/OfferRepository.js b/ghost/offers/lib/OfferRepository.js index ccdcf3f02e..ef1d4583a7 100644 --- a/ghost/offers/lib/OfferRepository.js +++ b/ghost/offers/lib/OfferRepository.js @@ -122,7 +122,8 @@ class OfferRepository { discount_amount: offer.amount.value, interval: offer.cadence.value, product_id: offer.tier.id, - duration: offer.duration.value + duration: offer.duration.value, + currency: offer.currency.value }); if (offer.codeChanged || offer.isNew) { @@ -143,6 +144,9 @@ class OfferRepository { if (offer.type.value === 'percent') { coupon.percent_off = offer.amount.value; + } else { + coupon.amount_off = offer.amount.value; + coupon.currency = offer.currency.value; } const couponData = await this.stripeAPIService.createCoupon(coupon); diff --git a/ghost/offers/lib/domain/models/Offer.js b/ghost/offers/lib/domain/models/Offer.js index c1fd30c870..8c956bcd1e 100644 --- a/ghost/offers/lib/domain/models/Offer.js +++ b/ghost/offers/lib/domain/models/Offer.js @@ -9,6 +9,7 @@ const OfferDescription = require('./OfferDescription'); const OfferCadence = require('./OfferCadence'); const OfferType = require('./OfferType'); const OfferDuration = require('./OfferDuration'); +const OfferCurrency = require('./OfferCurrency'); /** * @typedef {object} OfferProps @@ -21,7 +22,7 @@ const OfferDuration = require('./OfferDuration'); * @prop {OfferType} type * @prop {OfferAmount} amount * @prop {OfferDuration} duration - * @prop {string} currency + * @prop {OfferCurrency} currency * @prop {string} [stripe_coupon_id] * @prop {OfferTier} tier */ @@ -226,11 +227,14 @@ class Offer { const type = OfferType.create(data.type); const cadence = OfferCadence.create(data.cadence); const duration = OfferDuration.create(data.duration); + + let currency = null; let amount; - if (type.equals(OfferType.Percent)) { + if (type.equals(OfferType.Percentage)) { amount = OfferAmount.OfferPercentageAmount.create(data.amount); - } else { - amount = OfferAmount.OfferAbsoluteAmount.create(data.amount); + } else if (type.equals(OfferType.Fixed)) { + amount = OfferAmount.OfferFixedAmount.create(data.amount); + currency = OfferCurrency.create(data.currency); } if (isNew) { @@ -255,8 +259,6 @@ class Offer { }); } - const currency = data.currency; - if (isNew && data.stripe_coupon_id) { throw new errors.InvalidOfferCoupon({ message: 'Cannot supply a stripe_coupon_id for new Offers.' diff --git a/ghost/offers/lib/domain/models/OfferCurrency.js b/ghost/offers/lib/domain/models/OfferCurrency.js new file mode 100644 index 0000000000..4f5cc2026a --- /dev/null +++ b/ghost/offers/lib/domain/models/OfferCurrency.js @@ -0,0 +1,18 @@ +const ValueObject = require('../../shared/ValueObject'); +const InvalidOfferCurrency = require('../../errors').InvalidOfferCurrency; + +/** @extends ValueObject */ +class OfferCurrency extends ValueObject { + /** @param {unknown} currency */ + static create(currency) { + if (typeof currency !== 'string') { + throw new InvalidOfferCurrency({ + message: 'Offer `currency` must be a string.' + }); + } + // TODO: Validate it is a country code we support? + return new OfferCurrency(currency); + } +} + +module.exports = OfferCurrency;