Compare commits

...

22 Commits

Author SHA1 Message Date
Allan Carr
f19b9cb8e1 IO-3395 Postback Payment Date
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2025-10-07 10:59:10 -07:00
Allan Carr
bdd5056c9a IO-3395 Postback Payment Date
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2025-10-06 21:35:31 -07:00
Allan Carr
4f6db827e7 IO-3395 Postback Payment Date
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2025-10-06 17:50:19 -07:00
Patrick Fic
15792cb0ef Merged in hotfix/2025-10-06-remove-amplitude (pull request #2612)
Hotfix/2025 10 06 remove amplitude
2025-10-06 15:33:23 +00:00
Patrick Fic
856a24d496 Remove console log. 2025-10-06 08:33:01 -07:00
Patrick Fic
74d6bcc004 Remove amplitude. 2025-10-06 08:19:43 -07:00
Allan Carr
01664c52ec Merged in hotfix/2025-10-01 (pull request #2602)
IO-3384 Mitchell OP14 Import USA
2025-10-02 01:03:15 +00:00
Allan Carr
e66d52784f Merged in feature/IO-3387-Mitchell-OP14-Import-USA (pull request #2600)
IO-3384 Mitchell OP14 Import USA

Approved-by: Dave Richer
2025-10-01 23:33:36 +00:00
Allan Carr
a75969097e IO-3384 Mitchell OP14 Import USA
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2025-10-01 16:30:54 -07:00
Allan Carr
a384fd5072 Merged in release/2025-09-26 (pull request #2597)
IO-3330 CARFAX Adjustment
2025-09-27 06:17:33 +00:00
Allan Carr
490c66a9cb Merged in feature/IO-3330-CARFAX-Adjustments (pull request #2595)
IO-3330 CARFAX Adjustment
2025-09-27 06:13:25 +00:00
Allan Carr
d38dab0738 IO-3330 CARFAX Adjustment
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2025-09-26 23:14:10 -07:00
Dave Richer
37624d385f Merged in release/2025-09-26 (pull request #2592)
Release/2025 09 26 into master-AIO - IO-3365 - IO-3373 - IO-3325 - IO-3377 - IO-3330 - IO-3076
2025-09-27 01:35:06 +00:00
Allan Carr
d565934288 IO-3330 Carfax Adjustment
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2025-09-26 14:06:35 -07:00
Allan Carr
5d03574d65 Merged in feature/IO-3330-CARFAX-Adjustments (pull request #2593)
IO-3330 Carfax Adjustment
2025-09-26 21:05:19 +00:00
Patrick Fic
34f7c115b4 Merged in feature/IO-3076-update-usage-report-cron (pull request #2590)
IO-3076 auto trigger report on wed
2025-09-26 15:27:36 +00:00
Patrick Fic
3ac74df504 IO-3076 auto trigger report on wed 2025-09-26 08:26:09 -07:00
Allan Carr
d5f13f750f Merged in feature/IO-3330-CARFAX-Adjustments (pull request #2588)
IO-3330 CARFAX Adjustments

Approved-by: Dave Richer
2025-09-26 00:14:47 +00:00
Allan Carr
b9ddac36a9 IO-3330 CARFAX Adjustments
remove voided jobs

Signed-off-by: Allan Carr <allan@imexsystems.ca>
2025-09-25 16:30:02 -07:00
Allan Carr
c982dde1f5 IO-3330 CARFAX Adjustments
Signed-off-by: Allan Carr <allan@imexsystems.ca>
2025-09-25 16:20:28 -07:00
Dave Richer
7f61f652f7 Merged in feature/IO-3377-Add-Notification-Tone-For-Messaging (pull request #2586)
Feature/IO-3377 Add Notification Tone For Messaging
2025-09-24 18:39:52 +00:00
Dave Richer
282a22ff51 Merged in feature/IO-3377-Add-Notification-Tone-For-Messaging (pull request #2584)
feautre/IO-3377-Add-Notification-Tone-For-Messaging - Complete
2025-09-24 16:03:52 +00:00
12 changed files with 122 additions and 93 deletions

View File

@@ -4,7 +4,7 @@ import { getAuth, updatePassword, updateProfile } from "@firebase/auth";
import { getFirestore } from "@firebase/firestore";
import { getMessaging, getToken, onMessage } from "@firebase/messaging";
import { store } from "../redux/store";
import * as amplitude from '@amplitude/analytics-browser';
//import * as amplitude from '@amplitude/analytics-browser';
import posthog from 'posthog-js'
const config = JSON.parse(import.meta.env.VITE_APP_FIREBASE_CONFIG);
@@ -91,14 +91,14 @@ export const logImEXEvent = (eventName, additionalParams, stateProp = null) => {
// dbevent: false,
// env: `master-AIO|${import.meta.env.VITE_APP_GIT_SHA_DATE}`
// });
console.log(
"%c[Analytics]",
"background-color: green ;font-weight:bold;",
eventName,
eventParams
);
// console.log(
// "%c[Analytics]",
// "background-color: green ;font-weight:bold;",
// eventName,
// eventParams
// );
logEvent(analytics, eventName, eventParams);
amplitude.track(eventName, eventParams);
//amplitude.track(eventName, eventParams);
posthog.capture(eventName, eventParams);
} finally {

View File

@@ -14,7 +14,7 @@ import { persistor, store } from "./redux/store";
import reportWebVitals from "./reportWebVitals";
import "./translations/i18n";
import "./utils/CleanAxios";
import * as amplitude from "@amplitude/analytics-browser";
//import * as amplitude from "@amplitude/analytics-browser";
import { PostHogProvider } from "posthog-js/react";
import posthog from "posthog-js";
@@ -26,23 +26,23 @@ registerSW({ immediate: true });
// Dinero.globalLocale = "en-CA";
Dinero.globalRoundingMode = "HALF_EVEN";
amplitude.init(import.meta.env.VITE_APP_AMP_KEY, {
defaultTracking: true,
serverUrl: import.meta.env.VITE_APP_AMP_URL
// {
// attribution: {
// excludeReferrers: true,
// initialEmptyValue: true,
// resetSessionOnNewCampaign: true,
// },
// fileDownloads: true,
// formInteractions: true,
// pageViews: {
// trackHistoryChanges: 'all'
// },
// sessions: true
// }
});
// amplitude.init(import.meta.env.VITE_APP_AMP_KEY, {
// defaultTracking: true,
// serverUrl: import.meta.env.VITE_APP_AMP_URL
// // {
// // attribution: {
// // excludeReferrers: true,
// // initialEmptyValue: true,
// // resetSessionOnNewCampaign: true,
// // },
// // fileDownloads: true,
// // formInteractions: true,
// // pageViews: {
// // trackHistoryChanges: 'all'
// // },
// // sessions: true
// // }
// });
posthog.init(import.meta.env.VITE_PUBLIC_POSTHOG_KEY, {
autocapture: false,

View File

@@ -49,7 +49,7 @@ import {
validatePasswordResetSuccess
} from "./user.actions";
import UserActionTypes from "./user.types";
import * as amplitude from '@amplitude/analytics-browser';
//import * as amplitude from '@amplitude/analytics-browser';
import posthog from 'posthog-js';
const fpPromise = FingerprintJS.load();
@@ -92,7 +92,7 @@ export function* isUserAuthenticated() {
}
LogRocket.identify(user.email);
amplitude.setUserId(user.email);
//amplitude.setUserId(user.email);
posthog.identify(user.email);
const eulaQuery = yield client.query({
@@ -139,7 +139,7 @@ export function* signOutStart() {
imexshopid: state.user.bodyshop.imexshopid,
type: "messaging"
});
amplitude.reset();
//amplitude.reset();
} catch {
console.log("No FCM token. Skipping unsubscribe.");
}
@@ -365,7 +365,7 @@ export function* SetAuthLevelFromShopDetails({ payload }) {
}
try {
amplitude.setGroup('Shop', payload.shopname);
//amplitude.setGroup('Shop', payload.shopname);
window.$crisp.push(["set", "user:company", [payload.shopname]]);
if (authRecord[0] && authRecord[0].user.validemail) {
window.$crisp.push(["set", "user:email", [authRecord[0].user.email]]);

View File

@@ -51,12 +51,13 @@
comment: ""
- name: Rome Usage Report
webhook: '{{HASURA_API_URL}}/data/usagereport'
schedule: 0 12 * * 5
schedule: 0 12 * * 3,5
include_in_metadata: true
payload: {}
headers:
- name: x-imex-auth
value_from_env: DATAPUMP_AUTH
comment: ""
- name: Task Reminders
webhook: '{{HASURA_API_URL}}/tasks-remind-handler'
schedule: '*/15 * * * *'

View File

@@ -944,6 +944,7 @@
- autohouseid
- bill_allow_post_to_closed
- bill_tax_rates
- carfax_exclude
- cdk_configuration
- cdk_dealerid
- chatterid

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."bodyshops" add column "carfax_exclude" boolean
-- not null default 'false';

View File

@@ -0,0 +1,2 @@
alter table "public"."bodyshops" add column "carfax_exclude" boolean
not null default 'false';

View File

@@ -99,7 +99,7 @@ exports.default = async (req, res) => {
await processShopData(shopsToProcess, start, end, skipUpload, ignoreDateFilter, allXMLResults, allErrors);
await sendServerEmail({
subject: `CARFAX Report ${moment().format("MM-DD-YY")}`,
subject: `Project Mexico Report ${moment().format("MM-DD-YY")}`,
text: `Errors:\n${JSON.stringify(allErrors, null, 2)}\n\nUploaded:\n${JSON.stringify(
allXMLResults.map((x) => ({
imexshopid: x.imexshopid,
@@ -164,35 +164,36 @@ async function processShopData(shopsToProcess, start, end, skipUpload, ignoreDat
if (skipUpload) {
fs.writeFileSync(`./logs/${jsonObj.filename}`, jsonObj.json);
uploadToS3(jsonObj);
} else {
await uploadViaSFTP(jsonObj);
}
await sendMexicoBillingEmail({
subject: `${shopid.toUpperCase()}_Mexico${InstanceManager({
imex: "IO",
rome: "RO"
})}_${moment().format("MMDDYYYY")} ROs ${jsonObj.count} Error ${errorCode(jsonObj)}`,
text: `Errors:\n${JSON.stringify(
erroredJobs.map((ej) => ({
ro_number: ej.job?.ro_number,
jobid: ej.job?.id,
error: ej.error
})),
null,
2
)}\n\nUploaded:\n${JSON.stringify(
{
bodyshopid: bodyshop.id,
imexshopid: shopid,
count: jsonObj.count,
filename: jsonObj.filename,
result: jsonObj.result
},
null,
2
)}`
});
await sendMexicoBillingEmail({
subject: `${shopid.replace(/_/g, "").toUpperCase()}_Mexico${InstanceManager({
imex: "IO",
rome: "RO"
})}_${moment().format("MMDDYYYY")} ROs ${jsonObj.count} Error ${errorCode(jsonObj)}`,
text: `Errors:\n${JSON.stringify(
erroredJobs.map((ej) => ({
ro_number: ej.job?.ro_number,
jobid: ej.job?.id,
error: ej.error
})),
null,
2
)}\n\nUploaded:\n${JSON.stringify(
{
bodyshopid: bodyshop.id,
imexshopid: shopid,
count: jsonObj.count,
filename: jsonObj.filename,
result: jsonObj.result
},
null,
2
)}`
});
}
allXMLResults.push({
bodyshopid: bodyshop.id,
@@ -292,17 +293,22 @@ const CreateRepairOrderTag = (job, errorCallback) => {
v_make: job.v_make_desc || "",
v_model: job.v_model_desc || "",
date_estimated:
(job.date_estimated && moment(job.date_estimated).tz(job.bodyshop.timezone).format(AHDateFormat)) ||
(job.created_at && moment(job.created_at).tz(job.bodyshop.timezone).format(AHDateFormat)) ||
"",
data_opened:
(job.date_open && moment(job.date_open).tz(job.bodyshop.timezone).format(AHDateFormat)) ||
(job.created_at && moment(job.created_at).tz(job.bodyshop.timezone).format(AHDateFormat)) ||
"",
date_invoiced:
(job.date_invoiced && moment(job.date_invoiced).tz(job.bodyshop.timezone).format(AHDateFormat)) || "",
loss_date: (job.loss_date && moment(job.loss_date).format(AHDateFormat)) || "",
date_estimated: [job.date_estimated, job.created_at].find((date) => date)
? moment([job.date_open, job.created_at].find((date) => date))
.tz(job.bodyshop.timezone)
.format(AHDateFormat)
: "",
data_opened: [job.date_open, job.created_at].find((date) => date)
? moment([job.date_open, job.created_at].find((date) => date))
.tz(job.bodyshop.timezone)
.format(AHDateFormat)
: "",
date_invoiced: [job.date_invoiced, job.actual_delivery, job.actual_completion].find((date) => date)
? moment([job.date_invoiced, job.actual_delivery, job.actual_completion].find((date) => date))
.tz(job.bodyshop.timezone)
.format(AHDateFormat)
: "",
loss_date: job.loss_date ? moment(job.loss_date).format(AHDateFormat) : "",
ins_co_nm: job.ins_co_nm || "",
loss_desc: job.loss_desc || "",
@@ -329,7 +335,9 @@ const GenerateDetailLines = (line) => {
line_desc: line.line_desc ? line.line_desc.replace(NON_ASCII_REGEX, "") : null,
oem_partno: line.oem_partno ? line.oem_partno.replace(NON_ASCII_REGEX, "") : null,
alt_partno: line.alt_partno ? line.alt_partno.replace(NON_ASCII_REGEX, "") : null,
op_code_desc: line.op_code_desc ? line.op_code_desc.replace(NON_ASCII_REGEX, "") : null,
lbr_ty: generateLaborType(line.mod_lbr_ty),
lbr_hrs: line.mod_lb_hrs || 0,
part_qty: line.part_qty || 0,
part_type: generatePartType(line.part_type),
act_price: line.act_price || 0

View File

@@ -879,39 +879,43 @@ exports.CHATTER_QUERY = `query CHATTER_EXPORT($start: timestamptz, $bodyshopid:
}`;
exports.CARFAX_QUERY = `query CARFAX_EXPORT($start: timestamptz, $bodyshopid: uuid!, $end: timestamptz) {
bodyshops_by_pk(id: $bodyshopid){
bodyshops_by_pk(id: $bodyshopid) {
id
shopname
imexshopid
timezone
}
jobs(where: {_and: [{converted: {_eq: true}}, {v_vin: {_is_null: false}}, {date_invoiced: {_gt: $start}}, {date_invoiced: {_lte: $end}}, {shopid: {_eq: $bodyshopid}}]}) {
id
jobs(where: {_and: [{_or: [{date_invoiced: {_gt: $start, _lte: $end}}, {actual_delivery: {_gt: $start, _lte: $end}, date_invoiced: {_is_null: true}}, {actual_completion: {_gt: $start, _lte: $end}, actual_delivery: {_is_null: true}, date_invoiced: {_is_null: true}}]}, {_not: {_and: [{date_invoiced: {_is_null: true}}, {actual_delivery: {_is_null: true}}, {actual_completion: {_is_null: true}}]}}, {shopid: {_eq: $bodyshopid}}, {voided: {_neq: true}}, {v_vin: {_is_null: false}}, {ro_number: {_is_null: false}}]}) {
actual_completion
actual_delivery
area_of_damage
created_at
ro_number
v_model_yr
v_model_desc
v_make_desc
v_vin
date_estimated
date_open
date_invoiced
loss_date
date_open
id
ins_co_nm
job_totals
joblines(where: {removed: {_eq: false}}) {
act_price
alt_partno
line_desc
mod_lb_hrs
mod_lbr_ty
oem_partno
op_code_desc
part_type
part_qty
}
loss_date
loss_desc
ro_number
theft_ind
tlos_ind
job_totals
area_of_damage
joblines(where: {removed: {_eq: false}}) {
line_desc
oem_partno
alt_partno
mod_lbr_ty
part_qty
part_type
act_price
}
v_make_desc
v_model_desc
v_model_yr
v_vin
}
}`;
@@ -1854,7 +1858,7 @@ exports.GET_CHATTER_SHOPS = `query GET_CHATTER_SHOPS {
}`;
exports.GET_CARFAX_SHOPS = `query GET_CARFAX_SHOPS {
bodyshops(where: {external_shop_id: {_is_null: true}}){
bodyshops(where: {external_shop_id: {_is_null: true}, carfax_exclude: {_neq: "true"}}){
id
shopname
imexshopid
@@ -2855,6 +2859,7 @@ exports.GET_BODYSHOP_BY_ID = `
intellipay_config
state
notification_followers
timezone
}
}
`;
@@ -2946,6 +2951,7 @@ query GET_JOBID_BY_MERCHANTID_RONUMBER($merchantID: String!, $roNumber: String!)
id
intellipay_config
email
timezone
}
}
}`;
@@ -2955,6 +2961,7 @@ query GET_BODYSHOP_BY_MERCHANTID($merchantID: String!) {
bodyshops(where: {intellipay_merchant_id: {_eq: $merchantID}}) {
id
email
timezone
}
}`;

View File

@@ -48,7 +48,9 @@ const handleCommentBasedPayment = async (values, decodedComment, logger, logMeta
payer: "Customer",
type: getPaymentType(ipMapping, values.cardtype),
jobid: p.jobid,
date: moment(Date.now()),
date: moment()
.tz(bodyshop?.bodyshops_by_pk?.timezone ?? "UTC")
.format("YYYY-MM-DD"),
payment_responses: {
data: {
amount: values.total,

View File

@@ -97,7 +97,9 @@ const handleInvoiceBasedPayment = async (values, logger, logMeta, res) => {
payer: "Customer",
type: getPaymentType(ipMapping, values.cardtype),
jobid: job.id,
date: moment(Date.now())
date: moment()
.tz(bodyshop?.timezone ?? "UTC")
.format("YYYY-MM-DD")
}
});

View File

@@ -384,6 +384,8 @@ async function CalculateRatesTotals({ job, client }) {
if (item.lbr_op === "OP14" && item.act_price > 0 && (!item.part_type || item.mod_lb_hrs === 0)) {
//Scenario where SGI may pay out hours using a part price.
if (!ret[item.mod_lbr_ty.toLowerCase()].total) {
ret[item.mod_lbr_ty.toLowerCase()].base = Dinero();
ret[item.mod_lbr_ty.toLowerCase()].adjustment = Dinero();
ret[item.mod_lbr_ty.toLowerCase()].total = Dinero();
}
ret[item.mod_lbr_ty.toLowerCase()].total = ret[item.mod_lbr_ty.toLowerCase()].total.add(