From 5303ab01146ccc578f5e93418be9ecec4b2aa6f3 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 20 Apr 2020 17:23:02 -0700 Subject: [PATCH] BOD-50 Added duplication functionality for a job. --- bodyshop_translations.babel | 42 +++ .../jobs-detail-header-actions.component.jsx | 47 +++- .../jobs-detail-header-actions.duplicate.js | 49 ++++ .../jobs-detail-insurance.component.jsx | 10 +- client/src/graphql/jobs.queries.js | 250 ++++++++++++++++++ client/src/translations/en_us/common.json | 2 + client/src/translations/es/common.json | 2 + client/src/translations/fr/common.json | 2 + 8 files changed, 396 insertions(+), 8 deletions(-) create mode 100644 client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.duplicate.js diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 609ef9e7d..47baf336f 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -8593,6 +8593,27 @@ + + duplicateconfirm + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + existing_jobs false @@ -9526,6 +9547,27 @@ jobsactions + + duplicate + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + newcccontract false diff --git a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx index 7b585db89..164c96c3c 100644 --- a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx +++ b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx @@ -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 = ( {t("menus.jobsactions.newcccontract")} + + 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")} + + ); return ( @@ -28,3 +65,7 @@ export default function JobsDetailHeaderActions({ job }) { ); } +export default connect( + mapStateToProps, + mapDispatchToProps +)(JobsDetailHeaderActions); diff --git a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.duplicate.js b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.duplicate.js new file mode 100644 index 000000000..43cf3b477 --- /dev/null +++ b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.duplicate.js @@ -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; +} diff --git a/client/src/components/jobs-detail-insurance/jobs-detail-insurance.component.jsx b/client/src/components/jobs-detail-insurance/jobs-detail-insurance.component.jsx index 4c79e57db..4fb2f4e14 100644 --- a/client/src/components/jobs-detail-insurance/jobs-detail-insurance.component.jsx +++ b/client/src/components/jobs-detail-insurance/jobs-detail-insurance.component.jsx @@ -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 (
@@ -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.", + }, ]} > @@ -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.", + }, ]} > diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js index 4e6484020..df60a4830 100644 --- a/client/src/graphql/jobs.queries.js +++ b/client/src/graphql/jobs.queries.js @@ -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 + } + } + } +`; diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index f77d8ba6e..36dfb718c 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -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": { diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index e45d9801c..93516f850 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -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": { diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 26b125039..83bd483ae 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -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": {