Subversion Repositories SmartDukaan

Rev

Rev 26368 | Rev 26373 | 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.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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.transaction.annotation.Transactional;
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.ObjectMapper;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.ImeiDropSummaryModel;
import com.spice.profitmandi.common.model.ItemDescriptionModel;
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.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.inventory.ItemPricingHistory;
import com.spice.profitmandi.dao.entity.inventory.VendorItemPricing;
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.inventory.ItemPricingHistoryRepository;
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;

@Controller
@Transactional(rollbackFor=Throwable.class)
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 ItemPricingHistoryRepository itemPricingHistoryRepository;

        @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
        ReporticoService reporticoService;

        @Autowired
        LineItemImeisRepository lineItemImeisRepository;

        @RequestMapping(value = "/getItemDescription", method = RequestMethod.GET)
        public String getItemDescription(HttpServletRequest request, Model model) throws Throwable {
                List<PriceDrop> priceDrops = priceDropRepository.selectAll();
                Set<Integer> catalogIds = priceDrops.stream().map(x -> x.getCatalogItemId()).collect(Collectors.toSet());
                List<Item> items = itemRepository.selectAllByCatalogIds(catalogIds);
                Map<Integer, String> catalogDescription = items.stream().collect(Collectors.toMap(x -> x.getCatalogItemId(),
                                x -> x.getItemDescriptionNoColor(), (description1, description2) -> description1));
                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 = "/item", method = RequestMethod.GET)
        public String getItemPricing(HttpServletRequest request, Model model, @RequestParam String query) throws Throwable {
                String query1 = query.toLowerCase();
                List<ItemDescriptionModel> partnersItemDescription = inventoryService.getAllPartnerItemStringDescription().parallelStream()
                                .filter(x -> x.getItemDescription().toLowerCase().matches(".*?" + query1 + ".*?"))
                                .collect(Collectors.toList());

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

        @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(), null);
                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();

                // This call is used to persit imeis to pricedrop imeis in case its not there.
                //This should be called while creating price drop.
                //priceDropService.priceDropStatus(priceDropId);

                List<String> pendingImeis = new ArrayList<>();
                List<String> approvedImeis = new ArrayList<>();
                List<String> rejectedImeis = new ArrayList<>();
                List<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) {
                        priceDropService.processPriceDrop(priceDrop.getId());
                        priceDrop.setProcessTimestamp(LocalDateTime.now());
                        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 oldDp = tagListing.getSellingPrice();
                        float oldMop = tagListing.getMop();
                        float oldTp = 0;
                        float newDp = priceDropModel.getDp();

                        if (newDp != oldDp) {
                                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) {
                                                oldTp = vip.getNlc();
                                                vip.setDp(newDp);
                                                vip.setMop(priceDropModel.getMop());
                                                vip.setNlc(priceDropModel.getTp());
                                                vip.setTp(priceDropModel.getTp());
                                                vendorItemPricingRepository.persist(vip);
                                        }
                                        transactionService.updatePriceDrop(item.getId(), newDp);
                                }
                                
                                //Add to itemPricing history
                                ItemPricingHistory iph = new ItemPricingHistory();
                                iph.setCatalogId(currentItem.getCatalogItemId());
                                iph.setTp(priceDropModel.getTp());
                                iph.setDp(priceDropModel.getDp());
                                iph.setMop(priceDropModel.getMop());
                                //TODO: changedBy
                                iph.setChangedBy("me");
                                iph.setCreateTimestamp(LocalDateTime.now());
                                itemPricingHistoryRepository.persist(iph);
                                
                                
                                PriceDrop priceDrop = new PriceDrop();
                                priceDrop.setAffectedOn(priceDropModel.getAffectedDate());
                                priceDrop.setTp(oldTp);
                                priceDrop.setNlc(oldTp);
                                priceDrop.setMop(oldMop);
                                priceDrop.setOldDp(oldDp);
                                priceDrop.setAmount(oldDp - newDp);
                                priceDrop.setNewDp(newDp);
                                priceDrop.setCreatedOn(LocalDateTime.now());
                                priceDrop.setCatalogItemId(currentItem.getCatalogItemId());
                                priceDropRepository.persist(priceDrop);
                                priceDropService.priceDropStatus(priceDrop.getId());
                                response = true;
                        } else {
                                throw new ProfitMandiBusinessException("Price Drop", priceDropModel.getPd(),
                                                "Price Drop Should be greater than 0");
                        }
                }
                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);
                Map<String, PriceDropIMEI> priceDropIMEIsMap = priceDropIMEIRepository.selectByPriceDropId(priceDropId).
                                stream().collect(Collectors.toMap(x->x.getImei(), x->x));
                
                if(priceDropIMEIsMap.size()==0 && priceDrop.getProcessTimestamp()==null) {
                        priceDrop.setProcessTimestamp(LocalDateTime.now());
                } else {
                        priceDropService.priceDropStatus(priceDrop.getId());
                }
                
                Item item = itemRepository.selectAllByCatalogItemId(priceDrop.getCatalogItemId()).get(0);
                ByteArrayOutputStream baos = getByteArrayOutputStream(priceDrop.getAffectedOn(), priceDrop.getCatalogItemId(), priceDropIMEIsMap);
                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 updatePriceDropImeis(HttpServletRequest request,
                        @RequestBody PriceDropImeisModel priceDropImeisModel, Model model)
                        throws ProfitMandiBusinessException, Exception {
                PriceDropImeiStatus status = PriceDropImeiStatus.PENDING;

                switch (priceDropImeisModel.getUpdatedStatus()) {
                        case "approved": {
                                status = PriceDropImeiStatus.APPROVED;
                                break;
                        }
                        case "rejected": {
                                status = PriceDropImeiStatus.REJECTED;
                                break;
                        }
                }
                
                if(PriceDropImeiStatus.PENDING.equals(status)) {
                        throw new ProfitMandiBusinessException("INVALID STATUS", "PENDING", "only approved and rejected is allowed");
                }
                
                //TODO:PD 
                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(status)) {
                                continue;
                        }
                        priceDropIMEIsToProcess.add(priceDropIMEI);
                        if(status.equals(PriceDropImeiStatus.REJECTED)) {
                                priceDropIMEI.setRejectionReason(priceDropImeisModel.getRejectionReason());
                        }
                        priceDropIMEI.setUpdateTimestamp(LocalDateTime.now());
                }
                if (priceDropIMEIsToProcess.size() > 0) {
                        priceDropService.processManualPriceDrop(priceDropImeisModel.getPriceDropId(), priceDropIMEIsToProcess, status);
                }

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

        }

        private ByteArrayOutputStream getByteArrayOutputStream(LocalDateTime affectedOn, Integer catalogItemId, Map<String, PriceDropIMEI> priceDropImeis)
                        throws Exception {
                List<ImeiDropSummaryModel> imeiDropSummaryModelList = priceDropService
                                .getAllSerialNumbersByAffectedDate(affectedOn, catalogItemId);
                List<List<?>> rows = new ArrayList<>();
                for (ImeiDropSummaryModel imeiDropSummaryModel : imeiDropSummaryModelList) {
                        if(priceDropImeis == null) {
                                rows.add(this.getRow(imeiDropSummaryModel, null));
                        } else if(priceDropImeis.get(imeiDropSummaryModel.getSerialNumber()) != null) {
                                rows.add(this.getRow(imeiDropSummaryModel, priceDropImeis.get(imeiDropSummaryModel.getSerialNumber())));
                        }
                }
                return FileUtil.getCSVByteStream(Arrays.asList("IMEI Number", "Store Name", "Store Code", "Item ID", "Brand", 
                                "Model Name", "Model Number", "Color", "Status", "Rejection Reason", "Activated On", "Added On", "Last Scanned", "Vendor Name", "Activation Timestamp", "Activation Added On"), rows);
        }

        private List<? extends Serializable> getRow(ImeiDropSummaryModel imeiDropSummaryModel, PriceDropIMEI priceDropIMEI) {
                List<Serializable> 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());
                if(priceDropIMEI != null) {
                        row.add(priceDropIMEI.getStatus());
                        row.add(priceDropIMEI.getRejectionReason());
                } else {
                        row.add(PriceDropImeiStatus.PENDING);
                        row.add("");
                }
                row.add(imeiDropSummaryModel.getActivationTimestamp());
                row.add(imeiDropSummaryModel.getActivationAddedOn());
                row.add(FormattingUtils.formatReporitcoDate(imeiDropSummaryModel.getLastScanned()));
                row.add(imeiDropSummaryModel.getVendorName());
                return row;
        }

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

}