WIP Financial

This commit is contained in:
Patrick Fic
2020-04-09 09:13:19 -07:00
parent 26abbdcc62
commit ad5d371547
4 changed files with 75 additions and 38 deletions

View File

@@ -15,16 +15,16 @@ import InvoiceEnterModalComponent from "./invoice-enter-modal.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
invoiceEnterModal: selectInvoiceEnterModal, invoiceEnterModal: selectInvoiceEnterModal,
bodyshop: selectBodyshop bodyshop: selectBodyshop,
}); });
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = (dispatch) => ({
toggleModalVisible: () => dispatch(toggleModalVisible("invoiceEnter")) toggleModalVisible: () => dispatch(toggleModalVisible("invoiceEnter")),
}); });
function InvoiceEnterModalContainer({ function InvoiceEnterModalContainer({
invoiceEnterModal, invoiceEnterModal,
toggleModalVisible, toggleModalVisible,
bodyshop bodyshop,
}) { }) {
const [form] = Form.useForm(); const [form] = Form.useForm();
const { t } = useTranslation(); const { t } = useTranslation();
@@ -35,45 +35,45 @@ function InvoiceEnterModalContainer({
const { data: RoAutoCompleteData } = useQuery(ACTIVE_JOBS_FOR_AUTOCOMPLETE, { const { data: RoAutoCompleteData } = useQuery(ACTIVE_JOBS_FOR_AUTOCOMPLETE, {
fetchPolicy: "network-only", fetchPolicy: "network-only",
variables: { statuses: bodyshop.md_ro_statuses.open_statuses || ["Open"] }, variables: { statuses: bodyshop.md_ro_statuses.open_statuses || ["Open"] },
skip: !invoiceEnterModal.visible skip: !invoiceEnterModal.visible,
}); });
const { data: VendorAutoCompleteData } = useQuery( const { data: VendorAutoCompleteData } = useQuery(
SEARCH_VENDOR_AUTOCOMPLETE, SEARCH_VENDOR_AUTOCOMPLETE,
{ {
fetchPolicy: "network-only", fetchPolicy: "network-only",
skip: !invoiceEnterModal.visible skip: !invoiceEnterModal.visible,
} }
); );
const [loadLines, { data: lineData }] = useLazyQuery( const [loadLines, { data: lineData }] = useLazyQuery(
GET_JOB_LINES_TO_ENTER_INVOICE, GET_JOB_LINES_TO_ENTER_INVOICE,
{ {
fetchPolicy: "network-only" fetchPolicy: "network-only",
} }
); );
const handleFinish = values => { const handleFinish = (values) => {
insertInvoice({ insertInvoice({
variables: { variables: {
invoice: [ invoice: [
Object.assign({}, values, { Object.assign({}, values, {
invoicelines: { data: values.invoicelines } invoicelines: { data: values.invoicelines },
}) }),
] ],
} },
}) })
.then(r => { .then((r) => {
notification["success"]({ notification["success"]({
message: t("invoices.successes.created") message: t("invoices.successes.created"),
}); });
toggleModalVisible(); toggleModalVisible();
}) })
.catch(error => { .catch((error) => {
notification["error"]({ notification["error"]({
message: t("invoices.errors.creating", { message: t("invoices.errors.creating", {
message: JSON.stringify(error) message: JSON.stringify(error),
}) }),
}); });
}); });
}; };
@@ -82,6 +82,8 @@ function InvoiceEnterModalContainer({
toggleModalVisible(); toggleModalVisible();
}; };
console.log("invoiceEnterModal", invoiceEnterModal);
return ( return (
<Modal <Modal
title={ title={
@@ -96,7 +98,17 @@ function InvoiceEnterModalContainer({
onCancel={handleCancel} onCancel={handleCancel}
destroyOnClose 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 <InvoiceEnterModalComponent
form={form} form={form}
roAutoCompleteOptions={RoAutoCompleteData && RoAutoCompleteData.jobs} roAutoCompleteOptions={RoAutoCompleteData && RoAutoCompleteData.jobs}

View File

@@ -18,31 +18,47 @@ function CalculateTaxesTotals(job, otherTotals) {
job.towing_payable + job.towing_payable +
job.storage_payable; //Levies should be included?? job.storage_payable; //Levies should be included??
console.log("job.parts_tax_rates", job.parts_tax_rates);
const statePartsTax = job.joblines.reduce((acc, val) => { 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]) { if (!!job.parts_tax_rates[val.part_type]) {
return ( return (
acc + 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 { } else {
return acc; return acc;
} }
}, 0); }, 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 = { let ret = {
subtotal: subtotal, subtotal: subtotal,
federal_tax: subtotal * job.federal_tax_rate || 0, federal_tax: subtotal * (job.federal_tax_rate || 0),
statePartsTax, statePartsTax,
state_tax: state_tax:
statePartsTax + statePartsTax +
(otherTotals.rates.rates_subtotal * job.tax_lbr_rate || 0) + otherTotals.rates.rates_subtotal * (job.tax_lbr_rt || 0) +
(job.towing_payable || 0 * job.tax_tow_rt || 0) + ((job.towing_payable || 0) * job.tax_tow_rt || 0) +
(job.storage_payable || 0 * job.tax_str_rt || 0) + ((job.storage_payable || 0) * job.tax_str_rt || 0) +
(otherTotals.rates.paint_mat.subtotal * job.tax_paint_mat_rt || 0), (otherTotals.rates.paint_mat.total + otherTotals.rates.shop_mat.total) *
local_tax: subtotal * job.local_tax_rate || 0, (job.tax_paint_mat_rt || 0),
local_tax: subtotal * (job.local_tax_rate || 0),
}; };
ret.total_repairs = ret.total_repairs =
@@ -175,7 +191,11 @@ function CalculateRatesTotals(ratesList, shoprates) {
for (const property in ret) { for (const property in ret) {
ret[property].total = ret[property].hours * ret[property].rate; ret[property].total = ret[property].hours * ret[property].rate;
subtotal = subtotal + 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 =
rates_subtotal + ret[property].hours * ret[property].rate; rates_subtotal + ret[property].hours * ret[property].rate;
} }
@@ -201,7 +221,7 @@ function CalculatePartsTotals(jobLines) {
...acc, ...acc,
parts: { parts: {
...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 //TODO Add Adjustments in
}, },
}; };
@@ -237,7 +257,7 @@ function CalculatePartsTotals(jobLines) {
function CalculateCustPayable(job) { function CalculateCustPayable(job) {
return { return {
deductible: job.ded_amt || 0, 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, other_customer_amount: job.other_amount_payable || 0,
dep_taxes: job.depreciation_taxes || 0, dep_taxes: job.depreciation_taxes || 0,
total: total:

View File

@@ -9,9 +9,9 @@ import AlertComponent from "../alert/alert.component";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser //currentUser: selectCurrentUser
}); });
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = (dispatch) => ({
setInvoiceEnterContext: context => setInvoiceEnterContext: (context) =>
dispatch(setModalContext({ context: context, modal: "invoiceEnter" })) dispatch(setModalContext({ context: context, modal: "invoiceEnter" })),
}); });
export default connect( export default connect(
mapStateToProps, mapStateToProps,
@@ -19,17 +19,17 @@ export default connect(
)(function JobsDetailPliComponent({ )(function JobsDetailPliComponent({
setInvoiceEnterContext, setInvoiceEnterContext,
job, job,
invoicesQuery invoicesQuery,
}) { }) {
return ( return (
<div> <div>
<Button <Button
onClick={() => { onClick={() => {
setInvoiceEnterContext({ setInvoiceEnterContext({
actions: { refetch: null }, actions: { refetch: invoicesQuery.refetch || null },
context: { context: {
job job,
} },
}); });
}} }}
> >

View File

@@ -434,10 +434,15 @@ export const QUERY_JOB_FINANCIALS = gql`
rate_mash rate_mash
rate_matd rate_matd
joblines { joblines {
id
tax_part
prt_dsmk_p
prt_dsmk_m
mod_lbr_ty mod_lbr_ty
act_price act_price
mod_lb_hrs mod_lb_hrs
part_type part_type
part_qty
} }
} }
} }