import { useMutation } from "@apollo/client"; import { Button, notification } from "antd"; import axios from "axios"; import _ from "lodash"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries"; import { UPDATE_PAYMENTS } from "../../graphql/payments.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import client from "../../utils/GraphQLClient"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, currentUser: selectCurrentUser }); function updatePaymentCache(items) { client.cache.modify({ id: "ROOT_QUERY", fields: { payments(existingJobs = []) { return existingJobs.filter((paymentRef) => paymentRef.__ref.includes(items) === false); } } }); } export function PaymentsExportAllButton({ bodyshop, currentUser, paymentIds, disabled, loadingCallback, completedCallback, refetch }) { const { t } = useTranslation(); const [updatePayments] = useMutation(UPDATE_PAYMENTS); const [loading, setLoading] = useState(false); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); const handleQbxml = async () => { setLoading(true); if (loadingCallback) loadingCallback(true); let PartnerResponse; if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) { PartnerResponse = await axios.post(`/qbo/payments`, { payments: paymentIds, elgen: true }); } else { let QbXmlResponse; try { QbXmlResponse = await axios.post("/accounting/qbxml/payments", { payments: paymentIds }); } catch (error) { console.log("Error getting QBXML from Server.", error); notification["error"]({ message: t("payments.errors.exporting", { error: "Unable to retrieve QBXML. " + JSON.stringify(error.message) }) }); if (loadingCallback) loadingCallback(false); setLoading(false); return; } try { PartnerResponse = await axios.post("http://localhost:1337/qb/", QbXmlResponse.data); } catch (error) { console.log("Error connecting to quickbooks or partner.", error); notification["error"]({ message: t("payments.errors.exporting-partner") }); if (loadingCallback) loadingCallback(false); setLoading(false); return; } } const groupedData = _.groupBy(PartnerResponse.data, bodyshop.accountingconfig.qbo ? "paymentid" : "id"); const proms = []; Object.keys(groupedData).forEach((key) => { proms.push( (async () => { const failedTransactions = groupedData[key].filter((r) => !r.success); const successfulTransactions = groupedData[key].filter((r) => r.success); if (failedTransactions.length > 0) { //Uh oh. At least one was no good. failedTransactions.map((ft) => notification["error"]({ message: t("payments.errors.exporting", { error: ft.errorMessage || "" }) }) ); if (!(bodyshop.accountingconfig && bodyshop.accountingconfig.qbo)) { //QBO Logs are handled server side. await insertExportLog({ variables: { logs: [ { bodyshopid: bodyshop.id, paymentid: key, successful: false, message: JSON.stringify(failedTransactions.map((ft) => ft.errorMessage)), useremail: currentUser.email } ] } }); } } else { if (!(bodyshop.accountingconfig && bodyshop.accountingconfig.qbo)) { //QBO Logs are handled server side. await insertExportLog({ variables: { logs: [ { bodyshopid: bodyshop.id, paymentid: key, successful: true, useremail: currentUser.email } ] } }); const paymentUpdateResponse = await updatePayments({ variables: { paymentIdList: successfulTransactions.map( (st) => st[bodyshop.accountingconfig && bodyshop.accountingconfig.qbo ? "paymentid" : "id"] ), payment: { exportedat: new Date() } } }); if (!paymentUpdateResponse.errors) { notification.open({ type: "success", key: "paymentsuccessexport", message: t("payments.successes.exported") }); updatePaymentCache(paymentUpdateResponse.data.update_payments.returning.map((payment) => payment.id)); } else { notification["error"]({ message: t("payments.errors.exporting", { error: JSON.stringify(paymentUpdateResponse.error) }) }); } } if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) { notification.open({ type: "success", key: "paymentsuccessexport", message: t("payments.successes.exported") }); updatePaymentCache([ ...new Set( successfulTransactions.map( (st) => st[bodyshop.accountingconfig && bodyshop.accountingconfig.qbo ? "paymentid" : "id"] ) ) ]); } } })() ); }); await Promise.all(proms); if (completedCallback) completedCallback([]); if (loadingCallback) loadingCallback(false); setLoading(false); }; return ( ); } export default connect(mapStateToProps, null)(PaymentsExportAllButton);