Further work to refactor job costing + qb posting. BOD-383
This commit is contained in:
@@ -20162,6 +20162,32 @@
|
|||||||
<folder_node>
|
<folder_node>
|
||||||
<name>payments</name>
|
<name>payments</name>
|
||||||
<children>
|
<children>
|
||||||
|
<folder_node>
|
||||||
|
<name>errors</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>exporting</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>
|
||||||
<folder_node>
|
<folder_node>
|
||||||
<name>fields</name>
|
<name>fields</name>
|
||||||
<children>
|
<children>
|
||||||
|
|||||||
@@ -153,19 +153,20 @@ export default function AccountingPayablesTableComponent({
|
|||||||
loading={loading}
|
loading={loading}
|
||||||
title={() => {
|
title={() => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="imex-table-header">
|
||||||
|
<PaymentsExportAllButton
|
||||||
|
paymentIds={selectedPayments}
|
||||||
|
disabled={transInProgress || selectedPayments.length === 0}
|
||||||
|
loadingCallback={setTransInProgress}
|
||||||
|
completedCallback={setSelectedPayments}
|
||||||
|
/>
|
||||||
<Input
|
<Input
|
||||||
|
className="imex-table-header__search"
|
||||||
value={state.search}
|
value={state.search}
|
||||||
onChange={handleSearch}
|
onChange={handleSearch}
|
||||||
placeholder={t("general.labels.search")}
|
placeholder={t("general.labels.search")}
|
||||||
allowClear
|
allowClear
|
||||||
/>
|
/>
|
||||||
<PaymentsExportAllButton
|
|
||||||
paymentIds={selectedPayments}
|
|
||||||
disabled={transInProgress}
|
|
||||||
loadingCallback={setTransInProgress}
|
|
||||||
completedCallback={setSelectedPayments}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ function JobLinesUpsertModalContainer({
|
|||||||
.then((r) => {
|
.then((r) => {
|
||||||
if (jobLineEditModal.actions.refetch)
|
if (jobLineEditModal.actions.refetch)
|
||||||
jobLineEditModal.actions.refetch();
|
jobLineEditModal.actions.refetch();
|
||||||
|
//Need to recalcuate totals.
|
||||||
toggleModalVisible();
|
toggleModalVisible();
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: t("joblines.successes.created"),
|
message: t("joblines.successes.created"),
|
||||||
|
|||||||
@@ -80,27 +80,32 @@ export function JobsCloseExportButton({ bodyshop, jobId, disabled }) {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const jobUpdateResponse = await updateJob({
|
|
||||||
variables: {
|
|
||||||
jobId: jobId,
|
|
||||||
job: {
|
|
||||||
status: bodyshop.md_ro_statuses.default_exported || "Exported*",
|
|
||||||
date_exported: new Date(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!!!jobUpdateResponse.errors) {
|
|
||||||
notification["success"]({
|
// const jobUpdateResponse = await updateJob({
|
||||||
message: t("jobs.successes.exported"),
|
// variables: {
|
||||||
});
|
// jobId: jobId,
|
||||||
} else {
|
// job: {
|
||||||
notification["error"]({
|
// status: bodyshop.md_ro_statuses.default_exported || "Exported*",
|
||||||
message: t("jobs.errors.exporting", {
|
// date_exported: new Date(),
|
||||||
error: JSON.stringify(jobUpdateResponse.error),
|
// },
|
||||||
}),
|
// },
|
||||||
});
|
// });
|
||||||
}
|
|
||||||
|
// if (!!!jobUpdateResponse.errors) {
|
||||||
|
// notification["success"]({
|
||||||
|
// message: t("jobs.successes.exported"),
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// notification["error"]({
|
||||||
|
// message: t("jobs.errors.exporting", {
|
||||||
|
// error: JSON.stringify(jobUpdateResponse.error),
|
||||||
|
// }),
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
|||||||
@@ -73,14 +73,21 @@ export function JobsCloseLines({ bodyshop, joblines }) {
|
|||||||
name={[field.name, "profitcenter_part"]}
|
name={[field.name, "profitcenter_part"]}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required:
|
required: !!joblines[index].act_price,
|
||||||
!!joblines[index].part_type &&
|
|
||||||
!!joblines[index].act_price,
|
|
||||||
message: t("general.validation.required"),
|
message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Select allowClear>
|
<Select
|
||||||
|
allowClear
|
||||||
|
optionFilterProp="children"
|
||||||
|
showSearch
|
||||||
|
filterOption={(input, option) =>
|
||||||
|
option.children
|
||||||
|
.toLowerCase()
|
||||||
|
.indexOf(input.toLowerCase()) >= 0
|
||||||
|
}
|
||||||
|
>
|
||||||
{bodyshop.md_responsibility_centers.profits.map((p) => (
|
{bodyshop.md_responsibility_centers.profits.map((p) => (
|
||||||
<Select.Option key={p.name} value={p.name}>
|
<Select.Option key={p.name} value={p.name}>
|
||||||
{p.name}
|
{p.name}
|
||||||
@@ -99,7 +106,16 @@ export function JobsCloseLines({ bodyshop, joblines }) {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Select allowClear>
|
<Select
|
||||||
|
allowClear
|
||||||
|
optionFilterProp="children"
|
||||||
|
showSearch
|
||||||
|
filterOption={(input, option) =>
|
||||||
|
option.children
|
||||||
|
.toLowerCase()
|
||||||
|
.indexOf(input.toLowerCase()) >= 0
|
||||||
|
}
|
||||||
|
>
|
||||||
{bodyshop.md_responsibility_centers.profits.map((p) => (
|
{bodyshop.md_responsibility_centers.profits.map((p) => (
|
||||||
<Select.Option key={p.name} value={p.name}>
|
<Select.Option key={p.name} value={p.name}>
|
||||||
{p.name}
|
{p.name}
|
||||||
|
|||||||
@@ -151,7 +151,6 @@ export const GET_JOB_LINES_TO_ENTER_INVOICE = gql`
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
export const generateJobLinesUpdatesForInvoicing = (joblines) => {
|
export const generateJobLinesUpdatesForInvoicing = (joblines) => {
|
||||||
console.log("generateJobLinesUpdatesForInvoicing -> joblines", joblines);
|
|
||||||
const updates = joblines.reduce((acc, jl, idx) => {
|
const updates = joblines.reduce((acc, jl, idx) => {
|
||||||
return (
|
return (
|
||||||
acc +
|
acc +
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Button, Form, Space, notification, Popconfirm } from "antd";
|
import { Button, Form, Space, notification, Popconfirm } from "antd";
|
||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
@@ -24,22 +24,33 @@ export function JobsCloseComponent({ job, bodyshop }) {
|
|||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [closeJob] = useMutation(UPDATE_JOB);
|
const [closeJob] = useMutation(UPDATE_JOB);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// //if (job && form) form.setFields({ joblines: job.joblines });
|
// //if (job && form) form.setFields({ joblines: job.joblines });
|
||||||
// }, [job, form]);
|
// }, [job, form]);
|
||||||
|
|
||||||
const handleFinish = async (values) => {
|
const handleFinish = async (values) => {
|
||||||
console.log(values);
|
setLoading(true);
|
||||||
|
|
||||||
const result = await client.mutate({
|
const result = await client.mutate({
|
||||||
mutation: generateJobLinesUpdatesForInvoicing(values.joblines),
|
mutation: generateJobLinesUpdatesForInvoicing(values.joblines),
|
||||||
});
|
});
|
||||||
console.log("result.data", result.data);
|
if (!!!result.errors) {
|
||||||
|
notification["success"]({ message: t("job.successes.saved") });
|
||||||
|
form.resetFields();
|
||||||
|
} else {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("job.errors.saving", {
|
||||||
|
error: JSON.stringify(result.errors),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClose = async () => {
|
const handleClose = async () => {
|
||||||
|
setLoading(true);
|
||||||
const result = await closeJob({
|
const result = await closeJob({
|
||||||
variables: {
|
variables: {
|
||||||
jobId: job.id,
|
jobId: job.id,
|
||||||
@@ -54,6 +65,7 @@ export function JobsCloseComponent({ job, bodyshop }) {
|
|||||||
notification["success"]({ message: t("job.successes.closed") });
|
notification["success"]({ message: t("job.successes.closed") });
|
||||||
history.push(`/manage/jobs/${job.id}`);
|
history.push(`/manage/jobs/${job.id}`);
|
||||||
} else {
|
} else {
|
||||||
|
setLoading(false);
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("job.errors.closing", {
|
message: t("job.errors.closing", {
|
||||||
error: JSON.stringify(result.errors),
|
error: JSON.stringify(result.errors),
|
||||||
@@ -69,6 +81,7 @@ export function JobsCloseComponent({ job, bodyshop }) {
|
|||||||
form={form}
|
form={form}
|
||||||
onFinish={handleFinish}
|
onFinish={handleFinish}
|
||||||
initialValues={{ joblines: job.joblines }}
|
initialValues={{ joblines: job.joblines }}
|
||||||
|
scrollToFirstError
|
||||||
>
|
>
|
||||||
<Space>
|
<Space>
|
||||||
<JobsCloseAutoAllocate
|
<JobsCloseAutoAllocate
|
||||||
@@ -77,7 +90,7 @@ export function JobsCloseComponent({ job, bodyshop }) {
|
|||||||
disabled={!!job.date_exported}
|
disabled={!!job.date_exported}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button onClick={() => form.submit()}>
|
<Button loading={loading} onClick={() => form.submit()}>
|
||||||
{t("general.actions.save")}
|
{t("general.actions.save")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
@@ -87,7 +100,9 @@ export function JobsCloseComponent({ job, bodyshop }) {
|
|||||||
cancelText={t("general.labels.no")}
|
cancelText={t("general.labels.no")}
|
||||||
title={t("jobs.labels.closeconfirm")}
|
title={t("jobs.labels.closeconfirm")}
|
||||||
>
|
>
|
||||||
<Button type="danger">{t("general.actions.close")}</Button>
|
<Button loading={loading} type="danger">
|
||||||
|
{t("general.actions.close")}
|
||||||
|
</Button>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
|
|
||||||
<JobsScoreboardAdd job={job} disabled={false} />
|
<JobsScoreboardAdd job={job} disabled={false} />
|
||||||
|
|||||||
@@ -1242,6 +1242,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"payments": {
|
"payments": {
|
||||||
|
"errors": {
|
||||||
|
"exporting": "Error exporting payment(s). {{error}}"
|
||||||
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"amount": "Amount",
|
"amount": "Amount",
|
||||||
"created_at": "Created At",
|
"created_at": "Created At",
|
||||||
|
|||||||
@@ -1242,6 +1242,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"payments": {
|
"payments": {
|
||||||
|
"errors": {
|
||||||
|
"exporting": ""
|
||||||
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"amount": "",
|
"amount": "",
|
||||||
"created_at": "",
|
"created_at": "",
|
||||||
|
|||||||
@@ -1242,6 +1242,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"payments": {
|
"payments": {
|
||||||
|
"errors": {
|
||||||
|
"exporting": ""
|
||||||
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"amount": "",
|
"amount": "",
|
||||||
"created_at": "",
|
"created_at": "",
|
||||||
|
|||||||
@@ -76,11 +76,14 @@ const generatePayment = (payment) => {
|
|||||||
TotalAmount: Dinero({
|
TotalAmount: Dinero({
|
||||||
amount: Math.round(payment.amount * 100),
|
amount: Math.round(payment.amount * 100),
|
||||||
}).toFormat(DineroQbFormat),
|
}).toFormat(DineroQbFormat),
|
||||||
|
PaymentMethodRef: {
|
||||||
|
FullName: payment.type,
|
||||||
|
},
|
||||||
Memo: `RO ${payment.job.ro_number || ""} OWNER ${
|
Memo: `RO ${payment.job.ro_number || ""} OWNER ${
|
||||||
payment.job.ownr_fn || ""
|
payment.job.ownr_fn || ""
|
||||||
} ${payment.job.ownr_ln || ""} ${payment.job.ownr_co_nm || ""} ${
|
} ${payment.job.ownr_ln || ""} ${payment.job.ownr_co_nm || ""} ${
|
||||||
payment.stripeid
|
payment.stripeid || ""
|
||||||
}`,
|
} ${payment.payer ? ` PAID BY ${payment.payer}` : ""}`,
|
||||||
IsAutoApply: true,
|
IsAutoApply: true,
|
||||||
// AppliedToTxnAdd:{
|
// AppliedToTxnAdd:{
|
||||||
// T
|
// T
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ exports.default = async (req, res) => {
|
|||||||
const result = await client
|
const result = await client
|
||||||
.setHeaders({ Authorization: BearerToken })
|
.setHeaders({ Authorization: BearerToken })
|
||||||
.request(queries.QUERY_JOBS_FOR_RECEIVABLES_EXPORT, { ids: jobIds });
|
.request(queries.QUERY_JOBS_FOR_RECEIVABLES_EXPORT, { ids: jobIds });
|
||||||
console.log("result", result);
|
|
||||||
const { jobs } = result;
|
const { jobs } = result;
|
||||||
const { bodyshops } = result;
|
const { bodyshops } = result;
|
||||||
const QbXmlToExecute = [];
|
const QbXmlToExecute = [];
|
||||||
@@ -174,44 +173,74 @@ const generateJobQbxml = (
|
|||||||
const generateInvoiceQbxml = (jobs_by_pk, bodyshop) => {
|
const generateInvoiceQbxml = (jobs_by_pk, bodyshop) => {
|
||||||
//Build the Invoice XML file.
|
//Build the Invoice XML file.
|
||||||
const InvoiceLineAdd = [];
|
const InvoiceLineAdd = [];
|
||||||
const invoice_allocation = jobs_by_pk.invoice_allocation;
|
const responsibilityCenters = bodyshop.md_responsibility_centers;
|
||||||
Object.keys(invoice_allocation.partsAllocations).forEach(
|
|
||||||
(partsAllocationKey) => {
|
jobs_by_pk.joblines.map((jobline) => {
|
||||||
if (
|
if (jobline.profitcenter_part && jobline.act_price) {
|
||||||
!!!invoice_allocation.partsAllocations[partsAllocationKey].allocations
|
const DineroAmount = Dinero({
|
||||||
)
|
amount: Math.round(jobline.act_price * 100),
|
||||||
return;
|
|
||||||
invoice_allocation.partsAllocations[
|
|
||||||
partsAllocationKey
|
|
||||||
].allocations.forEach((alloc) => {
|
|
||||||
InvoiceLineAdd.push(
|
|
||||||
generateInvoiceLine(
|
|
||||||
jobs_by_pk,
|
|
||||||
alloc,
|
|
||||||
bodyshop.md_responsibility_centers
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
const account = responsibilityCenters.profits.find(
|
||||||
);
|
(i) => jobline.profitcenter_part.toLowerCase() === i.name.toLowerCase()
|
||||||
Object.keys(invoice_allocation.labMatAllocations).forEach((AllocationKey) => {
|
);
|
||||||
if (!!!invoice_allocation.labMatAllocations[AllocationKey].allocations)
|
|
||||||
return;
|
if (!!!account) {
|
||||||
invoice_allocation.labMatAllocations[AllocationKey].allocations.forEach(
|
throw new Error(
|
||||||
(alloc) => {
|
`A matching account does not exist for the allocation. Center: ${center}`
|
||||||
InvoiceLineAdd.push(
|
|
||||||
generateInvoiceLine(
|
|
||||||
jobs_by_pk,
|
|
||||||
alloc,
|
|
||||||
bodyshop.md_responsibility_centers
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
InvoiceLineAdd.push({
|
||||||
|
ItemRef: { FullName: account.accountitem },
|
||||||
|
Desc: `${account.accountdesc} - ${jobline.line_desc}`,
|
||||||
|
Quantity: jobline.part_qty,
|
||||||
|
Rate: DineroAmount.toFormat(DineroQbFormat),
|
||||||
|
//Amount: DineroAmount.toFormat(DineroQbFormat),
|
||||||
|
SalesTaxCodeRef: {
|
||||||
|
FullName: "E",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
jobline.profitcenter_labor &&
|
||||||
|
jobline.mod_lb_hrs &&
|
||||||
|
jobline.mod_lb_hrs > 0
|
||||||
|
) {
|
||||||
|
const DineroAmount = Dinero({
|
||||||
|
amount: Math.round(
|
||||||
|
jobs_by_pk[`rate_${jobline.mod_lbr_ty.toLowerCase()}`] * 100
|
||||||
|
),
|
||||||
|
});
|
||||||
|
console.log(
|
||||||
|
"Rate",
|
||||||
|
jobline.mod_lbr_ty,
|
||||||
|
jobs_by_pk[`rate_${jobline.mod_lbr_ty.toLowerCase()}`]
|
||||||
|
);
|
||||||
|
const account = responsibilityCenters.profits.find(
|
||||||
|
(i) => jobline.profitcenter_labor.toLowerCase() === i.name.toLowerCase()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!!!account) {
|
||||||
|
throw new Error(
|
||||||
|
`A matching account does not exist for the allocation. Center: ${center}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
InvoiceLineAdd.push({
|
||||||
|
ItemRef: { FullName: account.accountitem },
|
||||||
|
Desc: `${account.accountdesc} - ${jobline.op_code_desc} ${jobline.line_desc}`,
|
||||||
|
Quantity: jobline.mod_lb_hrs,
|
||||||
|
Rate: DineroAmount.toFormat(DineroQbFormat),
|
||||||
|
//Amount: DineroAmount.toFormat(DineroQbFormat),
|
||||||
|
SalesTaxCodeRef: {
|
||||||
|
FullName: "E",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Add tax lines
|
//Add tax lines
|
||||||
const job_totals = JSON.parse(jobs_by_pk.job_totals);
|
const job_totals = jobs_by_pk.job_totals;
|
||||||
|
|
||||||
const federal_tax = Dinero(job_totals.totals.federal_tax);
|
const federal_tax = Dinero(job_totals.totals.federal_tax);
|
||||||
const state_tax = Dinero(job_totals.totals.state_tax);
|
const state_tax = Dinero(job_totals.totals.state_tax);
|
||||||
@@ -288,31 +317,32 @@ const generateInvoiceQbxml = (jobs_by_pk, bodyshop) => {
|
|||||||
.end({ pretty: true });
|
.end({ pretty: true });
|
||||||
|
|
||||||
const invoiceQbxml_Full = QbXmlUtils.addQbxmlHeader(invoiceQbxml_partial);
|
const invoiceQbxml_Full = QbXmlUtils.addQbxmlHeader(invoiceQbxml_partial);
|
||||||
|
console.log("invoiceQbxml_Full", invoiceQbxml_Full);
|
||||||
|
|
||||||
return invoiceQbxml_Full;
|
return invoiceQbxml_Full;
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateInvoiceLine = (job, allocation, responsibilityCenters) => {
|
// const generateInvoiceLine = (job, allocation, responsibilityCenters) => {
|
||||||
const { amount, center } = allocation;
|
// const { amount, center } = allocation;
|
||||||
const DineroAmount = Dinero(amount);
|
// const DineroAmount = Dinero(amount);
|
||||||
const account = responsibilityCenters.profits.find(
|
// const account = responsibilityCenters.profits.find(
|
||||||
(i) => i.name.toLowerCase() === center.toLowerCase()
|
// (i) => i.name.toLowerCase() === center.toLowerCase()
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (!!!account) {
|
// if (!!!account) {
|
||||||
throw new Error(
|
// throw new Error(
|
||||||
`A matching account does not exist for the allocation. Center: ${center}`
|
// `A matching account does not exist for the allocation. Center: ${center}`
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
ItemRef: { FullName: account.accountitem },
|
// ItemRef: { FullName: account.accountitem },
|
||||||
Desc: account.accountdesc,
|
// Desc: account.accountdesc,
|
||||||
Quantity: 1,
|
// Quantity: 1,
|
||||||
//Rate: 100,
|
// //Rate: 100,
|
||||||
Amount: DineroAmount.toFormat(DineroQbFormat),
|
// Amount: DineroAmount.toFormat(DineroQbFormat),
|
||||||
SalesTaxCodeRef: {
|
// SalesTaxCodeRef: {
|
||||||
FullName: "E",
|
// FullName: "E",
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
};
|
// };
|
||||||
|
|||||||
@@ -59,9 +59,45 @@ query QUERY_JOBS_FOR_RECEIVABLES_EXPORT($ids: [uuid!]!) {
|
|||||||
ownr_city
|
ownr_city
|
||||||
ownr_st
|
ownr_st
|
||||||
ins_co_nm
|
ins_co_nm
|
||||||
|
job_totals
|
||||||
|
rate_la1
|
||||||
|
rate_la2
|
||||||
|
rate_la3
|
||||||
|
rate_la4
|
||||||
|
rate_laa
|
||||||
|
rate_lab
|
||||||
|
rate_lad
|
||||||
|
rate_lae
|
||||||
|
rate_laf
|
||||||
|
rate_lag
|
||||||
|
rate_lam
|
||||||
|
rate_lar
|
||||||
|
rate_las
|
||||||
|
rate_lau
|
||||||
|
rate_ma2s
|
||||||
|
rate_ma2t
|
||||||
|
rate_ma3s
|
||||||
|
rate_mabl
|
||||||
|
rate_macs
|
||||||
|
rate_mahw
|
||||||
|
rate_mapa
|
||||||
|
rate_mash
|
||||||
|
rate_matd
|
||||||
owner {
|
owner {
|
||||||
accountingid
|
accountingid
|
||||||
}
|
}
|
||||||
|
joblines{
|
||||||
|
id
|
||||||
|
line_desc
|
||||||
|
part_type
|
||||||
|
act_price
|
||||||
|
mod_lb_hrs
|
||||||
|
mod_lbr_ty
|
||||||
|
part_qty
|
||||||
|
op_code_desc
|
||||||
|
profitcenter_labor
|
||||||
|
profitcenter_part
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bodyshops(where: {associations: {active: {_eq: true}}}) {
|
bodyshops(where: {associations: {active: {_eq: true}}}) {
|
||||||
id
|
id
|
||||||
@@ -136,6 +172,8 @@ exports.QUERY_PAYMENTS_FOR_EXPORT = `
|
|||||||
stripeid
|
stripeid
|
||||||
exportedat
|
exportedat
|
||||||
stripeid
|
stripeid
|
||||||
|
type
|
||||||
|
payer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
Reference in New Issue
Block a user