Ghost/ghost/admin/app/services/members-utils.js
Simon Backx 076e3c02b2
Added linking between member and subscription created events (#15693)
fixes https://github.com/TryGhost/Team/issues/2160

- Adds a `batch_id` to both events that contain the same ID if they were created at the same time.
- Removes duplicate signup/conversion events using the batch_id
- Requires an update in mongo-knex to work (refs https://ghost.slack.com/archives/C02G9E68C/p1666773313272409?thread_ts=1666767872.375009&cid=C02G9E68C)
- Some dependencies needed an update to load the latest mongo-knex
- Added tiers to membersUtils, loaded on startup (we can start to use this instead of fetching it every time)
2022-10-27 11:44:19 +02:00

226 lines
7.5 KiB
JavaScript

import Service, {inject as service} from '@ember/service';
export default class MembersUtilsService extends Service {
@service config;
@service settings;
@service feature;
@service store;
paidTiers = null;
get isMembersEnabled() {
return this.settings.membersEnabled;
}
get paidMembersEnabled() {
return this.settings.paidMembersEnabled;
}
get isMembersInviteOnly() {
return this.settings.membersInviteOnly;
}
get hasMultipleTiers() {
return this.paidMembersEnabled && this.paidTiers && this.paidTiers.length > 1;
}
async fetch() {
if (this.paidTiers !== null) {
return;
}
return this.store.query('tier', {filter: 'type:paid+active:true', limit: 'all'}).then((tiers) => {
this.paidTiers = tiers;
});
}
async reload() {
return this.store.query('tier', {filter: 'type:paid+active:true', limit: 'all'}).then((tiers) => {
this.paidTiers = tiers;
});
}
/**
* Note: always use paidMembersEnabled! Only use this getter for the Stripe Connection UI.
*/
get isStripeEnabled() {
const stripeDirect = this.config.stripeDirect;
const hasDirectKeys = !!this.settings.stripeSecretKey && !!this.settings.stripePublishableKey;
const hasConnectKeys = !!this.settings.stripeConnectSecretKey && !!this.settings.stripeConnectPublishableKey;
if (stripeDirect) {
return hasDirectKeys;
}
return hasConnectKeys || hasDirectKeys;
}
// Button / Icon helpers ---------------------------------------------------
get defaultButtonIcons() {
return [
{
icon: 'portal-icon-1',
value: 'icon-1'
},
{
icon: 'portal-icon-2',
value: 'icon-2'
},
{
icon: 'portal-icon-3',
value: 'icon-3'
},
{
icon: 'portal-icon-4',
value: 'icon-4'
},
{
icon: 'portal-icon-5',
value: 'icon-5'
}
];
}
get defaultIconKeys() {
return this.defaultButtonIcons.map(buttonIcon => buttonIcon.value);
}
get buttonIcon() {
return this.settings.portalButtonIcon || this.defaultIconKeys[0];
}
// Plan helpers ------------------------------------------------------------
get isFreeChecked() {
const allowedPlans = this.settings.portalPlans || [];
return !!(this.settings.membersSignupAccess === 'all' && allowedPlans.includes('free'));
}
get isMonthlyChecked() {
const allowedPlans = this.settings.portalPlans || [];
return !!(this.isStripeConfigured && allowedPlans.includes('monthly'));
}
get isYearlyChecked() {
const allowedPlans = this.settings.portalPlans || [];
return !!(this.isStripeConfigured && allowedPlans.includes('yearly'));
}
// Portal preview ----------------------------------------------------------
getPortalPreviewUrl(overrides) {
let {
disableBackground = false,
page = 'signup',
button = this.settings.portalButton,
buttonIcon = this.buttonIcon,
isFreeChecked = this.isFreeChecked,
isMonthlyChecked = this.isMonthlyChecked,
isYearlyChecked = this.isYearlyChecked,
monthlyPrice,
yearlyPrice,
portalPlans = this.settings.portalPlans,
portalTiers,
currency,
membersSignupAccess = this.settings.membersSignupAccess
} = overrides;
const tiers = this.store.peekAll('tier') || [];
portalTiers = portalTiers || tiers.filter((t) => {
return t.visibility === 'public' && t.type === 'paid';
}).map(t => t.id);
const baseUrl = this.config.blogUrl;
const portalBase = '/#/portal/preview';
const settingsParam = new URLSearchParams();
const signupButtonText = this.settings.portalButtonSignupText || '';
const allowSelfSignup = membersSignupAccess === 'all' && (!this.isStripeEnabled || isFreeChecked);
settingsParam.append('button', button);
settingsParam.append('name', this.settings.portalName);
settingsParam.append('isFree', isFreeChecked);
settingsParam.append('isMonthly', isMonthlyChecked);
settingsParam.append('isYearly', isYearlyChecked);
settingsParam.append('page', page);
settingsParam.append('buttonIcon', encodeURIComponent(buttonIcon));
settingsParam.append('signupButtonText', encodeURIComponent(signupButtonText));
settingsParam.append('membersSignupAccess', membersSignupAccess);
settingsParam.append('allowSelfSignup', allowSelfSignup);
if (portalPlans) {
settingsParam.append('portalPrices', encodeURIComponent(portalPlans));
}
if (portalTiers) {
settingsParam.append('portalProducts', encodeURIComponent(portalTiers));
}
if (this.settings.accentColor === '' || this.settings.accentColor) {
settingsParam.append('accentColor', encodeURIComponent(`${this.settings.accentColor}`));
}
if (this.settings.portalButtonStyle) {
settingsParam.append('buttonStyle', encodeURIComponent(this.settings.portalButtonStyle));
}
if (monthlyPrice) {
settingsParam.append('monthlyPrice', monthlyPrice);
}
if (yearlyPrice) {
settingsParam.append('yearlyPrice', yearlyPrice);
}
if (currency) {
settingsParam.append('currency', currency);
}
if (disableBackground) {
settingsParam.append('disableBackground', true);
}
return `${baseUrl}${portalBase}?${settingsParam.toString()}`;
}
getOfferPortalPreviewUrl(overrides) {
const {
disableBackground = false,
name,
code,
displayTitle = '',
displayDescription = '',
type,
cadence,
amount = 0,
duration,
durationInMonths,
currency = 'usd',
status,
tierId
} = overrides;
const baseUrl = this.config.blogUrl;
const portalBase = '/#/portal/preview/offer';
const settingsParam = new URLSearchParams();
settingsParam.append('name', encodeURIComponent(name));
settingsParam.append('code', encodeURIComponent(code));
settingsParam.append('display_title', encodeURIComponent(displayTitle));
settingsParam.append('display_description', encodeURIComponent(displayDescription));
settingsParam.append('type', encodeURIComponent(type));
settingsParam.append('cadence', encodeURIComponent(cadence));
settingsParam.append('amount', encodeURIComponent(amount));
settingsParam.append('duration', encodeURIComponent(duration));
settingsParam.append('duration_in_months', encodeURIComponent(durationInMonths));
settingsParam.append('currency', encodeURIComponent(currency));
settingsParam.append('status', encodeURIComponent(status));
settingsParam.append('tier_id', encodeURIComponent(tierId));
if (disableBackground) {
settingsParam.append('disableBackground', 'true');
}
return `${baseUrl}${portalBase}?${settingsParam.toString()}`;
}
}