Subversion Repositories SmartDukaan

Rev

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

package com.smartdukaan.cron.scheduled;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.apache.commons.codec.CharEncoding;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.spice.profitmandi.common.enumuration.RechargeStatus;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.CustomRetailer;
import com.spice.profitmandi.common.model.RechargeCredential;
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.dtr.DailyRecharge;
import com.spice.profitmandi.dao.entity.dtr.RechargeProvider;
import com.spice.profitmandi.dao.entity.dtr.RechargeProviderCreditWalletHistory;
import com.spice.profitmandi.dao.entity.dtr.RechargeTransaction;
import com.spice.profitmandi.dao.entity.fofo.FofoOrder;
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
import com.spice.profitmandi.dao.entity.fofo.Purchase;
import com.spice.profitmandi.dao.entity.transaction.Order;
import com.spice.profitmandi.dao.repository.dtr.DailyRechargeRepository;
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
import com.spice.profitmandi.dao.repository.dtr.RechargeProviderCreditWalletHistoryRepository;
import com.spice.profitmandi.dao.repository.dtr.RechargeProviderRepository;
import com.spice.profitmandi.dao.repository.dtr.RechargeTransactionRepository;
import com.spice.profitmandi.dao.repository.fofo.FofoOrderRepository;
import com.spice.profitmandi.dao.repository.fofo.PurchaseRepository;
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
import com.spice.profitmandi.service.inventory.InventoryService;
import com.spice.profitmandi.service.recharge.provider.OxigenRechargeProviderService;
import com.spice.profitmandi.service.recharge.provider.ThinkWalnutDigitalRechargeProviderService;
import com.spice.profitmandi.service.scheme.SchemeService;
import com.spice.profitmandi.service.slab.TargetSlabService;
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;
import com.spice.profitmandi.dao.entity.fofo.SalesHead;;

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

        @Value("${oxigen.recharge.transaction.url}")
        private String oxigenRechargeTransactionUrl;

        @Value("${oxigen.recharge.enquiry.url}")
        private String oxigenRechargeEnquiryUrl;

        @Value("${oxigen.recharge.auth.key}")
        private String oxigenRechargeAuthKey;

        @Value("${oxigen.recharge.validation.url}")
        private String oxigenRechargeValidationUrl;

        @Value("${oxigen.recharge.validation.auth.key}")
        private String oxigenRechargeValidationAuthKey;

        @Value("${think.walnut.digital.recharge.transaction.mobile.url}")
        private String thinkWalnutDigitalRechargeTransactionMobileUrl;

        @Value("${think.walnut.digital.recharge.transaction.dth.url}")
        private String thinkWalnutDigitalRechargeTransactionDthUrl;

        @Value("${think.walnut.digital.recharge.enquiry.url}")
        private String thinkWalnutDigitalRechargeEnquiryUrl;

        @Value("${think.walnut.digital.recharge.balance.url}")
        private String thinkWalnutDigitalRechargeBalanceUrl;

        @Value("${think.walnut.digital.recharge.username}")
        private String thinkWalnutDigitalRechargeUserName;

        @Value("${think.walnut.digital.recharge.password}")
        private String thinkWalnutDigitalRechargePassword;

        @Value("${think.walnut.digital.recharge.auth.key}")
        private String thinkWalnutDigitalRechargeAuthKey;

        @Autowired
        private PurchaseRepository purchaseRepository;
        

        @Autowired
        private SchemeService schemeService;

        @Autowired
        private RechargeTransactionRepository rechargeTransactionRepository;

        @Autowired
        private RechargeProviderCreditWalletHistoryRepository rechargeProviderCreditWalletHistoryRepository;

        @Autowired
        private FofoOrderRepository fofoOrderRepository;

        @Autowired
        private WalletService walletService;

        @Autowired
        private ThinkWalnutDigitalRechargeProviderService thinkWalnutDigitalRechargeProviderService;

        @Autowired
        private OxigenRechargeProviderService oxigenRechargeProviderService;

        @Autowired
        private RechargeProviderRepository rechargeProviderRepository;

        @Autowired
        private DailyRechargeRepository dailyRechargeRepository;

        @Autowired
        private FofoStoreRepository fofoStoreRepository;
        
        @Autowired
        private TargetSlabService targetService;

        @Value("${prod}")
        private boolean prod;

        @Autowired
        private RetailerService retailerService;

        @Autowired
        private TransactionService transactionService;

        @Autowired
        private OrderRepository orderRepository;

        @Autowired
        private JavaMailSender mailSender;
        


        @Autowired
        @Qualifier(value = "googleMailSender")
        private JavaMailSender googleMailSender;

        @Autowired
        private InventoryService inventoryService;
        
        

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

        public void generateDailyRecharge() {
                List<RechargeProviderCreditWalletHistory> allCreditHistory = rechargeProviderCreditWalletHistoryRepository
                                .selectAll(0, 2000);
                List<RechargeProvider> rechargeProviders = rechargeProviderRepository.selectAll();
                rechargeProviders.stream().forEach(x -> x.setAmount(0));

                rechargeProviders.stream().forEach(x -> {
                        Map<LocalDate, List<RechargeProviderCreditWalletHistory>> dateWiseProviderCreditsMap = allCreditHistory
                                        .stream().filter(z -> z.getProviderId() == x.getId())
                                        .collect(Collectors.groupingBy(x1 -> x1.getReceiveTimestamp().toLocalDate()));

                        LOGGER.info("dateWiseProviderCreditsMap -- {}", dateWiseProviderCreditsMap);
                        LocalDate endDate = LocalDate.now().plusDays(1);
                        float previousDayClosing = 0;
                        LocalDate date = LocalDate.of(2018, 4, 6);
                        while (date.isBefore(endDate)) {
                                List<RechargeTransaction> dateWiseRechargeTransactions = rechargeTransactionRepository
                                                .selectAllBetweenTimestamp(Arrays.asList(RechargeStatus.values()), date.atStartOfDay(),
                                                                date.plusDays(1).atStartOfDay());

                                List<RechargeTransaction> successfulTransactions = dateWiseRechargeTransactions.stream()
                                                .filter(y -> y.getStatus().equals(RechargeStatus.SUCCESS)).collect(Collectors.toList());

                                float dailyAmount = 0;
                                float totalCommission = 0;
                                for (RechargeTransaction rechargeTransaction : successfulTransactions) {
                                        if (rechargeTransaction.getProviderId() == x.getId()) {
                                                dailyAmount += rechargeTransaction.getAmount();
                                                totalCommission += rechargeTransaction.getCommission();
                                        }
                                }

                                List<RechargeProviderCreditWalletHistory> rechargeHistoryList = dateWiseProviderCreditsMap.get(date);
                                float dailyWalletRecharge = 0;
                                if (rechargeHistoryList != null) {
                                        for (RechargeProviderCreditWalletHistory rechargeProviderCreditWalletHistory : rechargeHistoryList) {
                                                if (rechargeProviderCreditWalletHistory.getProviderId() == x.getId()) {
                                                        dailyWalletRecharge += rechargeProviderCreditWalletHistory.getAmount();
                                                }
                                        }
                                }
                                if (dailyAmount > 0 || dailyWalletRecharge > 0) {
                                        DailyRecharge dailyRecharge = null;
                                        try {
                                                dailyRecharge = dailyRechargeRepository.selectByProviderIdAndCreateDate(x.getId(), date);
                                        } catch (Exception e) {
                                                LOGGER.info("Could not find Recharge entry");
                                        }
                                        if (dailyRecharge == null) {
                                                dailyRecharge = new DailyRecharge();
                                                dailyRecharge.setCreateDate(date);
                                        }
                                        dailyRecharge.setOpeningBalance(previousDayClosing);
                                        dailyRecharge.setProviderId(x.getId());
                                        dailyRecharge.setWalletRechargeAmount(dailyWalletRecharge);
                                        dailyRecharge.setTotalAmount(dailyAmount);
                                        dailyRecharge.setTotalCommission(totalCommission);
                                        float closingBalance = dailyRecharge.getOpeningBalance() + dailyWalletRecharge - dailyAmount;
                                        dailyRecharge.setClosingBalance(closingBalance);
                                        dailyRechargeRepository.persist(dailyRecharge);
                                        x.setAmount(x.getAmount() + dailyRecharge.getClosingBalance() - dailyRecharge.getOpeningBalance());
                                        previousDayClosing = dailyRecharge.getClosingBalance();
                                }
                                date = date.plusDays(1);
                        }
                        rechargeProviderRepository.persist(x);
                });
                LOGGER.info("finished generating daily recharge");
        }

        public void reconcileRecharge() throws Exception {
                LocalDateTime fromDate = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).minusDays(30);
                LocalDateTime toDate = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS);
                List<RechargeStatus> nonSuccessRechargeStatuses = new ArrayList<>(Arrays.asList(RechargeStatus.values()));
                LOGGER.info("nonSuccessRechargeStatuses {} ", nonSuccessRechargeStatuses);
                nonSuccessRechargeStatuses.remove(RechargeStatus.SUCCESS);
                nonSuccessRechargeStatuses.remove(RechargeStatus.FAILED);
                RechargeCredential thinkWalnutDigitalRechargeEnquiryCredential = new RechargeCredential();
                thinkWalnutDigitalRechargeEnquiryCredential.setRechargeUrl(thinkWalnutDigitalRechargeEnquiryUrl);
                thinkWalnutDigitalRechargeEnquiryCredential.setRechargeUserName(thinkWalnutDigitalRechargeUserName);
                thinkWalnutDigitalRechargeEnquiryCredential.setRechargePassword(thinkWalnutDigitalRechargePassword);
                thinkWalnutDigitalRechargeEnquiryCredential.setRechargeAuthKey(thinkWalnutDigitalRechargeAuthKey);
                Map<String, RechargeStatus> requestRechargeStatusChanged = new HashMap<>();
                List<RechargeTransaction> rechargeTransactions = rechargeTransactionRepository
                                .selectAllBetweenTimestamp(nonSuccessRechargeStatuses, fromDate, toDate);
                for (RechargeTransaction rechargeTransaction : rechargeTransactions) {
                        try {
                                int providerId = rechargeTransaction.getProviderId();
                                if (providerId == 1) {
                                        oxigenRechargeProviderService.doCheckStatusRequest(oxigenRechargeEnquiryUrl, oxigenRechargeAuthKey,
                                                        rechargeTransaction);
                                } else if (providerId == 2) {
                                        thinkWalnutDigitalRechargeProviderService
                                                        .doCheckStatusRequest(thinkWalnutDigitalRechargeEnquiryCredential, rechargeTransaction);
                                }
                                if (rechargeTransaction.getStatus().equals(RechargeStatus.SUCCESS)
                                                || rechargeTransaction.getStatus().equals(RechargeStatus.FAILED)) {
                                        requestRechargeStatusChanged.put(rechargeTransaction.getRequestId(),
                                                        rechargeTransaction.getStatus());
                                }
                        } catch (Exception e) {
                                LOGGER.info("Could not check status for Request {}", rechargeTransaction.getRequestId());
                        }
                }
                LOGGER.info("Reconcile recharge ran successfully");
        }

        public void processScheme() throws Exception {
                LocalDateTime fromDate = LocalDateTime.now().minusDays(15);
                LOGGER.info("Started execution at {}", LocalDateTime.now());
                List<Purchase> purchases = purchaseRepository.selectFromPurchaseCompleteDate(fromDate);
                for (Purchase purchase : purchases) {
                        try {
                                schemeService.processSchemeIn(purchase.getId(), purchase.getFofoId());
                        } catch (Exception e) {
                                LOGGER.error("Error while processing purchase {} for scheme In ", purchase.getId());
                                e.printStackTrace();

                        }
                }
                List<FofoOrder> fofoOrders = fofoOrderRepository.selectFromSaleDate(fromDate);
                for (FofoOrder fofoOrder : fofoOrders) {
                        try {
                                schemeService.processSchemeOut(fofoOrder.getId(), fofoOrder.getFofoId());
                        } catch (Exception e) {
                                LOGGER.error("Error while processing sale order {} for scheme Out", fofoOrder.getId());
                        }
                }
                LOGGER.info("Schemes process successfully.");
        }

        public void processRechargeCashback() throws Throwable {
                LocalDateTime cashbackTime = LocalDateTime.now();
                int referenceId = (int) Timestamp.valueOf(cashbackTime).getTime() / 1000;
                List<RechargeTransaction> pendingTransactions = rechargeTransactionRepository
                                .getPendingCashBackRehargeTransactions();
                Map<Object, Double> totalRetailerCashbacks = pendingTransactions.stream().collect(
                                Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingDouble(x -> x.getCommission())));
                for (Map.Entry<Object, Double> totalRetailerCashback : totalRetailerCashbacks.entrySet()) {
                        int retailerId = (Integer) totalRetailerCashback.getKey();
                        float amount = totalRetailerCashback.getValue().floatValue();
                        if (Math.round(amount) > 0) {
                                walletService.addAmountToWallet(retailerId, referenceId, WalletReferenceType.CASHBACK,
                                                "Recharge Cashback", Math.round(amount));
                        }
                }
                for (RechargeTransaction rt : pendingTransactions) {
                        rt.setCashbackTimestamp(cashbackTime);
                        rt.setCashbackReference(referenceId);
                        rechargeTransactionRepository.persist(rt);
                }
                LOGGER.info("Cashbacks for Recharge processed Successfully");
        }

        public void sendPartnerInvestmentDetails() throws Exception {
                String fileName = "InvestmentSummary-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv";

                List<FofoStore> fofoStores = fofoStoreRepository.selectAll();
                Map<Integer, CustomRetailer> customRetailerMap = retailerService
                                .getFofoRetailers(fofoStores.stream().map(x -> x.getId()).collect(Collectors.toList()));

                List<String> headers = Arrays.asList("Code", "StoreName", "Email", "Mobile", "WalletAmount", "InStockAmount",
                                "UnbilledStockAmount", "GrnPendingStockAmount", "MinimumInvestment", "TotalInvested", "ShortAmount");
                List<List<Object>> rows = new ArrayList<>();
                for (FofoStore fofoStore : fofoStores) {
                        CustomRetailer retailer = customRetailerMap.get(fofoStore.getId());
                        if (retailer == null) {
                                LOGGER.info("Could not find retailer with retailer Id {}", fofoStore.getId());
                                continue;
                        }
                        float walletAmount = walletService.getUserWallet(fofoStore.getId()).getAmount();
                        float inStockAmount = inventoryService.getTotalAmountInStock(fofoStore.getId());

                        float unbilledStockAmount = 0;
                        List<Order> unbilledOrders = transactionService.getInTransitOrders(fofoStore.getId());
                        for (Order unBilledOrder : unbilledOrders) {
                                unbilledStockAmount += unBilledOrder.getTotalAmount();
                        }

                        float grnPendingStockAmount = 0;
                        List<Order> grnPendingOrders = orderRepository.selectPendingGrnOrders(fofoStore.getId());
                        for (Order grnPendingOrder : grnPendingOrders) {
                                LOGGER.info("Grn pending for Order {} and partner {}", grnPendingOrder.getId(),
                                                grnPendingOrder.getRetailerEmailId());
                                grnPendingStockAmount += grnPendingOrder.getTotalAmount();
                        }
                        float totalInvestedAmount = walletAmount + inStockAmount + unbilledStockAmount + grnPendingStockAmount;
                        List<Object> row = Arrays.asList(fofoStore.getCode(), retailer.getBusinessName(), retailer.getEmail(),
                                        retailer.getMobileNumber(), walletAmount, inStockAmount, unbilledStockAmount, grnPendingStockAmount,
                                        fofoStore.getMinimumInvestment(), totalInvestedAmount,
                                        fofoStore.getMinimumInvestment() - totalInvestedAmount);
                        rows.add(row);

                }
                ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, rows);
                Utils.sendMailWithAttachment(googleMailSender, "adeel.yazdani@smartdukaan.com",
                                new String[] { "amandeep.singh@smartdukaan.com", "tarun.verma@smartdukaan.com",
                                                "kamini.sharma@smartdukaan.com", "dhruv.kathpal@smartdukaan.com" },
                                "Partner Investment Summary", "PFA", fileName, new ByteArrayResource(baos.toByteArray()));
        }
        
        public  void sendMailWithAttachmentsForSalesHead(String[] email,String subject,String body,String saleHead) throws MessagingException, ProfitMandiBusinessException, IOException
        {
                MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message,true,CharEncoding.UTF_8);
        InputStream is=targetService.getDailySaleReportVsTargetForSaleHead(saleHead);
        helper.setSubject(subject);
        helper.setText(body);
        String ccEmails[]= {"Tarun.verma@smartdukaan.com","Kamini.sharma@smartdukaan.com","chaitnaya.vats@smartdukaan.com","dhruv.kathpal@smartdukaan.com"};
        helper.setCc(ccEmails);
        helper.addAttachment("saleReport"+LocalDate.now()+".xlsx",new ByteArrayResource(IOUtils.toByteArray(is)));
        helper.setTo(email);
        InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "ProfitMandi Admin");
        helper.setFrom(senderAddress);
        mailSender.send(message);
        }
        
        public  void sendMailWithAttachments(String[] email,String subject,String body) throws MessagingException, ProfitMandiBusinessException, IOException
        {
                MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message,true,CharEncoding.UTF_8);
        InputStream is=targetService.getDailySaleReportVsTarget();
        helper.setSubject(subject);
        helper.setText(body);
        String ccEmails[]= {"Tarun.verma@smartdukaan.com","Kamini.sharma@smartdukaan.com","chaitnaya.vats@smartdukaan.com","dhruv.kathpal@smartdukaan.com","care@smartdukaan.com"};
        helper.setCc(ccEmails);
        helper.addAttachment("saleReport"+LocalDate.now()+".xlsx",new ByteArrayResource(IOUtils.toByteArray(is)));
        helper.setTo(email);
        InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "ProfitMandi Admin");
        helper.setFrom(senderAddress);
        mailSender.send(message);
        }

}