import { DeleteFilled, CopyFilled } from "@ant-design/icons"; import { useLazyQuery, useMutation } from "@apollo/client"; import { Button, Card, Col, Form, Input, Row, Space, Spin, Statistic, message, notification } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { INSERT_PAYMENT_RESPONSE, QUERY_RO_AND_OWNER_BY_JOB_PKS } from "../../graphql/payment_response.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; import { toggleModalVisible } from "../../redux/modals/modals.actions"; import { selectCardPayment } from "../../redux/modals/modals.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component"; import JobSearchSelectComponent from "../job-search-select/job-search-select.component"; import { getCurrentUser } from "../../firebase/firebase.utils"; const mapStateToProps = createStructuredSelector({ cardPaymentModal: selectCardPayment, bodyshop: selectBodyshop, currentUser: getCurrentUser }); const mapDispatchToProps = (dispatch) => ({ insertAuditTrail: ({ jobid, operation, type }) => dispatch(insertAuditTrail({ jobid, operation, type })), toggleModalVisible: () => dispatch(toggleModalVisible("cardPayment")) }); const CardPaymentModalComponent = ({ bodyshop, currentUser, cardPaymentModal, toggleModalVisible, insertAuditTrail }) => { const { context, actions } = cardPaymentModal; const [form] = Form.useForm(); const [paymentLink, setPaymentLink] = useState(); const [loading, setLoading] = useState(false); // const [insertPayment] = useMutation(INSERT_NEW_PAYMENT); const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE); const { t } = useTranslation(); const [, { data, refetch, queryLoading }] = useLazyQuery(QUERY_RO_AND_OWNER_BY_JOB_PKS, { variables: { jobids: [context.jobid] }, skip: !context?.jobid }); //Initialize the intellipay window. const SetIntellipayCallbackFunctions = () => { console.log("*** Set IntelliPay callback functions."); window.intellipay.runOnClose(() => { //window.intellipay.initialize(); }); window.intellipay.runOnApproval(async function (response) { //2024-04-25: Nothing is going to happen here anymore. We'll completely rely on the callback. //Add a slight delay to allow the refetch to properly get the data. setTimeout(() => { if (actions && actions.refetch && typeof actions.refetch === "function") actions.refetch(); setLoading(false); toggleModalVisible(); }, 750); }); window.intellipay.runOnNonApproval(async function (response) { // Mutate unsuccessful payment const { payments } = form.getFieldsValue(); await insertPaymentResponse({ variables: { paymentResponse: payments.map((payment) => ({ amount: payment.amount, bodyshopid: bodyshop.id, jobid: payment.jobid, declinereason: response.declinereason, ext_paymentid: response.paymentid.toString(), successful: false, response })) } }); payments.forEach((payment) => insertAuditTrail({ jobid: payment.jobid, operation: AuditTrailMapping.failedpayment(), type: "failedpayment" }) ); }); }; const handleIntelliPayCharge = async () => { setLoading(true); //Validate try { await form.validateFields(); } catch (error) { setLoading(false); return; } try { const response = await axios.post("/intellipay/lightbox_credentials", { bodyshop, refresh: !!window.intellipay, paymentSplitMeta: form.getFieldsValue() }); if (window.intellipay) { // eslint-disable-next-line no-eval eval(response.data); SetIntellipayCallbackFunctions(); window.intellipay.autoOpen(); } else { var rg = document.createRange(); let node = rg.createContextualFragment(response.data); document.documentElement.appendChild(node); SetIntellipayCallbackFunctions(); window.intellipay.isAutoOpen = true; window.intellipay.initialize(); } } catch (error) { notification.open({ type: "error", message: t("job_payments.notifications.error.openingip") }); setLoading(false); } }; const handleIntelliPayChargeShortLink = async () => { setLoading(true); //Validate try { await form.validateFields(); } catch (error) { setLoading(false); return; } try { const { payments } = form.getFieldsValue(); const response = await axios.post("/intellipay/generate_payment_url", { bodyshop, amount: payments?.reduce((acc, val) => { return acc + (val?.amount || 0); }, 0), account: payments && data && data.jobs.length > 0 ? data.jobs.map((j) => j.ro_number).join(", ") : null, comment: btoa(JSON.stringify({ payments, userEmail: currentUser.email })), paymentSplitMeta: form.getFieldsValue() }); if (response.data) { setPaymentLink(response.data?.shorUrl); navigator.clipboard.writeText(response.data?.shorUrl); message.success(t("general.actions.copied")); } setLoading(false); } catch (error) { notification.open({ type: "error", message: t("job_payments.notifications.error.openingip") }); setLoading(false); } }; return (
{(fields, { add, remove, move }) => { return (
{fields.map((field, index) => ( { remove(field.name); }} /> ))}
); }}
prevValues.payments?.map((p) => p?.jobid + p?.amount).join() !== curValues.payments?.map((p) => p?.jobid + p?.amount).join() } > {() => { //If all of the job ids have been fileld in, then query and update the IP field. const { payments } = form.getFieldsValue(); if (payments?.length > 0 && payments?.filter((p) => p?.jobid).length === payments?.length) { refetch({ jobids: payments.map((p) => p.jobid) }); } return ( <> 0 ? data.jobs.map((j) => j.ro_number).join(", ") : null } /> 0 ? data.jobs.filter((j) => j.ownr_ea)[0]?.ownr_ea : null } /> ); }} prevValues.payments?.map((p) => p?.amount).join() !== curValues.payments?.map((p) => p?.amount).join() } > {() => { const { payments } = form.getFieldsValue(); const totalAmountToCharge = payments?.reduce((acc, val) => { return acc + (val?.amount || 0); }, 0); return ( ); }}
{paymentLink && ( { navigator.clipboard.writeText(paymentLink); message.success(t("general.actions.copied")); }} >
{paymentLink}
)}
); }; export default connect(mapStateToProps, mapDispatchToProps)(CardPaymentModalComponent);