Compare commits
49 Commits
feature/IO
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98bff6d8f6 | ||
|
|
7959dc67ce | ||
|
|
a4116b6c28 | ||
|
|
0d2cdec75c | ||
|
|
269ef25ece | ||
|
|
575fbd5357 | ||
|
|
2ad887fb82 | ||
|
|
40a1a86f72 | ||
|
|
95d43d936c | ||
|
|
9f56568680 | ||
|
|
3428940c72 | ||
|
|
ea604a5e64 | ||
|
|
5b76473cbc | ||
|
|
db5359e086 | ||
|
|
35046f11c2 | ||
|
|
69d8d27ad3 | ||
|
|
f4c4005a2a | ||
|
|
755acd24f0 | ||
|
|
079d6cfee6 | ||
|
|
3e3b3c269a | ||
|
|
39f1af7d4b | ||
|
|
1ea4d616d7 | ||
|
|
fdf0ecf6f6 | ||
|
|
e5f7285253 | ||
|
|
e46c304f7c | ||
|
|
1aa570db90 | ||
|
|
1c2be3c890 | ||
|
|
05e4eacf34 | ||
|
|
e1417b03f9 | ||
|
|
7b99de8046 | ||
|
|
6dc03d7f67 | ||
|
|
2a5e6a51aa | ||
|
|
885477fa68 | ||
|
|
c7db792793 | ||
|
|
31be51ef79 | ||
|
|
e4066c1570 | ||
|
|
ec480f2cb1 | ||
|
|
f5b30c9376 | ||
|
|
412508fbcf | ||
|
|
dbfd9bce54 | ||
|
|
52e0558c79 | ||
|
|
562d0b8641 | ||
|
|
d48d6cdd91 | ||
|
|
9363790541 | ||
|
|
2bceba948d | ||
|
|
cdf6050ec2 | ||
|
|
f451155689 | ||
|
|
9f06e19346 | ||
|
|
f4be3e9668 |
@@ -1,7 +1,8 @@
|
|||||||
VITE_APP_GRAPHQL_ENDPOINT=https://db.dev.bodyshop.app/v1/graphql
|
VITE_APP_GRAPHQL_ENDPOINT=https://db.dev.bodyshop.app/v1/graphql
|
||||||
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.dev.bodyshop.app/v1/graphql
|
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.dev.bodyshop.app/v1/graphql
|
||||||
VITE_APP_GA_CODE=231099835
|
VITE_APP_GA_CODE=231099835
|
||||||
VITE_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
|
# VITE_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
|
||||||
|
VITE_APP_FIREBASE_CONFIG={"apiKey":"AIzaSyDPLT8GiDHDR1R4nI66Qi0BY1aYviDPioc","authDomain":"imex-dev.firebaseapp.com","databaseURL":"https://imex-dev.firebaseio.com","projectId":"imex-dev","storageBucket":"imex-dev.appspot.com","messagingSenderId":"759548147434","appId":"1:759548147434:web:e8239868a48ceb36700993","measurementId":"G-K5XRBVVB4S"}
|
||||||
VITE_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/io-test
|
VITE_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/io-test
|
||||||
VITE_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/io-test
|
VITE_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/io-test
|
||||||
VITE_APP_CLOUDINARY_API_KEY=957865933348715
|
VITE_APP_CLOUDINARY_API_KEY=957865933348715
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
VITE_APP_GRAPHQL_ENDPOINT=https://db.dev.bodyshop.app/v1/graphql
|
VITE_APP_GRAPHQL_ENDPOINT=https://db.dev.bodyshop.app/v1/graphql
|
||||||
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.dev.bodyshop.app/v1/graphql
|
VITE_APP_GRAPHQL_ENDPOINT_WS=wss://db.dev.bodyshop.app/v1/graphql
|
||||||
VITE_APP_GA_CODE=231099835
|
VITE_APP_GA_CODE=231099835
|
||||||
VITE_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
|
# VITE_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
|
||||||
|
VITE_APP_FIREBASE_CONFIG={"apiKey":"AIzaSyDPLT8GiDHDR1R4nI66Qi0BY1aYviDPioc","authDomain":"imex-dev.firebaseapp.com","databaseURL":"https://imex-dev.firebaseio.com","projectId":"imex-dev","storageBucket":"imex-dev.appspot.com","messagingSenderId":"759548147434","appId":"1:759548147434:web:e8239868a48ceb36700993","measurementId":"G-K5XRBVVB4S"}
|
||||||
VITE_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/io-test
|
VITE_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/io-test
|
||||||
VITE_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/io-test
|
VITE_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/io-test
|
||||||
VITE_APP_CLOUDINARY_API_KEY=957865933348715
|
VITE_APP_CLOUDINARY_API_KEY=957865933348715
|
||||||
|
|||||||
56
client/public/firebase-messaging-sw.js
Normal file
56
client/public/firebase-messaging-sw.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// Scripts for firebase and firebase messaging
|
||||||
|
importScripts("https://www.gstatic.com/firebasejs/8.2.0/firebase-app.js");
|
||||||
|
importScripts("https://www.gstatic.com/firebasejs/8.2.0/firebase-messaging.js");
|
||||||
|
|
||||||
|
// Initialize the Firebase app in the service worker by passing the generated config
|
||||||
|
let firebaseConfig;
|
||||||
|
switch (this.location.hostname) {
|
||||||
|
case "localhost":
|
||||||
|
firebaseConfig = {
|
||||||
|
apiKey: "AIzaSyDPLT8GiDHDR1R4nI66Qi0BY1aYviDPioc",
|
||||||
|
authDomain: "imex-dev.firebaseapp.com",
|
||||||
|
databaseURL: "https://imex-dev.firebaseio.com",
|
||||||
|
projectId: "imex-dev",
|
||||||
|
storageBucket: "imex-dev.appspot.com",
|
||||||
|
messagingSenderId: "759548147434",
|
||||||
|
appId: "1:759548147434:web:e8239868a48ceb36700993",
|
||||||
|
measurementId: "G-K5XRBVVB4S",
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case "test.imex.online":
|
||||||
|
firebaseConfig = {
|
||||||
|
apiKey: "AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c",
|
||||||
|
authDomain: "imex-test.firebaseapp.com",
|
||||||
|
projectId: "imex-test",
|
||||||
|
storageBucket: "imex-test.appspot.com",
|
||||||
|
messagingSenderId: "991923618608",
|
||||||
|
appId: "1:991923618608:web:633437569cdad78299bef5",
|
||||||
|
// measurementId: "${config.measurementId}",
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case "imex.online":
|
||||||
|
default:
|
||||||
|
firebaseConfig = {
|
||||||
|
apiKey: "AIzaSyDSezy-jGJreo7ulgpLdlpOwAOrgcaEkhU",
|
||||||
|
authDomain: "imex-prod.firebaseapp.com",
|
||||||
|
databaseURL: "https://imex-prod.firebaseio.com",
|
||||||
|
projectId: "imex-prod",
|
||||||
|
storageBucket: "imex-prod.appspot.com",
|
||||||
|
messagingSenderId: "253497221485",
|
||||||
|
appId: "1:253497221485:web:3c81c483b94db84b227a64",
|
||||||
|
measurementId: "G-NTWBKG2L0M",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
firebase.initializeApp(firebaseConfig);
|
||||||
|
|
||||||
|
// Retrieve firebase messaging
|
||||||
|
const messaging = firebase.messaging();
|
||||||
|
|
||||||
|
messaging.onBackgroundMessage(function (payload) {
|
||||||
|
// Customize notification here
|
||||||
|
const channel = new BroadcastChannel("imex-sw-messages");
|
||||||
|
channel.postMessage(payload);
|
||||||
|
|
||||||
|
//self.registration.showNotification(notificationTitle, notificationOptions);
|
||||||
|
});
|
||||||
@@ -150,7 +150,7 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline
|
|||||||
<ProductFruits
|
<ProductFruits
|
||||||
workspaceCode={InstanceRenderMgr({
|
workspaceCode={InstanceRenderMgr({
|
||||||
imex: null,
|
imex: null,
|
||||||
rome: null,
|
rome: "9BkbEseqNqxw8jUH",
|
||||||
promanager: "aoJoEifvezYI0Z0P"
|
promanager: "aoJoEifvezYI0Z0P"
|
||||||
})}
|
})}
|
||||||
debug
|
debug
|
||||||
|
|||||||
@@ -25,31 +25,27 @@ const BillLineSearchSelect = ({ options, disabled, allowRemoved, ...restProps },
|
|||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
notFoundContent={"Removed."}
|
notFoundContent={"Removed."}
|
||||||
{...restProps}
|
options={[
|
||||||
>
|
{ value: "noline", label: t("billlines.labels.other"), name: t("billlines.labels.other") },
|
||||||
<Select.Option key={null} value={"noline"} cost={0} line_desc={""}>
|
...options.map((item) => ({
|
||||||
{t("billlines.labels.other")}
|
disabled: allowRemoved ? false : item.removed,
|
||||||
</Select.Option>
|
key: item.id,
|
||||||
{options
|
value: item.id,
|
||||||
? options.map((item) => (
|
cost: item.act_price ? item.act_price : 0,
|
||||||
<Option
|
part_type: item.part_type,
|
||||||
disabled={allowRemoved ? false : item.removed}
|
line_desc: item.line_desc,
|
||||||
key={item.id}
|
part_qty: item.part_qty,
|
||||||
value={item.id}
|
oem_partno: item.oem_partno,
|
||||||
cost={item.act_price ? item.act_price : 0}
|
alt_partno: item.alt_partno,
|
||||||
part_type={item.part_type}
|
act_price: item.act_price,
|
||||||
line_desc={item.line_desc}
|
style: {
|
||||||
part_qty={item.part_qty}
|
...(item.removed ? { textDecoration: "line-through" } : {})
|
||||||
oem_partno={item.oem_partno}
|
},
|
||||||
alt_partno={item.alt_partno}
|
name: `${item.removed ? `(REMOVED) ` : ""}${item.line_desc}${
|
||||||
act_price={item.act_price}
|
item.oem_partno ? ` - ${item.oem_partno}` : ""
|
||||||
style={{
|
}${item.alt_partno ? ` (${item.alt_partno})` : ""}`.trim(),
|
||||||
...(item.removed ? { textDecoration: "line-through" } : {})
|
label: (
|
||||||
}}
|
<>
|
||||||
name={`${item.removed ? `(REMOVED) ` : ""}${item.line_desc}${
|
|
||||||
item.oem_partno ? ` - ${item.oem_partno}` : ""
|
|
||||||
}${item.alt_partno ? ` (${item.alt_partno})` : ""}`.trim()}
|
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
{`${item.removed ? `(REMOVED) ` : ""}${item.line_desc}${
|
{`${item.removed ? `(REMOVED) ` : ""}${item.line_desc}${
|
||||||
item.oem_partno ? ` - ${item.oem_partno}` : ""
|
item.oem_partno ? ` - ${item.oem_partno}` : ""
|
||||||
@@ -60,14 +56,15 @@ const BillLineSearchSelect = ({ options, disabled, allowRemoved, ...restProps },
|
|||||||
<span style={{ float: "right", paddingleft: "1rem" }}>{`${item.mod_lb_hrs} units`}</span>
|
<span style={{ float: "right", paddingleft: "1rem" }}>{`${item.mod_lb_hrs} units`}</span>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<span style={{ float: "right", paddingleft: "1rem" }}>
|
<span style={{ float: "right", paddingleft: "1rem" }}>
|
||||||
{item.act_price ? `$${item.act_price && item.act_price.toFixed(2)}` : ``}
|
{item.act_price ? `$${item.act_price && item.act_price.toFixed(2)}` : ``}
|
||||||
</span>
|
</span>
|
||||||
</Option>
|
</>
|
||||||
))
|
)
|
||||||
: null}
|
}))
|
||||||
</Select>
|
]}
|
||||||
|
{...restProps}
|
||||||
|
></Select>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default forwardRef(BillLineSearchSelect);
|
export default forwardRef(BillLineSearchSelect);
|
||||||
|
|||||||
@@ -3,14 +3,13 @@ import axios from "axios";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
|
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
|
||||||
import OwnerNameDisplay, { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
|
import OwnerNameDisplay, { OwnerNameDisplayFunction } from "../owner-name-display/owner-name-display.component";
|
||||||
import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component";
|
import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component";
|
||||||
|
|
||||||
export default function GlobalSearchOs() {
|
export default function GlobalSearchOs() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const history = useNavigate();
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [data, setData] = useState(false);
|
const [data, setData] = useState(false);
|
||||||
|
|
||||||
@@ -178,15 +177,7 @@ export default function GlobalSearchOs() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AutoComplete
|
<AutoComplete options={data} onSearch={handleSearch} defaultActiveFirstOption onClear={() => setData([])}>
|
||||||
options={data}
|
|
||||||
onSearch={handleSearch}
|
|
||||||
defaultActiveFirstOption
|
|
||||||
onSelect={(val, opt) => {
|
|
||||||
history(opt.label.props.to);
|
|
||||||
}}
|
|
||||||
onClear={() => setData([])}
|
|
||||||
>
|
|
||||||
<Input.Search
|
<Input.Search
|
||||||
size="large"
|
size="large"
|
||||||
placeholder={t("general.labels.globalsearch")}
|
placeholder={t("general.labels.globalsearch")}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { AutoComplete, Divider, Input, Space } from "antd";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { GLOBAL_SEARCH_QUERY } from "../../graphql/search.queries";
|
import { GLOBAL_SEARCH_QUERY } from "../../graphql/search.queries";
|
||||||
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
|
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
@@ -12,7 +12,6 @@ import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.compon
|
|||||||
|
|
||||||
export default function GlobalSearch() {
|
export default function GlobalSearch() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const history = useNavigate();
|
|
||||||
const [callSearch, { loading, error, data }] = useLazyQuery(GLOBAL_SEARCH_QUERY);
|
const [callSearch, { loading, error, data }] = useLazyQuery(GLOBAL_SEARCH_QUERY);
|
||||||
|
|
||||||
const executeSearch = (v) => {
|
const executeSearch = (v) => {
|
||||||
@@ -157,14 +156,7 @@ export default function GlobalSearch() {
|
|||||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AutoComplete
|
<AutoComplete options={options} onSearch={handleSearch} defaultActiveFirstOption>
|
||||||
options={options}
|
|
||||||
onSearch={handleSearch}
|
|
||||||
defaultActiveFirstOption
|
|
||||||
onSelect={(val, opt) => {
|
|
||||||
history(opt.label.props.to);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Input.Search
|
<Input.Search
|
||||||
size="large"
|
size="large"
|
||||||
placeholder={t("general.labels.globalsearch")}
|
placeholder={t("general.labels.globalsearch")}
|
||||||
|
|||||||
@@ -141,11 +141,13 @@ function Header({
|
|||||||
accountingChildren.push(
|
accountingChildren.push(
|
||||||
{
|
{
|
||||||
key: "bills",
|
key: "bills",
|
||||||
|
id: "header-accounting-bills",
|
||||||
icon: <Icon component={FaFileInvoiceDollar} />,
|
icon: <Icon component={FaFileInvoiceDollar} />,
|
||||||
label: <Link to="/manage/bills">{t("menus.header.bills")}</Link>
|
label: <Link to="/manage/bills">{t("menus.header.bills")}</Link>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "enterbills",
|
key: "enterbills",
|
||||||
|
id: "header-accounting-enterbills",
|
||||||
icon: <Icon component={GiPayMoney} />,
|
icon: <Icon component={GiPayMoney} />,
|
||||||
label: t("menus.header.enterbills"),
|
label: t("menus.header.enterbills"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -165,6 +167,7 @@ function Header({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "inventory",
|
key: "inventory",
|
||||||
|
id: "header-accounting-inventory",
|
||||||
icon: <Icon component={FaFileInvoiceDollar} />,
|
icon: <Icon component={FaFileInvoiceDollar} />,
|
||||||
label: <Link to="/manage/inventory">{t("menus.header.inventory")}</Link>
|
label: <Link to="/manage/inventory">{t("menus.header.inventory")}</Link>
|
||||||
}
|
}
|
||||||
@@ -183,11 +186,13 @@ function Header({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "allpayments",
|
key: "allpayments",
|
||||||
|
id: "header-accounting-allpayments",
|
||||||
icon: <BankFilled />,
|
icon: <BankFilled />,
|
||||||
label: <Link to="/manage/payments">{t("menus.header.allpayments")}</Link>
|
label: <Link to="/manage/payments">{t("menus.header.allpayments")}</Link>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "enterpayments",
|
key: "enterpayments",
|
||||||
|
id: "header-accounting-enterpayments",
|
||||||
icon: <Icon component={FaCreditCard} />,
|
icon: <Icon component={FaCreditCard} />,
|
||||||
label: t("menus.header.enterpayment"),
|
label: t("menus.header.enterpayment"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -203,6 +208,7 @@ function Header({
|
|||||||
if (ImEXPay.treatment === "on") {
|
if (ImEXPay.treatment === "on") {
|
||||||
accountingChildren.push({
|
accountingChildren.push({
|
||||||
key: "entercardpayments",
|
key: "entercardpayments",
|
||||||
|
id: "header-accounting-entercardpayments",
|
||||||
icon: <Icon component={FaCreditCard} />,
|
icon: <Icon component={FaCreditCard} />,
|
||||||
label: t("menus.header.entercardpayment"),
|
label: t("menus.header.entercardpayment"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -227,6 +233,7 @@ function Header({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "timetickets",
|
key: "timetickets",
|
||||||
|
id: "header-accounting-timetickets",
|
||||||
icon: <FieldTimeOutlined />,
|
icon: <FieldTimeOutlined />,
|
||||||
label: <Link to="/manage/timetickets">{t("menus.header.timetickets")}</Link>
|
label: <Link to="/manage/timetickets">{t("menus.header.timetickets")}</Link>
|
||||||
}
|
}
|
||||||
@@ -235,6 +242,7 @@ function Header({
|
|||||||
if (bodyshop?.md_tasks_presets?.use_approvals) {
|
if (bodyshop?.md_tasks_presets?.use_approvals) {
|
||||||
accountingChildren.push({
|
accountingChildren.push({
|
||||||
key: "ttapprovals",
|
key: "ttapprovals",
|
||||||
|
id: "header-accounting-ttapprovals",
|
||||||
icon: <FieldTimeOutlined />,
|
icon: <FieldTimeOutlined />,
|
||||||
label: <Link to="/manage/ttapprovals">{t("menus.header.ttapprovals")}</Link>
|
label: <Link to="/manage/ttapprovals">{t("menus.header.ttapprovals")}</Link>
|
||||||
});
|
});
|
||||||
@@ -244,6 +252,7 @@ function Header({
|
|||||||
key: "entertimetickets",
|
key: "entertimetickets",
|
||||||
icon: <Icon component={GiPlayerTime} />,
|
icon: <Icon component={GiPlayerTime} />,
|
||||||
label: t("menus.header.entertimeticket"),
|
label: t("menus.header.entertimeticket"),
|
||||||
|
id: "header-accounting-entertimetickets",
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setTimeTicketContext({
|
setTimeTicketContext({
|
||||||
actions: {},
|
actions: {},
|
||||||
@@ -264,6 +273,7 @@ function Header({
|
|||||||
const accountingExportChildren = [
|
const accountingExportChildren = [
|
||||||
{
|
{
|
||||||
key: "receivables",
|
key: "receivables",
|
||||||
|
id: "header-accounting-receivables",
|
||||||
label: <Link to="/manage/accounting/receivables">{t("menus.header.accounting-receivables")}</Link>
|
label: <Link to="/manage/accounting/receivables">{t("menus.header.accounting-receivables")}</Link>
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -271,6 +281,7 @@ function Header({
|
|||||||
if (!((bodyshop && bodyshop.cdk_dealerid) || (bodyshop && bodyshop.pbs_serialnumber)) || DmsAp.treatment === "on") {
|
if (!((bodyshop && bodyshop.cdk_dealerid) || (bodyshop && bodyshop.pbs_serialnumber)) || DmsAp.treatment === "on") {
|
||||||
accountingExportChildren.push({
|
accountingExportChildren.push({
|
||||||
key: "payables",
|
key: "payables",
|
||||||
|
id: "header-accounting-payables",
|
||||||
label: <Link to="/manage/accounting/payables">{t("menus.header.accounting-payables")}</Link>
|
label: <Link to="/manage/accounting/payables">{t("menus.header.accounting-payables")}</Link>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -278,6 +289,7 @@ function Header({
|
|||||||
if (!((bodyshop && bodyshop.cdk_dealerid) || (bodyshop && bodyshop.pbs_serialnumber))) {
|
if (!((bodyshop && bodyshop.cdk_dealerid) || (bodyshop && bodyshop.pbs_serialnumber))) {
|
||||||
accountingExportChildren.push({
|
accountingExportChildren.push({
|
||||||
key: "payments",
|
key: "payments",
|
||||||
|
id: "header-accounting-payments",
|
||||||
label: <Link to="/manage/accounting/payments">{t("menus.header.accounting-payments")}</Link>
|
label: <Link to="/manage/accounting/payments">{t("menus.header.accounting-payments")}</Link>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -288,6 +300,7 @@ function Header({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "exportlogs",
|
key: "exportlogs",
|
||||||
|
id: "header-accounting-exportlogs",
|
||||||
label: <Link to="/manage/accounting/exportlogs">{t("menus.header.export-logs")}</Link>
|
label: <Link to="/manage/accounting/exportlogs">{t("menus.header.export-logs")}</Link>
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -301,6 +314,7 @@ function Header({
|
|||||||
) {
|
) {
|
||||||
accountingChildren.push({
|
accountingChildren.push({
|
||||||
key: "accountingexport",
|
key: "accountingexport",
|
||||||
|
id: "header-accounting-export",
|
||||||
icon: <ExportOutlined />,
|
icon: <ExportOutlined />,
|
||||||
label: t("menus.header.export"),
|
label: t("menus.header.export"),
|
||||||
children: accountingExportChildren
|
children: accountingExportChildren
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { DownCircleFilled } from "@ant-design/icons";
|
import { DownCircleFilled } from "@ant-design/icons";
|
||||||
import { useApolloClient, useMutation } from "@apollo/client";
|
import { useApolloClient, useMutation } from "@apollo/client";
|
||||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||||
import { Button, Card, Dropdown, Form, Input, Modal, Popconfirm, Popover, Select, Space, notification } from "antd";
|
import { Button, Card, Dropdown, Form, Input, Modal, notification, Popconfirm, Popover, Select, Space } from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import parsePhoneNumber from "libphonenumber-js";
|
import parsePhoneNumber from "libphonenumber-js";
|
||||||
import React, { useMemo, useState } from "react";
|
import React, { useMemo, useState } from "react";
|
||||||
@@ -641,6 +641,7 @@ export function JobsDetailHeaderActions({
|
|||||||
const menuItems = [
|
const menuItems = [
|
||||||
{
|
{
|
||||||
key: "schedule",
|
key: "schedule",
|
||||||
|
id: "job-actions-schedule",
|
||||||
disabled: !jobInPreProduction || !job.converted || jobRO,
|
disabled: !jobInPreProduction || !job.converted || jobRO,
|
||||||
label: t("jobs.actions.schedule"),
|
label: t("jobs.actions.schedule"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -657,6 +658,7 @@ export function JobsDetailHeaderActions({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "cancelallappointments",
|
key: "cancelallappointments",
|
||||||
|
id: "job-actions-cancelallappointments",
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
if (job.status !== bodyshop.md_ro_statuses.default_scheduled) {
|
if (job.status !== bodyshop.md_ro_statuses.default_scheduled) {
|
||||||
return;
|
return;
|
||||||
@@ -670,6 +672,7 @@ export function JobsDetailHeaderActions({
|
|||||||
imex: [
|
imex: [
|
||||||
{
|
{
|
||||||
key: "intake",
|
key: "intake",
|
||||||
|
id: "job-actions-intake",
|
||||||
disabled: !!job.intakechecklist || !jobInPreProduction || !job.converted || jobRO,
|
disabled: !!job.intakechecklist || !jobInPreProduction || !job.converted || jobRO,
|
||||||
label:
|
label:
|
||||||
!!job.intakechecklist || !jobInPreProduction || !job.converted || jobRO ? (
|
!!job.intakechecklist || !jobInPreProduction || !job.converted || jobRO ? (
|
||||||
@@ -680,6 +683,7 @@ export function JobsDetailHeaderActions({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "deliver",
|
key: "deliver",
|
||||||
|
id: "job-actions-deliver",
|
||||||
disabled: !jobInProduction || jobRO,
|
disabled: !jobInProduction || jobRO,
|
||||||
label: !jobInProduction ? (
|
label: !jobInProduction ? (
|
||||||
t("jobs.actions.deliver")
|
t("jobs.actions.deliver")
|
||||||
@@ -689,6 +693,7 @@ export function JobsDetailHeaderActions({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "checklist",
|
key: "checklist",
|
||||||
|
id: "job-actions-checklist",
|
||||||
disabled: !job.converted,
|
disabled: !job.converted,
|
||||||
label: <Link to={`/manage/jobs/${job.id}/checklist`}>{t("jobs.actions.viewchecklist")}</Link>
|
label: <Link to={`/manage/jobs/${job.id}/checklist`}>{t("jobs.actions.viewchecklist")}</Link>
|
||||||
}
|
}
|
||||||
@@ -697,6 +702,7 @@ export function JobsDetailHeaderActions({
|
|||||||
promanager: [
|
promanager: [
|
||||||
{
|
{
|
||||||
key: "toggleproduction",
|
key: "toggleproduction",
|
||||||
|
id: "job-actions-toggleproduction",
|
||||||
disabled: !job.converted || jobRO,
|
disabled: !job.converted || jobRO,
|
||||||
label: <JobsDetailHeaderActionsToggleProduction job={job} refetch={refetch} />
|
label: <JobsDetailHeaderActionsToggleProduction job={job} refetch={refetch} />
|
||||||
}
|
}
|
||||||
@@ -710,6 +716,7 @@ export function JobsDetailHeaderActions({
|
|||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: "entertimetickets",
|
key: "entertimetickets",
|
||||||
|
id: "job-actions-entertimetickets",
|
||||||
disabled: !job.converted || (!bodyshop.tt_allow_post_to_invoiced && job.date_invoiced),
|
disabled: !job.converted || (!bodyshop.tt_allow_post_to_invoiced && job.date_invoiced),
|
||||||
label: t("timetickets.actions.enter"),
|
label: t("timetickets.actions.enter"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -733,6 +740,7 @@ export function JobsDetailHeaderActions({
|
|||||||
if (bodyshop.md_tasks_presets.enable_tasks) {
|
if (bodyshop.md_tasks_presets.enable_tasks) {
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "claimtimetickettasks",
|
key: "claimtimetickettasks",
|
||||||
|
id: "job-actions-claimtimetickettasks",
|
||||||
disabled: !job.converted || (!bodyshop.tt_allow_post_to_invoiced && job.date_invoiced),
|
disabled: !job.converted || (!bodyshop.tt_allow_post_to_invoiced && job.date_invoiced),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setTimeTicketTaskContext({
|
setTimeTicketTaskContext({
|
||||||
@@ -746,6 +754,7 @@ export function JobsDetailHeaderActions({
|
|||||||
|
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "enterpayments",
|
key: "enterpayments",
|
||||||
|
id: "job-actions-enterpayments",
|
||||||
disabled: !job.converted,
|
disabled: !job.converted,
|
||||||
label: t("menus.header.enterpayment"),
|
label: t("menus.header.enterpayment"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -761,6 +770,7 @@ export function JobsDetailHeaderActions({
|
|||||||
if (ImEXPay.treatment === "on") {
|
if (ImEXPay.treatment === "on") {
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "entercardpayments",
|
key: "entercardpayments",
|
||||||
|
id: "job-actions-entercardpayments",
|
||||||
disabled: !job.converted,
|
disabled: !job.converted,
|
||||||
label: t("menus.header.entercardpayment"),
|
label: t("menus.header.entercardpayment"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -777,6 +787,7 @@ export function JobsDetailHeaderActions({
|
|||||||
if (HasFeatureAccess({ featureName: "courtesycars", bodyshop })) {
|
if (HasFeatureAccess({ featureName: "courtesycars", bodyshop })) {
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "cccontract",
|
key: "cccontract",
|
||||||
|
id: "job-actions-cccontract",
|
||||||
disabled: jobRO || !job.converted,
|
disabled: jobRO || !job.converted,
|
||||||
label: (
|
label: (
|
||||||
<Link state={{ jobId: job.id }} to="/manage/courtesycars/contracts/new">
|
<Link state={{ jobId: job.id }} to="/manage/courtesycars/contracts/new">
|
||||||
@@ -788,6 +799,7 @@ export function JobsDetailHeaderActions({
|
|||||||
|
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "createtask",
|
key: "createtask",
|
||||||
|
id: "job-actions-createtask",
|
||||||
label: t("menus.header.create_task"),
|
label: t("menus.header.create_task"),
|
||||||
onClick: () =>
|
onClick: () =>
|
||||||
setTaskUpsertContext({
|
setTaskUpsertContext({
|
||||||
@@ -800,12 +812,14 @@ export function JobsDetailHeaderActions({
|
|||||||
job.inproduction
|
job.inproduction
|
||||||
? {
|
? {
|
||||||
key: "removefromproduction",
|
key: "removefromproduction",
|
||||||
|
id: "job-actions-removefromproduction",
|
||||||
disabled: !job.converted,
|
disabled: !job.converted,
|
||||||
label: t("jobs.actions.removefromproduction"),
|
label: t("jobs.actions.removefromproduction"),
|
||||||
onClick: () => AddToProduction(client, job.id, refetch, true)
|
onClick: () => AddToProduction(client, job.id, refetch, true)
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
key: "addtoproduction",
|
key: "addtoproduction",
|
||||||
|
id: "job-actions-addtoproduction",
|
||||||
disabled: !job.converted,
|
disabled: !job.converted,
|
||||||
label: t("jobs.actions.addtoproduction"),
|
label: t("jobs.actions.addtoproduction"),
|
||||||
onClick: () => AddToProduction(client, job.id, refetch)
|
onClick: () => AddToProduction(client, job.id, refetch)
|
||||||
@@ -815,12 +829,14 @@ export function JobsDetailHeaderActions({
|
|||||||
menuItems.push(
|
menuItems.push(
|
||||||
{
|
{
|
||||||
key: "togglesuspend",
|
key: "togglesuspend",
|
||||||
|
id: "job-actions-togglesuspend",
|
||||||
onClick: handleSuspend,
|
onClick: handleSuspend,
|
||||||
label: job.suspended ? t("production.actions.unsuspend") : t("production.actions.suspend")
|
label: job.suspended ? t("production.actions.unsuspend") : t("production.actions.suspend")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "toggleAlert",
|
key: "toggleAlert",
|
||||||
onClick: handleAlertToggle,
|
onClick: handleAlertToggle,
|
||||||
|
id: "job-actions-togglealert",
|
||||||
label:
|
label:
|
||||||
job.production_vars && job.production_vars.alert
|
job.production_vars && job.production_vars.alert
|
||||||
? t("production.labels.alertoff")
|
? t("production.labels.alertoff")
|
||||||
@@ -832,6 +848,7 @@ export function JobsDetailHeaderActions({
|
|||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
key: "duplicate",
|
key: "duplicate",
|
||||||
|
id: "job-actions-duplicate",
|
||||||
label: (
|
label: (
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title={t("jobs.labels.duplicateconfirm")}
|
title={t("jobs.labels.duplicateconfirm")}
|
||||||
@@ -847,6 +864,7 @@ export function JobsDetailHeaderActions({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "duplicatenolines",
|
key: "duplicatenolines",
|
||||||
|
id: "job-actions-duplicatenolines",
|
||||||
label: (
|
label: (
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title={t("jobs.labels.duplicateconfirm")}
|
title={t("jobs.labels.duplicateconfirm")}
|
||||||
@@ -870,6 +888,7 @@ export function JobsDetailHeaderActions({
|
|||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: "postbills",
|
key: "postbills",
|
||||||
|
id: "job-actions-postbills",
|
||||||
disabled: !job.converted,
|
disabled: !job.converted,
|
||||||
label: t("jobs.actions.postbills"),
|
label: t("jobs.actions.postbills"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -888,6 +907,7 @@ export function JobsDetailHeaderActions({
|
|||||||
|
|
||||||
{
|
{
|
||||||
key: "addtopartsqueue",
|
key: "addtopartsqueue",
|
||||||
|
id: "job-actions-addtopartsqueue",
|
||||||
disabled: !job.converted || !jobInProduction || jobRO,
|
disabled: !job.converted || !jobInProduction || jobRO,
|
||||||
label: t("jobs.actions.addtopartsqueue"),
|
label: t("jobs.actions.addtopartsqueue"),
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
@@ -913,6 +933,7 @@ export function JobsDetailHeaderActions({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "closejob",
|
key: "closejob",
|
||||||
|
id: "job-actions-closejob",
|
||||||
disabled: !jobInPostProduction,
|
disabled: !jobInPostProduction,
|
||||||
label: !jobInPostProduction ? (
|
label: !jobInPostProduction ? (
|
||||||
t("menus.jobsactions.closejob")
|
t("menus.jobsactions.closejob")
|
||||||
@@ -928,6 +949,7 @@ export function JobsDetailHeaderActions({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "admin",
|
key: "admin",
|
||||||
|
id: "job-actions-admin",
|
||||||
label: (
|
label: (
|
||||||
<Link
|
<Link
|
||||||
to={{
|
to={{
|
||||||
@@ -949,6 +971,7 @@ export function JobsDetailHeaderActions({
|
|||||||
) {
|
) {
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "exportcustdata",
|
key: "exportcustdata",
|
||||||
|
id: "job-actions-exportcustdata",
|
||||||
disabled: !job.converted,
|
disabled: !job.converted,
|
||||||
label: t("jobs.actions.exportcustdata"),
|
label: t("jobs.actions.exportcustdata"),
|
||||||
onClick: handleExportCustData
|
onClick: handleExportCustData
|
||||||
@@ -959,18 +982,21 @@ export function JobsDetailHeaderActions({
|
|||||||
const children = [
|
const children = [
|
||||||
{
|
{
|
||||||
key: "email",
|
key: "email",
|
||||||
|
id: "job-actions-email",
|
||||||
disabled: !!!job.ownr_ea,
|
disabled: !!!job.ownr_ea,
|
||||||
label: t("general.labels.email"),
|
label: t("general.labels.email"),
|
||||||
onClick: handleCreateCsi
|
onClick: handleCreateCsi
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "text",
|
key: "text",
|
||||||
|
id: "job-actions-text",
|
||||||
disabled: !!!job.ownr_ph1,
|
disabled: !!!job.ownr_ph1,
|
||||||
label: t("general.labels.text"),
|
label: t("general.labels.text"),
|
||||||
onClick: handleCreateCsi
|
onClick: handleCreateCsi
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "generate",
|
key: "generate",
|
||||||
|
id: "job-actions-generate",
|
||||||
disabled: job.csiinvites && job.csiinvites.length > 0,
|
disabled: job.csiinvites && job.csiinvites.length > 0,
|
||||||
label: t("jobs.actions.generatecsi"),
|
label: t("jobs.actions.generatecsi"),
|
||||||
onClick: handleCreateCsi
|
onClick: handleCreateCsi
|
||||||
@@ -1004,6 +1030,7 @@ export function JobsDetailHeaderActions({
|
|||||||
}
|
}
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "sendcsi",
|
key: "sendcsi",
|
||||||
|
id: "job-actions-sendcsi",
|
||||||
label: t("jobs.actions.sendcsi"),
|
label: t("jobs.actions.sendcsi"),
|
||||||
disabled: !job.converted,
|
disabled: !job.converted,
|
||||||
children
|
children
|
||||||
@@ -1012,6 +1039,7 @@ export function JobsDetailHeaderActions({
|
|||||||
|
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "jobcosting",
|
key: "jobcosting",
|
||||||
|
id: "job-actions-jobcosting",
|
||||||
disabled: !job.converted,
|
disabled: !job.converted,
|
||||||
label: t("jobs.labels.jobcosting"),
|
label: t("jobs.labels.jobcosting"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -1029,6 +1057,7 @@ export function JobsDetailHeaderActions({
|
|||||||
if (job && !job.converted) {
|
if (job && !job.converted) {
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "deletejob",
|
key: "deletejob",
|
||||||
|
id: "job-actions-deletejob",
|
||||||
label: (
|
label: (
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title={t("jobs.labels.deleteconfirm")}
|
title={t("jobs.labels.deleteconfirm")}
|
||||||
@@ -1045,6 +1074,7 @@ export function JobsDetailHeaderActions({
|
|||||||
|
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "manualevent",
|
key: "manualevent",
|
||||||
|
id: "job-actions-manualevent",
|
||||||
onClick: (e) => {
|
onClick: (e) => {
|
||||||
setVisibility(true);
|
setVisibility(true);
|
||||||
},
|
},
|
||||||
@@ -1054,6 +1084,7 @@ export function JobsDetailHeaderActions({
|
|||||||
if (!jobRO && job.converted) {
|
if (!jobRO && job.converted) {
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
key: "voidjob",
|
key: "voidjob",
|
||||||
|
id: "job-actions-voidjob",
|
||||||
label: (
|
label: (
|
||||||
<RbacWrapper action="jobs:void" noauth>
|
<RbacWrapper action="jobs:void" noauth>
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ export function PartsOrderListTableComponent({
|
|||||||
} else {
|
} else {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
const result = await billQuery({
|
const result = await billQuery({
|
||||||
variables: { billid: returnfrombill },
|
variables: { billid: returnfrombill }
|
||||||
});
|
});
|
||||||
setBillData(result.data);
|
setBillData(result.data);
|
||||||
};
|
};
|
||||||
@@ -203,7 +203,7 @@ export function PartsOrderListTableComponent({
|
|||||||
is_credit_memo: record.return,
|
is_credit_memo: record.return,
|
||||||
billlines: record.parts_order_lines.map((pol) => {
|
billlines: record.parts_order_lines.map((pol) => {
|
||||||
return {
|
return {
|
||||||
joblineid: pol.job_line_id,
|
joblineid: pol.job_line_id || "noline",
|
||||||
line_desc: pol.line_desc,
|
line_desc: pol.line_desc,
|
||||||
quantity: pol.quantity,
|
quantity: pol.quantity,
|
||||||
|
|
||||||
|
|||||||
@@ -291,6 +291,7 @@ export function JobsDetailPage({
|
|||||||
{
|
{
|
||||||
key: "general",
|
key: "general",
|
||||||
icon: <Icon component={FaShieldAlt} />,
|
icon: <Icon component={FaShieldAlt} />,
|
||||||
|
id: "job-details-general",
|
||||||
label: t("menus.jobsdetail.general"),
|
label: t("menus.jobsdetail.general"),
|
||||||
forceRender: true,
|
forceRender: true,
|
||||||
children: <JobsDetailGeneral job={job} form={form} />
|
children: <JobsDetailGeneral job={job} form={form} />
|
||||||
@@ -298,6 +299,7 @@ export function JobsDetailPage({
|
|||||||
{
|
{
|
||||||
key: "repairdata",
|
key: "repairdata",
|
||||||
icon: <BarsOutlined />,
|
icon: <BarsOutlined />,
|
||||||
|
id: "job-details-repairdata",
|
||||||
label: t("menus.jobsdetail.repairdata"),
|
label: t("menus.jobsdetail.repairdata"),
|
||||||
forceRender: true,
|
forceRender: true,
|
||||||
children: <JobsLinesContainer job={job} joblines={job.joblines} refetch={refetch} form={form} />
|
children: <JobsLinesContainer job={job} joblines={job.joblines} refetch={refetch} form={form} />
|
||||||
@@ -305,18 +307,21 @@ export function JobsDetailPage({
|
|||||||
{
|
{
|
||||||
key: "rates",
|
key: "rates",
|
||||||
icon: <DollarCircleOutlined />,
|
icon: <DollarCircleOutlined />,
|
||||||
|
id: "job-details-rates",
|
||||||
label: t("menus.jobsdetail.rates"),
|
label: t("menus.jobsdetail.rates"),
|
||||||
forceRender: true,
|
forceRender: true,
|
||||||
children: <JobsDetailRates job={job} form={form} />
|
children: <JobsDetailRates job={job} form={form} />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "totals",
|
key: "totals",
|
||||||
|
id: "job-details-totals",
|
||||||
icon: <DollarCircleOutlined />,
|
icon: <DollarCircleOutlined />,
|
||||||
label: t("menus.jobsdetail.totals"),
|
label: t("menus.jobsdetail.totals"),
|
||||||
children: <JobsDetailTotals job={job} refetch={refetch} />
|
children: <JobsDetailTotals job={job} refetch={refetch} />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "partssublet",
|
key: "partssublet",
|
||||||
|
id: "job-details-partssublet",
|
||||||
icon: <ToolFilled />,
|
icon: <ToolFilled />,
|
||||||
label: HasFeatureAccess({ featureName: "bills", bodyshop })
|
label: HasFeatureAccess({ featureName: "bills", bodyshop })
|
||||||
? t("menus.jobsdetail.partssublet")
|
? t("menus.jobsdetail.partssublet")
|
||||||
@@ -331,6 +336,7 @@ export function JobsDetailPage({
|
|||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: "labor",
|
key: "labor",
|
||||||
|
id: "job-details-labor",
|
||||||
icon: <Icon component={FaHardHat} />,
|
icon: <Icon component={FaHardHat} />,
|
||||||
label: t("menus.jobsdetail.labor"),
|
label: t("menus.jobsdetail.labor"),
|
||||||
children: <JobsDetailLaborContainer job={job} jobId={job.id} />
|
children: <JobsDetailLaborContainer job={job} jobId={job.id} />
|
||||||
@@ -340,11 +346,13 @@ export function JobsDetailPage({
|
|||||||
{
|
{
|
||||||
key: "lifecycle",
|
key: "lifecycle",
|
||||||
icon: <BarsOutlined />,
|
icon: <BarsOutlined />,
|
||||||
|
id: "job-details-lifecycle",
|
||||||
label: t("menus.jobsdetail.lifecycle"),
|
label: t("menus.jobsdetail.lifecycle"),
|
||||||
children: <JobLifecycleComponent job={job} statuses={bodyshop.md_ro_statuses} />
|
children: <JobLifecycleComponent job={job} statuses={bodyshop.md_ro_statuses} />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "dates",
|
key: "dates",
|
||||||
|
id: "job-details-dates",
|
||||||
icon: <CalendarFilled />,
|
icon: <CalendarFilled />,
|
||||||
label: t("menus.jobsdetail.dates"),
|
label: t("menus.jobsdetail.dates"),
|
||||||
forceRender: true,
|
forceRender: true,
|
||||||
@@ -358,6 +366,7 @@ export function JobsDetailPage({
|
|||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: "documents",
|
key: "documents",
|
||||||
|
id: "job-details-documents",
|
||||||
icon: <FileImageFilled />,
|
icon: <FileImageFilled />,
|
||||||
label: t("jobs.labels.documents"),
|
label: t("jobs.labels.documents"),
|
||||||
children: bodyshop.uselocalmediaserver ? (
|
children: bodyshop.uselocalmediaserver ? (
|
||||||
@@ -370,6 +379,7 @@ export function JobsDetailPage({
|
|||||||
: []),
|
: []),
|
||||||
{
|
{
|
||||||
key: "notes",
|
key: "notes",
|
||||||
|
id: "job-details-notes",
|
||||||
icon: <Icon component={FaRegStickyNote} />,
|
icon: <Icon component={FaRegStickyNote} />,
|
||||||
label: t("jobs.labels.notes"),
|
label: t("jobs.labels.notes"),
|
||||||
children: <JobNotesContainer jobId={job.id} />
|
children: <JobNotesContainer jobId={job.id} />
|
||||||
@@ -377,12 +387,14 @@ export function JobsDetailPage({
|
|||||||
{
|
{
|
||||||
key: "audit",
|
key: "audit",
|
||||||
icon: <HistoryOutlined />,
|
icon: <HistoryOutlined />,
|
||||||
|
id: "job-details-audit",
|
||||||
label: t("jobs.labels.audit"),
|
label: t("jobs.labels.audit"),
|
||||||
children: <JobAuditTrail jobId={job.id} />
|
children: <JobAuditTrail jobId={job.id} />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "tasks",
|
key: "tasks",
|
||||||
icon: <FaTasks />,
|
icon: <FaTasks />,
|
||||||
|
id: "job-details-tasks",
|
||||||
label: (
|
label: (
|
||||||
<Space direction="horizontal">
|
<Space direction="horizontal">
|
||||||
{t("jobs.labels.tasks")}
|
{t("jobs.labels.tasks")}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export default async function FcmHandler({ client, payload }) {
|
export default async function FcmHandler({ client, payload }) {
|
||||||
|
console.log("FCM", payload);
|
||||||
switch (payload.type) {
|
switch (payload.type) {
|
||||||
case "messaging-inbound":
|
case "messaging-inbound":
|
||||||
client.cache.modify({
|
client.cache.modify({
|
||||||
|
|||||||
@@ -174,10 +174,7 @@ async function OpenSearchUpdateHandler(req, res) {
|
|||||||
const bulkOperation = [];
|
const bulkOperation = [];
|
||||||
slicedArray.forEach((bill) => {
|
slicedArray.forEach((bill) => {
|
||||||
bulkOperation.push({ index: { _index: "bills", _id: bill.id } });
|
bulkOperation.push({ index: { _index: "bills", _id: bill.id } });
|
||||||
bulkOperation.push({
|
bulkOperation.push({ ...bill, bodyshopid: bill.job.bodyshopid });
|
||||||
...omit(bill, ["job"]),
|
|
||||||
bodyshopid: bill.job.bodyshopid
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
promiseQueue.push(bulkOperation);
|
promiseQueue.push(bulkOperation);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
"admin": "cd admin && npm start",
|
"admin": "cd admin && npm start",
|
||||||
"client": "cd client && npm start",
|
"client": "cd client && npm start",
|
||||||
"server": "nodemon server.js",
|
"server": "nodemon server.js",
|
||||||
|
"server:imex": "nodemon server.js imex",
|
||||||
|
"server:rome": "nodemon server.js rome",
|
||||||
|
"server:promanager": "nodemon server.js promanager",
|
||||||
"build": "cd client && npm run build",
|
"build": "cd client && npm run build",
|
||||||
"dev": "concurrently --kill-others-on-fail \"npm run server\" \"npm run client\"",
|
"dev": "concurrently --kill-others-on-fail \"npm run server\" \"npm run client\"",
|
||||||
"deva": "concurrently --kill-others-on-fail \"npm run server\" \"npm run client\" \"npm run admin\"",
|
"deva": "concurrently --kill-others-on-fail \"npm run server\" \"npm run client\" \"npm run admin\"",
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ const cookieParser = require("cookie-parser");
|
|||||||
const http = require("http");
|
const http = require("http");
|
||||||
const { Server } = require("socket.io");
|
const { Server } = require("socket.io");
|
||||||
|
|
||||||
|
const instanceName = process.argv[2];
|
||||||
|
|
||||||
// Load environment variables
|
// Load environment variables
|
||||||
require("dotenv").config({
|
require("dotenv").config({
|
||||||
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
|
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}${instanceName ? `.${instanceName}` : ''}`)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Import custom utilities and handlers
|
// Import custom utilities and handlers
|
||||||
|
|||||||
@@ -71,16 +71,7 @@ exports.default = function ({ bodyshop, jobs_by_pk, qbo = false, items, taxCodes
|
|||||||
{
|
{
|
||||||
local: false,
|
local: false,
|
||||||
federal: InstanceManager({ imex: true, rome: false }),
|
federal: InstanceManager({ imex: true, rome: false }),
|
||||||
state:
|
state: checkStateTax(jobline, jobs_by_pk)
|
||||||
jobs_by_pk.state_tax_rate === 0
|
|
||||||
? false
|
|
||||||
: jobline.db_ref === "900511" ||
|
|
||||||
jobline.db_ref === "900510" ||
|
|
||||||
(jobline.mod_lb_hrs === 0 && //Extending IO-1375 as a part of IO-2023
|
|
||||||
jobline.act_price > 0 &&
|
|
||||||
jobline.lbr_op === "OP14")
|
|
||||||
? true
|
|
||||||
: jobline.tax_part
|
|
||||||
},
|
},
|
||||||
bodyshop.md_responsibility_centers.sales_tax_codes
|
bodyshop.md_responsibility_centers.sales_tax_codes
|
||||||
);
|
);
|
||||||
@@ -156,7 +147,7 @@ exports.default = function ({ bodyshop, jobs_by_pk, qbo = false, items, taxCodes
|
|||||||
{
|
{
|
||||||
local: false,
|
local: false,
|
||||||
federal: InstanceManager({ imex: true, rome: false }),
|
federal: InstanceManager({ imex: true, rome: false }),
|
||||||
state: jobs_by_pk.state_tax_rate === 0 ? false : true
|
state: jobs_by_pk.tax_lbr_rt === 0 ? false : true
|
||||||
},
|
},
|
||||||
bodyshop.md_responsibility_centers.sales_tax_codes
|
bodyshop.md_responsibility_centers.sales_tax_codes
|
||||||
);
|
);
|
||||||
@@ -224,7 +215,7 @@ exports.default = function ({ bodyshop, jobs_by_pk, qbo = false, items, taxCodes
|
|||||||
{
|
{
|
||||||
local: false,
|
local: false,
|
||||||
federal: InstanceManager({ imex: true, rome: false }),
|
federal: InstanceManager({ imex: true, rome: false }),
|
||||||
state: jobs_by_pk.state_tax_rate === 0 ? false : true
|
state: jobs_by_pk.tax_paint_mat_rt === 0 ? false : true
|
||||||
},
|
},
|
||||||
bodyshop.md_responsibility_centers.sales_tax_codes
|
bodyshop.md_responsibility_centers.sales_tax_codes
|
||||||
);
|
);
|
||||||
@@ -293,7 +284,7 @@ exports.default = function ({ bodyshop, jobs_by_pk, qbo = false, items, taxCodes
|
|||||||
{
|
{
|
||||||
local: false,
|
local: false,
|
||||||
federal: InstanceManager({ imex: true, rome: false }),
|
federal: InstanceManager({ imex: true, rome: false }),
|
||||||
state: jobs_by_pk.state_tax_rate === 0 ? false : true
|
state: jobs_by_pk.tax_shop_mat_rt === 0 ? false : true
|
||||||
},
|
},
|
||||||
bodyshop.md_responsibility_centers.sales_tax_codes
|
bodyshop.md_responsibility_centers.sales_tax_codes
|
||||||
);
|
);
|
||||||
@@ -379,7 +370,7 @@ exports.default = function ({ bodyshop, jobs_by_pk, qbo = false, items, taxCodes
|
|||||||
{
|
{
|
||||||
local: false,
|
local: false,
|
||||||
federal: InstanceManager({ imex: true, rome: false }),
|
federal: InstanceManager({ imex: true, rome: false }),
|
||||||
state: jobs_by_pk.state_tax_rate === 0 ? false : true
|
state: jobs_by_pk.tax_tow_rt === 0 ? false : true
|
||||||
},
|
},
|
||||||
bodyshop.md_responsibility_centers.sales_tax_codes
|
bodyshop.md_responsibility_centers.sales_tax_codes
|
||||||
);
|
);
|
||||||
@@ -439,7 +430,7 @@ exports.default = function ({ bodyshop, jobs_by_pk, qbo = false, items, taxCodes
|
|||||||
{
|
{
|
||||||
local: false,
|
local: false,
|
||||||
federal: InstanceManager({ imex: true, rome: false }),
|
federal: InstanceManager({ imex: true, rome: false }),
|
||||||
state: jobs_by_pk.state_tax_rate === 0 ? false : true
|
state: jobs_by_pk.tax_str_rt === 0 ? false : true
|
||||||
},
|
},
|
||||||
bodyshop.md_responsibility_centers.sales_tax_codes
|
bodyshop.md_responsibility_centers.sales_tax_codes
|
||||||
);
|
);
|
||||||
@@ -499,7 +490,7 @@ exports.default = function ({ bodyshop, jobs_by_pk, qbo = false, items, taxCodes
|
|||||||
{
|
{
|
||||||
local: false,
|
local: false,
|
||||||
federal: InstanceManager({ imex: true, rome: false }),
|
federal: InstanceManager({ imex: true, rome: false }),
|
||||||
state: jobs_by_pk.state_tax_rate === 0 ? false : true
|
state: jobs_by_pk.tax_lbr_rt === 0 ? false : true
|
||||||
},
|
},
|
||||||
bodyshop.md_responsibility_centers.sales_tax_codes
|
bodyshop.md_responsibility_centers.sales_tax_codes
|
||||||
);
|
);
|
||||||
@@ -879,6 +870,66 @@ exports.createMultiQbPayerLines = function ({ bodyshop, jobs_by_pk, qbo = false,
|
|||||||
return InvoiceLineAdd;
|
return InvoiceLineAdd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function checkStateTax(jobline, jobs_by_pk) {
|
||||||
|
const isPaintOrShopMat = jobline.db_ref === "936008" || jobline.db_ref === "936007";
|
||||||
|
|
||||||
|
if (isPaintOrShopMat) {
|
||||||
|
if (jobline.db_ref === "936008") {
|
||||||
|
if (jobs_by_pk.tax_paint_mat_rt === 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (jobline.db_ref === "936007") {
|
||||||
|
if (jobs_by_pk.tax_shop_mat_rt === 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isAdditionalCost =
|
||||||
|
(jobline.lbr_op === "OP13" || (jobline.db_ref && jobline.db_ref.startsWith("9360"))) && !isPaintOrShopMat;
|
||||||
|
|
||||||
|
if (!jobline.part_type && isAdditionalCost) {
|
||||||
|
if (jobs_by_pk.tax_lbr_rt === 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
jobline.db_ref === "900511" ||
|
||||||
|
jobline.db_ref === "900510" ||
|
||||||
|
(jobline.mod_lb_hrs === 0 && jobline.act_price > 0 && jobline.lbr_op === "OP14")
|
||||||
|
)
|
||||||
|
return true; //Extending IO-1375 as a part of IO-2023
|
||||||
|
|
||||||
|
if (jobline.tax_part === false) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (jobline.part_type) {
|
||||||
|
if (
|
||||||
|
jobs_by_pk.parts_tax_rates[`${jobline.part_type.toUpperCase()}`].prt_tax_in === false ||
|
||||||
|
jobs_by_pk.parts_tax_rates[`${jobline.part_type.toUpperCase()}`].prt_tax_rt === 0
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (jobs_by_pk.tax_lbr_rt === 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function CheckQBOUSATaxID({ jobline, job, type }) {
|
function CheckQBOUSATaxID({ jobline, job, type }) {
|
||||||
//Replacing this to be all non-taxable items with the refactor of parts tax rates.
|
//Replacing this to be all non-taxable items with the refactor of parts tax rates.
|
||||||
return "NON";
|
return "NON";
|
||||||
|
|||||||
@@ -206,8 +206,13 @@ query QUERY_JOBS_FOR_RECEIVABLES_EXPORT($ids: [uuid!]!) {
|
|||||||
adjustment_bottom_line
|
adjustment_bottom_line
|
||||||
state_tax_rate
|
state_tax_rate
|
||||||
qb_multiple_payers
|
qb_multiple_payers
|
||||||
|
parts_tax_rates
|
||||||
tax_paint_mat_rt
|
tax_paint_mat_rt
|
||||||
tax_lbr_rt
|
tax_lbr_rt
|
||||||
|
tax_shop_mat_rt
|
||||||
|
tax_sub_rt
|
||||||
|
tax_tow_rt
|
||||||
|
tax_str_rt
|
||||||
owner {
|
owner {
|
||||||
accountingid
|
accountingid
|
||||||
}
|
}
|
||||||
@@ -1534,6 +1539,7 @@ exports.QUERY_JOB_COSTING_DETAILS = ` query QUERY_JOB_COSTING_DETAILS($id: uuid!
|
|||||||
op_code_desc
|
op_code_desc
|
||||||
profitcenter_part
|
profitcenter_part
|
||||||
profitcenter_labor
|
profitcenter_labor
|
||||||
|
act_price_before_ppc
|
||||||
}
|
}
|
||||||
bills {
|
bills {
|
||||||
id
|
id
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const qs = require("query-string");
|
|||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
const moment = require("moment");
|
const moment = require("moment");
|
||||||
const logger = require("../utils/logger");
|
const logger = require("../utils/logger");
|
||||||
|
const InstanceManager = require("../utils/instanceMgr").default;
|
||||||
|
|
||||||
require("dotenv").config({
|
require("dotenv").config({
|
||||||
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
|
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
|
||||||
@@ -16,7 +17,10 @@ const domain = process.env.NODE_ENV ? "secure" : "test";
|
|||||||
const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager");
|
const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager");
|
||||||
|
|
||||||
const client = new SecretsManagerClient({
|
const client = new SecretsManagerClient({
|
||||||
region: "ca-central-1" //TODO-AIO: instance manager required when merged to master-AIO
|
region: InstanceManager({
|
||||||
|
imex: "ca-central-1",
|
||||||
|
rome: "us-east-2"
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
const gqlClient = require("../graphql-client/graphql-client").client;
|
const gqlClient = require("../graphql-client/graphql-client").client;
|
||||||
@@ -145,19 +149,19 @@ exports.generate_payment_url = async (req, res) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
exports.postback = async (req, res) => {
|
exports.postback = async (req, res) => {
|
||||||
logger.log("intellipay-postback", "DEBUG", req.user?.email, null, req.body);
|
|
||||||
const { body: values } = req;
|
|
||||||
|
|
||||||
const comment = Buffer.from(values?.comment, "base64").toString();
|
|
||||||
|
|
||||||
if ((!values.invoice || values.invoice === "") && !comment) {
|
|
||||||
//invoice is specified through the pay link. Comment by IO.
|
|
||||||
logger.log("intellipay-postback-ignored", "DEBUG", req.user?.email, null, req.body);
|
|
||||||
res.sendStatus(200);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
logger.log("intellipay-postback", "DEBUG", req.user?.email, null, req.body);
|
||||||
|
const { body: values } = req;
|
||||||
|
|
||||||
|
const comment = Buffer.from(values?.comment, "base64").toString();
|
||||||
|
|
||||||
|
if ((!values.invoice || values.invoice === "") && !comment) {
|
||||||
|
//invoice is specified through the pay link. Comment by IO.
|
||||||
|
logger.log("intellipay-postback-ignored", "DEBUG", req.user?.email, null, req.body);
|
||||||
|
res.sendStatus(200);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (values.invoice) {
|
if (values.invoice) {
|
||||||
//This is a link email that's been sent out.
|
//This is a link email that's been sent out.
|
||||||
const job = await gqlClient.request(queries.GET_JOB_BY_PK, {
|
const job = await gqlClient.request(queries.GET_JOB_BY_PK, {
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ function GenerateCostingData(job) {
|
|||||||
job &&
|
job &&
|
||||||
job.joblines.reduce(
|
job.joblines.reduce(
|
||||||
(acc, val) => {
|
(acc, val) => {
|
||||||
//Parts Lines
|
//Shop or Paint Material Flags
|
||||||
if (val.db_ref === "936008") {
|
if (val.db_ref === "936008") {
|
||||||
//If either of these DB REFs change, they also need to change in job-totals/job-costing calculations.
|
//If either of these DB REFs change, they also need to change in job-totals/job-costing calculations.
|
||||||
hasMapaLine = true;
|
hasMapaLine = true;
|
||||||
@@ -277,6 +277,8 @@ function GenerateCostingData(job) {
|
|||||||
if (val.db_ref === "936007") {
|
if (val.db_ref === "936007") {
|
||||||
hasMashLine = true;
|
hasMashLine = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Labor Profit Center
|
||||||
if (val.mod_lbr_ty) {
|
if (val.mod_lbr_ty) {
|
||||||
const laborProfitCenter = val.profitcenter_labor || defaultProfits[val.mod_lbr_ty] || "Unknown";
|
const laborProfitCenter = val.profitcenter_labor || defaultProfits[val.mod_lbr_ty] || "Unknown";
|
||||||
|
|
||||||
@@ -307,6 +309,7 @@ function GenerateCostingData(job) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Part Profit Center
|
||||||
if (val.part_type && val.part_type !== "PAE" && val.part_type !== "PAS" && val.part_type !== "PASL") {
|
if (val.part_type && val.part_type !== "PAE" && val.part_type !== "PAS" && val.part_type !== "PASL") {
|
||||||
const partsProfitCenter = val.profitcenter_part || defaultProfits[val.part_type] || "Unknown";
|
const partsProfitCenter = val.profitcenter_part || defaultProfits[val.part_type] || "Unknown";
|
||||||
|
|
||||||
@@ -315,7 +318,7 @@ function GenerateCostingData(job) {
|
|||||||
if (!partsProfitCenter)
|
if (!partsProfitCenter)
|
||||||
console.log("Unknown cost/profit center mapping for parts.", val.line_desc, val.part_type);
|
console.log("Unknown cost/profit center mapping for parts.", val.line_desc, val.part_type);
|
||||||
const partsAmount = Dinero({
|
const partsAmount = Dinero({
|
||||||
amount: Math.round((val.act_price || 0) * 100)
|
amount: val.act_price_before_ppc ? Math.round(val.act_price_before_ppc * 100) : Math.round(val.act_price * 100)
|
||||||
})
|
})
|
||||||
.multiply(val.part_qty || 1)
|
.multiply(val.part_qty || 1)
|
||||||
.add(
|
.add(
|
||||||
@@ -324,7 +327,7 @@ function GenerateCostingData(job) {
|
|||||||
? val.prt_dsmk_m
|
? val.prt_dsmk_m
|
||||||
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
|
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
|
||||||
: Dinero({
|
: Dinero({
|
||||||
amount: Math.round(val.act_price * 100)
|
amount: val.act_price_before_ppc ? Math.round(val.act_price_before_ppc * 100) : Math.round(val.act_price * 100)
|
||||||
})
|
})
|
||||||
.multiply(val.part_qty || 0)
|
.multiply(val.part_qty || 0)
|
||||||
.percentage(Math.abs(val.prt_dsmk_p || 0))
|
.percentage(Math.abs(val.prt_dsmk_p || 0))
|
||||||
@@ -334,6 +337,8 @@ function GenerateCostingData(job) {
|
|||||||
if (!acc.parts[partsProfitCenter]) acc.parts[partsProfitCenter] = Dinero();
|
if (!acc.parts[partsProfitCenter]) acc.parts[partsProfitCenter] = Dinero();
|
||||||
acc.parts[partsProfitCenter] = acc.parts[partsProfitCenter].add(partsAmount);
|
acc.parts[partsProfitCenter] = acc.parts[partsProfitCenter].add(partsAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Sublet Profit Center
|
||||||
if (val.part_type && val.part_type !== "PAE" && (val.part_type === "PAS" || val.part_type === "PASL")) {
|
if (val.part_type && val.part_type !== "PAE" && (val.part_type === "PAS" || val.part_type === "PASL")) {
|
||||||
const partsProfitCenter = val.profitcenter_part || defaultProfits[val.part_type] || "Unknown";
|
const partsProfitCenter = val.profitcenter_part || defaultProfits[val.part_type] || "Unknown";
|
||||||
|
|
||||||
@@ -362,8 +367,8 @@ function GenerateCostingData(job) {
|
|||||||
acc.sublet[partsProfitCenter] = acc.sublet[partsProfitCenter].add(partsAmount);
|
acc.sublet[partsProfitCenter] = acc.sublet[partsProfitCenter].add(partsAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
//To deal with additional costs.
|
//Additional Profit Center
|
||||||
if (!val.part_type && !val.mod_lbr_ty) {
|
if ((!val.part_type && !val.mod_lbr_ty) || (!val.part_type && val.mod_lbr_ty)) {
|
||||||
//Does it already have a defined profit center?
|
//Does it already have a defined profit center?
|
||||||
//If so, use it, otherwise try to use the same from the auto-allocate logic in IO app jobs-close-auto-allocate.
|
//If so, use it, otherwise try to use the same from the auto-allocate logic in IO app jobs-close-auto-allocate.
|
||||||
const partsProfitCenter = val.profitcenter_part || getAdditionalCostCenter(val, defaultProfits) || "Unknown";
|
const partsProfitCenter = val.profitcenter_part || getAdditionalCostCenter(val, defaultProfits) || "Unknown";
|
||||||
|
|||||||
Reference in New Issue
Block a user