Subversion Repositories SmartDukaan

Rev

Rev 24916 | Rev 24953 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.smartdukaan.cron.migrations;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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 org.springframework.transaction.annotation.Transactional;

import com.spice.profitmandi.common.util.FileUtil;
import com.spice.profitmandi.common.util.Utils;
import com.spice.profitmandi.dao.entity.fofo.CurrentInventorySnapshot;
import com.spice.profitmandi.dao.entity.fofo.FofoOrder;
import com.spice.profitmandi.dao.entity.fofo.FofoOrderItem;
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
import com.spice.profitmandi.dao.entity.fofo.PartnerTargetDetails;
import com.spice.profitmandi.dao.entity.fofo.Purchase;
import com.spice.profitmandi.dao.entity.fofo.ScanRecord;
import com.spice.profitmandi.dao.entity.fofo.TargetSlab;
import com.spice.profitmandi.dao.entity.transaction.LineItem;
import com.spice.profitmandi.dao.entity.transaction.LineItemImei;
import com.spice.profitmandi.dao.entity.transaction.Order;
import com.spice.profitmandi.dao.entity.transaction.SellerWarehouse;
import com.spice.profitmandi.dao.repository.GenericRepository;
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
import com.spice.profitmandi.dao.repository.fofo.CurrentInventorySnapshotRepository;
import com.spice.profitmandi.dao.repository.fofo.DebitNoteRepository;
import com.spice.profitmandi.dao.repository.fofo.FofoOrderItemRepository;
import com.spice.profitmandi.dao.repository.fofo.FofoOrderRepository;
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
import com.spice.profitmandi.dao.repository.fofo.InvoiceNumberGenerationSequenceRepository;
import com.spice.profitmandi.dao.repository.fofo.PartnerTargetRepository;
import com.spice.profitmandi.dao.repository.fofo.PurchaseRepository;
import com.spice.profitmandi.dao.repository.fofo.ScanRecordRepository;
import com.spice.profitmandi.dao.repository.fofo.SchemeInOutRepository;
import com.spice.profitmandi.dao.repository.fofo.TargetSlabRepository;
import com.spice.profitmandi.dao.repository.fofo.TargetSlabRepositoryImpl;
import com.spice.profitmandi.dao.repository.transaction.LineItemImeisRepository;
import com.spice.profitmandi.dao.repository.transaction.LineItemRepository;
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
import com.spice.profitmandi.dao.repository.transaction.ReturnOrderRepository;
import com.spice.profitmandi.dao.repository.transaction.SellerWarehouseRepository;
import com.spice.profitmandi.dao.repository.transaction.UserWalletHistoryRepository;
import com.spice.profitmandi.dao.repository.transaction.UserWalletRepository;
import com.spice.profitmandi.dao.repository.user.UserRepository;
import com.spice.profitmandi.service.inventory.InventoryService;
import com.spice.profitmandi.service.order.OrderService;
import com.spice.profitmandi.service.pricing.PriceDropService;
import com.spice.profitmandi.service.scheme.SchemeService;
import com.spice.profitmandi.service.transaction.TransactionService;
import com.spice.profitmandi.service.user.RetailerService;
import com.spice.profitmandi.service.wallet.WalletService;

import in.shop2020.model.v1.order.WalletReferenceType;

@Component
@Transactional(rollbackFor = Throwable.class)
public class RunOnceTasks {

        private static final Logger LOGGER = LogManager.getLogger(RunOnceTasks.class);

        @Autowired
        private LineItemRepository lineItemRepository;

        @Autowired
        private TargetSlabRepository targetSlabRepository;

        @Autowired
        private PartnerTargetRepository partnerTargetRepository;

        @Autowired
        private SellerWarehouseRepository sellerWarehouseRepository;

        @Autowired
        private FofoOrderItemRepository fofoOrderItemRepository;

        @Autowired
        private FofoOrderRepository fofoOrderRepository;

        @Autowired
        private UserWalletRepository userWalletRepository;

        @Autowired
        private UserWalletHistoryRepository userWalletHistoryRepository;

        @Autowired
        private UserRepository userRepository;

        @Autowired
        private WalletService walletService;

        @Autowired
        private InventoryService inventoryService;

        @Autowired
        private TransactionService transactionService;

        // Service for Tertiary/Partner Orders
        @Autowired
        private OrderService orderService;

        @Autowired
        private ReturnOrderRepository returnOrderRepository;

        @Autowired
        private FofoStoreRepository fofoStoreRepository;

        @Autowired
        private LineItemImeisRepository lineItemImeisRepository;

        @Autowired
        private InventoryItemRepository inventoryItemRepository;

        @Autowired
        private InvoiceNumberGenerationSequenceRepository invoiceNumberGenerationSequenceRepository;

        @Autowired
        private RetailerService retailerService;

        @Autowired
        private SchemeInOutRepository schemeInOutRepository;

        @Autowired
        private DebitNoteRepository debitNoteRepository;

        @Autowired
        private GenericRepository genericRepository;

        @Autowired
        private PurchaseRepository purchaseRepository;

        @Autowired
        private PriceDropService priceDropService;

        @Autowired
        private JavaMailSender googleMailSender;

        @Autowired
        private SchemeService schemeService;

        @Autowired
        private CurrentInventorySnapshotRepository currentInventorySnapshotRepository;

        @Autowired
        private OrderRepository orderRepository;

        @Autowired
        private ScanRecordRepository scanRecordRepository;

        @Autowired
        private JavaMailSender mailSender;

        public void dropCorrection() throws Exception {

                walletService.rollbackAmountFromWallet(175128034, 274, 4, WalletReferenceType.PRICE_DROP,
                                "Scheme  differential for Price Drop of Rs.712 on Samsung J6 J600GG, on 01-08-2018 for missing 1pc");
                walletService.rollbackAmountFromWallet(175128034, -259, 4, WalletReferenceType.PRICE_DROP,
                                "Scheme  differential for Price Drop of Rs.712 on Samsung J6 J600GG, on 01-08-2018 for missing 1pc");
                List<InventoryItem> iis = inventoryItemRepository.selectByIds(new HashSet<>(Arrays.asList(3518, 3516)));
                schemeService.reverseSchemes(iis, 8,
                                "Scheme  differential for Price Drop of Rs.712 on Samsung J6 J600GG, on 01-08-2018. Total 2 item(s)");
                List<InventoryItem> iis1 = inventoryItemRepository.selectByIds(new HashSet<>(Arrays.asList(3502, 3334, 3503)));
                schemeService.reverseSchemes(iis1, 13,
                                "Scheme  differential for Price Drop of Rs.485 on Samsung Galaxy J4 J400FD, on 18-07-2018. Total 3 item(s)");

                List<InventoryItem> iis2 = inventoryItemRepository.selectByIds(new HashSet<>(Arrays.asList(3319)));
                schemeService.reverseSchemes(iis2, 13,
                                "Scheme  differential for Price Drop of Rs.485 on Samsung Galaxy J4 J400FD, on 18-07-2018. Total 1 item(s)");
        }

        public void schemeRollback() {
                Map<Integer, Float> fofoIdAmount = new HashMap<>();
                fofoIdAmount.put(175135218, 1942f);
                String description = "Price drop/differential rolled out as, they were already returned, Total 2pcs.";
                for (Map.Entry<Integer, Float> fofoIdAmountEntry : fofoIdAmount.entrySet()) {
                        Integer fofoId = fofoIdAmountEntry.getKey();
                        Float amount = fofoIdAmountEntry.getValue();
                        walletService.rollbackAmountFromWallet(fofoId, amount, 4, WalletReferenceType.PRICE_DROP, description);
                }
                fofoIdAmount.put(175135218, 438f);
                for (Map.Entry<Integer, Float> fofoIdAmountEntry : fofoIdAmount.entrySet()) {
                        Integer fofoId = fofoIdAmountEntry.getKey();
                        Float amount = fofoIdAmountEntry.getValue();
                        walletService.rollbackAmountFromWallet(fofoId, amount, 4, WalletReferenceType.PRICE_DROP, description);
                }
        }

        public void populateGrnTimestamp() {
                List<Purchase> allPurchases = purchaseRepository.selectAll();
                for (Purchase p : allPurchases) {
                        String invoiceNumber = p.getPurchaseReference();
                        if (p.getCompleteTimestamp() == null) {
                                LOGGER.info("GRN for invoice {} is delivered but partially Completed.", p.getPurchaseReference());
                        } else {
                                List<Order> orders = orderRepository.selectByAirwayBillOrInvoiceNumber(invoiceNumber, p.getFofoId());
                                for (Order order : orders) {
                                        if (order.getPartnerGrnTimestamp() == null) {
                                                order.setPartnerGrnTimestamp(p.getCompleteTimestamp());
                                                orderRepository.persist(order);
                                        }
                                }
                        }
                }

        }

        public void migarateLineItemsToNewTable() throws Exception {
                LOGGER.info("Before Migrated LineItems Successfully");
                int lineItemImeiId = 0;
                LocalDateTime startDate = null;
                try {
                        lineItemImeiId = lineItemImeisRepository.selectMaxId();
                        LineItem lineItem = lineItemRepository
                                        .selectById(lineItemImeisRepository.selectById(lineItemImeiId).getLineItemId());
                        Order order = orderRepository.selectById(lineItem.getOrderId());
                        startDate = order.getBillingTimestamp();
                } catch (Exception e) {
                        LOGGER.info("Running before first time");
                        startDate = LocalDateTime.of(LocalDate.of(2017, 7, 1), LocalTime.MIDNIGHT);
                }
                List<Order> orders = orderRepository.selectAllByBillingDatesBetween(startDate, LocalDateTime.now());
                Collections.reverse(orders);

                for (Order order : orders) {
                        try {
                                String serialNumbers = order.getLineItem().getSerialNumber();
                                if (!StringUtils.isEmpty(serialNumbers)) {
                                        List<String> serialNumberList = Arrays.asList(serialNumbers.split(","));
                                        for (String serialNumber : serialNumberList) {
                                                int lineItemId = order.getLineItem().getId();
                                                LineItemImei lineItemImei = new LineItemImei();
                                                lineItemImei.setSerialNumber(serialNumber);
                                                lineItemImei.setLineItemId(lineItemId);
                                                lineItemImeisRepository.persist(lineItemImei);
                                        }
                                } else {
                                        LOGGER.info("Serial Numbers dont exist for Order {}", order.getId());
                                }
                        } catch (Exception e) {
                                LOGGER.info("Error occurred while creating lineitem imei {}, because of {}", order.getId(),
                                                e.getMessage());
                        }
                }
                LOGGER.info("Migrated LineItems Successfully");
        }

        public void cancelOrder(List<String> invoiceNumbers) throws Exception {
                orderService.cancelOrder(invoiceNumbers);
        }

        public void migratePurchase() throws Exception {
                List<Purchase> purchases = purchaseRepository.selectPurchaseAllPurchasesLessThanZero();
                System.out.printf("Total Purchases count is %s", purchases.size());
                for (Purchase purchase : purchases) {
                        List<InventoryItem> inventoryItems = inventoryItemRepository.selectByPurchaseId(purchase.getId());
                        Map<Integer, List<InventoryItem>> itemIdInventoryMap = inventoryItems.stream()
                                        .collect(Collectors.groupingBy(InventoryItem::getItemId));
                        List<Order> orders = orderRepository.selectByAirwayBillOrInvoiceNumber(purchase.getPurchaseReference(),
                                        purchase.getFofoId());
                        Map<Integer, Integer> ourSaleItemQtyMap = orders.stream().collect(Collectors.groupingBy(
                                        x -> x.getLineItem().getItemId(), Collectors.summingInt(x -> x.getLineItem().getQuantity())));
                        Map<Integer, Integer> theirPurchaseItemQtyMap = inventoryItems.stream().collect(Collectors
                                        .groupingBy(InventoryItem::getItemId, Collectors.summingInt(InventoryItem::getInitialQuantity)));
                        for (Map.Entry<Integer, Integer> itemQtyEntry : theirPurchaseItemQtyMap.entrySet()) {
                                if (!ourSaleItemQtyMap.containsKey(itemQtyEntry.getKey())) {
                                        LOGGER.info("Cannot find in Invoice {} item {}", purchase.getPurchaseReference(),
                                                        itemQtyEntry.getKey());
                                        continue;
                                }
                                int ourSale = ourSaleItemQtyMap.get(itemQtyEntry.getKey());
                                int quantityToReduce = itemQtyEntry.getValue() - ourSale;
                                List<InventoryItem> itemIis = itemIdInventoryMap.get(itemQtyEntry.getKey());
                                if (itemIdInventoryMap != null) {
                                        for (InventoryItem ii : itemIis) {
                                                if (ii.getSerialNumber() == null && ii.getGoodQuantity() == ii.getInitialQuantity()
                                                                && quantityToReduce >= ii.getInitialQuantity()) {
                                                        LOGGER.info("Changed in inventoryItems {}, {}, {}, {}, {}, {}",
                                                                        purchase.getPurchaseReference(), ii.getId(), ii.getItemId(),
                                                                        ii.getInitialQuantity(), ii.getGoodQuantity(), quantityToReduce);
                                                        List<ScanRecord> scanRecords = scanRecordRepository.selectByInventoryItemId(ii.getId());
                                                        for (ScanRecord scanRecord : scanRecords) {
                                                                CurrentInventorySnapshot cis = currentInventorySnapshotRepository
                                                                                .selectByItemIdAndFofoId(itemQtyEntry.getKey(), purchase.getFofoId());
                                                                scanRecord.setQuantity(0);
                                                                ii.setGoodQuantity(0);
                                                                quantityToReduce = quantityToReduce - ii.getInitialQuantity();
                                                                cis.setAvailability(cis.getAvailability() - ii.getInitialQuantity());
                                                                purchase.setUnfullfilledNonSerializedQuantity(
                                                                                purchase.getUnfullfilledNonSerializedQuantity() + quantityToReduce);
                                                                LOGGER.info("Rectified {}, {}, {}, {}, {}, {}", purchase.getPurchaseReference(),
                                                                                ii.getId(), ii.getItemId(), ii.getInitialQuantity(), ii.getGoodQuantity(),
                                                                                quantityToReduce);
                                                        }
                                                }
                                        }
                                }
                        }
                }
                //throw new Exception();
        }

        public void migrateChallansToInvoices() throws Exception {
                Map<String, List<Order>> invoiceOrdersMap = orderRepository.selectAllChallans().stream()
                                .filter(x -> !x.getLineItem().getHsnCode().equals("NOGST"))
                                .collect(Collectors.groupingBy(Order::getInvoiceNumber, Collectors.toList()));

                List<List<? extends Serializable>> rows = new ArrayList<>();
                for (String invoice : invoiceOrdersMap.keySet()) {
                        Order oneOrder = invoiceOrdersMap.get(invoice).get(0);
                        int totalOrders = invoiceOrdersMap.get(invoice).size();
                        LineItem lineItem = oneOrder.getLineItem();
                        oneOrder.setBillingTimestamp(LocalDateTime.now());
                        oneOrder.setInvoiceNumber(getInvoiceNumber(oneOrder));
                        rows.add(Arrays.asList(oneOrder.getId(), invoice, oneOrder.getInvoiceNumber(), lineItem.getQuantity()));
                        LOGGER.info(invoice + "\t" + oneOrder.getInvoiceNumber() + oneOrder.getId() + "\t",
                                        "\t" + totalOrders + "\t" + lineItem.getQuantity());
                        Purchase p = null;
                        try {
                                p = purchaseRepository.selectByPurchaseReferenceAndFofoId(invoice, oneOrder.getRetailerId());
                        } catch (Exception e) {
                                LOGGER.info("Could not find purchase for invoice {}", invoice);
                        }
                        if (p != null) {
                                List<InventoryItem> inventoryItems = inventoryItemRepository.selectByPurchaseId(p.getId());
                                for (InventoryItem inventoryItem : inventoryItems) {
                                        LOGGER.info(inventoryItem.getItemId() + " " + inventoryItem.getGoodQuantity() + " "
                                                        + inventoryItem.getHsnCode() + " " + inventoryItem.getSerialNumber() + " "
                                                        + p.getPurchaseReference());
                                }
                        }

                }
                changePartnerInvoices();
                ByteArrayOutputStream baos = FileUtil
                                .getCSVByteStream(Arrays.asList("Order id", "Challan", "Invoice", "Quantity"), rows);

                Utils.sendMailWithAttachment(googleMailSender,
                                new String[] { "amit.gupta@shop2020.in", "sunny.yadav@smartdukaan.com" }, null,
                                "Challans Converted to Invoice", "PFA", "Challans-To-Invoice.csv",
                                new ByteArrayResource(baos.toByteArray()));
                throw new Exception();
        }

        private String getInvoiceNumber(Order oneOrder) {
                String prefix = oneOrder.getInvoiceNumber().split("-")[1].replaceAll("\\d*", "");
                System.out.println("Prefix is " + prefix);
                SellerWarehouse sellerWarehouse = sellerWarehouseRepository.selectByPrefix(prefix);
                int newSequence = sellerWarehouse.getInvoiceSequence() + 1;
                sellerWarehouse.setInvoiceSequence(newSequence);
                return prefix + newSequence;
        }

        private void changePartnerInvoices() throws Exception {
                List<FofoOrder> fofoOrders = fofoOrderRepository.selectByInvoiceNumberLike("%SEC%");
                for (FofoOrder fofoOrder : fofoOrders) {
                        FofoOrderItem fofoOrderItem = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId()).get(0);
                        if (fofoOrderItem.getBrand().equals("Vivo")) {
                                String challanString = fofoOrder.getInvoiceNumber();
                                String storeCode = invoiceNumberGenerationSequenceRepository.selectByFofoId(fofoOrder.getFofoId())
                                                .getPrefix();
                                String invoiceNumber = orderService.getInvoiceNumber(fofoOrder.getFofoId(), storeCode);
                                fofoOrder.setInvoiceNumber(invoiceNumber);
                                fofoOrder.setCreateTimestamp(LocalDateTime.now());
                                LOGGER.info(challanString + "\t" + invoiceNumber + "\t" + fofoOrderItem.getQuantity());
                        }

                }
        }

        public void createMonthlyTargets() throws Exception {
                Map<String, List<TargetSlab>> defaultSlabs = targetSlabRepository.getAllDefaultSlabs();
                for (String memberType : defaultSlabs.keySet()) {
                        PartnerTargetDetails ptd = new PartnerTargetDetails();
                        ptd.setBrandName(null);

                        LocalDate startDate = LocalDate.now().withDayOfMonth(1);
                        int totalDays = startDate.lengthOfMonth();
                        String monthName = startDate.getMonth().toString();
                        ptd.setStartDate(startDate.atStartOfDay());
                        ptd.setEndDate(startDate.plusDays(totalDays - 1).atTime(LocalTime.MAX));
                        ptd.setTargetName(String.format("%s Sales Target for %s Partners", monthName, memberType));
                        partnerTargetRepository.persist(ptd);
                        TargetSlabRepositoryImpl.TYPE_PARTNER_MAPPING.get(memberType).forEach(x -> {
                                x.setTargetId(ptd.getId());
                                partnerTargetRepository.persist(x);
                        });

                        List<TargetSlab> slabs = defaultSlabs.get(memberType);
                        slabs.stream().forEach(x -> {
                                x.setTargetId(ptd.getId());
                                targetSlabRepository.persist(x);
                        });
                }
        }

}