From 4ba3077a9ba8b9af72d2ca3d3a5d57075b901d60 Mon Sep 17 00:00:00 2001 From: Ly Tuan Kiet Date: Mon, 9 Dec 2024 18:43:03 +0700 Subject: [PATCH] refactor: enhance refund ticket logic and role-based access control - Updated the RefundTicket schema to allow both customers and center mentors to request refunds, improving flexibility in refund processing. - Refined bank detail checks to differentiate between customers and center mentors, ensuring appropriate handling of bank information. - Implemented special handling for center mentors to always allow full refunds, enhancing user experience. - Improved error messages and validation checks throughout the refund process for better clarity and user guidance. --- src/Quiz/quiz.schema.ts | 1 - src/RefundTicket/refundticket.schema.ts | 77 ++++++++++++++++++------- 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/src/Quiz/quiz.schema.ts b/src/Quiz/quiz.schema.ts index 1f2d902..13e71e2 100644 --- a/src/Quiz/quiz.schema.ts +++ b/src/Quiz/quiz.schema.ts @@ -212,7 +212,6 @@ export class QuizSchema extends PothosSchema { 'centerMentorId', 'createdAt', 'updatedAt', - 'service', ]), required: true, }), diff --git a/src/RefundTicket/refundticket.schema.ts b/src/RefundTicket/refundticket.schema.ts index 5c1abcd..584ca43 100644 --- a/src/RefundTicket/refundticket.schema.ts +++ b/src/RefundTicket/refundticket.schema.ts @@ -122,14 +122,20 @@ export class RefundTicketSchema extends PothosSchema { if (ctx.isSubscription) { throw new Error('Subscription is not allowed') } - if (ctx.http.me?.role !== Role.CUSTOMER) { - throw new Error('Only customers can request refund') + + // Check if the user is a customer or a center mentor + if (ctx.http.me?.role !== Role.CUSTOMER && ctx.http.me?.role !== Role.CENTER_MENTOR) { + throw new Error('Only customers and center mentors can request refund') } - // check if bank bin and bank account number is exists else throw error - if (!ctx.http.me?.bankBin || !ctx.http.me?.bankAccountNumber) { - throw new Error('Bank bin and bank account number are required, please update your profile first') + + // Check bank details for non-center mentors + if (ctx.http.me?.role !== Role.CENTER_MENTOR) { + if (!ctx.http.me?.bankBin || !ctx.http.me?.bankAccountNumber) { + throw new Error('Bank bin and bank account number are required, please update your profile first') + } } - // check if order exists + + // Check if order exists const order = await this.prisma.order.findUnique({ where: { id: args.orderId }, include: { @@ -139,49 +145,78 @@ export class RefundTicketSchema extends PothosSchema { if (!order) { throw new Error('Order not found') } - // check if order status is PAID + + // Check if order status is PAID if (order.status !== OrderStatus.PAID) { throw new Error('Order is not paid') } - // check if order total is not null + + // Check if order total is not null if (!order.total || order.total === 0) { throw new Error('Order total is null or free') } + if (order.refundTicket) { throw new Error('Refund ticket already exists') } - // calculate refund amount based on order time: if order is less than 24 hours, refund 100%, if more than 24 hours, less than 48 hours, refund 50%, if more than 72 hours, cannot refund + + // Calculate refund amount based on order time const now = DateTimeUtils.now() const orderDate = DateTimeUtils.fromDate(order.createdAt) const diffTime = Math.abs(now.diff(orderDate).toMillis()) const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + let refundAmount = 0 - if (diffDays < 1) { + + // Special handling for center mentors - full refund always allowed + if (ctx.http.me?.role === Role.CENTER_MENTOR) { refundAmount = order.total - } else if (diffDays < 3) { - refundAmount = order.total * 0.5 + } else { + // Existing refund logic for customers + if (diffDays < 1) { + refundAmount = order.total + } else if (diffDays < 3) { + refundAmount = order.total * 0.5 + } } + if (refundAmount === 0) { throw new Error('Cannot refund after 3 days') } - // create refund ticket - // get bank name from bank bin from banks.json - // biome-ignore lint/suspicious/noExplicitAny: - const bank = banks.data.find((bank: any) => bank.bin === ctx.http.me?.bankBin) - if (!bank) { - throw new Error('Bank not found') + + // Prepare bank details + let bankBin = ctx.http.me?.bankBin + let bankAccountNumber = ctx.http.me?.bankAccountNumber + let bankName = '' + + // For center mentors, use a default or system bank account + if (ctx.http.me?.role === Role.CENTER_MENTOR) { + // You might want to replace this with a specific system bank account + bankBin = 'SYSTEM_MENTOR_REFUND' + bankAccountNumber = 'SYSTEM_MENTOR_ACCOUNT' + bankName = 'Center Mentor Refund Account' + } else { + // Existing bank lookup for customers + const bank = banks.data.find((bank: any) => bank.bin === bankBin) + if (!bank) { + throw new Error('Bank not found') + } + bankName = bank.name } + + // Create refund ticket const refundTicket = await this.prisma.refundTicket.create({ data: { orderId: order.id, status: RefundTicketStatus.PENDING, amount: refundAmount, reason: args.reason, - bankBin: ctx.http.me?.bankBin, - bankAccountNumber: ctx.http.me?.bankAccountNumber, - bankName: bank.name, + bankBin: bankBin, + bankAccountNumber: bankAccountNumber, + bankName: bankName, }, }) + return refundTicket }, }),