Compare commits
8 Commits
feature/IO
...
release/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4f4f45251 | ||
|
|
acc91abc0c | ||
|
|
d6d6ced7a4 | ||
|
|
17928741e3 | ||
|
|
f2914868e2 | ||
|
|
561f0313f9 | ||
|
|
02a49efbea | ||
|
|
4fb9c37c0d |
@@ -3645,6 +3645,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>returnfrombill</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>savewithdiscrepancy</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -13807,6 +13828,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>unavailable</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
|
||||
@@ -37,6 +37,9 @@ const CourtesyCarStatusComponent = ({ value, onChange }, ref) => {
|
||||
<Option value="courtesycars.status.leasereturn">
|
||||
{t("courtesycars.status.leasereturn")}
|
||||
</Option>
|
||||
<Option value="courtesycars.status.unavailable">
|
||||
{t("courtesycars.status.unavailable")}
|
||||
</Option>
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -77,6 +77,10 @@ export default function CourtesyCarsList({ loading, courtesycars, refetch }) {
|
||||
text: t("courtesycars.status.leasereturn"),
|
||||
value: "courtesycars.status.leasereturn",
|
||||
},
|
||||
{
|
||||
text: t("courtesycars.status.unavailable"),
|
||||
value: "courtesycars.status.unavailable",
|
||||
},
|
||||
],
|
||||
onFilter: (value, record) => record.status === value,
|
||||
sortOrder:
|
||||
|
||||
@@ -6,7 +6,8 @@ import { Link } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import { alphaSort, statusSort } from "../../utils/sorters";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
import { alphaSort, dateSort, statusSort } from "../../utils/sorters";
|
||||
import OwnerDetailUpdateJobsComponent from "../owner-detail-update-jobs/owner-detail-update-jobs.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
@@ -86,7 +87,18 @@ function OwnerDetailJobsComponent({ bodyshop, owner }) {
|
||||
})),
|
||||
onFilter: (value, record) => value.includes(record.status),
|
||||
},
|
||||
|
||||
{
|
||||
title: t("jobs.fields.actual_completion"),
|
||||
dataIndex: "actual_completion",
|
||||
key: "actual_completion",
|
||||
render: (text, record) => (
|
||||
<DateTimeFormatter>{record.actual_completion}</DateTimeFormatter>
|
||||
),
|
||||
sorter: (a, b) => dateSort(a.actual_completion, b.actual_completion),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "actual_completion" &&
|
||||
state.sortedInfo.order,
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.clm_total"),
|
||||
dataIndex: "clm_total",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DeleteFilled, EyeFilled, SyncOutlined } from "@ant-design/icons";
|
||||
import { useMutation } from "@apollo/client";
|
||||
import { useLazyQuery, useMutation } from "@apollo/client";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
@@ -13,20 +13,21 @@ import {
|
||||
Table,
|
||||
} from "antd";
|
||||
import queryString from "query-string";
|
||||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { QUERY_BILL_BY_PK } from "../../graphql/bills.queries";
|
||||
import { DELETE_PARTS_ORDER } from "../../graphql/parts-orders.queries";
|
||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import { DateFormatter } from "../../utils/DateFormatter";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
import { TemplateList } from "../../utils/TemplateConstants";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
import DataLabel from "../data-label/data-label.component";
|
||||
import PartsOrderBackorderEta from "../parts-order-backorder-eta/parts-order-backorder-eta.component";
|
||||
import PartsOrderCmReceived from "../parts-order-cm-received/parts-order-cm-received.component";
|
||||
@@ -78,19 +79,46 @@ export function PartsOrderListTableComponent({
|
||||
const [state, setState] = useState({
|
||||
sortedInfo: {},
|
||||
});
|
||||
|
||||
const [returnfrombill, setReturnFromBill] = useState();
|
||||
const [billData, setBillData] = useState();
|
||||
const search = queryString.parse(useLocation().search);
|
||||
const selectedpartsorder = search.partsorderid;
|
||||
const [searchText, setSearchText] = useState("");
|
||||
|
||||
const [billQuery] = useLazyQuery(QUERY_BILL_BY_PK);
|
||||
const [deletePartsOrder] = useMutation(DELETE_PARTS_ORDER);
|
||||
|
||||
const parts_orders = billsQuery.data ? billsQuery.data.parts_orders : [];
|
||||
const { refetch } = billsQuery;
|
||||
|
||||
useEffect(() => {
|
||||
if (returnfrombill === null) {
|
||||
setBillData(null);
|
||||
} else {
|
||||
const fetchData = async () => {
|
||||
const result = await billQuery({
|
||||
variables: { billid: returnfrombill },
|
||||
});
|
||||
setBillData(result.data);
|
||||
};
|
||||
fetchData();
|
||||
}
|
||||
}, [returnfrombill, billQuery]);
|
||||
|
||||
const recordActions = (record, showView = false) => (
|
||||
<Space wrap>
|
||||
{showView && (
|
||||
<Button onClick={() => handleOnRowClick(record)}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (record.returnfrombill) {
|
||||
setReturnFromBill(record.returnfrombill);
|
||||
} else {
|
||||
setReturnFromBill(null);
|
||||
}
|
||||
handleOnRowClick(record);
|
||||
}}
|
||||
>
|
||||
<EyeFilled />
|
||||
</Button>
|
||||
)}
|
||||
@@ -417,7 +445,11 @@ export function PartsOrderListTableComponent({
|
||||
return (
|
||||
<div>
|
||||
<PageHeader
|
||||
title={record && `${record.vendor.name} - ${record.order_number}`}
|
||||
title={
|
||||
billData
|
||||
? `${record.vendor.name} - ${record.order_number} - ${t("bills.labels.returnfrombill")}: ${billData.bills_by_pk.invoice_number}`
|
||||
: `${record.vendor.name} - ${record.order_number}`
|
||||
}
|
||||
extra={recordActions(record)}
|
||||
/>
|
||||
<Table
|
||||
|
||||
@@ -6,7 +6,8 @@ import { Link } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import { alphaSort, statusSort } from "../../utils/sorters";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
import { alphaSort, dateSort, statusSort } from "../../utils/sorters";
|
||||
import OwnerNameDisplay, {
|
||||
OwnerNameDisplayFunction,
|
||||
} from "../owner-name-display/owner-name-display.component";
|
||||
@@ -79,7 +80,18 @@ export function VehicleDetailJobsComponent({ vehicle, bodyshop }) {
|
||||
})),
|
||||
onFilter: (value, record) => value.includes(record.status),
|
||||
},
|
||||
|
||||
{
|
||||
title: t("jobs.fields.actual_completion"),
|
||||
dataIndex: "actual_completion",
|
||||
key: "actual_completion",
|
||||
render: (text, record) => (
|
||||
<DateTimeFormatter>{record.actual_completion}</DateTimeFormatter>
|
||||
),
|
||||
sorter: (a, b) => dateSort(a.actual_completion, b.actual_completion),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "actual_completion" &&
|
||||
state.sortedInfo.order,
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.clm_total"),
|
||||
dataIndex: "clm_total",
|
||||
|
||||
@@ -73,6 +73,7 @@ export const QUERY_BILLS_BY_JOBID = gql`
|
||||
order_date
|
||||
deliver_by
|
||||
return
|
||||
returnfrombill
|
||||
orderedby
|
||||
parts_order_lines {
|
||||
id
|
||||
|
||||
@@ -71,6 +71,7 @@ export const QUERY_OWNER_BY_ID = gql`
|
||||
tax_number
|
||||
jobs(order_by: { date_open: desc }) {
|
||||
id
|
||||
actual_completion
|
||||
ro_number
|
||||
clm_no
|
||||
status
|
||||
|
||||
@@ -30,6 +30,7 @@ export const QUERY_VEHICLE_BY_ID = gql`
|
||||
notes
|
||||
jobs(order_by: { date_open: desc }) {
|
||||
id
|
||||
actual_completion
|
||||
ro_number
|
||||
ownr_co_nm
|
||||
ownr_fn
|
||||
|
||||
@@ -222,6 +222,7 @@
|
||||
"onlycmforinvoiced": "Only credit memos can be entered for any Job that has been invoiced, exported, or voided.",
|
||||
"printlabels": "Print Labels",
|
||||
"retailtotal": "Bills Retail Total",
|
||||
"returnfrombill": "Return From Bill",
|
||||
"savewithdiscrepancy": "You are about to save this bill with a discrepancy. The system will continue to use the calculated amount using the bill lines. Press cancel to return to the bill.",
|
||||
"state_tax": "Provincial/State Tax",
|
||||
"subtotal": "Subtotal",
|
||||
@@ -827,10 +828,11 @@
|
||||
},
|
||||
"status": {
|
||||
"in": "Available",
|
||||
"inservice": "In Service",
|
||||
"inservice": "Service/Maintenance",
|
||||
"leasereturn": "Lease Returned",
|
||||
"out": "Rented",
|
||||
"sold": "Sold"
|
||||
"sold": "Sold",
|
||||
"unavailable": "Unavailable"
|
||||
},
|
||||
"successes": {
|
||||
"saved": "Courtesy Car saved successfully."
|
||||
|
||||
@@ -222,6 +222,7 @@
|
||||
"onlycmforinvoiced": "",
|
||||
"printlabels": "",
|
||||
"retailtotal": "",
|
||||
"returnfrombill": "",
|
||||
"savewithdiscrepancy": "",
|
||||
"state_tax": "",
|
||||
"subtotal": "",
|
||||
@@ -830,7 +831,8 @@
|
||||
"inservice": "",
|
||||
"leasereturn": "",
|
||||
"out": "",
|
||||
"sold": ""
|
||||
"sold": "",
|
||||
"unavailable": ""
|
||||
},
|
||||
"successes": {
|
||||
"saved": ""
|
||||
|
||||
@@ -222,6 +222,7 @@
|
||||
"onlycmforinvoiced": "",
|
||||
"printlabels": "",
|
||||
"retailtotal": "",
|
||||
"returnfrombill": "",
|
||||
"savewithdiscrepancy": "",
|
||||
"state_tax": "",
|
||||
"subtotal": "",
|
||||
@@ -830,7 +831,8 @@
|
||||
"inservice": "",
|
||||
"leasereturn": "",
|
||||
"out": "",
|
||||
"sold": ""
|
||||
"sold": "",
|
||||
"unavailable": ""
|
||||
},
|
||||
"successes": {
|
||||
"saved": ""
|
||||
|
||||
@@ -224,11 +224,34 @@ exports.default = async function (socket, jobid) {
|
||||
if (mapaAccount) {
|
||||
if (!costCenterHash[mapaAccountName])
|
||||
costCenterHash[mapaAccountName] = Dinero();
|
||||
costCenterHash[mapaAccountName] = costCenterHash[mapaAccountName].add(
|
||||
Dinero(job.job_totals.rates.mapa.total).percentage(
|
||||
bodyshop?.cdk_configuration?.sendmaterialscosting
|
||||
)
|
||||
);
|
||||
if (job.bodyshop.use_paint_scale_data === true) {
|
||||
if (job.mixdata.length > 0) {
|
||||
costCenterHash[mapaAccountName] = costCenterHash[
|
||||
mapaAccountName
|
||||
].add(
|
||||
Dinero({
|
||||
amount: Math.round(
|
||||
((job.mixdata[0] && job.mixdata[0].totalliquidcost) || 0) *
|
||||
100
|
||||
),
|
||||
})
|
||||
);
|
||||
} else {
|
||||
costCenterHash[mapaAccountName] = costCenterHash[
|
||||
mapaAccountName
|
||||
].add(
|
||||
Dinero(job.job_totals.rates.mapa.total).percentage(
|
||||
bodyshop?.cdk_configuration?.sendmaterialscosting
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
costCenterHash[mapaAccountName] = costCenterHash[mapaAccountName].add(
|
||||
Dinero(job.job_totals.rates.mapa.total).percentage(
|
||||
bodyshop?.cdk_configuration?.sendmaterialscosting
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
//console.log("NO MAPA ACCOUNT FOUND!!");
|
||||
}
|
||||
|
||||
@@ -1793,6 +1793,7 @@ exports.GET_CDK_ALLOCATIONS = `query QUERY_JOB_CLOSE_DETAILS($id: uuid!) {
|
||||
md_responsibility_centers
|
||||
cdk_configuration
|
||||
pbs_configuration
|
||||
use_paint_scale_data
|
||||
}
|
||||
ro_number
|
||||
dms_allocation
|
||||
@@ -1900,6 +1901,10 @@ exports.GET_CDK_ALLOCATIONS = `query QUERY_JOB_CLOSE_DETAILS($id: uuid!) {
|
||||
line_ref
|
||||
unq_seq
|
||||
}
|
||||
mixdata(limit: 1, order_by: {updated_at: desc}) {
|
||||
jobid
|
||||
totalliquidcost
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user