Rev 29404 | Rev 30836 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.spice.profitmandi.dao.cart;import java.time.LocalDateTime;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.HashMap;import java.util.HashSet;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import java.util.Set;import java.util.Map.Entry;import java.util.stream.Collectors;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;import com.spice.profitmandi.common.model.ProfitMandiConstants;import com.spice.profitmandi.dao.entity.catalog.Item;import com.spice.profitmandi.dao.entity.catalog.TagListing;import com.spice.profitmandi.dao.entity.cs.PartnerRegion;import com.spice.profitmandi.dao.entity.fofo.FofoStore;import com.spice.profitmandi.dao.entity.inventory.SaholicCIS;import com.spice.profitmandi.dao.entity.user.Cart;import com.spice.profitmandi.dao.entity.user.CartLine;import com.spice.profitmandi.dao.entity.user.User;import com.spice.profitmandi.dao.model.CartItem;import com.spice.profitmandi.dao.model.CartItemResponseModel;import com.spice.profitmandi.dao.model.CartMessage;import com.spice.profitmandi.dao.model.CartResponse;import com.spice.profitmandi.dao.repository.catalog.FocusedModelRepository;import com.spice.profitmandi.dao.repository.catalog.ItemRepository;import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;import com.spice.profitmandi.dao.repository.cs.PartnerRegionRepository;import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;import com.spice.profitmandi.dao.repository.dtr.RetailerBlockBrandsRepository;import com.spice.profitmandi.dao.repository.fofo.CurrentInventorySnapshotRepository;import com.spice.profitmandi.dao.repository.transaction.OrderRepository;import com.spice.profitmandi.dao.repository.user.CartLineRepository;import com.spice.profitmandi.dao.repository.user.CartRepository;import com.spice.profitmandi.dao.repository.user.UserRepository;import com.spice.profitmandi.service.NotificationService;import com.spice.profitmandi.service.inventory.FocusedShortageModel;import com.spice.profitmandi.service.inventory.SaholicInventoryService;import com.spice.profitmandi.service.transaction.TransactionService;@Componentpublic class CartServiceImpl implements CartService {private static final Set<Integer> tagIds = new HashSet<>(Arrays.asList(4));private static final Logger logger = LogManager.getLogger(CartServiceImpl.class);private static final Map<Integer, List<Integer>> focusedModelVariantMap = new HashMap<>();@AutowiredCartRepository cartRepository;@AutowiredCartLineRepository cartLineRepository;@AutowiredFofoStoreRepository fofoStoreRepository;@AutowiredTagListingRepository tagListingRepository;@AutowiredUserRepository saholicUserRepository;@AutowiredItemRepository itemRepository;@AutowiredSaholicInventoryService saholicInventoryService;@AutowiredCurrentInventorySnapshotRepository currentInventorySnapshotRepository;@Autowiredprivate FocusedModelRepository focusedModelRepository;@Autowiredprivate PartnerRegionRepository partnerRegionRepository;@Autowiredprivate TransactionService transactionService;@Autowiredprivate RetailerBlockBrandsRepository retailerBlockBrandRepository;@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate NotificationService notificationService;@Override// Unused methodpublic CartModel addToCart(int cartId, int itemId, int quantity, float sellingPrice) {CartLine cartItem = cartLineRepository.selectByCartItem(cartId, itemId);if (cartItem == null) {this.createCartItem(cartId, itemId, quantity, sellingPrice);} else {cartItem.setQuantity(quantity);cartItem.setActualPrice(sellingPrice);}return null;}private void createCartItem(int cartId, int itemId, int quantity, float sellingPrice) {CartLine cartLine = new CartLine();cartLine.setActualPrice(sellingPrice);cartLine.setCartId(cartId);cartLine.setQuantity(quantity);// TODO: Estmiate LogiccartLine.setEstimate(2);cartLineRepository.persist(cartLine);}@Overridepublic boolean clearCart(int cartId) throws ProfitMandiBusinessException {List<CartLine> cartLines = cartLineRepository.selectAllByCart(cartId);cartLines.stream().forEach(cartLine -> cartLineRepository.delete(cartLine));Cart cart = cartRepository.selectById(cartId);cart.setUpdateTimestamp(LocalDateTime.now());cart.setCheckoutTimestamp(null);cart.setTotalPrice(0);cart.setWalletAmount(0);return true;}@Overridepublic CartModel getCart(int cartId) {// TODO Auto-generated method stubreturn null;}// As of now it only works for Fofo Partners need to be refactored laterprivate Map<Integer, Integer> getAvailabilityMap(User user, Set<Integer> itemIds) {Map<Integer, Integer> itemAvailabilityMap = new HashMap<>();List<TagListing> tags = tagListingRepository.selectByItemIdsAndTagIds(itemIds, tagIds);tags.stream().forEach(tagListing -> {if (!tagListing.isActive() || tagListing.isHotDeals()) {// show actual values here} else {itemAvailabilityMap.put(tagListing.getItemId(), 100);}});return itemAvailabilityMap;}// As of now it only works for Fofo Partners need to be refactored laterprivate Map<Integer, Integer> getMinBuyQtyMap(User user, Set<Integer> itemIds) {List<Item> items = itemRepository.selectByIds(itemIds);return items.stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getCategoryId() == 10020 ? 1 : 10));}// As of now it only works for Fofo Partners need to be refactored laterprivate Map<Integer, Float> getPriceMap(User user, Set<Integer> itemIds) {List<TagListing> tags = tagListingRepository.selectByItemIdsAndTagIds(itemIds, tagIds);return tags.stream().collect(Collectors.toMap(x -> x.getItemId(), x -> x.getSellingPrice()));}@Overridepublic CartResponse getCartValidation(int cartId) throws ProfitMandiBusinessException {/** # No need to validate duplicate items since there are only two ways # to add* items to a cart and both of them check whether the item being # added is a* duplicate of an already existing item.*/Cart cart = cartRepository.selectById(cartId);List<CartLine> cartLines = cartLineRepository.selectAllByCart(cartId);User saholicUser = saholicUserRepository.selectByCartId(cartId);int totalQty = 0;double totalAmount = 0;CartResponse cartResponse = new CartResponse();List<CartMessage> cartMessages = new ArrayList<>();List<CartItemResponseModel> cartItemModels = new ArrayList<>();cartResponse.setCartMessages(cartMessages);cartResponse.setCartItems(cartItemModels);int cartMessageChanged = 0;int cartMessageOOS = 0;int cartMessageUndeliverable = 0;Set<Integer> itemIds = cartLines.stream().map(x -> x.getItemId()).collect(Collectors.toSet());logger.info("iteme ids -- {}", itemIds);List<TagListing> tagListings = tagListingRepository.selectByItemIdsAndTagIds(itemIds, tagIds);Map<Integer, TagListing> tagListingsMap = tagListings.stream().collect(Collectors.toMap(x -> x.getItemId(), x -> x));cart.setTotalPrice(0);int nonAccessoryQuantity = 0;for (CartLine cartLine : cartLines) {boolean itemQuantityChanged = false;CartItemResponseModel cartItemResponseModel = new CartItemResponseModel();int oldEstimate = cartLine.getEstimate();int itemId = cartLine.getItemId();Item item = null;try {item = itemRepository.selectById(itemId);cartItemResponseModel.setTitle(item.getItemDescriptionNoColor());} catch (ProfitMandiBusinessException e) {e.printStackTrace();logger.info("Error finding item with id {}", itemId);cartLineRepository.delete(cartLine);continue;}cartItemResponseModel.setItemId(itemId);cartItemResponseModel.setQuantity(0);cartItemResponseModel.setColor(item.getColor());List<CartItemMessage> cartItemMessages = new ArrayList<>();cartItemResponseModel.setCartItemMessages(cartItemMessages);cartItemResponseModel.setCatalogItemId(item.getCatalogItemId());cartItemResponseModel.setMinBuyQuantity(1);cartItemResponseModel.setQuantityStep(1);cartItemResponseModel.setMaxQuantity(0);/** int netAvailability = itemAvailabilityMap.get(itemId).stream()* .collect(Collectors.summingInt(x -> x.getNetavailability()));*/int availability = 30;if (availability < cartLine.getQuantity()) {cartLine.setQuantity(availability);itemQuantityChanged = true;}cartItemResponseModel.setMaxQuantity(Math.max(availability, 100));if (availability < cartItemResponseModel.getMinBuyQuantity()) {cartItemResponseModel.setMinBuyQuantity(availability);}if (cartLine.getQuantity() < cartItemResponseModel.getMinBuyQuantity()) {itemQuantityChanged = true;cartLine.setQuantity(cartItemResponseModel.getMinBuyQuantity());}if (cartLine.getQuantity() > cartItemResponseModel.getMaxQuantity()) {itemQuantityChanged = true;cartLine.setQuantity(cartItemResponseModel.getMaxQuantity());}cartLine.setActualPrice(tagListingsMap.get(itemId).getSellingPrice());if (item.getCategoryId() == 10006 || item.getCategoryId() == 10010) {nonAccessoryQuantity += cartItemResponseModel.getQuantity();cartItemResponseModel.setCategoryName("mobile");}cartItemResponseModel.setSellingPrice(cartLine.getActualPrice());if (availability > 0) {cart.setTotalPrice(cart.getTotalPrice() + (cartLine.getActualPrice() * cartLine.getQuantity()));cartItemResponseModel.setQuantity(cartLine.getQuantity());cartItemResponseModel.setEstimate(2);if (itemQuantityChanged) {cartMessageChanged += 1;if (oldEstimate != cartItemResponseModel.getEstimate()) {cartLine.setEstimate(cartItemResponseModel.getEstimate());cart.setUpdateTimestamp(LocalDateTime.now());}}totalAmount += cartLine.getActualPrice() * cartLine.getQuantity();} else {cartItemResponseModel.setQuantity(0);cartMessageOOS += 1;CartItemMessage cartItemMessage = new CartItemMessage();cartItemMessage.setType("danger");cartItemMessage.setMessageText("Out of Stock");cartItemMessages.add(cartItemMessage);cartLineRepository.delete(cartLine);}totalQty += cartItemResponseModel.getQuantity();if (cartItemMessages.size() > 0) {cartResponse.getCartItems().add(0, cartItemResponseModel);} else {cartResponse.getCartItems().add(cartItemResponseModel);}}if (cart.getCheckoutTimestamp() != null) {if (cart.getUpdateTimestamp().isBefore(cart.getCheckoutTimestamp())) {cart.setCheckoutTimestamp(null);}}cartResponse.setTotalQty(totalQty);cartResponse.setTotalAmount(totalAmount);cartResponse.setNonAccessoryQuantity(nonAccessoryQuantity);cartResponse.setShippingCharge(0);cartResponse.setCartMessageChanged(cartMessageChanged);cartResponse.setCartMessageOOS(cartMessageOOS);cartResponse.setCartMessageUndeliverable(cartMessageUndeliverable);cartResponse.setCod(false);return cartResponse;}@Overridepublic void addItemsToCart(int cartId, List<CartItem> cartItems) throws ProfitMandiBusinessException {logger.info("cart items {}", cartItems);cartItems = cartItems.stream().filter(x -> x.getQuantity() > 0).collect(Collectors.toList());Map<Integer, Integer> itemQuantityMap = cartItems.stream().collect(Collectors.toMap(x -> x.getItemId(), x -> x.getQuantity()));List<CartLine> cartLines = cartLineRepository.selectAllByCart(cartId);// Delete cartLines with 0 valuesfor (CartLine cartLine : cartLines) {Integer quantity = itemQuantityMap.get(cartLine.getItemId());if (quantity == null || quantity.intValue() == 0) {cartLineRepository.delete(cartLine);} else {cartLine.setQuantity(itemQuantityMap.get(cartLine.getItemId()));cartLine.setUpdateTimestapm(LocalDateTime.now());}}for (CartItem cartItem : cartItems) {if (cartLineRepository.selectByCartItem(cartId, cartItem.getItemId()) == null) {CartLine cartLineNew = new CartLine();cartLineNew.setItemId(cartItem.getItemId());cartLineNew.setQuantity(cartItem.getQuantity());cartLineNew.setCartId(cartId);cartLineNew.setCreateTimestamp(LocalDateTime.now());cartLineRepository.persist(cartLineNew);}}}@Overridepublic void addAddressToCart(int cartId, long addressId) throws ProfitMandiBusinessException {Cart cart = cartRepository.selectById(cartId);cart.setAddressId((int) addressId);}@Overridepublic void addShoppingBag(int cartId, long qty) {CartLine cl = new CartLine();cl.setItemId(ProfitMandiConstants.ITEM_CARRY_BAG);cl.setQuantity((int) qty);cl.setCartId(cartId);cl.setCreateTimestamp(LocalDateTime.now());cl.setDataProtectionAmount(0);cl.setEstimate(0);cl.setInsuranceAmount(0f);cl.setDataProtectionInsurer(0);cl.setActualPrice(0.01f);cartLineRepository.persist(cl);}@Overridepublic CartModel removeFromCart(int cartId, int itemId) {// TODO Auto-generated method stubreturn null;}@Overridepublic List<FocusedShortageModel> focusedModelShortageValidation(int fofoId,Map<Integer, Integer> catalogCartQtyMap) throws ProfitMandiBusinessException {logger.info("fofoId {}", fofoId);focusedModelVariantMap.put(1022771, Arrays.asList(1022771));focusedModelVariantMap.put(1023025, Arrays.asList(1022975, 1022945));focusedModelVariantMap.put(1023027, Arrays.asList(1022706));focusedModelVariantMap.put(1022976, Arrays.asList(1022744));focusedModelVariantMap.put(1023045, Arrays.asList(1022768));focusedModelVariantMap.put(1023066, Arrays.asList(1022858));Map<Integer, Long> inStockItemModel = new HashMap<>();Map<Integer, Long> itempendingIndent = new HashMap<>();Map<Integer, Long> grnItemPendingOrders = new HashMap<>();Map<Integer, Integer> focusedModelMap = null;inStockItemModel = currentInventorySnapshotRepository.selectSumInMobileStockGroupByCatalog(fofoId).stream().collect(Collectors.toMap(x -> x.getCatalogItemId(), x -> x.getQty()));itempendingIndent = transactionService.getInTransitOrders(fofoId).stream().collect(Collectors.groupingBy(x -> x.getLineItem().getItem().getCatalogItemId(),Collectors.summingLong(x -> (long) x.getLineItem().getQuantity())));grnItemPendingOrders = orderRepository.selectPendingGrnOrders(fofoId).stream().collect(Collectors.groupingBy(x -> x.getLineItem().getItem().getCatalogItemId(),Collectors.summingLong(x -> (long) x.getLineItem().getQuantity())));List<PartnerRegion> partnerRegions = partnerRegionRepository.selectByfofoId(fofoId);FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);List<String> retailerBlockBrands = retailerBlockBrandRepository.selectAllByRetailer(fofoId).stream().map(x -> x.getBlockBrands()).collect(Collectors.toList());if (partnerRegions.size() > 0) {focusedModelMap = focusedModelRepository.selectAllByRegionIds(partnerRegions.stream().map(x -> x.getRegionId()).collect(Collectors.toList())).stream().collect(Collectors.toMap(x -> x.getCatalogId(), x -> x.getMinimumQty()));} else {focusedModelMap = new HashMap<>();}Map<Integer, List<SaholicCIS>> itemAvailabilityMap = saholicInventoryService.getSaholicStock().get(fofoStore.getWarehouseId());Map<Integer, Integer> catalogItemAailabilityMap = new HashMap<>();for (Entry<Integer, Integer> fm : focusedModelMap.entrySet()) {List<Item> items = itemRepository.selectAllByCatalogItemId(fm.getKey());int allColorNetAvailability = 0;for (Item item : items) {if (retailerBlockBrands.contains(item.getBrand()))continue;List<SaholicCIS> currentAvailability = itemAvailabilityMap.get(item.getId());if (currentAvailability != null) {allColorNetAvailability += currentAvailability.stream().collect(Collectors.summingInt(SaholicCIS::getNetavailability));}}catalogItemAailabilityMap.put(fm.getKey(), allColorNetAvailability);}List<FocusedShortageModel> focusedModelShortageList = new ArrayList<>();for (Entry<Integer, Integer> fm : focusedModelMap.entrySet()) {logger.info("fm {}", fm);long overallStock = (inStockItemModel.get(fm.getKey()) == null ? 0 : inStockItemModel.get(fm.getKey()))+ (itempendingIndent.get(fm.getKey()) == null ? 0 : itempendingIndent.get(fm.getKey()))+ (grnItemPendingOrders.get(fm.getKey()) == null ? 0 : grnItemPendingOrders.get(fm.getKey()));logger.info("overallStock {}", overallStock);// Blocked brands available quantity is discussed to zerolong warehouseStock = catalogItemAailabilityMap.get(fm.getKey()) == null ? 0: catalogItemAailabilityMap.get(fm.getKey());logger.info("warehouseStock {}", warehouseStock);long cartValue = catalogCartQtyMap.get(fm.getKey()) == null ? 0 : catalogCartQtyMap.get(fm.getKey());logger.info("cartValue" + cartValue);long totalStock = overallStock + cartValue;logger.info("totalStock" + totalStock);long shortQty = Math.min(fm.getValue() - totalStock, warehouseStock);logger.info("shortQty {}", shortQty);if (shortQty > 0) {if (focusedModelVariantMap.get(fm.getKey()) != null) {List<Integer> variantCatalogIds = focusedModelVariantMap.get(fm.getKey());logger.info("variantCatalogIds {}", variantCatalogIds);int variantAvailability = 0;for (Integer vc : variantCatalogIds) {long variantOverallStock = (inStockItemModel.get(vc) == null ? 0 : inStockItemModel.get(vc))+ (itempendingIndent.get(vc) == null ? 0 : itempendingIndent.get(vc))+ (grnItemPendingOrders.get(vc) == null ? 0 : grnItemPendingOrders.get(vc));logger.info("variantOverallStock {}", variantOverallStock);// Blocked brands available quantity is discussed to zerolong variantWarehouseStock = catalogItemAailabilityMap.get(vc) == null ? 0: catalogItemAailabilityMap.get(vc);logger.info("variantWarehouseStock {}", variantWarehouseStock);long variantCartValue = catalogCartQtyMap.get(vc) == null ? 0 : catalogCartQtyMap.get(vc);logger.info("variantCartValue" + variantCartValue);long variantTotalStock = variantOverallStock + variantCartValue;logger.info("variantTotalStock" + variantTotalStock);variantAvailability += (int) variantTotalStock;}logger.info("variantAvailability {}", variantAvailability);shortQty = shortQty - variantAvailability;}}logger.info("shortQty" + shortQty);if (shortQty > 0) {Map<Integer, Integer> requiredItemQty = new HashMap<>();List<Item> it = itemRepository.selectAllByCatalogItemId(fm.getKey());FocusedShortageModel fms = new FocusedShortageModel();fms.setShortageQty((int) shortQty);fms.setCatalogId(fm.getKey());fms.setAvailabitiy(fm.getValue());fms.setInStock(overallStock);fms.setItemName(it.get(0).getBrand() + it.get(0).getModelNumber() + it.get(0).getModelName());Map<Integer, Integer> itemQtyMap = new HashMap<>();for (Item i : it) {List<SaholicCIS> ca = itemAvailabilityMap.get(i.getId());if (ca != null) {itemQtyMap.put(i.getId(),ca.stream().collect(Collectors.summingInt(SaholicCIS::getNetavailability)));}}itemQtyMap = itemQtyMap.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));for (long i = shortQty; i > 0; i--) {if (shortQty == 0) {break;}for (Entry<Integer, Integer> itemQty : itemQtyMap.entrySet()) {int availbleQty = itemQty.getValue();if (availbleQty == 0) {break;}if (requiredItemQty.get(itemQty.getKey()) == null) {requiredItemQty.put(itemQty.getKey(), 1);availbleQty = availbleQty - 1;if (availbleQty != 0) {itemQtyMap.put(itemQty.getKey(), availbleQty);}shortQty -= 1;} else {int qty = requiredItemQty.get(itemQty.getKey());requiredItemQty.put(itemQty.getKey(), qty + 1);availbleQty = availbleQty - 1;if (availbleQty != 0) {itemQtyMap.put(itemQty.getKey(), availbleQty);}shortQty -= 1;}if (shortQty == 0) {break;}}}Set<CartItem> cartItems = new HashSet<>();for (Entry<Integer, Integer> itemQtySet : requiredItemQty.entrySet()) {CartItem ci = new CartItem();Item item = itemRepository.selectById(itemQtySet.getKey());TagListing tl = tagListingRepository.selectByItemId(item.getId());ci.setItemId(item.getId());ci.setQuantity(itemQtySet.getValue());ci.setSellingPrice(tl.getSellingPrice());cartItems.add(ci);}fms.setCartItems(cartItems);// fms.setItemQtyAvailability(requiredItemQty);focusedModelShortageList.add(fms);}}logger.info("focusedModelShortageList {}", focusedModelShortageList);return focusedModelShortageList;}}