mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
feat: Payment system with voucher cards.
feat: Design with inversion dependency injection architecture. feat: Prettier http middleware. feat: Re-write items categories with preferred accounts.
This commit is contained in:
48
server/src/services/Subscription/Subscription.ts
Normal file
48
server/src/services/Subscription/Subscription.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Tenant, Plan } from '@/system/models';
|
||||
import { IPaymentContext } from '@/interfaces';
|
||||
import { NotAllowedChangeSubscriptionPlan } from '@/exceptions';
|
||||
|
||||
export default class Subscription<PaymentModel> {
|
||||
paymentContext: IPaymentContext|null;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {IPaymentContext}
|
||||
*/
|
||||
constructor(payment?: IPaymentContext) {
|
||||
this.paymentContext = payment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscripe to the given plan.
|
||||
* @param {Plan} plan
|
||||
* @throws {NotAllowedChangeSubscriptionPlan}
|
||||
*/
|
||||
async subscribe(
|
||||
tenant: Tenant,
|
||||
plan: Plan,
|
||||
paymentModel?: PaymentModel,
|
||||
subscriptionSlug: string = 'main',
|
||||
) {
|
||||
if (plan.price < 0) {
|
||||
await this.paymentContext.makePayment(paymentModel);
|
||||
}
|
||||
const subscription = await tenant.$relatedQuery('subscriptions')
|
||||
.modify('subscriptionBySlug', subscriptionSlug)
|
||||
.first();
|
||||
|
||||
// No allowed to re-new the the subscription while the subscription is active.
|
||||
if (subscription && subscription.active()) {
|
||||
throw new NotAllowedChangeSubscriptionPlan;
|
||||
|
||||
// In case there is already subscription associated to the given tenant.
|
||||
// renew it.
|
||||
} else if(subscription && subscription.inactive()) {
|
||||
await subscription.renew(plan);
|
||||
|
||||
// No stored past tenant subscriptions create new one.
|
||||
} else {
|
||||
await tenant.newSubscription(subscriptionSlug, plan);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
server/src/services/Subscription/SubscriptionPeriod.ts
Normal file
41
server/src/services/Subscription/SubscriptionPeriod.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import moment from 'moment';
|
||||
|
||||
export default class SubscriptionPeriod {
|
||||
start: Date;
|
||||
end: Date;
|
||||
interval: string;
|
||||
count: number;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {string} interval -
|
||||
* @param {number} count -
|
||||
* @param {Date} start -
|
||||
*/
|
||||
constructor(interval: string = 'month', count: number, start?: Date) {
|
||||
this.interval = interval;
|
||||
this.count = count;
|
||||
this.start = start;
|
||||
|
||||
if (!start) {
|
||||
this.start = moment().toDate();
|
||||
}
|
||||
this.end = moment(start).add(count, interval).toDate();
|
||||
}
|
||||
|
||||
getStartDate() {
|
||||
return this.start;
|
||||
}
|
||||
|
||||
getEndDate() {
|
||||
return this.end;
|
||||
}
|
||||
|
||||
getInterval() {
|
||||
return this.interval;
|
||||
}
|
||||
|
||||
getIntervalCount() {
|
||||
return this.interval;
|
||||
}
|
||||
}
|
||||
36
server/src/services/Subscription/SubscriptionService.ts
Normal file
36
server/src/services/Subscription/SubscriptionService.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { Service } from 'typedi';
|
||||
import { Plan, Tenant, Voucher } from '@/system/models';
|
||||
import Subscription from '@/services/Subscription/Subscription';
|
||||
import VocuherPaymentMethod from '@/services/Payment/VoucherPaymentMethod';
|
||||
import PaymentContext from '@/services/Payment';
|
||||
|
||||
@Service()
|
||||
export default class SubscriptionService {
|
||||
/**
|
||||
* Handles the payment process via voucher code and than subscribe to
|
||||
* the given tenant.
|
||||
*
|
||||
* @param {number} tenantId
|
||||
* @param {String} planSlug
|
||||
* @param {string} voucherCode
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
async subscriptionViaVoucher(
|
||||
tenantId: number,
|
||||
planSlug: string,
|
||||
voucherCode: string,
|
||||
subscriptionSlug: string = 'main',
|
||||
) {
|
||||
const plan = await Plan.query().findOne('slug', planSlug);
|
||||
const tenant = await Tenant.query().findById(tenantId);
|
||||
const voucherModel = await Voucher.query().findOne('voucher_code', voucherCode);
|
||||
|
||||
const paymentViaVoucher = new VocuherPaymentMethod();
|
||||
const paymentContext = new PaymentContext(paymentViaVoucher);
|
||||
|
||||
const subscription = new Subscription(paymentContext);
|
||||
|
||||
return subscription.subscribe(tenant, plan, voucherModel, subscriptionSlug);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
|
||||
export default (Model) => {
|
||||
return class UserSubscription extends Model{
|
||||
|
||||
onTrial() {
|
||||
|
||||
}
|
||||
|
||||
getSubscription() {
|
||||
|
||||
}
|
||||
|
||||
newSubscription() {
|
||||
|
||||
}
|
||||
|
||||
isSubcribedTo(plan) {
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user