Compare commits

..

3 Commits

Author SHA1 Message Date
Allan Carr
d7ddbf7e8d IO-2793 Change Additional Costs tax item
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-06-20 14:15:10 -07:00
Allan Carr
ace16ba873 IO-2793 Adjustment for parts
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-06-20 13:46:54 -07:00
Allan Carr
4940b10910 IO-2793 Adjustmnet for OP14
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
2024-06-20 08:30:58 -07:00
13 changed files with 56 additions and 123 deletions

View File

@@ -1,8 +1,7 @@
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_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":"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_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_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/io-test
VITE_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/io-test
VITE_APP_CLOUDINARY_API_KEY=957865933348715

View File

@@ -1,8 +1,7 @@
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_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":"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_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_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/io-test
VITE_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/io-test
VITE_APP_CLOUDINARY_API_KEY=957865933348715

View File

@@ -25,27 +25,31 @@ const BillLineSearchSelect = ({ options, disabled, allowRemoved, ...restProps },
);
}}
notFoundContent={"Removed."}
options={[
{ value: "noline", label: t("billlines.labels.other"), name: t("billlines.labels.other") },
...options.map((item) => ({
disabled: allowRemoved ? false : item.removed,
key: item.id,
value: item.id,
cost: item.act_price ? item.act_price : 0,
part_type: item.part_type,
line_desc: item.line_desc,
part_qty: item.part_qty,
oem_partno: item.oem_partno,
alt_partno: item.alt_partno,
act_price: item.act_price,
style: {
...(item.removed ? { textDecoration: "line-through" } : {})
},
name: `${item.removed ? `(REMOVED) ` : ""}${item.line_desc}${
item.oem_partno ? ` - ${item.oem_partno}` : ""
}${item.alt_partno ? ` (${item.alt_partno})` : ""}`.trim(),
label: (
<>
{...restProps}
>
<Select.Option key={null} value={"noline"} cost={0} line_desc={""}>
{t("billlines.labels.other")}
</Select.Option>
{options
? options.map((item) => (
<Option
disabled={allowRemoved ? false : item.removed}
key={item.id}
value={item.id}
cost={item.act_price ? item.act_price : 0}
part_type={item.part_type}
line_desc={item.line_desc}
part_qty={item.part_qty}
oem_partno={item.oem_partno}
alt_partno={item.alt_partno}
act_price={item.act_price}
style={{
...(item.removed ? { textDecoration: "line-through" } : {})
}}
name={`${item.removed ? `(REMOVED) ` : ""}${item.line_desc}${
item.oem_partno ? ` - ${item.oem_partno}` : ""
}${item.alt_partno ? ` (${item.alt_partno})` : ""}`.trim()}
>
<span>
{`${item.removed ? `(REMOVED) ` : ""}${item.line_desc}${
item.oem_partno ? ` - ${item.oem_partno}` : ""
@@ -56,15 +60,14 @@ 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.act_price ? `$${item.act_price && item.act_price.toFixed(2)}` : ``}
</span>
</>
)
}))
]}
{...restProps}
></Select>
</Option>
))
: null}
</Select>
);
};
export default forwardRef(BillLineSearchSelect);

View File

@@ -141,13 +141,11 @@ function Header({
accountingChildren.push(
{
key: "bills",
id: "header-accounting-bills",
icon: <Icon component={FaFileInvoiceDollar} />,
label: <Link to="/manage/bills">{t("menus.header.bills")}</Link>
},
{
key: "enterbills",
id: "header-accounting-enterbills",
icon: <Icon component={GiPayMoney} />,
label: t("menus.header.enterbills"),
onClick: () => {
@@ -167,7 +165,6 @@ function Header({
},
{
key: "inventory",
id: "header-accounting-inventory",
icon: <Icon component={FaFileInvoiceDollar} />,
label: <Link to="/manage/inventory">{t("menus.header.inventory")}</Link>
}
@@ -186,13 +183,11 @@ function Header({
},
{
key: "allpayments",
id: "header-accounting-allpayments",
icon: <BankFilled />,
label: <Link to="/manage/payments">{t("menus.header.allpayments")}</Link>
},
{
key: "enterpayments",
id: "header-accounting-enterpayments",
icon: <Icon component={FaCreditCard} />,
label: t("menus.header.enterpayment"),
onClick: () => {
@@ -208,7 +203,6 @@ function Header({
if (ImEXPay.treatment === "on") {
accountingChildren.push({
key: "entercardpayments",
id: "header-accounting-entercardpayments",
icon: <Icon component={FaCreditCard} />,
label: t("menus.header.entercardpayment"),
onClick: () => {
@@ -233,7 +227,6 @@ function Header({
},
{
key: "timetickets",
id: "header-accounting-timetickets",
icon: <FieldTimeOutlined />,
label: <Link to="/manage/timetickets">{t("menus.header.timetickets")}</Link>
}
@@ -242,7 +235,6 @@ function Header({
if (bodyshop?.md_tasks_presets?.use_approvals) {
accountingChildren.push({
key: "ttapprovals",
id: "header-accounting-ttapprovals",
icon: <FieldTimeOutlined />,
label: <Link to="/manage/ttapprovals">{t("menus.header.ttapprovals")}</Link>
});
@@ -252,7 +244,6 @@ function Header({
key: "entertimetickets",
icon: <Icon component={GiPlayerTime} />,
label: t("menus.header.entertimeticket"),
id: "header-accounting-entertimetickets",
onClick: () => {
setTimeTicketContext({
actions: {},
@@ -273,7 +264,6 @@ function Header({
const accountingExportChildren = [
{
key: "receivables",
id: "header-accounting-receivables",
label: <Link to="/manage/accounting/receivables">{t("menus.header.accounting-receivables")}</Link>
}
];
@@ -281,7 +271,6 @@ function Header({
if (!((bodyshop && bodyshop.cdk_dealerid) || (bodyshop && bodyshop.pbs_serialnumber)) || DmsAp.treatment === "on") {
accountingExportChildren.push({
key: "payables",
id: "header-accounting-payables",
label: <Link to="/manage/accounting/payables">{t("menus.header.accounting-payables")}</Link>
});
}
@@ -289,7 +278,6 @@ function Header({
if (!((bodyshop && bodyshop.cdk_dealerid) || (bodyshop && bodyshop.pbs_serialnumber))) {
accountingExportChildren.push({
key: "payments",
id: "header-accounting-payments",
label: <Link to="/manage/accounting/payments">{t("menus.header.accounting-payments")}</Link>
});
}
@@ -300,7 +288,6 @@ function Header({
},
{
key: "exportlogs",
id: "header-accounting-exportlogs",
label: <Link to="/manage/accounting/exportlogs">{t("menus.header.export-logs")}</Link>
}
);
@@ -314,7 +301,6 @@ function Header({
) {
accountingChildren.push({
key: "accountingexport",
id: "header-accounting-export",
icon: <ExportOutlined />,
label: t("menus.header.export"),
children: accountingExportChildren

View File

@@ -1,7 +1,7 @@
import { DownCircleFilled } from "@ant-design/icons";
import { useApolloClient, useMutation } from "@apollo/client";
import { useSplitTreatments } from "@splitsoftware/splitio-react";
import { Button, Card, Dropdown, Form, Input, Modal, notification, Popconfirm, Popover, Select, Space } from "antd";
import { Button, Card, Dropdown, Form, Input, Modal, Popconfirm, Popover, Select, Space, notification } from "antd";
import axios from "axios";
import parsePhoneNumber from "libphonenumber-js";
import React, { useMemo, useState } from "react";
@@ -641,7 +641,6 @@ export function JobsDetailHeaderActions({
const menuItems = [
{
key: "schedule",
id: "job-actions-schedule",
disabled: !jobInPreProduction || !job.converted || jobRO,
label: t("jobs.actions.schedule"),
onClick: () => {
@@ -658,7 +657,6 @@ export function JobsDetailHeaderActions({
},
{
key: "cancelallappointments",
id: "job-actions-cancelallappointments",
onClick: () => {
if (job.status !== bodyshop.md_ro_statuses.default_scheduled) {
return;
@@ -672,7 +670,6 @@ export function JobsDetailHeaderActions({
imex: [
{
key: "intake",
id: "job-actions-intake",
disabled: !!job.intakechecklist || !jobInPreProduction || !job.converted || jobRO,
label:
!!job.intakechecklist || !jobInPreProduction || !job.converted || jobRO ? (
@@ -683,7 +680,6 @@ export function JobsDetailHeaderActions({
},
{
key: "deliver",
id: "job-actions-deliver",
disabled: !jobInProduction || jobRO,
label: !jobInProduction ? (
t("jobs.actions.deliver")
@@ -693,7 +689,6 @@ export function JobsDetailHeaderActions({
},
{
key: "checklist",
id: "job-actions-checklist",
disabled: !job.converted,
label: <Link to={`/manage/jobs/${job.id}/checklist`}>{t("jobs.actions.viewchecklist")}</Link>
}
@@ -702,7 +697,6 @@ export function JobsDetailHeaderActions({
promanager: [
{
key: "toggleproduction",
id: "job-actions-toggleproduction",
disabled: !job.converted || jobRO,
label: <JobsDetailHeaderActionsToggleProduction job={job} refetch={refetch} />
}
@@ -716,7 +710,6 @@ export function JobsDetailHeaderActions({
? [
{
key: "entertimetickets",
id: "job-actions-entertimetickets",
disabled: !job.converted || (!bodyshop.tt_allow_post_to_invoiced && job.date_invoiced),
label: t("timetickets.actions.enter"),
onClick: () => {
@@ -740,7 +733,6 @@ export function JobsDetailHeaderActions({
if (bodyshop.md_tasks_presets.enable_tasks) {
menuItems.push({
key: "claimtimetickettasks",
id: "job-actions-claimtimetickettasks",
disabled: !job.converted || (!bodyshop.tt_allow_post_to_invoiced && job.date_invoiced),
onClick: () => {
setTimeTicketTaskContext({
@@ -754,7 +746,6 @@ export function JobsDetailHeaderActions({
menuItems.push({
key: "enterpayments",
id: "job-actions-enterpayments",
disabled: !job.converted,
label: t("menus.header.enterpayment"),
onClick: () => {
@@ -770,7 +761,6 @@ export function JobsDetailHeaderActions({
if (ImEXPay.treatment === "on") {
menuItems.push({
key: "entercardpayments",
id: "job-actions-entercardpayments",
disabled: !job.converted,
label: t("menus.header.entercardpayment"),
onClick: () => {
@@ -787,7 +777,6 @@ export function JobsDetailHeaderActions({
if (HasFeatureAccess({ featureName: "courtesycars", bodyshop })) {
menuItems.push({
key: "cccontract",
id: "job-actions-cccontract",
disabled: jobRO || !job.converted,
label: (
<Link state={{ jobId: job.id }} to="/manage/courtesycars/contracts/new">
@@ -799,7 +788,6 @@ export function JobsDetailHeaderActions({
menuItems.push({
key: "createtask",
id: "job-actions-createtask",
label: t("menus.header.create_task"),
onClick: () =>
setTaskUpsertContext({
@@ -812,14 +800,12 @@ export function JobsDetailHeaderActions({
job.inproduction
? {
key: "removefromproduction",
id: "job-actions-removefromproduction",
disabled: !job.converted,
label: t("jobs.actions.removefromproduction"),
onClick: () => AddToProduction(client, job.id, refetch, true)
}
: {
key: "addtoproduction",
id: "job-actions-addtoproduction",
disabled: !job.converted,
label: t("jobs.actions.addtoproduction"),
onClick: () => AddToProduction(client, job.id, refetch)
@@ -829,14 +815,12 @@ export function JobsDetailHeaderActions({
menuItems.push(
{
key: "togglesuspend",
id: "job-actions-togglesuspend",
onClick: handleSuspend,
label: job.suspended ? t("production.actions.unsuspend") : t("production.actions.suspend")
},
{
key: "toggleAlert",
onClick: handleAlertToggle,
id: "job-actions-togglealert",
label:
job.production_vars && job.production_vars.alert
? t("production.labels.alertoff")
@@ -848,7 +832,6 @@ export function JobsDetailHeaderActions({
children: [
{
key: "duplicate",
id: "job-actions-duplicate",
label: (
<Popconfirm
title={t("jobs.labels.duplicateconfirm")}
@@ -864,7 +847,6 @@ export function JobsDetailHeaderActions({
},
{
key: "duplicatenolines",
id: "job-actions-duplicatenolines",
label: (
<Popconfirm
title={t("jobs.labels.duplicateconfirm")}
@@ -888,7 +870,6 @@ export function JobsDetailHeaderActions({
? [
{
key: "postbills",
id: "job-actions-postbills",
disabled: !job.converted,
label: t("jobs.actions.postbills"),
onClick: () => {
@@ -907,7 +888,6 @@ export function JobsDetailHeaderActions({
{
key: "addtopartsqueue",
id: "job-actions-addtopartsqueue",
disabled: !job.converted || !jobInProduction || jobRO,
label: t("jobs.actions.addtopartsqueue"),
onClick: async () => {
@@ -933,7 +913,6 @@ export function JobsDetailHeaderActions({
},
{
key: "closejob",
id: "job-actions-closejob",
disabled: !jobInPostProduction,
label: !jobInPostProduction ? (
t("menus.jobsactions.closejob")
@@ -949,7 +928,6 @@ export function JobsDetailHeaderActions({
},
{
key: "admin",
id: "job-actions-admin",
label: (
<Link
to={{
@@ -971,7 +949,6 @@ export function JobsDetailHeaderActions({
) {
menuItems.push({
key: "exportcustdata",
id: "job-actions-exportcustdata",
disabled: !job.converted,
label: t("jobs.actions.exportcustdata"),
onClick: handleExportCustData
@@ -982,21 +959,18 @@ export function JobsDetailHeaderActions({
const children = [
{
key: "email",
id: "job-actions-email",
disabled: !!!job.ownr_ea,
label: t("general.labels.email"),
onClick: handleCreateCsi
},
{
key: "text",
id: "job-actions-text",
disabled: !!!job.ownr_ph1,
label: t("general.labels.text"),
onClick: handleCreateCsi
},
{
key: "generate",
id: "job-actions-generate",
disabled: job.csiinvites && job.csiinvites.length > 0,
label: t("jobs.actions.generatecsi"),
onClick: handleCreateCsi
@@ -1030,7 +1004,6 @@ export function JobsDetailHeaderActions({
}
menuItems.push({
key: "sendcsi",
id: "job-actions-sendcsi",
label: t("jobs.actions.sendcsi"),
disabled: !job.converted,
children
@@ -1039,7 +1012,6 @@ export function JobsDetailHeaderActions({
menuItems.push({
key: "jobcosting",
id: "job-actions-jobcosting",
disabled: !job.converted,
label: t("jobs.labels.jobcosting"),
onClick: () => {
@@ -1057,7 +1029,6 @@ export function JobsDetailHeaderActions({
if (job && !job.converted) {
menuItems.push({
key: "deletejob",
id: "job-actions-deletejob",
label: (
<Popconfirm
title={t("jobs.labels.deleteconfirm")}
@@ -1074,7 +1045,6 @@ export function JobsDetailHeaderActions({
menuItems.push({
key: "manualevent",
id: "job-actions-manualevent",
onClick: (e) => {
setVisibility(true);
},
@@ -1084,7 +1054,6 @@ export function JobsDetailHeaderActions({
if (!jobRO && job.converted) {
menuItems.push({
key: "voidjob",
id: "job-actions-voidjob",
label: (
<RbacWrapper action="jobs:void" noauth>
<Popconfirm

View File

@@ -101,7 +101,7 @@ export function PartsOrderListTableComponent({
} else {
const fetchData = async () => {
const result = await billQuery({
variables: { billid: returnfrombill }
variables: { billid: returnfrombill },
});
setBillData(result.data);
};
@@ -203,7 +203,7 @@ export function PartsOrderListTableComponent({
is_credit_memo: record.return,
billlines: record.parts_order_lines.map((pol) => {
return {
joblineid: pol.job_line_id || "noline",
joblineid: pol.job_line_id,
line_desc: pol.line_desc,
quantity: pol.quantity,

View File

@@ -291,7 +291,6 @@ export function JobsDetailPage({
{
key: "general",
icon: <Icon component={FaShieldAlt} />,
id: "job-details-general",
label: t("menus.jobsdetail.general"),
forceRender: true,
children: <JobsDetailGeneral job={job} form={form} />
@@ -299,7 +298,6 @@ export function JobsDetailPage({
{
key: "repairdata",
icon: <BarsOutlined />,
id: "job-details-repairdata",
label: t("menus.jobsdetail.repairdata"),
forceRender: true,
children: <JobsLinesContainer job={job} joblines={job.joblines} refetch={refetch} form={form} />
@@ -307,21 +305,18 @@ export function JobsDetailPage({
{
key: "rates",
icon: <DollarCircleOutlined />,
id: "job-details-rates",
label: t("menus.jobsdetail.rates"),
forceRender: true,
children: <JobsDetailRates job={job} form={form} />
},
{
key: "totals",
id: "job-details-totals",
icon: <DollarCircleOutlined />,
label: t("menus.jobsdetail.totals"),
children: <JobsDetailTotals job={job} refetch={refetch} />
},
{
key: "partssublet",
id: "job-details-partssublet",
icon: <ToolFilled />,
label: HasFeatureAccess({ featureName: "bills", bodyshop })
? t("menus.jobsdetail.partssublet")
@@ -336,7 +331,6 @@ export function JobsDetailPage({
? [
{
key: "labor",
id: "job-details-labor",
icon: <Icon component={FaHardHat} />,
label: t("menus.jobsdetail.labor"),
children: <JobsDetailLaborContainer job={job} jobId={job.id} />
@@ -346,13 +340,11 @@ export function JobsDetailPage({
{
key: "lifecycle",
icon: <BarsOutlined />,
id: "job-details-lifecycle",
label: t("menus.jobsdetail.lifecycle"),
children: <JobLifecycleComponent job={job} statuses={bodyshop.md_ro_statuses} />
},
{
key: "dates",
id: "job-details-dates",
icon: <CalendarFilled />,
label: t("menus.jobsdetail.dates"),
forceRender: true,
@@ -366,7 +358,6 @@ export function JobsDetailPage({
? [
{
key: "documents",
id: "job-details-documents",
icon: <FileImageFilled />,
label: t("jobs.labels.documents"),
children: bodyshop.uselocalmediaserver ? (
@@ -379,7 +370,6 @@ export function JobsDetailPage({
: []),
{
key: "notes",
id: "job-details-notes",
icon: <Icon component={FaRegStickyNote} />,
label: t("jobs.labels.notes"),
children: <JobNotesContainer jobId={job.id} />
@@ -387,14 +377,12 @@ export function JobsDetailPage({
{
key: "audit",
icon: <HistoryOutlined />,
id: "job-details-audit",
label: t("jobs.labels.audit"),
children: <JobAuditTrail jobId={job.id} />
},
{
key: "tasks",
icon: <FaTasks />,
id: "job-details-tasks",
label: (
<Space direction="horizontal">
{t("jobs.labels.tasks")}

View File

@@ -174,7 +174,10 @@ async function OpenSearchUpdateHandler(req, res) {
const bulkOperation = [];
slicedArray.forEach((bill) => {
bulkOperation.push({ index: { _index: "bills", _id: bill.id } });
bulkOperation.push({ ...bill, bodyshopid: bill.job.bodyshopid });
bulkOperation.push({
...omit(bill, ["job"]),
bodyshopid: bill.job.bodyshopid
});
});
promiseQueue.push(bulkOperation);
}

View File

@@ -12,9 +12,6 @@
"admin": "cd admin && npm start",
"client": "cd client && npm start",
"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",
"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\"",

View File

@@ -8,11 +8,9 @@ const cookieParser = require("cookie-parser");
const http = require("http");
const { Server } = require("socket.io");
const instanceName = process.argv[2];
// Load environment variables
require("dotenv").config({
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}${instanceName ? `.${instanceName}` : ''}`)
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
});
// Import custom utilities and handlers

View File

@@ -891,22 +891,19 @@ function checkStateTax(jobline, jobs_by_pk) {
}
const isAdditionalCost =
(jobline.lbr_op === "OP13" || (jobline.db_ref && jobline.db_ref.startsWith("9360"))) && !isPaintOrShopMat;
(jobline.lbr_op === "OP13" ||
(jobline.lbr_op === "OP14" && jobline.act_price > 0 && jobline.mod_lb_hrs === 0) ||
(jobline.db_ref && jobline.db_ref.startsWith("9360")) ||
(jobline.db_ref && jobline.db_ref.startsWith("90051"))) &&
!isPaintOrShopMat;
if (!jobline.part_type && isAdditionalCost) {
if (jobs_by_pk.tax_lbr_rt === 0) {
return false;
} else {
return true;
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;

View File

@@ -1539,7 +1539,6 @@ exports.QUERY_JOB_COSTING_DETAILS = ` query QUERY_JOB_COSTING_DETAILS($id: uuid!
op_code_desc
profitcenter_part
profitcenter_labor
act_price_before_ppc
}
bills {
id

View File

@@ -269,7 +269,7 @@ function GenerateCostingData(job) {
job &&
job.joblines.reduce(
(acc, val) => {
//Shop or Paint Material Flags
//Parts Lines
if (val.db_ref === "936008") {
//If either of these DB REFs change, they also need to change in job-totals/job-costing calculations.
hasMapaLine = true;
@@ -277,8 +277,6 @@ function GenerateCostingData(job) {
if (val.db_ref === "936007") {
hasMashLine = true;
}
//Labor Profit Center
if (val.mod_lbr_ty) {
const laborProfitCenter = val.profitcenter_labor || defaultProfits[val.mod_lbr_ty] || "Unknown";
@@ -309,7 +307,6 @@ function GenerateCostingData(job) {
}
}
// Part Profit Center
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";
@@ -318,7 +315,7 @@ function GenerateCostingData(job) {
if (!partsProfitCenter)
console.log("Unknown cost/profit center mapping for parts.", val.line_desc, val.part_type);
const partsAmount = Dinero({
amount: val.act_price_before_ppc ? Math.round(val.act_price_before_ppc * 100) : Math.round(val.act_price * 100)
amount: Math.round((val.act_price || 0) * 100)
})
.multiply(val.part_qty || 1)
.add(
@@ -327,7 +324,7 @@ function GenerateCostingData(job) {
? val.prt_dsmk_m
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
: Dinero({
amount: val.act_price_before_ppc ? Math.round(val.act_price_before_ppc * 100) : Math.round(val.act_price * 100)
amount: Math.round(val.act_price * 100)
})
.multiply(val.part_qty || 0)
.percentage(Math.abs(val.prt_dsmk_p || 0))
@@ -337,8 +334,6 @@ function GenerateCostingData(job) {
if (!acc.parts[partsProfitCenter]) acc.parts[partsProfitCenter] = Dinero();
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")) {
const partsProfitCenter = val.profitcenter_part || defaultProfits[val.part_type] || "Unknown";
@@ -367,8 +362,8 @@ function GenerateCostingData(job) {
acc.sublet[partsProfitCenter] = acc.sublet[partsProfitCenter].add(partsAmount);
}
//Additional Profit Center
if ((!val.part_type && !val.mod_lbr_ty) || (!val.part_type && val.mod_lbr_ty)) {
//To deal with additional costs.
if (!val.part_type && !val.mod_lbr_ty) {
//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.
const partsProfitCenter = val.profitcenter_part || getAdditionalCostCenter(val, defaultProfits) || "Unknown";