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.
This commit is contained in:
Fabien O'Carroll 2021-10-07 17:33:26 +02:00
parent 2c04afe810
commit 2b58ecd82e
3 changed files with 31 additions and 7 deletions

View File

@ -122,7 +122,8 @@ class OfferRepository {
discount_amount: offer.amount.value, discount_amount: offer.amount.value,
interval: offer.cadence.value, interval: offer.cadence.value,
product_id: offer.tier.id, product_id: offer.tier.id,
duration: offer.duration.value duration: offer.duration.value,
currency: offer.currency.value
}); });
if (offer.codeChanged || offer.isNew) { if (offer.codeChanged || offer.isNew) {
@ -143,6 +144,9 @@ class OfferRepository {
if (offer.type.value === 'percent') { if (offer.type.value === 'percent') {
coupon.percent_off = offer.amount.value; 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); const couponData = await this.stripeAPIService.createCoupon(coupon);

View File

@ -9,6 +9,7 @@ const OfferDescription = require('./OfferDescription');
const OfferCadence = require('./OfferCadence'); const OfferCadence = require('./OfferCadence');
const OfferType = require('./OfferType'); const OfferType = require('./OfferType');
const OfferDuration = require('./OfferDuration'); const OfferDuration = require('./OfferDuration');
const OfferCurrency = require('./OfferCurrency');
/** /**
* @typedef {object} OfferProps * @typedef {object} OfferProps
@ -21,7 +22,7 @@ const OfferDuration = require('./OfferDuration');
* @prop {OfferType} type * @prop {OfferType} type
* @prop {OfferAmount} amount * @prop {OfferAmount} amount
* @prop {OfferDuration} duration * @prop {OfferDuration} duration
* @prop {string} currency * @prop {OfferCurrency} currency
* @prop {string} [stripe_coupon_id] * @prop {string} [stripe_coupon_id]
* @prop {OfferTier} tier * @prop {OfferTier} tier
*/ */
@ -226,11 +227,14 @@ class Offer {
const type = OfferType.create(data.type); const type = OfferType.create(data.type);
const cadence = OfferCadence.create(data.cadence); const cadence = OfferCadence.create(data.cadence);
const duration = OfferDuration.create(data.duration); const duration = OfferDuration.create(data.duration);
let currency = null;
let amount; let amount;
if (type.equals(OfferType.Percent)) { if (type.equals(OfferType.Percentage)) {
amount = OfferAmount.OfferPercentageAmount.create(data.amount); amount = OfferAmount.OfferPercentageAmount.create(data.amount);
} else { } else if (type.equals(OfferType.Fixed)) {
amount = OfferAmount.OfferAbsoluteAmount.create(data.amount); amount = OfferAmount.OfferFixedAmount.create(data.amount);
currency = OfferCurrency.create(data.currency);
} }
if (isNew) { if (isNew) {
@ -255,8 +259,6 @@ class Offer {
}); });
} }
const currency = data.currency;
if (isNew && data.stripe_coupon_id) { if (isNew && data.stripe_coupon_id) {
throw new errors.InvalidOfferCoupon({ throw new errors.InvalidOfferCoupon({
message: 'Cannot supply a stripe_coupon_id for new Offers.' message: 'Cannot supply a stripe_coupon_id for new Offers.'

View File

@ -0,0 +1,18 @@
const ValueObject = require('../../shared/ValueObject');
const InvalidOfferCurrency = require('../../errors').InvalidOfferCurrency;
/** @extends ValueObject<string> */
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;