BOD-50 Added duplication functionality for a job.

This commit is contained in:
Patrick Fic
2020-04-20 17:23:02 -07:00
parent 0063e25bfa
commit 5303ab0114
8 changed files with 396 additions and 8 deletions

View File

@@ -8593,6 +8593,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>duplicateconfirm</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>existing_jobs</name>
<definition_loaded>false</definition_loaded>
@@ -9526,6 +9547,27 @@
<folder_node>
<name>jobsactions</name>
<children>
<concept_node>
<name>duplicate</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>newcccontract</name>
<definition_loaded>false</definition_loaded>

View File

@@ -1,23 +1,60 @@
import React from "react";
import { Menu, Dropdown, Button } from "antd";
import { Menu, Dropdown, Button, Popconfirm } from "antd";
import { useTranslation } from "react-i18next";
import { DownCircleFilled } from "@ant-design/icons";
import { Link } from "react-router-dom";
import DuplicateJob from "./jobs-detail-header-actions.duplicate";
import { useApolloClient } from "@apollo/react-hooks";
export default function JobsDetailHeaderActions({ job }) {
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { useHistory } from "react-router-dom";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export function JobsDetailHeaderActions({ job, bodyshop }) {
const { t } = useTranslation();
const client = useApolloClient();
const history = useHistory();
const statusmenu = (
<Menu key="popovermenu">
<Menu.Item key="cccontract">
<Link
to={{
pathname: "/manage/courtesycars/contracts/new",
state: { jobId: job.id }
state: { jobId: job.id },
}}
>
{t("menus.jobsactions.newcccontract")}
</Link>
</Menu.Item>
<Menu.Item key="duplicatejob">
<Popconfirm
title={t("jobs.labels.duplicateconfirm")}
okText="Yes"
cancelText="No"
onClick={(e) => e.stopPropagation()}
onConfirm={() =>
DuplicateJob(
client,
job.id,
{ defaultOpenStatus: bodyshop.md_ro_statuses.default_imported },
(newJobId) => {
history.push(`/manage/jobs/${newJobId}`);
}
)
}
getPopupContainer={(trigger) => trigger.parentNode}
>
{t("menus.jobsactions.duplicate")}
</Popconfirm>
</Menu.Item>
</Menu>
);
return (
@@ -28,3 +65,7 @@ export default function JobsDetailHeaderActions({ job }) {
</Dropdown>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(JobsDetailHeaderActions);

View File

@@ -0,0 +1,49 @@
import {
QUERY_ALL_JOB_FIELDS,
INSERT_NEW_JOB,
} from "../../graphql/jobs.queries";
export default function DuplicateJob(
apolloClient,
jobId,
config,
completionCallback
) {
const { defaultOpenStatus } = config;
//get a list of all fields on the job
apolloClient
.query({ query: QUERY_ALL_JOB_FIELDS, variables: { id: jobId } })
.then((res) => {
const { jobs_by_pk: existingJob } = res.data;
delete existingJob.__typename;
delete existingJob.id;
existingJob.date_estimated = new Date();
existingJob.status = defaultOpenStatus;
const _tempLines = existingJob.joblines;
_tempLines.forEach((line) => {
delete line.id;
delete line.__typename;
});
delete existingJob.joblines;
existingJob.joblines = { data: _tempLines };
apolloClient
.mutate({
mutation: INSERT_NEW_JOB,
variables: { job: [existingJob] },
})
.then((res2) => {
console.log("res2", res2);
if (completionCallback)
completionCallback(res2.data.insert_jobs.returning[0].id);
});
});
//insert the new job. call the callback with the returned ID when done.
return;
}

View File

@@ -8,7 +8,7 @@ export default function JobsDetailInsurance({ job, form }) {
const { getFieldValue } = form;
const { t } = useTranslation();
//initialValue: job.loss_date ? moment(job.loss_date) : null
console.log("job", job);
return (
<div>
<Form.Item label={t("jobs.fields.ins_co_id")} name="ins_co_id">
@@ -54,8 +54,8 @@ export default function JobsDetailInsurance({ job, form }) {
rules={[
{
type: "email",
message: "This is not a valid email address."
}
message: "This is not a valid email address.",
},
]}
>
<FormItemEmail email={getFieldValue("ins_ea")} />
@@ -84,8 +84,8 @@ export default function JobsDetailInsurance({ job, form }) {
rules={[
{
type: "email",
message: "This is not a valid email address."
}
message: "This is not a valid email address.",
},
]}
>
<FormItemEmail email={getFieldValue("est_ea")} />

View File

@@ -401,3 +401,253 @@ export const ACTIVE_JOBS_FOR_AUTOCOMPLETE = gql`
}
}
`;
//TODO Ensure this is always up to date.
export const QUERY_ALL_JOB_FIELDS = gql`
query QUERY_ALL_JOB_FIELDS($id: uuid!) {
jobs_by_pk(id: $id) {
id
adj_g_disc
adj_strdis
adj_towdis
adjustment_bottom_line
agt_addr1
agt_addr2
agt_city
agt_co_id
agt_co_nm
agt_ct_fn
agt_ct_ln
agt_ct_ph
agt_ct_phx
agt_ctry
agt_ea
agt_faxx
agt_fax
agt_lic_no
agt_ph1
agt_ph1x
agt_ph2
agt_zip
agt_st
agt_ph2x
area_of_damage
cat_no
cieca_stl
cieca_ttl
clm_addr1
clm_addr2
clm_city
clm_ct_fn
clm_ct_ln
clm_ct_ph
clm_ct_phx
clm_ctry
clm_ea
clm_fax
clm_faxx
clm_ofc_id
clm_ofc_nm
clm_ph1
clm_ph1x
clm_ph2
clm_ph2x
clm_st
clm_title
clm_total
clm_zip
csr
cust_pr
ded_amt
ded_status
depreciation_taxes
est_addr1
est_addr2
est_city
est_co_nm
est_ct_fn
est_ct_ln
est_ctry
est_ea
est_ph1
est_st
est_zip
federal_tax_payable
federal_tax_rate
g_bett_amt
ins_addr1
ins_addr2
ins_city
ins_co_id
ins_co_nm
ins_ct_fn
ins_ct_ln
ins_ct_ph
ins_ct_phx
ins_ctry
ins_ea
ins_fax
ins_faxx
ins_memo
ins_ph1
ins_ph1x
ins_ph2
ins_ph2x
ins_st
ins_title
ins_zip
insd_addr1
insd_addr2
insd_city
insd_co_nm
insd_ctry
insd_ea
insd_fax
insd_faxx
insd_fn
insd_ln
insd_ph1
insd_ph1x
insd_ph2
insd_ph2x
insd_st
insd_title
insd_zip
job_totals
labor_rate_desc
labor_rate_id
local_tax_rate
other_amount_payable
owner_owing
ownerid
ownr_addr1
ownr_addr2
ownr_city
ownr_co_nm
ownr_ctry
ownr_ea
ownr_fax
ownr_faxx
ownr_fn
ownr_ln
ownr_ph1
ownr_ph1x
ownr_ph2
ownr_ph2x
ownr_st
ownr_title
ownr_zip
parts_tax_rates
pay_amt
pay_chknm
pay_date
pay_type
payee_nms
plate_no
plate_st
po_number
policy_no
rate_atp
rate_la1
rate_la2
rate_la3
rate_la4
rate_laa
rate_lab
rate_lad
rate_lae
rate_lag
rate_laf
rate_lam
rate_lar
rate_las
rate_lau
rate_ma2s
rate_ma2t
rate_ma3s
rate_mabl
rate_macs
rate_mahw
rate_mapa
rate_mash
rate_matd
referral_source
regie_number
selling_dealer
selling_dealer_contact
servicing_dealer
servicing_dealer_contact
shopid
special_coverage_policy
state_tax_rate
storage_payable
tax_lbr_rt
tax_levies_rt
tax_paint_mat_rt
tax_predis
tax_prethr
tax_pstthr
tax_str_rt
tax_sub_rt
tax_thramt
tax_tow_rt
theft_ind
tlos_ind
towing_payable
unit_number
v_color
v_make_desc
v_model_desc
v_model_yr
v_vin
vehicleid
joblines {
act_price
alt_co_id
alt_overrd
alt_part_i
alt_partm
bett_amt
alt_partno
bett_pctg
bett_tax
bett_type
cert_part
db_hrs
db_price
db_ref
est_seq
glass_flag
id
lbr_amt
lbr_hrs_j
lbr_inc
lbr_op
lbr_op_j
lbr_tax
lbr_typ_j
line_desc
line_ind
line_ref
misc_amt
misc_sublt
misc_tax
mod_lb_hrs
mod_lbr_ty
oem_partno
op_code_desc
paint_stg
paint_tone
part_qty
part_type
price_inc
price_j
prt_dsmk_m
prt_dsmk_p
status
tax_part
unq_seq
}
}
}
`;

View File

@@ -551,6 +551,7 @@
},
"creating_new_job": "Creating new job...",
"documents": "Documents",
"duplicateconfirm": "Are you sure you want to duplicate this job? Some elements of this job will not be duplicated.",
"existing_jobs": "Existing Jobs",
"hrs_claimed": "Hours Claimed",
"hrs_total": "Hours Total",
@@ -606,6 +607,7 @@
"vehicles": "Vehicles"
},
"jobsactions": {
"duplicate": "Duplicate this Job",
"newcccontract": "Create Courtesy Car Contract"
},
"jobsdetail": {

View File

@@ -551,6 +551,7 @@
},
"creating_new_job": "Creando nuevo trabajo ...",
"documents": "documentos",
"duplicateconfirm": "",
"existing_jobs": "Empleos existentes",
"hrs_claimed": "",
"hrs_total": "",
@@ -606,6 +607,7 @@
"vehicles": "Vehículos"
},
"jobsactions": {
"duplicate": "",
"newcccontract": ""
},
"jobsdetail": {

View File

@@ -551,6 +551,7 @@
},
"creating_new_job": "Création d'un nouvel emploi ...",
"documents": "Les documents",
"duplicateconfirm": "",
"existing_jobs": "Emplois existants",
"hrs_claimed": "",
"hrs_total": "",
@@ -606,6 +607,7 @@
"vehicles": "Véhicules"
},
"jobsactions": {
"duplicate": "",
"newcccontract": ""
},
"jobsdetail": {