diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 9a1af3c1e..73a17a763 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -2150,6 +2150,90 @@ labels + + 2tiername + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + 2tiersetup + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + 2tiersource + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + accountingtiers + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + alljobstatuses false diff --git a/client/src/App/App.container.jsx b/client/src/App/App.container.jsx index def27878c..94dfd25e6 100644 --- a/client/src/App/App.container.jsx +++ b/client/src/App/App.container.jsx @@ -41,6 +41,7 @@ const wsLink = new WebSocketLink({ }, }, }); + const subscriptionMiddleware = { applyMiddleware: async (options, next) => { options.authToken = @@ -118,7 +119,6 @@ export const client = new ApolloClient({ export default class AppContainer extends Component { constructor() { super(); - this.state = { client }; } diff --git a/client/src/components/shop-info/shop-info.component.jsx b/client/src/components/shop-info/shop-info.component.jsx index 8c39bf08d..c05a7bf2c 100644 --- a/client/src/components/shop-info/shop-info.component.jsx +++ b/client/src/components/shop-info/shop-info.component.jsx @@ -1,5 +1,5 @@ import React from "react"; -import { Form, Input, Button, Collapse, InputNumber } from "antd"; +import { Form, Input, Button, Collapse, InputNumber, Radio } from "antd"; import { useTranslation } from "react-i18next"; import ShopInfoROStatusComponent from "./shop-info.rostatus.component"; import ShopInfoOrderStatusComponent from "./shop-info.orderstatus.component"; @@ -9,95 +9,126 @@ export default function ShopInfoComponent({ form }) { const { t } = useTranslation(); return (
- - - - + + + - + - + - + - + - + - + - + + name='federal_tax_id'> + name='insurance_vendor_id'> + name='logo_img_path'> + name='state_tax_id'> + name={["invoice_tax_rates", "federal_tax_rate"]}> + name={["invoice_tax_rates", "state_tax_rate"]}> + name={["invoice_tax_rates", "local_tax_rate"]}> + + + 2 + 3 + + + + {() => { + return ( + + + {t("bodyshop.labels.2tiername")} + + {t("bodyshop.labels.2tiersource")} + + + + ); + }} + + key='roStatus' + header={t("bodyshop.labels.jobstatuses")}> + key='orderStatus' + header={t("bodyshop.labels.orderstatuses")}> + key='responsibilityCenters' + header={t("bodyshop.labels.responsibilitycenters.title")}> diff --git a/client/src/graphql/bodyshop.queries.js b/client/src/graphql/bodyshop.queries.js index 0e0d51f6c..6e5f45310 100644 --- a/client/src/graphql/bodyshop.queries.js +++ b/client/src/graphql/bodyshop.queries.js @@ -29,6 +29,7 @@ export const QUERY_BODYSHOP = gql` production_config invoice_tax_rates inhousevendorid + accountingconfig employees { id first_name diff --git a/client/src/pages/jobs-all/jobs-all.container.jsx b/client/src/pages/jobs-all/jobs-all.container.jsx index 2cd772d4e..772aaddbf 100644 --- a/client/src/pages/jobs-all/jobs-all.container.jsx +++ b/client/src/pages/jobs-all/jobs-all.container.jsx @@ -1,6 +1,6 @@ import { useQuery } from "@apollo/react-hooks"; import queryString from "query-string"; -import React, { useEffect, useState } from "react"; +import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { useLocation } from "react-router-dom"; diff --git a/client/src/pages/manage/manage.page.component.jsx b/client/src/pages/manage/manage.page.component.jsx index deec86f50..a357ee254 100644 --- a/client/src/pages/manage/manage.page.component.jsx +++ b/client/src/pages/manage/manage.page.component.jsx @@ -14,7 +14,7 @@ import { selectInstanceConflict } from "../../redux/user/user.selectors"; import HeaderContainer from "../../components/header/header.container"; import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component"; import PrintCenterModalContainer from "../../components/print-center-modal/print-center-modal.container"; -import ConflictComponent from '../../components/conflict/conflict.component' +import ConflictComponent from "../../components/conflict/conflict.component"; import "./manage.page.styles.scss"; const ManageRootPage = lazy(() => @@ -118,9 +118,8 @@ export function Manage({ match, conflict }) { + className='content-container' + style={{ padding: "0em 4em 4em" }}> {conflict ? ( @@ -129,8 +128,7 @@ export function Manage({ match, conflict }) { - } - > + }> diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index fd0f979e5..418b2e949 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -142,6 +142,10 @@ "zip_post": "Zip/Postal Code" }, "labels": { + "2tiername": "Name => RO", + "2tiersetup": "2 Tier Setup", + "2tiersource": "Source => RO", + "accountingtiers": "Number of Tiers to Use for Export", "alljobstatuses": "All Job Statuses", "allopenjobstatuses": "All Open Job Statuses", "customtemplates": "Custom Templates", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 4f21aea93..851c834b3 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -142,6 +142,10 @@ "zip_post": "" }, "labels": { + "2tiername": "", + "2tiersetup": "", + "2tiersource": "", + "accountingtiers": "", "alljobstatuses": "", "allopenjobstatuses": "", "customtemplates": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 0005bc80d..340111aaa 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -142,6 +142,10 @@ "zip_post": "" }, "labels": { + "2tiername": "", + "2tiersetup": "", + "2tiersource": "", + "accountingtiers": "", "alljobstatuses": "", "allopenjobstatuses": "", "customtemplates": "", diff --git a/hasura/migrations/1590789133099_alter_table_public_bodyshops_add_column_accountingconfig/down.yaml b/hasura/migrations/1590789133099_alter_table_public_bodyshops_add_column_accountingconfig/down.yaml new file mode 100644 index 000000000..988d9aa47 --- /dev/null +++ b/hasura/migrations/1590789133099_alter_table_public_bodyshops_add_column_accountingconfig/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."bodyshops" DROP COLUMN "accountingconfig"; + type: run_sql diff --git a/hasura/migrations/1590789133099_alter_table_public_bodyshops_add_column_accountingconfig/up.yaml b/hasura/migrations/1590789133099_alter_table_public_bodyshops_add_column_accountingconfig/up.yaml new file mode 100644 index 000000000..52ad50ed2 --- /dev/null +++ b/hasura/migrations/1590789133099_alter_table_public_bodyshops_add_column_accountingconfig/up.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."bodyshops" ADD COLUMN "accountingconfig" jsonb NULL; + type: run_sql diff --git a/hasura/migrations/1590789150309_update_permission_user_public_table_bodyshops/down.yaml b/hasura/migrations/1590789150309_update_permission_user_public_table_bodyshops/down.yaml new file mode 100644 index 000000000..24fcc62ed --- /dev/null +++ b/hasura/migrations/1590789150309_update_permission_user_public_table_bodyshops/down.yaml @@ -0,0 +1,50 @@ +- args: + role: user + table: + name: bodyshops + schema: public + type: drop_select_permission +- args: + permission: + allow_aggregations: false + columns: + - address1 + - address2 + - city + - country + - created_at + - email + - federal_tax_id + - id + - inhousevendorid + - insurance_vendor_id + - intakechecklist + - invoice_tax_rates + - logo_img_path + - md_order_statuses + - md_responsibility_centers + - md_ro_statuses + - messagingservicesid + - production_config + - region_config + - shopname + - shoprates + - state + - state_tax_id + - template_header + - textid + - updated_at + - zip_post + computed_fields: [] + filter: + associations: + bodyshop: + associations: + user: + authid: + _eq: X-Hasura-User-Id + role: user + table: + name: bodyshops + schema: public + type: create_select_permission diff --git a/hasura/migrations/1590789150309_update_permission_user_public_table_bodyshops/up.yaml b/hasura/migrations/1590789150309_update_permission_user_public_table_bodyshops/up.yaml new file mode 100644 index 000000000..c7c8f849d --- /dev/null +++ b/hasura/migrations/1590789150309_update_permission_user_public_table_bodyshops/up.yaml @@ -0,0 +1,51 @@ +- args: + role: user + table: + name: bodyshops + schema: public + type: drop_select_permission +- args: + permission: + allow_aggregations: false + columns: + - accountingconfig + - address1 + - address2 + - city + - country + - created_at + - email + - federal_tax_id + - id + - inhousevendorid + - insurance_vendor_id + - intakechecklist + - invoice_tax_rates + - logo_img_path + - md_order_statuses + - md_responsibility_centers + - md_ro_statuses + - messagingservicesid + - production_config + - region_config + - shopname + - shoprates + - state + - state_tax_id + - template_header + - textid + - updated_at + - zip_post + computed_fields: [] + filter: + associations: + bodyshop: + associations: + user: + authid: + _eq: X-Hasura-User-Id + role: user + table: + name: bodyshops + schema: public + type: create_select_permission diff --git a/hasura/migrations/1590789163123_update_permission_user_public_table_bodyshops/down.yaml b/hasura/migrations/1590789163123_update_permission_user_public_table_bodyshops/down.yaml new file mode 100644 index 000000000..477056eb1 --- /dev/null +++ b/hasura/migrations/1590789163123_update_permission_user_public_table_bodyshops/down.yaml @@ -0,0 +1,48 @@ +- args: + role: user + table: + name: bodyshops + schema: public + type: drop_update_permission +- args: + permission: + columns: + - address1 + - address2 + - city + - country + - created_at + - email + - federal_tax_id + - id + - inhousevendorid + - insurance_vendor_id + - intakechecklist + - invoice_tax_rates + - logo_img_path + - md_order_statuses + - md_responsibility_centers + - md_ro_statuses + - production_config + - shopname + - shoprates + - state + - state_tax_id + - updated_at + - zip_post + filter: + associations: + bodyshop: + associations: + user: + authid: + _eq: X-Hasura-User-Id + localPresets: + - key: "" + value: "" + set: {} + role: user + table: + name: bodyshops + schema: public + type: create_update_permission diff --git a/hasura/migrations/1590789163123_update_permission_user_public_table_bodyshops/up.yaml b/hasura/migrations/1590789163123_update_permission_user_public_table_bodyshops/up.yaml new file mode 100644 index 000000000..86c1ba881 --- /dev/null +++ b/hasura/migrations/1590789163123_update_permission_user_public_table_bodyshops/up.yaml @@ -0,0 +1,49 @@ +- args: + role: user + table: + name: bodyshops + schema: public + type: drop_update_permission +- args: + permission: + columns: + - accountingconfig + - address1 + - address2 + - city + - country + - created_at + - email + - federal_tax_id + - id + - inhousevendorid + - insurance_vendor_id + - intakechecklist + - invoice_tax_rates + - logo_img_path + - md_order_statuses + - md_responsibility_centers + - md_ro_statuses + - production_config + - shopname + - shoprates + - state + - state_tax_id + - updated_at + - zip_post + filter: + associations: + bodyshop: + associations: + user: + authid: + _eq: X-Hasura-User-Id + localPresets: + - key: "" + value: "" + set: {} + role: user + table: + name: bodyshops + schema: public + type: create_update_permission diff --git a/hasura/migrations/1590790802468_run_sql_migration/down.yaml b/hasura/migrations/1590790802468_run_sql_migration/down.yaml new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/hasura/migrations/1590790802468_run_sql_migration/down.yaml @@ -0,0 +1 @@ +[] diff --git a/hasura/migrations/1590790802468_run_sql_migration/up.yaml b/hasura/migrations/1590790802468_run_sql_migration/up.yaml new file mode 100644 index 000000000..44e444fed --- /dev/null +++ b/hasura/migrations/1590790802468_run_sql_migration/up.yaml @@ -0,0 +1,7 @@ +- args: + cascade: true + read_only: false + sql: |- + alter table owners + drop column accountingid; + type: run_sql diff --git a/hasura/migrations/1590790827681_alter_table_public_owners_add_column_accountingid/down.yaml b/hasura/migrations/1590790827681_alter_table_public_owners_add_column_accountingid/down.yaml new file mode 100644 index 000000000..92c2567cf --- /dev/null +++ b/hasura/migrations/1590790827681_alter_table_public_owners_add_column_accountingid/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."owners" DROP COLUMN "accountingid"; + type: run_sql diff --git a/hasura/migrations/1590790827681_alter_table_public_owners_add_column_accountingid/up.yaml b/hasura/migrations/1590790827681_alter_table_public_owners_add_column_accountingid/up.yaml new file mode 100644 index 000000000..4e7f1d760 --- /dev/null +++ b/hasura/migrations/1590790827681_alter_table_public_owners_add_column_accountingid/up.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."owners" ADD COLUMN "accountingid" bigserial NOT NULL; + type: run_sql diff --git a/hasura/migrations/1590790851669_update_permission_user_public_table_owners/down.yaml b/hasura/migrations/1590790851669_update_permission_user_public_table_owners/down.yaml new file mode 100644 index 000000000..915b657e4 --- /dev/null +++ b/hasura/migrations/1590790851669_update_permission_user_public_table_owners/down.yaml @@ -0,0 +1,6 @@ +- args: + role: user + table: + name: owners + schema: public + type: drop_insert_permission diff --git a/hasura/migrations/1590790851669_update_permission_user_public_table_owners/up.yaml b/hasura/migrations/1590790851669_update_permission_user_public_table_owners/up.yaml new file mode 100644 index 000000000..ced04216b --- /dev/null +++ b/hasura/migrations/1590790851669_update_permission_user_public_table_owners/up.yaml @@ -0,0 +1,42 @@ +- args: + permission: + allow_upsert: true + check: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + columns: + - id + - created_at + - updated_at + - ownr_fn + - ownr_ln + - ownr_addr1 + - ownr_addr2 + - ownr_city + - ownr_st + - ownr_zip + - ownr_ctry + - ownr_ea + - ownr_ph1 + - preferred_contact + - allow_text_message + - shopid + - ownr_ph2 + - ownr_co_nm + - ownr_title + - accountingid + localPresets: + - key: "" + value: "" + set: {} + role: user + table: + name: owners + schema: public + type: create_insert_permission diff --git a/hasura/migrations/1590790859209_update_permission_user_public_table_owners/down.yaml b/hasura/migrations/1590790859209_update_permission_user_public_table_owners/down.yaml new file mode 100644 index 000000000..9f10ffd44 --- /dev/null +++ b/hasura/migrations/1590790859209_update_permission_user_public_table_owners/down.yaml @@ -0,0 +1,6 @@ +- args: + role: user + table: + name: owners + schema: public + type: drop_select_permission diff --git a/hasura/migrations/1590790859209_update_permission_user_public_table_owners/up.yaml b/hasura/migrations/1590790859209_update_permission_user_public_table_owners/up.yaml new file mode 100644 index 000000000..7a2479c36 --- /dev/null +++ b/hasura/migrations/1590790859209_update_permission_user_public_table_owners/up.yaml @@ -0,0 +1,40 @@ +- args: + permission: + allow_aggregations: false + columns: + - allow_text_message + - accountingid + - ownr_addr1 + - ownr_addr2 + - ownr_city + - ownr_co_nm + - ownr_ctry + - ownr_ea + - ownr_fn + - ownr_ln + - ownr_ph1 + - ownr_ph2 + - ownr_st + - ownr_title + - ownr_zip + - preferred_contact + - created_at + - updated_at + - id + - shopid + computed_fields: [] + filter: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + limit: null + role: user + table: + name: owners + schema: public + type: create_select_permission diff --git a/hasura/migrations/1590790873577_update_permission_user_public_table_owners/down.yaml b/hasura/migrations/1590790873577_update_permission_user_public_table_owners/down.yaml new file mode 100644 index 000000000..b94959d43 --- /dev/null +++ b/hasura/migrations/1590790873577_update_permission_user_public_table_owners/down.yaml @@ -0,0 +1,6 @@ +- args: + role: user + table: + name: owners + schema: public + type: drop_update_permission diff --git a/hasura/migrations/1590790873577_update_permission_user_public_table_owners/up.yaml b/hasura/migrations/1590790873577_update_permission_user_public_table_owners/up.yaml new file mode 100644 index 000000000..cb8f05bec --- /dev/null +++ b/hasura/migrations/1590790873577_update_permission_user_public_table_owners/up.yaml @@ -0,0 +1,41 @@ +- args: + permission: + columns: + - allow_text_message + - accountingid + - ownr_addr1 + - ownr_addr2 + - ownr_city + - ownr_co_nm + - ownr_ctry + - ownr_ea + - ownr_fn + - ownr_ln + - ownr_ph1 + - ownr_ph2 + - ownr_st + - ownr_title + - ownr_zip + - preferred_contact + - created_at + - updated_at + - id + - shopid + filter: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true + localPresets: + - key: "" + value: "" + set: {} + role: user + table: + name: owners + schema: public + type: create_update_permission diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml index 6ef734a5c..8df2ef107 100644 --- a/hasura/migrations/metadata.yaml +++ b/hasura/migrations/metadata.yaml @@ -444,6 +444,7 @@ tables: - role: user permission: columns: + - accountingconfig - address1 - address2 - city @@ -482,6 +483,7 @@ tables: - role: user permission: columns: + - accountingconfig - address1 - address2 - city @@ -2840,34 +2842,32 @@ tables: - active: _eq: true columns: - - accountingid - - allow_text_message - - created_at - id + - created_at + - updated_at + - ownr_fn + - ownr_ln - ownr_addr1 - ownr_addr2 - ownr_city - - ownr_co_nm + - ownr_st + - ownr_zip - ownr_ctry - ownr_ea - - ownr_fn - - ownr_ln - ownr_ph1 - - ownr_ph2 - - ownr_st - - ownr_title - - ownr_zip - preferred_contact + - allow_text_message - shopid - - updated_at + - ownr_ph2 + - ownr_co_nm + - ownr_title + - accountingid select_permissions: - role: user permission: columns: - - accountingid - allow_text_message - - created_at - - id + - accountingid - ownr_addr1 - ownr_addr2 - ownr_city @@ -2882,8 +2882,10 @@ tables: - ownr_title - ownr_zip - preferred_contact - - shopid + - created_at - updated_at + - id + - shopid filter: bodyshop: associations: @@ -2897,10 +2899,8 @@ tables: - role: user permission: columns: - - accountingid - allow_text_message - - created_at - - id + - accountingid - ownr_addr1 - ownr_addr2 - ownr_city @@ -2915,8 +2915,10 @@ tables: - ownr_title - ownr_zip - preferred_contact - - shopid + - created_at - updated_at + - id + - shopid filter: bodyshop: associations: diff --git a/server/accounting/qbxml/qbxml-receivables.js b/server/accounting/qbxml/qbxml-receivables.js index d4fee85b3..33cc4fda5 100644 --- a/server/accounting/qbxml/qbxml-receivables.js +++ b/server/accounting/qbxml/qbxml-receivables.js @@ -25,97 +25,195 @@ exports.default = async (req, res) => { const result = await client .setHeaders({ Authorization: BearerToken }) .request(queries.QUERY_JOBS_FOR_RECEIVABLES_EXPORT, { id: jobId }); - const { jobs_by_pk } = result; const { bodyshop } = jobs_by_pk; - //Build the XML file. + const QbXmlToExecute = []; - const InvoiceLineAdd = []; - const invoice_allocation = jobs_by_pk.invoice_allocation; - Object.keys(invoice_allocation.partsAllocations).forEach( - (partsAllocationKey) => { - if ( - !!!invoice_allocation.partsAllocations[partsAllocationKey].allocations - ) - return; + //Is this a two tier, or 3 tier setup? + const isThreeTier = bodyshop.accountingconfig.tiers === 3; - invoice_allocation.partsAllocations[ - partsAllocationKey - ].allocations.forEach((alloc) => { - InvoiceLineAdd.push( - generateInvoiceLine( - jobs_by_pk, - alloc, - bodyshop.md_responsibility_centers - ) - ); - }); - } - ); - Object.keys(invoice_allocation.labMatAllocations).forEach( - (AllocationKey) => { - if (!!!invoice_allocation.labMatAllocations[AllocationKey].allocations) - return; - - invoice_allocation.labMatAllocations[AllocationKey].allocations.forEach( - (alloc) => { - InvoiceLineAdd.push( - generateInvoiceLine( - jobs_by_pk, - alloc, - bodyshop.md_responsibility_centers - ) - ); - } - ); - } + QbXmlToExecute.push( + generateCustomerQbxml(jobs_by_pk, bodyshop, isThreeTier) ); - const foo = { - QBXML: { - QBXMLMsgsRq: { - "@onError": "stopOnError", - InvoiceAddRq: { - InvoiceAdd: { - CustomerRef: { - ListID: jobs_by_pk.owner.accountingid, - FullName: `${jobs_by_pk.ownr_ln}, ${jobs_by_pk.ownr_fn}`, - }, - TxnDate: new Date(), - RefNumber: jobs_by_pk.ro_number, - BillAddress: { - Addr1: jobs_by_pk.ownr_addr1, - Addr2: jobs_by_pk.ownr_addr2, - City: jobs_by_pk.ownr_city, - State: jobs_by_pk.ownr_st, - PostalCode: jobs_by_pk.ownrzip, - }, - // PONumber: "Ponumber", + if (isThreeTier) { + QbXmlToExecute.push(generateJobQbxml(jobs_by_pk, bodyshop, 2)); + QbXmlToExecute.push(generateJobQbxml(jobs_by_pk, bodyshop, 3)); + } - InvoiceLineAdd: InvoiceLineAdd, - }, - }, - }, - }, - }; - - var requestXML = builder - .create(foo, { version: "1.30", encoding: "UTF-8", headless: true }) - .end({ pretty: true }); - - const ret = ` - - ${requestXML} - `; - - console.log(ret); - res.status(200).send(ret); + console.log(QbXmlToExecute); + res.status(200).json(QbXmlToExecute); } catch (error) { console.log("error", error); res.status(400).send(JSON.stringify(error)); } }; +const generateCustomerQbxml = (jobs_by_pk, bodyshop, isThreeTier) => { + const customerQbxmlObj = { + QBXML: { + QBXMLMsgsRq: { + "@onError": "continueOnError", + CustomerAddRq: { + CustomerAdd: { + Name: isThreeTier + ? jobs_by_pk.ins_co_nm + : jobs_by_pk.ownr_co_nm + ? `${jobs_by_pk.ownr_co_nm} - ${jobs_by_pk.ownr_ln || ""} ${ + jobs_by_pk.ownr_fn || "" + } #${jobs_by_pk.owner.accountingid || ""}` + : `${jobs_by_pk.ownr_ln || ""} ${jobs_by_pk.ownr_fn || ""} #${ + jobs_by_pk.owner.accountingid || "" + }`, + BillAddress: isThreeTier + ? null + : { + Addr1: jobs_by_pk.ownr_addr1, + Addr2: jobs_by_pk.ownr_addr2, + City: jobs_by_pk.ownr_city, + State: jobs_by_pk.ownr_st, + PostalCode: jobs_by_pk.ownrzip, + }, + }, + }, + }, + }, + }; + + var customerQbxml_partial = builder + .create(customerQbxmlObj, { + version: "1.30", + encoding: "UTF-8", + headless: true, + }) + .end({ pretty: true }); + + const customerQbxml_Full = addQbxmlHeader(customerQbxml_partial); + + return customerQbxml_Full; +}; + +const generateJobQbxml = (jobs_by_pk, bodyshop, isThreeTier, tierLevel) => { + const tier1Name = jobs_by_pk.ownr_co_nm; + const tier2Name = jobs_by_pk.ownr_co_nm + ? `${jobs_by_pk.ownr_co_nm} - ${jobs_by_pk.ownr_ln || ""} ${ + jobs_by_pk.ownr_fn || "" + } #${jobs_by_pk.owner.accountingid || ""}` + : `${jobs_by_pk.ownr_ln || ""} ${jobs_by_pk.ownr_fn || ""} #${ + jobs_by_pk.owner.accountingid || "" + }`; + + const jobQbxmlObj = { + QBXML: { + QBXMLMsgsRq: { + "@onError": "continueOnError", + CustomerAddRq: { + CustomerAdd: { + Name: tierLevel === 2 ? null : null, + ParentRef: { + FullName: tierLevel === 2 ? null : null, + }, + }, + }, + }, + }, + }; + + var jobQbxml_partial = builder + .create(jobQbxmlObj, { + version: "1.30", + encoding: "UTF-8", + headless: true, + }) + .end({ pretty: true }); + + const jobQbxml_Full = addQbxmlHeader(jobQbxml_partial); + return jobQbxml_Full; +}; + +const generateInvoiceQbxml = (jobs_by_pk, bodyshop) => { + //Build the Invoice XML file. + const InvoiceLineAdd = []; + const invoice_allocation = jobs_by_pk.invoice_allocation; + Object.keys(invoice_allocation.partsAllocations).forEach( + (partsAllocationKey) => { + if ( + !!!invoice_allocation.partsAllocations[partsAllocationKey].allocations + ) + return; + invoice_allocation.partsAllocations[ + partsAllocationKey + ].allocations.forEach((alloc) => { + InvoiceLineAdd.push( + generateInvoiceLine( + jobs_by_pk, + alloc, + bodyshop.md_responsibility_centers + ) + ); + }); + } + ); + Object.keys(invoice_allocation.labMatAllocations).forEach((AllocationKey) => { + if (!!!invoice_allocation.labMatAllocations[AllocationKey].allocations) + return; + invoice_allocation.labMatAllocations[AllocationKey].allocations.forEach( + (alloc) => { + InvoiceLineAdd.push( + generateInvoiceLine( + jobs_by_pk, + alloc, + bodyshop.md_responsibility_centers + ) + ); + } + ); + }); + + const invoiceQbxmlObj = { + QBXML: { + QBXMLMsgsRq: { + "@onError": "stopOnError", + InvoiceAddRq: { + InvoiceAdd: { + CustomerRef: { + //This can equal the Customer or the Customer Job. + FullName: + bodyshop.accountingconfig.tiers === 3 + ? "3tier" + : bodyshop.accountingconfig.twotierpref === "name" + ? "2tiername" + : "2tiersource", + }, + TxnDate: new Date(), + RefNumber: jobs_by_pk.ro_number, + BillAddress: { + Addr1: jobs_by_pk.ownr_addr1, + Addr2: jobs_by_pk.ownr_addr2, + City: jobs_by_pk.ownr_city, + State: jobs_by_pk.ownr_st, + PostalCode: jobs_by_pk.ownrzip, + }, + PONumber: jobs_by_pk.clm_no, + InvoiceLineAdd: InvoiceLineAdd, + }, + }, + }, + }, + }; + var invoiceQbxml_partial = builder + .create(invoiceQbxmlObj, { + version: "1.30", + encoding: "UTF-8", + headless: true, + }) + .end({ pretty: true }); + + const invoiceQbxml_Full = addQbxmlHeader(invoiceQbxml_partial); + + return invoiceQbxml_Full; +}; + const generateInvoiceLine = (job, allocation, responsibilityCenters) => { const { amount, center } = allocation; const DineroAmount = Dinero(amount); @@ -140,3 +238,10 @@ const generateInvoiceLine = (job, allocation, responsibilityCenters) => { }, }; }; + +const addQbxmlHeader = (xml) => { + return ` + + ${xml} + `; +}; diff --git a/server/graphql-client/queries.js b/server/graphql-client/queries.js index c6591130c..e887c66ce 100644 --- a/server/graphql-client/queries.js +++ b/server/graphql-client/queries.js @@ -57,12 +57,14 @@ query QUERY_JOBS_FOR_RECEIVABLES_EXPORT($id: uuid!) { ownr_zip ownr_city ownr_st + ins_co_nm owner{ accountingid } bodyshop { id md_responsibility_centers + accountingconfig } } }