Added job intake and delivery bypass.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<babeledit_project version="1.2" be_version="2.7.1">
|
||||
<babeledit_project be_version="2.7.1" version="1.2">
|
||||
<!--
|
||||
|
||||
BabelEdit project file
|
||||
@@ -1789,6 +1789,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>jobdelivery</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>jobfieldchanged</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -1852,6 +1873,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>jobintake</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>jobinvoiced</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
|
||||
@@ -29,6 +29,7 @@ import FormDateTimePickerComponent from "../form-date-time-picker/form-date-time
|
||||
import dayjs from "../../utils/day";
|
||||
import {useSplitTreatments} from "@splitsoftware/splitio-react";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import JobsDetailHeaderActionsToggleProduction from "./jobs-detail-header-actions.toggle-production";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -664,7 +665,14 @@ export function JobsDetailHeaderActions({
|
||||
label: <Link to={`/manage/jobs/${job.id}/checklist`}>
|
||||
{t("jobs.actions.viewchecklist")}
|
||||
</Link>
|
||||
},], rome: "USE_IMEX", promanager:[]}),
|
||||
},], rome: "USE_IMEX", promanager:[
|
||||
{
|
||||
key:'toggleproduction',
|
||||
disabled: !job.converted || jobRO,
|
||||
label: <JobsDetailHeaderActionsToggleProduction job={job} refetch={refetch} />
|
||||
}
|
||||
|
||||
]}),
|
||||
...(InstanceRenderManager({
|
||||
imex: true,
|
||||
rome: "USE_IMEX",
|
||||
@@ -808,7 +816,7 @@ export function JobsDetailHeaderActions({
|
||||
}
|
||||
]
|
||||
},
|
||||
... InstanceRenderManager({
|
||||
...InstanceRenderManager({
|
||||
imex: true,
|
||||
rome: true,
|
||||
promanager: HasFeatureAccess({ featureName: 'bills', bodyshop }),
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { Button, Form, notification, Popover, Space } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { connect } from 'react-redux';
|
||||
import { createStructuredSelector } from 'reselect';
|
||||
import { JOB_PRODUCTION_TOGGLE } from '../../graphql/jobs.queries';
|
||||
import { insertAuditTrail } from '../../redux/application/application.actions';
|
||||
import { selectJobReadOnly } from '../../redux/application/application.selectors';
|
||||
import { selectBodyshop } from '../../redux/user/user.selectors';
|
||||
import AuditTrailMapping from '../../utils/AuditTrailMappings';
|
||||
import { DateTimeFormatterFunction } from '../../utils/DateFormatter';
|
||||
import FormDateTimePickerComponent from '../form-date-time-picker/form-date-time-picker.component';
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser,
|
||||
bodyshop: selectBodyshop,
|
||||
jobRO: selectJobReadOnly,
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
insertAuditTrail: ({ jobid, operation }) => dispatch(insertAuditTrail({ jobid, operation })),
|
||||
});
|
||||
|
||||
export function JobsDetailHeaderActionsToggleProduction({
|
||||
bodyshop,
|
||||
job,
|
||||
jobRO,
|
||||
insertAuditTrail,
|
||||
}) {
|
||||
const [scenario, setScenario] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [mutationUpdateJob] = useMutation(JOB_PRODUCTION_TOGGLE);
|
||||
const { t } = useTranslation();
|
||||
const [form] = Form.useForm();
|
||||
|
||||
useEffect(() => {
|
||||
//Figure out what scenario were in, populate accodingly
|
||||
if (job && bodyshop) {
|
||||
if (bodyshop.md_ro_statuses.pre_production_statuses.includes(job.status)) {
|
||||
setScenario('pre');
|
||||
} else if (bodyshop.md_ro_statuses.production_statuses.includes(job.status)) {
|
||||
setScenario('prod');
|
||||
} else {
|
||||
setScenario('post');
|
||||
}
|
||||
}
|
||||
}, [job, setScenario, bodyshop]);
|
||||
|
||||
const handleConvert = async (values) => {
|
||||
setLoading(true);
|
||||
const res = await mutationUpdateJob({
|
||||
variables: {
|
||||
jobId: job.id,
|
||||
job: {
|
||||
...values,
|
||||
status:
|
||||
scenario === 'pre'
|
||||
? bodyshop.md_ro_statuses.default_arrived
|
||||
: bodyshop.md_ro_statuses.default_delivered,
|
||||
inproduction: scenario === 'pre' ? true : false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.errors) {
|
||||
notification['success']({
|
||||
message: t('jobs.successes.converted'),
|
||||
});
|
||||
|
||||
insertAuditTrail({
|
||||
jobid: job.id,
|
||||
operation:
|
||||
scenario === 'pre'
|
||||
? AuditTrailMapping.jobintake(
|
||||
res.data.update_jobs.returning[0].status,
|
||||
DateTimeFormatterFunction(values.scheduled_completion)
|
||||
)
|
||||
: AuditTrailMapping.jobdelivery(
|
||||
res.data.update_jobs.returning[0].status,
|
||||
DateTimeFormatterFunction(values.actual_completion)
|
||||
),
|
||||
});
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const popMenu = (
|
||||
<div onClick={(e) => e.stopPropagation()}>
|
||||
<Form
|
||||
layout="vertical"
|
||||
form={form}
|
||||
onFinish={handleConvert}
|
||||
initialValues={{
|
||||
actual_in: dayjs(),
|
||||
scheduled_completion: job.scheduled_completion,
|
||||
actual_completion: job.actual_completion,
|
||||
scheduled_deliver: job.scheduled_deliver,
|
||||
actual_delivery: job.actual_delivery,
|
||||
}}
|
||||
>
|
||||
{scenario === 'pre' && (
|
||||
<>
|
||||
<Form.Item
|
||||
name={['actual_in']}
|
||||
label={t('jobs.fields.actual_in')}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<FormDateTimePickerComponent disabled={jobRO} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name={['scheduled_completion']}
|
||||
label={t('jobs.fields.scheduled_completion')}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<FormDateTimePickerComponent disabled={jobRO} />
|
||||
</Form.Item>
|
||||
<Form.Item name={['scheduled_delivery']} label={t('jobs.fields.scheduled_delivery')}>
|
||||
<FormDateTimePickerComponent disabled={jobRO} />
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
{scenario === 'prod' && (
|
||||
<>
|
||||
<Form.Item
|
||||
name={['actual_completion']}
|
||||
label={t('jobs.fields.actual_completion')}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<FormDateTimePickerComponent disabled={jobRO} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name={['actual_delivery']} label={t('jobs.fields.actual_delivery')}>
|
||||
<FormDateTimePickerComponent disabled={jobRO} />
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Space wrap>
|
||||
<Button type="primary" onClick={() => form.submit()} loading={loading}>
|
||||
{t('general.actions.save')}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={scenario === 'post'}
|
||||
onClick={() => {
|
||||
// setOpen(false);
|
||||
}}
|
||||
>
|
||||
{t('general.actions.close')}
|
||||
</Button>
|
||||
</Space>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover //open={open}
|
||||
content={popMenu}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
getPopupContainer={(trigger) => trigger.parentNode}
|
||||
trigger="click"
|
||||
>
|
||||
{scenario === 'pre' && t('jobs.actions.intake')}
|
||||
{scenario === 'prod' && t('jobs.actions.deliver')}
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(JobsDetailHeaderActionsToggleProduction);
|
||||
@@ -1201,6 +1201,21 @@ export const UPDATE_JOB = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const JOB_PRODUCTION_TOGGLE = gql`
|
||||
mutation UPDATE_JOB($jobId: uuid!, $job: jobs_set_input!) {
|
||||
update_jobs(where: { id: { _eq: $jobId } }, _set: $job) {
|
||||
returning {
|
||||
id
|
||||
status
|
||||
inproduction
|
||||
actual_completion
|
||||
scheduled_delivery
|
||||
actual_delivery
|
||||
scheduled_completion
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const UPDATE_JOB_ASSIGNMENTS = gql`
|
||||
mutation UPDATE_JOB_ASSIGNMENTS($jobId: uuid!, $job: jobs_set_input!) {
|
||||
|
||||
@@ -116,9 +116,11 @@
|
||||
"jobassignmentremoved": "Employee assignment removed for {{operation}}",
|
||||
"jobchecklist": "Checklist type \"{{type}}\" completed. In production set to {{inproduction}}. Status set to {{status}}.",
|
||||
"jobconverted": "Job converted and assigned number {{ro_number}}.",
|
||||
"jobdelivery": "Job intake completed. Status set to {{status}}. Actual completion is {{actual_completion}}.",
|
||||
"jobfieldchanged": "Job field $t(jobs.fields.{{field}}) changed to {{value}}.",
|
||||
"jobimported": "Job imported.",
|
||||
"jobinproductionchange": "Job production status set to {{inproduction}}",
|
||||
"jobintake": "Job intake completed. Status set to {{status}}. Scheduled completion is {{scheduled_completion}}.",
|
||||
"jobinvoiced": "Job has been invoiced.",
|
||||
"jobioucreated": "IOU Created.",
|
||||
"jobmodifylbradj": "Labor adjustments modified {{mod_lbr_ty}} / {{hours}}.",
|
||||
|
||||
@@ -116,9 +116,11 @@
|
||||
"jobassignmentremoved": "",
|
||||
"jobchecklist": "",
|
||||
"jobconverted": "",
|
||||
"jobdelivery": "",
|
||||
"jobfieldchanged": "",
|
||||
"jobimported": "",
|
||||
"jobinproductionchange": "",
|
||||
"jobintake": "",
|
||||
"jobinvoiced": "",
|
||||
"jobioucreated": "",
|
||||
"jobmodifylbradj": "",
|
||||
|
||||
@@ -116,9 +116,11 @@
|
||||
"jobassignmentremoved": "",
|
||||
"jobchecklist": "",
|
||||
"jobconverted": "",
|
||||
"jobdelivery": "",
|
||||
"jobfieldchanged": "",
|
||||
"jobimported": "",
|
||||
"jobinproductionchange": "",
|
||||
"jobintake": "",
|
||||
"jobinvoiced": "",
|
||||
"jobioucreated": "",
|
||||
"jobmodifylbradj": "",
|
||||
|
||||
@@ -26,6 +26,10 @@ const AuditTrailMapping = {
|
||||
i18n.t("audit_trail.messages.jobchecklist", {type, inproduction, status}),
|
||||
jobconverted: (ro_number) =>
|
||||
i18n.t("audit_trail.messages.jobconverted", {ro_number}),
|
||||
jobintake: (status, email, scheduled_completion) =>
|
||||
i18n.t("audit_trail.messages.jobintake", {status, email,scheduled_completion}),
|
||||
jobdelivery: (status, email, actual_completion) =>
|
||||
i18n.t("audit_trail.messages.jobdelivery", {status, email,actual_completion}),
|
||||
jobfieldchange: (field, value) =>
|
||||
i18n.t("audit_trail.messages.jobfieldchanged", {field, value}),
|
||||
jobimported: () => i18n.t("audit_trail.messages.jobimported"),
|
||||
|
||||
Reference in New Issue
Block a user