Compare commits
257 Commits
release/20
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44f2287b07 | ||
|
|
8f91416623 | ||
|
|
a18dbbb6c4 | ||
|
|
57d8ca5829 | ||
|
|
4c6a2d6d63 | ||
|
|
5861d0e9b6 | ||
|
|
e36904794b | ||
|
|
1c89d12034 | ||
|
|
5e36a4ae89 | ||
|
|
f553307587 | ||
|
|
2c80c81197 | ||
|
|
9d865cf130 | ||
|
|
8e119ce0dd | ||
|
|
fe49161718 | ||
|
|
040e366335 | ||
|
|
4655663dd8 | ||
|
|
6e1fbda79b | ||
|
|
b2f616f1eb | ||
|
|
76eec7bebc | ||
|
|
aa5f405e1b | ||
|
|
ca9752d119 | ||
|
|
45b4af5225 | ||
|
|
d2d310cf57 | ||
|
|
5d1a7657a9 | ||
|
|
5cb17994cd | ||
|
|
dab78e3dc9 | ||
|
|
1232f28b3d | ||
|
|
8e8d40d4b0 | ||
|
|
7fae408454 | ||
|
|
1cdafaa2cc | ||
|
|
b9ca7ef2e3 | ||
|
|
60867ae4dc | ||
|
|
b0ddb62ac0 | ||
|
|
39a4646339 | ||
|
|
584322819f | ||
|
|
051ee347a9 | ||
|
|
acf1b387de | ||
|
|
d350515c90 | ||
|
|
121e579388 | ||
|
|
cf5ebb8130 | ||
|
|
2dabf3c811 | ||
|
|
04509fa587 | ||
|
|
56fef0f43c | ||
|
|
42702ef015 | ||
|
|
25bee3cfdf | ||
|
|
baf06fee6c | ||
|
|
a3557bbc86 | ||
|
|
3e00e7981d | ||
|
|
12fa270a1a | ||
|
|
de250b152a | ||
|
|
c45741257f | ||
|
|
3988386c79 | ||
|
|
492032c1e2 | ||
|
|
8222e56485 | ||
|
|
49a61e1564 | ||
|
|
eed18aa1c5 | ||
|
|
2de3f8b022 | ||
|
|
91476c7ad3 | ||
|
|
00eb7926f9 | ||
|
|
854ad21b20 | ||
|
|
3c3f9521f6 | ||
|
|
561bcf10d9 | ||
|
|
75d9faa05b | ||
|
|
ac72177fbb | ||
|
|
088faf152c | ||
|
|
90cba9ed24 | ||
|
|
a0702785c5 | ||
|
|
6898d609fe | ||
|
|
d70893e2ba | ||
|
|
6155b8bf24 | ||
|
|
239dc5c62d | ||
|
|
2586855f11 | ||
|
|
b3b3c4c737 | ||
|
|
abe5fadeea | ||
|
|
08e5543536 | ||
|
|
f1a10e0df4 | ||
|
|
7dc3c00628 | ||
|
|
1c5c403d65 | ||
|
|
7594f53e88 | ||
|
|
b861957342 | ||
|
|
2bf24ff5a1 | ||
|
|
6e5fcbfdbd | ||
|
|
759a8ac58c | ||
|
|
833baca9cc | ||
|
|
889ef61185 | ||
|
|
add1eddbc1 | ||
|
|
1c63aa39c4 | ||
|
|
0cabd80b94 | ||
|
|
7f756bab88 | ||
|
|
99b847822f | ||
|
|
f66d9b8c09 | ||
|
|
5660de42af | ||
|
|
ccbe92c275 | ||
|
|
b0ea8a71fb | ||
|
|
060871306f | ||
|
|
2eb4e142ff | ||
|
|
adf8cf9e8d | ||
|
|
852fd9c388 | ||
|
|
e921f28105 | ||
|
|
6db68b76db | ||
|
|
51ebfd86e7 | ||
|
|
79a90bb9ee | ||
|
|
1664f9c935 | ||
|
|
23fcdd6375 | ||
|
|
ea7c22daec | ||
|
|
10ffb33ec9 | ||
|
|
f9e023f922 | ||
|
|
c7832bdd82 | ||
|
|
329bdbe22d | ||
|
|
2df046c39d | ||
|
|
46065f1986 | ||
|
|
66b3fb6988 | ||
|
|
5eda224393 | ||
|
|
e387abcd14 | ||
|
|
4c2d4e20a6 | ||
|
|
3d26c2e94e | ||
|
|
d9e2ef9300 | ||
|
|
b00fdadc1b | ||
|
|
4d5e06b9fc | ||
|
|
ad42dd1295 | ||
|
|
1f4c1c9e92 | ||
|
|
2938b9c94c | ||
|
|
2227acab3a | ||
|
|
bde17446ad | ||
|
|
081165b6f5 | ||
|
|
7e717c0b1f | ||
|
|
e242aaa9f5 | ||
|
|
fe60538acf | ||
|
|
2db88f57df | ||
|
|
7461e58000 | ||
|
|
cd0b7a4e56 | ||
|
|
2a3b4e89ab | ||
|
|
1d77eda3e2 | ||
|
|
490e1f696a | ||
|
|
b96c618f54 | ||
|
|
1afda01d34 | ||
|
|
b9d11580d4 | ||
|
|
27fadb9ae2 | ||
|
|
4c5a2cefe9 | ||
|
|
175692559c | ||
|
|
57b27f73c3 | ||
|
|
7badb09ba1 | ||
|
|
c39f1d824a | ||
|
|
132cf98a37 | ||
|
|
59f71d53cd | ||
|
|
f4b3a990d7 | ||
|
|
20371ea00d | ||
|
|
3086a654a1 | ||
|
|
60768c8847 | ||
|
|
a68f8d6880 | ||
|
|
0cad64ff6d | ||
|
|
522665256e | ||
|
|
d3fe2c9d06 | ||
|
|
f080e84985 | ||
|
|
2a0ad46eea | ||
|
|
3a83160b33 | ||
|
|
7725080a11 | ||
|
|
701c532e48 | ||
|
|
1932795f55 | ||
|
|
cc7bd1c792 | ||
|
|
7799d93f3d | ||
|
|
a7cf36d5f8 | ||
|
|
54cc02068c | ||
|
|
f575870685 | ||
|
|
171b61b92f | ||
|
|
de44116940 | ||
|
|
3c0a883326 | ||
|
|
14d6cc94dd | ||
|
|
c0d9bacf1d | ||
|
|
d787821345 | ||
|
|
ed6eab4c38 | ||
|
|
b12c9407d9 | ||
|
|
300aee5b02 | ||
|
|
357f40bdc2 | ||
|
|
0a93551db4 | ||
|
|
8602ccbb8a | ||
|
|
d7b0e3046b | ||
|
|
30689a8ca6 | ||
|
|
0e06b449cb | ||
|
|
8e8208dd9a | ||
|
|
79e2fecb24 | ||
|
|
86e909e4e9 | ||
|
|
c7ff893397 | ||
|
|
3981b8684c | ||
|
|
1fb856f95f | ||
|
|
c62c3fa938 | ||
|
|
554ec37ace | ||
|
|
be4feca990 | ||
|
|
ec45454b3d | ||
|
|
0e78cb47f9 | ||
|
|
e5b8d003ec | ||
|
|
2eb81dde37 | ||
|
|
614549a545 | ||
|
|
5717727d2a | ||
|
|
f3714cea1e | ||
|
|
a3375e6152 | ||
|
|
f48fb7130e | ||
|
|
1460fa6fd7 | ||
|
|
3d9a07bd39 | ||
|
|
bd4aa4027a | ||
|
|
9fa995f002 | ||
|
|
3ed48b26f1 | ||
|
|
d585cacdfc | ||
|
|
55ddaca328 | ||
|
|
3fc7af9780 | ||
|
|
146bf95e51 | ||
|
|
58defad2ea | ||
|
|
9c40a03a06 | ||
|
|
a1b6ccc23d | ||
|
|
9b4247d6f6 | ||
|
|
8a6d94f193 | ||
|
|
6e7d1abd70 | ||
|
|
6bd74aae87 | ||
|
|
f21caa10fc | ||
|
|
dde6f17029 | ||
|
|
1aceef9153 | ||
|
|
678892d134 | ||
|
|
dc187bbf24 | ||
|
|
09aae78715 | ||
|
|
c42276ab3a | ||
|
|
41d25cbc52 | ||
|
|
085c27ad20 | ||
|
|
38e6b5010e | ||
|
|
242c275e7d | ||
|
|
1dc6130fdf | ||
|
|
910afbf48d | ||
|
|
9d9edfd674 | ||
|
|
62a5b49836 | ||
|
|
e93e138f78 | ||
|
|
4639e31e55 | ||
|
|
e8fde14f9b | ||
|
|
90e87adc34 | ||
|
|
81053b3cbf | ||
|
|
f4290bf20c | ||
|
|
5371657aa4 | ||
|
|
599f4e143c | ||
|
|
94440e5c48 | ||
|
|
aa5d6f2090 | ||
|
|
6bde1b1baf | ||
|
|
fc404b1f3b | ||
|
|
c6ba3fd8f0 | ||
|
|
119904ca2b | ||
|
|
f7e1b023df | ||
|
|
5855569194 | ||
|
|
4f852e7493 | ||
|
|
deec40a89c | ||
|
|
145dd9bec6 | ||
|
|
b8e5d4412f | ||
|
|
277fb8f839 | ||
|
|
d3d5485846 | ||
|
|
55091d61d6 | ||
|
|
5b5df8a3a1 | ||
|
|
ccf48cfcf1 | ||
|
|
c89342b6ef | ||
|
|
e97ceb7cbe | ||
|
|
de34cbd937 | ||
|
|
cf7a1b0168 |
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
|||||||
|
GENERATE_SOURCEMAP=false
|
||||||
REACT_APP_GRAPHQL_ENDPOINT=https://db.imex.online/v1/graphql
|
REACT_APP_GRAPHQL_ENDPOINT=https://db.imex.online/v1/graphql
|
||||||
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.imex.online/v1/graphql
|
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.imex.online/v1/graphql
|
||||||
REACT_APP_GA_CODE=231103507
|
REACT_APP_GA_CODE=231103507
|
||||||
|
|||||||
@@ -46,10 +46,11 @@
|
|||||||
"react-cookie": "^4.1.1",
|
"react-cookie": "^4.1.1",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-drag-listview": "^0.2.1",
|
"react-drag-listview": "^0.2.1",
|
||||||
"react-grid-gallery": "^0.5.5",
|
"react-grid-gallery": "^1.0.0",
|
||||||
"react-grid-layout": "^1.3.4",
|
"react-grid-layout": "^1.3.4",
|
||||||
"react-i18next": "^12.2.0",
|
"react-i18next": "^12.2.0",
|
||||||
"react-icons": "^4.7.1",
|
"react-icons": "^4.7.1",
|
||||||
|
"react-image-lightbox": "^5.1.4",
|
||||||
"react-number-format": "^5.1.3",
|
"react-number-format": "^5.1.3",
|
||||||
"react-redux": "^8.0.5",
|
"react-redux": "^8.0.5",
|
||||||
"react-resizable": "^3.0.4",
|
"react-resizable": "^3.0.4",
|
||||||
|
|||||||
@@ -143,13 +143,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Update row highlighting on production board.
|
||||||
//Update row highlighting on production board.
|
|
||||||
.ant-table-tbody > tr.ant-table-row:hover > td {
|
.ant-table-tbody > tr.ant-table-row:hover > td {
|
||||||
background: #eaeaea !important;
|
background: #eaeaea !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.job-line-manual{
|
.job-line-manual {
|
||||||
color: tomato;
|
color: tomato;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td.ant-table-column-sort {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { DELETE_BILL } from "../../graphql/bills.queries";
|
import { DELETE_BILL } from "../../graphql/bills.queries";
|
||||||
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
||||||
|
|
||||||
export default function BillDeleteButton({ bill }) {
|
export default function BillDeleteButton({ bill, callback }) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [deleteBill] = useMutation(DELETE_BILL);
|
const [deleteBill] = useMutation(DELETE_BILL);
|
||||||
@@ -36,6 +36,8 @@ export default function BillDeleteButton({ bill }) {
|
|||||||
|
|
||||||
if (!!!result.errors) {
|
if (!!!result.errors) {
|
||||||
notification["success"]({ message: t("bills.successes.deleted") });
|
notification["success"]({ message: t("bills.successes.deleted") });
|
||||||
|
|
||||||
|
if (callback && typeof callback === "function") callback(bill.id);
|
||||||
} else {
|
} else {
|
||||||
//Check if it's an fkey violation.
|
//Check if it's an fkey violation.
|
||||||
const error = JSON.stringify(result.errors);
|
const error = JSON.stringify(result.errors);
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import { createStructuredSelector } from "reselect";
|
|||||||
import { selectBreadcrumbs } from "../../redux/application/application.selectors";
|
import { selectBreadcrumbs } from "../../redux/application/application.selectors";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import GlobalSearch from "../global-search/global-search.component";
|
import GlobalSearch from "../global-search/global-search.component";
|
||||||
|
import GlobalSearchOs from "../global-search/global-search-os.component";
|
||||||
import "./breadcrumbs.styles.scss";
|
import "./breadcrumbs.styles.scss";
|
||||||
|
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
breadcrumbs: selectBreadcrumbs,
|
breadcrumbs: selectBreadcrumbs,
|
||||||
@@ -15,6 +17,12 @@ const mapStateToProps = createStructuredSelector({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export function BreadCrumbs({ breadcrumbs, bodyshop }) {
|
export function BreadCrumbs({ breadcrumbs, bodyshop }) {
|
||||||
|
const { OpenSearch } = useTreatments(
|
||||||
|
["OpenSearch"],
|
||||||
|
{},
|
||||||
|
bodyshop && bodyshop.imexshopid
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className="breadcrumb-container">
|
<Row className="breadcrumb-container">
|
||||||
<Col xs={24} sm={24} md={16}>
|
<Col xs={24} sm={24} md={16}>
|
||||||
@@ -38,7 +46,7 @@ export function BreadCrumbs({ breadcrumbs, bodyshop }) {
|
|||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} sm={24} md={8}>
|
<Col xs={24} sm={24} md={8}>
|
||||||
<GlobalSearch />
|
{OpenSearch.treatment === "on" ? <GlobalSearchOs /> : <GlobalSearch />}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ export default function CABCpvrtCalculator({ disabled, form }) {
|
|||||||
|
|
||||||
const handleFinish = async (values) => {
|
const handleFinish = async (values) => {
|
||||||
logImEXEvent("job_ca_bc_pvrt_calculate");
|
logImEXEvent("job_ca_bc_pvrt_calculate");
|
||||||
form.setFieldsValue({ ca_bc_pvrt: ((values.rate||0) * (values.days||0)).toFixed(2) });
|
form.setFieldsValue({
|
||||||
|
ca_bc_pvrt: ((values.rate || 0) * (values.days || 0)).toFixed(2),
|
||||||
|
});
|
||||||
|
form.setFields([{ name: "ca_bc_pvrt", touched: true }]);
|
||||||
setVisibility(false);
|
setVisibility(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,216 @@
|
|||||||
|
import { AutoComplete, Divider, Input, Space } from "antd";
|
||||||
|
import axios from "axios";
|
||||||
|
import _ from "lodash";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Link, useHistory } from "react-router-dom";
|
||||||
|
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
|
||||||
|
import OwnerNameDisplay, {
|
||||||
|
OwnerNameDisplayFunction,
|
||||||
|
} from "../owner-name-display/owner-name-display.component";
|
||||||
|
import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component";
|
||||||
|
|
||||||
|
export default function GlobalSearchOs() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const history = useHistory();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [data, setData] = useState(false);
|
||||||
|
|
||||||
|
const executeSearch = async (v) => {
|
||||||
|
if (v && v && v !== "" && v.length >= 3) {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const searchData = await axios.post("/search", {
|
||||||
|
search: v,
|
||||||
|
});
|
||||||
|
|
||||||
|
const resultsByType = {
|
||||||
|
payments: [],
|
||||||
|
jobs: [],
|
||||||
|
bills: [],
|
||||||
|
owners: [],
|
||||||
|
vehicles: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
searchData.data.hits.hits.forEach((hit) => {
|
||||||
|
resultsByType[hit._index].push(hit._source);
|
||||||
|
});
|
||||||
|
setData([
|
||||||
|
{
|
||||||
|
label: renderTitle(t("menus.header.search.jobs")),
|
||||||
|
options: resultsByType.jobs.map((job) => {
|
||||||
|
return {
|
||||||
|
key: job.id,
|
||||||
|
value: job.ro_number || "N/A",
|
||||||
|
label: (
|
||||||
|
<Link to={`/manage/jobs/${job.id}`}>
|
||||||
|
<Space size="small" split={<Divider type="vertical" />}>
|
||||||
|
<strong>{job.ro_number || t("general.labels.na")}</strong>
|
||||||
|
<span>{`${job.status || ""}`}</span>
|
||||||
|
<span>
|
||||||
|
<OwnerNameDisplay ownerObject={job} />
|
||||||
|
</span>
|
||||||
|
<span>{`${job.v_model_yr || ""} ${
|
||||||
|
job.v_make_desc || ""
|
||||||
|
} ${job.v_model_desc || ""}`}</span>
|
||||||
|
<span>{`${job.clm_no || ""}`}</span>
|
||||||
|
</Space>
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: renderTitle(t("menus.header.search.owners")),
|
||||||
|
options: resultsByType.owners.map((owner) => {
|
||||||
|
return {
|
||||||
|
key: owner.id,
|
||||||
|
value: OwnerNameDisplayFunction(owner),
|
||||||
|
label: (
|
||||||
|
<Link to={`/manage/owners/${owner.id}`}>
|
||||||
|
<Space
|
||||||
|
size="small"
|
||||||
|
split={<Divider type="vertical" />}
|
||||||
|
wrap
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<OwnerNameDisplay ownerObject={owner} />
|
||||||
|
</span>
|
||||||
|
<PhoneNumberFormatter>
|
||||||
|
{owner.ownr_ph1}
|
||||||
|
</PhoneNumberFormatter>
|
||||||
|
<PhoneNumberFormatter>
|
||||||
|
{owner.ownr_ph2}
|
||||||
|
</PhoneNumberFormatter>
|
||||||
|
</Space>
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: renderTitle(t("menus.header.search.vehicles")),
|
||||||
|
options: resultsByType.vehicles.map((vehicle) => {
|
||||||
|
return {
|
||||||
|
key: vehicle.id,
|
||||||
|
value: `${vehicle.v_model_yr || ""} ${
|
||||||
|
vehicle.v_make_desc || ""
|
||||||
|
} ${vehicle.v_model_desc || ""}`,
|
||||||
|
label: (
|
||||||
|
<Link to={`/manage/vehicles/${vehicle.id}`}>
|
||||||
|
<Space size="small" split={<Divider type="vertical" />}>
|
||||||
|
<span>
|
||||||
|
{`${vehicle.v_model_yr || ""} ${
|
||||||
|
vehicle.v_make_desc || ""
|
||||||
|
} ${vehicle.v_model_desc || ""}`}
|
||||||
|
</span>
|
||||||
|
<span>{vehicle.plate_no || ""}</span>
|
||||||
|
<span>
|
||||||
|
<VehicleVinDisplay>
|
||||||
|
{vehicle.v_vin || ""}
|
||||||
|
</VehicleVinDisplay>
|
||||||
|
</span>
|
||||||
|
</Space>
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: renderTitle(t("menus.header.search.payments")),
|
||||||
|
options: resultsByType.payments.map((payment) => {
|
||||||
|
return {
|
||||||
|
key: payment.id,
|
||||||
|
value: `${payment.job?.ro_number} ${payment.amount}`,
|
||||||
|
label: (
|
||||||
|
<Link to={`/manage/jobs/${payment.job?.id}`}>
|
||||||
|
<Space size="small" split={<Divider type="vertical" />}>
|
||||||
|
<span>{payment.paymentnum}</span>
|
||||||
|
<span>{payment.job?.ro_number}</span>
|
||||||
|
<span>{payment.memo || ""}</span>
|
||||||
|
<span>{payment.amount || ""}</span>
|
||||||
|
<span>{payment.transactionid || ""}</span>
|
||||||
|
</Space>
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: renderTitle(t("menus.header.search.bills")),
|
||||||
|
options: resultsByType.bills.map((bill) => {
|
||||||
|
return {
|
||||||
|
key: bill.id,
|
||||||
|
value: `${bill.invoice_number} - ${bill.vendor.name}`,
|
||||||
|
label: (
|
||||||
|
<Link to={`/manage/bills?billid=${bill.id}`}>
|
||||||
|
<Space size="small" split={<Divider type="vertical" />}>
|
||||||
|
<span>{bill.invoice_number}</span>
|
||||||
|
<span>{bill.vendor.name}</span>
|
||||||
|
<span>{bill.date}</span>
|
||||||
|
</Space>
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// label: renderTitle(t("menus.header.search.phonebook")),
|
||||||
|
// options: resultsByType.search_phonebook.map((pb) => {
|
||||||
|
// return {
|
||||||
|
// key: pb.id,
|
||||||
|
// value: `${pb.firstname || ""} ${pb.lastname || ""} ${
|
||||||
|
// pb.company || ""
|
||||||
|
// }`,
|
||||||
|
// label: (
|
||||||
|
// <Link to={`/manage/phonebook?phonebookentry=${pb.id}`}>
|
||||||
|
// <Space size="small" split={<Divider type="vertical" />}>
|
||||||
|
// <span>{`${pb.firstname || ""} ${pb.lastname || ""} ${
|
||||||
|
// pb.company || ""
|
||||||
|
// }`}</span>
|
||||||
|
// <PhoneNumberFormatter>{pb.phone1}</PhoneNumberFormatter>
|
||||||
|
// <span>{pb.email}</span>
|
||||||
|
// </Space>
|
||||||
|
// </Link>
|
||||||
|
// ),
|
||||||
|
// };
|
||||||
|
// }),
|
||||||
|
// },
|
||||||
|
]);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error while fetching search results", error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const debouncedExecuteSearch = _.debounce(executeSearch, 750);
|
||||||
|
|
||||||
|
const handleSearch = (value) => {
|
||||||
|
debouncedExecuteSearch(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderTitle = (title) => {
|
||||||
|
return <span>{title}</span>;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AutoComplete
|
||||||
|
options={data}
|
||||||
|
onSearch={handleSearch}
|
||||||
|
defaultActiveFirstOption
|
||||||
|
onSelect={(val, opt) => {
|
||||||
|
history.push(opt.label.props.to);
|
||||||
|
}}
|
||||||
|
onClear={() => setData([])}
|
||||||
|
>
|
||||||
|
<Input.Search
|
||||||
|
size="large"
|
||||||
|
placeholder={t("general.labels.globalsearch")}
|
||||||
|
enterButton
|
||||||
|
allowClear
|
||||||
|
loading={loading}
|
||||||
|
/>
|
||||||
|
</AutoComplete>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ import { GLOBAL_SEARCH_QUERY } from "../../graphql/search.queries";
|
|||||||
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
|
import PhoneNumberFormatter from "../../utils/PhoneFormatter";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import OwnerNameDisplay, {
|
import OwnerNameDisplay, {
|
||||||
OwnerNameDisplayFunction
|
OwnerNameDisplayFunction,
|
||||||
} from "../owner-name-display/owner-name-display.component";
|
} from "../owner-name-display/owner-name-display.component";
|
||||||
import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component";
|
import VehicleVinDisplay from "../vehicle-vin-display/vehicle-vin-display.component";
|
||||||
export default function GlobalSearch() {
|
export default function GlobalSearch() {
|
||||||
@@ -18,11 +18,18 @@ export default function GlobalSearch() {
|
|||||||
useLazyQuery(GLOBAL_SEARCH_QUERY);
|
useLazyQuery(GLOBAL_SEARCH_QUERY);
|
||||||
|
|
||||||
const executeSearch = (v) => {
|
const executeSearch = (v) => {
|
||||||
if (v && v.variables.search && v.variables.search !== "") callSearch(v);
|
if (
|
||||||
|
v &&
|
||||||
|
v.variables.search &&
|
||||||
|
v.variables.search !== "" &&
|
||||||
|
v.variables.search.length >= 3
|
||||||
|
)
|
||||||
|
callSearch(v);
|
||||||
};
|
};
|
||||||
const debouncedExecuteSearch = _.debounce(executeSearch, 750);
|
const debouncedExecuteSearch = _.debounce(executeSearch, 750);
|
||||||
|
|
||||||
const handleSearch = (value) => {
|
const handleSearch = (value) => {
|
||||||
|
console.log("Handle Search");
|
||||||
debouncedExecuteSearch({ variables: { search: value } });
|
debouncedExecuteSearch({ variables: { search: value } });
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,7 +44,7 @@ export default function GlobalSearch() {
|
|||||||
options: data.search_jobs.map((job) => {
|
options: data.search_jobs.map((job) => {
|
||||||
return {
|
return {
|
||||||
key: job.id,
|
key: job.id,
|
||||||
value: job.ro_number,
|
value: job.ro_number || "N/A",
|
||||||
label: (
|
label: (
|
||||||
<Link to={`/manage/jobs/${job.id}`}>
|
<Link to={`/manage/jobs/${job.id}`}>
|
||||||
<Space size="small" split={<Divider type="vertical" />}>
|
<Space size="small" split={<Divider type="vertical" />}>
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ export function JobsConvertButton({
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Select>
|
<Select>
|
||||||
{bodyshop.md_ins_cos.map((s) => (
|
{bodyshop.md_ins_cos.map((s, i) => (
|
||||||
<Select.Option key={s.name} value={s.name}>
|
<Select.Option key={i} value={s.name}>
|
||||||
{s.name}
|
{s.name}
|
||||||
</Select.Option>
|
</Select.Option>
|
||||||
))}
|
))}
|
||||||
@@ -219,13 +219,15 @@ export function JobsConvertButton({
|
|||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
<Form.Item
|
{bodyshop.region_config.toLowerCase().startsWith("ca") && (
|
||||||
label={t("jobs.fields.ca_gst_registrant")}
|
<Form.Item
|
||||||
name="ca_gst_registrant"
|
label={t("jobs.fields.ca_gst_registrant")}
|
||||||
valuePropName="checked"
|
name="ca_gst_registrant"
|
||||||
>
|
valuePropName="checked"
|
||||||
<Switch />
|
>
|
||||||
</Form.Item>
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("jobs.fields.driveable")}
|
label={t("jobs.fields.driveable")}
|
||||||
name="driveable"
|
name="driveable"
|
||||||
|
|||||||
@@ -224,13 +224,15 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
|
|||||||
>
|
>
|
||||||
<CurrencyInput />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
{bodyshop.region_config.toLowerCase().startsWith("ca") && (
|
||||||
label={t("jobs.fields.ca_gst_registrant")}
|
<Form.Item
|
||||||
name="ca_gst_registrant"
|
label={t("jobs.fields.ca_gst_registrant")}
|
||||||
valuePropName="checked"
|
name="ca_gst_registrant"
|
||||||
>
|
valuePropName="checked"
|
||||||
<Switch />
|
>
|
||||||
</Form.Item>
|
<Switch />
|
||||||
|
</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"
|
||||||
|
|||||||
@@ -40,24 +40,26 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
|
|||||||
>
|
>
|
||||||
<CurrencyInput disabled={jobRO} min={0} />
|
<CurrencyInput disabled={jobRO} min={0} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Tooltip title={t("jobs.labels.ca_gst_all_if_null")}>
|
{bodyshop.region_config.toLowerCase().startsWith("ca") && (
|
||||||
<Form.Item
|
<Tooltip title={t("jobs.labels.ca_gst_all_if_null")}>
|
||||||
label={t("jobs.fields.ca_customer_gst")}
|
<Form.Item
|
||||||
name="ca_customer_gst"
|
label={t("jobs.fields.ca_customer_gst")}
|
||||||
>
|
name="ca_customer_gst"
|
||||||
<CurrencyInput
|
>
|
||||||
disabled={jobRO}
|
<CurrencyInput
|
||||||
min={0}
|
disabled={jobRO}
|
||||||
max={
|
min={0}
|
||||||
Math.round(
|
max={
|
||||||
(job.job_totals &&
|
Math.round(
|
||||||
job.job_totals.totals.federal_tax.amount) ||
|
(job.job_totals &&
|
||||||
0
|
job.job_totals.totals.federal_tax.amount) ||
|
||||||
) / 100
|
0
|
||||||
}
|
) / 100
|
||||||
/>
|
}
|
||||||
</Form.Item>
|
/>
|
||||||
</Tooltip>
|
</Form.Item>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
<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"
|
||||||
@@ -82,12 +84,14 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
|
|||||||
>
|
>
|
||||||
<CurrencyInput disabled={jobRO || bodyshop.cdk_dealerid} />
|
<CurrencyInput disabled={jobRO || bodyshop.cdk_dealerid} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Space align="end">
|
{bodyshop.region_config === "CA_BC" && (
|
||||||
<Form.Item label={t("jobs.fields.ca_bc_pvrt")} name="ca_bc_pvrt">
|
<Space align="center">
|
||||||
<CurrencyInput disabled={jobRO} min={0} />
|
<Form.Item label={t("jobs.fields.ca_bc_pvrt")} name="ca_bc_pvrt">
|
||||||
</Form.Item>
|
<CurrencyInput disabled={jobRO} min={0} />
|
||||||
<CABCpvrtCalculator form={form} disabled={jobRO} />
|
</Form.Item>
|
||||||
</Space>
|
<CABCpvrtCalculator form={form} disabled={jobRO} />
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("jobs.fields.auto_add_ats")}
|
label={t("jobs.fields.auto_add_ats")}
|
||||||
name="auto_add_ats"
|
name="auto_add_ats"
|
||||||
@@ -141,13 +145,15 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
|
|||||||
>
|
>
|
||||||
<InputNumber min={0} max={1} precision={2} disabled={jobRO} />
|
<InputNumber min={0} max={1} precision={2} disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
{bodyshop.region_config.toLowerCase().startsWith("ca") && (
|
||||||
label={t("jobs.fields.ca_gst_registrant")}
|
<Form.Item
|
||||||
name="ca_gst_registrant"
|
label={t("jobs.fields.ca_gst_registrant")}
|
||||||
valuePropName="checked"
|
name="ca_gst_registrant"
|
||||||
>
|
valuePropName="checked"
|
||||||
<Switch disabled={jobRO} />
|
>
|
||||||
</Form.Item>
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<Divider
|
<Divider
|
||||||
orientation="left"
|
orientation="left"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { EditFilled, FileExcelFilled, SyncOutlined } from "@ant-design/icons";
|
import { EditFilled, FileExcelFilled, SyncOutlined } from "@ant-design/icons";
|
||||||
import { Button, Card, Col, Row, Space } from "antd";
|
import { Button, Card, Col, Row, Space } from "antd";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Gallery from "react-grid-gallery";
|
import { Gallery } from "react-grid-gallery";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import DocumentsUploadComponent from "../documents-upload/documents-upload.component";
|
import DocumentsUploadComponent from "../documents-upload/documents-upload.component";
|
||||||
import { DetermineFileType } from "../documents-upload/documents-upload.utility";
|
import { DetermineFileType } from "../documents-upload/documents-upload.utility";
|
||||||
@@ -11,6 +11,9 @@ import JobsDocumentsGalleryReassign from "./jobs-document-gallery.reassign.compo
|
|||||||
import JobsDocumentsDeleteButton from "./jobs-documents-gallery.delete.component";
|
import JobsDocumentsDeleteButton from "./jobs-documents-gallery.delete.component";
|
||||||
import JobsDocumentsGallerySelectAllComponent from "./jobs-documents-gallery.selectall.component";
|
import JobsDocumentsGallerySelectAllComponent from "./jobs-documents-gallery.selectall.component";
|
||||||
|
|
||||||
|
import Lightbox from "react-image-lightbox";
|
||||||
|
import "react-image-lightbox/style.css";
|
||||||
|
|
||||||
function JobsDocumentsComponent({
|
function JobsDocumentsComponent({
|
||||||
data,
|
data,
|
||||||
jobId,
|
jobId,
|
||||||
@@ -23,11 +26,7 @@ function JobsDocumentsComponent({
|
|||||||
}) {
|
}) {
|
||||||
const [galleryImages, setgalleryImages] = useState({ images: [], other: [] });
|
const [galleryImages, setgalleryImages] = useState({ images: [], other: [] });
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [index, setIndex] = useState(0);
|
const [modalState, setModalState] = useState({ open: false, index: 0 });
|
||||||
|
|
||||||
const onCurrentImageChange = (index) => {
|
|
||||||
setIndex(index);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let documents = data.reduce(
|
let documents = data.reduce(
|
||||||
@@ -35,14 +34,16 @@ function JobsDocumentsComponent({
|
|||||||
const fileType = DetermineFileType(value.type);
|
const fileType = DetermineFileType(value.type);
|
||||||
if (value.type.startsWith("image")) {
|
if (value.type.startsWith("image")) {
|
||||||
acc.images.push({
|
acc.images.push({
|
||||||
src: GenerateSrcUrl(value),
|
// src: GenerateSrcUrl(value),
|
||||||
thumbnail: GenerateThumbUrl(value),
|
src: GenerateThumbUrl(value),
|
||||||
thumbnailHeight: 225,
|
// src: GenerateSrcUrl(value),
|
||||||
thumbnailWidth: 225,
|
// thumbnail: GenerateThumbUrl(value),
|
||||||
|
fullsize: GenerateSrcUrl(value),
|
||||||
|
height: 225,
|
||||||
|
width: 225,
|
||||||
isSelected: false,
|
isSelected: false,
|
||||||
key: value.key,
|
key: value.key,
|
||||||
extension: value.extension,
|
extension: value.extension,
|
||||||
|
|
||||||
id: value.id,
|
id: value.id,
|
||||||
type: value.type,
|
type: value.type,
|
||||||
size: value.size,
|
size: value.size,
|
||||||
@@ -62,7 +63,7 @@ function JobsDocumentsComponent({
|
|||||||
const fileName = value.key.split("/").pop();
|
const fileName = value.key.split("/").pop();
|
||||||
acc.other.push({
|
acc.other.push({
|
||||||
source: GenerateSrcUrl(value),
|
source: GenerateSrcUrl(value),
|
||||||
src: "",
|
src: thumb,
|
||||||
thumbnail: thumb,
|
thumbnail: thumb,
|
||||||
tags: [
|
tags: [
|
||||||
{
|
{
|
||||||
@@ -85,10 +86,9 @@ function JobsDocumentsComponent({
|
|||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
],
|
],
|
||||||
thumbnailHeight: 225,
|
height: 225,
|
||||||
thumbnailWidth: 225,
|
width: 225,
|
||||||
isSelected: false,
|
isSelected: false,
|
||||||
|
|
||||||
extension: value.extension,
|
extension: value.extension,
|
||||||
key: value.key,
|
key: value.key,
|
||||||
id: value.id,
|
id: value.id,
|
||||||
@@ -148,35 +148,15 @@ function JobsDocumentsComponent({
|
|||||||
<Card title={t("jobs.labels.documents-images")}>
|
<Card title={t("jobs.labels.documents-images")}>
|
||||||
<Gallery
|
<Gallery
|
||||||
images={galleryImages.images}
|
images={galleryImages.images}
|
||||||
backdropClosesModal={true}
|
onClick={(index, item) => {
|
||||||
currentImageWillChange={onCurrentImageChange}
|
setModalState({ open: true, index: index });
|
||||||
customControls={[
|
// window.open(
|
||||||
<Button
|
// item.fullsize,
|
||||||
key="edit-button"
|
// "_blank",
|
||||||
style={{
|
// "toolbar=0,location=0,menubar=0"
|
||||||
float: "right",
|
// );
|
||||||
zIndex: "5",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
const newWindow = window.open(
|
|
||||||
`${window.location.protocol}//${window.location.host}/edit?documentId=${galleryImages.images[index].id}`,
|
|
||||||
"_blank",
|
|
||||||
"noopener,noreferrer"
|
|
||||||
);
|
|
||||||
if (newWindow) newWindow.opener = null;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<EditFilled />
|
|
||||||
</Button>,
|
|
||||||
]}
|
|
||||||
onClickImage={(props) => {
|
|
||||||
window.open(
|
|
||||||
props.target.src,
|
|
||||||
"_blank",
|
|
||||||
"toolbar=0,location=0,menubar=0"
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
onSelectImage={(index, image) => {
|
onSelect={(index, image) => {
|
||||||
setgalleryImages({
|
setgalleryImages({
|
||||||
...galleryImages,
|
...galleryImages,
|
||||||
images: galleryImages.images.map((g, idx) =>
|
images: galleryImages.images.map((g, idx) =>
|
||||||
@@ -191,8 +171,6 @@ function JobsDocumentsComponent({
|
|||||||
<Card title={t("jobs.labels.documents-other")}>
|
<Card title={t("jobs.labels.documents-other")}>
|
||||||
<Gallery
|
<Gallery
|
||||||
images={galleryImages.other}
|
images={galleryImages.other}
|
||||||
backdropClosesModal={true}
|
|
||||||
enableLightbox={false}
|
|
||||||
thumbnailStyle={() => {
|
thumbnailStyle={() => {
|
||||||
return {
|
return {
|
||||||
backgroundImage: <FileExcelFilled />,
|
backgroundImage: <FileExcelFilled />,
|
||||||
@@ -201,14 +179,14 @@ function JobsDocumentsComponent({
|
|||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
onClickThumbnail={(index) => {
|
onClick={(index) => {
|
||||||
window.open(
|
window.open(
|
||||||
galleryImages.other[index].source,
|
galleryImages.other[index].source,
|
||||||
"_blank",
|
"_blank",
|
||||||
"toolbar=0,location=0,menubar=0"
|
"toolbar=0,location=0,menubar=0"
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
onSelectImage={(index) => {
|
onSelect={(index) => {
|
||||||
setgalleryImages({
|
setgalleryImages({
|
||||||
...galleryImages,
|
...galleryImages,
|
||||||
other: galleryImages.other.map((g, idx) =>
|
other: galleryImages.other.map((g, idx) =>
|
||||||
@@ -219,6 +197,53 @@ function JobsDocumentsComponent({
|
|||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
{modalState.open && (
|
||||||
|
<Lightbox
|
||||||
|
toolbarButtons={[
|
||||||
|
<EditFilled
|
||||||
|
onClick={() => {
|
||||||
|
const newWindow = window.open(
|
||||||
|
`${window.location.protocol}//${
|
||||||
|
window.location.host
|
||||||
|
}/edit?documentId=${
|
||||||
|
galleryImages.images[modalState.index].id
|
||||||
|
}`,
|
||||||
|
"_blank",
|
||||||
|
"noopener,noreferrer"
|
||||||
|
);
|
||||||
|
if (newWindow) newWindow.opener = null;
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
]}
|
||||||
|
mainSrc={galleryImages.images[modalState.index].fullsize}
|
||||||
|
nextSrc={
|
||||||
|
galleryImages.images[
|
||||||
|
(modalState.index + 1) % galleryImages.images.length
|
||||||
|
].fullsize
|
||||||
|
}
|
||||||
|
prevSrc={
|
||||||
|
galleryImages.images[
|
||||||
|
(modalState.index + galleryImages.images.length - 1) %
|
||||||
|
galleryImages.images.length
|
||||||
|
].fullsize
|
||||||
|
}
|
||||||
|
onCloseRequest={() => setModalState({ open: false, index: 0 })}
|
||||||
|
onMovePrevRequest={() =>
|
||||||
|
setModalState({
|
||||||
|
...modalState,
|
||||||
|
index:
|
||||||
|
(modalState.index + galleryImages.images.length - 1) %
|
||||||
|
galleryImages.images.length,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onMoveNextRequest={() =>
|
||||||
|
setModalState({
|
||||||
|
...modalState,
|
||||||
|
index: (modalState.index + 1) % galleryImages.images.length,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import Gallery from "react-grid-gallery";
|
import { Gallery } from "react-grid-gallery";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { GenerateSrcUrl, GenerateThumbUrl } from "./job-documents.utility";
|
import { GenerateThumbUrl } from "./job-documents.utility";
|
||||||
|
|
||||||
function JobsDocumentGalleryExternal({
|
function JobsDocumentGalleryExternal({
|
||||||
data,
|
data,
|
||||||
@@ -15,8 +15,8 @@ function JobsDocumentGalleryExternal({
|
|||||||
let documents = data.reduce((acc, value) => {
|
let documents = data.reduce((acc, value) => {
|
||||||
if (value.type.startsWith("image")) {
|
if (value.type.startsWith("image")) {
|
||||||
acc.push({
|
acc.push({
|
||||||
src: GenerateSrcUrl(value),
|
//src: GenerateSrcUrl(value),
|
||||||
thumbnail: GenerateThumbUrl(value),
|
src: GenerateThumbUrl(value),
|
||||||
thumbnailHeight: 225,
|
thumbnailHeight: 225,
|
||||||
thumbnailWidth: 225,
|
thumbnailWidth: 225,
|
||||||
isSelected: false,
|
isSelected: false,
|
||||||
@@ -39,7 +39,7 @@ function JobsDocumentGalleryExternal({
|
|||||||
<Gallery
|
<Gallery
|
||||||
images={galleryImages}
|
images={galleryImages}
|
||||||
backdropClosesModal={true}
|
backdropClosesModal={true}
|
||||||
onSelectImage={(index, image) => {
|
onSelect={(index, image) => {
|
||||||
setgalleryImages(
|
setgalleryImages(
|
||||||
galleryImages.map((g, idx) =>
|
galleryImages.map((g, idx) =>
|
||||||
index === idx ? { ...g, isSelected: !g.isSelected } : g
|
index === idx ? { ...g, isSelected: !g.isSelected } : g
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { SyncOutlined, FileExcelFilled } from "@ant-design/icons";
|
import { SyncOutlined, FileExcelFilled } from "@ant-design/icons";
|
||||||
import { Alert, Button, Card, Space } from "antd";
|
import { Alert, Button, Card, Space } from "antd";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Gallery from "react-grid-gallery";
|
import { Gallery } from "react-grid-gallery";
|
||||||
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";
|
||||||
@@ -19,6 +19,9 @@ import JobsLocalGalleryDownloadButton from "./jobs-documents-local-gallery.downl
|
|||||||
import JobsDocumentsLocalGalleryReassign from "./jobs-documents-local-gallery.reassign.component";
|
import JobsDocumentsLocalGalleryReassign from "./jobs-documents-local-gallery.reassign.component";
|
||||||
import JobsDocumentsLocalGallerySelectAllComponent from "./jobs-documents-local-gallery.selectall.component";
|
import JobsDocumentsLocalGallerySelectAllComponent from "./jobs-documents-local-gallery.selectall.component";
|
||||||
|
|
||||||
|
import Lightbox from "react-image-lightbox";
|
||||||
|
import "react-image-lightbox/style.css";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
allMedia: selectAllMedia,
|
allMedia: selectAllMedia,
|
||||||
@@ -49,6 +52,7 @@ export function JobsDocumentsLocalGallery({
|
|||||||
vendorid,
|
vendorid,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const [modalState, setModalState] = useState({ open: false, index: 0 });
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (job) {
|
if (job) {
|
||||||
if (invoice_number) {
|
if (invoice_number) {
|
||||||
@@ -70,12 +74,20 @@ export function JobsDocumentsLocalGallery({
|
|||||||
) {
|
) {
|
||||||
acc.images.push({
|
acc.images.push({
|
||||||
...val,
|
...val,
|
||||||
|
fullsize: val.src,
|
||||||
|
src: val.thumbnail,
|
||||||
|
height: val.thumbnailHeight,
|
||||||
|
width: val.thumbnailWidth,
|
||||||
...(val.optimized && { src: val.optimized, fullsize: val.src }),
|
...(val.optimized && { src: val.optimized, fullsize: val.src }),
|
||||||
});
|
});
|
||||||
if (val.optimized) optimized = true;
|
if (val.optimized) optimized = true;
|
||||||
} else {
|
} else {
|
||||||
acc.other.push({
|
acc.other.push({
|
||||||
...val,
|
...val,
|
||||||
|
fullsize: val.src,
|
||||||
|
src: val.thumbnail,
|
||||||
|
height: val.thumbnailHeight,
|
||||||
|
width: val.thumbnailWidth,
|
||||||
tags: [{ value: val.filename, title: val.filename }],
|
tags: [{ value: val.filename, title: val.filename }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -120,8 +132,7 @@ export function JobsDocumentsLocalGallery({
|
|||||||
<Card title={t("jobs.labels.documents-images")}>
|
<Card title={t("jobs.labels.documents-images")}>
|
||||||
<Gallery
|
<Gallery
|
||||||
images={jobMedia.images}
|
images={jobMedia.images}
|
||||||
backdropClosesModal={true}
|
onSelect={(index, image) => {
|
||||||
onSelectImage={(index, image) => {
|
|
||||||
toggleMediaSelected({ jobid: job.id, filename: image.filename });
|
toggleMediaSelected({ jobid: job.id, filename: image.filename });
|
||||||
}}
|
}}
|
||||||
{...(optimized && {
|
{...(optimized && {
|
||||||
@@ -133,24 +144,23 @@ export function JobsDocumentsLocalGallery({
|
|||||||
/>,
|
/>,
|
||||||
],
|
],
|
||||||
})}
|
})}
|
||||||
onClickImage={(props) => {
|
onClick={(index) => {
|
||||||
const media = allMedia[job.id].find(
|
setModalState({ open: true, index: index });
|
||||||
(m) => m.optimized === props.target.src
|
// const media = allMedia[job.id].find(
|
||||||
);
|
// (m) => m.optimized === item.src
|
||||||
|
// );
|
||||||
|
|
||||||
window.open(
|
// window.open(
|
||||||
media ? media.src : props.target.src,
|
// media ? media.fullsize : item.fullsize,
|
||||||
"_blank",
|
// "_blank",
|
||||||
"toolbar=0,location=0,menubar=0"
|
// "toolbar=0,location=0,menubar=0"
|
||||||
);
|
// );
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
<Card title={t("jobs.labels.documents-other")}>
|
<Card title={t("jobs.labels.documents-other")}>
|
||||||
<Gallery
|
<Gallery
|
||||||
images={jobMedia.other}
|
images={jobMedia.other}
|
||||||
backdropClosesModal={true}
|
|
||||||
enableLightbox={false}
|
|
||||||
thumbnailStyle={() => {
|
thumbnailStyle={() => {
|
||||||
return {
|
return {
|
||||||
backgroundImage: <FileExcelFilled />,
|
backgroundImage: <FileExcelFilled />,
|
||||||
@@ -159,18 +169,48 @@ export function JobsDocumentsLocalGallery({
|
|||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
onClickThumbnail={(index) => {
|
onClick={(index) => {
|
||||||
window.open(
|
window.open(
|
||||||
jobMedia.other[index].src,
|
jobMedia.other[index].fullsize,
|
||||||
"_blank",
|
"_blank",
|
||||||
"toolbar=0,location=0,menubar=0"
|
"toolbar=0,location=0,menubar=0"
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
onSelectImage={(index, image) => {
|
onSelect={(index, image) => {
|
||||||
toggleMediaSelected({ jobid: job.id, filename: image.filename });
|
toggleMediaSelected({ jobid: job.id, filename: image.filename });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
{modalState.open && (
|
||||||
|
<Lightbox
|
||||||
|
mainSrc={jobMedia.images[modalState.index].fullsize}
|
||||||
|
nextSrc={
|
||||||
|
jobMedia.images[(modalState.index + 1) % jobMedia.images.length]
|
||||||
|
.fullsize
|
||||||
|
}
|
||||||
|
prevSrc={
|
||||||
|
jobMedia.images[
|
||||||
|
(modalState.index + jobMedia.images.length - 1) %
|
||||||
|
jobMedia.images.length
|
||||||
|
].fullsize
|
||||||
|
}
|
||||||
|
onCloseRequest={() => setModalState({ open: false, index: 0 })}
|
||||||
|
onMovePrevRequest={() =>
|
||||||
|
setModalState({
|
||||||
|
...modalState,
|
||||||
|
index:
|
||||||
|
(modalState.index + jobMedia.images.length - 1) %
|
||||||
|
jobMedia.images.length,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onMoveNextRequest={() =>
|
||||||
|
setModalState({
|
||||||
|
...modalState,
|
||||||
|
index: (modalState.index + 1) % jobMedia.images.length,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import Gallery from "react-grid-gallery";
|
import { Gallery } from "react-grid-gallery";
|
||||||
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";
|
||||||
@@ -38,7 +38,7 @@ function JobDocumentsLocalGalleryExternal({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if ( jobId) {
|
if (jobId) {
|
||||||
getJobMedia(jobId);
|
getJobMedia(jobId);
|
||||||
}
|
}
|
||||||
}, [jobId, getJobMedia]);
|
}, [jobId, getJobMedia]);
|
||||||
@@ -52,11 +52,15 @@ function JobDocumentsLocalGalleryExternal({
|
|||||||
val.type.mime &&
|
val.type.mime &&
|
||||||
val.type.mime.startsWith("image")
|
val.type.mime.startsWith("image")
|
||||||
) {
|
) {
|
||||||
acc.push(val);
|
acc.push({ ...val, src: val.thumbnail });
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, [])
|
}, [])
|
||||||
: [];
|
: [];
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: jobs-documents-local-gallery.external.component.jsx:48 ~ useEffect ~ documents:",
|
||||||
|
documents
|
||||||
|
);
|
||||||
|
|
||||||
setgalleryImages(documents);
|
setgalleryImages(documents);
|
||||||
}, [allMedia, jobId, setgalleryImages, t]);
|
}, [allMedia, jobId, setgalleryImages, t]);
|
||||||
@@ -65,8 +69,7 @@ function JobDocumentsLocalGalleryExternal({
|
|||||||
<div className="clearfix">
|
<div className="clearfix">
|
||||||
<Gallery
|
<Gallery
|
||||||
images={galleryImages}
|
images={galleryImages}
|
||||||
backdropClosesModal={true}
|
onSelect={(index, image) => {
|
||||||
onSelectImage={(index, image) => {
|
|
||||||
setgalleryImages(
|
setgalleryImages(
|
||||||
galleryImages.map((g, idx) =>
|
galleryImages.map((g, idx) =>
|
||||||
index === idx ? { ...g, isSelected: !g.isSelected } : g
|
index === idx ? { ...g, isSelected: !g.isSelected } : g
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { SyncOutlined } from "@ant-design/icons";
|
import { SyncOutlined } from "@ant-design/icons";
|
||||||
import { Button, Card, Input, Space, Table, Typography } from "antd";
|
import { Button, Card, Input, Space, Table, Typography } from "antd";
|
||||||
|
import axios from "axios";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React 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";
|
||||||
import { Link, useHistory, useLocation } from "react-router-dom";
|
import { Link, useHistory, useLocation } from "react-router-dom";
|
||||||
@@ -21,6 +22,8 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
|
|
||||||
export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
||||||
const search = queryString.parse(useLocation().search);
|
const search = queryString.parse(useLocation().search);
|
||||||
|
const [openSearchResults, setOpenSearchResults] = useState([]);
|
||||||
|
const [searchLoading, setSearchLoading] = useState(false);
|
||||||
const { page, sortcolumn, sortorder } = search;
|
const { page, sortcolumn, sortorder } = search;
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
@@ -193,6 +196,28 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
|||||||
history.push({ search: queryString.stringify(search) });
|
history.push({ search: queryString.stringify(search) });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (search.search && search.search.trim() !== "") {
|
||||||
|
searchJobs();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function searchJobs(value) {
|
||||||
|
try {
|
||||||
|
setSearchLoading(true);
|
||||||
|
const searchData = await axios.post("/search", {
|
||||||
|
search: value || search.search,
|
||||||
|
index: "jobs",
|
||||||
|
});
|
||||||
|
setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source));
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error while fetching search results", error);
|
||||||
|
} finally {
|
||||||
|
setSearchLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
extra={
|
extra={
|
||||||
@@ -205,6 +230,7 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
|||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
delete search.search;
|
delete search.search;
|
||||||
|
delete search.page;
|
||||||
history.push({ search: queryString.stringify(search) });
|
history.push({ search: queryString.stringify(search) });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -220,24 +246,32 @@ export function JobsList({ bodyshop, refetch, loading, jobs, total }) {
|
|||||||
onSearch={(value) => {
|
onSearch={(value) => {
|
||||||
search.search = value;
|
search.search = value;
|
||||||
history.push({ search: queryString.stringify(search) });
|
history.push({ search: queryString.stringify(search) });
|
||||||
|
searchJobs(value);
|
||||||
}}
|
}}
|
||||||
|
loading={loading || searchLoading}
|
||||||
enterButton
|
enterButton
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
loading={loading}
|
loading={loading || searchLoading}
|
||||||
pagination={{
|
pagination={
|
||||||
position: "top",
|
search?.search
|
||||||
pageSize: 25,
|
? {
|
||||||
current: parseInt(page || 1),
|
pageSize: 25,
|
||||||
total: total,
|
showSizeChanger: false,
|
||||||
showSizeChanger: false,
|
}
|
||||||
}}
|
: {
|
||||||
|
pageSize: 25,
|
||||||
|
current: parseInt(page || 1),
|
||||||
|
total: total,
|
||||||
|
showSizeChanger: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
dataSource={jobs}
|
dataSource={search?.search ? openSearchResults : jobs}
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -75,6 +75,27 @@ export function JobNotesComponent({
|
|||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: t("notes.fields.type"),
|
||||||
|
dataIndex: "type",
|
||||||
|
key: "type",
|
||||||
|
width: 120,
|
||||||
|
filteredValue: filter?.type || null,
|
||||||
|
filters: [
|
||||||
|
{ value: "general", text: t("notes.fields.types.general") },
|
||||||
|
{ value: "customer", text: t("notes.fields.types.customer") },
|
||||||
|
{ value: "shop", text: t("notes.fields.types.shop") },
|
||||||
|
{ value: "office", text: t("notes.fields.types.office") },
|
||||||
|
{ value: "parts", text: t("notes.fields.types.parts") },
|
||||||
|
{ value: "paint", text: t("notes.fields.types.paint") },
|
||||||
|
{
|
||||||
|
value: "supplement",
|
||||||
|
text: t("notes.fields.types.supplement"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onFilter: (value, record) => value.includes(record.type),
|
||||||
|
render: (text, record) => t(`notes.fields.types.${record.type}`),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t("notes.fields.text"),
|
title: t("notes.fields.text"),
|
||||||
dataIndex: "text",
|
dataIndex: "text",
|
||||||
@@ -106,7 +127,7 @@ export function JobNotesComponent({
|
|||||||
title: t("notes.actions.actions"),
|
title: t("notes.actions.actions"),
|
||||||
dataIndex: "actions",
|
dataIndex: "actions",
|
||||||
key: "actions",
|
key: "actions",
|
||||||
width: 150,
|
width: 200,
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ export function LaborAllocationsTable({
|
|||||||
<Card title={t("jobs.labels.laborallocations")}>
|
<Card title={t("jobs.labels.laborallocations")}>
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="cost_center"
|
rowKey={(record) => `${record.cost_center} ${record.mod_lbr_ty}`}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
dataSource={totals}
|
dataSource={totals}
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ export const CalculateAllocationsTotals = (
|
|||||||
timetickets,
|
timetickets,
|
||||||
adjustments = []
|
adjustments = []
|
||||||
) => {
|
) => {
|
||||||
console.log(
|
|
||||||
"🚀 ~ file: labor-allocations-table.utility.js ~ line 9 ~ adjustments",
|
|
||||||
adjustments
|
|
||||||
);
|
|
||||||
const responsibilitycenters = bodyshop.md_responsibility_centers;
|
const responsibilitycenters = bodyshop.md_responsibility_centers;
|
||||||
const jobCodes = joblines.map((item) => item.mod_lbr_ty);
|
const jobCodes = joblines.map((item) => item.mod_lbr_ty);
|
||||||
//.filter((value, index, self) => self.indexOf(value) === index && !!value);
|
//.filter((value, index, self) => self.indexOf(value) === index && !!value);
|
||||||
|
|||||||
@@ -1,4 +1,14 @@
|
|||||||
import { Checkbox, Col, Form, Input, Row, Space, Switch, Tag } from "antd";
|
import {
|
||||||
|
Checkbox,
|
||||||
|
Col,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
Row,
|
||||||
|
Select,
|
||||||
|
Space,
|
||||||
|
Switch,
|
||||||
|
Tag,
|
||||||
|
} from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -46,6 +56,28 @@ export function NoteUpsertModalComponent({ form, noteUpsertModal }) {
|
|||||||
<Switch />
|
<Switch />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("notes.fields.type")}
|
||||||
|
name="type"
|
||||||
|
initialValue="general"
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
options={[
|
||||||
|
{ value: "general", label: t("notes.fields.types.general") },
|
||||||
|
{ value: "customer", label: t("notes.fields.types.customer") },
|
||||||
|
{ value: "shop", label: t("notes.fields.types.shop") },
|
||||||
|
{ value: "office", label: t("notes.fields.types.office") },
|
||||||
|
{ value: "parts", label: t("notes.fields.types.parts") },
|
||||||
|
{ value: "paint", label: t("notes.fields.types.paint") },
|
||||||
|
{
|
||||||
|
value: "supplement",
|
||||||
|
label: t("notes.fields.types.supplement"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<NotesPresetButton form={form} />
|
<NotesPresetButton form={form} />
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export function NoteUpsertModalContainer({
|
|||||||
const [updateNote] = useMutation(UPDATE_NOTE);
|
const [updateNote] = useMutation(UPDATE_NOTE);
|
||||||
|
|
||||||
const { visible, context, actions } = noteUpsertModal;
|
const { visible, context, actions } = noteUpsertModal;
|
||||||
const { jobId, existingNote } = context;
|
const { jobId, existingNote, text } = context;
|
||||||
const { refetch } = actions;
|
const { refetch } = actions;
|
||||||
|
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
@@ -45,8 +45,12 @@ export function NoteUpsertModalContainer({
|
|||||||
form.setFieldsValue(existingNote);
|
form.setFieldsValue(existingNote);
|
||||||
} else if (!existingNote && visible) {
|
} else if (!existingNote && visible) {
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
|
|
||||||
|
if (text) {
|
||||||
|
form.setFieldValue("text", text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [existingNote, form, visible]);
|
}, [existingNote, form, visible, text]);
|
||||||
|
|
||||||
const handleFinish = async (formValues) => {
|
const handleFinish = async (formValues) => {
|
||||||
const { relatedros, ...values } = formValues;
|
const { relatedros, ...values } = formValues;
|
||||||
@@ -82,6 +86,7 @@ export function NoteUpsertModalContainer({
|
|||||||
{ ...values, jobid: jobId, created_by: currentUser.email },
|
{ ...values, jobid: jobId, created_by: currentUser.email },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
refetchQueries: ["QUERY_NOTES_BY_JOB_PK"],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (AdditionalNoteInserts.length > 0) {
|
if (AdditionalNoteInserts.length > 0) {
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ export function PartsOrderListTableComponent({
|
|||||||
subject: record.return
|
subject: record.return
|
||||||
? Templates.parts_return_slip.subject
|
? Templates.parts_return_slip.subject
|
||||||
: Templates.parts_order.subject,
|
: Templates.parts_order.subject,
|
||||||
|
to: record.vendor.email,
|
||||||
}}
|
}}
|
||||||
id={job.id}
|
id={job.id}
|
||||||
/>
|
/>
|
||||||
@@ -296,7 +297,6 @@ export function PartsOrderListTableComponent({
|
|||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "quantity" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "quantity" && state.sortedInfo.order,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: t("parts_orders.fields.act_price"),
|
title: t("parts_orders.fields.act_price"),
|
||||||
dataIndex: "act_price",
|
dataIndex: "act_price",
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ function PaymentModalContainer({
|
|||||||
const { useStripe, sendby, ...paymentObj } = values;
|
const { useStripe, sendby, ...paymentObj } = values;
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
let updatedPayment; //Moved up from if statement for greater scope.
|
||||||
try {
|
try {
|
||||||
if (!context || (context && !context.id)) {
|
if (!context || (context && !context.id)) {
|
||||||
const newPayment = await insertPayment({
|
const newPayment = await insertPayment({
|
||||||
@@ -87,7 +87,7 @@ function PaymentModalContainer({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const updatedPayment = await updatePayment({
|
updatedPayment = await updatePayment({
|
||||||
variables: {
|
variables: {
|
||||||
paymentId: context.id,
|
paymentId: context.id,
|
||||||
payment: paymentObj,
|
payment: paymentObj,
|
||||||
@@ -101,7 +101,11 @@ function PaymentModalContainer({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actions.refetch) actions.refetch();
|
if (actions.refetch)
|
||||||
|
actions.refetch(
|
||||||
|
updatedPayment && updatedPayment.data.update_payments.returning[0]
|
||||||
|
);
|
||||||
|
|
||||||
if (enterAgain) {
|
if (enterAgain) {
|
||||||
const prev = form.getFieldsValue(["date"]);
|
const prev = form.getFieldsValue(["date"]);
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
import { EditFilled, SyncOutlined } from "@ant-design/icons";
|
import { EditFilled, SyncOutlined } from "@ant-design/icons";
|
||||||
|
import { useApolloClient } from "@apollo/client";
|
||||||
import { Button, Card, Input, Space, Table, Typography } from "antd";
|
import { Button, Card, Input, Space, Table, Typography } from "antd";
|
||||||
|
import axios from "axios";
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React, { 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";
|
||||||
import { Link, useHistory, useLocation } from "react-router-dom";
|
import { Link, useHistory, useLocation } from "react-router-dom";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { QUERY_PAYMENT_BY_ID } from "../../graphql/payments.queries";
|
||||||
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";
|
||||||
import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter";
|
import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter";
|
||||||
import { alphaSort } from "../../utils/sorters";
|
|
||||||
import { TemplateList } from "../../utils/TemplateConstants";
|
import { TemplateList } from "../../utils/TemplateConstants";
|
||||||
|
import { alphaSort } from "../../utils/sorters";
|
||||||
import CaBcEtfTableModalContainer from "../ca-bc-etf-table-modal/ca-bc-etf-table-modal.container";
|
import CaBcEtfTableModalContainer from "../ca-bc-etf-table-modal/ca-bc-etf-table-modal.container";
|
||||||
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
|
|
||||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||||
|
import PrintWrapperComponent from "../print-wrapper/print-wrapper.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
//currentUser: selectCurrentUser
|
//currentUser: selectCurrentUser
|
||||||
@@ -39,7 +42,10 @@ export function PaymentsListPaginated({
|
|||||||
bodyshop,
|
bodyshop,
|
||||||
}) {
|
}) {
|
||||||
const search = queryString.parse(useLocation().search);
|
const search = queryString.parse(useLocation().search);
|
||||||
|
const [openSearchResults, setOpenSearchResults] = useState([]);
|
||||||
|
const [searchLoading, setSearchLoading] = useState(false);
|
||||||
const { page, sortcolumn, sortorder } = search;
|
const { page, sortcolumn, sortorder } = search;
|
||||||
|
const client = useApolloClient();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
sortedInfo: {},
|
sortedInfo: {},
|
||||||
@@ -52,13 +58,17 @@ export function PaymentsListPaginated({
|
|||||||
title: t("jobs.fields.ro_number"),
|
title: t("jobs.fields.ro_number"),
|
||||||
dataIndex: "ro_number",
|
dataIndex: "ro_number",
|
||||||
key: "ro_number",
|
key: "ro_number",
|
||||||
sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
|
// sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
|
||||||
sortOrder: sortcolumn === "ro_number" && sortorder,
|
// sortOrder: sortcolumn === "ro_number" && sortorder,
|
||||||
render: (text, record) => (
|
render: (text, record) => {
|
||||||
<Link to={"/manage/jobs/" + record.job.id}>
|
return record.job ? (
|
||||||
{record.job.ro_number || t("general.labels.na")}
|
<Link to={"/manage/jobs/" + record.job.id}>
|
||||||
</Link>
|
{record.job.ro_number || t("general.labels.na")}
|
||||||
),
|
</Link>
|
||||||
|
) : (
|
||||||
|
<span>{t("general.labels.na")}</span>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("payments.fields.paymentnum"),
|
title: t("payments.fields.paymentnum"),
|
||||||
@@ -72,16 +82,16 @@ export function PaymentsListPaginated({
|
|||||||
dataIndex: "owner",
|
dataIndex: "owner",
|
||||||
key: "owner",
|
key: "owner",
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
sorter: (a, b) => alphaSort(a.job.ownr_ln, b.job.ownr_ln),
|
// sorter: (a, b) => alphaSort(a.job.ownr_ln, b.job.ownr_ln),
|
||||||
sortOrder: sortcolumn === "owner" && sortorder,
|
// sortOrder: sortcolumn === "owner" && sortorder,
|
||||||
render: (text, record) => {
|
render: (text, record) => {
|
||||||
return record.job.owner ? (
|
return record.job?.owner ? (
|
||||||
<Link to={"/manage/owners/" + record.job.owner.id}>
|
<Link to={"/manage/owners/" + record.job?.owner?.id}>
|
||||||
<OwnerNameDisplay ownerObject={record} />
|
<OwnerNameDisplay ownerObject={record.job} />
|
||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
<span>
|
<span>
|
||||||
<OwnerNameDisplay ownerObject={record} />
|
<OwnerNameDisplay ownerObject={record.job} />
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -147,10 +157,33 @@ export function PaymentsListPaginated({
|
|||||||
<Space>
|
<Space>
|
||||||
<Button
|
<Button
|
||||||
disabled={record.exportedat}
|
disabled={record.exportedat}
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
|
let apolloResults;
|
||||||
|
if (search.search) {
|
||||||
|
const { data } = await client.query({
|
||||||
|
query: QUERY_PAYMENT_BY_ID,
|
||||||
|
variables: {
|
||||||
|
paymentId: record.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
apolloResults = data.payments_by_pk;
|
||||||
|
}
|
||||||
setPaymentContext({
|
setPaymentContext({
|
||||||
actions: { refetch: refetch },
|
actions: {
|
||||||
context: record,
|
refetch: apolloResults
|
||||||
|
? (updatedRecord) => {
|
||||||
|
setOpenSearchResults((results) =>
|
||||||
|
results.map((result) => {
|
||||||
|
if (result.id !== record.id) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return updatedRecord;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
: refetch,
|
||||||
|
},
|
||||||
|
context: apolloResults ? apolloResults : record,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -177,6 +210,28 @@ export function PaymentsListPaginated({
|
|||||||
history.push({ search: queryString.stringify(search) });
|
history.push({ search: queryString.stringify(search) });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (search.search && search.search.trim() !== "") {
|
||||||
|
searchPayments();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function searchPayments(value) {
|
||||||
|
try {
|
||||||
|
setSearchLoading(true);
|
||||||
|
const searchData = await axios.post("/search", {
|
||||||
|
search: value || search.search,
|
||||||
|
index: "payments",
|
||||||
|
});
|
||||||
|
setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source));
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error while fetching search results", error);
|
||||||
|
} finally {
|
||||||
|
setSearchLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
extra={
|
extra={
|
||||||
@@ -189,6 +244,7 @@ export function PaymentsListPaginated({
|
|||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
delete search.search;
|
delete search.search;
|
||||||
|
delete search.page;
|
||||||
history.push({ search: queryString.stringify(search) });
|
history.push({ search: queryString.stringify(search) });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -212,24 +268,33 @@ export function PaymentsListPaginated({
|
|||||||
onSearch={(value) => {
|
onSearch={(value) => {
|
||||||
search.search = value;
|
search.search = value;
|
||||||
history.push({ search: queryString.stringify(search) });
|
history.push({ search: queryString.stringify(search) });
|
||||||
|
searchPayments(value);
|
||||||
}}
|
}}
|
||||||
|
loading={loading || searchLoading}
|
||||||
enterButton
|
enterButton
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Table
|
<Table
|
||||||
loading={loading}
|
loading={loading || searchLoading}
|
||||||
scroll={{ x: true }}
|
scroll={{ x: true }}
|
||||||
pagination={{
|
pagination={
|
||||||
position: "top",
|
search?.search
|
||||||
pageSize: 25,
|
? {
|
||||||
current: parseInt(page || 1),
|
pageSize: 25,
|
||||||
total: total,
|
showSizeChanger: false,
|
||||||
}}
|
}
|
||||||
|
: {
|
||||||
|
pageSize: 25,
|
||||||
|
current: parseInt(page || 1),
|
||||||
|
total: total,
|
||||||
|
showSizeChanger: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
dataSource={payments}
|
dataSource={search?.search ? openSearchResults : payments}
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -29,7 +29,10 @@ export function PrintCenterJobsComponent({ printCenterModal, bodyshop }) {
|
|||||||
})
|
})
|
||||||
.filter(
|
.filter(
|
||||||
(temp) =>
|
(temp) =>
|
||||||
!temp.regions || (temp.regions && temp.regions[bodyshop.region_config])
|
!temp.regions ||
|
||||||
|
(temp.regions && temp.regions[bodyshop.region_config]) ||
|
||||||
|
(temp.regions &&
|
||||||
|
bodyshop.region_config.includes(Object.keys(temp.regions)) === true)
|
||||||
);
|
);
|
||||||
|
|
||||||
const filteredJobsReportsList =
|
const filteredJobsReportsList =
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import { Col, List, Space, Typography } from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
const CardColorLegend = ({ bodyshop }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const data = bodyshop.ssbuckets.map((bucket) => {
|
||||||
|
let color = { r: 255, g: 255, b: 255 };
|
||||||
|
|
||||||
|
if (bucket.color) {
|
||||||
|
color = bucket.color;
|
||||||
|
|
||||||
|
if (bucket.color.rgb) {
|
||||||
|
color = bucket.color.rgb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: bucket.label,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Col>
|
||||||
|
<Typography>{t("production.labels.legend")}</Typography>
|
||||||
|
<List
|
||||||
|
grid={{
|
||||||
|
gutter: 16,
|
||||||
|
}}
|
||||||
|
dataSource={data}
|
||||||
|
renderItem={(item) => (
|
||||||
|
<List.Item>
|
||||||
|
<Space>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: "1.5rem",
|
||||||
|
aspectRatio: "1/1",
|
||||||
|
backgroundColor: `rgba(${item.color.r},${item.color.g},${item.color.b},${item.color.a})`,
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<div>{item.label}</div>
|
||||||
|
</Space>
|
||||||
|
</List.Item>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CardColorLegend;
|
||||||
@@ -18,6 +18,31 @@ import moment from "moment";
|
|||||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||||
import JobPartsQueueCount from "../job-parts-queue-count/job-parts-queue-count.component";
|
import JobPartsQueueCount from "../job-parts-queue-count/job-parts-queue-count.component";
|
||||||
|
|
||||||
|
const cardColor = (ssbuckets, totalHrs) => {
|
||||||
|
const bucket = ssbuckets.filter(
|
||||||
|
(bucket) =>
|
||||||
|
bucket.gte <= totalHrs && (!!bucket.lt ? bucket.lt > totalHrs : true)
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
let color = { r: 255, g: 255, b: 255 };
|
||||||
|
|
||||||
|
if (bucket && bucket.color) {
|
||||||
|
color = bucket.color;
|
||||||
|
|
||||||
|
if (bucket.color.rgb) {
|
||||||
|
color = bucket.color.rgb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
};
|
||||||
|
|
||||||
|
function getContrastYIQ(bgColor) {
|
||||||
|
const yiq = (bgColor.r * 299 + bgColor.g * 587 + bgColor.b * 114) / 1000;
|
||||||
|
|
||||||
|
return yiq >= 128 ? "black" : "white";
|
||||||
|
}
|
||||||
|
|
||||||
export default function ProductionBoardCard(
|
export default function ProductionBoardCard(
|
||||||
technician,
|
technician,
|
||||||
card,
|
card,
|
||||||
@@ -54,10 +79,22 @@ export default function ProductionBoardCard(
|
|||||||
.isSame(moment(card.scheduled_completion), "day") &&
|
.isSame(moment(card.scheduled_completion), "day") &&
|
||||||
"production-completion-soon"));
|
"production-completion-soon"));
|
||||||
|
|
||||||
|
const totalHrs =
|
||||||
|
card.labhrs.aggregate.sum.mod_lb_hrs + card.larhrs.aggregate.sum.mod_lb_hrs;
|
||||||
|
const bgColor = cardColor(bodyshop.ssbuckets, totalHrs);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
className="react-kanban-card imex-kanban-card"
|
className="react-kanban-card imex-kanban-card"
|
||||||
size="small"
|
size="small"
|
||||||
|
style={{
|
||||||
|
backgroundColor:
|
||||||
|
cardSettings &&
|
||||||
|
cardSettings.cardcolor &&
|
||||||
|
`rgba(${bgColor.r},${bgColor.g},${bgColor.b},${bgColor.a})`,
|
||||||
|
color:
|
||||||
|
cardSettings && cardSettings.cardcolor && getContrastYIQ(bgColor),
|
||||||
|
}}
|
||||||
title={
|
title={
|
||||||
<Space>
|
<Space>
|
||||||
<ProductionAlert record={card} key="alert" />
|
<ProductionAlert record={card} key="alert" />
|
||||||
|
|||||||
@@ -104,6 +104,13 @@ export default function ProductionBoardKanbanCardSettings({
|
|||||||
>
|
>
|
||||||
<Switch />
|
<Switch />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
valuePropName="checked"
|
||||||
|
label={t("production.labels.cardcolor")}
|
||||||
|
name="cardcolor"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -166,7 +173,7 @@ export default function ProductionBoardKanbanCardSettings({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<Popover content={overlay} visible={visible}>
|
<Popover content={overlay} visible={visible} placement="topRight">
|
||||||
<Button loading={loading} onClick={() => setVisible(true)}>
|
<Button loading={loading} onClick={() => setVisible(true)}>
|
||||||
{t("production.labels.cardsettings")}
|
{t("production.labels.cardsettings")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import ProductionBoardKanbanCardSettings from "./production-board-kanban.card-se
|
|||||||
//import "@asseinfo/react-kanban/dist/styles.css";
|
//import "@asseinfo/react-kanban/dist/styles.css";
|
||||||
import "./production-board-kanban.styles.scss";
|
import "./production-board-kanban.styles.scss";
|
||||||
import { createBoardData } from "./production-board-kanban.utils.js";
|
import { createBoardData } from "./production-board-kanban.utils.js";
|
||||||
|
import CardColorLegend from "../production-board-kanban-card/production-board-kanban-card-color-legend.component";
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
technician: selectTechnician,
|
technician: selectTechnician,
|
||||||
@@ -221,6 +222,7 @@ export function ProductionBoardKanbanComponent({
|
|||||||
employeeassignments: true,
|
employeeassignments: true,
|
||||||
scheduled_completion: true,
|
scheduled_completion: true,
|
||||||
stickyheader: false,
|
stickyheader: false,
|
||||||
|
cardcolor: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -256,6 +258,11 @@ export function ProductionBoardKanbanComponent({
|
|||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{cardSettings.cardcolor && (
|
||||||
|
<CardColorLegend cardSettings={cardSettings} bodyshop={bodyshop} />
|
||||||
|
)}
|
||||||
|
|
||||||
<ProductionListDetailComponent jobs={data} />
|
<ProductionListDetailComponent jobs={data} />
|
||||||
<StickyContainer>
|
<StickyContainer>
|
||||||
<Board
|
<Board
|
||||||
|
|||||||
@@ -91,11 +91,13 @@ const r = ({ technician, state, activeStatuses, bodyshop }) => {
|
|||||||
b.v_make_desc + b.v_model_desc
|
b.v_make_desc + b.v_model_desc
|
||||||
),
|
),
|
||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "ownr" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order,
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<span>{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
|
<Link to={`/manage/vehicles/${record.vehicleid}`}>{`${
|
||||||
record.v_model_desc || ""
|
record.v_model_yr || ""
|
||||||
} ${record.v_color || ""} ${record.plate_no || ""}`}</span>
|
} ${record.v_make_desc || ""} ${record.v_model_desc || ""} ${
|
||||||
|
record.v_color || ""
|
||||||
|
} ${record.plate_no || ""}`}</Link>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,12 +1,23 @@
|
|||||||
import Icon from "@ant-design/icons";
|
import Icon from "@ant-design/icons";
|
||||||
import { useMutation } from "@apollo/client";
|
import { useMutation } from "@apollo/client";
|
||||||
import { Button, Input, Popover } from "antd";
|
import { Button, Input, Popover, Space } from "antd";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { FaRegStickyNote } from "react-icons/fa";
|
import { FaRegStickyNote } from "react-icons/fa";
|
||||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||||
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
||||||
export default function ProductionListColumnProductionNote({ record }) {
|
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
setNoteUpsertContext: (context) =>
|
||||||
|
dispatch(setModalContext({ context: context, modal: "noteUpsert" })),
|
||||||
|
});
|
||||||
|
|
||||||
|
function ProductionListColumnProductionNote({ record, setNoteUpsertContext }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const [note, setNote] = useState(
|
const [note, setNote] = useState(
|
||||||
@@ -60,12 +71,26 @@ export default function ProductionListColumnProductionNote({ record }) {
|
|||||||
// onPressEnter={handleSaveNote}
|
// onPressEnter={handleSaveNote}
|
||||||
autoFocus
|
autoFocus
|
||||||
allowClear
|
allowClear
|
||||||
|
style={{ marginBottom: "1em" }}
|
||||||
/>
|
/>
|
||||||
<div>
|
<Space>
|
||||||
<Button onClick={handleSaveNote}>
|
<Button onClick={handleSaveNote} type="primary">
|
||||||
{t("general.actions.save")}
|
{t("general.actions.save")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setVisible(false);
|
||||||
|
setNoteUpsertContext({
|
||||||
|
context: {
|
||||||
|
jobId: record.id,
|
||||||
|
text: note,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("notes.actions.savetojobnotes")}
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
trigger={["click"]}
|
trigger={["click"]}
|
||||||
@@ -85,3 +110,8 @@ export default function ProductionListColumnProductionNote({ record }) {
|
|||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(ProductionListColumnProductionNote);
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export function ProductionListTable({
|
|||||||
state,
|
state,
|
||||||
activeStatuses: bodyshop.md_ro_statuses.active_statuses,
|
activeStatuses: bodyshop.md_ro_statuses.active_statuses,
|
||||||
}).find((e) => e.key === k.key),
|
}).find((e) => e.key === k.key),
|
||||||
width: k.width,
|
width: k.width ?? 100,
|
||||||
};
|
};
|
||||||
})) ||
|
})) ||
|
||||||
[]
|
[]
|
||||||
@@ -267,6 +267,8 @@ export function ProductionListTable({
|
|||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === c.key && state.sortedInfo.order,
|
state.sortedInfo.columnKey === c.key && state.sortedInfo.order,
|
||||||
title: headerItem(c),
|
title: headerItem(c),
|
||||||
|
ellipsis: true,
|
||||||
|
width: c.width ?? 100,
|
||||||
onHeaderCell: (column) => ({
|
onHeaderCell: (column) => ({
|
||||||
width: column.width,
|
width: column.width,
|
||||||
onResize: handleResize(index),
|
onResize: handleResize(index),
|
||||||
@@ -276,11 +278,12 @@ export function ProductionListTable({
|
|||||||
rowKey="id"
|
rowKey="id"
|
||||||
loading={loading}
|
loading={loading}
|
||||||
dataSource={dataSource}
|
dataSource={dataSource}
|
||||||
// scroll={{ x: true }}
|
scroll={{ x: 1000 }}
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
/>
|
/>
|
||||||
</ReactDragListView.DragColumn>
|
</ReactDragListView.DragColumn>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps, null)(ProductionListTable);
|
export default connect(mapStateToProps, null)(ProductionListTable);
|
||||||
|
|||||||
@@ -3,8 +3,26 @@ import { Resizable } from "react-resizable";
|
|||||||
|
|
||||||
export default function ResizableComponent(props) {
|
export default function ResizableComponent(props) {
|
||||||
const { onResize, width, ...restProps } = props;
|
const { onResize, width, ...restProps } = props;
|
||||||
|
|
||||||
|
if (!width) {
|
||||||
|
return <th {...restProps} />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Resizable width={width || 200} height={0} onResize={onResize}>
|
<Resizable
|
||||||
|
width={width || 200}
|
||||||
|
height={0}
|
||||||
|
onResize={onResize}
|
||||||
|
draggableOpts={{ enableUserSelectHack: false }}
|
||||||
|
handle={
|
||||||
|
<span
|
||||||
|
className="react-resizable-handle"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
<th {...restProps} />
|
<th {...restProps} />
|
||||||
</Resizable>
|
</Resizable>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -92,7 +92,11 @@ export function ReportCenterModalComponent({ reportCenterModal }) {
|
|||||||
to: values.to,
|
to: values.to,
|
||||||
subject: Templates[values.key]?.subject,
|
subject: Templates[values.key]?.subject,
|
||||||
},
|
},
|
||||||
values.sendby === "email" ? "e" : "p",
|
values.sendbyexcel === "excel"
|
||||||
|
? "x"
|
||||||
|
: values.sendby === "email"
|
||||||
|
? "e"
|
||||||
|
: "p",
|
||||||
id
|
id
|
||||||
);
|
);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -250,15 +254,38 @@ export function ReportCenterModalComponent({ reportCenterModal }) {
|
|||||||
ranges={DatePIckerRanges}
|
ranges={DatePIckerRanges}
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item style={{ margin: 0, padding: 0 }} dependencies={["key"]}>
|
||||||
label={t("general.labels.sendby")}
|
{() => {
|
||||||
name="sendby"
|
const key = form.getFieldValue("key");
|
||||||
initialValue="print"
|
//Kind of Id
|
||||||
>
|
const reporttype = Templates[key] && Templates[key].reporttype;
|
||||||
<Radio.Group>
|
|
||||||
<Radio value="email">{t("general.labels.email")}</Radio>
|
if (reporttype === "excel")
|
||||||
<Radio value="print">{t("general.labels.print")}</Radio>
|
return (
|
||||||
</Radio.Group>
|
<Form.Item
|
||||||
|
label={t("general.labels.sendby")}
|
||||||
|
name="sendbyexcel"
|
||||||
|
initialValue="excel"
|
||||||
|
>
|
||||||
|
<Radio.Group>
|
||||||
|
<Radio value="excel">{t("general.labels.excel")}</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
if (reporttype !== "excel")
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
label={t("general.labels.sendby")}
|
||||||
|
name="sendby"
|
||||||
|
initialValue="print"
|
||||||
|
>
|
||||||
|
<Radio.Group>
|
||||||
|
<Radio value="email">{t("general.labels.email")}</Radio>
|
||||||
|
<Radio value="print">{t("general.labels.print")}</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import Dinero from "dinero.js";
|
||||||
|
|
||||||
|
const CustomTooltip = ({ active, payload, label }) => {
|
||||||
|
if (active && payload && payload.length) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
backgroundColor: "white",
|
||||||
|
border: "1px solid gray",
|
||||||
|
padding: "0.5rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p style={{ margin: "0" }}>{label}</p>
|
||||||
|
{payload.map((data, index) => {
|
||||||
|
if (data.dataKey === "sales" || data.dataKey === "accSales")
|
||||||
|
return (
|
||||||
|
<p
|
||||||
|
style={{ margin: "10px 0", color: data.color }}
|
||||||
|
key={index}
|
||||||
|
>{`${data.name} : ${Dinero({
|
||||||
|
amount: Math.round(data.value * 100),
|
||||||
|
}).toFormat()}`}</p>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<p
|
||||||
|
style={{ margin: "10px 0", color: data.color }}
|
||||||
|
key={index}
|
||||||
|
>{`${data.name} : ${data.value}`}</p>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CustomTooltip;
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
import { Card } from "antd";
|
import { Card } from "antd";
|
||||||
|
import Dinero from "dinero.js";
|
||||||
|
import _ from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -17,7 +19,7 @@ import {
|
|||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import * as Utils from "../scoreboard-targets-table/scoreboard-targets-table.util";
|
import * as Utils from "../scoreboard-targets-table/scoreboard-targets-table.util";
|
||||||
import _ from "lodash";
|
import CustomTooltip from "./chart-custom-tooltip";
|
||||||
|
|
||||||
const graphProps = {
|
const graphProps = {
|
||||||
strokeWidth: 3,
|
strokeWidth: 3,
|
||||||
@@ -44,14 +46,19 @@ export function ScoreboardChart({ sbEntriesByDate, bodyshop }) {
|
|||||||
return {
|
return {
|
||||||
bodyhrs: dayAcc.bodyhrs + dayVal.bodyhrs,
|
bodyhrs: dayAcc.bodyhrs + dayVal.bodyhrs,
|
||||||
painthrs: dayAcc.painthrs + dayVal.painthrs,
|
painthrs: dayAcc.painthrs + dayVal.painthrs,
|
||||||
|
sales:
|
||||||
|
dayAcc.painthrs +
|
||||||
|
dayVal.job.job_totals.totals.subtotal.amount / 100 +
|
||||||
|
2500,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{ bodyhrs: 0, painthrs: 0 }
|
{ bodyhrs: 0, painthrs: 0, sales: 0 }
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
dayhrs = {
|
dayhrs = {
|
||||||
bodyhrs: 0,
|
bodyhrs: 0,
|
||||||
painthrs: 0,
|
painthrs: 0,
|
||||||
|
sales: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +71,9 @@ export function ScoreboardChart({ sbEntriesByDate, bodyshop }) {
|
|||||||
bodyshop.scoreboard_target.dailyBodyTarget +
|
bodyshop.scoreboard_target.dailyBodyTarget +
|
||||||
bodyshop.scoreboard_target.dailyPaintTarget,
|
bodyshop.scoreboard_target.dailyPaintTarget,
|
||||||
val
|
val
|
||||||
),
|
) +
|
||||||
|
bodyshop.scoreboard_target.dailyBodyTarget +
|
||||||
|
bodyshop.scoreboard_target.dailyPaintTarget,
|
||||||
1
|
1
|
||||||
),
|
),
|
||||||
accHrs: _.round(
|
accHrs: _.round(
|
||||||
@@ -73,6 +82,13 @@ export function ScoreboardChart({ sbEntriesByDate, bodyshop }) {
|
|||||||
: dayhrs.painthrs + dayhrs.bodyhrs,
|
: dayhrs.painthrs + dayhrs.bodyhrs,
|
||||||
1
|
1
|
||||||
),
|
),
|
||||||
|
sales: _.round(dayhrs.sales, 2),
|
||||||
|
accSales: _.round(
|
||||||
|
acc.length > 0
|
||||||
|
? acc[acc.length - 1].accSales + dayhrs.sales
|
||||||
|
: dayhrs.sales,
|
||||||
|
2
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
return [...acc, theValue];
|
return [...acc, theValue];
|
||||||
@@ -87,22 +103,27 @@ export function ScoreboardChart({ sbEntriesByDate, bodyshop }) {
|
|||||||
>
|
>
|
||||||
<CartesianGrid stroke="#f5f5f5" />
|
<CartesianGrid stroke="#f5f5f5" />
|
||||||
<XAxis dataKey="date" strokeWidth={graphProps.strokeWidth} />
|
<XAxis dataKey="date" strokeWidth={graphProps.strokeWidth} />
|
||||||
<YAxis strokeWidth={graphProps.strokeWidth} />
|
<YAxis
|
||||||
<Tooltip />
|
strokeWidth={graphProps.strokeWidth}
|
||||||
<Legend />
|
// allowDataOverflow
|
||||||
<Area
|
dataKey="sales"
|
||||||
type="monotone"
|
yAxisId="right"
|
||||||
name="Accumulated Hours"
|
tickFormatter={(value) =>
|
||||||
dataKey="accHrs"
|
Dinero({ amount: Math.round(value * 100) }).toFormat()
|
||||||
fill="lightgreen"
|
}
|
||||||
stroke="green"
|
orientation="right"
|
||||||
/>
|
/>
|
||||||
|
<YAxis yAxisId="left" strokeWidth={graphProps.strokeWidth} />
|
||||||
|
<Tooltip content={<CustomTooltip />} />
|
||||||
|
<Legend />
|
||||||
|
|
||||||
<Bar
|
<Bar
|
||||||
name="Body Hours"
|
name="Body Hours"
|
||||||
dataKey="bodyHrs"
|
dataKey="bodyHrs"
|
||||||
stackId="day"
|
stackId="day"
|
||||||
barSize={20}
|
barSize={20}
|
||||||
fill="darkblue"
|
fill="darkblue"
|
||||||
|
yAxisId="left"
|
||||||
/>
|
/>
|
||||||
<Bar
|
<Bar
|
||||||
name="Paint Hours"
|
name="Paint Hours"
|
||||||
@@ -110,12 +131,42 @@ export function ScoreboardChart({ sbEntriesByDate, bodyshop }) {
|
|||||||
stackId="day"
|
stackId="day"
|
||||||
barSize={20}
|
barSize={20}
|
||||||
fill="darkred"
|
fill="darkred"
|
||||||
|
yAxisId="left"
|
||||||
/>
|
/>
|
||||||
<Line
|
<Line
|
||||||
name="Target Hours"
|
name="Target Hours"
|
||||||
type="monotone"
|
type="monotone"
|
||||||
dataKey="accTargetHrs"
|
dataKey="accTargetHrs"
|
||||||
stroke="#ff7300"
|
stroke="#ff7300"
|
||||||
|
yAxisId="left"
|
||||||
|
strokeWidth={graphProps.strokeWidth}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Area
|
||||||
|
type="monotone"
|
||||||
|
name="MTD Hours"
|
||||||
|
dataKey="accHrs"
|
||||||
|
fill="lightblue"
|
||||||
|
stroke="blue"
|
||||||
|
yAxisId="left"
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
// <Area
|
||||||
|
// type="monotone"
|
||||||
|
// name="MTD Sales"
|
||||||
|
// dataKey="accSales"
|
||||||
|
// fill="lightgreen"
|
||||||
|
// stroke="green"
|
||||||
|
// yAxisId="right"
|
||||||
|
// />
|
||||||
|
}
|
||||||
|
<Bar
|
||||||
|
name="Sales"
|
||||||
|
dataKey="sales"
|
||||||
|
stackId="day"
|
||||||
|
barSize={20}
|
||||||
|
fill="darkgreen"
|
||||||
|
yAxisId="right"
|
||||||
strokeWidth={graphProps.strokeWidth}
|
strokeWidth={graphProps.strokeWidth}
|
||||||
/>
|
/>
|
||||||
</ComposedChart>
|
</ComposedChart>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Card, Statistic } from "antd";
|
import { Card, Divider, Statistic } from "antd";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -41,6 +41,9 @@ export function ScoreboardDayStats({ bodyshop, date, entries }) {
|
|||||||
label="P"
|
label="P"
|
||||||
value={paintHrs.toFixed(1)}
|
value={paintHrs.toFixed(1)}
|
||||||
/>
|
/>
|
||||||
|
<Divider style={{ margin: 0 }} />
|
||||||
|
|
||||||
|
<Statistic value={(bodyHrs + paintHrs).toFixed(1)} />
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { CalendarOutlined } from "@ant-design/icons";
|
import { CalendarOutlined } from "@ant-design/icons";
|
||||||
import { Card, Col, Row, Statistic } from "antd";
|
import { Card, Col, Divider, Row, Statistic } from "antd";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import React, { useMemo } from "react";
|
import React, { useMemo } from "react";
|
||||||
@@ -177,6 +177,9 @@ export function ScoreboardTargetsTable({ bodyshop, scoreBoardlist }) {
|
|||||||
<Statistic value={values.toDatePaint.toFixed(1)} />
|
<Statistic value={values.toDatePaint.toFixed(1)} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Divider style={{ margin: 5 }} />
|
||||||
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Col {...statSpans}></Col>
|
<Col {...statSpans}></Col>
|
||||||
<Col {...statSpans}>
|
<Col {...statSpans}>
|
||||||
@@ -184,14 +187,53 @@ export function ScoreboardTargetsTable({ bodyshop, scoreBoardlist }) {
|
|||||||
value={(values.todayPaint + values.todayBody).toFixed(1)}
|
value={(values.todayPaint + values.todayBody).toFixed(1)}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col {...statSpans}></Col>
|
<Col {...statSpans}>
|
||||||
|
<Statistic
|
||||||
|
value={(
|
||||||
|
Util.WeeklyTargetHrs(
|
||||||
|
bodyshop.scoreboard_target.dailyBodyTarget,
|
||||||
|
bodyshop
|
||||||
|
) +
|
||||||
|
Util.WeeklyTargetHrs(
|
||||||
|
bodyshop.scoreboard_target.dailyPaintTarget,
|
||||||
|
bodyshop
|
||||||
|
)
|
||||||
|
).toFixed(1)}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
<Col {...statSpans}>
|
<Col {...statSpans}>
|
||||||
<Statistic
|
<Statistic
|
||||||
value={(values.weeklyPaint + values.weeklyBody).toFixed(1)}
|
value={(values.weeklyPaint + values.weeklyBody).toFixed(1)}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col {...statSpans}></Col>
|
<Col {...statSpans}>
|
||||||
<Col {...statSpans}></Col>
|
<Statistic
|
||||||
|
value={(
|
||||||
|
Util.MonthlyTargetHrs(
|
||||||
|
bodyshop.scoreboard_target.dailyBodyTarget,
|
||||||
|
bodyshop
|
||||||
|
) +
|
||||||
|
Util.MonthlyTargetHrs(
|
||||||
|
bodyshop.scoreboard_target.dailyPaintTarget,
|
||||||
|
bodyshop
|
||||||
|
)
|
||||||
|
).toFixed(1)}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col {...statSpans}>
|
||||||
|
<Statistic
|
||||||
|
value={(
|
||||||
|
Util.AsOfTodayTargetHrs(
|
||||||
|
bodyshop.scoreboard_target.dailyBodyTarget,
|
||||||
|
bodyshop
|
||||||
|
) +
|
||||||
|
Util.AsOfTodayTargetHrs(
|
||||||
|
bodyshop.scoreboard_target.dailyPaintTarget,
|
||||||
|
bodyshop
|
||||||
|
)
|
||||||
|
).toFixed(1)}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
<Col {...statSpans}>
|
<Col {...statSpans}>
|
||||||
<Statistic
|
<Statistic
|
||||||
value={(values.toDatePaint + values.toDateBody).toFixed(1)}
|
value={(values.toDatePaint + values.toDateBody).toFixed(1)}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ export default function ScoreboardTimeTickets() {
|
|||||||
totalLastMonth: 0,
|
totalLastMonth: 0,
|
||||||
totalOverPeriod: 0,
|
totalOverPeriod: 0,
|
||||||
actualTotalOverPeriod: 0,
|
actualTotalOverPeriod: 0,
|
||||||
|
totalEffieciencyOverPeriod: 0,
|
||||||
employees: {},
|
employees: {},
|
||||||
};
|
};
|
||||||
data.fixedperiod.forEach((ticket) => {
|
data.fixedperiod.forEach((ticket) => {
|
||||||
@@ -94,6 +95,7 @@ export default function ScoreboardTimeTickets() {
|
|||||||
totalLastMonth: 0,
|
totalLastMonth: 0,
|
||||||
totalOverPeriod: 0,
|
totalOverPeriod: 0,
|
||||||
actualTotalOverPeriod: 0,
|
actualTotalOverPeriod: 0,
|
||||||
|
totalEffieciencyOverPeriod: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,6 +223,30 @@ export default function ScoreboardTimeTickets() {
|
|||||||
|
|
||||||
ret2.push(r);
|
ret2.push(r);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add total efficiency of employees
|
||||||
|
const totalActualAndProductive = Object.keys(ret.employees)
|
||||||
|
.map((key) => {
|
||||||
|
return { employee_number: key, ...ret.employees[key] };
|
||||||
|
})
|
||||||
|
.reduce(
|
||||||
|
(acc, e) => {
|
||||||
|
return {
|
||||||
|
totalOverPeriod: acc.totalOverPeriod + e.totalOverPeriod,
|
||||||
|
actualTotalOverPeriod:
|
||||||
|
acc.actualTotalOverPeriod + e.actualTotalOverPeriod,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ totalOverPeriod: 0, actualTotalOverPeriod: 0 }
|
||||||
|
);
|
||||||
|
|
||||||
|
ret.totalEffieciencyOverPeriod =
|
||||||
|
totalActualAndProductive.actualTotalOverPeriod
|
||||||
|
? (totalActualAndProductive.totalOverPeriod /
|
||||||
|
totalActualAndProductive.actualTotalOverPeriod) *
|
||||||
|
100
|
||||||
|
: 0;
|
||||||
|
|
||||||
roundObject(ret);
|
roundObject(ret);
|
||||||
roundObject(totals);
|
roundObject(totals);
|
||||||
roundObject(ret2);
|
roundObject(ret2);
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export function ScoreboardTicketsStats({ data, bodyshop }) {
|
|||||||
key: "efficiencyoverperiod",
|
key: "efficiencyoverperiod",
|
||||||
render: (text, record) =>
|
render: (text, record) =>
|
||||||
`${(
|
`${(
|
||||||
(record.totalOverPeriod / (record.actualTotalOverPeriod || .1)) *
|
(record.totalOverPeriod / (record.actualTotalOverPeriod || 0.1)) *
|
||||||
100
|
100
|
||||||
).toFixed(1)} %`,
|
).toFixed(1)} %`,
|
||||||
},
|
},
|
||||||
@@ -113,6 +113,12 @@ export function ScoreboardTicketsStats({ data, bodyshop }) {
|
|||||||
value={data.totalOverPeriod}
|
value={data.totalOverPeriod}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Statistic
|
||||||
|
title={t("scoreboard.labels.efficiencyoverperiod")}
|
||||||
|
value={`${data.totalEffieciencyOverPeriod || 0}%`}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Typography.Text type="secondary">
|
<Typography.Text type="secondary">
|
||||||
{t("scoreboard.labels.calendarperiod")}
|
{t("scoreboard.labels.calendarperiod")}
|
||||||
@@ -121,7 +127,7 @@ export function ScoreboardTicketsStats({ data, bodyshop }) {
|
|||||||
<Col md={24} lg={20}>
|
<Col md={24} lg={20}>
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey='employee_number'
|
rowKey="employee_number"
|
||||||
dataSource={tableData}
|
dataSource={tableData}
|
||||||
id="employee_number"
|
id="employee_number"
|
||||||
scroll={{ y: "300px" }}
|
scroll={{ y: "300px" }}
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ import {
|
|||||||
} from "antd";
|
} 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 FormItemEmail from "../form-items-formatted/email-form-item.component";
|
||||||
import PhoneFormItem, {
|
import PhoneFormItem, {
|
||||||
PhoneItemFormatterValidation,
|
PhoneItemFormatterValidation,
|
||||||
} from "../form-items-formatted/phone-form-item.component";
|
} from "../form-items-formatted/phone-form-item.component";
|
||||||
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
|
||||||
import FormItemEmail from "../form-items-formatted/email-form-item.component";
|
|
||||||
|
|
||||||
import momentTZ from "moment-timezone";
|
import momentTZ from "moment-timezone";
|
||||||
const timeZonesList = momentTZ.tz.names();
|
const timeZonesList = momentTZ.tz.names();
|
||||||
@@ -551,6 +551,13 @@ export default function ShopInfoGeneral({ form }) {
|
|||||||
>
|
>
|
||||||
<CurrencyInput />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name={["use_paint_scale_data"]}
|
||||||
|
label={t("bodyshop.fields.use_paint_scale_data")}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={["attach_pdf_to_email"]}
|
name={["attach_pdf_to_email"]}
|
||||||
label={t("bodyshop.fields.attach_pdf_to_email")}
|
label={t("bodyshop.fields.attach_pdf_to_email")}
|
||||||
@@ -589,6 +596,13 @@ export default function ShopInfoGeneral({ form }) {
|
|||||||
>
|
>
|
||||||
<Switch />
|
<Switch />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name={["tt_enforce_hours_for_tech_console"]}
|
||||||
|
label={t("bodyshop.fields.tt_enforce_hours_for_tech_console")}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={["bill_allow_post_to_closed"]}
|
name={["bill_allow_post_to_closed"]}
|
||||||
label={t("bodyshop.fields.bill_allow_post_to_closed")}
|
label={t("bodyshop.fields.bill_allow_post_to_closed")}
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ export function ShopInfoROStatusComponent({ bodyshop, form }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ColorPicker = ({ value, onChange, style, ...restProps }) => {
|
export const ColorPicker = ({ value, onChange, style, ...restProps }) => {
|
||||||
const handleChange = (color) => {
|
const handleChange = (color) => {
|
||||||
if (onChange) onChange(color.rgb);
|
if (onChange) onChange(color.rgb);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import ColorpickerFormItemComponent from "../form-items-formatted/colorpicker-form-item.component";
|
import ColorpickerFormItemComponent from "../form-items-formatted/colorpicker-form-item.component";
|
||||||
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
import { ColorPicker } from "./shop-info.rostatus.component";
|
||||||
|
|
||||||
export default function ShopInfoSchedulingComponent({ form }) {
|
export default function ShopInfoSchedulingComponent({ form }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -277,17 +278,50 @@ export default function ShopInfoSchedulingComponent({ form }) {
|
|||||||
>
|
>
|
||||||
<InputNumber />
|
<InputNumber />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Space wrap>
|
|
||||||
<DeleteFilled
|
<Space direction="horizontal">
|
||||||
onClick={() => {
|
<Form.Item
|
||||||
remove(field.name);
|
label={
|
||||||
}}
|
<Space>
|
||||||
/>
|
{t("bodyshop.fields.ssbuckets.color")}
|
||||||
<FormListMoveArrows
|
<Button
|
||||||
move={move}
|
size="small"
|
||||||
index={index}
|
onClick={() => {
|
||||||
total={fields.length}
|
form.setFieldValue([
|
||||||
/>
|
"ssbuckets",
|
||||||
|
field.name,
|
||||||
|
"color",
|
||||||
|
]);
|
||||||
|
|
||||||
|
form.setFields([
|
||||||
|
{
|
||||||
|
name: ["ssbuckets", field.name, "color"],
|
||||||
|
touched: true,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
key={`${index}color`}
|
||||||
|
name={[field.name, "color"]}
|
||||||
|
>
|
||||||
|
<ColorPicker />
|
||||||
|
</Form.Item>
|
||||||
|
<Space wrap>
|
||||||
|
<DeleteFilled
|
||||||
|
onClick={() => {
|
||||||
|
remove(field.name);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<FormListMoveArrows
|
||||||
|
move={move}
|
||||||
|
index={index}
|
||||||
|
total={fields.length}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ export function TechClockInContainer({
|
|||||||
technician,
|
technician,
|
||||||
bodyshop,
|
bodyshop,
|
||||||
}) {
|
}) {
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: tech-job-clock-in-form.container.jsx:29 ~ technician:",
|
||||||
|
technician
|
||||||
|
);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [insertTimeTicket] = useMutation(INSERT_NEW_TIME_TICKET, {
|
const [insertTimeTicket] = useMutation(INSERT_NEW_TIME_TICKET, {
|
||||||
@@ -33,6 +37,10 @@ export function TechClockInContainer({
|
|||||||
});
|
});
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const emps = bodyshop.employees.filter(
|
||||||
|
(e) => e.id === (technician && technician.id)
|
||||||
|
)[0];
|
||||||
|
|
||||||
const handleFinish = async (values) => {
|
const handleFinish = async (values) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const theTime = (await axios.post("/utils/time")).data;
|
const theTime = (await axios.post("/utils/time")).data;
|
||||||
@@ -87,7 +95,12 @@ export function TechClockInContainer({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setTimeTicketContext({
|
setTimeTicketContext({
|
||||||
actions: {},
|
actions: {},
|
||||||
context: { timeticket: { employeeid: technician.id } },
|
context: {
|
||||||
|
timeticket: {
|
||||||
|
employeeid: technician.id,
|
||||||
|
flat_rate: emps.flat_rate,
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useMutation } from "@apollo/client";
|
import { useMutation, useQuery } from "@apollo/client";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
@@ -21,6 +21,8 @@ import { selectTechnician } from "../../redux/tech/tech.selectors";
|
|||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import TechJobClockoutDelete from "../tech-job-clock-out-delete/tech-job-clock-out-delete.component";
|
import TechJobClockoutDelete from "../tech-job-clock-out-delete/tech-job-clock-out-delete.component";
|
||||||
import { LaborAllocationContainer } from "../time-ticket-modal/time-ticket-modal.component";
|
import { LaborAllocationContainer } from "../time-ticket-modal/time-ticket-modal.component";
|
||||||
|
import { GET_LINE_TICKET_BY_PK } from "../../graphql/jobs-lines.queries";
|
||||||
|
import { CalculateAllocationsTotals } from "../labor-allocations-table/labor-allocations-table.utility";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -39,7 +41,17 @@ export function TechClockOffButton({
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [updateTimeticket] = useMutation(UPDATE_TIME_TICKET);
|
const [updateTimeticket] = useMutation(UPDATE_TIME_TICKET);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
const { queryLoading, data: lineTicketData } = useQuery(
|
||||||
|
GET_LINE_TICKET_BY_PK,
|
||||||
|
{
|
||||||
|
variables: {
|
||||||
|
id: jobId,
|
||||||
|
},
|
||||||
|
skip: !jobId,
|
||||||
|
fetchPolicy: "network-only",
|
||||||
|
nextFetchPolicy: "network-only",
|
||||||
|
}
|
||||||
|
);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const emps = bodyshop.employees.filter(
|
const emps = bodyshop.employees.filter(
|
||||||
(e) => e.id === (technician && technician.id)
|
(e) => e.id === (technician && technician.id)
|
||||||
@@ -59,6 +71,7 @@ export function TechClockOffButton({
|
|||||||
emps &&
|
emps &&
|
||||||
emps.rates.filter((r) => r.cost_center === values.cost_center)[0]
|
emps.rates.filter((r) => r.cost_center === values.cost_center)[0]
|
||||||
?.rate,
|
?.rate,
|
||||||
|
flat_rate: emps && emps.flat_rate,
|
||||||
ciecacode:
|
ciecacode:
|
||||||
bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber
|
bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber
|
||||||
? values.cost_center
|
? values.cost_center
|
||||||
@@ -128,6 +141,54 @@ export function TechClockOffButton({
|
|||||||
required: true,
|
required: true,
|
||||||
//message: t("general.validation.required"),
|
//message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
|
({ getFieldValue }) => ({
|
||||||
|
validator(rule, value) {
|
||||||
|
console.log(
|
||||||
|
bodyshop.tt_enforce_hours_for_tech_console
|
||||||
|
);
|
||||||
|
if (!bodyshop.tt_enforce_hours_for_tech_console) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!value ||
|
||||||
|
getFieldValue("cost_center") === null ||
|
||||||
|
!lineTicketData
|
||||||
|
)
|
||||||
|
return Promise.resolve();
|
||||||
|
|
||||||
|
//Check the cost center,
|
||||||
|
const totals = CalculateAllocationsTotals(
|
||||||
|
bodyshop,
|
||||||
|
lineTicketData.joblines,
|
||||||
|
lineTicketData.timetickets,
|
||||||
|
lineTicketData.jobs_by_pk.lbr_adjustments
|
||||||
|
);
|
||||||
|
|
||||||
|
const fieldTypeToCheck =
|
||||||
|
bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber
|
||||||
|
? "mod_lbr_ty"
|
||||||
|
: "cost_center";
|
||||||
|
|
||||||
|
const costCenterDiff =
|
||||||
|
Math.round(
|
||||||
|
totals.find(
|
||||||
|
(total) =>
|
||||||
|
total[fieldTypeToCheck] ===
|
||||||
|
getFieldValue("cost_center")
|
||||||
|
)?.difference * 10
|
||||||
|
) / 10;
|
||||||
|
|
||||||
|
if (value > costCenterDiff)
|
||||||
|
return Promise.reject(
|
||||||
|
t(
|
||||||
|
"timetickets.validation.hoursenteredmorethanavailable"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
else {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} precision={1} />
|
<InputNumber min={0} precision={1} />
|
||||||
@@ -177,7 +238,11 @@ export function TechClockOffButton({
|
|||||||
</Col>
|
</Col>
|
||||||
{!isShiftTicket && (
|
{!isShiftTicket && (
|
||||||
<Col span={16}>
|
<Col span={16}>
|
||||||
<LaborAllocationContainer jobid={jobId} />
|
<LaborAllocationContainer
|
||||||
|
jobid={jobId || null}
|
||||||
|
loading={queryLoading}
|
||||||
|
lineTicketData={lineTicketData}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
)}
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
import { useQuery } from "@apollo/client";
|
||||||
|
import { Card, Col, Space, Statistic, Typography } from "antd";
|
||||||
|
import moment from "moment";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE } from "../../graphql/timetickets.queries";
|
||||||
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||||
|
import AlertComponent from "../alert/alert.component";
|
||||||
|
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||||
|
const { Title } = Typography;
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
technician: selectTechnician,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({});
|
||||||
|
|
||||||
|
const TechJobStatistics = ({ technician }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const startDate = moment().startOf("week");
|
||||||
|
const endDate = moment().endOf("week");
|
||||||
|
|
||||||
|
const { loading, error, data } = useQuery(
|
||||||
|
QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE,
|
||||||
|
{
|
||||||
|
variables: {
|
||||||
|
start: startDate.format("YYYY-MM-DD"),
|
||||||
|
end: endDate.format("YYYY-MM-DD"),
|
||||||
|
fixedStart: moment().startOf("month").format("YYYY-MM-DD"),
|
||||||
|
fixedEnd: moment().endOf("month").format("YYYY-MM-DD"),
|
||||||
|
employeeid: technician.id,
|
||||||
|
},
|
||||||
|
fetchPolicy: "network-only",
|
||||||
|
nextFetchPolicy: "network-only",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const totals = useMemo(() => {
|
||||||
|
if (data && data.timetickets && data.fixedperiod) {
|
||||||
|
const week = data.timetickets.reduce(
|
||||||
|
(acc, val) => {
|
||||||
|
acc.productivehrs = acc.productivehrs + val.productivehrs;
|
||||||
|
acc.actualhrs = acc.actualhrs + val.actualhrs;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{ productivehrs: 0, actualhrs: 0 }
|
||||||
|
);
|
||||||
|
|
||||||
|
const month = data.fixedperiod.reduce(
|
||||||
|
(acc, val) => {
|
||||||
|
acc.productivehrs = acc.productivehrs + val.productivehrs;
|
||||||
|
acc.actualhrs = acc.actualhrs + val.actualhrs;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{ productivehrs: 0, actualhrs: 0 }
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
week,
|
||||||
|
month,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
week: { productivehrs: 0, actualhrs: 0 },
|
||||||
|
month: { productivehrs: 0, actualhrs: 0 },
|
||||||
|
};
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
if (loading) return <LoadingSpinner />;
|
||||||
|
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card title={t("scoreboard.labels.productivestatistics")}>
|
||||||
|
<Space size={100}>
|
||||||
|
<Col>
|
||||||
|
<Title level={5}>{t("scoreboard.labels.thisweek")}</Title>
|
||||||
|
<Space size={20}>
|
||||||
|
<Statistic
|
||||||
|
title={t("timetickets.fields.productivehrs")}
|
||||||
|
value={totals.week.productivehrs.toFixed(2)}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("timetickets.fields.actualhrs")}
|
||||||
|
value={totals.week.actualhrs.toFixed(2)}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("timetickets.labels.efficiency")}
|
||||||
|
value={
|
||||||
|
totals.week.actualhrs
|
||||||
|
? `${(
|
||||||
|
(totals.week.productivehrs / totals.week.actualhrs) *
|
||||||
|
100
|
||||||
|
).toFixed(2)}%`
|
||||||
|
: "0%"
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<Title level={5}>{t("scoreboard.labels.thismonth")}</Title>
|
||||||
|
<Space size={20}>
|
||||||
|
<Statistic
|
||||||
|
title={t("timetickets.fields.productivehrs")}
|
||||||
|
value={totals.month.productivehrs.toFixed(2)}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("timetickets.fields.actualhrs")}
|
||||||
|
value={totals.month.actualhrs.toFixed(2)}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("timetickets.labels.efficiency")}
|
||||||
|
value={
|
||||||
|
totals.month.actualhrs
|
||||||
|
? `${(
|
||||||
|
(totals.month.productivehrs / totals.month.actualhrs) *
|
||||||
|
100
|
||||||
|
).toFixed(2)}%`
|
||||||
|
: "0%"
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</Col>
|
||||||
|
</Space>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(TechJobStatistics);
|
||||||
@@ -29,7 +29,17 @@ export function TechSider({ technician, techLogout }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sider collapsible collapsed={collapsed} onCollapse={onCollapse}>
|
<Sider
|
||||||
|
style={{
|
||||||
|
height: "100vh",
|
||||||
|
position: "sticky",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
}}
|
||||||
|
collapsible
|
||||||
|
collapsed={collapsed}
|
||||||
|
onCollapse={onCollapse}
|
||||||
|
>
|
||||||
<Menu theme="dark" defaultSelectedKeys={["1"]} mode="inline">
|
<Menu theme="dark" defaultSelectedKeys={["1"]} mode="inline">
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key="1"
|
key="1"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useQuery } from "@apollo/client";
|
import { useLazyQuery } from "@apollo/client";
|
||||||
import { Form, Input, InputNumber, Select, Switch } from "antd";
|
import { Form, Input, InputNumber, Select, Switch } from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -14,6 +14,7 @@ import FormDatePicker from "../form-date-picker/form-date-picker.component";
|
|||||||
import FormDateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
|
import FormDateTimePicker from "../form-date-time-picker/form-date-time-picker.component";
|
||||||
import JobSearchSelect from "../job-search-select/job-search-select.component";
|
import JobSearchSelect from "../job-search-select/job-search-select.component";
|
||||||
import LaborAllocationsTable from "../labor-allocations-table/labor-allocations-table.component";
|
import LaborAllocationsTable from "../labor-allocations-table/labor-allocations-table.component";
|
||||||
|
import { CalculateAllocationsTotals } from "../labor-allocations-table/labor-allocations-table.utility";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||||
import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component";
|
import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component";
|
||||||
@@ -38,7 +39,11 @@ export function TimeTicketModalComponent({
|
|||||||
employeeSelectDisabled,
|
employeeSelectDisabled,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const [loadLineTicketData, { called, loading, data: lineTicketData }] =
|
||||||
|
useLazyQuery(GET_LINE_TICKET_BY_PK, {
|
||||||
|
fetchPolicy: "network-only",
|
||||||
|
nextFetchPolicy: "network-only",
|
||||||
|
});
|
||||||
const CostCenterSelect = ({ emps, value, ...props }) => {
|
const CostCenterSelect = ({ emps, value, ...props }) => {
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
@@ -176,6 +181,51 @@ export function TimeTicketModalComponent({
|
|||||||
label={t("timetickets.fields.productivehrs")}
|
label={t("timetickets.fields.productivehrs")}
|
||||||
name="productivehrs"
|
name="productivehrs"
|
||||||
rules={[
|
rules={[
|
||||||
|
({ getFieldValue }) => ({
|
||||||
|
validator(rule, value) {
|
||||||
|
if (!bodyshop.tt_enforce_hours_for_tech_console) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!value ||
|
||||||
|
getFieldValue("cost_center") === null ||
|
||||||
|
!lineTicketData
|
||||||
|
)
|
||||||
|
return Promise.resolve();
|
||||||
|
|
||||||
|
//Check the cost center,
|
||||||
|
const totals = CalculateAllocationsTotals(
|
||||||
|
bodyshop,
|
||||||
|
lineTicketData.joblines,
|
||||||
|
lineTicketData.timetickets,
|
||||||
|
lineTicketData.jobs_by_pk.lbr_adjustments
|
||||||
|
);
|
||||||
|
|
||||||
|
const fieldTypeToCheck =
|
||||||
|
bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber
|
||||||
|
? "mod_lbr_ty"
|
||||||
|
: "cost_center";
|
||||||
|
|
||||||
|
const costCenterDiff =
|
||||||
|
Math.round(
|
||||||
|
totals.find(
|
||||||
|
(total) =>
|
||||||
|
total[fieldTypeToCheck] ===
|
||||||
|
getFieldValue("cost_center")
|
||||||
|
)?.difference * 10
|
||||||
|
) / 10;
|
||||||
|
|
||||||
|
if (value > costCenterDiff)
|
||||||
|
return Promise.reject(
|
||||||
|
t(
|
||||||
|
"timetickets.validation.hoursenteredmorethanavailable"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
else {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
{
|
{
|
||||||
required:
|
required:
|
||||||
form.getFieldValue("cost_center") !==
|
form.getFieldValue("cost_center") !==
|
||||||
@@ -291,23 +341,28 @@ export function TimeTicketModalComponent({
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<Form.Item dependencies={["jobid"]}>
|
<Form.Item dependencies={["jobid"]}>
|
||||||
{() => (
|
{() => {
|
||||||
<LaborAllocationContainer
|
const jobid = form.getFieldValue("jobid");
|
||||||
jobid={form.getFieldValue("jobid") || null}
|
if (
|
||||||
/>
|
(!called && jobid) ||
|
||||||
)}
|
(jobid && lineTicketData?.jobs_by_pk?.id !== jobid && !loading)
|
||||||
|
) {
|
||||||
|
loadLineTicketData({ variables: { id: jobid } });
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<LaborAllocationContainer
|
||||||
|
jobid={jobid || null}
|
||||||
|
loading={loading}
|
||||||
|
lineTicketData={lineTicketData}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LaborAllocationContainer({ jobid }) {
|
export function LaborAllocationContainer({ jobid, loading, lineTicketData }) {
|
||||||
const { loading, data: lineTicketData } = useQuery(GET_LINE_TICKET_BY_PK, {
|
|
||||||
variables: { id: jobid },
|
|
||||||
skip: !jobid,
|
|
||||||
fetchPolicy: "network-only",
|
|
||||||
nextFetchPolicy: "network-only",
|
|
||||||
});
|
|
||||||
if (loading) return <LoadingSkeleton />;
|
if (loading) return <LoadingSkeleton />;
|
||||||
if (!lineTicketData) return null;
|
if (!lineTicketData) return null;
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -20,13 +20,11 @@ export const DELETE_BILL = gql`
|
|||||||
|
|
||||||
export const QUERY_ALL_BILLS_PAGINATED = gql`
|
export const QUERY_ALL_BILLS_PAGINATED = gql`
|
||||||
query QUERY_ALL_BILLS_PAGINATED(
|
query QUERY_ALL_BILLS_PAGINATED(
|
||||||
$search: String
|
|
||||||
$offset: Int
|
$offset: Int
|
||||||
$limit: Int
|
$limit: Int
|
||||||
$order: [bills_order_by!]!
|
$order: [bills_order_by!]!
|
||||||
) {
|
) {
|
||||||
search_bills(
|
bills(
|
||||||
args: { search: $search }
|
|
||||||
offset: $offset
|
offset: $offset
|
||||||
limit: $limit
|
limit: $limit
|
||||||
order_by: $order
|
order_by: $order
|
||||||
@@ -51,7 +49,7 @@ export const QUERY_ALL_BILLS_PAGINATED = gql`
|
|||||||
ro_number
|
ro_number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
search_bills_aggregate(args: { search: $search }) {
|
bills_aggregate {
|
||||||
aggregate {
|
aggregate {
|
||||||
count(distinct: true)
|
count(distinct: true)
|
||||||
}
|
}
|
||||||
@@ -69,6 +67,7 @@ export const QUERY_BILLS_BY_JOBID = gql`
|
|||||||
vendor {
|
vendor {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
email
|
||||||
}
|
}
|
||||||
order_date
|
order_date
|
||||||
deliver_by
|
deliver_by
|
||||||
@@ -104,6 +103,7 @@ export const QUERY_BILLS_BY_JOBID = gql`
|
|||||||
vendor {
|
vendor {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
email
|
||||||
}
|
}
|
||||||
total
|
total
|
||||||
invoice_number
|
invoice_number
|
||||||
|
|||||||
@@ -116,6 +116,8 @@ export const QUERY_BODYSHOP = gql`
|
|||||||
md_lost_sale_reasons
|
md_lost_sale_reasons
|
||||||
md_parts_scan
|
md_parts_scan
|
||||||
enforce_conversion_category
|
enforce_conversion_category
|
||||||
|
tt_enforce_hours_for_tech_console
|
||||||
|
use_paint_scale_data
|
||||||
employees {
|
employees {
|
||||||
user_email
|
user_email
|
||||||
id
|
id
|
||||||
@@ -125,6 +127,7 @@ export const QUERY_BODYSHOP = gql`
|
|||||||
employee_number
|
employee_number
|
||||||
rates
|
rates
|
||||||
external_id
|
external_id
|
||||||
|
flat_rate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,6 +232,7 @@ export const UPDATE_SHOP = gql`
|
|||||||
md_lost_sale_reasons
|
md_lost_sale_reasons
|
||||||
md_parts_scan
|
md_parts_scan
|
||||||
enforce_conversion_category
|
enforce_conversion_category
|
||||||
|
tt_enforce_hours_for_tech_console
|
||||||
employees {
|
employees {
|
||||||
id
|
id
|
||||||
first_name
|
first_name
|
||||||
|
|||||||
@@ -284,6 +284,7 @@ export const QUERY_JOBS_IN_PRODUCTION = gql`
|
|||||||
clm_no
|
clm_no
|
||||||
v_make_desc
|
v_make_desc
|
||||||
v_color
|
v_color
|
||||||
|
vehicleid
|
||||||
plate_no
|
plate_no
|
||||||
actual_in
|
actual_in
|
||||||
scheduled_completion
|
scheduled_completion
|
||||||
@@ -1277,7 +1278,7 @@ export const SEARCH_JOBS_BY_ID_FOR_AUTOCOMPLETE = gql`
|
|||||||
|
|
||||||
export const SEARCH_FOR_JOBS = gql`
|
export const SEARCH_FOR_JOBS = gql`
|
||||||
query SEARCH_FOR_JOBS($search: String!) {
|
query SEARCH_FOR_JOBS($search: String!) {
|
||||||
search_jobs(args: { search: $search }) {
|
search_jobs(args: { search: $search }, limit: 25) {
|
||||||
id
|
id
|
||||||
ro_number
|
ro_number
|
||||||
ownr_fn
|
ownr_fn
|
||||||
@@ -1780,14 +1781,12 @@ export const QUERY_ALL_JOB_FIELDS = gql`
|
|||||||
|
|
||||||
export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql`
|
export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql`
|
||||||
query QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED(
|
query QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED(
|
||||||
$search: String
|
|
||||||
$offset: Int
|
$offset: Int
|
||||||
$limit: Int
|
$limit: Int
|
||||||
$order: [jobs_order_by!]
|
$order: [jobs_order_by!]
|
||||||
$statusList: [String!]
|
$statusList: [String!]
|
||||||
) {
|
) {
|
||||||
search_jobs(
|
jobs(
|
||||||
args: { search: $search }
|
|
||||||
offset: $offset
|
offset: $offset
|
||||||
limit: $limit
|
limit: $limit
|
||||||
order_by: $order
|
order_by: $order
|
||||||
@@ -1818,10 +1817,7 @@ export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql`
|
|||||||
updated_at
|
updated_at
|
||||||
ded_amt
|
ded_amt
|
||||||
}
|
}
|
||||||
search_jobs_aggregate(
|
jobs_aggregate(where: { status: { _in: $statusList } }) {
|
||||||
args: { search: $search }
|
|
||||||
where: { status: { _in: $statusList } }
|
|
||||||
) {
|
|
||||||
aggregate {
|
aggregate {
|
||||||
count(distinct: true)
|
count(distinct: true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,16 @@ export const INSERT_NEW_NOTE = gql`
|
|||||||
mutation INSERT_NEW_NOTE($noteInput: [notes_insert_input!]!) {
|
mutation INSERT_NEW_NOTE($noteInput: [notes_insert_input!]!) {
|
||||||
insert_notes(objects: $noteInput) {
|
insert_notes(objects: $noteInput) {
|
||||||
returning {
|
returning {
|
||||||
|
created_at
|
||||||
|
created_by
|
||||||
|
critical
|
||||||
id
|
id
|
||||||
|
jobid
|
||||||
|
private
|
||||||
|
text
|
||||||
|
updated_at
|
||||||
|
audit
|
||||||
|
type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,8 +24,8 @@ export const QUERY_NOTES_BY_JOB_PK = gql`
|
|||||||
jobs_by_pk(id: $id) {
|
jobs_by_pk(id: $id) {
|
||||||
id
|
id
|
||||||
ro_number
|
ro_number
|
||||||
vehicle{
|
vehicle {
|
||||||
jobs{
|
jobs {
|
||||||
id
|
id
|
||||||
ro_number
|
ro_number
|
||||||
status
|
status
|
||||||
@@ -33,6 +42,7 @@ export const QUERY_NOTES_BY_JOB_PK = gql`
|
|||||||
text
|
text
|
||||||
updated_at
|
updated_at
|
||||||
audit
|
audit
|
||||||
|
type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,6 +62,7 @@ export const UPDATE_NOTE = gql`
|
|||||||
text
|
text
|
||||||
updated_at
|
updated_at
|
||||||
audit
|
audit
|
||||||
|
type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,39 +12,39 @@ export const INSERT_NEW_PAYMENT = gql`
|
|||||||
|
|
||||||
export const QUERY_ALL_PAYMENTS_PAGINATED = gql`
|
export const QUERY_ALL_PAYMENTS_PAGINATED = gql`
|
||||||
query QUERY_ALL_PAYMENTS_PAGINATED(
|
query QUERY_ALL_PAYMENTS_PAGINATED(
|
||||||
$search: String
|
|
||||||
$offset: Int
|
$offset: Int
|
||||||
$limit: Int
|
$limit: Int
|
||||||
$order: [payments_order_by!]!
|
$order: [payments_order_by!]!
|
||||||
) {
|
) {
|
||||||
search_payments(
|
payments(offset: $offset, limit: $limit, order_by: $order) {
|
||||||
args: { search: $search }
|
|
||||||
offset: $offset
|
|
||||||
limit: $limit
|
|
||||||
order_by: $order
|
|
||||||
) {
|
|
||||||
id
|
id
|
||||||
|
amount
|
||||||
created_at
|
created_at
|
||||||
jobid
|
|
||||||
paymentnum
|
|
||||||
date
|
date
|
||||||
|
exportedat
|
||||||
|
jobid
|
||||||
job {
|
job {
|
||||||
id
|
id
|
||||||
ro_number
|
ownerid
|
||||||
|
ownr_co_nm
|
||||||
ownr_fn
|
ownr_fn
|
||||||
ownr_ln
|
ownr_ln
|
||||||
ownr_co_nm
|
owner {
|
||||||
|
id
|
||||||
|
ownr_co_nm
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
}
|
||||||
|
ro_number
|
||||||
}
|
}
|
||||||
transactionid
|
|
||||||
memo
|
memo
|
||||||
type
|
|
||||||
amount
|
|
||||||
stripeid
|
|
||||||
exportedat
|
|
||||||
stripeid
|
|
||||||
payer
|
payer
|
||||||
|
paymentnum
|
||||||
|
stripeid
|
||||||
|
transactionid
|
||||||
|
type
|
||||||
}
|
}
|
||||||
search_payments_aggregate(args: { search: $search }) {
|
payments_aggregate {
|
||||||
aggregate {
|
aggregate {
|
||||||
count(distinct: true)
|
count(distinct: true)
|
||||||
}
|
}
|
||||||
@@ -57,16 +57,31 @@ export const UPDATE_PAYMENT = gql`
|
|||||||
update_payments(where: { id: { _eq: $paymentId } }, _set: $payment) {
|
update_payments(where: { id: { _eq: $paymentId } }, _set: $payment) {
|
||||||
returning {
|
returning {
|
||||||
id
|
id
|
||||||
transactionid
|
|
||||||
memo
|
|
||||||
type
|
|
||||||
amount
|
amount
|
||||||
stripeid
|
created_at
|
||||||
|
date
|
||||||
exportedat
|
exportedat
|
||||||
stripeid
|
jobid
|
||||||
|
job {
|
||||||
|
id
|
||||||
|
ownerid
|
||||||
|
ownr_co_nm
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
owner {
|
||||||
|
id
|
||||||
|
ownr_co_nm
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
}
|
||||||
|
ro_number
|
||||||
|
}
|
||||||
|
memo
|
||||||
payer
|
payer
|
||||||
paymentnum
|
paymentnum
|
||||||
date
|
stripeid
|
||||||
|
transactionid
|
||||||
|
type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,17 +95,31 @@ export const UPDATE_PAYMENTS = gql`
|
|||||||
update_payments(where: { id: { _in: $paymentIdList } }, _set: $payment) {
|
update_payments(where: { id: { _in: $paymentIdList } }, _set: $payment) {
|
||||||
returning {
|
returning {
|
||||||
id
|
id
|
||||||
exportedat
|
|
||||||
transactionid
|
|
||||||
memo
|
|
||||||
type
|
|
||||||
amount
|
amount
|
||||||
stripeid
|
created_at
|
||||||
|
date
|
||||||
exportedat
|
exportedat
|
||||||
stripeid
|
jobid
|
||||||
|
job {
|
||||||
|
id
|
||||||
|
ownerid
|
||||||
|
ownr_co_nm
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
owner {
|
||||||
|
id
|
||||||
|
ownr_co_nm
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
}
|
||||||
|
ro_number
|
||||||
|
}
|
||||||
|
memo
|
||||||
payer
|
payer
|
||||||
paymentnum
|
paymentnum
|
||||||
date
|
stripeid
|
||||||
|
transactionid
|
||||||
|
type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,3 +138,36 @@ export const QUERY_JOB_PAYMENT_TOTALS = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const QUERY_PAYMENT_BY_ID = gql`
|
||||||
|
query QUERY_PAYMENT_BY_ID($paymentId: uuid!) {
|
||||||
|
payments_by_pk(id: $paymentId) {
|
||||||
|
id
|
||||||
|
amount
|
||||||
|
created_at
|
||||||
|
exportedat
|
||||||
|
date
|
||||||
|
jobid
|
||||||
|
job {
|
||||||
|
id
|
||||||
|
ownerid
|
||||||
|
ownr_co_nm
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
owner {
|
||||||
|
id
|
||||||
|
ownr_co_nm
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
}
|
||||||
|
ro_number
|
||||||
|
}
|
||||||
|
memo
|
||||||
|
payer
|
||||||
|
paymentnum
|
||||||
|
stripeid
|
||||||
|
transactionid
|
||||||
|
type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export const QUERY_SCOREBOARD = gql`
|
|||||||
v_make_desc
|
v_make_desc
|
||||||
v_model_desc
|
v_model_desc
|
||||||
v_model_yr
|
v_model_yr
|
||||||
|
job_totals
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,20 @@ import { gql } from "@apollo/client";
|
|||||||
|
|
||||||
export const GLOBAL_SEARCH_QUERY = gql`
|
export const GLOBAL_SEARCH_QUERY = gql`
|
||||||
query GLOBAL_SEARCH_QUERY($search: String) {
|
query GLOBAL_SEARCH_QUERY($search: String) {
|
||||||
search_jobs(args: { search: $search }) {
|
search_jobs(args: { search: $search }, limit: 25) {
|
||||||
id
|
id
|
||||||
ro_number
|
ro_number
|
||||||
status
|
status
|
||||||
|
|
||||||
clm_no
|
clm_no
|
||||||
v_model_yr
|
v_model_yr
|
||||||
v_model_desc
|
v_model_desc
|
||||||
v_make_desc
|
v_make_desc
|
||||||
v_color
|
v_color
|
||||||
|
|
||||||
ownr_fn
|
ownr_fn
|
||||||
ownr_ln
|
ownr_ln
|
||||||
ownr_co_nm
|
ownr_co_nm
|
||||||
}
|
}
|
||||||
search_owners(args: { search: $search }) {
|
search_owners(args: { search: $search }, limit: 25) {
|
||||||
id
|
id
|
||||||
ownr_fn
|
ownr_fn
|
||||||
ownr_ln
|
ownr_ln
|
||||||
@@ -25,7 +23,7 @@ export const GLOBAL_SEARCH_QUERY = gql`
|
|||||||
ownr_ph1
|
ownr_ph1
|
||||||
ownr_ph2
|
ownr_ph2
|
||||||
}
|
}
|
||||||
search_vehicles(args: { search: $search }) {
|
search_vehicles(args: { search: $search }, limit: 25) {
|
||||||
id
|
id
|
||||||
v_model_yr
|
v_model_yr
|
||||||
v_model_desc
|
v_model_desc
|
||||||
@@ -34,7 +32,7 @@ export const GLOBAL_SEARCH_QUERY = gql`
|
|||||||
v_vin
|
v_vin
|
||||||
plate_no
|
plate_no
|
||||||
}
|
}
|
||||||
search_payments(args: { search: $search }) {
|
search_payments(args: { search: $search }, limit: 25) {
|
||||||
id
|
id
|
||||||
amount
|
amount
|
||||||
paymentnum
|
paymentnum
|
||||||
@@ -45,7 +43,7 @@ export const GLOBAL_SEARCH_QUERY = gql`
|
|||||||
memo
|
memo
|
||||||
transactionid
|
transactionid
|
||||||
}
|
}
|
||||||
search_bills(args: { search: $search }) {
|
search_bills(args: { search: $search }, limit: 25) {
|
||||||
id
|
id
|
||||||
date
|
date
|
||||||
invoice_number
|
invoice_number
|
||||||
@@ -54,7 +52,7 @@ export const GLOBAL_SEARCH_QUERY = gql`
|
|||||||
name
|
name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
search_phonebook(args: { search: $search }) {
|
search_phonebook(args: { search: $search }, limit: 25) {
|
||||||
id
|
id
|
||||||
firstname
|
firstname
|
||||||
lastname
|
lastname
|
||||||
|
|||||||
@@ -59,6 +59,81 @@ export const QUERY_TIME_TICKETS_IN_RANGE = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE = gql`
|
||||||
|
query QUERY_TIME_TICKETS_TECHNICIAN_IN_RANGE(
|
||||||
|
$employeeid: uuid!
|
||||||
|
$start: date!
|
||||||
|
$end: date!
|
||||||
|
$fixedStart: date!
|
||||||
|
$fixedEnd: date!
|
||||||
|
) {
|
||||||
|
timetickets(
|
||||||
|
where: {
|
||||||
|
date: { _gte: $start, _lte: $end }
|
||||||
|
employeeid: { _eq: $employeeid }
|
||||||
|
}
|
||||||
|
order_by: { date: desc_nulls_first }
|
||||||
|
) {
|
||||||
|
actualhrs
|
||||||
|
ciecacode
|
||||||
|
clockoff
|
||||||
|
clockon
|
||||||
|
cost_center
|
||||||
|
created_at
|
||||||
|
date
|
||||||
|
id
|
||||||
|
rate
|
||||||
|
productivehrs
|
||||||
|
memo
|
||||||
|
jobid
|
||||||
|
flat_rate
|
||||||
|
job {
|
||||||
|
id
|
||||||
|
ro_number
|
||||||
|
}
|
||||||
|
employeeid
|
||||||
|
employee {
|
||||||
|
id
|
||||||
|
employee_number
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fixedperiod: timetickets(
|
||||||
|
where: {
|
||||||
|
date: { _gte: $fixedStart, _lte: $fixedEnd }
|
||||||
|
employeeid: { _eq: $employeeid }
|
||||||
|
}
|
||||||
|
order_by: { date: desc_nulls_first }
|
||||||
|
) {
|
||||||
|
actualhrs
|
||||||
|
ciecacode
|
||||||
|
clockoff
|
||||||
|
clockon
|
||||||
|
cost_center
|
||||||
|
created_at
|
||||||
|
date
|
||||||
|
id
|
||||||
|
rate
|
||||||
|
productivehrs
|
||||||
|
memo
|
||||||
|
jobid
|
||||||
|
flat_rate
|
||||||
|
job {
|
||||||
|
id
|
||||||
|
ro_number
|
||||||
|
}
|
||||||
|
employeeid
|
||||||
|
employee {
|
||||||
|
id
|
||||||
|
employee_number
|
||||||
|
first_name
|
||||||
|
last_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const QUERY_TIME_TICKETS_IN_RANGE_SB = gql`
|
export const QUERY_TIME_TICKETS_IN_RANGE_SB = gql`
|
||||||
query QUERY_TIME_TICKETS_IN_RANGE_SB(
|
query QUERY_TIME_TICKETS_IN_RANGE_SB(
|
||||||
$start: date!
|
$start: date!
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { SyncOutlined, EditFilled } from "@ant-design/icons";
|
import { EditFilled, SyncOutlined } from "@ant-design/icons";
|
||||||
import { Button, Card, Checkbox, Input, Space, Table, Typography } from "antd";
|
import { Button, Card, Checkbox, Input, Space, Table, Typography } from "antd";
|
||||||
|
import axios from "axios";
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React, { 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";
|
||||||
import { Link, useHistory, useLocation } from "react-router-dom";
|
import { Link, useHistory, useLocation } from "react-router-dom";
|
||||||
@@ -11,8 +12,8 @@ import PrintWrapperComponent from "../../components/print-wrapper/print-wrapper.
|
|||||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||||
import { DateFormatter } from "../../utils/DateFormatter";
|
import { DateFormatter } from "../../utils/DateFormatter";
|
||||||
import { alphaSort, dateSort } from "../../utils/sorters";
|
|
||||||
import { TemplateList } from "../../utils/TemplateConstants";
|
import { TemplateList } from "../../utils/TemplateConstants";
|
||||||
|
import { alphaSort, dateSort } from "../../utils/sorters";
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
setPartsOrderContext: (context) =>
|
setPartsOrderContext: (context) =>
|
||||||
@@ -29,34 +30,36 @@ export function BillsListPage({
|
|||||||
setPartsOrderContext,
|
setPartsOrderContext,
|
||||||
setBillEnterContext,
|
setBillEnterContext,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const search = queryString.parse(useLocation().search);
|
||||||
|
const [openSearchResults, setOpenSearchResults] = useState([]);
|
||||||
|
const [searchLoading, setSearchLoading] = useState(false);
|
||||||
|
const { page } = search;
|
||||||
|
const history = useHistory();
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
sortedInfo: {},
|
sortedInfo: {},
|
||||||
|
filteredInfo: { text: "" },
|
||||||
});
|
});
|
||||||
const history = useHistory();
|
|
||||||
const search = queryString.parse(useLocation().search);
|
|
||||||
const { page } = search;
|
|
||||||
const Templates = TemplateList("bill");
|
const Templates = TemplateList("bill");
|
||||||
|
const { t } = useTranslation();
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: t("bills.fields.vendorname"),
|
title: t("bills.fields.vendorname"),
|
||||||
dataIndex: "vendorname",
|
dataIndex: "vendorname",
|
||||||
key: "vendorname",
|
key: "vendorname",
|
||||||
sortObject: (direction) => {
|
// sortObject: (direction) => {
|
||||||
return {
|
// return {
|
||||||
vendor: {
|
// vendor: {
|
||||||
name: direction
|
// name: direction
|
||||||
? direction === "descend"
|
// ? direction === "descend"
|
||||||
? "desc"
|
// ? "desc"
|
||||||
: "asc"
|
// : "asc"
|
||||||
: "desc",
|
// : "desc",
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
},
|
// },
|
||||||
sorter: (a, b) => alphaSort(a.vendor.name, b.vendor.name),
|
// sorter: (a, b) => alphaSort(a.vendor.name, b.vendor.name),
|
||||||
sortOrder:
|
// sortOrder:
|
||||||
state.sortedInfo.columnKey === "vendorname" && state.sortedInfo.order,
|
// state.sortedInfo.columnKey === "vendorname" && state.sortedInfo.order,
|
||||||
render: (text, record) => <span>{record.vendor.name}</span>,
|
render: (text, record) => <span>{record.vendor.name}</span>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -72,20 +75,20 @@ export function BillsListPage({
|
|||||||
title: t("jobs.fields.ro_number"),
|
title: t("jobs.fields.ro_number"),
|
||||||
dataIndex: "ro_number",
|
dataIndex: "ro_number",
|
||||||
key: "ro_number",
|
key: "ro_number",
|
||||||
sortObject: (direction) => {
|
// sortObject: (direction) => {
|
||||||
return {
|
// return {
|
||||||
job: {
|
// job: {
|
||||||
ro_number: direction
|
// ro_number: direction
|
||||||
? direction === "descend"
|
// ? direction === "descend"
|
||||||
? "desc"
|
// ? "desc"
|
||||||
: "asc"
|
// : "asc"
|
||||||
: "desc",
|
// : "desc",
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
},
|
// },
|
||||||
sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
|
// sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
|
||||||
sortOrder:
|
// sortOrder:
|
||||||
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
|
// state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
|
||||||
render: (text, record) =>
|
render: (text, record) =>
|
||||||
record.job && (
|
record.job && (
|
||||||
<Link to={`/manage/jobs/${record.job.id}`}>
|
<Link to={`/manage/jobs/${record.job.id}`}>
|
||||||
@@ -174,7 +177,15 @@ export function BillsListPage({
|
|||||||
// {t("bills.actions.return")}
|
// {t("bills.actions.return")}
|
||||||
// </Button>
|
// </Button>
|
||||||
}
|
}
|
||||||
<BillDeleteButton bill={record} />
|
<BillDeleteButton
|
||||||
|
bill={record}
|
||||||
|
callback={(deletedBillid) => {
|
||||||
|
//Filter out the state and set it again.
|
||||||
|
setOpenSearchResults((currentResults) =>
|
||||||
|
currentResults.filter((bill) => bill.id !== deletedBillid)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
{record.isinhouse && (
|
{record.isinhouse && (
|
||||||
<PrintWrapperComponent
|
<PrintWrapperComponent
|
||||||
templateObject={{
|
templateObject={{
|
||||||
@@ -199,11 +210,32 @@ export function BillsListPage({
|
|||||||
search.sortcolumn = sorter.order ? sorter.columnKey : null;
|
search.sortcolumn = sorter.order ? sorter.columnKey : null;
|
||||||
search.sortorder = sorter.order;
|
search.sortorder = sorter.order;
|
||||||
}
|
}
|
||||||
|
|
||||||
search.sort = JSON.stringify({ [sorter.columnKey]: sorter.order });
|
search.sort = JSON.stringify({ [sorter.columnKey]: sorter.order });
|
||||||
history.push({ search: queryString.stringify(search) });
|
history.push({ search: queryString.stringify(search) });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (search.search && search.search.trim() !== "") {
|
||||||
|
searchBills();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function searchBills(value) {
|
||||||
|
try {
|
||||||
|
setSearchLoading(true);
|
||||||
|
const searchData = await axios.post("/search", {
|
||||||
|
search: value || search.search,
|
||||||
|
index: "bills",
|
||||||
|
});
|
||||||
|
setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source));
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error while fetching search results", error);
|
||||||
|
} finally {
|
||||||
|
setSearchLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
title={t("bills.labels.bills")}
|
title={t("bills.labels.bills")}
|
||||||
@@ -217,6 +249,7 @@ export function BillsListPage({
|
|||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
delete search.search;
|
delete search.search;
|
||||||
|
delete search.page;
|
||||||
history.push({ search: queryString.stringify(search) });
|
history.push({ search: queryString.stringify(search) });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -243,7 +276,10 @@ export function BillsListPage({
|
|||||||
onSearch={(value) => {
|
onSearch={(value) => {
|
||||||
search.search = value;
|
search.search = value;
|
||||||
history.push({ search: queryString.stringify(search) });
|
history.push({ search: queryString.stringify(search) });
|
||||||
|
searchBills(value);
|
||||||
}}
|
}}
|
||||||
|
loading={loading || searchLoading}
|
||||||
|
enterButton
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
@@ -251,19 +287,27 @@ export function BillsListPage({
|
|||||||
<PartsOrderModalContainer />
|
<PartsOrderModalContainer />
|
||||||
|
|
||||||
<Table
|
<Table
|
||||||
loading={loading}
|
loading={loading || searchLoading}
|
||||||
scroll={{
|
// scroll={{
|
||||||
x: "50%", // y: "40rem"
|
// x: "50%", // y: "40rem"
|
||||||
}}
|
// }}
|
||||||
pagination={{
|
scroll={{ x: true }}
|
||||||
position: "top",
|
pagination={
|
||||||
pageSize: 25,
|
search?.search
|
||||||
current: parseInt(page || 1),
|
? {
|
||||||
total: total,
|
pageSize: 25,
|
||||||
}}
|
showSizeChanger: false,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
pageSize: 25,
|
||||||
|
current: parseInt(page || 1),
|
||||||
|
total: total,
|
||||||
|
showSizeChanger: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
dataSource={data}
|
dataSource={search?.search ? openSearchResults : data}
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { useQuery } from "@apollo/client";
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useQuery } from "@apollo/client";
|
|
||||||
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";
|
||||||
@@ -22,7 +22,7 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) {
|
export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const searchParams = queryString.parse(useLocation().search);
|
const searchParams = queryString.parse(useLocation().search);
|
||||||
const { page, sortcolumn, sortorder, search, searchObj } = searchParams;
|
const { page, sortcolumn, sortorder, searchObj } = searchParams;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = t("titles.bills-list");
|
document.title = t("titles.bills-list");
|
||||||
@@ -38,7 +38,6 @@ export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) {
|
|||||||
fetchPolicy: "network-only",
|
fetchPolicy: "network-only",
|
||||||
nextFetchPolicy: "network-only",
|
nextFetchPolicy: "network-only",
|
||||||
variables: {
|
variables: {
|
||||||
search: search || "",
|
|
||||||
offset: page ? (page - 1) * 25 : 0,
|
offset: page ? (page - 1) * 25 : 0,
|
||||||
limit: 25,
|
limit: 25,
|
||||||
order: [
|
order: [
|
||||||
@@ -61,10 +60,10 @@ export function BillsPageContainer({ setBreadcrumbs, setSelectedHeader }) {
|
|||||||
<RbacWrapper action="bills:list">
|
<RbacWrapper action="bills:list">
|
||||||
<div>
|
<div>
|
||||||
<BillsPageComponent
|
<BillsPageComponent
|
||||||
data={data ? data.search_bills : []}
|
data={data ? data.bills : []}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
total={data ? data.search_bills_aggregate.aggregate.count : 0}
|
total={data ? data.bills_aggregate.aggregate.count : 0}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<BillDetailEditContainer />
|
<BillDetailEditContainer />
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
|
|
||||||
export function AllJobs({ setBreadcrumbs, setSelectedHeader }) {
|
export function AllJobs({ setBreadcrumbs, setSelectedHeader }) {
|
||||||
const searchParams = queryString.parse(useLocation().search);
|
const searchParams = queryString.parse(useLocation().search);
|
||||||
const { page, sortcolumn, sortorder, search, statusFilters } = searchParams;
|
const { page, sortcolumn, sortorder, statusFilters } = searchParams;
|
||||||
|
|
||||||
const { loading, error, data, refetch } = useQuery(
|
const { loading, error, data, refetch } = useQuery(
|
||||||
QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED,
|
QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED,
|
||||||
@@ -33,13 +33,12 @@ export function AllJobs({ setBreadcrumbs, setSelectedHeader }) {
|
|||||||
fetchPolicy: "network-only",
|
fetchPolicy: "network-only",
|
||||||
nextFetchPolicy: "network-only",
|
nextFetchPolicy: "network-only",
|
||||||
variables: {
|
variables: {
|
||||||
search: search || "",
|
|
||||||
offset: page ? (page - 1) * 25 : 0,
|
offset: page ? (page - 1) * 25 : 0,
|
||||||
limit: 25,
|
limit: 25,
|
||||||
...(statusFilters ? { statusList: JSON.parse(statusFilters) } : {}),
|
...(statusFilters ? { statusList: JSON.parse(statusFilters) } : {}),
|
||||||
order: [
|
order: [
|
||||||
{
|
{
|
||||||
[sortcolumn || "created_at"]:
|
[sortcolumn || "ro_number"]:
|
||||||
sortorder && sortorder !== "false"
|
sortorder && sortorder !== "false"
|
||||||
? sortorder === "descend"
|
? sortorder === "descend"
|
||||||
? "desc"
|
? "desc"
|
||||||
@@ -67,8 +66,8 @@ export function AllJobs({ setBreadcrumbs, setSelectedHeader }) {
|
|||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
searchParams={searchParams}
|
searchParams={searchParams}
|
||||||
total={data ? data.search_jobs_aggregate.aggregate.count : 0}
|
total={data ? data.jobs_aggregate.aggregate.count : 0}
|
||||||
jobs={data ? data.search_jobs : []}
|
jobs={data ? data.jobs : []}
|
||||||
/>
|
/>
|
||||||
</RbacWrapper>
|
</RbacWrapper>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
|||||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||||
import JobsDocumentsLocalGallery from "../../components/jobs-documents-local-gallery/jobs-documents-local-gallery.container";
|
import JobsDocumentsLocalGallery from "../../components/jobs-documents-local-gallery/jobs-documents-local-gallery.container";
|
||||||
import UndefinedToNull from "../../utils/undefinedtonull";
|
import UndefinedToNull from "../../utils/undefinedtonull";
|
||||||
|
import NoteUpsertModalComponent from "../../components/note-upsert-modal/note-upsert-modal.container";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -97,7 +98,11 @@ export function JobsDetailPage({
|
|||||||
variables: {
|
variables: {
|
||||||
jobId: job.id,
|
jobId: job.id,
|
||||||
job: {
|
job: {
|
||||||
...UndefinedToNull(values, ["alt_transport", "category", "referral_source"]),
|
...UndefinedToNull(values, [
|
||||||
|
"alt_transport",
|
||||||
|
"category",
|
||||||
|
"referral_source",
|
||||||
|
]),
|
||||||
parts_tax_rates: {
|
parts_tax_rates: {
|
||||||
...job.parts_tax_rates,
|
...job.parts_tax_rates,
|
||||||
...values.parts_tax_rates,
|
...values.parts_tax_rates,
|
||||||
@@ -231,6 +236,7 @@ export function JobsDetailPage({
|
|||||||
<ScheduleJobModalContainer />
|
<ScheduleJobModalContainer />
|
||||||
<JobReconciliationModal />
|
<JobReconciliationModal />
|
||||||
<JobLineUpsertModalContainer />
|
<JobLineUpsertModalContainer />
|
||||||
|
<NoteUpsertModalComponent />
|
||||||
<Form
|
<Form
|
||||||
form={form}
|
form={form}
|
||||||
name="JobDetailForm"
|
name="JobDetailForm"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
|
|
||||||
export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
|
export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
|
||||||
const searchParams = queryString.parse(useLocation().search);
|
const searchParams = queryString.parse(useLocation().search);
|
||||||
const { page, sortcolumn, sortorder, search } = searchParams;
|
const { page, sortcolumn, sortorder, searchObj } = searchParams;
|
||||||
|
|
||||||
const { loading, error, data, refetch } = useQuery(
|
const { loading, error, data, refetch } = useQuery(
|
||||||
QUERY_ALL_PAYMENTS_PAGINATED,
|
QUERY_ALL_PAYMENTS_PAGINATED,
|
||||||
@@ -34,11 +34,12 @@ export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
|
|||||||
fetchPolicy: "network-only",
|
fetchPolicy: "network-only",
|
||||||
nextFetchPolicy: "network-only",
|
nextFetchPolicy: "network-only",
|
||||||
variables: {
|
variables: {
|
||||||
search: search || "",
|
|
||||||
offset: page ? (page - 1) * 25 : 0,
|
offset: page ? (page - 1) * 25 : 0,
|
||||||
limit: 25,
|
limit: 25,
|
||||||
order: [
|
order: [
|
||||||
{
|
searchObj
|
||||||
|
? JSON.parse(searchObj)
|
||||||
|
: {
|
||||||
[sortcolumn || "date"]: sortorder
|
[sortcolumn || "date"]: sortorder
|
||||||
? sortorder === "descend"
|
? sortorder === "descend"
|
||||||
? "desc"
|
? "desc"
|
||||||
@@ -66,8 +67,8 @@ export function AllJobs({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
|
|||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
searchParams={searchParams}
|
searchParams={searchParams}
|
||||||
total={data ? data.search_payments_aggregate.aggregate.count : 0}
|
total={data ? data.payments_aggregate.aggregate.count : 0}
|
||||||
payments={data ? data.search_payments : []}
|
payments={data ? data.payments : []}
|
||||||
/>
|
/>
|
||||||
</RbacWrapper>
|
</RbacWrapper>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ import { Divider } from "antd";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import TechClockInFormContainer from "../../components/tech-job-clock-in-form/tech-job-clock-in-form.container";
|
import TechClockInFormContainer from "../../components/tech-job-clock-in-form/tech-job-clock-in-form.container";
|
||||||
import TechClockedInList from "../../components/tech-job-clocked-in-list/tech-job-clocked-in-list.component";
|
import TechClockedInList from "../../components/tech-job-clocked-in-list/tech-job-clocked-in-list.component";
|
||||||
|
import TechJobStatistics from "../../components/tech-job-statistics/tech-job-statistics.component";
|
||||||
|
|
||||||
export default function TechClockComponent() {
|
export default function TechClockComponent() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<TechJobStatistics />
|
||||||
<TechClockInFormContainer />
|
<TechClockInFormContainer />
|
||||||
<Divider />
|
<Divider />
|
||||||
<TechClockedInList />
|
<TechClockedInList />
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
.tech-content-container {
|
.tech-content-container {
|
||||||
overflow-y: auto;
|
overflow-y: visible;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tech-layout-container {
|
.tech-layout-container {
|
||||||
height: 100vh;
|
position: relative;
|
||||||
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"scheduledfor": "Scheduled appointment for: ",
|
"scheduledfor": "Scheduled appointment for: ",
|
||||||
"severalerrorsfound": "Several jobs have issues which may prevent accurate smart scheduling. Click to expand.",
|
"severalerrorsfound": "Several jobs have issues which may prevent accurate smart scheduling. Click to expand.",
|
||||||
"smartscheduling": "Smart Scheduling",
|
"smartscheduling": "Smart Scheduling",
|
||||||
|
"smspaymentreminder": "",
|
||||||
"suggesteddates": "Suggested Dates"
|
"suggesteddates": "Suggested Dates"
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -103,6 +104,7 @@
|
|||||||
"admin_jobunvoid": "ADMIN: Job has been unvoided.",
|
"admin_jobunvoid": "ADMIN: Job has been unvoided.",
|
||||||
"billposted": "Bill with invoice number {{invoice_number}} posted.",
|
"billposted": "Bill with invoice number {{invoice_number}} posted.",
|
||||||
"billupdated": "Bill with invoice number {{invoice_number}} updated.",
|
"billupdated": "Bill with invoice number {{invoice_number}} updated.",
|
||||||
|
"failedpayment": "",
|
||||||
"jobassignmentchange": "Employee {{name}} assigned to {{operation}}",
|
"jobassignmentchange": "Employee {{name}} assigned to {{operation}}",
|
||||||
"jobassignmentremoved": "Employee assignment removed for {{operation}}",
|
"jobassignmentremoved": "Employee assignment removed for {{operation}}",
|
||||||
"jobchecklist": "Checklist type \"{{type}}\" completed. In production set to {{inproduction}}. Status set to {{status}}.",
|
"jobchecklist": "Checklist type \"{{type}}\" completed. In production set to {{inproduction}}. Status set to {{status}}.",
|
||||||
@@ -227,6 +229,7 @@
|
|||||||
},
|
},
|
||||||
"bodyshop": {
|
"bodyshop": {
|
||||||
"actions": {
|
"actions": {
|
||||||
|
"add_task_preset": "",
|
||||||
"addapptcolor": "Add Appointment Color",
|
"addapptcolor": "Add Appointment Color",
|
||||||
"addbucket": "Add Definition",
|
"addbucket": "Add Definition",
|
||||||
"addpartslocation": "Add Parts Location",
|
"addpartslocation": "Add Parts Location",
|
||||||
@@ -339,6 +342,12 @@
|
|||||||
},
|
},
|
||||||
"md_payment_types": "Payment Types",
|
"md_payment_types": "Payment Types",
|
||||||
"md_referral_sources": "Referral Sources",
|
"md_referral_sources": "Referral Sources",
|
||||||
|
"md_tasks_presets": {
|
||||||
|
"hourstype": "",
|
||||||
|
"memo": "",
|
||||||
|
"name": "",
|
||||||
|
"percent": ""
|
||||||
|
},
|
||||||
"messaginglabel": "Messaging Preset Label",
|
"messaginglabel": "Messaging Preset Label",
|
||||||
"messagingtext": "Messaging Preset Text",
|
"messagingtext": "Messaging Preset Text",
|
||||||
"noteslabel": "Note Label",
|
"noteslabel": "Note Label",
|
||||||
@@ -374,6 +383,9 @@
|
|||||||
"export": "CSI -> Export",
|
"export": "CSI -> Export",
|
||||||
"page": "CSI -> Page"
|
"page": "CSI -> Page"
|
||||||
},
|
},
|
||||||
|
"employee_teams": {
|
||||||
|
"page": ""
|
||||||
|
},
|
||||||
"employees": {
|
"employees": {
|
||||||
"page": "Employees -> List"
|
"page": "Employees -> List"
|
||||||
},
|
},
|
||||||
@@ -432,10 +444,15 @@
|
|||||||
},
|
},
|
||||||
"timetickets": {
|
"timetickets": {
|
||||||
"edit": "Time Tickets -> Edit",
|
"edit": "Time Tickets -> Edit",
|
||||||
|
"editcommitted": "",
|
||||||
"enter": "Time Tickets -> Enter",
|
"enter": "Time Tickets -> Enter",
|
||||||
"list": "Time Tickets -> List",
|
"list": "Time Tickets -> List",
|
||||||
"shiftedit": "Time Tickets -> Shift Edit"
|
"shiftedit": "Time Tickets -> Shift Edit"
|
||||||
},
|
},
|
||||||
|
"ttapprovals": {
|
||||||
|
"approve": "",
|
||||||
|
"view": ""
|
||||||
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"editaccess": "Users -> Edit access"
|
"editaccess": "Users -> Edit access"
|
||||||
}
|
}
|
||||||
@@ -453,6 +470,8 @@
|
|||||||
"federal_tax": "Federal Tax",
|
"federal_tax": "Federal Tax",
|
||||||
"federal_tax_itc": "Federal Tax Credit",
|
"federal_tax_itc": "Federal Tax Credit",
|
||||||
"gst_override": "GST Override Account #",
|
"gst_override": "GST Override Account #",
|
||||||
|
"invoiceexemptcode": "",
|
||||||
|
"itemexemptcode": "",
|
||||||
"la1": "LA1",
|
"la1": "LA1",
|
||||||
"la2": "LA2",
|
"la2": "LA2",
|
||||||
"la3": "LA3",
|
"la3": "LA3",
|
||||||
@@ -504,6 +523,7 @@
|
|||||||
"dailyhrslimit": "Daily Incoming Hours Limit"
|
"dailyhrslimit": "Daily Incoming Hours Limit"
|
||||||
},
|
},
|
||||||
"ssbuckets": {
|
"ssbuckets": {
|
||||||
|
"color": "Job Color",
|
||||||
"gte": "Greater Than/Equal to (hrs)",
|
"gte": "Greater Than/Equal to (hrs)",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
"label": "Label",
|
"label": "Label",
|
||||||
@@ -541,7 +561,9 @@
|
|||||||
"target_touchtime": "Target Touch Time",
|
"target_touchtime": "Target Touch Time",
|
||||||
"timezone": "Timezone",
|
"timezone": "Timezone",
|
||||||
"tt_allow_post_to_invoiced": "Allow Time Tickets to be posted to Invoiced & Exported Jobs",
|
"tt_allow_post_to_invoiced": "Allow Time Tickets to be posted to Invoiced & Exported Jobs",
|
||||||
|
"tt_enforce_hours_for_tech_console": "Restrict Claimable hours from Tech Console",
|
||||||
"use_fippa": "Use FIPPA for Names on Generated Documents?",
|
"use_fippa": "Use FIPPA for Names on Generated Documents?",
|
||||||
|
"use_paint_scale_data": "Use Paint Scale Data for Job Costing?",
|
||||||
"uselocalmediaserver": "Use Local Media Server?",
|
"uselocalmediaserver": "Use Local Media Server?",
|
||||||
"website": "Website",
|
"website": "Website",
|
||||||
"zip_post": "Zip/Postal Code"
|
"zip_post": "Zip/Postal Code"
|
||||||
@@ -572,6 +594,7 @@
|
|||||||
"title": "DMS"
|
"title": "DMS"
|
||||||
},
|
},
|
||||||
"emaillater": "Email Later",
|
"emaillater": "Email Later",
|
||||||
|
"employee_teams": "",
|
||||||
"employees": "Employees",
|
"employees": "Employees",
|
||||||
"estimators": "Estimators",
|
"estimators": "Estimators",
|
||||||
"filehandlers": "File Handlers",
|
"filehandlers": "File Handlers",
|
||||||
@@ -580,6 +603,7 @@
|
|||||||
"jobstatuses": "Job Statuses",
|
"jobstatuses": "Job Statuses",
|
||||||
"laborrates": "Labor Rates",
|
"laborrates": "Labor Rates",
|
||||||
"licensing": "Licensing",
|
"licensing": "Licensing",
|
||||||
|
"md_tasks_presets": "",
|
||||||
"md_to_emails": "Preset To Emails",
|
"md_to_emails": "Preset To Emails",
|
||||||
"md_to_emails_emails": "Emails",
|
"md_to_emails_emails": "Emails",
|
||||||
"messagingpresets": "Messaging Presets",
|
"messagingpresets": "Messaging Presets",
|
||||||
@@ -606,6 +630,7 @@
|
|||||||
"speedprint": "Speed Print Configuration",
|
"speedprint": "Speed Print Configuration",
|
||||||
"ssbuckets": "Job Size Definitions",
|
"ssbuckets": "Job Size Definitions",
|
||||||
"systemsettings": "System Settings",
|
"systemsettings": "System Settings",
|
||||||
|
"task-presets": "",
|
||||||
"workingdays": "Working Days"
|
"workingdays": "Working Days"
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -905,6 +930,18 @@
|
|||||||
"sent": "Email sent successfully."
|
"sent": "Email sent successfully."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"employee_teams": {
|
||||||
|
"actions": {
|
||||||
|
"new": "",
|
||||||
|
"newmember": ""
|
||||||
|
},
|
||||||
|
"fields": {
|
||||||
|
"active": "",
|
||||||
|
"employeeid": "",
|
||||||
|
"name": "",
|
||||||
|
"percentage": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"employees": {
|
"employees": {
|
||||||
"actions": {
|
"actions": {
|
||||||
"addvacation": "Add Vacation",
|
"addvacation": "Add Vacation",
|
||||||
@@ -1014,6 +1051,7 @@
|
|||||||
"created_at": "Created At",
|
"created_at": "Created At",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
"errors": "Errors",
|
"errors": "Errors",
|
||||||
|
"excel": "Excel",
|
||||||
"exceptiontitle": "An error has occurred.",
|
"exceptiontitle": "An error has occurred.",
|
||||||
"friday": "Friday",
|
"friday": "Friday",
|
||||||
"globalsearch": "Global Search",
|
"globalsearch": "Global Search",
|
||||||
@@ -1063,6 +1101,7 @@
|
|||||||
"sunday": "Sunday",
|
"sunday": "Sunday",
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
"thursday": "Thursday",
|
"thursday": "Thursday",
|
||||||
|
"total": "Total",
|
||||||
"totals": "Totals",
|
"totals": "Totals",
|
||||||
"tuesday": "Tuesday",
|
"tuesday": "Tuesday",
|
||||||
"unknown": "Unknown",
|
"unknown": "Unknown",
|
||||||
@@ -1142,6 +1181,30 @@
|
|||||||
"updated": "Inventory line updated."
|
"updated": "Inventory line updated."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"job_payments": {
|
||||||
|
"buttons": {
|
||||||
|
"goback": "",
|
||||||
|
"proceedtopayment": "",
|
||||||
|
"refundpayment": ""
|
||||||
|
},
|
||||||
|
"notifications": {
|
||||||
|
"error": {
|
||||||
|
"description": "",
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"titles": {
|
||||||
|
"amount": "",
|
||||||
|
"dateOfPayment": "",
|
||||||
|
"descriptions": "",
|
||||||
|
"payer": "",
|
||||||
|
"payername": "",
|
||||||
|
"paymentid": "",
|
||||||
|
"paymenttype": "",
|
||||||
|
"refundamount": "",
|
||||||
|
"transactionid": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"joblines": {
|
"joblines": {
|
||||||
"actions": {
|
"actions": {
|
||||||
"converttolabor": "Convert amount to Labor.",
|
"converttolabor": "Convert amount to Labor.",
|
||||||
@@ -1374,7 +1437,7 @@
|
|||||||
"ded_amt": "Deductible",
|
"ded_amt": "Deductible",
|
||||||
"ded_note": "Deductible Note",
|
"ded_note": "Deductible Note",
|
||||||
"ded_status": "Deductible Status",
|
"ded_status": "Deductible Status",
|
||||||
"depreciation_taxes": "Depreciation/Taxes",
|
"depreciation_taxes": "Betterment/Depreciation/Taxes",
|
||||||
"dms": {
|
"dms": {
|
||||||
"address": "Customer Address",
|
"address": "Customer Address",
|
||||||
"amount": "Amount",
|
"amount": "Amount",
|
||||||
@@ -1574,6 +1637,7 @@
|
|||||||
"scheddates": "Schedule Dates"
|
"scheddates": "Schedule Dates"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
|
"act_price_ppc": "",
|
||||||
"actual_completion_inferred": "$t(jobs.fields.actual_completion) inferred using $t(jobs.fields.scheduled_completion).",
|
"actual_completion_inferred": "$t(jobs.fields.actual_completion) inferred using $t(jobs.fields.scheduled_completion).",
|
||||||
"actual_delivery_inferred": "$t(jobs.fields.actual_delivery) inferred using $t(jobs.fields.scheduled_delivery).",
|
"actual_delivery_inferred": "$t(jobs.fields.actual_delivery) inferred using $t(jobs.fields.scheduled_delivery).",
|
||||||
"actual_in_inferred": "$t(jobs.fields.actual_in) inferred using $t(jobs.fields.scheduled_in).",
|
"actual_in_inferred": "$t(jobs.fields.actual_in) inferred using $t(jobs.fields.scheduled_in).",
|
||||||
@@ -1710,6 +1774,7 @@
|
|||||||
"partstotal": "This is the total of all parts and sublet amounts on the vehicle (some of these may require an in-house invoice).<br/>\nItems such as shop and paint materials, labor online lines, etc. are not included in this total.",
|
"partstotal": "This is the total of all parts and sublet amounts on the vehicle (some of these may require an in-house invoice).<br/>\nItems such as shop and paint materials, labor online lines, etc. are not included in this total.",
|
||||||
"totalreturns": "The total <b>retail</b> amount of returns created for this job."
|
"totalreturns": "The total <b>retail</b> amount of returns created for this job."
|
||||||
},
|
},
|
||||||
|
"ppc": "",
|
||||||
"profileadjustments": "",
|
"profileadjustments": "",
|
||||||
"prt_dsmk_total": "Line Item Adjustment",
|
"prt_dsmk_total": "Line Item Adjustment",
|
||||||
"rates": "Rates",
|
"rates": "Rates",
|
||||||
@@ -1850,6 +1915,7 @@
|
|||||||
"customers": "Customers",
|
"customers": "Customers",
|
||||||
"dashboard": "Dashboard",
|
"dashboard": "Dashboard",
|
||||||
"enterbills": "Enter Bills",
|
"enterbills": "Enter Bills",
|
||||||
|
"entercardpayment": "",
|
||||||
"enterpayment": "Enter Payments",
|
"enterpayment": "Enter Payments",
|
||||||
"entertimeticket": "Enter Time Tickets",
|
"entertimeticket": "Enter Time Tickets",
|
||||||
"export": "Export",
|
"export": "Export",
|
||||||
@@ -1861,6 +1927,7 @@
|
|||||||
"newjob": "Create New Job",
|
"newjob": "Create New Job",
|
||||||
"owners": "Owners",
|
"owners": "Owners",
|
||||||
"parts-queue": "Parts Queue",
|
"parts-queue": "Parts Queue",
|
||||||
|
"paymentremindersms": "",
|
||||||
"phonebook": "Phonebook",
|
"phonebook": "Phonebook",
|
||||||
"productionboard": "Production Board - Visual",
|
"productionboard": "Production Board - Visual",
|
||||||
"productionlist": "Production Board - List",
|
"productionlist": "Production Board - List",
|
||||||
@@ -1886,6 +1953,7 @@
|
|||||||
"shop_vendors": "Vendors",
|
"shop_vendors": "Vendors",
|
||||||
"temporarydocs": "Temporary Documents",
|
"temporarydocs": "Temporary Documents",
|
||||||
"timetickets": "Time Tickets",
|
"timetickets": "Time Tickets",
|
||||||
|
"ttapprovals": "",
|
||||||
"vehicles": "Vehicles"
|
"vehicles": "Vehicles"
|
||||||
},
|
},
|
||||||
"jobsactions": {
|
"jobsactions": {
|
||||||
@@ -1958,7 +2026,8 @@
|
|||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
"deletenote": "Delete Note",
|
"deletenote": "Delete Note",
|
||||||
"edit": "Edit Note",
|
"edit": "Edit Note",
|
||||||
"new": "New Note"
|
"new": "New Note",
|
||||||
|
"savetojobnotes": "Save to Job Notes"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"inserting": "Error inserting note. {{error}}"
|
"inserting": "Error inserting note. {{error}}"
|
||||||
@@ -1968,6 +2037,16 @@
|
|||||||
"critical": "Critical",
|
"critical": "Critical",
|
||||||
"private": "Private",
|
"private": "Private",
|
||||||
"text": "Contents",
|
"text": "Contents",
|
||||||
|
"type": "Type",
|
||||||
|
"types": {
|
||||||
|
"customer": "Customer",
|
||||||
|
"general": "General",
|
||||||
|
"office": "Office",
|
||||||
|
"paint": "Paint",
|
||||||
|
"parts": "Parts",
|
||||||
|
"shop": "Shop",
|
||||||
|
"supplement": "Supplement"
|
||||||
|
},
|
||||||
"updatedat": "Updated At"
|
"updatedat": "Updated At"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
@@ -2224,6 +2303,7 @@
|
|||||||
"csi_invitation": "CSI Invitation",
|
"csi_invitation": "CSI Invitation",
|
||||||
"csi_invitation_action": "CSI Invite",
|
"csi_invitation_action": "CSI Invite",
|
||||||
"diagnostic_authorization": "Diagnostic Authorization",
|
"diagnostic_authorization": "Diagnostic Authorization",
|
||||||
|
"dms_posting_sheet": "DMS Posting Sheet",
|
||||||
"envelope_return_address": "#10 Envelope Return Address Label",
|
"envelope_return_address": "#10 Envelope Return Address Label",
|
||||||
"estimate": "Estimate Only",
|
"estimate": "Estimate Only",
|
||||||
"estimate_detail": "Estimate Details",
|
"estimate_detail": "Estimate Details",
|
||||||
@@ -2236,7 +2316,7 @@
|
|||||||
"folder_label_multiple": "Folder Label - Multi",
|
"folder_label_multiple": "Folder Label - Multi",
|
||||||
"glass_express_checklist": "Glass Express Checklist",
|
"glass_express_checklist": "Glass Express Checklist",
|
||||||
"guarantee": "Repair Guarantee",
|
"guarantee": "Repair Guarantee",
|
||||||
"individual_job_note": "Job Note RO # {{ro_number}}",
|
"individual_job_note": "RO Job Note",
|
||||||
"invoice_customer_payable": "Invoice (Customer Payable)",
|
"invoice_customer_payable": "Invoice (Customer Payable)",
|
||||||
"invoice_total_payable": "Invoice (Total Payable)",
|
"invoice_total_payable": "Invoice (Total Payable)",
|
||||||
"iou_form": "IOU Form",
|
"iou_form": "IOU Form",
|
||||||
@@ -2314,6 +2394,7 @@
|
|||||||
},
|
},
|
||||||
"subjects": {
|
"subjects": {
|
||||||
"jobs": {
|
"jobs": {
|
||||||
|
"individual_job_note": "Job Note RO: {{ro_number}}",
|
||||||
"parts_order": "Parts Order PO: {{ro_number}} - {{name}}",
|
"parts_order": "Parts Order PO: {{ro_number}} - {{name}}",
|
||||||
"sublet_order": "Sublet Order PO: {{ro_number}} - {{name}}"
|
"sublet_order": "Sublet Order PO: {{ro_number}} - {{name}}"
|
||||||
}
|
}
|
||||||
@@ -2357,6 +2438,7 @@
|
|||||||
"qbo_usa": "QBO USA"
|
"qbo_usa": "QBO USA"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cardcolor": "Card Colors",
|
||||||
"cardsettings": "Card Settings",
|
"cardsettings": "Card Settings",
|
||||||
"clm_no": "Claim Number",
|
"clm_no": "Claim Number",
|
||||||
"comment": "Comment",
|
"comment": "Comment",
|
||||||
@@ -2367,6 +2449,7 @@
|
|||||||
"ins_co_nm": "Insurance Company Name",
|
"ins_co_nm": "Insurance Company Name",
|
||||||
"jobdetail": "Job Details",
|
"jobdetail": "Job Details",
|
||||||
"laborhrs": "Labor Hours",
|
"laborhrs": "Labor Hours",
|
||||||
|
"legend": "Legend:",
|
||||||
"note": "Production Note",
|
"note": "Production Note",
|
||||||
"ownr_nm": "Owner Name",
|
"ownr_nm": "Owner Name",
|
||||||
"paintpriority": "P/P",
|
"paintpriority": "P/P",
|
||||||
@@ -2442,6 +2525,8 @@
|
|||||||
"export_payables": "Export Log - Payables",
|
"export_payables": "Export Log - Payables",
|
||||||
"export_payments": "Export Log - Payments",
|
"export_payments": "Export Log - Payments",
|
||||||
"export_receivables": "Export Log - Receivables",
|
"export_receivables": "Export Log - Receivables",
|
||||||
|
"exported_gsr_by_ro": "Exported Gross Sales - Excel",
|
||||||
|
"exported_gsr_by_ro_labor": "Exported Gross Sales (Labor) - Excel",
|
||||||
"gsr_by_atp": "",
|
"gsr_by_atp": "",
|
||||||
"gsr_by_ats": "Gross Sales by ATS",
|
"gsr_by_ats": "Gross Sales by ATS",
|
||||||
"gsr_by_category": "Gross Sales by Category",
|
"gsr_by_category": "Gross Sales by Category",
|
||||||
@@ -2603,6 +2688,7 @@
|
|||||||
},
|
},
|
||||||
"timetickets": {
|
"timetickets": {
|
||||||
"actions": {
|
"actions": {
|
||||||
|
"claimtasks": "",
|
||||||
"clockin": "Clock In",
|
"clockin": "Clock In",
|
||||||
"clockout": "Clock Out",
|
"clockout": "Clock Out",
|
||||||
"enter": "Enter New Time Ticket",
|
"enter": "Enter New Time Ticket",
|
||||||
@@ -2623,10 +2709,12 @@
|
|||||||
"clockhours": "Clock Hours",
|
"clockhours": "Clock Hours",
|
||||||
"clockoff": "Clock Off",
|
"clockoff": "Clock Off",
|
||||||
"clockon": "Clocked In",
|
"clockon": "Clocked In",
|
||||||
|
"committed": "",
|
||||||
"cost_center": "Cost Center",
|
"cost_center": "Cost Center",
|
||||||
"date": "Ticket Date",
|
"date": "Ticket Date",
|
||||||
"efficiency": "Efficiency",
|
"efficiency": "Efficiency",
|
||||||
"employee": "Employee",
|
"employee": "Employee",
|
||||||
|
"employee_team": "",
|
||||||
"flat_rate": "Flat Rate?",
|
"flat_rate": "Flat Rate?",
|
||||||
"memo": "Memo",
|
"memo": "Memo",
|
||||||
"productivehrs": "Productive Hours",
|
"productivehrs": "Productive Hours",
|
||||||
@@ -2661,7 +2749,8 @@
|
|||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"clockoffmustbeafterclockon": "Clock off time must be the same or after clock in time.",
|
"clockoffmustbeafterclockon": "Clock off time must be the same or after clock in time.",
|
||||||
"clockoffwithoutclockon": "Clock off time cannot be set without a clock in time."
|
"clockoffwithoutclockon": "Clock off time cannot be set without a clock in time.",
|
||||||
|
"hoursenteredmorethanavailable": "The number of hours entered is more than what is available for this cost center."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
@@ -2712,6 +2801,7 @@
|
|||||||
"shop-vendors": "Vendors",
|
"shop-vendors": "Vendors",
|
||||||
"temporarydocs": "Temporary Documents",
|
"temporarydocs": "Temporary Documents",
|
||||||
"timetickets": "Time Tickets",
|
"timetickets": "Time Tickets",
|
||||||
|
"ttapprovals": "",
|
||||||
"vehicle-details": "Vehicle: {{vehicle}}",
|
"vehicle-details": "Vehicle: {{vehicle}}",
|
||||||
"vehicles": "Vehicles"
|
"vehicles": "Vehicles"
|
||||||
},
|
},
|
||||||
@@ -2757,9 +2847,15 @@
|
|||||||
"shop_vendors": "Vendors | $t(titles.app)",
|
"shop_vendors": "Vendors | $t(titles.app)",
|
||||||
"temporarydocs": "Temporary Documents | $t(titles.app)",
|
"temporarydocs": "Temporary Documents | $t(titles.app)",
|
||||||
"timetickets": "Time Tickets | $t(titles.app)",
|
"timetickets": "Time Tickets | $t(titles.app)",
|
||||||
|
"ttapprovals": "",
|
||||||
"vehicledetail": "Vehicle Details {{vehicle}} | $t(titles.app)",
|
"vehicledetail": "Vehicle Details {{vehicle}} | $t(titles.app)",
|
||||||
"vehicles": "All Vehicles | $t(titles.app)"
|
"vehicles": "All Vehicles | $t(titles.app)"
|
||||||
},
|
},
|
||||||
|
"tt_approvals": {
|
||||||
|
"actions": {
|
||||||
|
"approveselected": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"actions": {
|
"actions": {
|
||||||
"changepassword": "Change Password",
|
"changepassword": "Change Password",
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"scheduledfor": "Cita programada para:",
|
"scheduledfor": "Cita programada para:",
|
||||||
"severalerrorsfound": "",
|
"severalerrorsfound": "",
|
||||||
"smartscheduling": "",
|
"smartscheduling": "",
|
||||||
|
"smspaymentreminder": "",
|
||||||
"suggesteddates": ""
|
"suggesteddates": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -103,6 +104,7 @@
|
|||||||
"admin_jobunvoid": "",
|
"admin_jobunvoid": "",
|
||||||
"billposted": "",
|
"billposted": "",
|
||||||
"billupdated": "",
|
"billupdated": "",
|
||||||
|
"failedpayment": "",
|
||||||
"jobassignmentchange": "",
|
"jobassignmentchange": "",
|
||||||
"jobassignmentremoved": "",
|
"jobassignmentremoved": "",
|
||||||
"jobchecklist": "",
|
"jobchecklist": "",
|
||||||
@@ -227,6 +229,7 @@
|
|||||||
},
|
},
|
||||||
"bodyshop": {
|
"bodyshop": {
|
||||||
"actions": {
|
"actions": {
|
||||||
|
"add_task_preset": "",
|
||||||
"addapptcolor": "",
|
"addapptcolor": "",
|
||||||
"addbucket": "",
|
"addbucket": "",
|
||||||
"addpartslocation": "",
|
"addpartslocation": "",
|
||||||
@@ -339,6 +342,12 @@
|
|||||||
},
|
},
|
||||||
"md_payment_types": "",
|
"md_payment_types": "",
|
||||||
"md_referral_sources": "",
|
"md_referral_sources": "",
|
||||||
|
"md_tasks_presets": {
|
||||||
|
"hourstype": "",
|
||||||
|
"memo": "",
|
||||||
|
"name": "",
|
||||||
|
"percent": ""
|
||||||
|
},
|
||||||
"messaginglabel": "",
|
"messaginglabel": "",
|
||||||
"messagingtext": "",
|
"messagingtext": "",
|
||||||
"noteslabel": "",
|
"noteslabel": "",
|
||||||
@@ -374,6 +383,9 @@
|
|||||||
"export": "",
|
"export": "",
|
||||||
"page": ""
|
"page": ""
|
||||||
},
|
},
|
||||||
|
"employee_teams": {
|
||||||
|
"page": ""
|
||||||
|
},
|
||||||
"employees": {
|
"employees": {
|
||||||
"page": ""
|
"page": ""
|
||||||
},
|
},
|
||||||
@@ -432,10 +444,15 @@
|
|||||||
},
|
},
|
||||||
"timetickets": {
|
"timetickets": {
|
||||||
"edit": "",
|
"edit": "",
|
||||||
|
"editcommitted": "",
|
||||||
"enter": "",
|
"enter": "",
|
||||||
"list": "",
|
"list": "",
|
||||||
"shiftedit": ""
|
"shiftedit": ""
|
||||||
},
|
},
|
||||||
|
"ttapprovals": {
|
||||||
|
"approve": "",
|
||||||
|
"view": ""
|
||||||
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"editaccess": ""
|
"editaccess": ""
|
||||||
}
|
}
|
||||||
@@ -453,6 +470,8 @@
|
|||||||
"federal_tax": "",
|
"federal_tax": "",
|
||||||
"federal_tax_itc": "",
|
"federal_tax_itc": "",
|
||||||
"gst_override": "",
|
"gst_override": "",
|
||||||
|
"invoiceexemptcode": "",
|
||||||
|
"itemexemptcode": "",
|
||||||
"la1": "",
|
"la1": "",
|
||||||
"la2": "",
|
"la2": "",
|
||||||
"la3": "",
|
"la3": "",
|
||||||
@@ -504,6 +523,7 @@
|
|||||||
"dailyhrslimit": ""
|
"dailyhrslimit": ""
|
||||||
},
|
},
|
||||||
"ssbuckets": {
|
"ssbuckets": {
|
||||||
|
"color": "",
|
||||||
"gte": "",
|
"gte": "",
|
||||||
"id": "",
|
"id": "",
|
||||||
"label": "",
|
"label": "",
|
||||||
@@ -541,7 +561,9 @@
|
|||||||
"target_touchtime": "",
|
"target_touchtime": "",
|
||||||
"timezone": "",
|
"timezone": "",
|
||||||
"tt_allow_post_to_invoiced": "",
|
"tt_allow_post_to_invoiced": "",
|
||||||
|
"tt_enforce_hours_for_tech_console": "",
|
||||||
"use_fippa": "",
|
"use_fippa": "",
|
||||||
|
"use_paint_scale_data": "",
|
||||||
"uselocalmediaserver": "",
|
"uselocalmediaserver": "",
|
||||||
"website": "",
|
"website": "",
|
||||||
"zip_post": ""
|
"zip_post": ""
|
||||||
@@ -572,6 +594,7 @@
|
|||||||
"title": ""
|
"title": ""
|
||||||
},
|
},
|
||||||
"emaillater": "",
|
"emaillater": "",
|
||||||
|
"employee_teams": "",
|
||||||
"employees": "",
|
"employees": "",
|
||||||
"estimators": "",
|
"estimators": "",
|
||||||
"filehandlers": "",
|
"filehandlers": "",
|
||||||
@@ -580,6 +603,7 @@
|
|||||||
"jobstatuses": "",
|
"jobstatuses": "",
|
||||||
"laborrates": "",
|
"laborrates": "",
|
||||||
"licensing": "",
|
"licensing": "",
|
||||||
|
"md_tasks_presets": "",
|
||||||
"md_to_emails": "",
|
"md_to_emails": "",
|
||||||
"md_to_emails_emails": "",
|
"md_to_emails_emails": "",
|
||||||
"messagingpresets": "",
|
"messagingpresets": "",
|
||||||
@@ -606,6 +630,7 @@
|
|||||||
"speedprint": "",
|
"speedprint": "",
|
||||||
"ssbuckets": "",
|
"ssbuckets": "",
|
||||||
"systemsettings": "",
|
"systemsettings": "",
|
||||||
|
"task-presets": "",
|
||||||
"workingdays": ""
|
"workingdays": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -905,6 +930,18 @@
|
|||||||
"sent": "Correo electrónico enviado con éxito."
|
"sent": "Correo electrónico enviado con éxito."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"employee_teams": {
|
||||||
|
"actions": {
|
||||||
|
"new": "",
|
||||||
|
"newmember": ""
|
||||||
|
},
|
||||||
|
"fields": {
|
||||||
|
"active": "",
|
||||||
|
"employeeid": "",
|
||||||
|
"name": "",
|
||||||
|
"percentage": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"employees": {
|
"employees": {
|
||||||
"actions": {
|
"actions": {
|
||||||
"addvacation": "",
|
"addvacation": "",
|
||||||
@@ -1014,6 +1051,7 @@
|
|||||||
"created_at": "",
|
"created_at": "",
|
||||||
"email": "",
|
"email": "",
|
||||||
"errors": "",
|
"errors": "",
|
||||||
|
"excel": "",
|
||||||
"exceptiontitle": "",
|
"exceptiontitle": "",
|
||||||
"friday": "",
|
"friday": "",
|
||||||
"globalsearch": "",
|
"globalsearch": "",
|
||||||
@@ -1063,6 +1101,7 @@
|
|||||||
"sunday": "",
|
"sunday": "",
|
||||||
"text": "",
|
"text": "",
|
||||||
"thursday": "",
|
"thursday": "",
|
||||||
|
"total": "",
|
||||||
"totals": "",
|
"totals": "",
|
||||||
"tuesday": "",
|
"tuesday": "",
|
||||||
"unknown": "Desconocido",
|
"unknown": "Desconocido",
|
||||||
@@ -1142,6 +1181,30 @@
|
|||||||
"updated": ""
|
"updated": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"job_payments": {
|
||||||
|
"buttons": {
|
||||||
|
"goback": "",
|
||||||
|
"proceedtopayment": "",
|
||||||
|
"refundpayment": ""
|
||||||
|
},
|
||||||
|
"notifications": {
|
||||||
|
"error": {
|
||||||
|
"description": "",
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"titles": {
|
||||||
|
"amount": "",
|
||||||
|
"dateOfPayment": "",
|
||||||
|
"descriptions": "",
|
||||||
|
"payer": "",
|
||||||
|
"payername": "",
|
||||||
|
"paymentid": "",
|
||||||
|
"paymenttype": "",
|
||||||
|
"refundamount": "",
|
||||||
|
"transactionid": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"joblines": {
|
"joblines": {
|
||||||
"actions": {
|
"actions": {
|
||||||
"converttolabor": "",
|
"converttolabor": "",
|
||||||
@@ -1574,6 +1637,7 @@
|
|||||||
"scheddates": ""
|
"scheddates": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
|
"act_price_ppc": "",
|
||||||
"actual_completion_inferred": "",
|
"actual_completion_inferred": "",
|
||||||
"actual_delivery_inferred": "",
|
"actual_delivery_inferred": "",
|
||||||
"actual_in_inferred": "",
|
"actual_in_inferred": "",
|
||||||
@@ -1710,6 +1774,7 @@
|
|||||||
"partstotal": "",
|
"partstotal": "",
|
||||||
"totalreturns": ""
|
"totalreturns": ""
|
||||||
},
|
},
|
||||||
|
"ppc": "",
|
||||||
"profileadjustments": "",
|
"profileadjustments": "",
|
||||||
"prt_dsmk_total": "",
|
"prt_dsmk_total": "",
|
||||||
"rates": "Tarifas",
|
"rates": "Tarifas",
|
||||||
@@ -1850,6 +1915,7 @@
|
|||||||
"customers": "Clientes",
|
"customers": "Clientes",
|
||||||
"dashboard": "",
|
"dashboard": "",
|
||||||
"enterbills": "",
|
"enterbills": "",
|
||||||
|
"entercardpayment": "",
|
||||||
"enterpayment": "",
|
"enterpayment": "",
|
||||||
"entertimeticket": "",
|
"entertimeticket": "",
|
||||||
"export": "",
|
"export": "",
|
||||||
@@ -1861,6 +1927,7 @@
|
|||||||
"newjob": "",
|
"newjob": "",
|
||||||
"owners": "propietarios",
|
"owners": "propietarios",
|
||||||
"parts-queue": "",
|
"parts-queue": "",
|
||||||
|
"paymentremindersms": "",
|
||||||
"phonebook": "",
|
"phonebook": "",
|
||||||
"productionboard": "",
|
"productionboard": "",
|
||||||
"productionlist": "",
|
"productionlist": "",
|
||||||
@@ -1886,6 +1953,7 @@
|
|||||||
"shop_vendors": "Vendedores",
|
"shop_vendors": "Vendedores",
|
||||||
"temporarydocs": "",
|
"temporarydocs": "",
|
||||||
"timetickets": "",
|
"timetickets": "",
|
||||||
|
"ttapprovals": "",
|
||||||
"vehicles": "Vehículos"
|
"vehicles": "Vehículos"
|
||||||
},
|
},
|
||||||
"jobsactions": {
|
"jobsactions": {
|
||||||
@@ -1958,7 +2026,8 @@
|
|||||||
"actions": "Comportamiento",
|
"actions": "Comportamiento",
|
||||||
"deletenote": "Borrar nota",
|
"deletenote": "Borrar nota",
|
||||||
"edit": "Editar nota",
|
"edit": "Editar nota",
|
||||||
"new": "Nueva nota"
|
"new": "Nueva nota",
|
||||||
|
"savetojobnotes": ""
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"inserting": ""
|
"inserting": ""
|
||||||
@@ -1968,6 +2037,16 @@
|
|||||||
"critical": "Crítico",
|
"critical": "Crítico",
|
||||||
"private": "Privado",
|
"private": "Privado",
|
||||||
"text": "Contenido",
|
"text": "Contenido",
|
||||||
|
"type": "",
|
||||||
|
"types": {
|
||||||
|
"customer": "",
|
||||||
|
"general": "",
|
||||||
|
"office": "",
|
||||||
|
"paint": "",
|
||||||
|
"parts": "",
|
||||||
|
"shop": "",
|
||||||
|
"supplement": ""
|
||||||
|
},
|
||||||
"updatedat": "Actualizado en"
|
"updatedat": "Actualizado en"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
@@ -2224,6 +2303,7 @@
|
|||||||
"csi_invitation": "",
|
"csi_invitation": "",
|
||||||
"csi_invitation_action": "",
|
"csi_invitation_action": "",
|
||||||
"diagnostic_authorization": "",
|
"diagnostic_authorization": "",
|
||||||
|
"dms_posting_sheet": "",
|
||||||
"envelope_return_address": "",
|
"envelope_return_address": "",
|
||||||
"estimate": "",
|
"estimate": "",
|
||||||
"estimate_detail": "",
|
"estimate_detail": "",
|
||||||
@@ -2314,6 +2394,7 @@
|
|||||||
},
|
},
|
||||||
"subjects": {
|
"subjects": {
|
||||||
"jobs": {
|
"jobs": {
|
||||||
|
"individual_job_note": "",
|
||||||
"parts_order": "",
|
"parts_order": "",
|
||||||
"sublet_order": ""
|
"sublet_order": ""
|
||||||
}
|
}
|
||||||
@@ -2357,6 +2438,7 @@
|
|||||||
"qbo_usa": ""
|
"qbo_usa": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cardcolor": "",
|
||||||
"cardsettings": "",
|
"cardsettings": "",
|
||||||
"clm_no": "",
|
"clm_no": "",
|
||||||
"comment": "",
|
"comment": "",
|
||||||
@@ -2367,6 +2449,7 @@
|
|||||||
"ins_co_nm": "",
|
"ins_co_nm": "",
|
||||||
"jobdetail": "",
|
"jobdetail": "",
|
||||||
"laborhrs": "",
|
"laborhrs": "",
|
||||||
|
"legend": "",
|
||||||
"note": "",
|
"note": "",
|
||||||
"ownr_nm": "",
|
"ownr_nm": "",
|
||||||
"paintpriority": "",
|
"paintpriority": "",
|
||||||
@@ -2442,6 +2525,8 @@
|
|||||||
"export_payables": "",
|
"export_payables": "",
|
||||||
"export_payments": "",
|
"export_payments": "",
|
||||||
"export_receivables": "",
|
"export_receivables": "",
|
||||||
|
"exported_gsr_by_ro": "",
|
||||||
|
"exported_gsr_by_ro_labor": "",
|
||||||
"gsr_by_atp": "",
|
"gsr_by_atp": "",
|
||||||
"gsr_by_ats": "",
|
"gsr_by_ats": "",
|
||||||
"gsr_by_category": "",
|
"gsr_by_category": "",
|
||||||
@@ -2603,6 +2688,7 @@
|
|||||||
},
|
},
|
||||||
"timetickets": {
|
"timetickets": {
|
||||||
"actions": {
|
"actions": {
|
||||||
|
"claimtasks": "",
|
||||||
"clockin": "",
|
"clockin": "",
|
||||||
"clockout": "",
|
"clockout": "",
|
||||||
"enter": "",
|
"enter": "",
|
||||||
@@ -2623,10 +2709,12 @@
|
|||||||
"clockhours": "",
|
"clockhours": "",
|
||||||
"clockoff": "",
|
"clockoff": "",
|
||||||
"clockon": "",
|
"clockon": "",
|
||||||
|
"committed": "",
|
||||||
"cost_center": "",
|
"cost_center": "",
|
||||||
"date": "",
|
"date": "",
|
||||||
"efficiency": "",
|
"efficiency": "",
|
||||||
"employee": "",
|
"employee": "",
|
||||||
|
"employee_team": "",
|
||||||
"flat_rate": "",
|
"flat_rate": "",
|
||||||
"memo": "",
|
"memo": "",
|
||||||
"productivehrs": "",
|
"productivehrs": "",
|
||||||
@@ -2661,7 +2749,8 @@
|
|||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"clockoffmustbeafterclockon": "",
|
"clockoffmustbeafterclockon": "",
|
||||||
"clockoffwithoutclockon": ""
|
"clockoffwithoutclockon": "",
|
||||||
|
"hoursenteredmorethanavailable": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
@@ -2712,6 +2801,7 @@
|
|||||||
"shop-vendors": "",
|
"shop-vendors": "",
|
||||||
"temporarydocs": "",
|
"temporarydocs": "",
|
||||||
"timetickets": "",
|
"timetickets": "",
|
||||||
|
"ttapprovals": "",
|
||||||
"vehicle-details": "",
|
"vehicle-details": "",
|
||||||
"vehicles": ""
|
"vehicles": ""
|
||||||
},
|
},
|
||||||
@@ -2757,9 +2847,15 @@
|
|||||||
"shop_vendors": "Vendedores | $t(titles.app)",
|
"shop_vendors": "Vendedores | $t(titles.app)",
|
||||||
"temporarydocs": "",
|
"temporarydocs": "",
|
||||||
"timetickets": "",
|
"timetickets": "",
|
||||||
|
"ttapprovals": "",
|
||||||
"vehicledetail": "Detalles del vehículo {{vehicle}} | $t(titles.app)",
|
"vehicledetail": "Detalles del vehículo {{vehicle}} | $t(titles.app)",
|
||||||
"vehicles": "Todos los vehiculos | $t(titles.app)"
|
"vehicles": "Todos los vehiculos | $t(titles.app)"
|
||||||
},
|
},
|
||||||
|
"tt_approvals": {
|
||||||
|
"actions": {
|
||||||
|
"approveselected": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"actions": {
|
"actions": {
|
||||||
"changepassword": "",
|
"changepassword": "",
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"scheduledfor": "Rendez-vous prévu pour:",
|
"scheduledfor": "Rendez-vous prévu pour:",
|
||||||
"severalerrorsfound": "",
|
"severalerrorsfound": "",
|
||||||
"smartscheduling": "",
|
"smartscheduling": "",
|
||||||
|
"smspaymentreminder": "",
|
||||||
"suggesteddates": ""
|
"suggesteddates": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -103,6 +104,7 @@
|
|||||||
"admin_jobunvoid": "",
|
"admin_jobunvoid": "",
|
||||||
"billposted": "",
|
"billposted": "",
|
||||||
"billupdated": "",
|
"billupdated": "",
|
||||||
|
"failedpayment": "",
|
||||||
"jobassignmentchange": "",
|
"jobassignmentchange": "",
|
||||||
"jobassignmentremoved": "",
|
"jobassignmentremoved": "",
|
||||||
"jobchecklist": "",
|
"jobchecklist": "",
|
||||||
@@ -227,6 +229,7 @@
|
|||||||
},
|
},
|
||||||
"bodyshop": {
|
"bodyshop": {
|
||||||
"actions": {
|
"actions": {
|
||||||
|
"add_task_preset": "",
|
||||||
"addapptcolor": "",
|
"addapptcolor": "",
|
||||||
"addbucket": "",
|
"addbucket": "",
|
||||||
"addpartslocation": "",
|
"addpartslocation": "",
|
||||||
@@ -339,6 +342,12 @@
|
|||||||
},
|
},
|
||||||
"md_payment_types": "",
|
"md_payment_types": "",
|
||||||
"md_referral_sources": "",
|
"md_referral_sources": "",
|
||||||
|
"md_tasks_presets": {
|
||||||
|
"hourstype": "",
|
||||||
|
"memo": "",
|
||||||
|
"name": "",
|
||||||
|
"percent": ""
|
||||||
|
},
|
||||||
"messaginglabel": "",
|
"messaginglabel": "",
|
||||||
"messagingtext": "",
|
"messagingtext": "",
|
||||||
"noteslabel": "",
|
"noteslabel": "",
|
||||||
@@ -374,6 +383,9 @@
|
|||||||
"export": "",
|
"export": "",
|
||||||
"page": ""
|
"page": ""
|
||||||
},
|
},
|
||||||
|
"employee_teams": {
|
||||||
|
"page": ""
|
||||||
|
},
|
||||||
"employees": {
|
"employees": {
|
||||||
"page": ""
|
"page": ""
|
||||||
},
|
},
|
||||||
@@ -432,10 +444,15 @@
|
|||||||
},
|
},
|
||||||
"timetickets": {
|
"timetickets": {
|
||||||
"edit": "",
|
"edit": "",
|
||||||
|
"editcommitted": "",
|
||||||
"enter": "",
|
"enter": "",
|
||||||
"list": "",
|
"list": "",
|
||||||
"shiftedit": ""
|
"shiftedit": ""
|
||||||
},
|
},
|
||||||
|
"ttapprovals": {
|
||||||
|
"approve": "",
|
||||||
|
"view": ""
|
||||||
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"editaccess": ""
|
"editaccess": ""
|
||||||
}
|
}
|
||||||
@@ -453,6 +470,8 @@
|
|||||||
"federal_tax": "",
|
"federal_tax": "",
|
||||||
"federal_tax_itc": "",
|
"federal_tax_itc": "",
|
||||||
"gst_override": "",
|
"gst_override": "",
|
||||||
|
"invoiceexemptcode": "",
|
||||||
|
"itemexemptcode": "",
|
||||||
"la1": "",
|
"la1": "",
|
||||||
"la2": "",
|
"la2": "",
|
||||||
"la3": "",
|
"la3": "",
|
||||||
@@ -504,6 +523,7 @@
|
|||||||
"dailyhrslimit": ""
|
"dailyhrslimit": ""
|
||||||
},
|
},
|
||||||
"ssbuckets": {
|
"ssbuckets": {
|
||||||
|
"color": "",
|
||||||
"gte": "",
|
"gte": "",
|
||||||
"id": "",
|
"id": "",
|
||||||
"label": "",
|
"label": "",
|
||||||
@@ -541,7 +561,9 @@
|
|||||||
"target_touchtime": "",
|
"target_touchtime": "",
|
||||||
"timezone": "",
|
"timezone": "",
|
||||||
"tt_allow_post_to_invoiced": "",
|
"tt_allow_post_to_invoiced": "",
|
||||||
|
"tt_enforce_hours_for_tech_console": "",
|
||||||
"use_fippa": "",
|
"use_fippa": "",
|
||||||
|
"use_paint_scale_data": "",
|
||||||
"uselocalmediaserver": "",
|
"uselocalmediaserver": "",
|
||||||
"website": "",
|
"website": "",
|
||||||
"zip_post": ""
|
"zip_post": ""
|
||||||
@@ -572,6 +594,7 @@
|
|||||||
"title": ""
|
"title": ""
|
||||||
},
|
},
|
||||||
"emaillater": "",
|
"emaillater": "",
|
||||||
|
"employee_teams": "",
|
||||||
"employees": "",
|
"employees": "",
|
||||||
"estimators": "",
|
"estimators": "",
|
||||||
"filehandlers": "",
|
"filehandlers": "",
|
||||||
@@ -580,6 +603,7 @@
|
|||||||
"jobstatuses": "",
|
"jobstatuses": "",
|
||||||
"laborrates": "",
|
"laborrates": "",
|
||||||
"licensing": "",
|
"licensing": "",
|
||||||
|
"md_tasks_presets": "",
|
||||||
"md_to_emails": "",
|
"md_to_emails": "",
|
||||||
"md_to_emails_emails": "",
|
"md_to_emails_emails": "",
|
||||||
"messagingpresets": "",
|
"messagingpresets": "",
|
||||||
@@ -606,6 +630,7 @@
|
|||||||
"speedprint": "",
|
"speedprint": "",
|
||||||
"ssbuckets": "",
|
"ssbuckets": "",
|
||||||
"systemsettings": "",
|
"systemsettings": "",
|
||||||
|
"task-presets": "",
|
||||||
"workingdays": ""
|
"workingdays": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -905,6 +930,18 @@
|
|||||||
"sent": "E-mail envoyé avec succès."
|
"sent": "E-mail envoyé avec succès."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"employee_teams": {
|
||||||
|
"actions": {
|
||||||
|
"new": "",
|
||||||
|
"newmember": ""
|
||||||
|
},
|
||||||
|
"fields": {
|
||||||
|
"active": "",
|
||||||
|
"employeeid": "",
|
||||||
|
"name": "",
|
||||||
|
"percentage": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"employees": {
|
"employees": {
|
||||||
"actions": {
|
"actions": {
|
||||||
"addvacation": "",
|
"addvacation": "",
|
||||||
@@ -1014,6 +1051,7 @@
|
|||||||
"created_at": "",
|
"created_at": "",
|
||||||
"email": "",
|
"email": "",
|
||||||
"errors": "",
|
"errors": "",
|
||||||
|
"excel": "",
|
||||||
"exceptiontitle": "",
|
"exceptiontitle": "",
|
||||||
"friday": "",
|
"friday": "",
|
||||||
"globalsearch": "",
|
"globalsearch": "",
|
||||||
@@ -1063,6 +1101,7 @@
|
|||||||
"sunday": "",
|
"sunday": "",
|
||||||
"text": "",
|
"text": "",
|
||||||
"thursday": "",
|
"thursday": "",
|
||||||
|
"total": "",
|
||||||
"totals": "",
|
"totals": "",
|
||||||
"tuesday": "",
|
"tuesday": "",
|
||||||
"unknown": "Inconnu",
|
"unknown": "Inconnu",
|
||||||
@@ -1142,6 +1181,30 @@
|
|||||||
"updated": ""
|
"updated": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"job_payments": {
|
||||||
|
"buttons": {
|
||||||
|
"goback": "",
|
||||||
|
"proceedtopayment": "",
|
||||||
|
"refundpayment": ""
|
||||||
|
},
|
||||||
|
"notifications": {
|
||||||
|
"error": {
|
||||||
|
"description": "",
|
||||||
|
"title": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"titles": {
|
||||||
|
"amount": "",
|
||||||
|
"dateOfPayment": "",
|
||||||
|
"descriptions": "",
|
||||||
|
"payer": "",
|
||||||
|
"payername": "",
|
||||||
|
"paymentid": "",
|
||||||
|
"paymenttype": "",
|
||||||
|
"refundamount": "",
|
||||||
|
"transactionid": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"joblines": {
|
"joblines": {
|
||||||
"actions": {
|
"actions": {
|
||||||
"converttolabor": "",
|
"converttolabor": "",
|
||||||
@@ -1574,6 +1637,7 @@
|
|||||||
"scheddates": ""
|
"scheddates": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
|
"act_price_ppc": "",
|
||||||
"actual_completion_inferred": "",
|
"actual_completion_inferred": "",
|
||||||
"actual_delivery_inferred": "",
|
"actual_delivery_inferred": "",
|
||||||
"actual_in_inferred": "",
|
"actual_in_inferred": "",
|
||||||
@@ -1710,6 +1774,7 @@
|
|||||||
"partstotal": "",
|
"partstotal": "",
|
||||||
"totalreturns": ""
|
"totalreturns": ""
|
||||||
},
|
},
|
||||||
|
"ppc": "",
|
||||||
"profileadjustments": "",
|
"profileadjustments": "",
|
||||||
"prt_dsmk_total": "",
|
"prt_dsmk_total": "",
|
||||||
"rates": "Les taux",
|
"rates": "Les taux",
|
||||||
@@ -1850,6 +1915,7 @@
|
|||||||
"customers": "Les clients",
|
"customers": "Les clients",
|
||||||
"dashboard": "",
|
"dashboard": "",
|
||||||
"enterbills": "",
|
"enterbills": "",
|
||||||
|
"entercardpayment": "",
|
||||||
"enterpayment": "",
|
"enterpayment": "",
|
||||||
"entertimeticket": "",
|
"entertimeticket": "",
|
||||||
"export": "",
|
"export": "",
|
||||||
@@ -1861,6 +1927,7 @@
|
|||||||
"newjob": "",
|
"newjob": "",
|
||||||
"owners": "Propriétaires",
|
"owners": "Propriétaires",
|
||||||
"parts-queue": "",
|
"parts-queue": "",
|
||||||
|
"paymentremindersms": "",
|
||||||
"phonebook": "",
|
"phonebook": "",
|
||||||
"productionboard": "",
|
"productionboard": "",
|
||||||
"productionlist": "",
|
"productionlist": "",
|
||||||
@@ -1886,6 +1953,7 @@
|
|||||||
"shop_vendors": "Vendeurs",
|
"shop_vendors": "Vendeurs",
|
||||||
"temporarydocs": "",
|
"temporarydocs": "",
|
||||||
"timetickets": "",
|
"timetickets": "",
|
||||||
|
"ttapprovals": "",
|
||||||
"vehicles": "Véhicules"
|
"vehicles": "Véhicules"
|
||||||
},
|
},
|
||||||
"jobsactions": {
|
"jobsactions": {
|
||||||
@@ -1958,7 +2026,8 @@
|
|||||||
"actions": "actes",
|
"actions": "actes",
|
||||||
"deletenote": "Supprimer la note",
|
"deletenote": "Supprimer la note",
|
||||||
"edit": "Note éditée",
|
"edit": "Note éditée",
|
||||||
"new": "Nouvelle note"
|
"new": "Nouvelle note",
|
||||||
|
"savetojobnotes": ""
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"inserting": ""
|
"inserting": ""
|
||||||
@@ -1968,6 +2037,16 @@
|
|||||||
"critical": "Critique",
|
"critical": "Critique",
|
||||||
"private": "privé",
|
"private": "privé",
|
||||||
"text": "Contenu",
|
"text": "Contenu",
|
||||||
|
"type": "",
|
||||||
|
"types": {
|
||||||
|
"customer": "",
|
||||||
|
"general": "",
|
||||||
|
"office": "",
|
||||||
|
"paint": "",
|
||||||
|
"parts": "",
|
||||||
|
"shop": "",
|
||||||
|
"supplement": ""
|
||||||
|
},
|
||||||
"updatedat": "Mis à jour à"
|
"updatedat": "Mis à jour à"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
@@ -2224,6 +2303,7 @@
|
|||||||
"csi_invitation": "",
|
"csi_invitation": "",
|
||||||
"csi_invitation_action": "",
|
"csi_invitation_action": "",
|
||||||
"diagnostic_authorization": "",
|
"diagnostic_authorization": "",
|
||||||
|
"dms_posting_sheet": "",
|
||||||
"envelope_return_address": "",
|
"envelope_return_address": "",
|
||||||
"estimate": "",
|
"estimate": "",
|
||||||
"estimate_detail": "",
|
"estimate_detail": "",
|
||||||
@@ -2314,6 +2394,7 @@
|
|||||||
},
|
},
|
||||||
"subjects": {
|
"subjects": {
|
||||||
"jobs": {
|
"jobs": {
|
||||||
|
"individual_job_note": "",
|
||||||
"parts_order": "",
|
"parts_order": "",
|
||||||
"sublet_order": ""
|
"sublet_order": ""
|
||||||
}
|
}
|
||||||
@@ -2357,6 +2438,7 @@
|
|||||||
"qbo_usa": ""
|
"qbo_usa": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cardcolor": "",
|
||||||
"cardsettings": "",
|
"cardsettings": "",
|
||||||
"clm_no": "",
|
"clm_no": "",
|
||||||
"comment": "",
|
"comment": "",
|
||||||
@@ -2367,6 +2449,7 @@
|
|||||||
"ins_co_nm": "",
|
"ins_co_nm": "",
|
||||||
"jobdetail": "",
|
"jobdetail": "",
|
||||||
"laborhrs": "",
|
"laborhrs": "",
|
||||||
|
"legend": "",
|
||||||
"note": "",
|
"note": "",
|
||||||
"ownr_nm": "",
|
"ownr_nm": "",
|
||||||
"paintpriority": "",
|
"paintpriority": "",
|
||||||
@@ -2442,6 +2525,8 @@
|
|||||||
"export_payables": "",
|
"export_payables": "",
|
||||||
"export_payments": "",
|
"export_payments": "",
|
||||||
"export_receivables": "",
|
"export_receivables": "",
|
||||||
|
"exported_gsr_by_ro": "",
|
||||||
|
"exported_gsr_by_ro_labor": "",
|
||||||
"gsr_by_atp": "",
|
"gsr_by_atp": "",
|
||||||
"gsr_by_ats": "",
|
"gsr_by_ats": "",
|
||||||
"gsr_by_category": "",
|
"gsr_by_category": "",
|
||||||
@@ -2603,6 +2688,7 @@
|
|||||||
},
|
},
|
||||||
"timetickets": {
|
"timetickets": {
|
||||||
"actions": {
|
"actions": {
|
||||||
|
"claimtasks": "",
|
||||||
"clockin": "",
|
"clockin": "",
|
||||||
"clockout": "",
|
"clockout": "",
|
||||||
"enter": "",
|
"enter": "",
|
||||||
@@ -2623,10 +2709,12 @@
|
|||||||
"clockhours": "",
|
"clockhours": "",
|
||||||
"clockoff": "",
|
"clockoff": "",
|
||||||
"clockon": "",
|
"clockon": "",
|
||||||
|
"committed": "",
|
||||||
"cost_center": "",
|
"cost_center": "",
|
||||||
"date": "",
|
"date": "",
|
||||||
"efficiency": "",
|
"efficiency": "",
|
||||||
"employee": "",
|
"employee": "",
|
||||||
|
"employee_team": "",
|
||||||
"flat_rate": "",
|
"flat_rate": "",
|
||||||
"memo": "",
|
"memo": "",
|
||||||
"productivehrs": "",
|
"productivehrs": "",
|
||||||
@@ -2661,7 +2749,8 @@
|
|||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"clockoffmustbeafterclockon": "",
|
"clockoffmustbeafterclockon": "",
|
||||||
"clockoffwithoutclockon": ""
|
"clockoffwithoutclockon": "",
|
||||||
|
"hoursenteredmorethanavailable": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
@@ -2712,6 +2801,7 @@
|
|||||||
"shop-vendors": "",
|
"shop-vendors": "",
|
||||||
"temporarydocs": "",
|
"temporarydocs": "",
|
||||||
"timetickets": "",
|
"timetickets": "",
|
||||||
|
"ttapprovals": "",
|
||||||
"vehicle-details": "",
|
"vehicle-details": "",
|
||||||
"vehicles": ""
|
"vehicles": ""
|
||||||
},
|
},
|
||||||
@@ -2757,9 +2847,15 @@
|
|||||||
"shop_vendors": "Vendeurs | $t(titles.app)",
|
"shop_vendors": "Vendeurs | $t(titles.app)",
|
||||||
"temporarydocs": "",
|
"temporarydocs": "",
|
||||||
"timetickets": "",
|
"timetickets": "",
|
||||||
|
"ttapprovals": "",
|
||||||
"vehicledetail": "Détails du véhicule {{vehicle} | $t(titles.app)",
|
"vehicledetail": "Détails du véhicule {{vehicle} | $t(titles.app)",
|
||||||
"vehicles": "Tous les véhicules | $t(titles.app)"
|
"vehicles": "Tous les véhicules | $t(titles.app)"
|
||||||
},
|
},
|
||||||
|
"tt_approvals": {
|
||||||
|
"actions": {
|
||||||
|
"approveselected": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"actions": {
|
"actions": {
|
||||||
"changepassword": "",
|
"changepassword": "",
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { gql } from "@apollo/client";
|
import { gql } from "@apollo/client";
|
||||||
import { notification } from "antd";
|
import { notification } from "antd";
|
||||||
import axios from "axios";
|
|
||||||
import jsreport from "@jsreport/browser-client";
|
import jsreport from "@jsreport/browser-client";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
@@ -9,7 +8,8 @@ import { setEmailOptions } from "../redux/email/email.actions";
|
|||||||
import { store } from "../redux/store";
|
import { store } from "../redux/store";
|
||||||
import client from "../utils/GraphQLClient";
|
import client from "../utils/GraphQLClient";
|
||||||
import { TemplateList } from "./TemplateConstants";
|
import { TemplateList } from "./TemplateConstants";
|
||||||
|
import cleanAxios from "./CleanAxios";
|
||||||
|
import axios from "axios";
|
||||||
const server = process.env.REACT_APP_REPORTS_SERVER_URL;
|
const server = process.env.REACT_APP_REPORTS_SERVER_URL;
|
||||||
|
|
||||||
jsreport.serverUrl = server;
|
jsreport.serverUrl = server;
|
||||||
@@ -26,10 +26,14 @@ export default async function RenderTemplate(
|
|||||||
if (window.jsr3) {
|
if (window.jsr3) {
|
||||||
jsreport.serverUrl = "https://reports3.test.imex.online/";
|
jsreport.serverUrl = "https://reports3.test.imex.online/";
|
||||||
}
|
}
|
||||||
|
const jsrAuth = (await axios.post("/utils/jsr")).data;
|
||||||
|
|
||||||
|
jsreport.headers["Authorization"] = jsrAuth;
|
||||||
|
|
||||||
//Query assets that match the template name. Must be in format <<templateName>>.query
|
//Query assets that match the template name. Must be in format <<templateName>>.query
|
||||||
let { contextData, useShopSpecificTemplate } = await fetchContextData(
|
let { contextData, useShopSpecificTemplate } = await fetchContextData(
|
||||||
templateObject
|
templateObject,
|
||||||
|
jsrAuth
|
||||||
);
|
);
|
||||||
|
|
||||||
const { ignoreCustomMargins } = Templates[templateObject.name];
|
const { ignoreCustomMargins } = Templates[templateObject.name];
|
||||||
@@ -137,11 +141,15 @@ export async function RenderTemplates(
|
|||||||
//Query assets that match the template name. Must be in format <<templateName>>.query
|
//Query assets that match the template name. Must be in format <<templateName>>.query
|
||||||
let unsortedTemplatesAndData = [];
|
let unsortedTemplatesAndData = [];
|
||||||
let proms = [];
|
let proms = [];
|
||||||
|
const jsrAuth = (await axios.post("/utils/jsr")).data;
|
||||||
|
jsreport.headers["Authorization"] = jsrAuth;
|
||||||
|
|
||||||
templateObjects.forEach((template) => {
|
templateObjects.forEach((template) => {
|
||||||
proms.push(
|
proms.push(
|
||||||
(async () => {
|
(async () => {
|
||||||
let { contextData, useShopSpecificTemplate } = await fetchContextData(
|
let { contextData, useShopSpecificTemplate } = await fetchContextData(
|
||||||
template
|
template,
|
||||||
|
jsrAuth
|
||||||
);
|
);
|
||||||
unsortedTemplatesAndData.push({
|
unsortedTemplatesAndData.push({
|
||||||
templateObject: template,
|
templateObject: template,
|
||||||
@@ -298,19 +306,22 @@ export const GenerateDocuments = async (templates) => {
|
|||||||
await RenderTemplates(templates, bodyshop);
|
await RenderTemplates(templates, bodyshop);
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchContextData = async (templateObject) => {
|
const fetchContextData = async (templateObject, jsrAuth) => {
|
||||||
const bodyshop = store.getState().user.bodyshop;
|
const bodyshop = store.getState().user.bodyshop;
|
||||||
|
|
||||||
jsreport.headers["Authorization"] =
|
jsreport.headers["FirebaseAuthorization"] =
|
||||||
"Bearer " + (await auth.currentUser.getIdToken());
|
"Bearer " + (await auth.currentUser.getIdToken());
|
||||||
|
|
||||||
const folders = await axios.get(`${server}/odata/folders`);
|
const folders = await cleanAxios.get(`${server}/odata/folders`, {
|
||||||
|
headers: { Authorization: jsrAuth },
|
||||||
|
});
|
||||||
const shopSpecificFolder = folders.data.value.find(
|
const shopSpecificFolder = folders.data.value.find(
|
||||||
(f) => f.name === bodyshop.imexshopid
|
(f) => f.name === bodyshop.imexshopid
|
||||||
);
|
);
|
||||||
|
|
||||||
const jsReportQueries = await axios.get(
|
const jsReportQueries = await cleanAxios.get(
|
||||||
`${server}/odata/assets?$filter=name eq '${templateObject.name}.query'`
|
`${server}/odata/assets?$filter=name eq '${templateObject.name}.query'`,
|
||||||
|
{ headers: { Authorization: jsrAuth } }
|
||||||
);
|
);
|
||||||
|
|
||||||
let templateQueryToExecute;
|
let templateQueryToExecute;
|
||||||
|
|||||||
@@ -7,23 +7,24 @@ export const EmailSettings = {
|
|||||||
|
|
||||||
export const TemplateList = (type, context) => {
|
export const TemplateList = (type, context) => {
|
||||||
//const { bodyshop } = store.getState().user;
|
//const { bodyshop } = store.getState().user;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
//If there's no type or the type is job, send it back.
|
//If there's no type or the type is job, send it back.
|
||||||
...(!type || type === "job"
|
...(!type || type === "job"
|
||||||
? {
|
? {
|
||||||
casl_authorization: {
|
casl_authorization: {
|
||||||
title: i18n.t("printcenter.jobs.casl_authorization"),
|
title: i18n.t("printcenter.jobs.casl_authorization"),
|
||||||
description: "CASL Authorization",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.casl_authorization"),
|
subject: i18n.t("printcenter.jobs.casl_authorization"),
|
||||||
key: "casl_authorization",
|
key: "casl_authorization",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "authorization",
|
group: "authorization",
|
||||||
|
regions: {
|
||||||
|
CA: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
fippa_authorization: {
|
fippa_authorization: {
|
||||||
title: i18n.t("printcenter.jobs.fippa_authorization"),
|
title: i18n.t("printcenter.jobs.fippa_authorization"),
|
||||||
description: "CASL Authorization",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.fippa_authorization"),
|
subject: i18n.t("printcenter.jobs.fippa_authorization"),
|
||||||
key: "fippa_authorization",
|
key: "fippa_authorization",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -31,7 +32,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
diagnostic_authorization: {
|
diagnostic_authorization: {
|
||||||
title: i18n.t("printcenter.jobs.diagnostic_authorization"),
|
title: i18n.t("printcenter.jobs.diagnostic_authorization"),
|
||||||
description: "Diagnostic Authorization",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.diagnostic_authorization"),
|
subject: i18n.t("printcenter.jobs.diagnostic_authorization"),
|
||||||
key: "diagnostic_authorization",
|
key: "diagnostic_authorization",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -39,7 +40,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
mechanical_authorization: {
|
mechanical_authorization: {
|
||||||
title: i18n.t("printcenter.jobs.mechanical_authorization"),
|
title: i18n.t("printcenter.jobs.mechanical_authorization"),
|
||||||
description: "Diagnostic Authorization",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.mechanical_authorization"),
|
subject: i18n.t("printcenter.jobs.mechanical_authorization"),
|
||||||
key: "mechanical_authorization",
|
key: "mechanical_authorization",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -47,7 +48,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
appointment_reminder: {
|
appointment_reminder: {
|
||||||
title: i18n.t("printcenter.jobs.appointment_reminder"),
|
title: i18n.t("printcenter.jobs.appointment_reminder"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.appointment_reminder"),
|
subject: i18n.t("printcenter.jobs.appointment_reminder"),
|
||||||
key: "appointment_reminder",
|
key: "appointment_reminder",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -55,7 +56,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
estimate_followup: {
|
estimate_followup: {
|
||||||
title: i18n.t("printcenter.jobs.estimate_followup"),
|
title: i18n.t("printcenter.jobs.estimate_followup"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.estimate_followup"),
|
subject: i18n.t("printcenter.jobs.estimate_followup"),
|
||||||
key: "estimate_followup",
|
key: "estimate_followup",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -63,7 +64,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
express_repair_checklist: {
|
express_repair_checklist: {
|
||||||
title: i18n.t("printcenter.jobs.express_repair_checklist"),
|
title: i18n.t("printcenter.jobs.express_repair_checklist"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.express_repair_checklist"),
|
subject: i18n.t("printcenter.jobs.express_repair_checklist"),
|
||||||
key: "express_repair_checklist",
|
key: "express_repair_checklist",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -71,7 +72,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
glass_express_checklist: {
|
glass_express_checklist: {
|
||||||
title: i18n.t("printcenter.jobs.glass_express_checklist"),
|
title: i18n.t("printcenter.jobs.glass_express_checklist"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.glass_express_checklist"),
|
subject: i18n.t("printcenter.jobs.glass_express_checklist"),
|
||||||
key: "glass_express_checklist",
|
key: "glass_express_checklist",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -79,7 +80,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
stolen_recovery_checklist: {
|
stolen_recovery_checklist: {
|
||||||
title: i18n.t("printcenter.jobs.stolen_recovery_checklist"),
|
title: i18n.t("printcenter.jobs.stolen_recovery_checklist"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.stolen_recovery_checklist"),
|
subject: i18n.t("printcenter.jobs.stolen_recovery_checklist"),
|
||||||
key: "stolen_recovery_checklist",
|
key: "stolen_recovery_checklist",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -87,7 +88,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
vehicle_check_in: {
|
vehicle_check_in: {
|
||||||
title: i18n.t("printcenter.jobs.vehicle_check_in"),
|
title: i18n.t("printcenter.jobs.vehicle_check_in"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.vehicle_check_in"),
|
subject: i18n.t("printcenter.jobs.vehicle_check_in"),
|
||||||
key: "vehicle_check_in",
|
key: "vehicle_check_in",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -95,16 +96,15 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
parts_order_history: {
|
parts_order_history: {
|
||||||
title: i18n.t("printcenter.jobs.parts_order_history"),
|
title: i18n.t("printcenter.jobs.parts_order_history"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.parts_order_history"),
|
subject: i18n.t("printcenter.jobs.parts_order_history"),
|
||||||
key: "parts_order_history",
|
key: "parts_order_history",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "ro",
|
group: "ro",
|
||||||
},
|
},
|
||||||
|
|
||||||
job_notes: {
|
job_notes: {
|
||||||
title: i18n.t("printcenter.jobs.job_notes"),
|
title: i18n.t("printcenter.jobs.job_notes"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.job_notes"),
|
subject: i18n.t("printcenter.jobs.job_notes"),
|
||||||
key: "job_notes",
|
key: "job_notes",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -112,7 +112,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
ro_with_description: {
|
ro_with_description: {
|
||||||
title: i18n.t("printcenter.jobs.ro_with_description"),
|
title: i18n.t("printcenter.jobs.ro_with_description"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.ro_with_description"),
|
subject: i18n.t("printcenter.jobs.ro_with_description"),
|
||||||
key: "ro_with_description",
|
key: "ro_with_description",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -120,7 +120,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
window_tag: {
|
window_tag: {
|
||||||
title: i18n.t("printcenter.jobs.window_tag"),
|
title: i18n.t("printcenter.jobs.window_tag"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.window_tag"),
|
subject: i18n.t("printcenter.jobs.window_tag"),
|
||||||
key: "window_tag",
|
key: "window_tag",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -128,7 +128,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
supplement_request: {
|
supplement_request: {
|
||||||
title: i18n.t("printcenter.jobs.supplement_request"),
|
title: i18n.t("printcenter.jobs.supplement_request"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.supplement_request"),
|
subject: i18n.t("printcenter.jobs.supplement_request"),
|
||||||
key: "supplement_request",
|
key: "supplement_request",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -136,7 +136,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
estimate: {
|
estimate: {
|
||||||
title: i18n.t("printcenter.jobs.estimate"),
|
title: i18n.t("printcenter.jobs.estimate"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.estimate"),
|
subject: i18n.t("printcenter.jobs.estimate"),
|
||||||
key: "estimate",
|
key: "estimate",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -144,7 +144,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
parts_list: {
|
parts_list: {
|
||||||
title: i18n.t("printcenter.jobs.parts_list"),
|
title: i18n.t("printcenter.jobs.parts_list"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.parts_list"),
|
subject: i18n.t("printcenter.jobs.parts_list"),
|
||||||
key: "parts_list",
|
key: "parts_list",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -152,7 +152,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
coversheet_portrait: {
|
coversheet_portrait: {
|
||||||
title: i18n.t("printcenter.jobs.coversheet_portrait"),
|
title: i18n.t("printcenter.jobs.coversheet_portrait"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.coversheet_portrait"),
|
subject: i18n.t("printcenter.jobs.coversheet_portrait"),
|
||||||
key: "coversheet_portrait",
|
key: "coversheet_portrait",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -160,7 +160,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
coversheet_landscape: {
|
coversheet_landscape: {
|
||||||
title: i18n.t("printcenter.jobs.coversheet_landscape"),
|
title: i18n.t("printcenter.jobs.coversheet_landscape"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.coversheet_landscape"),
|
subject: i18n.t("printcenter.jobs.coversheet_landscape"),
|
||||||
key: "coversheet_landscape",
|
key: "coversheet_landscape",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -168,7 +168,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
key_tag: {
|
key_tag: {
|
||||||
title: i18n.t("printcenter.jobs.key_tag"),
|
title: i18n.t("printcenter.jobs.key_tag"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.key_tag"),
|
subject: i18n.t("printcenter.jobs.key_tag"),
|
||||||
key: "key_tag",
|
key: "key_tag",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -176,7 +176,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
paint_grid: {
|
paint_grid: {
|
||||||
title: i18n.t("printcenter.jobs.paint_grid"),
|
title: i18n.t("printcenter.jobs.paint_grid"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.paint_grid"),
|
subject: i18n.t("printcenter.jobs.paint_grid"),
|
||||||
key: "paint_grid",
|
key: "paint_grid",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -184,7 +184,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
worksheet_by_line_number: {
|
worksheet_by_line_number: {
|
||||||
title: i18n.t("printcenter.jobs.worksheet_by_line_number"),
|
title: i18n.t("printcenter.jobs.worksheet_by_line_number"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.worksheet_by_line_number"),
|
subject: i18n.t("printcenter.jobs.worksheet_by_line_number"),
|
||||||
key: "worksheet_by_line_number",
|
key: "worksheet_by_line_number",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -194,7 +194,7 @@ export const TemplateList = (type, context) => {
|
|||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"printcenter.jobs.worksheet_sorted_by_operation_type"
|
"printcenter.jobs.worksheet_sorted_by_operation_type"
|
||||||
),
|
),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t(
|
subject: i18n.t(
|
||||||
"printcenter.jobs.worksheet_sorted_by_operation_type"
|
"printcenter.jobs.worksheet_sorted_by_operation_type"
|
||||||
),
|
),
|
||||||
@@ -204,7 +204,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
worksheet_sorted_by_operation: {
|
worksheet_sorted_by_operation: {
|
||||||
title: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
|
title: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
|
subject: i18n.t("printcenter.jobs.worksheet_sorted_by_operation"),
|
||||||
key: "worksheet_sorted_by_operation",
|
key: "worksheet_sorted_by_operation",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -214,7 +214,7 @@ export const TemplateList = (type, context) => {
|
|||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"printcenter.jobs.worksheet_sorted_by_operation_no_hours"
|
"printcenter.jobs.worksheet_sorted_by_operation_no_hours"
|
||||||
),
|
),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t(
|
subject: i18n.t(
|
||||||
"printcenter.jobs.worksheet_sorted_by_operation_no_hours"
|
"printcenter.jobs.worksheet_sorted_by_operation_no_hours"
|
||||||
),
|
),
|
||||||
@@ -226,7 +226,7 @@ export const TemplateList = (type, context) => {
|
|||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"printcenter.jobs.worksheet_sorted_by_operation_part_type"
|
"printcenter.jobs.worksheet_sorted_by_operation_part_type"
|
||||||
),
|
),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t(
|
subject: i18n.t(
|
||||||
"printcenter.jobs.worksheet_sorted_by_operation_part_type"
|
"printcenter.jobs.worksheet_sorted_by_operation_part_type"
|
||||||
),
|
),
|
||||||
@@ -236,7 +236,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
payments_by_job: {
|
payments_by_job: {
|
||||||
title: i18n.t("printcenter.jobs.payments_by_job"),
|
title: i18n.t("printcenter.jobs.payments_by_job"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.payments_by_job"),
|
subject: i18n.t("printcenter.jobs.payments_by_job"),
|
||||||
key: "payments_by_job",
|
key: "payments_by_job",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -244,7 +244,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
final_invoice: {
|
final_invoice: {
|
||||||
title: i18n.t("printcenter.jobs.final_invoice"),
|
title: i18n.t("printcenter.jobs.final_invoice"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.final_invoice"),
|
subject: i18n.t("printcenter.jobs.final_invoice"),
|
||||||
key: "final_invoice",
|
key: "final_invoice",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -252,7 +252,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
payment_request: {
|
payment_request: {
|
||||||
title: i18n.t("printcenter.jobs.payment_request"),
|
title: i18n.t("printcenter.jobs.payment_request"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.payment_request"),
|
subject: i18n.t("printcenter.jobs.payment_request"),
|
||||||
key: "payment_request",
|
key: "payment_request",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -260,7 +260,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
invoice_total_payable: {
|
invoice_total_payable: {
|
||||||
title: i18n.t("printcenter.jobs.invoice_total_payable"),
|
title: i18n.t("printcenter.jobs.invoice_total_payable"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.invoice_total_payable"),
|
subject: i18n.t("printcenter.jobs.invoice_total_payable"),
|
||||||
key: "invoice_total_payable",
|
key: "invoice_total_payable",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -268,7 +268,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
invoice_customer_payable: {
|
invoice_customer_payable: {
|
||||||
title: i18n.t("printcenter.jobs.invoice_customer_payable"),
|
title: i18n.t("printcenter.jobs.invoice_customer_payable"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.invoice_customer_payable"),
|
subject: i18n.t("printcenter.jobs.invoice_customer_payable"),
|
||||||
key: "invoice_customer_payable",
|
key: "invoice_customer_payable",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -276,7 +276,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
ro_totals: {
|
ro_totals: {
|
||||||
title: i18n.t("printcenter.jobs.ro_totals"),
|
title: i18n.t("printcenter.jobs.ro_totals"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.ro_totals"),
|
subject: i18n.t("printcenter.jobs.ro_totals"),
|
||||||
key: "ro_totals",
|
key: "ro_totals",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -284,7 +284,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
job_costing_ro: {
|
job_costing_ro: {
|
||||||
title: i18n.t("printcenter.jobs.job_costing_ro"),
|
title: i18n.t("printcenter.jobs.job_costing_ro"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.job_costing_ro"),
|
subject: i18n.t("printcenter.jobs.job_costing_ro"),
|
||||||
key: "job_costing_ro",
|
key: "job_costing_ro",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -292,7 +292,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
purchases_by_ro_detail: {
|
purchases_by_ro_detail: {
|
||||||
title: i18n.t("printcenter.jobs.purchases_by_ro_detail"),
|
title: i18n.t("printcenter.jobs.purchases_by_ro_detail"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.purchases_by_ro_detail"),
|
subject: i18n.t("printcenter.jobs.purchases_by_ro_detail"),
|
||||||
key: "purchases_by_ro_detail",
|
key: "purchases_by_ro_detail",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -300,7 +300,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
purchases_by_ro_summary: {
|
purchases_by_ro_summary: {
|
||||||
title: i18n.t("printcenter.jobs.purchases_by_ro_summary"),
|
title: i18n.t("printcenter.jobs.purchases_by_ro_summary"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.purchases_by_ro_summary"),
|
subject: i18n.t("printcenter.jobs.purchases_by_ro_summary"),
|
||||||
key: "purchases_by_ro_summary",
|
key: "purchases_by_ro_summary",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -308,7 +308,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
filing_coversheet_portrait: {
|
filing_coversheet_portrait: {
|
||||||
title: i18n.t("printcenter.jobs.filing_coversheet_portrait"),
|
title: i18n.t("printcenter.jobs.filing_coversheet_portrait"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.filing_coversheet_portrait"),
|
subject: i18n.t("printcenter.jobs.filing_coversheet_portrait"),
|
||||||
key: "filing_coversheet_portrait",
|
key: "filing_coversheet_portrait",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -316,7 +316,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
filing_coversheet_landscape: {
|
filing_coversheet_landscape: {
|
||||||
title: i18n.t("printcenter.jobs.filing_coversheet_landscape"),
|
title: i18n.t("printcenter.jobs.filing_coversheet_landscape"),
|
||||||
description: "CASL Authorization",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.filing_coversheet_landscape"),
|
subject: i18n.t("printcenter.jobs.filing_coversheet_landscape"),
|
||||||
key: "filing_coversheet_landscape",
|
key: "filing_coversheet_landscape",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -324,25 +324,23 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
qc_sheet: {
|
qc_sheet: {
|
||||||
title: i18n.t("printcenter.jobs.qc_sheet"),
|
title: i18n.t("printcenter.jobs.qc_sheet"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.qc_sheet"),
|
subject: i18n.t("printcenter.jobs.qc_sheet"),
|
||||||
key: "qc_sheet",
|
key: "qc_sheet",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "post",
|
group: "post",
|
||||||
},
|
},
|
||||||
|
|
||||||
vehicle_delivery_check: {
|
vehicle_delivery_check: {
|
||||||
title: i18n.t("printcenter.jobs.vehicle_delivery_check"),
|
title: i18n.t("printcenter.jobs.vehicle_delivery_check"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.vehicle_delivery_check"),
|
subject: i18n.t("printcenter.jobs.vehicle_delivery_check"),
|
||||||
key: "vehicle_delivery_check",
|
key: "vehicle_delivery_check",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "post",
|
group: "post",
|
||||||
},
|
},
|
||||||
|
|
||||||
guarantee: {
|
guarantee: {
|
||||||
title: i18n.t("printcenter.jobs.guarantee"),
|
title: i18n.t("printcenter.jobs.guarantee"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.guarantee"),
|
subject: i18n.t("printcenter.jobs.guarantee"),
|
||||||
key: "guarantee",
|
key: "guarantee",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -350,7 +348,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
csi_invitation: {
|
csi_invitation: {
|
||||||
title: i18n.t("printcenter.jobs.csi_invitation"),
|
title: i18n.t("printcenter.jobs.csi_invitation"),
|
||||||
description: "CSI invite",
|
description: "",
|
||||||
key: "csi_invitation",
|
key: "csi_invitation",
|
||||||
subject: i18n.t("printcenter.jobs.csi_invitation"),
|
subject: i18n.t("printcenter.jobs.csi_invitation"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -358,7 +356,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
window_tag_sublet: {
|
window_tag_sublet: {
|
||||||
title: i18n.t("printcenter.jobs.window_tag_sublet"),
|
title: i18n.t("printcenter.jobs.window_tag_sublet"),
|
||||||
description: "Window Tag Sublet",
|
description: "",
|
||||||
key: "window_tag_sublet",
|
key: "window_tag_sublet",
|
||||||
subject: i18n.t("printcenter.jobs.window_tag_sublet"),
|
subject: i18n.t("printcenter.jobs.window_tag_sublet"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -366,7 +364,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
thank_you_ro: {
|
thank_you_ro: {
|
||||||
title: i18n.t("printcenter.jobs.thank_you_ro"),
|
title: i18n.t("printcenter.jobs.thank_you_ro"),
|
||||||
description: "Thank You Letter by RO",
|
description: "",
|
||||||
key: "thank_you_ro",
|
key: "thank_you_ro",
|
||||||
subject: i18n.t("printcenter.jobs.thank_you_ro"),
|
subject: i18n.t("printcenter.jobs.thank_you_ro"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -374,7 +372,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
parts_label_single: {
|
parts_label_single: {
|
||||||
title: i18n.t("printcenter.jobs.parts_label_single"),
|
title: i18n.t("printcenter.jobs.parts_label_single"),
|
||||||
description: "Thank You Letter by RO",
|
description: "",
|
||||||
key: "parts_label_single",
|
key: "parts_label_single",
|
||||||
subject: i18n.t("printcenter.jobs.parts_label_single"),
|
subject: i18n.t("printcenter.jobs.parts_label_single"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -383,7 +381,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
envelope_return_address: {
|
envelope_return_address: {
|
||||||
title: i18n.t("printcenter.jobs.envelope_return_address"),
|
title: i18n.t("printcenter.jobs.envelope_return_address"),
|
||||||
description: "All Jobs Notes",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.envelope_return_address"),
|
subject: i18n.t("printcenter.jobs.envelope_return_address"),
|
||||||
key: "envelope_return_address",
|
key: "envelope_return_address",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -392,7 +390,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
sgi_certificate_of_repairs: {
|
sgi_certificate_of_repairs: {
|
||||||
title: i18n.t("printcenter.jobs.sgi_certificate_of_repairs"),
|
title: i18n.t("printcenter.jobs.sgi_certificate_of_repairs"),
|
||||||
description: "Thank You Letter by RO",
|
description: "",
|
||||||
key: "sgi_certificate_of_repairs",
|
key: "sgi_certificate_of_repairs",
|
||||||
subject: i18n.t("printcenter.jobs.sgi_certificate_of_repairs"),
|
subject: i18n.t("printcenter.jobs.sgi_certificate_of_repairs"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -403,7 +401,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
sgi_windshield_auth: {
|
sgi_windshield_auth: {
|
||||||
title: i18n.t("printcenter.jobs.sgi_windshield_auth"),
|
title: i18n.t("printcenter.jobs.sgi_windshield_auth"),
|
||||||
description: "Thank You Letter by RO",
|
description: "",
|
||||||
key: "sgi_windshield_auth",
|
key: "sgi_windshield_auth",
|
||||||
subject: i18n.t("printcenter.jobs.sgi_windshield_auth"),
|
subject: i18n.t("printcenter.jobs.sgi_windshield_auth"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -414,7 +412,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
mpi_final_acct_sheet: {
|
mpi_final_acct_sheet: {
|
||||||
title: i18n.t("printcenter.jobs.mpi_final_acct_sheet"),
|
title: i18n.t("printcenter.jobs.mpi_final_acct_sheet"),
|
||||||
description: "Thank You Letter by RO",
|
description: "",
|
||||||
key: "mpi_final_acct_sheet",
|
key: "mpi_final_acct_sheet",
|
||||||
subject: i18n.t("printcenter.jobs.mpi_final_acct_sheet"),
|
subject: i18n.t("printcenter.jobs.mpi_final_acct_sheet"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -425,7 +423,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
mpi_eglass_auth: {
|
mpi_eglass_auth: {
|
||||||
title: i18n.t("printcenter.jobs.mpi_eglass_auth"),
|
title: i18n.t("printcenter.jobs.mpi_eglass_auth"),
|
||||||
description: "Thank You Letter by RO",
|
description: "",
|
||||||
key: "mpi_eglass_auth",
|
key: "mpi_eglass_auth",
|
||||||
subject: i18n.t("printcenter.jobs.mpi_eglass_auth"),
|
subject: i18n.t("printcenter.jobs.mpi_eglass_auth"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -436,7 +434,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
mpi_animal_checklist: {
|
mpi_animal_checklist: {
|
||||||
title: i18n.t("printcenter.jobs.mpi_animal_checklist"),
|
title: i18n.t("printcenter.jobs.mpi_animal_checklist"),
|
||||||
description: "Thank You Letter by RO",
|
description: "",
|
||||||
key: "mpi_animal_checklist",
|
key: "mpi_animal_checklist",
|
||||||
subject: i18n.t("printcenter.jobs.mpi_animal_checklist"),
|
subject: i18n.t("printcenter.jobs.mpi_animal_checklist"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -447,7 +445,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
ab_proof_of_loss: {
|
ab_proof_of_loss: {
|
||||||
title: i18n.t("printcenter.jobs.ab_proof_of_loss"),
|
title: i18n.t("printcenter.jobs.ab_proof_of_loss"),
|
||||||
description: "Thank You Letter by RO",
|
description: "",
|
||||||
key: "ab_proof_of_loss",
|
key: "ab_proof_of_loss",
|
||||||
subject: i18n.t("printcenter.jobs.ab_proof_of_loss"),
|
subject: i18n.t("printcenter.jobs.ab_proof_of_loss"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -458,7 +456,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
// parts_label_multi: {
|
// parts_label_multi: {
|
||||||
// title: i18n.t("printcenter.jobs.parts_label_multi"),
|
// title: i18n.t("printcenter.jobs.parts_label_multi"),
|
||||||
// description: "Thank You Letter by RO",
|
// description: "",
|
||||||
// key: "parts_label_multi",
|
// key: "parts_label_multi",
|
||||||
// subject: i18n.t("printcenter.jobs.parts_label_multi"),
|
// subject: i18n.t("printcenter.jobs.parts_label_multi"),
|
||||||
// disabled: false,
|
// disabled: false,
|
||||||
@@ -466,7 +464,7 @@ export const TemplateList = (type, context) => {
|
|||||||
// },
|
// },
|
||||||
iou_form: {
|
iou_form: {
|
||||||
title: i18n.t("printcenter.jobs.iou_form"),
|
title: i18n.t("printcenter.jobs.iou_form"),
|
||||||
description: "CASL Authorization",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.iou_form"),
|
subject: i18n.t("printcenter.jobs.iou_form"),
|
||||||
key: "iou_form",
|
key: "iou_form",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -474,7 +472,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
lag_time_ro: {
|
lag_time_ro: {
|
||||||
title: i18n.t("printcenter.jobs.lag_time_ro"),
|
title: i18n.t("printcenter.jobs.lag_time_ro"),
|
||||||
description: "CASL Authorization",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.lag_time_ro"),
|
subject: i18n.t("printcenter.jobs.lag_time_ro"),
|
||||||
key: "lag_time_ro",
|
key: "lag_time_ro",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -482,7 +480,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
rental_reservation: {
|
rental_reservation: {
|
||||||
title: i18n.t("printcenter.jobs.rental_reservation"),
|
title: i18n.t("printcenter.jobs.rental_reservation"),
|
||||||
description: "CASL Authorization",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.rental_reservation"),
|
subject: i18n.t("printcenter.jobs.rental_reservation"),
|
||||||
key: "rental_reservation",
|
key: "rental_reservation",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -490,53 +488,61 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
timetickets_ro: {
|
timetickets_ro: {
|
||||||
title: i18n.t("printcenter.jobs.timetickets_ro"),
|
title: i18n.t("printcenter.jobs.timetickets_ro"),
|
||||||
description: "CASL Authorization",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.timetickets_ro"),
|
subject: i18n.t("printcenter.jobs.timetickets_ro"),
|
||||||
key: "timetickets_ro",
|
key: "timetickets_ro",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
group: "financial",
|
group: "financial",
|
||||||
},
|
},
|
||||||
|
dms_posting_sheet: {
|
||||||
|
title: i18n.t("printcenter.jobs.dms_posting_sheet"),
|
||||||
|
description: "",
|
||||||
|
subject: i18n.t("printcenter.jobs.dms_posting_sheet"),
|
||||||
|
key: "dms_posting_sheet",
|
||||||
|
disabled: false,
|
||||||
|
group: "financial",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(!type || type === "job_special"
|
...(!type || type === "job_special"
|
||||||
? {
|
? {
|
||||||
special_thirdpartypayer: {
|
special_thirdpartypayer: {
|
||||||
title: i18n.t("printcenter.jobs.thirdpartypayer"),
|
title: i18n.t("printcenter.jobs.thirdpartypayer"),
|
||||||
description: "CSI invite",
|
description: "",
|
||||||
key: "special_thirdpartypayer",
|
key: "special_thirdpartypayer",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
folder_label_multiple: {
|
folder_label_multiple: {
|
||||||
title: i18n.t("printcenter.jobs.folder_label_multiple"),
|
title: i18n.t("printcenter.jobs.folder_label_multiple"),
|
||||||
description: "Folder Label Multiple",
|
description: "",
|
||||||
key: "folder_label_multiple",
|
key: "folder_label_multiple",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
parts_label_multiple: {
|
parts_label_multiple: {
|
||||||
title: i18n.t("printcenter.jobs.parts_label_multiple"),
|
title: i18n.t("printcenter.jobs.parts_label_multiple"),
|
||||||
description: "Parts Label Multiple",
|
description: "",
|
||||||
key: "parts_label_multiple",
|
key: "parts_label_multiple",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
parts_invoice_label_single: {
|
parts_invoice_label_single: {
|
||||||
title: i18n.t("printcenter.jobs.parts_invoice_label_single"),
|
title: i18n.t("printcenter.jobs.parts_invoice_label_single"),
|
||||||
description: "Parts Label Multiple",
|
description: "",
|
||||||
key: "parts_invoice_label_single",
|
key: "parts_invoice_label_single",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
ignoreCustomMargins: true,
|
ignoreCustomMargins: true,
|
||||||
},
|
},
|
||||||
csi_invitation_action: {
|
csi_invitation_action: {
|
||||||
title: i18n.t("printcenter.jobs.csi_invitation_action"),
|
title: i18n.t("printcenter.jobs.csi_invitation_action"),
|
||||||
description: "CSI invite",
|
description: "",
|
||||||
key: "csi_invitation_action",
|
key: "csi_invitation_action",
|
||||||
subject: i18n.t("printcenter.jobs.csi_invitation_action"),
|
subject: i18n.t("printcenter.jobs.csi_invitation_action"),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
individual_job_note: {
|
individual_job_note: {
|
||||||
title: i18n.t("printcenter.jobs.individual_job_note"),
|
title: i18n.t("printcenter.jobs.individual_job_note"),
|
||||||
description: "CSI invite",
|
description: "",
|
||||||
key: "individual_job_note",
|
key: "individual_job_note",
|
||||||
subject: i18n.t("printcenter.jobs.individual_job_note", {
|
subject: i18n.t("printcenter.subjects.jobs.individual_job_note", {
|
||||||
ro_number: (context && context.ro_number) || "",
|
ro_number: (context && context.ro_number) || "",
|
||||||
}),
|
}),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -547,7 +553,7 @@ export const TemplateList = (type, context) => {
|
|||||||
? {
|
? {
|
||||||
appointment_confirmation: {
|
appointment_confirmation: {
|
||||||
title: i18n.t("printcenter.appointments.appointment_confirmation"),
|
title: i18n.t("printcenter.appointments.appointment_confirmation"),
|
||||||
description: "Appointment Confirmation",
|
description: "",
|
||||||
subject: i18n.t(
|
subject: i18n.t(
|
||||||
"printcenter.appointments.appointment_confirmation"
|
"printcenter.appointments.appointment_confirmation"
|
||||||
),
|
),
|
||||||
@@ -560,7 +566,7 @@ export const TemplateList = (type, context) => {
|
|||||||
? {
|
? {
|
||||||
parts_order: {
|
parts_order: {
|
||||||
title: i18n.t("printcenter.jobs.parts_order"),
|
title: i18n.t("printcenter.jobs.parts_order"),
|
||||||
description: "Parts Order",
|
description: "",
|
||||||
key: "parts_order",
|
key: "parts_order",
|
||||||
subject: i18n.t("printcenter.subjects.jobs.parts_order", {
|
subject: i18n.t("printcenter.subjects.jobs.parts_order", {
|
||||||
ro_number: context && context.job && context.job.ro_number,
|
ro_number: context && context.job && context.job.ro_number,
|
||||||
@@ -574,7 +580,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
sublet_order: {
|
sublet_order: {
|
||||||
title: i18n.t("printcenter.jobs.sublet_order"),
|
title: i18n.t("printcenter.jobs.sublet_order"),
|
||||||
description: "Parts Order",
|
description: "",
|
||||||
key: "sublet_order",
|
key: "sublet_order",
|
||||||
subject: i18n.t("printcenter.subjects.jobs.sublet_order", {
|
subject: i18n.t("printcenter.subjects.jobs.sublet_order", {
|
||||||
ro_number: context && context.job && context.job.ro_number,
|
ro_number: context && context.job && context.job.ro_number,
|
||||||
@@ -589,7 +595,7 @@ export const TemplateList = (type, context) => {
|
|||||||
parts_return_slip: {
|
parts_return_slip: {
|
||||||
title: i18n.t("printcenter.jobs.parts_return_slip"),
|
title: i18n.t("printcenter.jobs.parts_return_slip"),
|
||||||
subject: i18n.t("printcenter.jobs.parts_return_slip"),
|
subject: i18n.t("printcenter.jobs.parts_return_slip"),
|
||||||
description: "Parts Return",
|
description: "",
|
||||||
key: "parts_return_slip",
|
key: "parts_return_slip",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
@@ -599,7 +605,7 @@ export const TemplateList = (type, context) => {
|
|||||||
? {
|
? {
|
||||||
payment_receipt: {
|
payment_receipt: {
|
||||||
title: i18n.t("printcenter.jobs.payment_receipt"),
|
title: i18n.t("printcenter.jobs.payment_receipt"),
|
||||||
description: "Payment Receipt",
|
description: "",
|
||||||
subject: i18n.t("printcenter.jobs.payment_receipt"),
|
subject: i18n.t("printcenter.jobs.payment_receipt"),
|
||||||
key: "payment_receipt",
|
key: "payment_receipt",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -622,7 +628,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "sales",
|
group: "sales",
|
||||||
},
|
},
|
||||||
|
|
||||||
hours_sold_detail_closed_ins_co: {
|
hours_sold_detail_closed_ins_co: {
|
||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"reportcenter.templates.hours_sold_detail_closed_ins_co"
|
"reportcenter.templates.hours_sold_detail_closed_ins_co"
|
||||||
@@ -640,7 +645,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "sales",
|
group: "sales",
|
||||||
},
|
},
|
||||||
|
|
||||||
hours_sold_summary_closed: {
|
hours_sold_summary_closed: {
|
||||||
title: i18n.t("reportcenter.templates.hours_sold_summary_closed"),
|
title: i18n.t("reportcenter.templates.hours_sold_summary_closed"),
|
||||||
description: "",
|
description: "",
|
||||||
@@ -654,7 +658,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "sales",
|
group: "sales",
|
||||||
},
|
},
|
||||||
|
|
||||||
hours_sold_summary_closed_ins_co: {
|
hours_sold_summary_closed_ins_co: {
|
||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"reportcenter.templates.hours_sold_summary_closed_ins_co"
|
"reportcenter.templates.hours_sold_summary_closed_ins_co"
|
||||||
@@ -672,7 +675,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "sales",
|
group: "sales",
|
||||||
},
|
},
|
||||||
|
|
||||||
hours_sold_detail_open: {
|
hours_sold_detail_open: {
|
||||||
title: i18n.t("reportcenter.templates.hours_sold_detail_open"),
|
title: i18n.t("reportcenter.templates.hours_sold_detail_open"),
|
||||||
description: "",
|
description: "",
|
||||||
@@ -686,7 +688,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "sales",
|
group: "sales",
|
||||||
},
|
},
|
||||||
|
|
||||||
hours_sold_detail_open_ins_co: {
|
hours_sold_detail_open_ins_co: {
|
||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"reportcenter.templates.hours_sold_detail_open_ins_co"
|
"reportcenter.templates.hours_sold_detail_open_ins_co"
|
||||||
@@ -704,7 +705,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "sales",
|
group: "sales",
|
||||||
},
|
},
|
||||||
|
|
||||||
hours_sold_summary_open: {
|
hours_sold_summary_open: {
|
||||||
title: i18n.t("reportcenter.templates.hours_sold_summary_open"),
|
title: i18n.t("reportcenter.templates.hours_sold_summary_open"),
|
||||||
description: "",
|
description: "",
|
||||||
@@ -718,7 +718,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "sales",
|
group: "sales",
|
||||||
},
|
},
|
||||||
|
|
||||||
hours_sold_summary_open_ins_co: {
|
hours_sold_summary_open_ins_co: {
|
||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"reportcenter.templates.hours_sold_summary_open_ins_co"
|
"reportcenter.templates.hours_sold_summary_open_ins_co"
|
||||||
@@ -736,7 +735,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "sales",
|
group: "sales",
|
||||||
},
|
},
|
||||||
|
|
||||||
hours_sold_detail_closed_csr: {
|
hours_sold_detail_closed_csr: {
|
||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"reportcenter.templates.hours_sold_detail_closed_csr"
|
"reportcenter.templates.hours_sold_detail_closed_csr"
|
||||||
@@ -1090,7 +1088,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "customers",
|
group: "customers",
|
||||||
},
|
},
|
||||||
|
|
||||||
schedule: {
|
schedule: {
|
||||||
title: i18n.t("reportcenter.templates.schedule"),
|
title: i18n.t("reportcenter.templates.schedule"),
|
||||||
subject: i18n.t("reportcenter.templates.schedule"),
|
subject: i18n.t("reportcenter.templates.schedule"),
|
||||||
@@ -1102,7 +1099,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "customers",
|
group: "customers",
|
||||||
},
|
},
|
||||||
|
|
||||||
timetickets: {
|
timetickets: {
|
||||||
title: i18n.t("reportcenter.templates.timetickets"),
|
title: i18n.t("reportcenter.templates.timetickets"),
|
||||||
subject: i18n.t("reportcenter.templates.timetickets"),
|
subject: i18n.t("reportcenter.templates.timetickets"),
|
||||||
@@ -1126,7 +1122,6 @@ export const TemplateList = (type, context) => {
|
|||||||
title: i18n.t("reportcenter.templates.attendance_detail"),
|
title: i18n.t("reportcenter.templates.attendance_detail"),
|
||||||
subject: i18n.t("reportcenter.templates.attendance_detail"),
|
subject: i18n.t("reportcenter.templates.attendance_detail"),
|
||||||
key: "attendance_detail",
|
key: "attendance_detail",
|
||||||
|
|
||||||
disabled: false,
|
disabled: false,
|
||||||
rangeFilter: {
|
rangeFilter: {
|
||||||
object: i18n.t("reportcenter.labels.objects.timetickets"),
|
object: i18n.t("reportcenter.labels.objects.timetickets"),
|
||||||
@@ -1138,7 +1133,6 @@ export const TemplateList = (type, context) => {
|
|||||||
title: i18n.t("reportcenter.templates.attendance_summary"),
|
title: i18n.t("reportcenter.templates.attendance_summary"),
|
||||||
subject: i18n.t("reportcenter.templates.attendance_summary"),
|
subject: i18n.t("reportcenter.templates.attendance_summary"),
|
||||||
key: "attendance_summary",
|
key: "attendance_summary",
|
||||||
|
|
||||||
disabled: false,
|
disabled: false,
|
||||||
rangeFilter: {
|
rangeFilter: {
|
||||||
object: i18n.t("reportcenter.labels.objects.timetickets"),
|
object: i18n.t("reportcenter.labels.objects.timetickets"),
|
||||||
@@ -1158,7 +1152,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "payroll",
|
group: "payroll",
|
||||||
},
|
},
|
||||||
|
|
||||||
timetickets_summary: {
|
timetickets_summary: {
|
||||||
title: i18n.t("reportcenter.templates.timetickets_summary"),
|
title: i18n.t("reportcenter.templates.timetickets_summary"),
|
||||||
subject: i18n.t("reportcenter.templates.timetickets_summary"),
|
subject: i18n.t("reportcenter.templates.timetickets_summary"),
|
||||||
@@ -1171,7 +1164,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "payroll",
|
group: "payroll",
|
||||||
},
|
},
|
||||||
|
|
||||||
estimator_detail: {
|
estimator_detail: {
|
||||||
title: i18n.t("reportcenter.templates.estimator_detail"),
|
title: i18n.t("reportcenter.templates.estimator_detail"),
|
||||||
description: "",
|
description: "",
|
||||||
@@ -1224,7 +1216,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "purchases",
|
group: "purchases",
|
||||||
},
|
},
|
||||||
|
|
||||||
void_ros: {
|
void_ros: {
|
||||||
title: i18n.t("reportcenter.templates.void_ros"),
|
title: i18n.t("reportcenter.templates.void_ros"),
|
||||||
description: "",
|
description: "",
|
||||||
@@ -1329,7 +1320,6 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "sales",
|
group: "sales",
|
||||||
},
|
},
|
||||||
|
|
||||||
gsr_by_estimator: {
|
gsr_by_estimator: {
|
||||||
title: i18n.t("reportcenter.templates.gsr_by_estimator"),
|
title: i18n.t("reportcenter.templates.gsr_by_estimator"),
|
||||||
description: "",
|
description: "",
|
||||||
@@ -1814,7 +1804,9 @@ export const TemplateList = (type, context) => {
|
|||||||
group: "jobs",
|
group: "jobs",
|
||||||
},
|
},
|
||||||
purchase_return_ratio_grouped_by_vendor_detail: {
|
purchase_return_ratio_grouped_by_vendor_detail: {
|
||||||
title: i18n.t("reportcenter.templates.purchase_return_ratio_grouped_by_vendor_detail"),
|
title: i18n.t(
|
||||||
|
"reportcenter.templates.purchase_return_ratio_grouped_by_vendor_detail"
|
||||||
|
),
|
||||||
subject: i18n.t(
|
subject: i18n.t(
|
||||||
"reportcenter.templates.purchase_return_ratio_grouped_by_vendor_detail"
|
"reportcenter.templates.purchase_return_ratio_grouped_by_vendor_detail"
|
||||||
),
|
),
|
||||||
@@ -1828,7 +1820,9 @@ export const TemplateList = (type, context) => {
|
|||||||
group: "purchases",
|
group: "purchases",
|
||||||
},
|
},
|
||||||
purchase_return_ratio_grouped_by_vendor_summary: {
|
purchase_return_ratio_grouped_by_vendor_summary: {
|
||||||
title: i18n.t("reportcenter.templates.purchase_return_ratio_grouped_by_vendor_summary"),
|
title: i18n.t(
|
||||||
|
"reportcenter.templates.purchase_return_ratio_grouped_by_vendor_summary"
|
||||||
|
),
|
||||||
subject: i18n.t(
|
subject: i18n.t(
|
||||||
"reportcenter.templates.purchase_return_ratio_grouped_by_vendor_summary"
|
"reportcenter.templates.purchase_return_ratio_grouped_by_vendor_summary"
|
||||||
),
|
),
|
||||||
@@ -1843,9 +1837,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
production_over_time: {
|
production_over_time: {
|
||||||
title: i18n.t("reportcenter.templates.production_over_time"),
|
title: i18n.t("reportcenter.templates.production_over_time"),
|
||||||
subject: i18n.t(
|
subject: i18n.t("reportcenter.templates.production_over_time"),
|
||||||
"reportcenter.templates.production_over_time"
|
|
||||||
),
|
|
||||||
key: "production_over_time",
|
key: "production_over_time",
|
||||||
//idtype: "vendor",
|
//idtype: "vendor",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -1857,9 +1849,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
customer_list: {
|
customer_list: {
|
||||||
title: i18n.t("reportcenter.templates.customer_list"),
|
title: i18n.t("reportcenter.templates.customer_list"),
|
||||||
subject: i18n.t(
|
subject: i18n.t("reportcenter.templates.customer_list"),
|
||||||
"reportcenter.templates.customer_list"
|
|
||||||
),
|
|
||||||
key: "customer_list",
|
key: "customer_list",
|
||||||
//idtype: "vendor",
|
//idtype: "vendor",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -1869,6 +1859,32 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
group: "customers",
|
group: "customers",
|
||||||
},
|
},
|
||||||
|
exported_gsr_by_ro: {
|
||||||
|
title: i18n.t("reportcenter.templates.exported_gsr_by_ro"),
|
||||||
|
subject: i18n.t("reportcenter.templates.exported_gsr_by_ro"),
|
||||||
|
key: "exported_gsr_by_ro",
|
||||||
|
//idtype: "vendor",
|
||||||
|
reporttype: "excel",
|
||||||
|
disabled: false,
|
||||||
|
rangeFilter: {
|
||||||
|
object: i18n.t("reportcenter.labels.objects.jobs"),
|
||||||
|
field: i18n.t("jobs.fields.date_exported"),
|
||||||
|
},
|
||||||
|
group: "sales",
|
||||||
|
},
|
||||||
|
exported_gsr_by_ro_labor: {
|
||||||
|
title: i18n.t("reportcenter.templates.exported_gsr_by_ro_labor"),
|
||||||
|
subject: i18n.t("reportcenter.templates.exported_gsr_by_ro_labor"),
|
||||||
|
key: "exported_gsr_by_ro_labor",
|
||||||
|
//idtype: "vendor",
|
||||||
|
reporttype: "excel",
|
||||||
|
disabled: false,
|
||||||
|
rangeFilter: {
|
||||||
|
object: i18n.t("reportcenter.labels.objects.jobs"),
|
||||||
|
field: i18n.t("jobs.fields.date_exported"),
|
||||||
|
},
|
||||||
|
group: "sales",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(!type || type === "courtesycarcontract"
|
...(!type || type === "courtesycarcontract"
|
||||||
@@ -1877,7 +1893,7 @@ export const TemplateList = (type, context) => {
|
|||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"printcenter.courtesycarcontract.courtesy_car_contract"
|
"printcenter.courtesycarcontract.courtesy_car_contract"
|
||||||
),
|
),
|
||||||
description: "Est Detail",
|
description: "",
|
||||||
subject: i18n.t(
|
subject: i18n.t(
|
||||||
"printcenter.courtesycarcontract.courtesy_car_contract"
|
"printcenter.courtesycarcontract.courtesy_car_contract"
|
||||||
),
|
),
|
||||||
@@ -1886,7 +1902,7 @@ export const TemplateList = (type, context) => {
|
|||||||
},
|
},
|
||||||
courtesy_car_terms: {
|
courtesy_car_terms: {
|
||||||
title: i18n.t("printcenter.courtesycarcontract.courtesy_car_terms"),
|
title: i18n.t("printcenter.courtesycarcontract.courtesy_car_terms"),
|
||||||
description: "Est Detail",
|
description: "",
|
||||||
subject: i18n.t(
|
subject: i18n.t(
|
||||||
"printcenter.courtesycarcontract.courtesy_car_terms"
|
"printcenter.courtesycarcontract.courtesy_car_terms"
|
||||||
),
|
),
|
||||||
@@ -1897,7 +1913,7 @@ export const TemplateList = (type, context) => {
|
|||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"printcenter.courtesycarcontract.courtesy_car_impound"
|
"printcenter.courtesycarcontract.courtesy_car_impound"
|
||||||
),
|
),
|
||||||
description: "Est Detail",
|
description: "",
|
||||||
subject: i18n.t(
|
subject: i18n.t(
|
||||||
"printcenter.courtesycarcontract.courtesy_car_impound"
|
"printcenter.courtesycarcontract.courtesy_car_impound"
|
||||||
),
|
),
|
||||||
@@ -1912,7 +1928,7 @@ export const TemplateList = (type, context) => {
|
|||||||
title: i18n.t(
|
title: i18n.t(
|
||||||
"printcenter.courtesycarcontract.courtesy_car_inventory"
|
"printcenter.courtesycarcontract.courtesy_car_inventory"
|
||||||
),
|
),
|
||||||
description: "Est Detail",
|
description: "",
|
||||||
subject: i18n.t(
|
subject: i18n.t(
|
||||||
"printcenter.courtesycarcontract.courtesy_car_inventory"
|
"printcenter.courtesycarcontract.courtesy_car_inventory"
|
||||||
),
|
),
|
||||||
@@ -1925,7 +1941,7 @@ export const TemplateList = (type, context) => {
|
|||||||
? {
|
? {
|
||||||
inhouse_invoice: {
|
inhouse_invoice: {
|
||||||
title: i18n.t("printcenter.bills.inhouse_invoice"),
|
title: i18n.t("printcenter.bills.inhouse_invoice"),
|
||||||
description: "Est Detail",
|
description: "",
|
||||||
subject: i18n.t("printcenter.bills.inhouse_invoice"),
|
subject: i18n.t("printcenter.bills.inhouse_invoice"),
|
||||||
key: "inhouse_invoice",
|
key: "inhouse_invoice",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@@ -1936,7 +1952,7 @@ export const TemplateList = (type, context) => {
|
|||||||
? {
|
? {
|
||||||
// timetickets: {
|
// timetickets: {
|
||||||
// title: i18n.t("printcenter.timetickets.timetickets"),
|
// title: i18n.t("printcenter.timetickets.timetickets"),
|
||||||
// description: "Est Detail",
|
// description: "",
|
||||||
// subject: `${i18n.t("printcenter.timetickets.timetickets")} - ${
|
// subject: `${i18n.t("printcenter.timetickets.timetickets")} - ${
|
||||||
// context && context.job && context.job.ro_number
|
// context && context.job && context.job.ro_number
|
||||||
// }`,
|
// }`,
|
||||||
@@ -1949,21 +1965,20 @@ export const TemplateList = (type, context) => {
|
|||||||
? {
|
? {
|
||||||
purchases_by_vendor_detailed: {
|
purchases_by_vendor_detailed: {
|
||||||
title: i18n.t("printcenter.vendors.purchases_by_vendor_detailed"),
|
title: i18n.t("printcenter.vendors.purchases_by_vendor_detailed"),
|
||||||
description: "Est Detail",
|
description: "",
|
||||||
subject: i18n.t("printcenter.vendors.purchases_by_vendor_detailed"),
|
subject: i18n.t("printcenter.vendors.purchases_by_vendor_detailed"),
|
||||||
key: "purchases_by_vendor_detailed",
|
key: "purchases_by_vendor_detailed",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
purchases_by_vendor_summary: {
|
purchases_by_vendor_summary: {
|
||||||
title: i18n.t("printcenter.vendors.purchases_by_vendor_summary"),
|
title: i18n.t("printcenter.vendors.purchases_by_vendor_summary"),
|
||||||
description: "Est Detail",
|
description: "",
|
||||||
subject: i18n.t("printcenter.vendors.purchases_by_vendor_summary"),
|
subject: i18n.t("printcenter.vendors.purchases_by_vendor_summary"),
|
||||||
key: "purchases_by_vendor_summary",
|
key: "purchases_by_vendor_summary",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
|
|
||||||
...(!type || type === "production"
|
...(!type || type === "production"
|
||||||
? {
|
? {
|
||||||
production_by_last_name: {
|
production_by_last_name: {
|
||||||
@@ -2030,21 +2045,21 @@ export const TemplateList = (type, context) => {
|
|||||||
? {
|
? {
|
||||||
ca_bc_etf_table: {
|
ca_bc_etf_table: {
|
||||||
title: i18n.t("printcenter.payments.ca_bc_etf_table"),
|
title: i18n.t("printcenter.payments.ca_bc_etf_table"),
|
||||||
description: "Est Detail",
|
description: "",
|
||||||
subject: i18n.t("printcenter.payments.ca_bc_etf_table"),
|
subject: i18n.t("printcenter.payments.ca_bc_etf_table"),
|
||||||
key: "ca_bc_etf_table",
|
key: "ca_bc_etf_table",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
exported_payroll: {
|
exported_payroll: {
|
||||||
title: i18n.t("printcenter.payments.exported_payroll"),
|
title: i18n.t("printcenter.payments.exported_payroll"),
|
||||||
description: "Est Detail",
|
description: "",
|
||||||
subject: i18n.t("printcenter.payments.exported_payroll"),
|
subject: i18n.t("printcenter.payments.exported_payroll"),
|
||||||
key: "exported_payroll",
|
key: "exported_payroll",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
attendance_detail_csv: {
|
attendance_detail_csv: {
|
||||||
title: i18n.t("printcenter.special.attendance_detail_csv"),
|
title: i18n.t("printcenter.special.attendance_detail_csv"),
|
||||||
description: "Est Detail",
|
description: "",
|
||||||
subject: i18n.t("printcenter.special.attendance_detail_csv"),
|
subject: i18n.t("printcenter.special.attendance_detail_csv"),
|
||||||
key: "attendance_detail_csv",
|
key: "attendance_detail_csv",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
|||||||
@@ -3924,14 +3924,6 @@ anymatch@^3.0.3, anymatch@~3.1.2:
|
|||||||
normalize-path "^3.0.0"
|
normalize-path "^3.0.0"
|
||||||
picomatch "^2.0.4"
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
aphrodite@^0.5.0:
|
|
||||||
version "0.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/aphrodite/-/aphrodite-0.5.0.tgz#a4b9a8902662395d2702e70ac7a2b4ca66f25703"
|
|
||||||
integrity sha512-bPcR/68OdLg+16XDYAaKnlGJufxrbOw86ucElS7qHm7Y6ZNvMT/D/VDEEfodjFgfyRyoTeKmSaikULG92kSYvQ==
|
|
||||||
dependencies:
|
|
||||||
asap "^2.0.3"
|
|
||||||
inline-style-prefixer "^2.0.0"
|
|
||||||
|
|
||||||
apollo-link-logger@^2.0.1:
|
apollo-link-logger@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/apollo-link-logger/-/apollo-link-logger-2.0.1.tgz#63d86b4fe550c147c5a52108710075675694905c"
|
resolved "https://registry.yarnpkg.com/apollo-link-logger/-/apollo-link-logger-2.0.1.tgz#63d86b4fe550c147c5a52108710075675694905c"
|
||||||
@@ -4073,7 +4065,7 @@ array.prototype.tosorted@^1.1.1:
|
|||||||
es-shim-unscopables "^1.0.0"
|
es-shim-unscopables "^1.0.0"
|
||||||
get-intrinsic "^1.1.3"
|
get-intrinsic "^1.1.3"
|
||||||
|
|
||||||
asap@^2.0.3, asap@~2.0.6:
|
asap@~2.0.6:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||||
integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
|
integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
|
||||||
@@ -4484,11 +4476,6 @@ boolbase@^1.0.0, boolbase@~1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||||
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
|
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
|
||||||
|
|
||||||
bowser@^1.0.0:
|
|
||||||
version "1.9.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.9.4.tgz#890c58a2813a9d3243704334fa81b96a5c150c9a"
|
|
||||||
integrity sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==
|
|
||||||
|
|
||||||
brace-expansion@^1.1.7:
|
brace-expansion@^1.1.7:
|
||||||
version "1.1.11"
|
version "1.1.11"
|
||||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||||
@@ -6504,7 +6491,7 @@ executable@^4.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
pify "^2.2.0"
|
pify "^2.2.0"
|
||||||
|
|
||||||
exenv@^1.2.2:
|
exenv@^1.2.0:
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
|
resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
|
||||||
integrity sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==
|
integrity sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==
|
||||||
@@ -7404,11 +7391,6 @@ human-signals@^2.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
||||||
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
|
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
|
||||||
|
|
||||||
hyphenate-style-name@^1.0.1:
|
|
||||||
version "1.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
|
|
||||||
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
|
|
||||||
|
|
||||||
i18next-browser-languagedetector@^7.0.1:
|
i18next-browser-languagedetector@^7.0.1:
|
||||||
version "7.0.1"
|
version "7.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.0.1.tgz#ead34592edc96c6c3a618a51cb57ad027c5b5d87"
|
resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.0.1.tgz#ead34592edc96c6c3a618a51cb57ad027c5b5d87"
|
||||||
@@ -7543,14 +7525,6 @@ ini@^1.3.5:
|
|||||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||||
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||||
|
|
||||||
inline-style-prefixer@^2.0.0:
|
|
||||||
version "2.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-2.0.5.tgz#c153c7e88fd84fef5c602e95a8168b2770671fe7"
|
|
||||||
integrity sha512-rlgoApaAAv66JeDFqGYaXwglnlxjyIr7RMaFZqJw4opT0WKnZVXhXMC9SAfuMpN7NELPaImUhJmOO3hAamSlfw==
|
|
||||||
dependencies:
|
|
||||||
bowser "^1.0.0"
|
|
||||||
hyphenate-style-name "^1.0.1"
|
|
||||||
|
|
||||||
internal-slot@^1.0.3:
|
internal-slot@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
|
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
|
||||||
@@ -11157,13 +11131,10 @@ react-error-overlay@6.0.9, react-error-overlay@^6.0.11:
|
|||||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a"
|
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a"
|
||||||
integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==
|
integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==
|
||||||
|
|
||||||
react-grid-gallery@^0.5.5:
|
react-grid-gallery@^1.0.0:
|
||||||
version "0.5.5"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-grid-gallery/-/react-grid-gallery-0.5.5.tgz#1b3f3c23a190834e587ab613c96d53ec3af4f0a2"
|
resolved "https://registry.yarnpkg.com/react-grid-gallery/-/react-grid-gallery-1.0.0.tgz#31604b9488dfa75a899aa39bc8884138f0409a12"
|
||||||
integrity sha512-DkKg2/Am+VZPDG39fazelTcsZSQrfM/YllnIcWToyUEfOZcrzHxUoqCziCkuTPmCuMbHnrjidBFuDbAFgvSnvQ==
|
integrity sha512-S1gr6WXBlPFVrE0x2BHuu7jhyaB61mabcMQyx+8KCgAyKzGza0WF67AfAnS9Q00aurFEq4IP8eqb2Bk5F4RAmQ==
|
||||||
dependencies:
|
|
||||||
prop-types "^15.5.8"
|
|
||||||
react-images "^0.5.16"
|
|
||||||
|
|
||||||
react-grid-layout@^1.3.4:
|
react-grid-layout@^1.3.4:
|
||||||
version "1.3.4"
|
version "1.3.4"
|
||||||
@@ -11189,15 +11160,13 @@ react-icons@^4.7.1:
|
|||||||
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.7.1.tgz#0f4b25a5694e6972677cb189d2a72eabea7a8345"
|
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.7.1.tgz#0f4b25a5694e6972677cb189d2a72eabea7a8345"
|
||||||
integrity sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==
|
integrity sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==
|
||||||
|
|
||||||
react-images@^0.5.16:
|
react-image-lightbox@^5.1.4:
|
||||||
version "0.5.19"
|
version "5.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/react-images/-/react-images-0.5.19.tgz#9339570029e065f9f28a19f03fdb5d9d5aa109d3"
|
resolved "https://registry.yarnpkg.com/react-image-lightbox/-/react-image-lightbox-5.1.4.tgz#5b847dcb79e9efdf9d7cd5621a92e0f156d2cf30"
|
||||||
integrity sha512-B3d4W1uFJj+m17K8S65iAyEJShKGBjPk7n7N1YsPiAydEm8mIq9a6CoeQFMY1d7N2QMs6FBCjT9vELyc5jP5JA==
|
integrity sha512-kTiAODz091bgT7SlWNHab0LSMZAPJtlNWDGKv7pLlLY1krmf7FuG1zxE0wyPpeA8gPdwfr3cu6sPwZRqWsc3Eg==
|
||||||
dependencies:
|
dependencies:
|
||||||
aphrodite "^0.5.0"
|
prop-types "^15.7.2"
|
||||||
prop-types "^15.6.0"
|
react-modal "^3.11.1"
|
||||||
react-scrolllock "^2.0.1"
|
|
||||||
react-transition-group "2"
|
|
||||||
|
|
||||||
react-is@^16.10.2, react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0:
|
react-is@^16.10.2, react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
@@ -11214,11 +11183,21 @@ react-is@^18.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||||
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||||
|
|
||||||
react-lifecycles-compat@^3.0.4:
|
react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||||
|
|
||||||
|
react-modal@^3.11.1:
|
||||||
|
version "3.16.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.16.1.tgz#34018528fc206561b1a5467fc3beeaddafb39b2b"
|
||||||
|
integrity sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==
|
||||||
|
dependencies:
|
||||||
|
exenv "^1.2.0"
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
react-lifecycles-compat "^3.0.0"
|
||||||
|
warning "^4.0.3"
|
||||||
|
|
||||||
react-number-format@^5.1.3:
|
react-number-format@^5.1.3:
|
||||||
version "5.1.3"
|
version "5.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-5.1.3.tgz#5534f5141cea29e0fe889f76c73dfad11ddf2e17"
|
resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-5.1.3.tgz#5534f5141cea29e0fe889f76c73dfad11ddf2e17"
|
||||||
@@ -11240,11 +11219,6 @@ react-overlays@^5.2.1:
|
|||||||
uncontrollable "^7.2.1"
|
uncontrollable "^7.2.1"
|
||||||
warning "^4.0.3"
|
warning "^4.0.3"
|
||||||
|
|
||||||
react-prop-toggle@^1.0.2:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-prop-toggle/-/react-prop-toggle-1.0.2.tgz#8b0b7e74653606b1427cfcf6c4eaa9198330568e"
|
|
||||||
integrity sha512-JmerjAXs7qJ959+d0Ygt7Cb2+4fG+n3I2VXO6JO0AcAY1vkRN/JpZKAN67CMXY889xEJcfylmMPhzvf6nWO68Q==
|
|
||||||
|
|
||||||
react-redux@^7.2.0:
|
react-redux@^7.2.0:
|
||||||
version "7.2.8"
|
version "7.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.8.tgz#a894068315e65de5b1b68899f9c6ee0923dd28de"
|
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.8.tgz#a894068315e65de5b1b68899f9c6ee0923dd28de"
|
||||||
@@ -11373,14 +11347,6 @@ react-scripts@^5.0.1:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "^2.3.2"
|
fsevents "^2.3.2"
|
||||||
|
|
||||||
react-scrolllock@^2.0.1:
|
|
||||||
version "2.0.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-scrolllock/-/react-scrolllock-2.0.7.tgz#3b879e1fe308fc900ab76e226e9be594c41226fd"
|
|
||||||
integrity sha512-Gzpu8+ulxdYcybAgJOFTXc70xs7SBZDQbZNpKzchZUgLCJKjz6lrgESx6LHHZgfELx1xYL4yHu3kYQGQPFas/g==
|
|
||||||
dependencies:
|
|
||||||
exenv "^1.2.2"
|
|
||||||
react-prop-toggle "^1.0.2"
|
|
||||||
|
|
||||||
react-smooth@^2.0.1:
|
react-smooth@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.1.tgz#74c7309916d6ccca182c4b30c8992f179e6c5a05"
|
resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.1.tgz#74c7309916d6ccca182c4b30c8992f179e6c5a05"
|
||||||
@@ -11405,7 +11371,7 @@ react-sublime-video@^0.2.5:
|
|||||||
prop-types "^15.5.10"
|
prop-types "^15.5.10"
|
||||||
rc-tween-one "^1.2.5"
|
rc-tween-one "^1.2.5"
|
||||||
|
|
||||||
react-transition-group@2, react-transition-group@2.9.0:
|
react-transition-group@2.9.0:
|
||||||
version "2.9.0"
|
version "2.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
|
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
|
||||||
integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==
|
integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==
|
||||||
|
|||||||
@@ -673,6 +673,30 @@
|
|||||||
_eq: true
|
_eq: true
|
||||||
- exported:
|
- exported:
|
||||||
_eq: false
|
_eq: false
|
||||||
|
event_triggers:
|
||||||
|
- name: os_bills
|
||||||
|
definition:
|
||||||
|
delete:
|
||||||
|
columns: '*'
|
||||||
|
enable_manual: false
|
||||||
|
insert:
|
||||||
|
columns: '*'
|
||||||
|
update:
|
||||||
|
columns: '*'
|
||||||
|
retry_conf:
|
||||||
|
interval_sec: 10
|
||||||
|
num_retries: 3
|
||||||
|
timeout_sec: 60
|
||||||
|
webhook_from_env: HASURA_API_URL
|
||||||
|
headers:
|
||||||
|
- name: event-secret
|
||||||
|
value_from_env: EVENT_SECRET
|
||||||
|
request_transform:
|
||||||
|
method: POST
|
||||||
|
query_params: {}
|
||||||
|
template_engine: Kriti
|
||||||
|
url: '{{$base_url}}/opensearch'
|
||||||
|
version: 2
|
||||||
- table:
|
- table:
|
||||||
name: bodyshops
|
name: bodyshops
|
||||||
schema: public
|
schema: public
|
||||||
@@ -761,6 +785,13 @@
|
|||||||
table:
|
table:
|
||||||
name: email_audit_trail
|
name: email_audit_trail
|
||||||
schema: public
|
schema: public
|
||||||
|
- name: employee_teams
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: bodyshopid
|
||||||
|
table:
|
||||||
|
name: employee_teams
|
||||||
|
schema: public
|
||||||
- name: employees
|
- name: employees
|
||||||
using:
|
using:
|
||||||
foreign_key_constraint_on:
|
foreign_key_constraint_on:
|
||||||
@@ -824,6 +855,13 @@
|
|||||||
table:
|
table:
|
||||||
name: transitions
|
name: transitions
|
||||||
schema: public
|
schema: public
|
||||||
|
- name: tt_approval_queues
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: bodyshopid
|
||||||
|
table:
|
||||||
|
name: tt_approval_queue
|
||||||
|
schema: public
|
||||||
- name: vehicles
|
- name: vehicles
|
||||||
using:
|
using:
|
||||||
foreign_key_constraint_on:
|
foreign_key_constraint_on:
|
||||||
@@ -903,6 +941,7 @@
|
|||||||
- md_referral_sources
|
- md_referral_sources
|
||||||
- md_responsibility_centers
|
- md_responsibility_centers
|
||||||
- md_ro_statuses
|
- md_ro_statuses
|
||||||
|
- md_tasks_presets
|
||||||
- md_to_emails
|
- md_to_emails
|
||||||
- messagingservicesid
|
- messagingservicesid
|
||||||
- pbs_configuration
|
- pbs_configuration
|
||||||
@@ -928,8 +967,10 @@
|
|||||||
- textid
|
- textid
|
||||||
- timezone
|
- timezone
|
||||||
- tt_allow_post_to_invoiced
|
- tt_allow_post_to_invoiced
|
||||||
|
- tt_enforce_hours_for_tech_console
|
||||||
- updated_at
|
- updated_at
|
||||||
- use_fippa
|
- use_fippa
|
||||||
|
- use_paint_scale_data
|
||||||
- uselocalmediaserver
|
- uselocalmediaserver
|
||||||
- website
|
- website
|
||||||
- workingdays
|
- workingdays
|
||||||
@@ -998,6 +1039,7 @@
|
|||||||
- md_referral_sources
|
- md_referral_sources
|
||||||
- md_responsibility_centers
|
- md_responsibility_centers
|
||||||
- md_ro_statuses
|
- md_ro_statuses
|
||||||
|
- md_tasks_presets
|
||||||
- md_to_emails
|
- md_to_emails
|
||||||
- pbs_configuration
|
- pbs_configuration
|
||||||
- phone
|
- phone
|
||||||
@@ -1016,8 +1058,10 @@
|
|||||||
- target_touchtime
|
- target_touchtime
|
||||||
- timezone
|
- timezone
|
||||||
- tt_allow_post_to_invoiced
|
- tt_allow_post_to_invoiced
|
||||||
|
- tt_enforce_hours_for_tech_console
|
||||||
- updated_at
|
- updated_at
|
||||||
- use_fippa
|
- use_fippa
|
||||||
|
- use_paint_scale_data
|
||||||
- uselocalmediaserver
|
- uselocalmediaserver
|
||||||
- website
|
- website
|
||||||
- workingdays
|
- workingdays
|
||||||
@@ -1945,6 +1989,165 @@
|
|||||||
- active:
|
- active:
|
||||||
_eq: true
|
_eq: true
|
||||||
check: null
|
check: null
|
||||||
|
- table:
|
||||||
|
name: employee_team_members
|
||||||
|
schema: public
|
||||||
|
object_relationships:
|
||||||
|
- name: employee
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: employeeid
|
||||||
|
- name: employee_team
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: teamid
|
||||||
|
insert_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
check:
|
||||||
|
employee_team:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
columns:
|
||||||
|
- labor_rates
|
||||||
|
- percentage
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- teamid
|
||||||
|
select_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- labor_rates
|
||||||
|
- percentage
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- teamid
|
||||||
|
filter:
|
||||||
|
employee_team:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
update_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- labor_rates
|
||||||
|
- percentage
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- teamid
|
||||||
|
filter:
|
||||||
|
employee_team:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
check: null
|
||||||
|
delete_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
backend_only: false
|
||||||
|
filter:
|
||||||
|
employee_team:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
- table:
|
||||||
|
name: employee_teams
|
||||||
|
schema: public
|
||||||
|
object_relationships:
|
||||||
|
- name: bodyshop
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: bodyshopid
|
||||||
|
array_relationships:
|
||||||
|
- name: employee_team_members
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: teamid
|
||||||
|
table:
|
||||||
|
name: employee_team_members
|
||||||
|
schema: public
|
||||||
|
insert_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
check:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
columns:
|
||||||
|
- active
|
||||||
|
- name
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
- bodyshopid
|
||||||
|
- id
|
||||||
|
select_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- active
|
||||||
|
- name
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
- bodyshopid
|
||||||
|
- id
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
update_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- active
|
||||||
|
- bodyshopid
|
||||||
|
- name
|
||||||
|
- updated_at
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
check: null
|
||||||
- table:
|
- table:
|
||||||
name: employee_vacation
|
name: employee_vacation
|
||||||
schema: public
|
schema: public
|
||||||
@@ -2045,6 +2248,13 @@
|
|||||||
table:
|
table:
|
||||||
name: allocations
|
name: allocations
|
||||||
schema: public
|
schema: public
|
||||||
|
- name: employee_team_members
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: employeeid
|
||||||
|
table:
|
||||||
|
name: employee_team_members
|
||||||
|
schema: public
|
||||||
- name: employee_vacations
|
- name: employee_vacations
|
||||||
using:
|
using:
|
||||||
foreign_key_constraint_on:
|
foreign_key_constraint_on:
|
||||||
@@ -2087,6 +2297,13 @@
|
|||||||
table:
|
table:
|
||||||
name: timetickets
|
name: timetickets
|
||||||
schema: public
|
schema: public
|
||||||
|
- name: tt_approval_queues
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: employeeid
|
||||||
|
table:
|
||||||
|
name: tt_approval_queue
|
||||||
|
schema: public
|
||||||
insert_permissions:
|
insert_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
@@ -2218,30 +2435,32 @@
|
|||||||
- active:
|
- active:
|
||||||
_eq: true
|
_eq: true
|
||||||
columns:
|
columns:
|
||||||
- id
|
|
||||||
- created_at
|
|
||||||
- updated_at
|
|
||||||
- jobid
|
|
||||||
- billid
|
- billid
|
||||||
|
- bodyshopid
|
||||||
|
- created_at
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- message
|
||||||
|
- metadata
|
||||||
- paymentid
|
- paymentid
|
||||||
- successful
|
- successful
|
||||||
- message
|
- updated_at
|
||||||
- bodyshopid
|
|
||||||
- useremail
|
- useremail
|
||||||
select_permissions:
|
select_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
columns:
|
columns:
|
||||||
- successful
|
|
||||||
- message
|
|
||||||
- useremail
|
|
||||||
- created_at
|
|
||||||
- updated_at
|
|
||||||
- billid
|
- billid
|
||||||
- bodyshopid
|
- bodyshopid
|
||||||
|
- created_at
|
||||||
- id
|
- id
|
||||||
- jobid
|
- jobid
|
||||||
|
- message
|
||||||
|
- metadata
|
||||||
- paymentid
|
- paymentid
|
||||||
|
- successful
|
||||||
|
- updated_at
|
||||||
|
- useremail
|
||||||
filter:
|
filter:
|
||||||
bodyshop:
|
bodyshop:
|
||||||
associations:
|
associations:
|
||||||
@@ -2493,6 +2712,7 @@
|
|||||||
_eq: true
|
_eq: true
|
||||||
columns:
|
columns:
|
||||||
- act_price
|
- act_price
|
||||||
|
- act_price_before_ppc
|
||||||
- ah_detail_line
|
- ah_detail_line
|
||||||
- alt_co_id
|
- alt_co_id
|
||||||
- alt_overrd
|
- alt_overrd
|
||||||
@@ -2559,6 +2779,7 @@
|
|||||||
permission:
|
permission:
|
||||||
columns:
|
columns:
|
||||||
- act_price
|
- act_price
|
||||||
|
- act_price_before_ppc
|
||||||
- ah_detail_line
|
- ah_detail_line
|
||||||
- alt_co_id
|
- alt_co_id
|
||||||
- alt_overrd
|
- alt_overrd
|
||||||
@@ -2637,6 +2858,7 @@
|
|||||||
permission:
|
permission:
|
||||||
columns:
|
columns:
|
||||||
- act_price
|
- act_price
|
||||||
|
- act_price_before_ppc
|
||||||
- ah_detail_line
|
- ah_detail_line
|
||||||
- alt_co_id
|
- alt_co_id
|
||||||
- alt_overrd
|
- alt_overrd
|
||||||
@@ -2965,6 +3187,13 @@
|
|||||||
table:
|
table:
|
||||||
name: transitions
|
name: transitions
|
||||||
schema: public
|
schema: public
|
||||||
|
- name: tt_approval_queues
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: jobid
|
||||||
|
table:
|
||||||
|
name: tt_approval_queue
|
||||||
|
schema: public
|
||||||
insert_permissions:
|
insert_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
@@ -3853,6 +4082,29 @@
|
|||||||
template_engine: Kriti
|
template_engine: Kriti
|
||||||
url: '{{$base_url}}/record-handler/arms'
|
url: '{{$base_url}}/record-handler/arms'
|
||||||
version: 2
|
version: 2
|
||||||
|
- name: os_jobs
|
||||||
|
definition:
|
||||||
|
delete:
|
||||||
|
columns: '*'
|
||||||
|
enable_manual: false
|
||||||
|
insert:
|
||||||
|
columns: '*'
|
||||||
|
update:
|
||||||
|
columns: '*'
|
||||||
|
retry_conf:
|
||||||
|
interval_sec: 10
|
||||||
|
num_retries: 3
|
||||||
|
timeout_sec: 60
|
||||||
|
webhook_from_env: HASURA_API_URL
|
||||||
|
headers:
|
||||||
|
- name: event-secret
|
||||||
|
value_from_env: EVENT_SECRET
|
||||||
|
request_transform:
|
||||||
|
method: POST
|
||||||
|
query_params: {}
|
||||||
|
template_engine: Kriti
|
||||||
|
url: '{{$base_url}}/opensearch'
|
||||||
|
version: 2
|
||||||
- table:
|
- table:
|
||||||
name: masterdata
|
name: masterdata
|
||||||
schema: public
|
schema: public
|
||||||
@@ -4081,6 +4333,7 @@
|
|||||||
- jobid
|
- jobid
|
||||||
- private
|
- private
|
||||||
- text
|
- text
|
||||||
|
- type
|
||||||
- updated_at
|
- updated_at
|
||||||
select_permissions:
|
select_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
@@ -4094,6 +4347,7 @@
|
|||||||
- jobid
|
- jobid
|
||||||
- private
|
- private
|
||||||
- text
|
- text
|
||||||
|
- type
|
||||||
- updated_at
|
- updated_at
|
||||||
filter:
|
filter:
|
||||||
job:
|
job:
|
||||||
@@ -4117,6 +4371,7 @@
|
|||||||
- jobid
|
- jobid
|
||||||
- private
|
- private
|
||||||
- text
|
- text
|
||||||
|
- type
|
||||||
- updated_at
|
- updated_at
|
||||||
filter:
|
filter:
|
||||||
job:
|
job:
|
||||||
@@ -4277,6 +4532,30 @@
|
|||||||
_eq: X-Hasura-User-Id
|
_eq: X-Hasura-User-Id
|
||||||
- active:
|
- active:
|
||||||
_eq: true
|
_eq: true
|
||||||
|
event_triggers:
|
||||||
|
- name: os_owners
|
||||||
|
definition:
|
||||||
|
delete:
|
||||||
|
columns: '*'
|
||||||
|
enable_manual: false
|
||||||
|
insert:
|
||||||
|
columns: '*'
|
||||||
|
update:
|
||||||
|
columns: '*'
|
||||||
|
retry_conf:
|
||||||
|
interval_sec: 10
|
||||||
|
num_retries: 3
|
||||||
|
timeout_sec: 60
|
||||||
|
webhook_from_env: HASURA_API_URL
|
||||||
|
headers:
|
||||||
|
- name: event-secret
|
||||||
|
value_from_env: EVENT_SECRET
|
||||||
|
request_transform:
|
||||||
|
method: POST
|
||||||
|
query_params: {}
|
||||||
|
template_engine: Kriti
|
||||||
|
url: '{{$base_url}}/opensearch'
|
||||||
|
version: 2
|
||||||
- table:
|
- table:
|
||||||
name: parts_order_lines
|
name: parts_order_lines
|
||||||
schema: public
|
schema: public
|
||||||
@@ -4700,6 +4979,30 @@
|
|||||||
_eq: X-Hasura-User-Id
|
_eq: X-Hasura-User-Id
|
||||||
- active:
|
- active:
|
||||||
_eq: true
|
_eq: true
|
||||||
|
event_triggers:
|
||||||
|
- name: os_payments
|
||||||
|
definition:
|
||||||
|
delete:
|
||||||
|
columns: '*'
|
||||||
|
enable_manual: false
|
||||||
|
insert:
|
||||||
|
columns: '*'
|
||||||
|
update:
|
||||||
|
columns: '*'
|
||||||
|
retry_conf:
|
||||||
|
interval_sec: 10
|
||||||
|
num_retries: 3
|
||||||
|
timeout_sec: 60
|
||||||
|
webhook_from_env: HASURA_API_URL
|
||||||
|
headers:
|
||||||
|
- name: event-secret
|
||||||
|
value_from_env: EVENT_SECRET
|
||||||
|
request_transform:
|
||||||
|
method: POST
|
||||||
|
query_params: {}
|
||||||
|
template_engine: Kriti
|
||||||
|
url: '{{$base_url}}/opensearch'
|
||||||
|
version: 2
|
||||||
- table:
|
- table:
|
||||||
name: phonebook
|
name: phonebook
|
||||||
schema: public
|
schema: public
|
||||||
@@ -5030,6 +5333,12 @@
|
|||||||
- name: job
|
- name: job
|
||||||
using:
|
using:
|
||||||
foreign_key_constraint_on: jobid
|
foreign_key_constraint_on: jobid
|
||||||
|
- name: tt_approval_queue
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: ttapprovalqueueid
|
||||||
|
- name: user
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: commited_by
|
||||||
insert_permissions:
|
insert_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
@@ -5048,6 +5357,8 @@
|
|||||||
- ciecacode
|
- ciecacode
|
||||||
- clockoff
|
- clockoff
|
||||||
- clockon
|
- clockon
|
||||||
|
- commited_by
|
||||||
|
- committed_at
|
||||||
- cost_center
|
- cost_center
|
||||||
- created_at
|
- created_at
|
||||||
- date
|
- date
|
||||||
@@ -5058,6 +5369,7 @@
|
|||||||
- memo
|
- memo
|
||||||
- productivehrs
|
- productivehrs
|
||||||
- rate
|
- rate
|
||||||
|
- ttapprovalqueueid
|
||||||
- updated_at
|
- updated_at
|
||||||
select_permissions:
|
select_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
@@ -5068,6 +5380,8 @@
|
|||||||
- ciecacode
|
- ciecacode
|
||||||
- clockoff
|
- clockoff
|
||||||
- clockon
|
- clockon
|
||||||
|
- commited_by
|
||||||
|
- committed_at
|
||||||
- cost_center
|
- cost_center
|
||||||
- created_at
|
- created_at
|
||||||
- date
|
- date
|
||||||
@@ -5078,6 +5392,7 @@
|
|||||||
- memo
|
- memo
|
||||||
- productivehrs
|
- productivehrs
|
||||||
- rate
|
- rate
|
||||||
|
- ttapprovalqueueid
|
||||||
- updated_at
|
- updated_at
|
||||||
filter:
|
filter:
|
||||||
bodyshop:
|
bodyshop:
|
||||||
@@ -5097,6 +5412,8 @@
|
|||||||
- ciecacode
|
- ciecacode
|
||||||
- clockoff
|
- clockoff
|
||||||
- clockon
|
- clockon
|
||||||
|
- commited_by
|
||||||
|
- committed_at
|
||||||
- cost_center
|
- cost_center
|
||||||
- created_at
|
- created_at
|
||||||
- date
|
- date
|
||||||
@@ -5107,6 +5424,7 @@
|
|||||||
- memo
|
- memo
|
||||||
- productivehrs
|
- productivehrs
|
||||||
- rate
|
- rate
|
||||||
|
- ttapprovalqueueid
|
||||||
- updated_at
|
- updated_at
|
||||||
filter:
|
filter:
|
||||||
bodyshop:
|
bodyshop:
|
||||||
@@ -5217,6 +5535,119 @@
|
|||||||
authid:
|
authid:
|
||||||
_eq: X-Hasura-User-Id
|
_eq: X-Hasura-User-Id
|
||||||
check: {}
|
check: {}
|
||||||
|
- table:
|
||||||
|
name: tt_approval_queue
|
||||||
|
schema: public
|
||||||
|
object_relationships:
|
||||||
|
- name: bodyshop
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: bodyshopid
|
||||||
|
- name: employee
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: employeeid
|
||||||
|
- name: job
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: jobid
|
||||||
|
- name: user
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: approved_by
|
||||||
|
array_relationships:
|
||||||
|
- name: timetickets
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: ttapprovalqueueid
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
insert_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
check:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- approved_at
|
||||||
|
- approved_by
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- flat_rate
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- memo
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
select_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- approved_at
|
||||||
|
- approved_by
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- flat_rate
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- memo
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
allow_aggregations: true
|
||||||
|
update_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- approved_at
|
||||||
|
- approved_by
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- flat_rate
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- memo
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
check: null
|
||||||
- table:
|
- table:
|
||||||
name: users
|
name: users
|
||||||
schema: public
|
schema: public
|
||||||
@@ -5287,6 +5718,20 @@
|
|||||||
table:
|
table:
|
||||||
name: parts_orders
|
name: parts_orders
|
||||||
schema: public
|
schema: public
|
||||||
|
- name: timetickets
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: commited_by
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
- name: tt_approval_queues
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: approved_by
|
||||||
|
table:
|
||||||
|
name: tt_approval_queue
|
||||||
|
schema: public
|
||||||
insert_permissions:
|
insert_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
@@ -5472,6 +5917,30 @@
|
|||||||
_eq: X-Hasura-User-Id
|
_eq: X-Hasura-User-Id
|
||||||
- active:
|
- active:
|
||||||
_eq: true
|
_eq: true
|
||||||
|
event_triggers:
|
||||||
|
- name: os_vehicles
|
||||||
|
definition:
|
||||||
|
delete:
|
||||||
|
columns: '*'
|
||||||
|
enable_manual: false
|
||||||
|
insert:
|
||||||
|
columns: '*'
|
||||||
|
update:
|
||||||
|
columns: '*'
|
||||||
|
retry_conf:
|
||||||
|
interval_sec: 10
|
||||||
|
num_retries: 3
|
||||||
|
timeout_sec: 60
|
||||||
|
webhook_from_env: HASURA_API_URL
|
||||||
|
headers:
|
||||||
|
- name: event-secret
|
||||||
|
value_from_env: EVENT_SECRET
|
||||||
|
request_transform:
|
||||||
|
method: POST
|
||||||
|
query_params: {}
|
||||||
|
template_engine: Kriti
|
||||||
|
url: '{{$base_url}}/opensearch'
|
||||||
|
version: 2
|
||||||
- table:
|
- table:
|
||||||
name: vendors
|
name: vendors
|
||||||
schema: public
|
schema: public
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."joblines" add column "act_price_before_ppc" numeric
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."joblines" add column "act_price_before_ppc" numeric
|
||||||
|
null;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
DROP TABLE "public"."employee_teams";
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
CREATE TABLE "public"."employee_teams" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "bodyshopid" uuid NOT NULL, "name" text NOT NULL, "active" boolean NOT NULL DEFAULT true, PRIMARY KEY ("id") , FOREIGN KEY ("bodyshopid") REFERENCES "public"."bodyshops"("id") ON UPDATE cascade ON DELETE cascade);
|
||||||
|
CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
DECLARE
|
||||||
|
_new record;
|
||||||
|
BEGIN
|
||||||
|
_new := NEW;
|
||||||
|
_new."updated_at" = NOW();
|
||||||
|
RETURN _new;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
CREATE TRIGGER "set_public_employee_teams_updated_at"
|
||||||
|
BEFORE UPDATE ON "public"."employee_teams"
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"();
|
||||||
|
COMMENT ON TRIGGER "set_public_employee_teams_updated_at" ON "public"."employee_teams"
|
||||||
|
IS 'trigger to set value of column "updated_at" to current timestamp on row update';
|
||||||
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
DROP TABLE "public"."employee_team_members";
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
CREATE TABLE "public"."employee_team_members" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "teamid" uuid NOT NULL, "employeeid" uuid NOT NULL, "labor_rates" jsonb NOT NULL DEFAULT jsonb_build_object(), "percentage" numeric NOT NULL DEFAULT 0, PRIMARY KEY ("id") , FOREIGN KEY ("teamid") REFERENCES "public"."employee_teams"("id") ON UPDATE cascade ON DELETE cascade, FOREIGN KEY ("employeeid") REFERENCES "public"."employees"("id") ON UPDATE cascade ON DELETE cascade);
|
||||||
|
CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
DECLARE
|
||||||
|
_new record;
|
||||||
|
BEGIN
|
||||||
|
_new := NEW;
|
||||||
|
_new."updated_at" = NOW();
|
||||||
|
RETURN _new;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
CREATE TRIGGER "set_public_employee_team_members_updated_at"
|
||||||
|
BEFORE UPDATE ON "public"."employee_team_members"
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"();
|
||||||
|
COMMENT ON TRIGGER "set_public_employee_team_members_updated_at" ON "public"."employee_team_members"
|
||||||
|
IS 'trigger to set value of column "updated_at" to current timestamp on row update';
|
||||||
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."exportlog" add column "metadata" jsonb
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."exportlog" add column "metadata" jsonb
|
||||||
|
null;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."bodyshops" add column "tt_enforce_hours_for_tech_console" boolean
|
||||||
|
-- not null default 'false';
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."bodyshops" add column "tt_enforce_hours_for_tech_console" boolean
|
||||||
|
not null default 'false';
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."timetickets" add column "committed_at" timestamptz
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."timetickets" add column "committed_at" timestamptz
|
||||||
|
null;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
DROP TABLE "public"."tt_approval_queue";
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
CREATE TABLE "public"."tt_approval_queue" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "bodyshopid" uuid NOT NULL, "jobid" uuid NOT NULL, "employeeid" uuid NOT NULL, "timeticketid" uuid, "approved_by" text, "approved_at" timestamptz NOT NULL, "actualhrs" numeric NOT NULL DEFAULT 0, "productivehrs" numeric NOT NULL DEFAULT 0, "rate" numeric NOT NULL DEFAULT 0, "flat_rate" boolean NOT NULL DEFAULT true, "ciecacode" text, "cost_center" text NOT NULL, "date" date NOT NULL DEFAULT now(), "memo" text NOT NULL, PRIMARY KEY ("id") , FOREIGN KEY ("bodyshopid") REFERENCES "public"."bodyshops"("id") ON UPDATE cascade ON DELETE cascade, FOREIGN KEY ("jobid") REFERENCES "public"."jobs"("id") ON UPDATE cascade ON DELETE cascade, FOREIGN KEY ("employeeid") REFERENCES "public"."employees"("id") ON UPDATE cascade ON DELETE cascade, FOREIGN KEY ("timeticketid") REFERENCES "public"."timetickets"("id") ON UPDATE cascade ON DELETE cascade, FOREIGN KEY ("approved_by") REFERENCES "public"."users"("email") ON UPDATE restrict ON DELETE restrict);
|
||||||
|
CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
DECLARE
|
||||||
|
_new record;
|
||||||
|
BEGIN
|
||||||
|
_new := NEW;
|
||||||
|
_new."updated_at" = NOW();
|
||||||
|
RETURN _new;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
CREATE TRIGGER "set_public_tt_approval_queue_updated_at"
|
||||||
|
BEFORE UPDATE ON "public"."tt_approval_queue"
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"();
|
||||||
|
COMMENT ON TRIGGER "set_public_tt_approval_queue_updated_at" ON "public"."tt_approval_queue"
|
||||||
|
IS 'trigger to set value of column "updated_at" to current timestamp on row update';
|
||||||
|
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."tt_approval_queue" alter column "approved_at" set not null;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."tt_approval_queue" alter column "approved_at" drop not null;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."tt_approval_queue" alter column "memo" set not null;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."tt_approval_queue" alter column "memo" drop not null;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
alter table "public"."tt_approval_queue"
|
||||||
|
add constraint "tt_approval_queue_timeticketid_fkey"
|
||||||
|
foreign key ("timeticketid")
|
||||||
|
references "public"."timetickets"
|
||||||
|
("id") on update cascade on delete cascade;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."tt_approval_queue" drop constraint "tt_approval_queue_timeticketid_fkey";
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."tt_approval_queue" alter column "timeticketid" drop not null;
|
||||||
|
alter table "public"."tt_approval_queue" add column "timeticketid" uuid;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."tt_approval_queue" drop column "timeticketid" cascade;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."timetickets" add column "ttapprovalqueueid" uuid
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."timetickets" add column "ttapprovalqueueid" uuid
|
||||||
|
null;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."timetickets" drop constraint "timetickets_ttapprovalqueueid_fkey";
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
alter table "public"."timetickets"
|
||||||
|
add constraint "timetickets_ttapprovalqueueid_fkey"
|
||||||
|
foreign key ("ttapprovalqueueid")
|
||||||
|
references "public"."tt_approval_queue"
|
||||||
|
("id") on update cascade on delete set null;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."timetickets" add column "commited_by" text
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."timetickets" add column "commited_by" text
|
||||||
|
null;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
alter table "public"."timetickets" drop constraint "timetickets_commited_by_fkey";
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user