158 lines
5.5 KiB
JavaScript
158 lines
5.5 KiB
JavaScript
import { useMutation, useQuery } from "@apollo/client";
|
|
import { Button, Descriptions, InputNumber, Modal, Space } from "antd";
|
|
import axios from "axios";
|
|
import dayjs from "../../utils/day";
|
|
import React, { useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import {
|
|
GET_REFUNDABLE_AMOUNT_BY_JOBID,
|
|
INSERT_PAYMENT_RESPONSE,
|
|
QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID
|
|
} from "../../graphql/payment_response.queries";
|
|
import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries";
|
|
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
|
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
|
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
|
|
|
const { confirm } = Modal;
|
|
|
|
const openNotificationWithIcon = (type, t, notification) => {
|
|
notification[type]({
|
|
message: t("job_payments.notifications.error.title"),
|
|
description: t("job_payments.notifications.error.description")
|
|
});
|
|
};
|
|
|
|
const PaymentExpandedRowComponent = ({ record, bodyshop }) => {
|
|
const [refundAmount, setRefundAmount] = useState(0);
|
|
const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
|
|
const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE);
|
|
const { t } = useTranslation();
|
|
const notification = useNotification();
|
|
|
|
const { loading, error, data } = useQuery(QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID, {
|
|
variables: {
|
|
paymentid: record.id,
|
|
fetchPolicy: "network-only",
|
|
nextFetchPolicy: "network-only"
|
|
}
|
|
});
|
|
|
|
const { data: refundable_amount, refetch } = useQuery(GET_REFUNDABLE_AMOUNT_BY_JOBID, {
|
|
variables: {
|
|
jobid: record.jobid
|
|
}
|
|
});
|
|
|
|
const insertPayments = async (payment_response, refund_response) => {
|
|
await insertPayment({
|
|
variables: {
|
|
paymentInput: {
|
|
amount: -refund_response?.data?.amount,
|
|
transactionid: payment_response?.response?.receiptelements?.transid,
|
|
payer: record.payer,
|
|
type: "Refund",
|
|
jobid: payment_response.jobid,
|
|
date: dayjs(Date.now())
|
|
}
|
|
},
|
|
update(cache, { data }) {
|
|
cache.modify({
|
|
id: cache.identify({
|
|
id: payment_response.jobid,
|
|
__typename: "jobs"
|
|
}),
|
|
fields: {
|
|
payments(payments) {
|
|
return [...data.insert_payments.returning, ...payments];
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
await insertPaymentResponse({
|
|
variables: {
|
|
paymentResponse: {
|
|
amount: -refund_response.data.amount,
|
|
bodyshopid: payment_response.bodyshopid,
|
|
paymentid: payment_response.paymentid,
|
|
jobid: payment_response.jobid,
|
|
declinereason: "Refund",
|
|
ext_paymentid: payment_response.ext_paymentid,
|
|
successful: true,
|
|
response: refund_response.data
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
const showConfirm = (payment_response) => {
|
|
confirm({
|
|
title: "Do you want to refund payment?",
|
|
content: "The payment will be refunded. Click OK to confirm and Cancel to dismiss.",
|
|
async onOk() {
|
|
const refundResponse = await axios.post("/intellipay/payment_refund", {
|
|
bodyshop,
|
|
amount: refundAmount,
|
|
paymentid: payment_response.ext_paymentid
|
|
});
|
|
|
|
if (refundResponse.data.status < 0) {
|
|
openNotificationWithIcon("error", t, notification);
|
|
return;
|
|
}
|
|
|
|
insertPayments(payment_response, refundResponse);
|
|
|
|
// refetch refundable amount
|
|
refetch();
|
|
},
|
|
onCancel() {}
|
|
});
|
|
};
|
|
|
|
if (loading) return null;
|
|
|
|
if (error) return <p>Error loading data. Please Reload</p>;
|
|
|
|
const payment_response = data.payment_response[0];
|
|
const max_refundable_amount = refundable_amount?.payment_response_aggregate.aggregate.sum.amount;
|
|
|
|
return (
|
|
<div>
|
|
<Descriptions title={t("job_payments.titles.descriptions")} contentStyle={{ fontWeight: "600" }} column={4}>
|
|
<Descriptions.Item label={t("job_payments.titles.hint")}>
|
|
{payment_response?.response?.methodhint}
|
|
</Descriptions.Item>
|
|
<Descriptions.Item label={t("job_payments.titles.payername")}>
|
|
{payment_response?.response?.nameOnCard ?? ""}
|
|
</Descriptions.Item>
|
|
<Descriptions.Item label={t("job_payments.titles.amount")}>
|
|
<CurrencyFormatter>{record.amount}</CurrencyFormatter>
|
|
</Descriptions.Item>
|
|
<Descriptions.Item label={t("job_payments.titles.dateOfPayment")}>
|
|
{<DateTimeFormatter>{record.created_at}</DateTimeFormatter>}
|
|
</Descriptions.Item>
|
|
<Descriptions.Item label={t("job_payments.titles.transactionid")}>{record.transactionid}</Descriptions.Item>
|
|
<Descriptions.Item label={t("job_payments.titles.paymentid")}>
|
|
{payment_response?.ext_paymentid ?? ""}
|
|
</Descriptions.Item>
|
|
<Descriptions.Item label={t("job_payments.titles.paymenttype")}>{record.type}</Descriptions.Item>
|
|
<Descriptions.Item label={t("job_payments.titles.paymentnum")}>{record.paymentnum}</Descriptions.Item>
|
|
{payment_response && (
|
|
<Descriptions.Item label={t("job_payments.titles.refundamount")}>
|
|
<Space>
|
|
<InputNumber onChange={setRefundAmount} max={max_refundable_amount} min={0} />
|
|
|
|
<Button onClick={() => showConfirm(payment_response)}>{t("job_payments.buttons.refundpayment")}</Button>
|
|
</Space>
|
|
</Descriptions.Item>
|
|
)}
|
|
</Descriptions>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PaymentExpandedRowComponent;
|