edu.byu.softwareDistribution.web.controller.shopper.MyInvoicesController.java Source code

Java tutorial

Introduction

Here is the source code for edu.byu.softwareDistribution.web.controller.shopper.MyInvoicesController.java

Source

package edu.byu.softwareDistribution.web.controller.shopper;

import edu.byu.edge.person.basic.BasicPersonLookup;
import edu.byu.security.userdetails.IdentityDetails;
import edu.byu.softwareDist.ces.PersonRepo;
import edu.byu.softwareDist.dao.LineItemDao;
import edu.byu.softwareDist.dao.MaintenanceLineItemDAO;
import edu.byu.softwareDist.dao.PurchaseDao;
import edu.byu.softwareDist.dao.PurchaseLineItemDao;
import edu.byu.softwareDist.domain.LineItem;
import edu.byu.softwareDist.domain.MaintenanceLineItem;
import edu.byu.softwareDist.domain.Purchase;
import edu.byu.softwareDist.domain.PurchaseLineItem;
import edu.byu.softwareDist.manager.LicenseManager;
import edu.byu.softwareDist.manager.PurchaseManager;
import edu.byu.softwareDistribution.web.controller.ProxyController;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.*;

/**
 * Created by IntelliJ IDEA.
 * User: thirschi
 * Date: Nov 8, 2010
 */
@Controller
@RequestMapping("/shop")
public class MyInvoicesController extends ProxyController {

    private static final Logger LOG = Logger.getLogger(MyInvoicesController.class);

    private final PurchaseDao purchaseDao;
    private final PurchaseManager purchaseManager;
    private final PurchaseLineItemDao purchaseLineItemDao;
    private final MaintenanceLineItemDAO maintLineItemDao;
    private final LineItemDao lineItemDao;
    private final LicenseManager licenseManager;
    private final PersonRepo personRepo;
    private final BasicPersonLookup basicPersonLookup;

    @Autowired
    public MyInvoicesController(PurchaseDao purchaseDao, PurchaseManager purchaseManager,
            PurchaseLineItemDao purchaseLineItemDao, final MaintenanceLineItemDAO maintLineItemDao,
            final LineItemDao lineItemDao, LicenseManager licenseManager, PersonRepo personRepo,
            final BasicPersonLookup basicPersonLookup) {
        this.purchaseDao = purchaseDao;
        this.purchaseManager = purchaseManager;
        this.purchaseLineItemDao = purchaseLineItemDao;
        this.maintLineItemDao = maintLineItemDao;
        this.lineItemDao = lineItemDao;
        this.licenseManager = licenseManager;
        this.personRepo = personRepo;
        this.basicPersonLookup = basicPersonLookup;
    }

    @RequestMapping("/myInvoices")
    public String displayPage(Model model, @RequestParam(value = "byuId", required = false) String byuId) {
        final String personId = getPersonIdForWebPage(byuId, model);
        LOG.debug("Loading invoices for " + personId);
        final List<Purchase> purchases = purchaseDao.findByPurchaseBy(personId);
        sortLineItems(purchases);
        model.addAttribute("purchases", purchases);
        model.addAttribute("personRepo", personRepo);
        model.addAttribute("licenseManager", licenseManager);
        model.addAttribute("returnsAllowed",
                !personId.equals(IdentityDetails.getCurrentIdentityDetails().getPersonId()));
        return "shop/myInvoices";
    }

    @RequestMapping("/myInvoices/loadNotes.json")
    public @ResponseBody String loadNotes(@RequestParam(value = "lineItemId") int lineItemId,
            @RequestParam(value = "lineItemType") String lineItemType) {
        final LineItem x = getLineItem(lineItemId, lineItemType);
        return x.getNote();
    }

    @RequestMapping("/myInvoices/updateNotes.json")
    public @ResponseBody String updateNotes(@RequestParam(value = "lineItemId") int lineItemId,
            @RequestParam(value = "note") String note, @RequestParam(value = "lineItemType") String lineItemType) {
        final LineItem x = getLineItem(lineItemId, lineItemType);
        x.setNote(note);
        lineItemDao.update(x);
        return "Updated Notes for " + x.getDisplayName();
    }

    @RequestMapping("/myInvoices/changePurchasedFor.json")
    public @ResponseBody String changePurchasedFor(@RequestParam(value = "lineItemId") int lineItemId,
            @RequestParam(value = "purchasedFor") String purchasedFor,
            @RequestParam(value = "lineItemType") String lineItemType) {
        final LineItem x = getLineItem(lineItemId, lineItemType);
        x.setPurchasedFor(purchasedFor);
        lineItemDao.update(x);
        return "Updated person.";
    }

    @RequestMapping("/returnItem")
    public @ResponseBody String returnItem(@RequestParam(value = "lineItemId") int lineItemId,
            @RequestParam(value = "lineItemType") String lineItemType) {
        LOG.debug("Return line Item id = " + lineItemId);
        //      if (IdentityDetails.getCurrentIdentityDetails().getPersonId().equals(effectivePerson.getPersonId())) {
        //         throw new IllegalStateException("Cannot Return Self-purchased Items.");
        //      }
        final LineItem x = getLineItem(lineItemId, lineItemType);
        purchaseManager.refund(x);
        return String.format("Item %s on invoice %d has been refunded. (%d)", x.getDisplayName(),
                x.getPurchase().getPurchaseId(), x.getLineItemId());
    }

    private LineItem getLineItem(final int lineItemId, final String lineItemType) {
        final LineItem x = lookupLineItem(lineItemId, lineItemType);
        if (x == null) {
            throw new IllegalArgumentException("Unable to find lineItem (" + lineItemId + ").");
        }
        return x;
    }

    private LineItem lookupLineItem(final int lineItemId, final String lineItemType) {
        if (LineItem.Type.PURCHASE_LINE_ITEM.getRawVal().equals(lineItemType)) {
            return purchaseLineItemDao.findById(lineItemId);
        } else if (LineItem.Type.MAINTENANCE_LINE_ITEM.getRawVal().equals(lineItemType)) {
            return maintLineItemDao.findById(lineItemId);
        }
        throw new IllegalArgumentException("Invalid line type.");
    }

    private void sortLineItems(final List<Purchase> purchases) {
        if (purchases == null || purchases.isEmpty())
            return;
        final List<Future> futures = new ArrayList<Future>(purchases.size());
        for (final Purchase purchase : purchases) {
            futures.add(exec.get().submit(new LineItemSorter(purchase)));
        }
        waitForAll(futures);
    }

    private void waitForAll(final Collection<Future> futures) {
        for (final Future f : futures) {
            try {
                f.isDone();
            } catch (Throwable ignore) {
            }
        }
    }

    private static final ThreadLocal<ThreadPoolExecutor> exec = new ThreadLocal<ThreadPoolExecutor>() {

        @Override
        protected ThreadPoolExecutor initialValue() {
            return new ThreadPoolExecutor(2, 10, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(128),
                    new RejectedExecutionHandler() {
                        @Override
                        public void rejectedExecution(final Runnable r, final ThreadPoolExecutor executor) {
                            //we don't really care that much, it just means that the collection won't be sorted
                        }
                    });
        }

        @Override
        public void set(final ThreadPoolExecutor value) {
        }

        @Override
        public void remove() {
        }
    };

    private static class LineItemSorter implements Runnable {

        private final Purchase purchase;

        public LineItemSorter(final Purchase purchase) {
            this.purchase = purchase;
        }

        @Override
        public void run() {
            try {
                final SortedSet<PurchaseLineItem> a = new TreeSet<PurchaseLineItem>(LINE_ITEM_COMPARATOR);
                a.addAll(purchase.getLineItems());
                purchase.setLineItems(a);
                final SortedSet<MaintenanceLineItem> b = new TreeSet<MaintenanceLineItem>(LINE_ITEM_COMPARATOR);
                b.addAll(purchase.getMainItems());
                purchase.setMainItems(b);
            } catch (Throwable t) {
                LOG.info("error sorting line item list", t);
            }
        }
    }

    private static final Comparator<LineItem> LINE_ITEM_COMPARATOR = new LineItemComparator();

    private static class LineItemComparator implements Comparator<LineItem>, Serializable {
        private static final long serialVersionUID = 1L;

        @Override
        public int compare(final LineItem o1, final LineItem o2) {
            final String n1 = o1.getDisplayName();
            final String n2 = o2.getDisplayName();
            final LineItem.Type t1 = o1.getType();
            final LineItem.Type t2 = o2.getType();
            if (t1 != null && t2 != null) {
                final int x = t1.doComparisonTo(t2);
                if (x != 0)
                    return x;
            }
            final int a = n1.compareTo(n2);
            if (a != 0)
                return a;
            final int b = o1.getQty() - o2.getQty();
            if (b != 0)
                return b;
            return o1.getLineItemId() - o2.getLineItemId();
        }
    }
}