-1

This is the first time I am using Collections (TreeMap and Treeset). Other parts are working good but I am having NullPointerException. I tried but could not fix after several attempts. I think the problem is in calcTotal, calcSubtotal and calcTax methods. Could anyone help me find my mistake and fix this serious issue? Am I chaining the methods in the right way?

Exception

Exception in thread "main" java.lang.NullPointerException
    at posPD.Sale.calcTotal(Sale.java:92)
    at posPD.Session.calTotalSession(Session.java:149)
    at posTest.LoadStore.loadTheStore(LoadStore.java:52)
    at posTest.StoreTest.main(StoreTest.java:163)

Sale.java

package posPD;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * Sale information and services
 */
public class Sale {

    private LocalDateTime dateTime;

    private Boolean taxFree;
    private BigDecimal amountTendered;
    private ArrayList<SaleLineItem> saleLineItems;
    private ArrayList<Payment> payments;

    private LocalDate date;

    public Sale() {
        // TODO - implement Sale.Sale
        //throw new UnsupportedOperationException();
        saleLineItems = new ArrayList<SaleLineItem>();
        payments = new ArrayList<Payment>();
        //setTaxFree(false);
        setDate(date);
        setDateTime(dateTime);

        //dateTime = LocalDateTime.now();


    }


    /**
     * 
     * @param taxFree
     */
    public Sale(Session session, String taxFree) {
        // TODO - implement Sale.Sale
        //throw new UnsupportedOperationException();
        this();
        /*
        Boolean boolTax = Boolean.parseBoolean(taxFree);
        this.setTaxFree(boolTax);

        if (taxFree.equals("N")) {
            setTaxFree(false);
        } else {
            setTaxFree(true);
        }
        */
        if (taxFree == "Y") {
            this.setTaxFree(true);
        }
        else this.setTaxFree(false);
        session.addSale(this);
        //setSession(session);
    }

    /**
     * 
     * @param payment
     */
    public void addPayment(Payment payment) {
        // TODO - implement Sale.addPayment
        //throw new UnsupportedOperationException();
        payments.add(payment);


    }

    /**
     * 
     * @param payment
     */
    public void removePayment(Payment payment) {
        // TODO - implement Sale.removePayment
        //throw new UnsupportedOperationException();
        payments.remove(payment);
    }

    public BigDecimal calcTotal() {
        // TODO - implement Sale.calcTotal
        //throw new UnsupportedOperationException();

        BigDecimal total = new BigDecimal("0.0");

        if (this.taxFree) {
            total = calcSubTotal().setScale(2, BigDecimal.ROUND_HALF_UP);
            return total;
        }
        else {
            total = calcSubTotal().add(this.calcTax().setScale(2, BigDecimal.ROUND_HALF_UP));
            return total;
        }
    }

    public BigDecimal calcSubTotal() {
        // TODO - implement Sale.calcSubTotal
        //throw new UnsupportedOperationException();


        BigDecimal subTotal = new BigDecimal("0");
        for (SaleLineItem sli: saleLineItems) {
            subTotal = subTotal.add(sli.calcSubTotal());

        }
        System.out.println(subTotal);
        return subTotal.setScale(2, RoundingMode.HALF_UP);

    }

    public BigDecimal calcTax() {
        // TODO - implement Sale.calcTax
        //throw new UnsupportedOperationException();

        BigDecimal tax = new BigDecimal ("0");
        if (!getTaxFree()) {
            for (SaleLineItem sli : saleLineItems) {

                tax = tax.add(sli.calcTax());

            }
        }

        return tax.setScale(2, RoundingMode.HALF_UP);


    }

    public BigDecimal getTotalPayments() {
        // TODO - implement Sale.getTotalPayments
        //throw new UnsupportedOperationException();
        BigDecimal payment = new BigDecimal("0");
        for (Payment p : payments) {
            payment = payment.add(p.getAmount());
        }

        return payment.setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    public Boolean isPaymentEnough() {
        // TODO - implement Sale.isPaymentEnough
        //throw new UnsupportedOperationException();
        return (calcTotal().compareTo(calcAmtTendered()) <= 0);
    }

    /**
     * 
     * @param amountTendered
     */
    public void calcAmount(BigDecimal amountTendered) {
        // TODO - implement Sale.calcAmount
        //throw new UnsupportedOperationException();
        BigDecimal calcAmount = calcTotal().subtract(calcTotal());
        if (calcAmount.compareTo(amountTendered) > 0)
        {
            calcAmount = amountTendered;
        }
        System.out.println("Calc Amt : "+calcAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
        //return calcAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    public BigDecimal calcChange() {
        // TODO - implement Sale.calcChange
        //throw new UnsupportedOperationException();
        //return amountTendered.subtract(getTotalPayments())
        return getAmountTendered().subtract(getTotalPayments());
    }

    public BigDecimal calcAmtTendered() {
        // TODO - implement Sale.calcAmtTendered
        //throw new UnsupportedOperationException();
        //return amountTendered;
        BigDecimal amtTendered = new BigDecimal("0");
        for (Payment p : payments) {
            amtTendered = amtTendered.add(p.getAmtTendered());

        }
        System.out.println("Payment Amt:"+amtTendered.setScale(2, BigDecimal.ROUND_HALF_UP));
        return amtTendered.setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 
     * @param sli
     */
    public void addSaleLineItem(SaleLineItem sli) {
        // TODO - implement Sale.addSaleLineItem
        //throw new UnsupportedOperationException();
        saleLineItems.add(sli);


    }

    /**
     * 
     * @param sli
     */
    public void removeSaleLineItem(SaleLineItem sli) {
        // TODO - implement Sale.removeSaleLineItem
        //throw new UnsupportedOperationException();
        saleLineItems.remove(sli);

    }

    public BigDecimal getAmountTendered() {
        return amountTendered;
    }

    public void setAmountTendered(BigDecimal amountTendered) {
        this.amountTendered = amountTendered;
    }


    private ArrayList<SaleLineItem> getSaleLineItems() {
        return saleLineItems;
     }


    public String toString() {
        // TODO - implement Sale.toString
        //throw new UnsupportedOperationException();
        String slis = "";
        for (SaleLineItem sli : getSaleLineItems()) {
            slis += "  " +sli.toString() + "\r\n";

        }
        return "Sale : SubTotal = " +calcSubTotal().toPlainString()
        +" Tax = " +calcTax().toPlainString()
        +" Total =" +calcTotal().toPlainString()
        +" Payment =" +getTotalPayments().toPlainString()
        +" Change =" +calcChange().toPlainString() +"\r\n" 
        +slis;
    }

    public LocalDateTime getDateTime() {
        return dateTime;
    }

    public void setDateTime(LocalDateTime dateTime) {
        this.dateTime = dateTime;
    }

    public LocalDate getDate() {
        return date;
    }


    public void setDate(LocalDate date) {
        this.date = date;
    }

    public Boolean getTaxFree() {
        return taxFree;
    }




    public void setTaxFree(Boolean taxFree) {
        this.taxFree = taxFree;
    }

    public ArrayList<Payment> getPayments() {
        return payments;
    }

    public void setPayments(ArrayList<Payment> payments) {
        this.payments = payments;
    }

    public void setSaleLineItems(ArrayList<SaleLineItem> saleLineItems) {
        this.saleLineItems = saleLineItems;
    }




    public BigDecimal calcCash()
    {
        BigDecimal cash = new BigDecimal ("0");
        for (Payment p : payments)
        { if (p.hasCash()) cash = cash.add(p.getAmount());}

        return cash;
    }



}

SaleLineItem.java

package posPD;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * Items, Quantity details during a sale
 */
public class SaleLineItem {

    private int quantity;
    private Item item;
    //private Sale sale;
    private LocalDate date;
    private LocalDateTime dateTime;

    public SaleLineItem() {
        // TODO - implement SaleLineItem.SaleLineItem
        //throw new UnsupportedOperationException();
        //date = LocalDate.now();
        setDateTime(dateTime);
        setDate(date);


    }

    /**
     * 
     * @param itemNumber
     * @param quantity
     */
    public SaleLineItem(Item item, String quantity) {
        // TODO - implement SaleLineItem.SaleLineItem
        //throw new UnsupportedOperationException();
        //this.itemNumber = Integer.parseInt(itemNumber);
        //this.quantity = Integer.parseInt(quantity);
        //System.out.println(quantity);
        this();
        this.item = item;
        this.quantity =Integer.parseInt(quantity);
    }
    public SaleLineItem(Sale sale, Item item, int quantity)
    {
        this();
        this.sale = sale;
        setQuantity(quantity);
        setItem(item);
        sale.addSaleLineItem(this);
        getItem().addSaleLineItem(this);
        setSale(sale);
        System.out.println(sale);
    }

    /**
     * 
     * @param itemNumber
     * @param quantity
     */
    public SaleLineItem(Store store, Sale sale, String itemNumber, String quantity) {
        // TODO - implement SaleLineItem.SaleLineItem
        //throw new UnsupportedOperationException();
        this();
        setQuantity(Integer.parseInt(quantity));
        setItem(store.findItemForNumber(itemNumber));

        sale.addSaleLineItem(this);
        getItem().addSaleLineItem(this);
        setSale(sale);




    }

    public LocalDateTime getDateTime() {
        return dateTime;
    }

    public void setDateTime(LocalDateTime dateTime) {
        this.dateTime = dateTime;
    }

    public LocalDate getDate() {
        return date;
    }

    public void setDate(LocalDate date) {
        this.date = date;
    }

    public Sale getSale() {
        return sale;
    }

    public void setSale(Sale sale) {
        this.sale = sale;
    }

    private Sale sale;
    public int getQuantity() {
        return this.quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
    public Item getItem() {
        return this.item;
    }
    public void setItem(Item item) {
        this.item = item;
    }

    public BigDecimal calcSubTotal() {

        // TODO - implement SaleLineItem.calcSubTotal
        //throw new UnsupportedOperationException();
        //return getItem().calcAmountForDateQty(date, getQuantity());
        date = getSale().getDate();
        System.out.println(date);

        BigDecimal subTotal = getItem().calcTotal(date, getQuantity()); 

        return subTotal;

    }



    public BigDecimal calcTax() {
        // TODO - implement SaleLineItem.calcTax
        //throw new UnsupportedOperationException();
        BigDecimal amount = calcSubTotal();
        BigDecimal taxRate = new BigDecimal(getItem().getTaxRateForDate(getSale().getDate()).toString());
        BigDecimal tax = amount.multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP);
        return tax;

    }

    public String toString() {
        // TODO - implement SaleLineItem.toString
        //throw new UnsupportedOperationException();
        try {
            LocalDate date =  sale.getDate();
        } catch (Exception e) {
            System.out.println("Exception exists here in SaleLineItem b"+ e.getMessage());
        }

        return getItem().getNumber()
        +" "
        +getItem().getDescription() 
        + " Qty: "+getQuantity()  
        + "Price for Date: "
        +"@$"
        + getItem().getPriceForDate(date)
        +" $"+calcSubTotal().toString();

    }

}

Item.class

package posPD;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * information about the general details of items in the store
 */
public class Item {


    private String number;
    private String description;
    //private SaleLineItem saleLineItems;
    private TaxCategory taxCategory;
    private ArrayList<SaleLineItem> saleLineItems;
    private TreeMap<String, UPC> upcs;
    private TreeSet<Price> prices;

    public Item() {
        // TODO - implement Item.Item
        //throw new UnsupportedOperationException();
        upcs = new TreeMap<String, UPC>();
        prices = new TreeSet<Price>();
    }

    /**
     * 
     * @param number
     * @param description
     */
    public Item(String number, String description) {
        // TODO - implement Item.Item
        //throw new UnsupportedOperationException();
        this();
        this.setItemNumber(number);
        this.setItemDescription(description);
    }

    public String getItemNumber() {
        return this.number;
    }
    public void setItemNumber(String number) {
        this.number = number;
    }

    public String getItemDescription() {
        return this.description;
    }
    public void setItemDescription(String description) {
        this.description = description;
    }

    /*
    public SaleLineItem getSaleLineItems() {
        return saleLineItems;
    }

    public void setSaleLineItems(SaleLineItem saleLineItems) {
        this.saleLineItems = saleLineItems;
    }
    */
    public ArrayList<SaleLineItem> getSaleLineItems() {
        return saleLineItems;
    }

    public void setSaleLineItems(ArrayList<SaleLineItem> saleLineItems) {
        this.saleLineItems = saleLineItems;
    }

    public TaxCategory getTaxCategory() {
        return taxCategory;
    }



    public void setTaxCategory(TaxCategory taxCategory) {
        this.taxCategory = taxCategory;
    }

    /**
     * 
     * @param price
     */
    public void addPrice(Price price) {
        // TODO - implement Item.addPrice
        //throw new UnsupportedOperationException();
        prices.add(price);
    }

    /**
     * 
     * @param price
     */
    public void removePrice(Price price) {
        // TODO - implement Item.removePrice
        //throw new UnsupportedOperationException();
        prices.remove(price);
    }

    /**
     * 
     * @param upc
     */
    public void addUPC(UPC upc) {
        // TODO - implement Item.addUPC
        //throw new UnsupportedOperationException();
        upcs.put(upc.getUPC(), upc);
    }

    /**
     * 
     * @param upc
     */
    public void removeUPC(UPC upc) {
        // TODO - implement Item.removeUPC
        //throw new UnsupportedOperationException();
        upcs.remove(upc.getUPC());
    }

    public void addSaleLineItem (SaleLineItem sli)
    {
        if (sli != null)
        {
            getSaleLineItems().add(sli);
        }
    }

    public void removeSaleLineItem (SaleLineItem sli)
    {
        if (sli != null)
        {
            getSaleLineItems().remove(sli);
        }
    }
    /**
     * 
     * @param date
     */
    public BigDecimal getPriceForDate(LocalDate date) {
        // TODO - implement Item.getPriceForDate
        //throw new UnsupportedOperationException();
        Price currentPrice = new Price() ;
        for (Price price : getPrices()) {
            if (price.isEffective(date)) {
                currentPrice = price;
            }
        }
        return currentPrice.getPrice();

    }

    /**
     * 
     * @param date
     */
    public BigDecimal getTaxRateForDate(LocalDate date) {
    //public String getTaxRateForDate(LocalDate date) {
        //return null;
        // TODO - implement Item.getTaxRateForDate
        //throw new UnsupportedOperationException();
        //date = LocalDate.now();

        return  getTaxCategory().getTaxRateForEffectiveDate(date);

    }

    public BigDecimal calcTotal(LocalDate saleDate, int quantity) {
        // TODO Auto-generated method stub
        BigDecimal total;

        total = getPriceForDate(saleDate).multiply(new BigDecimal(quantity));
        return total;
    }
    /**
     * 
     * @param date
     * @param quantity
     */
    public BigDecimal calcAmountForDateQty(LocalDate date, int quantity) {
        // TODO - implement Item.calcAmountForDateQty
        //throw new UnsupportedOperationException();
        BigDecimal total;

        total = getPriceForDate(date).multiply(new BigDecimal(quantity));
        return total;
    }
    public TreeMap<String, UPC> getUpcs() {
        return upcs;
    }

    public void setUpcs(TreeMap<String, UPC> upcs) {
        this.upcs = upcs;
    }

    public TreeSet<Price> getPrices() {
        return prices;
    }

    public void setPrices(TreeSet<Price> prices) {
        this.prices = prices;
    }

    public String toString() {
        // TODO - implement Item.toString
        //throw new UnsupportedOperationException();
        String up="";
        //if (upcs.isEmpty()) System.out.println("EmptyXXXX");
        for(Map.Entry<String, UPC> entry : upcs.entrySet()) {
              //String key = entry.getKey();
              UPC value = entry.getValue();
              //up += key +": " + value;
              up += value;
              //System.out.println(key + " => " + value);
            }
        // for prices from tree set
        String pp = "";
        for (Price p : getPrices()) {
            pp += p;
        }
        return "\n"+"Item No: "+getItemNumber()+ " " + "Item: " + getItemDescription() + " Category: " + getTaxCategory() + " UPC: " + up  + " Price: " + pp +"\n";
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }   

}

part of LoadStore.Java triggering this exception

package posTest;

import java.time.LocalDate;

import posPD.*;

public class LoadStore {

    public LoadStore() {
        // TODO Auto-generated constructor stub
    }

    public void loadTheStore(Store myStore) {
//String list;

        //working codes here are removed

        System.out.println("\n==============\n");
        System.out.println("\nItems");
        System.out.println("\n==============\n");
        for(Item I : myStore.getItems().values()){
            System.out.println(I.toString()+" "
            +I.getPriceForDate(LocalDate.now())+" "
            +I.getTaxRateForDate(LocalDate.now())
            );
        }

        System.out.println("\n==============\n");
        System.out.println("\nSessions");
        System.out.println("\n==============\n");
        for(Session cashierSession: myStore.getSessions()){

            System.out.println("Cashier in Session: "+cashierSession.getCashier().getPerson().getPersonName()+" "+"Register : "+cashierSession.getRegister().getRegisterNumber());
            System.out.println("Total : "+cashierSession.calTotalSession());
            for(Sale sale : cashierSession.getSales()){
                System.out.println(sale);
            }
        }
        System.out.println("StoreCashierIsUsed : "+myStore.findCashierForNumber("1"));

    }

}
robinleathal
  • 251
  • 6
  • 24
  • @cricket_007 Do you mean setScale in the following line? BigDecimal tax = amount.multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); if so it is part of BigDecimal i imported it. – robinleathal Nov 03 '17 at 04:53
  • 1
    Well, what is at line 92 of that Sales class. [Try using a debugger](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – OneCricketeer Nov 03 '17 at 04:55

1 Answers1

0

How did you create Sale instance? Which constructor did you use, Sale(Session session, String taxFree) or Sale()? If you use Sale(), your attribute Boolean taxFree may not be initialized, it can throw NullPointerException when you call:

 public BigDecimal calcTotal() {
    // TODO - implement Sale.calcTotal
    //throw new UnsupportedOperationException();

    BigDecimal total = new BigDecimal("0.0");

    if (this.taxFree) { // <--- NullPointerException 's here
        total = calcSubTotal().setScale(2, BigDecimal.ROUND_HALF_UP);
        return total;
    }
    else {
        total = calcSubTotal().add(this.calcTax().setScale(2, BigDecimal.ROUND_HALF_UP));
        return total;
    }
}

To fix this, use private boolean taxFree; instead.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Nam Tran
  • 643
  • 4
  • 14
  • Yes I have declared private boolean taxFree; – robinleathal Nov 03 '17 at 05:15
  • use `boolean` instead of `Boolean`. You are using `Boolean`. – Nam Tran Nov 03 '17 at 05:26
  • doing so is giving even more exception. Exception in thread "main" java.lang.NullPointerException at posPD.SaleLineItem.calcSubTotal(SaleLineItem.java:119) at posPD.Sale.calcSubTotal(Sale.java:110) at posPD.Sale.calcTotal(Sale.java:98) at posPD.Session.calTotalSession(Session.java:149) at posTest.LoadStore.loadTheStore(LoadStore.java:52) at posTest.StoreTest.main(StoreTest.java:163) – robinleathal Nov 03 '17 at 05:28
  • Your code has many problems with variable declaration and initialization. You need to verify your code to avoid `NullPointerException`, it is easy to find out them by debugger. – Nam Tran Nov 03 '17 at 05:35
  • i used boolean and the previous exception disappear but got new exceptions. I came to know that my subtotal and total variable are null which are causing this new exceptions. Could you tell me why I am having this null values on subTotal and total? – robinleathal Nov 05 '17 at 02:58