Subversion Repositories SmartDukaan

Rev

Rev 24083 | Rev 24176 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.web.controller;

import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.spice.profitmandi.common.enumuration.ReporticoProject;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.ClosingStockOnDate;
import com.spice.profitmandi.common.model.GrnPendingDataModel;
import com.spice.profitmandi.common.model.ImeiDropSummaryModel;
import com.spice.profitmandi.common.model.ItemDescriptionModel;
import com.spice.profitmandi.common.model.PartnerImeiNotSold;
import com.spice.profitmandi.common.model.PriceDropImeisModel;
import com.spice.profitmandi.common.model.PriceDropModel;
import com.spice.profitmandi.common.model.PriceDropProcessModel;
import com.spice.profitmandi.common.model.ReporticoResponseModel;
import com.spice.profitmandi.common.services.ReporticoService;
import com.spice.profitmandi.common.util.FileUtil;
import com.spice.profitmandi.common.util.FormattingUtils;
import com.spice.profitmandi.dao.entity.catalog.Item;
import com.spice.profitmandi.dao.entity.catalog.TagListing;
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
import com.spice.profitmandi.dao.entity.inventory.VendorItemPricing;
import com.spice.profitmandi.dao.entity.transaction.LineItemImei;
import com.spice.profitmandi.dao.entity.transaction.PriceDrop;
import com.spice.profitmandi.dao.entity.transaction.PriceDropIMEI;
import com.spice.profitmandi.dao.enumuration.transaction.PriceDropImeiStatus;
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
import com.spice.profitmandi.dao.repository.fofo.SchemeInOutRepository;
import com.spice.profitmandi.dao.repository.inventory.VendorItemPricingRepository;
import com.spice.profitmandi.dao.repository.transaction.LineItemImeisRepository;
import com.spice.profitmandi.dao.repository.transaction.PriceDropIMEIRepository;
import com.spice.profitmandi.dao.repository.transaction.PriceDropRepository;
import com.spice.profitmandi.service.inventory.InventoryService;
import com.spice.profitmandi.service.pricing.PriceDropService;
import com.spice.profitmandi.service.scheme.SchemeService;
import com.spice.profitmandi.service.transaction.TransactionService;
import com.spice.profitmandi.service.wallet.WalletService;
import com.spice.profitmandi.web.util.MVCResponseSender;

import in.shop2020.model.v1.order.WalletReferenceType;

@Controller
@Transactional
public class PriceDropController {

        private static final Logger LOGGER = LogManager.getLogger(PriceDropController.class);

        @Autowired
        private PriceDropRepository priceDropRepository;

        @Autowired
        private ObjectMapper objectMapper;

        @Autowired
        private VendorItemPricingRepository vendorItemPricingRepository;

        @Autowired
        @Qualifier("fofoInventoryService")
        private InventoryService inventoryService;

        @Autowired
        private MVCResponseSender mvcResponseSender;

        @Autowired
        private PriceDropService priceDropService;

        @Autowired
        private InventoryItemRepository inventoryItemRepository;

        @Autowired
        private WalletService walletService;

        @Autowired
        private TagListingRepository tagListingRepository;

        @Autowired
        private TransactionService transactionService;

        @Autowired
        private PriceDropIMEIRepository priceDropIMEIRepository;

        @Autowired
        @Qualifier("catalogItemRepository")
        private ItemRepository itemRepository;

        @Autowired
        private SchemeService schemeService;

        @Autowired
        private SchemeInOutRepository schemeInOutRepository;

        @Autowired
        ReporticoService reporticoService;

        @Autowired
        LineItemImeisRepository lineItemImeisRepository;

        @RequestMapping(value = "/getItemDescription", method = RequestMethod.GET)
        public String getItemDescription(HttpServletRequest request, Model model) throws Throwable {

                List<TagListing> tagListings = tagListingRepository.selectAll(false);
                Map<Integer, TagListing> tagListingMap = new HashMap<>();
                Set<ItemDescriptionModel> customItems = new HashSet<>();
                List<ItemDescriptionModel> newCustomItems = new ArrayList<>();
                List<Item> items = itemRepository.selectRecentItems(100);
                for (Item item : items) {
                        ItemDescriptionModel itemDescriptionModel = new ItemDescriptionModel();
                        itemDescriptionModel.setItemId(item.getId());
                        itemDescriptionModel.setItemDescription(item.getItemDescription() + "(" + item.getId() + ")");
                        newCustomItems.add(itemDescriptionModel);
                }

                Map<Integer, String> catalogDescription = new HashMap<>();
                for (TagListing tagListing : tagListings) {
                        Item item = itemRepository.selectById(tagListing.getItemId());
                        tagListing.setItemDescription(item.getItemDescription());
                        tagListingMap.put(tagListing.getItemId(), tagListing);
                        ItemDescriptionModel itemDescriptionModel = new ItemDescriptionModel();
                        itemDescriptionModel.setItemId(tagListing.getItemId());
                        itemDescriptionModel
                                        .setItemDescription(tagListing.getItemDescription() + "(" + tagListing.getItemId() + ")");
                        customItems.add(itemDescriptionModel);
                        catalogDescription.put(item.getCatalogItemId(), item.getItemDescriptionNoColor());
                }

                newCustomItems.addAll(customItems);

                List<PriceDrop> priceDrops = priceDropRepository.selectAll();
                model.addAttribute("tagListingMap", tagListingMap);
                model.addAttribute("customItems", new JSONArray(customItems).toString());
                model.addAttribute("newCustomItems", new JSONArray(newCustomItems).toString());
                model.addAttribute("priceDrops", priceDrops);
                model.addAttribute("catalogDescription", catalogDescription);
                return "price-drop";

        }

        @RequestMapping(value = "/item-pricing/{itemId}", method = RequestMethod.GET)
        public String getItemPricing(HttpServletRequest request, Model model, @PathVariable int itemId) throws Throwable {

                TagListing tagListing;
                PriceDropModel pm = new PriceDropModel();
                try {
                        tagListing = tagListingRepository.selectByItemId(itemId);
                        if (tagListing != null) {
                                pm.setMop(tagListing.getMop());
                                pm.setDp(tagListing.getSellingPrice());
                                pm.setMrp(tagListing.getMrp());
                                List<VendorItemPricing> vips = vendorItemPricingRepository.selectAll(itemId);
                                if (vips.size() > 0) {
                                        VendorItemPricing vip = vips.get(0);
                                        pm.setNlc(vip.getNlc());
                                        pm.setTp(vip.getTp());
                                } else {
                                        throw new ProfitMandiBusinessException("Item Id", itemId, "Vendor item pricing does not exist");
                                }
                        }
                } catch (Exception e) {
                        LOGGER.info("Chose item that doesn't exist");
                }
                model.addAttribute("response", mvcResponseSender.createResponseString(pm));
                return "response";
        }

        /*
         * @RequestMapping(value = "/price-drop/imes1/download") public
         * ResponseEntity<ByteArrayResource> downloadPriceDropImeis1(HttpServletRequest
         * request,
         * 
         * @RequestParam LocalDateTime affectedDate, @RequestParam int itemId) throws
         * Exception { Item item = itemRepository.selectById(itemId);
         * List<ImeiDropSummaryModel> imeiDropSummaryModelList =
         * this.getAllSerialNumbersByAffectedDate(affectedDate,
         * item.getCatalogItemId()); List<String> imeis =
         * imeiDropSummaryModelList.stream().map(x->x.getSerialNumber()).collect(
         * Collectors.toList()); Map<String, ImeiDropSummaryModel> imeisDropMap =
         * imeiDropSummaryModelList.stream().collect(Collectors.toMap(
         * ImeiDropSummaryModel::getSerialNumber, x->x)); List<InventoryItem>
         * inventoryItems = inventoryItemRepository.selectBySerialNumbers(new
         * HashSet<>(imeis)); List<Integer> inventoryItemIds =
         * inventoryItems.stream().map(InventoryItem::getId).collect(Collectors.toList()
         * );
         * 
         * List<SchemeInOut> schemeInOuts =
         * schemeInOutRepository.selectByInventoryItemIds(new
         * HashSet<>(inventoryItemIds));
         * 
         * Set<ItemQuantity> itemSchemes = new HashSet<>(); Map<ItemQuantity,
         * SchemeInOut> itemSchemeInOutMap = new HashMap<>(); for(SchemeInOut
         * schemeInOut : schemeInOuts) { } List<List<Object>> rows = new ArrayList<>();
         * for (ImeiDropSummaryModel imeiDropSummaryModel : imeiDropSummaryModelList) {
         * List<Object> row = this.getRow(imeiDropSummaryModel);
         * 
         * rows.add(this.getRow(imeiDropSummaryModel)); }
         * 
         * FileUtil.getCSVByteStream(Arrays.asList("IMEI Number", "Store Name",
         * "Store Code", "Item ID", "Brand", "Model Name", "Model Number", "Color",
         * "Last Scanned"), rows); final HttpHeaders headers = new HttpHeaders();
         * headers.set("Content-Type",
         * "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
         * headers.set("Content-disposition", "inline; filename=imei-" +
         * item.getItemDescriptionNoColor() + ".csv"); return new
         * ResponseEntity<ByteArrayResource>(null, headers, HttpStatus.OK);
         * 
         * }
         */
        @RequestMapping(value = "/price-drop/imes/download")
        public ResponseEntity<ByteArrayResource> downloadPriceDropImeis(HttpServletRequest request,
                        @RequestParam LocalDateTime affectedDate, @RequestParam int itemId) throws Exception {
                Item item = itemRepository.selectById(itemId);
                ByteArrayOutputStream baos = getByteArrayOutputStream(affectedDate, item.getCatalogItemId());
                final HttpHeaders headers = new HttpHeaders();
                headers.set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                headers.set("Content-disposition", "inline; filename=imei-" + item.getItemDescriptionNoColor() + ".csv");
                byte[] byteArray = baos.toByteArray();
                headers.setContentLength(byteArray.length);
                return new ResponseEntity<ByteArrayResource>(new ByteArrayResource(byteArray), headers, HttpStatus.OK);
        }

        @RequestMapping(value = "/price-drop/addPayout", method = RequestMethod.POST)
        public String updatePriceDrop(HttpServletRequest request, @RequestBody PriceDropProcessModel priceDropProcessModel,
                        Model model) throws Exception {
                boolean response = false;
                PriceDrop priceDrop = priceDropRepository.selectById(priceDropProcessModel.getPriceDropId());
                if (priceDrop.getProcessTimestamp() == null) {
                        priceDrop.setPartnerPayout(priceDropProcessModel.getPartnerPayout());
                        priceDrop.setPriceDropIn(priceDropProcessModel.getPriceDropIn());
                        // priceDrop.setProcessTimestamp(LocalDateTime.now());
                        priceDropRepository.persist(priceDrop);
                        response = true;
                }
                model.addAttribute("response", mvcResponseSender.createResponseString(response));
                return "response";
        }

        @RequestMapping(value = "/priceDropImeis/{priceDropId}", method = RequestMethod.GET)
        public String priceDropStatus(HttpServletRequest request, @PathVariable int priceDropId, Model model)
                        throws Exception {

                PriceDropImeisModel priceDropImeisModel = new PriceDropImeisModel();
                List<String> pendingImeis = new ArrayList<>();
                List<String> approvedImeis = new ArrayList<>();
                List<String> rejectedImeis = new ArrayList<>();
                List<PriceDropIMEI> priceDropImeis = priceDropIMEIRepository.selectByPriceDropId(priceDropId);
                if (priceDropImeis.size() == 0) {
                        PriceDrop priceDrop = priceDropRepository.selectById(priceDropId);
                        List<ImeiDropSummaryModel> imeis = this.getAllSerialNumbersByAffectedDate(priceDrop.getAffectedOn(),
                                        priceDrop.getCatalogItemId());
                        for (ImeiDropSummaryModel imei : imeis) {
                                PriceDropIMEI priceDropIMEI = new PriceDropIMEI();
                                priceDropIMEI.setImei(imei.getSerialNumber());
                                priceDropIMEI.setPriceDropId(priceDropId);
                                priceDropIMEI.setPartnerId(imei.getRetailerId());
                                priceDropIMEIRepository.persist(priceDropIMEI);
                        }
                        priceDropImeis = priceDropIMEIRepository.selectByPriceDropId(priceDropId);
                }

                for (PriceDropIMEI priceDropIMEI : priceDropImeis) {
                        if (priceDropIMEI.getStatus().equals(PriceDropImeiStatus.PENDING)) {
                                pendingImeis.add(priceDropIMEI.getImei());
                        } else if (priceDropIMEI.getStatus().equals(PriceDropImeiStatus.APPROVED)) {
                                approvedImeis.add(priceDropIMEI.getImei());
                        }
                        if (priceDropIMEI.getStatus().equals(PriceDropImeiStatus.REJECTED)) {
                                rejectedImeis.add(priceDropIMEI.getImei());
                        }
                }
                priceDropImeisModel.setPendingImeis(pendingImeis);
                priceDropImeisModel.setPriceDropId(priceDropId);
                priceDropImeisModel.setApprovedImeis(approvedImeis);
                priceDropImeisModel.setRejectedImeis(rejectedImeis);
                model.addAttribute("response", mvcResponseSender.createResponseString(priceDropImeisModel));
                return "response";
        }

        @RequestMapping(value = "/processPriceDrop", method = RequestMethod.POST)
        public String processPriceDrop(HttpServletRequest request, @RequestBody PriceDropProcessModel priceDropProcess,
                        Model model) throws Exception {
                PriceDrop priceDrop = priceDropRepository.selectById(priceDropProcess.getPriceDropId());
                boolean response = false;
                if (priceDrop.getProcessTimestamp() == null) {
                        priceDrop.setProcessTimestamp(LocalDateTime.now());
                        priceDropRepository.persist(priceDrop);
                        response = true;
                }
                model.addAttribute("response", mvcResponseSender.createResponseString(response));
                return "response";
        }

        @RequestMapping(value = "/updateMop", method = RequestMethod.POST)
        public String addMop(HttpServletRequest request, Model model, @RequestBody PriceDropModel priceDropModel)
                        throws Exception {
                boolean response = false;
                priceDropModel.setAllColors(true);
                TagListing tagListing = tagListingRepository.selectByItemId(priceDropModel.getItemId());
                float newDp = tagListing.getSellingPrice() - priceDropModel.getPd();
                List<Item> allItems = null;
                Item currentItem = itemRepository.selectById(priceDropModel.getItemId());
                if (priceDropModel.isAllColors()) {
                        allItems = itemRepository.selectAllByCatalogItemId(currentItem.getCatalogItemId());

                } else {
                        allItems = Arrays.asList(currentItem);
                }
                for (Item item : allItems) {
                        TagListing itemTagListing = tagListingRepository.selectByItemId(item.getId());
                        if (itemTagListing == null)
                                continue;
                        itemTagListing.setMop(priceDropModel.getMop());
                        tagListingRepository.persist(tagListing);
                        List<VendorItemPricing> vipList = vendorItemPricingRepository.selectAll(item.getId());
                        for (VendorItemPricing vip : vipList) {
                                vip.setDp(newDp);
                                vip.setMop(priceDropModel.getMop());
                                vendorItemPricingRepository.persist(vip);
                        }
                        transactionService.updatePriceDrop(item.getId(), newDp);
                }
                PriceDrop priceDrop = new PriceDrop();
                priceDrop.setAffectedOn(LocalDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT));
                priceDrop.setOldDp(tagListing.getSellingPrice());
                priceDrop.setAmount(priceDropModel.getPd());
                priceDrop.setNewDp(tagListing.getSellingPrice());
                priceDrop.setNlc(priceDropModel.getNlc());
                priceDrop.setTp(priceDropModel.getTp());
                priceDrop.setCreatedOn(LocalDateTime.now());
                priceDrop.setCatalogItemId(currentItem.getCatalogItemId());
                priceDrop.setProcessTimestamp(LocalDateTime.now());
                priceDrop.setPartnerPayout(0);
                priceDrop.setPriceDropIn(0);
                priceDropRepository.persist(priceDrop);
                response = true;
                model.addAttribute("response", mvcResponseSender.createResponseString(response));
                return "response";
        }

        @RequestMapping(value = "/priceDrop", method = RequestMethod.POST)
        public String addPriceDrop(HttpServletRequest request, Model model, @RequestBody PriceDropModel priceDropModel)
                        throws Exception {
                boolean response = false;
                priceDropModel.setAllColors(true);
                if (this.validatePriceDrop(priceDropModel)) {
                        TagListing tagListing = tagListingRepository.selectByItemId(priceDropModel.getItemId());
                        float newDp = tagListing.getSellingPrice() - priceDropModel.getPd();
                        if (newDp > 0) {
                                List<Item> allItems = null;
                                Item currentItem = itemRepository.selectById(priceDropModel.getItemId());
                                if (priceDropModel.isAllColors()) {
                                        allItems = itemRepository.selectAllByCatalogItemId(currentItem.getCatalogItemId());

                                } else {
                                        allItems = Arrays.asList(currentItem);
                                }
                                for (Item item : allItems) {
                                        TagListing itemTagListing = tagListingRepository.selectByItemId(item.getId());
                                        if (itemTagListing == null)
                                                continue;
                                        itemTagListing.setSellingPrice(newDp);
                                        itemTagListing.setMop(priceDropModel.getMop());
                                        tagListingRepository.persist(tagListing);
                                        List<VendorItemPricing> vipList = vendorItemPricingRepository.selectAll(item.getId());
                                        for (VendorItemPricing vip : vipList) {
                                                vip.setDp(newDp);
                                                vip.setMop(priceDropModel.getMop());
                                                vip.setNlc(priceDropModel.getNlc());
                                                vip.setTp(priceDropModel.getTp());
                                                vendorItemPricingRepository.persist(vip);
                                        }
                                        transactionService.updatePriceDrop(item.getId(), newDp);
                                }
                                PriceDrop priceDrop = new PriceDrop();
                                priceDrop.setAffectedOn(priceDropModel.getAffectedDate());
                                priceDrop.setOldDp(newDp + priceDropModel.getPd());
                                priceDrop.setAmount(priceDropModel.getPd());
                                priceDrop.setNewDp(newDp);
                                priceDrop.setNlc(priceDropModel.getNlc());
                                priceDrop.setMop(priceDropModel.getMop());
                                priceDrop.setTp(priceDropModel.getTp());
                                priceDrop.setCreatedOn(LocalDateTime.now());
                                priceDrop.setCatalogItemId(currentItem.getCatalogItemId());
                                priceDropRepository.persist(priceDrop);
                                response = true;
                        } else {
                                throw new ProfitMandiBusinessException("Price Drop", priceDropModel.getPd(),
                                                "Price Drop Cannot be more than Current DP");
                        }
                }
                model.addAttribute("response", mvcResponseSender.createResponseString(response));
                return "response";
        }

        @RequestMapping(value = "/downloadtotalPriceDropIMEI/{priceDropId}", method = RequestMethod.GET)
        public ResponseEntity<?> downloadTotalPriceDropIMEI(HttpServletRequest request, @PathVariable int priceDropId,
                        Model model) throws ProfitMandiBusinessException, Exception {

                PriceDrop priceDrop = priceDropRepository.selectById(priceDropId);
                Item item = itemRepository.selectAllByCatalogItemId(priceDrop.getCatalogItemId()).get(0);
                ByteArrayOutputStream baos = getByteArrayOutputStream(priceDrop.getAffectedOn(), priceDrop.getCatalogItemId());
                final HttpHeaders headers = new HttpHeaders();
                headers.set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                headers.set("Content-disposition",
                                "inline; filename=pricedrop-" + item.getItemDescriptionNoColor().replaceAll("\\s?,\\s?", " ") + "-"
                                                + FormattingUtils.formatDate(priceDrop.getAffectedOn()) + ".csv");
                byte[] byteArray = baos.toByteArray();
                headers.setContentLength(byteArray.length);
                return new ResponseEntity<ByteArrayResource>(new ByteArrayResource(byteArray), headers, HttpStatus.OK);

        }

        @RequestMapping(value = "/updatePriceDropImeis", method = RequestMethod.POST)
        public String downloadTotalPriceDropIMEI(HttpServletRequest request,
                        @RequestBody PriceDropImeisModel priceDropImeisModel, Model model)
                        throws ProfitMandiBusinessException, Exception {
                PriceDropImeiStatus status=PriceDropImeiStatus.PENDING;;

                switch (priceDropImeisModel.getUpdatedStatus()) {
                case "pending": {
                        status = PriceDropImeiStatus.PENDING;
                        break;
                }
                case "approved": {
                        status = PriceDropImeiStatus.APPROVED;
                        break;
                }
                case "rejected": {
                        status = PriceDropImeiStatus.REJECTED;
                        break;
                }

                }
                List<PriceDropIMEI> priceDropIMEIs = priceDropIMEIRepository
                                .selectByPriceDropId(priceDropImeisModel.getPriceDropId());

                List<PriceDropIMEI> priceDropIMEIsToProcess = new ArrayList<>();
                for (PriceDropIMEI priceDropIMEI : priceDropIMEIs) {
                        if (!priceDropImeisModel.getUpdatedImeis().contains(priceDropIMEI.getImei())
                                        || priceDropIMEI.getStatus().equals(PriceDropImeiStatus.APPROVED)
                                        || priceDropIMEI.getStatus().equals(status)) {
                                continue;
                        } else {
                                if(status.equals(PriceDropImeiStatus.APPROVED)) {
                                        priceDropIMEIsToProcess.add(priceDropIMEI);
                                }
                                priceDropIMEI.setStatus(status);
                                priceDropIMEI.setUpdateTimestamp(LocalDateTime.now());
                                priceDropIMEIRepository.persist(priceDropIMEI);
                        }
                }
                PriceDrop priceDrop = priceDropRepository.selectById(priceDropImeisModel.getPriceDropId());
                Item item = itemRepository.selectAllByCatalogItemId(priceDrop.getCatalogItemId()).get(0);
                String description = item.getItemDescriptionNoColor();
                if (priceDropIMEIsToProcess.size() > 0) {
                        List<String> serialNumbers = priceDropIMEIsToProcess.stream().map(x -> x.getImei())
                                        .collect(Collectors.toList());
                        List<LineItemImei> lineItemImeis = lineItemImeisRepository.selectByIMEI(serialNumbers);
                        Map<Integer, List<InventoryItem>> pendingPartnerInventoryMap = priceDropService
                                        .getInventoryForPriceDrop(lineItemImeis, priceDrop).stream()
                                        .collect(Collectors.groupingBy(InventoryItem::getFofoId));

                        for (Map.Entry<Integer, List<InventoryItem>> pendingPartnerInventory : pendingPartnerInventoryMap
                                        .entrySet()) {
                                List<InventoryItem> fofoInventoryList = pendingPartnerInventory.getValue();
                                int fofoId = pendingPartnerInventory.getKey();

                                String reversalReason = MessageFormat.format(
                                                "Scheme  differential for Price Drop of Rs.{0} on {1}, on {3}. Total {2} item(s)",
                                                priceDrop.getAmount(), description, fofoInventoryList.size(),
                                                FormattingUtils.formatDate(priceDrop.getAffectedOn()));
                                String aReason = MessageFormat.format(
                                                "Payout of Rs.{4} per unit for Price Drop of Rs.{0} on {1}, on {3}. Total {2} item(s)",
                                                priceDrop.getAmount(), description, fofoInventoryList.size(),
                                                FormattingUtils.formatDate(priceDrop.getAffectedOn()), priceDrop.getPartnerPayout());
                                inventoryService.updatePriceDrop(fofoInventoryList, priceDrop.getAmount());
                                if (item.getBrand().equals("Samsung")) {
                                        schemeService.reverseSchemes(fofoInventoryList, priceDrop.getId(),
                                                        reversalReason);
                                }
                                walletService.addAmountToWallet(fofoId, priceDrop.getId(), WalletReferenceType.PRICE_DROP, aReason,
                                                priceDrop.getPartnerPayout() * fofoInventoryList.size());
                        }

                }
                
                
                model.addAttribute("response", mvcResponseSender.createResponseString(true));
                return "response";

        }

        private List<ImeiDropSummaryModel> getAllSerialNumbersByAffectedDate(LocalDateTime affectedOn,
                        Integer catalogItemId) throws Exception {
                List<Item> items = itemRepository.selectAllByCatalogItemId(catalogItemId);
                List<String> itemIds = items.stream().map(x -> String.valueOf(x.getId())).collect(Collectors.toList());

                Map<String, String> params = new HashMap<>();
                params.put("MANUAL_criteria1_FROMDATE", FormattingUtils.formatReporitcoDate(affectedOn.minusDays(1)));
                params.put("MANUAL_itemId", StringUtils.join(itemIds, ","));

                Map<String, String> params1 = new HashMap<>();
                params1.put("MANUAL_criteriaDate_FROMDATE", FormattingUtils.formatReporitcoDate(affectedOn.minusDays(1)));
                params1.put("MANUAL_criteriaItemId", StringUtils.join(itemIds, ","));

                Map<String, String> params2 = new HashMap<>();
                params2.put("MANUAL_Criteria2_FROMDATE", FormattingUtils.formatReporitcoDate(affectedOn.minusDays(1)));
                params2.put("MANUAL_Criteria1", StringUtils.join(itemIds, ","));

                List<? extends ImeiDropSummaryModel> grnPendingList = getReports(GrnPendingDataModel.class,
                                ReporticoProject.FOCO, "imeispendinggrn.xml", params);
                List<? extends ImeiDropSummaryModel> partnerImeiNotSoldList = getReports(PartnerImeiNotSold.class,
                                ReporticoProject.FOCO, "PartnerIMEINotSold.xml", params1);
                List<? extends ImeiDropSummaryModel> itemStockOnDateList = getReports(ClosingStockOnDate.class,
                                ReporticoProject.WAREHOUSENEW, "itemstockondate.xml", params2);

                List<ImeiDropSummaryModel> mergedImeis = new ArrayList<>();
                mergedImeis.addAll(grnPendingList);
                mergedImeis.addAll(partnerImeiNotSoldList);
                mergedImeis.addAll(itemStockOnDateList);
                return mergedImeis;
        }

        private ByteArrayOutputStream getByteArrayOutputStream(LocalDateTime affectedOn, Integer catalogItemId)
                        throws Exception {
                List<ImeiDropSummaryModel> imeiDropSummaryModelList = this.getAllSerialNumbersByAffectedDate(affectedOn,
                                catalogItemId);
                List<List<Object>> rows = new ArrayList<>();
                for (ImeiDropSummaryModel imeiDropSummaryModel : imeiDropSummaryModelList) {
                        rows.add(this.getRow(imeiDropSummaryModel));
                }
                return FileUtil.getCSVByteStream(Arrays.asList("IMEI Number", "Store Name", "Store Code", "Item ID", "Brand",
                                "Model Name", "Model Number", "Color", "Last Scanned"), rows);
        }

        private List<Object> getRow(ImeiDropSummaryModel imeiDropSummaryModel) {
                List<Object> row = new ArrayList<>();
                row.add(imeiDropSummaryModel.getSerialNumber());
                row.add(imeiDropSummaryModel.getStoreName());
                row.add(imeiDropSummaryModel.getPartnerCode());
                row.add(imeiDropSummaryModel.getItemId());
                row.add(imeiDropSummaryModel.getBrand());
                row.add(imeiDropSummaryModel.getModelName());
                row.add(imeiDropSummaryModel.getModelNumber());
                row.add(imeiDropSummaryModel.getColor());
                row.add(FormattingUtils.formatReporitcoDate(imeiDropSummaryModel.getLastScanned()));
                return row;
        }

        private <T> List<T> getReports(Class<T> className, ReporticoProject project, String reportName,
                        Map<String, String> params) throws Exception {
                HttpResponse reportResponse = reporticoService.getJsonFile(project, reportName, params);
                JavaType type = objectMapper.getTypeFactory().constructParametricType(ReporticoResponseModel.class, className);
                ObjectReader or = objectMapper.readerFor(type);
                ReporticoResponseModel<T> responseObj = or.readValue(reportResponse.getEntity().getContent());
                return responseObj.getData();
        }

        private boolean validatePriceDrop(PriceDropModel priceDropModel) throws ProfitMandiBusinessException {
                if (priceDropModel.getMop() > 0 && priceDropModel.getMop() > 0 && priceDropModel.getNlc() > 0
                                && priceDropModel.getTp() > 0 && priceDropModel.getNlc() > 0) {
                        return true;
                }
                return false;
        }

}