Compare commits

...

23 Commits

Author SHA1 Message Date
Patrick Fic
61e6511547 Add missing field to query. 2023-03-06 11:42:58 -08:00
Patrick Fic
85346e203b Update to env file. 2023-03-06 11:41:00 -08:00
Patrick Fic
c565e2199d IO-2195 Add additional check for conversation query. 2023-03-03 09:28:10 -08:00
Patrick Fic
8fa0946cfa IO-2195 Conversation query performance improvements. 2023-03-03 09:00:44 -08:00
Patrick Fic
a1ab254d6f Update hasura metadata. 2023-03-02 20:38:10 -08:00
Patrick Fic
99d3943955 Improve changing active shop profile methods to avoid multiple queries. 2023-03-02 20:04:54 -08:00
Patrick Fic
2415b4c2b4 IO-2194 Static control numbers for CDK. 2023-03-02 19:39:24 -08:00
Patrick Fic
99c7ba1fbc Disable ARMS on server side. 2023-03-02 19:38:37 -08:00
Patrick Fic
36e593f806 Io-2192 Add predefined vehicles list. 2023-03-02 19:06:08 -08:00
Patrick Fic
d825c04850 Package update modifications & IO-2192 Add ability to preselect make and model when creating a job. 2023-03-02 08:50:05 -08:00
Patrick Fic
ca7dfacec4 Package updates. 2023-03-01 13:01:48 -08:00
Patrick Fic
1138540518 Merged in release/2023-02-24 (pull request #682)
Release/2023 02 24
2023-02-27 18:11:31 +00:00
Allan Carr
59db305cb8 IO-2186 Production Over Time
Add new report requested by Loewen Body Shop
2023-02-23 11:14:00 -08:00
Patrick Fic
fea69fe3a5 Add payment response object. 2023-02-22 08:15:58 -08:00
Patrick Fic
43e4ff911e Merged in release/2023-02-17 (pull request #679)
Release/2023 02 17
2023-02-17 23:39:24 +00:00
Allan Carr
ae4cff98e7 IO-2175 Category Dropdown Clear
Allow for clear and correct for Select allowClear sending undefined and convert that to null. Overload UndefinedtoNull to have an array of keys
2023-02-16 17:26:57 -08:00
Allan Carr
3650cacb51 IO-2173 Job Line Discount
Correct for when new line is added with no part
2023-02-16 17:23:09 -08:00
Patrick Fic
c2bf6841e1 Documentation updates. 2023-02-14 15:05:09 -08:00
Allan Carr
f41b94d16d Merge branch 'release/2023-02-17' of https://bitbucket.org/snaptsoft/bodyshop into release/2023-02-17 2023-02-14 11:32:21 -08:00
Allan Carr
24da0207e5 IO-2173 Client Fusion - Job Line Discount not allowed
Adjust client job-line-upsert-modal to allow for discounts as markups were only allowed before. Convert prt_dsmk_p over to prt_dsmk_m on save of modal for both markup/discount for handling and viewing
2023-02-14 11:30:09 -08:00
Patrick Fic
bf34765e6b Additional Hasura Indexes. 2023-02-13 11:21:59 -08:00
Patrick Fic
4c98a347f5 Additional indexes for performance improvements. 2023-02-13 10:37:10 -08:00
Patrick Fic
840e760619 Merged in release/2023-02-10 (pull request #675)
Release/2023 02 10
2023-02-10 23:34:55 +00:00
93 changed files with 13266 additions and 11166 deletions

View File

@@ -1,4 +1,5 @@
{
"eslint.workingDirectories": ["./client", "./"],
"xml.fileAssociations": [
{
"pattern": "**/Test.xml",

View File

@@ -1,14 +1,3 @@
Yarn Dependency Management:
To force upgrades for some packages:
yarn upgrade-interactive --latest
To Start Hasura CLI:
npx hasura console
Migrating to Staging:
npx hasura migrate apply --endpoint https://db.imex.online/ --admin-secret 'Production-ImEXOnline!@#'
npx hasura migrate apply --endpoint https://db.test.bodyshop.app/ --admin-secret 'Test-ImEXOnlineBySnaptSoftware!'
NGROK TEsting:
./ngrok.exe http http://localhost:4000 -host-header="localhost:4000"
@@ -21,4 +10,4 @@ hasura migrate apply --version "1620771761757" --skip-execution --endpoint https
hasura migrate status --endpoint https://db.imex.online/ --admin-secret 'Production-ImEXOnline!@#'
Generate the license file:
$ generate-license-file --input package.json --output third-party-licenses.txt --overwrite
$ generate-license-file --input package.json --output third-party-licenses.txt --overwrite

View File

@@ -4339,6 +4339,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>dms_control_override</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>dms_wip_acctnumber</name>
<definition_loaded>false</definition_loaded>
@@ -42140,6 +42161,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>production_over_time</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>psr_by_make</name>
<definition_loaded>false</definition_loaded>
@@ -42161,6 +42203,48 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>purchase_return_ratio_grouped_by_vendor_detail</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>purchase_return_ratio_grouped_by_vendor_summary</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>purchases_by_cost_center_detail</name>
<definition_loaded>false</definition_loaded>

View File

@@ -8,6 +8,6 @@ REACT_APP_CLOUDINARY_API_KEY=957865933348715
REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
REACT_APP_FIREBASE_PUBLIC_VAPID_KEY='BG3tzU7L2BXlGZ_3VLK4PNaRceoEXEnmHfxcVbRMF5o5g05ejslhVPki9kBM9cBBT-08Ad9kN3HSpS6JmrWD6h4'
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
REACT_APP_AXIOS_BASE_API_URL=https://api.imex.online/
REACT_APP_AXIOS_BASE_API_URL=http://localhost:4000
REACT_APP_REPORTS_SERVER_URL=https://reports3.test.imex.online
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc

View File

@@ -4,69 +4,69 @@
"private": true,
"proxy": "http://localhost:4000",
"dependencies": {
"@apollo/client": "^3.6.9",
"@apollo/client": "^3.7.9",
"@asseinfo/react-kanban": "^2.2.0",
"@craco/craco": "^6.4.5",
"@craco/craco": "^7.0.0",
"@fingerprintjs/fingerprintjs": "^3.3.3",
"@jsreport/browser-client": "^3.1.0",
"@sentry/react": "^7.28.1",
"@sentry/tracing": "^7.28.1",
"@splitsoftware/splitio-react": "^1.6.0",
"@sentry/react": "^7.40.0",
"@sentry/tracing": "^7.40.0",
"@splitsoftware/splitio-react": "^1.8.1",
"@tanem/react-nprogress": "^5.0.8",
"antd": "^4.22.3",
"apollo-link-logger": "^2.0.0",
"axios": "^0.27.2",
"craco-less": "^1.20.0",
"antd": "^4.24.8",
"apollo-link-logger": "^2.0.1",
"axios": "^1.3.4",
"craco-less": "^2.0.0",
"dinero.js": "^1.9.1",
"dotenv": "^16.0.1",
"enquire-js": "^0.2.1",
"env-cmd": "^10.1.0",
"exifr": "^7.1.3",
"firebase": "^9.9.1",
"graphql": "^16.5.0",
"i18next": "^21.8.14",
"i18next-browser-languagedetector": "^6.1.4",
"firebase": "^9.17.1",
"graphql": "^16.6.0",
"i18next": "^22.4.10",
"i18next-browser-languagedetector": "^7.0.1",
"jsoneditor": "^9.9.0",
"jsreport-browser-client-dist": "^1.3.0",
"libphonenumber-js": "^1.10.9",
"libphonenumber-js": "^1.10.21",
"logrocket": "^3.0.1",
"markerjs2": "^2.22.0",
"markerjs2": "^2.28.1",
"moment-business-days": "^1.2.0",
"moment-timezone": "^0.5.34",
"normalize-url": "^7.0.3",
"phone": "^3.1.23",
"moment-timezone": "^0.5.41",
"normalize-url": "^8.0.0",
"phone": "^3.1.35",
"preval.macro": "^5.0.0",
"prop-types": "^15.8.1",
"query-string": "^7.1.1",
"query-string": "^7.1.3",
"rc-queue-anim": "^2.0.0",
"rc-scroll-anim": "^2.7.6",
"react": "^17.0.2",
"react-big-calendar": "^1.5.0",
"react-big-calendar": "^1.6.8",
"react-color": "^2.19.3",
"react-cookie": "^4.1.1",
"react-dom": "^17.0.2",
"react-drag-listview": "^0.2.1",
"react-grid-gallery": "^0.5.5",
"react-grid-layout": "^1.3.4",
"react-i18next": "^11.18.1",
"react-icons": "^4.4.0",
"react-number-format": "^4.9.3",
"react-redux": "^7.2.8",
"react-i18next": "^12.2.0",
"react-icons": "^4.7.1",
"react-number-format": "^5.1.3",
"react-redux": "^8.0.5",
"react-resizable": "^3.0.4",
"react-router-dom": "^5.3.0",
"react-scripts": "^4.0.3",
"react-scripts": "^5.0.1",
"react-sticky": "^6.0.3",
"react-sublime-video": "^0.2.5",
"react-virtualized": "^9.22.3",
"recharts": "^2.1.12",
"redux": "^4.2.0",
"recharts": "^2.4.3",
"redux": "^4.2.1",
"redux-persist": "^6.0.0",
"redux-saga": "^1.1.3",
"redux-saga": "^1.2.2",
"redux-state-sync": "^3.1.4",
"reselect": "^4.1.6",
"sass": "^1.54.0",
"socket.io-client": "^4.5.1",
"styled-components": "^5.3.5",
"reselect": "^4.1.7",
"sass": "^1.58.3",
"socket.io-client": "^4.6.1",
"styled-components": "^5.3.6",
"subscriptions-transport-ws": "^0.11.0",
"web-vitals": "^2.1.4",
"workbox-background-sync": "^6.5.3",

View File

@@ -42,6 +42,7 @@ export function ChatConversationContainer({ bodyshop, selectedConversation }) {
MARK_MESSAGES_AS_READ_BY_CONVERSATION,
{
variables: { conversationId: selectedConversation },
refetchQueries: ["UNREAD_CONVERSATION_COUNT"],
update(cache) {
cache.modify({
id: cache.identify({

View File

@@ -10,7 +10,10 @@ import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { CONVERSATION_LIST_QUERY } from "../../graphql/conversations.queries";
import {
CONVERSATION_LIST_QUERY,
UNREAD_CONVERSATION_COUNT,
} from "../../graphql/conversations.queries";
import { toggleChatVisible } from "../../redux/messaging/messaging.actions";
import {
selectChatVisible,
@@ -37,9 +40,17 @@ export function ChatPopupComponent({
}) {
const { t } = useTranslation();
const [pollInterval, setpollInterval] = useState(0);
const { data: unreadData } = useQuery(UNREAD_CONVERSATION_COUNT, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
...(pollInterval > 0 ? { pollInterval } : {}),
});
const { loading, data, refetch, called } = useQuery(CONVERSATION_LIST_QUERY, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
skip: !chatVisible,
...(pollInterval > 0 ? { pollInterval } : {}),
});
@@ -57,12 +68,14 @@ export function ChatPopupComponent({
if (called && chatVisible) refetch();
}, [chatVisible, called, refetch]);
const unreadCount = data
? data.conversations.reduce(
(acc, val) => val.messages_aggregate.aggregate.count + acc,
0
)
: 0;
// const unreadCount = data
// ? data.conversations.reduce(
// (acc, val) => val.messages_aggregate.aggregate.count + acc,
// 0
// )
// : 0;
const unreadCount = unreadData?.messages_aggregate.aggregate.count || 0;
return (
<Badge count={unreadCount}>

View File

@@ -289,7 +289,7 @@ export function JobLinesUpsertModalComponent({
name="prt_dsmk_p"
initialValue={0}
>
<InputNumber precision={0} min={0} max={100} />
<InputNumber precision={0} min={-100} max={100} />
</Form.Item>
<Form.Item
label={t("joblines.fields.tax_part")}

View File

@@ -13,6 +13,7 @@ import { selectJobLineEditModal } from "../../redux/modals/modals.selectors";
import UndefinedToNull from "../../utils/undefinedtonull";
import JobLinesUpdsertModal from "./job-lines-upsert-modal.component";
import Axios from "axios";
import Dinero from "dinero.js";
const mapStateToProps = createStructuredSelector({
jobLineEditModal: selectJobLineEditModal,
});
@@ -40,7 +41,15 @@ function JobLinesUpsertModalContainer({
manual_line: !(
jobLineEditModal.context && jobLineEditModal.context.id
),
...UndefinedToNull(values),
...UndefinedToNull({
...values,
prt_dsmk_m: Dinero({
amount: Math.round((values.act_price || 0) * 100),
})
.percentage(Math.abs(values.prt_dsmk_p || 0))
.multiply(values.prt_dsmk_p >= 0 ? 1 : -1)
.toFormat(0.0),
}),
},
],
},
@@ -68,7 +77,15 @@ function JobLinesUpsertModalContainer({
const r = await updateJobLine({
variables: {
lineId: jobLineEditModal.context.id,
line: values,
line: {
...values,
prt_dsmk_m: Dinero({
amount: Math.round(values.act_price * 100),
})
.percentage(Math.abs(values.prt_dsmk_p || 0))
.multiply(values.prt_dsmk_p >= 0 ? 1 : -1)
.toFormat(0.0),
},
},
refetchQueries: ["GET_LINE_TICKET_BY_PK"],
});

View File

@@ -9,7 +9,11 @@ const colSpan = {
lg: { span: 12 },
};
export default function JobsCreateVehicleInfoComponent({ loading, vehicles }) {
export default function JobsCreateVehicleInfoComponent({
loading,
vehicles,
form,
}) {
const [state, setState] = useContext(JobCreateContext);
const { t } = useTranslation();
return (
@@ -58,7 +62,7 @@ export default function JobsCreateVehicleInfoComponent({ loading, vehicles }) {
/>
</Col>
<Col {...colSpan}>
<JobsCreateVehicleInfoNewComponent />
<JobsCreateVehicleInfoNewComponent form={form}/>
</Col>
</Row>
</div>

View File

@@ -20,6 +20,7 @@ export default function JobsCreateVehicleInfoContainer({ form }) {
<JobsCreateVehicleInfoComponent
loading={loading}
vehicles={data ? data.search_vehicles : null}
form={form}
/>
);
}

View File

@@ -4,8 +4,9 @@ import { useTranslation } from "react-i18next";
import JobCreateContext from "../../pages/jobs-create/jobs-create.context";
import FormDatePicker from "../form-date-picker/form-date-picker.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import JobsCreateVehicleInfoPredefined from "./jobs-create-vehicle-info.predefined.component";
export default function JobsCreateVehicleInfoNewComponent() {
export default function JobsCreateVehicleInfoNewComponent({ form }) {
const [state] = useContext(JobCreateContext);
const { t } = useTranslation();
@@ -25,7 +26,7 @@ export default function JobsCreateVehicleInfoNewComponent() {
<Input disabled={!state.vehicle.new} />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow grow>
<LayoutFormRow grow noDivider>
<Form.Item
label={t("vehicles.fields.v_color")}
name={["vehicle", "data", "v_color"]}
@@ -52,8 +53,9 @@ export default function JobsCreateVehicleInfoNewComponent() {
</Form.Item>
</LayoutFormRow>
<LayoutFormRow grow>
<LayoutFormRow grow noDivider>
<Form.Item
span={10}
label={t("vehicles.fields.v_make_desc")}
name={["vehicle", "data", "v_make_desc"]}
rules={[
@@ -66,6 +68,7 @@ export default function JobsCreateVehicleInfoNewComponent() {
<Input disabled={!state.vehicle.new} />
</Form.Item>
<Form.Item
span={11}
label={t("vehicles.fields.v_model_desc")}
name={["vehicle", "data", "v_model_desc"]}
rules={[
@@ -77,6 +80,11 @@ export default function JobsCreateVehicleInfoNewComponent() {
>
<Input disabled={!state.vehicle.new} />
</Form.Item>
<JobsCreateVehicleInfoPredefined
disabled={!state.vehicle.new}
form={form}
span={1}
/>
</LayoutFormRow>
<LayoutFormRow header={t("vehicles.forms.registration")} grow>

View File

@@ -0,0 +1,81 @@
import { PlusOutlined, SearchOutlined } from "@ant-design/icons";
import { Button, Input, Popover, Table } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import PredefinedVehicles from "./predefined-vehicles.js";
export default function JobsCreateVehicleInfoPredefined({ disabled, form }) {
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");
const { t } = useTranslation();
const handleOpenChange = (newOpen) => {
setOpen(newOpen);
setSearch("");
};
const filteredPredefinedVehicles =
search === ""
? PredefinedVehicles
: PredefinedVehicles.filter(
(v) =>
v.make.toLowerCase().includes(search.toLowerCase()) ||
v.model.toLowerCase().includes(search.toLowerCase())
);
const popContent = () => (
<div>
<Table
size="small"
title={() => <Input.Search onSearch={(value) => setSearch(value)} />}
dataSource={filteredPredefinedVehicles}
columns={[
{
dataIndex: "make",
key: "make",
title: t("vehicles.fields.v_make_desc"),
},
{
dataIndex: "model",
key: "model",
title: t("vehicles.fields.v_model_desc"),
},
{
dataIndex: "select",
key: "select",
title: t("general.labels.actions"),
render: (value, record) => (
<Button
disabled={disabled}
onClick={() => {
form.setFieldsValue({
vehicle: {
data: {
v_make_desc: record.make,
v_model_desc: record.model,
},
},
});
setOpen(false);
setSearch("");
}}
>
<PlusOutlined />
</Button>
),
},
]}
/>
</div>
);
return (
<Popover
content={popContent}
trigger="click"
open={open}
placement="left"
onOpenChange={handleOpenChange}
destroyTooltipOnHide
>
<SearchOutlined style={{ cursor: "pointer" }} />
</Popover>
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -256,7 +256,7 @@ export function JobsDetailGeneral({ bodyshop, jobRO, job, form }) {
</FormRow>
<FormRow header={t("jobs.forms.other")}>
<Form.Item label={t("jobs.fields.category")} name="category">
<Select disabled={jobRO}>
<Select disabled={jobRO} allowClear>
{bodyshop.md_categories.map((s) => (
<Select.Option key={s} value={s}>
{s}

View File

@@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next";
import { logImEXEvent } from "../../firebase/firebase.utils";
import cleanAxios from "../../utils/CleanAxios";
import formatBytes from "../../utils/formatbytes";
import yauzl from "yauzl";
//import yauzl from "yauzl";
import { useTreatments } from "@splitsoftware/splitio-react";
import { connect } from "react-redux";
@@ -69,44 +69,44 @@ export function JobsDocumentsDownloadButton({
setDownload(null);
if (Direct_Media_Download.treatment === "on") {
try {
const parentDir = await window.showDirectoryPicker({
id: "media",
startIn: "downloads",
});
// const parentDir = await window.showDirectoryPicker({
// id: "media",
// startIn: "downloads",
// });
const directory = await parentDir.getDirectoryHandle(identifier, {
create: true,
});
// const directory = await parentDir.getDirectoryHandle(identifier, {
// create: true,
// });
yauzl.fromBuffer(
Buffer.from(theDownloadedZip.data),
{},
(err, zipFile) => {
if (err) throw err;
zipFile.on("entry", (entry) => {
zipFile.openReadStream(entry, async (readErr, readStream) => {
if (readErr) {
zipFile.close();
throw readErr;
}
if (err) throw err;
let fileSystemHandle = await directory.getFileHandle(
entry.fileName,
{
create: true,
}
);
const writable = await fileSystemHandle.createWritable();
readStream.on("data", async function (chunk) {
await writable.write(chunk);
});
readStream.on("end", async function () {
await writable.close();
});
});
});
}
);
// yauzl.fromBuffer(
// Buffer.from(theDownloadedZip.data),
// {},
// (err, zipFile) => {
// if (err) throw err;
// zipFile.on("entry", (entry) => {
// zipFile.openReadStream(entry, async (readErr, readStream) => {
// if (readErr) {
// zipFile.close();
// throw readErr;
// }
// if (err) throw err;
// let fileSystemHandle = await directory.getFileHandle(
// entry.fileName,
// {
// create: true,
// }
// );
// const writable = await fileSystemHandle.createWritable();
// readStream.on("data", async function (chunk) {
// await writable.write(chunk);
// });
// readStream.on("end", async function () {
// await writable.close();
// });
// });
// });
// }
// );
} catch (e) {
console.log(e);
standardMediaDownload(theDownloadedZip.data);

View File

@@ -55,6 +55,7 @@ export function ProductionListTable({
const assoc = bodyshop.associations.find(
(a) => a.useremail === currentUser.email
);
if (assoc) {
await updateDefaultProdView({
variables: { assocId: assoc.id, view: value },

View File

@@ -39,7 +39,7 @@ export default function ProfileShopsComponent({
),
},
];
console.log("🚀 ~ file: profile-shops.component.jsx:45 ~ data", data);
const filteredData =
search === ""
? data

View File

@@ -3,7 +3,7 @@ import React from "react";
import { logImEXEvent } from "../../firebase/firebase.utils";
import {
QUERY_ALL_ASSOCIATIONS,
UPDATE_ASSOCIATION,
UPDATE_ACTIVE_ASSOCIATION,
} from "../../graphql/associations.queries";
import AlertComponent from "../alert/alert.component";
import ProfileShopsComponent from "./profile-shops.component";
@@ -13,9 +13,13 @@ import { getToken } from "firebase/messaging";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import {
selectBodyshop,
selectCurrentUser,
} from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
currentUser: selectCurrentUser,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
@@ -25,14 +29,18 @@ export default connect(
mapDispatchToProps
)(ProfileShopsContainer);
export function ProfileShopsContainer({ bodyshop }) {
export function ProfileShopsContainer({ bodyshop, currentUser }) {
const { loading, error, data } = useQuery(QUERY_ALL_ASSOCIATIONS, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
variables: {
email: currentUser.email,
},
skip: !currentUser,
});
const [updateAssocation] = useMutation(UPDATE_ASSOCIATION);
const [updateActiveAssociation] = useMutation(UPDATE_ACTIVE_ASSOCIATION);
const updateActiveShop = async (activeShopId) => {
const updateActiveShop = async (newActiveAssocId) => {
logImEXEvent("profile_change_active_shop");
try {
@@ -46,16 +54,12 @@ export function ProfileShopsContainer({ bodyshop }) {
} catch (error) {
console.log("No FCM token. Skipping unsubscribe.");
}
await Promise.all(
data.associations.map(async (record) => {
await updateAssocation({
variables: {
assocId: record.id,
assocActive: record.id === activeShopId ? true : false,
},
});
})
);
await updateActiveAssociation({
variables: {
newActiveAssocId: newActiveAssocId,
},
});
//Force window refresh.

View File

@@ -217,7 +217,9 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
{t("jobs.fields.ponumber")}
</Select.Option>
<Select.Option value="account_number">
{t("jobs.fields.dms.control_type.account_number")}
{t(
"jobs.fields.dms.control_type.account_number"
)}
</Select.Option>
</Select>
</Form.Item>
@@ -423,6 +425,15 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
<Input onBlur={handleBlur} />
</Form.Item>
)}
{bodyshop.cdk_dealerid && (
<Form.Item
label={t("bodyshop.fields.dms.dms_control_override")}
key={`${index}dms_control_override`}
name={[field.name, "dms_control_override"]}
>
<Input onBlur={handleBlur} />
</Form.Item>
)}
<DeleteFilled
onClick={() => {
@@ -546,6 +557,15 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
<Input onBlur={handleBlur} />
</Form.Item>
)}
{bodyshop.cdk_dealerid && (
<Form.Item
label={t("bodyshop.fields.dms.dms_control_override")}
key={`${index}dms_control_override`}
name={[field.name, "dms_control_override"]}
>
<Input onBlur={handleBlur} />
</Form.Item>
)}
<DeleteFilled
onClick={() => {
remove(field.name);

View File

@@ -42,7 +42,9 @@ export default function ShopUsersAuthEdit({ association }) {
</div>
)}
{!visible && (
<div style={{ cursor: "pointer" }} onClick={() => setVisible(true)}>
<div
style={{ cursor: "pointer" }} //onClick={() => setVisible(true)}
>
{association.authlevel || t("general.labels.na")}
</div>
)}

View File

@@ -1,8 +1,11 @@
import { gql } from "@apollo/client";
export const QUERY_ALL_ASSOCIATIONS = gql`
query QUERY_ALL_ASSOCIATIONS {
associations(order_by: { bodyshop: { shopname: asc } }) {
query QUERY_ALL_ASSOCIATIONS($email: String) {
associations(
where: { useremail: { _eq: $email } }
order_by: { bodyshop: { shopname: asc } }
) {
id
active
bodyshop {
@@ -27,6 +30,30 @@ export const UPDATE_ASSOCIATION = gql`
}
}
`;
export const UPDATE_ACTIVE_ASSOCIATION = gql`
mutation UPDATE_ACTIVE_ASSOCIATION($newActiveAssocId: uuid) {
nweActive: update_associations(
where: { id: { _eq: $newActiveAssocId } }
_set: { active: true }
) {
returning {
id
shopid
active
}
}
inactive: update_associations(
where: { id: { _neq: $newActiveAssocId } }
_set: { active: false }
) {
returning {
id
shopid
active
}
}
}
`;
export const UPDATE_ACTIVE_PROD_LIST_VIEW = gql`
mutation UPDATE_ACTIVE_PROD_LIST_VIEW($assocId: uuid, $view: String) {

View File

@@ -12,6 +12,7 @@ export const QUERY_BODYSHOP = gql`
query QUERY_BODYSHOP {
bodyshops(where: { associations: { active: { _eq: true } } }) {
associations {
id
authlevel
useremail
default_prod_list_view

View File

@@ -31,6 +31,18 @@ import { gql } from "@apollo/client";
// }
// `;
export const UNREAD_CONVERSATION_COUNT = gql`
query UNREAD_CONVERSATION_COUNT {
messages_aggregate(
where: { read: { _eq: false }, isoutbound: { _eq: false } }
) {
aggregate {
count
}
}
}
`;
export const CONVERSATION_LIST_QUERY = gql`
query CONVERSATION_LIST_QUERY {
conversations(

View File

@@ -2060,6 +2060,7 @@ export const QUERY_JOB_EXPORT_DMS = gql`
ownr_fn
ownr_ln
ownr_co_nm
ins_co_nm
kmin
kmout
v_make_desc

View File

@@ -101,7 +101,10 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
];
});
});
socket.on("connect_error", (err) => {
console.log(`connect_error due to ${err}`, err);
notification.error({ message: err.message });
});
socket.on("log-event", (payload) => {
setLogs((logs) => {
return [...logs, payload];

View File

@@ -17,7 +17,7 @@ export default function JobsCreateComponent({ form }) {
const steps = [
{
title: t("jobs.labels.create.vehicleinfo"),
content: <JobsCreateVehicleInfoContainer />,
content: <JobsCreateVehicleInfoContainer form={form} />,
validation:
!!state.vehicle.new ||
!!state.vehicle.selectedid ||

View File

@@ -51,6 +51,7 @@ import JobAuditTrail from "../../components/job-audit-trail/job-audit-trail.comp
import AuditTrailMapping from "../../utils/AuditTrailMappings";
import { insertAuditTrail } from "../../redux/application/application.actions";
import JobsDocumentsLocalGallery from "../../components/jobs-documents-local-gallery/jobs-documents-local-gallery.container";
import UndefinedToNull from "../../utils/undefinedtonull";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -96,7 +97,7 @@ export function JobsDetailPage({
variables: {
jobId: job.id,
job: {
...values,
...UndefinedToNull(values, ["alt_transport", "category", "referral_source"]),
parts_tax_rates: {
...job.parts_tax_rates,
...values.parts_tax_rates,

View File

@@ -270,6 +270,7 @@
"disablebillwip": "Disable bill WIP for A/P Posting",
"disablecontactvehiclecreation": "Disable Contact & Vehicle Updates/Creation",
"dms_acctnumber": "DMS Account #",
"dms_control_override": "Static Control # Override",
"dms_wip_acctnumber": "DMS W.I.P. Account #",
"generic_customer_number": "Generic Customer Number",
"itc_federal": "Federal Tax is ITC?",
@@ -2485,6 +2486,7 @@
"production_by_target_date": "Production by Target Date",
"production_by_technician": "Production by Technician",
"production_by_technician_one": "Production filtered by Technician",
"production_over_time": "Production Level over Time",
"psr_by_make": "Percent of Sales by Vehicle Make",
"purchase_return_ratio_grouped_by_vendor_detail": "Purchase & Return Ratio by Vendor (Detail)",
"purchase_return_ratio_grouped_by_vendor_summary": "Purchase & Return Ratio by Vendor (Summary)",

View File

@@ -270,6 +270,7 @@
"disablebillwip": "",
"disablecontactvehiclecreation": "",
"dms_acctnumber": "",
"dms_control_override": "",
"dms_wip_acctnumber": "",
"generic_customer_number": "",
"itc_federal": "",
@@ -2485,6 +2486,7 @@
"production_by_target_date": "",
"production_by_technician": "",
"production_by_technician_one": "",
"production_over_time": "",
"psr_by_make": "",
"purchase_return_ratio_grouped_by_vendor_detail": "",
"purchase_return_ratio_grouped_by_vendor_summary": "",

View File

@@ -270,6 +270,7 @@
"disablebillwip": "",
"disablecontactvehiclecreation": "",
"dms_acctnumber": "",
"dms_control_override": "",
"dms_wip_acctnumber": "",
"generic_customer_number": "",
"itc_federal": "",
@@ -2485,6 +2486,7 @@
"production_by_target_date": "",
"production_by_technician": "",
"production_by_technician_one": "",
"production_over_time": "",
"psr_by_make": "",
"purchase_return_ratio_grouped_by_vendor_detail": "",
"purchase_return_ratio_grouped_by_vendor_summary": "",

View File

@@ -1,9 +1,9 @@
import React from "react";
import NumberFormat from "react-number-format";
import { NumericFormat } from "react-number-format";
export default function CurrencyFormatter(props) {
return (
<NumberFormat
<NumericFormat
thousandSeparator={true}
decimalScale={2}
fixedDecimalScale={true}

View File

@@ -142,7 +142,7 @@ middlewares.push(
const cache = new InMemoryCache({});
export default new ApolloClient({
const client = new ApolloClient({
link: ApolloLink.from(middlewares),
cache,
connectToDevTools: process.env.NODE_ENV !== "production",
@@ -161,3 +161,4 @@ export default new ApolloClient({
},
},
});
export default client;

View File

@@ -1841,6 +1841,20 @@ export const TemplateList = (type, context) => {
},
group: "purchases",
},
production_over_time: {
title: i18n.t("reportcenter.templates.production_over_time"),
subject: i18n.t(
"reportcenter.templates.production_over_time"
),
key: "production_over_time",
//idtype: "vendor",
disabled: false,
rangeFilter: {
object: i18n.t("reportcenter.labels.objects.jobs"),
field: i18n.t("jobs.fields.actual_in"),
},
group: "jobs",
},
}
: {}),
...(!type || type === "courtesycarcontract"

View File

@@ -1,6 +1,10 @@
export default function UndefinedToNull(obj) {
export default function UndefinedToNull(obj, keys) {
Object.keys(obj).forEach((key) => {
if (keys && keys.indexOf(key) >= 0) {
if (obj[key] === undefined) obj[key] = null;
} else {
if (obj[key] === undefined) obj[key] = null;
}
});
return obj;
}

File diff suppressed because it is too large Load Diff

View File

@@ -223,11 +223,9 @@
- kanban_settings
- qbo_realmId
filter:
bodyshop:
associations:
user:
authid:
_eq: X-Hasura-User-Id
user:
authid:
_eq: X-Hasura-User-Id
check: null
- table:
name: audit_trail
@@ -4502,6 +4500,62 @@
_eq: X-Hasura-User-Id
- active:
_eq: true
- table:
name: payment_response
schema: public
object_relationships:
- name: bodyshop
using:
foreign_key_constraint_on: bodyshopid
- name: job
using:
foreign_key_constraint_on: jobid
- name: payment
using:
foreign_key_constraint_on: paymentid
insert_permissions:
- role: user
permission:
check:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- amount
- bodyshopid
- declinereason
- ext_paymentid
- jobid
- paymentid
- response
- successful
select_permissions:
- role: user
permission:
columns:
- successful
- response
- amount
- declinereason
- ext_paymentid
- bodyshopid
- id
- jobid
- paymentid
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
- table:
name: payments
schema: public

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."jobs_idx_date_open";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "jobs_idx_date_open" on
"public"."jobs" using btree ("date_open");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."jobs_idx_date_invoiced";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "jobs_idx_date_invoiced" on
"public"."jobs" using btree ("date_invoiced");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_bills_vendorid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_bills_vendorid" on
"public"."bills" using btree ("vendorid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_parts_orders_vendorid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_parts_orders_vendorid" on
"public"."parts_orders" using btree ("vendorid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_ccc_jobid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_ccc_jobid" on
"public"."cccontracts" using btree ("jobid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_ccc_courtesycarid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_ccc_courtesycarid" on
"public"."cccontracts" using btree ("courtesycarid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_jobs_actual_completion";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_jobs_actual_completion" on
"public"."jobs" using btree ("actual_completion");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_jobs_actual_in";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_jobs_actual_in" on
"public"."jobs" using btree ("actual_in");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_jobs_employee_csr";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_jobs_employee_csr" on
"public"."jobs" using btree ("employee_csr");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_jobs_body_csr";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_jobs_body_csr" on
"public"."jobs" using btree ("employee_body");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_jobs_employee_refinish";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_jobs_employee_refinish" on
"public"."jobs" using btree ("employee_refinish");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_timetickets_employeeid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_timetickets_employeeid" on
"public"."timetickets" using btree ("employeeid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_timetickets_cost_center";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_timetickets_cost_center" on
"public"."timetickets" using btree ("cost_center");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_scoreboard_jobid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_scoreboard_jobid" on
"public"."scoreboard" using btree ("jobid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_scoreboard_date";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_scoreboard_date" on
"public"."scoreboard" using btree ("date");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_payments_date";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_payments_date" on
"public"."payments" using btree ("date");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."exportlog_createdat";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "exportlog_createdat" on
"public"."exportlog" using btree ("created_at");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_transitions_jobid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_transitions_jobid" on
"public"."transitions" using btree ("jobid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_transitions_start";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_transitions_start" on
"public"."transitions" using btree ("start");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_transitions_end";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_transitions_end" on
"public"."transitions" using btree ("end");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_audit_bodyshopid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_audit_bodyshopid" on
"public"."audit_trail" using btree ("bodyshopid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_audit_jobid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_audit_jobid" on
"public"."audit_trail" using btree ("jobid");

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "public"."idx_audit_billid";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "idx_audit_billid" on
"public"."audit_trail" using btree ("billid");

View File

@@ -0,0 +1,11 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- CREATE INDEX idx_phonebook_firstname ON public.phonebook USING gin (firstname public.gin_trgm_ops);
-- CREATE INDEX idx_phonebook_lastname ON public.phonebook USING gin (lastname public.gin_trgm_ops);
-- CREATE INDEX idx_phonebook_company ON public.phonebook USING gin (company public.gin_trgm_ops);
-- CREATE INDEX idx_phonebook_address1 ON public.phonebook USING gin (address1 public.gin_trgm_ops);
-- CREATE INDEX idx_phonebook_phone1 ON public.phonebook USING gin (phone1 public.gin_trgm_ops);
-- CREATE INDEX idx_phonebook_phone2 ON public.phonebook USING gin (phone2 public.gin_trgm_ops);
-- CREATE INDEX idx_phonebook_email ON public.phonebook USING gin (email public.gin_trgm_ops);
-- CREATE INDEX idx_phonebook_category ON public.phonebook USING gin (category public.gin_trgm_ops);
-- CREATE INDEX idx_vendor_name ON public.vendors USING gin (name public.gin_trgm_ops);

View File

@@ -0,0 +1,9 @@
CREATE INDEX idx_phonebook_firstname ON public.phonebook USING gin (firstname public.gin_trgm_ops);
CREATE INDEX idx_phonebook_lastname ON public.phonebook USING gin (lastname public.gin_trgm_ops);
CREATE INDEX idx_phonebook_company ON public.phonebook USING gin (company public.gin_trgm_ops);
CREATE INDEX idx_phonebook_address1 ON public.phonebook USING gin (address1 public.gin_trgm_ops);
CREATE INDEX idx_phonebook_phone1 ON public.phonebook USING gin (phone1 public.gin_trgm_ops);
CREATE INDEX idx_phonebook_phone2 ON public.phonebook USING gin (phone2 public.gin_trgm_ops);
CREATE INDEX idx_phonebook_email ON public.phonebook USING gin (email public.gin_trgm_ops);
CREATE INDEX idx_phonebook_category ON public.phonebook USING gin (category public.gin_trgm_ops);
CREATE INDEX idx_vendor_name ON public.vendors USING gin (name public.gin_trgm_ops);

View File

@@ -0,0 +1 @@
DROP TABLE "public"."payment_response";

View File

@@ -0,0 +1,2 @@
CREATE TABLE "public"."payment_response" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "bodyshopid" uuid NOT NULL, "jobid" uuid, "paymentid" uuid, "successful" boolean NOT NULL DEFAULT false, "ext_paymentid" text NOT NULL, "amount" numeric NOT NULL, "declinereason" text, "response" jsonb NOT NULL DEFAULT jsonb_build_object(), PRIMARY KEY ("id") , FOREIGN KEY ("bodyshopid") REFERENCES "public"."bodyshops"("id") ON UPDATE cascade ON DELETE cascade, FOREIGN KEY ("jobid") REFERENCES "public"."jobs"("id") ON UPDATE cascade ON DELETE cascade, FOREIGN KEY ("paymentid") REFERENCES "public"."payments"("id") ON UPDATE cascade ON DELETE cascade);
CREATE EXTENSION IF NOT EXISTS pgcrypto;

5634
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -17,41 +17,41 @@
"start": "node server.js"
},
"dependencies": {
"aws-sdk": "^2.1181.0",
"aws-sdk": "^2.1326.0",
"axios": "^0.27.2",
"bluebird": "^3.7.2",
"body-parser": "^1.20.0",
"cloudinary": "^1.30.1",
"body-parser": "^1.20.2",
"cloudinary": "^1.34.0",
"compression": "^1.7.4",
"cookie-parser": "^1.4.6",
"cors": "2.8.5",
"csrf": "^3.1.0",
"dinero.js": "^1.9.1",
"dotenv": "16.0.1",
"express": "^4.18.1",
"firebase-admin": "^11.0.0",
"graphql": "^16.5.0",
"dotenv": "16.0.3",
"express": "^4.18.2",
"firebase-admin": "^11.5.0",
"graphql": "^16.6.0",
"graphql-request": "^4.2.0",
"graylog2": "^0.2.1",
"inline-css": "^4.0.1",
"inline-css": "^4.0.2",
"intuit-oauth": "^4.0.0",
"json-2-csv": "^3.17.1",
"json-2-csv": "^3.19.0",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"moment-timezone": "^0.5.34",
"moment-timezone": "^0.5.41",
"multer": "^1.4.5-lts.1",
"node-mailjet": "^5.1.0",
"node-persist": "^3.1.0",
"node-quickbooks": "^2.0.39",
"nodemailer": "^6.7.7",
"phone": "^3.1.23",
"node-mailjet": "^6.0.2",
"node-persist": "^3.1.3",
"node-quickbooks": "^2.0.41",
"nodemailer": "^6.9.1",
"phone": "^3.1.35",
"query-string": "^7.1.1",
"soap": "^0.45.0",
"socket.io": "^4.5.0",
"ssh2-sftp-client": "^9.0.2",
"soap": "^1.0.0",
"socket.io": "^4.6.1",
"ssh2-sftp-client": "^9.0.4",
"stripe": "^9.15.0",
"twilio": "^3.80.0",
"uuid": "^8.3.2",
"twilio": "^4.8.0",
"uuid": "^9.0.0",
"xml2js": "^0.4.23",
"xmlbuilder2": "^3.0.2"
},

View File

@@ -1092,7 +1092,13 @@ async function GenerateTransWips(socket) {
if (alloc.sale.getAmount() > 0 && !alloc.tax) {
const item = {
acct: alloc.profitCenter.dms_acctnumber,
cntl: socket.JobData.ro_number,
cntl:
alloc.profitCenter.dms_control_override &&
alloc.profitCenter.dms_control_override !== null &&
alloc.profitCenter.dms_control_override !== undefined &&
alloc.profitCenter.dms_control_override?.trim() !== ""
? alloc.profitCenter.dms_control_override
: socket.JobData.ro_number,
cntl2: null,
credtMemoNo: null,
postAmt: alloc.sale.multiply(-1).getAmount(),
@@ -1109,7 +1115,13 @@ async function GenerateTransWips(socket) {
if (alloc.cost.getAmount() > 0 && !alloc.tax) {
const item = {
acct: alloc.costCenter.dms_acctnumber,
cntl: socket.JobData.ro_number,
cntl:
alloc.costCenter.dms_control_override &&
alloc.costCenter.dms_control_override !== null &&
alloc.costCenter.dms_control_override !== undefined &&
alloc.costCenter.dms_control_override?.trim() !== ""
? alloc.costCenter.dms_control_override
: socket.JobData.ro_number,
cntl2: null,
credtMemoNo: null,
postAmt: alloc.cost.getAmount(),
@@ -1123,7 +1135,13 @@ async function GenerateTransWips(socket) {
const itemWip = {
acct: alloc.costCenter.dms_wip_acctnumber,
cntl: socket.JobData.ro_number,
cntl:
alloc.costCenter.dms_control_override &&
alloc.costCenter.dms_control_override !== null &&
alloc.costCenter.dms_control_override !== undefined &&
alloc.costCenter.dms_control_override?.trim() !== ""
? alloc.costCenter.dms_control_override
: socket.JobData.ro_number,
cntl2: null,
credtMemoNo: null,
postAmt: alloc.cost.multiply(-1).getAmount(),
@@ -1158,7 +1176,13 @@ async function GenerateTransWips(socket) {
if (alloc.sale.getAmount() > 0) {
const item2 = {
acct: alloc.profitCenter.dms_acctnumber,
cntl: socket.JobData.ro_number,
cntl:
alloc.profitCenter.dms_control_override &&
alloc.profitCenter.dms_control_override !== null &&
alloc.profitCenter.dms_control_override !== undefined &&
alloc.profitCenter.dms_control_override?.trim() !== ""
? alloc.profitCenter.dms_control_override
: socket.JobData.ro_number,
cntl2: null,
credtMemoNo: null,
postAmt: alloc.sale.multiply(-1).getAmount(),

View File

@@ -42,14 +42,16 @@ function pollFunc(fn, timeout, interval) {
pollFunc(getEntegralShopData, 0, 5 * 60 * 1000); //Set the metadata to refresh every 5 minutes.
async function getEntegralShopData() {
await storage.init({ logging: true });
const { bodyshops } = await client.request(queries.GET_ENTEGRAL_SHOPS);
logger.log("set-entegral-shops-local-storage", "DEBUG", "API", null, null);
await storage.setItem("entegralShops", bodyshops);
return true; //Continue execution.
// await storage.init({ logging: true });
// const { bodyshops } = await client.request(queries.GET_ENTEGRAL_SHOPS);
// logger.log("set-entegral-shops-local-storage", "DEBUG", "API", null, null);
// await storage.setItem("entegralShops", bodyshops);
// return true; //Continue execution.
}
exports.default = async (req, res) => {
res.sendStatus(200);
return;
//Query for the List of Bodyshop Clients.
const job = req.body.event.data.new;
logger.log("arms-job-update", "DEBUG", "api", job.id, null);

View File

@@ -28,7 +28,7 @@ exports.sendServerEmail = async function ({ subject, text }) {
transporter.sendMail(
{
from: `ImEX Online API - ${process.env.NODE_ENV} <noreply@imex.online>`,
to: ["patrick@snapt.ca"],
to: ["patrick@imexsystems.ca"],
subject: subject,
text: text,
ses: {

2855
yarn.lock

File diff suppressed because it is too large Load Diff