Merge branch 'release/2021-10-29' into test
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
Row,
|
||||
Select,
|
||||
Space,
|
||||
Statistic,
|
||||
Switch,
|
||||
Typography,
|
||||
} from "antd";
|
||||
@@ -75,6 +76,12 @@ export function ScheduleJobModalComponent({
|
||||
return (
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={12}>
|
||||
<Space>
|
||||
<Typography.Title level={3}>{lbrHrsData?.jobs_by_pk?.ro_number}</Typography.Title>
|
||||
<Typography.Title
|
||||
level={4}
|
||||
>{`B/R Hrs:${lbrHrsData?.jobs_by_pk.labhrs?.aggregate.sum.mod_lb_hrs}/${lbrHrsData?.jobs_by_pk.larhrs?.aggregate.sum.mod_lb_hrs}`}</Typography.Title>
|
||||
</Space>
|
||||
<LayoutFormRow grow>
|
||||
<Form.Item
|
||||
name="start"
|
||||
|
||||
@@ -208,6 +208,7 @@ export const QUERY_LBR_HRS_BY_PK = gql`
|
||||
query QUERY_LBR_HRS_BY_PK($id: uuid!) {
|
||||
jobs_by_pk(id: $id) {
|
||||
id
|
||||
ro_number
|
||||
labhrs: joblines_aggregate(
|
||||
where: {
|
||||
_and: [{ mod_lbr_ty: { _neq: "LAR" } }, { removed: { _eq: false } }]
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -76,7 +76,7 @@ exports.default = function ({
|
||||
{
|
||||
local: false,
|
||||
federal: true,
|
||||
state: jobline.tax_part,
|
||||
state: (jobline.db_ref === "900511" || jobline.db_ref === "900510") ? true: jobline.tax_part,
|
||||
},
|
||||
bodyshop.md_responsibility_centers.sales_tax_codes
|
||||
);
|
||||
|
||||
@@ -27,6 +27,7 @@ const {
|
||||
} = require("../qbo/qbo-receivables");
|
||||
const { urlBuilder } = require("./qbo");
|
||||
const { DineroQbFormat } = require("../accounting-constants");
|
||||
const { findTaxCode } = require("../qb-receivables-lines");
|
||||
|
||||
exports.default = async (req, res) => {
|
||||
const oauthClient = new OAuthClient({
|
||||
@@ -135,7 +136,17 @@ exports.default = async (req, res) => {
|
||||
);
|
||||
}
|
||||
|
||||
await InsertPayment(oauthClient, qbo_realmId, req, payment, jobTier);
|
||||
if (payment.amount > 0) {
|
||||
await InsertPayment(oauthClient, qbo_realmId, req, payment, jobTier);
|
||||
} else {
|
||||
await InsertCreditMemo(
|
||||
oauthClient,
|
||||
qbo_realmId,
|
||||
req,
|
||||
payment,
|
||||
jobTier
|
||||
);
|
||||
}
|
||||
ret.push({ paymentid: payment.id, success: true });
|
||||
} catch (error) {
|
||||
logger.log("qbo-payment-create-error", "ERROR", req.user.email, {
|
||||
@@ -173,7 +184,8 @@ async function InsertPayment(
|
||||
oauthClient,
|
||||
qbo_realmId,
|
||||
req,
|
||||
payment.job.ro_number
|
||||
payment.job.ro_number,
|
||||
false
|
||||
);
|
||||
|
||||
if (invoices && invoices.length !== 1) {
|
||||
@@ -235,7 +247,13 @@ async function InsertPayment(
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async function QueryMetaData(oauthClient, qbo_realmId, req, ro_number) {
|
||||
async function QueryMetaData(
|
||||
oauthClient,
|
||||
qbo_realmId,
|
||||
req,
|
||||
ro_number,
|
||||
isCreditMemo
|
||||
) {
|
||||
const invoice = await oauthClient.makeApiCall({
|
||||
url: urlBuilder(
|
||||
qbo_realmId,
|
||||
@@ -288,8 +306,50 @@ async function QueryMetaData(oauthClient, qbo_realmId, req, ro_number) {
|
||||
// classes.json.QueryResponse.Class.forEach((t) => {
|
||||
// accountMapping[t.Name] = t.Id;
|
||||
// });
|
||||
let ret = {};
|
||||
|
||||
if (isCreditMemo) {
|
||||
const taxCodes = await oauthClient.makeApiCall({
|
||||
url: urlBuilder(qbo_realmId, "query", `select * From TaxCode`),
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
const items = await oauthClient.makeApiCall({
|
||||
url: urlBuilder(qbo_realmId, "query", `select * From Item`),
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
setNewRefreshToken(req.user.email, items);
|
||||
|
||||
const itemMapping = {};
|
||||
|
||||
items.json &&
|
||||
items.json.QueryResponse &&
|
||||
items.json.QueryResponse.Item &&
|
||||
items.json.QueryResponse.Item.forEach((t) => {
|
||||
itemMapping[t.Name] = t.Id;
|
||||
});
|
||||
const taxCodeMapping = {};
|
||||
|
||||
taxCodes.json &&
|
||||
taxCodes.json.QueryResponse &&
|
||||
taxCodes.json.QueryResponse.TaxCode &&
|
||||
taxCodes.json.QueryResponse.TaxCode.forEach((t) => {
|
||||
taxCodeMapping[t.Name] = t.Id;
|
||||
});
|
||||
ret = {
|
||||
...ret,
|
||||
items: itemMapping,
|
||||
taxCodes: taxCodeMapping,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...ret,
|
||||
paymentMethods: paymentMethodMapping,
|
||||
invoices:
|
||||
invoice.json &&
|
||||
@@ -297,3 +357,85 @@ async function QueryMetaData(oauthClient, qbo_realmId, req, ro_number) {
|
||||
invoice.json.QueryResponse.Invoice,
|
||||
};
|
||||
}
|
||||
async function InsertCreditMemo(
|
||||
oauthClient,
|
||||
qbo_realmId,
|
||||
req,
|
||||
payment,
|
||||
parentRef
|
||||
) {
|
||||
const { paymentMethods, invoices, items, taxCodes } = await QueryMetaData(
|
||||
oauthClient,
|
||||
qbo_realmId,
|
||||
req,
|
||||
payment.job.ro_number,
|
||||
true
|
||||
);
|
||||
|
||||
if (invoices && invoices.length !== 1) {
|
||||
throw new Error(
|
||||
`More than 1 invoice with DocNumber ${payment.ro_number} found.`
|
||||
);
|
||||
}
|
||||
|
||||
const paymentQbo = {
|
||||
CustomerRef: {
|
||||
value: parentRef.Id,
|
||||
},
|
||||
TxnDate: moment(payment.date).format("YYYY-MM-DD"),
|
||||
DocNumber: payment.paymentnum,
|
||||
...(invoices[0] ? { InvoiceRef: { value: invoices[0].Id } } : {}),
|
||||
Line: [
|
||||
{
|
||||
DetailType: "SalesItemLineDetail",
|
||||
Amount: Dinero({ amount: Math.round(payment.amount * -100) }).toFormat(
|
||||
DineroQbFormat
|
||||
),
|
||||
SalesItemLineDetail: {
|
||||
ItemRef: {
|
||||
value:
|
||||
items[
|
||||
payment.job.bodyshop.md_responsibility_centers.refund
|
||||
.accountitem
|
||||
],
|
||||
},
|
||||
Qty: 1,
|
||||
TaxCodeRef: {
|
||||
value:
|
||||
taxCodes[
|
||||
findTaxCode(
|
||||
{
|
||||
local: false,
|
||||
federal: false,
|
||||
state: false,
|
||||
},
|
||||
payment.job.bodyshop.md_responsibility_centers.sales_tax_codes
|
||||
)
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
logger.log("qbo-payments-objectlog", "DEBUG", req.user.email, payment.id, {
|
||||
paymentQbo,
|
||||
});
|
||||
try {
|
||||
const result = await oauthClient.makeApiCall({
|
||||
url: urlBuilder(qbo_realmId, "creditmemo"),
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(paymentQbo),
|
||||
});
|
||||
setNewRefreshToken(req.user.email, result);
|
||||
return result && result.Bill;
|
||||
} catch (error) {
|
||||
logger.log("qbo-payables-error", "DEBUG", req.user.email, payment.id, {
|
||||
error: error && error.message,
|
||||
method: "InsertCreditMemo",
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ const generatePayment = (payment, isThreeTier, twoTierPref) => {
|
||||
QBXML: {
|
||||
QBXMLMsgsRq: {
|
||||
"@onError": "continueOnError",
|
||||
CreditMemoAddRq: {
|
||||
wMemoAddRq: {
|
||||
CreditMemoAdd: {
|
||||
CustomerRef: {
|
||||
FullName: (payment.job.bodyshop.accountingconfig.tiers === 3
|
||||
|
||||
Reference in New Issue
Block a user