Subversion Repositories SmartDukaan

Rev

Rev 7410 | Rev 11801 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.inventory.controllers;

import in.shop2020.model.v1.catalog.Item;
import in.shop2020.model.v1.inventory.InventoryService;
import in.shop2020.model.v1.inventory.InventoryType;
import in.shop2020.model.v1.inventory.Warehouse;
import in.shop2020.model.v1.inventory.WarehouseType;
import in.shop2020.model.v1.order.LineItem;
import in.shop2020.purchase.Invoice;
import in.shop2020.purchase.PurchaseOrder;
import in.shop2020.purchase.PurchaseServiceException;
import in.shop2020.thrift.clients.CatalogClient;
import in.shop2020.thrift.clients.HelperClient;
import in.shop2020.thrift.clients.InventoryClient;
import in.shop2020.thrift.clients.PurchaseClient;
import in.shop2020.thrift.clients.WarehouseClient;
import in.shop2020.utils.HelperService;
import in.shop2020.utils.ModelUtils;
import in.shop2020.warehouse.InventoryItem;
import in.shop2020.warehouse.ScanType;
import in.shop2020.warehouse.WarehouseService;
import in.shop2020.warehouse.WarehouseService.Client;
import in.shop2020.warehouse.WarehouseServiceException;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings("serial")
@Results({ @Result(name = "redirect", type = "redirectAction", params = {
        "actionName", "warehouse" }) })
public class PurchaseController extends BaseController {
    /**
     * 
     */
    private static final int NUM_BULK__SCAN_ITEMS = 10;
    private static Logger logger = LoggerFactory.getLogger(PurchaseController.class);
    public static enum ScanRecordType { VALID, BLANK };

    private ServletContext context;
    private String id;
    private Long transferLotId;
    private String itemId;
    private String itemNo;
    private String errorMsg = "";
    private List<Item> items;
    private List<LineItem> lineItems;
    private List<Invoice> invoices;
    
    private String invoiceNumber;
    private Double freightCharges ;
    private Long poId;

    private String purchaseOrderId;
    private Long warehouseId;
    private Long transferWarehouseId;
    private Warehouse warehouse;

    public String editNew() {
        purchaseOrderId = request.getParameter("poId");

        try {
            in.shop2020.purchase.PurchaseService.Client purchaseClient = new PurchaseClient().getClient();
            //invoices = purchaseClient.getInvoices(getPreviousDay(getPreviousDay(new Date())).getTime());
            PurchaseOrder po = purchaseClient.getPurchaseOrder(Long.parseLong(purchaseOrderId));
            invoices = purchaseClient.getInvoicesForWarehouse(po.getWarehouseId(), po.getSupplierId(), getPreviousDay(getPreviousDay(new Date())).getTime());
        } catch (Exception e) {
            logger.error("Error loading invoices", e);
        }

        return "new";
    }

    private Date getPreviousDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }

    public String create() {
        this.purchaseOrderId = request.getParameter("poId");
        poId = Long.parseLong(purchaseOrderId);
        invoiceNumber = request.getParameter("invoiceNo");
        String fc = request.getParameter("freightCharges").trim();
        freightCharges = 0D;
        id = "0";
        if (fc != null && !fc.isEmpty())
            freightCharges = Double.parseDouble(fc);
        return show();
        //return "create";

    }

    public String show() {
        resetLineItems();
        setItemsFromPO();
        return SHOW;
    }

    private void resetLineItems() {
        lineItems = new ArrayList<LineItem>();

        for (int i = 0; i < NUM_BULK__SCAN_ITEMS; i++) {
            LineItem lineItem = new LineItem();
            lineItem.setId(i);
            lineItem.setExtra_info("");
            lineItem.setSerial_number("");
            lineItem.setItem_number("");
            lineItem.setQuantity(1);
            lineItem.setItem_id(-1);
            lineItems.add(lineItem);
        }
    }

    public boolean createPurchase(){
        try {
                logger.info("poId="+poId+" invoiceNumber="+invoiceNumber+" freightCharges="+freightCharges);
            PurchaseClient purchaseClient = new PurchaseClient();
            in.shop2020.purchase.PurchaseService.Client client = purchaseClient
                    .getClient();
            id = "" + client.startPurchase(poId, invoiceNumber, freightCharges);
            logger.info("id = "+id);
        } catch (TTransportException e) {
            errorMsg = "Error while establishing connection to the warehouse server";
            logger.error(errorMsg, e);
        } catch (TException e) {
            errorMsg = "Error while scanning in the item";
            logger.error(errorMsg, e);
        } catch (PurchaseServiceException e) {
            errorMsg = e.getMessage();
            logger.error(errorMsg, e);
        }

        if (errorMsg.isEmpty())
            return true;
        else {
            addActionError(errorMsg);
            return false;
        }
    }
    
    public String update() {
        setItemsFromPO();

        try {
            if (!areValidScans()) {
                return SHOW;
            }
            if(id == null || Long.parseLong(id)==0) {
                    if(!createPurchase()) {
                                return "new";
                        }
            }

            WarehouseClient warehouseClient = new WarehouseClient();
            Client client = warehouseClient.getClient();
            in.shop2020.purchase.PurchaseService.Client purchaseClient = new PurchaseClient().getClient();
            PurchaseOrder po = purchaseClient.getPurchaseOrder(poId);
            if(transferLotId==null || transferLotId==0) {
                    if(transferWarehouseId!=null && transferWarehouseId!=0) {
                        InventoryService.Client inventoryClient = new InventoryClient().getClient();
                        Warehouse fulfilmentWarehouse = inventoryClient.getWarehouses(WarehouseType.OURS, InventoryType.GOOD, po.getSupplierId(), po.getWarehouseId(), 0L).get(0);
                        transferLotId = client.createTransferLot(po.getWarehouseId(), transferWarehouseId);
                    }
            }
            for (LineItem lineItem : lineItems) {
                if (ScanRecordType.BLANK.name().equals(lineItem.getExtra_info())) {
                    continue;
                }

                InventoryItem inventoryItem = new InventoryItem();
                inventoryItem.setItemId(lineItem.getItem_id());
                inventoryItem.setPurchaseId(Long.parseLong(id));
                inventoryItem.setCurrentQuantity(0);
                inventoryItem.setItemNumber(lineItem.getItem_number());
                inventoryItem.setSerialNumber(lineItem.getSerial_number());
                inventoryItem.setInitialQuantity(new Double(lineItem.getQuantity()).longValue());
                inventoryItem.setPhysicalWarehouseId(po.getWarehouseId());
                client.scan(inventoryItem, ScanType.PURCHASE, new Double(lineItem.getQuantity()).longValue(), warehouseId, (transferLotId!=null)?transferLotId:0L);
            }

            resetLineItems();
        } catch (TTransportException e) {
            errorMsg = "Error while establishing connection to the warehouse server";
            logger.error(errorMsg, e);
        } catch (WarehouseServiceException e) {
            errorMsg = e.getMessage();
            logger.error(errorMsg, e);
        } catch (TException e) {
            errorMsg = "Error while scanning in the item";
            logger.error(errorMsg, e);
        } catch (PurchaseServiceException e) {
            errorMsg = "Error while creating the purchase";
            logger.error(errorMsg, e);
        }

        if (!errorMsg.isEmpty()) {
            addActionError(errorMsg);
        }

        return SHOW;
    }

    /**
     * @return
     * @throws TException 
     * @throws NumberFormatException 
     * @throws PurchaseServiceException 
     */
    private boolean areValidScans() throws NumberFormatException, TException, PurchaseServiceException {
        boolean areValidScans = true;
        in.shop2020.purchase.PurchaseService.Client purchaseClient = new PurchaseClient().getClient();
        //PurchaseOrder purchaseOrder = purchaseClient.getPurchaseOrderForPurchase(Long.parseLong(id));
        PurchaseOrder purchaseOrder = purchaseClient.getPurchaseOrder(poId);
        Map<Long, Long> itemsQuantityMapFromPO = new HashMap<Long, Long>();
        for (in.shop2020.purchase.LineItem lineItem : purchaseOrder.getLineitems()) {
            itemsQuantityMapFromPO.put(lineItem.getItemId(), (long) lineItem.getUnfulfilledQuantity());
        }

        Client warehouseClient = new WarehouseClient().getClient();
        for (LineItem lineItem : lineItems) {
            if (lineItem.getItem_id() == -1 && lineItem.getItem_number().isEmpty() && lineItem.getSerial_number().isEmpty()) {
                lineItem.setExtra_info(ScanRecordType.BLANK.name());
            }
            else {
                lineItem.setExtra_info(ScanRecordType.VALID.name());
                if (StringUtils.isNotBlank(lineItem.getSerial_number())) {
                    try {
                        InventoryItem inventoryItem = warehouseClient.getInventoryItem(lineItem.getSerial_number());
                        if(inventoryItem.getLastScanType()!=ScanType.PURCHASE_RETURN) {
                               lineItem.setExtra_info("Item scanned already.");
                               areValidScans = false;
                               continue;
                        }
                    } catch (Exception e) {
                    }
                }

                if (lineItem.getItem_id() == -1 && 
                        (StringUtils.isBlank(lineItem.getItem_number()) || 
                         StringUtils.isBlank(lineItem.getSerial_number())))
                {
                    lineItem.setExtra_info("Item not selected/Item or serial number not present");
                    areValidScans = false;
                    continue;
                }

                if (StringUtils.isBlank(lineItem.getItem_number())) {
                        lineItem.setExtra_info("Item number not entered");
                        areValidScans = false;
                        continue;
                }
                
                if (lineItem.getItem_id() == -1) {
                    List<Long> itemIds = warehouseClient.getItemIds(lineItem.getItem_number());
                    if (itemIds.isEmpty()) {
                        lineItem.setExtra_info("Unknown item number");
                        areValidScans = false;
                        continue;
                    }

                    if (itemIds.size() > 0) {
                        int numItemsInPO = 0;
                        for (long itemId : itemIds) {
                            if (itemsQuantityMapFromPO.containsKey(itemId)) {
                                numItemsInPO++;
                                lineItem.setItem_id(itemId);
                            }
                        }
                        
                        if (numItemsInPO > 1) {
                            lineItem.setExtra_info("Multiple items found for given item Number. Choose item explicitly.");
                            areValidScans = false;
                            continue;
                        }
                    }
                }

                if (!itemsQuantityMapFromPO.containsKey(lineItem.getItem_id())) {
                    lineItem.setExtra_info("Item not present in PO.");
                    areValidScans = false;
                    continue;
                }

                itemsQuantityMapFromPO.put(lineItem.getItem_id(),
                        itemsQuantityMapFromPO.get(lineItem.getItem_id()) - new Double(lineItem.getQuantity()).longValue());

                if (itemsQuantityMapFromPO.get(lineItem.getItem_id()) < 0) {
                    lineItem.setExtra_info("Item already fulfilled in PO.");
                    areValidScans = false;
                    continue;
                }
            }
        }

        return areValidScans;
    }

    private void setItemsFromPO() {
        try {
            items = new ArrayList<Item>();
            in.shop2020.purchase.PurchaseService.Client purchaseClient = new PurchaseClient().getClient();
            //PurchaseOrder purchaseOrder = purchaseClient.getPurchaseOrderForPurchase(id);
            PurchaseOrder purchaseOrder = purchaseClient.getPurchaseOrder(poId);
            warehouseId = purchaseOrder.getWarehouseId();
            in.shop2020.model.v1.catalog.CatalogService.Client catalogClient = new CatalogClient().getClient();

            for (in.shop2020.purchase.LineItem lineItem : purchaseOrder.getLineitems()) {
                items.add(catalogClient.getItem(lineItem.getItemId()));
            }

            in.shop2020.model.v1.inventory.InventoryService.Client inventoryClient = new InventoryClient().getClient();
            warehouse = inventoryClient.getWarehouses(WarehouseType.OURS, InventoryType.GOOD, purchaseOrder.getSupplierId(), warehouseId, warehouseId).get(0);
        } catch (Exception e) {
            logger.error("Could not find items in PO with purchase: " + id, e);
        }
    }

    public String destroy() {
        long id = Long.parseLong(this.id);

        try {
            PurchaseClient warehouseClient = new PurchaseClient();
            in.shop2020.purchase.PurchaseService.Client client = warehouseClient
                    .getClient();
            client.closePurchase(id);
        } catch (TTransportException e) {
            errorMsg = "Error while establishing connection to the warehouse server";
            logger.error(errorMsg, e);
        } catch (TException e) {
            errorMsg = "Error while scanning in the item";
            logger.error(errorMsg, e);
        } catch (PurchaseServiceException e) {
            errorMsg = e.getMessage();
            logger.error(errorMsg, e);
        }
        return "redirect";
    }

    public String createItemNumberMapping() {
        long itemIdLong = Long.parseLong(itemId);

        try {
            Client warehouseClient = new WarehouseClient().getClient();
            warehouseClient.createItemNumberMapping(itemNo, itemIdLong);
        } catch (TTransportException e) {
            logger.error("Could not create thrift client", e);
        } catch (TException e) {
            logger.error("Could not create item number mapping", e);
        }

        return show();
    }
    
    /*public String setTransferItemsOption() {
        boolean isTransferAllowed = false;
        try {
                        Client warehouseClient = new WarehouseClient().getClient();
                isTransferAllowed = warehouseClient.isItemTransferAllowed(warehouseId, transferWarehouseId);
        } catch (TTransportException e) {
            logger.error("Could not create thrift client", e);
        } catch (TException e) {
            logger.error("Could not check if item transfer allowed between warehouses", e);
        }//TODO
        return "";
    }*/
    
    public List<Warehouse> getAllowedDestinationWarehousesForTransfer(long originWarehouseId){
        try {
                WarehouseService.Client warehouseClient = new WarehouseClient().getClient();
                List<Long> allowedWarehouseIds = warehouseClient.getAllowedDestinationWarehousesForTransfer(originWarehouseId);
                List<Warehouse> allowedWarehouses = new ArrayList<Warehouse>();
                InventoryService.Client inventoryClient = new InventoryClient().getClient();
                for(Long allowedWarehouseId : allowedWarehouseIds) {
                        allowedWarehouses.add(inventoryClient.getWarehouse(allowedWarehouseId));
                }
                return allowedWarehouses;
        } catch(Exception e) {
                logger.error("Error while getting all destination warehouses for warehouseId " + warehouseId, e);
                return new ArrayList<Warehouse>();
        }
    }

    public String itemNumberMappingEditNew() {
        return "item-number-mapping";
    }

    public String getName(Item item){
        return ModelUtils.extractProductNameFromItem(item);
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public String getErrorMessage() {
        return errorMsg;
    }

    public String getPurchaseOrderId() {
        return purchaseOrderId;
    }

    public String getServletContextPath() {
        return context.getContextPath();
    }

    public String getItemId() {
        return itemId;
    }

    public void setItemId(String itemId) {
        this.itemId = itemId;
    }

    public String getItemNo() {
        return itemNo;
    }

    public void setItemNo(String itemNo) {
        this.itemNo = itemNo;
    }

    public List<Item> getItems() {
        return items;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }

    public List<LineItem> getLineItems() {
        return lineItems;
    }

    public void setLineItems(List<LineItem> lineItems) {
        this.lineItems = lineItems;
    }

    public Warehouse getWarehouse() {
        return warehouse;
    }

    public List<Invoice> getInvoices() {
        return invoices;
    }

    public void setInvoices(List<Invoice> invoices) {
        this.invoices = invoices;
    }

        public String getInvoiceNumber() {
                return invoiceNumber;
        }

        public void setInvoiceNumber(String invoiceNumber) {
                this.invoiceNumber = invoiceNumber;
        }

        public Double getFreightCharges() {
                return freightCharges;
        }

        public void setFreightCharges(Double freightCharges) {
                this.freightCharges = freightCharges;
        }

        public Long getPoId() {
                return poId;
        }

        public void setPoId(Long poId) {
                this.poId = poId;
        }

        public Long getWarehouseId() {
                return warehouseId;
        }

        public void setWarehouseId(Long warehouseId) {
                this.warehouseId = warehouseId;
        }

        public Long getTransferWarehouseId() {
                return transferWarehouseId;
        }

        public void setTransferWarehouseId(Long transferWarehouseId) {
                this.transferWarehouseId = transferWarehouseId;
        }

        public Long getTransferLotId() {
                return transferLotId;
        }

        public void setTransferLotId(Long transferLotId) {
                this.transferLotId = transferLotId;
        }
        
}