Updated contract creation to include auto status changes. BOD-314

This commit is contained in:
Patrick Fic
2020-08-28 09:44:55 -07:00
parent 554a8f6170
commit fbde4ddc2a
15 changed files with 328 additions and 226 deletions

View File

@@ -1,4 +1,4 @@
<babeledit_project be_version="2.7.1" version="1.2">
<babeledit_project version="1.2" be_version="2.7.1">
<!--
BabelEdit project file
@@ -4687,6 +4687,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>mileage</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>model</name>
<definition_loaded>false</definition_loaded>
@@ -5159,6 +5180,27 @@
</concept_node>
</children>
</folder_node>
<concept_node>
<name>outwith</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>return</name>
<definition_loaded>false</definition_loaded>

View File

@@ -4,15 +4,17 @@ import { QUERY_AVAILABLE_CC } from "../../graphql/courtesy-car.queries";
import AlertComponent from "../alert/alert.component";
import ContractCarsComponent from "./contract-cars.component";
export default function ContractCarsContainer({ selectedCarState, bodyshop }) {
export default function ContractCarsContainer({ selectedCarState, form }) {
const { loading, error, data } = useQuery(QUERY_AVAILABLE_CC);
const [selectedCar, setSelectedCar] = selectedCarState;
const handleSelect = record => {
const handleSelect = (record) => {
setSelectedCar(record.id);
form.setFieldsValue({
kmstart: record.mileage,
dailyrate: record.dailycost,
});
};
if (error) return <AlertComponent message={error.message} type="error" />;

View File

@@ -6,7 +6,7 @@ import FormDatePicker from "../form-date-picker/form-date-picker.component";
import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
import InputPhone from "../form-items-formatted/phone-form-item.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function ContractFormComponent({ form }) {
export default function ContractFormComponent({ form, create = false }) {
const { t } = useTranslation();
return (
<div>
@@ -14,18 +14,21 @@ export default function ContractFormComponent({ form }) {
<FormFieldsChanged form={form} />
</div>
<LayoutFormRow>
<Form.Item
label={t("contracts.fields.status")}
name="status"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<ContractStatusSelector />
</Form.Item>
{create ? null : (
<Form.Item
label={t("contracts.fields.status")}
name="status"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<ContractStatusSelector />
</Form.Item>
)}
<Form.Item
label={t("contracts.fields.start")}
name="start"
@@ -50,12 +53,14 @@ export default function ContractFormComponent({ form }) {
>
<FormDatePicker />
</Form.Item>
<Form.Item
label={t("contracts.fields.actualreturn")}
name="actualreturn"
>
<FormDatePicker />
</Form.Item>
{create ? null : (
<Form.Item
label={t("contracts.fields.actualreturn")}
name="actualreturn"
>
<FormDatePicker />
</Form.Item>
)}
</LayoutFormRow>
<LayoutFormRow>
@@ -71,9 +76,11 @@ export default function ContractFormComponent({ form }) {
>
<InputNumber />
</Form.Item>
<Form.Item label={t("contracts.fields.kmend")} name="kmend">
<InputNumber />
</Form.Item>
{create ? null : (
<Form.Item label={t("contracts.fields.kmend")} name="kmend">
<InputNumber />
</Form.Item>
)}
</LayoutFormRow>
<LayoutFormRow>
<Form.Item

View File

@@ -8,7 +8,7 @@ import { DateFormatter } from "../../utils/DateFormatter";
export default function CourtesyCarContractListComponent({ contracts }) {
const [state, setState] = useState({
sortedInfo: {},
filteredInfo: { text: "" }
filteredInfo: { text: "" },
});
const { t } = useTranslation();
@@ -26,7 +26,7 @@ export default function CourtesyCarContractListComponent({ contracts }) {
<Link to={`/manage/courtesycars/contracts/${record.id}`}>
{record.agreementnumber || ""}
</Link>
)
),
},
{
title: t("jobs.fields.ro_number"),
@@ -40,7 +40,7 @@ export default function CourtesyCarContractListComponent({ contracts }) {
<Link to={`/manage/jobs/${record.job.id}`}>
{record.job.ro_number || ""}
</Link>
)
),
},
{
title: t("contracts.fields.driver"),
@@ -50,7 +50,7 @@ export default function CourtesyCarContractListComponent({ contracts }) {
sortOrder:
state.sortedInfo.columnKey === "driver_ln" && state.sortedInfo.order,
render: (text, record) =>
`${record.driver_fn || ""} ${record.driver_ln || ""}`
`${record.driver_fn || ""} ${record.driver_ln || ""}`,
},
{
title: t("contracts.fields.status"),
@@ -59,7 +59,7 @@ export default function CourtesyCarContractListComponent({ contracts }) {
sorter: (a, b) => alphaSort(a.status, b.status),
sortOrder:
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
render: (text, record) => t(record.status)
render: (text, record) => t(record.status),
},
{
title: t("contracts.fields.start"),
@@ -68,7 +68,7 @@ export default function CourtesyCarContractListComponent({ contracts }) {
sorter: (a, b) => alphaSort(a.start, b.start),
sortOrder:
state.sortedInfo.columnKey === "start" && state.sortedInfo.order,
render: (text, record) => <DateFormatter>{record.start}</DateFormatter>
render: (text, record) => <DateFormatter>{record.start}</DateFormatter>,
},
{
title: t("contracts.fields.scheduledreturn"),
@@ -80,8 +80,8 @@ export default function CourtesyCarContractListComponent({ contracts }) {
state.sortedInfo.order,
render: (text, record) => (
<DateFormatter>{record.scheduledreturn}</DateFormatter>
)
}
),
},
];
const handleTableChange = (pagination, filters, sorter) => {
@@ -91,7 +91,7 @@ export default function CourtesyCarContractListComponent({ contracts }) {
<Table
size="small"
pagination={{ position: "top" }}
columns={columns.map(item => ({ ...item }))}
columns={columns.map((item) => ({ ...item }))}
rowKey="id"
dataSource={contracts}
onChange={handleTableChange}

View File

@@ -6,161 +6,137 @@ import CourtesyCarStatus from "../courtesy-car-status-select/courtesy-car-status
import FormDatePicker from "../form-date-picker/form-date-picker.component";
import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function CourtesyCarCreateFormComponent({ form, saveLoading }) {
const { t } = useTranslation();
return (
<div>
<Button type="primary" loading={saveLoading} htmlType="submit">
<Button
type="primary"
loading={saveLoading}
onClick={() => form.submit()}
>
{t("general.actions.save")}
</Button>
<div className="imex-flex-row__grow imex-flex-row__margin-large">
<FormFieldsChanged form={form} />
</div>
<Form.Item
label={t("courtesycars.fields.make")}
name="make"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.model")}
name="model"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.year")}
name="year"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.plate")}
name="plate"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.color")}
name="color"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.vin")}
name="vin"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.fleetnumber")}
name="fleetnumber"
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.purchasedate")}
name="purchasedate"
>
<FormDatePicker />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.servicestartdate")}
name="servicestartdate"
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.serviceenddate")}
name="serviceenddate"
>
<FormDatePicker />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.leaseenddate")}
name="leaseenddate"
>
<FormDatePicker />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.status")}
name="status"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<CourtesyCarStatus />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.nextservicekm")}
name="nextservicekm"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.nextservicedate")}
name="nextservicedate"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<FormDatePicker />
</Form.Item>
<Form.Item label={t("courtesycars.fields.damage")} name="damage">
<Input />
</Form.Item>
<Form.Item label={t("courtesycars.fields.notes")} name="notes">
<Input />
</Form.Item>
<FormFieldsChanged form={form} />
<LayoutFormRow>
<Form.Item
label={t("courtesycars.fields.make")}
name="make"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.model")}
name="model"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.year")}
name="year"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.plate")}
name="plate"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.color")}
name="color"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.vin")}
name="vin"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<Input />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow>
<Form.Item
label={t("courtesycars.fields.mileage")}
name="mileage"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.fleetnumber")}
name="fleetnumber"
>
<Input />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.purchasedate")}
name="purchasedate"
>
<FormDatePicker />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.servicestartdate")}
name="servicestartdate"
>
<FormDatePicker />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.serviceenddate")}
name="serviceenddate"
>
<FormDatePicker />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.leaseenddate")}
name="leaseenddate"
>
<FormDatePicker />
</Form.Item>
</LayoutFormRow>
<Form.Item
label={t("courtesycars.fields.fuel")}
name="fuel"
@@ -173,33 +149,78 @@ export default function CourtesyCarCreateFormComponent({ form, saveLoading }) {
>
<CourtesyCarFuelSlider />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.registrationexpires")}
name="registrationexpires"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<FormDatePicker />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.insuranceexpires")}
name="insuranceexpires"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<FormDatePicker />
</Form.Item>
<Form.Item label={t("courtesycars.fields.dailycost")} name="dailycost">
<CurrencyInput />
</Form.Item>
<LayoutFormRow>
<Form.Item
label={t("courtesycars.fields.status")}
name="status"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<CourtesyCarStatus />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.nextservicekm")}
name="nextservicekm"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.nextservicedate")}
name="nextservicedate"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<FormDatePicker />
</Form.Item>
<Form.Item label={t("courtesycars.fields.damage")} name="damage">
<Input.TextArea />
</Form.Item>
<Form.Item label={t("courtesycars.fields.notes")} name="notes">
<Input.TextArea />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.registrationexpires")}
name="registrationexpires"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<FormDatePicker />
</Form.Item>
<Form.Item
label={t("courtesycars.fields.insuranceexpires")}
name="insuranceexpires"
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<FormDatePicker />
</Form.Item>
<Form.Item label={t("courtesycars.fields.dailycost")} name="dailycost">
<CurrencyInput />
</Form.Item>
</LayoutFormRow>
</div>
);
}

View File

@@ -76,7 +76,7 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
state.sortedInfo.columnKey === "model" && state.sortedInfo.order,
},
{
title: t("courtesycars.fields.outwith"),
title: t("courtesycars.labels.outwith"),
dataIndex: "outwith",
key: "outwith",
// sorter: (a, b) => alphaSort(a.model, b.model),

View File

@@ -6,7 +6,7 @@ export default function LayoutFormRow({ header, children, grow = false }) {
if (!!!children.length) {
//We have only one element. It's going to get the whole thing.
return (
<div className='imex-form-row'>
<div className="imex-form-row">
{header ? (
<Typography.Title level={4}>{header}</Typography.Title>
) : null}
@@ -37,14 +37,17 @@ export default function LayoutFormRow({ header, children, grow = false }) {
};
return (
<div className='imex-form-row'>
<div className="imex-form-row">
{header ? <Typography.Title level={4}>{header}</Typography.Title> : null}
<Row {...rowGutter}>
{children.map((c, idx) => (
<Col key={idx} {...colSpan(c.props && c.props.span)}>
{c}
</Col>
))}
{children.map(
(c, idx) =>
c && (
<Col key={idx} {...colSpan(c && c.props && c.props.span)}>
{c}
</Col>
)
)}
</Row>
</div>
);

View File

@@ -1,12 +1,22 @@
import gql from "graphql-tag";
export const INSERT_NEW_CONTRACT = gql`
mutation INSERT_NEW_CONTRACT($contract: [cccontracts_insert_input!]!) {
mutation INSERT_NEW_CONTRACT(
$contract: [cccontracts_insert_input!]!
$ccId: uuid!
) {
insert_cccontracts(objects: $contract) {
returning {
id
}
}
update_courtesycars_by_pk(
pk_columns: { id: $ccId }
_set: { status: "courtesycars.status.out" }
) {
status
id
}
}
`;

View File

@@ -14,7 +14,12 @@ export const INSERT_NEW_COURTESY_CAR = gql`
export const QUERY_AVAILABLE_CC = gql`
query QUERY_AVAILABLE_CC {
courtesycars(where: { serviceenddate: { _is_null: true } }) {
courtesycars(
where: {
serviceenddate: { _is_null: true }
status: { _eq: "courtesycars.status.in" }
}
) {
color
dailycost
damage
@@ -26,6 +31,8 @@ export const QUERY_AVAILABLE_CC = gql`
plate
status
year
dailycost
mileage
}
}
`;
@@ -96,7 +103,9 @@ export const QUERY_CC_BY_PK = gql`
status
vin
year
mileage
cccontracts {
agreementnumber
id
status
start

View File

@@ -18,9 +18,9 @@ export default function ContractCreatePageComponent({
{t("general.actions.create")}
</Button>
<ContractJobsContainer selectedJobState={selectedJobState} />
<ContractCarsContainer selectedCarState={selectedCarState} />
<ContractCarsContainer selectedCarState={selectedCarState} form={form} />
<ContractLicenseDecodeButton form={form} />
<ContractFormComponent form={form} />
<ContractFormComponent create form={form} />
</div>
);
}

View File

@@ -35,8 +35,10 @@ export function ContractCreatePageContainer({ bodyshop, setBreadcrumbs }) {
setLoading(true);
insertContract({
variables: {
ccId: selectedCarState[0],
contract: {
...values,
status: "contracts.status.out",
courtesycarid: selectedCarState[0],
jobid: selectedJobState[0],
},
@@ -46,7 +48,7 @@ export function ContractCreatePageContainer({ bodyshop, setBreadcrumbs }) {
notification["success"]({
message: t("contracts.successes.saved"),
});
form.resetFields();
history.push(
`/manage/courtesycars/contracts/${response.data.insert_cccontracts.returning[0].id}`
);
@@ -87,7 +89,6 @@ export function ContractCreatePageContainer({ bodyshop, setBreadcrumbs }) {
form={form}
layout="vertical"
autoComplete="no"
initialValues={{ status: "contracts.status.new" }}
onFinish={handleFinish}
>
<ContractCreatePageComponent

View File

@@ -108,6 +108,7 @@ export function CourtesyCarDetailPageContainer({
form={form}
autoComplete="no"
onFinish={handleFinish}
layout="vertical"
initialValues={
data
? {

View File

@@ -291,6 +291,7 @@
"insuranceexpires": "Insurance Expires On",
"leaseenddate": "Lease Ends On",
"make": "Make",
"mileage": "Mileage",
"model": "Model",
"nextservicedate": "Next Service Date",
"nextservicekm": "Next Service KMs",
@@ -317,6 +318,7 @@
"empty": "Empty",
"full": "Full"
},
"outwith": "Out With",
"return": "Return Courtesy Car",
"vehicle": "Vehicle Description"
},

View File

@@ -291,6 +291,7 @@
"insuranceexpires": "",
"leaseenddate": "",
"make": "",
"mileage": "",
"model": "",
"nextservicedate": "",
"nextservicekm": "",
@@ -317,6 +318,7 @@
"empty": "",
"full": ""
},
"outwith": "",
"return": "",
"vehicle": ""
},

View File

@@ -291,6 +291,7 @@
"insuranceexpires": "",
"leaseenddate": "",
"make": "",
"mileage": "",
"model": "",
"nextservicedate": "",
"nextservicekm": "",
@@ -317,6 +318,7 @@
"empty": "",
"full": ""
},
"outwith": "",
"return": "",
"vehicle": ""
},