Rev 28339 | Rev 28456 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.spice.profitmandi.service.order;import java.time.LocalDate;import java.time.LocalDateTime;import java.time.LocalTime;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Optional;import java.util.Random;import java.util.Set;import java.util.AbstractMap.SimpleEntry;import java.util.function.Function;import java.util.stream.Collectors;import javax.persistence.criteria.CriteriaBuilder;import javax.persistence.criteria.CriteriaQuery;import javax.persistence.criteria.Predicate;import javax.persistence.criteria.Root;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.json.JSONObject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Component;import com.mongodb.MongoClient;import com.spice.profitmandi.common.enumuration.ItemType;import com.spice.profitmandi.common.enumuration.SearchType;import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;import com.spice.profitmandi.common.model.BadReturnRequest;import com.spice.profitmandi.common.model.CartFofo;import com.spice.profitmandi.common.model.CreateOrderRequest;import com.spice.profitmandi.common.model.CreditNotePdfModel;import com.spice.profitmandi.common.model.CustomAddress;import com.spice.profitmandi.common.model.CustomCustomer;import com.spice.profitmandi.common.model.CustomFofoOrderItem;import com.spice.profitmandi.common.model.CustomInsurancePolicy;import com.spice.profitmandi.common.model.CustomLineItem;import com.spice.profitmandi.common.model.CustomOrderItem;import com.spice.profitmandi.common.model.CustomPaymentOption;import com.spice.profitmandi.common.model.CustomRetailer;import com.spice.profitmandi.common.model.FoiBadReturnRequest;import com.spice.profitmandi.common.model.GstRate;import com.spice.profitmandi.common.model.InsuranceModel;import com.spice.profitmandi.common.model.ItemIdQuantityAvailability;import com.spice.profitmandi.common.model.PdfModel;import com.spice.profitmandi.common.model.PriceModel;import com.spice.profitmandi.common.model.ProfitMandiConstants;import com.spice.profitmandi.common.model.Quantity;import com.spice.profitmandi.common.model.SerialNumberDetail;import com.spice.profitmandi.common.util.FormattingUtils;import com.spice.profitmandi.common.util.StringUtils;import com.spice.profitmandi.common.util.Utils;import com.spice.profitmandi.dao.entity.catalog.Item;import com.spice.profitmandi.dao.entity.catalog.TagListing;import com.spice.profitmandi.dao.entity.dtr.InsurancePolicy;import com.spice.profitmandi.dao.entity.dtr.PaymentOptionTransaction;import com.spice.profitmandi.dao.entity.dtr.Retailer;import com.spice.profitmandi.dao.entity.dtr.User;import com.spice.profitmandi.dao.entity.fofo.CurrentInventorySnapshot;import com.spice.profitmandi.dao.entity.fofo.Customer;import com.spice.profitmandi.dao.entity.fofo.CustomerAddress;import com.spice.profitmandi.dao.entity.fofo.CustomerCreditNote;import com.spice.profitmandi.dao.entity.fofo.CustomerReturnItem;import com.spice.profitmandi.dao.entity.fofo.FofoLineItem;import com.spice.profitmandi.dao.entity.fofo.FofoOrder;import com.spice.profitmandi.dao.entity.fofo.FofoOrderItem;import com.spice.profitmandi.dao.entity.fofo.FofoStore;import com.spice.profitmandi.dao.entity.fofo.HygieneData;import com.spice.profitmandi.dao.entity.fofo.InventoryItem;import com.spice.profitmandi.dao.entity.fofo.InvoiceNumberGenerationSequence;import com.spice.profitmandi.dao.entity.fofo.LiveDemoSerialNumber;import com.spice.profitmandi.dao.entity.fofo.PendingOrder;import com.spice.profitmandi.dao.entity.fofo.PendingOrderItem;import com.spice.profitmandi.dao.entity.fofo.ScanRecord;import com.spice.profitmandi.dao.entity.transaction.Order;import com.spice.profitmandi.dao.entity.user.Address;import com.spice.profitmandi.dao.entity.user.Counter;import com.spice.profitmandi.dao.entity.user.PrivateDealUser;import com.spice.profitmandi.dao.entity.warehouse.WarehouseInventoryItem;import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;import com.spice.profitmandi.dao.enumuration.dtr.PaymentOptionReferenceType;import com.spice.profitmandi.dao.enumuration.fofo.ReturnType;import com.spice.profitmandi.dao.enumuration.fofo.ScanType;import com.spice.profitmandi.dao.enumuration.fofo.SettlementType;import com.spice.profitmandi.dao.enumuration.transaction.OrderStatus;import com.spice.profitmandi.dao.repository.catalog.ItemRepository;import com.spice.profitmandi.dao.repository.catalog.StateGstRateRepository;import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;import com.spice.profitmandi.dao.repository.dtr.InsurancePolicyRepository;import com.spice.profitmandi.dao.repository.dtr.InsuranceProviderRepository;import com.spice.profitmandi.dao.repository.dtr.Mongo;import com.spice.profitmandi.dao.repository.dtr.PaymentOptionTransactionRepository;import com.spice.profitmandi.dao.repository.dtr.PolicyNumberGenerationSequenceRepository;import com.spice.profitmandi.dao.repository.dtr.RetailerRegisteredAddressRepository;import com.spice.profitmandi.dao.repository.dtr.RetailerRepository;import com.spice.profitmandi.dao.repository.dtr.UserAccountRepository;import com.spice.profitmandi.dao.repository.dtr.UserRepository;import com.spice.profitmandi.dao.repository.fofo.CurrentInventorySnapshotRepository;import com.spice.profitmandi.dao.repository.fofo.CustomerAddressRepository;import com.spice.profitmandi.dao.repository.fofo.CustomerCreditNoteRepository;import com.spice.profitmandi.dao.repository.fofo.CustomerRepository;import com.spice.profitmandi.dao.repository.fofo.CustomerReturnItemRepository;import com.spice.profitmandi.dao.repository.fofo.FofoLineItemRepository;import com.spice.profitmandi.dao.repository.fofo.FofoOrderItemRepository;import com.spice.profitmandi.dao.repository.fofo.FofoOrderRepository;import com.spice.profitmandi.dao.repository.fofo.HygieneDataRepository;import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;import com.spice.profitmandi.dao.repository.fofo.InvoiceNumberGenerationSequenceRepository;import com.spice.profitmandi.dao.repository.fofo.LiveDemoBillingRespository;import com.spice.profitmandi.dao.repository.fofo.PaymentOptionRepository;import com.spice.profitmandi.dao.repository.fofo.PendingOrderItemRepository;import com.spice.profitmandi.dao.repository.fofo.PendingOrderRepository;import com.spice.profitmandi.dao.repository.fofo.PurchaseReturnItemRepository;import com.spice.profitmandi.dao.repository.fofo.ScanRecordRepository;import com.spice.profitmandi.dao.repository.inventory.StateRepository;import com.spice.profitmandi.dao.repository.transaction.OrderRepository;import com.spice.profitmandi.dao.repository.user.AddressRepository;import com.spice.profitmandi.dao.repository.user.CounterRepository;import com.spice.profitmandi.dao.repository.user.PrivateDealUserRepository;import com.spice.profitmandi.dao.repository.warehouse.WarehouseInventoryItemRepository;import com.spice.profitmandi.service.integrations.zest.InsuranceService;import com.spice.profitmandi.service.inventory.InventoryService;import com.spice.profitmandi.service.inventory.PurchaseReturnService;import com.spice.profitmandi.service.inventory.SaholicInventoryService;import com.spice.profitmandi.service.offers.ItemCriteria;import com.spice.profitmandi.service.offers.PartnerCriteria;import com.spice.profitmandi.service.pricing.PricingService;import com.spice.profitmandi.service.scheme.SchemeService;import com.spice.profitmandi.service.user.RetailerService;import com.spice.profitmandi.service.wallet.WalletService;@Componentpublic class OrderServiceImpl implements OrderService {private static final Logger LOGGER = LogManager.getLogger(OrderServiceImpl.class);private static Map<String, Integer> serialNumberOrderIdMap = new HashMap<>();static {serialNumberOrderIdMap.put("862897055749275", 67228);}@Autowired@Qualifier("fofoInventoryItemRepository")private InventoryItemRepository inventoryItemRepository;@Autowiredprivate StateGstRateRepository stateGstRateRepository;@Autowiredprivate SaholicInventoryService saholicInventoryService;@Autowiredprivate LiveDemoBillingRespository liveDemoBillingRespository;@Autowiredprivate InsuranceService insuranceService;@Autowiredprivate WalletService walletService;@Autowired@Qualifier("fofoCurrentInventorySnapshotRepository")private CurrentInventorySnapshotRepository currentInventorySnapshotRepository;@Autowiredprivate InvoiceNumberGenerationSequenceRepository invoiceNumberGenerationSequenceRepository;@Autowiredprivate PurchaseReturnService purchaseReturnService;@Autowiredprivate RetailerService retailerService;@Autowiredprivate CustomerRepository customerRepository;@Autowiredprivate PurchaseReturnItemRepository purchaseReturnItemRepository;@Autowiredprivate AddressRepository addressRepository;@Autowiredprivate FofoLineItemRepository fofoLineItemRepository;@Autowiredprivate WarehouseInventoryItemRepository warehouseInventoryItemRepository;@Autowiredprivate FofoOrderItemRepository fofoOrderItemRepository;@Autowiredprivate PaymentOptionRepository paymentOptionRepository;@Autowiredprivate CustomerReturnItemRepository customerReturnItemRepository;@Autowired@Qualifier("fofoScanRecordRepository")private ScanRecordRepository scanRecordRepository;@Autowiredprivate FofoOrderRepository fofoOrderRepository;@Autowiredprivate RetailerRepository retailerRepository;@Autowiredprivate UserRepository userRepository;@Autowiredprivate UserAccountRepository userAccountRepository;@Autowiredprivate RetailerRegisteredAddressRepository retailerRegisteredAddressRepository;@Autowiredprivate CustomerAddressRepository customerAddressRepository;@Autowired@Qualifier("catalogItemRepository")private ItemRepository itemRepository;@Autowiredprivate InsuranceProviderRepository insuranceProviderRepository;@Autowiredprivate InsurancePolicyRepository insurancePolicyRepository;@Autowiredprivate StateRepository stateRepository;@Autowiredprivate PolicyNumberGenerationSequenceRepository policyNumberGenerationSequenceRepository;@Autowiredprivate PricingService pricingService;@Autowiredprivate PrivateDealUserRepository privateDealUserRepository;@Autowiredprivate TagListingRepository tagListingRepository;@Autowiredprivate CounterRepository counterRepository;@Autowiredprivate FofoStoreRepository fofoStoreRepository;@Autowiredprivate PaymentOptionTransactionRepository paymentOptionTransactionRepository;@Autowiredprivate SchemeService schemeService;private static final List<Integer> orderIdsConsumed = new ArrayList<>();@Autowired@Qualifier("fofoInventoryService")private InventoryService inventoryService;@Autowiredprivate CustomerCreditNoteRepository customerCreditNoteRepository;@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate HygieneDataRepository hygieneDataRepository;@Autowiredprivate SessionFactory sessionFactory;@Autowiredprivate Mongo mongoClient;@Autowiredprivate PendingOrderRepository pendingOrderRepository;@Autowiredprivate PendingOrderItemRepository pendingOrderItemRepository;@Overridepublic int createOrder(CreateOrderRequest createOrderRequest, int fofoId, boolean accessoriesDeals)throws ProfitMandiBusinessException {LOGGER.info("fofoId -- {} Order Request -- {}", fofoId, createOrderRequest);CustomCustomer customCustomer = createOrderRequest.getCustomer();if (!StringUtils.isValidGstNumber(customCustomer.getGstNumber())) {LOGGER.error("invalid customer gstNumber {} ", customCustomer.getGstNumber());throw new ProfitMandiBusinessException(ProfitMandiConstants.CUSTOMER_GST_NUMBER,customCustomer.getGstNumber(), "VE_1072");}Map<Integer, Integer> itemIdQuantity = new HashMap<>(); // this is for errorMap<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap = new HashMap<>();Map<Integer, Float> lineItemPrice = new HashMap<>(); // this is for pricing errorfloat totalAmount = 0;boolean noGST = false;for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {// itemIds.add(customFofoOrderItem.getItemId());Set<String> serialNumbers = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());if (!serialNumbers.isEmpty() && customFofoOrderItem.getQuantity() != serialNumbers.size()) {itemIdQuantity.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getQuantity());}if (!(customFofoOrderItem.getSellingPrice() > 0)) {lineItemPrice.put(customFofoOrderItem.getItemId(), customFofoOrderItem.getSellingPrice());} else {totalAmount = totalAmount + customFofoOrderItem.getSellingPrice() * customFofoOrderItem.getQuantity();totalAmount = totalAmount - customFofoOrderItem.getDiscountAmount() * customFofoOrderItem.getQuantity();for (SerialNumberDetail serialNumberDetail : customFofoOrderItem.getSerialNumberDetails()) {if (serialNumberDetail.getAmount() > 0) {totalAmount = totalAmount + serialNumberDetail.getAmount();}}}itemIdCustomFofoOrderItemMap.put(customFofoOrderItem.getItemId(), customFofoOrderItem);}if (!itemIdQuantity.isEmpty()) {// if item quantity does not match with given serialnumbers sizeLOGGER.error("itemId's quantity should be equal to given serialnumber size {} ", itemIdQuantity);throw new ProfitMandiBusinessException("itemIdQuantity", itemIdQuantity, "FFORDR_1001");// return "error";}this.validatePaymentOptionsAndTotalAmount(createOrderRequest.getPaymentOptions(), totalAmount);if (!lineItemPrice.isEmpty()) {// given fofo line item price must be greater than zeroLOGGER.error("requested itemId's selling price must greater than 0");throw new ProfitMandiBusinessException(ProfitMandiConstants.PRICE, lineItemPrice, "FFORDR_1002");}List<CurrentInventorySnapshot> currentInventorySnapshots = currentInventorySnapshotRepository.selectByFofoItemIds(fofoId, itemIdCustomFofoOrderItemMap.keySet());this.validateCurrentInventorySnapshotQuantities(currentInventorySnapshots, itemIdCustomFofoOrderItemMap);List<Item> items = itemRepository.selectByIds(itemIdCustomFofoOrderItemMap.keySet());if (items.size() != itemIdCustomFofoOrderItemMap.keySet().size()) {LOGGER.error("Requested ItemIds not found in catalog");// invalid itemIdsthrow new ProfitMandiBusinessException("invalidItemIds", itemIdCustomFofoOrderItemMap.keySet(),"FFORDR_1003");}Map<Integer, Item> itemMap = this.toItemMap(items);Set<Integer> nonSerializedItemIds = new HashSet<>();Set<String> serialNumbers = new HashSet<>();List<InsuranceModel> insuredModels = new ArrayList<>();for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {Item item = itemMap.get(customFofoOrderItem.getItemId());noGST = item.getHsnCode().equals("NOGST");if (item.getType().equals(ItemType.SERIALIZED)) {for (SerialNumberDetail serialNumberDetail : customFofoOrderItem.getSerialNumberDetails()) {serialNumbers.add(serialNumberDetail.getSerialNumber());if (serialNumberDetail.getAmount() > 0) {InsuranceModel im = new InsuranceModel();im.setBrand(item.getBrand());im.setColor(item.getColor());im.setModelName(item.getModelName() + item.getModelNumber());im.setInsuranceAmount(serialNumberDetail.getAmount());im.setDeviceSellingPrice(customFofoOrderItem.getSellingPrice());im.setInsuranceId(serialNumberDetail.getInsurance());im.setSerialNumber(serialNumberDetail.getSerialNumber());im.setMemory(serialNumberDetail.getMemory());im.setRam(serialNumberDetail.getRam());im.setMfgDate(serialNumberDetail.getMfgDate());insuredModels.add(im);}}} else {nonSerializedItemIds.add(customFofoOrderItem.getItemId());}}Map<Integer, Set<InventoryItem>> serializedInventoryItemMap = new HashMap<>();Map<Integer, Set<InventoryItem>> nonSerializedInventoryItemMap = new HashMap<>();// Map<String, Float> serialNumberItemPrice = new HashMap<>();if (!serialNumbers.isEmpty()) {List<InventoryItem> serializedInventoryItems = inventoryItemRepository.selectByFofoIdSerialNumbers(fofoId,serialNumbers, false);LOGGER.info("serializedInventoryItems {}", serializedInventoryItems);for (InventoryItem inventoryItem : serializedInventoryItems) {if (inventoryItem.getGoodQuantity() == 1) {if (serializedInventoryItemMap.containsKey(inventoryItem.getItemId())) {serializedInventoryItemMap.get(inventoryItem.getItemId()).add(inventoryItem);} else {Set<InventoryItem> itemIdInventoryItems = new HashSet<>();itemIdInventoryItems.add(inventoryItem);serializedInventoryItemMap.put(inventoryItem.getItemId(), itemIdInventoryItems);}}}}if (!nonSerializedItemIds.isEmpty()) {List<InventoryItem> nonSerializedInventoryItems = inventoryItemRepository.selectByFofoIdItemIds(fofoId,nonSerializedItemIds);LOGGER.info("nonSerializedInventoryItems {}", nonSerializedInventoryItems);for (InventoryItem it : nonSerializedInventoryItems) {if (it.getGoodQuantity() > 0) {if (nonSerializedInventoryItemMap.containsKey(it.getItemId())) {nonSerializedInventoryItemMap.get(it.getItemId()).add(it);} else {Set<InventoryItem> tmp = new HashSet<>();tmp.add(it);nonSerializedInventoryItemMap.put(it.getItemId(), tmp);}}}}this.validateItemsSerializedNonSerialized(items, itemIdCustomFofoOrderItemMap);Map<Integer, Set<InventoryItem>> inventoryItemsToBill = new HashMap<>();Map<Integer, Integer> inventoryItemIdQuantityUsed = new HashMap<>(); // to keep track of inventoryitem quanity// used for scan records insertionLOGGER.info("itemMap keys {}", itemMap.keySet());// Lets reduce quantity and decide what inventory items to use.for (Item item : items) {if (item.getType().equals(ItemType.SERIALIZED)) {// TODO:handle nullif (serializedInventoryItemMap.get(item.getId()) == null|| itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().size() != serializedInventoryItemMap.get(item.getId()).size()) {List<String> invalidSerialNumbers = itemIdCustomFofoOrderItemMap.get(item.getId()).getSerialNumberDetails().stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());throw new ProfitMandiBusinessException("invalidSerialNumbers", invalidSerialNumbers, "FFORDR_1004");}List<String> serialNumberList = liveDemoBillingRespository.selectAllSerialNumber();Set<InventoryItem> inventoryItemsSerializedserialized = serializedInventoryItemMap.get(item.getId());for (InventoryItem inventoryItem : inventoryItemsSerializedserialized) {inventoryItem.setGoodQuantity(0);inventoryItemIdQuantityUsed.put(inventoryItem.getId(), 1);if (serialNumberList.contains(inventoryItem.getSerialNumber())) {LiveDemoSerialNumber liveDemoSerialNumber = liveDemoBillingRespository.selectBySerialNumber(inventoryItem.getSerialNumber());liveDemoBillingRespository.delete(liveDemoSerialNumber);}}inventoryItemsToBill.put(item.getId(), inventoryItemsSerializedserialized);} else {Set<InventoryItem> inventoryItemsNonSerialized = nonSerializedInventoryItemMap.get(item.getId());int quantityToBill = itemIdCustomFofoOrderItemMap.get(item.getId()).getQuantity();int totalLeft = quantityToBill;Set<InventoryItem> inventoryItemsNonSerializedUsed = new HashSet<>();if (inventoryItemsNonSerialized != null) {for (InventoryItem inventoryItem : inventoryItemsNonSerialized) {if (totalLeft > 0) {int toUse = Math.min(totalLeft, inventoryItem.getGoodQuantity());inventoryItemIdQuantityUsed.put(inventoryItem.getId(), toUse);inventoryItem.setGoodQuantity(inventoryItem.getGoodQuantity() - toUse);totalLeft = totalLeft - toUse;inventoryItemsNonSerializedUsed.add(inventoryItem);}}}if (totalLeft > 0) {// not enough quanity for non-serializedLOGGER.error("not enough quanity for non-serialized");throw new ProfitMandiBusinessException("notEnoughQuantityForNonSerialized", totalLeft,"FFORDR_1005");}inventoryItemsToBill.put(item.getId(), inventoryItemsNonSerializedUsed);}}Map<Integer, PriceModel> itemIdMopPriceMap = pricingService.getPurchasePriceMopPriceNotFound(itemIdCustomFofoOrderItemMap.keySet(), fofoId);if (accessoriesDeals) {this.validateDpPrice(itemIdMopPriceMap, itemIdCustomFofoOrderItemMap);} else {this.validateMopPrice(itemIdMopPriceMap, itemIdCustomFofoOrderItemMap);}String fofoStoreCode = this.getFofoStoreCode(fofoId);String documentNumber = null;if (noGST) {documentNumber = this.getSecurityDepositNumber(fofoId, fofoStoreCode);} else {documentNumber = this.getInvoiceNumber(fofoId, fofoStoreCode);}Customer customer = customerRepository.selectById(customCustomer.getCustomerId());CustomerAddress customerAddress = customer.getCustomerAddress().stream().filter(x -> x.getId() == customCustomer.getCustomerAddressId()).findFirst().get();FofoOrder fofoOrder = this.createAndGetFofoOrder(customer.getId(), customCustomer.getGstNumber(), fofoId,documentNumber, totalAmount, customerAddress.getId());this.createPaymentOptions(fofoOrder, createOrderRequest.getPaymentOptions());int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoId);Address retailerAddress = addressRepository.selectById(retailerAddressId);Integer stateId = null;if (customerAddress.getState().equals(retailerAddress.getState())) {try {stateId = Long.valueOf(Utils.getStateInfo(customerAddress.getState()).getId()).intValue();} catch (Exception e) {LOGGER.error("Unable to get state rates");}}for (CustomFofoOrderItem customFofoOrderItem : createOrderRequest.getFofoOrderItems()) {FofoOrderItem fofoOrderItem = this.createAndGetFofoOrderItem(customFofoOrderItem, fofoOrder.getId(),itemMap, inventoryItemsToBill.get(customFofoOrderItem.getItemId()), stateId);Set<InventoryItem> inventoryItems = inventoryItemsToBill.get(customFofoOrderItem.getItemId());this.createFofoLineItem(fofoOrderItem.getId(), inventoryItems, inventoryItemIdQuantityUsed);this.updateCurrentInventorySnapshot(currentInventorySnapshots, fofoId, customFofoOrderItem.getItemId(),customFofoOrderItem.getQuantity());this.updateInventoryItemsAndScanRecord(inventoryItems, fofoId, inventoryItemIdQuantityUsed,fofoOrder.getId());}List<FofoOrderItem> fofoItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());for (FofoOrderItem fofoItem : fofoItems) {Item orderItem = itemRepository.selectById(fofoItem.getItemId());if (orderItem.getCategoryId() == ProfitMandiConstants.MOBILE_CATEGORY_ID) {this.createAndGetHygieneData(fofoOrder.getId(), fofoOrder.getFofoId());}}// insurance calculation is insurance flag is enabled//if (insuredModels.size() > 0) {LOGGER.info("Processing insurane for serialNumbers");LOGGER.info("InsuranceModels {}", insuredModels);LocalDate customerDateOfBirth = LocalDate.from(createOrderRequest.getCustomer().getDateOfBirth());fofoOrder.setDateOfBirth(customerDateOfBirth);for (InsuranceModel insuranceModel : insuredModels) {try {insuranceService.createInsurance(fofoOrder, insuranceModel);} catch (Exception e) {e.printStackTrace();throw new ProfitMandiBusinessException("Insurance creation", insuranceModel,"Failed to create insurance");}}}schemeService.processSchemeOut(fofoOrder.getId(), fofoId);if (createOrderRequest.getPoId() != 0) {PendingOrder po = pendingOrderRepository.selectById(createOrderRequest.getPoId());po.setBilledAmount(po.getBilledAmount() + totalAmount);PendingOrderItem poi = pendingOrderItemRepository.selectById(createOrderRequest.getPoItemId());poi.setStatus(OrderStatus.BILLED);poi.setBilledTimestamp(LocalDateTime.now());}return fofoOrder.getId();}private HygieneData createAndGetHygieneData(int id, int fofoId) {HygieneData hygieneData = new HygieneData();hygieneData.setOrderId(id);hygieneData.setFofoId(fofoId);hygieneData.setCreatedTimestamp(LocalDateTime.now());hygieneDataRepository.persist(hygieneData);return hygieneData;}@Overridepublic String getInvoiceNumber(int fofoId, String fofoStoreCode) {InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;try {invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);invoiceNumberGenerationSequence.setSequence(invoiceNumberGenerationSequence.getSequence() + 1);} catch (ProfitMandiBusinessException profitMandiBusinessException) {invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();invoiceNumberGenerationSequence.setFofoId(fofoId);invoiceNumberGenerationSequence.setPrefix(fofoStoreCode);invoiceNumberGenerationSequence.setSequence(1);}invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);return invoiceNumberGenerationSequence.getPrefix() + "/" + invoiceNumberGenerationSequence.getSequence();}private String getSecurityDepositNumber(int fofoId, String fofoStoreCode) {InvoiceNumberGenerationSequence invoiceNumberGenerationSequence = null;try {invoiceNumberGenerationSequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoId);invoiceNumberGenerationSequence.setChallanNumberSequence(invoiceNumberGenerationSequence.getChallanNumberSequence() + 1);} catch (ProfitMandiBusinessException profitMandiBusinessException) {invoiceNumberGenerationSequence = new InvoiceNumberGenerationSequence();invoiceNumberGenerationSequence.setFofoId(fofoId);invoiceNumberGenerationSequence.setPrefix(fofoStoreCode);invoiceNumberGenerationSequence.setChallanNumberSequence(1);}invoiceNumberGenerationSequenceRepository.persist(invoiceNumberGenerationSequence);return invoiceNumberGenerationSequence.getPrefix() + "/SEC"+ invoiceNumberGenerationSequence.getChallanNumberSequence();}private Set<String> serialNumberDetailsToSerialNumbers(Set<SerialNumberDetail> serialNumberDetails) {Set<String> serialNumbers = new HashSet<>();for (SerialNumberDetail serialNumberDetail : serialNumberDetails) {if (serialNumberDetail.getSerialNumber() != null && !serialNumberDetail.getSerialNumber().isEmpty()) {serialNumbers.add(serialNumberDetail.getSerialNumber());}}return serialNumbers;}@Overridepublic PdfModel getInvoicePdfModel(int orderId) throws ProfitMandiBusinessException {FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(orderId);return this.getInvoicePdfModel(fofoOrder);}@Override@Cacheable(value = "order.dummymodel", cacheManager = "oneDayCacheManager")public PdfModel getDummyPdfModel(String serialNumber) throws ProfitMandiBusinessException {List<WarehouseInventoryItem> warehouseInventoryItems = warehouseInventoryItemRepository.selectWarehouseInventoryItemBySerailNumbers(Arrays.asList(serialNumber));if (warehouseInventoryItems.size() > 0) {WarehouseInventoryItem warehouseInventoryItem = warehouseInventoryItems.get(0);int currentQuantity = warehouseInventoryItems.get(0).getCurrentQuantity();if (currentQuantity > 0) {throw new ProfitMandiBusinessException("Serial Number", serialNumber,"Serial Number exist in our warehouse");} else {try {InventoryItem inventoryItem = inventoryItemRepository.selectBySerialNumber(serialNumber);if (inventoryItem.getGoodQuantity() > 0) {throw new ProfitMandiBusinessException("Serial Number", serialNumber,"Serial Number is not yet billed by the partner");} else {List<ScanRecord> scanRecords = scanRecordRepository.selectByInventoryItemId(inventoryItem.getId());Optional<ScanRecord> scanRecord = scanRecords.stream().filter(x -> x.getOrderId() != 0).findFirst();if (scanRecord.isPresent()) {FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(scanRecord.get().getOrderId());orderIdsConsumed.add(fofoOrder.getId());return this.getInvoicePdfModel(fofoOrder);} else {throw new ProfitMandiBusinessException("Serial Number", serialNumber,"Serial Number returned by partner, but in transit");}}} catch (Exception e) {int itemId = warehouseInventoryItem.getItemId();if(serialNumberOrderIdMap.containsKey(serialNumber)) {FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(serialNumberOrderIdMap.get(serialNumber));PdfModel pdfModel = this.getInvoicePdfModel(fofoOrder.getId());this.modifyDummyModel(fofoOrder, pdfModel, itemId, serialNumber);return pdfModel;}// Map this serialNumber for dummy billingLocalDateTime grnDate = warehouseInventoryItem.getCreated();Random random = new Random();int randomDays = random.ints(2, 15).findFirst().getAsInt();LocalDateTime saleDate = grnDate.plusDays(randomDays);if (saleDate.isAfter(LocalDate.now().atStartOfDay())) {saleDate = LocalDateTime.now().minusDays(2);}Random offsetRandom = new Random();int offset = offsetRandom.ints(2, 100).findFirst().getAsInt();FofoOrder fofoOrder = fofoOrderRepository.selectFirstOrderAfterDate(saleDate, offset);while (orderIdsConsumed.contains(fofoOrder.getId())) {Random offsetRandom2 = new Random();int offset2 = offsetRandom2.ints(2, 100).findFirst().getAsInt();FofoOrder fofoOrder2 = fofoOrderRepository.selectFirstOrderAfterDate(saleDate, offset2);if (fofoOrder2 != null) {fofoOrder = fofoOrder2;}}PdfModel pdfModel = this.getInvoicePdfModel(fofoOrder.getId());orderIdsConsumed.add(fofoOrder.getId());this.modifyDummyModel(fofoOrder, pdfModel, itemId, serialNumber);return pdfModel;}}} else {throw new ProfitMandiBusinessException("Serial Number", serialNumber,"Serial Number does not exist in our warehouse");}}void modifyDummyModel(FofoOrder fofoOrder, PdfModel pdfModel, int itemId, String serialNumber)throws ProfitMandiBusinessException {int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoOrder.getFofoId());Address retailerAddress = addressRepository.selectById(retailerAddressId);Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());CustomerAddress customerAddress = customer.getCustomerAddress().stream().filter(x -> x.getId() == fofoOrder.getCustomerAddressId()).findFirst().get();Integer stateId = null;if (customerAddress.getState().equals(retailerAddress.getState())) {try {stateId = Long.valueOf(Utils.getStateInfo(customerAddress.getState()).getId()).intValue();} catch (Exception e) {LOGGER.error("Unable to get state rates");}}CustomOrderItem cli = pdfModel.getOrderItems().stream().findFirst().get();List<FofoOrderItem> fofoOrderItems = Arrays.asList(this.getDummyFofoOrderItem(itemId, fofoOrder.getId(), serialNumber, stateId));pdfModel.setPaymentOptions(pdfModel.getPaymentOptions().stream().limit(1).collect(Collectors.toList()));CustomPaymentOption paymentOption = pdfModel.getPaymentOptions().get(0);paymentOption.setAmount(fofoOrderItems.get(0).getMop());Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();for (FofoOrderItem fofoOrderItem : fofoOrderItems) {CustomOrderItem customFofoOrderItem = new CustomOrderItem();float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate()+ fofoOrderItem.getCgstRate();float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " "+ fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());// LOGGER.info("serialNumbers {}", serialNumbers);// LOGGER.info("serialNumbers is empty {}", serialNumbers.isEmpty());if (!serialNumbers.isEmpty()) {customFofoOrderItem.setDescription(customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));}customFofoOrderItem.setRate(taxableSellingPrice);customFofoOrderItem.setDiscount(taxableDiscountPrice);customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());customFofoOrderItem.setNetAmount((fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * fofoOrderItem.getQuantity());float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());customFofoOrderItem.setIgstAmount(igstAmount);customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());customFofoOrderItem.setCgstAmount(cgstAmount);customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());customFofoOrderItem.setSgstAmount(sgstAmount);customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());customerFofoOrderItems.add(customFofoOrderItem);}pdfModel.setTotalAmount(paymentOption.getAmount());pdfModel.setOrderItems(customerFofoOrderItems);}private PdfModel getInvoicePdfModel(FofoOrder fofoOrder) throws ProfitMandiBusinessException {List<PaymentOptionTransaction> paymentOptionTransactions = paymentOptionTransactionRepository.selectByReferenceIdAndType(fofoOrder.getId(), PaymentOptionReferenceType.ORDER);List<CustomPaymentOption> paymentOptions = new ArrayList<>();PdfModel pdfModel = new PdfModel();pdfModel.setCancelled(fofoOrder.getCancelledTimestamp() != null);for (PaymentOptionTransaction paymentOptionTransaction : paymentOptionTransactions) {CustomPaymentOption cpi = new CustomPaymentOption();cpi.setAmount(paymentOptionTransaction.getAmount());cpi.setPaymentOption(paymentOptionRepository.selectById(paymentOptionTransaction.getPaymentOptionId()).getName());paymentOptions.add(cpi);}List<FofoOrderItem> fofoOrderItems = this.getByOrderId(fofoOrder.getId());pdfModel.setTitle("Retailer Invoice");if (fofoOrderItems.stream().findAny().get().getHsnCode().equals("NOGST")) {pdfModel.setTitle("Security Deposit Receipt");}pdfModel.setPaymentOptions(paymentOptions);pdfModel.setAuther("SmartDukaan");pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));// insurance calculationList<InsurancePolicy> insurancePolicies = insurancePolicyRepository.selectByRetailerIdInvoiceNumber(fofoOrder.getFofoId(), fofoOrder.getInvoiceNumber());Set<CustomInsurancePolicy> customInsurancePolicies = new HashSet<>();final float totalInsuranceTaxRate = 18;for (InsurancePolicy insurancePolicy : insurancePolicies) {float taxableInsurancePrice = insurancePolicy.getSaleAmount() / (1 + totalInsuranceTaxRate / 100);CustomInsurancePolicy customInsurancePolicy = new CustomInsurancePolicy();customInsurancePolicy.setDescription("Damage Protection Plan for device IMEI #"+ insurancePolicy.getSerialNumber() + "\n Certificate No. " + insurancePolicy.getPolicyNumber());customInsurancePolicy.setHsnCode("998716");customInsurancePolicy.setRate(taxableInsurancePrice);customInsurancePolicy.setIgstRate(18);customInsurancePolicy.setIgstAmount(taxableInsurancePrice * 18 / 100);customInsurancePolicy.setCgstRate(9);customInsurancePolicy.setCgstAmount(taxableInsurancePrice * 9 / 100);customInsurancePolicy.setSgstRate(9);customInsurancePolicy.setSgstAmount(taxableInsurancePrice * 9 / 100);customInsurancePolicy.setNetAmount(insurancePolicy.getSaleAmount());customInsurancePolicies.add(customInsurancePolicy);}pdfModel.setInsurancePolicies(customInsurancePolicies);List<String> tncs = new ArrayList<>();tncs.add("I agree that goods received are in good working condition");tncs.add("Goods once sold cannot be exchanged or taken back");tncs.add("Warranty for the goods received by me is the responsibility of the manufacturer only.");tncs.add("Tempered Glass Replacement will be done only for the Mobile Phone which was purchased from SmartDukaan");tncs.add("Customers requesting Tempered Glass Replacement will have to bring the broken tempered glass, either pasted on the phone or along with the phone");tncs.add("Service fee of Rs.20 will be chargeable for each Tempered Glass Replacement");if (pdfModel.getInsurancePolicies() != null && pdfModel.getInsurancePolicies().size() > 0) {tncs.add("Damage protection provided is the responisibility of Protection Provider only");}pdfModel.setTncs(tncs);pdfModel.setCustomer(getCustomCustomer(fofoOrder));pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());pdfModel.setTotalAmount(fofoOrder.getTotalAmount());Retailer retailer = retailerRepository.selectById(fofoOrder.getFofoId());PrivateDealUser privateDealUser = null;try {privateDealUser = privateDealUserRepository.selectById(retailer.getId());} catch (ProfitMandiBusinessException profitMandiBusinessException) {LOGGER.error("Private Deal User not found : ", profitMandiBusinessException);}User user = userRepository.selectById(userAccountRepository.selectUserIdByRetailerId(retailer.getId()));CustomRetailer customRetailer = new CustomRetailer();customRetailer.setBusinessName(retailer.getName());customRetailer.setMobileNumber(user.getMobileNumber());// customRetailer.setTinNumber(retailer.getNumber());if (privateDealUser == null) {customRetailer.setGstNumber(null);} else {if (null != privateDealUser.getCounterId()) {Counter counter = counterRepository.selectById(privateDealUser.getCounterId());customRetailer.setGstNumber(counter.getGstin());} else {customRetailer.setGstNumber(null);}}Address retailerAddress = addressRepository.selectById(retailerRegisteredAddressRepository.selectAddressIdByRetailerId(retailer.getId()));customRetailer.setAddress(this.createCustomAddress(retailerAddress));pdfModel.setRetailer(customRetailer);Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();for (FofoOrderItem fofoOrderItem : fofoOrderItems) {CustomOrderItem customFofoOrderItem = new CustomOrderItem();float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate()+ fofoOrderItem.getCgstRate();float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);customFofoOrderItem.setAmount(fofoOrderItem.getQuantity() * (taxableSellingPrice - taxableDiscountPrice));customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " "+ fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());Set<String> serialNumbers = this.toSerialNumbers(fofoOrderItem.getFofoLineItems());// LOGGER.info("serialNumbers {}", serialNumbers);// LOGGER.info("serialNumbers is empty {}", serialNumbers.isEmpty());if (!serialNumbers.isEmpty()) {customFofoOrderItem.setDescription(customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));}customFofoOrderItem.setRate(taxableSellingPrice);customFofoOrderItem.setDiscount(taxableDiscountPrice);customFofoOrderItem.setQuantity(fofoOrderItem.getQuantity());customFofoOrderItem.setNetAmount((fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * fofoOrderItem.getQuantity());float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());customFofoOrderItem.setIgstAmount(igstAmount);customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());customFofoOrderItem.setCgstAmount(cgstAmount);customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());customFofoOrderItem.setSgstAmount(sgstAmount);customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());customerFofoOrderItems.add(customFofoOrderItem);}pdfModel.setOrderItems(customerFofoOrderItems);String partnerAddressStateCode = stateRepository.selectByName(pdfModel.getRetailer().getAddress().getState()).getCode();String customerAddressStateCode = stateRepository.selectByName(pdfModel.getCustomer().getAddress().getState()).getCode();pdfModel.setPartnerAddressStateCode(partnerAddressStateCode);pdfModel.setCustomerAddressStateCode(customerAddressStateCode);pdfModel.setCancelled(false);return pdfModel;}private CustomCustomer getCustomCustomer(FofoOrder fofoOrder) throws ProfitMandiBusinessException {Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());CustomCustomer customCustomer = new CustomCustomer();customCustomer.setFirstName(customer.getFirstName());customCustomer.setLastName(customer.getLastName());customCustomer.setEmailId(customer.getEmailId());customCustomer.setMobileNumber(customer.getMobileNumber());customCustomer.setGstNumber(fofoOrder.getCustomerGstNumber());CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());customCustomer.setAddress(this.createCustomAddress(customerAddress));return customCustomer;}@Overridepublic PdfModel getInvoicePdfModel(int fofoId, int orderId) throws ProfitMandiBusinessException {FofoOrder fofoOrder = fofoOrderRepository.selectByFofoIdAndOrderId(fofoId, orderId);return this.getInvoicePdfModel(fofoOrder);}public String getBillingAddress(CustomerAddress customerAddress) {StringBuilder address = new StringBuilder();if ((customerAddress.getLine1() != null) && (!customerAddress.getLine1().isEmpty())) {address.append(customerAddress.getLine1());address.append(", ");}if ((customerAddress.getLine2() != null) && (!customerAddress.getLine2().isEmpty())) {address.append(customerAddress.getLine2());address.append(", ");}if ((customerAddress.getLandmark() != null) && (!customerAddress.getLandmark().isEmpty())) {address.append(customerAddress.getLandmark());address.append(", ");}if ((customerAddress.getCity() != null) && (!customerAddress.getCity().isEmpty())) {address.append(customerAddress.getCity());address.append(", ");}if ((customerAddress.getState() != null) && (!customerAddress.getState().isEmpty())) {address.append(customerAddress.getState());}if ((customerAddress.getPinCode() != null) && (!customerAddress.getPinCode().isEmpty())) {address.append("- ");address.append(customerAddress.getPinCode());}return address.toString();}@Overridepublic List<CartFofo> cartCheckout(String cartJson) throws ProfitMandiBusinessException {try {JSONObject cartObject = new JSONObject(cartJson);Iterator<?> keys = cartObject.keys();Set<Integer> itemIds = new HashSet<>();List<CartFofo> cartItems = new ArrayList<CartFofo>();while (keys.hasNext()) {String key = (String) keys.next();if (cartObject.get(key) instanceof JSONObject) {LOGGER.info(cartObject.get(key).toString());}CartFofo cf = new CartFofo();cf.setItemId(cartObject.getJSONObject(key).getInt("itemId"));cf.setQuantity(cartObject.getJSONObject(key).getInt("quantity"));if (cartObject.getJSONObject(key).has("poId")) {cf.setPoId(cartObject.getJSONObject(key).getInt("poId"));cf.setPoItemId(cartObject.getJSONObject(key).getInt("poItemId"));}if (cf.getQuantity() <= 0) {continue;}cartItems.add(cf);itemIds.add(cartObject.getJSONObject(key).getInt("itemId"));}Map<Integer, Item> itemMap = new HashMap<Integer, Item>();if (itemIds.size() > 0) {List<Item> items = itemRepository.selectByIds(itemIds);for (Item i : items) {itemMap.put(i.getId(), i);}}for (CartFofo cf : cartItems) {Item i = itemMap.get(cf.getItemId());if (i == null) {continue;}cf.setDisplayName(getValidName(i.getBrand()) + " " + getValidName(i.getModelName()) + " "+ getValidName(i.getModelNumber()) + " " + getValidName(i.getColor()).replaceAll("\\s+", " "));cf.setItemType(i.getType());}return cartItems;} catch (Exception e) {LOGGER.error("Unable to Prepare cart to place order...", e);throw new ProfitMandiBusinessException("cartData", cartJson, "FFORDR_1006");}}@Overridepublic Map<String, Object> getSaleHistory(int fofoId, SearchType searchType, String searchValue,LocalDateTime startDate, LocalDateTime endDate, int offset, int limit) throws ProfitMandiBusinessException {long countItems = 0;List<FofoOrder> fofoOrders = new ArrayList<>();if (searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()) {fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, null, null,offset, limit);countItems = fofoOrderRepository.selectCountByCustomerMobileNumber(fofoId, searchValue, null, null);} else if (searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()) {fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, null, null, offset,limit);countItems = fofoOrderRepository.selectCountByCustomerName(fofoId, searchValue, null, null);} else if (searchType == SearchType.IMEI && !searchValue.isEmpty()) {fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, null, null, offset,limit);countItems = fofoOrderRepository.selectCountBySerialNumber(fofoId, searchValue, null, null);} else if (searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()) {fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, null, null, offset, limit);countItems = fofoOrderRepository.selectCountByItemName(fofoId, searchValue, null, null);} else if (searchType == SearchType.INVOICE_NUMBER && !searchValue.isEmpty()) {fofoOrders = Arrays.asList(fofoOrderRepository.selectByFofoIdAndInvoiceNumber(fofoId, searchValue));countItems = fofoOrders.size();} else if (searchType == SearchType.DATE_RANGE) {fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDate, endDate, offset, limit);countItems = fofoOrderRepository.selectCountByFofoId(fofoId, startDate, endDate);}Map<String, Object> map = new HashMap<>();map.put("saleHistories", fofoOrders);map.put("start", offset + 1);map.put("size", countItems);map.put("searchType", searchType);map.put("searchTypes", SearchType.values());map.put("startDate", startDate);map.put("searchValue", searchValue);map.put(ProfitMandiConstants.END_TIME, endDate);if (fofoOrders.size() < limit) {map.put("end", offset + fofoOrders.size());} else {map.put("end", offset + limit);}return map;}@Overridepublic Map<String, Object> getSaleHistoryPaginated(int fofoId, SearchType searchType, String searchValue,LocalDateTime startDate, LocalDateTime endDate, int offset, int limit) throws ProfitMandiBusinessException {List<FofoOrder> fofoOrders = new ArrayList<>();if (searchType == SearchType.CUSTOMER_MOBILE_NUMBER && !searchValue.isEmpty()) {fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerMobileNumber(fofoId, searchValue, startDate,endDate, offset, limit);} else if (searchType == SearchType.CUSTOMER_NAME && !searchValue.isEmpty()) {fofoOrders = fofoOrderRepository.selectByFofoIdAndCustomerName(fofoId, searchValue, startDate, endDate,offset, limit);} else if (searchType == SearchType.IMEI && !searchValue.isEmpty()) {fofoOrders = fofoOrderRepository.selectByFofoIdAndSerialNumber(fofoId, searchValue, startDate, endDate,offset, limit);} else if (searchType == SearchType.ITEM_NAME && !searchValue.isEmpty()) {fofoOrders = fofoOrderRepository.selectByFofoIdAndItemName(fofoId, searchValue, startDate, endDate, offset,limit);} else if (searchType == SearchType.DATE_RANGE) {fofoOrders = fofoOrderRepository.selectByFofoId(fofoId, startDate, endDate, offset, limit);}Map<String, Object> map = new HashMap<>();map.put("saleHistories", fofoOrders);map.put("searchType", searchType);map.put("searchTypes", SearchType.values());map.put("startDate", startDate);map.put("searchValue", searchValue);map.put(ProfitMandiConstants.END_TIME, endDate);return map;}private String getFofoStoreCode(int fofoId) throws ProfitMandiBusinessException {FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);return fofoStore.getCode();}private String getValidName(String name) {return name != null ? name : "";}private Set<String> toSerialNumbers(Set<FofoLineItem> fofoLineItems) {Set<String> serialNumbers = new HashSet<>();for (FofoLineItem fofoLineItem : fofoLineItems) {if (fofoLineItem.getSerialNumber() != null && !fofoLineItem.getSerialNumber().isEmpty()) {serialNumbers.add(fofoLineItem.getSerialNumber());}}return serialNumbers;}private void validateDpPrice(Map<Integer, PriceModel> itemIdMopPriceMap,Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException {for (Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoLineItemMap.entrySet()) {int itemId = entry.getKey();CustomFofoOrderItem customFofoOrderItem = entry.getValue();PriceModel priceModel = itemIdMopPriceMap.get(itemId);if (customFofoOrderItem.getSerialNumberDetails().stream().filter(x -> org.apache.commons.lang.StringUtils.isNotEmpty(x.getSerialNumber())).collect(Collectors.toList()).size() > 0) {if (priceModel.getPrice() > customFofoOrderItem.getSellingPrice()) {throw new ProfitMandiBusinessException("Selling Price for ",itemRepository.selectById(itemId).getItemDescription(), "FFORDR_1010");}} else {if (priceModel.getPurchasePrice() > customFofoOrderItem.getSellingPrice()) {throw new ProfitMandiBusinessException("Selling Price",itemRepository.selectById(itemId).getItemDescription(),"Selling Price should not be less than DP");}}}}private void validateMopPrice(Map<Integer, PriceModel> itemIdMopPriceMap,Map<Integer, CustomFofoOrderItem> itemIdCustomFofoLineItemMap) throws ProfitMandiBusinessException {Map<Integer, Float> invalidMopItemIdPriceMap = new HashMap<>();for (Map.Entry<Integer, PriceModel> entry : itemIdMopPriceMap.entrySet()) {CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoLineItemMap.get(entry.getKey());if (customFofoOrderItem.getSellingPrice() < entry.getValue().getPrice()) {invalidMopItemIdPriceMap.put(entry.getKey(), customFofoOrderItem.getSellingPrice());}}if (!invalidMopItemIdPriceMap.isEmpty()) {LOGGER.error("Invalid itemIds selling prices{} should be greater than mop prices {}",invalidMopItemIdPriceMap, itemIdMopPriceMap);throw new ProfitMandiBusinessException("invalidMopItemIdPrice", invalidMopItemIdPriceMap, "FFORDR_1010");}}private void updateInventoryItemsAndScanRecord(Set<InventoryItem> inventoryItems, int fofoId,Map<Integer, Integer> inventoryItemQuantityUsed, int fofoOrderId) {for (InventoryItem inventoryItem : inventoryItems) {inventoryItem.setLastScanType(ScanType.SALE);inventoryItemRepository.persist(inventoryItem);ScanRecord scanRecord = new ScanRecord();scanRecord.setInventoryItemId(inventoryItem.getId());scanRecord.setFofoId(fofoId);scanRecord.setOrderId(fofoOrderId);// correct thisscanRecord.setQuantity(inventoryItemQuantityUsed.get(inventoryItem.getId()));scanRecord.setType(ScanType.SALE);scanRecordRepository.persist(scanRecord);purchaseReturnItemRepository.deleteById(inventoryItem.getId());}}private void createFofoLineItem(int fofoOrderItemId, Set<InventoryItem> inventoryItems,Map<Integer, Integer> inventoryItemIdQuantityUsed) {for (InventoryItem inventoryItem : inventoryItems) {FofoLineItem fofoLineItem = new FofoLineItem();fofoLineItem.setFofoOrderItemId(fofoOrderItemId);fofoLineItem.setSerialNumber(inventoryItem.getSerialNumber());fofoLineItem.setInventoryItemId(inventoryItem.getId());fofoLineItem.setQuantity(inventoryItemIdQuantityUsed.get(inventoryItem.getId()));fofoLineItemRepository.persist(fofoLineItem);}}private FofoOrderItem createAndGetFofoOrderItem(CustomFofoOrderItem customFofoOrderItem, int fofoOrderId,Map<Integer, Item> itemMap, Set<InventoryItem> inventoryItems, Integer stateId)throws ProfitMandiBusinessException {FofoOrderItem fofoOrderItem = new FofoOrderItem();fofoOrderItem.setItemId(customFofoOrderItem.getItemId());fofoOrderItem.setQuantity(customFofoOrderItem.getQuantity());fofoOrderItem.setSellingPrice(customFofoOrderItem.getSellingPrice());fofoOrderItem.setOrderId(fofoOrderId);TagListing tl = tagListingRepository.selectByItemId(customFofoOrderItem.getItemId());// In case listing gets removed rebill it using the selling priceif (tl != null) {fofoOrderItem.setDp(tl.getSellingPrice());fofoOrderItem.setMop(tl.getMop());} else {fofoOrderItem.setDp(customFofoOrderItem.getSellingPrice());fofoOrderItem.setMop(customFofoOrderItem.getSellingPrice());}fofoOrderItem.setDiscount(customFofoOrderItem.getDiscountAmount());Item item = itemMap.get(customFofoOrderItem.getItemId());Map<Integer, GstRate> itemIdStateTaxRateMap = null;Map<Integer, Float> itemIdIgstTaxRateMap = null;if (stateId != null) {itemIdStateTaxRateMap = stateGstRateRepository.getStateTaxRate(new ArrayList<>(itemMap.keySet()), stateId);} else {itemIdIgstTaxRateMap = stateGstRateRepository.getIgstTaxRate(new ArrayList<>(itemMap.keySet()));}for (InventoryItem inventoryItem : inventoryItems) {if (stateId == null) {fofoOrderItem.setIgstRate(itemIdIgstTaxRateMap.get(inventoryItem.getItemId()));} else {fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getCgstRate());fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(inventoryItem.getItemId()).getSgstRate());}fofoOrderItem.setHsnCode(inventoryItem.getHsnCode());break;}fofoOrderItem.setBrand(item.getBrand());fofoOrderItem.setModelName(item.getModelName());fofoOrderItem.setModelNumber(item.getModelNumber());fofoOrderItem.setColor(item.getColor());fofoOrderItemRepository.persist(fofoOrderItem);return fofoOrderItem;}private FofoOrderItem getDummyFofoOrderItem(int itemId, int fofoOrderId, String serialNumber, Integer stateId)throws ProfitMandiBusinessException {Item item = itemRepository.selectById(itemId);TagListing tl = tagListingRepository.selectByItemId(itemId);FofoOrderItem fofoOrderItem = new FofoOrderItem();fofoOrderItem.setItemId(itemId);fofoOrderItem.setQuantity(1);fofoOrderItem.setSellingPrice(tl.getMop());fofoOrderItem.setOrderId(fofoOrderId);// In case listing gets removed rebill it using the selling pricefofoOrderItem.setDp(tl.getSellingPrice());fofoOrderItem.setMop(tl.getMop());fofoOrderItem.setDiscount(0);Map<Integer, GstRate> itemIdStateTaxRateMap = null;Map<Integer, Float> itemIdIgstTaxRateMap = null;if (stateId != null) {itemIdStateTaxRateMap = stateGstRateRepository.getStateTaxRate(Arrays.asList(itemId), stateId);} else {itemIdIgstTaxRateMap = stateGstRateRepository.getIgstTaxRate(Arrays.asList(itemId));}if (stateId == null) {fofoOrderItem.setIgstRate(itemIdIgstTaxRateMap.get(itemId));} else {fofoOrderItem.setCgstRate(itemIdStateTaxRateMap.get(itemId).getCgstRate());fofoOrderItem.setSgstRate(itemIdStateTaxRateMap.get(itemId).getSgstRate());}fofoOrderItem.setHsnCode(item.getHsnCode());fofoOrderItem.setBrand(item.getBrand());fofoOrderItem.setModelName(item.getModelName());fofoOrderItem.setModelNumber(item.getModelNumber());fofoOrderItem.setColor(item.getColor());Set<FofoLineItem> fofoLineItems = new HashSet<>();FofoLineItem fli = new FofoLineItem();fli.setQuantity(1);fli.setSerialNumber(serialNumber);fofoLineItems.add(fli);fofoOrderItem.setFofoLineItems(fofoLineItems);return fofoOrderItem;}private void updateCurrentInventorySnapshot(List<CurrentInventorySnapshot> currentInventorySnapshots, int fofoId,int itemId, int quantity) throws ProfitMandiBusinessException {for (CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {if (currentInventorySnapshot.getItemId() == itemId && currentInventorySnapshot.getFofoId() == fofoId) {currentInventorySnapshotRepository.updateAvailabilityByItemIdAndFofoId(itemId, fofoId,currentInventorySnapshot.getAvailability() - quantity);}}}private void createPaymentOptions(FofoOrder fofoOrder, Set<CustomPaymentOption> customPaymentOptions)throws ProfitMandiBusinessException {for (CustomPaymentOption customPaymentOption : customPaymentOptions) {if (customPaymentOption.getAmount() > 0) {PaymentOptionTransaction paymentOptionTransaction = new PaymentOptionTransaction();paymentOptionTransaction.setReferenceId(fofoOrder.getId());paymentOptionTransaction.setPaymentOptionId(customPaymentOption.getPaymentOptionId());paymentOptionTransaction.setReferenceType(PaymentOptionReferenceType.ORDER);paymentOptionTransaction.setAmount(customPaymentOption.getAmount());paymentOptionTransaction.setFofoId(fofoOrder.getFofoId());paymentOptionTransactionRepository.persist(paymentOptionTransaction);}}}private FofoOrder createAndGetFofoOrder(int customerId, String customerGstNumber, int fofoId, String documentNumber,float totalAmount, int customerAddressId) {FofoOrder fofoOrder = new FofoOrder();fofoOrder.setCustomerGstNumber(customerGstNumber);fofoOrder.setCustomerId(customerId);fofoOrder.setFofoId(fofoId);fofoOrder.setInvoiceNumber(documentNumber);fofoOrder.setTotalAmount(totalAmount);fofoOrder.setCustomerAddressId(customerAddressId);fofoOrderRepository.persist(fofoOrder);return fofoOrder;}private void validateItemsSerializedNonSerialized(List<Item> items,Map<Integer, CustomFofoOrderItem> customFofoOrderItemMap) throws ProfitMandiBusinessException {List<Integer> invalidItemIdSerialNumbers = new ArrayList<Integer>();List<Integer> itemIdNonSerializedSerialNumbers = new ArrayList<Integer>();for (Item i : items) {CustomFofoOrderItem customFofoOrderItem = customFofoOrderItemMap.get(i.getId());if (i.getType().equals(ItemType.SERIALIZED)) {if (customFofoOrderItem == null || customFofoOrderItem.getSerialNumberDetails().isEmpty()) {invalidItemIdSerialNumbers.add(i.getId());}} else {Set<String> serialNumbers = this.serialNumberDetailsToSerialNumbers(customFofoOrderItem.getSerialNumberDetails());if (customFofoOrderItem == null || !serialNumbers.isEmpty()) {itemIdNonSerializedSerialNumbers.add(i.getId());}}}if (!invalidItemIdSerialNumbers.isEmpty()) {LOGGER.error("Invalid itemId's serialNumbers for serialized{}", invalidItemIdSerialNumbers);// itemId's are serialized you are saying these are not serializedthrow new ProfitMandiBusinessException("invalidItemIdSerialNumbers", invalidItemIdSerialNumbers,"FFORDR_1013");}if (!itemIdNonSerializedSerialNumbers.isEmpty()) {LOGGER.error("Invalid itemId's serialNumbers for non serialized{}", itemIdNonSerializedSerialNumbers);// itemId's are non serialized you are saying these are serializedthrow new ProfitMandiBusinessException("itemIdNonSerializedSerialNumbers", itemIdNonSerializedSerialNumbers,"FFORDR_1014");}}private void validateCurrentInventorySnapshotQuantities(List<CurrentInventorySnapshot> currentInventorySnapshots,Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap) throws ProfitMandiBusinessException {if (itemIdCustomFofoOrderItemMap.keySet().size() != currentInventorySnapshots.size()) {throw new ProfitMandiBusinessException("quantiiesSize", currentInventorySnapshots.size(), "");}List<ItemIdQuantityAvailability> itemIdQuantityAvailabilities = new ArrayList<>(); // this is for errorLOGGER.info("currentInventorySnapshots " + currentInventorySnapshots);LOGGER.info("CustomFofoLineItemMap {}", itemIdCustomFofoOrderItemMap);for (CurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {CustomFofoOrderItem customFofoOrderItem = itemIdCustomFofoOrderItemMap.get(currentInventorySnapshot.getItemId());LOGGER.info("customFofoOrderItem {}", customFofoOrderItem);if (customFofoOrderItem.getQuantity() > currentInventorySnapshot.getAvailability()) {ItemIdQuantityAvailability itemIdQuantityAvailability = new ItemIdQuantityAvailability();itemIdQuantityAvailability.setItemId(customFofoOrderItem.getItemId());Quantity quantity = new Quantity();quantity.setAvailable(currentInventorySnapshot.getAvailability());quantity.setRequested(customFofoOrderItem.getQuantity());itemIdQuantityAvailability.setQuantity(quantity);itemIdQuantityAvailabilities.add(itemIdQuantityAvailability);}}if (!itemIdQuantityAvailabilities.isEmpty()) {// itemIdQuantity request is not validLOGGER.error("Requested quantities should not be greater than currently available quantities {}",itemIdQuantityAvailabilities);throw new ProfitMandiBusinessException("itemIdQuantityAvailabilities", itemIdQuantityAvailabilities,"FFORDR_1015");}}private int getItemIdFromSerialNumber(Map<Integer, CustomFofoOrderItem> itemIdCustomFofoOrderItemMap,String serialNumber) {int itemId = 0;for (Map.Entry<Integer, CustomFofoOrderItem> entry : itemIdCustomFofoOrderItemMap.entrySet()) {Set<SerialNumberDetail> serialNumberDetails = entry.getValue().getSerialNumberDetails();for (SerialNumberDetail serialNumberDetail : serialNumberDetails) {if (serialNumberDetail.getSerialNumber().equals(serialNumber)) {itemId = entry.getKey();break;}}}return itemId;}private Map<Integer, Item> toItemMap(List<Item> items) {Function<Item, Integer> itemIdFunction = new Function<Item, Integer>() {@Overridepublic Integer apply(Item item) {return item.getId();}};Function<Item, Item> itemFunction = new Function<Item, Item>() {@Overridepublic Item apply(Item item) {return item;}};return items.stream().collect(Collectors.toMap(itemIdFunction, itemFunction));}private void setCustomerAddress(CustomerAddress customerAddress, CustomAddress customAddress) {customerAddress.setName(customAddress.getName());customerAddress.setLine1(customAddress.getLine1());customerAddress.setLine2(customAddress.getLine2());customerAddress.setLandmark(customAddress.getLandmark());customerAddress.setCity(customAddress.getCity());customerAddress.setPinCode(customAddress.getPinCode());customerAddress.setState(customAddress.getState());customerAddress.setCountry(customAddress.getCountry());customerAddress.setPhoneNumber(customAddress.getPhoneNumber());}private CustomAddress createCustomAddress(Address address) {CustomAddress customAddress = new CustomAddress();customAddress.setName(address.getName());customAddress.setLine1(address.getLine1());customAddress.setLine2(address.getLine2());customAddress.setLandmark(address.getLandmark());customAddress.setCity(address.getCity());customAddress.setPinCode(address.getPinCode());customAddress.setState(address.getState());customAddress.setCountry(address.getCountry());customAddress.setPhoneNumber(address.getPhoneNumber());return customAddress;}private CustomAddress createCustomAddress(CustomerAddress customerAddress) {CustomAddress customAddress = new CustomAddress();customAddress.setName(customerAddress.getName());customAddress.setLastName(customerAddress.getLastName());customAddress.setLine1(customerAddress.getLine1());customAddress.setLine2(customerAddress.getLine2());customAddress.setLandmark(customerAddress.getLandmark());customAddress.setCity(customerAddress.getCity());customAddress.setPinCode(customerAddress.getPinCode());customAddress.setState(customerAddress.getState());customAddress.setCountry(customerAddress.getCountry());customAddress.setPhoneNumber(customerAddress.getPhoneNumber());return customAddress;}private void validatePaymentOptionsAndTotalAmount(Set<CustomPaymentOption> customPaymentOptions, float totalAmount)throws ProfitMandiBusinessException {Set<Integer> paymentOptionIds = new HashSet<>();float calculatedAmount = 0;for (CustomPaymentOption customPaymentOption : customPaymentOptions) {paymentOptionIds.add(customPaymentOption.getPaymentOptionId());calculatedAmount = calculatedAmount + customPaymentOption.getAmount();}if (calculatedAmount != totalAmount) {LOGGER.warn("Error occured while validating payment options amount[{}] != TotalAmount [{}]",calculatedAmount, totalAmount);throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_CALCULATED_AMOUNT,calculatedAmount, "FFORDR_1016");}List<Integer> foundPaymentOptionIds = paymentOptionRepository.selectIdsByIds(paymentOptionIds);if (foundPaymentOptionIds.size() != paymentOptionIds.size()) {paymentOptionIds.removeAll(foundPaymentOptionIds);throw new ProfitMandiBusinessException(ProfitMandiConstants.PAYMENT_OPTION_ID, paymentOptionIds,"FFORDR_1017");}}@Overridepublic List<FofoOrderItem> getByOrderId(int orderId) throws ProfitMandiBusinessException {List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(orderId);if (!fofoOrderItems.isEmpty()) {List<FofoOrderItem> newFofoOrderItems = new ArrayList<>();Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = this.toFofoOrderItemIdFofoLineItems(fofoOrderItems);Iterator<FofoOrderItem> fofoOrderItemsIterator = fofoOrderItems.iterator();while (fofoOrderItemsIterator.hasNext()) {FofoOrderItem fofoOrderItem = fofoOrderItemsIterator.next();fofoOrderItem.setFofoLineItems(fofoOrderItemIdFofoLineItemsMap.get(fofoOrderItem.getId()));newFofoOrderItems.add(fofoOrderItem);fofoOrderItemsIterator.remove();}fofoOrderItems = newFofoOrderItems;}return fofoOrderItems;}private Set<Integer> toFofoOrderItemIds(List<FofoOrderItem> fofoOrderItems) {Function<FofoOrderItem, Integer> fofoOrderItemToFofoOrderItemIdFunction = new Function<FofoOrderItem, Integer>() {@Overridepublic Integer apply(FofoOrderItem fofoOrderItem) {return fofoOrderItem.getId();}};return fofoOrderItems.stream().map(fofoOrderItemToFofoOrderItemIdFunction).collect(Collectors.toSet());}private Map<Integer, Set<FofoLineItem>> toFofoOrderItemIdFofoLineItems(List<FofoOrderItem> fofoOrderItems) {Set<Integer> fofoOrderItemIds = this.toFofoOrderItemIds(fofoOrderItems);List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIds);Map<Integer, Set<FofoLineItem>> fofoOrderItemIdFofoLineItemsMap = new HashMap<>();for (FofoLineItem fofoLineItem : fofoLineItems) {if (!fofoOrderItemIdFofoLineItemsMap.containsKey(fofoLineItem.getFofoOrderItemId())) {Set<FofoLineItem> fofoLineItems2 = new HashSet<>();fofoLineItems2.add(fofoLineItem);fofoOrderItemIdFofoLineItemsMap.put(fofoLineItem.getFofoOrderItemId(), fofoLineItems2);} else {fofoOrderItemIdFofoLineItemsMap.get(fofoLineItem.getFofoOrderItemId()).add(fofoLineItem);}}return fofoOrderItemIdFofoLineItemsMap;}@Overridepublic void updateCustomerDetails(CustomCustomer customCustomer, String invoiceNumber)throws ProfitMandiBusinessException {FofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());customer.setFirstName(customCustomer.getFirstName());customer.setLastName(customCustomer.getLastName());customer.setMobileNumber(customCustomer.getMobileNumber());customer.setEmailId(customCustomer.getEmailId());customerRepository.persist(customer);CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());if (!customerAddress.getState().equalsIgnoreCase(customCustomer.getAddress().getState())) {List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());resetTaxation(fofoOrder.getFofoId(), customerAddress, fofoOrderItems);}this.setCustomerAddress(customerAddress, customCustomer.getAddress());customerAddressRepository.persist(customerAddress);fofoOrder.setCustomerGstNumber(customCustomer.getGstNumber());}private void resetTaxation(int fofoId, CustomerAddress customerAddress, List<FofoOrderItem> fofoOrderItems)throws ProfitMandiBusinessException {int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(fofoId);Address retailerAddress = addressRepository.selectById(retailerAddressId);Integer stateId = null;if (customerAddress.getState().equalsIgnoreCase(retailerAddress.getState())) {try {stateId = Long.valueOf(Utils.getStateInfo(customerAddress.getState()).getId()).intValue();} catch (Exception e) {LOGGER.error("Unable to get state rates");}}List<Integer> itemIds = fofoOrderItems.stream().map(x -> x.getItemId()).collect(Collectors.toList());final Map<Integer, GstRate> gstRates;if (stateId != null) {gstRates = stateGstRateRepository.getStateTaxRate(itemIds, stateId);} else {gstRates = new HashMap<>();stateGstRateRepository.getIgstTaxRate(itemIds).entrySet().forEach(x -> {GstRate gstRate = new GstRate();gstRate.setIgstRate(x.getValue());gstRate.setCgstRate(0f);gstRate.setSgstRate(0f);gstRates.put(x.getKey(), gstRate);});}for (FofoOrderItem fofoOrderItem : fofoOrderItems) {GstRate rate = gstRates.get(fofoOrderItem.getItemId());fofoOrderItem.setCgstRate(rate.getCgstRate());fofoOrderItem.setSgstRate(rate.getSgstRate());fofoOrderItem.setIgstRate(rate.getIgstRate());}}@Overridepublic CustomerCreditNote badReturn(int fofoId, FoiBadReturnRequest foiBadReturnRequest)throws ProfitMandiBusinessException {FofoOrderItem foi = fofoOrderItemRepository.selectById(foiBadReturnRequest.getFofoOrderItemId());FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(foi.getOrderId());if (fofoOrder.getFofoId() != fofoId) {throw new ProfitMandiBusinessException("Partner Auth", "", "Invalid Order");}int billedQty = foi.getQuantity() - customerReturnItemRepository.selectAllByOrderItemId(foi.getId()).size();if (foiBadReturnRequest.getMarkedBadArr().size() > billedQty) {throw new ProfitMandiBusinessException("Cant bad return more than what is billed", "", "Invalid Quantity");}List<CustomerReturnItem> customerReturnItems = new ArrayList<>();for (BadReturnRequest badReturnRequest : foiBadReturnRequest.getMarkedBadArr()) {CustomerReturnItem customerReturnItem = new CustomerReturnItem();customerReturnItem.setFofoId(fofoId);customerReturnItem.setFofoOrderItemId(foiBadReturnRequest.getFofoOrderItemId());customerReturnItem.setFofoOrderId(fofoOrder.getId());customerReturnItem.setRemarks(badReturnRequest.getRemarks());customerReturnItem.setInventoryItemId(badReturnRequest.getInventoryItemId());customerReturnItem.setQuantity(1);customerReturnItem.setType(ReturnType.BAD);// customerReturnItemRepository.persist(customerReturnItem);inventoryService.saleReturnInventoryItem(customerReturnItem);customerReturnItems.add(customerReturnItem);}CustomerCreditNote creditNote = generateCreditNote(fofoOrder, customerReturnItems);for (CustomerReturnItem customerReturnItem : customerReturnItems) {purchaseReturnService.returnInventoryItem(fofoId, false, customerReturnItem.getInventoryItemId(),ReturnType.BAD);}// This should cancel the orderfofoOrder.setCancelledTimestamp(LocalDateTime.now());return creditNote;}private CustomerCreditNote generateCreditNote(FofoOrder fofoOrder, List<CustomerReturnItem> customerReturnItems)throws ProfitMandiBusinessException {InvoiceNumberGenerationSequence sequence = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoOrder.getFofoId());sequence.setCreditNoteSequence(sequence.getCreditNoteSequence() + 1);invoiceNumberGenerationSequenceRepository.persist(sequence);String creditNoteNumber = sequence.getPrefix() + "/" + sequence.getCreditNoteSequence();CustomerCreditNote creditNote = new CustomerCreditNote();creditNote.setCreditNoteNumber(creditNoteNumber);creditNote.setFofoId(fofoOrder.getFofoId());creditNote.setFofoOrderId(fofoOrder.getId());creditNote.setFofoOrderItemId(customerReturnItems.get(0).getFofoOrderItemId());creditNote.setSettlementType(SettlementType.UNSETTLED);customerCreditNoteRepository.persist(creditNote);for (CustomerReturnItem customerReturnItem : customerReturnItems) {customerReturnItem.setCreditNoteId(creditNote.getId());customerReturnItemRepository.persist(customerReturnItem);}// this.returnInventoryItems(inventoryItems, debitNote);return creditNote;}@Overridepublic CreditNotePdfModel getCreditNotePdfModel(int customerCreditNoteId) throws ProfitMandiBusinessException {CustomerCreditNote creditNote = customerCreditNoteRepository.selectById(customerCreditNoteId);return getCreditNotePdfModel(creditNote);}private CreditNotePdfModel getCreditNotePdfModel(CustomerCreditNote creditNote)throws ProfitMandiBusinessException {FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(creditNote.getFofoOrderId());List<CustomerReturnItem> customerReturnItems = customerReturnItemRepository.selectAllByCreditNoteId(creditNote.getId());CustomCustomer customCustomer = getCustomCustomer(fofoOrder);Set<CustomOrderItem> customerFofoOrderItems = new HashSet<>();CustomRetailer customRetailer = retailerService.getFofoRetailers(Arrays.asList(fofoOrder.getFofoId())).get(fofoOrder.getFofoId());FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(creditNote.getFofoOrderItemId());float totalTaxRate = fofoOrderItem.getIgstRate() + fofoOrderItem.getSgstRate() + fofoOrderItem.getCgstRate();float taxableSellingPrice = fofoOrderItem.getSellingPrice() / (1 + totalTaxRate / 100);float taxableDiscountPrice = fofoOrderItem.getDiscount() / (1 + totalTaxRate / 100);CustomOrderItem customFofoOrderItem = new CustomOrderItem();customFofoOrderItem.setAmount(customerReturnItems.size() * (taxableSellingPrice - taxableDiscountPrice));customFofoOrderItem.setDescription(fofoOrderItem.getBrand() + " " + fofoOrderItem.getModelName() + " "+ fofoOrderItem.getModelNumber() + "-" + fofoOrderItem.getColor());if (ItemType.SERIALIZED.equals(itemRepository.selectById(fofoOrderItem.getItemId()).getType())) {Set<Integer> inventoryItemIds = customerReturnItems.stream().map(x -> x.getInventoryItemId()).collect(Collectors.toSet());List<String> serialNumbers = inventoryItemRepository.selectByIds(inventoryItemIds).stream().map(x -> x.getSerialNumber()).collect(Collectors.toList());customFofoOrderItem.setDescription(customFofoOrderItem.getDescription() + "\n IMEIS - " + String.join(", ", serialNumbers));}customFofoOrderItem.setRate(taxableSellingPrice);customFofoOrderItem.setDiscount(taxableDiscountPrice);customFofoOrderItem.setQuantity(customerReturnItems.size());customFofoOrderItem.setNetAmount((fofoOrderItem.getSellingPrice() - fofoOrderItem.getDiscount()) * customFofoOrderItem.getQuantity());float igstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getIgstRate()) / 100;float cgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getCgstRate()) / 100;float sgstAmount = (customFofoOrderItem.getAmount() * fofoOrderItem.getSgstRate()) / 100;LOGGER.info("fofoOrderItem - {}", fofoOrderItem);customFofoOrderItem.setIgstRate(fofoOrderItem.getIgstRate());customFofoOrderItem.setIgstAmount(igstAmount);customFofoOrderItem.setCgstRate(fofoOrderItem.getCgstRate());customFofoOrderItem.setCgstAmount(cgstAmount);customFofoOrderItem.setSgstRate(fofoOrderItem.getSgstRate());customFofoOrderItem.setSgstAmount(sgstAmount);customFofoOrderItem.setHsnCode(fofoOrderItem.getHsnCode());customFofoOrderItem.setOrderId(1);customerFofoOrderItems.add(customFofoOrderItem);PdfModel pdfModel = new PdfModel();pdfModel.setAuther("NSSPL");pdfModel.setCustomer(customCustomer);pdfModel.setInvoiceNumber(fofoOrder.getInvoiceNumber());pdfModel.setInvoiceDate(FormattingUtils.formatDate(fofoOrder.getCreateTimestamp()));pdfModel.setTitle("Credit Note");pdfModel.setRetailer(customRetailer);pdfModel.setTotalAmount(customFofoOrderItem.getNetAmount());pdfModel.setOrderItems(customerFofoOrderItems);CreditNotePdfModel creditNotePdfModel = new CreditNotePdfModel();creditNotePdfModel.setCreditNoteDate(FormattingUtils.formatDate(creditNote.getCreateTimestamp()));creditNotePdfModel.setCreditNoteNumber(creditNote.getCreditNoteNumber());creditNotePdfModel.setPdfModel(pdfModel);return creditNotePdfModel;}// This will remove the order and maintain order record and reverse inventory// and scheme@Overridepublic void cancelOrder(List<String> invoiceNumbers) throws Exception {for (String invoiceNumber : invoiceNumbers) {// Cancel only when not cancelledFofoOrder fofoOrder = fofoOrderRepository.selectByInvoiceNumber(invoiceNumber);if (fofoOrder.getCancelledTimestamp() == null) {fofoOrder.setCancelledTimestamp(LocalDateTime.now());fofoOrderRepository.persist(fofoOrder);List<PaymentOptionTransaction> paymentTransactions = paymentOptionTransactionRepository.selectByReferenceIdAndType(fofoOrder.getId(), PaymentOptionReferenceType.ORDER);for (PaymentOptionTransaction paymentOptionTransaction : paymentTransactions) {paymentOptionTransactionRepository.delete(paymentOptionTransaction);}List<FofoOrderItem> fois = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());List<InventoryItem> inventoryItems = new ArrayList<>();fois.stream().forEach(x -> {x.getFofoLineItems().stream().forEach(y -> {inventoryService.rollbackInventory(y.getInventoryItemId(), y.getQuantity(),fofoOrder.getFofoId());inventoryItems.add(inventoryItemRepository.selectById(y.getInventoryItemId()));});});String reversalReason = "Order Rolledback/Cancelled for Invoice Number " + invoiceNumber;schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, SchemeType.OUT);schemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, SchemeType.ACTIVATION);// If insured that no cancellation happens on next monthschemeService.reverseSchemes(inventoryItems, fofoOrder.getId(), reversalReason, SchemeType.INVESTMENT);}}}@Overridepublic float getSales(int fofoId, LocalDateTime startDate, LocalDateTime endDate) {Float sales = fofoOrderRepository.selectSaleSumGroupByFofoIds(startDate, endDate).get(fofoId);return sales == null ? 0f : sales;}@Overridepublic LocalDateTime getMaxSalesDate(int fofoId, LocalDateTime startDate, LocalDateTime endDate) {LocalDateTime dateTime = fofoOrderRepository.selectMaxSaleDateGroupByFofoIds(startDate, endDate).get(fofoId);return dateTime;}@Override// Only being used internallypublic float getSales(int fofoId, LocalDate onDate) {LocalDateTime startTime = LocalDateTime.of(onDate, LocalTime.MIDNIGHT);LocalDateTime endTime = LocalDateTime.of(onDate, LocalTime.MIDNIGHT).plusDays(1);return this.getSales(fofoId, startTime, endTime);}@Overridepublic float getSales(LocalDateTime onDate) {// TODO Auto-generated method stubreturn 0;}@Overridepublic float getSales(LocalDateTime startDate, LocalDateTime endDate) {// TODO Auto-generated method stubreturn 0;}@Overridepublic boolean notifyColorChange(int orderId, int itemId) throws ProfitMandiBusinessException {Order order = orderRepository.selectById(orderId);saholicInventoryService.reservationCountByColor(itemId, order);order.getLineItem().setItemId(itemId);Item item = itemRepository.selectById(itemId);order.getLineItem().setColor(item.getColor());return true;}@Overridepublic FofoOrder getOrderByInventoryItemId(int inventoryItemId) throws Exception {List<FofoLineItem> lineItems = fofoLineItemRepository.selectByInventoryItemId(inventoryItemId);if (lineItems.size() > 0) {FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectById(lineItems.get(0).getFofoOrderItemId());fofoOrderItem.setFofoLineItems(new HashSet<>(lineItems));FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(fofoOrderItem.getOrderId());fofoOrder.setOrderItem(fofoOrderItem);return fofoOrder;} else {throw new Exception(String.format("Could not find inventoryItemId - %s", inventoryItemId));}}@Overridepublic Map<Integer, Long> carryBagCreditCount(int fofoId) throws ProfitMandiBusinessException {FofoStore fs = fofoStoreRepository.selectByRetailerId(fofoId);LocalDateTime lastCredit = fs.getBagsLastCredited();/** long carryBagCount = 0; List<FofoOrder> fofoOrders =* fofoOrderRepository.selectByFofoIdBetweenCreatedTimeStamp(fofoId,* lastCredit.atStartOfDay(), LocalDate.now().plusDays(1).atStartOfDay()); for* (FofoOrder fo : fofoOrders) { carryBagCount +=* fofoOrderItemRepository.selectByOrderId(fo.getId()).stream() .filter(x ->* x.getSellingPrice() >= 12000).count();** }*/Session session = sessionFactory.getCurrentSession();CriteriaBuilder cb = session.getCriteriaBuilder();CriteriaQuery<SimpleEntry> query = cb.createQuery(SimpleEntry.class);Root<FofoOrder> fofoOrder = query.from(FofoOrder.class);Root<FofoOrderItem> fofoOrderItem = query.from(FofoOrderItem.class);Predicate p2 = cb.between(fofoOrder.get(ProfitMandiConstants.CREATE_TIMESTAMP), lastCredit,LocalDate.now().atStartOfDay());Predicate p3 = cb.isNull(fofoOrder.get("cancelledTimestamp"));Predicate p4 = cb.equal(fofoOrder.get(ProfitMandiConstants.ID),fofoOrderItem.get(ProfitMandiConstants.ORDER_ID));Predicate p5 = cb.equal(fofoOrder.get(ProfitMandiConstants.FOFO_ID), fofoId);ItemCriteria itemCriteria = new ItemCriteria();itemCriteria.setBrands(mongoClient.getMongoBrands(fofoId, null, 3).stream().map(x -> (String) x.get("name")).collect(Collectors.toList()));float startValue = 12000;itemCriteria.setStartPrice(startValue);itemCriteria.setEndPrice(0);itemCriteria.setFeaturedPhone(false);itemCriteria.setSmartPhone(true);itemCriteria.setCatalogIds(new ArrayList<>());itemCriteria.setExcludeCatalogIds(new ArrayList<>());Predicate itemPredicate = itemRepository.getItemPredicate(itemCriteria, query, cb, fofoOrderItem, "dp");Predicate finalPredicate = cb.and(itemPredicate, p2, p3, p4, p5);query = query.multiselect(fofoOrder.get(ProfitMandiConstants.FOFO_ID), cb.count(fofoOrder)).where(finalPredicate).groupBy(fofoOrder.get(ProfitMandiConstants.FOFO_ID));List<SimpleEntry> simpleEntries = session.createQuery(query).getResultList();Map<Integer, Long> returnMap = new HashMap<>();for (SimpleEntry simpleEntry : simpleEntries) {returnMap.put((Integer) simpleEntry.getKey(), (Long) simpleEntry.getValue());}return returnMap;}}