Merged in feature/2021-08-06 (pull request #160)

Feature/2021 08 06
This commit is contained in:
Patrick Fic
2021-08-05 16:18:03 +00:00
11 changed files with 112 additions and 35 deletions

View File

@@ -8144,6 +8144,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>allow_text_message</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> <concept_node>
<name>checklist</name> <name>checklist</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -18,6 +18,7 @@ import DateTimePicker from "../../../form-date-time-picker/form-date-time-picker
import moment from "moment-business-days"; import moment from "moment-business-days";
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 { UPDATE_OWNER } from "../../../../graphql/owners.queries";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
@@ -41,6 +42,8 @@ export function JobChecklistForm({
const [intakeJob] = useMutation(UPDATE_JOB); const [intakeJob] = useMutation(UPDATE_JOB);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [markAptArrived] = useMutation(MARK_LATEST_APPOINTMENT_AS_ARRIVED); const [markAptArrived] = useMutation(MARK_LATEST_APPOINTMENT_AS_ARRIVED);
const [updateOwner] = useMutation(UPDATE_OWNER);
const { jobId } = useParams(); const { jobId } = useParams();
const history = useHistory(); const history = useHistory();
const search = queryString.parse(useLocation().search); const search = queryString.parse(useLocation().search);
@@ -114,6 +117,23 @@ export function JobChecklistForm({
}); });
} }
} }
//Updae Owner Allow to Text
const updateOwnerResult = await updateOwner({
variables: {
ownerId: job.owner.id,
owner: { allow_text_message: values.allow_text_message },
},
});
if (!!updateOwnerResult.errors) {
notification["error"]({
message: t("checklist.errors.complete", {
error: JSON.stringify(result.errors),
}),
});
}
setLoading(false); setLoading(false);
if (!!!result.errors) { if (!!!result.errors) {
@@ -156,6 +176,7 @@ export function JobChecklistForm({
initialValues={{ initialValues={{
...(type === "intake" && { ...(type === "intake" && {
addToProduction: true, addToProduction: true,
allow_text_message: job.owner.allow_text_message,
scheduled_completion: scheduled_completion:
(job && job.scheduled_completion) || (job && job.scheduled_completion) ||
moment().businessAdd( moment().businessAdd(
@@ -191,6 +212,14 @@ export function JobChecklistForm({
> >
<Switch disabled={readOnly} /> <Switch disabled={readOnly} />
</Form.Item> </Form.Item>
<Form.Item
name="allow_text_message"
valuePropName="checked"
label={t("checklist.labels.allow_text_message")}
disabled={readOnly}
>
<Switch disabled={readOnly} />
</Form.Item>
<Form.Item <Form.Item
name="scheduled_completion" name="scheduled_completion"
label={t("jobs.fields.scheduled_completion")} label={t("jobs.fields.scheduled_completion")}

View File

@@ -75,7 +75,7 @@ export function JobsAvailableContainer({
const client = useApolloClient(); const client = useApolloClient();
const estDataLazyLoad = useLazyQuery(QUERY_AVAILABLE_NEW_JOBS_EST_DATA_BY_PK); const estDataLazyLoad = useLazyQuery(QUERY_AVAILABLE_NEW_JOBS_EST_DATA_BY_PK);
const [loadEstData, estData] = estDataLazyLoad; const [loadEstData, estDataRaw] = estDataLazyLoad;
const importOptionsState = useState({ overrideHeaders: false }); const importOptionsState = useState({ overrideHeaders: false });
const importOptions = importOptionsState[0]; const importOptions = importOptionsState[0];
@@ -88,11 +88,13 @@ export function JobsAvailableContainer({
setOwnerModalVisible(false); setOwnerModalVisible(false);
setInsertLoading(true); setInsertLoading(true);
const estData = replaceEmpty(estDataRaw.data.available_jobs_by_pk);
if ( if (
!( !(
estData.data &&
estData.data.available_jobs_by_pk && estData &&
estData.data.available_jobs_by_pk.est_data estData.est_data
) )
) { ) {
//We don't have the right data. Error! //We don't have the right data. Error!
@@ -106,28 +108,28 @@ export function JobsAvailableContainer({
const newTotals = ( const newTotals = (
await Axios.post("/job/totals", { await Axios.post("/job/totals", {
job: { job: {
...estData.data.available_jobs_by_pk.est_data, ...estData.est_data,
joblines: estData.data.available_jobs_by_pk.est_data.joblines.data, joblines: estData.est_data.joblines.data,
}, },
}) })
).data; ).data;
let existingVehicles; let existingVehicles;
if ( if (
estData.data.available_jobs_by_pk.est_data.vehicle && estData.est_data.vehicle &&
estData.data.available_jobs_by_pk.est_data.vin estData.est_data.vin
) { ) {
//There's vehicle data, need to double check the VIN. //There's vehicle data, need to double check the VIN.
existingVehicles = await client.query({ existingVehicles = await client.query({
query: SEARCH_VEHICLE_BY_VIN, query: SEARCH_VEHICLE_BY_VIN,
variables: { variables: {
vin: estData.data.available_jobs_by_pk.est_data.vehicle.data.v_vin, vin: estData.est_data.vehicle.data.v_vin,
}, },
}); });
} }
const newJob = { const newJob = {
...estData.data.available_jobs_by_pk.est_data, ...estData.est_data,
clm_total: Dinero(newTotals.totals.total_repairs).toFormat("0.00"), clm_total: Dinero(newTotals.totals.total_repairs).toFormat("0.00"),
owner_owing: Dinero(newTotals.totals.custPayable.total).toFormat("0.00"), owner_owing: Dinero(newTotals.totals.custPayable.total).toFormat("0.00"),
job_totals: newTotals, job_totals: newTotals,
@@ -172,7 +174,7 @@ export function JobsAvailableContainer({
}); });
deleteJob({ deleteJob({
variables: { id: estData.data.available_jobs_by_pk.id }, variables: { id: estData.id },
}).then((r) => { }).then((r) => {
refetch(); refetch();
setInsertLoading(false); setInsertLoading(false);
@@ -194,12 +196,12 @@ export function JobsAvailableContainer({
setJobModalVisible(false); setJobModalVisible(false);
setInsertLoading(true); setInsertLoading(true);
const estData = replaceEmpty(estDataRaw.data.available_jobs_by_pk);
if ( if (
!( !(
estData.data &&
estData.data.available_jobs_by_pk && estData &&
estData.data.available_jobs_by_pk.est_data estData.est_data
) )
) { ) {
//We don't have the right data. Error! //We don't have the right data. Error!
@@ -209,7 +211,7 @@ export function JobsAvailableContainer({
}); });
} else { } else {
//create upsert job //create upsert job
let supp = _.cloneDeep(estData.data.available_jobs_by_pk.est_data); let supp = _.cloneDeep(estData.est_data);
delete supp.owner; delete supp.owner;
delete supp.vehicle; delete supp.vehicle;
@@ -220,7 +222,7 @@ export function JobsAvailableContainer({
let suppDelta = await GetSupplementDelta( let suppDelta = await GetSupplementDelta(
client, client,
selectedJob, selectedJob,
estData.data.available_jobs_by_pk.est_data.joblines.data estData.est_data.joblines.data
); );
delete supp.joblines; delete supp.joblines;
@@ -279,7 +281,7 @@ export function JobsAvailableContainer({
//Job has been inserted. Clean up the available jobs record. //Job has been inserted. Clean up the available jobs record.
deleteJob({ deleteJob({
variables: { id: estData.data.available_jobs_by_pk.id }, variables: { id: estData.id },
}).then((r) => { }).then((r) => {
refetch(); refetch();
setInsertLoading(false); setInsertLoading(false);
@@ -305,13 +307,13 @@ export function JobsAvailableContainer({
}; };
const owner = const owner =
estData.data && estDataRaw.data &&
estData.data.available_jobs_by_pk && estDataRaw.data.available_jobs_by_pk &&
estData.data.available_jobs_by_pk.est_data && estDataRaw.data.available_jobs_by_pk.est_data &&
estData.data.available_jobs_by_pk.est_data.owner && estDataRaw.data.available_jobs_by_pk.est_data.owner &&
estData.data.available_jobs_by_pk.est_data.owner.data && estDataRaw.data.available_jobs_by_pk.est_data.owner.data &&
!estData.data.available_jobs_by_pk.issupplement !estDataRaw.data.available_jobs_by_pk.issupplement
? estData.data.available_jobs_by_pk.est_data.owner.data ? estDataRaw.data.available_jobs_by_pk.est_data.owner.data
: null; : null;
const onOwnerModalCancel = () => { const onOwnerModalCancel = () => {
@@ -349,8 +351,8 @@ export function JobsAvailableContainer({
message={t("jobs.labels.creating_new_job")} message={t("jobs.labels.creating_new_job")}
> >
<OwnerFindModalContainer <OwnerFindModalContainer
loading={estData.loading} loading={estDataRaw.loading}
error={estData.error} error={estDataRaw.error}
owner={owner} owner={owner}
selectedOwner={selectedOwner} selectedOwner={selectedOwner}
setSelectedOwner={setSelectedOwner} setSelectedOwner={setSelectedOwner}
@@ -359,8 +361,8 @@ export function JobsAvailableContainer({
onCancel={onOwnerModalCancel} onCancel={onOwnerModalCancel}
/> />
<JobsFindModalContainer <JobsFindModalContainer
loading={estData.loading} loading={estDataRaw.loading}
error={estData.error} error={estDataRaw.error}
selectedJob={selectedJob} selectedJob={selectedJob}
setSelectedJob={setSelectedJob} setSelectedJob={setSelectedJob}
importOptionsState={importOptionsState} importOptionsState={importOptionsState}
@@ -390,3 +392,12 @@ export default connect(
mapStateToProps, mapStateToProps,
mapDispatchToProps mapDispatchToProps
)(JobsAvailableContainer); )(JobsAvailableContainer);
function replaceEmpty(someObj, replaceValue = null) {
const replacer = (key, value) => (value === "" ? replaceValue : value);
//^ because you seem to want to replace (strings) "null" or "undefined" too
console.log(someObj)
const temp = JSON.stringify(someObj, replacer);
console.log(`temp`, temp);
return JSON.parse(temp);
}

View File

@@ -25,6 +25,7 @@ export function ProductionListTable({
currentUser, currentUser,
state, state,
setColumns, setColumns,
setState,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [updateDefaultProdView] = useMutation(UPDATE_ACTIVE_PROD_LIST_VIEW); const [updateDefaultProdView] = useMutation(UPDATE_ACTIVE_PROD_LIST_VIEW);
@@ -43,6 +44,10 @@ export function ProductionListTable({
}; };
}) })
); );
setState(
bodyshop.production_config.filter((pc) => pc.name === value)[0].columns
.tableState
);
const assoc = bodyshop.associations.find( const assoc = bodyshop.associations.find(
(a) => a.useremail === currentUser.email (a) => a.useremail === currentUser.email
@@ -77,6 +82,8 @@ export function ProductionListTable({
}; };
}) })
); );
setState(bodyshop.production_config[0].columns.tableState);
}; };
return ( return (

View File

@@ -41,9 +41,9 @@ export function ProductionListTable({
const [state, setState] = useState( const [state, setState] = useState(
(bodyshop.production_config && (bodyshop.production_config &&
bodyshop.production_config.find((p) => p.name === defaultView) bodyshop.production_config.find((p) => p.name === defaultView)?.columns
?.tableState) || .tableState) ||
bodyshop.production_config[0]?.tableState || { bodyshop.production_config[0]?.columns.tableState || {
sortedInfo: {}, sortedInfo: {},
filteredInfo: { text: "" }, filteredInfo: { text: "" },
} }
@@ -155,7 +155,7 @@ export function ProductionListTable({
// } // }
// }; // };
if (!!!columns) return <div>No columns found.</div>; if (!!!columns || columns.length === 0) return <div>No columns found.</div>;
return ( return (
<div> <div>
@@ -173,6 +173,7 @@ export function ProductionListTable({
<ProductionListTableViewSelect <ProductionListTableViewSelect
state={state} state={state}
setState={setState}
setColumns={setColumns} setColumns={setColumns}
/> />

View File

@@ -105,7 +105,8 @@ export function TimeTicketList({
title: t("jobs.fields.ro_number"), title: t("jobs.fields.ro_number"),
dataIndex: "ro_number", dataIndex: "ro_number",
key: "ro_number", key: "ro_number",
sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number), sorter: (a, b) =>
alphaSort(a.job && a.job.ro_number, b.job && b.job.ro_number),
sortOrder: sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order, state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
render: (text, record) => render: (text, record) =>

View File

@@ -208,6 +208,10 @@ export const QUERY_INTAKE_CHECKLIST = gql`
scheduled_delivery scheduled_delivery
intakechecklist intakechecklist
status status
owner {
allow_text_message
id
}
labhrs: joblines_aggregate( labhrs: joblines_aggregate(
where: { where: {
_and: [{ mod_lbr_ty: { _neq: "LAR" } }, { removed: { _eq: false } }] _and: [{ mod_lbr_ty: { _neq: "LAR" } }, { removed: { _eq: false } }]

View File

@@ -512,6 +512,7 @@
}, },
"labels": { "labels": {
"addtoproduction": "Add Job to Production?", "addtoproduction": "Add Job to Production?",
"allow_text_message": "Permission to Text?",
"checklist": "Checklist", "checklist": "Checklist",
"printpack": "Job Intake Print Pack", "printpack": "Job Intake Print Pack",
"removefromproduction": "Remove job from production?" "removefromproduction": "Remove job from production?"

View File

@@ -512,6 +512,7 @@
}, },
"labels": { "labels": {
"addtoproduction": "", "addtoproduction": "",
"allow_text_message": "",
"checklist": "", "checklist": "",
"printpack": "", "printpack": "",
"removefromproduction": "" "removefromproduction": ""

View File

@@ -512,6 +512,7 @@
}, },
"labels": { "labels": {
"addtoproduction": "", "addtoproduction": "",
"allow_text_message": "",
"checklist": "", "checklist": "",
"printpack": "", "printpack": "",
"removefromproduction": "" "removefromproduction": ""

View File

@@ -48,7 +48,7 @@ const roundTripLink = new ApolloLink((operation, forward) => {
}); });
const TrackExecutionTime = async (operationName, time) => { const TrackExecutionTime = async (operationName, time) => {
await axios.post("/ioevent", { operationName, time, dbevent: true }); //await axios.post("/ioevent", { operationName, time, dbevent: true });
}; };
const subscriptionMiddleware = { const subscriptionMiddleware = {