diff --git a/apps/Frontend/src/components/claims/claim-form.tsx b/apps/Frontend/src/components/claims/claim-form.tsx index 2ca5049..08e59f5 100644 --- a/apps/Frontend/src/components/claims/claim-form.tsx +++ b/apps/Frontend/src/components/claims/claim-form.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, useRef } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { @@ -39,7 +39,6 @@ import { } from "@repo/db/types"; import { Decimal } from "decimal.js"; import { - COMBO_BUTTONS, mapPricesForForm, applyComboToForm, getDescriptionForCode, @@ -257,6 +256,16 @@ export function ClaimForm({ setForm({ ...form, serviceLines: updatedLines }); }; + // for serviceLine rows, to auto scroll when it got updated by combo buttons and all. + const rowRefs = useRef<(HTMLDivElement | null)[]>([]); + + const scrollToLine = (index: number) => { + const el = rowRefs.current[index]; + if (el) { + el.scrollIntoView({ behavior: "smooth", block: "start" }); + } + }; + // Map Price function const onMapPrice = () => { setForm((prev) => @@ -573,7 +582,11 @@ export function ClaimForm({ return (
{ + rowRefs.current[i] = el; + if (!el) rowRefs.current.splice(i, 1); + }} + className="scroll-mt-28 grid grid-cols-[1.5fr,0.5fr,1fr,1fr,1fr,1fr,1fr] gap-1 mb-2 items-center" >
))} -
+
-
{/* File Upload Section */} diff --git a/apps/Frontend/src/utils/procedureCombos.ts b/apps/Frontend/src/utils/procedureCombos.ts index 0082b78..ab83d93 100644 --- a/apps/Frontend/src/utils/procedureCombos.ts +++ b/apps/Frontend/src/utils/procedureCombos.ts @@ -1,6 +1,6 @@ export const PROCEDURE_COMBOS: Record< string, - { id: string; label: string; codes: string[] } + { id: string; label: string; codes: string[]; toothNumbers?: (string | null)[] } > = { childRecall: { id: "childRecall", @@ -16,6 +16,7 @@ export const PROCEDURE_COMBOS: Record< id: "adultRecall", label: "Adult Recall", codes: ["D0120", "D0220", "D0230", "D0274", "D1110"], + toothNumbers: [null, "9", "24", null, null], // only these two need values }, newChildPatient: { id: "newChildPatient", diff --git a/apps/Frontend/src/utils/procedureCombosMapping.ts b/apps/Frontend/src/utils/procedureCombosMapping.ts index b971f44..2b21564 100644 --- a/apps/Frontend/src/utils/procedureCombosMapping.ts +++ b/apps/Frontend/src/utils/procedureCombosMapping.ts @@ -251,7 +251,10 @@ export function applyComboToForm( procedureCode: code, procedureDate: lineDate, oralCavityArea: original?.oralCavityArea ?? "", - toothNumber: original?.toothNumber ?? "", + toothNumber: + preset.toothNumbers?.[j] ?? + original?.toothNumber ?? + "", toothSurface: original?.toothSurface ?? "", totalBilled: price, totalAdjusted: new Decimal(0), diff --git a/apps/PdfService/main.py b/apps/PdfService/main.py index 88d21cb..0ee840d 100644 --- a/apps/PdfService/main.py +++ b/apps/PdfService/main.py @@ -4,35 +4,68 @@ import re app = Flask(__name__) +DOB_RE = re.compile(r'(?= 8): - member_id = line - name_lines = [] - j = i + 1 - while j < len(lines) and not re.match(r"\d{1,2}/\d{1,2}/\d{4}", lines[j]): - name_lines.append(lines[j]) - j += 1 - name = " ".join(name_lines).strip() - if j < len(lines): - dob = lines[j].strip() + # 1) Find the first plausible member ID (8–14 digits) + id_idx = -1 + for i, line in enumerate(lines): + if ID_RE.match(line): + member_id = line + id_idx = i break - return { + if id_idx == -1: + return jsonify({"memberId": "", "name": "", "dob": ""}) + + # 2) Scan forward to collect name + DOB; handle both same-line and next-line cases + collected = [] + j = id_idx + 1 + while j < len(lines): + low = lines[j].lower() + if any(sw in low for sw in STOP_WORDS): + break + collected.append(lines[j]) + # If we already found a DOB, we can stop early + if DOB_RE.search(lines[j]): + break + j += 1 + + # Flatten the collected chunk to search for a date (works if DOB is on same line or next) + blob = " ".join(collected).strip() + + m = DOB_RE.search(blob) + if m: + dob = m.group(0) + # name is everything before the date within the same blob + name = blob[:m.start()].strip() + else: + # fallback: if we didn't find a date, assume first collected line(s) are name + name = blob + + return jsonify({ "memberId": member_id, "name": name, "dob": dob - } + }) if __name__ == "__main__": app.run(port=5001)