1

I am setting up a es6/oop tax calculator and having some issues setting the tax amount correctly. I am instantiating product objects with their quantity and price and adding them to an inventory and then calling a total method on the entire inventory. Some products are tax exempt, so I am using a BasicProduct object and an ExemptProduct object:

const Product = require('./Product')

class ExemptProduct extends Product {
  constructor(product) {
    super(product)

    this._salesTax = product.salesTax
  }

  get salesTax() {
    return this.setSalesTax();
  }

  setSalesTax () {
    return null;
  }
}

module.exports = ExemptProduct

The BasicObject sets the sales tax to .10. My total method is here:

total() {
    let total = 0
    let tax = 0
    let importDuty = .05

    for (let productId in this.items) {
        total += this.inventory.products.find(product => {
            return product.id == productId
        }).price * this.items[productId]

        tax += this.inventory.products.find(product => {
            return product.id == productId
        }).salesTax * this.items[productId]

        console.log(tax)
    }

    let taxToApply = total * tax
    let importDutyToApply = total * importDuty
    total = total + taxToApply + importDutyToApply

    return total
}

Right now I am testing with three inventory items, two of which are instantiating as tax exempt products. They all log out with the correct tax amount until they hit this for in. The console.log I left in there is printing out .10 for all three, when two of them should be 0/null. I am trying to avoid hard coding the tax amount per item, as ultimately there will only be two tax types.

Matt Larsuma
  • 1,456
  • 4
  • 20
  • 52
  • I think you've run into a common JavaScript gotcha: function closures in for-loops do not work as you expect them to. Take a look at this related post: https://stackoverflow.com/questions/19696015/javascript-creating-functions-in-a-for-loop – Patrick Hund Jul 01 '18 at 14:54
  • 2
    @PatrickHund That has nothing to do with it. Not only is `find` synchronous, the code also uses `let` syntax. – Bergi Jul 01 '18 at 15:07
  • 1
    `0` is not the same as `null`. Use the number when you are dealing with numbers. – Bergi Jul 01 '18 at 15:10
  • What exactly do you expect `instance.salesTax` to return? Is it a percentage, is the tax for that item? Why do you in your loop both accumulate `tax` (with `+=`) on all items, *and* then also multiply (`*`) it with the `total`? – Bergi Jul 01 '18 at 15:12
  • You are right @Bergi I was jumping to quick conclusions – Patrick Hund Jul 01 '18 at 15:12
  • The salesTax is the percentage. Only some items are exempt, so 0 would be hard to work with, as I'd be multiplying a total by 0, which would return 0. That's another can of worms I guess. The tax is the actual tax amount, before being added to the total. I need to print that out in a receipt. So I need to break it down like such: Price: 10.00, Tax: 1, Total: 11. – Matt Larsuma Jul 01 '18 at 15:14
  • Not sure the best practice to not apply tax for the exempt items, but multiplying by null does indeed return 0. – Matt Larsuma Jul 01 '18 at 15:18
  • > The console.log I left in there is printing out .10 for all three, when two of them should be 0/null. < You're not logging the tax of each item individually. You're logging the accumulated tax. Notice that you += each item's individual tax to your variable tax. .1 + 0 is still .1. – Jeff M Jul 01 '18 at 17:54

0 Answers0