Files
DentalManagementMH06/apps/Frontend/src/components/reports/report-config.tsx
Gitead 7360b1930b feat: add provider column, commission tracking, and report provider filter
- Claims & Payments: save npiProviderId when submitting MH claim; sync between claim and payment on update
- Claims table: add Provider column showing rendering provider name
- Payments table: add Provider column + purple Commissioned badge on status
- Claim edit modal: add Rendering Provider dropdown (defaults to Mary Scannell)
- Payment edit modal: add Rendering Provider dropdown + Commissioned metadata display
- Reports page: add Provider filter dropdown (dynamic from NPI providers settings)
- Reports page: remove Collections by Doctor report type and Select Doctor dropdown
- Commission section: new section in reports page with date range + provider filter, shows eligible paid claims/payments per provider, multi-select checkboxes, Pay Commission modal with print + save, marks payments as commissioned so they are excluded from future cycles
- DB: add CommissionBatch and CommissionBatchItem tables; backfill Payment.npiProviderId from linked claims
- Backend: PATCH /api/payments/:id/provider syncs to linked claim; PUT /api/claims/:id syncs to linked payment; new /api/commissions routes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 23:51:39 -04:00

158 lines
4.8 KiB
TypeScript
Executable File

import React from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Calendar } from "lucide-react";
import { formatLocalDate, parseLocalDate } from "@/utils/dateUtils";
import { DateInput } from "@/components/ui/dateInput";
import { useQuery } from "@tanstack/react-query";
import { apiRequest } from "@/lib/queryClient";
import { NpiProvider } from "@repo/db/types";
type ReportType =
| "patients_with_balance"
| "patients_no_balance"
| "monthly_collections"
| "procedure_codes_by_doctor"
| "payment_methods"
| "insurance_vs_patient_payments"
| "aging_report";
export default function ReportConfig({
startDate,
endDate,
setStartDate,
setEndDate,
selectedReportType,
setSelectedReportType,
npiProviderId,
setNpiProviderId,
}: {
startDate: string;
endDate: string;
setStartDate: (s: string) => void;
setEndDate: (s: string) => void;
selectedReportType: ReportType;
setSelectedReportType: (r: ReportType) => void;
npiProviderId: number | null;
setNpiProviderId: (id: number | null) => void;
}) {
let startDateObj: Date | null = null;
if (startDate) {
try { startDateObj = parseLocalDate(startDate); } catch { startDateObj = null; }
}
let endDateObj: Date | null = null;
if (endDate) {
try { endDateObj = parseLocalDate(endDate); } catch { endDateObj = null; }
}
const { data: npiProviders = [] } = useQuery<NpiProvider[]>({
queryKey: ["/api/npiProviders/"],
queryFn: async () => {
const res = await apiRequest("GET", "/api/npiProviders/");
return res.json();
},
staleTime: 60_000,
});
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Calendar className="h-5 w-5" /> Report Configuration
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="text-sm text-gray-500">
Choose the report type, date range, and provider.
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div>
<DateInput
label="Start Date"
value={startDateObj}
onChange={(d) => setStartDate(d ? formatLocalDate(d) : "")}
disableFuture
/>
</div>
<div>
<DateInput
label="End Date"
value={endDateObj}
onChange={(d) => setEndDate(d ? formatLocalDate(d) : "")}
disableFuture
/>
</div>
<div className="space-y-2">
<Label>Provider</Label>
<Select
value={npiProviderId?.toString() ?? "all"}
onValueChange={(v) =>
setNpiProviderId(v === "all" ? null : Number(v))
}
>
<SelectTrigger>
<SelectValue placeholder="All Providers" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All Providers</SelectItem>
{npiProviders.map((p) => (
<SelectItem key={p.id} value={p.id.toString()}>
{p.providerName}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="report-type">Report Type</Label>
<Select
value={selectedReportType}
onValueChange={(v) => setSelectedReportType(v as ReportType)}
>
<SelectTrigger>
<SelectValue placeholder="Select report type" />
</SelectTrigger>
<SelectContent>
<SelectItem value="patients_with_balance">
Patients with Outstanding Balance
</SelectItem>
<SelectItem value="patients_no_balance">
Patients with Zero Balance
</SelectItem>
<SelectItem value="monthly_collections">
Monthly Collections Summary
</SelectItem>
<SelectItem value="procedure_codes_by_doctor">
Procedure Codes by Doctor
</SelectItem>
<SelectItem value="payment_methods">
Payment Methods Breakdown
</SelectItem>
<SelectItem value="insurance_vs_patient_payments">
Insurance vs Patient Payments
</SelectItem>
<SelectItem value="aging_report">
Accounts Receivable Aging
</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</CardContent>
</Card>
);
}