From 1a9eddf7c60aa298df95ca6c4534ad7b2ad44be3 Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Wed, 5 May 2021 09:35:22 -0700 Subject: [PATCH] IO-990 Refactor job closing. --- .../jobs-change-status.component.jsx | 8 +++- client/src/graphql/jobs.queries.js | 2 + .../pages/jobs-close/jobs-close.component.jsx | 47 +++++++++---------- .../pages/jobs-close/jobs-close.container.jsx | 19 ++++++-- .../jobs-detail.page.container.jsx | 7 +-- client/src/utils/jobReadOnly.js | 4 ++ 6 files changed, 54 insertions(+), 33 deletions(-) create mode 100644 client/src/utils/jobReadOnly.js diff --git a/client/src/components/jobs-change-status/jobs-change-status.component.jsx b/client/src/components/jobs-change-status/jobs-change-status.component.jsx index 441f2f8a9..4ba09efcc 100644 --- a/client/src/components/jobs-change-status/jobs-change-status.component.jsx +++ b/client/src/components/jobs-change-status/jobs-change-status.component.jsx @@ -56,7 +56,13 @@ export function JobsChangeStatus({ job, bodyshop, jobRO }) { } else if ( bodyshop.md_ro_statuses.post_production_statuses.includes(job.status) ) { - setAvailableStatuses(bodyshop.md_ro_statuses.post_production_statuses); + setAvailableStatuses( + bodyshop.md_ro_statuses.post_production_statuses.filter( + (s) => + s !== bodyshop.md_ro_statuses.default_invoiced && + s !== bodyshop.md_ro_statuses.default_exported + ) + ); if (bodyshop.md_ro_statuses.production_statuses[0]) setOtherStages([bodyshop.md_ro_statuses.production_statuses[0]]); } else { diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js index bfa28ae1c..8eb2d24b7 100644 --- a/client/src/graphql/jobs.queries.js +++ b/client/src/graphql/jobs.queries.js @@ -1406,6 +1406,8 @@ export const QUERY_JOB_CLOSE_DETAILS = gql` rate_matd status date_exported + date_invoiced + voided joblines(where: { removed: { _eq: false } }) { id removed diff --git a/client/src/pages/jobs-close/jobs-close.component.jsx b/client/src/pages/jobs-close/jobs-close.component.jsx index a76adc926..0b6a6dd7b 100644 --- a/client/src/pages/jobs-close/jobs-close.component.jsx +++ b/client/src/pages/jobs-close/jobs-close.component.jsx @@ -3,12 +3,11 @@ import { Button, Form, notification, Popconfirm, Space } from "antd"; import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; -import { useHistory } from "react-router-dom"; +//import { useHistory } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import FormsFieldChanged from "../../components/form-fields-changed-alert/form-fields-changed-alert.component"; import JobsScoreboardAdd from "../../components/job-scoreboard-add-button/job-scoreboard-add-button.component"; import JobsCloseAutoAllocate from "../../components/jobs-close-auto-allocate/jobs-close-auto-allocate.component"; -import JobsCloseExportButton from "../../components/jobs-close-export-button/jobs-close-export-button.component"; import JobsCloseLines from "../../components/jobs-close-lines/jobs-close-lines.component"; import { generateJobLinesUpdatesForInvoicing } from "../../graphql/jobs-lines.queries"; import { UPDATE_JOB } from "../../graphql/jobs.queries"; @@ -23,12 +22,9 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) { const { t } = useTranslation(); const [form] = Form.useForm(); const client = useApolloClient(); - const history = useHistory(); + // const history = useHistory(); const [closeJob] = useMutation(UPDATE_JOB); const [loading, setLoading] = useState(false); - // useEffect(() => { - // //if (job && form) form.setFields({ joblines: job.joblines }); - // }, [job, form]); const handleFinish = async (values) => { setLoading(true); @@ -37,7 +33,7 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) { refetchQueries: ["QUERY_JOB_CLOSE_DETAILS"], awaitRefetchQueries: true, }); - if (!!!result.errors) { + if (!result.errors) { notification["success"]({ message: t("jobs.successes.save") }); // form.resetFields(); } else { @@ -46,15 +42,12 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) { error: JSON.stringify(result.errors), }), }); + return; // Abandon the rest of the close. } form.resetFields(); form.resetFields(); - setLoading(false); - }; - const handleClose = async () => { - setLoading(true); - const result = await closeJob({ + const closeResult = await closeJob({ variables: { jobId: job.id, job: { @@ -64,21 +57,23 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) { }, }); - if (!!!result.errors) { + if (!closeResult.errors) { setLoading(false); notification["success"]({ message: t("jobs.successes.closed"), }); - history.push(`/manage/jobs/${job.id}`); + // history.push(`/manage/jobs/${job.id}`); } else { setLoading(false); notification["error"]({ message: t("job.errors.closing", { - error: JSON.stringify(result.errors), + error: JSON.stringify(closeResult.errors), }), }); } + + setLoading(false); }; return ( @@ -97,16 +92,18 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) { disabled={!!job.date_exported || jobRO} /> - + { + // + } form.submit()} disabled={jobRO} okText={t("general.labels.yes")} cancelText={t("general.labels.no")} @@ -118,7 +115,9 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) { - + { + // + } diff --git a/client/src/pages/jobs-close/jobs-close.container.jsx b/client/src/pages/jobs-close/jobs-close.container.jsx index 0353cc046..bc224cc82 100644 --- a/client/src/pages/jobs-close/jobs-close.container.jsx +++ b/client/src/pages/jobs-close/jobs-close.container.jsx @@ -1,32 +1,44 @@ import { useQuery } from "@apollo/client"; +import { Result } from "antd"; import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { useParams } from "react-router-dom"; import AlertComponent from "../../components/alert/alert.component"; +import JobCalculateTotals from "../../components/job-calculate-totals/job-calculate-totals.component"; import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component"; import NotFound from "../../components/not-found/not-found.component"; import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component"; import { QUERY_JOB_CLOSE_DETAILS } from "../../graphql/jobs.queries"; import { setBreadcrumbs, + setJobReadOnly, setSelectedHeader, } from "../../redux/application/application.actions"; +import IsJobReadOnly from "../../utils/jobReadOnly"; import JobsCloseComponent from "./jobs-close.component"; -import { Result } from "antd"; -import JobCalculateTotals from "../../components/job-calculate-totals/job-calculate-totals.component"; const mapDispatchToProps = (dispatch) => ({ setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)), setSelectedHeader: (key) => dispatch(setSelectedHeader(key)), + setJobReadOnly: (bool) => dispatch(setJobReadOnly(bool)), }); -export function JobsCloseContainer({ setBreadcrumbs, setSelectedHeader }) { +export function JobsCloseContainer({ + setBreadcrumbs, + setSelectedHeader, + setJobReadOnly, +}) { const { jobId } = useParams(); const { loading, error, data } = useQuery(QUERY_JOB_CLOSE_DETAILS, { variables: { id: jobId }, }); const { t } = useTranslation(); + useEffect(() => { + if (data && data.jobs_by_pk) { + setJobReadOnly(IsJobReadOnly(data.jobs_by_pk)); + } + }, [data, setJobReadOnly]); useEffect(() => { setSelectedHeader("activejobs"); document.title = t("titles.jobs-close", { @@ -54,6 +66,7 @@ export function JobsCloseContainer({ setBreadcrumbs, setSelectedHeader }) { if (loading) return ; if (error) return ; if (!!!data.jobs_by_pk) return ; + if (!data.jobs_by_pk.job_totals) return (