import type { Payment, Prisma } from "@prisma/client"; import dayjs from "@calcom/dayjs"; import prisma from "@calcom/prisma"; import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; import { getPaymentAppData } from "../getPaymentAppData"; import { handlePaymentRefund } from "./handlePaymentRefund"; import { RefundPolicy } from "./types"; export const processPaymentRefund = async ({ booking, teamId, }: { booking: { startTime: Date; endTime: Date; payment: Payment[]; eventType: { owner?: { id: number; } | null; metadata?: Prisma.JsonValue; } | null; }; teamId?: number | null; }) => { const { startTime, eventType, payment } = booking; if (!teamId && !eventType?.owner) return; const successPayment = payment.find((p) => p.success); if (!successPayment) return; const eventTypeMetadata = EventTypeMetaDataSchema.parse(eventType?.metadata); const appData = getPaymentAppData({ currency: successPayment.currency, metadata: eventTypeMetadata, price: successPayment.amount, }); if (!appData?.refundPolicy || appData.refundPolicy === RefundPolicy.NEVER) return; const credentialWhereClause: Prisma.CredentialFindManyArgs["where"] = { appId: successPayment.appId, }; if (eventType?.owner) { credentialWhereClause.userId = eventType.owner.id; } else if (teamId) { credentialWhereClause.teamId = teamId; } const paymentAppCredentials = await prisma.credential.findMany({ where: credentialWhereClause, select: { key: true, appId: true, app: { select: { categories: true, dirName: true, }, }, }, }); const paymentAppCredential = paymentAppCredentials.find((credential) => { return credential.appId === successPayment.appId; }); if (!paymentAppCredential) return; const { refundPolicy, refundCountCalendarDays, refundDaysCount } = appData; //refundDaysCount would always be present in case DAYS is selected, but adding it in AND jut for type safety if (refundPolicy === RefundPolicy.DAYS && refundDaysCount) { const refundDeadline = refundCountCalendarDays === true ? dayjs(startTime).subtract(refundDaysCount, "days") : // businessDaysSubtract exists on extended dayjs instance, but ts is messing up // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore dayjs(startTime).businessDaysSubtract(refundDaysCount); if (dayjs().isAfter(refundDeadline)) return; } await handlePaymentRefund(successPayment.id, paymentAppCredential); };