Subversion Repositories SmartDukaan

Rev

Rev 27361 | Rev 27377 | 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
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.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
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.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.InputStreamResource;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.gson.Gson;
import com.spice.profitmandi.common.enumuration.DateTimePattern;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.CustomRetailer;
import com.spice.profitmandi.common.model.MapWrapper;
import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.common.model.SchemeItems;
import com.spice.profitmandi.common.model.SchemeModel;
import com.spice.profitmandi.common.util.ExcelUtils;
import com.spice.profitmandi.common.util.StringUtils;
import com.spice.profitmandi.common.web.util.ResponseSender;
import com.spice.profitmandi.dao.entity.catalog.Item;
import com.spice.profitmandi.dao.entity.catalog.Offer;
import com.spice.profitmandi.dao.entity.catalog.OfferPartner;
import com.spice.profitmandi.dao.entity.catalog.Offermargin;
import com.spice.profitmandi.dao.entity.catalog.Scheme;
import com.spice.profitmandi.dao.entity.fofo.PartnerType;
import com.spice.profitmandi.dao.entity.fofo.PrebookingListing;
import com.spice.profitmandi.dao.entity.fofo.SchemeItem;
import com.spice.profitmandi.dao.enumuration.catalog.ItemCriteriaType;
import com.spice.profitmandi.dao.model.AmountMarginModel;
import com.spice.profitmandi.dao.model.CreateOfferRequest;
import com.spice.profitmandi.dao.model.CreateSchemeRequest;
import com.spice.profitmandi.dao.model.ItemTypeParams;
import com.spice.profitmandi.dao.model.SimpleItemType;
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
import com.spice.profitmandi.dao.repository.catalog.OfferMarginRepository;
import com.spice.profitmandi.dao.repository.catalog.OfferPartnerRepository;
import com.spice.profitmandi.dao.repository.catalog.OfferRepository;
import com.spice.profitmandi.dao.repository.catalog.SchemeRepository;
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
import com.spice.profitmandi.dao.repository.dtr.Mongo;
import com.spice.profitmandi.dao.repository.dtr.RoleRepository;
import com.spice.profitmandi.dao.repository.fofo.PartnerTypeChangeService;
import com.spice.profitmandi.dao.repository.fofo.PurchaseRepository;
import com.spice.profitmandi.dao.repository.fofo.SchemeItemRepository;
import com.spice.profitmandi.service.authentication.RoleManager;
import com.spice.profitmandi.service.inventory.InventoryService;
import com.spice.profitmandi.service.scheme.SchemeService;
import com.spice.profitmandi.service.user.RetailerService;
import com.spice.profitmandi.web.model.LoginDetails;
import com.spice.profitmandi.web.util.CookiesProcessor;
import com.spice.profitmandi.web.util.MVCResponseSender;

@Controller
@Transactional(rollbackOn = Throwable.class)
public class SchemeController {

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

        @Autowired
        private SchemeService schemeService;

        @Autowired
        private SchemeRepository schemeRepository;

        @Autowired
        private SchemeItemRepository schemeItemRepository;

        @Autowired
        private MVCResponseSender mvcResponseSender;

        @Autowired
        private CookiesProcessor cookiesProcessor;

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

        @Autowired
        private TagListingRepository tagListingRepository;

        @Autowired
        private RoleManager roleManager;

        @Autowired
        private PurchaseRepository purchaseRepository;

        @Autowired
        private RoleRepository roleRepository;

        @Autowired
        private ResponseSender<?> responseSender;

        @Autowired
        private OfferRepository offerRepository;

        @Autowired
        private OfferMarginRepository offerMarginRepository;

        @Autowired
        private FofoStoreRepository fofoStoreRepository;

        @Autowired
        private OfferPartnerRepository offerPartnerRepository;

        @Autowired
        private ItemRepository itemRepository;

        @Autowired
        private Gson gson;

        @Autowired
        private RetailerService retailerService;

        @Autowired
        private Mongo mongoClient;

        @Autowired
        private PartnerTypeChangeService partnerTypeChangeService;

        @RequestMapping(value = "/createScheme", method = RequestMethod.GET)
        public String createScheme(HttpServletRequest request, Model model) {
                // Map<Integer, String> itemIdItemDescriptionMap =
                // inventoryService.getAllItemIdItemDescriptionMap();
                // model.addAttribute("itemIdItemDescriptionMap", itemIdItemDescriptionMap);
                Set<String> brands = inventoryService.getAllTagListingBrands(ProfitMandiConstants.MOBILE_CATEGORY_ID);
                brands.addAll(inventoryService.getAllTagListingBrands(14206));
                model.addAttribute("brands", brands);
                model.addAttribute("retailerTypes", PartnerType.values());
                return "create-scheme";
        }

        @RequestMapping(value = "/getTagListingItemsByBrand", method = RequestMethod.POST)
        public String getTagListingItemsByBrand(HttpServletRequest request, @RequestBody List<String> brands, Model model) {
                Map<Integer, String> itemIdItemDescriptionMap = new HashMap<>();
                LOGGER.info("brands" + brands);

                List<MapWrapper<Integer, String>> itemIdItemDescriptionMaplist = inventoryService
                                .getAllTagListingItemIdItemDescriptionMap(new HashSet<>(brands));
                for (MapWrapper<Integer, String> mapWrapper : itemIdItemDescriptionMaplist) {
                        itemIdItemDescriptionMap.put(mapWrapper.getKey(), mapWrapper.getValue());
                }
                model.addAttribute("itemIdItemDescriptionMap", itemIdItemDescriptionMap);
                // model.addAttribute("brands", inventoryService.getAllBrands());

                return "tag-listing-items-description";
        }

        @RequestMapping(value = "/schemes/update-schemes-page", method = RequestMethod.GET)
        public String updateShcemes(HttpServletRequest request) throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                if (!roleManager.isAdmin(loginDetails.getRoleIds())) {
                        throw new ProfitMandiBusinessException("User", loginDetails.getEmailId(), "Unauthorised access");
                }
                return "update-schemes-page";
        }

        @RequestMapping(value = "/schemes/update", method = RequestMethod.POST)
        public String updateShcemes(HttpServletRequest request, @RequestBody SchemeItems schemeItems, Model model)
                        throws Exception {
                for (int schemeId : schemeItems.getSchemeIds()) {
                        if (schemeRepository.selectById(schemeId) != null)
                                for (int itemId : schemeItems.getItemIds()) {
                                        if (tagListingRepository.selectByItemIdsAndTagIds(new HashSet<>(Arrays.asList(itemId)),
                                                        new HashSet<>(Arrays.asList(4, 7))).size() > 0) {
                                                SchemeItem si = new SchemeItem();
                                                si.setItemId(itemId);
                                                si.setSchemeId(schemeId);
                                                try {
                                                        schemeItemRepository.persist(si);
                                                } catch (Exception e) {
                                                        LOGGER.info("Scheme aleady exist");
                                                }
                                                model.addAttribute("response", mvcResponseSender.createResponseString(true));
                                        } else {
                                                model.addAttribute("response", mvcResponseSender.createResponseString(false));
                                                throw new ProfitMandiBusinessException("ItemId", itemId, "Invalid Item Id");
                                        }
                                }
                }
                return "response";
        }

        @RequestMapping(value = "/addItemToScheme", method = RequestMethod.POST)
        public String updateScheme(HttpServletRequest request, @RequestBody SchemeItems schemeItems, Model model)
                        throws Exception {
                for (int schemeId : schemeItems.getSchemeIds()) {
                        List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(schemeId);
                        if (schemeRepository.selectById(schemeId) != null)
                                for (int itemId : schemeItems.getItemIds()) {
                                        if (tagListingRepository.selectByItemIdsAndTagIds(new HashSet<>(Arrays.asList(itemId)),
                                                        new HashSet<>(Arrays.asList(4, 7))).size() > 0 && (!(itemIds.contains(itemId)))) {
                                                SchemeItem si = new SchemeItem();
                                                si.setItemId(itemId);
                                                si.setSchemeId(schemeId);
                                                try {
                                                        schemeItemRepository.persist(si);
                                                } catch (Exception e) {
                                                        LOGGER.info("Scheme already exist");
                                                }
                                                model.addAttribute("response", mvcResponseSender.createResponseString(true));
                                        } else {
                                                model.addAttribute("response", mvcResponseSender.createResponseString(false));
                                        }
                                }
                }
                return "response";
        }

        @RequestMapping(value = "/schemes/delete", method = RequestMethod.DELETE)
        public String deleteShcemes(HttpServletRequest request,
                        @RequestParam(name = "schemeId", required = false, defaultValue = "0") int schemeId,
                        @RequestParam(name = "itemId", required = false, defaultValue = "0") int itemId, Model model)
                        throws Exception {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                if (!(schemeId == 0 && itemId == 0) || (!(schemeId == 0 || itemId == 0))) {
                        schemeItemRepository.deletebyItemIdsandSchemeIds(itemId, schemeId);

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

                        model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));

                }
                return "response";
        }

        @RequestMapping(value = "/extendAllSchemes", method = RequestMethod.POST)
        public String extendAllScheme(HttpServletRequest request, @RequestBody LocalDateTime extendDatetime, Model model)
                        throws Exception {

                List<Scheme> schemes = schemeRepository.selectActiveAll();
                if (schemes.size() > 0) {
                        for (Scheme scheme : schemes) {
                                if (scheme.getExpireTimestamp() == null) {
                                        scheme.setEndDateTime(extendDatetime);
                                        schemeRepository.persist(scheme);
                                }
                        }
                        model.addAttribute("response", mvcResponseSender.createResponseString(true));
                        return "response";
                }
                model.addAttribute("response", mvcResponseSender.createResponseString(false));
                return "response";
        }

        @RequestMapping(value = "/extendSchemeById", method = RequestMethod.POST)
        public String extendSchemeById(HttpServletRequest request,

                        @RequestParam(name = ProfitMandiConstants.SCHEME_ID) int schemeId,
                        @RequestBody LocalDateTime extendDatetime, Model model) throws Exception {

                LOGGER.info("ExtendDatetime" + extendDatetime);
                LOGGER.info("schemeId" + schemeId);
                Scheme scheme = schemeRepository.selectById(schemeId);
                if ((!(scheme.getActiveTimestamp() == null)) && scheme.getExpireTimestamp() == null) {
                        scheme.setEndDateTime(extendDatetime);
                        schemeRepository.persist(scheme);
                        model.addAttribute("response", mvcResponseSender.createResponseString(true));
                        return "response";
                }
                model.addAttribute("response", mvcResponseSender.createResponseString(false));
                return "response";
        }

        @RequestMapping(value = "/createScheme", method = RequestMethod.POST)
        public String createScheme(HttpServletRequest request, @RequestBody CreateSchemeRequest createSchemeRequest,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchItem", required = false, defaultValue = "") String searchItem,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                LOGGER.info("CreateSchemeRequest {}", createSchemeRequest);
                schemeService.saveScheme(loginDetails.getFofoId(), createSchemeRequest);
                LOGGER.info("Scheme saved successfully");
                long size = schemeRepository.selectAllCount();
                List<Scheme> schemes = schemeRepository.selectAll(offset, limit);
                model.addAttribute("schemes", schemes);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                model.addAttribute("searchItem", searchItem);
                model.addAttribute("searchTerm", searchTerm);
                model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));
                if (schemes.size() < limit) {
                        model.addAttribute("end", offset + schemes.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }
                return "schemes";

        }

        @RequestMapping(value = "/getSchemes", method = RequestMethod.GET)
        public String getSchemes(HttpServletRequest request, @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchItem", required = false, defaultValue = "") String searchItem,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm,
                        @RequestParam(name = "partnerType", required = false, defaultValue = "") PartnerType partnerType,
                        Model model) throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());

                LOGGER.info("isAdmin" + isAdmin);
                List<Scheme> schemes = null;
                long size = 0;
                LOGGER.info("partnerType" + partnerType);
                if (partnerType == null) {
                        partnerType = partnerTypeChangeService.getTypeOnDate(loginDetails.getFofoId(), LocalDate.now());
                }
                if (!(searchTerm.equals("")) && searchItem.equals("")) {
                        schemes = schemeRepository.selectBySearchTerm(searchTerm, offset, limit);
                        if (!(schemes.size() == 0)) {
                                size = schemeRepository.selectAllCount();
                                LOGGER.info("schemes" + schemes);
                                model.addAttribute("schemes", schemes);
                                model.addAttribute("start", offset + 1);
                                model.addAttribute("size", size);
                                model.addAttribute("searchTerm", searchTerm);
                                model.addAttribute("searchItem", searchItem);
                                model.addAttribute("partnerType", partnerType);
                                model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));
                                if (schemes.size() < limit) {
                                        model.addAttribute("end", offset + schemes.size());
                                } else {
                                        model.addAttribute("end", offset + limit);
                                }
                        } else {
                                throw new ProfitMandiBusinessException("SchemeId", searchTerm, "SchemeId Not Found");
                        }
                } else {
                        int itemId = 0;
                        if (!(searchItem.equals("")) && searchTerm.equals("")) {
                                itemId = Integer.parseInt(searchItem);
                        }

                        schemes = schemeService.selectSchemeByPartnerType(partnerType, itemId, isAdmin, offset, limit);
                        size = schemeService.selectSchemeCount(partnerType, itemId, isAdmin);
                        model.addAttribute("schemes", schemes);
                        model.addAttribute("start", offset + 1);
                        model.addAttribute("size", size);
                        model.addAttribute("searchItem", searchItem);
                        model.addAttribute("searchTerm", searchTerm);
                        model.addAttribute("partnerType", partnerType);
                        model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));
                        if (schemes.size() < limit) {
                                model.addAttribute("end", offset + schemes.size());
                        } else {
                                model.addAttribute("end", offset + limit);
                        }
                }
                // model.addAttribute("roleTypes", loginDetails.getRoleTypes());
                return "schemes";
        }

        @RequestMapping(value = "/getPaginatedSchemes", method = RequestMethod.GET)
        public String getPaginatedSchemes(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchItem", required = false, defaultValue = "") String searchItem,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm,
                        @RequestParam(name = "partnerType", required = false, defaultValue = "") PartnerType partnerType,
                        Model model) throws ProfitMandiBusinessException {

                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());

                LOGGER.info("requested offset=[{}], limit = [{}]", offset, limit);
                List<Scheme> schemes = null;
                /*
                 * if (roleManager.isAdmin(loginDetails.getRoleIds())) { schemes =
                 * schemeRepository.selectAll(offset, limit); } else { schemes =
                 * schemeRepository.selectActiveAll(offset, limit); }
                 */
                if (partnerType == null) {
                        partnerType = partnerTypeChangeService.getTypeOnDate(loginDetails.getFofoId(), LocalDate.now());
                }
                LOGGER.info("partnerType" + partnerType);
                int itemId = 0;
                if (!(searchItem.equals("")) && searchTerm.equals("")) {
                        itemId = Integer.parseInt(searchItem);
                }
                schemes = schemeService.selectSchemeByPartnerType(partnerType, itemId, isAdmin, offset, limit);

                model.addAttribute("schemes", schemes);
                model.addAttribute("partnerType", partnerType);
                model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));
                return "schemes-paginated";
        }

        @RequestMapping(value = "/schemes/downloadPage", method = RequestMethod.GET)
        public String downloadPage(HttpServletRequest request, Model model) {
                return "schemes-download";
        }

        @RequestMapping(value = "/schemes/download", method = RequestMethod.GET)
        public ResponseEntity<?> downloadInventoryItemAgingByInterval(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.START_DATE_TIME) String startDateTimeString,
                        @RequestParam(name = ProfitMandiConstants.END_DATE_TIME) String endDateTimeString, Model model)
                        throws ProfitMandiBusinessException {
                LocalDateTime startDateTime = StringUtils.toDateTime(startDateTimeString,
                                DateTimePattern.DD_MM_yyyy_T_HH_MM_SS);
                LocalDateTime endDateTime = StringUtils.toDateTime(endDateTimeString, DateTimePattern.DD_MM_yyyy_T_HH_MM_SS);

                List<SchemeModel> schemeModels = schemeService.getAllSchemeModels(startDateTime, endDateTime);

                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                ExcelUtils.writeSchemeModels(schemeModels, byteArrayOutputStream);

                final HttpHeaders headers = new HttpHeaders();
                headers.set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                headers.set("Content-disposition", "inline; filename=SchemesReport.xlsx");
                headers.setContentLength(byteArrayOutputStream.toByteArray().length);
                final InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                final InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
                return new ResponseEntity<InputStreamResource>(inputStreamResource, headers, HttpStatus.OK);

                // return responseSender.ok(ResponseCodeHolder.getMessage("ITM_AGNG_OK_1000"));
        }

        @RequestMapping(value = "/getSchemeById", method = RequestMethod.GET)
        public String getSchemeById(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.SCHEME_ID) int schemeId, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                Scheme scheme = schemeService.getSchemeById(schemeId);
                model.addAttribute("scheme", scheme);
                model.addAttribute("isAdmin", roleManager.isAdmin(loginDetails.getRoleIds()));
                return "scheme-details";

        }

        @RequestMapping(value = "/activeSchemeById", method = RequestMethod.PUT)
        public String activeSchemeById(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.SCHEME_ID) int schemeId,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                schemeService.activeSchemeById(schemeId);
                List<Scheme> schemes = schemeRepository.selectAll(offset, limit);
                model.addAttribute("schemes", schemes);
                return "schemes-paginated";
        }

        @RequestMapping(value = "/expireSchemeById", method = RequestMethod.PUT)
        public String expireSchemeById(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.SCHEME_ID) int schemeId,
                        @RequestParam(name = ProfitMandiConstants.EXPIRE_TIMESTAMP) LocalDateTime expiryTimestamp,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                schemeService.expireSchemeById(schemeId, expiryTimestamp);
                List<Scheme> schemes = schemeRepository.selectAll(offset, limit);
                model.addAttribute("schemes", schemes);
                return "schemes-paginated";
        }

        @RequestMapping(value = "/getSchemesJson", method = RequestMethod.GET)
        public ResponseEntity<?> getSchemesJson(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                return responseSender.ok(schemeService.getSchemes(loginDetails.getRoleIds(), offset, limit));
        }

        @RequestMapping(value = "/searchSchemeByCategory")
        public String getSchemeByCategory(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchItem", required = false, defaultValue = "") String searchItem,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm,
                        @RequestParam(name = "category", required = true, defaultValue = "") PartnerType category, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<Scheme> schemes = null;
                long size = 0;

                schemes = schemeRepository.selectByPartnerType(category, offset, limit);

                if (!(schemes.size() == 0)) {
                        size = schemeRepository.selectAllCount();
                        LOGGER.info("schemes" + schemes);
                        model.addAttribute("schemes", schemes);
                        model.addAttribute("start", offset + 1);
                        model.addAttribute("size", size);
                        model.addAttribute("searchTerm", searchTerm);
                        model.addAttribute("searchItem", searchItem);
                        model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));
                        if (schemes.size() < limit) {
                                model.addAttribute("end", offset + schemes.size());
                        } else {
                                model.addAttribute("end", offset + limit);
                        }
                }

                return "schemes";
        }

        @RequestMapping(value = "/getSchemeByCategoryPaginated")
        public String getSchemeByCategoryPaginated(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchItem", required = false, defaultValue = "") String searchItem,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm,
                        @RequestParam(name = "category", required = true, defaultValue = "") PartnerType category, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                LOGGER.info("In search Item....");
                List<Scheme> schemes = null;

                schemes = schemeRepository.selectByPartnerType(category, offset, limit);

                model.addAttribute("schemes", schemes);
                model.addAttribute("searchItem", searchItem);
                model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));
                return "schemes-paginated";
        }

        @RequestMapping(value = "/searchScheme")
        public String getSchemeBySchemeId(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm,
                        @RequestParam(name = "searchItem", required = false, defaultValue = "") String searchItem, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<Scheme> schemes = null;
                long size = 0;
                if (!(searchTerm.equals("")) && searchItem.equals("")) {
                        schemes = schemeRepository.selectBySearchTerm(searchTerm, offset, limit);
                        if (!(schemes.size() == 0)) {
                                size = schemeRepository.selectAllCount();
                                LOGGER.info("schemes" + schemes);
                                model.addAttribute("schemes", schemes);
                                model.addAttribute("start", offset + 1);
                                model.addAttribute("size", size);
                                model.addAttribute("searchTerm", searchTerm);
                                model.addAttribute("searchItem", searchItem);
                                model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));
                                if (schemes.size() < limit) {
                                        model.addAttribute("end", offset + schemes.size());
                                } else {
                                        model.addAttribute("end", offset + limit);
                                }
                        } else {
                                throw new ProfitMandiBusinessException("SchemeId", searchTerm, "SchemeId Not Found");
                        }
                } else if (!(searchItem.equals("")) && searchTerm.equals("")) {
                        List<Integer> schemeIds = schemeItemRepository.selectSchemeIdByItemId(Integer.parseInt(searchItem));
                        if (!(schemeIds.size() == 0)) {
                                LOGGER.info("schemeIds in searchItemScheme" + schemeIds);
                                schemes = schemeRepository.selectBySchemeIds(schemeIds, offset, limit);
                                size = schemeIds.size();
                                LOGGER.info("Size" + size);
                                model.addAttribute("schemes", schemes);
                                model.addAttribute("start", offset + 1);
                                model.addAttribute("size", size);
                                model.addAttribute("searchItem", searchItem);
                                model.addAttribute("searchTerm", searchTerm);
                                model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));
                                if (schemes.size() < limit) {
                                        model.addAttribute("end", offset + schemes.size());
                                } else {
                                        model.addAttribute("end", offset + limit);
                                }

                        } else {
                                throw new ProfitMandiBusinessException("SchemeIds", searchItem, "SchemeId Not Found");
                        }
                } else {
                        if (roleManager.isAdmin(loginDetails.getRoleIds())) {
                                schemes = schemeRepository.selectAll(offset, limit);
                                size = schemeRepository.selectAllCount();
                        } else {
                                schemes = schemeRepository.selectActiveAll(offset, limit);
                                size = schemeRepository.selectAllActiveCount();
                        }
                        model.addAttribute("schemes", schemes);
                        model.addAttribute("start", offset + 1);
                        model.addAttribute("size", size);
                        model.addAttribute("searchItem", searchItem);
                        model.addAttribute("searchTerm", searchTerm);
                        model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));
                        if (schemes.size() < limit) {
                                model.addAttribute("end", offset + schemes.size());
                        } else {
                                model.addAttribute("end", offset + limit);
                        }
                }
                return "schemes";
        }

        @RequestMapping(value = "/searchItemSchemePanigated")
        public String getSchemeByItemPanigated(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchItem", required = false, defaultValue = "") String searchItem, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                LOGGER.info("In search Item....");
                List<Scheme> schemes = null;
                if (!searchItem.equals("")) {
                        List<Integer> schemeIds = schemeItemRepository.selectSchemeIdByItemId(Integer.parseInt(searchItem));
                        if (schemeIds != null) {
                                LOGGER.info(schemeIds);
                                schemes = schemeRepository.selectBySchemeIds(schemeIds, offset, limit);

                        }
                }
                model.addAttribute("schemes", schemes);
                model.addAttribute("searchItem", searchItem);
                model.addAttribute("roleType", roleManager.isAdmin(loginDetails.getRoleIds()));
                return "schemes-paginated";

        }

        @RequestMapping(value = "/getCreateOffer", method = RequestMethod.GET)
        public String getCreateOffer(HttpServletRequest request, Model model) throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<Integer> fofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId())
                                .collect(Collectors.toList());

                List<String> brands = mongoClient.getMongoBrands(loginDetails.getFofoId(), null, 3).stream()
                                .map(x -> (String) x.get("name")).collect(Collectors.toList());

                Map<Integer, CustomRetailer> customRetailersMap = retailerService.getFofoRetailers(fofoIds);

                model.addAttribute("customRetailersMap", customRetailersMap);
                model.addAttribute("itemCriteriaType", ItemCriteriaType.values());
                model.addAttribute("brands", brands);
                model.addAttribute("partnerCategories", PartnerType.values());
                return "scheme_offer";

        }

        @RequestMapping(value = "/createOffer", method = RequestMethod.POST)
        public String createOffer(HttpServletRequest request, @RequestBody CreateOfferRequest createOfferRequest,
                        Model model) throws Exception {
                LOGGER.info("createOfferRequest" + createOfferRequest.getAmountOffer());

                Offer offer = new Offer();
                offer.setName(createOfferRequest.getName());
                offer.setDescription(createOfferRequest.getDescription());
                offer.setItemCreteria(createOfferRequest.getItemCriteria());
                offer.setTargetType(createOfferRequest.getTargetType());
                offer.setAmountType(createOfferRequest.getAmountType());
                offer.setStartDateTime(createOfferRequest.getStartDate());
                offer.setEndDateTime(createOfferRequest.getEndDate());
                offer.setPrice(createOfferRequest.getPrice());
                offer.setCreatedTimestamp(LocalDateTime.now());
                offer.setSchemeType(createOfferRequest.getSchemeType());
                offer.setCriteria(createOfferRequest.getCriteria());
                offer.setPartnerType(createOfferRequest.getPartnerType());

                if (createOfferRequest.getItemCriteria().equals(ItemCriteriaType.Item_Model)) {
                        ItemTypeParams itemTypeParams = new ItemTypeParams();
                        itemTypeParams.setCatalogId(createOfferRequest.getCatalogIds());
                        SimpleItemType sit = new SimpleItemType(itemTypeParams);
                        sit.setItemTypeParams(itemTypeParams);
                        offer.setItemParam(gson.toJson(itemTypeParams));
                } else if (createOfferRequest.getItemCriteria().equals(ItemCriteriaType.Multiple_Brand)) {
                        ItemTypeParams itemTypeParams = new ItemTypeParams();
                        itemTypeParams.setBrands(createOfferRequest.getBrands());
                        SimpleItemType sit = new SimpleItemType(itemTypeParams);
                        sit.setItemTypeParams(itemTypeParams);
                        offer.setItemParam(gson.toJson(itemTypeParams));
                }

                offerRepository.persist(offer);
                if (createOfferRequest.getFofoIds().isEmpty()) {
                        List<Integer> fofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId())
                                        .collect(Collectors.toList());
                        for (Integer fofoId : fofoIds) {
                                PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(fofoId,
                                                offer.getStartDateTime().toLocalDate());
                                if (offer.getPartnerType().equals(partnerType)) {
                                        LOGGER.info("partnerType" + partnerType);
                                        LOGGER.info("fofoId" + fofoId);

                                        OfferPartner op = new OfferPartner();
                                        op.setFofoId(fofoId);
                                        op.setOfferId(offer.getId());
                                        offerPartnerRepository.persist(op);
                                }

                        }
                }

                else {

                        for (Integer fofoId : createOfferRequest.getFofoIds()) {
                                OfferPartner op = new OfferPartner();
                                op.setFofoId(fofoId);
                                op.setOfferId(offer.getId());
                                offerPartnerRepository.persist(op);
                        }
                }
                for (AmountMarginModel amm : createOfferRequest.getAmountOffer()) {
                        Offermargin om = new Offermargin();
                        om.setValue(amm.getValue());
                        om.setMargin(amm.getMargin());
                        om.setOfferId(offer.getId());
                        offerMarginRepository.persist(om);
                }

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

        }

        @RequestMapping(value = "/getOffers", method = RequestMethod.GET)
        public String createOffer(HttpServletRequest request, @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm, Model model)
                        throws Exception {

                List<Offer> offers = null;
                long size = 0;

                offers = offerRepository.selectAll(offset, limit);
                size = offerRepository.selectAllCount();

                model.addAttribute("offers", offers);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                model.addAttribute("searchTerm", searchTerm);

                if (offers.size() < limit) {
                        model.addAttribute("end", offset + offers.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }

                return "offer_history";

        }

        @RequestMapping(value = "/getPaginatedOffers", method = RequestMethod.GET)
        public String getPaginatedOffers(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {

                List<Offer> offers = null;
                offers = offerRepository.selectAll(offset, limit);
                model.addAttribute("offers", offers);

                return "offer_history_paginated";
        }

        @RequestMapping(value = "/searchOffer")
        public String getOfferById(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit,
                        @RequestParam(name = "searchTerm", required = false, defaultValue = "") String searchTerm, Model model)
                        throws ProfitMandiBusinessException {
                List<Offer> offers = null;
                long size = 0;
                if (!(searchTerm.equals(""))) {
                        offers = offerRepository.selectBySearchTerm(searchTerm, offset, limit);
                        if (!(offers.size() == 0)) {
                                size = offerRepository.selectAllCount();
                                LOGGER.info("offers" + offers);
                                model.addAttribute("offers", offers);
                                model.addAttribute("start", offset + 1);
                                model.addAttribute("size", size);
                                model.addAttribute("searchTerm", searchTerm);
                                if (offers.size() < limit) {
                                        model.addAttribute("end", offset + offers.size());
                                } else {
                                        model.addAttribute("end", offset + limit);
                                }
                        } else {
                                throw new ProfitMandiBusinessException("OfferId", searchTerm, "offerId Not Found");
                        }
                } else {

                        offers = offerRepository.selectAll(offset, limit);
                        size = schemeRepository.selectAllCount();

                        model.addAttribute("offers", offers);
                        model.addAttribute("start", offset + 1);
                        model.addAttribute("size", size);
                        model.addAttribute("searchTerm", searchTerm);

                        if (offers.size() < limit) {
                                model.addAttribute("end", offset + offers.size());
                        } else {
                                model.addAttribute("end", offset + limit);
                        }
                }
                return "offer_history";
        }

        @RequestMapping(value = "/updateOfferStatus", method = RequestMethod.POST)
        public String updateOfferStatus(HttpServletRequest request, @RequestParam int id, Model model) throws Exception {

                Offer offer = offerRepository.selectById(id);
                LOGGER.info("status" + offer.getStatus());

                if (offer.getStatus() == false) {
                        offer.setStatus(true);
                } else {
                        offer.setStatus(false);
                }
                offer.setCreatedTimestamp(LocalDateTime.now());
                model.addAttribute("response", mvcResponseSender.createResponseString(true));
                return "response";

        }

        @RequestMapping(value = "/getOfferMargin", method = RequestMethod.GET)
        public String getOfferMargin(HttpServletRequest request,
                        @RequestParam(name = "offerId", defaultValue = "0") int offerId, Model model) throws Exception {
                Offer offer = offerRepository.selectById(offerId);
                List<Integer> fofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId())
                                .collect(Collectors.toList());
                Map<Integer, CustomRetailer> customRetailersMap = retailerService.getFofoRetailers(fofoIds);
                List<OfferPartner> offerPartners = offerPartnerRepository.selectByOfferId(offerId);

                LOGGER.info("offerId" + offer.getId());

                Map<Integer, Double> value = offerRepository.selectSumOfferByRetailer(offer.getStartDateTime(),
                                offer.getEndDateTime(), 0, offer, true);

                LOGGER.info("value" + value);
                List<Offermargin> offerMargin = offerMarginRepository.selectByOfferId(offerId);
                Map<Integer, Double> partnerValueMap = new HashMap<>();
                Map<Integer, List<Double>> partnerMarginMap = new HashMap<Integer, List<Double>>();
                Map<Integer, Integer> shortageAmount = new HashMap<>();

                for (OfferPartner op : offerPartners) {

                        LOGGER.info("offerPartneer" + op.getFofoId());
                        if (value.containsKey(op.getFofoId())) {
                                partnerValueMap.put(op.getFofoId(), value.get(op.getFofoId()));

                        } else {
                                value.put(op.getFofoId(), 0d);

                                partnerValueMap.put(op.getFofoId(), 0d);

                        }
                        List<Double> valSetOne = new ArrayList<Double>();

                        for (Offermargin om : offerMargin) {

                                if (value.get(op.getFofoId()) <= om.getValue()) {
                                        LOGGER.info("om1" + om.getMargin());
                                        shortageAmount.put(op.getFofoId(), om.getValue() - value.get(op.getFofoId()).intValue());
                                        valSetOne.add(om.getMargin());
                                        partnerMarginMap.put(op.getFofoId(), valSetOne);

                                        break;
                                } else {
                                        LOGGER.info("om2" + om.getMargin());
                                        valSetOne.add(om.getMargin());

                                        int shortage = om.getValue() - value.get(op.getFofoId()).intValue();

                                        if (shortage < 0) {
                                                shortageAmount.put(op.getFofoId(), 0);
                                        }

                                        partnerMarginMap.put(op.getFofoId(), valSetOne);

                                }
                        }

                }

                LOGGER.info("partnerMarginMap" + partnerMarginMap);
                LOGGER.info("partnerValueMap" + partnerValueMap);
                LOGGER.info("shortageAmount" + shortageAmount);

/*              ItemTypeParams scp = gson.fromJson(offer.getItemParam(), ItemTypeParams.class);
                if (offer.getItemCriteria().equals(ItemCriteriaType.Multiple_Brand)) {
                        List<String> brands = scp.getBrands();
                        model.addAttribute("brands", brands);
                }
                if (offer.getItemCriteria().equals(ItemCriteriaType.Item_Model)) {
                        List<Integer> catalogIds = scp.getCatalogId();
                        List<Item> newList = new ArrayList<>();
                        Set<Integer> catalogId = new HashSet<>();
                        List<Item> items = itemRepository.selectAllByCatalogIds(catalogIds.stream().collect(Collectors.toSet()));
                        for (Item item : items) {
                                if (catalogId.add(item.getCatalogItemId())) {
                                        newList.add(item);
                                }
                        }
                        model.addAttribute("items", newList);
                }*/
                model.addAttribute("partnerMarginMap", partnerMarginMap);
                model.addAttribute("partnerValueMap", partnerValueMap);
                model.addAttribute("customRetailersMap", customRetailersMap);
                model.addAttribute("offerMargin", offerMargin);
                model.addAttribute("offer", offer);
                model.addAttribute("shortageAmount", shortageAmount);

                return "offer_margin_detail";

        }

        @RequestMapping(value = "/offerById", method = RequestMethod.GET)
        public String offerById(HttpServletRequest request, int offerId, Model model) throws ProfitMandiBusinessException {
                Offer offer = offerRepository.selectById(offerId);

                model.addAttribute("offer", offer);

                return "offer-edit";

        }

        @RequestMapping(value = "/extendByOfferId", method = RequestMethod.POST)
        public String extendByOfferId(HttpServletRequest request,

                        int offerId, @RequestBody LocalDateTime extendDatetime, Model model) throws Exception {

                LOGGER.info("ExtendDatetime" + extendDatetime);
                LOGGER.info("schemeId" + offerId);
                Offer offer = offerRepository.selectById(offerId);

                offer.setEndDateTime(extendDatetime);
                offerRepository.persist(offer);
                model.addAttribute("response", mvcResponseSender.createResponseString(true));

                return "response";
        }

}