Subversion Repositories SmartDukaan

Rev

Rev 30426 | Rev 31203 | 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 com.eclipsesource.json.JsonObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.spice.profitmandi.common.enumuration.MessageType;
import com.spice.profitmandi.common.enumuration.SchemeType;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.*;
import com.spice.profitmandi.common.solr.SolrService;
import com.spice.profitmandi.common.util.FormattingUtils;
import com.spice.profitmandi.common.util.PdfUtils;
import com.spice.profitmandi.common.util.Utils;
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.ScratchOffer;
import com.spice.profitmandi.dao.entity.dtr.User;
import com.spice.profitmandi.dao.entity.dtr.WebListing;
import com.spice.profitmandi.dao.entity.dtr.WebOffer;
import com.spice.profitmandi.dao.entity.fofo.*;
import com.spice.profitmandi.dao.enumuration.dtr.OtpType;
import com.spice.profitmandi.dao.enumuration.inventory.ScratchedGift;
import com.spice.profitmandi.dao.enumuration.transaction.OrderStatus;
import com.spice.profitmandi.dao.model.*;
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
import com.spice.profitmandi.dao.repository.cs.CsService;
import com.spice.profitmandi.dao.repository.dtr.*;
import com.spice.profitmandi.dao.repository.fofo.*;
import com.spice.profitmandi.dao.repository.inventory.ItemAvailabilityCacheRepository;
import com.spice.profitmandi.dao.repository.user.UserRepository;
import com.spice.profitmandi.service.CustomerService;
import com.spice.profitmandi.service.EmailService;
import com.spice.profitmandi.service.NotificationService;
import com.spice.profitmandi.service.authentication.RoleManager;
import com.spice.profitmandi.service.inventory.*;
import com.spice.profitmandi.service.order.OrderService;
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 com.spice.profitmandi.web.services.PartnerIndexService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
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.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
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.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@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);

        @Autowired
        CustomerAddressRepository customerAddressRepository;

        @Autowired
        WebOfferRepository webOfferRepository;

        @Value("${new.solr.url}")
        private String solrUrl;

        @Autowired
        private PartnerIndexService partnerIndexService;

        @Autowired
        InventoryService inventoryService;

        @Autowired
        UserAccountRepository userAccountRepository;

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

        @Autowired
        CustomerService customerService;

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

        @Autowired
        private SaholicInventoryService saholicInventoryService;

        @Autowired
        private PincodePartnerRepository pincodePartnerRepository;

        @Autowired
        private FofoStoreRepository fofoStoreRepository;

        @Autowired
        private RetailerService retailerService;

        @Autowired
        private PendingOrderRepository pendingOrderRepository;

        @Autowired
        private PendingOrderItemRepository pendingOrderItemRepository;

        @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 UserRepository userRepository;

        @Autowired
        private ItemAvailabilityCacheRepository itemAvailabilityCacheRepository;

        @Autowired
        private WebListingRepository webListingRepository;

        @Autowired
        private WebProductListingRepository webProductListingRepository;

        @Autowired
        private RoleManager roleManagerService;

        @Autowired
        EmailService emailService;

        @Autowired
        CsService csService;

        @Autowired
        private NotificationService notificationService;

        @Autowired
        private com.spice.profitmandi.dao.repository.dtr.UserRepository dtrUserRepository;

        @Autowired
        private FofoOrderRepository fofoOrderRepository;

        @Autowired
        private FofoOrderItemRepository fofoOrderItemRepository;

        @Autowired
        private OrderService orderService;

        @Autowired
        private ScratchOfferRepository scratchOfferRepository;
        private static final List<String> offlineOrders = Arrays.asList("EMIOD", "POD");

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

        @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> dealResponses = new ArrayList<>();
                List<Integer> tagIds = Arrays.asList(4);
                FofoCatalogResponse fofoCatalogResponse = null;
                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, solrUrl, 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");
                        dealResponses = getCatalogResponse(docs, false, userInfo.getRetailerId());
                        fofoCatalogResponse = dealResponses.get(0);
                        fofoCatalogResponse
                                        .setWebOffers(webOfferRepository.selectAllActiveOffers().get(fofoCatalogResponse.getCatalogId()));

                } else {
                        return responseSender.badRequest(
                                        new ProfitMandiBusinessException("Retailer id", userInfo.getUserId(), "NOT_FOFO_RETAILER"));
                }
                return responseSender.ok(dealResponses.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 {
                UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                WebListing webListing = webListingRepository.selectByUrl(listingUrl);
                webListing.setFofoCatalogResponses(getDealResponses(userInfo, webListing));
                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.REGISTRATION));

        }

        @RequestMapping(value = "/store/checkmobile/{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/signin", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> signIn(HttpServletRequest request, @RequestBody UserModel userModel) throws Exception {
                if (customerService.authenticate(userModel.getMobile(), userModel.getPassword())) {
                        return responseSender.ok(true);
                } else {
                        return responseSender.ok(false);
                }
        }

        @RequestMapping(value = "/store/resetPassword", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> resetPassword(HttpServletRequest request, @RequestBody UserModel userModel)
                        throws Exception {
                customerService.changePassword(userModel.getMobile(), userModel.getPassword());
                return responseSender.ok(true);
        }

        @RequestMapping(value = "/store/register", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> register(HttpServletRequest request, @RequestBody UserModel userModel) throws Exception {
                Customer customer = new Customer();
                customer.setPassword(userModel.getPassword());
                customer.setEmailId(userModel.getEmail());
                customer.setFirstName(userModel.getFirstName());
                customer.setLastName(userModel.getLastName());
                customer.setMobileNumber(userModel.getMobile());
                return responseSender.ok(customerService.addCustomer(customer));
        }

        @RequestMapping(value = "/store/confirmOrder", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> confirmOrder(HttpServletRequest request,
                        @RequestBody CreatePendingOrderRequest createPendingOrderRequest) throws Exception {
                UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                Integer storeId = userInfo.getRetailerId();
                createPendingOrderRequest.setFofoId(storeId);
                List<CreatePendingOrderItem> pendingOrderItems = createPendingOrderRequest.getCreatePendingOrderItem();
                List<CartItem> cartItems = new ArrayList<>();
                pendingOrderItems.stream().forEach(x -> {
                        CartItem ci = new CartItem();
                        ci.setItemId(x.getItemId());
                        ci.setQuantity(x.getQuantity());
                        ci.setSellingPrice(x.getSellingPrice());
                        cartItems.add(ci);
                });
                CartResponse cr = this.validateCart(storeId, cartItems);
                if (cr.getCartMessageChanged() > 0 || cr.getTotalAmount() != createPendingOrderRequest.getTotalAmount()) {
                        return responseSender.badRequest("Invalid request");
                }

                Map<String, String> returnMap = this.pendingOrderService.createPendingOrder(createPendingOrderRequest, cr);

                PendingOrder pendingOrder = pendingOrderRepository.selectById(Integer.parseInt(returnMap.get("poId")));
                if (offlineOrders.contains(pendingOrder.getPayMethod())) {

                        Map<String, Object> emailModel = pendingOrderService.sendCreateOrderMail(pendingOrder);

                        CustomRetailer customRetailer = retailerService.getFofoRetailer(pendingOrder.getFofoId());
                        Customer customer = customerRepository.selectById(pendingOrder.getCustomerId());
                        String[] customerEmail = null;
                        if (Utils.validateEmail(customer.getEmailId())) {
                                customerEmail = new String[] { customer.getEmailId() };
                        }

                        List<String> bccTo = Arrays.asList("kamini.sharma@smartdukaan.com", "tarun.verma@smartdukaan.com",
                                        "niranjan.kala@smartdukaan.com", "sm@smartdukaan.com", "tejbeer.kaur@shop2020.in",
                                        "devkinandan.lal@smartdukaan.com", customRetailer.getEmail());

                        List<String> authUserEmails = csService.getAuthUserByPartnerId(customRetailer.getPartnerId());
                        if (authUserEmails != null) {
                                authUserEmails = new ArrayList<>();
                        }
                        logger.info("authUserEmails {}", authUserEmails);
                        authUserEmails.addAll(bccTo);
                        StringBuffer itemBuffer = new StringBuffer();
                        List<PendingOrderItem> orderItems = pendingOrderItemRepository.selectByOrderId(pendingOrder.getId());
                        int totalItems = 0;
                        String itemNoColor = null;
                        float maxValue = 0;
                        for (PendingOrderItem orderItem : orderItems) {
                                if (maxValue < orderItem.getSellingPrice()) {
                                        maxValue = orderItem.getSellingPrice();
                                        itemNoColor = itemRepository.selectById(orderItem.getItemId()).getItemDescriptionNoColor();
                                }
                                totalItems += orderItem.getQuantity();
                        }
                        if (totalItems > 1) {
                                itemBuffer.append(StringUtils.abbreviate(itemNoColor, 22));
                                itemBuffer.append(" +").append(totalItems - 1).append(" items");
                        } else {
                                itemBuffer.append(StringUtils.abbreviate(itemNoColor, 30));
                        }
                        String message = String.format(OtpProcessor.TEMPLATE_ORDER_CREATED, pendingOrder.getId(),
                                        itemBuffer.toString(), pendingOrder.getTotalAmount());
                        otpProcessor.sendSms(OtpProcessor.TEMPLATE_ORDER_CREATED_ID, message, customer.getMobileNumber());

                        emailService.sendMailWithAttachments("Order Created with SmartDukaan", "order-confirm.vm", emailModel,
                                        customerEmail, null, bccTo.toArray(new String[0]));

                        List<String> emailIds = csService.getAuthUserIdByPartnerId(customRetailer.getPartnerId()).stream()
                                        .map(x -> x.getEmailId()).collect(Collectors.toList());
                        emailIds.add("tarun.verma@smartdukaan.com");
                        emailIds.add("devkinandan.lal@smartdukaan.com");
                        emailIds.add("tejbeer.kaur@shop2020.in");
                        List<User> user = dtrUserRepository.selectAllByEmailIds(emailIds);
                        List<Integer> userIds = user.stream().map(x -> x.getId()).collect(Collectors.toList());

                        logger.info("userIds" + userIds);
                        SendNotificationModel sendNotificationModel = new SendNotificationModel();
                        sendNotificationModel.setCampaignName("Online Order Alert");
                        sendNotificationModel.setTitle("Online Order Update");
                        sendNotificationModel.setMessage(String.format(
                                        "You have new Online Order. Please check your Dashboard. In case of an activation scheme pls ensure the handset is activated, payout will be processed as per brand's activation report."));
                        sendNotificationModel.setType("url");
                        sendNotificationModel.setUrl("https://app.smartdukaan.com/pages/home/notifications");
                        sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(1));
                        sendNotificationModel.setMessageType(MessageType.notification);
                        int userId = userAccountRepository.selectUserIdByRetailerId(pendingOrder.getFofoId());
                        sendNotificationModel.setUserIds(Arrays.asList(userId));
                        notificationService.sendNotification(sendNotificationModel);

                        SendNotificationModel snm = new SendNotificationModel();
                        snm.setCampaignName("Online Order Alert");
                        snm.setTitle("Online Order Update");
                        snm.setMessage(String.format("Your Partner " + customRetailer.getBusinessName()
                                        + " have new Online Order. Please inform your partner. In case of an activation scheme pls ensure the handset is activated, payout will be processed as per brand's activation report."));
                        snm.setType("url");
                        snm.setUrl("https://app.smartdukaan.com/pages/home/notifications");
                        snm.setExpiresat(LocalDateTime.now().plusDays(1));
                        snm.setMessageType(MessageType.notification);
                        snm.setUserIds(userIds);
                        notificationService.sendNotification(snm);

                }
                return responseSender.ok(returnMap);

        }

        @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 = ProfitMandiConstants.DEFAULT_STORE;
                if (pincodePartners.size() > 0) {
                        List<Integer> fofoIds = pincodePartners.stream().map(x -> x.getFofoId()).collect(Collectors.toList());
                        List<FofoStore> fofoStores = fofoStoreRepository.selectActivePartnersByRetailerIds(fofoIds);
                        if (fofoStores.size() > 0) {
                                fofoId = fofoStores.get(0).getId();
                        }

                }
                return responseSender.ok(fofoStoreRepository.selectByRetailerId(fofoId).getCode());
        }

        @RequestMapping(value = "/store/addresses", 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<?> getStoresByPincod(HttpServletRequest request, @RequestParam String pincode,
                        @RequestParam(name = "fofoCode", defaultValue = "", required = false) String fofoCode) throws Exception {

                List<CustomRetailer> customerRetailers = new ArrayList<>();

                logger.info("fofoCode" + fofoCode);

                if (fofoCode != null) {
                        FofoStore fs = fofoStoreRepository.selectByStoreCode(fofoCode.toUpperCase());
                        PincodePartner pp = pincodePartnerRepository.selectPartnerByPincode(pincode, fs.getId());
                        if (pp != null) {
                                return responseSender.ok(customerRetailers.add(retailerService.getFofoRetailer(pp.getFofoId())));
                        } else {

                                List<PincodePartner> pincodePartners = pincodePartnerRepository.selectPartnersByPincode(pincode);
                                if (pincodePartners.size() > 0) {

                                        List<Integer> fofoIds = pincodePartners.stream().map(x -> x.getFofoId())
                                                        .collect(Collectors.toList());
                                        List<Integer> activefofoIds = fofoStoreRepository.selectByRetailerIds(fofoIds).stream()
                                                        .filter(x -> x.isActive()).map(x -> x.getId()).collect(Collectors.toList());

                                        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();

                                        Map<Integer, CustomRetailer> customerRetailerMap = activefofoIds.stream()
                                                        .map(x -> customRetailerMap.get(x)).filter(x -> x != null).collect(Collectors.toList())
                                                        .stream().collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));

                                        customerRetailers.addAll(customerRetailerMap.values());

                                }
                                return responseSender.ok(customerRetailers);

                        }
                } else {

                        List<PincodePartner> pincodePartners = pincodePartnerRepository.selectPartnersByPincode(pincode);
                        if (pincodePartners.size() > 0) {
                                List<Integer> fofoIds = pincodePartners.stream().map(x -> x.getFofoId()).collect(Collectors.toList());
                                List<Integer> activefofoIds = fofoStoreRepository.selectByRetailerIds(fofoIds).stream()
                                                .filter(x -> x.isActive()).map(x -> x.getId()).collect(Collectors.toList());

                                Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();

                                Map<Integer, CustomRetailer> customerRetailerMap = activefofoIds.stream()
                                                .map(x -> customRetailerMap.get(x)).filter(x -> x != null).collect(Collectors.toList()).stream()
                                                .collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));

                                customerRetailers.addAll(customerRetailerMap.values());
                        }

                        return responseSender.ok(customerRetailers);

                }

        }

        @RequestMapping(value = "/store/address/detail/{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<?> getStoresDetailsByPincode(HttpServletRequest request, @PathVariable String pincode)
                        throws Exception {
                List<CustomRetailer> customerRetailers = new ArrayList<>();
                List<PincodePartner> pincodePartners = pincodePartnerRepository.selectPartnersByPincode(pincode);

                if (!pincodePartners.isEmpty()) {
                        List<Integer> fofoIds = pincodePartners.stream().map(x -> x.getFofoId()).collect(Collectors.toList());
                        List<Integer> activefofoIds = fofoStoreRepository.selectByRetailerIds(fofoIds).stream()
                                        .filter(x -> x.isActive()).map(x -> x.getId()).collect(Collectors.toList());

                        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();

                        Map<Integer, CustomRetailer> customerRetailerMap = activefofoIds.stream().map(x -> customRetailerMap.get(x))
                                        .filter(x -> x != null).collect(Collectors.toList()).stream()
                                        .collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));

                        customerRetailers.addAll(customerRetailerMap.values());
                }

                logger.info("customerRetailers" + customerRetailers);
                return responseSender.ok(customerRetailers);
        }

        @RequestMapping(value = "/store/order", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> getOrderDetail(HttpServletRequest request, @RequestParam(value = "id") int id,
                        @RequestParam(name = "offset") int offset, @RequestParam(name = "limit") int limit) throws Exception {
                List<CustomerOrderDetail> customerOrderDetails = new ArrayList<>();
                List<Integer> catalogIds = new ArrayList<>();
                List<PendingOrder> pendingOrders = pendingOrderRepository.selectByCustomerId(id, offset, limit);

                if (!pendingOrders.isEmpty()) {
                        for (PendingOrder po : pendingOrders) {
                                List<PendingOrderItem> pois = pendingOrderItemRepository.selectByOrderId(po.getId());
                                for (PendingOrderItem pendingOrderItem : pois) {
                                        Item item = itemRepository.selectById(pendingOrderItem.getItemId());
                                        pendingOrderItem.setItemName(item.getItemDescription());
                                        catalogIds.add(item.getCatalogItemId());
                                }

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

                                for (PendingOrderItem poi : pois) {

                                        CustomerOrderDetail customerOrderDetail = new CustomerOrderDetail();

                                        Item item = itemRepository.selectById(poi.getItemId());
                                        JSONObject jsonObj = contentMap.get(item.getCatalogItemId());
                                        customerOrderDetail.setImageUrl(jsonObj.getString("imageUrl_s"));
                                        customerOrderDetail.setBrand(item.getBrand());
                                        customerOrderDetail.setColor(item.getColor());
                                        customerOrderDetail.setPendingOrderItemId(poi.getId());
                                        customerOrderDetail.setId(poi.getOrderId());
                                        customerOrderDetail.setItemId(poi.getItemId());
                                        customerOrderDetail.setModelName(item.getModelName());
                                        customerOrderDetail.setModelNumber(item.getModelNumber());
                                        customerOrderDetail.setQuantity(poi.getQuantity());
                                        customerOrderDetail.setBilledTimestamp(poi.getBilledTimestamp());
                                        customerOrderDetail.setStatus(poi.getStatus());
                                        customerOrderDetail.setTotalPrice(poi.getSellingPrice());
                                        customerOrderDetail.setPayMethod(po.getPayMethod());
                                        customerOrderDetail.setCreatedTimeStamp(po.getCreateTimestamp());
                                        customerOrderDetails.add(customerOrderDetail);
                                }
                        }
                }

                return responseSender.ok(customerOrderDetails);
        }

        @RequestMapping(value = "/store/invoiceOrder", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> getOrderInvoiceDetail(HttpServletRequest request, @RequestParam(value = "id") int id,
                        @RequestParam(name = "offset") int offset, @RequestParam(name = "limit") int limit) throws Exception {
                List<CustomerOrderDetail> customerOrderDetails = new ArrayList<>();
                List<Integer> catalogIds = new ArrayList<>();
                List<FofoOrder> fofoOrders = fofoOrderRepository.selectOrderByCustomerId(id, offset, limit);

                if (!fofoOrders.isEmpty()) {
                        for (FofoOrder fo : fofoOrders) {
                                List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fo.getId());
                                for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
                                        Item item = itemRepository.selectById(fofoOrderItem.getItemId());
                                        fofoOrderItem.setItemName(item.getItemDescription());
                                        catalogIds.add(item.getCatalogItemId());
                                }

                                Map<Integer, JSONObject> contentMap = commonSolrService.getContentByCatalogIds(catalogIds);
                                for (FofoOrderItem foi : fofoOrderItems) {

                                        CustomerOrderDetail customerOrderDetail = new CustomerOrderDetail();

                                        Item item = itemRepository.selectById(foi.getItemId());
                                        JSONObject jsonObj = contentMap.get(item.getCatalogItemId());
                                        customerOrderDetail.setImageUrl(jsonObj.getString("imageUrl_s"));
                                        customerOrderDetail.setBrand(item.getBrand());
                                        customerOrderDetail.setColor(item.getColor());
                                        customerOrderDetail.setFofoOrderItemId(foi.getId());
                                        customerOrderDetail.setFofoOrderId(foi.getOrderId());
                                        customerOrderDetail.setItemId(foi.getItemId());
                                        customerOrderDetail.setModelName(item.getModelName());
                                        customerOrderDetail.setModelNumber(item.getModelNumber());
                                        customerOrderDetail.setQuantity(foi.getQuantity());
                                        customerOrderDetail.setTotalPrice(foi.getSellingPrice());
                                        customerOrderDetail.setCreatedTimeStamp(foi.getCreateTimestamp());
                                        customerOrderDetail.setInvoiceNumber(fo.getInvoiceNumber());
                                        customerOrderDetail.setCancelledTimestamp(fo.getCancelledTimestamp());
                                        customerOrderDetails.add(customerOrderDetail);
                                }
                        }

                }
                return responseSender.ok(customerOrderDetails);
        }

        @RequestMapping(value = "/store/generateInvoice", method = RequestMethod.GET)
        public ResponseEntity<?> generateInvoice(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.ORDER_ID) int orderId) throws ProfitMandiBusinessException {
                InvoicePdfModel pdfModel = null;
                FofoOrder fo = fofoOrderRepository.selectByOrderId(orderId);
                pdfModel = orderService.getInvoicePdfModel(fo.getFofoId(), orderId);
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                PdfUtils.generateAndWrite(Arrays.asList(pdfModel), byteArrayOutputStream);
                try {
                        byteArrayOutputStream.close();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                final HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_PDF);
                // headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");

                headers.setContentType(MediaType.parseMediaType("application/pdf"));
                headers.set("Content-disposition", "inline; filename=invoice-" + pdfModel.getInvoiceNumber() + ".pdf");
                headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
                headers.add("Pragma", "no-cache");
                headers.add("Expires", "0");

                headers.setContentLength(byteArrayOutputStream.toByteArray().length);
                final InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                final InputStreamResource inputStreamResource = new InputStreamResource(inputStream);
                return new ResponseEntity<>(inputStreamResource, headers, HttpStatus.OK);
                // return responseSender.ok(new
                // ResponseEntity<byte[]>(byteArrayOutputStream.toByteArray(),
                // headers,HttpStatus.OK));
                /*
                 * ResponseEntity<byte[]> response = new
                 * ResponseEntity<byte[]>(byteArrayOutputStream.toByteArray(), headers,
                 * HttpStatus.OK); return response;
                 */

        }

        @RequestMapping(value = "/store/listing", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> getStoresListing(HttpServletRequest request) throws Exception {
                List<WebListing> webListings = webListingRepository.selectAllWebListing(Optional.of(true));
                UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                for (WebListing webListing : webListings) {
                        webListing.setFofoCatalogResponses(getDealResponses(userInfo, webListing));
                }
                return responseSender.ok(webListings);
        }

        private List<FofoCatalogResponse> getDealResponses(UserInfo userInfo, WebListing webListing)
                        throws ProfitMandiBusinessException {
                List<Integer> webProducts = webProductListingRepository.selectAllByWebListingId(webListing.getId()).stream()
                                .filter(x -> x.getRank() > 0).map(x -> x.getEntityId()).collect(Collectors.toList());
                if (webProducts.size() == 0) {
                        return new ArrayList<>();
                }
                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(100));
                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");
                List<FofoCatalogResponse> dealResponse = getCatalogResponse(docs, false, userInfo.getRetailerId());
                return dealResponse;
        }

        @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 {
                UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                Integer storeId = userInfo.getRetailerId();
                ValidateCartResponse vc = new ValidateCartResponse(this.validateCart(storeId, cartRequest.getCartItems()),
                                "Success", "Items added to cart successfully");
                return responseSender.ok(vc);
        }

        // Validate Cart for B2C Customers
        private CartResponse validateCart(int storeId, List<CartItem> cartItems) throws Exception {
                cartItems = cartItems.stream().filter(x -> x.getQuantity() > 0).collect(Collectors.toList());
                List<Integer> itemIds = cartItems.stream().map(x -> x.getItemId()).collect(Collectors.toList());
                Map<Integer, AvailabilityModel> inventoryItemAvailabilityMap = inventoryService.getStoreAndOurStock(storeId,
                                itemIds);
                CartResponse cartResponse = new CartResponse();
                List<CartItemResponseModel> cartItemResponseModels = new ArrayList<>();
                cartResponse.setCartItems(cartItemResponseModels);
                Set<Integer> itemsIdsSet = new HashSet<>(itemIds);
                logger.info("Store Id {}, Item Ids {}", storeId, itemsIdsSet);

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

                Map<Integer, TagListing> tagListingMap = 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()
                int cartMessageChanged = 0;
                int cartMessageOOS = 0;
                int totalAmount = 0;
                int totalQty = 0;
                for (CartItem cartItem : cartItems) {
                        Item item = itemsMap.get(cartItem.getItemId());
                        TagListing tagListing = tagListingMap.get(cartItem.getItemId());
                        Float cashback = schemeService.getCatalogSchemeCashBack()
                                        .get(itemsMap.get(cartItem.getItemId()).getCatalogItemId());
                        cashback = cashback == null ? 0 : cashback;
                        float itemSellingPrice = tagListing.getMop() - cashback;
                        CartItemResponseModel cartItemResponseModel = new CartItemResponseModel();
                        cartItemResponseModel.setSellingPrice(cartItem.getSellingPrice());
                        if (itemSellingPrice != cartItem.getSellingPrice()) {
                                cartItemResponseModel.setSellingPrice(itemSellingPrice);
                                cartMessageChanged++;
                        }
                        int estimate = -2;
                        LocalDateTime promiseDeliveryTime = LocalDateTime.now();
                        int qtyRequired = (int) cartItem.getQuantity();
                        AvailabilityModel availabilityModel = inventoryItemAvailabilityMap.get(cartItem.getItemId());
                        cartItemResponseModel.setMaxQuantity(availabilityModel.getMaxAvailability());
                        if (availabilityModel.getStoreAvailability() >= qtyRequired) {
                                estimate = 0;
                        } else if (availabilityModel.getWarehouseAvailability() >= qtyRequired) {
                                estimate = 2;
                        } else if (availabilityModel.getStoreAvailability() > 0) {
                                estimate = 0;
                                qtyRequired = availabilityModel.getStoreAvailability();
                                cartMessageChanged++;
                        } else if (availabilityModel.getWarehouseAvailability() > 0) {
                                qtyRequired = availabilityModel.getWarehouseAvailability();
                                estimate = 2;
                                cartMessageChanged++;
                        } else {
                                qtyRequired = 0;
                                cartMessageChanged++;
                        }
                        cartItemResponseModel.setQuantity(qtyRequired);
                        if (estimate >= 0 && LocalTime.now().isAfter(CUTOFF_TIME)) {
                                estimate = estimate + 1;
                                promiseDeliveryTime = promiseDeliveryTime.plusDays(3);
                        }
                        totalQty += qtyRequired;
                        totalAmount += qtyRequired * itemSellingPrice;
                        cartItemResponseModel.setEstimate(estimate);
                        cartItemResponseModel.setTitle(item.getItemDescriptionNoColor());
                        cartItemResponseModel.setItemId(cartItem.getItemId());
                        cartItemResponseModel.setMinBuyQuantity(1);
                        cartItemResponseModel.setQuantity(qtyRequired);
                        cartItemResponseModel.setQuantityStep(1);
                        cartItemResponseModel.setPromiseDelivery(promiseDeliveryTime);
                        cartItemResponseModel.setMaxQuantity(availabilityModel.getMaxAvailability());
                        cartItemResponseModel.setCatalogItemId(item.getCatalogItemId());
                        cartItemResponseModel.setImageUrl(contentMap.get(item.getCatalogItemId()).getString("imageUrl_s"));
                        cartItemResponseModel.setColor(item.getColor());
                        cartItemResponseModels.add(cartItemResponseModel);
                }
                cartResponse.setCartItems(cartItemResponseModels);
                cartResponse.setCartMessageChanged(cartMessageChanged);
                cartResponse.setCartMessageOOS(cartMessageOOS);
                int maxEstimate = cartItemResponseModels.stream().mapToInt(x -> x.getEstimate()).max().getAsInt();
                cartResponse.setMaxEstimate(maxEstimate);
                cartResponse.setTotalAmount(totalAmount);
                cartResponse.setTotalQty(totalQty);

                return cartResponse;

        }

        @RequestMapping(value = "/store/partnerStock", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> partnerStock(HttpServletRequest request,
                        @RequestParam(value = "categoryId", required = false, defaultValue = "3") 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(required = false) String listing,
                        @RequestParam(required = false, defaultValue = "true") boolean partnerStockOnly) throws Throwable {
                List<FofoCatalogResponse> dealResponse = new ArrayList<>();
                UserInfo userInfo = (UserInfo) request.getAttribute("userInfo");
                FofoStore fs = fofoStoreRepository.selectByRetailerId(userInfo.getRetailerId());
                sort = "w" + fs.getWarehouseId() + "_i desc";
                dealResponse = this.getCatalogResponse(
                                commonSolrService.getSolrDocs(queryTerm, categoryId, offset, limit, sort, brand, subCategoryId, false),
                                false, userInfo.getRetailerId());
                return responseSender.ok(dealResponse);
        }

        private List<FofoCatalogResponse> getCatalogResponse(JSONArray docs, boolean hotDeal, int fofoId)
                        throws ProfitMandiBusinessException {
                Map<Integer, Integer> ourItemAvailabilityMap = null;
                Map<Integer, Integer> partnerStockAvailabilityMap = 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;
                        }
                        if (fofoId > 0) {
                                partnerStockAvailabilityMap = currentInventorySnapshotRepository.selectItemsStock(fofoId).stream()
                                                .collect(Collectors.toMap(x -> x.getItemId(), x -> x.getAvailability()));
                        }
                        ourItemAvailabilityMap = saholicInventoryService.getTotalAvailabilityByItemIds(new ArrayList<>(itemsSet));
                }

                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"));
                        List<WebOffer> webOffers = webOfferRepository.selectAllActiveOffers().get(ffdr.getCatalogId());
                        if (webOffers != null && webOffers.size() > 0) {
                                ffdr.setOffers(webOffers.stream().map(x -> x.getTitle()).collect(Collectors.toList()));
                        }
                        try {
                                ffdr.setFeature(doc.getString("feature_s"));
                        } catch (Exception e) {
                                ffdr.setFeature(null);
                        }
                        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");
                                        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.setSellingPrice(sellingPrice);
                                                fdi.setMrp(childItem.getDouble("mrp_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);
                                                Float cashBack = schemeService.getCatalogSchemeCashBack().get(ffdr.getCatalogId());
                                                cashBack = cashBack == null ? 0 : cashBack;
                                                // TODO:Dont commit
                                                // fdi.setCashback(Math.min(100, fdi.getMop()));
                                                fdi.setCashback(cashBack);
                                                fdi.setMinBuyQuantity(1);
                                                int partnerAvailability = partnerStockAvailabilityMap.get(itemId) == null ? 0
                                                                : partnerStockAvailabilityMap.get(itemId);
                                                int ourStockAvailability = ourItemAvailabilityMap.get(itemId) == null ? 0
                                                                : Math.max(0, ourItemAvailabilityMap.get(itemId));
                                                fdi.setActive(partnerAvailability > 0);
                                                // fdi.setActive(true);
                                                fdi.setAvailability(Math.min(5, ourStockAvailability + partnerAvailability));
                                                fdi.setQuantityStep(1);
                                                fdi.setMaxQuantity(fdi.getAvailability());
                                                fofoAvailabilityInfoMap.put(itemId, fdi);
                                        }
                                }
                        }
                        if (fofoAvailabilityInfoMap.values().size() > 0) {
                                ffdr.setItems(fofoAvailabilityInfoMap.values().stream()
                                                .sorted(Comparator.comparing(FofoAvailabilityInfo::isActive, Comparator.reverseOrder())
                                                                .thenComparingInt(y -> -y.getAvailability()))
                                                .collect(Collectors.toList()));
                                dealResponse.add(ffdr);
                        }
                }
                return dealResponse.stream()
                                .sorted(Comparator
                                                .comparing(FofoCatalogResponse::getItems,
                                                                (s1, s2) -> (s2.get(0).isActive() ? 1 : 0) - (s1.get(0).isActive() ? 1 : 0))
                                                .thenComparing(FofoCatalogResponse::getItems,
                                                                (x, y) -> y.get(0).getAvailability() - x.get(0).getAvailability()))
                                .collect(Collectors.toList());
        }

        @GetMapping(value = "store/order-status/{pendingOrderId}")
        public ResponseEntity<?> orderStatus(HttpServletRequest request, @PathVariable int pendingOrderId)
                        throws Exception {
                PendingOrder pendingOrder = pendingOrderRepository.selectById(pendingOrderId);
                List<PendingOrderItem> pendingOrderItems = pendingOrderItemRepository.selectByOrderId(pendingOrder.getId());
                List<Integer> catalogIds = new ArrayList<>();
                for (PendingOrderItem pendingOrderItem : pendingOrderItems) {
                        Item item = itemRepository.selectById(pendingOrderItem.getItemId());
                        pendingOrderItem.setItemName(item.getItemDescription());
                        catalogIds.add(item.getCatalogItemId());
                }
                Map<Integer, JSONObject> contentMap = commonSolrService.getContentByCatalogIds(catalogIds);
                for (PendingOrderItem pendingOrderItem : pendingOrderItems) {
                        Item item = itemRepository.selectById(pendingOrderItem.getItemId());
                        JSONObject jsonObj = contentMap.get(item.getCatalogItemId());
                        pendingOrderItem.setImgUrl(jsonObj.getString("imageUrl_s"));
                }
                pendingOrder.setPendingOrderItems(pendingOrderItems);

                return responseSender.ok(pendingOrder);
        }

        @RequestMapping(value = "/store/addresses/{customerId}", method = RequestMethod.GET)
        public ResponseEntity<?> getAll(HttpServletRequest request, @PathVariable int customerId) throws Throwable {
                return responseSender.ok(customerAddressRepository.selectByActiveCustomerId(customerId));
        }

        @RequestMapping(value = "/store/address", method = RequestMethod.POST)
        public ResponseEntity<?> addAddress(HttpServletRequest request, @RequestBody CustomerAddress customerAddress)
                        throws Throwable {
                customerAddressRepository.persist(customerAddress);
                return responseSender.ok(customerAddress);
        }

        @RequestMapping(value = "/store/deactivateCustomerAddress", method = RequestMethod.POST)
        public ResponseEntity<?> deactivateAddresss(HttpServletRequest request, @RequestParam int id) throws Throwable {
                CustomerAddress cust = customerAddressRepository.selectById(id);
                cust.setActive(false);
                return responseSender.ok(cust);
        }

        @RequestMapping(value = "/store/updateCustomer", method = RequestMethod.POST)
        public ResponseEntity<?> updateCustomerProfile(HttpServletRequest request, @RequestBody Customer customer)
                        throws Throwable {
                Customer cust = customerRepository.selectById(customer.getId());
                cust.setGender(customer.getGender());
                cust.setProfileImageId(customer.getProfileImageId());
                cust.setDob(customer.getDob());
                return responseSender.ok(cust);
        }

        @RequestMapping(value = "/stores/{state}/{city}/{storeCode}", method = RequestMethod.GET)
        public void getStoreIndex(HttpServletResponse response, HttpServletRequest request, @PathVariable String state,
                        @PathVariable String city, @PathVariable String storeCode) throws Throwable {
                logger.info("Store code {}", storeCode);
                Map<String, Integer> map = retailerService.getStoreCodeRetailerMap();
                logger.info("retailer id {}", map.get(storeCode));
                String retailerName = retailerService.getAllFofoRetailers().get(map.get(storeCode)).getBusinessName();
                String html = partnerIndexService.getPartnerIndexHtml();
                logger.info("html {}", html);
                html = html.replace("Buy Mobiles and Accessories at exciting prices - SmartDukaan",
                                String.format("%s is now ONLINE. Buy Mobiles, Accessories & more | SmartDukaan", retailerName));
                response.getWriter().write(html);
        }

        @RequestMapping(value = "/cancelPendingOrderItem", method = RequestMethod.POST)
        public ResponseEntity<?> cancelPendingOrderItem(HttpServletRequest request, @RequestParam int id,

                        @RequestParam String statusDescription, @RequestParam String reason) throws Exception {

                PendingOrderItem pendingOrderItem = pendingOrderItemRepository.selectById(id);
                PendingOrder pendingOrder = pendingOrderRepository.selectById(pendingOrderItem.getOrderId());
                Customer customer = customerRepository.selectById(pendingOrder.getCustomerId());
                if (pendingOrderItem.getBilledTimestamp() == null) {
                        pendingOrderItem.setStatus(OrderStatus.CANCELLED);
                        pendingOrderItem.setRemark(reason);
                        pendingOrderItem.setStatusDescription("cancel by self");
                        pendingOrderItem.setCancelledTimestamp(LocalDateTime.now());
                        List<OrderStatus> status = pendingOrderItemRepository.selectByOrderId(pendingOrderItem.getOrderId())
                                        .stream().map(x -> x.getStatus()).collect(Collectors.toList());

                        if (!status.contains(OrderStatus.PENDING) && !status.contains(OrderStatus.PROCESSING)
                                        && !status.contains(OrderStatus.BILLED) && !status.contains(OrderStatus.UNSETTLED)
                                        && !status.contains(OrderStatus.CLAIMED)) {
                                pendingOrder.setStatus(OrderStatus.CLOSED);
                        }

                        pendingOrderItemRepository.persist(pendingOrderItem);
                        String itemDescription = itemRepository.selectById(pendingOrderItem.getItemId()).getItemDescription();
                        otpProcessor.sendSms(OtpProcessor.SELF_CANCELLED_TEMPLATE_ID,
                                        String.format(OtpProcessor.SELF_CANCELLED_TEMPLATE, pendingOrder.getId(),
                                                        StringUtils.abbreviate(itemDescription, 30),
                                                        FormattingUtils.format(pendingOrderItem.getCancelledTimestamp())),
                                        customer.getMobileNumber());

                        List<Integer> catalogIds = new ArrayList<>();

                        Item item = itemRepository.selectById(pendingOrderItem.getItemId());
                        pendingOrderItem.setItemName(item.getItemDescription());
                        catalogIds.add(item.getCatalogItemId());

                        Map<Integer, JSONObject> contentMap = commonSolrService.getContentByCatalogIds(catalogIds);
                        JSONObject jsonObj = contentMap.get(item.getCatalogItemId());
                        pendingOrderItem.setImgUrl(jsonObj.getString("imageUrl_s"));
                        pendingOrder.setPendingOrderItems(Arrays.asList(pendingOrderItem));
                        CustomerAddress customerAddress = customerAddressRepository.selectById(pendingOrder.getCustomerAddressId());

                        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy h:mm a");

                        Map<String, Object> emailModel = new HashMap<>();
                        emailModel.put("customer", customerAddress);
                        emailModel.put("pendingOrder", pendingOrder);
                        emailModel.put("date", dateTimeFormatter);

                        String[] customerEmail = null;
                        if (customer.getEmailId() != null) {
                                customerEmail = new String[] { customer.getEmailId() };

                                List<String> bccTo = Arrays.asList("tejbeer.kaur@smartdukaan.com");

                                emailService.sendMailWithAttachments("Order Cancellation", "order-cancellation.vm", emailModel,
                                                customerEmail, null, bccTo.toArray(new String[0]));

                        }
                }

                return responseSender.ok(true);

        }

        @RequestMapping(value = "/store/checkEligibilityStoreOffers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> checkEligibilityStoreOffers(HttpServletRequest request, @RequestParam(value = "id") int id)
                        throws Exception {

                boolean eligibility = false;

                List<ScratchOffer> scratchOffers = scratchOfferRepository.selectBycCustomerId(id);

                if (!scratchOffers.isEmpty()) {
                        eligibility = true;

                } else {
                        eligibility = false;
                }

                return responseSender.ok(eligibility);
        }

        @RequestMapping(value = "/store/ScratchOffers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> scratchOffers(HttpServletRequest request, @RequestParam(value = "id") int id)
                        throws Exception {

                List<ScratchOffer> scratchOffers = scratchOfferRepository.selectBycCustomerId(id);
                for (ScratchOffer so : scratchOffers) {

                        if (so.getOfferName() != null) {
                                /*
                                 * if (so.getOfferName().equals(ScratchedGift.OTSR)) {
                                 * so.setExpiredTimestamp(so.getCreatedTimestamp().plusDays(1)); } else
                                 */if (so.getOfferName().equals(ScratchedGift.EW)) {
                                        so.setExpiredTimestamp(so.getCreatedTimestamp().plusDays(2));
                                }
                        }
                        if (LocalDateTime.now().isAfter(so.getUnlockedAt())) {
                                so.setUnlocked(true);
                        } else {
                                so.setUnlocked(false);
                        }
                }

                return responseSender.ok(scratchOffers);
        }

        @RequestMapping(value = "/store/ScratchedOffer", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        public ResponseEntity<?> scratchedOffer(HttpServletRequest request, @RequestParam(value = "id") int id)
                        throws Exception {

                ScratchOffer scratchOffer = scratchOfferRepository.selectById(id);
                scratchOffer.setScratched(true);
                scratchOffer.setScracthedAt(LocalDateTime.now());

                return responseSender.ok(true);
        }

}