diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 8ec8d4156..adb7a9610 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -11,7 +11,7 @@ react-intl bodyshop_translations.babel - + client @@ -1723,6 +1723,27 @@ + + open_statuses + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -1751,6 +1772,48 @@ labels + + alljobstatuses + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + allopenjobstatuses + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + jobstatuses false @@ -7986,6 +8049,32 @@ owners + + actions + + + update + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + errors @@ -8398,6 +8487,69 @@ + + fromclaim + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + fromowner + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + updateowner + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + @@ -10266,7 +10418,7 @@ en-US - + client/src tab namespaced-json true diff --git a/client/src/components/owner-detail-jobs/owner-detail-jobs.component.jsx b/client/src/components/owner-detail-jobs/owner-detail-jobs.component.jsx index 2f26506dd..04de5d41c 100644 --- a/client/src/components/owner-detail-jobs/owner-detail-jobs.component.jsx +++ b/client/src/components/owner-detail-jobs/owner-detail-jobs.component.jsx @@ -1,10 +1,20 @@ -import React from "react"; import { Table } from "antd"; +import React, { useState } from "react"; import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; import { Link } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import { selectBodyshop } from "../../redux/user/user.selectors"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; -export default function OwnerDetailJobsComponent({ owner }) { +import OwnerDetailUpdateJobsComponent from "../owner-detail-update-jobs/owner-detail-update-jobs.component"; + +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop +}); + +function OwnerDetailJobsComponent({ bodyshop, owner }) { const { t } = useTranslation(); + const [selectedJobs, setSelectedJobs] = useState([]); const columns = [ { title: t("jobs.fields.ro_number"), @@ -50,10 +60,31 @@ export default function OwnerDetailJobsComponent({ owner }) { return ( ( + + + + )} pagination={{ position: "bottom" }} columns={columns.map(item => ({ ...item }))} - rowKey="id" + rowKey='id' dataSource={owner.jobs} + rowSelection={{ + onSelect: props => { + setSelectedJobs([...selectedJobs, props.id]); + }, + // type: "radio", + selectedRowKeys: selectedJobs, + getCheckboxProps: record => ({ + disabled: bodyshop.md_ro_statuses.open_statuses + ? !bodyshop.md_ro_statuses.open_statuses.includes(record.status) + : true + }) + }} /> ); } +export default connect(mapStateToProps, null)(OwnerDetailJobsComponent); diff --git a/client/src/components/owner-detail-update-jobs/owner-detail-update-jobs.component.jsx b/client/src/components/owner-detail-update-jobs/owner-detail-update-jobs.component.jsx new file mode 100644 index 000000000..949a92b38 --- /dev/null +++ b/client/src/components/owner-detail-update-jobs/owner-detail-update-jobs.component.jsx @@ -0,0 +1,37 @@ +import React from "react"; +import { Button } from "antd"; +import { useTranslation } from "react-i18next"; +import { useMutation } from "@apollo/react-hooks"; +import { UPDATE_JOBS } from "../../graphql/jobs.queries"; + +export default function OwnerDetailUpdateJobsComponent({ + owner, + selectedJobs +}) { + const { t } = useTranslation(); + const [updateJobs] = useMutation(UPDATE_JOBS); + const handlecClick = e => { + updateJobs({ + variables: { + jobIds: selectedJobs, + fields: { + ownr_addr1: owner["ownr_addr1"], + ownr_addr2: owner["ownr_addr2"], + ownr_co_nm: owner["ownr_co_nm"], + ownr_city: owner["ownr_city"], + ownr_ctry: owner["ownr_ctry"], + ownr_ea: owner["ownr_ea"], + ownr_fn: owner["ownr_fn"], + ownr_ph1: owner["ownr_ph1"], + ownr_ln: owner["ownr_ln"], + ownr_ph2: owner["ownr_ph2"], + ownr_st: owner["ownr_st"], + ownr_title: owner["ownr_title"], + ownr_zip: owner["ownr_zip"] + } + } + }); + }; + + return {t("owners.actions.update")}; +} diff --git a/client/src/components/owner-tag-popover/owner-tag-popover.component.jsx b/client/src/components/owner-tag-popover/owner-tag-popover.component.jsx index 513ded7f7..69ccc602f 100644 --- a/client/src/components/owner-tag-popover/owner-tag-popover.component.jsx +++ b/client/src/components/owner-tag-popover/owner-tag-popover.component.jsx @@ -1,26 +1,75 @@ -import { Button, Col, Popover, Row, Tag } from "antd"; +import { Button, Col, Popover, Row, Tag, Descriptions } from "antd"; import React from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; - +import PhoneFormatter from "../../utils/PhoneFormatter"; export default function OwnerTagPopoverComponent({ job }) { const { t } = useTranslation(); const content = ( - - The Content + - Claim Info - Owner Info + + + {`${job.ownr_fn || + ""} ${job.ownr_ln || ""} ${job.ownr_co_nm || + ""}`} + + {job.ownr_ph1 || ""} + + + {`${job.ownr_addr1 || ""} ${job.ownr_addr2 || + ""} ${job.ownr_city || ""} ${job.ownr_st || + ""} ${job.ownr_zip || ""} ${job.ownr_ctry || + ""} ${job.ownr_city || ""}`} + + + {job.ownr_ea || ""} + { + //TODO Should add an email formatter. + } + + + + + + {`${job + .owner.ownr_fn || ""} ${job.owner.ownr_ln || ""} ${job.owner + .ownr_co_nm || ""}`} + + {job.owner.ownr_ph1 || ""} + + + {`${job.owner.ownr_addr1 || ""} ${job.owner.ownr_addr2 || + ""} ${job.owner.ownr_city || ""} ${job.owner.ownr_st || + ""} ${job.owner.ownr_zip || ""} ${job.owner.ownr_ctry || + ""} ${job.owner.ownr_city || ""}`} + + + {job.owner.ownr_ea || ""} + { + //TODO Should add an email formatter. + } + + + - {t("owners.actions.update")} + {t("owners.labels.updateowner")} ); return ( - - + + {job.owner ? `${job.ownr_co_nm || ""}${job.ownr_fn || ""} ${job.ownr_ln || ""}` : t("jobs.errors.noowner")} diff --git a/client/src/components/shop-info/shop-info.rostatus.component.jsx b/client/src/components/shop-info/shop-info.rostatus.component.jsx index ab22c2ee9..59d07bb89 100644 --- a/client/src/components/shop-info/shop-info.rostatus.component.jsx +++ b/client/src/components/shop-info/shop-info.rostatus.component.jsx @@ -6,7 +6,7 @@ import styled from "styled-components"; const SelectorDiv = styled.div` .ant-form-item .ant-select { - width: 125px; + width: 200px; } `; //TODO Fix up styles. @@ -24,7 +24,8 @@ export default function ShopInfoROStatusComponent({ form }) { return ( - + + {t("bodyshop.labels.alljobstatuses")} {(fields, { add, remove }) => { return ( @@ -32,8 +33,7 @@ export default function ShopInfoROStatusComponent({ form }) { {fields.map((field, index) => ( + style={{ padding: 0, margin: 2 }}> + ]}> { add(); }} - style={{ width: "100%" }} - > + style={{ width: "100%" }}> {t("bodyshop.actions.newstatus")} @@ -75,6 +73,24 @@ export default function ShopInfoROStatusComponent({ form }) { + + + {options.map((item, idx) => ( + + {item} + + ))} + + + name={["md_ro_statuses", "default_scheduled"]}> {options.map((item, idx) => ( {item} @@ -99,8 +114,7 @@ export default function ShopInfoROStatusComponent({ form }) { message: t("general.validation.required") } ]} - name={["md_ro_statuses", "default_arrived"]} - > + name={["md_ro_statuses", "default_arrived"]}> {options.map((item, idx) => ( {item} @@ -115,8 +129,7 @@ export default function ShopInfoROStatusComponent({ form }) { message: t("general.validation.required") } ]} - name={["md_ro_statuses", "default_exported"]} - > + name={["md_ro_statuses", "default_exported"]}> {options.map((item, idx) => ( {item} @@ -131,8 +144,7 @@ export default function ShopInfoROStatusComponent({ form }) { message: t("general.validation.required") } ]} - name={["md_ro_statuses", "default_imported"]} - > + name={["md_ro_statuses", "default_imported"]}> {options.map((item, idx) => ( {item} @@ -147,8 +159,7 @@ export default function ShopInfoROStatusComponent({ form }) { message: t("general.validation.required") } ]} - name={["md_ro_statuses", "default_invoiced"]} - > + name={["md_ro_statuses", "default_invoiced"]}> {options.map((item, idx) => ( {item} @@ -163,8 +174,7 @@ export default function ShopInfoROStatusComponent({ form }) { message: t("general.validation.required") } ]} - name={["md_ro_statuses", "default_completed"]} - > + name={["md_ro_statuses", "default_completed"]}> {options.map((item, idx) => ( {item} @@ -179,8 +189,7 @@ export default function ShopInfoROStatusComponent({ form }) { message: t("general.validation.required") } ]} - name={["md_ro_statuses", "default_delivered"]} - > + name={["md_ro_statuses", "default_delivered"]}> {options.map((item, idx) => ( {item} diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js index 761e53666..e9991c9e8 100644 --- a/client/src/graphql/jobs.queries.js +++ b/client/src/graphql/jobs.queries.js @@ -153,10 +153,26 @@ export const GET_JOB_BY_PK = gql` adjustment_bottom_line ownr_fn ownr_ln + ownr_ea + ownr_addr1 + ownr_addr2 + ownr_city + ownr_st + ownr_zip + ownr_ctry + ownr_ph1 owner { id ownr_fn ownr_ln + ownr_ea + ownr_addr1 + ownr_addr2 + ownr_city + ownr_st + ownr_zip + ownr_ctry + ownr_ph1 } labor_rate_desc rate_lab @@ -303,6 +319,18 @@ export const UPDATE_JOB = gql` } `; +export const UPDATE_JOBS = gql` + mutation UPDATE_JOBS($jobIds: [uuid!]!, $fields: jobs_set_input!) { + update_jobs(where: { id: { _in: $jobIds } }, _set: $fields) { + returning { + id + est_ph1 + est_ea + } + } + } +`; + export const CONVERT_JOB_TO_RO = gql` mutation CONVERT_JOB_TO_RO($jobId: uuid!) { update_jobs(where: { id: { _eq: $jobId } }, _set: { converted: true }) { diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 1decfdd9d..d90c90cce 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -118,11 +118,14 @@ "default_invoiced": "Default Invoiced Status", "default_ordered": "Default Ordered Status", "default_received": "Default Received Status", - "default_scheduled": "Default Scheduled Status" + "default_scheduled": "Default Scheduled Status", + "open_statuses": "Open Statuses" }, "zip_post": "Zip/Postal Code" }, "labels": { + "alljobstatuses": "All Job Statuses", + "allopenjobstatuses": "All Open Job Statuses", "jobstatuses": "Job Statuses", "orderstatuses": "Order Statuses", "responsibilitycenters": { @@ -523,6 +526,9 @@ } }, "owners": { + "actions": { + "update": "Update Selected Records" + }, "errors": { "noaccess": "The record does not exist or you do not have access to it. ", "selectexistingornew": "Select an existing owner record or create a new one. " @@ -546,7 +552,10 @@ }, "labels": { "create_new": "Create a new owner record.", - "existing_owners": "Existing Owners" + "existing_owners": "Existing Owners", + "fromclaim": "Info From Claim", + "fromowner": "Info From Previous", + "updateowner": "Update Owner" }, "successes": { "save": "Owner saved successfully." diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 0a04706da..3e4569125 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -118,11 +118,14 @@ "default_invoiced": "", "default_ordered": "", "default_received": "", - "default_scheduled": "" + "default_scheduled": "", + "open_statuses": "" }, "zip_post": "" }, "labels": { + "alljobstatuses": "", + "allopenjobstatuses": "", "jobstatuses": "", "orderstatuses": "", "responsibilitycenters": { @@ -523,6 +526,9 @@ } }, "owners": { + "actions": { + "update": "" + }, "errors": { "noaccess": "El registro no existe o no tiene acceso a él.", "selectexistingornew": "" @@ -546,7 +552,10 @@ }, "labels": { "create_new": "Crea un nuevo registro de propietario.", - "existing_owners": "Propietarios existentes" + "existing_owners": "Propietarios existentes", + "fromclaim": "", + "fromowner": "", + "updateowner": "" }, "successes": { "save": "Propietario guardado con éxito." diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index db3fa913c..5b518e56c 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -118,11 +118,14 @@ "default_invoiced": "", "default_ordered": "", "default_received": "", - "default_scheduled": "" + "default_scheduled": "", + "open_statuses": "" }, "zip_post": "" }, "labels": { + "alljobstatuses": "", + "allopenjobstatuses": "", "jobstatuses": "", "orderstatuses": "", "responsibilitycenters": { @@ -523,6 +526,9 @@ } }, "owners": { + "actions": { + "update": "" + }, "errors": { "noaccess": "L'enregistrement n'existe pas ou vous n'y avez pas accès.", "selectexistingornew": "" @@ -546,7 +552,10 @@ }, "labels": { "create_new": "Créez un nouvel enregistrement de propriétaire.", - "existing_owners": "Propriétaires existants" + "existing_owners": "Propriétaires existants", + "fromclaim": "", + "fromowner": "", + "updateowner": "" }, "successes": { "save": "Le propriétaire a bien enregistré."