import { InsertPayment, Payment, PaymentWithExtras, UpdatePayment, } from "@repo/db/types"; import { prisma as db } from "@repo/db/client"; export interface IStorage { // Payment methods: getPayment(id: number): Promise; createPayment(data: InsertPayment): Promise; updatePayment(id: number, updates: UpdatePayment): Promise; updatePaymentStatus( id: number, updates: UpdatePayment, updatedById?: number ): Promise; deletePayment(id: number, userId: number): Promise; getPaymentById(id: number): Promise; getRecentPaymentsByPatientId( patientId: number, limit: number, offset: number ): Promise; getTotalPaymentCountByPatient(patientId: number): Promise; getPaymentsByClaimId(claimId: number): Promise; getRecentPayments( limit: number, offset: number ): Promise; getPaymentsByDateRange(from: Date, to: Date): Promise; getTotalPaymentCount(): Promise; } export const paymentsStorage: IStorage = { // Payment Methods async getPayment(id: number): Promise { const payment = await db.payment.findUnique({ where: { id } }); return payment ?? undefined; }, async createPayment(payment: InsertPayment): Promise { return db.payment.create({ data: payment as Payment }); }, async updatePayment(id: number, updates: UpdatePayment): Promise { const existing = await db.payment.findFirst({ where: { id } }); if (!existing) { throw new Error("Payment not found"); } return db.payment.update({ where: { id }, data: updates, }); }, async updatePaymentStatus( id: number, updates: UpdatePayment, updatedById?: number ): Promise { const existing = await db.payment.findFirst({ where: { id } }); if (!existing) { throw new Error("Payment not found"); } const data: any = { ...updates }; if (typeof updatedById === "number") data.updatedById = updatedById; return db.payment.update({ where: { id }, data, }); }, async deletePayment(id: number, userId: number): Promise { const existing = await db.payment.findFirst({ where: { id, userId } }); if (!existing) { throw new Error("Not authorized or payment not found"); } await db.payment.delete({ where: { id } }); }, async getRecentPaymentsByPatientId( patientId: number, limit: number, offset: number ): Promise { const payments = await db.payment.findMany({ where: { patientId }, orderBy: { createdAt: "desc" }, skip: offset, take: limit, include: { claim: { include: { serviceLines: true, }, }, serviceLines: true, serviceLineTransactions: { include: { serviceLine: true, }, }, updatedBy: true, patient: true, }, }); return payments.map((payment) => ({ ...payment, patientName: payment.claim?.patientName ?? "", paymentDate: payment.createdAt, paymentMethod: payment.serviceLineTransactions[0]?.method ?? "OTHER", })); }, async getTotalPaymentCountByPatient(patientId: number): Promise { return db.payment.count({ where: { patientId }, }); }, async getPaymentById(id: number): Promise { const payment = await db.payment.findFirst({ where: { id }, include: { claim: { include: { serviceLines: true, }, }, serviceLines: true, serviceLineTransactions: { include: { serviceLine: true, }, }, updatedBy: true, patient: true, }, }); if (!payment) return null; return { ...payment, patientName: payment.claim?.patientName ?? "", paymentDate: payment.createdAt, paymentMethod: payment.serviceLineTransactions[0]?.method ?? "OTHER", }; }, async getPaymentsByClaimId( claimId: number ): Promise { const payment = await db.payment.findFirst({ where: { claimId }, include: { claim: { include: { serviceLines: true, }, }, serviceLines: true, serviceLineTransactions: { include: { serviceLine: true, }, }, updatedBy: true, patient: true, }, }); if (!payment) return null; return { ...payment, patientName: payment.claim?.patientName ?? "", paymentDate: payment.createdAt, paymentMethod: payment.serviceLineTransactions[0]?.method ?? "OTHER", }; }, async getRecentPayments( limit: number, offset: number ): Promise { const payments = await db.payment.findMany({ orderBy: { createdAt: "desc" }, skip: offset, take: limit, include: { claim: { include: { serviceLines: true, }, }, serviceLines: true, serviceLineTransactions: { include: { serviceLine: true, }, }, updatedBy: true, patient: true, }, }); return payments.map((payment) => ({ ...payment, patientName: payment.claim?.patientName ?? "", paymentDate: payment.createdAt, paymentMethod: payment.serviceLineTransactions[0]?.method ?? "OTHER", })); }, async getPaymentsByDateRange( from: Date, to: Date ): Promise { const payments = await db.payment.findMany({ where: { createdAt: { gte: from, lte: to, }, }, orderBy: { createdAt: "desc" }, include: { claim: { include: { serviceLines: true, }, }, serviceLines: true, serviceLineTransactions: { include: { serviceLine: true, }, }, updatedBy: true, patient: true, }, }); return payments.map((payment) => ({ ...payment, patientName: payment.claim?.patientName ?? "", paymentDate: payment.createdAt, paymentMethod: payment.serviceLineTransactions[0]?.method ?? "OTHER", })); }, async getTotalPaymentCount(): Promise { return db.payment.count(); }, };