Rev 22955 | Rev 23297 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.spice.profitmandi.service.scheme;import java.time.LocalDateTime;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import com.spice.profitmandi.common.enumuration.DateTimePattern;import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;import com.spice.profitmandi.common.model.CreateSchemeRequest;import com.spice.profitmandi.common.model.ProfitMandiConstants;import com.spice.profitmandi.common.model.SchemeModel;import com.spice.profitmandi.common.util.StringUtils;import com.spice.profitmandi.dao.entity.catalog.RetailerScheme;import com.spice.profitmandi.dao.entity.catalog.Scheme;import com.spice.profitmandi.dao.entity.fofo.FofoLineItem;import com.spice.profitmandi.dao.entity.fofo.FofoOrderItem;import com.spice.profitmandi.dao.entity.fofo.InventoryItem;import com.spice.profitmandi.dao.entity.fofo.SchemeInOut;import com.spice.profitmandi.dao.entity.fofo.SchemeItem;import com.spice.profitmandi.dao.enumuration.catalog.SchemeAmountType;import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;import com.spice.profitmandi.dao.repository.catalog.ItemRepository;import com.spice.profitmandi.dao.repository.catalog.RetailerSchemeRepository;import com.spice.profitmandi.dao.repository.catalog.SchemeRepository;import com.spice.profitmandi.dao.repository.dtr.RetailerRepository;import com.spice.profitmandi.dao.repository.fofo.FofoLineItemRepository;import com.spice.profitmandi.dao.repository.fofo.FofoOrderItemRepository;import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;import com.spice.profitmandi.dao.repository.fofo.SchemeInOutRepository;import com.spice.profitmandi.dao.repository.fofo.SchemeItemRepository;import com.spice.profitmandi.service.inventory.OrderService;import com.spice.profitmandi.service.wallet.WalletService;import in.shop2020.model.v1.catalog.ItemType;import in.shop2020.model.v1.order.WalletReferenceType;@Componentpublic class SchemeServiceImpl implements SchemeService {private static final Logger LOGGER = LoggerFactory.getLogger(SchemeServiceImpl.class);@Autowiredprivate InventoryItemRepository inventoryItemRepository;@Autowiredprivate OrderService orderService;@Autowiredprivate SchemeRepository schemeRepository;@Autowiredprivate RetailerRepository retailerRepository;@Autowiredprivate RetailerSchemeRepository retailerSchemeRepository;@Autowiredprivate SchemeInOutRepository schemeInOutRepository;@Autowiredprivate ItemRepository itemRepository;@Autowiredprivate SchemeItemRepository schemeItemRepository;@Autowiredprivate WalletService walletService;@Autowiredprivate FofoOrderItemRepository fofoOrderItemRepository;@Autowiredprivate FofoLineItemRepository fofoLineItemRepository;@Overridepublic void saveScheme(int creatorId, CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException {this.validateCreateSchemeRequest(createSchemeRequest);Scheme scheme = this.toScheme(creatorId, createSchemeRequest);if(scheme.getStartDateTime().isAfter(scheme.getEndDateTime())){throw new ProfitMandiBusinessException(ProfitMandiConstants.START_DATE + ", " + ProfitMandiConstants.END_DATE, scheme.getStartDateTime() + ", " + scheme.getEndDateTime(), "SCHM_VE_1005");}this.validateItemIds(createSchemeRequest);schemeRepository.persist(scheme);if(!createSchemeRequest.isRetailerAll()){this.validateRetailerIds(createSchemeRequest);for(int retailerId : createSchemeRequest.getRetailerIds()){RetailerScheme retailerScheme = new RetailerScheme();retailerScheme.setRetailerId(retailerId);retailerScheme.setSchemeId(scheme.getId());retailerSchemeRepository.persist(retailerScheme);}}for(int itemId : createSchemeRequest.getItemIds()){SchemeItem schemeItem = new SchemeItem();schemeItem.setSchemeId(scheme.getId());schemeItem.setItemId(itemId);schemeItemRepository.persist(schemeItem);}}private void validateCreateSchemeRequest(CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException{if(createSchemeRequest.getName() == null || createSchemeRequest.getName().isEmpty()){throw new ProfitMandiBusinessException(ProfitMandiConstants.NAME, createSchemeRequest.getName(), "SCHM_VE_1000");}if(createSchemeRequest.getAmount() <= 0){throw new ProfitMandiBusinessException(ProfitMandiConstants.AMOUNT, createSchemeRequest.getAmount(), "SCHM_VE_1001");}if(SchemeAmountType.valueOf(createSchemeRequest.getAmountType()) == SchemeAmountType.PERCENTAGE && createSchemeRequest.getAmount() > 100){throw new ProfitMandiBusinessException(ProfitMandiConstants.AMOUNT, createSchemeRequest.getAmount(), "SCHM_VE_1002");}if(createSchemeRequest.getStartDateTimeString() == null || createSchemeRequest.getStartDateTimeString().isEmpty()){throw new ProfitMandiBusinessException(ProfitMandiConstants.START_DATE, createSchemeRequest.getStartDateTimeString(), "SCHM_VE_1003");}if(createSchemeRequest.getEndDateTimeString() == null || createSchemeRequest.getStartDateTimeString().isEmpty()){throw new ProfitMandiBusinessException(ProfitMandiConstants.END_DATE, createSchemeRequest.getEndDateTimeString(), "SCHM_VE_1004");}}private Scheme toScheme(int creatorId, CreateSchemeRequest createSchemeRequest){Scheme scheme = new Scheme();scheme.setName(createSchemeRequest.getName());scheme.setDescription(createSchemeRequest.getDescription());scheme.setType(SchemeType.valueOf(createSchemeRequest.getType()));scheme.setAmountType(SchemeAmountType.valueOf(createSchemeRequest.getAmountType()));scheme.setAmount(createSchemeRequest.getAmount());scheme.setStartDateTime(StringUtils.toDateTime(createSchemeRequest.getStartDateTimeString(), DateTimePattern.DD_MM_YYYY_T_HH_MM_SS));scheme.setEndDateTime(StringUtils.toDateTime(createSchemeRequest.getEndDateTimeString(), DateTimePattern.DD_MM_YYYY_T_HH_MM_SS));scheme.setCreatedBy(creatorId);scheme.setRetailerAll(createSchemeRequest.isRetailerAll());return scheme;}private void validateRetailerIds(CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException{if(createSchemeRequest.getRetailerIds() == null || createSchemeRequest.getRetailerIds().isEmpty()){throw new ProfitMandiBusinessException(ProfitMandiConstants.RETAILER_ID, createSchemeRequest.getRetailerIds(), "SCHM_1001");}List<Integer> foundRetailerIds = retailerRepository.selectIdsByIds(createSchemeRequest.getRetailerIds());if(foundRetailerIds.size() != createSchemeRequest.getRetailerIds().size()){createSchemeRequest.getRetailerIds().removeAll(foundRetailerIds);throw new ProfitMandiBusinessException(ProfitMandiConstants.RETAILER_ID, createSchemeRequest.getRetailerIds(), "SCHM_1002");}}private void validateItemIds(CreateSchemeRequest createSchemeRequest) throws ProfitMandiBusinessException{if(createSchemeRequest.getItemIds() == null || createSchemeRequest.getItemIds().isEmpty()){throw new ProfitMandiBusinessException(ProfitMandiConstants.ITEM_ID, createSchemeRequest.getItemIds(), "SCHM_1003");}List<Integer> foundItemIds = itemRepository.selectIdsByIdsAndType(createSchemeRequest.getItemIds(), ItemType.SERIALIZED);if(foundItemIds.size() != createSchemeRequest.getItemIds().size()){createSchemeRequest.getItemIds().removeAll(foundItemIds);throw new ProfitMandiBusinessException(ProfitMandiConstants.ITEM_ID, createSchemeRequest.getItemIds(), "SCHM_1004");}}@Overridepublic Scheme getSchemeById(int schemeId) throws ProfitMandiBusinessException {Scheme scheme = schemeRepository.selectById(schemeId);if(!scheme.isRetailerAll()){List<Integer> retailerIds = retailerSchemeRepository.selectRetailerIdsBySchemeId(scheme.getId());scheme.getRetailerIds().addAll(retailerIds);}List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(scheme.getId());scheme.setItemIds(new HashSet<>(itemIds));return scheme;}@Overridepublic List<SchemeModel> getAllSchemeModels(LocalDateTime startDateTime, LocalDateTime endDateTime) {List<Scheme> schemes = schemeRepository.selectAllBetweenCreateTimestamp(startDateTime, endDateTime);Map<Integer, Scheme> schemeIdSchemeMap = this.toSchemeIdSchemeMap(schemes);List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIds(schemeIdSchemeMap.keySet());this.addItemIdsToSchemes(schemeItems, schemeIdSchemeMap);List<RetailerScheme> retailerSchemes = retailerSchemeRepository.selectBySchemeIds(schemeIdSchemeMap.keySet());this.addRetailerIdsToSchemes(retailerSchemes, schemeIdSchemeMap);return this.toSchemeModels(schemeIdSchemeMap);}private void addItemIdsToSchemes(List<SchemeItem> schemeItems, Map<Integer, Scheme> schemeIdSchemeMap){for(SchemeItem schemeItem : schemeItems){schemeIdSchemeMap.get(schemeItem.getSchemeId()).getItemIds().add(schemeItem.getItemId());}}private void addRetailerIdsToSchemes(List<RetailerScheme> retailerSchemes, Map<Integer, Scheme> schemeIdSchemeMap){for(RetailerScheme retailerScheme : retailerSchemes){schemeIdSchemeMap.get(retailerScheme.getSchemeId()).getRetailerIds().add(retailerScheme.getRetailerId());}}private List<SchemeModel> toSchemeModels(Map<Integer, Scheme> schemeIdSchemeMap){List<SchemeModel> schemeModels = new ArrayList<>();for(Map.Entry<Integer, Scheme> schemeIdSchemeEntry : schemeIdSchemeMap.entrySet()){schemeModels.add(this.toSchemeModel(schemeIdSchemeEntry.getValue()));}return schemeModels;}private SchemeModel toSchemeModel(Scheme scheme){SchemeModel schemeModel = new SchemeModel();schemeModel.setSchemeId(scheme.getId());schemeModel.setName(scheme.getName());schemeModel.setDescription(scheme.getDescription());schemeModel.setSchemeType(scheme.getType().toString());schemeModel.setAmountType(scheme.getAmountType().toString());schemeModel.setAmount(scheme.getAmount());schemeModel.setStartDateTime(StringUtils.toString(scheme.getStartDateTime()));schemeModel.setEndDateTime(StringUtils.toString(scheme.getEndDateTime()));schemeModel.setCreateTimestamp(StringUtils.toString(scheme.getCreateTimestamp()));schemeModel.setActiveTimestamp(StringUtils.toString(scheme.getActiveTimestamp()));schemeModel.setExpireTimestamp(StringUtils.toString(scheme.getExpireTimestamp()));schemeModel.setCreatedBy(scheme.getCreatedBy());schemeModel.setItemIds(scheme.getItemIds());schemeModel.setRetailerIds(scheme.getRetailerIds());return schemeModel;}@Overridepublic void activeSchemeById(int schemeId) throws ProfitMandiBusinessException {Scheme scheme = schemeRepository.selectById(schemeId);if(scheme.getActiveTimestamp() != null){throw new ProfitMandiBusinessException(ProfitMandiConstants.ACTIVE_TIMESTAMP, scheme.getActiveTimestamp(), "SCHM_1005");}if(scheme.getExpireTimestamp() != null){throw new ProfitMandiBusinessException(ProfitMandiConstants.EXPIRE_TIMESTAMP, scheme.getExpireTimestamp(), "SCHM_1006");}scheme.setActiveTimestamp(LocalDateTime.now());schemeRepository.persist(scheme);if(scheme.getType() == SchemeType.IN){this.processPreviousPurchases(scheme);}else if(scheme.getType() == SchemeType.OUT){this.processPreviousSales(scheme);}}private void processPreviousPurchases(Scheme scheme) throws ProfitMandiBusinessException{List<InventoryItem> inventoryItems = inventoryItemRepository.selectBetweenDates(scheme.getStartDateTime(), LocalDateTime.now());List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(scheme.getId());List<InventoryItem> completedInventoryItems = this.toFilteredPurchaseCompletedInventoryItems(inventoryItems, itemIds, true);if(scheme.isRetailerAll()){for(InventoryItem inventoryItem : completedInventoryItems){float cashback = this.createSchemeInOut(scheme, inventoryItem);walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItem.getPurchaseId(), WalletReferenceType.SCHEME_IN, "Added for SCHEME_IN", cashback);}}else{List<Integer> retailerIds = retailerSchemeRepository.selectRetailerIdsBySchemeId(scheme.getId());for(InventoryItem inventoryItem : completedInventoryItems){if(retailerIds.contains(inventoryItem.getFofoId())){float cashback = this.createSchemeInOut(scheme, inventoryItem);walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItem.getPurchaseId(), WalletReferenceType.SCHEME_IN, "Added for SCHEME_IN", cashback);}}}}private Map<Integer, Integer> toInventoryItemIdFofoOrderMap(List<FofoLineItem> fofoLineItems, Map<Integer, FofoOrderItem> fofoOrderItemIdFofoOrderItemMap){Map<Integer, Integer> inventoryItemIdFofoOrderIdMap = new HashMap<>();for(FofoLineItem fofoLineItem : fofoLineItems){inventoryItemIdFofoOrderIdMap.put(fofoLineItem.getInventoryItemId(),fofoOrderItemIdFofoOrderItemMap.get(fofoLineItem.getFofoOrderItemId()).getOrderId());}return inventoryItemIdFofoOrderIdMap;}private void processPreviousSales(Scheme scheme) throws ProfitMandiBusinessException{List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectBetweenDates(scheme.getStartDateTime(), LocalDateTime.now());Map<Integer, FofoOrderItem> fofoOrderItemIdFofoOrderItemMap = this.toFofoOrderItemIdFofoOrderItemMap(fofoOrderItems);List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIdFofoOrderItemMap.keySet());Map<Integer, Integer> inventoryItemIdFofoOrderIdMap = this.toInventoryItemIdFofoOrderMap(fofoLineItems, fofoOrderItemIdFofoOrderItemMap);List<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIdFofoOrderIdMap.keySet());List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(scheme.getId());List<InventoryItem> completedInventoryItems = this.toFilteredPurchaseCompletedInventoryItems(inventoryItems, itemIds, false);if(scheme.isRetailerAll()){for(InventoryItem inventoryItem : completedInventoryItems){float cashback = this.createSchemeInOut(scheme, inventoryItem);walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItem.getPurchaseId(), WalletReferenceType.SCHEME_IN, "Added for SCHEME_IN", cashback);}}else{List<Integer> retailerIds = retailerSchemeRepository.selectRetailerIdsBySchemeId(scheme.getId());for(InventoryItem inventoryItem : completedInventoryItems){if(retailerIds.contains(inventoryItem.getFofoId())){float cashback = this.createSchemeInOut(scheme, inventoryItem);walletService.addAmountToWallet(inventoryItem.getFofoId(), inventoryItemIdFofoOrderIdMap.get(inventoryItem.getId()), WalletReferenceType.SCHEME_IN, "Added for SCHEME_IN", cashback);}}}}private Map<Integer, FofoOrderItem> toFofoOrderItemIdFofoOrderItemMap(List<FofoOrderItem> fofoOrderItems){Map<Integer, FofoOrderItem> fofoOrderItemIdFofoOrderItemMap = new HashMap<>();for(FofoOrderItem fofoOrderItem : fofoOrderItems){fofoOrderItemIdFofoOrderItemMap.put(fofoOrderItem.getId(), fofoOrderItem);}return fofoOrderItemIdFofoOrderItemMap;}private List<InventoryItem> toFilteredPurchaseCompletedInventoryItems(List<InventoryItem> inventoryItems, List<Integer> itemIds, boolean purchase){List<InventoryItem> completedInventoryItems = new ArrayList<>();for(InventoryItem inventoryItem : inventoryItems){if(purchase && inventoryItem.getPurchase().getCompleteTimestamp() != null && itemIds.contains(inventoryItem.getItemId())){completedInventoryItems.add(inventoryItem);}else if(itemIds.contains(inventoryItem.getItemId())){}}return completedInventoryItems;}//private List<InventoryItem> to@Overridepublic void expireSchemeById(int schemeId) throws ProfitMandiBusinessException {Scheme scheme = schemeRepository.selectById(schemeId);if(scheme.getActiveTimestamp() == null){throw new ProfitMandiBusinessException(ProfitMandiConstants.ACTIVE_TIMESTAMP, scheme.getActiveTimestamp(), "SCHM_1007");}if(scheme.getExpireTimestamp() != null){throw new ProfitMandiBusinessException(ProfitMandiConstants.EXPIRE_TIMESTAMP, scheme.getExpireTimestamp(), "SCHM_1008");}scheme.setExpireTimestamp(LocalDateTime.now());schemeRepository.persist(scheme);}private Map<Integer, Scheme> toSchemeIdSchemeMap(List<Scheme> schemes){Map<Integer, Scheme> schemeIdSchemeMap = new HashMap<>();for(Scheme scheme : schemes){schemeIdSchemeMap.put(scheme.getId(), scheme);}return schemeIdSchemeMap;}private Set<Integer> inventoryItemSchemesMapToSchemeIds(Map<InventoryItem, Set<Scheme>> inventoryItemSchemesMap){Set<Integer> schemeIds = new HashSet<>();for(Map.Entry<InventoryItem, Set<Scheme>> inventoryItemSchemesEntry : inventoryItemSchemesMap.entrySet()){for(Scheme scheme : inventoryItemSchemesEntry.getValue()){schemeIds.add(scheme.getId());}}return schemeIds;}private Set<Integer> fofoLineItemSchemesMapToSchemeIds(Map<FofoOrderItem, Set<Scheme>> fofoLineItemSchemesMap){Set<Integer> schemeIds = new HashSet<>();for(Map.Entry<FofoOrderItem, Set<Scheme>> inventoryItemSchemesEntry : fofoLineItemSchemesMap.entrySet()){for(Scheme scheme : inventoryItemSchemesEntry.getValue()){schemeIds.add(scheme.getId());}}return schemeIds;}private Set<Integer> inventoryItemsToItemIds(List<InventoryItem> inventoryItems){Set<Integer> itemIds = new HashSet<>();for(InventoryItem inventoryItem : inventoryItems){itemIds.add(inventoryItem.getItemId());}return itemIds;}private Set<Integer> fofoOrderItemsToItemIds(List<FofoOrderItem> fofoOrderItems){Set<Integer> itemIds = new HashSet<>();for(FofoOrderItem fofoOrderItem : fofoOrderItems){itemIds.add(fofoOrderItem.getItemId());}return itemIds;}private Map<Integer, Set<Scheme>> toItemIdSchemesMap(List<SchemeItem> schemeItems, List<Scheme> schemes){Map<Integer, Scheme> schemeIdSchemesMap = this.toSchemeIdSchemeMap(schemes);Map<Integer, Set<Scheme>> itemIdSchemesMap = new HashMap<>();for(SchemeItem schemeItem : schemeItems){if(!itemIdSchemesMap.containsKey(schemeItem.getItemId())){Set<Scheme> schemesSet = new HashSet<>();schemesSet.add(schemeIdSchemesMap.get(schemeItem.getSchemeId()));itemIdSchemesMap.put(schemeItem.getItemId(), schemesSet);}else{itemIdSchemesMap.get(schemeItem.getItemId()).add(schemeIdSchemesMap.get(schemeItem.getSchemeId()));}}return itemIdSchemesMap;}private Map<InventoryItem, Set<Scheme>> toInventoryItemSchemesMap(List<Scheme> schemes, List<InventoryItem> inventoryItems){Set<Integer> schemeIds = new HashSet<>();for(Scheme scheme : schemes){schemeIds.add(scheme.getId());}Set<Integer> itemIds = this.inventoryItemsToItemIds(inventoryItems);List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIdsAndItemIds(schemeIds, itemIds);Map<Integer, Set<Scheme>> itemIdSchemesMap = this.toItemIdSchemesMap(schemeItems, schemes);Map<InventoryItem, Set<Scheme>> inventoryItemSchemsMap = new HashMap<>();for(InventoryItem inventoryItem : inventoryItems){if(itemIdSchemesMap.containsKey(inventoryItem.getItemId())){inventoryItemSchemsMap.put(inventoryItem, itemIdSchemesMap.get(inventoryItem.getItemId()));}}return inventoryItemSchemsMap;}private Map<FofoOrderItem, Set<Scheme>> toFofoOrderItemSchemesMap(List<Scheme> schemes, List<FofoOrderItem> fofoOrderItems){Set<Integer> schemeIds = new HashSet<>();for(Scheme scheme : schemes){schemeIds.add(scheme.getId());}Set<Integer> itemIds = this.fofoOrderItemsToItemIds(fofoOrderItems);List<SchemeItem> schemeItems = schemeItemRepository.selectBySchemeIdsAndItemIds(schemeIds, itemIds);Map<FofoOrderItem, Set<Scheme>> fofoOrderItemSchemsMap = new HashMap<>();if(!schemeItems.isEmpty()){Map<Integer, Set<Scheme>> itemIdSchemesMap = this.toItemIdSchemesMap(schemeItems, schemes);for(FofoOrderItem fofoOrderItem : fofoOrderItems){if(itemIdSchemesMap.containsKey(fofoOrderItem.getItemId())){fofoOrderItemSchemsMap.put(fofoOrderItem, itemIdSchemesMap.get(fofoOrderItem.getItemId()));}}}return fofoOrderItemSchemsMap;}@Overridepublic float processSchemeIn(int purchaseId, int retailerId) throws ProfitMandiBusinessException {List<Scheme> schemes = schemeRepository.selectActiveAll(SchemeType.IN, LocalDateTime.now());float totalCashback = 0;if(schemes.isEmpty()){return 0;}List<InventoryItem> inventoryItems = inventoryItemRepository.selectByPurchaseId(purchaseId);LOGGER.info("SchemeIn filter inventoryItems {}", inventoryItems);Map<InventoryItem, Set<Scheme>> inventoryItemSchemesMap = this.toInventoryItemSchemesMap(schemes, inventoryItems);if(inventoryItemSchemesMap.isEmpty()){return 0;}Map<InventoryItem, Set<Scheme>> notAllInventoryItemSchemesMap = new HashMap<>();Map<InventoryItem, Set<Scheme>> allInventoryItemSchemesMap = new HashMap<>();for(Map.Entry<InventoryItem, Set<Scheme>> inventoryItemSchemesEntry : inventoryItemSchemesMap.entrySet()){Set<Scheme> notAllSchemes = new HashSet<>();Set<Scheme> allSchemes = new HashSet<>();for(Scheme scheme : inventoryItemSchemesEntry.getValue()){if(!scheme.isRetailerAll()){notAllSchemes.add(scheme);}else{allSchemes.add(scheme);}}notAllInventoryItemSchemesMap.put(inventoryItemSchemesEntry.getKey(), notAllSchemes);allInventoryItemSchemesMap.put(inventoryItemSchemesEntry.getKey(), allSchemes);}for(Map.Entry<InventoryItem, Set<Scheme>> allInventoryItemSchemesEntry : allInventoryItemSchemesMap.entrySet()){for(Scheme scheme : allInventoryItemSchemesEntry.getValue()){float cashback = this.createSchemeInOut(scheme, allInventoryItemSchemesEntry.getKey());totalCashback = totalCashback + cashback;}}Set<Integer> schemeIds = this.inventoryItemSchemesMapToSchemeIds(notAllInventoryItemSchemesMap);if(!schemeIds.isEmpty()){List<Integer> foundSchemeIds = retailerSchemeRepository.selectSchemeIds(schemeIds, retailerId);for(Map.Entry<InventoryItem, Set<Scheme>> notAllInventoryItemSchemesEntry : notAllInventoryItemSchemesMap.entrySet()){for(Scheme scheme : notAllInventoryItemSchemesEntry.getValue()){if(foundSchemeIds.contains(scheme.getId())){float cashback = this.createSchemeInOut(scheme, notAllInventoryItemSchemesEntry.getKey());totalCashback = totalCashback + cashback;}}}}if(totalCashback > 0){walletService.addAmountToWallet(retailerId, purchaseId, WalletReferenceType.SCHEME_IN, "Added for SCHEME_IN", totalCashback);}return totalCashback;}private float createSchemeInOut(Scheme scheme, InventoryItem inventoryItem){float amount = this.getAmount(inventoryItem, scheme);SchemeInOut schemeInOut = new SchemeInOut();schemeInOut.setSchemeId(scheme.getId());schemeInOut.setInventoryItemId(inventoryItem.getId());schemeInOut.setAmount(amount);schemeInOutRepository.persist(schemeInOut);return amount;}private float getAmount(InventoryItem inventoryItem, Scheme scheme){float amount = 0;float totalTaxRate = inventoryItem.getIgstRate() + inventoryItem.getSgstRate() + inventoryItem.getCgstRate();float taxableSellingPrice = inventoryItem.getUnitPrice() / (1 + totalTaxRate / 100);if(scheme.getAmountType() == SchemeAmountType.PERCENTAGE){amount = taxableSellingPrice * scheme.getAmount() / 100;}else{amount = scheme.getAmount();}return amount;}private Map<Integer, InventoryItem> toInventoryItemIdInventoryItemMap(List<InventoryItem> inventoryItems){Map<Integer, InventoryItem> itemIdInventoryItemMap = new HashMap<>();for(InventoryItem inventoryItem : inventoryItems){itemIdInventoryItemMap.put(inventoryItem.getId(), inventoryItem);}return itemIdInventoryItemMap;}private Set<Integer> toInventoryItemIds(Set<FofoOrderItem> fofoOrderItems){Set<Integer> inventoryItemIds = new HashSet<>();//Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = this.toFofoOrderItemIdFofoLineItems(fofoOrderItems);for(FofoOrderItem fofoOrderItem : fofoOrderItems){for(FofoLineItem fofoLineItem : fofoOrderItem.getFofoLineItems()){inventoryItemIds.add(fofoLineItem.getInventoryItemId());}}return inventoryItemIds;}@Overridepublic float processSchemeOut(int fofoOrderId, int retailerId) throws ProfitMandiBusinessException {List<Scheme> schemes = schemeRepository.selectActiveAll(SchemeType.OUT, LocalDateTime.now());LOGGER.info("Active Schemes {}", schemes);float totalCashback = 0;if(schemes.isEmpty()){return 0;}List<FofoOrderItem> fofoOrderItems = orderService.getByOrderId(fofoOrderId);//LOGGER.info("fofoOrderItems {}", fofoOrderItems);Map<FofoOrderItem, Set<Scheme>> fofoOrderItemSchemesMap = this.toFofoOrderItemSchemesMap(schemes, fofoOrderItems);LOGGER.info("fofoOrderItemSchemesMap {}", fofoOrderItemSchemesMap);if(fofoOrderItemSchemesMap.isEmpty()){return 0;}Set<Integer> inventoryItemIds = this.toInventoryItemIds(fofoOrderItemSchemesMap.keySet());List<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIds);Map<Integer, InventoryItem> inventoryItemIdInventoryItemMap = this.toInventoryItemIdInventoryItemMap(inventoryItems);Map<FofoOrderItem, Set<Scheme>> notAllFofoOrderItemSchemesMap = new HashMap<>();Map<FofoOrderItem, Set<Scheme>> allFofoOrderItemSchemesMap = new HashMap<>();for(Map.Entry<FofoOrderItem, Set<Scheme>> fofoOrderItemSchemesEntry : fofoOrderItemSchemesMap.entrySet()){Set<Scheme> notAllSchemes = new HashSet<>();Set<Scheme> allSchemes = new HashSet<>();for(Scheme scheme : fofoOrderItemSchemesEntry.getValue()){if(!scheme.isRetailerAll()){notAllSchemes.add(scheme);}else{allSchemes.add(scheme);}}notAllFofoOrderItemSchemesMap.put(fofoOrderItemSchemesEntry.getKey(), notAllSchemes);allFofoOrderItemSchemesMap.put(fofoOrderItemSchemesEntry.getKey(), allSchemes);}for(Map.Entry<FofoOrderItem, Set<Scheme>> allFofoOrderItemSchemesEntry : allFofoOrderItemSchemesMap.entrySet()){for(FofoLineItem fofoLineItem : allFofoOrderItemSchemesEntry.getKey().getFofoLineItems()){for(Scheme scheme : allFofoOrderItemSchemesEntry.getValue()){float cashback = this.createSchemeInOut(scheme, inventoryItemIdInventoryItemMap.get(fofoLineItem.getInventoryItemId()));totalCashback = totalCashback + cashback;}}}Set<Integer> schemeIds = this.fofoLineItemSchemesMapToSchemeIds(notAllFofoOrderItemSchemesMap);if(!schemeIds.isEmpty()){List<Integer> foundSchemeIds = retailerSchemeRepository.selectSchemeIds(schemeIds, retailerId);for(Map.Entry<FofoOrderItem, Set<Scheme>> notAllFofoOrderItemSchemesEntry : notAllFofoOrderItemSchemesMap.entrySet()){for(FofoLineItem fofoLineItem : notAllFofoOrderItemSchemesEntry.getKey().getFofoLineItems()){for(Scheme scheme : notAllFofoOrderItemSchemesEntry.getValue()){if(foundSchemeIds.contains(scheme.getId())){float cashback = this.createSchemeInOut(scheme, inventoryItemIdInventoryItemMap.get(fofoLineItem.getInventoryItemId()));totalCashback = totalCashback + cashback;}}}}}if(totalCashback > 0){walletService.addAmountToWallet(retailerId, fofoOrderId, WalletReferenceType.SCHEME_OUT, "Added for SCHEME_OUT", totalCashback);}return totalCashback;}}