WIP Financial
This commit is contained in:
@@ -15,16 +15,16 @@ import InvoiceEnterModalComponent from "./invoice-enter-modal.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
invoiceEnterModal: selectInvoiceEnterModal,
|
||||
bodyshop: selectBodyshop
|
||||
bodyshop: selectBodyshop,
|
||||
});
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
toggleModalVisible: () => dispatch(toggleModalVisible("invoiceEnter"))
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
toggleModalVisible: () => dispatch(toggleModalVisible("invoiceEnter")),
|
||||
});
|
||||
|
||||
function InvoiceEnterModalContainer({
|
||||
invoiceEnterModal,
|
||||
toggleModalVisible,
|
||||
bodyshop
|
||||
bodyshop,
|
||||
}) {
|
||||
const [form] = Form.useForm();
|
||||
const { t } = useTranslation();
|
||||
@@ -35,45 +35,45 @@ function InvoiceEnterModalContainer({
|
||||
const { data: RoAutoCompleteData } = useQuery(ACTIVE_JOBS_FOR_AUTOCOMPLETE, {
|
||||
fetchPolicy: "network-only",
|
||||
variables: { statuses: bodyshop.md_ro_statuses.open_statuses || ["Open"] },
|
||||
skip: !invoiceEnterModal.visible
|
||||
skip: !invoiceEnterModal.visible,
|
||||
});
|
||||
|
||||
const { data: VendorAutoCompleteData } = useQuery(
|
||||
SEARCH_VENDOR_AUTOCOMPLETE,
|
||||
{
|
||||
fetchPolicy: "network-only",
|
||||
skip: !invoiceEnterModal.visible
|
||||
skip: !invoiceEnterModal.visible,
|
||||
}
|
||||
);
|
||||
|
||||
const [loadLines, { data: lineData }] = useLazyQuery(
|
||||
GET_JOB_LINES_TO_ENTER_INVOICE,
|
||||
{
|
||||
fetchPolicy: "network-only"
|
||||
fetchPolicy: "network-only",
|
||||
}
|
||||
);
|
||||
|
||||
const handleFinish = values => {
|
||||
const handleFinish = (values) => {
|
||||
insertInvoice({
|
||||
variables: {
|
||||
invoice: [
|
||||
Object.assign({}, values, {
|
||||
invoicelines: { data: values.invoicelines }
|
||||
})
|
||||
]
|
||||
}
|
||||
invoicelines: { data: values.invoicelines },
|
||||
}),
|
||||
],
|
||||
},
|
||||
})
|
||||
.then(r => {
|
||||
.then((r) => {
|
||||
notification["success"]({
|
||||
message: t("invoices.successes.created")
|
||||
message: t("invoices.successes.created"),
|
||||
});
|
||||
toggleModalVisible();
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
notification["error"]({
|
||||
message: t("invoices.errors.creating", {
|
||||
message: JSON.stringify(error)
|
||||
})
|
||||
message: JSON.stringify(error),
|
||||
}),
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -82,6 +82,8 @@ function InvoiceEnterModalContainer({
|
||||
toggleModalVisible();
|
||||
};
|
||||
|
||||
console.log("invoiceEnterModal", invoiceEnterModal);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={
|
||||
@@ -96,7 +98,17 @@ function InvoiceEnterModalContainer({
|
||||
onCancel={handleCancel}
|
||||
destroyOnClose
|
||||
>
|
||||
<Form onFinish={handleFinish} autoComplete={"off"} form={form}>
|
||||
<Form
|
||||
onFinish={handleFinish}
|
||||
autoComplete={"off"}
|
||||
form={form}
|
||||
initialValues={{
|
||||
jobid:
|
||||
(invoiceEnterModal.context.job &&
|
||||
invoiceEnterModal.context.job.id) ||
|
||||
null,
|
||||
}}
|
||||
>
|
||||
<InvoiceEnterModalComponent
|
||||
form={form}
|
||||
roAutoCompleteOptions={RoAutoCompleteData && RoAutoCompleteData.jobs}
|
||||
|
||||
@@ -18,31 +18,47 @@ function CalculateTaxesTotals(job, otherTotals) {
|
||||
job.towing_payable +
|
||||
job.storage_payable; //Levies should be included??
|
||||
|
||||
console.log("job.parts_tax_rates", job.parts_tax_rates);
|
||||
|
||||
const statePartsTax = job.joblines.reduce((acc, val) => {
|
||||
if (!!!val.part_type) return acc;
|
||||
console.log("val", val);
|
||||
if (!!!val.tax_part) return acc;
|
||||
if (!!job.parts_tax_rates[val.part_type]) {
|
||||
return (
|
||||
acc +
|
||||
(val.act_price * job.parts_tax_rates[val.part_type].prt_tax_rt || 0)
|
||||
val.act_price *
|
||||
val.part_qty *
|
||||
(job.parts_tax_rates[val.part_type].prt_tax_rt || 0)
|
||||
);
|
||||
} else {
|
||||
return acc;
|
||||
}
|
||||
}, 0);
|
||||
|
||||
console.log("otherTotals", otherTotals);
|
||||
|
||||
console.log("job", job);
|
||||
console.log("parts pst", statePartsTax);
|
||||
console.log(
|
||||
"pst on labor",
|
||||
otherTotals.rates.rates_subtotal * (job.tax_lbr_rt || 0)
|
||||
);
|
||||
console.log(
|
||||
"pst on mat",
|
||||
(otherTotals.rates.paint_mat.total + otherTotals.rates.shop_mat.total) *
|
||||
(job.tax_paint_mat_rt || 0)
|
||||
);
|
||||
|
||||
let ret = {
|
||||
subtotal: subtotal,
|
||||
federal_tax: subtotal * job.federal_tax_rate || 0,
|
||||
federal_tax: subtotal * (job.federal_tax_rate || 0),
|
||||
statePartsTax,
|
||||
state_tax:
|
||||
statePartsTax +
|
||||
(otherTotals.rates.rates_subtotal * job.tax_lbr_rate || 0) +
|
||||
(job.towing_payable || 0 * job.tax_tow_rt || 0) +
|
||||
(job.storage_payable || 0 * job.tax_str_rt || 0) +
|
||||
(otherTotals.rates.paint_mat.subtotal * job.tax_paint_mat_rt || 0),
|
||||
local_tax: subtotal * job.local_tax_rate || 0,
|
||||
otherTotals.rates.rates_subtotal * (job.tax_lbr_rt || 0) +
|
||||
((job.towing_payable || 0) * job.tax_tow_rt || 0) +
|
||||
((job.storage_payable || 0) * job.tax_str_rt || 0) +
|
||||
(otherTotals.rates.paint_mat.total + otherTotals.rates.shop_mat.total) *
|
||||
(job.tax_paint_mat_rt || 0),
|
||||
local_tax: subtotal * (job.local_tax_rate || 0),
|
||||
};
|
||||
|
||||
ret.total_repairs =
|
||||
@@ -175,7 +191,11 @@ function CalculateRatesTotals(ratesList, shoprates) {
|
||||
for (const property in ret) {
|
||||
ret[property].total = ret[property].hours * ret[property].rate;
|
||||
subtotal = subtotal + ret[property].hours * ret[property].rate;
|
||||
if (property !== "paint_mat" && property !== "shop_mat")
|
||||
if (
|
||||
property !== "paint_mat" &&
|
||||
property !== "shop_mat" &&
|
||||
property !== "rate_atp"
|
||||
)
|
||||
rates_subtotal =
|
||||
rates_subtotal + ret[property].hours * ret[property].rate;
|
||||
}
|
||||
@@ -201,7 +221,7 @@ function CalculatePartsTotals(jobLines) {
|
||||
...acc,
|
||||
parts: {
|
||||
...acc.parts,
|
||||
subtotal: acc.parts.subtotal + value.act_price,
|
||||
subtotal: acc.parts.subtotal + value.act_price * value.part_qty,
|
||||
//TODO Add Adjustments in
|
||||
},
|
||||
};
|
||||
@@ -237,7 +257,7 @@ function CalculatePartsTotals(jobLines) {
|
||||
function CalculateCustPayable(job) {
|
||||
return {
|
||||
deductible: job.ded_amt || 0,
|
||||
federal_tax: job.federal_tax_payable || 0,
|
||||
federal_tax: job.federal_tax_payable || 0, //TODO Should this be renamed to make it more clear this is customer GST?
|
||||
other_customer_amount: job.other_amount_payable || 0,
|
||||
dep_taxes: job.depreciation_taxes || 0,
|
||||
total:
|
||||
|
||||
@@ -9,9 +9,9 @@ import AlertComponent from "../alert/alert.component";
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
});
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
setInvoiceEnterContext: context =>
|
||||
dispatch(setModalContext({ context: context, modal: "invoiceEnter" }))
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setInvoiceEnterContext: (context) =>
|
||||
dispatch(setModalContext({ context: context, modal: "invoiceEnter" })),
|
||||
});
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
@@ -19,17 +19,17 @@ export default connect(
|
||||
)(function JobsDetailPliComponent({
|
||||
setInvoiceEnterContext,
|
||||
job,
|
||||
invoicesQuery
|
||||
invoicesQuery,
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setInvoiceEnterContext({
|
||||
actions: { refetch: null },
|
||||
actions: { refetch: invoicesQuery.refetch || null },
|
||||
context: {
|
||||
job
|
||||
}
|
||||
job,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -434,10 +434,15 @@ export const QUERY_JOB_FINANCIALS = gql`
|
||||
rate_mash
|
||||
rate_matd
|
||||
joblines {
|
||||
id
|
||||
tax_part
|
||||
prt_dsmk_p
|
||||
prt_dsmk_m
|
||||
mod_lbr_ty
|
||||
act_price
|
||||
mod_lb_hrs
|
||||
part_type
|
||||
part_qty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user