Files
bodyshop/client/src/pages/jobs-close/jobs-close.component.jsx
2022-01-03 10:49:01 -08:00

290 lines
9.1 KiB
JavaScript

import { useApolloClient, useMutation } from "@apollo/client";
import {
Button,
Form,
notification,
Popconfirm,
Space,
Alert,
Divider,
PageHeader,
InputNumber,
Input,
} from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
//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 JobsCloseLines from "../../components/jobs-close-lines/jobs-close-lines.component";
import { generateJobLinesUpdatesForInvoicing } from "../../graphql/jobs-lines.queries";
import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import LayoutFormRow from "../../components/layout-form-row/layout-form-row.component";
import DateTimePicker from "../../components/form-date-time-picker/form-date-time-picker.component";
import moment from "moment";
import { Link } from "react-router-dom";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
jobRO: selectJobReadOnly,
});
export function JobsCloseComponent({ job, bodyshop, jobRO }) {
const { t } = useTranslation();
const [form] = Form.useForm();
const client = useApolloClient();
// const history = useHistory();
const [closeJob] = useMutation(UPDATE_JOB);
const [loading, setLoading] = useState(false);
const handleFinish = async (values) => {
setLoading(true);
const result = await client.mutate({
mutation: generateJobLinesUpdatesForInvoicing(values.joblines),
});
if (result.errors) {
return; // Abandon the rest of the close.
}
const closeResult = await closeJob({
variables: {
jobId: job.id,
job: {
status: bodyshop.md_ro_statuses.default_invoiced || "",
date_invoiced: new Date(),
actual_in: values.actual_in,
actual_completion: values.actual_completion,
actual_delivery: values.actual_delivery,
kmin: values.kmin,
kmout: values.kmout,
dms_allocation: values.dms_allocation,
invoice_final_note: values.invoice_final_note,
},
},
refetchQueries: ["QUERY_JOB_CLOSE_DETAILS"],
awaitRefetchQueries: true,
});
if (!result.errors) {
// notification["success"]({ message: t("jobs.successes.save") });
// form.resetFields();
} else {
notification["error"]({
message: t("job.errors.saving", {
error: JSON.stringify(result.errors),
}),
});
return; // Abandon the rest of the close.
}
if (!closeResult.errors) {
setLoading(false);
notification["success"]({
message: t("jobs.successes.closed"),
});
// history.push(`/manage/jobs/${job.id}`);
} else {
setLoading(false);
notification["error"]({
message: t("job.errors.closing", {
error: JSON.stringify(closeResult.errors),
}),
});
}
form.resetFields();
form.resetFields();
setLoading(false);
};
return (
<div>
<Form
layout="vertical"
form={form}
onFinish={handleFinish}
initialValues={{
joblines: job.joblines,
actual_in: job.actual_in
? moment(job.actual_in)
: job.scheduled_in && moment(job.scheduled_in),
actual_completion: job.actual_completion
? moment(job.actual_completion)
: job.scheduled_completion && moment(job.scheduled_completion),
actual_delivery: job.actual_delivery
? moment(job.actual_delivery)
: job.scheduled_delivery && moment(job.scheduled_delivery),
kmin: job.kmin,
kmout: job.kmout,
dms_allocation: job.dms_allocation,
invoice_final_note: job.invoice_final_note,
}}
scrollToFirstError
>
<PageHeader
title={t("jobs.labels.closejob", { ro_number: job.ro_number })}
extra={
<Space>
<JobsCloseAutoAllocate
joblines={job.joblines}
form={form}
disabled={!!job.date_exported || jobRO}
/>
<Popconfirm
onConfirm={() => form.submit()}
disabled={jobRO}
okText={t("general.labels.yes")}
cancelText={t("general.labels.no")}
title={t("jobs.labels.closeconfirm")}
>
<Button loading={loading} type="danger" disabled={jobRO}>
{t("general.actions.close")}
</Button>
</Popconfirm>
{(bodyshop.pbs_serialnumber || bodyshop.cdk_dealerid) && (
<Link to={`/manage/dms?jobId=${job.id}`}>
<Button disabled={job.date_exported || !jobRO}>
{t("jobs.actions.sendtodms")}
</Button>
</Link>
)}
<JobsScoreboardAdd job={job} disabled={false} />
</Space>
}
/>
<Space wrap direction="vertical" style={{ width: "100%" }}>
<FormsFieldChanged form={form} />
{!job.actual_in && job.scheduled_in && (
<Alert
type="warning"
message={t("jobs.labels.actual_in_inferred")}
/>
)}
{!job.actual_completion && job.scheduled_completion && (
<Alert
type="warning"
message={t("jobs.labels.actual_completion_inferred")}
/>
)}
{!job.actual_delivery && job.scheduled_delivery && (
<Alert
type="warning"
message={t("jobs.labels.actual_delivery_inferred")}
/>
)}
</Space>
<LayoutFormRow>
<Form.Item
label={t("jobs.fields.actual_in")}
rules={[
{
required: true,
},
]}
name="actual_in"
>
<DateTimePicker disabled={jobRO} />
</Form.Item>
<Form.Item shouldUpdate>
{() => {
return (
<Form.Item
label={t("jobs.fields.actual_completion")}
name="actual_completion"
rules={[
{
required: true,
},
]}
>
<DateTimePicker disabled={jobRO} />
</Form.Item>
);
}}
</Form.Item>
<Form.Item
label={t("jobs.fields.actual_delivery")}
name="actual_delivery"
rules={[
{
required: true,
},
]}
>
<DateTimePicker disabled={jobRO} />
</Form.Item>
{(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
<Form.Item
label={t("jobs.fields.kmin")}
name="kmin"
rules={[
{
required: true,
},
]}
>
<InputNumber precision={0} disabled={jobRO} />
</Form.Item>
)}
{(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
<Form.Item
label={t("jobs.fields.kmout")}
name="kmout"
dependencies={["kmin"]}
hasFeedback
rules={[
{
required: true,
},
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue("kmin") <= value) {
return Promise.resolve();
}
return Promise.reject(
new Error(t("jobs.labels.dms.kmoutnotgreaterthankmin"))
);
},
}),
]}
>
<InputNumber precision={0} disabled={jobRO} />
</Form.Item>
)}
{(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
<Form.Item
label={t("jobs.fields.dms_allocation")}
name="dms_allocation"
rules={[
{
required: true,
},
]}
>
<Input disabled />
</Form.Item>
)}
<Form.Item
label={t("jobs.fields.invoice_final_note")}
name="invoice_final_note"
>
<Input.TextArea disabled={jobRO} />
</Form.Item>
</LayoutFormRow>
<Divider />
<JobsCloseLines job={job} />
</Form>
</div>
);
}
export default connect(mapStateToProps, null)(JobsCloseComponent);