Job costing improvements. IO-527

This commit is contained in:
Patrick Fic
2021-02-04 19:36:41 -08:00
parent 89d59d256c
commit 7a21721034
6 changed files with 66 additions and 16 deletions

View File

@@ -8,7 +8,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
import JobCostingPartsTable from "../job-costing-parts-table/job-costing-parts-table.component"; import JobCostingPartsTable from "../job-costing-parts-table/job-costing-parts-table.component";
import JobCostingStatistics from "../job-costing-statistics/job-costing-statistics.component"; import JobCostingStatistics from "../job-costing-statistics/job-costing-statistics.component";
import JobCostingPie from "./job-costing-modal.pie.component"; import JobCostingPie from "./job-costing-modal.pie.component";
import _ from "lodash";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
}); });
@@ -18,6 +18,11 @@ const mapDispatchToProps = (dispatch) => ({
export function JobCostingModalComponent({ bodyshop, job }) { export function JobCostingModalComponent({ bodyshop, job }) {
const defaultProfits = bodyshop.md_responsibility_centers.defaults.profits; const defaultProfits = bodyshop.md_responsibility_centers.defaults.profits;
const allProfitCenters = _.union(
bodyshop.md_responsibility_centers.profits.map((p) => p.name),
bodyshop.md_responsibility_centers.costs.map((p) => p.name)
);
// const defaultCosts = bodyshop.md_responsibility_centers.defaults.costs; // const defaultCosts = bodyshop.md_responsibility_centers.defaults.costs;
const { t } = useTranslation(); const { t } = useTranslation();
const jobLineTotalsByProfitCenter = const jobLineTotalsByProfitCenter =
@@ -71,6 +76,7 @@ export function JobCostingModalComponent({ bodyshop, job }) {
.multiply(line_val.quantity) .multiply(line_val.quantity)
.multiply(bill_val.is_credit_memo ? -1 : 1) .multiply(bill_val.is_credit_memo ? -1 : 1)
); );
return null; return null;
}); });
return bill_acc; return bill_acc;
@@ -107,8 +113,8 @@ export function JobCostingModalComponent({ bodyshop, job }) {
gppercentFormatted: null, gppercentFormatted: null,
}; };
const costCenterData = Object.keys(defaultProfits).map((key, idx) => { const costCenterData = allProfitCenters.map((key, idx) => {
const ccVal = defaultProfits[key]; const ccVal = key; // defaultProfits[key];
const sale_labor = const sale_labor =
jobLineTotalsByProfitCenter.labor[ccVal] || Dinero({ amount: 0 }); jobLineTotalsByProfitCenter.labor[ccVal] || Dinero({ amount: 0 });
const sale_parts = const sale_parts =
@@ -178,7 +184,11 @@ export function JobCostingModalComponent({ bodyshop, job }) {
return ( return (
<div> <div>
<JobCostingStatistics job={job} summaryData={summaryData} /> <JobCostingStatistics job={job} summaryData={summaryData} />
<JobCostingPartsTable job={job} data={costCenterData} /> <JobCostingPartsTable
job={job}
data={costCenterData}
summaryData={summaryData}
/>
<div className="imex-flex-row"> <div className="imex-flex-row">
<div style={{ flex: 1 }}> <div style={{ flex: 1 }}>
<Typography.Title level={4}> <Typography.Title level={4}>

View File

@@ -37,7 +37,9 @@ export function JobCostingModalContainer({
<Modal <Modal
visible={visible} visible={visible}
title={t("jobs.labels.jobcosting")} title={t("jobs.labels.jobcosting")}
onOk={() => toggleModalVisible()}
onCancel={() => toggleModalVisible()} onCancel={() => toggleModalVisible()}
cancelButtonProps={{ style: { display: "none" } }}
width="90%" width="90%"
destroyOnClose destroyOnClose
> >

View File

@@ -44,8 +44,6 @@ export default function JobCostingPieComponent({
Calculatedata, Calculatedata,
]); ]);
console.log(type, memoizedData);
return ( return (
<ResponsiveContainer width="100%" height={175}> <ResponsiveContainer width="100%" height={175}>
<PieChart> <PieChart>

View File

@@ -1,9 +1,10 @@
import { Table } from "antd"; import { Input, Table, Typography } from "antd";
import React, { useState } from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters"; import { alphaSort } from "../../utils/sorters";
export default function JobCostingPartsTable({ job, data }) { export default function JobCostingPartsTable({ job, data, summaryData }) {
const [searchText, setSearchText] = useState("");
const [state, setState] = useState({ const [state, setState] = useState({
sortedInfo: {}, sortedInfo: {},
}); });
@@ -59,16 +60,61 @@ export default function JobCostingPartsTable({ job, data }) {
}, },
]; ];
const filteredData =
searchText === ""
? data
: data.filter((d) =>
(d.cost_center || "")
.toString()
.toLowerCase()
.includes(searchText.toLowerCase())
);
return ( return (
<div> <div>
<Table <Table
size="small" size="small"
title={() => {
return (
<div className="imex-table-header">
<div className="imex-table-header__search">
<Input.Search
placeholder={t("general.labels.search")}
value={searchText}
onChange={(e) => {
e.preventDefault();
setSearchText(e.target.value);
}}
/>
</div>
</div>
);
}}
scroll={{ x: "50%", y: "40rem" }} scroll={{ x: "50%", y: "40rem" }}
onChange={handleTableChange} onChange={handleTableChange}
pagination={{ position: "top", defaultPageSize: 25 }} pagination={{ position: "top", defaultPageSize: 25 }}
columns={columns} columns={columns}
rowKey="id" rowKey="id"
dataSource={data} dataSource={filteredData}
summary={() => (
<Table.Summary.Row>
<Table.Summary.Cell>
<Typography.Title level={4}>
{t("general.labels.totals")}
</Typography.Title>
</Table.Summary.Cell>
<Table.Summary.Cell>
{summaryData.totalSales.toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell>
{summaryData.totalCost.toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell>
{summaryData.gpdollars.toFormat()}
</Table.Summary.Cell>
<Table.Summary.Cell></Table.Summary.Cell>
</Table.Summary.Row>
)}
/> />
</div> </div>
); );

View File

@@ -37,13 +37,6 @@ export default function ReportCenterModalComponent({ context }) {
autoComplete={"off"} autoComplete={"off"}
layout="vertical" layout="vertical"
form={form} form={form}
initialValues={{
to: [
"allan.carr@thinkimex.com",
"allanlcarr@outlook.com",
"allanlcarr@icloud.com",
],
}}
> >
<Form.Item <Form.Item
name="key" name="key"

View File

@@ -28,6 +28,7 @@ export function ReportCenterModalContainer({
visible={visible} visible={visible}
title={t("printcenter.labels.reportcentermodal")} title={t("printcenter.labels.reportcentermodal")}
onOk={() => toggleModalVisible()} onOk={() => toggleModalVisible()}
onCancel={() => toggleModalVisible()}
cancelButtonProps={{ style: { display: "none" } }} cancelButtonProps={{ style: { display: "none" } }}
destroyOnClose destroyOnClose
> >