Compare commits

..

8 Commits

Author SHA1 Message Date
Allan Carr
e6071709be IO-3610 Export Log DMS Bug
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2026-03-12 16:28:14 -07:00
Allan Carr
c95c11fd0e Merged in hotfix/2026-03-12 (pull request #3125)
IO-3585 saleClassValue fix
2026-03-12 19:01:16 +00:00
Allan Carr
1351fbb814 Merged in feature/IO-3585-Fortellis-Insert-and-Update-Vehicle (pull request #3123)
IO-3585 saleClassValue fix
2026-03-12 18:58:35 +00:00
Allan Carr
dcd3a078ef IO-3585 saleClassValue fix
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2026-03-12 11:58:40 -07:00
Dave Richer
bf11e10676 Merged in hotfix/2026-03-12 (pull request #3119)
hotfix/2026-03-12 - Be more specific on CDK error passing, resolve circular dependency
2026-03-12 16:38:15 +00:00
Dave
7ec8a73c30 hotfix/2026-03-12 - Be more specific on CDK error passing, resolve circular dependency 2026-03-12 12:33:54 -04: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
7 changed files with 65 additions and 114 deletions

View File

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

View File

@@ -142,13 +142,13 @@ export function ExportLogsPageComponent() {
<div>
<ul>
{message.map((m, idx) => (
<li key={idx}>{m}</li>
<li key={idx}>{typeof m === "object" ? JSON.stringify(m) : m}</li>
))}
</ul>
</div>
);
} else {
return <div>{record.message}</div>;
return <div>{typeof message === "object" ? JSON.stringify(message) : message}</div>;
}
}
}

View File

@@ -130,13 +130,12 @@ exports.default = async (req, res) => {
async function QueryVendorRecord(oauthClient, qbo_realmId, req, bill) {
try {
const url = urlBuilder(
qbo_realmId,
"query",
`select * From vendor where DisplayName = '${StandardizeName(bill.vendor.name)}'`
);
const result = await oauthClient.makeApiCall({
url: url,
url: urlBuilder(
qbo_realmId,
"query",
`select * From vendor where DisplayName = '${StandardizeName(bill.vendor.name)}'`
),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -151,11 +150,6 @@ async function QueryVendorRecord(oauthClient, qbo_realmId, req, bill) {
bodyshopid: bill.job.shopid,
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];
} catch (error) {
@@ -173,9 +167,8 @@ async function InsertVendorRecord(oauthClient, qbo_realmId, req, bill) {
DisplayName: StandardizeName(bill.vendor.name)
};
try {
const url = urlBuilder(qbo_realmId, "vendor");
const result = await oauthClient.makeApiCall({
url: url,
url: urlBuilder(qbo_realmId, "vendor"),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -191,12 +184,6 @@ async function InsertVendorRecord(oauthClient, qbo_realmId, req, bill) {
bodyshopid: bill.job.shopid,
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) {
throw new Error(JSON.stringify(result.json.Fault));
@@ -287,12 +274,11 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
VendorRef: {
value: vendor.Id
},
...(vendor.TermRef &&
!bill.is_credit_memo && {
SalesTermRef: {
value: vendor.TermRef.value
}
}),
...(vendor.TermRef && !bill.is_credit_memo && {
SalesTermRef: {
value: vendor.TermRef.value
}
}),
TxnDate: moment(bill.date)
//.tz(bill.job.bodyshop.timezone)
.format("YYYY-MM-DD"),
@@ -332,9 +318,8 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
[logKey]: logValue
});
try {
const url = urlBuilder(qbo_realmId, bill.is_credit_memo ? "vendorcredit" : "bill");
const result = await oauthClient.makeApiCall({
url: url,
url: urlBuilder(qbo_realmId, bill.is_credit_memo ? "vendorcredit" : "bill"),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -350,12 +335,6 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
bodyshopid: bill.job.shopid,
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) {
throw new Error(JSON.stringify(result.json.Fault));

View File

@@ -82,7 +82,14 @@ exports.default = async (req, res) => {
if (isThreeTier || (!isThreeTier && twoTierPref === "name")) {
//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.
if (!ownerCustomerTier) {
ownerCustomerTier = await InsertOwner(
@@ -222,9 +229,8 @@ async function InsertPayment(oauthClient, qbo_realmId, req, payment, parentRef)
paymentQbo
});
try {
const url = urlBuilder(qbo_realmId, "payment");
const result = await oauthClient.makeApiCall({
url: url,
url: urlBuilder(qbo_realmId, "payment"),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -240,12 +246,6 @@ async function InsertPayment(oauthClient, qbo_realmId, req, payment, parentRef)
bodyshopid: payment.job.shopid,
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) {
throw new Error(JSON.stringify(result.json.Fault));
@@ -428,9 +428,8 @@ async function InsertCreditMemo(oauthClient, qbo_realmId, req, payment, parentRe
paymentQbo
});
try {
const url = urlBuilder(qbo_realmId, "creditmemo");
const result = await oauthClient.makeApiCall({
url: url,
url: urlBuilder(qbo_realmId, "creditmemo"),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -446,12 +445,6 @@ async function InsertCreditMemo(oauthClient, qbo_realmId, req, payment, parentRe
bodyshopid: req.user.bodyshopid,
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) {
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) {
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({
url: url,
url: urlBuilder(
qbo_realmId,
"query",
`select * From Customer where DisplayName = '${StandardizeName(job.ins_co_nm.trim())}' and Active = true`
),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -234,11 +233,6 @@ async function QueryInsuranceCo(oauthClient, qbo_realmId, req, job) {
jobid: job.id,
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];
} catch (error) {
@@ -272,9 +266,8 @@ async function InsertInsuranceCo(oauthClient, qbo_realmId, req, job, bodyshop) {
}
};
try {
const url = urlBuilder(qbo_realmId, "customer");
const result = await oauthClient.makeApiCall({
url: url,
url: urlBuilder(qbo_realmId, "customer"),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -290,12 +283,6 @@ async function InsertInsuranceCo(oauthClient, qbo_realmId, req, job, bodyshop) {
jobid: job.id,
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;
} catch (error) {
@@ -311,13 +298,12 @@ exports.InsertInsuranceCo = InsertInsuranceCo;
async function QueryOwner(oauthClient, qbo_realmId, req, job, parentTierRef) {
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({
url: url,
url: urlBuilder(
qbo_realmId,
"query",
`select * From Customer where DisplayName = '${StandardizeName(ownerName)}' and Active = true`
),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -332,11 +318,6 @@ async function QueryOwner(oauthClient, qbo_realmId, req, job, parentTierRef) {
jobid: job.id,
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);
}
@@ -366,9 +347,8 @@ async function InsertOwner(oauthClient, qbo_realmId, req, job, isThreeTier, pare
: {})
};
try {
const url = urlBuilder(qbo_realmId, "customer");
const result = await oauthClient.makeApiCall({
url: url,
url: urlBuilder(qbo_realmId, "customer"),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -384,12 +364,6 @@ async function InsertOwner(oauthClient, qbo_realmId, req, job, isThreeTier, pare
jobid: job.id,
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;
} catch (error) {
@@ -404,13 +378,12 @@ async function InsertOwner(oauthClient, qbo_realmId, req, job, isThreeTier, pare
exports.InsertOwner = InsertOwner;
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({
url: url,
url: urlBuilder(
qbo_realmId,
"query",
`select * From Customer where DisplayName = '${job.ro_number}' and Active = true`
),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -425,11 +398,6 @@ async function QueryJob(oauthClient, qbo_realmId, req, job, parentTierRef) {
jobid: job.id,
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;
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 {
const url = urlBuilder(qbo_realmId, "customer");
const result = await oauthClient.makeApiCall({
url: url,
url: urlBuilder(qbo_realmId, "customer"),
method: "POST",
headers: {
"Content-Type": "application/json"
@@ -473,12 +440,6 @@ async function InsertJob(oauthClient, qbo_realmId, req, job, parentTierRef) {
jobid: job.id,
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) {
throw new Error(JSON.stringify(result.json.Fault));

View File

@@ -66,7 +66,12 @@ exports.default = async function ReloadCdkMakes(req, res) {
} catch (error) {
logger.log("cdk-replace-makes-models-error", "ERROR", req.user.email, null, {
cdk_dealerid,
error
error: {
message: error?.message,
stack: error?.stack,
name: error?.name,
code: error?.code
}
});
res.status(500).json(error);
}
@@ -105,7 +110,12 @@ async function GetCdkMakes(req, cdk_dealerid) {
} catch (error) {
logger.log("cdk-replace-makes-models-error", "ERROR", req.user.email, null, {
cdk_dealerid,
error
error: {
message: error?.message,
stack: error?.stack,
name: error?.name,
code: error?.code
}
});
throw new Error(error);
@@ -141,7 +151,12 @@ async function GetFortellisMakes(req, cdk_dealerid) {
} catch (error) {
logger.log("fortellis-replace-makes-models-error", "ERROR", req.user.email, null, {
cdk_dealerid,
error
error: {
message: error?.message,
stack: error?.stack,
name: error?.name,
code: error?.code
}
});
throw new Error(error);

View File

@@ -959,7 +959,7 @@ async function UpdateDmsVehicle({ socket, redisHelpers, JobData, DMSVeh, DMSCust
delete DMSVehToSend.inventoryAccount;
!DMSVehToSend.vehicle.engineNumber && delete DMSVehToSend.vehicle.engineNumber;
!DMSVehToSend.vehicle.saleClassValue && DMSVehToSend.vehicle.saleClassValue === "MISC";
!DMSVehToSend.vehicle.saleClassValue && (DMSVehToSend.vehicle.saleClassValue = "MISC");
!DMSVehToSend.vehicle.exteriorColor && delete DMSVehToSend.vehicle.exteriorColor;
const result = await MakeFortellisCall({