From 034d1b83456cb680a2fe9ea101a8d718068e5244 Mon Sep 17 00:00:00 2001 From: Matt Gramigna Date: Sun, 24 Dec 2023 13:21:50 -0500 Subject: [PATCH] feat: submit payment notice --- apps/expo/src/app/(app)/profile/billing.tsx | 56 +++++++++++- .../molecules/SubmitPaymentModal.tsx | 88 +++++++++++++++++++ packages/canvas/src/utils/errors.ts | 1 + 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 apps/expo/src/components/molecules/SubmitPaymentModal.tsx diff --git a/apps/expo/src/app/(app)/profile/billing.tsx b/apps/expo/src/app/(app)/profile/billing.tsx index 2dec2f0..d1d8865 100644 --- a/apps/expo/src/app/(app)/profile/billing.tsx +++ b/apps/expo/src/app/(app)/profile/billing.tsx @@ -5,6 +5,10 @@ import { Skeleton } from '@/components/atoms/Skeleton'; import { Text } from '@/components/atoms/Text'; import { AddEditInsuranceModal } from '@/components/molecules/AddEditInsuranceModal'; import { ScreenView } from '@/components/molecules/ScreenView'; +import { + SubmitPaymentModal, + type PaymentFormType, +} from '@/components/molecules/SubmitPaymentModal'; import { CoverageDetail } from '@/components/organisms/CoverageDetail'; import { DocumentDownloadCard } from '@/components/organisms/DocumentDownloadCard'; import { type InsuranceFormType } from '@/components/organisms/InsuranceForm'; @@ -13,12 +17,14 @@ import { palette } from '@/theme/colors'; import { api } from '@/utils/api'; import { getCoverageResource } from '@/utils/fhir'; import { Ionicons } from '@expo/vector-icons'; +import dayjs from 'dayjs'; import { type Coverage } from '@careforge/canvas'; const Billing = () => { const { patientId } = useAuth(); const [insuranceModalOpen, setInsuranceModalOpen] = useState(false); + const [paymentModalOpen, setPaymentModalOpen] = useState(false); const { data: invoiceBundle, @@ -57,6 +63,22 @@ const Billing = () => { }, }); + const createPaymentMutation = api.paymentnotice.create.useMutation({ + onSuccess: async () => { + await utils.documentreference.search.invalidate({ + category: 'invoicefull', + }); + setPaymentModalOpen(false); + }, + onError: (error) => { + if (error.data?.code === 'UNPROCESSABLE_CONTENT') { + Alert.alert('Submitted amount must be less than or equal to the amount owed'); + } else { + Alert.alert('Something went wrong'); + } + }, + }); + const handleCoverageSave = useCallback( (form: InsuranceFormType) => { const coverage = getCoverageResource({ @@ -69,6 +91,26 @@ const Billing = () => { [createCoverageMutation, patientId], ); + const handlePaymentSubmit = useCallback( + (form: PaymentFormType) => { + createPaymentMutation.mutate({ + resourceType: 'PaymentNotice', + status: 'active', + request: { + reference: `Patient/${patientId}`, + }, + created: dayjs().toISOString(), + payment: {}, + recipient: {}, + amount: { + value: parseFloat(form.amount), + currency: 'USD', + }, + }); + }, + [createPaymentMutation, patientId], + ); + const onRefresh = useCallback(() => { Promise.all([refetchInvoices(), refetchCoverage()]).catch(() => Alert.alert('Error refreshing data'), @@ -115,6 +157,11 @@ const Billing = () => { )} + {(invoiceBundle?.total ?? 0) > 0 && ( + +