135 lines
3.8 KiB
TypeScript
Executable File
135 lines
3.8 KiB
TypeScript
Executable File
import {
|
|
Claim,
|
|
ClaimStatus,
|
|
ClaimWithServiceLines,
|
|
InsertClaim,
|
|
UpdateClaim,
|
|
} from "@repo/db/types";
|
|
import { prisma as db } from "@repo/db/client";
|
|
|
|
export interface IStorage {
|
|
getClaim(id: number): Promise<Claim | undefined>;
|
|
getActiveClaimByAppointmentId(appointmentId: number): Promise<ClaimWithServiceLines | null>;
|
|
getRecentClaimsByPatientId(
|
|
patientId: number,
|
|
limit: number,
|
|
offset: number
|
|
): Promise<ClaimWithServiceLines[]>;
|
|
getTotalClaimCountByPatient(patientId: number): Promise<number>;
|
|
getClaimsByAppointmentId(appointmentId: number): Promise<Claim[]>;
|
|
getRecentClaims(limit: number, offset: number): Promise<Claim[]>;
|
|
getTotalClaimCount(): Promise<number>;
|
|
createClaim(claim: InsertClaim): Promise<Claim>;
|
|
updateClaim(id: number, updates: UpdateClaim): Promise<Claim>;
|
|
updateClaimStatus(id: number, status: ClaimStatus): Promise<Claim>;
|
|
deleteClaim(id: number): Promise<void>;
|
|
getAppointmentIdsWithClaimNumbers(ids: number[]): Promise<Set<number>>;
|
|
}
|
|
|
|
export const claimsStorage: IStorage = {
|
|
async getClaim(id: number): Promise<Claim | undefined> {
|
|
const claim = await db.claim.findUnique({ where: { id } });
|
|
return claim ?? undefined;
|
|
},
|
|
|
|
async getRecentClaimsByPatientId(
|
|
patientId: number,
|
|
limit: number,
|
|
offset: number
|
|
): Promise<ClaimWithServiceLines[]> {
|
|
return db.claim.findMany({
|
|
where: { patientId },
|
|
orderBy: { createdAt: "desc" },
|
|
skip: offset,
|
|
take: limit,
|
|
include: {
|
|
serviceLines: true,
|
|
staff: true,
|
|
claimFiles: true,
|
|
},
|
|
});
|
|
},
|
|
|
|
async getTotalClaimCountByPatient(patientId: number): Promise<number> {
|
|
return db.claim.count({
|
|
where: { patientId },
|
|
});
|
|
},
|
|
|
|
async getActiveClaimByAppointmentId(appointmentId: number): Promise<ClaimWithServiceLines | null> {
|
|
return db.claim.findFirst({
|
|
where: {
|
|
appointmentId,
|
|
status: { notIn: ["CANCELLED"] },
|
|
},
|
|
orderBy: { createdAt: "desc" },
|
|
include: { serviceLines: true, claimFiles: true, staff: true },
|
|
}) as Promise<ClaimWithServiceLines | null>;
|
|
},
|
|
|
|
async getClaimsByAppointmentId(appointmentId: number): Promise<Claim[]> {
|
|
return await db.claim.findMany({ where: { appointmentId } });
|
|
},
|
|
|
|
async getRecentClaims(
|
|
limit: number,
|
|
offset: number
|
|
): Promise<ClaimWithServiceLines[]> {
|
|
return db.claim.findMany({
|
|
orderBy: { createdAt: "desc" },
|
|
skip: offset,
|
|
take: limit,
|
|
include: { serviceLines: true, staff: true, claimFiles: true },
|
|
});
|
|
},
|
|
|
|
async getTotalClaimCount(): Promise<number> {
|
|
return db.claim.count();
|
|
},
|
|
|
|
async createClaim(claim: InsertClaim): Promise<Claim> {
|
|
return await db.claim.create({ data: claim as Claim });
|
|
},
|
|
|
|
async updateClaim(id: number, updates: UpdateClaim): Promise<Claim> {
|
|
try {
|
|
return await db.claim.update({
|
|
where: { id },
|
|
data: updates,
|
|
});
|
|
} catch (err) {
|
|
throw new Error(`Claim with ID ${id} not found`);
|
|
}
|
|
},
|
|
|
|
async updateClaimStatus(id: number, status: ClaimStatus): Promise<Claim> {
|
|
const existing = await db.claim.findUnique({ where: { id } });
|
|
if (!existing) {
|
|
throw new Error("Claim not found");
|
|
}
|
|
|
|
return db.claim.update({
|
|
where: { id },
|
|
data: { status },
|
|
});
|
|
},
|
|
|
|
async deleteClaim(id: number): Promise<void> {
|
|
try {
|
|
await db.claim.delete({ where: { id } });
|
|
} catch (err) {
|
|
throw new Error(`Claim with ID ${id} not found`);
|
|
}
|
|
},
|
|
|
|
async getAppointmentIdsWithClaimNumbers(ids: number[]): Promise<Set<number>> {
|
|
if (!ids.length) return new Set();
|
|
const rows = await db.claim.findMany({
|
|
where: { appointmentId: { in: ids }, claimNumber: { not: null } },
|
|
select: { appointmentId: true },
|
|
distinct: ["appointmentId"],
|
|
});
|
|
return new Set(rows.map((r) => r.appointmentId));
|
|
},
|
|
};
|