WIP Read Only for Jobs BOD-409

This commit is contained in:
Patrick Fic
2020-09-28 14:00:35 -07:00
parent a7051c0f86
commit 3ee003000d
22 changed files with 278 additions and 129 deletions

View File

@@ -13439,6 +13439,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>federal_tax_rate</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>ins_addr1</name> <name>ins_addr1</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -14053,6 +14074,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>local_tax_rate</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>loss_date</name> <name>loss_date</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -15376,6 +15418,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>state_tax_rate</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>status</name> <name>status</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -11,6 +11,12 @@ import { alphaSort } from "../../utils/sorters";
import queryString from "query-string"; import queryString from "query-string";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly,
});
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
setPartsOrderContext: (context) => setPartsOrderContext: (context) =>
dispatch(setModalContext({ context: context, modal: "partsOrder" })), dispatch(setModalContext({ context: context, modal: "partsOrder" })),
@@ -21,6 +27,7 @@ const mapDispatchToProps = (dispatch) => ({
}); });
export function BillsListTableComponent({ export function BillsListTableComponent({
jobRO,
job, job,
billsQuery, billsQuery,
handleOnRowClick, handleOnRowClick,
@@ -94,11 +101,15 @@ export function BillsListTableComponent({
key: "actions", key: "actions",
render: (text, record) => ( render: (text, record) => (
<div> <div>
{jobRO ? (
<Button disabled>{t("bills.actions.edit")}</Button>
) : (
<Link <Link
to={`/manage/bills?billid=${record.id}&vendorid=${record.vendorid}`} to={`/manage/bills?billid=${record.id}&vendorid=${record.vendorid}`}
> >
<Button>{t("bills.actions.edit")}</Button> <Button>{t("bills.actions.edit")}</Button>
</Link> </Link>
)}
</div> </div>
), ),
}, },
@@ -227,7 +238,7 @@ export function BillsListTableComponent({
</Descriptions.Item> </Descriptions.Item>
</Descriptions> </Descriptions>
<Button <Button
disabled={record.is_credit_memo} disabled={record.is_credit_memo || jobRO}
onClick={() => onClick={() =>
setPartsOrderContext({ setPartsOrderContext({
actions: {}, actions: {},
@@ -292,6 +303,7 @@ export function BillsListTableComponent({
{job ? ( {job ? (
<div> <div>
<Button <Button
disabled={jobRO}
onClick={() => { onClick={() => {
setBillEnterContext({ setBillEnterContext({
actions: { refetch: billsQuery.refetch }, actions: { refetch: billsQuery.refetch },

View File

@@ -3,16 +3,9 @@ import Axios from "axios";
import React, { useState } from "react"; import React, { useState } from "react";
import { useMutation } from "react-apollo"; import { useMutation } from "react-apollo";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({ export default function JobCalculateTotals({ job, disabled }) {
bodyshop: selectBodyshop,
});
export function JobCalculateTotals({ bodyshop, job }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [updateJob] = useMutation(UPDATE_JOB); const [updateJob] = useMutation(UPDATE_JOB);
@@ -49,10 +42,9 @@ export function JobCalculateTotals({ bodyshop, job }) {
return ( return (
<div> <div>
<Button loading={loading} onClick={handleCalculate}> <Button loading={loading} onClick={handleCalculate} disabled={disabled}>
{t("jobs.actions.recalculate")} {t("jobs.actions.recalculate")}
</Button> </Button>
</div> </div>
); );
} }
export default connect(mapStateToProps, null)(JobCalculateTotals);

View File

@@ -15,6 +15,13 @@ import JobLineNotePopup from "../job-line-note-popup/job-line-note-popup.compone
// import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container"; // import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container";
import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container"; import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container";
import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
jobRO: selectJobReadOnly,
});
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
setJobLineEditContext: (context) => setJobLineEditContext: (context) =>
dispatch(setModalContext({ context: context, modal: "jobLineEdit" })), dispatch(setModalContext({ context: context, modal: "jobLineEdit" })),
@@ -23,6 +30,7 @@ const mapDispatchToProps = (dispatch) => ({
}); });
export function JobLinesComponent({ export function JobLinesComponent({
jobRO,
setPartsOrderContext, setPartsOrderContext,
loading, loading,
refetch, refetch,
@@ -179,13 +187,17 @@ export function JobLinesComponent({
title: t("joblines.fields.notes"), title: t("joblines.fields.notes"),
dataIndex: "notes", dataIndex: "notes",
key: "notes", key: "notes",
render: (text, record) => <JobLineNotePopup jobline={record} />, render: (text, record) => (
<JobLineNotePopup disabled={jobRO} jobline={record} />
),
}, },
{ {
title: t("joblines.fields.location"), title: t("joblines.fields.location"),
dataIndex: "location", dataIndex: "location",
key: "location", key: "location",
render: (text, record) => <JobLineLocationPopup jobline={record} />, render: (text, record) => (
<JobLineLocationPopup jobline={record} disabled={jobRO} />
),
}, },
{ {
title: t("joblines.fields.status"), title: t("joblines.fields.status"),
@@ -244,6 +256,7 @@ export function JobLinesComponent({
render: (text, record) => ( render: (text, record) => (
<div> <div>
<Button <Button
disabled={jobRO}
onClick={() => { onClick={() => {
setJobLineEditContext({ setJobLineEditContext({
actions: { refetch: refetch }, actions: { refetch: refetch },
@@ -309,7 +322,9 @@ export function JobLinesComponent({
</Button> </Button>
<Button <Button
disabled={ disabled={
!job.converted || (selectedLines.length > 0 ? false : true) !job.converted ||
(selectedLines.length > 0 ? false : true) ||
jobRO
} }
onClick={() => { onClick={() => {
setPartsOrderContext({ setPartsOrderContext({
@@ -345,6 +360,7 @@ export function JobLinesComponent({
// /> // />
} }
<Button <Button
disabled={jobRO}
onClick={() => { onClick={() => {
setJobLineEditContext({ setJobLineEditContext({
actions: { refetch: refetch }, actions: { refetch: refetch },
@@ -398,4 +414,4 @@ export function JobLinesComponent({
</div> </div>
); );
} }
export default connect(null, mapDispatchToProps)(JobLinesComponent); export default connect(mapStateToProps, mapDispatchToProps)(JobLinesComponent);

View File

@@ -6,8 +6,10 @@ import { Select, Button, Popover } from "antd";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
jobRO: selectJobReadOnly,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language)) //setUserLanguage: language => dispatch(setUserLanguage(language))
@@ -15,6 +17,7 @@ const mapDispatchToProps = (dispatch) => ({
export function JobEmployeeAssignments({ export function JobEmployeeAssignments({
bodyshop, bodyshop,
jobRO,
body, body,
refinish, refinish,
prep, prep,
@@ -52,7 +55,7 @@ export function JobEmployeeAssignments({
</Select> </Select>
<Button <Button
type="primary" type="primary"
disabled={!assignment.employeeid} disabled={!assignment.employeeid || jobRO}
onClick={() => { onClick={() => {
handleAdd(assignment); handleAdd(assignment);
setVisibility(false); setVisibility(false);
@@ -79,14 +82,18 @@ export function JobEmployeeAssignments({
}`}</span> }`}</span>
<MinusOutlined <MinusOutlined
operation="body" operation="body"
onClick={() => handleRemove("body")} disabled={jobRO}
onClick={() => !jobRO && handleRemove("body")}
/> />
</div> </div>
) : ( ) : (
<PlusCircleFilled <PlusCircleFilled
disabled={jobRO}
onClick={() => { onClick={() => {
if (!jobRO) {
setAssignment({ operation: "body" }); setAssignment({ operation: "body" });
setVisibility(true); setVisibility(true);
}
}} }}
/> />
)} )}
@@ -101,15 +108,19 @@ export function JobEmployeeAssignments({
prep.last_name || "" prep.last_name || ""
}`}</span> }`}</span>
<MinusOutlined <MinusOutlined
disabled={jobRO}
operation="prep" operation="prep"
onClick={() => handleRemove("prep")} onClick={() => !jobRO && handleRemove("prep")}
/> />
</div> </div>
) : ( ) : (
<PlusCircleFilled <PlusCircleFilled
disabled={jobRO}
onClick={() => { onClick={() => {
if (!jobRO) {
setAssignment({ operation: "prep" }); setAssignment({ operation: "prep" });
setVisibility(true); setVisibility(true);
}
}} }}
/> />
)} )}
@@ -124,15 +135,19 @@ export function JobEmployeeAssignments({
refinish.last_name || "" refinish.last_name || ""
}`}</span> }`}</span>
<MinusOutlined <MinusOutlined
disabled={jobRO}
operation="refinish" operation="refinish"
onClick={() => handleRemove("refinish")} onClick={() => !jobRO && handleRemove("refinish")}
/> />
</div> </div>
) : ( ) : (
<PlusCircleFilled <PlusCircleFilled
disabled={jobRO}
onClick={() => { onClick={() => {
if (!jobRO) {
setAssignment({ operation: "refinish" }); setAssignment({ operation: "refinish" });
setVisibility(true); setVisibility(true);
}
}} }}
/> />
)} )}

View File

@@ -16,7 +16,7 @@ const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language)) //setUserLanguage: language => dispatch(setUserLanguage(language))
}); });
export function JobLineLocationPopup({ bodyshop, jobline }) { export function JobLineLocationPopup({ bodyshop, jobline, disabled }) {
const [editing, setEditing] = useState(false); const [editing, setEditing] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [location, setLocation] = useState(jobline.location); const [location, setLocation] = useState(jobline.location);
@@ -73,7 +73,7 @@ export function JobLineLocationPopup({ bodyshop, jobline }) {
return ( return (
<div <div
style={{ width: "100%", minHeight: "2rem", cursor: "pointer" }} style={{ width: "100%", minHeight: "2rem", cursor: "pointer" }}
onClick={() => setEditing(true)} onClick={() => !disabled && setEditing(true)}
> >
{jobline.location} {jobline.location}
</div> </div>

View File

@@ -5,7 +5,7 @@ import { useMutation } from "react-apollo";
import { UPDATE_JOB_LINE } from "../../graphql/jobs-lines.queries"; import { UPDATE_JOB_LINE } from "../../graphql/jobs-lines.queries";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
export default function JobLineNotePopup({ jobline }) { export default function JobLineNotePopup({ jobline, disabled }) {
const [editing, setEditing] = useState(false); const [editing, setEditing] = useState(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [note, setNote] = useState(jobline.note); const [note, setNote] = useState(jobline.note);
@@ -57,7 +57,7 @@ export default function JobLineNotePopup({ jobline }) {
return ( return (
<div <div
style={{ width: "100%", minHeight: "2rem", cursor: "pointer" }} style={{ width: "100%", minHeight: "2rem", cursor: "pointer" }}
onClick={() => setEditing(true)} onClick={() => !disabled && setEditing(true)}
> >
{jobline.notes} {jobline.notes}
</div> </div>

View File

@@ -6,12 +6,14 @@ import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import JobCalculateTotals from "../job-calculate-totals/job-calculate-totals.component"; import JobCalculateTotals from "../job-calculate-totals/job-calculate-totals.component";
import "./job-totals-table.styles.scss"; import "./job-totals-table.styles.scss";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser //currentUser: selectCurrentUser
jobRO: selectJobReadOnly,
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
}); });
@@ -20,14 +22,14 @@ const colSpan = {
lg: { span: 12 }, lg: { span: 12 },
}; };
export function JobsTotalsTableComponent({ bodyshop, job }) { export function JobsTotalsTableComponent({ bodyshop, jobRO, job }) {
const { t } = useTranslation(); const { t } = useTranslation();
if (!!!job.job_totals) { if (!!!job.job_totals) {
return ( return (
<Result <Result
title={t("jobs.errors.nofinancial")} title={t("jobs.errors.nofinancial")}
extra={<JobCalculateTotals job={job} />} extra={<JobCalculateTotals job={job} disabled={jobRO} />}
/> />
); );
} }
@@ -333,7 +335,7 @@ export function JobsTotalsTableComponent({ bodyshop, job }) {
value={Dinero(job.job_totals.totals.net_repairs).toFormat()} value={Dinero(job.job_totals.totals.net_repairs).toFormat()}
/> />
</div> </div>
<JobCalculateTotals job={job} /> <JobCalculateTotals job={job} disabled={jobRO} />
<Editor <Editor
value={{ value={{
CIECA: job.cieca_ttl && job.cieca_ttl.data, CIECA: job.cieca_ttl && job.cieca_ttl.data,

View File

@@ -1,21 +1,23 @@
import { DownCircleFilled } from "@ant-design/icons"; import { DownCircleFilled } from "@ant-design/icons";
import { Button, Dropdown, Menu, notification } from "antd"; import { Button, Dropdown, Menu, notification } from "antd";
import React, { useState, useEffect } from "react"; import React, { useEffect, useState } from "react";
import { useMutation } from "react-apollo"; import { useMutation } from "react-apollo";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { UPDATE_JOB_STATUS } from "../../graphql/jobs.queries"; import { UPDATE_JOB_STATUS } from "../../graphql/jobs.queries";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
jobRO: selectJobReadOnly,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language)) //setUserLanguage: language => dispatch(setUserLanguage(language))
}); });
export function JobsChangeStatus({ job, bodyshop }) { export function JobsChangeStatus({ job, bodyshop, jobRO }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [availableStatuses, setAvailableStatuses] = useState([]); const [availableStatuses, setAvailableStatuses] = useState([]);
@@ -70,6 +72,7 @@ export function JobsChangeStatus({ job, bodyshop }) {
overlay={statusmenu} overlay={statusmenu}
trigger={["click"]} trigger={["click"]}
key="changestatus" key="changestatus"
disabled={jobRO}
> >
<Button> <Button>
{t("jobs.actions.changestatus")} <DownCircleFilled /> {t("jobs.actions.changestatus")} <DownCircleFilled />

View File

@@ -1,21 +1,23 @@
import { Button, notification, Popover, Form, Select } from "antd"; import { Button, Form, notification, Popover, Select } from "antd";
import React, { useState } from "react"; import React, { useState } from "react";
import { useMutation } from "react-apollo"; import { useMutation } from "react-apollo";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { CONVERT_JOB_TO_RO } from "../../graphql/jobs.queries"; import { CONVERT_JOB_TO_RO } from "../../graphql/jobs.queries";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser //currentUser: selectCurrentUser
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
jobRO: selectJobReadOnly,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language)) //setUserLanguage: language => dispatch(setUserLanguage(language))
}); });
export function JobsConvertButton({ bodyshop, job, refetch }) { export function JobsConvertButton({ bodyshop, job, refetch, jobRO }) {
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [mutationConvertJob] = useMutation(CONVERT_JOB_TO_RO); const [mutationConvertJob] = useMutation(CONVERT_JOB_TO_RO);
const { t } = useTranslation(); const { t } = useTranslation();
@@ -88,7 +90,7 @@ export function JobsConvertButton({ bodyshop, job, refetch }) {
className="imex-flex-row__margin" className="imex-flex-row__margin"
type="danger" type="danger"
style={{ display: job.converted ? "none" : "" }} style={{ display: job.converted ? "none" : "" }}
disabled={job.converted} disabled={job.converted || jobRO}
onClick={() => setVisible(true)} onClick={() => setVisible(true)}
> >
{t("jobs.actions.convert")} {t("jobs.actions.convert")}

View File

@@ -3,6 +3,7 @@ import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import FormDatePicker from "../form-date-picker/form-date-picker.component"; import FormDatePicker from "../form-date-picker/form-date-picker.component";
import InputNumberCalculator from "../form-input-number-calculator/form-input-number-calculator.component"; import InputNumberCalculator from "../form-input-number-calculator/form-input-number-calculator.component";
@@ -13,7 +14,7 @@ import Car from "../job-damage-visual/job-damage-visual.component";
import FormRow from "../layout-form-row/layout-form-row.component"; import FormRow from "../layout-form-row/layout-form-row.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser jobRO: selectJobReadOnly,
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
@@ -22,7 +23,7 @@ const mapDispatchToProps = (dispatch) => ({
const lossColFields = { sm: { span: 24 }, md: { span: 18 }, lg: { span: 20 } }; const lossColFields = { sm: { span: 24 }, md: { span: 18 }, lg: { span: 20 } };
const lossColDamage = { sm: { span: 24 }, md: { span: 6 }, lg: { span: 4 } }; const lossColDamage = { sm: { span: 24 }, md: { span: 6 }, lg: { span: 4 } };
export function JobsDetailGeneral({ bodyshop, job, form }) { export function JobsDetailGeneral({ bodyshop, jobRO, job, form }) {
const { getFieldValue } = form; const { getFieldValue } = form;
const { t } = useTranslation(); const { t } = useTranslation();
@@ -30,10 +31,10 @@ export function JobsDetailGeneral({ bodyshop, job, form }) {
<div> <div>
<FormRow header={t("jobs.forms.claiminfo")}> <FormRow header={t("jobs.forms.claiminfo")}>
<Form.Item label={t("jobs.fields.clm_no")} name="clm_no"> <Form.Item label={t("jobs.fields.clm_no")} name="clm_no">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.ded_status")} name="ded_status"> <Form.Item label={t("jobs.fields.ded_status")} name="ded_status">
<Select> <Select disabled={jobRO}>
<Select.Option value="W"> <Select.Option value="W">
{t("jobs.labels.deductible.waived")} {t("jobs.labels.deductible.waived")}
</Select.Option> </Select.Option>
@@ -46,34 +47,34 @@ export function JobsDetailGeneral({ bodyshop, job, form }) {
</Select> </Select>
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.ded_amt")} name="ded_amt"> <Form.Item label={t("jobs.fields.ded_amt")} name="ded_amt">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.policy_no")} name="policy_no"> <Form.Item label={t("jobs.fields.policy_no")} name="policy_no">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.regie_number")} name="regie_number"> <Form.Item label={t("jobs.fields.regie_number")} name="regie_number">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.ins_co_id")} name="ins_co_id"> <Form.Item label={t("jobs.fields.ins_co_id")} name="ins_co_id">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.ins_co_nm")} name="ins_co_nm"> <Form.Item label={t("jobs.fields.ins_co_nm")} name="ins_co_nm">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.ins_addr1")} name="ins_addr1"> <Form.Item label={t("jobs.fields.ins_addr1")} name="ins_addr1">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.ins_city")} name="ins_city"> <Form.Item label={t("jobs.fields.ins_city")} name="ins_city">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.ins_ct_ln")} name="ins_ct_ln"> <Form.Item label={t("jobs.fields.ins_ct_ln")} name="ins_ct_ln">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.ins_ct_fn")} name="ins_ct_fn"> <Form.Item label={t("jobs.fields.ins_ct_fn")} name="ins_ct_fn">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.ins_ph1")} name="ins_ph1"> <Form.Item label={t("jobs.fields.ins_ph1")} name="ins_ph1">
<FormItemPhone customInput={Input} /> <FormItemPhone customInput={Input} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.ins_ea")} label={t("jobs.fields.ins_ea")}
@@ -85,13 +86,13 @@ export function JobsDetailGeneral({ bodyshop, job, form }) {
}, },
]} ]}
> >
<FormItemEmail email={getFieldValue("ins_ea")} /> <FormItemEmail email={getFieldValue("ins_ea")} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.referralsource")} label={t("jobs.fields.referralsource")}
name="referral_source" name="referral_source"
> >
<Select> <Select disabled={jobRO}>
{bodyshop.md_referral_sources.map((s) => ( {bodyshop.md_referral_sources.map((s) => (
<Select.Option key={s} value={s}> <Select.Option key={s} value={s}>
{s} {s}
@@ -104,35 +105,35 @@ export function JobsDetailGeneral({ bodyshop, job, form }) {
<Col {...lossColFields}> <Col {...lossColFields}>
<FormRow header={t("jobs.forms.lossinfo")}> <FormRow header={t("jobs.forms.lossinfo")}>
<Form.Item label={t("jobs.fields.loss_desc")} name="loss_desc"> <Form.Item label={t("jobs.fields.loss_desc")} name="loss_desc">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.loss_date")} name="loss_date"> <Form.Item label={t("jobs.fields.loss_date")} name="loss_date">
<FormDatePicker /> <FormDatePicker disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.kmin")} name="kmin"> <Form.Item label={t("jobs.fields.kmin")} name="kmin">
<InputNumberCalculator precision={1} min={0} /> <InputNumberCalculator precision={1} min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.kmout")} name="kmout"> <Form.Item label={t("jobs.fields.kmout")} name="kmout">
<InputNumberCalculator precision={1} min={0} /> <InputNumberCalculator precision={1} min={0} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.ponumber")} name="po_number"> <Form.Item label={t("jobs.fields.ponumber")} name="po_number">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.unitnumber")} name="unit_number"> <Form.Item label={t("jobs.fields.unitnumber")} name="unit_number">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.specialcoveragepolicy")} label={t("jobs.fields.specialcoveragepolicy")}
valuePropName="checked" valuePropName="checked"
name="special_coverage_policy" name="special_coverage_policy"
> >
<Switch /> <Switch disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.tax_registration_number")} label={t("jobs.fields.tax_registration_number")}
name="tax_registration_number" name="tax_registration_number"
> >
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
</FormRow> </FormRow>
</Col> </Col>
@@ -150,16 +151,16 @@ export function JobsDetailGeneral({ bodyshop, job, form }) {
<FormRow header={t("jobs.forms.appraiserinfo")}> <FormRow header={t("jobs.forms.appraiserinfo")}>
<Form.Item label={t("jobs.fields.est_co_nm")} name="est_co_nm"> <Form.Item label={t("jobs.fields.est_co_nm")} name="est_co_nm">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.est_ct_fn")} name="est_ct_fn"> <Form.Item label={t("jobs.fields.est_ct_fn")} name="est_ct_fn">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.est_ct_ln")} name="est_ct_ln"> <Form.Item label={t("jobs.fields.est_ct_ln")} name="est_ct_ln">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.est_ph1")} name="est_ph1"> <Form.Item label={t("jobs.fields.est_ph1")} name="est_ph1">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.est_ea")} label={t("jobs.fields.est_ea")}
@@ -171,16 +172,16 @@ export function JobsDetailGeneral({ bodyshop, job, form }) {
}, },
]} ]}
> >
<FormItemEmail email={getFieldValue("est_ea")} /> <FormItemEmail email={getFieldValue("est_ea")} disabled={jobRO} />
</Form.Item> </Form.Item>
</FormRow> </FormRow>
<FormRow header={t("jobs.forms.other")}> <FormRow header={t("jobs.forms.other")}>
<Form.Item label={t("jobs.fields.csr")} name="csr"> <Form.Item label={t("jobs.fields.csr")} name="csr">
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.category")} name="category"> <Form.Item label={t("jobs.fields.category")} name="category">
<Select> <Select disabled={jobRO}>
{bodyshop.md_categories.map((s) => ( {bodyshop.md_categories.map((s) => (
<Select.Option key={s} value={s}> <Select.Option key={s} value={s}>
{s} {s}
@@ -193,25 +194,25 @@ export function JobsDetailGeneral({ bodyshop, job, form }) {
label={t("jobs.fields.selling_dealer")} label={t("jobs.fields.selling_dealer")}
name="selling_dealer" name="selling_dealer"
> >
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.servicing_dealer")} label={t("jobs.fields.servicing_dealer")}
name="servicing_dealer" name="servicing_dealer"
> >
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.selling_dealer_contact")} label={t("jobs.fields.selling_dealer_contact")}
name="selling_dealer_contact" name="selling_dealer_contact"
> >
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.servicing_dealer_contact")} label={t("jobs.fields.servicing_dealer_contact")}
name="servicing_dealer_contact" name="servicing_dealer_contact"
> >
<Input /> <Input disabled={jobRO} />
</Form.Item> </Form.Item>
</FormRow> </FormRow>
</div> </div>

View File

@@ -12,9 +12,11 @@ import AddToProduction from "./jobs-detail-header-actions.addtoproduction.util";
import JobsDetaiLheaderCsi from "./jobs-detail-header-actions.csi.component"; import JobsDetaiLheaderCsi from "./jobs-detail-header-actions.csi.component";
import DuplicateJob from "./jobs-detail-header-actions.duplicate.util"; import DuplicateJob from "./jobs-detail-header-actions.duplicate.util";
import { logImEXEvent } from "../../firebase/firebase.utils"; import { logImEXEvent } from "../../firebase/firebase.utils";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
jobRO: selectJobReadOnly,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
@@ -36,6 +38,7 @@ export function JobsDetailHeaderActions({
setBillEnterContext, setBillEnterContext,
setPaymentContext, setPaymentContext,
setJobCostingContext, setJobCostingContext,
jobRO,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const client = useApolloClient(); const client = useApolloClient();
@@ -58,7 +61,7 @@ export function JobsDetailHeaderActions({
const statusmenu = ( const statusmenu = (
<Menu key="popovermenu"> <Menu key="popovermenu">
<Menu.Item <Menu.Item
disabled={!jobInPreProduction || !job.converted} disabled={!jobInPreProduction || !job.converted || jobRO}
onClick={() => { onClick={() => {
logImEXEvent("job_header_schedule"); logImEXEvent("job_header_schedule");
@@ -75,10 +78,16 @@ export function JobsDetailHeaderActions({
</Menu.Item> </Menu.Item>
<Menu.Item <Menu.Item
disabled={ disabled={
!!job.intakechecklist || !jobInPreProduction || !job.converted !!job.intakechecklist ||
!jobInPreProduction ||
!job.converted ||
jobRO
} }
> >
{!!job.intakechecklist || !jobInPreProduction || !job.converted ? ( {!!job.intakechecklist ||
!jobInPreProduction ||
!job.converted ||
jobRO ? (
t("jobs.actions.intake") t("jobs.actions.intake")
) : ( ) : (
<Link to={`/manage/jobs/${job.id}/intake`}> <Link to={`/manage/jobs/${job.id}/intake`}>
@@ -86,7 +95,7 @@ export function JobsDetailHeaderActions({
</Link> </Link>
)} )}
</Menu.Item> </Menu.Item>
<Menu.Item disabled={!jobInProduction}> <Menu.Item disabled={!jobInProduction || jobRO}>
{!jobInProduction ? ( {!jobInProduction ? (
t("jobs.actions.deliver") t("jobs.actions.deliver")
) : ( ) : (
@@ -97,6 +106,7 @@ export function JobsDetailHeaderActions({
</Menu.Item> </Menu.Item>
<Menu.Item <Menu.Item
key="enterpayments" key="enterpayments"
disabled={jobRO}
onClick={() => { onClick={() => {
logImEXEvent("job_header_enter_payment"); logImEXEvent("job_header_enter_payment");
@@ -108,7 +118,7 @@ export function JobsDetailHeaderActions({
> >
{t("menus.header.enterpayment")} {t("menus.header.enterpayment")}
</Menu.Item> </Menu.Item>
<Menu.Item key="cccontract"> <Menu.Item key="cccontract" disabled={jobRO}>
<Link <Link
to={{ to={{
pathname: "/manage/courtesycars/contracts/new", pathname: "/manage/courtesycars/contracts/new",
@@ -120,7 +130,7 @@ export function JobsDetailHeaderActions({
</Menu.Item> </Menu.Item>
<Menu.Item <Menu.Item
key="addtoproduction" key="addtoproduction"
disabled={!!!job.converted || !!job.inproduction} disabled={!!!job.converted || !!job.inproduction || jobRO}
onClick={() => AddToProduction(client, job.id, refetch)} onClick={() => AddToProduction(client, job.id, refetch)}
> >
{t("jobs.actions.addtoproduction")} {t("jobs.actions.addtoproduction")}
@@ -148,6 +158,7 @@ export function JobsDetailHeaderActions({
</Menu.Item> </Menu.Item>
<Menu.Item <Menu.Item
key="postbills" key="postbills"
disabled={jobRO}
onClick={() => { onClick={() => {
logImEXEvent("job_header_enter_bills"); logImEXEvent("job_header_enter_bills");
@@ -162,10 +173,10 @@ export function JobsDetailHeaderActions({
{t("jobs.actions.postbills")} {t("jobs.actions.postbills")}
</Menu.Item> </Menu.Item>
<Menu.Item <Menu.Item
disabled={!!job.date_invoiced || !jobInPostProduction} disabled={!!job.date_invoiced || !jobInPostProduction || jobRO}
key="closejob" key="closejob"
> >
{!!job.date_invoiced || !jobInPostProduction ? ( {!!job.date_invoiced || !jobInPostProduction || jobRO ? (
t("menus.jobsactions.closejob") t("menus.jobsactions.closejob")
) : ( ) : (
<Link <Link

View File

@@ -4,8 +4,8 @@ import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { setModalContext } from "../../redux/modals/modals.actions"; import { setModalContext } from "../../redux/modals/modals.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CurrencyFormatter from "../../utils/CurrencyFormatter"; import CurrencyFormatter from "../../utils/CurrencyFormatter";
import JobEmployeeAssignments from "../job-employee-assignments/job-employee-assignments.container"; import JobEmployeeAssignments from "../job-employee-assignments/job-employee-assignments.container";
import JobsChangeStatus from "../jobs-change-status/jobs-change-status.component"; import JobsChangeStatus from "../jobs-change-status/jobs-change-status.component";
@@ -16,7 +16,7 @@ import VehicleTagPopoverComponent from "../vehicle-tag-popover/vehicle-tag-popov
import "./jobs-detail-header.styles.scss"; import "./jobs-detail-header.styles.scss";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, jobRO: selectJobReadOnly,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
@@ -25,11 +25,10 @@ const mapDispatchToProps = (dispatch) => ({
}); });
export function JobsDetailHeader({ export function JobsDetailHeader({
setPrintCenterContext,
jobRO,
job, job,
refetch, refetch,
setPrintCenterContext,
bodyshop,
setScheduleContext,
loading, loading,
form, form,
}) { }) {
@@ -60,6 +59,7 @@ export function JobsDetailHeader({
<Button <Button
type="primary" type="primary"
loading={loading} loading={loading}
disabled={jobRO}
className="imex-flex-row__margin" className="imex-flex-row__margin"
onClick={() => form.submit()} onClick={() => form.submit()}
> >

View File

@@ -10,7 +10,7 @@ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
}); });
export function JobsDetailRatesChangeButton({ form, bodyshop }) { export function JobsDetailRatesChangeButton({ disabled, form, bodyshop }) {
const { t } = useTranslation(); const { t } = useTranslation();
const handleClick = ({ item, key, keyPath }) => { const handleClick = ({ item, key, keyPath }) => {
@@ -30,7 +30,7 @@ export function JobsDetailRatesChangeButton({ form, bodyshop }) {
); );
return ( return (
<Dropdown overlay={menu}> <Dropdown overlay={menu} disabled={disabled}>
<a <a
className="ant-dropdown-link" className="ant-dropdown-link"
href=" #" href=" #"

View File

@@ -1,11 +1,18 @@
import { Form, InputNumber, Select } from "antd"; import { Form, InputNumber, Select, Switch } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import CurrencyInput from "../form-items-formatted/currency-form-item.component"; import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component"; import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component";
import FormRow from "../layout-form-row/layout-form-row.component"; import FormRow from "../layout-form-row/layout-form-row.component";
export default function JobsDetailRates({ job, form }) { import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly,
});
export function JobsDetailRates({ job, jobRO, form }) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
@@ -18,127 +25,128 @@ export default function JobsDetailRates({ job, form }) {
label={t("jobs.fields.depreciation_taxes")} label={t("jobs.fields.depreciation_taxes")}
name="depreciation_taxes" name="depreciation_taxes"
> >
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.other_amount_payable")} label={t("jobs.fields.other_amount_payable")}
name="other_amount_payable" name="other_amount_payable"
> >
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.towing_payable")} label={t("jobs.fields.towing_payable")}
name="towing_payable" name="towing_payable"
> >
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.storage_payable")} label={t("jobs.fields.storage_payable")}
name="storage_payable" name="storage_payable"
> >
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.adjustment_bottom_line")} label={t("jobs.fields.adjustment_bottom_line")}
name="adjustment_bottom_line" name="adjustment_bottom_line"
> >
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.ca_gst_registrant")} label={t("jobs.fields.ca_gst_registrant")}
name="ca_gst_registrant" name="ca_gst_registrant"
valuePropName="checked" valuePropName="checked"
> >
<Switch /> <Switch disabled={jobRO} />
</Form.Item> </Form.Item>
</FormRow> </FormRow>
<JobsDetailRatesChangeButton form={form} /> <JobsDetailRatesChangeButton form={form} disabled={jobRO} />
<FormRow header={t("jobs.forms.laborrates")}> <FormRow header={t("jobs.forms.laborrates")}>
<Form.Item label={t("jobs.fields.rate_laa")} name="rate_laa"> <Form.Item label={t("jobs.fields.rate_laa")} name="rate_laa">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lab")} name="rate_lab"> <Form.Item label={t("jobs.fields.rate_lab")} name="rate_lab">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lad")} name="rate_lad"> <Form.Item label={t("jobs.fields.rate_lad")} name="rate_lad">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lae")} name="rate_lae"> <Form.Item label={t("jobs.fields.rate_lae")} name="rate_lae">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lar")} name="rate_lar"> <Form.Item label={t("jobs.fields.rate_lar")} name="rate_lar">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_las")} name="rate_las"> <Form.Item label={t("jobs.fields.rate_las")} name="rate_las">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_laf")} name="rate_laf"> <Form.Item label={t("jobs.fields.rate_laf")} name="rate_laf">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lam")} name="rate_lam"> <Form.Item label={t("jobs.fields.rate_lam")} name="rate_lam">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lag")} name="rate_lag"> <Form.Item label={t("jobs.fields.rate_lag")} name="rate_lag">
<CurrencyInput /> <CurrencyInput />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_la1")} name="rate_la1"> <Form.Item label={t("jobs.fields.rate_la1")} name="rate_la1">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_la2")} name="rate_la2"> <Form.Item label={t("jobs.fields.rate_la2")} name="rate_la2">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_la3")} name="rate_la3"> <Form.Item label={t("jobs.fields.rate_la3")} name="rate_la3">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_la4")} name="rate_la4"> <Form.Item label={t("jobs.fields.rate_la4")} name="rate_la4">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_lau")} name="rate_lau"> <Form.Item label={t("jobs.fields.rate_lau")} name="rate_lau">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_mapa")} name="rate_mapa"> <Form.Item label={t("jobs.fields.rate_mapa")} name="rate_mapa">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_mash")} name="rate_mash"> <Form.Item label={t("jobs.fields.rate_mash")} name="rate_mash">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_mahw")} name="rate_mahw"> <Form.Item label={t("jobs.fields.rate_mahw")} name="rate_mahw">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_ma2s")} name="rate_ma2s"> <Form.Item label={t("jobs.fields.rate_ma2s")} name="rate_ma2s">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_ma3s")} name="rate_ma3s"> <Form.Item label={t("jobs.fields.rate_ma3s")} name="rate_ma3s">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_mabl")} name="rate_mabl"> <Form.Item label={t("jobs.fields.rate_mabl")} name="rate_mabl">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_macs")} name="rate_macs"> <Form.Item label={t("jobs.fields.rate_macs")} name="rate_macs">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item label={t("jobs.fields.rate_matd")} name="rate_matd"> <Form.Item label={t("jobs.fields.rate_matd")} name="rate_matd">
<CurrencyInput /> <CurrencyInput disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.federal_tax_rate")} label={t("jobs.fields.federal_tax_rate")}
name="federal_tax_rate" name="federal_tax_rate"
> >
<InputNumber min={0} max={1} precision={2} /> <InputNumber min={0} max={1} precision={2} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.state_tax_rate")} label={t("jobs.fields.state_tax_rate")}
name="state_tax_rate" name="state_tax_rate"
> >
<InputNumber min={0} max={1} precision={2} /> <InputNumber min={0} max={1} precision={2} disabled={jobRO} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label={t("jobs.fields.local_tax_rate")} label={t("jobs.fields.local_tax_rate")}
name="local_tax_rate" name="local_tax_rate"
> >
<InputNumber min={0} max={1} precision={2} /> <InputNumber min={0} max={1} precision={2} disabled={jobRO} />
</Form.Item> </Form.Item>
</FormRow> </FormRow>
</div> </div>
); );
} }
export default connect(mapStateToProps, null)(JobsDetailRates);

View File

@@ -4,6 +4,7 @@ import React, { useMemo } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { setModalContext } from "../../redux/modals/modals.actions"; import { setModalContext } from "../../redux/modals/modals.actions";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import CurrencyFormatter from "../../utils/CurrencyFormatter"; import CurrencyFormatter from "../../utils/CurrencyFormatter";
@@ -12,6 +13,7 @@ import JobTotalsTable from "../job-totals-table/job-totals-table.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
jobRO: selectJobReadOnly,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
@@ -23,6 +25,7 @@ const stripeTestEnv = process.env.REACT_APP_STRIPE_PUBLIC_KEY; //.includes("test
export function JobsDetailTotals({ export function JobsDetailTotals({
job, job,
jobRO,
bodyshop, bodyshop,
setPaymentContext, setPaymentContext,
refetch, refetch,
@@ -96,6 +99,7 @@ export function JobsDetailTotals({
</table> </table>
<Space direction="vertical"> <Space direction="vertical">
<Button <Button
disabled={jobRO}
onClick={() => onClick={() =>
setPaymentContext({ setPaymentContext({
actions: { refetch: refetch }, actions: { refetch: refetch },

View File

@@ -17,6 +17,7 @@ export function PartsOrderLineBackorderButton({
partsOrderStatus, partsOrderStatus,
partsLineId, partsLineId,
jobLineId, jobLineId,
disabled,
bodyshop, bodyshop,
}) { }) {
const [visibility, setVisibility] = useState(false); const [visibility, setVisibility] = useState(false);
@@ -84,7 +85,12 @@ export function PartsOrderLineBackorderButton({
); );
return ( return (
<Popover destroyTooltipOnHide content={popContent} visible={visibility}> <Popover
destroyTooltipOnHide
content={popContent}
visible={visibility}
disabled={disabled}
>
<Button loading={loading} onClick={handlePopover}> <Button loading={loading} onClick={handlePopover}>
{isAlreadyBackordered {isAlreadyBackordered
? t("parts_orders.actions.receive") ? t("parts_orders.actions.receive")

View File

@@ -13,9 +13,10 @@ import { DateFormatter } from "../../utils/DateFormatter";
import { alphaSort } from "../../utils/sorters"; import { alphaSort } from "../../utils/sorters";
import PartsOrderLineBackorderButton from "../parts-order-line-backorder-button/parts-order-line-backorder-button.component"; import PartsOrderLineBackorderButton from "../parts-order-line-backorder-button/parts-order-line-backorder-button.component";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser jobRO: selectJobReadOnly,
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
}); });
@@ -27,8 +28,8 @@ const mapDispatchToProps = (dispatch) => ({
export function PartsOrderListTableComponent({ export function PartsOrderListTableComponent({
setBillEnterContext, setBillEnterContext,
bodyshop, bodyshop,
jobRO,
job, job,
billsQuery, billsQuery,
handleOnRowClick, handleOnRowClick,
}) { }) {
@@ -90,6 +91,7 @@ export function PartsOrderListTableComponent({
key: "actions", key: "actions",
render: (text, record) => ( render: (text, record) => (
<Button <Button
disabled={jobRO}
onClick={() => { onClick={() => {
logImEXEvent("parts_order_receive_bill"); logImEXEvent("parts_order_receive_bill");
@@ -197,6 +199,7 @@ export function PartsOrderListTableComponent({
render: (text, record) => ( render: (text, record) => (
<div> <div>
<PartsOrderLineBackorderButton <PartsOrderLineBackorderButton
disabled={jobRO}
partsOrderStatus={record.status} partsOrderStatus={record.status}
partsLineId={record.id} partsLineId={record.id}
jobLineId={record.job_line_id} jobLineId={record.job_line_id}

View File

@@ -26,6 +26,7 @@ import FormFieldsChanged from "../../components/form-fields-changed-alert/form-f
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component"; import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import JobsDetailChecklists from "../../components/jobs-detail-checklists/jobs-detail-checklists.component"; import JobsDetailChecklists from "../../components/jobs-detail-checklists/jobs-detail-checklists.component";
import { selectJobReadOnly } from "../../redux/application/application.selectors";
const JobsLinesContainer = lazy(() => const JobsLinesContainer = lazy(() =>
import("../../components/job-detail-lines/job-lines.container") import("../../components/job-detail-lines/job-lines.container")
@@ -79,6 +80,7 @@ const JobReconciliationModal = lazy(() =>
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
jobRO: selectJobReadOnly,
}); });
export function JobsDetailPage({ export function JobsDetailPage({
@@ -86,7 +88,7 @@ export function JobsDetailPage({
mutationUpdateJob, mutationUpdateJob,
handleSubmit, handleSubmit,
refetch, refetch,
bodyshop, jobRO,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [form] = Form.useForm(); const [form] = Form.useForm();

View File

@@ -854,6 +854,7 @@
"est_number": "Estimate #", "est_number": "Estimate #",
"est_ph1": "Appraiser Phone #", "est_ph1": "Appraiser Phone #",
"federal_tax_payable": "Federal Tax Payable", "federal_tax_payable": "Federal Tax Payable",
"federal_tax_rate": "Federal Tax Rate",
"ins_addr1": "Insurance Co. Address", "ins_addr1": "Insurance Co. Address",
"ins_city": "Insurance City", "ins_city": "Insurance City",
"ins_co_id": "Insurance Co. ID", "ins_co_id": "Insurance Co. ID",
@@ -885,6 +886,7 @@
"lar": "Refinish", "lar": "Refinish",
"las": "Structural", "las": "Structural",
"lau": "LAU", "lau": "LAU",
"local_tax_rate": "Local Tax Rate",
"loss_date": "Loss Date", "loss_date": "Loss Date",
"loss_desc": "Loss Description", "loss_desc": "Loss Description",
"ma2s": "2 Stage Paint", "ma2s": "2 Stage Paint",
@@ -948,6 +950,7 @@
"servicing_dealer": "Servicing Dealer", "servicing_dealer": "Servicing Dealer",
"servicing_dealer_contact": "Servicing Dealer Contact", "servicing_dealer_contact": "Servicing Dealer Contact",
"specialcoveragepolicy": "Special Coverage Policy", "specialcoveragepolicy": "Special Coverage Policy",
"state_tax_rate": "State Tax Rate",
"status": "Job Status", "status": "Job Status",
"storage_payable": "Storage/PVRT", "storage_payable": "Storage/PVRT",
"tax_registration_number": "Tax Registration Number", "tax_registration_number": "Tax Registration Number",

View File

@@ -854,6 +854,7 @@
"est_number": "Numero Estimado", "est_number": "Numero Estimado",
"est_ph1": "Número de teléfono del tasador", "est_ph1": "Número de teléfono del tasador",
"federal_tax_payable": "Impuesto federal por pagar", "federal_tax_payable": "Impuesto federal por pagar",
"federal_tax_rate": "",
"ins_addr1": "Dirección de Insurance Co.", "ins_addr1": "Dirección de Insurance Co.",
"ins_city": "Ciudad de seguros", "ins_city": "Ciudad de seguros",
"ins_co_id": "ID de la compañía de seguros", "ins_co_id": "ID de la compañía de seguros",
@@ -885,6 +886,7 @@
"lar": "", "lar": "",
"las": "", "las": "",
"lau": "", "lau": "",
"local_tax_rate": "",
"loss_date": "Fecha de pérdida", "loss_date": "Fecha de pérdida",
"loss_desc": "", "loss_desc": "",
"ma2s": "", "ma2s": "",
@@ -948,6 +950,7 @@
"servicing_dealer": "Distribuidor de servicio", "servicing_dealer": "Distribuidor de servicio",
"servicing_dealer_contact": "Servicio Contacto con el concesionario", "servicing_dealer_contact": "Servicio Contacto con el concesionario",
"specialcoveragepolicy": "Política de cobertura especial", "specialcoveragepolicy": "Política de cobertura especial",
"state_tax_rate": "",
"status": "Estado del trabajo", "status": "Estado del trabajo",
"storage_payable": "Almacenamiento / PVRT", "storage_payable": "Almacenamiento / PVRT",
"tax_registration_number": "", "tax_registration_number": "",

View File

@@ -854,6 +854,7 @@
"est_number": "Numéro d'estimation", "est_number": "Numéro d'estimation",
"est_ph1": "Numéro de téléphone de l'évaluateur", "est_ph1": "Numéro de téléphone de l'évaluateur",
"federal_tax_payable": "Impôt fédéral à payer", "federal_tax_payable": "Impôt fédéral à payer",
"federal_tax_rate": "",
"ins_addr1": "Adresse Insurance Co.", "ins_addr1": "Adresse Insurance Co.",
"ins_city": "Insurance City", "ins_city": "Insurance City",
"ins_co_id": "ID de la compagnie d'assurance", "ins_co_id": "ID de la compagnie d'assurance",
@@ -885,6 +886,7 @@
"lar": "", "lar": "",
"las": "", "las": "",
"lau": "", "lau": "",
"local_tax_rate": "",
"loss_date": "Date de perte", "loss_date": "Date de perte",
"loss_desc": "", "loss_desc": "",
"ma2s": "", "ma2s": "",
@@ -948,6 +950,7 @@
"servicing_dealer": "Concessionnaire", "servicing_dealer": "Concessionnaire",
"servicing_dealer_contact": "Contacter le concessionnaire", "servicing_dealer_contact": "Contacter le concessionnaire",
"specialcoveragepolicy": "Politique de couverture spéciale", "specialcoveragepolicy": "Politique de couverture spéciale",
"state_tax_rate": "",
"status": "Statut de l'emploi", "status": "Statut de l'emploi",
"storage_payable": "Stockage / PVRT", "storage_payable": "Stockage / PVRT",
"tax_registration_number": "", "tax_registration_number": "",