Handled new type column for tiers (#356)

refs https://github.com/TryGhost/Team/issues/1037

Tiers have a new `type` column to differentiate between `free` and `paid` tiers. This change -

- sets type as paid for all new tiers created, as `free` tier is created by default
- excludes any price/stripe data change for free tier
- updates all usages of default product to fetch the first paid product from the products list in DB instead of just the first product it finds.
This commit is contained in:
Rishabh Garg 2022-01-17 23:02:02 +05:30 committed by GitHub
parent fb3010384b
commit ca18f140c4
4 changed files with 38 additions and 9 deletions

View File

@ -44,7 +44,8 @@ module.exports = class StripeMigrations {
const products = productModels.toJSON();
const {data} = await this._Product.findPage({
...options,
limit: 1
limit: 1,
filter: 'type:paid'
});
const defaultProduct = data[0] && data[0].toJSON();
@ -142,7 +143,11 @@ module.exports = class StripeMigrations {
if (!defaultStripeProduct) {
logging.info('Could not find Stripe Product - creating one');
const productsPage = await this._Product.findPage({...options, limit: 1});
const productsPage = await this._Product.findPage({
...options,
limit: 1,
filter: 'type:paid'
});
const defaultProduct = productsPage.data[0];
const stripeProduct = await this._stripeAPIService.createProduct({
name: defaultProduct.get('name')
@ -417,7 +422,10 @@ module.exports = class StripeMigrations {
});
}
logging.info('Migrating members_monthly_price_id setting to monthly_price_id column');
const productsPage = await this._Product.findPage({...options, limit: 1});
const productsPage = await this._Product.findPage({
...options, limit: 1,
filter: 'type:paid'
});
const defaultProduct = productsPage.data[0];
if (defaultProduct.get('monthly_price_id')) {
@ -438,7 +446,11 @@ module.exports = class StripeMigrations {
});
}
logging.info('Migrating members_yearly_price_id setting to yearly_price_id column');
const productsPage = await this._Product.findPage({...options, limit: 1});
const productsPage = await this._Product.findPage({
...options,
limit: 1,
filter: 'type:paid'
});
const defaultProduct = productsPage.data[0];
if (defaultProduct.get('yearly_price_id')) {

View File

@ -564,7 +564,10 @@ module.exports = class MemberRepository {
ghostProduct = await this._productRepository.get({stripe_product_id: subscriptionPriceData.product}, options);
// Use first Ghost product as default product in case of missing link
if (!ghostProduct) {
let {data: pageData} = await this._productRepository.list({limit: 1});
let {data: pageData} = await this._productRepository.list({
limit: 1,
filter: 'type:paid'
});
ghostProduct = (pageData && pageData[0]) || null;
}
@ -950,7 +953,12 @@ module.exports = class MemberRepository {
return this.isActiveSubscriptionStatus(subscription.get('status'));
});
const productPage = await this._productRepository.list({limit: 1, withRelated: ['stripePrices'], ...options});
const productPage = await this._productRepository.list({
limit: 1,
withRelated: ['stripePrices'],
filter: 'type:paid',
...options
});
const defaultProduct = productPage && productPage.data && productPage.data[0] && productPage.data[0].toJSON();

View File

@ -133,6 +133,7 @@ class ProductRepository {
}
const productData = {
type: 'paid',
name: data.name,
description: data.description,
benefits: data.benefits
@ -266,19 +267,26 @@ class ProductRepository {
});
});
}
const productId = data.id || options.id;
const productData = {
const existingProduct = await this._Product.findOne({id: productId}, options);
let productData = {
name: data.name,
description: data.description,
benefits: data.benefits
};
if (existingProduct.get('type') === 'free') {
delete productData.name;
}
let product = await this._Product.edit(productData, {
...options,
id: data.id || options.id
id: productId
});
if (this._stripeAPIService.configured) {
if (this._stripeAPIService.configured && product.get('type') !== 'free') {
await product.related('stripeProducts').fetch(options);
if (!product.related('stripeProducts').first()) {

View File

@ -125,6 +125,7 @@ module.exports = class MembersCSVImporter {
const membersApi = await this._getMembersApi();
const defaultProductPage = await membersApi.productRepository.list({
filter: 'type:paid',
limit: 1
});