mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-31 23:33:43 +00:00
@@ -0,0 +1,109 @@
|
||||
import { AlertDialogAction, AlertDialogCancel, AlertDialogFooter } from "@/components/ui/alert-dialog"
|
||||
import { useAtom, useAtomValue } from "jotai"
|
||||
import { bankRecDateAtom, bankRecUnreconcileModalAtom, selectedBankAccountAtom } from "./bankRecAtoms"
|
||||
import { useMemo } from "react"
|
||||
import { useFrappeGetDoc, useFrappePostCall, useSWRConfig } from "frappe-react-sdk"
|
||||
import { BankTransaction } from "@/types/Accounts/BankTransaction"
|
||||
import { toast } from "sonner"
|
||||
import ErrorBanner from "@/components/ui/error-banner"
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||||
import { formatCurrency } from "@/lib/numbers"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { slug } from "@/lib/frappe"
|
||||
import SelectedTransactionDetails from "./SelectedTransactionDetails"
|
||||
import _ from "@/lib/translate"
|
||||
|
||||
const BankTransactionUnreconcileModalBody = () => {
|
||||
const bankAccount = useAtomValue(selectedBankAccountAtom)
|
||||
const dates = useAtomValue(bankRecDateAtom)
|
||||
|
||||
const { mutate } = useSWRConfig()
|
||||
|
||||
const [unreconcileModal, setBankRecUnreconcileModal] = useAtom(bankRecUnreconcileModalAtom)
|
||||
|
||||
const { data: transaction, error, isLoading } = useFrappeGetDoc<BankTransaction>('Bank Transaction', unreconcileModal)
|
||||
|
||||
const { call, loading, error: unreconcileError } = useFrappePostCall('erpnext.accounts.doctype.bank_transaction.bank_transaction.unreconcile_transaction')
|
||||
|
||||
const onUnreconcile = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
call({
|
||||
transaction_name: unreconcileModal
|
||||
}).then(() => {
|
||||
mutate(`bank-reconciliation-bank-transactions-${bankAccount?.name}-${dates.fromDate}-${dates.toDate}`)
|
||||
mutate(`bank-reconciliation-unreconciled-transactions-${bankAccount?.name}-${dates.fromDate}-${dates.toDate}`)
|
||||
mutate(`bank-reconciliation-account-closing-balance-${bankAccount?.name}-${dates.toDate}`)
|
||||
toast.success(_("Transaction Unreconciled"))
|
||||
setBankRecUnreconcileModal('')
|
||||
})
|
||||
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
const vouchersWhichWillBeCancelled = useMemo(() => {
|
||||
return transaction?.payment_entries?.filter((payment) => payment.reconciliation_type === 'Voucher Created')
|
||||
}, [transaction])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col gap-3">
|
||||
{error && <ErrorBanner error={error} />}
|
||||
{unreconcileError && <ErrorBanner error={unreconcileError} />}
|
||||
{transaction && <SelectedTransactionDetails transaction={transaction} />}
|
||||
<span className="font-medium text-sm">{_("This transaction has been reconciled with the following document(s):")}</span>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>{_("Document")}</TableHead>
|
||||
<TableHead>{_("Amount")}</TableHead>
|
||||
<TableHead>{_("Reconciliation Type")}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{transaction?.payment_entries?.map((voucher) => {
|
||||
return (
|
||||
<TableRow key={voucher.name}>
|
||||
<TableCell>
|
||||
<a
|
||||
className="underline underline-offset-4"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href={`/desk/${slug(voucher.payment_document as string)}/${voucher.payment_entry}`}
|
||||
>
|
||||
{`${_(voucher.payment_document)}: ${voucher.payment_entry}`}
|
||||
</a>
|
||||
</TableCell>
|
||||
<TableCell>{formatCurrency(voucher.allocated_amount)}</TableCell>
|
||||
<TableCell>
|
||||
{voucher.reconciliation_type === 'Voucher Created' ?
|
||||
<Badge theme="green">{_(voucher.reconciliation_type)}</Badge> :
|
||||
<Badge theme="blue">{_(voucher.reconciliation_type ?? "Matched")}</Badge>}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div className="py-4">
|
||||
{vouchersWhichWillBeCancelled && vouchersWhichWillBeCancelled?.length > 0 && (
|
||||
<span>The following documents will be <strong>cancelled</strong>:</span>
|
||||
)}
|
||||
{vouchersWhichWillBeCancelled && vouchersWhichWillBeCancelled?.length > 0 && (
|
||||
<ol className="ms-6 list-disc [&>li]:mt-2">
|
||||
{vouchersWhichWillBeCancelled?.map((voucher) => {
|
||||
return <li key={voucher.name}>{_(voucher.payment_document)}: {voucher.payment_entry}</li>
|
||||
})}
|
||||
</ol>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel disabled={loading}>{_("Cancel")}</AlertDialogCancel>
|
||||
<AlertDialogAction onClick={onUnreconcile} theme="red" disabled={loading || isLoading}>
|
||||
{_("Unreconcile")}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default BankTransactionUnreconcileModalBody
|
||||
Reference in New Issue
Block a user