Subversion Repositories SmartDukaan

Rev

Rev 25573 | Rev 25581 | 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.Serializable;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
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.Optional;
import java.util.Set;
import java.util.stream.Collectors;

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

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONObject;
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.core.io.InputStreamSource;
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.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.spice.profitmandi.common.enumuration.RechargeStatus;
import com.spice.profitmandi.common.enumuration.ReporticoProject;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.CustomRetailer;
import com.spice.profitmandi.common.model.GstRate;
import com.spice.profitmandi.common.model.RechargeCredential;
import com.spice.profitmandi.common.services.ReporticoService;
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.common.util.Utils.Attachment;
import com.spice.profitmandi.dao.Interface.Campaign;
import com.spice.profitmandi.dao.convertor.LocalDateTimeJsonConverter;
import com.spice.profitmandi.dao.entity.catalog.Scheme;
import com.spice.profitmandi.dao.entity.dtr.DailyRecharge;
import com.spice.profitmandi.dao.entity.dtr.NotificationCampaign;
import com.spice.profitmandi.dao.entity.dtr.NotificationCampaigns;
import com.spice.profitmandi.dao.entity.dtr.PushNotifications;
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.CustomerAddress;
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.InventoryItem;
import com.spice.profitmandi.dao.entity.fofo.PartnerDailyInvestment;
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.SchemeInOut;
import com.spice.profitmandi.dao.entity.transaction.PriceDrop;
import com.spice.profitmandi.dao.entity.transaction.UserWallet;
import com.spice.profitmandi.dao.entity.transaction.UserWalletHistory;
import com.spice.profitmandi.dao.entity.user.Address;
import com.spice.profitmandi.dao.entity.user.Device;
import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;
import com.spice.profitmandi.dao.enumuration.fofo.ScanType;
import com.spice.profitmandi.dao.model.SimpleCampaign;
import com.spice.profitmandi.dao.model.SimpleCampaignParams;
import com.spice.profitmandi.dao.repository.catalog.DeviceRepository;
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
import com.spice.profitmandi.dao.repository.catalog.SchemeRepository;
import com.spice.profitmandi.dao.repository.dtr.DailyRechargeRepository;
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
import com.spice.profitmandi.dao.repository.dtr.Mongo;
import com.spice.profitmandi.dao.repository.dtr.NotificationCampaignRepository;
import com.spice.profitmandi.dao.repository.dtr.PushNotificationRepository;
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.dtr.RetailerRegisteredAddressRepository;
import com.spice.profitmandi.dao.repository.dtr.UserAccountRepository;
import com.spice.profitmandi.dao.repository.fofo.CustomerAddressRepository;
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.InventoryItemRepository;
import com.spice.profitmandi.dao.repository.fofo.PartnerDailyInvestmentRepository;
import com.spice.profitmandi.dao.repository.fofo.PartnerTargetRepository;
import com.spice.profitmandi.dao.repository.fofo.PartnerTypeChangeService;
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.transaction.OrderRepository;
import com.spice.profitmandi.dao.repository.transaction.PriceDropRepository;
import com.spice.profitmandi.dao.repository.transaction.UserWalletHistoryRepository;
import com.spice.profitmandi.dao.repository.transaction.UserWalletRepository;
import com.spice.profitmandi.dao.repository.user.AddressRepository;
import com.spice.profitmandi.service.PartnerInvestmentService;
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.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;;

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

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

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

        @Autowired
        private PartnerTypeChangeService partnerTypeChangeService;

        @Autowired
        private PriceDropService priceDropService;

        @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 ReporticoService reporticoService;

        @Autowired
        private PartnerInvestmentService partnerInvestmentService;

        @Autowired
        private FofoOrderItemRepository fofoOrderItemRepository;

        @Autowired
        private PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;

        @Autowired
        private SchemeInOutRepository schemeInOutRepository;

        @Autowired
        private RechargeTransactionRepository rechargeTransactionRepository;

        @Autowired
        private CustomerAddressRepository customerAddressRepository;

        @Autowired
        private RechargeProviderCreditWalletHistoryRepository rechargeProviderCreditWalletHistoryRepository;

        @Autowired
        private FofoLineItemRepository fofoLineItemRepository;

        @Autowired
        private FofoOrderRepository fofoOrderRepository;

        @Autowired
        private UserWalletHistoryRepository userWalletHistoryRepository;

        @Autowired
        private UserWalletRepository userWalletRepository;

        @Autowired
        private InventoryItemRepository inventoryItemRepository;

        @Autowired
        private WalletService walletService;

        @Autowired
        private ThinkWalnutDigitalRechargeProviderService thinkWalnutDigitalRechargeProviderService;

        @Autowired
        private OxigenRechargeProviderService oxigenRechargeProviderService;

        @Autowired
        private RechargeProviderRepository rechargeProviderRepository;

        @Autowired
        private ScanRecordRepository scanRecordRepository;

        @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 ItemRepository itemRepository;

        @Autowired
        private OrderRepository orderRepository;

        @Autowired
        private OrderService orderService;

        @Autowired
        private SchemeRepository schemeRepository;

        @Autowired
        private JavaMailSender mailSender;

        @Autowired
        private PriceDropRepository priceDropRepository;

        @Autowired
        private PartnerTargetRepository partnerTargetRepository;

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

        @Autowired
        private InventoryService inventoryService;

        @Autowired
        private AddressRepository addressRepository;

        @Autowired
        private RetailerRegisteredAddressRepository retailerRegisteredAddressRepository;

        @Autowired
        private Mongo mongoClient;

        @Autowired
        private DeviceRepository deviceRepository;

        @Autowired
        private PushNotificationRepository pushNotificationRepository;

        @Autowired
        private NotificationCampaignRepository notificationCampaignRepository;

        @Autowired
        private UserAccountRepository userAccountRepository;

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

        private String FCM_URL = "https://fcm.googleapis.com/fcm/send";
        private String FCM_API_KEY = "AAAASAjNcn4:APA91bG6fWRIgYJI0L9gCjP5ynaXz2hJHYKtD9dfH7Depdv31Nd9APJwhx-OPkAJ1WSz4BGNYG8lHThLFSjDGFxIwUZv241YcAJEGDLgt86mxq9FXJe-yBRu-S0_ZwHqmX-QaVKl5F_A";

        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");
        }

        // TemporaryMethod
        public void migrateInvoice() {
                List<FofoOrder> fofoOrders = fofoOrderRepository.selectFromSaleDate(LocalDateTime.now().minusDays(3));
                Map<Integer, List<FofoOrder>> partnerOrdersMap = new HashMap<>();
                partnerOrdersMap = fofoOrders.stream()
                                .collect(Collectors.groupingBy(FofoOrder::getFofoId, Collectors.toList()));
                for (List<FofoOrder> orderList : partnerOrdersMap.values()) {
                        int sequence = 0;
                        String prefix = "";
                        List<FofoOrder> sortedList = orderList.stream().sorted((x1, x2) -> x1.getId() - x2.getId())
                                        .collect(Collectors.toList());
                        for (FofoOrder order : sortedList) {

                                LOGGER.info("Order Id is {}, partner Id is {}", order.getId(), order.getFofoId());
                                if (!order.getInvoiceNumber().contains("SEC")) {
                                        sequence = Integer.parseInt(order.getInvoiceNumber().split("/")[1]);
                                        prefix = order.getInvoiceNumber().split("/")[0];
                                } else {
                                        sequence += 1;
                                        String invoiceNumber = prefix + "/" + sequence;
                                        order.setInvoiceNumber(invoiceNumber);
                                        fofoOrderRepository.persist(order);
                                }
                        }

                }
        }

        // Temporary Method
        public void evaluateExcessSchemeOut() throws Exception {
                Map<Integer, String> userNameMap = retailerService.getAllFofoRetailerIdNameMap();
                Map<Integer, Float> userAmountMap = new HashMap<>();

                List<List<? extends Serializable>> rows = new ArrayList<>();
                List<String> headers = Arrays.asList("Scheme", "Item", "Partner", "Amount", "Credited On", "Invoice Number",
                                "Sale On", "Scheme Start", "Scheme End", "Active On", "Expired On");
                schemeRepository.selectAll().stream().forEach(x -> {
                        if (x.getType().equals(SchemeType.OUT)) {
                                List<SchemeInOut> sioList = schemeInOutRepository
                                                .selectBySchemeIds(new HashSet<>(Arrays.asList(x.getId())));
                                if (x.getActiveTimestamp() != null) {
                                        LocalDateTime endDateTime = x.getEndDateTime();
                                        if (x.getExpireTimestamp() != null && x.getExpireTimestamp().isBefore(x.getEndDateTime())) {
                                                endDateTime = x.getExpireTimestamp();
                                        }
                                        for (SchemeInOut sio : sioList) {
                                                InventoryItem inventoryItem = null;
                                                inventoryItem = inventoryItemRepository.selectById(sio.getInventoryItemId());
                                                FofoOrder fofoOrder = fofoOrderRepository.selectByFofoIdAndSerialNumber(
                                                                inventoryItem.getFofoId(), inventoryItem.getSerialNumber(), null, null, 0, 1).get(0);
                                                Optional<ScanRecord> record = scanRecordRepository
                                                                .selectByInventoryItemId(sio.getInventoryItemId()).stream()
                                                                .filter(y -> y.getType().equals(ScanType.SALE)).findFirst();
                                                if (record.isPresent()) {
                                                        int fofoId = record.get().getFofoId();
                                                        if (record.get().getCreateTimestamp().isAfter(endDateTime)
                                                                        || record.get().getCreateTimestamp().isBefore(x.getStartDateTime())) {
                                                                if (!userAmountMap.containsKey(fofoId)) {
                                                                        userAmountMap.put(fofoId, 0f);
                                                                }
                                                                userAmountMap.put(fofoId, sio.getAmount() + userAmountMap.get(fofoId));
                                                                try {
                                                                        rows.add(Arrays.asList(x.getDescription(),
                                                                                        itemRepository.selectById(inventoryItem.getItemId()).getItemDescription(),
                                                                                        userNameMap.get(fofoId), sio.getAmount(),
                                                                                        FormattingUtils.formatDate(sio.getCreateTimestamp()),
                                                                                        fofoOrder.getInvoiceNumber(),
                                                                                        FormattingUtils.formatDate(record.get().getCreateTimestamp()),
                                                                                        FormattingUtils.formatDate(x.getStartDateTime()),
                                                                                        FormattingUtils.formatDate(x.getEndDateTime()),
                                                                                        FormattingUtils.formatDate(x.getActiveTimestamp()),
                                                                                        FormattingUtils.formatDate(x.getExpireTimestamp())));
                                                                } catch (Exception e) {
                                                                        e.printStackTrace();
                                                                }
                                                        }
                                                }
                                        }
                                }
                        }
                });
                userAmountMap.entrySet().stream()
                                .forEach(x -> LOGGER.info("{} to be deducted from {}({}) for wrongly disbursed due to technical error.",
                                                x.getValue(), userNameMap.get(x.getKey())));

                ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, rows);
                Utils.sendMailWithAttachment(googleMailSender,
                                new String[] { "amit.gupta@shop2020.in", "adeel.yazdani@smartdukaan.com" }, null,
                                "Partner Excess Amount", "PFA", "ListofSchemes.csv", new ByteArrayResource(baos.toByteArray()));

        }

        public void processScheme(int offset) throws Exception {
                LocalDateTime startDate = LocalDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT).minusDays(offset);
                LocalDateTime endDate = startDate.plusDays(30);
                processScheme(startDate, endDate);
        }

        public void processScheme(int offset, int durationDays) throws Exception {
                LocalDateTime startDate = LocalDateTime.of(LocalDate.now(), LocalTime.MIDNIGHT).minusDays(offset);
                LocalDateTime endDate = startDate.plusDays(durationDays);
                processScheme(startDate, endDate);
        }

        public void processScheme() throws Exception {
                LocalDateTime fromDate = LocalDateTime.now().minusDays(30);
                processScheme(fromDate, LocalDateTime.now());
        }

        public void processScheme(LocalDateTime startDate, LocalDateTime endDate) throws Exception {
                LOGGER.info("Started execution at {}", LocalDateTime.now());
                System.out.println(
                                "InventoryId\tSerialNumber\tItem Id\tScheme Id\tScheme Name\tScheme Type\tAmount Type\tDP\tTaxable\tScheme Amount\tAmount Paid");
                try {
                        List<Purchase> purchases = purchaseRepository.selectAllBetweenPurchaseDate(startDate, endDate);
                        for (Purchase purchase : purchases) {
                                schemeService.processSchemeIn(purchase.getId(), purchase.getFofoId());
                        }

                        List<FofoOrder> fofoOrders = fofoOrderRepository.selectBetweenSaleDate(startDate, endDate);
                        for (FofoOrder fofoOrder : fofoOrders) {
                                schemeService.processSchemeOut(fofoOrder.getId(), fofoOrder.getFofoId());
                        }
                } catch (Exception e) {
                        e.printStackTrace();
                        throw e;
                }
                List<UserWalletHistory> uwhs = userWalletHistoryRepository.selectAllByDateType(startDate, endDate,
                                Arrays.asList(WalletReferenceType.SCHEME_IN, WalletReferenceType.SCHEME_OUT));
                System.out.println("Amount\tReference\tReferenceType\tTimestamp\tDescription");
                for (UserWalletHistory uwh : uwhs) {
                        System.out.println(String.format("%d\t%d\t%s\t%s\t%s", uwh.getAmount(), uwh.getReference(),
                                        uwh.getReferenceType(), uwh.getTimestamp().toString(), uwh.getDescription()));
                }
                LOGGER.info("Schemes process successfully.");
                //throw new Exception();
        }

        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(List<String> sendTo) throws Exception {
                if (sendTo == null) {
                        sendTo = Arrays.asList("tarun.verma@smartdukaan.com", "kamini.sharma@smartdukaan.com",
                                        "amit.gupta@shop2020.in", "amod.sen@smartdukaan.com");
                }
                LocalDate yesterDay = LocalDate.now().minusDays(1);
                List<FofoStore> fofoStores = fofoStoreRepository.selectActiveStores();
                Map<Integer, CustomRetailer> customRetailerMap = retailerService
                                .getFofoRetailers(fofoStores.stream().map(x -> x.getId()).collect(Collectors.toList()));

                List<String> headers = Arrays.asList("Code", "Firm Name", "Store Name", "State Manager", "Teritory Manager",
                                "Team Leader", "Wallet Amount", "In Stock Amount", "Return In Transit Stock", "Unbilled Amount",
                                "Grn Pending Amount", "Min Investment", "Investment Amount", "Investment Short", "Unbilled Qty");
                List<List<? extends Serializable>> rows = new ArrayList<>();
                Map<String, List<? extends Serializable>> partnerRow = new HashMap<>();
                for (FofoStore fofoStore : fofoStores) {
                        if (!fofoStore.isActive())
                                continue;
                        CustomRetailer retailer = customRetailerMap.get(fofoStore.getId());
                        if (retailer == null || storeManagerMap.get(retailer.getEmail()) == null) {
                                LOGGER.info("Could not find retailer with retailer Id {}", fofoStore.getId());
                                continue;
                        }
                        PartnerDailyInvestment partnerDailyInvestment = partnerInvestmentService.getInvestment(fofoStore.getId(),
                                        1);
                        partnerDailyInvestment.setDate(yesterDay);
                        partnerDailyInvestmentRepository.persist(partnerDailyInvestment);

                        List<? extends Serializable> row = Arrays.asList(fofoStore.getCode(), retailer.getBusinessName(),
                                        "SmartDukaan-" + fofoStore.getCode().replaceAll("[a-zA-Z]+", ""),
                                        storeManagerMap.get(retailer.getEmail()).get(2), storeManagerMap.get(retailer.getEmail()).get(1),
                                        storeManagerMap.get(retailer.getEmail()).get(0), partnerDailyInvestment.getWalletAmount(),
                                        partnerDailyInvestment.getInStockAmount(), 0, partnerDailyInvestment.getUnbilledAmount(),
                                        partnerDailyInvestment.getGrnPendingAmount(), partnerDailyInvestment.getMinInvestment(),
                                        partnerDailyInvestment.getTotalInvestment(), partnerDailyInvestment.getShortInvestment(),
                                        partnerDailyInvestment.getUnbilledQty());
                        partnerRow.put(retailer.getEmail(), row);
                        rows.add(row);

                }
                Map<String, Set<String>> storeGuyMap = new HashMap<>();
                for (Map.Entry<String, List<String>> entry : storeManagerMap.entrySet()) {
                        String storeEmail = entry.getKey();
                        List<String> storeGuys = entry.getValue();
                        for (String storeGuy : storeGuys) {
                                if (!storeGuyMap.containsKey(storeGuy)) {
                                        storeGuyMap.put(storeGuy, new HashSet<>());
                                }
                                storeGuyMap.get(storeGuy).add(storeEmail);
                        }
                }
                storeGuyMap.remove("");

                String fileName = "InvestmentSummary-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv";
                for (Map.Entry<String, Set<String>> storeGuyEntry : storeGuyMap.entrySet()) {
                        List<List<? extends Serializable>> filteredRows = storeGuyEntry.getValue().stream()
                                        .map(x -> partnerRow.get(x)).filter(x -> x != null).collect(Collectors.toList());
                        ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, filteredRows);
                        String[] sendToArray = new String[] { nameEmail.get(storeGuyEntry.getKey()) };
                        Utils.sendMailWithAttachment(googleMailSender, sendToArray, null, "Partner Investment Summary", "PFA",
                                        fileName, new ByteArrayResource(baos.toByteArray()));
                }

                ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, rows);
                String[] sendToArray = sendTo.toArray(new String[sendTo.size()]);
                Utils.sendMailWithAttachment(googleMailSender, sendToArray, null, "Partner Investment Summary", "PFA", fileName,
                                new ByteArrayResource(baos.toByteArray()));

        }

        public void sendPartnerInvestmentDetails() throws Exception {
                this.sendPartnerInvestmentDetails(null);

        }

        public void sendTargetVsSalesReport(List<String> sendTo) throws Exception {

                if (sendTo == null) {
                        sendTo = Arrays.asList("tarun.verma@smartdukaan.com", "kamini.sharma@smartdukaan.com",
                                        "amit.gupta@shop2020.in", "amod.sen@smartdukaan.com");
                }
                List<PartnerTargetDetails> partnerTargetDetails = partnerTargetRepository
                                .selectAllGeEqAndLeEqStartDateAndEndDate(LocalDateTime.now().minusDays(1));
                Map<String, List<? extends Serializable>> partnerSalesTargetRowsMap = new HashMap<>();
                for (PartnerTargetDetails partnerTargetDetail : partnerTargetDetails) {
                        partnerSalesTargetRowsMap.putAll(targetService.getDailySaleReportVsTarget(partnerTargetDetail));
                }
                Map<Integer, FofoStore> fofoStoresMap = fofoStoreRepository.selectActiveStores().stream()
                                .collect(Collectors.toMap(x -> x.getId(), x -> x));

                Map<Integer, CustomRetailer> customRetailerMap = retailerService
                                .getFofoRetailers(new ArrayList<>(fofoStoresMap.keySet()));

                Map<String, CustomRetailer> customRetailerEmailMap = customRetailerMap.values().stream()
                                .collect(Collectors.toMap(x -> x.getEmail(), x -> x));

                List<String> headers = Arrays.asList("Code", "Firm Name", "Store Name", "State Manager", "Teritory Manager",
                                "Team Leader", "Target Name", "Target Value", "Target Achieved", "Achived Percentage",
                                "Remaining Target", "Today's Target", "Today's achievement");

                List<List<? extends Serializable>> rows = new ArrayList<>();
                Map<String, List<Serializable>> partnerRowMap = new HashMap<>();
                for (Map.Entry<String, List<? extends Serializable>> partnerSalesTargetRowEntry : partnerSalesTargetRowsMap
                                .entrySet()) {
                        CustomRetailer retailer = customRetailerEmailMap.get(partnerSalesTargetRowEntry.getKey());
                        FofoStore fofoStore = fofoStoresMap.get(retailer.getPartnerId());
                        Serializable code = fofoStore.getCode();
                        Serializable storeName = "SmartDukaan-" + fofoStore.getCode().replaceAll("[a-zA-Z]", "");
                        Serializable businessName = retailer.getBusinessName();
                        try {
                                Serializable stateManager = storeManagerMap.get(retailer.getEmail()).get(2);
                                Serializable territoryManager = storeManagerMap.get(retailer.getEmail()).get(1);
                                Serializable teamLeader = storeManagerMap.get(retailer.getEmail()).get(0);
                                List<Serializable> row = new ArrayList<>(
                                                Arrays.asList(code, businessName, storeName, stateManager, territoryManager, teamLeader));
                                if (partnerSalesTargetRowsMap.get(retailer.getEmail()) != null) {
                                        row.addAll(partnerSalesTargetRowsMap.get(retailer.getEmail()));
                                        partnerRowMap.put(retailer.getEmail(), row);
                                        rows.add(row);
                                }
                        } catch (Exception e) {
                                LOGGER.warn("Could not find partner with email - {}", retailer.getEmail());
                        }

                }

                String fileName = "TargetVsSales-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv";
                for (Map.Entry<String, Set<String>> storeGuyEntry : getStoreGuyMap().entrySet()) {
                        List<List<? extends Serializable>> filteredRows = storeGuyEntry.getValue().stream()
                                        .map(x -> partnerRowMap.get(x)).filter(x -> x != null).collect(Collectors.toList());
                        ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, filteredRows);
                        String[] sendToArray = new String[] { nameEmail.get(storeGuyEntry.getKey()) };
                        Utils.sendMailWithAttachment(googleMailSender, sendToArray, null, "Target vs Sales Summary", "PFA",
                                        fileName, new ByteArrayResource(baos.toByteArray()));
                }

                ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, rows);
                String[] sendToArray = sendTo.toArray(new String[sendTo.size()]);
                Utils.sendMailWithAttachment(googleMailSender, sendToArray, null, "Target vs Sales Summary", "PFA", fileName,
                                new ByteArrayResource(baos.toByteArray()));
        }

        private Map<String, Set<String>> getStoreGuyMap() {
                Map<String, Set<String>> storeGuyMap = new HashMap<>();
                for (Map.Entry<String, List<String>> entry : storeManagerMap.entrySet()) {
                        String storeEmail = entry.getKey();
                        List<String> storeGuys = entry.getValue();
                        for (String storeGuy : storeGuys) {
                                if (!storeGuyMap.containsKey(storeGuy)) {
                                        storeGuyMap.put(storeGuy, new HashSet<>());
                                }
                                storeGuyMap.get(storeGuy).add(storeEmail);
                        }
                }
                storeGuyMap.remove("");
                return storeGuyMap;
        }

        public void sendAgeingReport(String... sendTo) throws Exception {

                InputStreamSource isr = reporticoService.getReportInputStreamSource(ReporticoProject.WAREHOUSENEW,
                                "itemstockageing.xml");
                InputStreamSource isr1 = reporticoService.getReportInputStreamSource(ReporticoProject.FOCO,
                                "ItemwiseOverallPendingIndent.xml");
                Attachment attachment = new Attachment(
                                "ageing-report-" + FormattingUtils.formatDate(LocalDateTime.now().minusDays(1)) + ".csv", isr);
                Attachment attachment1 = new Attachment(
                                "pending-indent-" + FormattingUtils.formatDate(LocalDateTime.now().minusDays(1)) + ".csv", isr1);
                Utils.sendMailWithAttachments(googleMailSender, sendTo, null, "Stock Aeging Report", "PFA", attachment,
                                attachment1);

                // Reports to be sent to mapped partners
                Map<String, Set<String>> storeGuysMap = getStoreGuyMap();

                String[] sendToArray = new String[storeGuysMap.size()];
                int i = 0;
                for (String storeGuyName : storeGuysMap.keySet()) {
                        sendToArray[i] = nameEmail.get(storeGuyName);
                        i++;
                }
                Utils.sendMailWithAttachments(googleMailSender, sendToArray, null, "Stock Aeging Report", "PFA", attachment);

                for (Map.Entry<String, Set<String>> storeGuyEntry : storeGuysMap.entrySet()) {
                        Map<String, String> params = new HashMap<>();
                        if (storeGuyEntry.getValue().size() == 0)
                                continue;
                        params.put("MANUAL_email", String.join(",", storeGuyEntry.getValue()));
                        InputStreamSource isr3 = reporticoService.getReportInputStreamSource(ReporticoProject.FOCO,
                                        "focostockreport.xml", params);
                        Attachment attache = new Attachment(
                                        "partner-stock-report" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv", isr3);
                        Utils.sendMailWithAttachments(googleMailSender, storeGuyEntry.getValue().toArray(new String[] {}), null,
                                        "Partner Stock Report", "PFA", attache);
                }

        }

        public void sendAgeingReport() throws Exception {
                sendAgeingReport("kamini.sharma@smartdukaan.com", "tarun.verma@smartdukaan.com",
                                "chaitnaya.vats@smartdukaan.com");
        }

        public void moveImeisToPriceDropImeis() throws Exception {
                List<PriceDrop> priceDrops = priceDropRepository.selectAll();
                for (PriceDrop priceDrop : priceDrops) {
                        priceDropService.priceDropStatus(priceDrop.getId());
                }
        }

        public void walletmismatch() throws Exception {
                LocalDate curDate = LocalDate.now();
                List<PartnerDailyInvestment> pdis = partnerDailyInvestmentRepository.selectAll(curDate.minusDays(2));
                System.out.println(pdis.size());
                for (PartnerDailyInvestment pdi : pdis) {
                        int fofoId = pdi.getFofoId();
                        for (PartnerDailyInvestment investment : Lists
                                        .reverse(partnerDailyInvestmentRepository.selectAll(fofoId, null, null))) {
                                float statementAmount = walletService.getOpeningTill(fofoId,
                                                investment.getDate().plusDays(1).atTime(LocalTime.of(4, 0)));
                                CustomRetailer retailer = retailerService.getFofoRetailer(fofoId);
                                LOGGER.info("{}\t{}\t{}\t{}\t{}", fofoId, retailer.getBusinessName(), retailer.getMobileNumber(),
                                                investment.getDate().toString(), investment.getWalletAmount(), statementAmount);

                        }
                }

        }

        public void gst() throws Exception {
                List<FofoOrder> fofoOrders = fofoOrderRepository.selectBetweenSaleDate(LocalDate.of(2019, 1, 26).atStartOfDay(),
                                LocalDate.of(2019, 1, 27).atTime(LocalTime.MAX));
                for (FofoOrder fofoOrder : fofoOrders) {
                        int retailerAddressId = retailerRegisteredAddressRepository
                                        .selectAddressIdByRetailerId(fofoOrder.getFofoId());

                        Address retailerAddress = addressRepository.selectById(retailerAddressId);
                        CustomerAddress customerAddress = customerAddressRepository.selectById(fofoOrder.getCustomerAddressId());
                        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");
                                }
                        }
                        Map<Integer, GstRate> itemIdStateTaxRateMap = null;
                        Map<Integer, Float> itemIdIgstTaxRateMap = null;

                        List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
                        Set<Integer> itemIds = fofoOrderItems.stream().map(x -> x.getItemId()).collect(Collectors.toSet());
                        if (stateId != null) {
                                itemIdStateTaxRateMap = Utils.getStateTaxRate(new ArrayList<>(itemIds), stateId);
                        } else {
                                itemIdIgstTaxRateMap = Utils.getIgstTaxRate(new ArrayList<>(itemIds));
                        }

                        for (FofoOrderItem foi : fofoOrderItems) {
                                if (stateId == null) {
                                        foi.setIgstRate(itemIdIgstTaxRateMap.get(foi.getItemId()));
                                } else {
                                        foi.setCgstRate(itemIdStateTaxRateMap.get(foi.getItemId()).getCgstRate());
                                        foi.setSgstRate(itemIdStateTaxRateMap.get(foi.getItemId()).getSgstRate());
                                }
                                fofoOrderItemRepository.persist(foi);
                        }
                }

        }

        public void schemewalletmismatch() {
                LocalDate dateToReconcile = LocalDate.of(2018, 4, 1);
                while (dateToReconcile.isBefore(LocalDate.now())) {
                        reconcileSchemes(dateToReconcile);
                        // reconcileOrders(dateTime);
                        // reconcileRecharges(dateTime);
                        dateToReconcile = dateToReconcile.plusDays(1);
                }
        }

        private void reconcileSchemes(LocalDate date) {
                LocalDateTime startDate = date.atStartOfDay();
                LocalDateTime endDate = startDate.plusDays(1);
                List<SchemeInOut> siosCreated = schemeInOutRepository.selectAllByCreateDate(startDate, endDate);
                List<SchemeInOut> siosRefunded = schemeInOutRepository.selectAllByRefundDate(startDate, endDate);
                double totalSchemeDisbursed = siosCreated.stream().mapToDouble(x -> x.getAmount()).sum();
                double totalSchemeRolledback = siosRefunded.stream().mapToDouble(x -> x.getAmount()).sum();
                double netSchemeDisbursed = totalSchemeDisbursed - totalSchemeRolledback;
                List<WalletReferenceType> walletReferenceTypes = Arrays.asList(WalletReferenceType.SCHEME_IN,
                                WalletReferenceType.SCHEME_OUT);
                List<UserWalletHistory> history = userWalletHistoryRepository.selectAllByDateType(startDate, endDate,
                                walletReferenceTypes);
                double schemeAmountWalletTotal = history.stream().mapToDouble(x -> x.getAmount()).sum();
                if (Math.abs(netSchemeDisbursed - schemeAmountWalletTotal) > 10d) {
                        LOGGER.info("Scheme Amount mismatched for Date {}", date);

                        Map<Integer, Double> inventoryItemSchemeIO = siosCreated.stream().collect(Collectors
                                        .groupingBy(x -> x.getInventoryItemId(), Collectors.summingDouble(SchemeInOut::getAmount)));

                        Map<Integer, Double> userSchemeMap = inventoryItemRepository.selectByIds(inventoryItemSchemeIO.keySet())
                                        .stream().collect(Collectors.groupingBy(x -> x.getFofoId(),
                                                        Collectors.summingDouble(x -> inventoryItemSchemeIO.get(x.getId()))));

                        Map<Integer, Double> inventoryItemSchemeIORefunded = siosRefunded.stream().collect(Collectors
                                        .groupingBy(x -> x.getInventoryItemId(), Collectors.summingDouble(SchemeInOut::getAmount)));

                        Map<Integer, Double> userSchemeRefundedMap = inventoryItemRepository
                                        .selectByIds(inventoryItemSchemeIORefunded.keySet()).stream()
                                        .collect(Collectors.groupingBy(x -> x.getFofoId(),
                                                        Collectors.summingDouble(x -> inventoryItemSchemeIORefunded.get(x.getId()))));

                        Map<Integer, Double> finalUserSchemeAmountMap = new HashMap<>();
                        for (Map.Entry<Integer, Double> schemeAmount : userSchemeMap.entrySet()) {
                        }
                        for (Map.Entry<Integer, Double> schemeAmount : userSchemeRefundedMap.entrySet()) {
                                if (!finalUserSchemeAmountMap.containsKey(schemeAmount.getKey())) {
                                        finalUserSchemeAmountMap.put(schemeAmount.getKey(), schemeAmount.getValue());
                                } else {
                                        finalUserSchemeAmountMap.put(schemeAmount.getKey(),
                                                        finalUserSchemeAmountMap.get(schemeAmount.getKey()) + schemeAmount.getValue());
                                }
                        }
                        Map<Integer, Integer> userWalletMap = userWalletRepository
                                        .selectByRetailerIds(finalUserSchemeAmountMap.keySet()).stream()
                                        .collect(Collectors.toMap(UserWallet::getUserId, UserWallet::getId));

                        Map<Integer, Double> walletAmountMap = history.stream().collect(Collectors.groupingBy(
                                        UserWalletHistory::getWalletId, Collectors.summingDouble((UserWalletHistory::getAmount))));
                        for (Map.Entry<Integer, Double> userAmount : walletAmountMap.entrySet()) {
                                double diff = Math.abs(finalUserSchemeAmountMap.get(userAmount.getKey()) - userAmount.getValue());
                                if (diff > 5) {
                                        LOGGER.info("Partner scheme mismatched for Userid {}", userWalletMap.get(userAmount.getKey()));
                                }
                        }
                }

        }

        public void dryRunSchemeReco() throws Exception {
                Map<Integer, Integer> userWalletMap = userWalletRepository.selectAll().stream()
                                .collect(Collectors.toMap(UserWallet::getUserId, UserWallet::getId));

                List<UserWalletHistory> userWalletHistory = new ArrayList<>();
                List<SchemeInOut> rolledbackSios = new ArrayList<>();
                Map<Integer, SchemeType> schemeTypeMap = schemeRepository.selectAll().stream()
                                .collect(Collectors.toMap(Scheme::getId, Scheme::getType));
                Set<String> serialNumbersConsidered = new HashSet<>();

                LocalDateTime startDate = LocalDate.of(2018, 3, 1).atStartOfDay();
                LocalDateTime endDate = LocalDate.now().atStartOfDay();
                List<Purchase> purchases = purchaseRepository.selectAllBetweenPurchaseDate(startDate, endDate);

                Map<Integer, String> storeNameMap = fofoStoreRepository.getStoresMap();
                purchases.stream().forEach(purchase -> {
                        float amountToRollback = 0;
                        String description = "Adjustment of Duplicate Scheme for Purchase Invoice "
                                        + purchase.getPurchaseReference();
                        Map<Integer, String> inventorySerialNumberMap = inventoryItemRepository.selectByPurchaseId(purchase.getId())
                                        .stream().filter(ii -> ii.getSerialNumber() != null)
                                        .collect(Collectors.toMap(InventoryItem::getId, InventoryItem::getSerialNumber));
                        if (inventorySerialNumberMap.size() > 0) {
                                for (Map.Entry<Integer, String> inventorySerialNumberEntry : inventorySerialNumberMap.entrySet()) {
                                        String serialNumber = inventorySerialNumberEntry.getValue();
                                        int inventoryItemId = inventorySerialNumberEntry.getKey();
                                        if (serialNumbersConsidered.contains(serialNumber)) {
                                                // This will rollback scheme for differenct orders for same serial
                                                List<SchemeInOut> sios = schemeInOutRepository
                                                                .selectByInventoryItemIds(new HashSet<>(Arrays.asList(inventoryItemId))).stream()
                                                                .filter(x -> x.getRolledBackTimestamp() == null
                                                                                && schemeTypeMap.get(x.getSchemeId()).equals(SchemeType.IN))
                                                                .collect(Collectors.toList());
                                                Collections.reverse(sios);
                                                for (SchemeInOut sio : sios) {
                                                        sio.setRolledBackTimestamp(LocalDateTime.now());
                                                        amountToRollback += sio.getAmount();
                                                        // sio.setSchemeType(SchemeType.OUT);
                                                        sio.setSerialNumber(serialNumber);
                                                        rolledbackSios.add(sio);
                                                }
                                                description = description.concat(" " + serialNumber + " ");
                                        } else {
                                                serialNumbersConsidered.add(serialNumber);
                                                List<Integer> schemesConsidered = new ArrayList<>();
                                                List<SchemeInOut> sios = schemeInOutRepository
                                                                .selectByInventoryItemIds(new HashSet<>(Arrays.asList(inventoryItemId))).stream()
                                                                .filter(x -> x.getRolledBackTimestamp() == null
                                                                                && schemeTypeMap.get(x.getSchemeId()).equals(SchemeType.IN))
                                                                .collect(Collectors.toList());
                                                Collections.reverse(sios);
                                                for (SchemeInOut sio : sios) {
                                                        if (!schemesConsidered.contains(sio.getSchemeId())) {
                                                                schemesConsidered.add(sio.getSchemeId());
                                                                continue;
                                                        }
                                                        sio.setRolledBackTimestamp(LocalDateTime.now());
                                                        amountToRollback += sio.getAmount();
                                                        // sio.setSchemeType(SchemeType.OUT);
                                                        sio.setSerialNumber(serialNumber);
                                                        sio.setStoreCode(storeNameMap.get(purchase.getFofoId()));
                                                        sio.setReference(purchase.getId());
                                                        rolledbackSios.add(sio);
                                                }
                                        }

                                }
                        }
                        if (amountToRollback > 0) {
                                // Address address =
                                // addressRepository.selectAllByRetailerId(purchase.getFofoId(), 0, 10).get(0);
                                UserWalletHistory uwh = new UserWalletHistory();
                                uwh.setAmount(Math.round(amountToRollback));
                                uwh.setDescription(description);
                                uwh.setTimestamp(LocalDateTime.now());
                                uwh.setReferenceType(WalletReferenceType.SCHEME_IN);
                                uwh.setReference(purchase.getId());
                                uwh.setWalletId(userWalletMap.get(purchase.getFofoId()));
                                uwh.setFofoId(purchase.getFofoId());
                                uwh.setStoreCode(storeNameMap.get(purchase.getFofoId()));
                                userWalletHistory.add(uwh);
                        }
                });
                ByteArrayOutputStream baos = FileUtil.getCSVByteStream(
                                Arrays.asList("User Id", "Store Code", "Reference Type", "Reference", "Amount", "Description",
                                                "Timestamp"),
                                userWalletHistory.stream()
                                                .map(x -> Arrays.asList(x.getWalletId(), x.getStoreCode(), x.getReferenceType(),
                                                                x.getReference(), x.getAmount(), x.getDescription(), x.getTimestamp()))
                                                .collect(Collectors.toList()));

                ByteArrayOutputStream baosOuts = FileUtil.getCSVByteStream(
                                Arrays.asList("Scheme ID", "SchemeType", "Reference", "Store Code", "Serial Number", "Amount",
                                                "Created", "Rolledback"),
                                rolledbackSios.stream()
                                                .map(x -> Arrays.asList(x.getSchemeId(), x.getSchemeType(), x.getReference(), x.getStoreCode(),
                                                                x.getSerialNumber(), x.getAmount(), x.getCreateTimestamp(), x.getRolledBackTimestamp()))
                                                .collect(Collectors.toList()));

                Utils.sendMailWithAttachments(googleMailSender, new String[] { "amit.gupta@shop2020.in" }, null,
                                "Partner Excess Amount Scheme In", "PFA",
                                new Attachment[] { new Attachment("WalletSummary.csv", new ByteArrayResource(baos.toByteArray())),
                                                new Attachment("SchemeInRolledback.csv", new ByteArrayResource(baosOuts.toByteArray())) });

                throw new Exception();

        }

        public void dryRunOutSchemeReco() throws Exception {
                List<UserWalletHistory> userWalletHistory = new ArrayList<>();
                List<SchemeInOut> rolledbackSios = new ArrayList<>();
                Map<Integer, Integer> userWalletMap = userWalletRepository.selectAll().stream()
                                .collect(Collectors.toMap(UserWallet::getUserId, UserWallet::getId));
                Map<Integer, SchemeType> schemeTypeMap = schemeRepository.selectAll().stream()
                                .collect(Collectors.toMap(Scheme::getId, Scheme::getType));
                LocalDateTime startDate = LocalDate.of(2019, 5, 1).atStartOfDay();
                LocalDateTime endDate = LocalDate.now().atStartOfDay();
                List<FofoOrder> allOrders = fofoOrderRepository.selectBetweenSaleDate(startDate, endDate);
                // Collections.reverse(allOrders);
                // List<FofoOrder> allOrders =
                // List<FofoOrder> allOrders =
                // Arrays.asList(fofoOrderRepository.selectByInvoiceNumber("UPGZ019/25"));
                Set<String> serialNumbersConsidered = new HashSet<>();
                allOrders.stream().forEach(fofoOrder -> {
                        String description = "Adjustment of Duplicate Scheme for Sale Invoice " + fofoOrder.getInvoiceNumber();
                        Map<Integer, String> inventorySerialNumberMap = new HashMap<>();
                        float amountToRollback = 0;
                        List<FofoOrderItem> orderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
                        orderItems.forEach(x -> {
                                inventorySerialNumberMap.putAll(x.getFofoLineItems().stream().filter(li -> li.getSerialNumber() != null)
                                                .collect(Collectors.toMap(FofoLineItem::getInventoryItemId, FofoLineItem::getSerialNumber)));
                        });
                        if (inventorySerialNumberMap.size() > 0) {
                                for (Map.Entry<Integer, String> inventorySerialNumberEntry : inventorySerialNumberMap.entrySet()) {
                                        String serialNumber = inventorySerialNumberEntry.getValue();
                                        int inventoryItemId = inventorySerialNumberEntry.getKey();
                                        if (serialNumbersConsidered.contains(serialNumber)) {
                                                // This will rollback scheme for differenct orders for same serial
                                                List<SchemeInOut> sios = schemeInOutRepository
                                                                .selectByInventoryItemIds(new HashSet<>(Arrays.asList(inventoryItemId))).stream()
                                                                .filter(x -> x.getRolledBackTimestamp() == null
                                                                                && schemeTypeMap.get(x.getSchemeId()).equals(SchemeType.OUT))
                                                                .collect(Collectors.toList());
                                                Collections.reverse(sios);
                                                for (SchemeInOut sio : sios) {
                                                        sio.setRolledBackTimestamp(LocalDateTime.now());
                                                        amountToRollback += sio.getAmount();
                                                        // sio.setSchemeType(SchemeType.OUT);
                                                        sio.setSerialNumber(serialNumber);
                                                        sio.setStoreCode(fofoOrder.getInvoiceNumber().split("/")[0]);
                                                        sio.setReference(fofoOrder.getId());
                                                        rolledbackSios.add(sio);
                                                }
                                                description = description.concat(" " + serialNumber + " ");
                                        } else {
                                                serialNumbersConsidered.add(serialNumber);
                                                List<Integer> schemesConsidered = new ArrayList<>();
                                                List<SchemeInOut> sios = schemeInOutRepository
                                                                .selectByInventoryItemIds(new HashSet<>(Arrays.asList(inventoryItemId))).stream()
                                                                .filter(x -> x.getRolledBackTimestamp() == null
                                                                                && schemeTypeMap.get(x.getSchemeId()).equals(SchemeType.OUT))
                                                                .collect(Collectors.toList());
                                                Collections.reverse(sios);
                                                for (SchemeInOut sio : sios) {
                                                        if (!schemesConsidered.contains(sio.getSchemeId())) {
                                                                schemesConsidered.add(sio.getSchemeId());
                                                                continue;
                                                        }
                                                        sio.setRolledBackTimestamp(LocalDateTime.now());
                                                        amountToRollback += sio.getAmount();
                                                        // sio.setSchemeType(SchemeType.OUT);
                                                        sio.setReference(fofoOrder.getId());
                                                        sio.setSerialNumber(serialNumber);
                                                        sio.setStoreCode(fofoOrder.getInvoiceNumber().split("/")[0]);
                                                        rolledbackSios.add(sio);
                                                }
                                        }

                                }
                        }
                        if (amountToRollback > 0) {
                                UserWalletHistory uwh = new UserWalletHistory();
                                uwh.setAmount(Math.round(amountToRollback));
                                uwh.setDescription(description);
                                uwh.setTimestamp(LocalDateTime.now());
                                uwh.setReferenceType(WalletReferenceType.SCHEME_OUT);
                                uwh.setReference(fofoOrder.getId());
                                uwh.setWalletId(userWalletMap.get(fofoOrder.getFofoId()));
                                uwh.setFofoId(fofoOrder.getFofoId());
                                uwh.setStoreCode(fofoOrder.getInvoiceNumber().split("/")[0]);
                                userWalletHistory.add(uwh);
                        }
                });

                ByteArrayOutputStream baos = FileUtil.getCSVByteStream(
                                Arrays.asList("Wallet Id", "Store Code", "Reference Type", "Reference", "Amount", "Description",
                                                "Timestamp"),
                                userWalletHistory.stream()
                                                .map(x -> Arrays.asList(x.getWalletId(), x.getStoreCode(), x.getReferenceType(),
                                                                x.getReference(), x.getAmount(), x.getDescription(), x.getTimestamp()))
                                                .collect(Collectors.toList()));

                ByteArrayOutputStream baosOuts = FileUtil.getCSVByteStream(
                                Arrays.asList("Scheme ID", "SchemeType", "Store Code", "Serial Number", "Amount", "Created",
                                                "Rolledback"),
                                rolledbackSios.stream()
                                                .map(x -> Arrays.asList(x.getSchemeId(), x.getSchemeType(), x.getStoreCode(),
                                                                x.getSerialNumber(), x.getAmount(), x.getCreateTimestamp(), x.getRolledBackTimestamp()))
                                                .collect(Collectors.toList()));

                Utils.sendMailWithAttachments(googleMailSender, new String[] { "amit.gupta@shop2020.in" }, null,
                                "Partner Excess Amount Scheme Out", "PFA",
                                new Attachment[] { new Attachment("WalletSummary.csv", new ByteArrayResource(baos.toByteArray())),
                                                new Attachment("SchemeOutRolledback.csv", new ByteArrayResource(baosOuts.toByteArray())) });

                throw new Exception();
        }

        public void dryRunSchemeOutReco1() throws Exception {
                List<Integer> references = Arrays.asList(6744, 7347, 8320, 8891, 9124, 9217, 9263, 9379);
                List<UserWalletHistory> userWalletHistory = new ArrayList<>();
                List<SchemeInOut> rolledbackSios = new ArrayList<>();
                Map<Integer, Integer> userWalletMap = userWalletRepository.selectAll().stream()
                                .collect(Collectors.toMap(UserWallet::getUserId, UserWallet::getId));
                Map<Integer, SchemeType> schemeTypeMap = schemeRepository.selectAll().stream()
                                .collect(Collectors.toMap(Scheme::getId, Scheme::getType));
                references.stream().forEach(reference -> {
                        FofoOrder fofoOrder = null;
                        try {
                                fofoOrder = fofoOrderRepository.selectByOrderId(reference);
                        } catch (Exception e) {

                        }
                        String description = "Adjustment of Duplicate Scheme for Sale Invoice " + fofoOrder.getInvoiceNumber();
                        Map<Integer, String> inventorySerialNumberMap = new HashMap<>();
                        float amountToRollback = 0;
                        List<FofoOrderItem> orderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());
                        orderItems.forEach(x -> {
                                inventorySerialNumberMap.putAll(x.getFofoLineItems().stream().filter(li -> li.getSerialNumber() != null)
                                                .collect(Collectors.toMap(FofoLineItem::getInventoryItemId, FofoLineItem::getSerialNumber)));
                        });
                        if (inventorySerialNumberMap.size() > 0) {
                                List<SchemeInOut> sios = schemeInOutRepository
                                                .selectByInventoryItemIds(inventorySerialNumberMap.keySet()).stream()
                                                .filter(x -> schemeTypeMap.get(x.getSchemeId()).equals(SchemeType.OUT))
                                                .collect(Collectors.toList());
                                LOGGER.info("Found {} duplicate schemeouts for Orderid {}", sios.size(), fofoOrder.getId());
                                UserWalletHistory uwh = new UserWalletHistory();
                                Map<Integer, List<SchemeInOut>> inventoryIdSouts = sios.stream()
                                                .collect(Collectors.groupingBy(SchemeInOut::getInventoryItemId, Collectors.toList()));
                                for (Map.Entry<Integer, List<SchemeInOut>> inventorySioEntry : inventoryIdSouts.entrySet()) {
                                        List<SchemeInOut> outList = inventorySioEntry.getValue();
                                        if (outList.size() > 1) {

                                        }
                                }
                                uwh.setAmount(Math.round(amountToRollback));
                                uwh.setDescription(description);
                                uwh.setTimestamp(LocalDateTime.now());
                                uwh.setReferenceType(WalletReferenceType.SCHEME_OUT);
                                uwh.setReference(fofoOrder.getId());
                                uwh.setWalletId(userWalletMap.get(fofoOrder.getFofoId()));
                                uwh.setFofoId(fofoOrder.getFofoId());
                                uwh.setStoreCode(fofoOrder.getInvoiceNumber().split("/")[0]);
                                userWalletHistory.add(uwh);
                        }
                });

                ByteArrayOutputStream baos = FileUtil.getCSVByteStream(
                                Arrays.asList("User Id", "Reference Type", "Reference", "Amount", "Description", "Timestamp"),
                                userWalletHistory.stream().map(x -> Arrays.asList(x.getWalletId(), x.getReferenceType(),
                                                x.getReference(), x.getAmount(), x.getDescription(), x.getTimestamp()))
                                                .collect(Collectors.toList()));

                ByteArrayOutputStream baosOuts = FileUtil.getCSVByteStream(
                                Arrays.asList("Scheme ID", "SchemeType", "Store Code", "Serial Number", "Amount", "Created",
                                                "Rolledback"),
                                rolledbackSios.stream()
                                                .map(x -> Arrays.asList(x.getSchemeId(), x.getSchemeType(), x.getStoreCode(),
                                                                x.getSerialNumber(), x.getAmount(), x.getCreateTimestamp(), x.getRolledBackTimestamp()))
                                                .collect(Collectors.toList()));

                Utils.sendMailWithAttachments(googleMailSender,
                                new String[] { "amit.gupta@shop2020.in", "neeraj.gupta@smartdukaan.com" }, null,
                                "Partner Excess Amount", "PFA",
                                new Attachment[] { new Attachment("WalletSummary.csv", new ByteArrayResource(baos.toByteArray())),
                                                new Attachment("SchemeOutRolledback.csv", new ByteArrayResource(baosOuts.toByteArray())) });

                throw new Exception();

        }

        public void sendDailySalesReportNotificationToPartner(Integer fofoIdInt)
                        throws ProfitMandiBusinessException, MessagingException, IOException {
                LocalDateTime now = LocalDateTime.now();
                LocalDateTime from = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 00, 00);
                Map<Integer, Double> salesByFofoIdMap = new HashMap<>();
                List<Integer> fofoIds = null;
                if (fofoIdInt == null) {
                        fofoIds = fofoStoreRepository.selectAll().stream().filter(x -> x.isActive()).map(x -> x.getId())
                                        .collect(Collectors.toList());
                } else {
                        fofoIds = Arrays.asList(fofoIdInt);
                }
                List<PartnerTargetDetails> partnerTargetDetails = partnerTargetRepository
                                .selectAllGeEqAndLeEqStartDateAndEndDate(now);
                DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("h a");

                Map<Integer, Float> dailyTarget = new HashMap<>();
                for (Integer fofoId : fofoIds) {
                        Map<Integer, Float> dailyAverageSale = null;
                        double sale = fofoOrderRepository.selectTotalSaleSumByFofoIdBrtweenDate(fofoId, from, now);
                        for (PartnerTargetDetails partnerTargetDetail : partnerTargetDetails) {
                                Map<Integer, Float> targetValues = targetService.getTargetValueByFofoIdAndTargetId(fofoId,
                                                partnerTargetDetail.getId());
                                if (targetValues.size() == 0) {
                                        continue;
                                } else {
                                        List<Integer> partnerIds = new ArrayList<>();
                                        partnerIds.add(fofoId);
                                        dailyAverageSale = targetService.getDailyAverageSaleForCurrentForSingleFofoIdAndBrand(partnerIds,
                                                        targetValues, partnerTargetDetail.getStartDate(), partnerTargetDetail.getEndDate(),
                                                        partnerTargetDetail.getBrandName());
                                        dailyTarget.put(fofoId, dailyAverageSale.get(fofoId));
                                        break;
                                }
                        }
                        NotificationCampaigns notification = new NotificationCampaigns();
                        notification.setName("Daily Sales");
                        notification.setTitle("Daily Sale Update");
                        if (dailyAverageSale != null && dailyAverageSale.get(fofoId) != null) {
                                notification.setMessage(String.format("Rs.%.0f till %s. Today's Target is Rs.%.0f", sale,
                                                now.format(timeFormatter), dailyAverageSale.get(fofoId)));
                        } else {
                                notification.setMessage(String.format("Rs.%.0f till %s", sale, now.format(timeFormatter)));
                        }
                        // notification.setMessage("Your sale is "+salesbyfofoId.get(fofoId));
                        notification.setType("url");
                        notification.setUrl("http://app.profitmandi.com/pages/home/notifications");
                        LOGGER.info("UserID" + userAccountRepository.selectUserIdByRetailerId(fofoId));
                        notification.setSql("SELECT distinct d1.user_id from devices d1 left join devices d2 on"
                                        + "(d1.imeinumber = d2.imeinumber and d1.created < d2.created) "
                                        + " where d2.id is null and d1.user_id = "
                                        + userAccountRepository.selectUserIdByRetailerId(fofoId));
                        LOGGER.info("SELECT distinct d1.user_id from devices d1 left join devices d2 on"
                                        + "(d1.imeinumber = d2.imeinumber and d1.created < d2.created) "
                                        + " where d2.id is null and d1.user_id = "
                                        + userAccountRepository.selectUserIdByRetailerId(fofoId));
                        notification.setExpiresat(LocalDateTime.now().plusDays(1).toEpochSecond(ZoneOffset.UTC) * 1000);
                        notification.setStatus("active");
                        notification.setSmsprocessed(0);
                        notification.setNotification_processed(0);
                        notification.setNotification_type("GENERAL_NOTIFICATION");
                        mongoClient.persistNotificationCmpInfo(notification);
                        salesByFofoIdMap.put(fofoId, sale);
                        LOGGER.info(sale);
                }
                String saleReport = this.getDailySalesReportByPartnerId(salesByFofoIdMap, dailyTarget);
                LOGGER.info(saleReport);
                String cc[] = { "Tarun.verma@smartdukaan.com", "Kamini.sharma@smartdukaan.com",
                                "chaitnaya.vats@smartdukaan.com", "adeel.yazdani@smartdukaan.com", "mohinder.mutreja@smartdukaan.com" };
                String subject = "sale report till" + " " + now.format(timeFormatter);
                this.sendMailOfHtmlFomat("amod.sen@smartdukaan.com", saleReport, cc, subject);
        }

        public String getDailySalesReportByPartnerId(Map<Integer, Double> salesByFofoIdMap, Map<Integer, Float> dailyTarget)
                        throws ProfitMandiBusinessException {
                StringBuilder sb = new StringBuilder();
                sb.append("<html><body><p>Sale Report:</p><br/><table style='border:1px solid black ;padding: 5px';>");
                sb.append("<tbody>\n" + "                                       <tr>\n"
                                + "                                             <th style='border:1px solid black;padding: 5px'>Partner</th>\n"
                                + "                                             <th style='border:1px solid black;padding: 5px'>Daily Target</th>\n"
                                + "                                             <th style='border:1px solid black;padding: 5px'>Sale</th>\n"
                                + "                                     </tr>");
                for (Integer fofoId : salesByFofoIdMap.keySet()) {
                        try {
                                String PartnerName = retailerService.getFofoRetailer(fofoId).getBusinessName();
                                sb.append("<tr>");
                                sb.append("<td style='border:1px solid black;padding: 5px'>" + PartnerName + "</td>");
                                if (dailyTarget != null && dailyTarget.get(fofoId) != null) {
                                        sb.append("<td style='border:1px solid black;padding: 5px'>" + dailyTarget.get(fofoId) + "</td>");
                                } else {
                                        sb.append("<td style='border:1px solid black;padding: 5px'>" + 0.0 + "</td>");
                                }
                                sb.append("<td style='border:1px solid black;padding: 5px'>" + salesByFofoIdMap.get(fofoId) + "</td>");

                                sb.append("</tr>");
                        } catch (Exception e) {
                                e.printStackTrace();
                        }

                }

                sb.append("</tbody></table></body></html>");
                return sb.toString();
        }

        private void sendMailOfHtmlFomat(String email, String body, String cc[], String subject)
                        throws MessagingException, ProfitMandiBusinessException, IOException {
                MimeMessage message = mailSender.createMimeMessage();
                MimeMessageHelper helper = new MimeMessageHelper(message);
                helper.setSubject(subject);
                helper.setText(body, true);
                helper.setTo(email);
                if (cc != null) {
                        helper.setCc(cc);
                }
                InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smart Dukaan");
                helper.setFrom(senderAddress);
                mailSender.send(message);
        }

        public void sendNotification() throws Exception {
                List<PushNotifications> pushNotifications = pushNotificationRepository.selectAllByTimestamp();
                if (!pushNotifications.isEmpty()) {
                        for (PushNotifications pushNotification : pushNotifications) {
                                Device device = deviceRepository.selectById(pushNotification.getDeviceId());
                                NotificationCampaign notificationCampaign = notificationCampaignRepository
                                                .selectById(pushNotification.getNotificationCampaignid());
                                Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls()
                                                .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeJsonConverter()).create();

                                SimpleCampaignParams scp = gson.fromJson(notificationCampaign.getImplementationParams(),
                                                SimpleCampaignParams.class);
                                Campaign campaign = new SimpleCampaign(scp);
                                String result_url = campaign.getUrl() + "&user_id=" + device.getUser_id();
                                JSONObject json = new JSONObject();
                                json.put("to", device.getFcmId());
                                JSONObject jsonObj = new JSONObject();
                                jsonObj.put("message", campaign.getMessage());
                                jsonObj.put("title", campaign.getTitle());
                                jsonObj.put("type", campaign.getType());
                                jsonObj.put("url", result_url);
                                jsonObj.put("time_to_live", campaign.getExpireTimestamp());
                                jsonObj.put("image", campaign.getImageUrl());
                                jsonObj.put("largeIcon", "large_icon");
                                jsonObj.put("smallIcon", "small_icon");
                                jsonObj.put("vibrate", 1);
                                jsonObj.put("pid", pushNotification.getId());
                                jsonObj.put("sound", 1);
                                jsonObj.put("priority", "high");
                                json.put("data", jsonObj);
                                try {
                                        CloseableHttpClient client = HttpClients.createDefault();
                                        HttpPost httpPost = new HttpPost(FCM_URL);

                                        httpPost.setHeader("Content-Type", "application/json; utf-8");
                                        httpPost.setHeader("authorization", "key=" + FCM_API_KEY);
                                        StringEntity entity = new StringEntity(json.toString());
                                        httpPost.setEntity(entity);
                                        CloseableHttpResponse response = client.execute(httpPost);
                                        LOGGER.info("response" + response);

                                        if (response.getStatusLine().getStatusCode() == 200) {
                                                pushNotification.setSentTimestamp(LocalDateTime.now());
                                        } else {
                                                pushNotification.setSentTimestamp(LocalDateTime.of(1970, 1, 1, 00, 00));
                                                LOGGER.info("message" + "not sent");
                                        }

                                } catch (Exception e) {
                                        e.printStackTrace();
                                        LOGGER.info("message" + "not sent");
                                }
                        }
                }
        }

        public static final Map<String, List<String>> storeManagerMap = new HashMap<>();

        public static final Map<String, String> nameEmail = new HashMap<>();
        static {
                nameEmail.put("Amod", "amod.sen@smartdukaan.com");
                nameEmail.put("Parmod", "parmod.kumar@smartdukaan.com");
                nameEmail.put("Anis", "md.anis@smartdukaan.com");
                nameEmail.put("Manoj", "manoj.singh@smartdukaan.com");
                nameEmail.put("Adeel", "adeel.yazdani@smartdukaan.com");
                nameEmail.put("Mohinder", "mohinder.mutreja@smartdukaan.com");
                nameEmail.put("Dharmendar", "dharmender.verma@smartdukaan.com");
                nameEmail.put("Rajat", "rajat.gupta@smartdukaan.com");
                nameEmail.put("Ankit", "ankit.bhatia@smartdukaan.com");
                nameEmail.put("Rajit", "rajit.alag@smartdukaan.com");
                nameEmail.put("Gulshan", "gulshan.kumar@smartdukaan.com");
                nameEmail.put("PramodSharma", "parmod.sharma@smartdukaan.com");
                nameEmail.put("Sohan", "sohan.lal@smartdukaan.com");
                nameEmail.put("Ajay", "ajay.kumar@smartdukaan.com");
                // nameEmail.put("Gulshan","");

                storeManagerMap.put("themobileplanet03@gmail.com", Arrays.asList("Amod", "", "Adeel"));
                storeManagerMap.put("mobileplanet7599@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("robintelecom.snp@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("smartconnect4141@gmail.com", Arrays.asList("Amod", "", "Adeel"));
                storeManagerMap.put("bhimsain919@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("babitaranirk@gmail.com", Arrays.asList("PramodSharma", "", "Mohinder"));
                storeManagerMap.put("dharmendery079@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("kkv.enterprises1@gmail.com", Arrays.asList("PramodSharma", "", "Mohinder"));
                storeManagerMap.put("gulshersaifi74226@gmail.com", Arrays.asList("Amod", "", "Adeel"));
                storeManagerMap.put("deepak.lalwani1985@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("gupta.smartdukaan@gmail.com", Arrays.asList("Amod", "", "Adeel"));
                storeManagerMap.put("sachinindri2006@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("kambojanil83@gmail.com", Arrays.asList("PramodSharma", "", "Mohinder"));
                storeManagerMap.put("uppal.neeraj82@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("thefonehousekarnal@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("richa9910763006@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("smartdukangzb@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("lovelymobile183@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("smartdukaan.sonepat@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("arunmittal299@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("gtc01100@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("sumittyagi1975@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("metrofurniture342@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("suryaelectronicskaithal@gmail.com", Arrays.asList("PramodSharma", "", "Mohinder"));
                storeManagerMap.put("mmtelecomsec16@gmail.com", Arrays.asList("Amod", "", "Adeel"));
                storeManagerMap.put("omsonsindia08@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("smartenterprisespv@gmail.com", Arrays.asList("Amod", "", "Adeel"));
                storeManagerMap.put("cachaitnya@gmail.com", Arrays.asList("Amod", "", "Adeel"));
                storeManagerMap.put("ajaykumarkansal03@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("spurwar73@gmail.com", Arrays.asList("", "Rajat", "Adeel"));
                storeManagerMap.put("Shreemobile.ind@gmail.com", Arrays.asList("", "Rajat", "Adeel"));
                storeManagerMap.put("felixenterprises2017@rediffmail.com", Arrays.asList("", "Dharmendar", "Mohinder"));
                storeManagerMap.put("nareandergupta@gmail.com", Arrays.asList("", "Dharmendar", "Mohinder"));
                storeManagerMap.put("shreebalajielectronic2019@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("saranshary@gmail.com", Arrays.asList("", "Dharmendar", "Mohinder"));
                storeManagerMap.put("gambhirsmartphone@gmail.com", Arrays.asList("", "Gulshan", "Adeel"));
                storeManagerMap.put("Priyankaenterprises9910@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("pawan.dhimaan@gmail.com", Arrays.asList("", "Dharmendar", "Mohinder"));
                storeManagerMap.put("lakshaydhulla62@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("parastelecom.stp@gmail.com", Arrays.asList("", "Rajat", "Adeel"));
                storeManagerMap.put("talwarmukesh298@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("sahilnarang0009@gmail.com", Arrays.asList("PramodSharma", "", "Mohinder"));
                storeManagerMap.put("supertelecomjind@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("saketnagpal@gmail.com", Arrays.asList("", "Rajit", "Mohinder"));
                storeManagerMap.put("DEEPAKGOYAL702.DG@GMAIL.COM", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("sambhav350@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("mayankarora98133@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("vijaymobilityandmoew@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("amitv70003@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("newagelucknow.123@gmail.com", Arrays.asList("", "Rajat", "Adeel"));
                storeManagerMap.put("Newagetechnologygomtinagar@gmail.com", Arrays.asList("", "Rajat", "Adeel"));
                storeManagerMap.put("rohitbatra106@gmail.com", Arrays.asList("PramodSharma", "Dharmendar", "Mohinder"));
                storeManagerMap.put("sonisunil9050873061@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("moderncohsr@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("raghubir.ngh@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("aman007singla@gmail.com", Arrays.asList("", "Rajit", "Mohinder"));

                storeManagerMap.put("suryaelectronicskaithal@gmail.com", Arrays.asList("Sohan", "Ankit", "Mohinder"));
                storeManagerMap.put("amitv70003@gmail.com", Arrays.asList("Sohan", "Ankit", "Mohinder"));
                storeManagerMap.put("uppal.neeraj82@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("DEEPAKGOYAL702.DG@GMAIL.COM", Arrays.asList("Sohan", "Ankit", "Mohinder"));
                storeManagerMap.put("supertelecomjind@gmail.com", Arrays.asList("Sohan", "Ankit", "Mohinder"));
                storeManagerMap.put("saranshary@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("sonisunil9050873061@gmail.com", Arrays.asList("Sohan", "Ankit", "Mohinder"));
                storeManagerMap.put("mayankarora98133@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("babitaranirk@gmail.com", Arrays.asList("", "Ankit", "Mohinder"));
                storeManagerMap.put("KK Enterprises", Arrays.asList("", "Dharmendar", "Mohinder"));
                storeManagerMap.put("kambojanil83@gmail.com", Arrays.asList("Ajay", "Dharmendar", "Mohinder"));
                storeManagerMap.put("robintelecom.snp@gmail.com", Arrays.asList("", "Dharmendar", "Mohinder"));
                storeManagerMap.put("gtc01100@gmail.com", Arrays.asList("Ajay", "Dharmendar", "Mohinder"));
                storeManagerMap.put("sahilnarang0009@gmail.com", Arrays.asList("Ajay", "Dharmendar", "Mohinder"));
                storeManagerMap.put("metrofurniture342@gmail.com", Arrays.asList("Ajay", "Dharmendar", "Mohinder"));
                storeManagerMap.put("omsonsindia08@gmail.com", Arrays.asList("Ajay", "Dharmendar", "Mohinder"));
                storeManagerMap.put("sachinindri2006@gmail.com", Arrays.asList("Ajay", "Dharmendar", "Mohinder"));
                storeManagerMap.put("smartdukaan.sonepat@gmail.com", Arrays.asList("", "Dharmendar", "Mohinder"));
                storeManagerMap.put("sambhav350@gmail.com", Arrays.asList("Ajay", "Dharmendar", "Mohinder"));
                storeManagerMap.put("talwarmukesh298@gmail.com", Arrays.asList("Ajay", "Dharmendar", "Mohinder"));
                storeManagerMap.put("bhimsain919@gmail.com", Arrays.asList("", "Dharmendar", "Mohinder"));
                storeManagerMap.put("rohitbatra106@gmail.com", Arrays.asList("Ajay", "Dharmendar", "Mohinder"));
                storeManagerMap.put("thefonehousekarnal@gmail.com", Arrays.asList("", "Dharmendar", "Mohinder"));
                storeManagerMap.put("mobileplanet7599@gmail.com", Arrays.asList("", "Dharmendar", "Mohinder"));
                storeManagerMap.put("raghubir.ngh@gmail.com", Arrays.asList("Ajay", "Rajit", "Mohinder"));
                storeManagerMap.put("saketnagpal@gmail.com", Arrays.asList("Ajay", "Rajit", "Mohinder"));
                storeManagerMap.put("dharmendery079@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("sumittyagi1975@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("deepak.lalwani1985@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("Priyankaenterprises9910@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("richa9910763006@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("lovelymobile183@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("ajaykumarkansal03@gmail.com", Arrays.asList("Manoj", "", "Adeel"));
                storeManagerMap.put("gupta.smartdukaan@gmail.com", Arrays.asList("", "", "Adeel"));
                storeManagerMap.put("smartenterprisespv@gmail.com", Arrays.asList("", "", "Adeel"));
                storeManagerMap.put("ysinghal34@gmail.com", Arrays.asList("", "", "Adeel"));
                storeManagerMap.put("dishatelecommars@gmail.com", Arrays.asList("", "", "Adeel"));
                storeManagerMap.put("gulshersaifi74226@gmail.com", Arrays.asList("", "", "Adeel"));
                storeManagerMap.put("mmtelecomsec16@gmail.com", Arrays.asList("", "", "Adeel"));
                storeManagerMap.put("cachaitnya@gmail.com", Arrays.asList("", "", "Adeel"));
                storeManagerMap.put("KHURANAMOBILE753@GMAIL.COM", Arrays.asList("Sohan", "Ankit", "Mohinder"));

        }

        public void grouping() throws Exception {
                for (FofoStore fofoStore : fofoStoreRepository.selectAll()) {
                        /*LOGGER.info("{}, {}", fofoStore.getId(),
                                        partnerTypeChangeService.getTypeOnDate(fofoStore.getId(), LocalDate.now().plusDays(1)));*/
                                UserWallet userWallet = userWalletRepository.selectByRetailerId(fofoStore.getId());
                                if(userWallet==null) continue;
                                System.out.printf("Store Code %s, Wallet amount %d, Sum amount %f%n", fofoStore.getCode(), userWallet.getAmount(), walletService.getWalletAmount(fofoStore.getId()));
                }
        }
}