Subversion Repositories SmartDukaan

Rev

Rev 35945 | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.dao.cart;

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.fofo.PartnerType;
import com.spice.profitmandi.dao.entity.inventory.SaholicCISTable;
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.*;
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.fofo.PartnerTypeChangeService;
import com.spice.profitmandi.dao.repository.inventory.SaholicCISTableRepository;
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.dao.repository.warehouse.BrandRegionMappingRepository;
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.inventory.WarehouseIntransitDataModel;
import com.spice.profitmandi.service.transaction.TransactionService;
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 java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

@Component
public 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<>();

    @Autowired
    CartRepository cartRepository;

    @Autowired
    CartLineRepository cartLineRepository;

    @Autowired
    FofoStoreRepository fofoStoreRepository;

    @Autowired
    TagListingRepository tagListingRepository;

    @Autowired
    SaholicInventoryService saholicInventoryService;

    @Autowired
    UserRepository saholicUserRepository;

    @Autowired
    ItemRepository itemRepository;


    @Autowired
    CurrentInventorySnapshotRepository currentInventorySnapshotRepository;

    @Autowired
    private FocusedModelRepository focusedModelRepository;

    @Autowired
    private PartnerRegionRepository partnerRegionRepository;

    @Autowired
    private TransactionService transactionService;

    @Autowired
    private RetailerBlockBrandsRepository retailerBlockBrandRepository;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private NotificationService notificationService;
    @Autowired
    private SaholicCISTableRepository saholicCISTableRepository;

    @Autowired
    private BrandRegionMappingRepository brandRegionMappingRepository;

    @Autowired
    private PartnerTypeChangeService partnerTypeChangeService;

    @Override
    // Unused method
    public 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 Logic
        cartLine.setEstimate(2);
        cartLineRepository.persist(cartLine);

    }

    @Override
    public 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;
    }

    @Override
    public CartModel getCart(int cartId) {
        // TODO Auto-generated method stub
        return null;
    }

    // As of now it only works for Fofo Partners need to be refactored later
    private 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(), 400);
            }
        });
        return itemAvailabilityMap;
    }

    // As of now it only works for Fofo Partners need to be refactored later
    private Map<Integer, Integer> getMinBuyQtyMap(User user, Set<Integer> itemIds) throws ProfitMandiBusinessException {
        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 later
    private 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()));

    }

    @Override
    public 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("Item ids {}", itemIds);
        List<TagListing> tagListings = tagListingRepository.selectByItemIdsAndTagIds(itemIds, tagIds);
        Map<Integer, TagListing> tagListingsMap = tagListings.stream()
                .collect(Collectors.toMap(x -> x.getItemId(), x -> x));

        // N+1 fix: Pre-fetch all items before the loop
        Map<Integer, Item> itemMap = itemRepository.selectByIds(itemIds).stream()
                .collect(Collectors.toMap(Item::getId, item -> item));

        User user = saholicUserRepository.selectByCartId(cartId);
        FofoStore fs = fofoStoreRepository.selectByRetailerId(user.getId());
        Map<Integer, Integer> warehouseItemQtyMap = saholicInventoryService.getSaholicNetAvailability(fs.getWarehouseId(), new ArrayList<>(itemIds));
        PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(fs.getId(), LocalDate.now());
        // Get in-transit data for this warehouse
        List<WarehouseIntransitDataModel> warehouseIntransitDataModels =
                saholicInventoryService.getWarehouseIntransistDataList().stream()
                        .filter(x -> x.getWarehouseId() == fs.getWarehouseId())
                        .collect(Collectors.toList());

        // Add in-transit quantities into the map
        for (WarehouseIntransitDataModel intransitData : warehouseIntransitDataModels) {
            if (intransitData.getQty() > 0) {
                int itemId = intransitData.getItemId();
                int existingQty = warehouseItemQtyMap.getOrDefault(itemId, 0);
                warehouseItemQtyMap.put(itemId, existingQty + intransitData.getQty());
            }
        }
        cart.setTotalPrice(0);
        int nonAccessoryQuantity = 0;
        for (CartLine cartLine : cartLines) {
            CartItemResponseModel cartItemResponseModel = new CartItemResponseModel();
            int oldEstimate = cartLine.getEstimate();
            int itemId = cartLine.getItemId();
            // N+1 fix: Use pre-fetched itemMap instead of querying per item
            Item item = itemMap.get(itemId);
            if (item == null) {
                logger.info("Error finding item with id {}", itemId);
                cartLineRepository.delete(cartLine);
                continue;
            }
            cartItemResponseModel.setTitle(item.getItemDescriptionNoColor());
            cartItemResponseModel.setItemId(itemId);
            cartItemResponseModel.setQuantity(cartLine.getQuantity());
            cartItemResponseModel.setColor(item.getColor());
            cartItemResponseModel.setCatalogItemId(item.getCatalogItemId());
            cartItemResponseModel.setMinBuyQuantity(1);
            cartItemResponseModel.setQuantityStep(1);
            cartItemResponseModel.setMaxQuantity(400);
            int currentAvailability = warehouseItemQtyMap.get(itemId) == null ? 0 : warehouseItemQtyMap.get(itemId);
            int oldAvailability = cartLine.getAvailability();
            cartItemResponseModel.setAvailability(currentAvailability);

            //Current availability is less than required quantity
            if (currentAvailability < cartLine.getQuantity()) {
                //Current Availability is reduced
                if (oldAvailability > currentAvailability) {
                    cartMessageChanged += 1;
                }
            }

            //As of now one can buy upto 100 Qty
            if (cartLine.getQuantity() > cartItemResponseModel.getMaxQuantity()) {
                cartMessageChanged +=1;
                cartLine.setQuantity(cartItemResponseModel.getMaxQuantity());
            }

            if (item.getCategoryId() == 10006 || item.getCategoryId() == 10010) {
                nonAccessoryQuantity += cartItemResponseModel.getQuantity();
                cartItemResponseModel.setCategoryName("mobile");
            }
            if (cartItemResponseModel.getItemId() == ProfitMandiConstants.ITEM_CARRY_BAG) {
                if (partnerType.equals(PartnerType.SILVER) || partnerType.equals(PartnerType.BRONZE)) {
                    cartLine.setActualPrice(tagListingsMap.get(itemId).getSellingPrice());
                    cartItemResponseModel.setSellingPrice(cartLine.getActualPrice());
                } else {
                    cartItemResponseModel.setSellingPrice(1);
                    cartLine.setActualPrice(1);
                }
            } else {
                // Check for price mismatch between cart and current TagListing
                TagListing currentTagListing = tagListingsMap.get(itemId);
                if (currentTagListing != null) {
                    float cartPrice = cartLine.getActualPrice();
                    float currentPrice = currentTagListing.getSellingPrice();

                    // If cart price is 0 or unset, silently update to current price (client bug)
                    if (cartPrice < 0.01f) {
                        logger.info("Cart price was 0/unset for itemId {}, setting to current price {}",
                            itemId, currentPrice);
                        cartLine.setActualPrice(currentPrice);
                    }
                    // Use tolerance comparison to avoid float precision false positives
                    else if (Math.abs(cartPrice - currentPrice) > 0.01f) {
                        cartMessageChanged += 1;
                        String priceChangeMsg = String.format("Price updated for %s: Rs. %.2f to Rs. %.2f",
                            item.getItemDescriptionNoColor(), cartPrice, currentPrice);
                        CartMessage cartMessage = new CartMessage();
                        cartMessage.setMessageText(priceChangeMsg);
                        cartMessage.setType("PRICE_CHANGED");
                        cartMessages.add(cartMessage);
                        logger.info("Price mismatch detected for itemId {}: cart price {} vs current price {}",
                            itemId, cartPrice, currentPrice);
                        // Update cart line with current price
                        cartLine.setActualPrice(currentPrice);
                    }
                }
                cartItemResponseModel.setSellingPrice(cartLine.getActualPrice());
            }

            //if (availability > 0) {
            cart.setTotalPrice(cart.getTotalPrice() + (cartLine.getActualPrice() * cartLine.getQuantity()));
            cartItemResponseModel.setQuantity(cartLine.getQuantity());
            cartItemResponseModel.setEstimate(2);
            cartLine.setEstimate(cartItemResponseModel.getEstimate());
            cart.setUpdateTimestamp(LocalDateTime.now());


            totalAmount += cartLine.getActualPrice() * cartLine.getQuantity();
            totalQty += cartItemResponseModel.getQuantity();
            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;
    }

    @Override
    public 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);
        Map<Integer, CartLine> itemCartLineMap = cartLines.stream().collect(Collectors.toMap(x->x.getItemId(), x->x));
        // Delete cartLines with 0 values
        for (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 (!itemCartLineMap.containsKey(cartItem.getItemId())) {
                CartLine cartLineNew = new CartLine();
                cartLineNew.setItemId(cartItem.getItemId());
                cartLineNew.setQuantity(cartItem.getQuantity());
                cartLineNew.setCartId(cartId);
                cartLineNew.setActualPrice((float) cartItem.getSellingPrice());
                cartLineNew.setCreateTimestamp(LocalDateTime.now());
                cartLineRepository.persist(cartLineNew);
            }
        }

    }

    @Override
    public void addAddressToCart(int cartId, long addressId) throws ProfitMandiBusinessException {
        Cart cart = cartRepository.selectById(cartId);
        cart.setAddressId((int) addressId);

    }

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

    }

    @Override
    public CartModel removeFromCart(int cartId, int itemId) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public List<FocusedShortageModel> focusedModelShortageValidation(int fofoId,
                                                                     Map<Integer, Integer> catalogCartQtyMap) throws ProfitMandiBusinessException {

        Map<Integer, Long> inStockItemModel = currentInventorySnapshotRepository.selectSumInMobileStockGroupByCatalog(fofoId).stream()
                .collect(Collectors.toMap(x -> x.getCatalogItemId(), x -> x.getQty()));

        Map<Integer, Long> itempendingIndent = transactionService.getInTransitOrders(fofoId).stream()
                .collect(Collectors.groupingBy(x -> x.getLineItem().getItem().getCatalogItemId(),
                        Collectors.summingLong(x -> (long) x.getLineItem().getQuantity())));

        Map<Integer, Long> grnItemPendingOrders = orderRepository.selectPendingGrnOrders(fofoId).stream()
                .collect(Collectors.groupingBy(x -> x.getLineItem().getItem().getCatalogItemId(),
                        Collectors.summingLong(x -> (long) x.getLineItem().getQuantity())));

        FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);

        List<String> retailerBlockBrands = retailerBlockBrandRepository.selectAllByRetailer(fofoId).stream()
                .map(x -> x.getBlockBrands()).collect(Collectors.toList());

        List<PartnerRegion> partnerRegions = partnerRegionRepository.selectByfofoId(fofoId);
        Map<Integer, Integer> focusedModelMap;
        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<>();
        }

        return focusedModelShortageValidation(fofoId, catalogCartQtyMap, inStockItemModel,
                itempendingIndent, grnItemPendingOrders, fofoStore, retailerBlockBrands, focusedModelMap);
    }

    @Override
    public List<FocusedShortageModel> focusedModelShortageValidation(int fofoId,
                                                                     Map<Integer, Integer> catalogCartQtyMap,
                                                                     Map<Integer, Long> inStockItemModel,
                                                                     Map<Integer, Long> itempendingIndent,
                                                                     Map<Integer, Long> grnItemPendingOrders,
                                                                     FofoStore fofoStore,
                                                                     List<String> retailerBlockBrands,
                                                                     Map<Integer, Integer> focusedModelMap) 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, 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<SaholicCISTable> currentAvailability = saholicCISTableRepository.selectByItemWarehouse(item.getId(), fofoStore.getWarehouseId());

                if (currentAvailability != null) {
                    allColorNetAvailability += currentAvailability.stream()
                            .collect(Collectors.summingInt(SaholicCISTable::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 zero
            long 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 zero
                        long 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<SaholicCISTable> ca = saholicCISTableRepository.selectByItemWarehouse(i.getId(), fofoStore.getWarehouseId());
                    if (ca != null) {
                        itemQtyMap.put(i.getId(),
                                ca.stream().collect(Collectors.summingInt(SaholicCISTable::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;
    }

    @Override
    public UserCart setCartItems(int fofoId, List<CartItem> cartItems) throws ProfitMandiBusinessException {
        User user = saholicUserRepository.selectById(fofoId);
        this.clearCart(user.getActiveCartId());
        this.addItemsToCart(user.getActiveCartId(), cartItems);

        UserCart userCart = new UserCart();
        userCart.setCartId(user.getActiveCartId());
        userCart.setUserId(user.getId());
        return userCart;
    }

}