Rev 24785 | Rev 24826 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.smartdukaan.cron.scheduled;import java.io.Serializable;import java.time.LocalDate;import java.util.ArrayList;import java.util.Arrays;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;import java.util.stream.Collectors;import org.apache.commons.io.output.ByteArrayOutputStream;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.core.io.ByteArrayResource;import org.springframework.mail.javamail.JavaMailSender;import org.springframework.stereotype.Component;import com.spice.profitmandi.common.util.FileUtil;import com.spice.profitmandi.common.util.FormattingUtils;import com.spice.profitmandi.common.util.Utils;import com.spice.profitmandi.dao.entity.catalog.Scheme;import com.spice.profitmandi.dao.entity.fofo.InventoryItem;import com.spice.profitmandi.dao.entity.fofo.SchemeInOut;import com.spice.profitmandi.dao.entity.transaction.Order;import com.spice.profitmandi.dao.entity.transaction.ReturnOrder;import com.spice.profitmandi.dao.entity.transaction.UserWallet;import com.spice.profitmandi.dao.entity.transaction.UserWalletHistory;import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;import com.spice.profitmandi.dao.repository.catalog.SchemeRepository;import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;import com.spice.profitmandi.dao.repository.fofo.SchemeInOutRepository;import com.spice.profitmandi.dao.repository.transaction.OrderRepository;import com.spice.profitmandi.dao.repository.transaction.ReturnOrderRepository;import com.spice.profitmandi.dao.repository.transaction.UserWalletHistoryRepository;import com.spice.profitmandi.dao.repository.transaction.UserWalletRepository;import com.spice.profitmandi.service.user.RetailerService;import in.shop2020.model.v1.order.OrderStatus;import in.shop2020.model.v1.order.WalletReferenceType;@Componentpublic class Reconciliation {@Autowiredprivate FofoStoreRepository fofoStoreRepository;@Autowiredprivate UserWalletRepository userWalletRepository;@Autowiredprivate UserWalletHistoryRepository userWalletHistoryRepository;@Autowiredprivate SchemeInOutRepository schemeInOutRepository;@Autowiredprivate SchemeRepository schemeRepository;@Autowiredprivate InventoryItemRepository inventoryRepository;@Autowiredprivate RetailerService retailerService;@Autowiredprivate ReturnOrderRepository returnOrderRepository;@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate JavaMailSender mailSender;public void dailyReconciliation() throws Exception {Map<SchemeType, Set<Integer>> schemeTypeMap = schemeRepository.selectAll().stream().collect(Collectors.groupingBy(Scheme::getType, Collectors.mapping(Scheme::getId, Collectors.toSet())));boolean reconciled = true;Map<Integer, String> stores = fofoStoreRepository.getStoresMap();List<List<? extends Serializable>> rows = new ArrayList<>();LocalDate yesterday = LocalDate.now().minusDays(1);Map<Integer, String> retailerNameMap = retailerService.getAllFofoRetailerIdNameMap(new ArrayList<>(stores.keySet()));for (int partnerId : stores.keySet()) {UserWallet uw = userWalletRepository.selectByRetailerId(partnerId);List<UserWalletHistory> walletHistory = userWalletHistoryRepository.selectByWalletIdAndDate(uw.getId(),yesterday);Map<WalletReferenceType, List<UserWalletHistory>> referenceWiseWalletHistory = walletHistory.stream().collect(Collectors.groupingBy(x -> x.getReferenceType(), Collectors.toList()));for (Map.Entry<WalletReferenceType, List<UserWalletHistory>> entry : referenceWiseWalletHistory.entrySet()) {LocalDate dateToReconcile = yesterday;List<UserWalletHistory> history = entry.getValue();List<Serializable> reconciliation = Arrays.asList(retailerNameMap.get(partnerId));Map<Integer, Integer> referenceWalletMap = entry.getValue().stream().collect(Collectors.groupingBy(x -> x.getReference(), Collectors.summingInt(x -> x.getAmount())));switch (entry.getKey()) {case PURCHASE:reconciliation.addAll(reconcileOrdersAndWallet(uw.getUserId(), dateToReconcile, referenceWalletMap, history));break;case SCHEME_IN:reconciliation.addAll(reconcileSchemeInAndWallet(uw.getUserId(), dateToReconcile,referenceWalletMap, history, schemeTypeMap.get(SchemeType.IN)));break;case SCHEME_OUT:break;default:break;}reconciled = reconciled || Boolean.TRUE.equals(reconciliation.get(0));rows.add(reconciliation);}}ByteArrayOutputStream baos = FileUtil.getCSVByteStream(Arrays.asList("Store Name", "Wallet amount consumed","Ordered Total", "Cancelled Total", "Refunded Total", "Scheme In to Wallet", "Scheme In disbursed", "Scheme In rolledback","Scheme Out to Wallet", "Scheme Out Disbursed", "Scheme Out Rolledback"), rows);Utils.sendMailWithAttachment(mailSender, new String[] { "amit.gupta@shop2020.in" }, new String[] {},reconciled ? "Reconciled Successfully" : "Reconciliation failed", "Report attached",String.format("reconciliation-%s.csv", FormattingUtils.formatDate(yesterday.atStartOfDay())),new ByteArrayResource(baos.toByteArray()));}private List<? extends Serializable> reconcileOrdersAndWallet(int fofoId, LocalDate localDate,Map<Integer, Integer> transactionsOnThatDate, List<UserWalletHistory> history) throws Exception {int totalWalletConsumed = 0;float cancelledAmount = 0;float returnedAmount = 0;float totalDeductedAmount = 0;for (int transactionId : transactionsOnThatDate.keySet()) {List<Order> orders = orderRepository.selectAllByTransactionId(transactionId);for (Order o : orders) {if (o.getCreateTimestamp().toLocalDate().equals(localDate)) {if (Arrays.asList(OrderStatus.PAYMENT_PENDING, OrderStatus.PAYMENT_FAILED).contains(o.getStatus())) {cancelledAmount += o.getWalletAmount();} else if (o.getRefundTimestamp() != null&& o.getRefundTimestamp().toLocalDate().equals(localDate)) {ReturnOrder returnedOrder = returnOrderRepository.selectByOrderId(o.getId());if (returnedOrder == null) {cancelledAmount += o.getWalletAmount();} else {returnedAmount += returnedOrder.getTotalPrice();}}totalDeductedAmount += o.getWalletAmount();} else if (o.getRefundTimestamp() != null && o.getRefundTimestamp().toLocalDate().equals(localDate)) {ReturnOrder returnedOrder = returnOrderRepository.selectByOrderId(o.getId());if (returnedOrder == null) {cancelledAmount += o.getWalletAmount();} else {returnedAmount += returnedOrder.getTotalPrice();}}}totalWalletConsumed -= transactionsOnThatDate.get(transactionId);}boolean reconciled = Math.abs(totalWalletConsumed - (totalDeductedAmount - cancelledAmount - returnedAmount)) < 2;return Arrays.asList(reconciled, totalWalletConsumed, totalDeductedAmount, cancelledAmount, returnedAmount);}private List<? extends Serializable> reconcileSchemeInAndWallet(int fofoId, LocalDate localDate,Map<Integer, Integer> transactionsOnThatDate, List<UserWalletHistory> history, Set<Integer> schemeIds) {int totalSchemeInWalletCredited = 0;float schemeInAmountAdded = 0;float schemeInAmountRolledBack = 0;for (int transactionId : transactionsOnThatDate.keySet()) {List<InventoryItem> inventoryItems = inventoryRepository.selectByPurchaseId(transactionId).stream().filter(x -> x.getSerialNumber() != null).collect(Collectors.toList());Set<Integer> inventoryItemIds = inventoryItems.stream().map(x -> x.getId()).collect(Collectors.toSet());List<SchemeInOut> sios = schemeInOutRepository.selectByInventoryItemIds(new HashSet<>(inventoryItemIds)).stream().filter(x -> schemeIds.contains(x.getSchemeId())).collect(Collectors.toList());totalSchemeInWalletCredited += transactionsOnThatDate.get(transactionId);for (SchemeInOut sio : sios) {if (sio.getCreateTimestamp().toLocalDate().equals(localDate)) {schemeInAmountAdded += sio.getAmount();}if (sio.getRolledBackTimestamp().toLocalDate().equals(localDate)) {schemeInAmountAdded += sio.getAmount();}}}boolean reconciled = Math.abs(totalSchemeInWalletCredited - (schemeInAmountAdded - schemeInAmountRolledBack)) < 5;return Arrays.asList(reconciled, totalSchemeInWalletCredited, schemeInAmountAdded, schemeInAmountRolledBack);}private void reconcileSchemeOutAndWallet() {}}