Merge release & add time ticket calculations.

This commit is contained in:
Patrick Fic
2021-09-13 14:47:09 -07:00
13 changed files with 7789 additions and 7604 deletions

View File

@@ -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 BabelEdit project file
@@ -3683,6 +3683,69 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>itc_federal</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>itc_local</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>itc_state</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> <concept_node>
<name>mappingname</name> <name>mappingname</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -5819,27 +5882,6 @@
<folder_node> <folder_node>
<name>responsibilitycenters</name> <name>responsibilitycenters</name>
<children> <children>
<concept_node>
<name>LA4</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> <concept_node>
<name>ap</name> <name>ap</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -5987,6 +6029,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>la4</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> <concept_node>
<name>lab</name> <name>lab</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -17284,6 +17347,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>getmakes</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> <concept_node>
<name>post</name> <name>post</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -120,7 +120,9 @@ export function DmsAllocationsSummary({ socket, bodyshop, jobId, title }) {
{totals.totalSale.toFormat()} {totals.totalSale.toFormat()}
</Table.Summary.Cell> </Table.Summary.Cell>
<Table.Summary.Cell> <Table.Summary.Cell>
{totals.totalCost.toFormat()} {
// totals.totalCost.toFormat()
}
</Table.Summary.Cell> </Table.Summary.Cell>
<Table.Summary.Cell></Table.Summary.Cell> <Table.Summary.Cell></Table.Summary.Cell>
<Table.Summary.Cell></Table.Summary.Cell> <Table.Summary.Cell></Table.Summary.Cell>

View File

@@ -13,6 +13,7 @@ import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { selectJobReadOnly } from "../../redux/application/application.selectors"; import { selectJobReadOnly } from "../../redux/application/application.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CABCpvrtCalculator from "../ca-bc-pvrt-calculator/ca-bc-pvrt-calculator.component"; import CABCpvrtCalculator from "../ca-bc-pvrt-calculator/ca-bc-pvrt-calculator.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component"; import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component"; import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component";
@@ -22,9 +23,10 @@ import JobsDetailRatesParts from "./jobs-detail-rates.parts.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
jobRO: selectJobReadOnly, jobRO: selectJobReadOnly,
bodyshop: selectBodyshop,
}); });
export function JobsDetailRates({ jobRO, form, job }) { export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div> <div>
@@ -77,7 +79,7 @@ export function JobsDetailRates({ jobRO, form, job }) {
label={t("jobs.fields.adjustment_bottom_line")} label={t("jobs.fields.adjustment_bottom_line")}
name="adjustment_bottom_line" name="adjustment_bottom_line"
> >
<CurrencyInput disabled={jobRO} /> <CurrencyInput disabled={jobRO || bodyshop.cdk_dealerid} />
</Form.Item> </Form.Item>
<Space align="end"> <Space align="end">
<Form.Item label={t("jobs.fields.ca_bc_pvrt")} name="ca_bc_pvrt"> <Form.Item label={t("jobs.fields.ca_bc_pvrt")} name="ca_bc_pvrt">

View File

@@ -121,6 +121,27 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
> >
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item
label={t("bodyshop.fields.dms.itc_federal")}
valuePropName="checked"
name={["cdk_configuration", "itc_federal"]}
>
<Switch />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.dms.itc_state")}
valuePropName="checked"
name={["cdk_configuration", "itc_state"]}
>
<Switch />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.dms.itc_local")}
valuePropName="checked"
name={["cdk_configuration", "itc_local"]}
>
<Switch />
</Form.Item>
</LayoutFormRow> </LayoutFormRow>
<LayoutFormRow header={t("bodyshop.labels.dms.cdk.payers")}> <LayoutFormRow header={t("bodyshop.labels.dms.cdk.payers")}>
<Form.List name={["cdk_configuration", "payers"]}> <Form.List name={["cdk_configuration", "payers"]}>
@@ -471,20 +492,26 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
{fields.map((field, index) => ( {fields.map((field, index) => (
<Form.Item key={field.key}> <Form.Item key={field.key}>
<div> <div>
<Form.Item <LayoutFormRow>
label={t("bodyshop.fields.dms.mappingname")} <Form.Item
key={`${index}name`} label={t("bodyshop.fields.dms.mappingname")}
name={[field.name, "name"]} key={`${index}name`}
rules={[ name={[field.name, "name"]}
{ rules={[
required: true, {
//message: t("general.validation.required"), required: true,
}, //message: t("general.validation.required"),
]} },
> ]}
<Input /> >
</Form.Item> <Input />
</Form.Item>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
</LayoutFormRow>
<LayoutFormRow <LayoutFormRow
header={t("bodyshop.labels.defaultcostsmapping")} header={t("bodyshop.labels.defaultcostsmapping")}
> >
@@ -1627,12 +1654,6 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
</Select> </Select>
</Form.Item> </Form.Item>
</LayoutFormRow> </LayoutFormRow>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
</div> </div>
</Form.Item> </Form.Item>
))} ))}
@@ -2717,7 +2738,7 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
</Form.Item> </Form.Item>
{bodyshop.cdk_dealerid && ( {bodyshop.cdk_dealerid && (
<Form.Item <Form.Item
label={t("bodyshop.fields.responsibilitycenter_dms_acctnumber")} label={t("bodyshop.fields.dms.dms_acctnumber")}
rules={[ rules={[
{ {
required: true, required: true,
@@ -2815,7 +2836,7 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
</Form.Item> </Form.Item>
{bodyshop.cdk_dealerid && ( {bodyshop.cdk_dealerid && (
<Form.Item <Form.Item
label={t("bodyshop.fields.responsibilitycenter_dms_acctnumber")} label={t("bodyshop.fields.dms.dms_acctnumber")}
rules={[ rules={[
{ {
required: true, required: true,
@@ -2911,21 +2932,9 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
> >
<Input /> <Input />
</Form.Item> </Form.Item>
<Form.Item
label={t("bodyshop.fields.responsibilitycenter_rate")}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
name={["md_responsibility_centers", "taxes", "local", "rate"]}
>
<InputNumber precision={2} />
</Form.Item>
{bodyshop.cdk_dealerid && ( {bodyshop.cdk_dealerid && (
<Form.Item <Form.Item
label={t("bodyshop.fields.responsibilitycenter_dms_acctnumber")} label={t("bodyshop.fields.dms.dms_acctnumber")}
rules={[ rules={[
{ {
required: true, required: true,
@@ -2942,6 +2951,18 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
<Input /> <Input />
</Form.Item> </Form.Item>
)} )}
<Form.Item
label={t("bodyshop.fields.responsibilitycenter_rate")}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
name={["md_responsibility_centers", "taxes", "local", "rate"]}
>
<InputNumber precision={2} />
</Form.Item>
</LayoutFormRow> </LayoutFormRow>
<LayoutFormRow header={<div>AR</div>}> <LayoutFormRow header={<div>AR</div>}>
{/* <Form.Item {/* <Form.Item

View File

@@ -108,6 +108,8 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
}); });
history.push("/manage/accounting/receivables"); history.push("/manage/accounting/receivables");
}); });
if (socket.disconnected) socket.connect();
return () => { return () => {
socket.removeAllListeners(); socket.removeAllListeners();
socket.disconnect(); socket.disconnect();

View File

@@ -218,7 +218,7 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) {
}, },
]} ]}
> >
<InputNumber disabled={jobRO} /> <InputNumber precision={0} disabled={jobRO} />
</Form.Item> </Form.Item>
)} )}
{bodyshop.cdk_dealerid && ( {bodyshop.cdk_dealerid && (
@@ -244,7 +244,7 @@ export function JobsCloseComponent({ job, bodyshop, jobRO }) {
}), }),
]} ]}
> >
<InputNumber disabled={jobRO} /> <InputNumber precision={0} disabled={jobRO} />
</Form.Item> </Form.Item>
)} )}
</LayoutFormRow> </LayoutFormRow>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -79,40 +79,78 @@ exports.default = async function (socket, jobid) {
bill_val.billlines.map((line_val) => { bill_val.billlines.map((line_val) => {
if (!bill_acc[line_val.cost_center]) if (!bill_acc[line_val.cost_center])
bill_acc[line_val.cost_center] = Dinero(); bill_acc[line_val.cost_center] = Dinero();
const lineDinero = Dinero({
let lineDinero = Dinero({
amount: Math.round((line_val.actual_cost || 0) * 100), amount: Math.round((line_val.actual_cost || 0) * 100),
}) })
.multiply(line_val.quantity) .multiply(line_val.quantity)
.multiply(bill_val.is_credit_memo ? -1 : 1); .multiply(bill_val.is_credit_memo ? -1 : 1);
bill_acc[line_val.cost_center] =
bill_acc[line_val.cost_center].add(lineDinero);
//Add appropriate tax amounts. //Add appropriate tax amounts.
const { const {
applicable_taxes: { local, state, federal }, applicable_taxes: { local, state, federal },
} = line_val; } = line_val;
if (local) { if (local) {
taxAllocations.local.cost = taxAllocations.local.cost.add( if (bodyshop.cdk_configuration.itc_local)
taxAllocations.local.cost = taxAllocations.local.cost.add(
lineDinero.percentage(bill_val.local_tax_rate || 0)
);
lineDinero = lineDinero.add(
lineDinero.percentage(bill_val.local_tax_rate || 0) lineDinero.percentage(bill_val.local_tax_rate || 0)
); );
} }
if (state) { if (state) {
taxAllocations.state.cost = taxAllocations.state.cost.add( if (bodyshop.cdk_configuration.itc_state)
taxAllocations.state.cost = taxAllocations.state.cost.add(
lineDinero.percentage(bill_val.state_tax_rate || 0)
);
lineDinero = lineDinero.add(
lineDinero.percentage(bill_val.state_tax_rate || 0) lineDinero.percentage(bill_val.state_tax_rate || 0)
); );
} }
if (federal) { if (federal) {
taxAllocations.federal.cost = taxAllocations.federal.cost.add( //If it's an ITC, add it as a negative cost, otherwise add it to the item cost.
if (bodyshop.cdk_configuration.itc_federal)
taxAllocations.federal.cost = taxAllocations.federal.cost.add(
lineDinero.percentage(bill_val.federal_tax_rate || 0)
);
lineDinero = lineDinero.add(
lineDinero.percentage(bill_val.federal_tax_rate || 0) lineDinero.percentage(bill_val.federal_tax_rate || 0)
); );
// bill_acc[line_val.cost_center] = bill_acc[line_val.cost_center].add(
// lineDinero.percentage(bill_val.federal_tax_rate || 0)
// );
} }
bill_acc[line_val.cost_center] =
bill_acc[line_val.cost_center].add(lineDinero);
return null; return null;
}); });
return bill_acc; return bill_acc;
}, {}); }, {});
job.timetickets.forEach((ticket) => {
//Get the total amount of the ticket.
let TicketTotal = Dinero({
amount: Math.round(
ticket.rate *
(ticket.employee && ticket.employee.flat_rate
? ticket.productivehrs || 0
: ticket.actualhrs || 0) *
100
),
});
//Add it to the right cost center.
if (!costCenterHash[ticket.cost_center])
costCenterHash[ticket.cost_center] = Dinero();
costCenterHash[ticket.cost_center] =
costCenterHash[ticket.cost_center].add(TicketTotal);
});
const jobAllocations = _.union( const jobAllocations = _.union(
Object.keys(profitCenterHash), Object.keys(profitCenterHash),
Object.keys(costCenterHash) Object.keys(costCenterHash)

View File

@@ -976,7 +976,7 @@ async function GenerateTransWips(socket) {
const allocations = await CalcualteAllocations(socket, socket.JobData.id); const allocations = await CalcualteAllocations(socket, socket.JobData.id);
const wips = []; const wips = [];
allocations.forEach((alloc) => { allocations.forEach((alloc) => {
//Add the sale item //Add the sale item from each allocation.
if (alloc.sale.getAmount() > 0 && !alloc.tax) { if (alloc.sale.getAmount() > 0 && !alloc.tax) {
const item = { const item = {
acct: alloc.profitCenter.dms_acctnumber, acct: alloc.profitCenter.dms_acctnumber,
@@ -993,6 +993,7 @@ async function GenerateTransWips(socket) {
wips.push(item); wips.push(item);
} }
//Add the cost Item.
if (alloc.cost.getAmount() > 0 && !alloc.tax) { if (alloc.cost.getAmount() > 0 && !alloc.tax) {
const item = { const item = {
acct: alloc.costCenter.dms_acctnumber, acct: alloc.costCenter.dms_acctnumber,
@@ -1025,33 +1026,38 @@ async function GenerateTransWips(socket) {
} }
if (alloc.tax) { if (alloc.tax) {
const item = { // if (alloc.cost.getAmount() > 0) {
acct: alloc.costCenter.dms_acctnumber, // const item = {
cntl: socket.JobData.ro_number, // acct: alloc.costCenter.dms_acctnumber,
cntl2: null, // cntl: socket.JobData.ro_number,
credtMemoNo: null, // cntl2: null,
postAmt: alloc.cost.getAmount(), // credtMemoNo: null,
postDesc: null, // postAmt: alloc.cost.getAmount(),
prod: null, // postDesc: null,
statCnt: 1, // prod: null,
transID: socket.DMSTransHeader.transID, // statCnt: 1,
trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco, // transID: socket.DMSTransHeader.transID,
}; // trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco,
// };
wips.push(item); // wips.push(item);
const item2 = { // }
acct: alloc.profitCenter.dms_acctnumber,
cntl: socket.JobData.ro_number, if (alloc.sale.getAmount() > 0) {
cntl2: null, const item2 = {
credtMemoNo: null, acct: alloc.profitCenter.dms_acctnumber,
postAmt: alloc.sale.multiply(-1).getAmount(), cntl: socket.JobData.ro_number,
postDesc: null, cntl2: null,
prod: null, credtMemoNo: null,
statCnt: 1, postAmt: alloc.sale.multiply(-1).getAmount(),
transID: socket.DMSTransHeader.transID, postDesc: null,
trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco, prod: null,
}; statCnt: 1,
wips.push(item2); transID: socket.DMSTransHeader.transID,
trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco,
};
wips.push(item2);
}
} }
}); });
@@ -1076,7 +1082,11 @@ async function GenerateTransWips(socket) {
console.log( console.log(
"WIPS TOTAL", "WIPS TOTAL",
wips.reduce((acc, val) => acc + val.postAmt, 0) wips.reduce((acc, val) => {
console.log(val);
console.log(acc + val.postAmt);
return acc + val.postAmt;
}, 0)
); );
return wips; return wips;

View File

@@ -954,106 +954,116 @@ affected_rows
`; `;
exports.GET_CDK_ALLOCATIONS = ` exports.GET_CDK_ALLOCATIONS = `query QUERY_JOB_CLOSE_DETAILS($id: uuid!) {
query QUERY_JOB_CLOSE_DETAILS($id: uuid!) { jobs_by_pk(id: $id) {
jobs_by_pk(id: $id) { bodyshop {
bodyshop{
id
md_responsibility_centers
}
ro_number
invoice_allocation
ins_co_id
id id
ded_amt md_responsibility_centers
ded_status cdk_configuration
depreciation_taxes }
other_amount_payable ro_number
towing_payable invoice_allocation
storage_payable ins_co_id
adjustment_bottom_line id
federal_tax_rate ded_amt
state_tax_rate ded_status
local_tax_rate depreciation_taxes
tax_tow_rt other_amount_payable
tax_str_rt towing_payable
tax_paint_mat_rt storage_payable
tax_sub_rt adjustment_bottom_line
tax_lbr_rt federal_tax_rate
tax_levies_rt state_tax_rate
parts_tax_rates local_tax_rate
job_totals tax_tow_rt
rate_la1 tax_str_rt
rate_la2 tax_paint_mat_rt
rate_la3 tax_sub_rt
rate_la4 tax_lbr_rt
rate_laa tax_levies_rt
rate_lab parts_tax_rates
rate_lad job_totals
rate_lae rate_la1
rate_laf rate_la2
rate_lag rate_la3
rate_lam rate_la4
rate_lar rate_laa
rate_las rate_lab
rate_lau rate_lad
rate_ma2s rate_lae
rate_ma2t rate_laf
rate_ma3s rate_lag
rate_mabl rate_lam
rate_macs rate_lar
rate_mahw rate_las
rate_mapa rate_lau
rate_mash rate_ma2s
rate_matd rate_ma2t
status rate_ma3s
date_exported rate_mabl
date_invoiced rate_macs
voided rate_mahw
scheduled_completion rate_mapa
actual_completion rate_mash
scheduled_delivery rate_matd
actual_delivery status
scheduled_in date_exported
actual_in date_invoiced
bills { voided
id scheduled_completion
federal_tax_rate actual_completion
local_tax_rate scheduled_delivery
state_tax_rate actual_delivery
is_credit_memo scheduled_in
billlines { actual_in
actual_cost timetickets {
cost_center id
id actualhrs
quantity cost_center
applicable_taxes productivehrs
} rate
} employee {
joblines(where: { removed: { _eq: false } }) { flat_rate
id
removed
tax_part
line_desc
prt_dsmk_p
prt_dsmk_m
part_type
oem_partno
db_price
act_price
part_qty
mod_lbr_ty
db_hrs
mod_lb_hrs
lbr_op
lbr_amt
op_code_desc
profitcenter_labor
profitcenter_part
prt_dsmk_p
} }
} }
bills(where: {isinhouse: {_eq: false}}) {
id
federal_tax_rate
local_tax_rate
state_tax_rate
is_credit_memo
billlines {
actual_cost
cost_center
id
quantity
applicable_taxes
}
}
joblines(where: {removed: {_eq: false}}) {
id
removed
tax_part
line_desc
prt_dsmk_p
prt_dsmk_m
part_type
oem_partno
db_price
act_price
part_qty
mod_lbr_ty
db_hrs
mod_lb_hrs
lbr_op
lbr_amt
op_code_desc
profitcenter_labor
profitcenter_part
prt_dsmk_p
}
} }
}
`; `;
exports.GET_QBO_AUTH = `query GET_QBO_AUTH($email: String!) { exports.GET_QBO_AUTH = `query GET_QBO_AUTH($email: String!) {

View File

@@ -50,7 +50,11 @@ io.on("connection", (socket) => {
socket.on("set-log-level", (level) => { socket.on("set-log-level", (level) => {
socket.log_level = level; socket.log_level = level;
createLogEvent(socket, "DEBUG", `Updated log level to ${level}`); socket.emit("log-event", {
timestamp: new Date(),
level: "INFO",
message: `Updated log level to ${level}`,
});
}); });
socket.on("cdk-export-job", (jobid) => { socket.on("cdk-export-job", (jobid) => {