@@ -1,47 +1,41 @@
|
||||
import {notification} from "antd";
|
||||
import { notification } from "antd";
|
||||
import i18n from "i18next";
|
||||
import {logImEXEvent} from "../../firebase/firebase.utils";
|
||||
import {UPDATE_JOB} from "../../graphql/jobs.queries";
|
||||
import {insertAuditTrail} from "../../redux/application/application.actions";
|
||||
import {store} from "../../redux/store";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||
import { store } from "../../redux/store";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
|
||||
export default function AddToProduction(
|
||||
apolloClient,
|
||||
jobId,
|
||||
completionCallback,
|
||||
remove = false
|
||||
) {
|
||||
logImEXEvent("job_add_to_production");
|
||||
export default function AddToProduction(apolloClient, jobId, completionCallback, remove = false) {
|
||||
logImEXEvent("job_add_to_production");
|
||||
|
||||
//get a list of all fields on the job
|
||||
apolloClient
|
||||
.mutate({
|
||||
mutation: UPDATE_JOB,
|
||||
variables: {jobId: jobId, job: {inproduction: !remove}},
|
||||
//get a list of all fields on the job
|
||||
apolloClient
|
||||
.mutate({
|
||||
mutation: UPDATE_JOB,
|
||||
variables: { jobId: jobId, job: { inproduction: !remove } }
|
||||
})
|
||||
.then((res) => {
|
||||
notification["success"]({
|
||||
message: i18n.t("jobs.successes.save")
|
||||
});
|
||||
|
||||
store.dispatch(
|
||||
insertAuditTrail({
|
||||
jobid: jobId,
|
||||
operation: AuditTrailMapping.jobinproductionchange(!remove),
|
||||
type: "jobinproductionchange"
|
||||
})
|
||||
.then((res) => {
|
||||
notification["success"]({
|
||||
message: i18n.t("jobs.successes.save"),
|
||||
});
|
||||
|
||||
store.dispatch(
|
||||
insertAuditTrail({
|
||||
jobid: jobId,
|
||||
operation: AuditTrailMapping.jobinproductionchange(!remove),
|
||||
type: "jobinproductionchange",
|
||||
})
|
||||
);
|
||||
if (completionCallback) completionCallback();
|
||||
);
|
||||
if (completionCallback) completionCallback();
|
||||
})
|
||||
.catch((error) => {
|
||||
notification["errors"]({
|
||||
message: i18n.t("jobs.errors.saving", {
|
||||
error: JSON.stringify(error)
|
||||
})
|
||||
.catch((error) => {
|
||||
notification["errors"]({
|
||||
message: i18n.t("jobs.errors.saving", {
|
||||
error: JSON.stringify(error),
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
//insert the new job. call the callback with the returned ID when done.
|
||||
});
|
||||
});
|
||||
|
||||
//insert the new job. call the callback with the returned ID when done.
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,138 +1,124 @@
|
||||
import Axios from "axios";
|
||||
import _ from "lodash";
|
||||
import {logImEXEvent} from "../../firebase/firebase.utils";
|
||||
import {INSERT_NEW_JOB, QUERY_JOB_FOR_DUPE} from "../../graphql/jobs.queries";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { INSERT_NEW_JOB, QUERY_JOB_FOR_DUPE } from "../../graphql/jobs.queries";
|
||||
import dayjs from "../../utils/day";
|
||||
import i18n from "i18next";
|
||||
|
||||
export default async function DuplicateJob(
|
||||
apolloClient,
|
||||
jobId,
|
||||
config,
|
||||
completionCallback,
|
||||
keepJobLines = false
|
||||
) {
|
||||
logImEXEvent("job_duplicate");
|
||||
export default async function DuplicateJob(apolloClient, jobId, config, completionCallback, keepJobLines = false) {
|
||||
logImEXEvent("job_duplicate");
|
||||
|
||||
const {defaultOpenStatus} = config;
|
||||
//get a list of all fields on the job
|
||||
const res = await apolloClient.query({
|
||||
query: QUERY_JOB_FOR_DUPE,
|
||||
variables: {id: jobId},
|
||||
});
|
||||
const { defaultOpenStatus } = config;
|
||||
//get a list of all fields on the job
|
||||
const res = await apolloClient.query({
|
||||
query: QUERY_JOB_FOR_DUPE,
|
||||
variables: { id: jobId }
|
||||
});
|
||||
|
||||
const {jobs_by_pk} = res.data;
|
||||
const existingJob = _.cloneDeep(jobs_by_pk);
|
||||
delete existingJob.__typename;
|
||||
delete existingJob.id;
|
||||
delete existingJob.createdat;
|
||||
delete existingJob.updatedat;
|
||||
delete existingJob.cieca_stl;
|
||||
delete existingJob.cieca_ttl;
|
||||
const { jobs_by_pk } = res.data;
|
||||
const existingJob = _.cloneDeep(jobs_by_pk);
|
||||
delete existingJob.__typename;
|
||||
delete existingJob.id;
|
||||
delete existingJob.createdat;
|
||||
delete existingJob.updatedat;
|
||||
delete existingJob.cieca_stl;
|
||||
delete existingJob.cieca_ttl;
|
||||
|
||||
const newJob = {
|
||||
...existingJob,
|
||||
status: defaultOpenStatus,
|
||||
};
|
||||
const newJob = {
|
||||
...existingJob,
|
||||
status: defaultOpenStatus
|
||||
};
|
||||
|
||||
const _tempLines = _.cloneDeep(existingJob.joblines);
|
||||
_tempLines.forEach((line) => {
|
||||
delete line.id;
|
||||
delete line.__typename;
|
||||
line.manual_line = true;
|
||||
});
|
||||
newJob.joblines = keepJobLines ? _tempLines : [];
|
||||
const _tempLines = _.cloneDeep(existingJob.joblines);
|
||||
_tempLines.forEach((line) => {
|
||||
delete line.id;
|
||||
delete line.__typename;
|
||||
line.manual_line = true;
|
||||
});
|
||||
newJob.joblines = keepJobLines ? _tempLines : [];
|
||||
|
||||
delete newJob.joblines;
|
||||
newJob.joblines = keepJobLines ? {data: _tempLines} : null;
|
||||
delete newJob.joblines;
|
||||
newJob.joblines = keepJobLines ? { data: _tempLines } : null;
|
||||
|
||||
const res2 = await apolloClient.mutate({
|
||||
mutation: INSERT_NEW_JOB,
|
||||
variables: {job: [newJob]},
|
||||
});
|
||||
await Axios.post("/job/totalsssu", {
|
||||
id: res2.data.insert_jobs.returning[0].id,
|
||||
});
|
||||
const res2 = await apolloClient.mutate({
|
||||
mutation: INSERT_NEW_JOB,
|
||||
variables: { job: [newJob] }
|
||||
});
|
||||
await Axios.post("/job/totalsssu", {
|
||||
id: res2.data.insert_jobs.returning[0].id
|
||||
});
|
||||
|
||||
if (completionCallback)
|
||||
completionCallback(res2.data.insert_jobs.returning[0].id);
|
||||
if (completionCallback) completionCallback(res2.data.insert_jobs.returning[0].id);
|
||||
|
||||
//insert the new job. call the callback with the returned ID when done.
|
||||
//insert the new job. call the callback with the returned ID when done.
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
export async function CreateIouForJob(
|
||||
apolloClient,
|
||||
jobId,
|
||||
config,
|
||||
jobLinesToKeep
|
||||
) {
|
||||
logImEXEvent("job_create_iou");
|
||||
export async function CreateIouForJob(apolloClient, jobId, config, jobLinesToKeep) {
|
||||
logImEXEvent("job_create_iou");
|
||||
|
||||
const {status} = config;
|
||||
//get a list of all fields on the job
|
||||
const res = await apolloClient.query({
|
||||
query: QUERY_JOB_FOR_DUPE,
|
||||
variables: {id: jobId},
|
||||
});
|
||||
const { status } = config;
|
||||
//get a list of all fields on the job
|
||||
const res = await apolloClient.query({
|
||||
query: QUERY_JOB_FOR_DUPE,
|
||||
variables: { id: jobId }
|
||||
});
|
||||
|
||||
const {jobs_by_pk} = res.data;
|
||||
const existingJob = _.cloneDeep(jobs_by_pk);
|
||||
delete existingJob.__typename;
|
||||
delete existingJob.id;
|
||||
delete existingJob.createdat;
|
||||
delete existingJob.updatedat;
|
||||
delete existingJob.cieca_stl;
|
||||
delete existingJob.cieca_ttl;
|
||||
const { jobs_by_pk } = res.data;
|
||||
const existingJob = _.cloneDeep(jobs_by_pk);
|
||||
delete existingJob.__typename;
|
||||
delete existingJob.id;
|
||||
delete existingJob.createdat;
|
||||
delete existingJob.updatedat;
|
||||
delete existingJob.cieca_stl;
|
||||
delete existingJob.cieca_ttl;
|
||||
|
||||
const newJob = {
|
||||
...existingJob,
|
||||
const newJob = {
|
||||
...existingJob,
|
||||
|
||||
converted: true,
|
||||
status: status,
|
||||
iouparent: jobId,
|
||||
date_open: dayjs(),
|
||||
audit_trails: {
|
||||
data: [
|
||||
{
|
||||
useremail: config.useremail,
|
||||
bodyshopid: config.bodyshopid,
|
||||
operation: i18n.t("audit_trail.messages.jobioucreated"),
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
converted: true,
|
||||
status: status,
|
||||
iouparent: jobId,
|
||||
date_open: dayjs(),
|
||||
audit_trails: {
|
||||
data: [
|
||||
{
|
||||
useremail: config.useremail,
|
||||
bodyshopid: config.bodyshopid,
|
||||
operation: i18n.t("audit_trail.messages.jobioucreated")
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const selectedJoblinesIds = jobLinesToKeep.map((l) => l.id);
|
||||
const selectedJoblinesIds = jobLinesToKeep.map((l) => l.id);
|
||||
|
||||
const _tempLines = _.cloneDeep(existingJob.joblines).filter((l) =>
|
||||
selectedJoblinesIds.includes(l.id)
|
||||
);
|
||||
_tempLines.forEach((line) => {
|
||||
delete line.id;
|
||||
delete line.__typename;
|
||||
line.oem_partno = `${line.oem_partno ? `${line.oem_partno} - ` : ``}IOU $${
|
||||
(line.act_price && line.act_price.toFixed(2)) || 0
|
||||
}/${line.mod_lb_hrs || 0}hrs`;
|
||||
line.act_price = 0;
|
||||
line.mod_lb_hrs = 0;
|
||||
line.manual_line = true;
|
||||
});
|
||||
const _tempLines = _.cloneDeep(existingJob.joblines).filter((l) => selectedJoblinesIds.includes(l.id));
|
||||
_tempLines.forEach((line) => {
|
||||
delete line.id;
|
||||
delete line.__typename;
|
||||
line.oem_partno = `${line.oem_partno ? `${line.oem_partno} - ` : ``}IOU $${
|
||||
(line.act_price && line.act_price.toFixed(2)) || 0
|
||||
}/${line.mod_lb_hrs || 0}hrs`;
|
||||
line.act_price = 0;
|
||||
line.mod_lb_hrs = 0;
|
||||
line.manual_line = true;
|
||||
});
|
||||
|
||||
delete newJob.joblines;
|
||||
newJob.joblines = {data: _tempLines};
|
||||
delete newJob.joblines;
|
||||
newJob.joblines = { data: _tempLines };
|
||||
|
||||
const res2 = await apolloClient.mutate({
|
||||
mutation: INSERT_NEW_JOB,
|
||||
variables: {job: [newJob]},
|
||||
});
|
||||
const res2 = await apolloClient.mutate({
|
||||
mutation: INSERT_NEW_JOB,
|
||||
variables: { job: [newJob] }
|
||||
});
|
||||
|
||||
Axios.post("/job/totalsssu", {
|
||||
id: res2.data.insert_jobs.returning[0].id,
|
||||
});
|
||||
Axios.post("/job/totalsssu", {
|
||||
id: res2.data.insert_jobs.returning[0].id
|
||||
});
|
||||
|
||||
//insert the new job. call the callback with the returned ID when done.
|
||||
//insert the new job. call the callback with the returned ID when done.
|
||||
|
||||
return res2.data.insert_jobs.returning[0].id;
|
||||
return res2.data.insert_jobs.returning[0].id;
|
||||
}
|
||||
|
||||
@@ -1,33 +1,28 @@
|
||||
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';
|
||||
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,
|
||||
jobRO: selectJobReadOnly
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
insertAuditTrail: ({ jobid, operation }) => dispatch(insertAuditTrail({ jobid, operation })),
|
||||
insertAuditTrail: ({ jobid, operation }) => dispatch(insertAuditTrail({ jobid, operation }))
|
||||
});
|
||||
|
||||
export function JobsDetailHeaderActionsToggleProduction({
|
||||
bodyshop,
|
||||
job,
|
||||
jobRO,
|
||||
insertAuditTrail,
|
||||
}) {
|
||||
export function JobsDetailHeaderActionsToggleProduction({ bodyshop, job, jobRO, insertAuditTrail }) {
|
||||
const [scenario, setScenario] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [mutationUpdateJob] = useMutation(JOB_PRODUCTION_TOGGLE);
|
||||
@@ -38,11 +33,11 @@ export function JobsDetailHeaderActionsToggleProduction({
|
||||
//Figure out what scenario were in, populate accodingly
|
||||
if (job && bodyshop) {
|
||||
if (bodyshop.md_ro_statuses.pre_production_statuses.includes(job.status)) {
|
||||
setScenario('pre');
|
||||
setScenario("pre");
|
||||
} else if (bodyshop.md_ro_statuses.production_statuses.includes(job.status)) {
|
||||
setScenario('prod');
|
||||
setScenario("prod");
|
||||
} else {
|
||||
setScenario('post');
|
||||
setScenario("post");
|
||||
}
|
||||
}
|
||||
}, [job, setScenario, bodyshop]);
|
||||
@@ -55,23 +50,21 @@ export function JobsDetailHeaderActionsToggleProduction({
|
||||
job: {
|
||||
...values,
|
||||
status:
|
||||
scenario === 'pre'
|
||||
? bodyshop.md_ro_statuses.default_arrived
|
||||
: bodyshop.md_ro_statuses.default_delivered,
|
||||
inproduction: scenario === 'pre' ? true : false,
|
||||
},
|
||||
},
|
||||
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'),
|
||||
notification["success"]({
|
||||
message: t("jobs.successes.converted")
|
||||
});
|
||||
|
||||
insertAuditTrail({
|
||||
jobid: job.id,
|
||||
operation:
|
||||
scenario === 'pre'
|
||||
scenario === "pre"
|
||||
? AuditTrailMapping.jobintake(
|
||||
res.data.update_jobs.returning[0].status,
|
||||
DateTimeFormatterFunction(values.scheduled_completion)
|
||||
@@ -79,7 +72,7 @@ export function JobsDetailHeaderActionsToggleProduction({
|
||||
: AuditTrailMapping.jobdelivery(
|
||||
res.data.update_jobs.returning[0].status,
|
||||
DateTimeFormatterFunction(values.actual_completion)
|
||||
),
|
||||
)
|
||||
});
|
||||
}
|
||||
setLoading(false);
|
||||
@@ -96,56 +89,56 @@ export function JobsDetailHeaderActionsToggleProduction({
|
||||
scheduled_completion: job.scheduled_completion,
|
||||
actual_completion: job.actual_completion,
|
||||
scheduled_deliver: job.scheduled_deliver,
|
||||
actual_delivery: job.actual_delivery,
|
||||
actual_delivery: job.actual_delivery
|
||||
}}
|
||||
>
|
||||
{scenario === 'pre' && (
|
||||
{scenario === "pre" && (
|
||||
<>
|
||||
<Form.Item
|
||||
name={['actual_in']}
|
||||
label={t('jobs.fields.actual_in')}
|
||||
name={["actual_in"]}
|
||||
label={t("jobs.fields.actual_in")}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
required: true
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
}
|
||||
]}
|
||||
>
|
||||
<FormDateTimePickerComponent disabled={jobRO} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name={['scheduled_completion']}
|
||||
label={t('jobs.fields.scheduled_completion')}
|
||||
name={["scheduled_completion"]}
|
||||
label={t("jobs.fields.scheduled_completion")}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
required: true
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
}
|
||||
]}
|
||||
>
|
||||
<FormDateTimePickerComponent disabled={jobRO} />
|
||||
</Form.Item>
|
||||
<Form.Item name={['scheduled_delivery']} label={t('jobs.fields.scheduled_delivery')}>
|
||||
<Form.Item name={["scheduled_delivery"]} label={t("jobs.fields.scheduled_delivery")}>
|
||||
<FormDateTimePickerComponent disabled={jobRO} />
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
{scenario === 'prod' && (
|
||||
{scenario === "prod" && (
|
||||
<>
|
||||
<Form.Item
|
||||
name={['actual_completion']}
|
||||
label={t('jobs.fields.actual_completion')}
|
||||
name={["actual_completion"]}
|
||||
label={t("jobs.fields.actual_completion")}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
required: true
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
}
|
||||
]}
|
||||
>
|
||||
<FormDateTimePickerComponent disabled={jobRO} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name={['actual_delivery']} label={t('jobs.fields.actual_delivery')}>
|
||||
<Form.Item name={["actual_delivery"]} label={t("jobs.fields.actual_delivery")}>
|
||||
<FormDateTimePickerComponent disabled={jobRO} />
|
||||
</Form.Item>
|
||||
</>
|
||||
@@ -153,15 +146,15 @@ export function JobsDetailHeaderActionsToggleProduction({
|
||||
|
||||
<Space wrap>
|
||||
<Button type="primary" onClick={() => form.submit()} loading={loading}>
|
||||
{t('general.actions.save')}
|
||||
{t("general.actions.save")}
|
||||
</Button>
|
||||
<Button
|
||||
disabled={scenario === 'post'}
|
||||
disabled={scenario === "post"}
|
||||
onClick={() => {
|
||||
// setOpen(false);
|
||||
// setOpen(false);
|
||||
}}
|
||||
>
|
||||
{t('general.actions.close')}
|
||||
{t("general.actions.close")}
|
||||
</Button>
|
||||
</Space>
|
||||
</Form>
|
||||
@@ -175,13 +168,10 @@ export function JobsDetailHeaderActionsToggleProduction({
|
||||
getPopupContainer={(trigger) => trigger.parentNode}
|
||||
trigger="click"
|
||||
>
|
||||
{scenario === 'pre' && t('jobs.actions.intake')}
|
||||
{scenario === 'prod' && t('jobs.actions.deliver')}
|
||||
{scenario === "pre" && t("jobs.actions.intake")}
|
||||
{scenario === "prod" && t("jobs.actions.deliver")}
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(JobsDetailHeaderActionsToggleProduction);
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(JobsDetailHeaderActionsToggleProduction);
|
||||
|
||||
Reference in New Issue
Block a user