import { useMutation } from "@apollo/client"; import { Button, notification } from "antd"; import axios from "axios"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { Link } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import { auth, logImEXEvent } from "../../firebase/firebase.utils"; import { INSERT_EXPORT_LOG } from "../../graphql/accounting.queries"; import { UPDATE_BILLS } from "../../graphql/bills.queries"; import { selectBodyshop, selectCurrentUser, } from "../../redux/user/user.selectors"; import client from "../../utils/GraphQLClient"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, currentUser: selectCurrentUser, }); function updateBillCache(items) { client.cache.modify({ id: "ROOT_QUERY", fields: { bills(existingJobs = []) { return existingJobs.filter( (billRef) => billRef.__ref.includes(items) === false ); }, }, }); } export function PayableExportButton({ bodyshop, currentUser, billId, disabled, loadingCallback, setSelectedBills, refetch, }) { const { t } = useTranslation(); const [updateBill] = useMutation(UPDATE_BILLS); const [loading, setLoading] = useState(false); const [insertExportLog] = useMutation(INSERT_EXPORT_LOG); const handleQbxml = async () => { logImEXEvent("accounting_export_payable"); setLoading(true); if (!!loadingCallback) loadingCallback(true); //Check if it's a QBO Setup. let PartnerResponse; if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) { PartnerResponse = await axios.post(`/qbo/payables`, { bills: [billId], elgen: true, }); } else { //Default is QBD let QbXmlResponse; try { QbXmlResponse = await axios.post( "/accounting/qbxml/payables", { bills: [billId] }, { headers: { Authorization: `Bearer ${await auth.currentUser.getIdToken()}`, }, } ); } catch (error) { console.log("Error getting QBXML from Server.", error); notification["error"]({ message: t("bills.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("bills.errors.exporting-partner"), }); if (!!loadingCallback) loadingCallback(false); setLoading(false); return; } } console.log("handleQbxml -> PartnerResponse", PartnerResponse); const failedTransactions = PartnerResponse.data.filter((r) => !r.success); const successfulTransactions = PartnerResponse.data.filter( (r) => r.success ); if (failedTransactions.length > 0) { //Uh oh. At least one was no good. failedTransactions.map((ft) => notification["error"]({ message: t("bills.errors.exporting", { error: ft.errorMessage || "", }), }) ); if (!(bodyshop.accountingconfig && bodyshop.accountingconfig.qbo)) { //QBO Logs are handled server side. await insertExportLog({ variables: { logs: [ { bodyshopid: bodyshop.id, billid: billId, successful: false, message: JSON.stringify( failedTransactions.map((ft) => ft.errorMessage) ), useremail: currentUser.email, }, ], }, }); } } if (successfulTransactions.length > 0) { if (!(bodyshop.accountingconfig && bodyshop.accountingconfig.qbo)) { //QBO Logs are handled server side. await insertExportLog({ variables: { logs: [ { bodyshopid: bodyshop.id, billid: billId, successful: true, useremail: currentUser.email, }, ], }, }); const billUpdateResponse = await updateBill({ variables: { billIdList: successfulTransactions.map( (st) => st[ bodyshop.accountingconfig && bodyshop.accountingconfig.qbo ? "billid" : "id" ] ), bill: { exported: true, exported_at: new Date(), }, }, }); if (!!!billUpdateResponse.errors) { notification.open({ type: "success", key: "billsuccessexport", message: t("bills.successes.exported"), }); updateBillCache( billUpdateResponse.data.update_bills.returning.map( (bill) => bill.id ) ); } else { notification["error"]({ message: t("bills.errors.exporting", { error: JSON.stringify(billUpdateResponse.error), }), }); } } if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) { notification.open({ type: "success", key: "billsuccessexport", message: t("bills.successes.exported"), }); updateBillCache([ ...new Set( successfulTransactions.map( (st) => st[ bodyshop.accountingconfig && bodyshop.accountingconfig.qbo ? "billid" : "id" ] ) ), ]); } if (setSelectedBills) { setSelectedBills((selectedBills) => { return selectedBills.filter((i) => i !== billId); }); } } if (!!loadingCallback) loadingCallback(false); setLoading(false); }; if (bodyshop.pbs_serialnumber) return ( ); return ( ); } export default connect(mapStateToProps, null)(PayableExportButton);