Subversion Repositories SmartDukaan

Rev

Rev 26777 | Rev 26784 | 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.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
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.eclipsesource.json.JsonObject;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Ordering;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.spice.profitmandi.common.enumuration.SchemeType;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.CreatePendingOrderRequest;
import com.spice.profitmandi.common.model.CustomRetailer;
import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.common.model.UserInfo;
import com.spice.profitmandi.common.solr.SolrService;
import com.spice.profitmandi.common.web.client.RestClient;
import com.spice.profitmandi.common.web.util.ResponseSender;
import com.spice.profitmandi.dao.entity.catalog.Item;
import com.spice.profitmandi.dao.entity.catalog.TagListing;
import com.spice.profitmandi.dao.entity.dtr.WebListing;
import com.spice.profitmandi.dao.entity.fofo.CurrentInventorySnapshot;
import com.spice.profitmandi.dao.entity.fofo.Customer;
import com.spice.profitmandi.dao.entity.fofo.PincodePartner;
import com.spice.profitmandi.dao.entity.inventory.ItemAvailabilityCache;
import com.spice.profitmandi.dao.enumuration.dtr.OtpType;
import com.spice.profitmandi.dao.model.AddCartRequest;
import com.spice.profitmandi.dao.model.CartItem;
import com.spice.profitmandi.dao.model.CartItemResponseModel;
import com.spice.profitmandi.dao.model.CartResponse;
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
import com.spice.profitmandi.dao.repository.dtr.WebListingRepository;
import com.spice.profitmandi.dao.repository.dtr.WebProductListingRepository;
import com.spice.profitmandi.dao.repository.fofo.CurrentInventorySnapshotRepository;
import com.spice.profitmandi.dao.repository.fofo.CustomerRepository;
import com.spice.profitmandi.dao.repository.fofo.PendingOrderService;
import com.spice.profitmandi.dao.repository.fofo.PincodePartnerRepository;
import com.spice.profitmandi.dao.repository.inventory.ItemAvailabilityCacheRepository;
import com.spice.profitmandi.service.authentication.RoleManager;
import com.spice.profitmandi.service.inventory.FofoAvailabilityInfo;
import com.spice.profitmandi.service.inventory.FofoCatalogResponse;
import com.spice.profitmandi.service.scheme.SchemeService;
import com.spice.profitmandi.service.user.RetailerService;
import com.spice.profitmandi.web.processor.OtpProcessor;
import com.spice.profitmandi.web.res.DealBrands;
import com.spice.profitmandi.web.res.DealObjectResponse;
import com.spice.profitmandi.web.res.DealsResponse;
import com.spice.profitmandi.web.res.ValidateCartResponse;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@Controller
@Transactional(rollbackFor = Throwable.class)
public class StoreController {

        private static final Logger logger = LogManager.getLogger(StoreController.class);

        private static final LocalTime CUTOFF_TIME = LocalTime.of(15, 0);

        private static final List<Integer> TAG_IDS = Arrays.asList(4);

        private static final int DEFAULT_STORE = 171912487;

        @Value("${python.api.host}")
        private String host;

        @Value("${python.api.port}")
        private int port;

        // This is now unused as we are not supporting multiple companies.
        @Value("${gadgetCops.invoice.cc}")
        private String[] ccGadgetCopInvoiceTo;

        @Autowired
        private PincodePartnerRepository pincodePartnerRepository;

        @Autowired
        private FofoStoreRepository fofoStoreRepository;

        @Autowired
        private RetailerService retailerService;

        @Autowired
        private PendingOrderService pendingOrderService;

        @Autowired
        private CustomerRepository customerRepository;

        @Autowired
        private SolrService commonSolrService;

        @Autowired
        private OtpProcessor otpProcessor;

        @Autowired
        private CurrentInventorySnapshotRepository currentInventorySnapshotRepository;

        @Autowired
        private ResponseSender<?> responseSender;

        @Autowired
        private TagListingRepository tagListingRepository;

        @Autowired
        private ItemRepository itemRepository;

        @Autowired
        private SchemeService schemeService;

        @Autowired
        private ItemAvailabilityCacheRepository itemAvailabilityCacheRepository;

        @Autowired
        private WebListingRepository webListingRepository;

        @Autowired
        private WebProductListingRepository webProductListingRepository;

        @Autowired
        private RoleManager roleManagerService;

        List<String> filterableParams = Arrays.asList("brand");

        @ApiImplicitParams({
                        @ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header") })
        @RequestMapping(value = "/store/fofo", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> getFofo(HttpServletRequest request,
                        @RequestParam(value = "categoryId", required = false, defaultValue = "(3 OR 6)") String categoryId,
                        @RequestParam(value = "offset") String offset, @RequestParam(value = "limit") String limit,
                        @RequestParam(value = "sort", required = false) String sort,
                        @RequestParam(value = "brand", required = false) String brand,
                        @RequestParam(value = "subCategoryId", required = false) int subCategoryId,
                        @RequestParam(value = "q", required = false) String queryTerm,
                        @RequestParam(value = "hotDeal", required = false) boolean hotDeal) throws Throwable {
                List<FofoCatalogResponse> dealResponse = new ArrayList<>();
                UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                if (roleManagerService.isPartner(userInfo.getRoleIds())) {
                        // UserCart uc = userAccountRepository.getUserCart(userInfo.getUserId());
                        RestClient rc = new RestClient();
                        Map<String, String> params = new HashMap<>();
                        List<String> mandatoryQ = new ArrayList<>();
                        if (queryTerm != null && !queryTerm.equals("null")) {
                                mandatoryQ.add(String.format("+(%s)", queryTerm));
                        } else {
                                queryTerm = null;
                        }
                        if (subCategoryId != 0) {
                                mandatoryQ
                                                .add(String.format("+(subCategoryId_i:%s) +{!parent which=\"subCategoryId_i:%s\"} tagId_i:(%s)",
                                                                subCategoryId, subCategoryId, StringUtils.join(TAG_IDS, " ")));
                        } else if (hotDeal) {
                                mandatoryQ.add(String.format("+{!parent which=\"hot_deals_b=true\"} tagId_i:(%s)",
                                                StringUtils.join(TAG_IDS, " ")));

                        } else if (StringUtils.isNotBlank(brand)) {
                                mandatoryQ.add(
                                                String.format("+(categoryId_i:%s) +(brand_ss:%s) +{!parent which=\"brand_ss:%s\"} tagId_i:(%s)",
                                                                categoryId, brand, brand, StringUtils.join(TAG_IDS, " ")));

                        } else {
                                mandatoryQ.add(
                                                String.format("+{!parent which=\"id:catalog*\"} tagId_i:(%s)", StringUtils.join(TAG_IDS, " ")));
                        }
                        params.put("q", StringUtils.join(mandatoryQ, " "));
                        params.put("fl", "*, [child parentFilter=id:catalog*]");
                        if (queryTerm == null) {
                                params.put("sort", "create_s desc");
                        }
                        params.put("start", String.valueOf(offset));
                        params.put("rows", String.valueOf(limit));
                        params.put("wt", "json");
                        String response = null;
                        try {
                                response = rc.get(SchemeType.HTTP, "50.116.10.120", 8984, "solr/demo/select", params);
                        } catch (HttpHostConnectException e) {
                                throw new ProfitMandiBusinessException("", "", "Could not connect to host");
                        }
                        JSONObject solrResponseJSONObj = new JSONObject(response).getJSONObject("response");
                        JSONArray docs = solrResponseJSONObj.getJSONArray("docs");
                        dealResponse = getCatalogResponse(docs, hotDeal);
                        /*
                         * if (Mongo.PARTNER_BLoCKED_BRANDS.containsKey(userInfo.getEmail())) {
                         * dealResponse.stream() .filter(x ->
                         * Mongo.PARTNER_BLoCKED_BRANDS.get(userInfo.getEmail()).contains(x.getBrand()))
                         * ; }
                         */
                } else {
                        return responseSender.badRequest(
                                        new ProfitMandiBusinessException("Retailer id", userInfo.getUserId(), "NOT_FOFO_RETAILER"));
                }
                return responseSender.ok(dealResponse);
        }

        @RequestMapping(value = "/store/entity/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        @ApiImplicitParams({
                        @ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header") })
        @ApiOperation(value = "Get unit deal object")
        public ResponseEntity<?> getUnitFocoDeal(HttpServletRequest request, @PathVariable(value = "id") long id)
                        throws ProfitMandiBusinessException {
                List<FofoCatalogResponse> dealResponse = new ArrayList<>();
                List<Integer> tagIds = Arrays.asList(4);
                UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                if (roleManagerService.isPartner(userInfo.getRoleIds())) {
                        String categoryId = "(3 OR 6)";

                        RestClient rc = new RestClient();
                        Map<String, String> params = new HashMap<>();
                        List<String> mandatoryQ = new ArrayList<>();
                        String catalogString = "catalog" + id;

                        mandatoryQ.add(String.format("+(categoryId_i:%s) +(id:%s) +{!parent which=\"id:%s\"} tagId_i:(%s)",
                                        categoryId, catalogString, catalogString, StringUtils.join(tagIds, " ")));

                        params.put("q", StringUtils.join(mandatoryQ, " "));
                        params.put("fl", "*, [child parentFilter=id:catalog*]");
                        params.put("sort", "rank_i asc, create_s desc");
                        params.put("wt", "json");
                        String response = null;
                        try {
                                response = rc.get(SchemeType.HTTP, "50.116.10.120", 8984, "solr/demo/select", params);
                        } catch (HttpHostConnectException e) {
                                throw new ProfitMandiBusinessException("", "", "Could not connect to host");
                        }
                        JSONObject solrResponseJSONObj = new JSONObject(response).getJSONObject("response");
                        JSONArray docs = solrResponseJSONObj.getJSONArray("docs");
                        dealResponse = getCatalogResponse(docs, false);
                } else {
                        return responseSender.badRequest(
                                        new ProfitMandiBusinessException("Retailer id", userInfo.getUserId(), "NOT_FOFO_RETAILER"));
                }
                return responseSender.ok(dealResponse.get(0));
        }

        private Object toDealObject(JsonObject jsonObject) {
                if (jsonObject.get("dealObject") != null && jsonObject.get("dealObject").asInt() == 1) {
                        return new Gson().fromJson(jsonObject.toString(), DealObjectResponse.class);
                }
                return new Gson().fromJson(jsonObject.toString(), DealsResponse.class);
        }

        @RequestMapping(value = "/store/brands", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        @ApiImplicitParams({
                        @ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header") })
        @ApiOperation(value = "Get brand list and count for category")
        public ResponseEntity<?> getBrands(HttpServletRequest request,
                        @RequestParam(value = "category_id") String category_id) throws ProfitMandiBusinessException {
                logger.info("Request " + request.getParameterMap());
                String response = null;
                // TODO: move to properties
                String uri = ProfitMandiConstants.URL_BRANDS;
                RestClient rc = new RestClient();
                Map<String, String> params = new HashMap<>();
                params.put("category_id", category_id);
                List<DealBrands> dealBrandsResponse = null;
                try {
                        response = rc.get(SchemeType.HTTP, host, port, uri, params);
                } catch (HttpHostConnectException e) {
                        throw new ProfitMandiBusinessException("", "", "Could not connect to host");
                }

                dealBrandsResponse = new Gson().fromJson(response, new TypeToken<List<DealBrands>>() {
                }.getType());

                return responseSender.ok(dealBrandsResponse);
        }

        @RequestMapping(value = "/store/listing/{listingUrl}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> bestSellers(HttpServletRequest request, @PathVariable String listingUrl) throws Exception {
                List<FofoCatalogResponse> dealResponse = new ArrayList<>();
                // UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                // UserCart uc = userAccountRepository.getUserCart(userInfo.getUserId());
                List<Integer> tagIds = Arrays.asList(4);

                WebListing webListing = webListingRepository.selectByUrl("url");
                if (webListing == null) {
                        throw new ProfitMandiBusinessException("Url", listingUrl, "Could not find the Url");
                }
                List<Integer> webProducts = webProductListingRepository.selectAllByWebListingId(webListing.getId()).stream()
                                .filter(x -> x.getRank() > 0).map(x -> x.getEntityId()).collect(Collectors.toList());

                RestClient rc = new RestClient();
                Map<String, String> params = new HashMap<>();
                List<String> mandatoryQ = new ArrayList<>();
                mandatoryQ.add(String.format(
                                "+{!parent which=\"catalogId_i:" + StringUtils.join(webProducts, " ") + "\"} tagId_i:(%s)",
                                StringUtils.join(tagIds, " ")));
                params.put("q", StringUtils.join(mandatoryQ, " "));
                params.put("fl", "*, [child parentFilter=id:catalog*]");
                // params.put("sort", "create_s desc");
                params.put("start", String.valueOf(0));
                params.put("rows", String.valueOf(30));
                params.put("wt", "json");
                String response = null;
                try {
                        response = rc.get(SchemeType.HTTP, "50.116.10.120", 8984, "solr/demo/select", params);
                } catch (HttpHostConnectException e) {
                        throw new ProfitMandiBusinessException("", "", "Could not connect to host");
                }
                JSONObject solrResponseJSONObj = new JSONObject(response).getJSONObject("response");
                JSONArray docs = solrResponseJSONObj.getJSONArray("docs");
                final Ordering<Integer> rankOrdering = Ordering.explicit(webProducts);
                dealResponse = getCatalogResponse(docs, false).stream().sorted(new Comparator<FofoCatalogResponse>() {
                        @Override
                        public int compare(FofoCatalogResponse o1, FofoCatalogResponse o2) {
                                return rankOrdering.compare(o1.getCatalogId(), o2.getCatalogId());
                        }
                }).collect(Collectors.toList());
                webListing.setFofoCatalogResponses(dealResponse);
                return responseSender.ok(webListing);
        }

        @RequestMapping(value = "/store/otp/generateOTP", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> generateOtp(HttpServletRequest request, @RequestParam String mobile) throws Exception {

                return responseSender.ok(otpProcessor.generateOtp(mobile, OtpType.PREBOOKING_ORDER));

        }

        @RequestMapping(value = "/store/login/{mobile}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> checkRegistrationUsingMobile(HttpServletRequest request, @PathVariable String mobile) throws Exception {
                try {
                        Customer customer = customerRepository.selectByMobileNumber(mobile);
                        customer.setPasswordExist(StringUtils.isNotEmpty(customer.getPassword()));
                        return responseSender.ok(new CustomerModel(true, customer));
                } catch (Exception e) {
                        return responseSender.ok(new CustomerModel(false, null));
                }
        }

        @RequestMapping(value = "/store/confirmOrder", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> confirmCart(HttpServletRequest request,
                        @RequestBody CreatePendingOrderRequest createPendingOrderRequest) throws Exception {
                UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                Integer storeId = userInfo.getRetailerId();
                createPendingOrderRequest.setFofoId(storeId);
                this.pendingOrderService.createPendingOrder(createPendingOrderRequest);
                return responseSender.ok(true);

        }

        @RequestMapping(value = "/store/address", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        @ApiImplicitParams({
                        @ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header") })
        @ApiOperation(value = "Get brand list and count for category")
        public ResponseEntity<?> getAddress(HttpServletRequest request) throws Exception {
                UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                Integer storeId = userInfo.getRetailerId();
                CustomRetailer customRetailer = retailerService.getFofoRetailer(storeId);

                return responseSender.ok(customRetailer.getAddress());

        }

        @RequestMapping(value = "/store/address/{pincode}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        @ApiImplicitParams({
                        @ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header") })
        @ApiOperation(value = "Get brand list and count for category")
        public ResponseEntity<?> getStoresByPincode(HttpServletRequest request, @PathVariable String pincode)
                        throws Exception {
                List<PincodePartner> pincodePartners = pincodePartnerRepository.selectPartnersByPincode(pincode);
                int fofoId = DEFAULT_STORE;
                if (pincodePartners.size() > 0) {
                        fofoId = pincodePartners.get(0).getFofoId();
                }
                return responseSender.ok(fofoStoreRepository.selectByRetailerId(fofoId).getCode());
        }

        @RequestMapping(value = "/store/listing", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        @Cacheable(value = "storelisting.all", cacheManager = "thirtyMinsTimeOutCacheManager")
        public ResponseEntity<?> getStoresListing(HttpServletRequest request) throws Exception {
                List<WebListing> webListings = webListingRepository.selectAllWebListing(Optional.of(true));
                for (WebListing webListing : webListings) {
                        List<Integer> webProducts = webProductListingRepository.selectAllByWebListingId(webListing.getId()).stream()
                                        .filter(x -> x.getRank() > 0).map(x -> x.getEntityId()).collect(Collectors.toList());

                        RestClient rc = new RestClient();
                        Map<String, String> params = new HashMap<>();
                        List<String> mandatoryQ = new ArrayList<>();
                        mandatoryQ.add(String.format(
                                        "+{!parent which=\"catalogId_i:" + StringUtils.join(webProducts, " ") + "\"} tagId_i:(%s)",
                                        StringUtils.join(TAG_IDS, " ")));
                        params.put("q", StringUtils.join(mandatoryQ, " "));
                        params.put("fl", "*, [child parentFilter=id:catalog*]");
                        // params.put("sort", "create_s desc");
                        params.put("start", String.valueOf(0));
                        params.put("rows", String.valueOf(30));
                        params.put("wt", "json");
                        String response = null;
                        try {
                                response = rc.get(SchemeType.HTTP, "50.116.10.120", 8984, "solr/demo/select", params);
                        } catch (HttpHostConnectException e) {
                                throw new ProfitMandiBusinessException("", "", "Could not connect to host");
                        }
                        JSONObject solrResponseJSONObj = new JSONObject(response).getJSONObject("response");
                        JSONArray docs = solrResponseJSONObj.getJSONArray("docs");
                        final Ordering<Integer> colorOrdering = Ordering.explicit(webProducts);
                        List<FofoCatalogResponse> dealResponse = getCatalogResponse(docs, false).stream()
                                        .sorted(new Comparator<FofoCatalogResponse>() {
                                                @Override
                                                public int compare(FofoCatalogResponse o1, FofoCatalogResponse o2) {
                                                        return colorOrdering.compare(o1.getCatalogId(), o2.getCatalogId());
                                                }
                                        }).collect(Collectors.toList());
                        webListing.setFofoCatalogResponses(dealResponse);
                }
                return responseSender.ok(webListings);
        }

        @RequestMapping(value = "/store/cart", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        @ApiImplicitParams({
                        @ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header") })
        @ApiOperation(value = "Get brand list and count for category")
        public ResponseEntity<?> cart(HttpServletRequest request, @RequestBody AddCartRequest cartRequest)
                        throws Exception {
                CartResponse cartResponse = new CartResponse();
                List<CartItemResponseModel> cartItemResponseModels = new ArrayList<>();
                cartResponse.setCartItems(cartItemResponseModels);

                UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                Integer storeId = userInfo.getRetailerId();
                List<Integer> itemIds = cartRequest.getCartItems().stream().map(x -> x.getItemId())
                                .collect(Collectors.toList());
                Set<Integer> itemsIdsSet = new HashSet<>(itemIds);
                logger.info("Store Id {}, Item Ids {}", storeId, itemsIdsSet);
                List<CurrentInventorySnapshot> currentInventorySnapshot = currentInventorySnapshotRepository
                                .selectByFofoItemIds(storeId, itemsIdsSet);
                Map<Integer, Integer> storeItemAvailabilityMap = currentInventorySnapshot.stream()
                                .filter(x -> x.getAvailability() > 0)
                                .collect(Collectors.toMap(x -> x.getItemId(), x -> x.getAvailability()));

                Map<Integer, Item> itemsMap = itemRepository.selectByIds(itemsIdsSet).stream()
                                .collect(Collectors.toMap(x -> x.getId(), x -> x));

                Map<Integer, TagListing> sdItemAvailabilityMap = tagListingRepository
                                .selectByItemIdsAndTagIds(new HashSet<>(itemIds), new HashSet<>(Arrays.asList(4))).stream()
                                .collect(Collectors.toMap(x -> x.getItemId(), x -> x));

                List<Integer> catalogIds = itemsMap.values().stream().map(x -> x.getCatalogItemId())
                                .collect(Collectors.toList());

                Map<Integer, JSONObject> contentMap = commonSolrService.getContentByCatalogIds(catalogIds);

                // cartResponse.getCartItems()
                for (CartItem cartItem : cartRequest.getCartItems()) {
                        if (cartItem.getQuantity() == 0) {
                                continue;
                        }
                        Item item = itemsMap.get(cartItem.getItemId());
                        TagListing tagListing = sdItemAvailabilityMap.get(cartItem.getItemId());
                        CartItemResponseModel cartItemResponseModel = new CartItemResponseModel();
                        int estimate = -2;
                        if (storeItemAvailabilityMap.containsKey(cartItem.getItemId())) {
                                if (storeItemAvailabilityMap.get(cartItem.getItemId()) >= cartItem.getQuantity()) {
                                        estimate = 0;
                                } else if (tagListing.isActive()) {
                                        estimate = 2;
                                } else {
                                        estimate = -2;
                                }
                        } else if (tagListing.isActive()) {
                                estimate = 2;
                        } else {
                                estimate = -2;
                        }
                        if (estimate >= 0 && LocalTime.now().isAfter(CUTOFF_TIME)) {
                                estimate = estimate + 1;
                        }
                        cartItemResponseModel.setEstimate(estimate);
                        cartItemResponseModel.setTitle(item.getItemDescriptionNoColor());
                        cartItemResponseModel.setItemId(cartItem.getItemId());
                        cartItemResponseModel.setMinBuyQuantity(1);
                        cartItemResponseModel.setQuantity(cartItem.getQuantity());
                        cartItemResponseModel.setQuantityStep(1);
                        Float cashback = schemeService.getItemSchemeCashBack().get(cartItem.getItemId());
                        cashback = cashback == null ? 0 : cashback;
                        cartItemResponseModel.setSellingPrice(tagListing.getMop() - cashback);
                        cartItemResponseModel.setMaxQuantity(2);
                        cartItemResponseModel.setCatalogItemId(item.getCatalogItemId());
                        cartItemResponseModel.setImageUrl(contentMap.get(item.getCatalogItemId()).getString("imageUrl_s"));
                        cartItemResponseModel.setColor(item.getColor());
                        cartItemResponseModels.add(cartItemResponseModel);
                }
                ValidateCartResponse vc = new ValidateCartResponse(cartResponse, "Success", "Items added to cart successfully");
                return responseSender.ok(vc);
        }

        private boolean validateCart(int storeId, List<CartItem> cartItems) {
                return false;
        }

        private List<FofoCatalogResponse> getCatalogResponse(JSONArray docs, boolean hotDeal)
                        throws ProfitMandiBusinessException {
                Map<Integer, Float> itemCashbackMap = schemeService.getItemSchemeCashBack();
                Map<Integer, TagListing> itemTagListingMap = null;
                List<FofoCatalogResponse> dealResponse = new ArrayList<>();
                List<Integer> tagIds = Arrays.asList(4);
                if (docs.length() > 0) {
                        HashSet<Integer> itemsSet = new HashSet<>();
                        for (int i = 0; i < docs.length(); i++) {
                                JSONObject doc = docs.getJSONObject(i);
                                if (doc.has("_childDocuments_")) {
                                        for (int j = 0; j < doc.getJSONArray("_childDocuments_").length(); j++) {
                                                JSONObject childItem = doc.getJSONArray("_childDocuments_").getJSONObject(j);
                                                int itemId = childItem.getInt("itemId_i");
                                                itemsSet.add(itemId);
                                        }
                                }
                        }
                        if (itemsSet.size() == 0) {
                                return dealResponse;
                        }
                        itemTagListingMap = tagListingRepository.selectByItemIdsAndTagIds(itemsSet, new HashSet<>(tagIds)).stream()
                                        .collect(Collectors.toMap(x -> x.getItemId(), x -> x));
                }

                for (int i = 0; i < docs.length(); i++) {
                        Map<Integer, FofoAvailabilityInfo> fofoAvailabilityInfoMap = new HashMap<>();
                        JSONObject doc = docs.getJSONObject(i);
                        FofoCatalogResponse ffdr = new FofoCatalogResponse();
                        ffdr.setCatalogId(doc.getInt("catalogId_i"));
                        ffdr.setImageUrl(doc.getString("imageUrl_s"));
                        ffdr.setTitle(doc.getString("title_s"));
                        try {
                                ffdr.setFeature(doc.getString("feature_s"));
                        } catch (Exception e) {
                                ffdr.setFeature(null);
                                logger.info("Could not find Feature_s for {}", ffdr.getCatalogId());
                        }
                        ffdr.setBrand(doc.getJSONArray("brand_ss").getString(0));
                        if (doc.has("_childDocuments_")) {
                                for (int j = 0; j < doc.getJSONArray("_childDocuments_").length(); j++) {
                                        JSONObject childItem = doc.getJSONArray("_childDocuments_").getJSONObject(j);
                                        int itemId = childItem.getInt("itemId_i");
                                        TagListing tl = itemTagListingMap.get(itemId);
                                        if (tl == null) {
                                                logger.warn("Could not find item id {}", itemId);
                                                continue;
                                        }
                                        if (hotDeal) {
                                                if (!tl.isHotDeals()) {
                                                        continue;
                                                }
                                        }
                                        float sellingPrice = (float) childItem.getDouble("sellingPrice_f");
                                        if (fofoAvailabilityInfoMap.containsKey(itemId)) {
                                                if (fofoAvailabilityInfoMap.get(itemId).getSellingPrice() > sellingPrice) {
                                                        fofoAvailabilityInfoMap.get(itemId).setSellingPrice(sellingPrice);
                                                        fofoAvailabilityInfoMap.get(itemId).setMop((float) childItem.getDouble("mop_f"));
                                                }
                                        } else {
                                                FofoAvailabilityInfo fdi = new FofoAvailabilityInfo();
                                                fdi.setCashback(itemCashbackMap.get(itemId) == null ? 0 : itemCashbackMap.get(itemId));
                                                fdi.setSellingPrice((float) childItem.getDouble("sellingPrice_f"));
                                                fdi.setMop((float) childItem.getDouble("mop_f"));
                                                fdi.setColor(childItem.has("color_s") ? childItem.getString("color_s") : "");
                                                fdi.setTagId(childItem.getInt("tagId_i"));
                                                fdi.setItem_id(itemId);
                                                fdi.setMrp(tl.getMrp());
                                                // In case its tampered glass moq should be 5
                                                fdi.setMinBuyQuantity(1);
                                                if (hotDeal || !tl.isActive()) {

                                                        int totalAvailability = 0; // Using item availability
                                                        // cache for now but can be
                                                        // changed to
                                                        // use caching later.
                                                        try {
                                                                ItemAvailabilityCache iac = itemAvailabilityCacheRepository.selectByItemId(itemId);
                                                                totalAvailability = iac.getTotalAvailability();
                                                                fdi.setAvailability(totalAvailability);
                                                        } catch (Exception e) {
                                                                continue;
                                                        }
                                                        if (totalAvailability <= 0) {
                                                                continue;
                                                        }
                                                } else {
                                                        // For accessories item availability should at be ordered for Rs.1000
                                                        fdi.setAvailability(2);
                                                }
                                                fdi.setQuantityStep(1);
                                                fdi.setMaxQuantity(Math.min(fdi.getAvailability(), 2));
                                                fofoAvailabilityInfoMap.put(itemId, fdi);
                                        }
                                }
                        }
                        if (fofoAvailabilityInfoMap.values().size() > 0) {
                                ffdr.setItems(new ArrayList<FofoAvailabilityInfo>(fofoAvailabilityInfoMap.values()));
                                dealResponse.add(ffdr);
                        }
                }
                return dealResponse;
        }

}

class CustomerModel {

        @JsonProperty(required = false)
        private Customer customer;
        @JsonProperty(required = true)
        private boolean exists;

        public CustomerModel(boolean exists, Customer customer) {
                super();
                this.customer = customer;
                this.exists = exists;
        }

        @Override
        public String toString() {
                return "CustomerModel [customer=" + customer + ", exists=" + exists + "]";
        }

        public Customer getCustomer() {
                return customer;
        }

        public void setCustomer(Customer customer) {
                this.customer = customer;
        }

        public boolean isExists() {
                return exists;
        }

        public void setExists(boolean exists) {
                this.exists = exists;
        }
}