BillBean.java 7.15 KB
package fi.insomnia.bortal.beans;

import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fi.insomnia.bortal.beanutil.PdfPrinter;
import fi.insomnia.bortal.bortal.views.BillSummary;
import fi.insomnia.bortal.enums.Permission;
import fi.insomnia.bortal.enums.RolePermission;
import fi.insomnia.bortal.exceptions.PermissionDeniedException;
import fi.insomnia.bortal.facade.BillFacade;
import fi.insomnia.bortal.facade.BillLineFacade;
import fi.insomnia.bortal.model.AccountEvent;
import fi.insomnia.bortal.model.Bill;
import fi.insomnia.bortal.model.BillLine;
import fi.insomnia.bortal.model.Discount;
import fi.insomnia.bortal.model.LanEvent;
import fi.insomnia.bortal.model.Product;
import fi.insomnia.bortal.model.User;

/**
 * Session Bean implementation class BillBean
 */
@Stateless
public class BillBean implements BillBeanLocal {

    private static final Logger logger = LoggerFactory.getLogger(BillBean.class);

    @EJB
    private BillFacade billFacade;

    @EJB
    private UserBeanLocal userBean;

    @EJB
    private SecurityBeanLocal secubean;

    @EJB
    private EventBeanLocal eventbean;
    @EJB
    private BillLineFacade billLineFacade;
    @PersistenceContext
    private EntityManager em;

    @EJB
    private ProductBeanLocal productBean;

    @EJB
    private PlaceBeanLocal placebean;

    /**
     * Default constructor.
     */
    public BillBean() {
        // TODO Auto-generated constructor stub
    }

    public Bill findById(int id) {
        LanEvent event = eventbean.getCurrentEvent();
        if (id <= 0) {
            return null;
        }
        Bill bill = billFacade.find(event.getId(), id);
        User currentuser = userBean.getCurrentUser();

        if (!currentuser.equals(bill.getUser())) {
            userBean.fatalPermission(Permission.USER_MANAGEMENT, RolePermission.READ, "User tried to print the bill with insufficient rights. Bill id: ", bill);
        }
        return bill;

    }

    @Override
    public void getPdfBillStream(Bill bill, OutputStream ostream) {
        if (bill == null) {
            return;
        }
        if (bill.getBillNumber() == null || bill.getBillNumber() <= 0) {
            generateBillNumber(bill);
        }
        new PdfPrinter(bill).output(ostream);
    }

    private void generateBillNumber(Bill bill) {
        if (bill.getBillNumber() == null || bill.getBillNumber() == 0) {
            LanEvent currEvent = eventbean.getCurrentEvent();
            Integer billnr = billFacade.getBiggestBillNumber(currEvent);
            if (billnr == null || billnr < currEvent.getNextBillNumber()) {
                billnr = currEvent.getNextBillNumber();
            } else {
                ++billnr;
            }
            bill.setBillNumber(billnr);
            billFacade.merge(bill);
        }

    }

    @Override
    public Bill createEmptyBill(User shoppingUser) {

        if (shoppingUser != null && !userBean.isCurrentUser(shoppingUser)) {
            userBean.fatalPermission(Permission.USER_MANAGEMENT, RolePermission.EXECUTE, "User tried to shop to ", shoppingUser, " another without sufficient rights");
        }

        if (shoppingUser == null) {
            shoppingUser = userBean.getCurrentUser();
        }
        LanEvent event = eventbean.getCurrentEvent();
        Bill ret = new Bill(event, shoppingUser);
        billFacade.create(ret);
        ret.setUser(shoppingUser);
        em.flush();
        logger.debug("Created bill with id {} and user {}", ret.getId(), ret.getUser());
        return ret;
    }

    @Override
    public BillLine addProductToBill(Bill bill, Product product, BigDecimal count) {
        userBean.fatalPermission(Permission.BILL, RolePermission.EXECUTE, "User tried to add a product to bill");

        // If bill number > 0 bill has been sent and extra privileges are needed
        // to modify.
        boolean iscurrent = userBean.isCurrentUser(bill.getUser());
        Integer billnr = bill.getBillNumber();
        if (!iscurrent || billnr != null) {
            userBean.fatalPermission(Permission.USER_MANAGEMENT, RolePermission.EXECUTE, "User tried to modify bill ", bill, "without sufficient permissions");
        }
        BillLine line = new BillLine(bill, product.getName(), product.getUnitName(), count, product.getPrice(), product.getVat());
        line.setLineProduct(product);
        billLineFacade.create(line);

        List<Discount> discounts = productBean.getActiveDiscounts(product, count);

        for (Discount disc : discounts) {
            BigDecimal unitPrice = product.getPrice().subtract(product.getPrice().multiply(disc.getPercentage())).negate().setScale(2, RoundingMode.HALF_UP);
            BigDecimal vatPrice = product.getVat().subtract(product.getVat().multiply(disc.getPercentage())).negate().setScale(2, RoundingMode.HALF_UP);

            BillLine discountLine = new BillLine(bill, disc.getShortdesc(), product.getUnitName(), count, unitPrice, vatPrice);
            billLineFacade.create(discountLine);

        }

        em.flush();
        return line;
    }

    @Override
    public List<Bill> findAll() {
        if (!userBean.hasPermission(Permission.BILL, RolePermission.WRITE)) {
            throw new PermissionDeniedException(secubean, userBean.getCurrentUser(), "User tried to list all bills without sufficient permissions");
        }
        return billFacade.findAll(eventbean.getCurrentEvent());
    }

    @Override
    public Collection<BillSummary> getBillLineSummary() {
        userBean.fatalPermission(Permission.BILL, RolePermission.READ, "User tried to view the bill summary");

        Collection<BillSummary> ret = billLineFacade.getLineSummary(eventbean.getCurrentEvent());
        for (BillSummary foo : ret) {
            logger.debug("linesum {}", foo);
        }
        return ret;
    }

    @Override
    public void markPaid(Bill bill, Calendar when) {
        userBean.fatalPermission(Permission.BILL, RolePermission.WRITE, "User tried to mark the bill paid");

        Product creditproduct = productBean.findCreditProduct();

        AccountEvent ac = productBean.createAccountEvent(creditproduct, bill.totalPrice(), bill.getUser());
        ac.setDelivered(when);
        ac.setEventTime(when);
        ac.setBill(bill);
        ac.setSeller(userBean.getCurrentUser());

        bill.setAccountEvent(ac);
        bill.setPaidDate(when);

        billFacade.merge(bill);

        for (BillLine bl : bill.getBillLines()) {
            Product prod = bl.getLineProduct();
            if (prod != null) {
                if (prod.isPrepaidInstant()) {
                    logger.debug("Creating Bill prepaidInstant product {}, {}", prod.getName(), bl.getQuantity());
                    if (prod.getPlaces().size() > 0) {
                        placebean.lockPlaces(bill.getUser(), prod, bl.getQuantity());
                    }

                    productBean.createAccountEvent(prod, bl.getQuantity(), bill.getUser());

                }
            }
        }

    }
}