package com.refresh.pos.domain.sale; import com.refresh.pos.domain.DateTimeStrategy; import com.refresh.pos.domain.inventory.Inventory; import com.refresh.pos.domain.inventory.LineItem; import com.refresh.pos.domain.inventory.Product; import com.refresh.pos.domain.inventory.Stock; import com.refresh.pos.techicalservices.NoDaoSetException; import com.refresh.pos.techicalservices.sale.SaleDao; /** * Handles all Sale processes. * * @author Refresh Team * */ public class Register { private static Register instance = null; private static SaleDao saleDao = null; private static Stock stock = null; private Sale currentSale; private Register() throws NoDaoSetException { if (!isDaoSet()) { throw new NoDaoSetException(); } stock = Inventory.getInstance().getStock(); } /** * Determines whether the DAO already set or not. * @return true if the DAO already set; otherwise false. */ public static boolean isDaoSet() { return saleDao != null; } public static Register getInstance() throws NoDaoSetException { if (instance == null) instance = new Register(); return instance; } /** * Injects its sale DAO * @param dao DAO of sale */ public static void setSaleDao(SaleDao dao) { saleDao = dao; } /** * Initiates a new Sale. * @param startTime time that sale created. * @return Sale that created. */ public Sale initiateSale(String startTime) { if (currentSale != null) { return currentSale; } currentSale = saleDao.initiateSale(startTime); return currentSale; } /** * Add Product to Sale. * @param product product to be added. * @param quantity quantity of product that added. * @return LineItem of Sale that just added. */ public LineItem addItem(Product product, int quantity) { if (currentSale == null) initiateSale(DateTimeStrategy.getCurrentTime()); LineItem lineItem = currentSale.addLineItem(product, quantity); if (lineItem.getId() == LineItem.UNDEFINED) { int lineId = saleDao.addLineItem(currentSale.getId(), lineItem); lineItem.setId(lineId); } else { saleDao.updateLineItem(currentSale.getId(), lineItem); } return lineItem; } /** * Returns total price of Sale. * @return total price of Sale. */ public double getTotal() { if (currentSale == null) return 0; return currentSale.getTotal(); } /** * End the Sale. * @param endTime time that Sale ended. */ public void endSale(String endTime) { if (currentSale != null) { saleDao.endSale(currentSale, endTime); for(LineItem line : currentSale.getAllLineItem()){ stock.updateStockSum(line.getProduct().getId(), line.getQuantity()); } currentSale = null; } } /** * Returns the current Sale of this Register. * @return the current Sale of this Register. */ public Sale getCurrentSale() { if (currentSale == null) initiateSale(DateTimeStrategy.getCurrentTime()); return currentSale; } /** * Sets the current Sale of this Register. * @param id of Sale to retrieve. * @return true if success to load Sale from ID; otherwise false. */ public boolean setCurrentSale(int id) { currentSale = saleDao.getSaleById(id); return false; } /** * Determines that if there is a Sale handling or not. * @return true if there is a current Sale; otherwise false. */ public boolean hasSale(){ if(currentSale == null)return false; return true; } /** * Cancels the current Sale. */ public void cancleSale() { if (currentSale != null){ saleDao.cancelSale(currentSale,DateTimeStrategy.getCurrentTime()); currentSale = null; } } /** * Edit the specific LineItem * @param saleId ID of LineItem to be edited. * @param lineItem LineItem to be edited. * @param quantity a new quantity to set. * @param priceAtSale a new priceAtSale to set. */ public void updateItem(int saleId, LineItem lineItem, int quantity, double priceAtSale) { lineItem.setUnitPriceAtSale(priceAtSale); lineItem.setQuantity(quantity); saleDao.updateLineItem(saleId, lineItem); } /** * Removes LineItem from the current Sale. * @param lineItem lineItem to be removed. */ public void removeItem(LineItem lineItem) { saleDao.removeLineItem(lineItem.getId()); currentSale.removeItem(lineItem); if (currentSale.getAllLineItem().isEmpty()) { cancleSale(); } } }