Merged in release/2024-08-09-no-zoho (pull request #1596)
Release/2024 08 09 no zoho
This commit is contained in:
@@ -31,3 +31,11 @@
|
|||||||
|
|
||||||
These allow users to turn fields on or off, turning them all off will show the card in the most minimal form
|
These allow users to turn fields on or off, turning them all off will show the card in the most minimal form
|
||||||
|
|
||||||
|
|
||||||
|
### Statistics
|
||||||
|
|
||||||
|
- The statistics section allows users to see accumulations of both jobs on the board, and jobs in production.
|
||||||
|
- you can click a statistic to turn it on and off, and drag and drop the statistics to rearrange them
|
||||||
|
|
||||||
|
### Filters
|
||||||
|
- Allows you to set, and persist filters for estimators and insurance companies
|
||||||
|
|||||||
@@ -161,3 +161,15 @@
|
|||||||
.rowWithColor > td {
|
.rowWithColor > td {
|
||||||
background-color: var(--bgColor) !important;
|
background-color: var(--bgColor) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.muted-button {
|
||||||
|
color: lightgray;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px; /* Adjust as needed */
|
||||||
|
}
|
||||||
|
|
||||||
|
.muted-button:hover {
|
||||||
|
color: darkgrey;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { PageHeader } from "@ant-design/pro-layout";
|
||||||
import { useMutation, useQuery } from "@apollo/client";
|
import { useMutation, useQuery } from "@apollo/client";
|
||||||
import { Button, Divider, Form, Popconfirm, Space } from "antd";
|
import { Button, Divider, Form, Popconfirm, Space } from "antd";
|
||||||
import dayjs from "../../utils/day";
|
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -13,6 +13,7 @@ import { insertAuditTrail } from "../../redux/application/application.actions";
|
|||||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||||
|
import dayjs from "../../utils/day";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import BillFormContainer from "../bill-form/bill-form.container";
|
import BillFormContainer from "../bill-form/bill-form.container";
|
||||||
import BillMarkExportedButton from "../bill-mark-exported-button/bill-mark-exported-button.component";
|
import BillMarkExportedButton from "../bill-mark-exported-button/bill-mark-exported-button.component";
|
||||||
@@ -22,7 +23,6 @@ import JobDocumentsGallery from "../jobs-documents-gallery/jobs-documents-galler
|
|||||||
import JobsDocumentsLocalGallery from "../jobs-documents-local-gallery/jobs-documents-local-gallery.container";
|
import JobsDocumentsLocalGallery from "../jobs-documents-local-gallery/jobs-documents-local-gallery.container";
|
||||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||||
import BillDetailEditReturn from "./bill-detail-edit-return.component";
|
import BillDetailEditReturn from "./bill-detail-edit-return.component";
|
||||||
import { PageHeader } from "@ant-design/pro-layout";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop
|
||||||
@@ -153,6 +153,7 @@ export function BillDetailEditcontainer({ setPartsOrderContext, insertAuditTrail
|
|||||||
if (!search.billid) return <></>; //<div>{t("bills.labels.noneselected")}</div>;
|
if (!search.billid) return <></>; //<div>{t("bills.labels.noneselected")}</div>;
|
||||||
|
|
||||||
const exported = data && data.bills_by_pk && data.bills_by_pk.exported;
|
const exported = data && data.bills_by_pk && data.bills_by_pk.exported;
|
||||||
|
const isinhouse = data && data.bills_by_pk && data.bills_by_pk.isinhouse;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -188,7 +189,7 @@ export function BillDetailEditcontainer({ setPartsOrderContext, insertAuditTrail
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Form form={form} onFinish={handleFinish} initialValues={transformData(data)} layout="vertical">
|
<Form form={form} onFinish={handleFinish} initialValues={transformData(data)} layout="vertical">
|
||||||
<BillFormContainer form={form} billEdit disabled={exported} />
|
<BillFormContainer form={form} billEdit disabled={exported} disableInHouse={isinhouse} />
|
||||||
<Divider orientation="left">{t("general.labels.media")}</Divider>
|
<Divider orientation="left">{t("general.labels.media")}</Divider>
|
||||||
{bodyshop.uselocalmediaserver ? (
|
{bodyshop.uselocalmediaserver ? (
|
||||||
<JobsDocumentsLocalGallery
|
<JobsDocumentsLocalGallery
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ export function BillFormComponent({
|
|||||||
job,
|
job,
|
||||||
loadOutstandingReturns,
|
loadOutstandingReturns,
|
||||||
loadInventory,
|
loadInventory,
|
||||||
preferredMake
|
preferredMake,
|
||||||
|
disableInHouse
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
@@ -177,7 +178,7 @@ export function BillFormComponent({
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<VendorSearchSelect
|
<VendorSearchSelect
|
||||||
disabled={disabled}
|
disabled={disabled || disableInHouse}
|
||||||
options={vendorAutoCompleteOptions}
|
options={vendorAutoCompleteOptions}
|
||||||
preferredMake={preferredMake}
|
preferredMake={preferredMake}
|
||||||
onSelect={handleVendorSelect}
|
onSelect={handleVendorSelect}
|
||||||
@@ -243,7 +244,7 @@ export function BillFormComponent({
|
|||||||
})
|
})
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Input disabled={disabled || disableInvNumber} />
|
<Input disabled={disabled || disableInvNumber || disableInHouse} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("bills.fields.date")}
|
label={t("bills.fields.date")}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const mapStateToProps = createStructuredSelector({
|
|||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop
|
||||||
});
|
});
|
||||||
|
|
||||||
export function BillFormContainer({ bodyshop, form, billEdit, disabled, disableInvNumber }) {
|
export function BillFormContainer({ bodyshop, form, billEdit, disabled, disableInvNumber, disableInHouse }) {
|
||||||
const {
|
const {
|
||||||
treatments: { Simple_Inventory }
|
treatments: { Simple_Inventory }
|
||||||
} = useSplitTreatments({
|
} = useSplitTreatments({
|
||||||
@@ -47,6 +47,7 @@ export function BillFormContainer({ bodyshop, form, billEdit, disabled, disableI
|
|||||||
job={lineData ? lineData.jobs_by_pk : null}
|
job={lineData ? lineData.jobs_by_pk : null}
|
||||||
responsibilityCenters={bodyshop.md_responsibility_centers || null}
|
responsibilityCenters={bodyshop.md_responsibility_centers || null}
|
||||||
disableInvNumber={disableInvNumber}
|
disableInvNumber={disableInvNumber}
|
||||||
|
disableInHouse={disableInHouse}
|
||||||
loadOutstandingReturns={loadOutstandingReturns}
|
loadOutstandingReturns={loadOutstandingReturns}
|
||||||
loadInventory={loadInventory}
|
loadInventory={loadInventory}
|
||||||
preferredMake={lineData ? lineData.jobs_by_pk.v_make_desc : null}
|
preferredMake={lineData ? lineData.jobs_by_pk.v_make_desc : null}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
|||||||
import { Col, Row, notification } from "antd";
|
import { Col, Row, notification } from "antd";
|
||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import dayjs from "../../utils/day";
|
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -24,6 +23,8 @@ import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selecto
|
|||||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||||
import confirmDialog from "../../utils/asyncConfirm";
|
import confirmDialog from "../../utils/asyncConfirm";
|
||||||
import CriticalPartsScan from "../../utils/criticalPartsScan";
|
import CriticalPartsScan from "../../utils/criticalPartsScan";
|
||||||
|
import dayjs from "../../utils/day";
|
||||||
|
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import JobsAvailableScan from "../jobs-available-scan/jobs-available-scan.component";
|
import JobsAvailableScan from "../jobs-available-scan/jobs-available-scan.component";
|
||||||
import JobsFindModalContainer from "../jobs-find-modal/jobs-find-modal.container";
|
import JobsFindModalContainer from "../jobs-find-modal/jobs-find-modal.container";
|
||||||
@@ -32,7 +33,6 @@ import OwnerFindModalContainer from "../owner-find-modal/owner-find-modal.contai
|
|||||||
import { GetSupplementDelta } from "./jobs-available-supplement.estlines.util";
|
import { GetSupplementDelta } from "./jobs-available-supplement.estlines.util";
|
||||||
import HeaderFields from "./jobs-available-supplement.headerfields";
|
import HeaderFields from "./jobs-available-supplement.headerfields";
|
||||||
import JobsAvailableTableComponent from "./jobs-available-table.component";
|
import JobsAvailableTableComponent from "./jobs-available-table.component";
|
||||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -580,12 +580,13 @@ function ResolveCCCLineIssues(estData, bodyshop) {
|
|||||||
InstanceRenderManager({
|
InstanceRenderManager({
|
||||||
executeFunction: true,
|
executeFunction: true,
|
||||||
args: [],
|
args: [],
|
||||||
promanager: () => {
|
rome: () => {
|
||||||
if (line.mod_lbr_ty === "LAET" || line.mod_lbr_ty === "LAUT") {
|
if (line.mod_lbr_ty === "LAET" || line.mod_lbr_ty === "LAUT") {
|
||||||
// line.notes += ` | ET/UT Update (prev = ${line.mod_lbr_ty})`;
|
// line.notes += ` | ET/UT Update (prev = ${line.mod_lbr_ty})`;
|
||||||
line.mod_lbr_ty = "LAR";
|
line.mod_lbr_ty = "LAR";
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
promanager: "USE_ROME"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -290,6 +290,22 @@ const PartsStatusComponent = ({ metadata, cardSettings }) =>
|
|||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const TasksToolTip = ({ metadata, cardSettings, t }) =>
|
||||||
|
cardSettings?.tasks && (
|
||||||
|
<Col span={12}>
|
||||||
|
<EllipsesToolTip
|
||||||
|
title={`${t("production.labels.tasks")}: ${metadata.tasks_aggregate?.aggregate?.count || 0}`}
|
||||||
|
kiosk={cardSettings.kiosk}
|
||||||
|
>
|
||||||
|
{metadata.tasks_aggregate?.aggregate?.count ? (
|
||||||
|
`T: ${metadata.tasks_aggregate.aggregate.count}`
|
||||||
|
) : (
|
||||||
|
<span>T: 0</span>
|
||||||
|
)}
|
||||||
|
</EllipsesToolTip>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
|
||||||
export default function ProductionBoardCard({ technician, card, bodyshop, cardSettings, clone }) {
|
export default function ProductionBoardCard({ technician, card, bodyshop, cardSettings, clone }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { metadata } = card;
|
const { metadata } = card;
|
||||||
@@ -336,21 +352,15 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe
|
|||||||
cardSettings?.production_note ||
|
cardSettings?.production_note ||
|
||||||
cardSettings?.partsstatus ||
|
cardSettings?.partsstatus ||
|
||||||
cardSettings?.estimator ||
|
cardSettings?.estimator ||
|
||||||
cardSettings?.subtotal
|
cardSettings?.subtotal ||
|
||||||
|
cardSettings?.tasks
|
||||||
);
|
);
|
||||||
}, [cardSettings]);
|
}, [cardSettings]);
|
||||||
|
|
||||||
const headerContent = (
|
const headerContent = (
|
||||||
<div className="header-content-container">
|
<div className="header-content-container">
|
||||||
<div className="inner-container">
|
<div className="inner-container">
|
||||||
<ProductionAlert
|
<ProductionAlert id={card.id} productionVars={metadata?.production_vars} refetch={card?.refetch} key="alert" />
|
||||||
record={{
|
|
||||||
id: card.id,
|
|
||||||
production_vars: card?.metadata.production_vars,
|
|
||||||
refetch: card?.refetch
|
|
||||||
}}
|
|
||||||
key="alert"
|
|
||||||
/>
|
|
||||||
{metadata?.suspended && <PauseCircleOutlined className="circle-outline" key="suspended" />}
|
{metadata?.suspended && <PauseCircleOutlined className="circle-outline" key="suspended" />}
|
||||||
{metadata?.iouparent && (
|
{metadata?.iouparent && (
|
||||||
<EllipsesToolTip
|
<EllipsesToolTip
|
||||||
@@ -393,6 +403,7 @@ export default function ProductionBoardCard({ technician, card, bodyshop, cardSe
|
|||||||
employee_csr={employee_csr}
|
employee_csr={employee_csr}
|
||||||
/>
|
/>
|
||||||
<EstimatorToolTip metadata={metadata} cardSettings={cardSettings} />
|
<EstimatorToolTip metadata={metadata} cardSettings={cardSettings} />
|
||||||
|
<TasksToolTip metadata={metadata} cardSettings={cardSettings} t={t} />
|
||||||
<SubtotalTooltip metadata={metadata} cardSettings={cardSettings} t={t} />
|
<SubtotalTooltip metadata={metadata} cardSettings={cardSettings} t={t} />
|
||||||
<ActualInToolTip metadata={metadata} cardSettings={cardSettings} />
|
<ActualInToolTip metadata={metadata} cardSettings={cardSettings} />
|
||||||
<ScheduledCompletionToolTip metadata={metadata} cardSettings={cardSettings} pastDueAlert={pastDueAlert} />
|
<ScheduledCompletionToolTip metadata={metadata} cardSettings={cardSettings} pastDueAlert={pastDueAlert} />
|
||||||
@@ -15,13 +15,13 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
|||||||
import IndefiniteLoading from "../indefinite-loading/indefinite-loading.component";
|
import IndefiniteLoading from "../indefinite-loading/indefinite-loading.component";
|
||||||
import ProductionBoardFilters from "../production-board-filters/production-board-filters.component";
|
import ProductionBoardFilters from "../production-board-filters/production-board-filters.component";
|
||||||
import ProductionListDetailComponent from "../production-list-detail/production-list-detail.component";
|
import ProductionListDetailComponent from "../production-list-detail/production-list-detail.component";
|
||||||
import CardColorLegend from "../production-board-kanban-card/production-board-kanban-card-color-legend.component";
|
import CardColorLegend from "./production-board-kanban-card-color-legend.component.jsx";
|
||||||
import "./production-board-kanban.styles.scss";
|
import "./production-board-kanban.styles.scss";
|
||||||
import { createBoardData } from "./production-board-kanban.utils.js";
|
import { createBoardData } from "./production-board-kanban.utils.js";
|
||||||
import ProductionBoardKanbanSettings from "./settings/production-board-kanban.settings.component.jsx";
|
import ProductionBoardKanbanSettings from "./settings/production-board-kanban.settings.component.jsx";
|
||||||
import cloneDeep from "lodash/cloneDeep";
|
import cloneDeep from "lodash/cloneDeep";
|
||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
import { defaultKanbanSettings } from "./settings/defaultKanbanSettings.js";
|
import { mergeWithDefaults } from "./settings/defaultKanbanSettings.js";
|
||||||
import NoteUpsertModal from "../../components/note-upsert-modal/note-upsert-modal.container";
|
import NoteUpsertModal from "../../components/note-upsert-modal/note-upsert-modal.container";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
@@ -182,13 +182,10 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
[boardLanes, client, getCardByID, isMoving, t, insertAuditTrail]
|
[boardLanes, client, getCardByID, isMoving, t, insertAuditTrail]
|
||||||
);
|
);
|
||||||
|
|
||||||
const cardSettings = useMemo(
|
const cardSettings = useMemo(() => {
|
||||||
() =>
|
const kanbanSettings = associationSettings?.kanban_settings;
|
||||||
associationSettings?.kanban_settings && Object.keys(associationSettings.kanban_settings).length > 0
|
return mergeWithDefaults(kanbanSettings);
|
||||||
? associationSettings.kanban_settings
|
}, [associationSettings]);
|
||||||
: defaultKanbanSettings,
|
|
||||||
[associationSettings]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleSettingsChange = useCallback((newSettings) => {
|
const handleSettingsChange = useCallback((newSettings) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ import React, { useMemo } from "react";
|
|||||||
import { Card, Statistic } from "antd";
|
import { Card, Statistic } from "antd";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { statisticsItems, defaultKanbanSettings } from "./settings/defaultKanbanSettings.js";
|
import { defaultKanbanSettings, statisticsItems } from "./settings/defaultKanbanSettings.js";
|
||||||
|
|
||||||
export const StatisticType = {
|
export const StatisticType = {
|
||||||
HOURS: "hours",
|
HOURS: "hours",
|
||||||
AMOUNT: "amount",
|
AMOUNT: "amount",
|
||||||
JOBS: "jobs"
|
JOBS: "jobs",
|
||||||
|
TASKS: "tasks"
|
||||||
};
|
};
|
||||||
|
|
||||||
const mergeStatistics = (items, values) => {
|
const mergeStatistics = (items, values) => {
|
||||||
@@ -122,6 +124,20 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
|
|||||||
return parseFloat(total.toFixed(2));
|
return parseFloat(total.toFixed(2));
|
||||||
}, [reducerData, cardSettings.totalAmountOnBoard]);
|
}, [reducerData, cardSettings.totalAmountOnBoard]);
|
||||||
|
|
||||||
|
const tasksInProduction = useMemo(() => {
|
||||||
|
if (!data || !cardSettings.tasksInProduction) return null;
|
||||||
|
return data.reduce((acc, item) => acc + (item.tasks_aggregate?.aggregate?.count || 0), 0);
|
||||||
|
}, [data, cardSettings.tasksInProduction]);
|
||||||
|
|
||||||
|
const tasksOnBoard = useMemo(() => {
|
||||||
|
if (!reducerData || !cardSettings.tasksOnBoard) return null;
|
||||||
|
return reducerData.lanes.reduce((acc, lane) => {
|
||||||
|
return (
|
||||||
|
acc + lane.cards.reduce((laneAcc, card) => laneAcc + (card.metadata.tasks_aggregate?.aggregate?.count || 0), 0)
|
||||||
|
);
|
||||||
|
}, 0);
|
||||||
|
}, [reducerData, cardSettings.tasksOnBoard]);
|
||||||
|
|
||||||
const statistics = useMemo(
|
const statistics = useMemo(
|
||||||
() =>
|
() =>
|
||||||
mergeStatistics(statisticsItems, [
|
mergeStatistics(statisticsItems, [
|
||||||
@@ -134,7 +150,9 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
|
|||||||
{ id: 6, value: totalAmountOnBoard, type: StatisticType.AMOUNT },
|
{ id: 6, value: totalAmountOnBoard, type: StatisticType.AMOUNT },
|
||||||
{ id: 7, value: totalLABOnBoard, type: StatisticType.HOURS },
|
{ id: 7, value: totalLABOnBoard, type: StatisticType.HOURS },
|
||||||
{ id: 8, value: totalLAROnBoard, type: StatisticType.HOURS },
|
{ id: 8, value: totalLAROnBoard, type: StatisticType.HOURS },
|
||||||
{ id: 9, value: jobsOnBoard, type: StatisticType.JOBS }
|
{ id: 9, value: jobsOnBoard, type: StatisticType.JOBS },
|
||||||
|
{ id: 10, value: tasksOnBoard, type: StatisticType.TASKS },
|
||||||
|
{ id: 11, value: tasksInProduction, type: StatisticType.TASKS }
|
||||||
]),
|
]),
|
||||||
[
|
[
|
||||||
totalHrs,
|
totalHrs,
|
||||||
@@ -146,7 +164,9 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
|
|||||||
totalAmountOnBoard,
|
totalAmountOnBoard,
|
||||||
totalLABOnBoard,
|
totalLABOnBoard,
|
||||||
totalLAROnBoard,
|
totalLAROnBoard,
|
||||||
jobsOnBoard
|
jobsOnBoard,
|
||||||
|
tasksOnBoard,
|
||||||
|
tasksInProduction
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -187,37 +207,9 @@ const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ProductionStatistics.propTypes = {
|
ProductionStatistics.propTypes = {
|
||||||
data: PropTypes.arrayOf(
|
data: PropTypes.array.isRequired,
|
||||||
PropTypes.shape({
|
cardSettings: PropTypes.object.isRequired,
|
||||||
labhrs: PropTypes.object,
|
reducerData: PropTypes.object
|
||||||
larhrs: PropTypes.object,
|
|
||||||
job_totals: PropTypes.object
|
|
||||||
})
|
|
||||||
).isRequired,
|
|
||||||
cardSettings: PropTypes.shape({
|
|
||||||
totalHrs: PropTypes.bool,
|
|
||||||
totalLAB: PropTypes.bool,
|
|
||||||
totalLAR: PropTypes.bool,
|
|
||||||
jobsInProduction: PropTypes.bool,
|
|
||||||
totalAmountInProduction: PropTypes.bool,
|
|
||||||
totalHrsOnBoard: PropTypes.bool,
|
|
||||||
totalLABOnBoard: PropTypes.bool,
|
|
||||||
totalLAROnBoard: PropTypes.bool,
|
|
||||||
jobsOnBoard: PropTypes.bool,
|
|
||||||
totalAmountOnBoard: PropTypes.bool,
|
|
||||||
statisticsOrder: PropTypes.arrayOf(PropTypes.number)
|
|
||||||
}).isRequired,
|
|
||||||
reducerData: PropTypes.shape({
|
|
||||||
lanes: PropTypes.arrayOf(
|
|
||||||
PropTypes.shape({
|
|
||||||
cards: PropTypes.arrayOf(
|
|
||||||
PropTypes.shape({
|
|
||||||
metadata: PropTypes.object
|
|
||||||
})
|
|
||||||
).isRequired
|
|
||||||
})
|
|
||||||
).isRequired
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProductionStatistics;
|
export default ProductionStatistics;
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ const InformationSettings = ({ t }) => (
|
|||||||
"sublets",
|
"sublets",
|
||||||
"partsstatus",
|
"partsstatus",
|
||||||
"estimator",
|
"estimator",
|
||||||
"subtotal"
|
"subtotal",
|
||||||
|
"tasks"
|
||||||
].map((item) => (
|
].map((item) => (
|
||||||
<Col span={4} key={item}>
|
<Col span={4} key={item}>
|
||||||
<Form.Item name={item} valuePropName="checked">
|
<Form.Item name={item} valuePropName="checked">
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ const statisticsItems = [
|
|||||||
{ id: 6, name: "totalAmountOnBoard", label: "total_amount_on_board" },
|
{ id: 6, name: "totalAmountOnBoard", label: "total_amount_on_board" },
|
||||||
{ id: 7, name: "totalLABOnBoard", label: "total_lab_on_board" },
|
{ id: 7, name: "totalLABOnBoard", label: "total_lab_on_board" },
|
||||||
{ id: 8, name: "totalLAROnBoard", label: "total_lar_on_board" },
|
{ id: 8, name: "totalLAROnBoard", label: "total_lar_on_board" },
|
||||||
{ id: 9, name: "jobsOnBoard", label: "total_jobs_on_board" }
|
{ id: 9, name: "jobsOnBoard", label: "total_jobs_on_board" },
|
||||||
|
{ id: 10, name: "tasksOnBoard", label: "tasks_on_board" },
|
||||||
|
{ id: 11, name: "tasksInProduction", label: "tasks_in_production" }
|
||||||
];
|
];
|
||||||
|
|
||||||
const defaultKanbanSettings = {
|
const defaultKanbanSettings = {
|
||||||
@@ -23,6 +25,7 @@ const defaultKanbanSettings = {
|
|||||||
scheduled_completion: true,
|
scheduled_completion: true,
|
||||||
cardcolor: false,
|
cardcolor: false,
|
||||||
orientation: false,
|
orientation: false,
|
||||||
|
tasks: false,
|
||||||
cardSize: "small",
|
cardSize: "small",
|
||||||
model_info: true,
|
model_info: true,
|
||||||
kiosk: false,
|
kiosk: false,
|
||||||
@@ -35,6 +38,8 @@ const defaultKanbanSettings = {
|
|||||||
totalLABOnBoard: false,
|
totalLABOnBoard: false,
|
||||||
totalLAROnBoard: false,
|
totalLAROnBoard: false,
|
||||||
jobsOnBoard: false,
|
jobsOnBoard: false,
|
||||||
|
tasksOnBoard: false,
|
||||||
|
tasksInProduction: false,
|
||||||
totalAmountOnBoard: true,
|
totalAmountOnBoard: true,
|
||||||
estimator: false,
|
estimator: false,
|
||||||
subtotal: false,
|
subtotal: false,
|
||||||
@@ -43,4 +48,20 @@ const defaultKanbanSettings = {
|
|||||||
selectedEstimators: []
|
selectedEstimators: []
|
||||||
};
|
};
|
||||||
|
|
||||||
export { defaultKanbanSettings, statisticsItems };
|
const mergeWithDefaults = (settings) => {
|
||||||
|
// Create a new object that starts with the default settings
|
||||||
|
const mergedSettings = { ...defaultKanbanSettings };
|
||||||
|
|
||||||
|
// Override with the provided settings, if any
|
||||||
|
if (settings) {
|
||||||
|
for (const key in settings) {
|
||||||
|
if (settings.hasOwnProperty(key)) {
|
||||||
|
mergedSettings[key] = settings[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mergedSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { defaultKanbanSettings, statisticsItems, mergeWithDefaults };
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ import { Button, Card, Col, Form, notification, Popover, Row, Tabs } from "antd"
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { UPDATE_KANBAN_SETTINGS } from "../../../graphql/user.queries.js";
|
import { UPDATE_KANBAN_SETTINGS } from "../../../graphql/user.queries.js";
|
||||||
import { defaultKanbanSettings } from "./defaultKanbanSettings.js";
|
import { defaultKanbanSettings, mergeWithDefaults } from "./defaultKanbanSettings.js";
|
||||||
import LayoutSettings from "./LayoutSettings.jsx";
|
import LayoutSettings from "./LayoutSettings.jsx";
|
||||||
import InformationSettings from "./InformationSettings.jsx";
|
import InformationSettings from "./InformationSettings.jsx";
|
||||||
import StatisticsSettings from "./StatisticsSettings.jsx";
|
import StatisticsSettings from "./StatisticsSettings.jsx";
|
||||||
import FilterSettings from "./FilterSettings.jsx";
|
import FilterSettings from "./FilterSettings.jsx";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
|
||||||
export default function ProductionBoardKanbanSettings({ associationSettings, parentLoading, bodyshop, data }) {
|
function ProductionBoardKanbanSettings({ associationSettings, parentLoading, bodyshop, data }) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -23,16 +24,11 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (associationSettings?.kanban_settings) {
|
if (associationSettings?.kanban_settings) {
|
||||||
form.setFieldsValue(associationSettings.kanban_settings);
|
const finalSettings = mergeWithDefaults(associationSettings.kanban_settings);
|
||||||
if (associationSettings.kanban_settings.statisticsOrder) {
|
form.setFieldsValue(finalSettings);
|
||||||
setStatisticsOrder(associationSettings.kanban_settings.statisticsOrder);
|
setStatisticsOrder(finalSettings.statisticsOrder);
|
||||||
}
|
setSelectedMdInsCos(finalSettings.selectedMdInsCos);
|
||||||
if (associationSettings.kanban_settings.selectedMdInsCos) {
|
setSelectedEstimators(finalSettings.selectedEstimators);
|
||||||
setSelectedMdInsCos(associationSettings.kanban_settings.selectedMdInsCos);
|
|
||||||
}
|
|
||||||
if (associationSettings.kanban_settings.selectedEstimators) {
|
|
||||||
setSelectedEstimators(associationSettings.kanban_settings.selectedEstimators);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [form, associationSettings]);
|
}, [form, associationSettings]);
|
||||||
|
|
||||||
@@ -155,3 +151,12 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
|||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProductionBoardKanbanSettings.propTypes = {
|
||||||
|
associationSettings: PropTypes.object,
|
||||||
|
parentLoading: PropTypes.func.isRequired,
|
||||||
|
bodyshop: PropTypes.object.isRequired,
|
||||||
|
data: PropTypes.array
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProductionBoardKanbanSettings;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { EyeInvisibleOutlined, EyeOutlined } from "@ant-design/icons";
|
|||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { selectBodyshop } from "../../../../redux/user/user.selectors.js";
|
import { selectBodyshop } from "../../../../redux/user/user.selectors.js";
|
||||||
import { selectTechnician } from "../../../../redux/tech/tech.selectors.js";
|
import { selectTechnician } from "../../../../redux/tech/tech.selectors.js";
|
||||||
import ProductionBoardCard from "../../../production-board-kanban-card/production-board-kanban-card.component.jsx";
|
import ProductionBoardCard from "../../production-board-kanban-card.component.jsx";
|
||||||
import HeightMemoryWrapper from "../components/HeightMemoryWrapper.jsx";
|
import HeightMemoryWrapper from "../components/HeightMemoryWrapper.jsx";
|
||||||
import SizeMemoryWrapper from "../components/SizeMemoryWrapper.jsx";
|
import SizeMemoryWrapper from "../components/SizeMemoryWrapper.jsx";
|
||||||
import ListComponent from "../components/ListComponent.jsx";
|
import ListComponent from "../components/ListComponent.jsx";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ExclamationCircleFilled } from "@ant-design/icons";
|
import { ExclamationCircleFilled, PlusCircleFilled } from "@ant-design/icons";
|
||||||
import { useMutation } from "@apollo/client";
|
import { useMutation } from "@apollo/client";
|
||||||
import { Button } from "antd";
|
import { Button, Popconfirm } from "antd";
|
||||||
import React, { useCallback } from "react";
|
import React, { useCallback } from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
@@ -8,6 +8,7 @@ import { logImEXEvent } from "../../firebase/firebase.utils";
|
|||||||
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
||||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({});
|
const mapStateToProps = createStructuredSelector({});
|
||||||
|
|
||||||
@@ -22,22 +23,24 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
const ProductionListColumnAlert = ({ record, insertAuditTrail }) => {
|
const ProductionListColumnAlert = ({ id, productionVars, refetch, insertAuditTrail }) => {
|
||||||
const [updateAlert] = useMutation(UPDATE_JOB);
|
const [updateAlert] = useMutation(UPDATE_JOB);
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleAlertToggle = useCallback(() => {
|
const handleAlertToggle = useCallback(() => {
|
||||||
logImEXEvent("production_toggle_alert");
|
logImEXEvent("production_toggle_alert");
|
||||||
|
|
||||||
const newAlertState = !!record.production_vars?.alert ? !record.production_vars.alert : true;
|
const newAlertState = !!productionVars?.alert ? !productionVars?.alert : true;
|
||||||
|
const finalProductionVars = {
|
||||||
|
...productionVars,
|
||||||
|
alert: newAlertState
|
||||||
|
};
|
||||||
|
|
||||||
updateAlert({
|
updateAlert({
|
||||||
variables: {
|
variables: {
|
||||||
jobId: record.id,
|
jobId: id,
|
||||||
job: {
|
job: {
|
||||||
production_vars: {
|
production_vars: finalProductionVars
|
||||||
...record.production_vars,
|
|
||||||
alert: newAlertState
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
@@ -45,17 +48,26 @@ const ProductionListColumnAlert = ({ record, insertAuditTrail }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
insertAuditTrail({
|
insertAuditTrail({
|
||||||
jobid: record.id,
|
jobid: id,
|
||||||
operation: AuditTrailMapping.alertToggle(newAlertState),
|
operation: AuditTrailMapping.alertToggle(newAlertState),
|
||||||
type: "alertToggle"
|
type: "alertToggle"
|
||||||
});
|
});
|
||||||
|
|
||||||
if (record.refetch) record.refetch();
|
if (refetch) refetch();
|
||||||
}, [updateAlert, insertAuditTrail, record]);
|
}, [updateAlert, insertAuditTrail, id, productionVars, refetch]);
|
||||||
|
|
||||||
if (!record.production_vars?.alert) return null;
|
return productionVars?.alert ? (
|
||||||
|
<Popconfirm
|
||||||
return <Button className="production-alert" icon={<ExclamationCircleFilled />} onClick={handleAlertToggle} />;
|
title={t("general.actions.remove_alert")}
|
||||||
|
onConfirm={handleAlertToggle}
|
||||||
|
okText={t("general.labels.yes")}
|
||||||
|
cancelText={t("general.labels.no")}
|
||||||
|
>
|
||||||
|
<Button className="production-alert" icon={<ExclamationCircleFilled />} />
|
||||||
|
</Popconfirm>
|
||||||
|
) : (
|
||||||
|
<Button className="muted-button" icon={<PlusCircleFilled />} onClick={handleAlertToggle} />
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(ProductionListColumnAlert);
|
export default connect(mapStateToProps, mapDispatchToProps)(ProductionListColumnAlert);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import ProductionListColumnPartsReceived from "./production-list-columns.partsre
|
|||||||
import ProductionListColumnNote from "./production-list-columns.productionnote.component";
|
import ProductionListColumnNote from "./production-list-columns.productionnote.component";
|
||||||
import ProductionListColumnCategory from "./production-list-columns.status.category";
|
import ProductionListColumnCategory from "./production-list-columns.status.category";
|
||||||
import ProductionListColumnStatus from "./production-list-columns.status.component";
|
import ProductionListColumnStatus from "./production-list-columns.status.component";
|
||||||
import ProductionlistColumnTouchTime from "./prodution-list-columns.touchtime.component";
|
import ProductionListColumnTouchTime from "./prodution-list-columns.touchtime.component";
|
||||||
import { store } from "../../redux/store";
|
import { store } from "../../redux/store";
|
||||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||||
@@ -349,7 +349,9 @@ const r = ({ technician, state, activeStatuses, data, bodyshop, refetch, treatme
|
|||||||
key: "alert",
|
key: "alert",
|
||||||
sorter: (a, b) => Number(a.production_vars?.alert || false) - Number(b.production_vars?.alert || false),
|
sorter: (a, b) => Number(a.production_vars?.alert || false) - Number(b.production_vars?.alert || false),
|
||||||
sortOrder: state.sortedInfo.columnKey === "alert" && state.sortedInfo.order,
|
sortOrder: state.sortedInfo.columnKey === "alert" && state.sortedInfo.order,
|
||||||
render: (text, record) => <ProductionListColumnAlert record={{ record }} />
|
render: (text, record) => (
|
||||||
|
<ProductionListColumnAlert id={record.id} productionVars={record?.production_vars} refetch={refetch} />
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18n.t("production.labels.note"),
|
title: i18n.t("production.labels.note"),
|
||||||
@@ -370,7 +372,7 @@ const r = ({ technician, state, activeStatuses, data, bodyshop, refetch, treatme
|
|||||||
dataIndex: "tt",
|
dataIndex: "tt",
|
||||||
key: "tt",
|
key: "tt",
|
||||||
render: (text, record) => {
|
render: (text, record) => {
|
||||||
return <ProductionlistColumnTouchTime job={record} />;
|
return <ProductionListColumnTouchTime job={record} />;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ export function ProductionListEmpAssignment({ insertAuditTrail, bodyshop, record
|
|||||||
) : (
|
) : (
|
||||||
<PlusCircleFilled
|
<PlusCircleFilled
|
||||||
style={iconStyle}
|
style={iconStyle}
|
||||||
|
className="muted-button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setAssignment({ operation: type });
|
setAssignment({ operation: type });
|
||||||
setVisibility(true);
|
setVisibility(true);
|
||||||
|
|||||||
@@ -2465,6 +2465,11 @@ export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
|
|||||||
export const QUERY_JOBS_IN_PRODUCTION = gql`
|
export const QUERY_JOBS_IN_PRODUCTION = gql`
|
||||||
query QUERY_JOBS_IN_PRODUCTION {
|
query QUERY_JOBS_IN_PRODUCTION {
|
||||||
jobs(where: { inproduction: { _eq: true } }) {
|
jobs(where: { inproduction: { _eq: true } }) {
|
||||||
|
tasks_aggregate(where: { completed: { _eq: false }, deleted: { _eq: false } }) {
|
||||||
|
aggregate {
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
id
|
id
|
||||||
updated_at
|
updated_at
|
||||||
comment
|
comment
|
||||||
|
|||||||
@@ -1160,7 +1160,8 @@
|
|||||||
"submit": "Submit",
|
"submit": "Submit",
|
||||||
"tryagain": "Try Again",
|
"tryagain": "Try Again",
|
||||||
"view": "View",
|
"view": "View",
|
||||||
"viewreleasenotes": "See What's Changed"
|
"viewreleasenotes": "See What's Changed",
|
||||||
|
"remove_alert": "Are you sure you want to dismiss the alert?"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"fcm": "You must allow notification permissions to have real time messaging. Click to try again.",
|
"fcm": "You must allow notification permissions to have real time messaging. Click to try again.",
|
||||||
@@ -2757,7 +2758,9 @@
|
|||||||
"total_lab_on_board": "Body Hours on Board",
|
"total_lab_on_board": "Body Hours on Board",
|
||||||
"total_lar_on_board": "Refinish Hours on Board",
|
"total_lar_on_board": "Refinish Hours on Board",
|
||||||
"total_amount_on_board": "Dollars on Board",
|
"total_amount_on_board": "Dollars on Board",
|
||||||
"total_jobs_on_board": "Jobs on Board"
|
"total_jobs_on_board": "Jobs on Board",
|
||||||
|
"tasks_in_production": "Tasks in Production",
|
||||||
|
"tasks_on_board": "Tasks on Board"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -2792,6 +2795,7 @@
|
|||||||
"model_info": "Vehicle Info",
|
"model_info": "Vehicle Info",
|
||||||
"actual_in": "Actual In",
|
"actual_in": "Actual In",
|
||||||
"alert": "Alert",
|
"alert": "Alert",
|
||||||
|
"tasks": "Tasks",
|
||||||
"alertoff": "Remove alert from Job",
|
"alertoff": "Remove alert from Job",
|
||||||
"alerton": "Add alert to Job",
|
"alerton": "Add alert to Job",
|
||||||
"ats": "Alternative Transportation",
|
"ats": "Alternative Transportation",
|
||||||
@@ -2845,6 +2849,9 @@
|
|||||||
"total_lar_on_board": "Refinish Hours on Board",
|
"total_lar_on_board": "Refinish Hours on Board",
|
||||||
"total_amount_on_board": "Dollars on Board",
|
"total_amount_on_board": "Dollars on Board",
|
||||||
"total_jobs_on_board": "Jobs on Board",
|
"total_jobs_on_board": "Jobs on Board",
|
||||||
|
"tasks_in_production": "Tasks in Production",
|
||||||
|
"tasks_on_board": "Tasks on Board",
|
||||||
|
"tasks": "Tasks",
|
||||||
"hours": "Hours",
|
"hours": "Hours",
|
||||||
"currency_symbol": "$",
|
"currency_symbol": "$",
|
||||||
"jobs": "Jobs"
|
"jobs": "Jobs"
|
||||||
|
|||||||
@@ -1160,7 +1160,8 @@
|
|||||||
"submit": "",
|
"submit": "",
|
||||||
"tryagain": "",
|
"tryagain": "",
|
||||||
"view": "",
|
"view": "",
|
||||||
"viewreleasenotes": ""
|
"viewreleasenotes": "",
|
||||||
|
"remove_alert": ""
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"fcm": "",
|
"fcm": "",
|
||||||
@@ -2757,7 +2758,9 @@
|
|||||||
"total_lab_on_board": "",
|
"total_lab_on_board": "",
|
||||||
"total_lar_on_board": "",
|
"total_lar_on_board": "",
|
||||||
"total_amount_on_board": "",
|
"total_amount_on_board": "",
|
||||||
"total_jobs_on_board": ""
|
"total_jobs_on_board": "",
|
||||||
|
"tasks_in_production": "",
|
||||||
|
"tasks_on_board": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -2792,6 +2795,7 @@
|
|||||||
"model_info": "",
|
"model_info": "",
|
||||||
"actual_in": "",
|
"actual_in": "",
|
||||||
"alert": "",
|
"alert": "",
|
||||||
|
"tasks": "",
|
||||||
"alertoff": "",
|
"alertoff": "",
|
||||||
"alerton": "",
|
"alerton": "",
|
||||||
"ats": "",
|
"ats": "",
|
||||||
@@ -2845,6 +2849,9 @@
|
|||||||
"total_lar_on_board": "",
|
"total_lar_on_board": "",
|
||||||
"total_amount_on_board": "",
|
"total_amount_on_board": "",
|
||||||
"total_jobs_on_board": "",
|
"total_jobs_on_board": "",
|
||||||
|
"tasks_in_production": "",
|
||||||
|
"tasks_on_board": "",
|
||||||
|
"tasks": "",
|
||||||
"hours": "",
|
"hours": "",
|
||||||
"currency_symbol": "",
|
"currency_symbol": "",
|
||||||
"jobs": ""
|
"jobs": ""
|
||||||
|
|||||||
@@ -1160,7 +1160,8 @@
|
|||||||
"submit": "",
|
"submit": "",
|
||||||
"tryagain": "",
|
"tryagain": "",
|
||||||
"view": "",
|
"view": "",
|
||||||
"viewreleasenotes": ""
|
"viewreleasenotes": "",
|
||||||
|
"remove_alert": ""
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"fcm": "",
|
"fcm": "",
|
||||||
@@ -2757,7 +2758,9 @@
|
|||||||
"total_lab_on_board": "",
|
"total_lab_on_board": "",
|
||||||
"total_lar_on_board": "",
|
"total_lar_on_board": "",
|
||||||
"total_amount_on_board": "",
|
"total_amount_on_board": "",
|
||||||
"total_jobs_on_board": ""
|
"total_jobs_on_board": "",
|
||||||
|
"tasks_in_production": "",
|
||||||
|
"tasks_on_board": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -2792,6 +2795,7 @@
|
|||||||
"model_info": "",
|
"model_info": "",
|
||||||
"actual_in": "",
|
"actual_in": "",
|
||||||
"alert": "",
|
"alert": "",
|
||||||
|
"tasks": "",
|
||||||
"alertoff": "",
|
"alertoff": "",
|
||||||
"alerton": "",
|
"alerton": "",
|
||||||
"ats": "",
|
"ats": "",
|
||||||
@@ -2845,6 +2849,9 @@
|
|||||||
"total_lar_on_board": "",
|
"total_lar_on_board": "",
|
||||||
"total_amount_on_board": "",
|
"total_amount_on_board": "",
|
||||||
"total_jobs_on_board": "",
|
"total_jobs_on_board": "",
|
||||||
|
"tasks_in_production": "",
|
||||||
|
"tasks_on_board": "",
|
||||||
|
"tasks": "",
|
||||||
"hours": "",
|
"hours": "",
|
||||||
"currency_symbol": "",
|
"currency_symbol": "",
|
||||||
"jobs": ""
|
"jobs": ""
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- UPDATE "public"."masterdata"
|
||||||
|
-- SET value = jsonb_set(
|
||||||
|
-- value::jsonb,
|
||||||
|
-- '{OP20}',
|
||||||
|
-- '{"desc": "REMOVE AND REINSTALL", "opcode": "OP20", "partcode": "PAE"}'::jsonb,
|
||||||
|
-- true
|
||||||
|
-- );
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
UPDATE "public"."masterdata"
|
||||||
|
SET value = jsonb_set(
|
||||||
|
value::jsonb,
|
||||||
|
'{OP20}',
|
||||||
|
'{"desc": "REMOVE AND REINSTALL", "opcode": "OP20", "partcode": "PAE"}'::jsonb,
|
||||||
|
true
|
||||||
|
);
|
||||||
@@ -273,7 +273,7 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
|
|||||||
return result && result.json && result.json.Bill;
|
return result && result.json && result.json.Bill;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("qbo-payables-error", "DEBUG", req.user.email, bill.id, {
|
logger.log("qbo-payables-error", "DEBUG", req.user.email, bill.id, {
|
||||||
error: (error && error.authResponse && error.authResponse.body) || (error && error.message),
|
error: error, //(error && error.authResponse && error.authResponse.body) || (error && error.message),
|
||||||
method: "InsertBill"
|
method: "InsertBill"
|
||||||
});
|
});
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const ftpSetup = {
|
|||||||
exports.default = async (req, res) => {
|
exports.default = async (req, res) => {
|
||||||
//Query for the List of Bodyshop Clients.
|
//Query for the List of Bodyshop Clients.
|
||||||
logger.log("kaizen-start", "DEBUG", "api", null, null);
|
logger.log("kaizen-start", "DEBUG", "api", null, null);
|
||||||
const kaizenShopsIDs = ["SUMMIT", "STRATHMORE", "SUNRIDGE"];
|
const kaizenShopsIDs = ["SUMMIT", "STRATHMORE", "SUNRIDGE", "SHAW"];
|
||||||
|
|
||||||
const { bodyshops } = await client.request(queries.GET_KAIZEN_SHOPS, {
|
const { bodyshops } = await client.request(queries.GET_KAIZEN_SHOPS, {
|
||||||
imexshopid: kaizenShopsIDs
|
imexshopid: kaizenShopsIDs
|
||||||
|
|||||||
Reference in New Issue
Block a user