@@ -1,4 +1,4 @@
|
||||
<babeledit_project version="1.2" be_version="2.7.1">
|
||||
<babeledit_project be_version="2.7.1" version="1.2">
|
||||
<!--
|
||||
|
||||
BabelEdit project file
|
||||
@@ -40261,6 +40261,53 @@
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>validation</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>clockoffmustbeafterclockon</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>clockoffwithoutclockon</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
Space,
|
||||
Switch,
|
||||
Table,
|
||||
Tooltip,
|
||||
Tooltip
|
||||
} from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -334,6 +334,19 @@ export function BillEnterModalLinesComponent({
|
||||
additional: (record, index) => (
|
||||
<Form.Item shouldUpdate style={{ display: "inline-block" }}>
|
||||
{() => {
|
||||
const price = getFieldValue([
|
||||
"billlines",
|
||||
record.name,
|
||||
"actual_price",
|
||||
]);
|
||||
|
||||
const adjustmentRate = getFieldValue([
|
||||
"billlines",
|
||||
record.name,
|
||||
"lbr_adjustment",
|
||||
"rate",
|
||||
]);
|
||||
|
||||
if (getFieldValue(["billlines", record.name, "deductedfromlbr"]))
|
||||
return (
|
||||
<div>
|
||||
@@ -406,6 +419,9 @@ export function BillEnterModalLinesComponent({
|
||||
>
|
||||
<InputNumber precision={2} min={0.01} />
|
||||
</Form.Item>
|
||||
{price &&
|
||||
adjustmentRate &&
|
||||
`${(price / adjustmentRate).toFixed(1)} hrs`}
|
||||
</div>
|
||||
);
|
||||
return <></>;
|
||||
|
||||
@@ -38,6 +38,7 @@ export default function ScheduleEventContainer({ bodyshop, event, refetch }) {
|
||||
job: {
|
||||
date_scheduled: null,
|
||||
scheduled_in: null,
|
||||
scheduled_completion:null,
|
||||
status: bodyshop.md_ro_statuses.default_imported,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -6,9 +6,11 @@ import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { setPartnerVersion } from "../../redux/application/application.actions";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
@@ -19,7 +21,7 @@ export default connect(
|
||||
mapDispatchToProps
|
||||
)(PartnerPingComponent);
|
||||
|
||||
export function PartnerPingComponent({ setPartnerVersion }) {
|
||||
export function PartnerPingComponent({ bodyshop, setPartnerVersion }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -29,16 +31,25 @@ export function PartnerPingComponent({ setPartnerVersion }) {
|
||||
//if (process.env.NODE_ENV === "development") return;
|
||||
const PartnerResponse = await axios.post("http://localhost:1337/ping/");
|
||||
const { appver, qbpath } = PartnerResponse.data;
|
||||
|
||||
if (!bodyshop) return;
|
||||
setPartnerVersion(appver);
|
||||
console.log({ appver, qbpath });
|
||||
if (!qbpath) {
|
||||
if (
|
||||
!qbpath &&
|
||||
!(
|
||||
bodyshop &&
|
||||
(bodyshop.cdk_dealerid ||
|
||||
bodyshop.pbs_serialnumber ||
|
||||
bodyshop.accountingconfig.qbo)
|
||||
)
|
||||
) {
|
||||
notification["error"]({
|
||||
title: "",
|
||||
message: t("general.messages.noacctfilepath"),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
notification["error"]({
|
||||
title: "",
|
||||
message: t("general.messages.partnernotrunning"),
|
||||
@@ -48,7 +59,7 @@ export function PartnerPingComponent({ setPartnerVersion }) {
|
||||
// Execute the created function directly
|
||||
checkPartnerStatus();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [bodyshop]);
|
||||
|
||||
return <></>;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ import AlertComponent from "../alert/alert.component";
|
||||
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||
import PartsOrderModalComponent from "./parts-order-modal.component";
|
||||
import axios from "axios";
|
||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||
import _ from "lodash";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
currentUser: selectCurrentUser,
|
||||
@@ -57,6 +59,11 @@ export function PartsOrderModalContainer({
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const client = useApolloClient();
|
||||
const { OEConnection_PriceChange } = useTreatments(
|
||||
["OEConnection_PriceChange"],
|
||||
{},
|
||||
bodyshop.imexshopid
|
||||
);
|
||||
const { visible, context, actions } = partsOrderModal;
|
||||
const {
|
||||
jobId,
|
||||
@@ -230,11 +237,22 @@ export function PartsOrderModalContainer({
|
||||
id: insertResult.data.insert_parts_orders.returning[0].id,
|
||||
},
|
||||
});
|
||||
let po;
|
||||
//Massage the data based on the split. Should they be able to overwrite OEC pricing?
|
||||
if (OEConnection_PriceChange.treatment === "on") {
|
||||
//Set the flag to include the override.
|
||||
po = _.cloneDeep(partsOrder.data.parts_orders_by_pk);
|
||||
po.parts_order_lines.forEach((pol) => {
|
||||
pol.priceChange = true;
|
||||
});
|
||||
}
|
||||
|
||||
console.log(partsOrder.data.parts_orders_by_pk);
|
||||
|
||||
const oecResponse = await axios.post(
|
||||
"http://localhost:1337/oec/",
|
||||
|
||||
partsOrder.data.parts_orders_by_pk,
|
||||
po || partsOrder.data.parts_orders_by_pk,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${await auth.currentUser.getIdToken()}`,
|
||||
|
||||
@@ -208,7 +208,7 @@ export function TimeTicketModalComponent({
|
||||
>
|
||||
<InputNumber min={0} precision={1} />
|
||||
</Form.Item>
|
||||
{isEdit && (
|
||||
{
|
||||
<>
|
||||
<Form.Item label={t("timetickets.fields.clockon")} name="clockon">
|
||||
<FormDateTimePicker
|
||||
@@ -221,7 +221,29 @@ export function TimeTicketModalComponent({
|
||||
}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label={t("timetickets.fields.clockoff")} name="clockoff">
|
||||
<Form.Item
|
||||
label={t("timetickets.fields.clockoff")}
|
||||
name="clockoff"
|
||||
rules={[
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
const clockon = getFieldValue("clockon");
|
||||
|
||||
if (!value) return Promise.resolve();
|
||||
if (!clockon && value)
|
||||
return Promise.reject(
|
||||
t("timetickets.validation.clockoffwithoutclockon")
|
||||
);
|
||||
if (!value.isSameOrAfter(clockon))
|
||||
return Promise.reject(
|
||||
t("timetickets.validation.clockoffmustbeafterclockon")
|
||||
);
|
||||
|
||||
return Promise.resolve();
|
||||
},
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<FormDateTimePicker
|
||||
disabled={
|
||||
!HasRbacAccess({
|
||||
@@ -233,7 +255,7 @@ export function TimeTicketModalComponent({
|
||||
/>
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
}
|
||||
|
||||
<Form.Item label={t("timetickets.fields.memo")} name="memo">
|
||||
<MemoInput />
|
||||
|
||||
@@ -2406,6 +2406,10 @@
|
||||
"clockedout": "Clocked out successfully.",
|
||||
"created": "Time ticket entered successfully.",
|
||||
"deleted": "Time ticket deleted successfully."
|
||||
},
|
||||
"validation": {
|
||||
"clockoffmustbeafterclockon": "Clock off time must be the same or after clock in time.",
|
||||
"clockoffwithoutclockon": "Clock off time cannot be set without a clock in time."
|
||||
}
|
||||
},
|
||||
"titles": {
|
||||
|
||||
@@ -2406,6 +2406,10 @@
|
||||
"clockedout": "",
|
||||
"created": "",
|
||||
"deleted": ""
|
||||
},
|
||||
"validation": {
|
||||
"clockoffmustbeafterclockon": "",
|
||||
"clockoffwithoutclockon": ""
|
||||
}
|
||||
},
|
||||
"titles": {
|
||||
|
||||
@@ -2406,6 +2406,10 @@
|
||||
"clockedout": "",
|
||||
"created": "",
|
||||
"deleted": ""
|
||||
},
|
||||
"validation": {
|
||||
"clockoffmustbeafterclockon": "",
|
||||
"clockoffwithoutclockon": ""
|
||||
}
|
||||
},
|
||||
"titles": {
|
||||
|
||||
@@ -815,6 +815,7 @@
|
||||
- email
|
||||
- enforce_class
|
||||
- enforce_referral
|
||||
- entegral_id
|
||||
- features
|
||||
- federal_tax_id
|
||||
- id
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "appointments_bodyshopid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "appointments_bodyshopid" on
|
||||
"public"."appointments" using btree ("bodyshopid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "appointments_jobid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "appointments_jobid" on
|
||||
"public"."appointments" using btree ("jobid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "appointments_start";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "appointments_start" on
|
||||
"public"."appointments" using btree ("start");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "appointments_end";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "appointments_end" on
|
||||
"public"."appointments" using btree ("end");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "associations_bodyshopid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "associations_bodyshopid" on
|
||||
"public"."associations" using btree ("shopid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "associations_useremail";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "associations_useremail" on
|
||||
"public"."associations" using btree ("useremail");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "invoicelines_billid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "invoicelines_billid" on
|
||||
"public"."billlines" using btree ("billid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "invoicelines_jobid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "invoicelines_jobid" on
|
||||
"public"."billlines" using btree ("joblineid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "bills_jobid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "bills_jobid" on
|
||||
"public"."bills" using btree ("jobid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "conversations_shopid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "conversations_shopid" on
|
||||
"public"."conversations" using btree ("bodyshopid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "documents_shopid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "documents_shopid" on
|
||||
"public"."documents" using btree ("bodyshopid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "documents_jobid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "documents_jobid" on
|
||||
"public"."documents" using btree ("jobid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "documents_billid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "documents_billid" on
|
||||
"public"."documents" using btree ("billid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "jobline_jobid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "jobline_jobid" on
|
||||
"public"."joblines" using btree ("jobid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "jobs_updatedat";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "jobs_updatedat" on
|
||||
"public"."jobs" using btree ("updated_at");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "jobs_bodyshopid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "jobs_bodyshopid" on
|
||||
"public"."jobs" using btree ("shopid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "messages_conversationid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "messages_conversationid" on
|
||||
"public"."messages" using btree ("conversationid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "timetickets_jobid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "timetickets_jobid" on
|
||||
"public"."timetickets" using btree ("jobid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "parts_orders_jobid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "parts_orders_jobid" on
|
||||
"public"."parts_orders" using btree ("jobid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "parts_order_lines_poid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "parts_order_lines_poid" on
|
||||
"public"."parts_order_lines" using btree ("orderid");
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS "parts_order_lines_joblineid";
|
||||
@@ -0,0 +1,2 @@
|
||||
CREATE INDEX "parts_order_lines_joblineid" on
|
||||
"public"."parts_order_lines" using btree ("job_line_id");
|
||||
@@ -9,6 +9,7 @@ exports.default = function ({
|
||||
qbo = false,
|
||||
items,
|
||||
taxCodes,
|
||||
classes,
|
||||
}) {
|
||||
const InvoiceLineAdd = [];
|
||||
const responsibilityCenters = bodyshop.md_responsibility_centers;
|
||||
@@ -95,6 +96,9 @@ exports.default = function ({
|
||||
DetailType: "SalesItemLineDetail",
|
||||
Amount: DineroAmount,
|
||||
SalesItemLineDetail: {
|
||||
...(jobs_by_pk.class
|
||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||
: {}),
|
||||
ItemRef: {
|
||||
value: items[account.accountitem],
|
||||
},
|
||||
@@ -161,6 +165,9 @@ exports.default = function ({
|
||||
DetailType: "SalesItemLineDetail",
|
||||
Amount: DineroAmount,
|
||||
SalesItemLineDetail: {
|
||||
...(jobs_by_pk.class
|
||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||
: {}),
|
||||
ItemRef: {
|
||||
value: items[account.accountitem],
|
||||
},
|
||||
@@ -227,6 +234,9 @@ exports.default = function ({
|
||||
ItemRef: {
|
||||
value: items[mapaAccount.accountitem],
|
||||
},
|
||||
...(jobs_by_pk.class
|
||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||
: {}),
|
||||
TaxCodeRef: {
|
||||
value: QboTaxId,
|
||||
},
|
||||
@@ -290,6 +300,9 @@ exports.default = function ({
|
||||
ItemRef: {
|
||||
value: items[mashAccount.accountitem],
|
||||
},
|
||||
...(jobs_by_pk.class
|
||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||
: {}),
|
||||
TaxCodeRef: {
|
||||
value: QboTaxId,
|
||||
},
|
||||
@@ -367,6 +380,9 @@ exports.default = function ({
|
||||
amount: Math.round((jobs_by_pk.towing_payable || 0) * 100),
|
||||
}).toFormat(DineroQbFormat),
|
||||
SalesItemLineDetail: {
|
||||
...(jobs_by_pk.class
|
||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||
: {}),
|
||||
ItemRef: {
|
||||
value: items[account.accountitem],
|
||||
},
|
||||
@@ -415,6 +431,9 @@ exports.default = function ({
|
||||
amount: Math.round((jobs_by_pk.storage_payable || 0) * 100),
|
||||
}).toFormat(DineroQbFormat),
|
||||
SalesItemLineDetail: {
|
||||
...(jobs_by_pk.class
|
||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||
: {}),
|
||||
ItemRef: {
|
||||
value: items[account.accountitem],
|
||||
},
|
||||
@@ -466,6 +485,9 @@ exports.default = function ({
|
||||
amount: Math.round((jobs_by_pk.adjustment_bottom_line || 0) * 100),
|
||||
}).toFormat(DineroQbFormat),
|
||||
SalesItemLineDetail: {
|
||||
...(jobs_by_pk.class
|
||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||
: {}),
|
||||
ItemRef: {
|
||||
value: items[account.accountitem],
|
||||
},
|
||||
@@ -554,6 +576,9 @@ exports.default = function ({
|
||||
DineroQbFormat
|
||||
),
|
||||
SalesItemLineDetail: {
|
||||
...(jobs_by_pk.class
|
||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||
: {}),
|
||||
ItemRef: {
|
||||
value: items["PVRT"],
|
||||
},
|
||||
|
||||
@@ -181,11 +181,9 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor) {
|
||||
TxnDate: moment(bill.date).format("YYYY-MM-DD"),
|
||||
//DueDate: bill.due_date && moment(bill.due_date).format("YYYY-MM-DD"),
|
||||
DocNumber: bill.invoice_number,
|
||||
...(bill.job.class ? { ClassRef: { Id: classes[bill.job.class] } } : {}),
|
||||
//...(bill.job.class ? { ClassRef: { Id: classes[bill.job.class] } } : {}),
|
||||
|
||||
PrivateNote: `RO ${bill.job.ro_number || ""} OWNER ${
|
||||
bill.job.ownr_fn || ""
|
||||
} ${bill.job.ownr_ln || ""} ${bill.job.ownr_co_nm || ""}`,
|
||||
PrivateNote: `RO ${bill.job.ro_number || ""}`,
|
||||
Line: bill.billlines.map((il) =>
|
||||
generateBillLine(
|
||||
il,
|
||||
@@ -249,12 +247,11 @@ const generateBillLine = (
|
||||
) => {
|
||||
const account = costCenters.find((c) => c.name === billLine.cost_center);
|
||||
|
||||
console.log(account.accountname, accounts[account.accountname]);
|
||||
return {
|
||||
DetailType: "AccountBasedExpenseLineDetail",
|
||||
|
||||
AccountBasedExpenseLineDetail: {
|
||||
...(jobClass ? { ClassRef: { Id: classes[jobClass] } } : {}),
|
||||
...(jobClass ? { ClassRef: { value: classes[jobClass] } } : {}),
|
||||
TaxCodeRef: {
|
||||
value:
|
||||
taxCodes[findTaxCode(billLine.applicable_taxes, ioSalesTaxCodes)],
|
||||
@@ -324,7 +321,7 @@ async function QueryMetaData(oauthClient, qbo_realmId, req) {
|
||||
classes.json.QueryResponse &&
|
||||
classes.json.QueryResponse.Class &&
|
||||
classes.json.QueryResponse.Class.forEach((t) => {
|
||||
accountMapping[t.Name] = t.Id;
|
||||
classMapping[t.Name] = t.Id;
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -356,7 +356,7 @@ async function InsertJob(oauthClient, qbo_realmId, req, job, parentTierRef) {
|
||||
exports.InsertJob = InsertJob;
|
||||
async function QueryMetaData(oauthClient, qbo_realmId, req) {
|
||||
const items = await oauthClient.makeApiCall({
|
||||
url: urlBuilder(qbo_realmId, "query", `select * From Item`),
|
||||
url: urlBuilder(qbo_realmId, "query", `select * From Item where active=true maxresults 1000`),
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -402,7 +402,7 @@ async function QueryMetaData(oauthClient, qbo_realmId, req) {
|
||||
classes.json.QueryResponse &&
|
||||
classes.json.QueryResponse.Class &&
|
||||
classes.json.QueryResponse.Class.forEach((t) => {
|
||||
itemMapping[t.Name] = t.Id;
|
||||
classMapping[t.Name] = t.Id;
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -431,13 +431,19 @@ async function InsertInvoice(
|
||||
qbo: true,
|
||||
items,
|
||||
taxCodes,
|
||||
classes
|
||||
});
|
||||
|
||||
const invoiceObj = {
|
||||
Line: InvoiceLineAdd,
|
||||
TxnDate: moment(job.date_invoiced).format("YYYY-MM-DD"),
|
||||
DocNumber: job.ro_number,
|
||||
...(job.class ? { ClassRef: { Id: classes[job.class] } } : {}),
|
||||
...(job.class ? { ClassRef: { value: classes[job.class] } } : {}),
|
||||
CustomerMemo: {
|
||||
value: `${job.clm_no ? `Claim No: ${job.clm_no}` : ``}${
|
||||
job.po_number ? `PO No: ${job.po_number}` : ``
|
||||
}`.trim(),
|
||||
},
|
||||
CustomerRef: {
|
||||
value: parentTierRef.Id,
|
||||
},
|
||||
@@ -447,6 +453,15 @@ async function InsertInvoice(
|
||||
...(bodyshop.accountingconfig.emaillater && job.ownr_ea
|
||||
? { EmailStatus: "NeedToSend" }
|
||||
: {}),
|
||||
BillAddr: {
|
||||
Line3: `${job.ownr_city || ""}, ${job.ownr_st || ""} ${
|
||||
job.ownr_zip || ""
|
||||
}`.trim(),
|
||||
Line2: job.ownr_addr1 || "",
|
||||
Line1: `${job.ownr_fn || ""} ${job.ownr_ln || ""} ${
|
||||
job.ownr_co_nm || ""
|
||||
}`,
|
||||
},
|
||||
};
|
||||
|
||||
logger.log("qbo-receivable-objectlog", "DEBUG", req.user.email, job.id, {
|
||||
|
||||
@@ -566,6 +566,13 @@ exports.AUTOHOUSE_QUERY = `query AUTOHOUSE_EXPORT($start: timestamptz, $bodyshop
|
||||
status
|
||||
est_ct_fn
|
||||
est_ct_ln
|
||||
ownr_fn
|
||||
ownr_ln
|
||||
ownr_co_nm
|
||||
ownr_addr1
|
||||
ownr_city
|
||||
ownr_st
|
||||
ownr_ph1
|
||||
ownr_zip
|
||||
referral_source
|
||||
loss_type
|
||||
|
||||
Reference in New Issue
Block a user