Additional Menu Refactors

Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
Dave Richer
2024-01-04 13:31:44 -05:00
18 changed files with 441 additions and 192 deletions

View File

@@ -2,20 +2,25 @@ import {useMutation, useQuery} from "@apollo/client";
import {Button, Form, Popconfirm, Space} from "antd"; import {Button, Form, Popconfirm, Space} from "antd";
import dayjs from "../../utils/day"; import dayjs from "../../utils/day";
import queryString from "query-string"; import queryString from "query-string";
import React, {useState} from "react"; import React, { useState } from "react";
import {useTranslation} from "react-i18next"; import { useTranslation } from "react-i18next";
import {connect} from "react-redux"; import { connect } from "react-redux";
import {useLocation} from "react-router-dom"; import { useLocation } from "react-router-dom";
import {createStructuredSelector} from "reselect"; import { createStructuredSelector } from "reselect";
import {DELETE_BILL_LINE, INSERT_NEW_BILL_LINES, UPDATE_BILL_LINE} from "../../graphql/bill-lines.queries"; import {
import {QUERY_BILL_BY_PK, UPDATE_BILL} from "../../graphql/bills.queries"; DELETE_BILL_LINE,
import {insertAuditTrail} from "../../redux/application/application.actions"; INSERT_NEW_BILL_LINES,
import {setModalContext} from "../../redux/modals/modals.actions"; UPDATE_BILL_LINE
import {selectBodyshop} from "../../redux/user/user.selectors"; } from "../../graphql/bill-lines.queries";
import { QUERY_BILL_BY_PK, UPDATE_BILL } from "../../graphql/bills.queries";
import { insertAuditTrail } from "../../redux/application/application.actions";
import { setModalContext } from "../../redux/modals/modals.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
import AuditTrailMapping from "../../utils/AuditTrailMappings"; import AuditTrailMapping from "../../utils/AuditTrailMappings";
import AlertComponent from "../alert/alert.component"; import AlertComponent from "../alert/alert.component";
import BillFormContainer from "../bill-form/bill-form.container"; import BillFormContainer from "../bill-form/bill-form.container";
import BillMarkExportedButton from "../bill-mark-exported-button/bill-mark-exported-button.component"; import BillMarkExportedButton from "../bill-mark-exported-button/bill-mark-exported-button.component";
import BillPrintButton from "../bill-print-button/bill-print-button.component";
import BillReeportButtonComponent from "../bill-reexport-button/bill-reexport-button.component"; import BillReeportButtonComponent from "../bill-reexport-button/bill-reexport-button.component";
import JobDocumentsGallery from "../jobs-documents-gallery/jobs-documents-gallery.container"; import JobDocumentsGallery from "../jobs-documents-gallery/jobs-documents-gallery.container";
import JobsDocumentsLocalGallery from "../jobs-documents-local-gallery/jobs-documents-local-gallery.container"; import JobsDocumentsLocalGallery from "../jobs-documents-local-gallery/jobs-documents-local-gallery.container";
@@ -158,49 +163,49 @@ export function BillDetailEditcontainer({setPartsOrderContext, insertAuditTrail,
const exported = data && data.bills_by_pk && data.bills_by_pk.exported; const exported = data && data.bills_by_pk && data.bills_by_pk.exported;
return ( return (
<>
{loading && <LoadingSkeleton />}
{data && (
<> <>
{loading && <LoadingSkeleton/>} <PageHeader
{data && ( title={
<> data &&
<PageHeader `${data.bills_by_pk.invoice_number} - ${data.bills_by_pk.vendor.name}`
title={ }
data && extra={
`${data.bills_by_pk.invoice_number} - ${data.bills_by_pk.vendor.name}` <Space>
} <BillDetailEditReturn data={data} />
extra={ <BillPrintButton billid={search.billid} />
<Space> <Popconfirm
<BillDetailEditReturn data={data}/> visible={visible}
onConfirm={() => form.submit()}
<Popconfirm onCancel={() => setVisible(false)}
open={visible} okButtonProps={{ loading: updateLoading }}
onConfirm={() => form.submit()} title={t("bills.labels.editadjwarning")}
onCancel={() => setVisible(false)} >
okButtonProps={{loading: updateLoading}} <Button
title={t("bills.labels.editadjwarning")} htmlType="submit"
> disabled={exported}
<Button onClick={handleSave}
htmlType="submit" loading={updateLoading}
disabled={exported} type="primary"
onClick={handleSave} >
loading={updateLoading} {t("general.actions.save")}
type="primary" </Button>
> </Popconfirm>
{t("general.actions.save")} <BillReeportButtonComponent bill={data && data.bills_by_pk} />
</Button> <BillMarkExportedButton bill={data && data.bills_by_pk} />
</Popconfirm> </Space>
<BillReeportButtonComponent bill={data && data.bills_by_pk}/> }
<BillMarkExportedButton bill={data && data.bills_by_pk}/> />
</Space> <Form
} form={form}
/> onFinish={handleFinish}
<Form initialValues={transformData(data)}
form={form} layout="vertical"
onFinish={handleFinish} >
initialValues={transformData(data)} <BillFormContainer form={form} billEdit disabled={exported} />
layout="vertical"
>
<BillFormContainer form={form} billEdit disabled={exported}/>
{bodyshop.uselocalmediaserver ? ( {bodyshop.uselocalmediaserver ? (
<JobsDocumentsLocalGallery <JobsDocumentsLocalGallery

View File

@@ -0,0 +1,38 @@
import { Button, Space } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { GenerateDocument } from "../../utils/RenderTemplate";
import { TemplateList } from "../../utils/TemplateConstants";
export default function BillPrintButton({ billid }) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const Templates = TemplateList("job_special");
const submitHandler = async () => {
setLoading(true);
try {
await GenerateDocument(
{
name: Templates.parts_invoice_label_single.key,
variables: {
id: billid,
},
},
{},
"p"
);
} catch (e) {
console.warn("Warning: Error generating a document.");
}
setLoading(false);
};
return (
<Space wrap>
<Button loading={loading} onClick={submitHandler}>
{t("bills.labels.printlabels")}
</Button>
</Space>
);
}

View File

@@ -35,6 +35,15 @@ export default function ContractsCarsComponent({
state.sortedInfo.columnKey === "status" && state.sortedInfo.order, state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
render: (text, record) => <div>{t(record.status)}</div>, render: (text, record) => <div>{t(record.status)}</div>,
}, },
{
title: t("courtesycars.fields.readiness"),
dataIndex: "readiness",
key: "readiness",
sorter: (a, b) => alphaSort(a.readiness, b.readiness),
sortOrder:
state.sortedInfo.columnKey === "readiness" && state.sortedInfo.order,
render: (text, record) => t(record.readiness),
},
{ {
title: t("courtesycars.fields.year"), title: t("courtesycars.fields.year"),
dataIndex: "year", dataIndex: "year",

View File

@@ -8,6 +8,7 @@ import { useTranslation } from "react-i18next";
import { CHECK_CC_FLEET_NUMBER } from "../../graphql/courtesy-car.queries"; import { CHECK_CC_FLEET_NUMBER } from "../../graphql/courtesy-car.queries";
import { DateFormatter } from "../../utils/DateFormatter"; import { DateFormatter } from "../../utils/DateFormatter";
import CourtesyCarFuelSlider from "../courtesy-car-fuel-select/courtesy-car-fuel-select.component"; import CourtesyCarFuelSlider from "../courtesy-car-fuel-select/courtesy-car-fuel-select.component";
import CourtesyCarReadiness from "../courtesy-car-readiness-select/courtesy-car-readiness-select.component";
import CourtesyCarStatus from "../courtesy-car-status-select/courtesy-car-status-select.component"; import CourtesyCarStatus from "../courtesy-car-status-select/courtesy-car-status-select.component";
import FormDatePicker from "../form-date-picker/form-date-picker.component"; import FormDatePicker from "../form-date-picker/form-date-picker.component";
//import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component"; //import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
@@ -214,6 +215,12 @@ export default function CourtesyCarCreateFormComponent({ form, saveLoading }) {
> >
<CourtesyCarStatus /> <CourtesyCarStatus />
</Form.Item> </Form.Item>
<Form.Item
label={t("courtesycars.fields.readiness")}
name="readiness"
>
<CourtesyCarReadiness />
</Form.Item>
<div> <div>
<Form.Item <Form.Item
label={t("courtesycars.fields.nextservicekm")} label={t("courtesycars.fields.nextservicekm")}

View File

@@ -34,6 +34,32 @@ const CourtesyCarFuelComponent = (props, ref) => {
step={null} step={null}
style={{ marginLeft: "2rem", marginRight: "2rem" }} style={{ marginLeft: "2rem", marginRight: "2rem" }}
{...props} {...props}
tooltip={{
formatter: (value) => {
switch (value) {
case 0:
return t("courtesycars.labels.fuel.empty");
case 13:
return t("courtesycars.labels.fuel.18");
case 25:
return t("courtesycars.labels.fuel.14");
case 38:
return t("courtesycars.labels.fuel.38");
case 50:
return t("courtesycars.labels.fuel.12");
case 63:
return t("courtesycars.labels.fuel.58");
case 75:
return t("courtesycars.labels.fuel.34");
case 88:
return t("courtesycars.labels.fuel.78");
case 100:
return t("courtesycars.labels.fuel.full");
default:
return value;
}
},
}}
/> />
); );
}; };

View File

@@ -0,0 +1,35 @@
import { Select } from "antd";
import React, { forwardRef, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
const { Option } = Select;
const CourtesyCarReadinessComponent = ({ value, onChange }, ref) => {
const [option, setOption] = useState(value);
const { t } = useTranslation();
useEffect(() => {
if (value !== option && onChange) {
onChange(option);
}
}, [value, option, onChange]);
return (
<Select
allowClear
ref={ref}
value={option}
style={{
width: 100,
}}
onChange={setOption}
>
<Option value="courtesycars.readiness.ready">
{t("courtesycars.readiness.ready")}
</Option>
<Option value="courtesycars.readiness.notready">
{t("courtesycars.readiness.notready")}
</Option>
</Select>
);
};
export default forwardRef(CourtesyCarReadinessComponent);

View File

@@ -90,6 +90,26 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
); );
}, },
}, },
{
title: t("courtesycars.fields.readiness"),
dataIndex: "readiness",
key: "readiness",
sorter: (a, b) => alphaSort(a.readiness, b.readiness),
filters: [
{
text: t("courtesycars.readiness.ready"),
value: "courtesycars.readiness.ready",
},
{
text: t("courtesycars.readiness.notready"),
value: "courtesycars.readiness.notready",
},
],
onFilter: (value, record) => value.includes(record.readiness),
sortOrder:
state.sortedInfo.columnKey === "readiness" && state.sortedInfo.order,
render: (text, record) => t(record.readiness),
},
{ {
title: t("courtesycars.fields.year"), title: t("courtesycars.fields.year"),
dataIndex: "year", dataIndex: "year",
@@ -130,6 +150,36 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
sortOrder: sortOrder:
state.sortedInfo.columnKey === "plate" && state.sortedInfo.order, state.sortedInfo.columnKey === "plate" && state.sortedInfo.order,
}, },
{
title: t("courtesycars.fields.fuel"),
dataIndex: "fuel",
key: "fuel",
sorter: (a, b) => alphaSort(a.fuel, b.fuel),
sortOrder:
state.sortedInfo.columnKey === "fuel" && state.sortedInfo.order,
render: (text, record) => {
switch (record.fuel) {
case 100:
return t("courtesycars.labels.fuel.full");
case 88:
return t("courtesycars.labels.fuel.78");
case 63:
return t("courtesycars.labels.fuel.58");
case 50:
return t("courtesycars.labels.fuel.12");
case 38:
return t("courtesycars.labels.fuel.34");
case 25:
return t("courtesycars.labels.fuel.14");
case 13:
return t("courtesycars.labels.fuel.18");
case 0:
return t("courtesycars.labels.fuel.empty");
default:
return record.fuel;
}
},
},
{ {
title: t("courtesycars.labels.outwith"), title: t("courtesycars.labels.outwith"),
dataIndex: "outwith", dataIndex: "outwith",

View File

@@ -1,8 +1,8 @@
import { import {
BranchesOutlined,
ExclamationCircleFilled, ExclamationCircleFilled,
PauseCircleOutlined, PauseCircleOutlined,
WarningFilled, WarningFilled,
BranchesOutlined,
} from "@ant-design/icons"; } from "@ant-design/icons";
import { Card, Col, Row, Space, Tag, Tooltip } from "antd"; import { Card, Col, Row, Space, Tag, Tooltip } from "antd";
import React, { useState } from "react"; import React, { useState } from "react";
@@ -222,6 +222,9 @@ export function JobsDetailHeader({ job, bodyshop, disabled }) {
{`${job.v_vin || t("general.labels.na")}`} {`${job.v_vin || t("general.labels.na")}`}
</VehicleVinDisplay> </VehicleVinDisplay>
</DataLabel> </DataLabel>
<DataLabel label={t("jobs.fields.regie_number")}>
{job.regie_number || t("general.labels.na")}
</DataLabel>
<DataLabel label={t("jobs.labels.relatedros")}> <DataLabel label={t("jobs.labels.relatedros")}>
<JobsRelatedRos jobid={job.id} job={job} /> <JobsRelatedRos jobid={job.id} job={job} />
</DataLabel> </DataLabel>

View File

@@ -1,83 +1,126 @@
import { Button, Dropdown } from "antd"; import {Button, Dropdown} from "antd";
import React, { useState } from "react"; import React, {useState} from "react";
import { TemplateList } from "../../utils/TemplateConstants"; import {TemplateList} from "../../utils/TemplateConstants";
import { useTranslation } from "react-i18next"; import {useTranslation} from "react-i18next";
import { GenerateDocument } from "../../utils/RenderTemplate"; import {GenerateDocument} from "../../utils/RenderTemplate";
import {connect} from "react-redux";
import {createStructuredSelector} from "reselect";
import {selectBodyshop} from "../../redux/user/user.selectors";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
const ProdTemplates = TemplateList("production"); const ProdTemplates = TemplateList("production");
const { const {
production_by_technician_one, production_by_technician_one,
production_by_category_one, production_by_category_one,
production_by_repair_status_one, production_by_repair_status_one,
} = TemplateList("special"); } = TemplateList("special");
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language)) //setUserLanguage: language => dispatch(setUserLanguage(language))
}); });
export default connect( export default connect(
mapStateToProps, mapStateToProps,
mapDispatchToProps mapDispatchToProps
)(ProductionListPrint); )(ProductionListPrint);
export function ProductionListPrint({ bodyshop }) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const menu = {
items: [
...Object.keys(ProdTemplates).map((key) => ({
key: key,
label: ProdTemplates[key].title,
})),
{
key: "production_by_technician_one",
label: t("reportcenter.templates.production_by_technician_one"),
children: bodyshop.employees
.filter((e) => e.active)
.map((e) => ({
key: e.id,
label: `${e.first_name} ${e.last_name}`,
})),
},
{
key: "production_by_category_one",
label: t("reportcenter.templates.production_by_category_one"),
children: bodyshop.md_categories.map((e) => ({
key: e,
label: e,
})),
},
{
key: "production_by_repair_status_one",
label: t("reportcenter.templates.production_by_repair_status_one"),
children: bodyshop.md_ro_statuses.production_statuses.map((e) => ({
key: e,
label: e,
})),
},
],
onClick: async (e) => {
setLoading(true);
await GenerateDocument(
{
name: ProdTemplates[e.key].key,
// variables: { id: contract.id },
},
{},
"p"
);
setLoading(false);
},
} export function ProductionListPrint({bodyshop}) {
return ( const {t} = useTranslation();
<Dropdown trigger="click" menu={menu}> const [loading, setLoading] = useState(false);
<Button loading={loading}>{t("general.labels.print")}</Button>
</Dropdown> const menu = {
); items: [
...Object.keys(ProdTemplates).map((key) => {
return {
key: key,
label: ProdTemplates[key].title,
onClick: async () => {
setLoading(true);
await GenerateDocument(
{
name: ProdTemplates[key].key,
// variables: { id: contract.id },
},
{},
"p"
);
setLoading(false);
}
};
}),
{
key: key,
label: t("reportcenter.templates.production_by_technician_one"),
children: bodyshop.employees
.filter((e) => e.active)
.map((e) => {
return {
key: e.id,
label: `${e.first_name} ${e.last_name}`,
onClick: async () => {
setLoading(true);
await GenerateDocument(
{
name: production_by_technician_one.key,
variables: {id: e.id},
},
{},
"p"
);
setLoading(false);
}
};
})
},
{
label: t("reportcenter.templates.production_by_category_one"),
children: bodyshop.md_categories.map((e) => {
return {
key: e,
label: e,
onClick: async () => {
setLoading(true);
await GenerateDocument(
{
name: production_by_category_one.key,
variables: {category: e},
},
{},
"p"
);
setLoading(false);
}
};
})
},
{
label: t("reportcenter.templates.production_by_repair_status_one"),
children: bodyshop.md_ro_statuses.production_statuses.map((e) => {
return {
key: e,
label: e,
onClick: async () => {
setLoading(true);
await GenerateDocument(
{
name: production_by_repair_status_one.key,
variables: {status: e},
},
{},
"p"
);
setLoading(false);
}
};
})
}
]
};
return (<Dropdown trigger="click" menu={menu}>
<Button loading={loading}>{t("general.labels.print")}</Button>
</Dropdown>
);
} }

View File

@@ -30,15 +30,15 @@ export const QUERY_AVAILABLE_CC = gql`
fuel fuel
id id
make make
model
plate
status
year
dailycost
mileage mileage
model
notes notes
nextservicekm nextservicekm
nextservicedate nextservicedate
plate
readiness
status
year
} }
} }
`; `;
@@ -68,19 +68,20 @@ export const QUERY_ALL_CC = gql`
insuranceexpires insuranceexpires
leaseenddate leaseenddate
make make
mileage
model model
nextservicedate nextservicedate
nextservicekm nextservicekm
notes notes
plate plate
purchasedate purchasedate
readiness
registrationexpires registrationexpires
serviceenddate serviceenddate
servicestartdate servicestartdate
status status
vin vin
year year
mileage
cccontracts( cccontracts(
where: { status: { _eq: "contracts.status.out" } } where: { status: { _eq: "contracts.status.out" } }
order_by: { contract_date: desc } order_by: { contract_date: desc }
@@ -90,10 +91,10 @@ export const QUERY_ALL_CC = gql`
scheduledreturn scheduledreturn
job { job {
id id
ro_number
ownr_fn ownr_fn
ownr_ln ownr_ln
ownr_co_nm ownr_co_nm
ro_number
} }
} }
} }
@@ -119,19 +120,20 @@ export const QUERY_CC_BY_PK = gql`
insuranceexpires insuranceexpires
leaseenddate leaseenddate
make make
mileage
model model
nextservicedate nextservicedate
nextservicekm nextservicekm
notes notes
plate plate
purchasedate purchasedate
readiness
registrationexpires registrationexpires
serviceenddate serviceenddate
servicestartdate servicestartdate
status status
vin vin
year year
mileage
cccontracts_aggregate { cccontracts_aggregate {
aggregate { aggregate {
count(distinct: true) count(distinct: true)
@@ -139,21 +141,20 @@ export const QUERY_CC_BY_PK = gql`
} }
cccontracts(offset: $offset, limit: $limit, order_by: $order) { cccontracts(offset: $offset, limit: $limit, order_by: $order) {
agreementnumber agreementnumber
driver_fn
driver_ln
id id
status
start
scheduledreturn
kmstart kmstart
kmend kmend
driver_ln scheduledreturn
driver_fn start
status
job { job {
ro_number id
ownr_ln ownr_ln
ownr_fn ownr_fn
ownr_co_nm ownr_co_nm
id ro_number
} }
} }
} }

View File

@@ -1,6 +1,6 @@
import { useMutation, useQuery } from "@apollo/client"; import { useMutation, useQuery } from "@apollo/client";
import { Form, notification } from "antd"; import { Form, notification } from "antd";
import dayjs from "../../utils/day"; import dayjs from "dayjs";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
@@ -14,6 +14,7 @@ import {
setSelectedHeader, setSelectedHeader,
} from "../../redux/application/application.actions"; } from "../../redux/application/application.actions";
import { CreateRecentItem } from "../../utils/create-recent-item"; import { CreateRecentItem } from "../../utils/create-recent-item";
import UndefinedToNull from "./../../utils/undefinedtonull";
import CourtesyCarDetailPageComponent from "./courtesy-car-detail.page.component"; import CourtesyCarDetailPageComponent from "./courtesy-car-detail.page.component";
import NotFound from "../../components/not-found/not-found.component"; import NotFound from "../../components/not-found/not-found.component";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component"; import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
@@ -112,7 +113,10 @@ export function CourtesyCarDetailPageContainer({
setSaveLoading(true); setSaveLoading(true);
const result = await updateCourtesyCar({ const result = await updateCourtesyCar({
variables: { cc: { ...values }, ccId: ccId }, variables: {
cc: { ...UndefinedToNull(values, ["readiness"]) },
ccId: ccId,
},
refetchQueries: ["QUERY_CC_BY_PK"], refetchQueries: ["QUERY_CC_BY_PK"],
awaitRefetchQueries: true, awaitRefetchQueries: true,
}); });

View File

@@ -1,6 +1,6 @@
import _ from "lodash";
import { useLazyQuery, useMutation } from "@apollo/client"; import { useLazyQuery, useMutation } from "@apollo/client";
import { Form, notification } from "antd"; import { Form, notification } from "antd";
import _ from "lodash";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
@@ -90,6 +90,7 @@ function JobsCreateContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
{}, {},
values, values,
{ date_open: new Date() }, { date_open: new Date() },
{ date_estimated: new Date() },
{ {
vehicle: vehicle:
state.vehicle.selectedid || state.vehicle.none state.vehicle.selectedid || state.vehicle.none

View File

@@ -214,6 +214,7 @@
"new": "New Bill", "new": "New Bill",
"noneselected": "No bill selected.", "noneselected": "No bill selected.",
"onlycmforinvoiced": "Only credit memos can be entered for any Job that has been invoiced, exported, or voided.", "onlycmforinvoiced": "Only credit memos can be entered for any Job that has been invoiced, exported, or voided.",
"printlabels": "Print Labels",
"retailtotal": "Bills Retail Total", "retailtotal": "Bills Retail Total",
"savewithdiscrepancy": "You are about to save this bill with a discrepancy. The system will continue to use the calculated amount using the bill lines. Press cancel to return to the bill.", "savewithdiscrepancy": "You are about to save this bill with a discrepancy. The system will continue to use the calculated amount using the bill lines. Press cancel to return to the bill.",
"state_tax": "Provincial/State Tax", "state_tax": "Provincial/State Tax",
@@ -785,6 +786,7 @@
"notes": "Notes", "notes": "Notes",
"plate": "Plate Number", "plate": "Plate Number",
"purchasedate": "Purchase Date", "purchasedate": "Purchase Date",
"readiness": "Readiness",
"registrationexpires": "Registration Expires On", "registrationexpires": "Registration Expires On",
"serviceenddate": "Usage End Date", "serviceenddate": "Usage End Date",
"servicestartdate": "Usage Start Date", "servicestartdate": "Usage Start Date",
@@ -821,6 +823,10 @@
}, },
"successes": { "successes": {
"saved": "Courtesy Car saved successfully." "saved": "Courtesy Car saved successfully."
},
"readiness": {
"notready": "Not Ready",
"ready": "Ready"
} }
}, },
"csi": { "csi": {

View File

@@ -214,6 +214,7 @@
"new": "", "new": "",
"noneselected": "", "noneselected": "",
"onlycmforinvoiced": "", "onlycmforinvoiced": "",
"printlabels": "",
"retailtotal": "", "retailtotal": "",
"savewithdiscrepancy": "", "savewithdiscrepancy": "",
"state_tax": "", "state_tax": "",
@@ -785,6 +786,7 @@
"notes": "", "notes": "",
"plate": "", "plate": "",
"purchasedate": "", "purchasedate": "",
"readiness": "",
"registrationexpires": "", "registrationexpires": "",
"serviceenddate": "", "serviceenddate": "",
"servicestartdate": "", "servicestartdate": "",
@@ -821,6 +823,10 @@
}, },
"successes": { "successes": {
"saved": "" "saved": ""
},
"readiness": {
"notready": "",
"ready": ""
} }
}, },
"csi": { "csi": {

View File

@@ -214,6 +214,7 @@
"new": "", "new": "",
"noneselected": "", "noneselected": "",
"onlycmforinvoiced": "", "onlycmforinvoiced": "",
"printlabels": "",
"retailtotal": "", "retailtotal": "",
"savewithdiscrepancy": "", "savewithdiscrepancy": "",
"state_tax": "", "state_tax": "",
@@ -785,6 +786,7 @@
"notes": "", "notes": "",
"plate": "", "plate": "",
"purchasedate": "", "purchasedate": "",
"readiness": "",
"registrationexpires": "", "registrationexpires": "",
"serviceenddate": "", "serviceenddate": "",
"servicestartdate": "", "servicestartdate": "",
@@ -821,6 +823,10 @@
}, },
"successes": { "successes": {
"saved": "" "saved": ""
},
"readiness": {
"notready": "",
"ready": ""
} }
}, },
"csi": { "csi": {

View File

@@ -1388,60 +1388,62 @@
- active: - active:
_eq: true _eq: true
columns: columns:
- id
- created_at
- updated_at
- bodyshopid - bodyshopid
- make
- model
- year
- plate
- color - color
- vin - created_at
- fleetnumber
- purchasedate
- servicestartdate
- serviceenddate
- leaseenddate
- status
- nextservicekm
- nextservicedate
- damage
- notes
- fuel
- registrationexpires
- insuranceexpires
- dailycost - dailycost
- damage
- fleetnumber
- fuel
- id
- insuranceexpires
- leaseenddate
- make
- mileage - mileage
- model
- nextservicedate
- nextservicekm
- notes
- plate
- purchasedate
- readiness
- registrationexpires
- serviceenddate
- servicestartdate
- status
- updated_at
- vin
- year
select_permissions: select_permissions:
- role: user - role: user
permission: permission:
columns: columns:
- bodyshopid
- color
- created_at
- dailycost
- damage
- fleetnumber
- fuel
- id
- insuranceexpires - insuranceexpires
- leaseenddate - leaseenddate
- make
- mileage
- model
- nextservicedate - nextservicedate
- nextservicekm
- notes
- plate
- purchasedate - purchasedate
- readiness
- registrationexpires - registrationexpires
- serviceenddate - serviceenddate
- servicestartdate - servicestartdate
- dailycost
- fuel
- mileage
- nextservicekm
- color
- damage
- fleetnumber
- make
- model
- notes
- plate
- status - status
- updated_at
- vin - vin
- year - year
- created_at
- updated_at
- bodyshopid
- id
filter: filter:
bodyshop: bodyshop:
associations: associations:
@@ -1456,31 +1458,32 @@
- role: user - role: user
permission: permission:
columns: columns:
- bodyshopid
- color
- created_at
- dailycost
- damage
- fleetnumber
- fuel
- id
- insuranceexpires - insuranceexpires
- leaseenddate - leaseenddate
- make
- mileage
- model
- nextservicedate - nextservicedate
- nextservicekm
- notes
- plate
- purchasedate - purchasedate
- readiness
- registrationexpires - registrationexpires
- serviceenddate - serviceenddate
- servicestartdate - servicestartdate
- dailycost
- fuel
- mileage
- nextservicekm
- color
- damage
- fleetnumber
- make
- model
- notes
- plate
- status - status
- updated_at
- vin - vin
- year - year
- created_at
- updated_at
- bodyshopid
- id
filter: filter:
bodyshop: bodyshop:
associations: associations:

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."courtesycars" add column "readiness" text
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."courtesycars" add column "readiness" text
null;