Subversion Repositories SmartDukaan

Rev

Rev 35458 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.web.controller;

import com.spice.profitmandi.common.enumuration.MessageType;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.CustomRetailer;
import com.spice.profitmandi.common.model.SendNotificationModel;
import com.spice.profitmandi.common.util.Utils;
import com.spice.profitmandi.dao.entity.auth.AuthUser;
import com.spice.profitmandi.dao.entity.dtr.CreditAccount;
import com.spice.profitmandi.dao.entity.dtr.CreditStatus;
import com.spice.profitmandi.dao.entity.fofo.CurrentPartnerDailyInvestment;
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
import com.spice.profitmandi.dao.entity.fofo.PartnerDailyInvestment;
import com.spice.profitmandi.dao.entity.transaction.*;
import com.spice.profitmandi.dao.entity.user.Address;
import com.spice.profitmandi.dao.enumuration.fofo.Gateway;
import com.spice.profitmandi.dao.enumuration.transaction.LoanSummaryType;
import com.spice.profitmandi.dao.enumuration.transaction.SanctionStatus;
import com.spice.profitmandi.dao.model.*;
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
import com.spice.profitmandi.dao.repository.cs.CsService;
import com.spice.profitmandi.dao.repository.cs.CsService1;
import com.spice.profitmandi.dao.repository.dtr.CreditAccountRepository;
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
import com.spice.profitmandi.dao.repository.dtr.UserRepository;
import com.spice.profitmandi.dao.repository.fofo.CurrentPartnerDailyInvestmentRepository;
import com.spice.profitmandi.dao.repository.fofo.FofoOrderItemRepository;
import com.spice.profitmandi.dao.repository.fofo.PartnerDailyInvestmentRepository;
import com.spice.profitmandi.dao.repository.transaction.*;
import com.spice.profitmandi.dao.repository.user.AddressRepository;
import com.spice.profitmandi.service.NotificationService;
import com.spice.profitmandi.service.transaction.SDCreditService;
import com.spice.profitmandi.service.user.RetailerService;
import com.spice.profitmandi.service.user.UserService;
import com.spice.profitmandi.web.model.LoginDetails;
import com.spice.profitmandi.web.util.CookiesProcessor;
import com.spice.profitmandi.web.util.MVCResponseSender;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

@Controller
@Transactional(rollbackFor = Throwable.class)
public class SDCreditController {

    @Autowired
    private RetailerService retailerService;

    @Autowired
    private UserService userService;

    @Autowired
    SDCreditRequirementRepository sdCreditRequirementRepository;

    @Autowired
    SanctionRequestRepository sanctionRequestRepository;

    @Autowired
    PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;

    @Autowired
    private FofoStoreRepository fofoStoreRepository;

    @Autowired
    private CreditAccountRepository creditAccountRepository;

    @Autowired
    private SDCreditService sdCreditService;

    @Autowired
    private CsService1 csService1;

    @Autowired
    private NotificationService notificationService;

    @Autowired
    private AuthRepository authRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private CurrentPartnerDailyInvestmentRepository currentPartnerDailyInvestmentRepository;

    @Autowired
    private UserWalletRepository userWalletRepository;

    @Autowired
    LoanRepository loanRepository;

    @Autowired
    private CookiesProcessor cookiesProcessor;

    @Autowired
    private CsService csService;

    @Autowired
    AddressRepository addressRepository;

    @Autowired
    OrderRepository orderRepository;

    @Autowired
    private LoanStatementRepository loanStatementRepository;

    @Autowired
    private com.spice.profitmandi.dao.repository.user.UserRepository userUserRepository;

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private MVCResponseSender mvcResponseSender;

    @Autowired
    private FofoOrderItemRepository fofoOrderItemRepository;

    @Autowired
    private com.spice.profitmandi.service.transaction.CreditBlockedExceptionPartnersRepository creditBlockedExceptionPartnersRepository;

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

    @RequestMapping(value = "/getSDCreditReq", method = RequestMethod.GET)
    public String getSDCreditReq(HttpServletRequest request, Model model) throws ProfitMandiBusinessException {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isTarun = loginDetails.getEmailId().equals("tarun.verma@smartdukaan.com") || loginDetails.getEmailId().equals("kamini.sharma@smartdukaan.com");

        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(true);

        Map<Integer, SDCreditRequirement> sdCreditRequirementMap = sdCreditRequirementRepository.selectAll().stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
        for (Entry<Integer, CustomRetailer> customRetailerEntry : customRetailerMap.entrySet()) {
            int fofoId = customRetailerEntry.getKey();

            SDCreditRequirement sdCreditRequirement = sdCreditRequirementMap.get(customRetailerEntry.getKey());

            if (sdCreditRequirement != null) {

                BigDecimal utilizedLimit = sdCreditService.getUtilizationAmount(fofoId);

                BigDecimal availableLimit = sdCreditRequirement.getLimit().subtract(utilizedLimit);

                LOGGER.info("utilizedLimit {} ", utilizedLimit);

                LOGGER.info("availableLimit {} ", availableLimit);

                sdCreditRequirement.setUtilizedAmount(utilizedLimit);

                sdCreditRequirement.setUpdateTimestamp(LocalDateTime.now());
            }

        }

        model.addAttribute("customRetailerMap", customRetailerMap);
        model.addAttribute("sdCreditRequirementMap", sdCreditRequirementMap);
        model.addAttribute("isTarun", isTarun);
        return "sd-credit";
    }

    @RequestMapping(value = "/creditRequirement", method = RequestMethod.POST)
    public String sdCredit(HttpServletRequest request, @RequestBody SdCreditRequirementModel sdCreditRequirementModel, Model model) throws Exception {

        LOGGER.info("sdCreditRequirementModel {} ", sdCreditRequirementModel);

        int fofoId = sdCreditRequirementModel.getFofoId();

        SDCreditRequirement sdCreditRequirement = sdCreditRequirementRepository.selectByFofoId(sdCreditRequirementModel.getFofoId());

        // sdCreditRequirement.setSecurityCheck(2);
        sdCreditRequirement.setSecurityCheck(sdCreditRequirementModel.getSecurityCheck());


        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isTarun = loginDetails.getEmailId().equals("tarun.verma@smartdukaan.com") || loginDetails.getEmailId().equals("kamini.sharma@smartdukaan.com");
        sdCreditRequirement.setInterestRate(sdCreditRequirementModel.getInterest());
        sdCreditRequirement.setFreeDays(sdCreditRequirementModel.getFreeDays());
        BigDecimal utilizedLimit = sdCreditService.getUtilizationAmount(fofoId);
        BigDecimal availableLimit = sdCreditRequirement.getLimit().subtract(utilizedLimit);
        sdCreditRequirement.setUtilizedAmount(utilizedLimit);
        if (isTarun) {
            if (sdCreditRequirement.getLimit() != sdCreditRequirementModel.getLimit()) {
                sdCreditRequirement.setLimit(sdCreditRequirementModel.getLimit());
                sdCreditRequirement.setHardLimit(true);
                sdCreditService.updateMinInvestmentForHardLimit(sdCreditRequirement, true);
            }
        }

        sdCreditRequirement.setLimit(sdCreditRequirementModel.getLimit());
        sdCreditRequirement.setCreditDays(15);
        sdCreditRequirement.setUpdateTimestamp(LocalDateTime.now());

        if (sdCreditRequirement.getSecurityCheck() > 0) {

            CreditAccount creditAccount = creditAccountRepository.selectByFofoIdAndGateway(sdCreditRequirementModel.getFofoId(), Gateway.SDDIRECT);
            if (creditAccount == null) {
                creditAccount = new CreditAccount();
                creditAccount.setFofoId(sdCreditRequirementModel.getFofoId());
                creditAccount.setGateway(Gateway.SDDIRECT);
                creditAccount.setCreditStatus(CreditStatus.SANCTIONED);
                creditAccount.setActive(false);

                creditAccount.setUpdatedOn(LocalDateTime.now());

                creditAccountRepository.persist(creditAccount);
            }
            creditAccount.setInterestRate(sdCreditRequirement.getInterestRate().floatValue());
            creditAccount.setSanctionedAmount(sdCreditRequirement.getLimit().floatValue());
            creditAccount.setAvailableAmount(availableLimit.floatValue());
            creditAccount.setFreeDays(sdCreditRequirement.getFreeDays());
            creditAccount.setUpdatedOn(LocalDateTime.now());
        }
        LOGGER.info("sdCreditRequirement {} ", sdCreditRequirement);

        CustomRetailer customRetailer = retailerService.getFofoRetailer(sdCreditRequirementModel.getFofoId());

        sdCreditRequirement = sdCreditRequirementRepository.selectByFofoId(sdCreditRequirementModel.getFofoId());

        Map<Integer, SDCreditRequirement> sdCreditRequirementMap = new HashMap<>();
        sdCreditRequirementMap.put(sdCreditRequirement.getFofoId(), sdCreditRequirement);
        model.addAttribute("sdCreditRequirementMap", sdCreditRequirementMap);
        model.addAttribute("customRetailer", customRetailer);
        model.addAttribute("isTarun", isTarun);

        return "sd-credit-requirement-row";

    }

    @RequestMapping(value = "/resetHardLimit", method = RequestMethod.PUT)
    public String resetHardLimit(HttpServletRequest request, @RequestParam int id, Model model) throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        if (loginDetails.getEmailId().equals("tarun.verma@smartdukaan.com") || loginDetails.getEmailId().equals("kamini.sharma@smartdukaan.com")) {
            SDCreditRequirement sdCreditRequirement = sdCreditRequirementRepository.selectById(id);
            sdCreditRequirement.setHardLimit(false);
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(sdCreditRequirement.getFofoId());
            fofoStore.setMinimumInvestment(fofoStore.getMinimumInvestmentOld());
            sdCreditRequirement.setLimit(sdCreditRequirement.getSuggestedLimit());
        }
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
        return "response";
    }

    @RequestMapping(value = "/addCreditBlockedException", method = RequestMethod.POST)
    public String addCreditBlockedException(HttpServletRequest request, @RequestParam int fofoId, Model model) throws Exception {
        LOGGER.info("Adding credit blocked exception for fofoId: {} for today", fofoId);

        CreditBlockedExceptionPartner existingException = creditBlockedExceptionPartnersRepository.select(fofoId);
        if (existingException != null && existingException.getOnDate().equals(LocalDate.now())) {
            LOGGER.info("Exception already exists for fofoId: {} for today", fofoId);
            model.addAttribute("response1", mvcResponseSender.createResponseString(true));
            return "response";
        }

        CreditBlockedExceptionPartner exception = new CreditBlockedExceptionPartner();
        exception.setFofoId(fofoId);
        exception.setOnDate(LocalDate.now());
        creditBlockedExceptionPartnersRepository.persist(exception);

        LOGGER.info("Credit blocked exception added successfully for fofoId: {}", fofoId);
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
        return "response";
    }

    @RequestMapping(value = "/getSanctionRequest", method = RequestMethod.GET)
    public String getSanctionRequest(HttpServletRequest request, Model model) throws ProfitMandiBusinessException {

        List<SanctionRequest> sanctionRequests = sanctionRequestRepository.getL2ApprovedByDate(LocalDate.now(), SanctionStatus.APPROVED);


        if (!sanctionRequests.isEmpty()) {

            List<Integer> authIds = sanctionRequests.stream().map(x -> x.getAuthId()).collect(Collectors.toList());

            Map<Integer, String> authMap = authRepository.selectByIds(authIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getFullName()));


            List<Integer> fofoIds = sanctionRequests.stream().map(x -> x.getFofoId()).collect(Collectors.toList());

            Map<Integer, Long> partnerCreditDaysMap = new HashMap<>();

            Map<Integer, Integer> partnerActiveLoanMap = new HashMap<>();
            Map<Integer, Integer> partnerAverageCreditDaysMap = new HashMap<>();

            LocalDateTime curDate = LocalDate.now().atStartOfDay();

            /*Map<Integer, Double> lmtdSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
                    curDate.withDayOfMonth(1).minusMonths(1), curDate.with(LocalTime.MAX).minusMonths(1), 0, false);

            Map<Integer, Double> mtdSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX), 0, false);

            Map<Integer, Double> lmsSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
                    curDate.withDayOfMonth(1).minusMonths(1), curDate.withDayOfMonth(1), 0, false);*/

            Map<Integer, Double> secondaryMtd = orderRepository
                    .selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));
            Map<Integer, Double> secondaryLmtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(
                    curDate.withDayOfMonth(1).minusMonths(1), curDate.with(LocalTime.MAX).minusMonths(1));
            Map<Integer, Double> secondaryLms = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(
                    curDate.withDayOfMonth(1).minusMonths(1), curDate.withDayOfMonth(1));

            List<Loan> loans = loanRepository.selectAllLoans(fofoIds, DateRangeModel.withStartDate(curDate.minusYears(2)));
            Map<Integer, List<Loan>> partnerClosedLoansMap = loans.stream().filter(x -> x.getPendingAmount().compareTo(BigDecimal.ZERO) == 0)
                    .collect(Collectors.groupingBy(x -> x.getFofoId()));


            Map<Integer, List<Loan>> activeLoansMap = loans.stream().filter(x -> x.getPendingAmount().compareTo(BigDecimal.ZERO) == 1).collect(Collectors.groupingBy(x -> x.getFofoId()));

            for (Integer fofoId : fofoIds) {
                LOGGER.info("Fofo Id - {}", fofoId);
                List<Loan> activeLoans = activeLoansMap.get(fofoId);
                if (activeLoans != null) {
                    partnerActiveLoanMap.put(fofoId, activeLoans.size());
                    Loan loan = activeLoans.stream().sorted(Comparator.comparing(Loan::getCreatedOn)).findFirst().get();
                    long daysBetween = Duration.between(loan.getCreatedOn(), LocalDateTime.now()).toDays();
                    partnerCreditDaysMap.put(fofoId, daysBetween);
                }
                List<Loan> closedLoans = partnerClosedLoansMap.get(fofoId);
                if (closedLoans != null) {
                    long averageCreditDays = Math.round(closedLoans.stream().mapToLong(x -> Duration.between(x.getCreatedOn(),
                            x.getSettledOn() == null ? x.getCreatedOn().plusDays(10) : x.getSettledOn()).toDays() + 1).average().orElse(0.0));
                    partnerAverageCreditDaysMap.put(fofoId, (int) averageCreditDays);
                }

            }
            model.addAttribute("partnerActiveLoanMap", partnerActiveLoanMap);
            model.addAttribute("partnerCreditDaysMap", partnerCreditDaysMap);
            model.addAttribute("partnerAverageCreditDaysMap", partnerAverageCreditDaysMap);

            Map<Integer, SDCreditRequirement> sdCreditRequirementMap = sdCreditRequirementRepository.selectAll().stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));

            Map<Integer, UserWallet> userWalletMap = userWalletRepository.selectByRetailerIds(new HashSet<>(fofoIds)).stream().collect(Collectors.toMap(x -> x.getUserId(), x -> x));

            Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(fofoIds);
            Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = partnerDailyInvestmentRepository.selectAll(fofoIds, LocalDate.now().minusDays(1)).stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
            LOGGER.info("partnerDailyInvestmentMap {}", partnerDailyInvestmentMap);

            model.addAttribute("customRetailerMap", customRetailerMap);

            model.addAttribute("partnerDailyInvestmentMap", partnerDailyInvestmentMap);
            model.addAttribute("sdCreditRequirementMap", sdCreditRequirementMap);

            model.addAttribute("userWalletMap", userWalletMap);
            model.addAttribute("authMap", authMap);
            model.addAttribute("secondaryMtd", secondaryMtd);
            model.addAttribute("secondarylmtd", secondaryLmtd);
            model.addAttribute("secondarylms", secondaryLms);

            List<CreditAccount> creditAccounts = creditAccountRepository.selectByFofoIds(fofoIds);
            model.addAttribute("creditAccounts", creditAccounts.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x.getGateway())));
        }

        model.addAttribute("sanctionRequests", sanctionRequests);

        model.addAttribute("sanctionStatus", SanctionStatus.values());
        return "sanction-request";

    }


    @RequestMapping(value = "/getRbmL2SanctionRequest", method = RequestMethod.GET)
    public String getRbmL2SanctionRequest(HttpServletRequest request, Model model) throws ProfitMandiBusinessException {

        List<SanctionRequest> sanctionRequests = sanctionRequestRepository.selectByDate(LocalDate.now());


        if (!sanctionRequests.isEmpty()) {

            List<Integer> authIds = sanctionRequests.stream().map(x -> x.getAuthId()).collect(Collectors.toList());

            Map<Integer, String> authMap = authRepository.selectByIds(authIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getFullName()));


            List<Integer> fofoIds = sanctionRequests.stream().map(x -> x.getFofoId()).collect(Collectors.toList());

            Map<Integer, Long> partnerCreditDaysMap = new HashMap<>();

            Map<Integer, Integer> partnerActiveLoanMap = new HashMap<>();
            Map<Integer, Integer> partnerAverageCreditDaysMap = new HashMap<>();

            LocalDateTime curDate = LocalDate.now().atStartOfDay();

            Map<Integer, Double> secondaryMtd = orderRepository
                    .selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));
            Map<Integer, Double> secondaryLmtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(
                    curDate.withDayOfMonth(1).minusMonths(1), curDate.with(LocalTime.MAX).minusMonths(1));
            Map<Integer, Double> secondaryLms = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(
                    curDate.withDayOfMonth(1).minusMonths(1), curDate.withDayOfMonth(1));

            List<Loan> loans = loanRepository.selectAllLoans(fofoIds, DateRangeModel.withStartDate(curDate.minusYears(2)));
            Map<Integer, List<Loan>> partnerClosedLoansMap = loans.stream().filter(x -> x.getPendingAmount().compareTo(BigDecimal.ZERO) == 0)
                    .collect(Collectors.groupingBy(x -> x.getFofoId()));


            Map<Integer, List<Loan>> activeLoansMap = loans.stream().filter(x -> x.getPendingAmount().compareTo(BigDecimal.ZERO) == 1).collect(Collectors.groupingBy(x -> x.getFofoId()));

            for (Integer fofoId : fofoIds) {
                LOGGER.info("Fofo Id - {}", fofoId);
                List<Loan> activeLoans = activeLoansMap.get(fofoId);
                if (activeLoans != null) {
                    partnerActiveLoanMap.put(fofoId, activeLoans.size());
                    Loan loan = activeLoans.stream().sorted(Comparator.comparing(Loan::getCreatedOn)).findFirst().get();
                    long daysBetween = Duration.between(loan.getCreatedOn(), LocalDateTime.now()).toDays();
                    partnerCreditDaysMap.put(fofoId, daysBetween);
                }
                List<Loan> closedLoans = partnerClosedLoansMap.get(fofoId);
                if (closedLoans != null) {
                    long averageCreditDays = Math.round(closedLoans.stream().mapToLong(x -> Duration.between(x.getCreatedOn(),
                            x.getSettledOn() == null ? x.getCreatedOn().plusDays(10) : x.getSettledOn()).toDays() + 1).average().orElse(0.0));
                    partnerAverageCreditDaysMap.put(fofoId, (int) averageCreditDays);
                }

            }
            model.addAttribute("partnerActiveLoanMap", partnerActiveLoanMap);
            model.addAttribute("partnerCreditDaysMap", partnerCreditDaysMap);
            model.addAttribute("partnerAverageCreditDaysMap", partnerAverageCreditDaysMap);

            Map<Integer, SDCreditRequirement> sdCreditRequirementMap = sdCreditRequirementRepository.selectAll().stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));

            Map<Integer, UserWallet> userWalletMap = userWalletRepository.selectByRetailerIds(new HashSet<>(fofoIds)).stream().collect(Collectors.toMap(x -> x.getUserId(), x -> x));

            Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(fofoIds);
            Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = partnerDailyInvestmentRepository.selectAll(fofoIds, LocalDate.now().minusDays(1)).stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));

            model.addAttribute("customRetailerMap", customRetailerMap);

            model.addAttribute("partnerDailyInvestmentMap", partnerDailyInvestmentMap);
            model.addAttribute("sdCreditRequirementMap", sdCreditRequirementMap);

            model.addAttribute("userWalletMap", userWalletMap);
            model.addAttribute("authMap", authMap);
            model.addAttribute("secondaryMtd", secondaryMtd);
            model.addAttribute("secondarylmtd", secondaryLmtd);
            model.addAttribute("secondarylms", secondaryLms);

            List<CreditAccount> creditAccounts = creditAccountRepository.selectByFofoIds(fofoIds);
            model.addAttribute("creditAccounts", creditAccounts.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x.getGateway())));
        }

        model.addAttribute("sanctionRequests", sanctionRequests);

        model.addAttribute("sanctionStatus", SanctionStatus.values());
        return "sanction-request-l2";

    }

    @RequestMapping(value = "/sanctionRequest", method = RequestMethod.POST)
    public String sanctionRequest(HttpServletRequest request, @RequestBody SanctionRequestModel sanctionRequestModel, Model model) throws Exception {

        LOGGER.info("sanctionRequestModel {} ", sanctionRequestModel);
        Map<Integer, SDCreditRequirement> sdCreditRequirementMap = sdCreditRequirementRepository.selectAll().stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));

        SanctionRequest sanctionRequest = sanctionRequestRepository.selectById(sanctionRequestModel.getId());

        Map<Integer, String> authMap = new HashMap<>();
        AuthUser authUser = authRepository.selectById(sanctionRequest.getAuthId());

        authMap.put(authUser.getId(), authUser.getFullName());

        model.addAttribute("authMap", authMap);
        List<Integer> fofoIds = sanctionRequestRepository.selectByDate(LocalDate.now()).stream().map(x -> x.getFofoId()).collect(Collectors.toList());

        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(fofoIds);

        LOGGER.info("freeDays {} ", sdCreditRequirementMap.get(sanctionRequest.getFofoId()).getFreeDays());

        if (sanctionRequestModel.getStatus().equals(SanctionStatus.APPROVED)) {
            CustomRetailer customRetailer = customRetailerMap.get(sanctionRequest.getFofoId());
            sanctionRequest.setApprovalTimestamp(LocalDateTime.now());
            BigDecimal availableAmount = sdCreditService.getAvailableAmount(sanctionRequest.getFofoId());

            String title = "Sanction Request Approved";
            String url = "http://app.smartdukaan.com/pages/home/credit";
            String message = "Congratulations! Your credit limit is increased for today Rs." + sanctionRequest.getApprovalAmount().setScale(2, RoundingMode.HALF_UP) + ". Your total available limit is Rs." + availableAmount.setScale(2, RoundingMode.HALF_UP) + ".";
            notificationService.sendNotification(sanctionRequest.getFofoId(), title, MessageType.notification, title, message, url);
            com.spice.profitmandi.dao.entity.user.User user = userUserRepository.selectById(sanctionRequest.getFofoId());

            Address address = addressRepository.selectById(user.getAddressId());
            //TODO-Whatsapp
            //notificationService.sendWhatsappMessage(message, title, address.getPhoneNumber());

            String empMessage = "Congratulations! Your Partner " + customRetailer.getBusinessName() + " credit limit is increased for today by Rs." + sanctionRequest.getApprovalAmount().setScale(2, RoundingMode.HALF_UP) + " and now the new total available limit is Rs." + availableAmount.setScale(2, RoundingMode.HALF_UP) + ".";
            SendNotificationModel sendNotificationModel = new SendNotificationModel();
            sendNotificationModel.setCampaignName("Sanction Request");
            sendNotificationModel.setTitle("title");
            sendNotificationModel.setMessage(empMessage);
            sendNotificationModel.setType("url");
            sendNotificationModel.setUrl("https://app.smartdukaan.com/pages/home/credit");
            sendNotificationModel.setExpiresat(LocalDateTime.now().plusDays(2));
            sendNotificationModel.setMessageType(MessageType.notification);
            sendNotificationModel.setUserIds(Arrays.asList(userRepository.selectByEmailId(authUser.getEmailId()).getId()));
            System.out.println(sendNotificationModel);
            notificationService.sendNotification(sendNotificationModel);

            //notificationService.sendWhatsappMessage(empMessage, title, authUser.getMobileNumber());

        }

        sanctionRequest.setFreeDays(sanctionRequestModel.getFreeDays());

        sanctionRequest.setApprovalAmount(sanctionRequestModel.getApprovalAmount());
        if (sanctionRequestModel.getApprovalAmount() == null) {
            sanctionRequest.setStatus(SanctionStatus.REJECTED);
            sanctionRequest.setRbmL2ApprovalStatus(SanctionStatus.REJECTED);
        } else {
            sanctionRequest.setStatus(sanctionRequestModel.getStatus());
        }

        sanctionRequest.setStockHold(sanctionRequestModel.isStockHold());

        LocalDateTime curDate = LocalDate.now().atStartOfDay();

        /*Map<Integer, Double> lmtdSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
                curDate.withDayOfMonth(1).minusMonths(1), curDate.with(LocalTime.MAX).minusMonths(1), sanctionRequest.getFofoId(), false);

        Map<Integer, Double> mtdSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX), sanctionRequest.getFofoId(), false);

        Map<Integer, Double> lmsSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
                curDate.withDayOfMonth(1).minusMonths(1), curDate.withDayOfMonth(1), sanctionRequest.getFofoId(), false);*/

        Map<Integer, Double> secondaryMtd = orderRepository
                .selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));
        Map<Integer, Double> secondarylmtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(
                curDate.withDayOfMonth(1).minusMonths(1), curDate.with(LocalTime.MAX).minusMonths(1));
        Map<Integer, Double> secondarylms = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(
                curDate.withDayOfMonth(1).minusMonths(1), curDate.withDayOfMonth(1));

        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = partnerDailyInvestmentRepository.selectAll(fofoIds, LocalDate.now().minusDays(1)).stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));

        Map<Integer, UserWallet> userWalletMap = userWalletRepository.selectByRetailerIds(new HashSet<>(fofoIds)).stream().collect(Collectors.toMap(x -> x.getUserId(), x -> x));

        sanctionRequest = sanctionRequestRepository.selectById(sanctionRequestModel.getId());
        model.addAttribute("customRetailerMap", customRetailerMap);
        model.addAttribute("sanctionRequest", sanctionRequest);
        model.addAttribute("partnerDailyInvestmentMap", partnerDailyInvestmentMap);
        model.addAttribute("sdCreditRequirementMap", sdCreditRequirementMap);
        model.addAttribute("userWalletMap", userWalletMap);

        model.addAttribute("sanctionStatus", SanctionStatus.values());

        model.addAttribute("secondarylmtd", secondarylmtd);
        model.addAttribute("secondaryMtd", secondaryMtd);
        model.addAttribute("secondarylms", secondarylms);

        List<CreditAccount> creditAccounts = creditAccountRepository.selectByFofoIds(Arrays.asList(sanctionRequest.getFofoId()));
        model.addAttribute("creditAccounts", creditAccounts.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x.getGateway())));
        return "sanction-request-row";

    }

    @RequestMapping(value = "/rbmL2ApprovalSanctionRequest", method = RequestMethod.POST)
    public String rbmL2ApprovalSanctionRequest(HttpServletRequest request, @RequestBody SanctionRequestModel sanctionRequestModel, Model model) throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        AuthUser approverAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
        LOGGER.info("sanctionRequestModel {} ", sanctionRequestModel);
        Map<Integer, SDCreditRequirement> sdCreditRequirementMap = sdCreditRequirementRepository.selectAll().stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));

        SanctionRequest sanctionRequest = sanctionRequestRepository.selectById(sanctionRequestModel.getId());

        Map<Integer, String> authMap = new HashMap<>();

        AuthUser authUser = authRepository.selectById(sanctionRequest.getAuthId());

        authMap.put(authUser.getId(), authUser.getFullName());

        model.addAttribute("authMap", authMap);
        List<Integer> fofoIds = sanctionRequestRepository.selectByDate(LocalDate.now()).stream().map(x -> x.getFofoId()).collect(Collectors.toList());

        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(fofoIds);

        LOGGER.info("freeDays {} ", sdCreditRequirementMap.get(sanctionRequest.getFofoId()).getFreeDays());

        if (sanctionRequestModel.getStatus().equals(SanctionStatus.APPROVED)) {
            sanctionRequest.setRbmL2ApprovalTimestamp(LocalDateTime.now());
            sanctionRequest.setRbmL2ApproverEmail(approverAuthUser.getEmailId());
        }

        sanctionRequest.setFreeDays(sanctionRequestModel.getFreeDays());

        sanctionRequest.setApprovalAmount(sanctionRequestModel.getApprovalAmount());
        if (sanctionRequestModel.getApprovalAmount() == null) {

            sanctionRequest.setStatus(SanctionStatus.REJECTED);

            sanctionRequest.setRbmL2ApprovalStatus(SanctionStatus.REJECTED);
            sanctionRequest.setRbmL2ApprovalTimestamp(LocalDateTime.now());
            sanctionRequest.setRbmL2ApproverEmail(approverAuthUser.getEmailId());
        } else {
            sanctionRequest.setRbmL2ApprovalStatus(sanctionRequestModel.getStatus());
        }

        sanctionRequest.setStockHold(sanctionRequestModel.isStockHold());

        LocalDateTime curDate = LocalDate.now().atStartOfDay();


        Map<Integer, Double> secondaryMtd = orderRepository
                .selectBillingDatesBetweenSumGroupByRetailerId(curDate.withDayOfMonth(1), curDate.with(LocalTime.MAX));
        Map<Integer, Double> secondarylmtd = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(
                curDate.withDayOfMonth(1).minusMonths(1), curDate.with(LocalTime.MAX).minusMonths(1));
        Map<Integer, Double> secondarylms = orderRepository.selectBillingDatesBetweenSumGroupByRetailerId(
                curDate.withDayOfMonth(1).minusMonths(1), curDate.withDayOfMonth(1));

        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = partnerDailyInvestmentRepository.selectAll(fofoIds, LocalDate.now().minusDays(1)).stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));

        Map<Integer, UserWallet> userWalletMap = userWalletRepository.selectByRetailerIds(new HashSet<>(fofoIds)).stream().collect(Collectors.toMap(x -> x.getUserId(), x -> x));

        sanctionRequest = sanctionRequestRepository.selectById(sanctionRequestModel.getId());
        model.addAttribute("customRetailerMap", customRetailerMap);
        model.addAttribute("sanctionRequest", sanctionRequest);
        model.addAttribute("partnerDailyInvestmentMap", partnerDailyInvestmentMap);
        model.addAttribute("sdCreditRequirementMap", sdCreditRequirementMap);
        model.addAttribute("userWalletMap", userWalletMap);

        model.addAttribute("sanctionStatus", SanctionStatus.values());

        model.addAttribute("secondarylmtd", secondarylmtd);
        model.addAttribute("secondaryMtd", secondaryMtd);
        model.addAttribute("secondarylms", secondarylms);

        List<CreditAccount> creditAccounts = creditAccountRepository.selectByFofoIds(Arrays.asList(sanctionRequest.getFofoId()));
        model.addAttribute("creditAccounts", creditAccounts.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x.getGateway())));
        return "rbm-l2-pending-sanction-request";

    }

    List<String> emails = Arrays.asList("kamini.sharma@smartdukaan.com", "neeraj.gupta@smartdukaan.com", "amit.gupta@smartdukaan.com");

    @RequestMapping(value = "/getLoans", method = RequestMethod.GET)
    public String getLoans(HttpServletRequest request, Model model) throws ProfitMandiBusinessException {

        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        String email = loginDetails.getEmailId();

        AuthUser authUser = authRepository.selectByEmailOrMobile(email);
        Set<Integer> fofoIds = csService1.getAuthFofoIds(email, false);

        LOGGER.info("fofoIds" + fofoIds);
        if (fofoIds == null) {
            throw new ProfitMandiBusinessException("you are not authorized", "", "you are not authorized" + " " + "");
        }

        List<LoanCountByFofoIdModel> loanCountByFofoIdModels = loanRepository.getAllLoanCountByFofoId(fofoIds);
        Map<Integer, Long> loanCountMap = loanCountByFofoIdModels.stream().collect(Collectors.toMap(LoanCountByFofoIdModel::getFofoId, LoanCountByFofoIdModel::getLoanCount));

//        List<Loan> loans = loanRepository.selectAllLoans(new ArrayList<>(fofoIds));

        List<Integer> loanFofoIds = loanCountByFofoIdModels.stream().map(x -> x.getFofoId()).collect(Collectors.toList());

        List<SDCreditRequirement> sdCreditRequirements = sdCreditRequirementRepository.selectByFofoIds(new ArrayList<>(loanFofoIds));

//        Map<Integer, Long> loanCountMap = loans.stream().collect(Collectors.groupingBy(x -> x.getFofoId(), Collectors.counting()));
//        LOGGER.info("loanCountMap" + loanCountMap);

        Map<Integer, UserWallet> userWalletMap = userWalletRepository.selectByRetailerIds(fofoIds).stream().collect(Collectors.toMap(x -> x.getUserId(), x -> x));
        Map<Integer, CurrentPartnerDailyInvestment> currentPartnerDailyInvestmentMap = currentPartnerDailyInvestmentRepository.selectAll().stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));

        model.addAttribute("userWalletMap", userWalletMap);

        model.addAttribute("currentPartnerDailyInvestmentMap", currentPartnerDailyInvestmentMap);

        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(new ArrayList<>(fofoIds));
        model.addAttribute("sdCreditRequirements", sdCreditRequirements);
        model.addAttribute("loanCountMap", loanCountMap);
        model.addAttribute("customRetailerMap", customRetailerMap);
        return "loan-summary";

    }

    @RequestMapping(value = "/getPartnerWiseLoanSummary", method = RequestMethod.GET)
    public String getPartnerWiseLoanSummary(HttpServletRequest request, @RequestParam LoanSummaryType loanSummaryType, Model model) throws ProfitMandiBusinessException {
        Map<Integer, FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();
        List<Loan> loans = loanRepository.selectAllActiveLoan();
        if (loanSummaryType.equals(LoanSummaryType.DEFAULT_LOAN)) {
            loans = loans.stream().filter(x -> x.isDefault()).collect(Collectors.toList());
        } else if (loanSummaryType.equals(LoanSummaryType.DUE_LOAN)) {
            loans = loans.stream().filter(x -> x.isOverdue()).collect(Collectors.toList());
        }
        List<Integer> fofoIds = loans.stream().map(x -> x.getFofoId()).collect(Collectors.toList());
        Map<Integer, Double> fofoIdLoansMap = loans.stream().collect(Collectors.groupingBy(x -> x.getFofoId(), Collectors.summingDouble(x -> x.getPendingAmount().doubleValue())));
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(fofoIds);
        Map<Integer, Long> loanCountMap = loans.stream().collect(Collectors.groupingBy(x -> x.getFofoId(), Collectors.counting()));
        model.addAttribute("customRetailerMap", customRetailerMap);
        model.addAttribute("loans", loans);
        model.addAttribute("fofoReportingModelMap", fofoReportingModelMap);
        model.addAttribute("fofoIdLoansMap", fofoIdLoansMap);
        model.addAttribute("loanCountMap", loanCountMap);
        return "partner-wise-loan-summary";
    }

    @RequestMapping(value = "/getPartnerStateWiseLoanSummary", method = RequestMethod.GET)
    public String getPartnerStateWiseLoanSummary(HttpServletRequest request, @RequestParam LoanSummaryType loanSummaryType, @RequestParam String stateName, @RequestParam(required = false) Integer fromDays, @RequestParam(required = false) Integer toDays, Model model) throws ProfitMandiBusinessException {
        Map<Integer, FofoReportingModel> fofoReportingModelMap = csService.getPartnerIdSalesHeaders();
        List<Loan> loans = loanRepository.selectAllStateWiseActiveLoan(stateName);
        if (loanSummaryType.equals(LoanSummaryType.DEFAULT_LOAN)) {
            loans = loans.stream().filter(x -> x.isDefault()).collect(Collectors.toList());
        } else if (loanSummaryType.equals(LoanSummaryType.DUE_LOAN)) {
            loans = loans.stream().filter(x -> x.isOverdue()).collect(Collectors.toList());
        }

        // Apply aging filter
        if (fromDays != null && toDays != null) {
            loans = loans.stream()
                    .filter(x -> x.getLoanAgeInDays() >= fromDays &&
                            x.getLoanAgeInDays() <= toDays)
                    .collect(Collectors.toList());

        } else if (fromDays != null) {
            loans = loans.stream()
                    .filter(x -> x.getLoanAgeInDays() >= fromDays)
                    .collect(Collectors.toList());

        }

        List<Integer> fofoIds = loans.stream().map(x -> x.getFofoId()).collect(Collectors.toList());
        Map<Integer, Double> fofoIdLoansMap = loans.stream().collect(Collectors.groupingBy(x -> x.getFofoId(), Collectors.summingDouble(x -> x.getPendingAmount().doubleValue())));
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getFofoRetailers(fofoIds);
        Map<Integer, Long> loanCountMap = loans.stream().collect(Collectors.groupingBy(x -> x.getFofoId(), Collectors.counting()));
        model.addAttribute("customRetailerMap", customRetailerMap);
        model.addAttribute("loans", loans);
        model.addAttribute("fofoReportingModelMap", fofoReportingModelMap);
        model.addAttribute("fofoIdLoansMap", fofoIdLoansMap);
        model.addAttribute("loanCountMap", loanCountMap);
        return "partner-wise-loan-summary";
    }

    @RequestMapping(value = "/getLoanSummary", method = RequestMethod.GET)
    public String getLoanSummary(HttpServletRequest request, @RequestParam int fofoId, Model model) throws ProfitMandiBusinessException {

        SDCreditResponseOut sdCreditResponseOut = sdCreditService.sdDirectService(fofoId);
        CustomRetailer customRetailer = retailerService.getFofoRetailer(fofoId);

        model.addAttribute("customRetailer", customRetailer);
        model.addAttribute("loanSummary", sdCreditResponseOut.getLoans());

        return "loan-summary-detail";

    }

    @RequestMapping(value = "/getSanctionUnholdOrder", method = RequestMethod.GET)
    public String getSanctionUnholdOrder(HttpServletRequest request, Model model) throws ProfitMandiBusinessException {

        List<Order> allOrders = orderRepository.selectHoldOrder();

        List<SanctionRequest> sanctionRequests = sanctionRequestRepository.selectHoldSanction();


        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
        if (!allOrders.isEmpty()) {
            Map<Integer, Double> transactionAmountMap = allOrders.stream().collect(
                    Collectors.groupingBy(Order::getTransactionId, Collectors.summingDouble(x -> x.getTotalAmount())));

            Map<Integer, List<Order>> transactionOrdersMap = allOrders.stream().collect(Collectors.groupingBy(Order::getTransactionId, Collectors.toList()));


            model.addAttribute("transactionAmountMap", transactionAmountMap);

            model.addAttribute("transactionOrdersMap", transactionOrdersMap);

        }
        model.addAttribute("sanctionRequests", sanctionRequests);

        model.addAttribute("customRetailerMap", customRetailerMap);


        return "sanction-order-unhold";

    }


    @RequestMapping(value = "/getSanctionHoldOrder", method = RequestMethod.GET)
    public String getSanctionHoldOrder(HttpServletRequest request, Model model) throws ProfitMandiBusinessException {

        List<Order> allOrders = orderRepository.selectHoldOrder();

        List<SanctionRequest> sanctionRequests = sanctionRequestRepository.selectHoldSanction();
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();

        if (!allOrders.isEmpty()) {
            Map<Integer, Double> transactionAmountMap = allOrders.stream().collect(
                    Collectors.groupingBy(Order::getTransactionId, Collectors.summingDouble(x -> x.getTotalAmount())));

            Map<Integer, List<Order>> transactionOrdersMap = allOrders.stream().collect(Collectors.groupingBy(Order::getTransactionId, Collectors.toList()));


            model.addAttribute("transactionAmountMap", transactionAmountMap);

            model.addAttribute("transactionOrdersMap", transactionOrdersMap);

        }
        model.addAttribute("sanctionRequests", sanctionRequests);
        model.addAttribute("customRetailerMap", customRetailerMap);


        return "sanction-order-hold";

    }

    @RequestMapping(value = "/unholdOrder", method = RequestMethod.POST)
    public String unholdOrder(HttpServletRequest request, @RequestParam int transactionId, Model model) throws Exception {

        List<Order> orders = orderRepository.selectAllByTransactionId(transactionId);

        SanctionRequest sanctionRequest = sanctionRequestRepository.selectByTransactionId(transactionId);


        LOGGER.info("orders" + orders);

        if (sanctionRequest != null) {
            sanctionRequest.setPendingAmount(BigDecimal.ZERO);
        }

        if (!orders.isEmpty()) {
            orders.forEach(x -> x.setShipmentHold(false));
        }

        double totalAmount = orders.stream().collect(Collectors.summingDouble(x -> x.getTotalAmount()));

        try {

            List<String> authUserEmail = csService.getAuthUserIdByPartnerId(orders.get(0).getRetailerId()).stream().map(x -> x.getEmailId()).collect(Collectors.toList());

            authUserEmail.add("vinay.p@smartdukaan.com");
            authUserEmail.add("shivam.gupta@smartdukaan.com");

            String[] emailTo = authUserEmail.toArray(new String[authUserEmail.size()]);

            String[] ccTo = {"tarun.verma@smartdukaan.com", "kamini.sharma@smartdukaan.com"};

            String subject = "Dispatched " + (orders.get(0).getRetailerName());
            String message = String.format("Dear Team, \n" + "Kindly note the meterial for the " + orders.get(0).getRetailerName() + "of Rs." + totalAmount + " is dispatched.");

            LOGGER.info("message" + message);

            Utils.sendMailWithAttachments(mailSender, emailTo, ccTo, subject, message);
        } catch (Exception e) {

            e.printStackTrace();

        }

        model.addAttribute("response1", mvcResponseSender.createResponseString(true));

        return "response";

    }


//    adjusting loan for specific loan if loan is not adjusting and other loan is adjusting

    @RequestMapping(value = "/settle-loan/{fofoId}/{loanId}", method = RequestMethod.GET)
    public String settleAndCreateLoanById(HttpServletRequest request, @PathVariable int loanId, @PathVariable int fofoId, Model model) throws Exception {
        Loan loan = loanRepository.selectByLoanId(loanId);
        double loanAmount = loan.getPendingAmount().doubleValue();

        if (loanAmount > 0) {
            sdCreditService.createLoan(fofoId, loanAmount, 0, "Amount added for loan adjustment");
            sdCreditService.settleLoan(loan);
        }


        model.addAttribute("response1", mvcResponseSender.createResponseString(true));

        return "response";

    }

    @RequestMapping(value = "/settle-negative-wallet/{fofoId}", method = RequestMethod.GET)
    public String settleNegativeWalletCreateLoanById(HttpServletRequest request, @PathVariable int fofoId, Model model) throws Exception {
        this.sdCreditService.fundWallet(fofoId);

        model.addAttribute("response1", mvcResponseSender.createResponseString(true));

        return "response";

    }

    private void sendUnholdEmail(List<Order> orders) throws Exception {


        orders.forEach(x -> x.setShipmentHold(false));
        orders = orders.stream().filter(x -> x.getRefundTimestamp() != null).collect(Collectors.toList());
        if (orders.size() > 0) {

            double totalAmount = orders.stream().collect(Collectors.summingDouble(x -> x.getTotalAmount()));

            List<String> authUserEmail = csService.getAuthUserIdByPartnerId(orders.get(0).getRetailerId()).stream().map(x -> x.getEmailId()).collect(Collectors.toList());
            authUserEmail.add("vinay.p@smartdukaan.com");
            authUserEmail.add("shivam.gupta@smartdukaan.com");

            String[] emailTo = authUserEmail.toArray(new String[authUserEmail.size()]);

            String[] ccTo = {"tarun.verma@smartdukaan.com", "kamini.sharma@smartdukaan.com"};

            String subject = "Dispatch held orders of - " + (orders.get(0).getRetailerName());
            String message = String.format("Dear Team, \n" + "kindly note the material for the " + orders.get(0).getRetailerName() + "of Rs." + totalAmount + "is unhold now and needs to be dispatched.");
            Utils.sendMailWithAttachments(mailSender, emailTo, ccTo, subject, message);
        }


    }

}