Subversion Repositories SmartDukaan

Rev

Rev 25112 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.inventory.controllers;

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;

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.POStatus;*/
import in.shop2020.purchase.PurchaseOrder;
/*import in.shop2020.purchase.PurchaseService;*/
import in.shop2020.purchase.PurchaseServiceException;
import in.shop2020.thrift.clients.CatalogClient;
import in.shop2020.thrift.clients.InventoryClient;
import in.shop2020.thrift.clients.PurchaseClient;
import in.shop2020.thrift.clients.WarehouseClient;
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;

@SuppressWarnings("serial")
@Results({ 
        @Result(name = "redirect", type = "redirectAction", params = { "actionName", "warehouse" }),
        @Result(name = "redirectPoShow", type = "redirectAction", params = { "actionName", "purchase-order/${poId}"})
})
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 static final long DUMMY_VENDOR_ID = 40;

        private ServletContext context;
        private String id;
        private Long transferLotId;
        private String itemId;
        private String itemNo;
        private double invoicePrice;

        public double getInvoicePrice() {
                return invoicePrice;
        }

        public void setInvoicePrice(double invoicePrice) {
                this.invoicePrice = invoicePrice;
        }

        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 purchaseComments;

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

        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");
                if (invoiceNumber.endsWith(",")) {
                        addActionError("Invoice Number should not end with Comma");
                        return "show";
                }
                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
                                        + " purchaseComments= " + purchaseComments);
                        PurchaseClient purchaseClient = new PurchaseClient();
                        in.shop2020.purchase.PurchaseService.Client client = purchaseClient.getClient();
                        id = "" + client.startPurchase(poId, invoiceNumber, freightCharges, purchaseComments);
                        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);
                        InventoryService.Client inventoryClient = new InventoryClient().getClient();
                        if (transferLotId == null || transferLotId == 0) {
                                if (transferWarehouseId != null && transferWarehouseId != 0) {
                                        Warehouse fulfilmentWarehouse = inventoryClient.getWarehouses(WarehouseType.OURS,
                                                        InventoryType.GOOD, po.getSupplierId(), po.getWarehouseId(), 0L).get(0);
                                        transferLotId = client.createTransferLot(po.getWarehouseId(), transferWarehouseId);
                                }
                        }
                        boolean checkDirectScanWarehouse = false;

                        if (thirdPartyWarehouse.getVendor().getId() == DUMMY_VENDOR_ID
                                        && thirdPartyWarehouse.getInventoryType() == InventoryType.GOOD
                                        && thirdPartyWarehouse.getWarehouseType() == WarehouseType.OURS_THIRDPARTY) {
                                checkDirectScanWarehouse = true;
                        }

                        long currentWarehouseId = 0;
                        if (!checkDirectScanWarehouse) {
                                Warehouse fulfilmentWarehouse = inventoryClient.getWarehouses(WarehouseType.OURS, InventoryType.GOOD,
                                                po.getSupplierId(), po.getWarehouseId(), 0).get(0);
                                currentWarehouseId = fulfilmentWarehouse.getId();
                        }

                        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());
                                logger.info("checkDirectScanWarehouse..... " + checkDirectScanWarehouse);
                                if (checkDirectScanWarehouse) {
                                        logger.info("Come into this loop.... where direct scan Warehouse Id exist");
                                        inventoryItem.setPhysicalWarehouseId(po.getWarehouseId());
                                        inventoryItem.setCurrentWarehouseId(po.getWarehouseId());
                                } else {
                                        logger.info("Come into this loop.... where direct scan Warehouse Id Not Exist");
                                        inventoryItem.setPhysicalWarehouseId(po.getWarehouseId());
                                        inventoryItem.setCurrentWarehouseId(currentWarehouseId);
                                }

                                if (!client.isAlive()) {
                                        client = warehouseClient.getClient();
                                }
                                client.scan(inventoryItem, ScanType.PURCHASE, new Double(lineItem.getQuantity()).longValue(),
                                                warehouseId, (transferLotId != null) ? transferLotId : 0L);
                        }

                        resetLineItems();
                } catch (TTransportException e) {
                        errorMsg = "Issue while scanning:- " + e.getMessage();
                        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
                                                                && inventoryItem.getLastScanType() != ScanType.DOA_REPLACED) {
                                                        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()) {
                                if(lineItem.getInvoicePrice() > 0) {
                                        items.add(catalogClient.getItem(lineItem.getItemId()));
                                }
                        }

                        in.shop2020.model.v1.inventory.InventoryService.Client inventoryClient = new InventoryClient().getClient();
                        thirdPartyWarehouse = inventoryClient.getWarehouse(warehouseId);
                        if (thirdPartyWarehouse.getVendor().getId() == DUMMY_VENDOR_ID
                                        && thirdPartyWarehouse.getInventoryType() == InventoryType.GOOD
                                        && thirdPartyWarehouse.getWarehouseType() == WarehouseType.OURS_THIRDPARTY) {
                                warehouse = thirdPartyWarehouse;
                        } else {
                                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() throws Exception {
                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 boolean canItemCanBeScannedIn(long id) { double itemWeight = 0.0; try
         * { in.shop2020.model.v1.catalog.CatalogService.Client catalogClient = new
         * CatalogClient().getClient(); Item item = catalogClient.getItem(id);
         * itemWeight = item.getWeight(); } catch (Exception e) {
         * logger.error("Could not fetch item to get weight of it ", e); }
         * if(itemWeight> 0.0){ return true; } return false; }
         */
        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;
        }

        public String getPurchaseComments() {
                return purchaseComments;
        }

        public void setPurchaseComments(String purchaseComments) {
                this.purchaseComments = purchaseComments;
        }

        public Warehouse getThirdPartyWarehouse() {
                return thirdPartyWarehouse;
        }

        public void setThirdPartyWarehouse(Warehouse thirdPartyWarehouse) {
                this.thirdPartyWarehouse = thirdPartyWarehouse;
        }

}