feat: add CCA claim submission with Selenium automation

- Add CCA claim submit Selenium worker (login, fill form, attach docs, submit, capture dashboard PDF)
- Add CCA fee schedule (procedureCodesMH.json renamed, procedureCodesCCA.json added with D6010)
- Add backend route /api/claims/cca-claim, processor, and Selenium client
- Wire CCA claim handler in claims-page with job tracking and PDF preview popup
- Add insurance type dropdown in claim form (same options as eligibility page)
- Auto-populate insurance type from patient.insuranceProvider in claim form and patient edit form
- Map fee schedule by insurance type in Map Price button and combo buttons
- Fix CCA login speed (remove fixed sleeps, use readyState check)
- Fix CCA claim DOB format bug (was sending MM-DD-YYYY, now sends YYYY-MM-DD)
- Fix npiProviderId not saved for CCA claims
- Change Add Service → CCA Claim button (blue), MH → MH Claim

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gitead
2026-05-22 13:34:03 -04:00
parent 58b2e4af93
commit 0e664e4813
21 changed files with 4768 additions and 77 deletions

View File

@@ -145,12 +145,28 @@ export default function ClaimsPage() {
if (!pendingClaimJobId) return;
if (jobStatus === "completed" && jobResult) {
setPendingClaimJobId(null);
handleMHSeleniumPdfDownload(
jobResult,
pendingClaimMeta.current.patientId,
pendingClaimMeta.current.groupKey
);
queryClient.invalidateQueries({ queryKey: ["claims-recent"] });
// CCA result: pdfFileId is already saved by the processor — open preview directly
if (jobResult.pdfFileId) {
setPreviewPdfId(jobResult.pdfFileId);
setPreviewFallbackFilename(jobResult.pdfFilename ?? `cca_claim_${jobResult.claimNumber ?? "unknown"}.pdf`);
setPreviewOpen(true);
dispatch(setTaskStatus({
key: "claimSubmit",
status: "success",
message: jobResult.claimNumber
? `CCA claim submitted — Encounter ID: ${jobResult.claimNumber}`
: "CCA claim submitted successfully",
}));
} else {
// MH claim: needs PDF download step
handleMHSeleniumPdfDownload(
jobResult,
pendingClaimMeta.current.patientId,
pendingClaimMeta.current.groupKey
);
}
} else if (jobStatus === "failed") {
setPendingClaimJobId(null);
dispatch(setTaskStatus({ key: "claimSubmit", status: "error", message: "Selenium job failed" }));
@@ -409,6 +425,35 @@ export default function ClaimsPage() {
}
};
// CCA claim selenium handler
const handleCCAClaimSubmitSelenium = async (data: any) => {
const formData = new FormData();
formData.append("data", JSON.stringify(data));
if (socketId) formData.append("socketId", socketId);
const uploadedFiles: File[] = data.uploadedFiles ?? [];
uploadedFiles.forEach((file: File) => {
if (file.type === "application/pdf") {
formData.append("pdfs", file);
} else if (file.type.startsWith("image/")) {
formData.append("images", file);
}
});
try {
dispatch(setTaskStatus({ key: "claimSubmit", status: "pending", message: "Submitting CCA claim..." }));
const response = await apiRequest("POST", "/api/claims/cca-claim", formData);
const result = await response.json();
if (result.error) throw new Error(result.error);
// Track job so the completion useEffect fires when Selenium finishes
pendingClaimMeta.current = { patientId: selectedPatientId, groupKey: "INSURANCE_CLAIM" };
setPendingClaimJobId(result.jobId);
dispatch(setTaskStatus({ key: "claimSubmit", status: "pending", message: "CCA claim queued. Awaiting Selenium..." }));
toast({ title: "CCA Claim queued", description: "Selenium is processing the claim.", variant: "default" });
} catch (error: any) {
dispatch(setTaskStatus({ key: "claimSubmit", status: "error", message: error.message || "CCA claim failed" }));
toast({ title: "CCA Claim error", description: error.message || "An error occurred.", variant: "destructive" });
}
};
// 5. selenium pdf download handler
const handleMHSeleniumPdfDownload = async (
data: any,
@@ -620,6 +665,7 @@ export default function ClaimsPage() {
onHandleUpdatePatient={handleUpdatePatient}
onHandleForMHSeleniumClaim={handleMHClaimSubmitSelenium}
onHandleForMHSeleniumClaimPreAuth={handleMHClaimPreAuthSubmitSelenium}
onHandleForCCASeleniumClaim={handleCCAClaimSubmitSelenium}
/>
)}