Subversion Repositories SmartDukaan

Rev

Rev 5451 | Rev 5690 | 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.InventoryService.Client;
import in.shop2020.model.v1.catalog.InventoryServiceException;
import in.shop2020.model.v1.catalog.Item;
import in.shop2020.model.v1.catalog.ItemInventory;
import in.shop2020.model.v1.catalog.ItemType;
import in.shop2020.model.v1.catalog.VendorItemMapping;
import in.shop2020.model.v1.catalog.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.TransactionClient;
import in.shop2020.utils.ConfigClientKeys;
import in.shop2020.utils.GmailUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.mail.MessagingException;

import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opensymphony.xwork2.ModelDriven;

public class UpdatesController implements ModelDriven<InventoryUpdate>{

    /**
     * 
     */
    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, String> hotspotMappings = new HashMap<Long, String>();

        private int errorCode = 0;
        private String errorMessage;
        private boolean fullPlbSync = false;
        private String id;
        
        
        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 CatalogClient().getClient();
                        long warehouseId = Long.parseLong(getId());
                        Warehouse warehouse = client.getWarehouse(warehouseId);
                        timestampAndItemIds = warehouse.getVendorString();

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

                        if (!fullPlbSync) {
                            client = new CatalogClient().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 {
            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 {
            Client snapshotClient = new CatalogClient().getClient();
            return snapshotClient.getItemInventoryByItemId(itemId);
        } catch (Exception e) {
            logger.error("Could not fetch all items. Retrying.", e);
            return fetchInventory(itemId);
        }
    }

    /**
     * 
     */
    private void loadHotspotMappings() {
        try {
            Client snapshotClient = new CatalogClient().getClient();
            for (VendorItemMapping mapping : snapshotClient.getAllVendorItemMappings()) {
                if (mapping.getVendorId() == 1) {
                    hotspotMappings.put(mapping.getItemId(),
                            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);
            }

            loadHotspotMappings();
        }
    }

    /**
         * 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.
                    CatalogClient snapshotCatalogServiceClient = new CatalogClient();
                        Client snapshotClient = snapshotCatalogServiceClient.getClient();

                 //The history client is used to update the inventory history on the processing system.
            CatalogClient historyCatalogServiceClient = new CatalogClient(
                    ConfigClientKeys.inventory_history_service_server_host.toString(),
                    ConfigClientKeys.inventory_history_service_server_port.toString());
                        Client historyClient = historyCatalogServiceClient.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);
                        historyClient.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());
                                }
                        }

                        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[]{ "mandeep.dhir@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) {
            loadHotspotMappings();
            Map<Item, PLBDetails> mismatches = new HashMap<Item, PLBDetails>();
            List<Item> items = fetchItems();
            for (Item item : items) {
                if (hotspotMappings.containsKey(item.getId())) {
                    PLBDetails plbDetails = currentInventory
                            .get(hotspotMappings.get(item.getId()).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;
            StringBuilder body = new StringBuilder("Item Id\tBrand\tModel Name\tModel Number\tColor\tSpice Online Retail\tHotspot\n");
            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();
                body.append(item.getId() + "\t" + item.getBrand() + "\t" + item.getModelName() + "\t" + item.getModelNumber() + "\t" + item.getColor() + "\t" + currentSnapshotQuantity + "\t" + plbQuantity + "\n");
            }

            logger.info(body.toString());
            GmailUtils g = new GmailUtils();
            g.sendSSLMessage(new String[]{ "mandeep.dhir@shop2020.in" }, subject, body.toString(), "cnc.center@shop2020.in", "5h0p2o2o", new ArrayList<File>());
        }
    }

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