diff --git a/src/app/api/admin/SubscriptionsController.ts b/src/app/api/admin/SubscriptionsController.ts index f082ad9c..cbf50ed8 100644 --- a/src/app/api/admin/SubscriptionsController.ts +++ b/src/app/api/admin/SubscriptionsController.ts @@ -41,7 +41,10 @@ export default class SubscriptionsController extends ApiController { const subscriptionsEntities = await this.subscriptionsService.get(query); //Hydrate ressource with prisma entity - const subscriptions = Subscription.hydrateArray(subscriptionsEntities, { strategy: "excludeAll" }); + const subscriptions = Subscription.hydrateArray(subscriptionsEntities, { strategy: "excludeAll" }); + + console.log(subscriptions[0]?.seats); + //success this.httpSuccess(response, subscriptions); @@ -169,4 +172,43 @@ export default class SubscriptionsController extends ApiController { return; } } + + // /** + // * @description Update a subscription seats + // */ + // @Put("/api/v1/admin/subscriptions/:uid/seats", [authHandler, roleHandler]) + // protected async updateSubscriptionSeats(req: Request, response: Response) { + // try { + // const uid = req.params["uid"]; + // if (!uid) { + // this.httpBadRequest(response, "No uid provided"); + // return; + // } + + // const subscriptionFound = await this.subscriptionsService.getByUid(uid); + + // if (!subscriptionFound) { + // this.httpNotFoundRequest(response, "subscription not found"); + // return; + // } + + // //init Subscription resource with request body values + // const seatEntities = Seat.hydrateArray(req.body); + + // //call service to get prisma entity + // const subscriptionEntityUpdated = await this.subscriptionsService.update(uid, subscriptionEntity); + + // //Hydrate ressource with prisma entity + // const subscription = Subscription.hydrate(subscriptionEntityUpdated, { + // strategy: "excludeAll", + // }); + + // //success + // this.httpSuccess(response, subscription); + + // } catch (error) { + // this.httpInternalError(response, error); + // return; + // } + // } } diff --git a/src/app/api/idnot/UserController.ts b/src/app/api/idnot/UserController.ts index 78eaab70..3819ed6e 100644 --- a/src/app/api/idnot/UserController.ts +++ b/src/app/api/idnot/UserController.ts @@ -69,43 +69,44 @@ export default class UserController extends ApiController { this.httpUnauthorized(response, "Email not found"); return; } - let isSubscribed = false; - if (userHydrated.role?.name === "admin") { + let isSubscribed = false; + + const subscriptions = await this.subscriptionsService.get({ where: { office_uid: userHydrated.office_membership?.uid } }); + + if (!subscriptions || subscriptions.length === 0 || subscriptions[0]?.status === ESubscriptionStatus.INACTIVE) { + this.httpUnauthorized(response, "User not subscribed"); + isSubscribed = false; + return; + } + + if (subscriptions[0]?.type === EType.Unlimited) { isSubscribed = true; } else { - const subscriptions = await this.subscriptionsService.get({ where: { office_uid: userHydrated.office_membership?.uid } }); + const hasSeat = await this.subscriptionsService.get({ + where: { status: ESubscriptionStatus.ACTIVE, seats: { some: { user_uid: userHydrated.uid } } }, + }); - if (!subscriptions || subscriptions.length === 0 || subscriptions[0]?.status === ESubscriptionStatus.INACTIVE) { - this.httpUnauthorized(response, "User not subscribed"); - isSubscribed = false; - return; - } - - if (subscriptions[0]?.type === EType.Unlimited) { + if (hasSeat && hasSeat.length > 0) { isSubscribed = true; } else { - const hasSeat = await this.subscriptionsService.get({ - where: { status: ESubscriptionStatus.ACTIVE, seats: { some: { user_uid: userHydrated.uid } } }, - }); + const nbMaxSeats = subscriptions[0]!.nb_seats; - if (hasSeat && hasSeat.length > 0) { - isSubscribed = true; - } else { - const nbMaxSeats = subscriptions[0]!.nb_seats; + const nbCurrentSeats = await this.seatsService.get({ where: { subscription_uid: subscriptions[0]!.uid } }); - const nbCurrentSeats = await this.seatsService.get({ where: { subscription_uid: subscriptions[0]!.uid } }); - - //if nbMaxSeats < nbCurrentSeats, create a new seat for the user - if (nbMaxSeats > nbCurrentSeats.length) { - const seatAdded = await this.seatsService.create(user.uid, subscriptions[0]!.uid); - if (seatAdded) { - isSubscribed = true; - } + //if nbMaxSeats < nbCurrentSeats, create a new seat for the user + if (nbMaxSeats > nbCurrentSeats.length) { + const seatAdded = await this.seatsService.create(user.uid, subscriptions[0]!.uid); + if (seatAdded) { + isSubscribed = true; } } } } + if (userHydrated.role?.name === "admin") { + isSubscribed = true; + } + if (!isSubscribed) { this.httpUnauthorized(response, "User not subscribed"); return; diff --git a/src/common/databases/migrations/20240408143448_subscription_seats_date/migration.sql b/src/common/databases/migrations/20240408143448_subscription_seats_date/migration.sql new file mode 100644 index 00000000..d66ecc67 --- /dev/null +++ b/src/common/databases/migrations/20240408143448_subscription_seats_date/migration.sql @@ -0,0 +1,7 @@ +-- AlterTable +ALTER TABLE "seats" ADD COLUMN "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "updated_at" TIMESTAMP(3); + +-- AlterTable +ALTER TABLE "subscriptions" ADD COLUMN "created_at" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "updated_at" TIMESTAMP(3); diff --git a/src/common/databases/schema.prisma b/src/common/databases/schema.prisma index 06d8c782..9f21c34d 100644 --- a/src/common/databases/schema.prisma +++ b/src/common/databases/schema.prisma @@ -388,6 +388,8 @@ model Subscriptions { office Offices @relation(fields: [office_uid], references: [uid], onDelete: Cascade) office_uid String @db.VarChar(255) seats Seats[] + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt @@map("subscriptions") } @@ -397,6 +399,8 @@ model Seats { subscription_uid String @db.VarChar(255) user Users @relation(fields: [user_uid], references: [uid], onDelete: Cascade) user_uid String @db.VarChar(255) + created_at DateTime? @default(now()) + updated_at DateTime? @updatedAt @@map("seats") } diff --git a/src/common/repositories/SeatsRepository.ts b/src/common/repositories/SeatsRepository.ts index 3806fda2..4a3a255d 100644 --- a/src/common/repositories/SeatsRepository.ts +++ b/src/common/repositories/SeatsRepository.ts @@ -16,7 +16,7 @@ export default class SeatsRepository extends BaseRepository { } /** - * @description : Find many subscriptions + * @description : Find many seats */ public async findMany(query: Prisma.SeatsFindManyArgs) { query.take = Math.min(query.take || this.defaultFetchRows, this.maxFetchRows); @@ -25,7 +25,7 @@ export default class SeatsRepository extends BaseRepository { } /** - * @description : find unique subscription + * @description : find unique seat */ public async findOneByUid(uid: string, query?: Prisma.SeatsInclude): Promise { return this.model.findUnique({ @@ -37,7 +37,7 @@ export default class SeatsRepository extends BaseRepository { } /** - * @description : Create a subscription + * @description : Create a seat */ public async create(userUid: string, subscriptionUid: string): Promise { @@ -63,5 +63,16 @@ export default class SeatsRepository extends BaseRepository { } + /** + * @description : Delete a seat + */ + public async delete(uid: string) { + return this.model.delete({ + where: { + uid: uid, + }, + }); + } + } diff --git a/src/common/repositories/SubscriptionsRepository.ts b/src/common/repositories/SubscriptionsRepository.ts index 0b6fa624..4394495b 100644 --- a/src/common/repositories/SubscriptionsRepository.ts +++ b/src/common/repositories/SubscriptionsRepository.ts @@ -85,7 +85,25 @@ export default class SubscriptionsRepository extends BaseRepository { /** * @description : update given subscription */ - public async update(uid: string, subscription: Subscription): Promise { + public async update(uid: string, subscription: Subscription): Promise { + if(!subscription.type || subscription.type === ""){ + const updateArgs: Prisma.SubscriptionsUpdateArgs = { + where: { + uid: uid, + }, + data: { + seats:{ + deleteMany: {}, + createMany: { + data: subscription.seats?.map((seat) => ({ + user_uid: seat.user.uid || "", + })) ?? [], + }, + } + }, + }; + return this.model.update(updateArgs); + } if(subscription.type === "STANDARD") { const updateArgs: Prisma.SubscriptionsUpdateArgs = { diff --git a/src/services/admin/SeatsService/SeatsService.ts b/src/services/admin/SeatsService/SeatsService.ts index 77af21a0..f4f2dcbb 100644 --- a/src/services/admin/SeatsService/SeatsService.ts +++ b/src/services/admin/SeatsService/SeatsService.ts @@ -34,4 +34,12 @@ export default class SeatsService extends BaseService { return this.seatsRepository.create(subscriptionUid, userUid); } + /** + * @description : Delete a seat + * @throws {Error} If seat cannot be deleted + */ + public async delete(uid: string) { + return this.seatsRepository.delete(uid); + } + } diff --git a/src/services/admin/SubscriptionsService/SubscriptionsService.ts.ts b/src/services/admin/SubscriptionsService/SubscriptionsService.ts.ts index 0f311f03..3c44fd96 100644 --- a/src/services/admin/SubscriptionsService/SubscriptionsService.ts.ts +++ b/src/services/admin/SubscriptionsService/SubscriptionsService.ts.ts @@ -4,10 +4,11 @@ import { Service } from "typedi"; import { Prisma, Subscriptions } from "@prisma/client"; import SubscriptionsRepository from "@Repositories/SubscriptionsRepository"; import { Subscription } from "le-coffre-resources/dist/Admin"; +import SeatsService from "../SeatsService/SeatsService"; @Service() export default class SubscriptionsService extends BaseService { - constructor(private subscriptionsRepository: SubscriptionsRepository) { + constructor(private subscriptionsRepository: SubscriptionsRepository, private seatsService: SeatsService) { super(); } @@ -39,7 +40,18 @@ export default class SubscriptionsService extends BaseService { * @description : Modify a subscription * @throws {Error} If subscription cannot be modified */ - public async update(uid: string, subscriptionEntity: Subscription): Promise { + public async update(uid: string, subscriptionEntity: Subscription): Promise { + console.log(subscriptionEntity); + + if(subscriptionEntity.type === "STANDARD"){ + const seats = await this.seatsService.get({ where: { subscription: { uid: uid } }, orderBy: {created_at: 'asc'} }); + const seatsToKeep = subscriptionEntity.nb_seats; + const seatsToDelete = seats.slice(seatsToKeep); + + for (const seat of seatsToDelete) { + await this.seatsService.delete(seat.uid); + } + } return this.subscriptionsRepository.update(uid, subscriptionEntity); }