import { EditFilled } from "@ant-design/icons"; import { Button, Card, Space, Table } from "antd"; import Dinero from "dinero.js"; import React, { useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectJobReadOnly } from "../../redux/application/application.selectors"; import { openChatByPhone, setMessage } from "../../redux/messaging/messaging.actions"; import { setModalContext } from "../../redux/modals/modals.actions"; import { selectBodyshop } from "../../redux/user/user.selectors"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { DateFormatter } from "../../utils/DateFormatter"; import { TemplateList } from "../../utils/TemplateConstants"; import { alphaSort, dateSort } from "../../utils/sorters"; import DataLabel from "../data-label/data-label.component"; import PaymentExpandedRowComponent from "../payment-expanded-row/payment-expanded-row.component"; import PaymentsGenerateLink from "../payments-generate-link/payments-generate-link.component"; import PrintWrapperComponent from "../print-wrapper/print-wrapper.component"; import { useSplitTreatments } from "@splitsoftware/splitio-react"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, jobRO: selectJobReadOnly }); const mapDispatchToProps = (dispatch) => ({ setPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "payment" })), setCardPaymentContext: (context) => dispatch(setModalContext({ context: context, modal: "cardPayment" })), openChatByPhone: (phone) => dispatch(openChatByPhone(phone)), setMessage: (text) => dispatch(setMessage(text)) }); export function JobPayments({ job, jobRO, bodyshop, setMessage, openChatByPhone, setPaymentContext, setCardPaymentContext, refetch }) { const { treatments: { ImEXPay } } = useSplitTreatments({ attributes: {}, names: ["ImEXPay"], splitKey: bodyshop && bodyshop.imexshopid }); const { t } = useTranslation(); const [state, setState] = useState({ sortedInfo: {}, filteredInfo: {} }); const columns = [ { title: t("payments.fields.date"), dataIndex: "date", key: "date", sorter: (a, b) => dateSort(a.date, b.date), sortOrder: state.sortedInfo.columnKey === "date" && state.sortedInfo.order, render: (text, record) => {record.date} }, { title: t("payments.fields.payer"), dataIndex: "payer", key: "payer", sorter: (a, b) => alphaSort(a.payer, b.payer), sortOrder: state.sortedInfo.columnKey === "payer" && state.sortedInfo.order }, { title: t("payments.fields.amount"), dataIndex: "amount", key: "amount", sorter: (a, b) => a.amount - b.amount, sortOrder: state.sortedInfo.columnKey === "amount" && state.sortedInfo.order, render: (text, record) => {record.amount} }, { title: t("payments.fields.memo"), dataIndex: "memo", key: "memo", sorter: (a, b) => alphaSort(a.memo, b.memo), sortOrder: state.sortedInfo.columnKey === "memo" && state.sortedInfo.order }, { title: t("payments.fields.type"), dataIndex: "type", key: "type", sorter: (a, b) => alphaSort(a.type, b.type), sortOrder: state.sortedInfo.columnKey === "type" && state.sortedInfo.order }, { title: t("payments.fields.transactionid"), dataIndex: "transactionid", key: "transactionid", sorter: (a, b) => alphaSort(a.transactionid, b.transactionid), sortOrder: state.sortedInfo.columnKey === "transactionid" && state.sortedInfo.order }, { title: t("general.labels.actions"), dataIndex: "actions", key: "actions", render: (text, record) => ( ) } ]; //Same as in RO guard. If changed, update in both. const total = useMemo(() => { return ( job.payments && job.payments.reduce((acc, val) => { acc = acc.add(Dinero({ amount: Math.round(val.amount * 100) })); return acc; }, Dinero()) ); }, [job.payments]); const balance = useMemo(() => { if (job && job.job_totals && job.job_totals.totals.total_repairs) return Dinero(job.job_totals.totals.total_repairs).subtract(total); return Dinero({ amount: 0 }).subtract(total); }, [job, total]); const handleTableChange = (pagination, filters, sorter) => { setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); }; return ( {ImEXPay.treatment === "on" && ( <> )} {balance.toFormat()} } > }} summary={() => ( <> {t("payments.labels.totalpayments")} {total.toFormat()} )} /> ); } export default connect(mapStateToProps, mapDispatchToProps)(JobPayments);