diff --git a/_reference/reportFiltersAndSorters.md b/_reference/reportFiltersAndSorters.md
index 2aea3f11a..0b5b16aaf 100644
--- a/_reference/reportFiltersAndSorters.md
+++ b/_reference/reportFiltersAndSorters.md
@@ -59,7 +59,7 @@ Filters can make use of reflection to pre-fill select boxes, the following is an
"type": "internal",
"name": "special.job_statuses"
}
- },
+ }
```
in this example, a reflector with the type 'internal' (all types at the moment require this, and it is used for future functionality), with a name of `special.job_statuses`
@@ -74,9 +74,13 @@ The following cases are available
- `special.employees` - This will reflect the employees `bodyshop.employees`
- `special.first_names` - This will reflect the first names `bodyshop.employees`
- `special.last_names` - This will reflect the last names `bodyshop.employees`
-- `special.referral_sources` - This will reflect the referral sources `bodyshop.md_referral_sources
+- `special.referral_sources` - This will reflect the referral sources `bodyshop.md_referral_sources`
- `special.class`- This will reflect the class `bodyshop.md_classes`
--
+- `special.lost_sale_reasons` - This will reflect the lost sale reasons `bodyshop.md_lost_sale_reasons`
+- `special.alt_transports` - This will reflect the alternative transports `bodyshop.appt_alt_transport`
+- `special.payment_types` - This will reflect the payment types `bodyshop.md_payment_types`
+- `special.payment_payers` - This is a special case with a key value set of [Customer, Insurance]
+
### Path without brackets, multi level
`"name": "jobs.joblines.mod_lb_hrs",`
@@ -156,6 +160,7 @@ query gendoc_hours_sold_detail_open($starttz: timestamptz!, $endtz: timestamptz!
- Do not add the ability to filter things that are already filtered as part of the original query, this would be
redundant and could cause issues.
- Do not add the ability to filter on things like FK constraints, must like the above example.
+- *INHERITANCE CAVEAT* If you have a filters file on a parent report that has a child that you do not want the filters inherited from, you must place a blank filters file (valid json so {}) on the child report level. This will than fetch the child filters, which are empty and move along, versus inheriting the parent filters.
## Sorters
diff --git a/client/src/components/accounting-payables-table/accounting-payables-table.component.jsx b/client/src/components/accounting-payables-table/accounting-payables-table.component.jsx
index 260589c2f..d8b477005 100644
--- a/client/src/components/accounting-payables-table/accounting-payables-table.component.jsx
+++ b/client/src/components/accounting-payables-table/accounting-payables-table.component.jsx
@@ -1,21 +1,21 @@
-import { Input, Table, Checkbox, Card, Space } from "antd";
+import { Card, Checkbox, Input, Space, Table } from "antd";
+import queryString from "query-string";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
-import { Link } from "react-router-dom";
-import CurrencyFormatter from "../../utils/CurrencyFormatter";
-import { alphaSort, dateSort } from "../../utils/sorters";
-import PayableExportButton from "../payable-export-button/payable-export-button.component";
-import PayableExportAll from "../payable-export-all-button/payable-export-all-button.component";
-import { DateFormatter } from "../../utils/DateFormatter";
-import queryString from "query-string";
-import { logImEXEvent } from "../../firebase/firebase.utils";
-import QboAuthorizeComponent from "../qbo-authorize/qbo-authorize.component";
import { connect } from "react-redux";
+import { Link } from "react-router-dom";
import { createStructuredSelector } from "reselect";
+import { logImEXEvent } from "../../firebase/firebase.utils";
import { selectBodyshop } from "../../redux/user/user.selectors";
+import CurrencyFormatter from "../../utils/CurrencyFormatter";
+import { DateFormatter } from "../../utils/DateFormatter";
+import { pageLimit } from "../../utils/config";
+import { alphaSort, dateSort } from "../../utils/sorters";
import ExportLogsCountDisplay from "../export-logs-count-display/export-logs-count-display.component";
+import PayableExportAll from "../payable-export-all-button/payable-export-all-button.component";
+import PayableExportButton from "../payable-export-button/payable-export-button.component";
import BillMarkSelectedExported from "../payable-mark-selected-exported/payable-mark-selected-exported.component";
-import {pageLimit} from "../../utils/config";
+import QboAuthorizeComponent from "../qbo-authorize/qbo-authorize.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
diff --git a/client/src/components/accounting-payments-table/accounting-payments-table.component.jsx b/client/src/components/accounting-payments-table/accounting-payments-table.component.jsx
index ecd785f91..48e32394b 100644
--- a/client/src/components/accounting-payments-table/accounting-payments-table.component.jsx
+++ b/client/src/components/accounting-payments-table/accounting-payments-table.component.jsx
@@ -8,14 +8,16 @@ import { logImEXEvent } from "../../firebase/firebase.utils";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter";
+import { pageLimit } from "../../utils/config";
import { alphaSort, dateSort } from "../../utils/sorters";
import ExportLogsCountDisplay from "../export-logs-count-display/export-logs-count-display.component";
-import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
+import OwnerNameDisplay, {
+ OwnerNameDisplayFunction,
+} from "../owner-name-display/owner-name-display.component";
import PaymentExportButton from "../payment-export-button/payment-export-button.component";
import PaymentMarkSelectedExported from "../payment-mark-selected-exported/payment-mark-selected-exported.component";
import PaymentsExportAllButton from "../payments-export-all-button/payments-export-all-button.component";
import QboAuthorizeComponent from "../qbo-authorize/qbo-authorize.component";
-import {pageLimit} from "../../utils/config";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -75,7 +77,8 @@ export function AccountingPayablesTableComponent({
dataIndex: "owner",
key: "owner",
ellipsis: true,
- sorter: (a, b) => alphaSort(a.job.ownr_ln, b.job.ownr_ln),
+ sorter: (a, b) =>
+ alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
@@ -94,6 +97,9 @@ export function AccountingPayablesTableComponent({
title: t("payments.fields.amount"),
dataIndex: "amount",
key: "amount",
+ sorter: (a, b) => a.amount - b.amount,
+ sortOrder:
+ state.sortedInfo.columnKey === "amount" && state.sortedInfo.order,
render: (text, record) => (
{record.amount}
),
@@ -112,18 +118,21 @@ export function AccountingPayablesTableComponent({
title: t("payments.fields.created_at"),
dataIndex: "created_at",
key: "created_at",
+ sorter: (a, b) => dateSort(a.created_at, b.created_at),
+ sortOrder:
+ state.sortedInfo.columnKey === "created_at" && state.sortedInfo.order,
render: (text, record) => (
{record.created_at}
),
},
- {
- title: t("payments.fields.exportedat"),
- dataIndex: "exportedat",
- key: "exportedat",
- render: (text, record) => (
- {record.exportedat}
- ),
- },
+ // {
+ // title: t("payments.fields.exportedat"),
+ // dataIndex: "exportedat",
+ // key: "exportedat",
+ // render: (text, record) => (
+ // {record.exportedat}
+ // ),
+ // },
{
title: t("exportlogs.labels.attempts"),
dataIndex: "attempts",
diff --git a/client/src/components/accounting-receivables-table/accounting-receivables-table.component.jsx b/client/src/components/accounting-receivables-table/accounting-receivables-table.component.jsx
index 082d42da2..672a9474a 100644
--- a/client/src/components/accounting-receivables-table/accounting-receivables-table.component.jsx
+++ b/client/src/components/accounting-receivables-table/accounting-receivables-table.component.jsx
@@ -4,17 +4,19 @@ import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { logImEXEvent } from "../../firebase/firebase.utils";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
-import { alphaSort, dateSort } from "../../utils/sorters";
+import { alphaSort, dateSort, statusSort } from "../../utils/sorters";
import JobExportButton from "../jobs-close-export-button/jobs-close-export-button.component";
import JobsExportAllButton from "../jobs-export-all-button/jobs-export-all-button.component";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
-import QboAuthorizeComponent from "../qbo-authorize/qbo-authorize.component";
import { DateFormatter } from "../../utils/DateFormatter";
-import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import ExportLogsCountDisplay from "../export-logs-count-display/export-logs-count-display.component";
+import OwnerNameDisplay, {
+ OwnerNameDisplayFunction,
+} from "../owner-name-display/owner-name-display.component";
+import QboAuthorizeComponent from "../qbo-authorize/qbo-authorize.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -63,7 +65,7 @@ export function AccountingReceivablesTableComponent({
title: t("jobs.fields.status"),
dataIndex: "status",
key: "status",
- sorter: (a, b) => a.status - b.status,
+ sorter: (a, b) => statusSort(a, b, bodyshop.md_ro_statuses.statuses),
sortOrder:
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
},
@@ -83,7 +85,8 @@ export function AccountingReceivablesTableComponent({
title: t("jobs.fields.owner"),
dataIndex: "owner",
key: "owner",
- sorter: (a, b) => alphaSort(a.ownr_ln, b.ownr_ln),
+ sorter: (a, b) =>
+ alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
@@ -103,6 +106,15 @@ export function AccountingReceivablesTableComponent({
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
+ sorter: (a, b) =>
+ alphaSort(
+ `${a.v_model_yr || ""} ${a.v_make_desc || ""} ${
+ a.v_model_desc || ""
+ }`,
+ `${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
+ ),
+ sortOrder:
+ state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order,
render: (text, record) => {
return record.vehicleid ? (
diff --git a/client/src/components/bill-delete-button/bill-delete-button.component.jsx b/client/src/components/bill-delete-button/bill-delete-button.component.jsx
index ca3f3822d..0e30cabad 100644
--- a/client/src/components/bill-delete-button/bill-delete-button.component.jsx
+++ b/client/src/components/bill-delete-button/bill-delete-button.component.jsx
@@ -12,8 +12,8 @@ import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
const mapStateToProps = createStructuredSelector({});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(mapStateToProps, mapDispatchToProps)(BillDeleteButton);
@@ -51,6 +51,7 @@ export function BillDeleteButton({ bill, jobid, callback, insertAuditTrail }) {
insertAuditTrail({
jobid: jobid,
operation: AuditTrailMapping.billdeleted(bill.invoice_number),
+ type: "billdeleted",
});
if (callback && typeof callback === "function") callback(bill.id);
diff --git a/client/src/components/bill-detail-edit/bill-detail-edit-component.jsx b/client/src/components/bill-detail-edit/bill-detail-edit-component.jsx
index 12ca80301..93d115254 100644
--- a/client/src/components/bill-detail-edit/bill-detail-edit-component.jsx
+++ b/client/src/components/bill-detail-edit/bill-detail-edit-component.jsx
@@ -33,8 +33,8 @@ const mapStateToProps = createStructuredSelector({
const mapDispatchToProps = (dispatch) => ({
setPartsOrderContext: (context) =>
dispatch(setModalContext({ context: context, modal: "partsOrder" })),
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(
@@ -150,6 +150,7 @@ export function BillDetailEditcontainer({
jobid: bill.jobid,
billid: search.billid,
operation: AuditTrailMapping.billupdated(bill.invoice_number),
+ type: "billupdated",
});
await refetch();
diff --git a/client/src/components/bill-detail-edit/bill-detail-edit-return.component.jsx b/client/src/components/bill-detail-edit/bill-detail-edit-return.component.jsx
index 81571f8b0..3935fc5f2 100644
--- a/client/src/components/bill-detail-edit/bill-detail-edit-return.component.jsx
+++ b/client/src/components/bill-detail-edit/bill-detail-edit-return.component.jsx
@@ -16,8 +16,8 @@ const mapStateToProps = createStructuredSelector({
const mapDispatchToProps = (dispatch) => ({
setPartsOrderContext: (context) =>
dispatch(setModalContext({ context: context, modal: "partsOrder" })),
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(
diff --git a/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx b/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx
index c106a8c4c..b75d51d14 100644
--- a/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx
+++ b/client/src/components/bill-enter-modal/bill-enter-modal.container.jsx
@@ -37,8 +37,8 @@ const mapStateToProps = createStructuredSelector({
});
const mapDispatchToProps = (dispatch) => ({
toggleModalVisible: () => dispatch(toggleModalVisible("billEnter")),
- insertAuditTrail: ({ jobid, billid, operation }) =>
- dispatch(insertAuditTrail({ jobid, billid, operation })),
+ insertAuditTrail: ({ jobid, billid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, billid, operation, type })),
});
const Templates = TemplateList("job_special");
@@ -171,6 +171,7 @@ function BillEnterModalContainer({
mod_lbr_ty: key,
hours: adjustmentsToInsert[key].toFixed(1),
}),
+ type: "jobmodifylbradj",
});
});
@@ -320,6 +321,7 @@ function BillEnterModalContainer({
operation: AuditTrailMapping.billposted(
r1.data.insert_bills.returning[0].invoice_number
),
+ type: "billposted",
});
if (enterAgain) {
diff --git a/client/src/components/card-payment-modal/card-payment-modal.component..jsx b/client/src/components/card-payment-modal/card-payment-modal.component..jsx
index 071e2a758..a1e0b2461 100644
--- a/client/src/components/card-payment-modal/card-payment-modal.component..jsx
+++ b/client/src/components/card-payment-modal/card-payment-modal.component..jsx
@@ -37,8 +37,8 @@ const mapStateToProps = createStructuredSelector({
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
toggleModalVisible: () => dispatch(toggleModalVisible("cardPayment")),
});
@@ -102,6 +102,7 @@ const CardPaymentModalComponent = ({
insertAuditTrail({
jobid: payment.jobid,
operation: AuditTrailMapping.failedpayment(),
+ type: "failedpayment",
})
);
});
diff --git a/client/src/components/job-at-change/schedule-event.container.jsx b/client/src/components/job-at-change/schedule-event.container.jsx
index 60abf9c61..f51d4379a 100644
--- a/client/src/components/job-at-change/schedule-event.container.jsx
+++ b/client/src/components/job-at-change/schedule-event.container.jsx
@@ -53,6 +53,7 @@ export default function ScheduleEventContainer({ bodyshop, event, refetch }) {
insertAuditTrail({
jobid: event.job.id,
operation: AuditTrailMapping.appointmentcancel(lost_sale_reason),
+ type: "appointmentcancel",
})
);
}
diff --git a/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx b/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx
index a809100a6..eae9b707b 100644
--- a/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx
+++ b/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx
@@ -28,8 +28,8 @@ const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export function JobChecklistForm({
@@ -183,6 +183,7 @@ export function JobChecklistForm({
(type === "intake" && bodyshop.md_ro_statuses.default_arrived) ||
(type === "deliver" && bodyshop.md_ro_statuses.default_delivered)
),
+ type: "jobchecklist",
});
} else {
notification["error"]({
diff --git a/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx b/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx
index 71e56c53c..a5feb3fa7 100644
--- a/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx
+++ b/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx
@@ -14,8 +14,8 @@ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(
mapStateToProps,
@@ -46,6 +46,7 @@ export function JobEmployeeAssignmentsContainer({
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.jobassignmentchange(operation, name),
+ type: "jobassignmentchange",
});
if (!!result.errors) {
@@ -76,6 +77,7 @@ export function JobEmployeeAssignmentsContainer({
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.jobassignmentremoved(operation),
+ type: "jobassignmentremoved",
});
setLoading(false);
};
diff --git a/client/src/components/job-line-convert-to-labor/job-line-convert-to-labor.component.jsx b/client/src/components/job-line-convert-to-labor/job-line-convert-to-labor.component.jsx
index dea8e5dcc..80ecffdc2 100644
--- a/client/src/components/job-line-convert-to-labor/job-line-convert-to-labor.component.jsx
+++ b/client/src/components/job-line-convert-to-labor/job-line-convert-to-labor.component.jsx
@@ -28,8 +28,8 @@ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(
mapStateToProps,
@@ -113,6 +113,7 @@ export function JobLineConvertToLabor({
hours: calculateAdjustment({ mod_lbr_ty, job, jobline }).toFixed(1),
mod_lbr_ty,
}),
+ type: "jobmodifylbradj",
});
setLoading(false);
setVisibility(false);
diff --git a/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx b/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx
index 54a020d37..995da5ba0 100644
--- a/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx
+++ b/client/src/components/jobs-admin-change-status/jobs-admin-change.status.component.jsx
@@ -14,8 +14,8 @@ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(mapStateToProps, mapDispatchToProps)(JobsAdminStatus);
@@ -32,6 +32,7 @@ export function JobsAdminStatus({ insertAuditTrail, bodyshop, job }) {
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.admin_jobstatuschange(status),
+ type: "admin_jobstatuschange",
});
// refetch();
})
diff --git a/client/src/components/jobs-admin-dates/jobs-admin-dates.component.jsx b/client/src/components/jobs-admin-dates/jobs-admin-dates.component.jsx
index 5ac31da74..4e038dcb8 100644
--- a/client/src/components/jobs-admin-dates/jobs-admin-dates.component.jsx
+++ b/client/src/components/jobs-admin-dates/jobs-admin-dates.component.jsx
@@ -20,8 +20,8 @@ const mapStateToProps = createStructuredSelector({
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(
@@ -57,6 +57,7 @@ export function JobsAdminDatesChange({ insertAuditTrail, job }) {
? DateTimeFormat(changedAuditFields[key])
: changedAuditFields[key]
),
+ type: "admin_jobfieldchange",
});
});
diff --git a/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx b/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx
index 98f5c65d5..f59c6f7d6 100644
--- a/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx
+++ b/client/src/components/jobs-admin-mark-reexport/jobs-admin-mark-reexport.component.jsx
@@ -23,8 +23,8 @@ const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(
mapStateToProps,
@@ -59,6 +59,7 @@ export function JobAdminMarkReexport({
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.admin_jobmarkforreexport(),
+ type: "admin_jobmarkforreexport",
});
} else {
notification["error"]({
@@ -99,6 +100,7 @@ export function JobAdminMarkReexport({
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.admin_jobmarkexported(),
+ type: "admin_jobmarkexported",
});
} else {
notification["error"]({
@@ -124,6 +126,7 @@ export function JobAdminMarkReexport({
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.admin_jobuninvoice(),
+ type: "admin_jobuninvoice",
});
} else {
notification["error"]({
diff --git a/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx b/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx
index f1bda15ce..86aa54c01 100644
--- a/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx
+++ b/client/src/components/jobs-admin-remove-ar/jobs-admin-remove-ar.component.jsx
@@ -10,8 +10,8 @@ import AuditTrailMapping from "../../utils/AuditTrailMappings";
const mapStateToProps = createStructuredSelector({});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(mapStateToProps, mapDispatchToProps)(JobsAdminRemoveAR);
@@ -34,6 +34,7 @@ export function JobsAdminRemoveAR({ insertAuditTrail, job }) {
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.admin_job_remove_from_ar(value),
+ type: "admin_job_remove_from_ar",
});
setSwitchValue(value);
} else {
diff --git a/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx b/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx
index 2094178c4..2b79a406a 100644
--- a/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx
+++ b/client/src/components/jobs-admin-unvoid/jobs-admin-unvoid.component.jsx
@@ -17,8 +17,8 @@ const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(mapStateToProps, mapDispatchToProps)(JobsAdminUnvoid);
@@ -49,6 +49,7 @@ export function JobsAdminUnvoid({
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.admin_jobunvoid(),
+ type: "admin_jobunvoid",
});
} else {
notification["error"]({
diff --git a/client/src/components/jobs-available-table/jobs-available-table.container.jsx b/client/src/components/jobs-available-table/jobs-available-table.container.jsx
index bbad59845..20efbe600 100644
--- a/client/src/components/jobs-available-table/jobs-available-table.container.jsx
+++ b/client/src/components/jobs-available-table/jobs-available-table.container.jsx
@@ -47,8 +47,8 @@ const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export function JobsAvailableContainer({
bodyshop,
@@ -190,6 +190,7 @@ export function JobsAvailableContainer({
insertAuditTrail({
jobid: r.data.insert_jobs.returning[0].id,
operation: AuditTrailMapping.jobimported(),
+ type: "jobimported",
});
deleteJob({
@@ -350,6 +351,7 @@ export function JobsAvailableContainer({
insertAuditTrail({
jobid: selectedJob,
operation: AuditTrailMapping.jobsupplement(),
+ type: "jobsupplement",
});
}
};
diff --git a/client/src/components/jobs-change-status/jobs-change-status.component.jsx b/client/src/components/jobs-change-status/jobs-change-status.component.jsx
index aa5f61fc2..12eb9d8ea 100644
--- a/client/src/components/jobs-change-status/jobs-change-status.component.jsx
+++ b/client/src/components/jobs-change-status/jobs-change-status.component.jsx
@@ -16,8 +16,8 @@ const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly,
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export function JobsChangeStatus({ job, bodyshop, jobRO, insertAuditTrail }) {
@@ -35,6 +35,7 @@ export function JobsChangeStatus({ job, bodyshop, jobRO, insertAuditTrail }) {
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.jobstatuschange(status),
+ type: "jobstatuschange",
});
// refetch();
})
diff --git a/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx b/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx
index 34acb7994..df598b409 100644
--- a/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx
+++ b/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx
@@ -23,8 +23,8 @@ const mapStateToProps = createStructuredSelector({
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
function updateJobCache(items) {
@@ -192,6 +192,7 @@ export function JobsCloseExportButton({
insertAuditTrail({
jobid: jobId,
operation: AuditTrailMapping.jobexported(),
+ type: "jobexported",
});
updateJobCache(
jobUpdateResponse.data.update_jobs.returning.map((job) => job.id)
@@ -217,6 +218,7 @@ export function JobsCloseExportButton({
insertAuditTrail({
jobid: jobId,
operation: AuditTrailMapping.jobexported(),
+ type: "jobexported",
});
updateJobCache([
...new Set(
diff --git a/client/src/components/jobs-convert-button/jobs-convert-button.component.jsx b/client/src/components/jobs-convert-button/jobs-convert-button.component.jsx
index 543ad36ca..e72f26720 100644
--- a/client/src/components/jobs-convert-button/jobs-convert-button.component.jsx
+++ b/client/src/components/jobs-convert-button/jobs-convert-button.component.jsx
@@ -25,8 +25,8 @@ const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly,
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export function JobsConvertButton({
@@ -78,6 +78,7 @@ export function JobsConvertButton({
operation: AuditTrailMapping.jobconverted(
res.data.update_jobs.returning[0].ro_number
),
+ type: "jobconverted",
});
setVisible(false);
diff --git a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.addtoproduction.util.jsx b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.addtoproduction.util.jsx
index 90c8ebd8b..2aa592763 100644
--- a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.addtoproduction.util.jsx
+++ b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.addtoproduction.util.jsx
@@ -29,6 +29,7 @@ export default function AddToProduction(
insertAuditTrail({
jobid: jobId,
operation: AuditTrailMapping.jobinproductionchange(!remove),
+ type: "jobinproductionchange",
})
);
if (completionCallback) completionCallback();
diff --git a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx
index bc76f668e..76a093822 100644
--- a/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx
+++ b/client/src/components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx
@@ -52,8 +52,8 @@ const mapDispatchToProps = (dispatch) => ({
dispatch(setModalContext({ context: context, modal: "timeTicket" })),
setCardPaymentContext: (context) =>
dispatch(setModalContext({ context: context, modal: "cardPayment" })),
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export function JobsDetailHeaderActions({
@@ -115,6 +115,7 @@ export function JobsDetailHeaderActions({
? !job.production_vars.alert
: true
),
+ type: "alertToggle",
});
};
@@ -134,6 +135,7 @@ export function JobsDetailHeaderActions({
operation: AuditTrailMapping.jobsuspend(
!!job.suspended ? !job.suspended : true
),
+ type: "jobsuspend",
});
};
@@ -190,6 +192,7 @@ export function JobsDetailHeaderActions({
jobid: job.id,
operation:
AuditTrailMapping.appointmentcancel(lost_sale_reason),
+ type: "appointmentcancel",
});
return;
}
@@ -549,6 +552,7 @@ export function JobsDetailHeaderActions({
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.jobvoid(),
+ type: "jobvoid",
});
//go back to jobs list.
history.push(`/manage/`);
diff --git a/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx b/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx
index 2bb338d97..25a08fb88 100644
--- a/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx
+++ b/client/src/components/jobs-export-all-button/jobs-export-all-button.component.jsx
@@ -23,8 +23,8 @@ const mapStateToProps = createStructuredSelector({
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
function updateJobCache(items) {
@@ -189,6 +189,7 @@ export function JobsExportAllButton({
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.jobexported(),
+ type: "jobexported",
});
});
updateJobCache(
@@ -230,6 +231,7 @@ export function JobsExportAllButton({
insertAuditTrail({
jobid: successfulTransactionsSet[0],
operation: AuditTrailMapping.jobexported(),
+ type: "jobexported",
});
}
updateJobCache(successfulTransactionsSet);
diff --git a/client/src/components/jobs-list/jobs-list.component.jsx b/client/src/components/jobs-list/jobs-list.component.jsx
index 68b3f3425..94024bccc 100644
--- a/client/src/components/jobs-list/jobs-list.component.jsx
+++ b/client/src/components/jobs-list/jobs-list.component.jsx
@@ -21,6 +21,7 @@ import useLocalStorage from "../../utils/useLocalStorage";
import AlertComponent from "../alert/alert.component";
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
+import { OwnerNameDisplayFunction } from "./../owner-name-display/owner-name-display.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -145,7 +146,8 @@ export function JobsList({ bodyshop }) {
key: "owner",
ellipsis: true,
responsive: ["md"],
- sorter: (a, b) => alphaSort(a.ownr_ln, b.ownr_ln),
+ sorter: (a, b) =>
+ alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
@@ -188,7 +190,8 @@ export function JobsList({ bodyshop }) {
dataIndex: "status",
key: "status",
ellipsis: true,
- sorter: (a, b) => alphaSort(a.status, b.status),
+ sorter: (a, b) =>
+ statusSort(a.status, b.status, bodyshop.md_ro_statuses.active_statuses),
sortOrder:
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
filteredValue: filter?.status || null,
@@ -219,6 +222,15 @@ export function JobsList({ bodyshop }) {
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
+ sorter: (a, b) =>
+ alphaSort(
+ `${a.v_model_yr || ""} ${a.v_make_desc || ""} ${
+ a.v_model_desc || ""
+ }`,
+ `${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
+ ),
+ sortOrder:
+ state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order,
render: (text, record) => {
return record.vehicleid ? (
alphaSort(a.ins_co_nm, b.ins_co_nm),
+ sortOrder:
+ state.sortedInfo.columnKey === "ins_co_nm" && state.sortedInfo.order,
filteredValue: filter?.ins_co_nm || null,
filters:
(jobs &&
@@ -302,6 +317,13 @@ export function JobsList({ bodyshop }) {
key: "estimator",
ellipsis: true,
responsive: ["xl"],
+ sorter: (a, b) =>
+ alphaSort(
+ `${a.est_ct_fn || ""} ${a.est_ct_ln || ""}`.trim(),
+ `${b.est_ct_fn || ""} ${b.est_ct_ln || ""}`.trim()
+ ),
+ sortOrder:
+ state.sortedInfo.columnKey === "estimator" && state.sortedInfo.order,
filterSearch: true,
filteredValue: filter?.estimator || null,
filters:
diff --git a/client/src/components/jobs-notes/jobs-notes.container.jsx b/client/src/components/jobs-notes/jobs-notes.container.jsx
index f62a219cb..897435c4b 100644
--- a/client/src/components/jobs-notes/jobs-notes.container.jsx
+++ b/client/src/components/jobs-notes/jobs-notes.container.jsx
@@ -19,8 +19,8 @@ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(mapStateToProps, mapDispatchToProps)(JobNotesContainer);
@@ -49,6 +49,7 @@ export function JobNotesContainer({ jobId, insertAuditTrail }) {
insertAuditTrail({
jobid: jobId,
operation: AuditTrailMapping.jobnotedeleted(),
+ type: "jobnotedeleted",
});
});
setDeleteLoading(false);
diff --git a/client/src/components/labor-allocations-adjustment-edit/labor-allocations-adjustment-edit.component.jsx b/client/src/components/labor-allocations-adjustment-edit/labor-allocations-adjustment-edit.component.jsx
index 5d5a56d2c..5978c8019 100644
--- a/client/src/components/labor-allocations-adjustment-edit/labor-allocations-adjustment-edit.component.jsx
+++ b/client/src/components/labor-allocations-adjustment-edit/labor-allocations-adjustment-edit.component.jsx
@@ -20,8 +20,8 @@ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
});
const mapDispatchToProps = (dispatch) => ({
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export default connect(
mapStateToProps,
@@ -76,6 +76,7 @@ export function LaborAllocationsAdjustmentEdit({
values.hours -
((adjustments && adjustments[mod_lbr_ty]) || 0).toFixed(1),
}),
+ type: "jobmodifylbradj",
});
}
setLoading(false);
diff --git a/client/src/components/note-upsert-modal/note-upsert-modal.container.jsx b/client/src/components/note-upsert-modal/note-upsert-modal.container.jsx
index f925b7100..2b9e27439 100644
--- a/client/src/components/note-upsert-modal/note-upsert-modal.container.jsx
+++ b/client/src/components/note-upsert-modal/note-upsert-modal.container.jsx
@@ -19,8 +19,8 @@ const mapStateToProps = createStructuredSelector({
});
const mapDispatchToProps = (dispatch) => ({
toggleModalVisible: () => dispatch(toggleModalVisible("noteUpsert")),
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export function NoteUpsertModalContainer({
@@ -70,6 +70,7 @@ export function NoteUpsertModalContainer({
insertAuditTrail({
jobid: context.jobId,
operation: AuditTrailMapping.jobnoteupdated(),
+ type: "jobnoteupdated",
});
});
if (refetch) refetch();
@@ -102,6 +103,7 @@ export function NoteUpsertModalContainer({
insertAuditTrail({
jobid: newJobId,
operation: AuditTrailMapping.jobnoteadded(),
+ type: "jobnoteadded",
});
});
}
@@ -115,6 +117,7 @@ export function NoteUpsertModalContainer({
insertAuditTrail({
jobid: context.jobId,
operation: AuditTrailMapping.jobnoteadded(),
+ type: "jobnoteadded",
});
}
};
diff --git a/client/src/components/parts-order-modal/parts-order-modal.container.jsx b/client/src/components/parts-order-modal/parts-order-modal.container.jsx
index 0f30012a3..b7edad316 100644
--- a/client/src/components/parts-order-modal/parts-order-modal.container.jsx
+++ b/client/src/components/parts-order-modal/parts-order-modal.container.jsx
@@ -1,12 +1,16 @@
-import { useMutation, useQuery, useApolloClient } from "@apollo/client";
+import { useApolloClient, useMutation, useQuery } from "@apollo/client";
+import { useTreatments } from "@splitsoftware/splitio-react";
import { Form, Modal, notification } from "antd";
+import axios from "axios";
+import _ from "lodash";
import moment from "moment";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
-import { logImEXEvent, auth } from "../../firebase/firebase.utils";
+import { auth, logImEXEvent } from "../../firebase/firebase.utils";
import { UPDATE_JOB_LINE_STATUS } from "../../graphql/jobs-lines.queries";
+import { UPDATE_JOB } from "../../graphql/jobs.queries";
import {
INSERT_NEW_PARTS_ORDERS,
QUERY_PARTS_ORDER_OEC,
@@ -29,10 +33,6 @@ import { TemplateList } from "../../utils/TemplateConstants";
import AlertComponent from "../alert/alert.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import PartsOrderModalComponent from "./parts-order-modal.component";
-import axios from "axios";
-import { useTreatments } from "@splitsoftware/splitio-react";
-import _ from "lodash";
-import { UPDATE_JOB } from "../../graphql/jobs.queries";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
@@ -45,8 +45,8 @@ const mapDispatchToProps = (dispatch) => ({
toggleModalVisible: () => dispatch(toggleModalVisible("partsOrder")),
setBillEnterContext: (context) =>
dispatch(setModalContext({ context: context, modal: "billEnter" })),
- insertAuditTrail: ({ jobid, operation }) =>
- dispatch(insertAuditTrail({ jobid, operation })),
+ insertAuditTrail: ({ jobid, operation, type }) =>
+ dispatch(insertAuditTrail({ jobid, operation, type })),
});
export function PartsOrderModalContainer({
@@ -142,6 +142,7 @@ export function PartsOrderModalContainer({
: AuditTrailMapping.jobspartsorder(
insertResult.data.insert_parts_orders.returning[0].order_number
),
+ type: isReturn ? "jobspartsreturn" : "jobspartsorder",
});
const jobLinesResult = await updateJobLines({
diff --git a/client/src/components/phonebook-form/phonebook-form.component.jsx b/client/src/components/phonebook-form/phonebook-form.component.jsx
index e40096ce9..4795c14ad 100644
--- a/client/src/components/phonebook-form/phonebook-form.component.jsx
+++ b/client/src/components/phonebook-form/phonebook-form.component.jsx
@@ -1,6 +1,12 @@
import { Button, Form, Input, PageHeader, Space } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import {
+ selectAuthLevel,
+ selectBodyshop,
+} from "../../redux/user/user.selectors";
import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
import FormItemEmail from "../form-items-formatted/email-form-item.component";
import PhoneFormItem, {
@@ -8,12 +14,6 @@ import PhoneFormItem, {
} from "../form-items-formatted/phone-form-item.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component";
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import {
- selectAuthLevel,
- selectBodyshop,
-} from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({
authLevel: selectAuthLevel,
bodyshop: selectBodyshop,
@@ -46,13 +46,19 @@ export function PhonebookFormComponent({
return (
+ {() =>
+ `${form.getFieldValue("firstname") || ""} ${
+ form.getFieldValue("lastname") || ""
+ }${
+ form.getFieldValue("company")
+ ? ` - ${form.getFieldValue("company")}`
+ : ""
+ }`
+ }
+
+ }
extra={