diff --git a/src/app/api/admin/StripeController.ts b/src/app/api/admin/StripeController.ts index ae4c211d..84550974 100644 --- a/src/app/api/admin/StripeController.ts +++ b/src/app/api/admin/StripeController.ts @@ -1,7 +1,7 @@ import authHandler from "@App/middlewares/AuthHandler"; // import roleHandler from "@App/middlewares/RolesHandler"; 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 { validateOrReject } from "class-validator"; import { Request, Response } from "express"; @@ -39,4 +39,22 @@ export default class StripeController extends ApiController { 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; + } + } } \ No newline at end of file diff --git a/src/app/api/admin/SubscriptionsController.ts b/src/app/api/admin/SubscriptionsController.ts index 4de51386..a79c2feb 100644 --- a/src/app/api/admin/SubscriptionsController.ts +++ b/src/app/api/admin/SubscriptionsController.ts @@ -12,11 +12,12 @@ import { validateOrReject } from "class-validator"; import ObjectHydrate from "@Common/helpers/ObjectHydrate"; import roleHandler from "@App/middlewares/RolesHandler"; import authHandler from "@App/middlewares/AuthHandler"; +import EmailBuilder from "@Common/emails/EmailBuilder"; @Controller() @Service() export default class SubscriptionsController extends ApiController { - constructor(private subscriptionsService: SubscriptionsService) { + constructor(private subscriptionsService: SubscriptionsService, private emailBuilder: EmailBuilder) { super(); } @@ -142,4 +143,32 @@ export default class SubscriptionsController extends ApiController { 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; + } + } } diff --git a/src/common/config/variables/Variables.ts b/src/common/config/variables/Variables.ts index 3b37f398..a65bd265 100644 --- a/src/common/config/variables/Variables.ts +++ b/src/common/config/variables/Variables.ts @@ -157,6 +157,9 @@ export class BackendVariables { @IsNotEmpty() public readonly STRIPE_PAYMENT_CANCEL_URL!: string; + @IsNotEmpty() + public readonly IDNOT_PROD_BASE_URL!: string; + public constructor() { dotenv.config(); 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_PAYMENT_SUCCESS_URL = process.env["STRIPE_PAYMENT_SUCCESS_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[]) { const validationOptions = groups ? { groups } : undefined; diff --git a/src/common/emails/EmailBuilder.ts b/src/common/emails/EmailBuilder.ts index 81eb1c1e..bc7757e2 100644 --- a/src/common/emails/EmailBuilder.ts +++ b/src/common/emails/EmailBuilder.ts @@ -106,4 +106,32 @@ export default class EmailBuilder { if (civility === "MALE") return "Mr"; 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, + }); + }); + } } diff --git a/src/common/emails/Templates/EmailTemplates.ts b/src/common/emails/Templates/EmailTemplates.ts index 081cfadb..520098e2 100644 --- a/src/common/emails/Templates/EmailTemplates.ts +++ b/src/common/emails/Templates/EmailTemplates.ts @@ -2,4 +2,5 @@ export const ETemplates = { DOCUMENT_ASKED: "DOCUMENT_ASKED", DOCUMENT_REFUSED: "DOCUMENT_REFUSED", DOCUMENT_RECAP: "DOCUMENT_RECAP", + SUBSCRIPTION_INVITATION: "SUBSCRIPTION_INVITATION", }; \ No newline at end of file diff --git a/src/common/repositories/SubscriptionsRepository.ts b/src/common/repositories/SubscriptionsRepository.ts index a8203886..ee5f787f 100644 --- a/src/common/repositories/SubscriptionsRepository.ts +++ b/src/common/repositories/SubscriptionsRepository.ts @@ -40,7 +40,7 @@ export default class SubscriptionsRepository extends BaseRepository { /** * @description : Create a subscription */ - public async create(subscription: Subscription): Promise { + public async create(subscription: Subscription): Promise { if(subscription.type === "STANDARD") { const createArgs: Prisma.SubscriptionsCreateArgs = { @@ -56,15 +56,6 @@ export default class SubscriptionsRepository extends BaseRepository { uid: subscription.office!.uid, }, }, - seats: { - create: subscription.seats!.map(seat => ({ - user: { - connect: { - uid: seat.user!.uid, - }, - }, - })), - }, }, }; return this.model.create(createArgs); diff --git a/src/services/common/StripeService/StripeService.ts b/src/services/common/StripeService/StripeService.ts index 59c261f5..cae8d469 100644 --- a/src/services/common/StripeService/StripeService.ts +++ b/src/services/common/StripeService/StripeService.ts @@ -14,23 +14,35 @@ export default class StripeService { return this.client; } - public async createCheckoutSession(subscription: Subscription) { - const priceId = subscription.type === "STANDARD" ? this.variables.STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID : this.variables.STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID; - return this.client.checkout.sessions.create({ - mode: "subscription", - payment_method_types: ["card", "paypal"], - billing_address_collection: "auto", - line_items: [ - { - price: priceId, - quantity: subscription.nb_seats, - }, - ], - success_url: this.variables.STRIPE_PAYMENT_SUCCESS_URL, - cancel_url: this.variables.STRIPE_PAYMENT_CANCEL_URL, - metadata: { - subscription: JSON.stringify(subscription), - }, - }); - } -} \ No newline at end of file + public async createCheckoutSession(subscription: Subscription) { + const priceId = + subscription.type === "STANDARD" + ? this.variables.STRIPE_STANDARD_SUBSCRIPTION_PRICE_ID + : this.variables.STRIPE_UNLIMITED_SUBSCRIPTION_PRICE_ID; + return this.client.checkout.sessions.create({ + mode: "subscription", + payment_method_types: ["card", "paypal"], + billing_address_collection: "auto", + line_items: [ + { + price: priceId, + quantity: subscription.nb_seats, + }, + ], + 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", + }); + } +}