Compare commits
19 Commits
feature/IO
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84f4d5956a | ||
|
|
7472285641 | ||
|
|
67ff9f30c6 | ||
|
|
a27092dbcc | ||
|
|
ca41bff446 | ||
|
|
cf8280590c | ||
|
|
b649ca1f00 | ||
|
|
b441301007 | ||
|
|
2e93238b5c | ||
|
|
ce4fe84536 | ||
|
|
9b7c0af025 | ||
|
|
dfdaf36ed1 | ||
|
|
cc8d1b3793 | ||
|
|
eb359d83c5 | ||
|
|
ae13e9e36a | ||
|
|
016a62b6d5 | ||
|
|
3e226b50ab | ||
|
|
ab84cb5ada | ||
|
|
7825aa4122 |
24522
client/package-lock.json
generated
Normal file
24522
client/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
"@apollo/client": "^3.7.9",
|
||||
"@asseinfo/react-kanban": "^2.2.0",
|
||||
"@craco/craco": "^7.0.0",
|
||||
"@fingerprintjs/fingerprintjs": "^3.3.3",
|
||||
"@fingerprintjs/fingerprintjs": "^3.4.2",
|
||||
"@jsreport/browser-client": "^3.1.0",
|
||||
"@sentry/react": "^7.40.0",
|
||||
"@sentry/tracing": "^7.40.0",
|
||||
|
||||
@@ -50,6 +50,7 @@ export function BillFormComponent({
|
||||
job,
|
||||
loadOutstandingReturns,
|
||||
loadInventory,
|
||||
preferredMake,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const client = useApolloClient();
|
||||
@@ -185,6 +186,7 @@ export function BillFormComponent({
|
||||
<VendorSearchSelect
|
||||
disabled={disabled}
|
||||
options={vendorAutoCompleteOptions}
|
||||
preferredMake={preferredMake}
|
||||
onSelect={handleVendorSelect}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { useLazyQuery, useQuery } from "@apollo/client";
|
||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { QUERY_OUTSTANDING_INVENTORY } from "../../graphql/inventory.queries";
|
||||
import { GET_JOB_LINES_TO_ENTER_BILL } from "../../graphql/jobs-lines.queries";
|
||||
import { QUERY_UNRECEIVED_LINES } from "../../graphql/parts-orders.queries";
|
||||
import { SEARCH_VENDOR_AUTOCOMPLETE } from "../../graphql/vendors.queries";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import BillFormComponent from "./bill-form.component";
|
||||
import BillCmdReturnsTableComponent from "../bill-cm-returns-table/bill-cm-returns-table.component";
|
||||
import { QUERY_UNRECEIVED_LINES } from "../../graphql/parts-orders.queries";
|
||||
import BillInventoryTable from "../bill-inventory-table/bill-inventory-table.component";
|
||||
import { QUERY_OUTSTANDING_INVENTORY } from "../../graphql/inventory.queries";
|
||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||
import BillFormComponent from "./bill-form.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -59,6 +59,7 @@ export function BillFormContainer({
|
||||
disableInvNumber={disableInvNumber}
|
||||
loadOutstandingReturns={loadOutstandingReturns}
|
||||
loadInventory={loadInventory}
|
||||
preferredMake={lineData ? lineData.jobs_by_pk.v_make_desc : null}
|
||||
/>
|
||||
{!billEdit && (
|
||||
<BillCmdReturnsTableComponent
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { Gallery } from "react-grid-gallery";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { GenerateThumbUrl } from "./job-documents.utility";
|
||||
import { GenerateSrcUrl, GenerateThumbUrl } from "./job-documents.utility";
|
||||
|
||||
function JobsDocumentGalleryExternal({
|
||||
data,
|
||||
@@ -15,7 +15,7 @@ function JobsDocumentGalleryExternal({
|
||||
let documents = data.reduce((acc, value) => {
|
||||
if (value.type.startsWith("image")) {
|
||||
acc.push({
|
||||
//src: GenerateSrcUrl(value),
|
||||
fullsize: GenerateSrcUrl(value),
|
||||
src: GenerateThumbUrl(value),
|
||||
thumbnailHeight: 225,
|
||||
thumbnailWidth: 225,
|
||||
|
||||
@@ -16,13 +16,17 @@ import { QUERY_LBR_HRS_BY_PK, UPDATE_JOBS } from "../../graphql/jobs.queries";
|
||||
import { setEmailOptions } from "../../redux/email/email.actions";
|
||||
import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
||||
import { selectSchedule } from "../../redux/modals/modals.selectors";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import {
|
||||
selectBodyshop,
|
||||
selectCurrentUser,
|
||||
} from "../../redux/user/user.selectors";
|
||||
import { TemplateList } from "../../utils/TemplateConstants";
|
||||
import ScheduleJobModalComponent from "./schedule-job-modal.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
scheduleModal: selectSchedule,
|
||||
currentUser: selectCurrentUser,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
toggleModalVisible: () => dispatch(toggleModalVisible("schedule")),
|
||||
@@ -34,6 +38,7 @@ export function ScheduleJobModalContainer({
|
||||
bodyshop,
|
||||
toggleModalVisible,
|
||||
setEmailOptions,
|
||||
currentUser,
|
||||
}) {
|
||||
const { visible, context, actions } = scheduleModal;
|
||||
const { jobId, job, previousEvent } = context;
|
||||
@@ -122,6 +127,7 @@ export function ScheduleJobModalContainer({
|
||||
end: moment(values.start).add(bodyshop.appt_length || 60, "minutes"),
|
||||
color: values.color,
|
||||
note: values.note,
|
||||
created_by: currentUser.email,
|
||||
},
|
||||
jobId: jobId,
|
||||
altTransport: values.alt_transport,
|
||||
|
||||
@@ -219,6 +219,7 @@ export const GET_JOB_LINES_TO_ENTER_BILL = gql`
|
||||
id
|
||||
ro_number
|
||||
}
|
||||
v_make_desc
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -104,6 +104,7 @@ export const SEARCH_VENDOR_AUTOCOMPLETE = gql`
|
||||
id
|
||||
cost_center
|
||||
active
|
||||
favorite
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import Fingerprint2 from "@fingerprintjs/fingerprintjs";
|
||||
import FingerprintJS from "@fingerprintjs/fingerprintjs";
|
||||
import * as Sentry from "@sentry/browser";
|
||||
import { notification } from "antd";
|
||||
import axios from "axios";
|
||||
import { setUserId, setUserProperties } from "firebase/analytics";
|
||||
import {
|
||||
checkActionCode,
|
||||
confirmPasswordReset,
|
||||
sendPasswordResetEmail,
|
||||
signInWithEmailAndPassword,
|
||||
signOut,
|
||||
sendPasswordResetEmail,
|
||||
} from "firebase/auth";
|
||||
import { doc } from "firebase/firestore";
|
||||
import { doc, getDoc, setDoc } from "firebase/firestore";
|
||||
import { getToken } from "firebase/messaging";
|
||||
import i18next from "i18next";
|
||||
import LogRocket from "logrocket";
|
||||
import { all, call, delay, put, select, takeLatest } from "redux-saga/effects";
|
||||
@@ -20,6 +22,7 @@ import {
|
||||
firestore,
|
||||
getCurrentUser,
|
||||
logImEXEvent,
|
||||
messaging,
|
||||
updateCurrentUser,
|
||||
} from "../../firebase/firebase.utils";
|
||||
import {
|
||||
@@ -28,6 +31,7 @@ import {
|
||||
sendPasswordResetSuccess,
|
||||
setAuthlevel,
|
||||
setInstanceConflict,
|
||||
setInstanceId,
|
||||
setLocalFingerprint,
|
||||
signInFailure,
|
||||
signInSuccess,
|
||||
@@ -39,9 +43,8 @@ import {
|
||||
validatePasswordResetSuccess,
|
||||
} from "./user.actions";
|
||||
import UserActionTypes from "./user.types";
|
||||
import axios from "axios";
|
||||
import { messaging } from "../../firebase/firebase.utils";
|
||||
import { getToken } from "firebase/messaging";
|
||||
|
||||
const fpPromise = FingerprintJS.load();
|
||||
|
||||
export function* onEmailSignInStart() {
|
||||
yield takeLatest(UserActionTypes.EMAIL_SIGN_IN_START, signInWithEmail);
|
||||
@@ -148,17 +151,15 @@ export function* setInstanceIdSaga({ payload: uid }) {
|
||||
try {
|
||||
const userInstanceRef = doc(firestore, `userInstance/${uid}`);
|
||||
|
||||
const fingerprint = Fingerprint2.x64hash128(
|
||||
(yield Fingerprint2.getPromise({})).map((c) => c.value).join(""),
|
||||
31
|
||||
);
|
||||
|
||||
yield userInstanceRef.set({
|
||||
// Get the visitor identifier when you need it.
|
||||
const fp = yield fpPromise;
|
||||
const result = yield fp.get();
|
||||
yield setDoc(userInstanceRef, {
|
||||
timestamp: new Date(),
|
||||
fingerprint,
|
||||
fingerprint: result.visitorId,
|
||||
});
|
||||
|
||||
yield put(setLocalFingerprint(fingerprint));
|
||||
yield put(setLocalFingerprint(result.visitorId));
|
||||
yield delay(5 * 60 * 1000);
|
||||
if (process.env.NODE_ENV === "production") yield put(checkInstanceId(uid));
|
||||
} catch (error) {
|
||||
@@ -171,11 +172,9 @@ export function* onCheckInstanceId() {
|
||||
}
|
||||
export function* checkInstanceIdSaga({ payload: uid }) {
|
||||
try {
|
||||
const userInstanceRef = doc(firestore, `userInstance/${uid}`);
|
||||
|
||||
const snapshot = yield userInstanceRef.get();
|
||||
const snapshot = yield getDoc(doc(firestore, `userInstance/${uid}`));
|
||||
let fingerprint = yield select((state) => state.user.fingerprint);
|
||||
|
||||
yield put(setInstanceConflict());
|
||||
if (snapshot.data().fingerprint === fingerprint) {
|
||||
yield delay(5 * 60 * 1000);
|
||||
yield put(checkInstanceId(uid));
|
||||
@@ -215,7 +214,6 @@ export function* signInSuccessSaga({ payload }) {
|
||||
console.log("Error updating Crisp settings.", error);
|
||||
}
|
||||
|
||||
// if (!payload.email.includes("@imex.")) yield put(setInstanceId(payload.uid));
|
||||
setUserId(analytics, payload.email);
|
||||
setUserProperties(analytics, payload);
|
||||
yield logImEXEvent("redux_sign_in_success");
|
||||
@@ -289,6 +287,14 @@ export function* SetAuthLevelFromShopDetails({ payload }) {
|
||||
: { validemail: false }
|
||||
)
|
||||
);
|
||||
|
||||
if (payload.features.singleDeviceOnly) {
|
||||
const user = yield select((state) => state.user.currentUser);
|
||||
|
||||
if (!(user.email.includes("@imex.") || user.email.includes("@rome.")))
|
||||
yield put(setInstanceId(user.uid));
|
||||
}
|
||||
|
||||
try {
|
||||
window.$crisp.push(["set", "user:company", [payload.shopname]]);
|
||||
if (authRecord[0] && authRecord[0].user.validemail) {
|
||||
|
||||
@@ -2597,6 +2597,7 @@
|
||||
"open_orders_csr": "Open Orders by CSR",
|
||||
"open_orders_estimator": "Open Orders by Estimator",
|
||||
"open_orders_ins_co": "Open Orders by Insurance Company",
|
||||
"open_orders_referral": "Open Orders by Referral Source",
|
||||
"open_orders_specific_csr": "Open Orders filtered by CSR",
|
||||
"open_orders_status": "Open Orders by Status",
|
||||
"parts_backorder": "IOU Parts List",
|
||||
|
||||
@@ -2597,6 +2597,7 @@
|
||||
"open_orders_csr": "",
|
||||
"open_orders_estimator": "",
|
||||
"open_orders_ins_co": "",
|
||||
"open_orders_referral": "",
|
||||
"open_orders_specific_csr": "",
|
||||
"open_orders_status": "",
|
||||
"parts_backorder": "",
|
||||
|
||||
@@ -2597,6 +2597,7 @@
|
||||
"open_orders_csr": "",
|
||||
"open_orders_estimator": "",
|
||||
"open_orders_ins_co": "",
|
||||
"open_orders_referral": "",
|
||||
"open_orders_specific_csr": "",
|
||||
"open_orders_status": "",
|
||||
"parts_backorder": "",
|
||||
|
||||
@@ -1502,6 +1502,19 @@ export const TemplateList = (type, context) => {
|
||||
},
|
||||
group: "jobs",
|
||||
},
|
||||
open_orders_specific_csr: {
|
||||
title: i18n.t("reportcenter.templates.open_orders_specific_csr"),
|
||||
description: "",
|
||||
subject: i18n.t("reportcenter.templates.open_orders_specific_csr"),
|
||||
key: "open_orders_specific_csr",
|
||||
idtype: "employee",
|
||||
disabled: false,
|
||||
rangeFilter: {
|
||||
object: i18n.t("reportcenter.labels.objects.jobs"),
|
||||
field: i18n.t("jobs.fields.date_open"),
|
||||
},
|
||||
group: "jobs",
|
||||
},
|
||||
open_orders_estimator: {
|
||||
title: i18n.t("reportcenter.templates.open_orders_estimator"),
|
||||
description: "",
|
||||
@@ -1528,12 +1541,12 @@ export const TemplateList = (type, context) => {
|
||||
},
|
||||
group: "jobs",
|
||||
},
|
||||
open_orders_specific_csr: {
|
||||
title: i18n.t("reportcenter.templates.open_orders_specific_csr"),
|
||||
open_orders_referral: {
|
||||
title: i18n.t("reportcenter.templates.open_orders_referral"),
|
||||
description: "",
|
||||
subject: i18n.t("reportcenter.templates.open_orders_specific_csr"),
|
||||
key: "open_orders_specific_csr",
|
||||
idtype: "employee",
|
||||
subject: i18n.t("reportcenter.templates.open_orders_referral"),
|
||||
key: "open_orders_referral",
|
||||
//idtype: "vendor",
|
||||
disabled: false,
|
||||
rangeFilter: {
|
||||
object: i18n.t("reportcenter.labels.objects.jobs"),
|
||||
|
||||
4642
client/yarn.lock
4642
client/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -110,6 +110,7 @@
|
||||
- canceled
|
||||
- color
|
||||
- created_at
|
||||
- created_by
|
||||
- end
|
||||
- id
|
||||
- isintake
|
||||
@@ -128,6 +129,7 @@
|
||||
- canceled
|
||||
- color
|
||||
- created_at
|
||||
- created_by
|
||||
- end
|
||||
- id
|
||||
- isintake
|
||||
@@ -156,6 +158,7 @@
|
||||
- canceled
|
||||
- color
|
||||
- created_at
|
||||
- created_by
|
||||
- end
|
||||
- id
|
||||
- isintake
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Could not auto-generate a down migration.
|
||||
-- Please write an appropriate down migration for the SQL below:
|
||||
-- alter table "public"."appointments" add column "created_by" text
|
||||
-- null;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."appointments" add column "created_by" text
|
||||
null;
|
||||
@@ -17,7 +17,7 @@ let Client = require("ssh2-sftp-client");
|
||||
const client = require("../graphql-client/graphql-client").client;
|
||||
const { sendServerEmail } = require("../email/sendemail");
|
||||
const CCDineroFormat = "0,0.00";
|
||||
const AhDateFormat = "MMDDYYYY";
|
||||
const AhDateFormat = "MM/DD/YYYY";
|
||||
|
||||
const repairOpCodes = ["OP4", "OP9", "OP10"];
|
||||
const replaceOpCodes = ["OP2", "OP5", "OP11", "OP12"];
|
||||
@@ -104,7 +104,7 @@ exports.default = async (req, res) => {
|
||||
allxmlsToUpload.push({
|
||||
count: claimsCorpObject.DataFeed.ShopInfo.RO.length,
|
||||
xml: ret,
|
||||
filename: `${bodyshop.claimscorpid}-MIS-${moment().format(
|
||||
filename: `${bodyshop.claimscorpid}-${moment().format(
|
||||
"YYYYMMDDTHHMMss"
|
||||
)}.xml`,
|
||||
});
|
||||
@@ -245,7 +245,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
|
||||
try {
|
||||
const ret = {
|
||||
RONumber: job.ro_number,
|
||||
RoNumber: job.ro_number,
|
||||
Customer: {
|
||||
CustomerZip: (job.ownr_zip && job.ownr_zip.substring(0, 3)) || "",
|
||||
CustomerState: job.ownr_st || "",
|
||||
@@ -312,7 +312,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
(job.date_estimated &&
|
||||
moment(job.date_estimated).format(AhDateFormat)) ||
|
||||
"",
|
||||
DateofLoss:
|
||||
DateLoss:
|
||||
(job.loss_date && moment(job.loss_date).format(AhDateFormat)) || "",
|
||||
DateFNOL: "",
|
||||
DateContact: "",
|
||||
@@ -384,7 +384,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
"",
|
||||
BilledDate: "",
|
||||
PaidInFullDate: "",
|
||||
RoStatus: job.tlos_ind
|
||||
ROStatus: job.tlos_ind
|
||||
? "TOT"
|
||||
: StatusMapping(job.status, job.bodyshop.md_ro_statuses),
|
||||
},
|
||||
@@ -397,9 +397,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
Paint: Dinero(job.job_totals.rates.lar.total).toFormat(CCDineroFormat),
|
||||
Prep: Dinero().toFormat(CCDineroFormat),
|
||||
Frame: Dinero(job.job_totals.rates.laf.total).toFormat(CCDineroFormat),
|
||||
Mechanical: Dinero(job.job_totals.rates.lam.total).toFormat(
|
||||
CCDineroFormat
|
||||
),
|
||||
Mech: Dinero(job.job_totals.rates.lam.total).toFormat(CCDineroFormat),
|
||||
Glass: Dinero(job.job_totals.rates.lag.total).toFormat(CCDineroFormat),
|
||||
Elec: Dinero(job.job_totals.rates.lae.total).toFormat(CCDineroFormat),
|
||||
Detail: detailAdjustments.amount.toFormat(CCDineroFormat),
|
||||
@@ -481,7 +479,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
.filter((line) => repairOpCodes.includes(line.lbr_op))
|
||||
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
|
||||
.toFixed(2),
|
||||
BodyReplaceHours: job.joblines
|
||||
BodyReplacehours: job.joblines
|
||||
.filter((line) => replaceOpCodes.includes(line.lbr_op))
|
||||
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
|
||||
.toFixed(2),
|
||||
@@ -523,7 +521,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
AM: repairCosts.PartsAMCost.toFormat(CCDineroFormat),
|
||||
MechParts: Dinero().toFormat(CCDineroFormat),
|
||||
OtherParts: Dinero().toFormat(CCDineroFormat), //Check Synergy
|
||||
OtherCosts: repairCosts.PartsOtherCost.toFormat(CCDineroFormat),
|
||||
OtherCost: repairCosts.PartsOtherCost.toFormat(CCDineroFormat),
|
||||
Sublet: repairCosts.SubletTotalCost.toFormat(CCDineroFormat),
|
||||
Towing: repairCosts.TowingTotalCost.toFormat(CCDineroFormat),
|
||||
Storage: repairCosts.StorageTotalCost.toFormat(CCDineroFormat),
|
||||
|
||||
Reference in New Issue
Block a user