Rev 22925 | Rev 23019 | 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.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.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.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;@Overridepublic void saveScheme(int creatorId, 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.getStartDateString() == null || createSchemeRequest.getStartDateString().isEmpty()){throw new ProfitMandiBusinessException(ProfitMandiConstants.START_DATE, createSchemeRequest.getStartDateString(), "SCHM_VE_1003");}if(createSchemeRequest.getEndDateString() == null || createSchemeRequest.getStartDateString().isEmpty()){throw new ProfitMandiBusinessException(ProfitMandiConstants.END_DATE, createSchemeRequest.getEndDateString(), "SCHM_VE_1004");}Scheme scheme = this.toScheme(creatorId, createSchemeRequest);if(scheme.getStartDate().isAfter(scheme.getEndDate())){throw new ProfitMandiBusinessException(ProfitMandiConstants.START_DATE + ", " + ProfitMandiConstants.END_DATE, scheme.getStartDate() + ", " + scheme.getEndDate(), "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 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.setStartDate(StringUtils.toDateTime(createSchemeRequest.getStartDateString(), DateTimePattern.YYYY_MM_DD_T_HH_MM));scheme.setEndDate(StringUtils.toDateTime(createSchemeRequest.getEndDateString(), DateTimePattern.YYYY_MM_DD_T_HH_MM));if(createSchemeRequest.isActive()){scheme.setActiveTimestamp(LocalDateTime.now());}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<RetailerScheme> retailerSchemes = retailerSchemeRepository.selectBySchemeId(scheme.getId());for(RetailerScheme retailerScheme : retailerSchemes){scheme.getRetailerIds().add(retailerScheme.getRetailerId());}}List<Integer> itemIds = schemeItemRepository.selectItemIdsBySchemeId(scheme.getId());scheme.setItemIds(new HashSet<>(itemIds));return scheme;}@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);}@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> toSchemeIdSchemesMap(List<Scheme> schemes){Map<Integer, Scheme> schemeIdSchemesMap = new HashMap<>();for(Scheme scheme : schemes){schemeIdSchemesMap.put(scheme.getId(), scheme);}return schemeIdSchemesMap;}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.toSchemeIdSchemesMap(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;}}