Add bill ref to job lines table. IO-582
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<babeledit_project be_version="2.7.1" version="1.2">
|
||||
<babeledit_project version="1.2" be_version="2.7.1">
|
||||
<!--
|
||||
|
||||
BabelEdit project file
|
||||
@@ -12294,6 +12294,27 @@
|
||||
<folder_node>
|
||||
<name>labels</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>billref</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>edit</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
import { SyncOutlined, FilterFilled } from "@ant-design/icons";
|
||||
import { FilterFilled, SyncOutlined } from "@ant-design/icons";
|
||||
import { useQuery } from "@apollo/react-hooks";
|
||||
import { Button, Dropdown, Input, Menu, Table } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { Link } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { QUERY_BILLS_BY_JOB_REF } from "../../graphql/bill-lines.queries";
|
||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
||||
import { onlyUnique } from "../../utils/arrayHelper";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
import JobLineLocationPopup from "../job-line-location-popup/job-line-location-popup.component";
|
||||
import JobLineNotePopup from "../job-line-note-popup/job-line-note-popup.component";
|
||||
import JobLinesBillRefernece from "../job-lines-bill-reference/job-lines-bill-reference.component";
|
||||
// import AllocationsAssignmentContainer from "../allocations-assignment/allocations-assignment.container";
|
||||
// import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container";
|
||||
// import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container";
|
||||
import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container";
|
||||
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
jobRO: selectJobReadOnly,
|
||||
@@ -42,6 +44,29 @@ export function JobLinesComponent({
|
||||
setJobLineEditContext,
|
||||
form,
|
||||
}) {
|
||||
const {
|
||||
loading: billLinesLoading,
|
||||
error: billLinesError,
|
||||
data: billLinesData,
|
||||
} = useQuery(QUERY_BILLS_BY_JOB_REF, {
|
||||
variables: { jobId: job.id },
|
||||
skip: loading,
|
||||
});
|
||||
|
||||
console.log("billLinesLoading :>> ", billLinesLoading);
|
||||
const billLinesDataObj = useMemo(() => {
|
||||
console.log("Memoized object called");
|
||||
if (!billLinesData) return {};
|
||||
const ret = {};
|
||||
billLinesData.billlines.map((b) => {
|
||||
if (b.joblineid) {
|
||||
ret[b.joblineid] = { ...b, total: b.actual_price * b.quantity };
|
||||
}
|
||||
return null;
|
||||
});
|
||||
return ret;
|
||||
}, [billLinesData]);
|
||||
|
||||
const [state, setState] = useState({
|
||||
sortedInfo: {},
|
||||
filteredInfo: {},
|
||||
@@ -200,6 +225,18 @@ export function JobLinesComponent({
|
||||
<JobLineLocationPopup jobline={record} disabled={jobRO} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("joblines.labels.billref"),
|
||||
dataIndex: "billref",
|
||||
key: "billref",
|
||||
render: (text, record) => (
|
||||
<JobLinesBillRefernece
|
||||
jobline={record}
|
||||
loading={billLinesLoading}
|
||||
billLinesObject={billLinesDataObj}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t("joblines.fields.status"),
|
||||
dataIndex: "status",
|
||||
@@ -383,25 +420,25 @@ export function JobLinesComponent({
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
expandedRowRender={(record) => (
|
||||
<div>
|
||||
<strong>{t("parts_orders.labels.orderhistory")}</strong>
|
||||
{record.parts_order_lines.map((item) => (
|
||||
<div key={item.id}>
|
||||
<Link
|
||||
to={`/manage/jobs/${job.id}?tab=partssublet&partsorderid=${item.parts_order.id}`}
|
||||
>
|
||||
{item.parts_order.order_number || ""}
|
||||
</Link>
|
||||
-
|
||||
<Link to={`/manage/shop/vendors/${item.parts_order.vendor.id}`}>
|
||||
{item.parts_order.vendor.name || ""}
|
||||
</Link>
|
||||
{` on ${item.parts_order.order_date || ""}`}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
// expandedRowRender={(record) => (
|
||||
// <div>
|
||||
// <strong>{t("parts_orders.labels.orderhistory")}</strong>
|
||||
// {record.parts_order_lines.map((item) => (
|
||||
// <div key={item.id}>
|
||||
// <Link
|
||||
// to={`/manage/jobs/${job.id}?tab=partssublet&partsorderid=${item.parts_order.id}`}
|
||||
// >
|
||||
// {item.parts_order.order_number || ""}
|
||||
// </Link>
|
||||
// -
|
||||
// <Link to={`/manage/shop/vendors/${item.parts_order.vendor.id}`}>
|
||||
// {item.parts_order.vendor.name || ""}
|
||||
// </Link>
|
||||
// {` on ${item.parts_order.order_date || ""}`}
|
||||
// </div>
|
||||
// ))}
|
||||
// </div>
|
||||
// )}
|
||||
rowClassName="table-small-margin"
|
||||
rowSelection={{
|
||||
selectedRowKeys: selectedLines.map((item) => item.id),
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Spin } from "antd";
|
||||
import React from "react";
|
||||
|
||||
export default function JobLinesBillRefernece({
|
||||
jobline,
|
||||
loading,
|
||||
billLinesObject,
|
||||
}) {
|
||||
if (loading)
|
||||
return (
|
||||
<div>
|
||||
<Spin size="small" className="loading-spinner" />
|
||||
</div>
|
||||
);
|
||||
if (!billLinesObject) return null;
|
||||
|
||||
const billLine = billLinesObject[jobline.id];
|
||||
if (!billLine) return null;
|
||||
|
||||
return (
|
||||
<div>{`${(billLine.actual_price * billLine.quantity).toFixed(2)} (${
|
||||
billLine.bill.vendor.name
|
||||
})`}</div>
|
||||
);
|
||||
}
|
||||
@@ -22,3 +22,26 @@ export const INSERT_NEW_BILL_LINES = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const QUERY_BILLS_BY_JOB_REF = gql`
|
||||
query QUERY_BILLS_BY_JOB_REF($jobId: uuid!) {
|
||||
billlines(
|
||||
where: { bill: { jobid: { _eq: $jobId } } }
|
||||
limit: 1
|
||||
order_by: { bill: { date: desc } }
|
||||
) {
|
||||
id
|
||||
quantity
|
||||
actual_cost
|
||||
actual_price
|
||||
joblineid
|
||||
bill {
|
||||
id
|
||||
vendor {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -803,6 +803,7 @@
|
||||
"unq_seq": "Seq #"
|
||||
},
|
||||
"labels": {
|
||||
"billref": "Latest Bill",
|
||||
"edit": "Edit Line",
|
||||
"new": "New Line",
|
||||
"nostatus": "No Status"
|
||||
|
||||
@@ -803,6 +803,7 @@
|
||||
"unq_seq": "Seq #"
|
||||
},
|
||||
"labels": {
|
||||
"billref": "",
|
||||
"edit": "Línea de edición",
|
||||
"new": "Nueva línea",
|
||||
"nostatus": ""
|
||||
|
||||
@@ -803,6 +803,7 @@
|
||||
"unq_seq": "Seq #"
|
||||
},
|
||||
"labels": {
|
||||
"billref": "",
|
||||
"edit": "Ligne d'édition",
|
||||
"new": "Nouvelle ligne",
|
||||
"nostatus": ""
|
||||
|
||||
Reference in New Issue
Block a user