Merge branch 'dev' into staging
This commit is contained in:
commit
7a453b65fa
@ -1,7 +1,7 @@
|
|||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
// import roleHandler from "@App/middlewares/RolesHandler";
|
// import roleHandler from "@App/middlewares/RolesHandler";
|
||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import { Controller, Post } from "@ControllerPattern/index";
|
import { Controller, Get, Post } from "@ControllerPattern/index";
|
||||||
import StripeService from "@Services/common/StripeService/StripeService";
|
import StripeService from "@Services/common/StripeService/StripeService";
|
||||||
import { validateOrReject } from "class-validator";
|
import { validateOrReject } from "class-validator";
|
||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
@ -39,4 +39,22 @@ export default class StripeController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get("/api/v1/admin/stripe/:uid", [authHandler])
|
||||||
|
protected async get(req: Request, response: Response) {
|
||||||
|
try {
|
||||||
|
const uid = req.params["uid"];
|
||||||
|
if (!uid) {
|
||||||
|
this.httpBadRequest(response, "No uid provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const client_portal = await this.stripeService.createClientPortalSession(uid);
|
||||||
|
|
||||||
|
this.httpSuccess(response, client_portal);
|
||||||
|
} catch (error) {
|
||||||
|
this.httpInternalError(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -12,11 +12,12 @@ import { validateOrReject } from "class-validator";
|
|||||||
import ObjectHydrate from "@Common/helpers/ObjectHydrate";
|
import ObjectHydrate from "@Common/helpers/ObjectHydrate";
|
||||||
import roleHandler from "@App/middlewares/RolesHandler";
|
import roleHandler from "@App/middlewares/RolesHandler";
|
||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
|
import EmailBuilder from "@Common/emails/EmailBuilder";
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@Service()
|
@Service()
|
||||||
export default class SubscriptionsController extends ApiController {
|
export default class SubscriptionsController extends ApiController {
|
||||||
constructor(private subscriptionsService: SubscriptionsService) {
|
constructor(private subscriptionsService: SubscriptionsService, private emailBuilder: EmailBuilder) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,4 +143,32 @@ export default class SubscriptionsController extends ApiController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Invite collaborators to a subscription
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Post("/api/v1/admin/subscriptions/invite", [authHandler, roleHandler])
|
||||||
|
protected async inviteCollaborators(req: Request, response: Response) {
|
||||||
|
try {
|
||||||
|
//get email list from body
|
||||||
|
const emails: [string] = req.body.emails;
|
||||||
|
if (!emails || emails.length < 1){
|
||||||
|
this.httpBadRequest(response, "No emails provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(emails);
|
||||||
|
|
||||||
|
//create emails for asked document
|
||||||
|
await this.emailBuilder.sendInvitationEmails(emails);
|
||||||
|
|
||||||
|
//success
|
||||||
|
this.httpSuccess(response);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
this.httpInternalError(response, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,6 +157,9 @@ export class BackendVariables {
|
|||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
public readonly STRIPE_PAYMENT_CANCEL_URL!: string;
|
public readonly STRIPE_PAYMENT_CANCEL_URL!: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
public readonly IDNOT_PROD_BASE_URL!: string;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
this.DATABASE_PORT = process.env["DATABASE_PORT"]!;
|
this.DATABASE_PORT = process.env["DATABASE_PORT"]!;
|
||||||
@ -210,6 +213,7 @@ export class BackendVariables {
|
|||||||
this.STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID = process.env["STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID"]!;
|
this.STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID = process.env["STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID"]!;
|
||||||
this.STRIPE_PAYMENT_SUCCESS_URL = process.env["STRIPE_PAYMENT_SUCCESS_URL"]!;
|
this.STRIPE_PAYMENT_SUCCESS_URL = process.env["STRIPE_PAYMENT_SUCCESS_URL"]!;
|
||||||
this.STRIPE_PAYMENT_CANCEL_URL = process.env["STRIPE_PAYMENT_CANCEL_URL"]!;
|
this.STRIPE_PAYMENT_CANCEL_URL = process.env["STRIPE_PAYMENT_CANCEL_URL"]!;
|
||||||
|
this.IDNOT_PROD_BASE_URL = process.env["IDNOT_PROD_BASE_URL"]!;
|
||||||
}
|
}
|
||||||
public async validate(groups?: string[]) {
|
public async validate(groups?: string[]) {
|
||||||
const validationOptions = groups ? { groups } : undefined;
|
const validationOptions = groups ? { groups } : undefined;
|
||||||
|
@ -106,4 +106,32 @@ export default class EmailBuilder {
|
|||||||
if (civility === "MALE") return "Mr";
|
if (civility === "MALE") return "Mr";
|
||||||
else return "Mme";
|
else return "Mme";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async sendInvitationEmails(emails: string[]) {
|
||||||
|
emails.forEach((email) => {
|
||||||
|
const to = email;
|
||||||
|
|
||||||
|
const templateVariables = {
|
||||||
|
link: this.variables.APP_HOST,
|
||||||
|
idNotLink: this.variables.IDNOT_PROD_BASE_URL,
|
||||||
|
};
|
||||||
|
|
||||||
|
const templateName = ETemplates.SUBSCRIPTION_INVITATION;
|
||||||
|
const subject = "Invitation abonnement LeCoffre";
|
||||||
|
|
||||||
|
this.mailchimpService.create({
|
||||||
|
templateName,
|
||||||
|
to,
|
||||||
|
subject,
|
||||||
|
templateVariables,
|
||||||
|
uid: "",
|
||||||
|
from: null,
|
||||||
|
cc: [],
|
||||||
|
cci: [],
|
||||||
|
sentAt: null,
|
||||||
|
nbTrySend: null,
|
||||||
|
lastTrySendDate: null,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,5 @@ export const ETemplates = {
|
|||||||
DOCUMENT_ASKED: "DOCUMENT_ASKED",
|
DOCUMENT_ASKED: "DOCUMENT_ASKED",
|
||||||
DOCUMENT_REFUSED: "DOCUMENT_REFUSED",
|
DOCUMENT_REFUSED: "DOCUMENT_REFUSED",
|
||||||
DOCUMENT_RECAP: "DOCUMENT_RECAP",
|
DOCUMENT_RECAP: "DOCUMENT_RECAP",
|
||||||
|
SUBSCRIPTION_INVITATION: "SUBSCRIPTION_INVITATION",
|
||||||
};
|
};
|
@ -40,7 +40,7 @@ export default class SubscriptionsRepository extends BaseRepository {
|
|||||||
/**
|
/**
|
||||||
* @description : Create a subscription
|
* @description : Create a subscription
|
||||||
*/
|
*/
|
||||||
public async create(subscription: Subscription): Promise<Subscriptions> {
|
public async create(subscription: Subscription): Promise<Subscriptions> {
|
||||||
if(subscription.type === "STANDARD")
|
if(subscription.type === "STANDARD")
|
||||||
{
|
{
|
||||||
const createArgs: Prisma.SubscriptionsCreateArgs = {
|
const createArgs: Prisma.SubscriptionsCreateArgs = {
|
||||||
@ -56,15 +56,6 @@ export default class SubscriptionsRepository extends BaseRepository {
|
|||||||
uid: subscription.office!.uid,
|
uid: subscription.office!.uid,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
seats: {
|
|
||||||
create: subscription.seats!.map(seat => ({
|
|
||||||
user: {
|
|
||||||
connect: {
|
|
||||||
uid: seat.user!.uid,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return this.model.create(createArgs);
|
return this.model.create(createArgs);
|
||||||
|
@ -14,23 +14,35 @@ export default class StripeService {
|
|||||||
return this.client;
|
return this.client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createCheckoutSession(subscription: Subscription) {
|
public async createCheckoutSession(subscription: Subscription) {
|
||||||
const priceId = subscription.type === "STANDARD" ? this.variables.STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID : this.variables.STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID;
|
const priceId =
|
||||||
return this.client.checkout.sessions.create({
|
subscription.type === "STANDARD"
|
||||||
mode: "subscription",
|
? this.variables.STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID
|
||||||
payment_method_types: ["card", "paypal"],
|
: this.variables.STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID;
|
||||||
billing_address_collection: "auto",
|
return this.client.checkout.sessions.create({
|
||||||
line_items: [
|
mode: "subscription",
|
||||||
{
|
payment_method_types: ["card", "paypal"],
|
||||||
price: priceId,
|
billing_address_collection: "auto",
|
||||||
quantity: subscription.nb_seats,
|
line_items: [
|
||||||
},
|
{
|
||||||
],
|
price: priceId,
|
||||||
success_url: this.variables.STRIPE_PAYMENT_SUCCESS_URL,
|
quantity: subscription.nb_seats,
|
||||||
cancel_url: this.variables.STRIPE_PAYMENT_CANCEL_URL,
|
},
|
||||||
metadata: {
|
],
|
||||||
subscription: JSON.stringify(subscription),
|
success_url: this.variables.STRIPE_PAYMENT_SUCCESS_URL,
|
||||||
},
|
cancel_url: this.variables.STRIPE_PAYMENT_CANCEL_URL,
|
||||||
});
|
metadata: {
|
||||||
}
|
subscription: JSON.stringify(subscription),
|
||||||
}
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async createClientPortalSession(subscriptionId: string) {
|
||||||
|
const subscription = await this.client.subscriptions.retrieve(subscriptionId);
|
||||||
|
|
||||||
|
return this.client.billingPortal.sessions.create({
|
||||||
|
customer: subscription.customer as string,
|
||||||
|
return_url: this.variables.APP_HOST + "/subscription/manage",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user