Compare commits

..

3 Commits

Author SHA1 Message Date
Allan Carr
e669c19b98 IO-3584 Duplicate Job with Full Rates
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2026-03-11 18:48:23 -07:00
Dave Richer
b9b3e2c2aa Merged in hotfix/2026-03-09 (pull request #3109)
hotfix/2026-03-09 - Eula
2026-03-09 17:00:49 +00:00
Dave
7e5363f911 hotfix/2026-03-09 - Eula 2026-03-09 12:33:20 -04:00
5 changed files with 48 additions and 108 deletions

View File

@@ -25,6 +25,7 @@ const Eula = ({ currentEula, currentUser, acceptEula }) => {
const handleScroll = useCallback( const handleScroll = useCallback(
(e) => { (e) => {
if (!e.target) return;
const bottom = e.target.scrollHeight - 100 <= e.target.scrollTop + e.target.clientHeight; const bottom = e.target.scrollHeight - 100 <= e.target.scrollTop + e.target.clientHeight;
if (bottom && !hasEverScrolledToBottom) { if (bottom && !hasEverScrolledToBottom) {
setHasEverScrolledToBottom(true); setHasEverScrolledToBottom(true);
@@ -36,7 +37,9 @@ const Eula = ({ currentEula, currentUser, acceptEula }) => {
); );
useEffect(() => { useEffect(() => {
handleScroll({ target: markdownCardRef.current }); if (markdownCardRef.current) {
handleScroll({ target: markdownCardRef.current });
}
}, [handleScroll]); }, [handleScroll]);
const handleChange = useCallback(() => { const handleChange = useCallback(() => {

View File

@@ -1375,6 +1375,9 @@ export const QUERY_JOB_FOR_DUPE = gql`
agt_ph2x agt_ph2x
area_of_damage area_of_damage
cat_no cat_no
cieca_pfl
cieca_pfo
cieca_pft
cieca_stl cieca_stl
cieca_ttl cieca_ttl
clm_addr1 clm_addr1
@@ -1452,6 +1455,7 @@ export const QUERY_JOB_FOR_DUPE = gql`
labor_rate_desc labor_rate_desc
labor_rate_id labor_rate_id
local_tax_rate local_tax_rate
materials
other_amount_payable other_amount_payable
owner_owing owner_owing
ownerid ownerid

View File

@@ -130,13 +130,12 @@ exports.default = async (req, res) => {
async function QueryVendorRecord(oauthClient, qbo_realmId, req, bill) { async function QueryVendorRecord(oauthClient, qbo_realmId, req, bill) {
try { try {
const url = urlBuilder(
qbo_realmId,
"query",
`select * From vendor where DisplayName = '${StandardizeName(bill.vendor.name)}'`
);
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(
qbo_realmId,
"query",
`select * From vendor where DisplayName = '${StandardizeName(bill.vendor.name)}'`
),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -151,11 +150,6 @@ async function QueryVendorRecord(oauthClient, qbo_realmId, req, bill) {
bodyshopid: bill.job.shopid, bodyshopid: bill.job.shopid,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-payables-query", "DEBUG", req.user.email, null, {
method: "QueryVendorRecord",
call: url,
result: result.json
});
return result.json?.QueryResponse?.Vendor?.[0]; return result.json?.QueryResponse?.Vendor?.[0];
} catch (error) { } catch (error) {
@@ -173,9 +167,8 @@ async function InsertVendorRecord(oauthClient, qbo_realmId, req, bill) {
DisplayName: StandardizeName(bill.vendor.name) DisplayName: StandardizeName(bill.vendor.name)
}; };
try { try {
const url = urlBuilder(qbo_realmId, "vendor");
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(qbo_realmId, "vendor"),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -191,12 +184,6 @@ async function InsertVendorRecord(oauthClient, qbo_realmId, req, bill) {
bodyshopid: bill.job.shopid, bodyshopid: bill.job.shopid,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-payments-insert", "DEBUG", req.user.email, null, {
method: "InsertVendorRecord",
call: url,
Vendor: Vendor,
result: result.json
});
if (result.status >= 400) { if (result.status >= 400) {
throw new Error(JSON.stringify(result.json.Fault)); throw new Error(JSON.stringify(result.json.Fault));
@@ -287,12 +274,11 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
VendorRef: { VendorRef: {
value: vendor.Id value: vendor.Id
}, },
...(vendor.TermRef && ...(vendor.TermRef && !bill.is_credit_memo && {
!bill.is_credit_memo && { SalesTermRef: {
SalesTermRef: { value: vendor.TermRef.value
value: vendor.TermRef.value }
} }),
}),
TxnDate: moment(bill.date) TxnDate: moment(bill.date)
//.tz(bill.job.bodyshop.timezone) //.tz(bill.job.bodyshop.timezone)
.format("YYYY-MM-DD"), .format("YYYY-MM-DD"),
@@ -332,9 +318,8 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
[logKey]: logValue [logKey]: logValue
}); });
try { try {
const url = urlBuilder(qbo_realmId, bill.is_credit_memo ? "vendorcredit" : "bill");
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(qbo_realmId, bill.is_credit_memo ? "vendorcredit" : "bill"),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -350,12 +335,6 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
bodyshopid: bill.job.shopid, bodyshopid: bill.job.shopid,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-payables-insert", "DEBUG", req.user.email, null, {
method: "InsertBill",
call: url,
postingObj: bill.is_credit_memo ? VendorCredit : billQbo,
result: result.json
});
if (result.status >= 400) { if (result.status >= 400) {
throw new Error(JSON.stringify(result.json.Fault)); throw new Error(JSON.stringify(result.json.Fault));

View File

@@ -82,7 +82,14 @@ exports.default = async (req, res) => {
if (isThreeTier || (!isThreeTier && twoTierPref === "name")) { if (isThreeTier || (!isThreeTier && twoTierPref === "name")) {
//Insert the name/owner and account for whether the source should be the ins co in 3 tier.. //Insert the name/owner and account for whether the source should be the ins co in 3 tier..
ownerCustomerTier = await QueryOwner(oauthClient, qbo_realmId, req, payment.job, insCoCustomerTier); ownerCustomerTier = await QueryOwner(
oauthClient,
qbo_realmId,
req,
payment.job,
isThreeTier,
insCoCustomerTier
);
//Query for the owner itself. //Query for the owner itself.
if (!ownerCustomerTier) { if (!ownerCustomerTier) {
ownerCustomerTier = await InsertOwner( ownerCustomerTier = await InsertOwner(
@@ -222,9 +229,8 @@ async function InsertPayment(oauthClient, qbo_realmId, req, payment, parentRef)
paymentQbo paymentQbo
}); });
try { try {
const url = urlBuilder(qbo_realmId, "payment");
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(qbo_realmId, "payment"),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -240,12 +246,6 @@ async function InsertPayment(oauthClient, qbo_realmId, req, payment, parentRef)
bodyshopid: payment.job.shopid, bodyshopid: payment.job.shopid,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-payments-insert", "DEBUG", req.user.email, null, {
method: "InsertPayment",
call: url,
paymentQbo: paymentQbo,
result: result.json
});
if (result.status >= 400) { if (result.status >= 400) {
throw new Error(JSON.stringify(result.json.Fault)); throw new Error(JSON.stringify(result.json.Fault));
@@ -428,9 +428,8 @@ async function InsertCreditMemo(oauthClient, qbo_realmId, req, payment, parentRe
paymentQbo paymentQbo
}); });
try { try {
const url = urlBuilder(qbo_realmId, "creditmemo");
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(qbo_realmId, "creditmemo"),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -446,12 +445,6 @@ async function InsertCreditMemo(oauthClient, qbo_realmId, req, payment, parentRe
bodyshopid: req.user.bodyshopid, bodyshopid: req.user.bodyshopid,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-metadata-query", "DEBUG", req.user.email, null, {
method: "InsertCreditMemo",
call: url,
paymentQbo: paymentQbo,
result: result.json
});
if (result.status >= 400) { if (result.status >= 400) {
throw new Error(JSON.stringify(result.json.Fault)); throw new Error(JSON.stringify(result.json.Fault));

View File

@@ -213,13 +213,12 @@ exports.default = async (req, res) => {
async function QueryInsuranceCo(oauthClient, qbo_realmId, req, job) { async function QueryInsuranceCo(oauthClient, qbo_realmId, req, job) {
try { try {
const url = urlBuilder(
qbo_realmId,
"query",
`select * From Customer where DisplayName = '${StandardizeName(job.ins_co_nm.trim())}' and Active = true`
);
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(
qbo_realmId,
"query",
`select * From Customer where DisplayName = '${StandardizeName(job.ins_co_nm.trim())}' and Active = true`
),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -234,11 +233,6 @@ async function QueryInsuranceCo(oauthClient, qbo_realmId, req, job) {
jobid: job.id, jobid: job.id,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-receivables-query", "DEBUG", req.user.email, job.id, {
method: "QueryInsuranceCo",
call: url,
result: result.json
});
return result.json?.QueryResponse?.Customer?.[0]; return result.json?.QueryResponse?.Customer?.[0];
} catch (error) { } catch (error) {
@@ -272,9 +266,8 @@ async function InsertInsuranceCo(oauthClient, qbo_realmId, req, job, bodyshop) {
} }
}; };
try { try {
const url = urlBuilder(qbo_realmId, "customer");
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(qbo_realmId, "customer"),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -290,12 +283,6 @@ async function InsertInsuranceCo(oauthClient, qbo_realmId, req, job, bodyshop) {
jobid: job.id, jobid: job.id,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-receivables-insert", "DEBUG", req.user.email, job.id, {
method: "InsertInsuranceCo",
call: url,
customerObj: Customer,
result: result.json
});
return result.json?.Customer; return result.json?.Customer;
} catch (error) { } catch (error) {
@@ -311,13 +298,12 @@ exports.InsertInsuranceCo = InsertInsuranceCo;
async function QueryOwner(oauthClient, qbo_realmId, req, job, parentTierRef) { async function QueryOwner(oauthClient, qbo_realmId, req, job, parentTierRef) {
const ownerName = generateOwnerTier(job, true, null); const ownerName = generateOwnerTier(job, true, null);
const url = urlBuilder(
qbo_realmId,
"query",
`select * From Customer where DisplayName = '${StandardizeName(ownerName)}' and Active = true`
);
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(
qbo_realmId,
"query",
`select * From Customer where DisplayName = '${StandardizeName(ownerName)}' and Active = true`
),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -332,11 +318,6 @@ async function QueryOwner(oauthClient, qbo_realmId, req, job, parentTierRef) {
jobid: job.id, jobid: job.id,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-receivables-query", "DEBUG", req.user.email, job.id, {
method: "QueryOwner",
call: url,
result: result.json
});
return result.json?.QueryResponse?.Customer?.find((x) => x.ParentRef?.value === parentTierRef?.Id); return result.json?.QueryResponse?.Customer?.find((x) => x.ParentRef?.value === parentTierRef?.Id);
} }
@@ -366,9 +347,8 @@ async function InsertOwner(oauthClient, qbo_realmId, req, job, isThreeTier, pare
: {}) : {})
}; };
try { try {
const url = urlBuilder(qbo_realmId, "customer");
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(qbo_realmId, "customer"),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -384,12 +364,6 @@ async function InsertOwner(oauthClient, qbo_realmId, req, job, isThreeTier, pare
jobid: job.id, jobid: job.id,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-receivables-insert", "DEBUG", req.user.email, job.id, {
method: "InsertOwner",
call: url,
customerObj: Customer,
result: result.json
});
return result.json?.Customer; return result.json?.Customer;
} catch (error) { } catch (error) {
@@ -404,13 +378,12 @@ async function InsertOwner(oauthClient, qbo_realmId, req, job, isThreeTier, pare
exports.InsertOwner = InsertOwner; exports.InsertOwner = InsertOwner;
async function QueryJob(oauthClient, qbo_realmId, req, job, parentTierRef) { async function QueryJob(oauthClient, qbo_realmId, req, job, parentTierRef) {
const url = urlBuilder(
qbo_realmId,
"query",
`select * From Customer where DisplayName = '${job.ro_number}' and Active = true`
);
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(
qbo_realmId,
"query",
`select * From Customer where DisplayName = '${job.ro_number}' and Active = true`
),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -425,11 +398,6 @@ async function QueryJob(oauthClient, qbo_realmId, req, job, parentTierRef) {
jobid: job.id, jobid: job.id,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-receivables-query", "DEBUG", req.user.email, job.id, {
method: "QueryJob",
call: url,
result: result.json
});
const customers = result.json?.QueryResponse?.Customer; const customers = result.json?.QueryResponse?.Customer;
return customers && (parentTierRef ? customers.find((x) => x.ParentRef.value === parentTierRef.Id) : customers[0]); return customers && (parentTierRef ? customers.find((x) => x.ParentRef.value === parentTierRef.Id) : customers[0]);
@@ -455,9 +423,8 @@ async function InsertJob(oauthClient, qbo_realmId, req, job, parentTierRef) {
} }
}; };
try { try {
const url = urlBuilder(qbo_realmId, "customer");
const result = await oauthClient.makeApiCall({ const result = await oauthClient.makeApiCall({
url: url, url: urlBuilder(qbo_realmId, "customer"),
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -473,12 +440,6 @@ async function InsertJob(oauthClient, qbo_realmId, req, job, parentTierRef) {
jobid: job.id, jobid: job.id,
email: req.user.email email: req.user.email
}); });
logger.log("qbo-receivables-insert", "DEBUG", req.user.email, job.id, {
method: "InsertJob",
call: url,
customerObj: Customer,
result: result.json
});
if (result.status >= 400) { if (result.status >= 400) {
throw new Error(JSON.stringify(result.json.Fault)); throw new Error(JSON.stringify(result.json.Fault));