From 56c1b6f992ed9cad4ab70dece9f8ae8bde8c7ba3 Mon Sep 17 00:00:00 2001 From: Allan Carr Date: Mon, 11 Sep 2023 09:07:38 -0700 Subject: [PATCH 1/6] IO-2368 Confirm that there are successful transaction --- .../jobs-close-export-button.component.jsx | 2 +- .../jobs-export-all-button/jobs-export-all-button.component.jsx | 2 +- .../payable-export-all-button.component.jsx | 2 +- .../payable-export-button/payable-export-button.component.jsx | 2 +- .../payment-export-button/payment-export-button.component.jsx | 2 +- .../payments-export-all-button.component.jsx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx b/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx index 795e60110..8bbda03e1 100644 --- a/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx +++ b/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx @@ -192,7 +192,7 @@ export function JobsCloseExportButton({ }); } } - if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) { + if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) { notification.open({ type: "success", key: "jobsuccessexport", diff --git a/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx b/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx index 15fdb32b4..3204d7311 100644 --- a/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx +++ b/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx @@ -190,7 +190,7 @@ export function JobsExportAllButton({ }); } } - if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) { + if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) { notification.open({ type: "success", key: "jobsuccessexport", diff --git a/client/src/components/payable-export-all-button/payable-export-all-button.component.jsx b/client/src/components/payable-export-all-button/payable-export-all-button.component.jsx index 723fd0526..c448e4f4a 100644 --- a/client/src/components/payable-export-all-button/payable-export-all-button.component.jsx +++ b/client/src/components/payable-export-all-button/payable-export-all-button.component.jsx @@ -192,7 +192,7 @@ export function PayableExportAll({ }); } } - if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) { + if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) { notification.open({ type: "success", key: "billsuccessexport", diff --git a/client/src/components/payable-export-button/payable-export-button.component.jsx b/client/src/components/payable-export-button/payable-export-button.component.jsx index 1836acb18..c2970b8d8 100644 --- a/client/src/components/payable-export-button/payable-export-button.component.jsx +++ b/client/src/components/payable-export-button/payable-export-button.component.jsx @@ -185,7 +185,7 @@ export function PayableExportButton({ }); } } - if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) { + if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) { notification.open({ type: "success", key: "billsuccessexport", diff --git a/client/src/components/payment-export-button/payment-export-button.component.jsx b/client/src/components/payment-export-button/payment-export-button.component.jsx index 91f9ccc88..931254b92 100644 --- a/client/src/components/payment-export-button/payment-export-button.component.jsx +++ b/client/src/components/payment-export-button/payment-export-button.component.jsx @@ -191,7 +191,7 @@ export function PaymentExportButton({ }); } } - if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) { + if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) { notification.open({ type: "success", key: "paymentsuccessexport", diff --git a/client/src/components/payments-export-all-button/payments-export-all-button.component.jsx b/client/src/components/payments-export-all-button/payments-export-all-button.component.jsx index 721e906d5..0b2e6cd7b 100644 --- a/client/src/components/payments-export-all-button/payments-export-all-button.component.jsx +++ b/client/src/components/payments-export-all-button/payments-export-all-button.component.jsx @@ -179,7 +179,7 @@ export function PaymentsExportAllButton({ }); } } - if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) { + if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) { notification.open({ type: "success", key: "paymentsuccessexport", From 53e3b3fa037a110f24be84dbdae6e9382185bf58 Mon Sep 17 00:00:00 2001 From: Allan Carr Date: Mon, 11 Sep 2023 11:15:50 -0700 Subject: [PATCH 2/6] IO-2395 Payment Expansion Formatting --- .../payment-expanded-row.component.jsx | 19 ++++++++++++------- client/src/graphql/jobs.queries.js | 2 +- client/src/translations/en_us/common.json | 1 + client/src/translations/es/common.json | 1 + client/src/translations/fr/common.json | 1 + 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx b/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx index 6266457a7..a96683b70 100644 --- a/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx +++ b/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx @@ -1,15 +1,17 @@ -import React, { useState } from "react"; import { useMutation, useQuery } from "@apollo/client"; +import { Button, Descriptions, InputNumber, Modal, notification } from "antd"; +import axios from "axios"; +import moment from "moment"; +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 { Button, Descriptions, InputNumber, Modal, notification } from "antd"; -import moment from "moment"; -import axios from "axios"; import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries"; -import { useTranslation } from "react-i18next"; +import CurrencyFormatter from "../../utils/CurrencyFormatter"; +import { DateTimeFormatter } from "../../utils/DateFormatter"; const { confirm } = Modal; @@ -137,10 +139,10 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => { {payment_response?.response?.nameOnCard ?? ""} - {record.amount} + {record.amount} - {moment(record.created_at).format("YYYY-MM-DD HH:mm:ss")} + {{record.created_at}} {record.transactionid} @@ -151,6 +153,9 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => { {record.type} + + {record.paymentnum} + {payment_response && ( Date: Thu, 14 Sep 2023 11:18:40 -0700 Subject: [PATCH 3/6] Respect default import status on new creation. --- .../jobs-available-table.container.jsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/src/components/jobs-available-table/jobs-available-table.container.jsx b/client/src/components/jobs-available-table/jobs-available-table.container.jsx index d632324b5..0e74276b2 100644 --- a/client/src/components/jobs-available-table/jobs-available-table.container.jsx +++ b/client/src/components/jobs-available-table/jobs-available-table.container.jsx @@ -3,7 +3,7 @@ import { useApolloClient, useLazyQuery, useMutation, - useQuery + useQuery, } from "@apollo/client"; import { useTreatments } from "@splitsoftware/splitio-react"; import { Col, notification, Row } from "antd"; @@ -20,7 +20,7 @@ import { logImEXEvent } from "../../firebase/firebase.utils"; import { DELETE_AVAILABLE_JOB, QUERY_AVAILABLE_JOBS, - QUERY_AVAILABLE_NEW_JOBS_EST_DATA_BY_PK + QUERY_AVAILABLE_NEW_JOBS_EST_DATA_BY_PK, } from "../../graphql/available-jobs.queries"; import { INSERT_NEW_JOB, UPDATE_JOB } from "../../graphql/jobs.queries"; import { INSERT_NEW_NOTE } from "../../graphql/notes.queries"; @@ -28,7 +28,7 @@ import { SEARCH_VEHICLE_BY_VIN } from "../../graphql/vehicles.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; import { selectBodyshop, - selectCurrentUser + selectCurrentUser, } from "../../redux/user/user.selectors"; import confirmDialog from "../../utils/asyncConfirm"; import AuditTrailMapping from "../../utils/AuditTrailMappings"; @@ -135,6 +135,7 @@ export function JobsAvailableContainer({ owner_owing: Dinero(newTotals.totals.custPayable.total).toFormat("0.00"), job_totals: newTotals, date_open: moment(), + status: bodyshop.md_ro_statuses.default_imported, notes: { data: { created_by: currentUser.email, From 41849644f363a4dee9e033c7b34111280ba89b5e Mon Sep 17 00:00:00 2001 From: Allan Carr Date: Fri, 15 Sep 2023 09:15:34 -0700 Subject: [PATCH 4/6] IO-2395 Adjust Payment Number Label --- .../payment-expanded-row/payment-expanded-row.component.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx b/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx index a96683b70..eaa0d20ed 100644 --- a/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx +++ b/client/src/components/payment-expanded-row/payment-expanded-row.component.jsx @@ -153,7 +153,7 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => { {record.type} - + {record.paymentnum} {payment_response && ( From 5ca34105eff766c9f918d080c1e7c798b604f505 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 15 Sep 2023 10:37:09 -0700 Subject: [PATCH 5/6] Refactor payments for intellipay. --- bodyshop_translations.babel | 21 + .../card-payment-modal.component..jsx | 361 +++++++++++------- .../card-payment-modal.container..jsx | 2 +- .../components/header/header.component.jsx | 2 +- .../payment-expanded-row.component.jsx | 27 +- .../src/graphql/payment_response.queries.js | 16 +- client/src/translations/en_us/common.json | 3 +- client/src/translations/es/common.json | 3 +- client/src/translations/fr/common.json | 3 +- 9 files changed, 281 insertions(+), 157 deletions(-) diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 13e91e869..5bc83e3b8 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -37301,6 +37301,27 @@ + + inserting + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + diff --git a/client/src/components/card-payment-modal/card-payment-modal.component..jsx b/client/src/components/card-payment-modal/card-payment-modal.component..jsx index 15c4ffe3a..071e2a758 100644 --- a/client/src/components/card-payment-modal/card-payment-modal.component..jsx +++ b/client/src/components/card-payment-modal/card-payment-modal.component..jsx @@ -1,12 +1,15 @@ -import { useMutation, useQuery } from "@apollo/client"; +import { DeleteFilled } from "@ant-design/icons"; +import { useLazyQuery, useMutation } from "@apollo/client"; import { Button, Card, + Col, Form, Input, - InputNumber, Row, + Space, Spin, + Statistic, notification, } from "antd"; import axios from "axios"; @@ -17,7 +20,7 @@ import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { INSERT_PAYMENT_RESPONSE, - QUERY_RO_AND_OWNER_BY_JOB_PK, + QUERY_RO_AND_OWNER_BY_JOB_PKS, } from "../../graphql/payment_response.queries"; import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries"; import { insertAuditTrail } from "../../redux/application/application.actions"; @@ -25,9 +28,8 @@ 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 DataLabel from "../data-label/data-label.component"; +import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component"; import JobSearchSelectComponent from "../job-search-select/job-search-select.component"; -import LayoutFormRow from "../layout-form-row/layout-form-row.component"; const mapStateToProps = createStructuredSelector({ cardPaymentModal: selectCardPayment, @@ -49,18 +51,21 @@ const CardPaymentModalComponent = ({ const { context } = cardPaymentModal; const [form] = Form.useForm(); - const amount = Form.useWatch("amount", form); - const jobid = Form.useWatch("jobid", form); + const [loading, setLoading] = useState(false); const [insertPayment] = useMutation(INSERT_NEW_PAYMENT); const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE); const { t } = useTranslation(); - const { data, refetch } = useQuery(QUERY_RO_AND_OWNER_BY_JOB_PK, { - variables: { jobid: context?.jobid ?? "" }, - skip: !context?.jobid, - }); + const [, { data, refetch, queryLoading }] = useLazyQuery( + QUERY_RO_AND_OWNER_BY_JOB_PKS, + { + variables: { jobids: [context.jobid] }, + skip: true, + } + ); + console.log("🚀 ~ file: card-payment-modal.component..jsx:61 ~ data:", data); //Initialize the intellipay window. const SetIntellipayCallbackFunctions = () => { console.log("*** Set IntelliPay callback functions."); @@ -76,69 +81,68 @@ const CardPaymentModalComponent = ({ window.intellipay.runOnNonApproval(async function (response) { // Mutate unsuccessful payment + + const { payments } = form.getFieldsValue(); + await insertPaymentResponse({ variables: { - paymentResponse: { - amount: response.amount, + paymentResponse: payments.map((payment) => ({ + amount: payment.amount, bodyshopid: bodyshop.id, - jobid: jobid || context.jobid, + jobid: payment.jobid, declinereason: response.declinereason, ext_paymentid: response.paymentid.toString(), successful: false, response, - }, + })), }, }); - insertAuditTrail({ - jobid: jobid || context?.jobid, - operation: AuditTrailMapping.failedpayment(), - }); + + payments.forEach((payment) => + insertAuditTrail({ + jobid: payment.jobid, + operation: AuditTrailMapping.failedpayment(), + }) + ); }); }; const handleFinish = async (values) => { try { - const paymentResult = await insertPayment({ + await insertPayment({ variables: { - paymentInput: { - amount: values.amount, + paymentInput: values.payments.map((payment) => ({ + amount: payment.amount, transactionid: (values.paymentResponse.paymentid || "").toString(), payer: t("payments.labels.customer"), type: values.paymentResponse.cardbrand, - jobid: values.jobid, + jobid: payment.jobid, date: moment(Date.now()), - }, + payment_responses: { + data: [ + { + amount: payment.amount, + bodyshopid: bodyshop.id, + + jobid: payment.jobid, + declinereason: values.paymentResponse.declinereason, + ext_paymentid: values.paymentResponse.paymentid.toString(), + successful: true, + response: values.paymentResponse, + }, + ], + }, + })), }, refetchQueries: ["GET_JOB_BY_PK"], - update(cache, { data }) { - cache.modify({ - id: cache.identify({ id: values.jobid, __typename: "jobs" }), - fields: { - payments(cachedPayments) { - return [...data.insert_payments.returning, ...cachedPayments]; - }, - }, - }); - }, - }); - - await insertPaymentResponse({ - variables: { - paymentResponse: { - amount: values.amount, - bodyshopid: bodyshop.id, - paymentid: paymentResult.data.insert_payments.returning[0].id, - jobid: values.jobid, - declinereason: values.paymentResponse.declinereason, - ext_paymentid: values.paymentResponse.paymentid.toString(), - successful: true, - response: values.paymentResponse, - }, - }, }); toggleModalVisible(); } catch (error) { console.error(error); + notification.open({ + type: "error", + message: t("payments.errors.inserting", { error: error.message }), + }); } finally { setLoading(false); } @@ -146,9 +150,16 @@ const CardPaymentModalComponent = ({ const handleIntelliPayCharge = async () => { setLoading(true); - try { - console.warn("*** Window.Intellipay", !!window.intellipay); + //Validate + try { + await form.validateFields(); + } catch (error) { + setLoading(false); + return; + } + + try { const response = await axios.post("/intellipay/lightbox_credentials", { bodyshop, refresh: !!window.intellipay, @@ -182,93 +193,175 @@ const CardPaymentModalComponent = ({
- - - { - refetch({ jobid: e }); - }} - /> - - + + {(fields, { add, remove, move }) => { + return ( +
+ {fields.map((field, index) => ( + + + + + + + + + + + + + + { + remove(field.name); + }} + /> + + + + ))} + + + +
+ ); + }} +
- {/* Lighbox Input amount needs to be hidden */} - - - - {/* Lightbox payment response when it is completed */} -
{payment_response && ( - + + - + + )} diff --git a/client/src/graphql/payment_response.queries.js b/client/src/graphql/payment_response.queries.js index 8722e6cd8..a23d00dbb 100644 --- a/client/src/graphql/payment_response.queries.js +++ b/client/src/graphql/payment_response.queries.js @@ -28,16 +28,14 @@ export const QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID = gql` } `; -export const QUERY_RO_AND_OWNER_BY_JOB_PK = gql` - query QUERY_RO_AND_OWNER_BY_JOB_PK($jobid: uuid!) { - jobs_by_pk(id: $jobid) { +export const QUERY_RO_AND_OWNER_BY_JOB_PKS = gql` + query QUERY_RO_AND_OWNER_BY_JOB_PKS($jobids: [uuid!]!) { + jobs(where: { id: { _in: $jobids } }) { ro_number - owner { - ownr_fn - ownr_ln - ownr_ea - ownr_zip - } + ownr_fn + ownr_ln + ownr_ea + ownr_zip } } `; diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index e3d3a4a15..f25ae0656 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -2206,7 +2206,8 @@ }, "errors": { "exporting": "Error exporting payment(s). {{error}}", - "exporting-partner": "Error exporting to partner. Please check the partner interaction log for more errors." + "exporting-partner": "Error exporting to partner. Please check the partner interaction log for more errors.", + "inserting": "Error inserting payment. {{error}}" }, "fields": { "amount": "Amount", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 9ea597631..95187d8c4 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -2206,7 +2206,8 @@ }, "errors": { "exporting": "", - "exporting-partner": "" + "exporting-partner": "", + "inserting": "" }, "fields": { "amount": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 4a76f081c..7f3b4706a 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -2206,7 +2206,8 @@ }, "errors": { "exporting": "", - "exporting-partner": "" + "exporting-partner": "", + "inserting": "" }, "fields": { "amount": "", From dc05e4e16673915c3b70371652e239a36bcf3f45 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 26 Sep 2023 12:58:33 -0700 Subject: [PATCH 6/6] Add CIECA PFO object to job. --- hasura/metadata/tables.yaml | 3 +++ .../down.sql | 4 ++++ .../up.sql | 2 ++ 3 files changed, 9 insertions(+) create mode 100644 hasura/migrations/1695757361064_alter_table_public_jobs_add_column_cieca_pfo/down.sql create mode 100644 hasura/migrations/1695757361064_alter_table_public_jobs_add_column_cieca_pfo/up.sql diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml index 1d05bd8fd..9b19c1777 100644 --- a/hasura/metadata/tables.yaml +++ b/hasura/metadata/tables.yaml @@ -3274,6 +3274,7 @@ - cat_no - category - cieca_pfl + - cieca_pfo - cieca_pft - cieca_stl - cieca_ttl @@ -3542,6 +3543,7 @@ - cat_no - category - cieca_pfl + - cieca_pfo - cieca_pft - cieca_stl - cieca_ttl @@ -3821,6 +3823,7 @@ - cat_no - category - cieca_pfl + - cieca_pfo - cieca_pft - cieca_stl - cieca_ttl diff --git a/hasura/migrations/1695757361064_alter_table_public_jobs_add_column_cieca_pfo/down.sql b/hasura/migrations/1695757361064_alter_table_public_jobs_add_column_cieca_pfo/down.sql new file mode 100644 index 000000000..31337afb8 --- /dev/null +++ b/hasura/migrations/1695757361064_alter_table_public_jobs_add_column_cieca_pfo/down.sql @@ -0,0 +1,4 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- alter table "public"."jobs" add column "cieca_pfo" jsonb +-- null default jsonb_build_object(); diff --git a/hasura/migrations/1695757361064_alter_table_public_jobs_add_column_cieca_pfo/up.sql b/hasura/migrations/1695757361064_alter_table_public_jobs_add_column_cieca_pfo/up.sql new file mode 100644 index 000000000..d21094fdd --- /dev/null +++ b/hasura/migrations/1695757361064_alter_table_public_jobs_add_column_cieca_pfo/up.sql @@ -0,0 +1,2 @@ +alter table "public"."jobs" add column "cieca_pfo" jsonb + null default jsonb_build_object();