Merged in release/2024-03-08 (pull request #1331)
Release into Master for 03 08 Release Approved-by: Allan Carr
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
@@ -138,7 +138,6 @@ export function AccountingPayablesTableComponent({
|
||||
title: t("exportlogs.labels.attempts"),
|
||||
dataIndex: "attempts",
|
||||
key: "attempts",
|
||||
|
||||
render: (text, record) => (
|
||||
<ExportLogsCountDisplay logs={record.exportlogs} />
|
||||
),
|
||||
@@ -147,8 +146,6 @@ export function AccountingPayablesTableComponent({
|
||||
title: t("general.labels.actions"),
|
||||
dataIndex: "actions",
|
||||
key: "actions",
|
||||
sorter: (a, b) => a.clm_total - b.clm_total,
|
||||
|
||||
render: (text, record) => (
|
||||
<PayableExportButton
|
||||
billId={record.id}
|
||||
|
||||
@@ -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,11 @@ 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.job),
|
||||
OwnerNameDisplayFunction(b.job)
|
||||
),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
|
||||
render: (text, record) => {
|
||||
@@ -94,6 +100,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) => (
|
||||
<CurrencyFormatter>{record.amount}</CurrencyFormatter>
|
||||
),
|
||||
@@ -112,18 +121,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) => (
|
||||
<DateTimeFormatter>{record.created_at}</DateTimeFormatter>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("payments.fields.exportedat"),
|
||||
dataIndex: "exportedat",
|
||||
key: "exportedat",
|
||||
render: (text, record) => (
|
||||
<DateTimeFormatter>{record.exportedat}</DateTimeFormatter>
|
||||
),
|
||||
},
|
||||
// {
|
||||
// title: t("payments.fields.exportedat"),
|
||||
// dataIndex: "exportedat",
|
||||
// key: "exportedat",
|
||||
// render: (text, record) => (
|
||||
// <DateTimeFormatter>{record.exportedat}</DateTimeFormatter>
|
||||
// ),
|
||||
// },
|
||||
{
|
||||
title: t("exportlogs.labels.attempts"),
|
||||
dataIndex: "attempts",
|
||||
@@ -137,8 +149,6 @@ export function AccountingPayablesTableComponent({
|
||||
title: t("general.labels.actions"),
|
||||
dataIndex: "actions",
|
||||
key: "actions",
|
||||
sorter: (a, b) => a.clm_total - b.clm_total,
|
||||
|
||||
render: (text, record) => (
|
||||
<PaymentExportButton
|
||||
paymentId={record.id}
|
||||
|
||||
@@ -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 ? (
|
||||
<Link to={"/manage/vehicles/" + record.vehicleid}>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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",
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -53,6 +53,7 @@ export default function ScheduleEventContainer({ bodyshop, event, refetch }) {
|
||||
insertAuditTrail({
|
||||
jobid: event.job.id,
|
||||
operation: AuditTrailMapping.appointmentcancel(lost_sale_reason),
|
||||
type: "appointmentcancel",
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"]({
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
})
|
||||
|
||||
@@ -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",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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"]({
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"]({
|
||||
|
||||
@@ -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",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
})
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -29,6 +29,7 @@ export default function AddToProduction(
|
||||
insertAuditTrail({
|
||||
jobid: jobId,
|
||||
operation: AuditTrailMapping.jobinproductionchange(!remove),
|
||||
type: "jobinproductionchange",
|
||||
})
|
||||
);
|
||||
if (completionCallback) completionCallback();
|
||||
|
||||
@@ -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/`);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ? (
|
||||
<Link
|
||||
@@ -266,6 +278,9 @@ export function JobsList({ bodyshop }) {
|
||||
dataIndex: "ins_co_nm",
|
||||
key: "ins_co_nm",
|
||||
ellipsis: true,
|
||||
sorter: (a, b) => 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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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 (
|
||||
<div>
|
||||
<PageHeader
|
||||
title={`${form.getFieldValue("firstname") || ""} ${
|
||||
form.getFieldValue("lastname") || ""
|
||||
}${
|
||||
form.getFieldValue("company")
|
||||
? ` - ${form.getFieldValue("company")}`
|
||||
: ""
|
||||
}`}
|
||||
title={
|
||||
<Form.Item shouldUpdate>
|
||||
{() =>
|
||||
`${form.getFieldValue("firstname") || ""} ${
|
||||
form.getFieldValue("lastname") || ""
|
||||
}${
|
||||
form.getFieldValue("company")
|
||||
? ` - ${form.getFieldValue("company")}`
|
||||
: ""
|
||||
}`
|
||||
}
|
||||
</Form.Item>
|
||||
}
|
||||
extra={
|
||||
<Space>
|
||||
<Button
|
||||
|
||||
@@ -29,8 +29,8 @@ const mapStateToProps = createStructuredSelector({
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
insertAuditTrail: ({ jobid, operation }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation })),
|
||||
insertAuditTrail: ({ jobid, operation, type }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation, type })),
|
||||
});
|
||||
|
||||
export function ProductionBoardKanbanComponent({
|
||||
@@ -133,6 +133,7 @@ export function ProductionBoardKanbanComponent({
|
||||
insertAuditTrail({
|
||||
jobid: card.id,
|
||||
operation: AuditTrailMapping.jobstatuschange(destination.toColumnId),
|
||||
type: "jobstatuschange",
|
||||
});
|
||||
|
||||
if (update.errors) {
|
||||
|
||||
@@ -13,8 +13,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 function ProductionListColumnAlert({ record, insertAuditTrail }) {
|
||||
@@ -46,6 +46,7 @@ export function ProductionListColumnAlert({ record, insertAuditTrail }) {
|
||||
? !record.production_vars.alert
|
||||
: true
|
||||
),
|
||||
type: "alertToggle",
|
||||
}).then(() => {
|
||||
if (record.refetch) record.refetch();
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { BranchesOutlined, PauseCircleOutlined } from "@ant-design/icons";
|
||||
import { Space, Tooltip } from "antd";
|
||||
import { Checkbox, Space, Tooltip } from "antd";
|
||||
import i18n from "i18next";
|
||||
import moment from "moment";
|
||||
import { Link } from "react-router-dom";
|
||||
@@ -10,7 +10,9 @@ import { onlyUnique } from "../../utils/arrayHelper";
|
||||
import { alphaSort, dateSort, statusSort } from "../../utils/sorters";
|
||||
import JobAltTransportChange from "../job-at-change/job-at-change.component";
|
||||
import JobPartsQueueCount from "../job-parts-queue-count/job-parts-queue-count.component";
|
||||
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
|
||||
import OwnerNameDisplay, {
|
||||
OwnerNameDisplayFunction,
|
||||
} from "../owner-name-display/owner-name-display.component";
|
||||
import ProductionSubletsManageComponent from "../production-sublets-manage/production-sublets-manage.component";
|
||||
import ProductionListColumnAlert from "./production-list-columns.alert.component";
|
||||
import ProductionListColumnBodyPriority from "./production-list-columns.bodypriority.component";
|
||||
@@ -84,7 +86,8 @@ const r = ({ technician, state, activeStatuses, data, bodyshop }) => {
|
||||
<OwnerNameDisplay ownerObject={record} />
|
||||
</Link>
|
||||
),
|
||||
sorter: (a, b) => alphaSort(a.ownr_ln, b.ownr_ln),
|
||||
sorter: (a, b) =>
|
||||
alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "ownr" && state.sortedInfo.order,
|
||||
},
|
||||
@@ -95,8 +98,10 @@ const r = ({ technician, state, activeStatuses, data, bodyshop }) => {
|
||||
ellipsis: true,
|
||||
sorter: (a, b) =>
|
||||
alphaSort(
|
||||
a.v_make_desc + a.v_model_desc,
|
||||
b.v_make_desc + b.v_model_desc
|
||||
`${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,
|
||||
@@ -291,6 +296,20 @@ const r = ({ technician, state, activeStatuses, data, bodyshop }) => {
|
||||
dataIndex: "special_coverage_policy",
|
||||
key: "special_coverage_policy",
|
||||
ellipsis: true,
|
||||
sorter: (a, b) =>
|
||||
Number(a.special_coverage_policy) - Number(b.special_coverage_policy),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "special_coverage_policy" &&
|
||||
state.sortedInfo.order,
|
||||
filters: [
|
||||
{ text: "True", value: true },
|
||||
{ text: "False", value: false },
|
||||
],
|
||||
onFilter: (value, record) =>
|
||||
value.includes(record.special_coverage_policy),
|
||||
render: (text, record) => (
|
||||
<Checkbox disabled checked={record.special_coverage_policy} />
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
@@ -302,6 +321,16 @@ const r = ({ technician, state, activeStatuses, data, bodyshop }) => {
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "alt_transport" &&
|
||||
state.sortedInfo.order,
|
||||
filters:
|
||||
(bodyshop &&
|
||||
bodyshop.appt_alt_transport.map((s) => {
|
||||
return {
|
||||
text: s,
|
||||
value: [s],
|
||||
};
|
||||
})) ||
|
||||
[],
|
||||
onFilter: (value, record) => value.includes(record.alt_transport),
|
||||
render: (text, record) => (
|
||||
<div>
|
||||
{record.alt_transport}
|
||||
@@ -382,7 +411,11 @@ const r = ({ technician, state, activeStatuses, data, bodyshop }) => {
|
||||
title: i18n.t("production.labels.alert"),
|
||||
dataIndex: "alert",
|
||||
key: "alert",
|
||||
|
||||
sorter: (a, b) =>
|
||||
Number(a.production_vars?.alert || false) -
|
||||
Number(b.production_vars?.alert || false),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "alert" && state.sortedInfo.order,
|
||||
render: (text, record) => <ProductionListColumnAlert record={record} />,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -3,12 +3,12 @@ import { useMutation } from "@apollo/client";
|
||||
import {
|
||||
Button,
|
||||
Col,
|
||||
notification,
|
||||
Popover,
|
||||
Row,
|
||||
Select,
|
||||
Space,
|
||||
Spin,
|
||||
notification,
|
||||
} from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -25,8 +25,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 function ProductionListEmpAssignment({
|
||||
@@ -55,6 +55,7 @@ export function ProductionListEmpAssignment({
|
||||
insertAuditTrail({
|
||||
jobid: record.id,
|
||||
operation: AuditTrailMapping.jobassignmentchange(empAssignment, name),
|
||||
type: "jobassignmentchange",
|
||||
});
|
||||
|
||||
if (!!result.errors) {
|
||||
@@ -80,6 +81,7 @@ export function ProductionListEmpAssignment({
|
||||
insertAuditTrail({
|
||||
jobid: record.id,
|
||||
operation: AuditTrailMapping.jobassignmentremoved(empAssignment),
|
||||
type: "jobassignmentremoved",
|
||||
});
|
||||
|
||||
if (!!result.errors) {
|
||||
|
||||
@@ -12,8 +12,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 function ProductionListColumnCategory({ record, bodyshop }) {
|
||||
const [updateJob] = useMutation(UPDATE_JOB);
|
||||
|
||||
@@ -5,16 +5,16 @@ import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { UPDATE_JOB } from "../../graphql/jobs.queries";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
|
||||
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 function ProductionListColumnStatus({
|
||||
record,
|
||||
@@ -40,6 +40,7 @@ export function ProductionListColumnStatus({
|
||||
insertAuditTrail({
|
||||
jobid: record.id,
|
||||
operation: AuditTrailMapping.jobstatuschange(key),
|
||||
type: "jobstatuschange",
|
||||
});
|
||||
|
||||
setLoading(false);
|
||||
|
||||
@@ -142,7 +142,8 @@ function FiltersSection({filters, form, bodyshop}) {
|
||||
return generateInternalReflections({
|
||||
bodyshop,
|
||||
upperPath,
|
||||
finalPath
|
||||
finalPath,
|
||||
t
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ const generateOptionsFromArray = (bodyshop, path) => {
|
||||
})), 'value');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Valid internal reflections
|
||||
* Note: This is intended for future functionality
|
||||
@@ -57,10 +56,34 @@ const generateOptionsFromObject = (bodyshop, path, labelPath, valuePath) => {
|
||||
* Generate special reflections
|
||||
* @param bodyshop
|
||||
* @param finalPath
|
||||
* @param t - i18n
|
||||
* @returns {{label: *, value: *}[]|{label: *, value: *}[]|{label: string, value: *}[]|*[]}
|
||||
*/
|
||||
const generateSpecialReflections = (bodyshop, finalPath) => {
|
||||
const generateSpecialReflections = (bodyshop, finalPath, t) => {
|
||||
switch (finalPath) {
|
||||
case 'payment_payers':
|
||||
return [
|
||||
{
|
||||
label: t("payments.labels.customer"),
|
||||
value: t("payments.labels.customer"),
|
||||
},
|
||||
{
|
||||
label: t("payments.labels.insurance"),
|
||||
value: t("payments.labels.insurance"),
|
||||
},
|
||||
// This is a weird one supposedly only used by one shop and could potentially be
|
||||
// placed behind a SplitSDK
|
||||
{
|
||||
label: t("payments.labels.external"),
|
||||
value: t("payments.labels.external"),
|
||||
}
|
||||
];
|
||||
case 'payment_types':
|
||||
return generateOptionsFromArray(bodyshop, 'md_payment_types');
|
||||
case 'alt_transports':
|
||||
return generateOptionsFromArray(bodyshop, 'appt_alt_transport');
|
||||
case 'lost_sale_reasons':
|
||||
return generateOptionsFromArray(bodyshop, 'md_lost_sale_reasons');
|
||||
// Special case because Referral Sources is an Array, not an Object.
|
||||
case 'referral_source':
|
||||
return generateOptionsFromArray(bodyshop, 'md_referral_sources');
|
||||
@@ -121,12 +144,13 @@ const generateBodyshopReflections = (bodyshop, finalPath) => {
|
||||
* @param bodyshop
|
||||
* @param upperPath
|
||||
* @param finalPath
|
||||
* @param t - i18n
|
||||
* @returns {{label: *, value: *}[]|[]|{label: *, value: *}[]|{label: string, value: *}[]|{label: *, value: *}[]|*[]}
|
||||
*/
|
||||
const generateInternalReflections = ({bodyshop, upperPath, finalPath}) => {
|
||||
const generateInternalReflections = ({bodyshop, upperPath, finalPath, t}) => {
|
||||
switch (upperPath) {
|
||||
case 'special':
|
||||
return generateSpecialReflections(bodyshop, finalPath);
|
||||
return generateSpecialReflections(bodyshop, finalPath, t);
|
||||
case 'bodyshop':
|
||||
return generateBodyshopReflections(bodyshop, finalPath);
|
||||
default:
|
||||
|
||||
@@ -34,8 +34,8 @@ const mapStateToProps = createStructuredSelector({
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
toggleModalVisible: () => dispatch(toggleModalVisible("schedule")),
|
||||
setEmailOptions: (e) => dispatch(setEmailOptions(e)),
|
||||
insertAuditTrail: ({ jobid, operation }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation })),
|
||||
insertAuditTrail: ({ jobid, operation, type }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation, type })),
|
||||
});
|
||||
|
||||
export function ScheduleJobModalContainer({
|
||||
@@ -146,6 +146,7 @@ export function ScheduleJobModalContainer({
|
||||
operation: AuditTrailMapping.appointmentinsert(
|
||||
DateTimeFormat(values.start)
|
||||
),
|
||||
type: "appointmentinsert",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ export const INSERT_AUDIT_TRAIL = gql`
|
||||
bodyshopid
|
||||
created
|
||||
operation
|
||||
type
|
||||
useremail
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1862,6 +1862,7 @@ export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql`
|
||||
ownr_co_nm
|
||||
ownr_ph1
|
||||
ownr_ph2
|
||||
ownerid
|
||||
plate_no
|
||||
plate_st
|
||||
v_vin
|
||||
|
||||
@@ -40,8 +40,8 @@ const mapStateToProps = createStructuredSelector({
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
|
||||
setSelectedHeader: (key) => dispatch(setSelectedHeader(key)),
|
||||
insertAuditTrail: ({ jobid, operation }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation })),
|
||||
insertAuditTrail: ({ jobid, operation, type }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation, type })),
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(DmsContainer);
|
||||
@@ -127,6 +127,7 @@ export function DmsContainer({
|
||||
insertAuditTrail({
|
||||
jobid: payload,
|
||||
operation: AuditTrailMapping.jobexported(),
|
||||
type: "jobexported",
|
||||
});
|
||||
history.push("/manage/accounting/receivables");
|
||||
});
|
||||
|
||||
@@ -12,7 +12,8 @@ import AlertComponent from "../../components/alert/alert.component";
|
||||
import { QUERY_EXPORT_LOG_PAGINATED } from "../../graphql/accounting.queries";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
import {pageLimit} from "../../utils/config";
|
||||
import { pageLimit } from "../../utils/config";
|
||||
import { alphaSort, dateSort } from "./../../utils/sorters";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -34,11 +35,43 @@ export function ExportLogsPageComponent({ bodyshop }) {
|
||||
limit: pageLimit,
|
||||
order: [
|
||||
{
|
||||
[sortcolumn || "created_at"]: sortorder
|
||||
? sortorder === "descend"
|
||||
? "desc"
|
||||
: "asc"
|
||||
: "desc",
|
||||
...(sortcolumn === "ro_number"
|
||||
? {
|
||||
job: {
|
||||
[sortcolumn || "created_at"]: sortorder
|
||||
? sortorder === "descend"
|
||||
? "desc"
|
||||
: "asc"
|
||||
: "desc",
|
||||
},
|
||||
}
|
||||
: sortcolumn === "invoice_number"
|
||||
? {
|
||||
bill: {
|
||||
[sortcolumn || "created_at"]: sortorder
|
||||
? sortorder === "descend"
|
||||
? "desc"
|
||||
: "asc"
|
||||
: "desc",
|
||||
},
|
||||
}
|
||||
: sortcolumn === "paymentnum"
|
||||
? {
|
||||
payment: {
|
||||
[sortcolumn || "created_at"]: sortorder
|
||||
? sortorder === "descend"
|
||||
? "desc"
|
||||
: "asc"
|
||||
: "desc",
|
||||
},
|
||||
}
|
||||
: {
|
||||
[sortcolumn || "created_at"]: sortorder
|
||||
? sortorder === "descend"
|
||||
? "desc"
|
||||
: "asc"
|
||||
: "desc",
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -68,6 +101,8 @@ export function ExportLogsPageComponent({ bodyshop }) {
|
||||
title: t("general.labels.created_at"),
|
||||
dataIndex: "created_at",
|
||||
key: "created_at",
|
||||
sorter: (a, b) => dateSort(a.created_at, b.created_at),
|
||||
sortOrder: sortcolumn === "created_at" && sortorder,
|
||||
render: (text, record) => (
|
||||
<DateTimeFormatter>{record.created_at}</DateTimeFormatter>
|
||||
),
|
||||
@@ -81,7 +116,8 @@ export function ExportLogsPageComponent({ bodyshop }) {
|
||||
title: t("jobs.fields.ro_number"),
|
||||
dataIndex: "ro_number",
|
||||
key: "ro_number",
|
||||
|
||||
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
|
||||
sortOrder: sortcolumn === "ro_number" && sortorder,
|
||||
render: (text, record) =>
|
||||
record.job && (
|
||||
<Link to={`/manage/jobs/${record.job.id}`}>
|
||||
@@ -93,6 +129,8 @@ export function ExportLogsPageComponent({ bodyshop }) {
|
||||
title: t("bills.fields.invoice_number"),
|
||||
dataIndex: "invoice_number",
|
||||
key: "invoice_number",
|
||||
sorter: (a, b) => alphaSort(a.invoice_number, b.invoice_number),
|
||||
sortOrder: sortcolumn === "invoice_number" && sortorder,
|
||||
render: (text, record) =>
|
||||
record.bill && (
|
||||
<Link to={"/manage/bills?billid=" + (record.bill && record.bill.id)}>
|
||||
@@ -104,6 +142,8 @@ export function ExportLogsPageComponent({ bodyshop }) {
|
||||
title: t("payments.fields.paymentnum"),
|
||||
dataIndex: "paymentnum",
|
||||
key: "paymentnum",
|
||||
sorter: (a, b) => alphaSort(a.paymentnum, b.paymentnum),
|
||||
sortOrder: sortcolumn === "paymentnum" && sortorder,
|
||||
render: (text, record) =>
|
||||
record.payment && (
|
||||
<Link
|
||||
@@ -120,6 +160,13 @@ export function ExportLogsPageComponent({ bodyshop }) {
|
||||
title: t("general.labels.successful"),
|
||||
dataIndex: "successful",
|
||||
key: "successful",
|
||||
sorter: (a, b) => Number(a.successful) - Number(b.successful),
|
||||
sortOrder: sortcolumn === "successful" && sortorder,
|
||||
filters: [
|
||||
{ text: "True", value: true },
|
||||
{ text: "False", value: false },
|
||||
],
|
||||
onFilter: (value, record) => record.successful === value,
|
||||
render: (text, record) => (
|
||||
<Checkbox disabled checked={record.successful} />
|
||||
),
|
||||
|
||||
@@ -47,11 +47,11 @@ const mapStateToProps = createStructuredSelector({
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
insertAuditTrail: ({ jobid, operation }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation })),
|
||||
insertAuditTrail: ({ jobid, operation, type }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation, type })),
|
||||
});
|
||||
|
||||
export function JobsCloseComponent({ job, bodyshop, jobRO, insertAuditTrail, }) {
|
||||
export function JobsCloseComponent({ job, bodyshop, jobRO, insertAuditTrail }) {
|
||||
const { t } = useTranslation();
|
||||
const [form] = Form.useForm();
|
||||
const client = useApolloClient();
|
||||
@@ -121,6 +121,7 @@ export function JobsCloseComponent({ job, bodyshop, jobRO, insertAuditTrail, })
|
||||
insertAuditTrail({
|
||||
jobid: job.id,
|
||||
operation: AuditTrailMapping.jobinvoiced(),
|
||||
type: "jobinvoiced",
|
||||
});
|
||||
// history.push(`/manage/jobs/${job.id}`);
|
||||
} else {
|
||||
|
||||
@@ -29,6 +29,7 @@ import { createStructuredSelector } from "reselect";
|
||||
import FormFieldsChanged from "../../components/form-fields-changed-alert/form-fields-changed-alert.component";
|
||||
import JobAuditTrail from "../../components/job-audit-trail/job-audit-trail.component";
|
||||
import JobsLinesContainer from "../../components/job-detail-lines/job-lines.container";
|
||||
import JobLifecycleComponent from "../../components/job-lifecycle/job-lifecycle.component";
|
||||
import JobLineUpsertModalContainer from "../../components/job-lines-upsert-modal/job-lines-upsert-modal.container";
|
||||
import JobReconciliationModal from "../../components/job-reconciliation-modal/job-reconciliation.modal.container";
|
||||
import JobSyncButton from "../../components/job-sync-button/job-sync-button.component";
|
||||
@@ -54,7 +55,6 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
import UndefinedToNull from "../../utils/undefinedtonull";
|
||||
import { DateTimeFormat } from "./../../utils/DateFormatter";
|
||||
import JobLifecycleComponent from "../../components/job-lifecycle/job-lifecycle.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -63,8 +63,8 @@ const mapStateToProps = createStructuredSelector({
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setPrintCenterContext: (context) =>
|
||||
dispatch(setModalContext({ context: context, modal: "printCenter" })),
|
||||
insertAuditTrail: ({ jobid, operation }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation })),
|
||||
insertAuditTrail: ({ jobid, operation, type }) =>
|
||||
dispatch(insertAuditTrail({ jobid, operation, type })),
|
||||
});
|
||||
export function JobsDetailPage({
|
||||
bodyshop,
|
||||
@@ -177,6 +177,7 @@ export function JobsDetailPage({
|
||||
? DateTimeFormat(changedAuditFields[key])
|
||||
: changedAuditFields[key]
|
||||
),
|
||||
type: "jobfieldchange",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -334,15 +335,23 @@ export function JobsDetailPage({
|
||||
>
|
||||
<JobsDetailLaborContainer job={job} jobId={job.id} />
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane
|
||||
forceRender
|
||||
tab={<span><BarsOutlined />{t('menus.jobsdetail.lifecycle')}</span>}
|
||||
key="lifecycle"
|
||||
>
|
||||
<JobLifecycleComponent job={job} statuses={bodyshop.md_ro_statuses}/>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane
|
||||
forceRender
|
||||
tab={
|
||||
<span>
|
||||
<BarsOutlined />
|
||||
{t("menus.jobsdetail.lifecycle")}
|
||||
</span>
|
||||
}
|
||||
key="lifecycle"
|
||||
>
|
||||
<JobLifecycleComponent
|
||||
job={job}
|
||||
statuses={bodyshop.md_ro_statuses}
|
||||
/>
|
||||
</Tabs.TabPane>
|
||||
|
||||
<Tabs.TabPane
|
||||
<Tabs.TabPane
|
||||
forceRender
|
||||
tab={
|
||||
<span>
|
||||
|
||||
@@ -54,9 +54,9 @@ export const setOnline = (isOnline) => ({
|
||||
payload: isOnline,
|
||||
});
|
||||
|
||||
export const insertAuditTrail = ({ jobid, billid, operation }) => ({
|
||||
export const insertAuditTrail = ({ jobid, billid, operation, type }) => ({
|
||||
type: ApplicationActionTypes.INSERT_AUDIT_TRAIL,
|
||||
payload: { jobid, billid, operation },
|
||||
payload: { jobid, billid, operation, type },
|
||||
});
|
||||
export const setProblemJobs = (problemJobs) => ({
|
||||
type: ApplicationActionTypes.SET_PROBLEM_JOBS,
|
||||
|
||||
@@ -266,7 +266,7 @@ export function* onInsertAuditTrail() {
|
||||
}
|
||||
|
||||
export function* insertAuditTrailSaga({
|
||||
payload: { jobid, billid, operation },
|
||||
payload: { jobid, billid, operation, type },
|
||||
}) {
|
||||
const state = yield select();
|
||||
const bodyshop = state.user.bodyshop;
|
||||
@@ -278,6 +278,7 @@ export function* insertAuditTrailSaga({
|
||||
jobid,
|
||||
billid,
|
||||
operation,
|
||||
type,
|
||||
useremail: currentUser.email,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -259,28 +259,30 @@
|
||||
- active:
|
||||
_eq: true
|
||||
columns:
|
||||
- id
|
||||
- billid
|
||||
- bodyshopid
|
||||
- created
|
||||
- operation
|
||||
- id
|
||||
- jobid
|
||||
- new_val
|
||||
- old_val
|
||||
- operation
|
||||
- type
|
||||
- useremail
|
||||
- bodyshopid
|
||||
- jobid
|
||||
- billid
|
||||
select_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
columns:
|
||||
- billid
|
||||
- bodyshopid
|
||||
- created
|
||||
- id
|
||||
- jobid
|
||||
- new_val
|
||||
- old_val
|
||||
- operation
|
||||
- type
|
||||
- useremail
|
||||
- created
|
||||
- billid
|
||||
- bodyshopid
|
||||
- jobid
|
||||
filter:
|
||||
bodyshop:
|
||||
associations:
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Could not auto-generate a down migration.
|
||||
-- Please write an appropriate down migration for the SQL below:
|
||||
-- alter table "public"."audit_trail" add column "type" text
|
||||
-- null;
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."audit_trail" add column "type" text
|
||||
null;
|
||||
Reference in New Issue
Block a user