Subversion Repositories SmartDukaan

Rev

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

package in.shop2020.support.controllers;

import in.shop2020.model.v1.catalog.Item;
import in.shop2020.model.v1.inventory.InventoryService.Client;
import in.shop2020.model.v1.inventory.InventoryServiceException;
import in.shop2020.model.v1.inventory.ItemInventory;
import in.shop2020.model.v1.inventory.VendorItemMapping;
import in.shop2020.model.v1.inventory.Warehouse;
import in.shop2020.support.models.BillingUpdate;
import in.shop2020.support.models.InventoryUpdate;
import in.shop2020.support.models.PLBDetails;
import in.shop2020.support.models.Update;
import in.shop2020.thrift.clients.CatalogClient;
import in.shop2020.thrift.clients.InventoryClient;
import in.shop2020.thrift.clients.TransactionClient;
import in.shop2020.utils.GmailUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.mail.MessagingException;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opensymphony.xwork2.ModelDriven;

public class UpdatesController implements ModelDriven<InventoryUpdate>{

    /**
     * 
     */
    private static final int HOTSPOT_VENDOR_ID = 1;

    /**
     * 
     */
    private static final String FIELD_DELIMITER = "~#~#~#";

    private static Logger logger = LoggerFactory.getLogger(UpdatesController.class);
    
        private InventoryUpdate inventoryUpdate = new InventoryUpdate();
        private String timestampAndItemIds;
        
        private Map<Long, List<String>> hotspotMappings = new HashMap<Long, List<String>>();

        private int errorCode = 0;
        private String errorMessage;
        private boolean fullPlbSync = false;
        private String id;

    private Client snapshotClient;
        
        
        public UpdatesController(){
                
        }
        
        @Override
        public InventoryUpdate getModel() {
                return this.inventoryUpdate;
        }
        
        public HttpHeaders show(){
                logger.info("Status requested for warehouse id: " + getId());
                Client client;
                
                try {
                        client = new InventoryClient().getClient();
                        long warehouseId = Long.parseLong(getId());
                        Warehouse warehouse = client.getWarehouse(warehouseId);
                        timestampAndItemIds = warehouse.getVendorString();

                        List<String> itemKeys = new ArrayList<String>();

                        if (!fullPlbSync) {
                            client = new InventoryClient().getClient();
                            itemKeys = client.getItemKeysToBeProcessed(warehouseId);
                        }

                        for (String itemKey : itemKeys) {
                            timestampAndItemIds += FIELD_DELIMITER + itemKey;
                        }
                } catch (Exception e) {
                        logger.error("Error getting the warehouse or setting the timestamp", e);
                }
                return new DefaultHttpHeaders("lsuccess");
        }
        
        /**
     * @return
     */
    private List<Item> fetchItems() {
        try {
            in.shop2020.model.v1.catalog.CatalogService.Client snapshotClient = new CatalogClient().getClient();
            return snapshotClient.getAllItems(true);
        } catch (Exception e) {
            logger.error("Could not fetch all items. Retrying.", e);
            try {
                Thread.sleep(30000 * Long.parseLong(inventoryUpdate.getwarehouseId()));
            } catch (Exception e1) {
                logger.error("Could not sleep.", e1);
            }

            return fetchItems();
        }
    }

        /**
     * @return
     */
    private ItemInventory fetchInventory(long itemId) {
        try {
            return snapshotClient.getItemInventoryByItemId(itemId);
        } catch (Exception e) {
            logger.error("Could not fetch all items. Retrying.", e);
            try {
                snapshotClient = new InventoryClient().getClient();
                return fetchInventory(itemId);
            } catch (TTransportException e1) {
                logger.error("Could not create client", e);
                return null;
            }
        }
    }

    /**
     * 
     */
    private void loadHotspotMappings() {
        try {
            for (VendorItemMapping mapping : snapshotClient.getAllVendorItemMappings()) {
                if (mapping.getVendorId() == HOTSPOT_VENDOR_ID) {
                    long itemId = mapping.getItemId();
                    if (!hotspotMappings.containsKey(itemId)) {
                        hotspotMappings.put(itemId, new ArrayList<String>());
                    }

                    hotspotMappings.get(itemId).add(mapping.getItemKey().trim().toLowerCase());
                }
            }
        } catch (Exception e) {
            logger.error("Could not load vendor item mappings. Trying to reload.", e);

            try {
                Thread.sleep(30000 * Long.parseLong(inventoryUpdate.getwarehouseId()));
            } catch (Exception e1) {
                logger.error("Could not sleep.", e1);
            }

            try {
                snapshotClient = new InventoryClient().getClient();
                loadHotspotMappings();
            } catch (TTransportException e1) {
                logger.error("Could not create client", e);
            }
        }
    }

    /**
         * Stores the inventory updates on the history and the production server.
         * @return
         */
        public HttpHeaders create(){
                logger.info(inventoryUpdate.toString());
                try {
                    //The snapshot client is used to update the inventory snapshot for production systems.
                    InventoryClient snapshotCatalogServiceClient = new InventoryClient();
                        Client snapshotClient = snapshotCatalogServiceClient.getClient();

                    //The snapshot client is used to update the inventory snapshot for production systems.
                    TransactionClient transactionClient = new TransactionClient();
                        in.shop2020.model.v1.order.TransactionService.Client tClient = transactionClient.getClient();

                        Long warehouseId = Long.parseLong(inventoryUpdate.getwarehouseId());
                        String timestamp = inventoryUpdate.getCurrentTimestamp();
                        Map<String, Long> availability = new HashMap<String, Long>();
                        List<Update> updates = inventoryUpdate.getUpdates();
                        if (updates != null) {
                    for(Update update: updates){
                        String key = update.getKey();
                        long quantity = (long) Double.parseDouble(update.getQuantity());
                        if(availability.containsKey(key)){
                            quantity = quantity + availability.get(key);
                        }
                        availability.put(key, quantity);
                    }                       
                        }

                        //Update the snapshot before the history since that is more important.
                        snapshotClient.updateInventory(warehouseId, timestamp, availability);
                        snapshotClient.updateInventoryHistory(warehouseId, timestamp, availability);
                        
                        List<BillingUpdate> billingUpdates = inventoryUpdate.getBillingUpdates();
                        if(billingUpdates!=null){
                                for(BillingUpdate billingUpdate: billingUpdates){
                                        tClient.addInvoiceNumber(Long.parseLong(billingUpdate.getOrderId()), billingUpdate.getInvoiceNumber(), billingUpdate.getColor(), billingUpdate.getSerialNumber(), billingUpdate.getItemNumber());
                                }
                        }

                        List<PLBDetails> plbDetails = inventoryUpdate.getPlbDetails();
                        if (plbDetails != null) {
                            Map<String, PLBDetails> currentInventory = new HashMap<String, PLBDetails>();
                            for (PLBDetails plbDetail : plbDetails) {
                                try {
                                    if (fullPlbSync) {
                                        currentInventory.put(plbDetail.getItemKey().toLowerCase(), plbDetail);
                                    }
                                    else {
                                snapshotClient.resetAvailability(
                                        plbDetail.getItemKey(), 1,
                                        plbDetail.getQuantity().longValue(), warehouseId);
                                snapshotClient.markMissedInventoryUpdatesAsProcessed(
                                        plbDetail.getItemKey(), warehouseId);
                                    }
                    } catch (Exception e) {
                        logger.error("Could not reset availability of: " + plbDetail.getItemKey(), e);
                        GmailUtils g = new GmailUtils();
                        g.sendSSLMessage(new String[]{ "amit.gupta@shop2020.in","amar.kumar@shop2020.in" }, "Error resetting availability for " + plbDetail.getItemKey() + " in warehouseId: " + warehouseId + " to " + plbDetail.getQuantity(), "", "cnc.center@shop2020.in", "5hop2o2o", new ArrayList<File>());
                    }
                            }

                            sendMailForPLBMismatches(warehouseId, currentInventory);
                        }
                } catch (Exception e) {
                        logger.error("Unable to update inventory", e);
                }

                return new DefaultHttpHeaders("psuccess");
        }

    private void sendMailForPLBMismatches(Long warehouseId, Map<String, PLBDetails> currentInventory)
            throws InventoryServiceException, TException, MessagingException {
        if (fullPlbSync) {
            snapshotClient = new InventoryClient().getClient();
            loadHotspotMappings();
            Map<Item, PLBDetails> mismatches = new HashMap<Item, PLBDetails>();
            List<Item> items = fetchItems();
            for (Item item : items) {
                if (hotspotMappings.containsKey(item.getId())) {
                    PLBDetails plbDetails = null;
                    for (String s : hotspotMappings.get(item.getId())) {
                        if (currentInventory.containsKey(s.trim().toLowerCase())) {
                            plbDetails = currentInventory.get(s.trim().toLowerCase());
                        }
                    }

                    Long currentSnapshotAvailability = fetchInventory(item.getId()).getAvailability().get(warehouseId);
                    if ((currentSnapshotAvailability == null || currentSnapshotAvailability.equals(0l)) && 
                        (plbDetails == null || plbDetails.getQuantity().longValue() == 0))
                    {
                        continue;
                    }

                    if (currentSnapshotAvailability == null || plbDetails == null ||
                        !currentSnapshotAvailability.equals(plbDetails.getQuantity().longValue()))
                    {
                        mismatches.put(item, plbDetails);
                    }
                }
            }

            String subject = mismatches.size() + " mismatches with PLB sync for warehouse id: " + warehouseId;
            File file = new File("mismatches.xls");

            try {
                BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
                bufferedWriter.write(StringUtils.join(new String[] { "Item Id",
                        "Brand", "Model Name", "Model Number",
                        "Color", "SpiceOnlineRetailStock", "HotspotStock" }, '\t'));
                for (Item item : mismatches.keySet()) {
                    Long currentSnapshotAvailability = fetchInventory(item.getId()).getAvailability().get(warehouseId);
                    String plbQuantity = mismatches.get(item) == null ? "0" : mismatches.get(item).getQuantity().toString();
                    String currentSnapshotQuantity = currentSnapshotAvailability == null ? "0" : currentSnapshotAvailability.toString();
                    bufferedWriter.newLine();
                    bufferedWriter.write(StringUtils.join(new String[] { String.valueOf(item.getId()), item.getBrand(), item.getModelName(),
                            item.getModelNumber(), item.getColor(),currentSnapshotQuantity, plbQuantity }, "\t"));
                }

                bufferedWriter.close();
            } catch (IOException e) {
                logger.error("Could not write mismatches to file", e);
            }

            GmailUtils g = new GmailUtils();
            g.sendSSLMessage(new String[]{ "sandeep.sachdeva@shop2020.in", "khushal.bhatia@shop2020.in", "rajneesh.arora@shop2020.in", "amit.gupta@shop2020.in", "amar.kumar@shop2020.in", "rajveer.singh@shop2020.in" }, subject, 
                    "", "cnc.center@shop2020.in", "5h0p2o2o", file.getAbsolutePath());
        }
    }

        public int getErrorCode() {
                return errorCode;
        }

        public String getErrorMessage() {
                return errorMessage;
        }
        
        public String getId(){
                return id;
        }
        
        public void setId(String id){
                this.id = id;
        }

        public InventoryUpdate getInventoryUpdate() {
                return inventoryUpdate;
        }

        public void setInventoryUpdate(InventoryUpdate inventoryUpdate) {
                this.inventoryUpdate = inventoryUpdate;
        }

        public void setTimestampAndItemIds(String timestampAndItemIds) {
                this.timestampAndItemIds = timestampAndItemIds;
        }

        public String getTimestampAndItemIds() {
                return timestampAndItemIds;
        }

    public boolean isFullPlbSync() {
        return fullPlbSync;
    }

    public void setFullPlbSync(boolean fullPlbSync) {
        this.fullPlbSync = fullPlbSync;
    }
}