@wepublish/api
Version:
API core for we.publish.
214 lines • 9.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SubscriptionEventDictionary = void 0;
const tslib_1 = require("tslib");
const date_fns_1 = require("date-fns");
const client_1 = require("@prisma/client");
const common_1 = require("@nestjs/common");
/**
* This class loads all subscription flows and allows filtering by member plan,
* payment method, periodicity, renewal and EITHER the daysAwayFromEnding or a
* list of event names.
*/
let SubscriptionEventDictionary = exports.SubscriptionEventDictionary = class SubscriptionEventDictionary {
constructor(prismaService) {
this.prismaService = prismaService;
this.allFlows = [];
}
/**
* Get the earliest date when an invoice must be created.
* @param date The current date.
* @returns The earliest date.
*/
getEarliestInvoiceCreationDate(date) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
yield this.initialize();
const allIntervals = this.allFlows.map(flow => flow.intervals).flat();
const allCreationEvents = allIntervals.filter(interval => interval.event === client_1.SubscriptionEvent.INVOICE_CREATION);
if (allCreationEvents.length === 0) {
throw new common_1.NotFoundException('No invoice creation date found!');
}
let earliest = Number.MAX_SAFE_INTEGER;
for (const event of allCreationEvents) {
if (event.daysAwayFromEnding !== null && event.daysAwayFromEnding < earliest) {
earliest = event.daysAwayFromEnding;
}
}
return (0, date_fns_1.subDays)(this.normalizeDate(date), earliest);
});
}
/**
* Get an array of the dates where custom events have been defined.
* @param date The current date.
* @returns An array of dates.
*/
getDatesWithCustomEvent(date) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
yield this.initialize();
const customEventDaysAwayFromEnding = [];
const allIntervals = this.allFlows.map(flow => flow.intervals).flat();
const allCustomEvents = allIntervals.filter(interval => interval.event === client_1.SubscriptionEvent.CUSTOM);
for (const event of allCustomEvents) {
if (event.daysAwayFromEnding !== null &&
!customEventDaysAwayFromEnding.includes(event.daysAwayFromEnding)) {
customEventDaysAwayFromEnding.push(event.daysAwayFromEnding);
}
}
return customEventDaysAwayFromEnding.map(daysAwayFromEnding => (0, date_fns_1.subDays)(this.normalizeDate(date), daysAwayFromEnding));
});
}
/**
* Try to get the MailTemplates for a specific filter of [memberPlan,
* paymentMethod, periodicity, autoRenewal]. You additionally need to pass
* either `daysAwayFromEnding` or `events` to filter further. If any
* filter leads to an empty result set, the templates of the default flow are
* returned.
* @param query The filter of the above properties.
* @returns An array of MailTemplates.
*/
getActionsForSubscriptions(query) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
yield this.initialize();
if (query.daysAwayFromEnding && query.events) {
throw new Error('Its not supported to query for daysAwayFromEnding combined with an event list');
}
const defaultFlow = this.allFlows.find(flow => flow.default);
if (!defaultFlow) {
throw new Error('Default flow is missing!');
}
const filteredFlows = this.allFlows.filter(flow => flow.memberPlanId === query.memberplanId &&
flow.paymentMethods.map(pm => pm.id).includes(query.paymentMethodId) &&
flow.periodicities.includes(query.periodicity) &&
flow.autoRenewal.includes(query.autorenwal));
if (filteredFlows.length === 0) {
return this.getActionByDay(defaultFlow.actions, query.daysAwayFromEnding, query.events);
}
return this.getActionByDay(filteredFlows[0].actions, query.daysAwayFromEnding, query.events);
});
}
/**
* Load all subscription flows. This is automatically called once per instance.
* {@link getActionsForSubscriptions}.
*/
initialize() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
this.allFlows = (yield this.prismaService.subscriptionFlow.findMany({
include: {
paymentMethods: true,
intervals: {
include: {
mailTemplate: true
}
}
}
})).map(flow => {
return Object.assign(Object.assign({}, flow), { actions: flow.intervals.map(int => ({
type: int.event,
daysAwayFromEnding: int.daysAwayFromEnding,
externalMailTemplate: int.mailTemplate ? int.mailTemplate.externalMailTemplateId : null
})) });
});
const defaultFlows = this.allFlows.filter(flow => flow.default);
if (defaultFlows.length === 0) {
throw new common_1.NotFoundException('Default user subscription flow not found!');
}
if (defaultFlows.length > 1) {
throw new Error('Multiple default memberplans found! This is a data integrity error!');
}
const nonDefaultFlows = this.allFlows.filter(flow => !flow.default);
if (nonDefaultFlows.filter(flow => !flow.memberPlanId).length) {
throw new Error('Subscription Flow with no memberplan found that is not default! This is a data integrity error!');
}
});
}
/**
* Filter the MailTemplates stored for a specific flow. They can either be
* filtered by `daysAwayFromEnding` or by `lookupEvents`.
* @param timeline The leaf of the store.
* @param daysAwayFromEnding Number of days away from ending.
* @param lookupEvents The event identifiers.
* @returns Array of mail templates.
*/
getActionByDay(timeline, daysAwayFromEnding, lookupEvents) {
if (lookupEvents) {
return timeline.filter(e => lookupEvents.includes(e.type));
}
// Return user actions for null and 0!
if (!daysAwayFromEnding) {
return timeline.filter(t => t.daysAwayFromEnding === 0 || t.daysAwayFromEnding === null);
}
return timeline.filter(t => t.daysAwayFromEnding === daysAwayFromEnding);
}
normalizeDate(date) {
return (0, date_fns_1.startOfDay)(date);
}
/**
* Get the External Mail Template name for a specific subscription and subscription event.
* @param prisma The Prisma client.
* @param subsciption The subscription to search for.
* @param subscriptionEvent The event to search for.
* @returns The external template identifier OR undefined of none was found.
*/
getSubsciptionTemplateIdentifier(subsciption, subscriptionEvent) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
let flow = yield this.prismaService.subscriptionFlow.findFirst({
where: {
default: false,
memberPlan: {
id: subsciption.memberPlanID
},
autoRenewal: {
has: subsciption.autoRenew
},
periodicities: {
has: subsciption.paymentPeriodicity
},
paymentMethods: {
some: {
id: subsciption.paymentMethodID
}
}
},
include: {
intervals: {
where: {
event: subscriptionEvent
},
include: {
mailTemplate: true
}
}
}
});
if (!flow) {
flow = yield this.prismaService.subscriptionFlow.findFirst({
where: {
default: true
},
include: {
intervals: {
where: {
event: subscriptionEvent
},
include: {
mailTemplate: true
}
}
}
});
}
if (flow && flow.intervals[0]) {
if (!flow.intervals[0].mailTemplate) {
return undefined;
}
return flow.intervals[0].mailTemplate.externalMailTemplateId;
}
return undefined;
});
}
};
exports.SubscriptionEventDictionary = SubscriptionEventDictionary = tslib_1.__decorate([
(0, common_1.Injectable)(),
tslib_1.__metadata("design:paramtypes", [client_1.PrismaClient])
], SubscriptionEventDictionary);
//# sourceMappingURL=subscription-event-dictionary.js.map