Subversion Repositories SmartDukaan

Rev

Rev 25965 | Rev 28742 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.web.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.thrift.TException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.gson.Gson;
import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.common.web.util.ResponseSender;
import com.spice.profitmandi.dao.entity.catalog.Item;
import com.spice.profitmandi.dao.entity.dtr.UserAccount;
import com.spice.profitmandi.dao.enumuration.dtr.AccountType;
import com.spice.profitmandi.dao.model.AddCartRequest;
import com.spice.profitmandi.dao.model.CartItem;
import com.spice.profitmandi.dao.model.CartResponse;
import com.spice.profitmandi.dao.model.ProductPojo;
import com.spice.profitmandi.dao.model.UserCart;
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
import com.spice.profitmandi.dao.repository.dtr.UserAccountRepository;
import com.spice.profitmandi.dao.util.ContentPojoPopulator;
import com.spice.profitmandi.dao.util.LogisticsService;
import com.spice.profitmandi.service.inventory.ItemBucketService;
import com.spice.profitmandi.thrift.clients.UserClient;
import com.spice.profitmandi.web.res.ValidateCartResponse;

import in.shop2020.logistics.DeliveryType;
import in.shop2020.model.v1.user.ItemQuantity;
import in.shop2020.model.v1.user.UserContextService;
import in.shop2020.model.v1.user.UserContextService.Client;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

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

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

        @Autowired
        private ResponseSender<?> responseSender;

        @Autowired
        private UserAccountRepository userAccountRepository;

        @Autowired
        private ItemBucketService itemBucketService;

        @Autowired
        private ContentPojoPopulator contentPojoPopulator;

        @Autowired
        private ItemRepository itemRepository;

        public static final Map<String, Integer> MIN_BRAND_QTY_LIMIT = new HashMap<>();

        static {
                // MIN_BRAND_QTY_LIMIT.put("Realme", 10);
                MIN_BRAND_QTY_LIMIT.put("Reliance", 5);
        }

        @RequestMapping(value = ProfitMandiConstants.URL_CART, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        @ApiImplicitParams({
                        @ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header") })
        @ApiOperation(value = "Add items to cart")
        public ResponseEntity<?> validateCart(HttpServletRequest request,
                        @RequestParam(value = "pincode", defaultValue = "110001") String pincode, @RequestParam int bucketId)
                        throws Throwable {

                AddCartRequest cartRequest = new AddCartRequest();
                List<CartItem> ci = new ArrayList<>();
                itemBucketService.getBucketDetails(bucketId).stream().forEach(x -> {
                        ci.add(new CartItem(x.getQuantity(),x.getItemId()));
                });
                cartRequest.setCartItems(ci);
                return this.validateCart(request, cartRequest, "110001");

        }

        @RequestMapping(value = ProfitMandiConstants.URL_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 = "Add items to cart")
        public ResponseEntity<?> validateCart(HttpServletRequest request, @RequestBody AddCartRequest cartRequest,
                        @RequestParam(value = "pincode", defaultValue = "110001") String pincode) throws Throwable {
                UserAccount userAccount = null;
                ValidateCartResponse vc = null;
                int userId = (int) request.getAttribute("userId");

                userAccount = userAccountRepository.selectByUserIdType(userId, AccountType.cartId);
                logger.info("UserAccount................." + userAccount);
                Map<String, Integer> brandQtyMap = new HashMap<>();
                List<ItemQuantity> itemQuantities = new ArrayList<ItemQuantity>();
                List<CartItem> cartItems = cartRequest.getCartItems();
                List<Integer> itemsList = new ArrayList<Integer>();
                // Only Keep Non Billable Stock if partner adds both
                boolean nogst = false;

                for (CartItem ci : cartItems) {
                        if (ci.getQuantity() > 0 && itemRepository.selectById(ci.getItemId()).getHsnCode().equals("NOGST")) {
                                nogst = true;
                        }
                }

                JSONObject cartMessage = null;
                for (CartItem ci : cartItems) {
                        if (nogst && !itemRepository.selectById(ci.getItemId()).getHsnCode().equals("NOGST")) {
                                if (cartMessage == null) {
                                        cartMessage = new JSONObject();
                                        cartMessage.put("messageText", "Billable items can't be billed along with non Billable items");
                                }
                                continue;

                        }
                        itemsList.add(ci.getItemId());
                        ItemQuantity iq = new ItemQuantity(ci.getItemId(), ci.getQuantity());
                        itemQuantities.add(iq);
                }
                if (cartMessage == null) {
                        cartMessage = new JSONObject();
                }

                Client userClient = null;
                try {
                        userClient = new UserClient().getClient();
                        userClient.addItemsToCart(Integer.valueOf(userAccount.getAccountKey()), itemQuantities, null);
                } catch (Exception e) {
                        vc = new ValidateCartResponse(null, "Error", "Problem occurred while updating cart");
                        return responseSender.internalServerError(vc);
                }
                String cartString = null;
                // Use source id temporarily for purpose of tag id as it is just one lets
                // hardcode the tag id
                int source = -1;
                cartString = userClient.validateCartNew(Integer.valueOf(userAccount.getAccountKey()), pincode, source);
                JSONObject cartObj = new JSONObject(cartString);
                JSONArray arr = cartObj.getJSONArray("cartItems");
                int maxEstimate = -2;
                boolean allSame = true;
                int removedCount = 0;
                cartObj.put("cartMessagesMerged", 0);

                for (int j = 0; j < arr.length(); j++) {
                        JSONObject itemObj = arr.getJSONObject(j - removedCount);
                        if (!itemsList.contains(itemObj.getInt("itemId"))) {
                                if (itemObj.getInt("quantity") == 0) {
                                        arr.remove(j - removedCount);
                                        removedCount++;
                                        if (itemObj.has("estimate") && itemObj.getInt("estimate") == -1) {
                                                cartObj.put("cartMessageUndeliverable", cartObj.getInt("cartMessageUndeliverable") - 1);
                                        } else {
                                                cartObj.put("cartMessageOOS", cartObj.getInt("cartMessageOOS") - 1);
                                        }
                                        continue;
                                } else {
                                        JSONArray messagesArray = new JSONArray();
                                        itemObj.put("cartItemMessages", messagesArray);
                                        if (itemsList.size() > 0) {
                                                JSONObject message = new JSONObject();
                                                message.put("type", "info");
                                                message.put("messageText", "Added from earlier cart");
                                                messagesArray.put(message);
                                                cartObj.put("cartMessagesMerged", cartObj.getInt("cartMessagesMerged") + 1);
                                        }
                                }
                        }
                        Item item = itemRepository.selectById(itemObj.getInt("itemId"));
                        if (!brandQtyMap.containsKey(item.getBrand())) {
                                brandQtyMap.put(item.getBrand(), 0);
                        }
                        brandQtyMap.put(item.getBrand(), brandQtyMap.get(item.getBrand()) + itemObj.getInt("quantity"));
                        try {
                                ProductPojo pp = contentPojoPopulator.getShortContent(itemObj.getLong("catalogItemId"));

                                if (itemObj.has("estimate")) {
                                        if (allSame) {
                                                allSame = maxEstimate == -2 || maxEstimate == itemObj.getInt("estimate");
                                        }
                                        if (itemObj.getInt("estimate") > maxEstimate) {
                                                maxEstimate = itemObj.getInt("estimate");
                                        }
                                }
                                itemObj.put("imageUrl", pp.getImageUrl());
                                itemObj.put("title", pp.getTitle());
                        } catch (Throwable t) {
                                itemObj.put("imageUrl", "");
                                itemObj.put("title", item.getBrand() + " " + item.getModelName() + "" + item.getModelNumber());
                        }
                }

                ArrayList<JSONObject> listdata = new ArrayList<JSONObject>();
                if (arr != null) {
                        for (int i = 0; i < arr.length(); i++) {
                                JSONArray itemMessages = arr.getJSONObject(i).optJSONArray(("cartItemMessages"));
                                if (itemMessages != null && itemMessages.length() > 0) {
                                        listdata.add(0, arr.getJSONObject(i));
                                } else {
                                        listdata.add(arr.getJSONObject(i));
                                }
                        }
                }
                arr = new JSONArray();
                for (int i = 0; i < listdata.size(); i++) {
                        arr.put(listdata.get(i));
                }

                cartObj.put("cartItems", arr);
                JSONArray cartMessagesArray = new JSONArray();
                for (Map.Entry<String, Integer> minBrandQtyLimit : MIN_BRAND_QTY_LIMIT.entrySet()) {
                        if (brandQtyMap.containsKey(minBrandQtyLimit.getKey())) {
                                if (brandQtyMap.get(minBrandQtyLimit.getKey()) < minBrandQtyLimit.getValue()) {
                                        cartMessagesArray
                                                        .put(new JSONObject()
                                                                        .put("messageText",
                                                                                        String.format("Minimum qty for %s brand should be %d",
                                                                                                        minBrandQtyLimit.getKey(), minBrandQtyLimit.getValue()))
                                                                        .put("type", "warn"));
                                }
                        }
                }

                for (String message : Arrays.asList("cartMessageOOS", "cartMessageUndeliverable", "cartMessageChanged",
                                "cartMessagesMerged")) {
                        int count = cartObj.getInt(message);
                        if (count > 0) {
                                String type = "danger";
                                if (message.equals("cartMessagesMerged")) {
                                        type = "info";
                                        if (count == 1) {
                                                cartMessage.put("messageText", "1 item is added from earlier cart");
                                        } else {
                                                cartMessage.put("messageText", "Few items are added from earlier cart");
                                        }
                                } else if (message.equals("cartMessageOOS")) {
                                        if (count == 1) {
                                                cartMessage.put("messageText", "One item is currently Out of Stock");
                                        } else {
                                                cartMessage.put("messageText", "Few items are currently Out of Stock");
                                        }
                                } else if (message.equals("cartMessageUndeliverable")) {
                                        if (count == 1) {
                                                cartMessage.put("messageText", "One item is undeliverable");
                                        } else {
                                                cartMessage.put("messageText", "Few items are underiverable");
                                        }
                                } else if (message.equals("cartMessageChanged")) {
                                        if (count == 1) {
                                                cartMessage.put("messageText", "One item qty has changed");
                                        } else {
                                                cartMessage.put("messageText", "Few items qty have changed");
                                        }
                                }
                                cartMessage.put("type", type);
                                cartMessagesArray.put(cartMessage);
                        }
                }
                cartObj.put("cartMessages", cartMessagesArray);
                // Hardcode maxEstimate to -3 for managing brands quantity
                if (maxEstimate == -1) {
                        cartObj.put("estimateString", "Can't ship here");
                } else if (maxEstimate == -2) {
                        cartObj.put("estimateString", "Out of Stock");
                } else {
                        try {
                                cartObj.put("cod", cartObj.getBoolean("codAllowed"));
                                cartObj.put("estimateString", LogisticsService.getDeliveryDateString(maxEstimate, DeliveryType.COD));
                        } catch (NumberFormatException | JSONException | TException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                vc = new ValidateCartResponse(null, "Error", "Problem occurred while getting delivery estimates");
                                return responseSender.internalServerError(vc);
                        }

                }
                cartObj.put("maxEstimate", maxEstimate);
                CartResponse cartResponse = new Gson().fromJson(cartObj.toString(), CartResponse.class);
                vc = new ValidateCartResponse(cartResponse, "Success", "Items added to cart successfully");
                return responseSender.ok(vc);
        }

        @RequestMapping(value = ProfitMandiConstants.URL_CART_CHANGE_ADDRESS, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        @ApiImplicitParams({
                        @ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header") })

        @ApiOperation(value = "Change address")
        public ResponseEntity<?> changeAddress(HttpServletRequest request,
                        @RequestParam(value = "addressId") long addressId) throws Throwable {
                UserCart uc = userAccountRepository.getUserCart((int) request.getAttribute("userId"));
                UserContextService.Client userClient = new UserClient().getClient();
                userClient.addAddressToCart(uc.getCartId(), addressId);
                return responseSender.ok("Address Changed successfully");
        }
}