fix: D0140 claim sync, schedule column prefill, multi-appt, DentaQuest OTP session
- Fix Express route ordering in appointments-procedures so /prefill-from-appointment is matched before /:id (D0140 and other codes now always reach the claim) - claim-form: always fetch AppointmentProcedure records when an existing claim loads so post-save procedure edits (e.g. adding D0140) are reflected immediately - appointments-page: replace sessionStorage with React state (newApptPrefill) for slot-click prefill so columns B-F correctly carry their staffId into the form - add-appointment-modal / appointment-form: thread prefillData prop; add NewAppointmentPrefill interface; useEffect applies values via setValue - appointments upsert: remove per-patient dedup so the same patient can have multiple appointments on the same day in the same column - DentaQuest / TuftsSCO: navigate to about:blank and minimize instead of quit_driver after each run — session cookie stays in memory so OTP is only required once per app startup, not on every eligibility or claim check Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -331,26 +331,54 @@ export function ClaimForm({
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// Restore service lines
|
||||
const mappedLines = (claim.serviceLines ?? []).map((sl: any) => ({
|
||||
procedureCode: sl.procedureCode ?? "",
|
||||
procedureDate: sl.procedureDate
|
||||
? String(sl.procedureDate).split("T")[0]
|
||||
: claimDate,
|
||||
quad: sl.quad ?? "",
|
||||
arch: sl.arch ?? "",
|
||||
toothNumber: sl.toothNumber ?? "",
|
||||
toothSurface: sl.toothSurface ?? "",
|
||||
totalBilled: new Decimal(Number(sl.totalBilled ?? 0)),
|
||||
totalAdjusted: new Decimal(Number(sl.totalAdjusted ?? 0)),
|
||||
totalPaid: new Decimal(Number(sl.totalPaid ?? 0)),
|
||||
}));
|
||||
// Prefer AppointmentProcedure records for service lines — they reflect any
|
||||
// updates the user made in the Select Procedure dialog after the claim was saved.
|
||||
let serviceLines: InputServiceLine[] = [];
|
||||
try {
|
||||
const procRes = await apiRequest(
|
||||
"GET",
|
||||
`/api/appointment-procedures/prefill-from-appointment/${appointmentId}`,
|
||||
);
|
||||
if (procRes.ok) {
|
||||
const procData = await procRes.json();
|
||||
if ((procData.procedures || []).length > 0) {
|
||||
serviceLines = (procData.procedures as any[]).map((p) => ({
|
||||
procedureCode: p.procedureCode ?? "",
|
||||
procedureDate: claimDate || serviceDate,
|
||||
quad: p.quad || "",
|
||||
arch: p.arch || "",
|
||||
toothNumber: p.toothNumber || "",
|
||||
toothSurface: p.toothSurface || "",
|
||||
totalBilled: new Decimal(Number(p.fee ?? 0)),
|
||||
totalAdjusted: new Decimal(0),
|
||||
totalPaid: new Decimal(0),
|
||||
}));
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
// Fall back to the claim's own service lines if no AppointmentProcedure records exist
|
||||
if (serviceLines.length === 0) {
|
||||
serviceLines = (claim.serviceLines ?? []).map((sl: any) => ({
|
||||
procedureCode: sl.procedureCode ?? "",
|
||||
procedureDate: sl.procedureDate
|
||||
? String(sl.procedureDate).split("T")[0]
|
||||
: claimDate,
|
||||
quad: sl.quad ?? "",
|
||||
arch: sl.arch ?? "",
|
||||
toothNumber: sl.toothNumber ?? "",
|
||||
toothSurface: sl.toothSurface ?? "",
|
||||
totalBilled: new Decimal(Number(sl.totalBilled ?? 0)),
|
||||
totalAdjusted: new Decimal(Number(sl.totalAdjusted ?? 0)),
|
||||
totalPaid: new Decimal(Number(sl.totalPaid ?? 0)),
|
||||
}));
|
||||
}
|
||||
|
||||
setForm((prev) => ({
|
||||
...prev,
|
||||
claimId: claim.id,
|
||||
serviceDate: claimDate || prev.serviceDate,
|
||||
serviceLines: mappedLines.length > 0 ? mappedLines : prev.serviceLines,
|
||||
serviceLines: serviceLines.length > 0 ? serviceLines : prev.serviceLines,
|
||||
remarks: claim.remarks ?? "",
|
||||
missingTeethStatus: (claim.missingTeethStatus as MissingTeethStatus) ?? "No_missing",
|
||||
missingTeeth: (claim.missingTeeth as Record<string, "X" | "O">) ?? {},
|
||||
@@ -2168,10 +2196,10 @@ export function ClaimForm({
|
||||
</h3>
|
||||
{proceduresOnly ? (
|
||||
<div className="flex justify-center gap-3">
|
||||
<Button className="w-40" variant="default" onClick={handleProceduresSave}>
|
||||
<Button className="w-40" variant="default" onClick={() => runWithPriceCheck(handleProceduresSave)}>
|
||||
Save Procedures
|
||||
</Button>
|
||||
<Button className="w-40" variant="secondary" onClick={handleProceduresUpdate}>
|
||||
<Button className="w-40" variant="secondary" onClick={() => runWithPriceCheck(handleProceduresUpdate)}>
|
||||
Update & Resubmit
|
||||
</Button>
|
||||
<Button className="w-28" variant="destructive" onClick={handleProceduresVoid}>
|
||||
|
||||
Reference in New Issue
Block a user