Subversion Repositories SmartDukaan

Rev

Rev 34713 | 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.ReporticoProject;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.CustomRetailer;
import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.common.model.ReporticoUrlInfo;
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.dao.entity.auth.AuthUser;
import com.spice.profitmandi.dao.entity.cs.Position;
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
import com.spice.profitmandi.dao.entity.fofo.PendingOrderItem;
import com.spice.profitmandi.dao.entity.transaction.CreditNote;
import com.spice.profitmandi.dao.entity.transaction.UserWallet;
import com.spice.profitmandi.dao.entity.transaction.UserWalletHistory;
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.PositionRepository;
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
import com.spice.profitmandi.dao.repository.dtr.RoleRepository;
import com.spice.profitmandi.dao.repository.fofo.*;
import com.spice.profitmandi.dao.repository.transaction.*;
import com.spice.profitmandi.service.authentication.RoleManager;
import com.spice.profitmandi.service.order.OrderService;
import com.spice.profitmandi.service.transaction.CreditNoteService;
import com.spice.profitmandi.service.transaction.InventoryMarginModel;
import com.spice.profitmandi.service.transaction.TransactionService;
import com.spice.profitmandi.service.user.RetailerService;
import com.spice.profitmandi.service.wallet.WalletService;
import com.spice.profitmandi.web.model.LoginDetails;
import com.spice.profitmandi.web.util.CookiesProcessor;
import in.shop2020.model.v1.order.WalletReferenceType;
import org.apache.http.HttpResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Controller
@Transactional(rollbackFor = Throwable.class)
public class ReportsController {
    private static final Logger LOGGER = LogManager.getLogger(OrderController.class);
    private static final Logger Logger = LogManager.getLogger(OrderController.class);
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private FofoOrderRepository fofoOrderRepository;
    @Autowired
    private RetailerService retailerService;
    @Autowired
    private PendingOrderItemRepository pendingOrderItemRepository;
    @Autowired
    private PendingOrderService pendingOrderService;
    @Autowired
    private CookiesProcessor cookiesProcessor;
    @Autowired
    private FofoStoreRepository fofoStoreRepository;
    @Autowired
    private ReporticoService reporticoService;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private RoleManager roleManager;
    @Autowired
    private OrderService orderService;
    @Autowired
    private CsService csService;
    @Autowired
    private AuthRepository authRepository;
    @Autowired
    private WalletService walletService;
    @Autowired
    private UserWalletHistoryRepository userWalletHistoryRepository;
    @Autowired
    private TransactionService transactionService;
    @Autowired
    private LoanStatementRepository loanStatementRepository;
    @Autowired
    PositionRepository positionRepository;

    @Autowired
    CreditNoteRepository creditNoteRepository;

    @Autowired
    CreditNoteService creditNoteService;

    @Autowired
    PriceDropIMEIRepository priceDropIMEIRepository;

    @Autowired
    SchemeInOutRepository schemeInOutRepository;

    @Autowired
    OfferPayoutRepository offerPayoutRepository;

    @Autowired
    UserWalletRepository userWalletRepository;
    @PostMapping(value = "/reports/{projectName}/{fileName}")
    public ResponseEntity<?> fetchReport(HttpServletRequest request, @PathVariable String fileName,
                                         @PathVariable ReporticoProject projectName, @RequestBody Map<String, String> paramsMap)
            throws ProfitMandiBusinessException, UnsupportedOperationException, IOException {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        HttpResponse response;
        if (roleManager.isAdmin(loginDetails.getRoleIds())) {

            if (fileName.equalsIgnoreCase("LeadsReport")) {
                if (paramsMap == null) {
                    paramsMap = new HashMap<String, String>();
                }
                Map<Integer, List<Integer>> mapping = csService.getL2L1Mapping();

                AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());

                List<Integer> authIds = mapping.get(authUser.getId());
                if (authIds == null) {
                    authIds = new ArrayList<>();
                }
                authIds.add(authUser.getId());

                paramsMap.put("authId", authIds + "");
            }
        } else {
            if (paramsMap == null) {
                paramsMap = new HashMap<String, String>();
            }

            paramsMap.put("MANUAL_fofoId", loginDetails.getFofoId() + "");

        }
        response = getAdminReportFile(loginDetails.getEmailId(), projectName, fileName + ".xml", paramsMap);
        HttpHeaders headers = new HttpHeaders();
        InputStreamResource is = new InputStreamResource(response.getEntity().getContent());
        headers.set("Content-Type", "application/vnd.ms-excel");
        headers.set("Content-disposition", "inline; filename=report-" + fileName + ".csv");
        headers.setContentLength(response.getEntity().getContentLength());
        return new ResponseEntity<InputStreamResource>(is, headers, HttpStatus.OK);
    }

    private HttpResponse getAdminReportFile(String email, ReporticoProject projectName, String fileName,
                                            Map<String, String> reportParams) throws ProfitMandiBusinessException, IOException {
        return reporticoService.getReportFile(projectName, fileName, reportParams);
    }

    @RequestMapping(value = "/collectionSummary", method = RequestMethod.GET)
    public String getCollectionSummary(HttpServletRequest request,
                                       Model model) throws ProfitMandiBusinessException {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        LocalDateTime currentDate = LocalDate.now().atStartOfDay();
        LocalDateTime currentStartMonth = currentDate.minusDays(30).toLocalDate().atStartOfDay();
        List<CollectionSummary> collectionSummaryList = orderRepository.selectCollectionSummary(fofoDetails.getFofoId(), currentStartMonth, currentDate);
        Logger.info("CollectionSummaryList {}", collectionSummaryList);
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(fofoDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        model.addAttribute("startDate", currentDate.minusDays(30).toLocalDate());
        model.addAttribute("endDate", LocalDate.now());
        model.addAttribute("collectionSummaryList", collectionSummaryList);
        model.addAttribute("isAdmin", isAdmin);
        return "partner-collection-summary";
    }

    @RequestMapping(value = "/collectionSummaryFetchReportByDate", method = RequestMethod.GET)
    public String getcollectionSummaryFetchReport(HttpServletRequest request,
                                                  @RequestParam(defaultValue = "0") int fofoId,
                                                  @RequestParam(name = "startDate", required = true, defaultValue = "") LocalDate startDate,
                                                  @RequestParam(name = "endDate", required = true, defaultValue = "") LocalDate endDate, Model model)
            throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        if (isAdmin) {
            startDate = LocalDate.now().minusDays(30);
            endDate = LocalDate.now();
        }
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(fofoDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("isAdmin", isAdmin);


        if (isAdmin) {
            if (fofoId == 0) {
                //No need to send any data
                model.addAttribute("collectionSummaryList", new ArrayList<>());
                return "partner-collection-summary";
            } else {
                List<CollectionSummary> collectionSummaryList = orderRepository
                        .selectCollectionSummary(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
                model.addAttribute("collectionSummaryList", collectionSummaryList);
                return "partner-collection-summary";
            }
        } else {
            fofoId = fofoDetails.getFofoId();
            List<CollectionSummary> collectionSummaryList = orderRepository
                    .selectCollectionSummary(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
            model.addAttribute("collectionSummaryList", collectionSummaryList);
            return "partner-collection-summary";

        }
    }

    @RequestMapping(value = "/downloadCollectionSummary", method = RequestMethod.GET)
    public ResponseEntity<?> getDownloadCollectionSummary(HttpServletRequest request,
                                                          @RequestParam(defaultValue = "0") int fofoId,
                                                          @RequestParam(name = "startDate") LocalDate startDate,
                                                          @RequestParam(name = "endDate") LocalDate endDate, Model model) throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        List<List<?>> rows = new ArrayList<>();
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        List<CollectionSummary> collectionSummaryList = null;
        if (isAdmin) {
            if (fofoId == 0) {
                collectionSummaryList = new ArrayList<>();
            } else {
                collectionSummaryList = orderRepository.selectCollectionSummary(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
            }
        } else {
            collectionSummaryList = orderRepository.selectCollectionSummary(fofoDetails.getFofoId(), startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        }
        Logger.info("CollectionSummaryList {}", collectionSummaryList);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
        for (CollectionSummary cs : collectionSummaryList) {
            rows.add(Arrays.asList(cs.getDate().format(
                            dateTimeFormatter), cs.getReferenceType(), cs.getCash(), cs.getPinelabs(), cs.getBajajFinserv(), cs.getHomeCredit(), cs.getPaytm(),
                    cs.getCapitalFirst(), cs.getZestMoney(), cs.getSamsungSure(), cs.getTotalAmount()));
        }
        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil
                .getCSVByteStream(Arrays.asList("Date", "Reference Type", "Cash", "Pinelabs", "Bajaj Finservice", "Home Credit", "Paymt",
                        "Capital First", "Zest Money", "Samsung Sure", "Total Amount"), rows);
        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows, "Collection Summary Report");

        return responseEntity;
    }

    @RequestMapping(value = "/franchiseeSalesReport", method = RequestMethod.GET)
    public String getFranchiseeSalesReport(HttpServletRequest request, Model model, @RequestParam(defaultValue = "0") int fofoId,
                                           @RequestParam(required = false) LocalDate startDate, @RequestParam(required = false) LocalDate endDate)
            throws ProfitMandiBusinessException {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);

        }
        endDate = LocalDate.now();
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("isAdmin", isAdmin);
        LOGGER.info("q {}, starDate - {}, endDate - {}", fofoId, startDate, endDate);
        if (isAdmin) {
            if (fofoId == 0) {
                //No need to pull any data
                model.addAttribute("focoSaleReportList", new ArrayList<>());
                return "foco-sale-report";

            }
        } else {
            fofoId = loginDetails.getFofoId();
        }


        FofoStore fs = fofoStoreRepository.selectByRetailerId(fofoId);

        List<FocoSaleReportModel> focoSaleReportList = fofoOrderRepository.selectFocoSaleReport(fofoId, fs.getCode(), startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        model.addAttribute("focoSaleReportList", focoSaleReportList);
        return "foco-sale-report";
    }

    @RequestMapping(value = "/franchiseeSalesFetchReportByDate", method = RequestMethod.GET)
    public String getfranchiseeSalesFetchReport(HttpServletRequest request, Model model,
                                                @RequestParam(defaultValue = "0") int fofoId,
                                                @RequestParam(required = false) LocalDate startDate,
                                                @RequestParam(required = false) LocalDate endDate)
            throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        if (startDate == null) {

            startDate = LocalDate.now().minusDays(30);
            endDate = LocalDate.now();
        }
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("isAdmin", isAdmin);

        // List<List<?>> rows = new ArrayList<>();

        LOGGER.info("q {}, starDate - {}, endDate - {}", fofoId, startDate, endDate);
        if (isAdmin) {
            if (fofoId == 0) {
                //no need any data
                model.addAttribute("focoSaleReportList", new ArrayList<>());
                return "foco-sale-report";
            }
        } else {
            fofoId = loginDetails.getFofoId();
        }
        FofoStore fs = fofoStoreRepository.selectByRetailerId(fofoId);
        List<FocoSaleReportModel> focoSaleReportList = fofoOrderRepository.selectFocoSaleReport(fofoId, fs.getCode(), startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        model.addAttribute("focoSaleReportList", focoSaleReportList);
        return "foco-sale-report";
    }


    @RequestMapping(value = "/downloadFranchiseeSales", method = RequestMethod.GET)
    public ResponseEntity<?> getdownloadFranchiseeSales(HttpServletRequest request,
                                                        @RequestParam(defaultValue = "0") int fofoId,
                                                        @RequestParam(name = "startDate") LocalDate startDate,
                                                        @RequestParam(name = "endDate") LocalDate endDate,
                                                        Model model)
            throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);

        List<List<?>> rows = new ArrayList<>();
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        List<FocoSaleReportModel> focoSaleReportList = null;
        FofoStore fs = null;
        if (isAdmin) {
            fs = fofoStoreRepository.selectByRetailerId(fofoId);
            if (fofoId == 0) {
                focoSaleReportList = new ArrayList<>();
            } else {

                focoSaleReportList = fofoOrderRepository.selectFocoSaleReport(fofoId,
                        fs.getCode(), startDate.atStartOfDay(), endDate.atStartOfDay().plusDays(1));
            }

        } else {
            fs = fofoStoreRepository.selectByRetailerId(fofoDetails.getFofoId());

            focoSaleReportList = fofoOrderRepository.selectFocoSaleReport(fofoDetails.getFofoId(),
                    fs.getCode(), startDate.atStartOfDay(), endDate.atStartOfDay().plusDays(1));
        }
        LOGGER.info("FocoSaleReportList {}", focoSaleReportList);
        String partnerName = null;
        for (FocoSaleReportModel fsr : focoSaleReportList) {
            partnerName = fsr.getName();
            rows.add(Arrays.asList(fsr.getCode(), fsr.getName(), fsr.getCity(), fsr.getState(), fsr.getRegion(),
                    fsr.getItemId(), fsr.getBrand(), fsr.getModelName(), fsr.getModelNumber(), fsr.getColor(),
                    fsr.getQuantity(), fsr.getDp(), fsr.getSellingPrice(), fsr.getMop(), fsr.getSerialNumber(),
                    FormattingUtils.format(fsr.getCreateDate()), fsr.getCustomerName(), fsr.getCustomerPhone(),
                    fsr.getCustomerCity(), fsr.getCustomerPincode(), fsr.getInvoiceNumber(), fsr.getPurchaseReference(),
                    fsr.getCustomerGstNumber(), FormattingUtils.format(fsr.getCancelledTimestamp()),
                    FormattingUtils.format(fsr.getGrnCompleteDate()), fsr.getHygieneRating(), fsr.getRating(),
                    fsr.getStatus(), fsr.getRemark(), FormattingUtils.format(fsr.getCreatedTimestamp()),
                    FormattingUtils.format(fsr.getDisposedTimestamp()),
                    FormattingUtils.format(fsr.getNextTimestamp()),
                    FormattingUtils.format(fsr.getActivationTimestamp()),
                    FormattingUtils.format(fsr.getActivationTimestamp()), fsr.getLabel()));

        }

        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil.getCSVByteStream(
                Arrays.asList("Code", "Name", "City", "State", "Region", "Item Id", "Brand", "Model Name",
                        "Model Number", "Color", "Quantity", "Dp", "Selling_Price", "mop", "Serial Number",
                        "Create Date", "Customer Name", "Customer Phone", "Customer City", " Customer Pincode",
                        "Invoice  Number", "Purchase Reference", "Customer Gst Number", " Cancelled Timestamp",
                        "GRN Complete Date", "Hygiene Rating", "Rating", "Status", "Remark", "Created Timestamp",
                        "Disposed Timestamp", " Next Timestamp", "Activation Timestamp", "Create Timestamp", "Label"),
                rows);

        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows, partnerName + " Franchisee Sales Report");

        return responseEntity;

    }

    @RequestMapping(value = "/downloadWalletSummaryReport", method = RequestMethod.GET)
    public ResponseEntity<?> getDownloadWalletSummaryReport(HttpServletRequest request,
                                                            @RequestParam(defaultValue = "0", name = "fofoId") int fofoId,
                                                            @RequestParam(name = "startDate") LocalDate startDate,
                                                            @RequestParam(name = "endDate") LocalDate endDate, Model model)
            throws Exception {

        List<List<?>> rows = new ArrayList<>();
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());

        if (!isAdmin) fofoId = fofoDetails.getFofoId();
        List<WalletSummaryReportModel> walletSummaryList = fofoOrderRepository.selectWalletSummaryReport(
                fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        double openingBalance = walletService.getOpeningTill(fofoId, startDate.atStartOfDay());

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
        String partnerDetail = null;
// Headers for the table data
        rows.add(Arrays.asList(
                "Timestamp", "Reference_type", "Reference", "Amount", "Running Balance", "Description"));
        double runningBalance = openingBalance;
        for (
                WalletSummaryReportModel walletSummary : walletSummaryList) {
            runningBalance += walletSummary.getAmount();
            partnerDetail = walletSummary.getName() + "(" + walletSummary.getCode() + "-" + walletSummary.getPhone() + ")" + "-" + walletSummary.getEmail();

            rows.add(Arrays.asList(
                    FormattingUtils.format(walletSummary.getTimestamp()),
                    walletSummary.getReferenceType(),
                    walletSummary.getReference(),
                    walletSummary.getAmount(),
                    runningBalance,
                    walletSummary.getDescription()
            ));

        }


        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil
                .getCSVByteStream(Arrays.asList("Opening Balance - : " + openingBalance), rows);
        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows, partnerDetail + " Wallet Statement Report");

        return responseEntity;

    }
    @RequestMapping(value = "/walletSummaryFetchReportByDate", method = RequestMethod.GET)
    public String getwalletSummaryFetchReport(HttpServletRequest request, Model model, @RequestParam(defaultValue = "0") int fofoId,
                                              @RequestParam(required = false) LocalDate startDate,
                                              @RequestParam(required = false) LocalDate endDate)
            throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        UserWallet userWallet = userWalletRepository.selectByRetailerId(fofoId);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
        }
        if (endDate == null) {
            endDate = LocalDate.now();
        }
        List<WalletSummaryReportModel> walletSummartList = new ArrayList<>();
        float openingBalance = 0;
        float openingPendingAmount = 0;
        if (isAdmin) {
            if (fofoId > 0) {
                openingBalance = walletService.getOpeningTill(fofoId, startDate.atStartOfDay());
                Map<Integer, Float> openingAmountMap = transactionService.getPendingIndentValueMap(startDate.atStartOfDay(), Optional.of(fofoId));
                openingPendingAmount = openingAmountMap.get(fofoId) == null ? 0 : openingAmountMap.get(fofoId);
                walletSummartList = fofoOrderRepository.selectWalletSummaryReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
                LOGGER.info("startDate - " + startDate.atStartOfDay());
                LOGGER.info("endDate - " + endDate.atTime(LocalTime.MAX));
            }
        } else {
            walletSummartList = fofoOrderRepository.selectWalletSummaryReport(loginDetails.getFofoId(), startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        }
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);

        LOGGER.info("walletSummartList {}", walletSummartList);
        model.addAttribute("walletSummartList", walletSummartList);
        model.addAttribute("openingBalance", (openingBalance + openingPendingAmount));
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("isAdmin", isAdmin);
        model.addAttribute("userWallet", userWallet);
        return "wallet-summary-report";
    }

    @RequestMapping(value = "/walletSummaryReport", method = RequestMethod.GET)
    public String getWalletSummaryReport(HttpServletRequest request, Model model) throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        LocalDateTime startDate = LocalDateTime.now().minusDays(30);
        LocalDateTime endDate = LocalDateTime.now();
        List<WalletSummaryReportModel> walletSummartList = new ArrayList<>();
        if (!isAdmin) {
            walletSummartList = fofoOrderRepository
                    .selectWalletSummaryReport(fofoDetails.getFofoId(), startDate, endDate);
        }
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(fofoDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);

        LOGGER.info("walletSummartList {}", walletSummartList);
        model.addAttribute("startDate", startDate.toLocalDate());
        model.addAttribute("endDate", endDate.toLocalDate());
        model.addAttribute("walletSummartList", walletSummartList);
        model.addAttribute("isAdmin", isAdmin);

        return "wallet-summary-report";
    }

    @RequestMapping(value = "/pendingIndentReport", method = RequestMethod.GET)
    public String getPendingIndentReport(HttpServletRequest request, Model model) throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(fofoDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);

        LocalDateTime currentDate = LocalDate.now().atStartOfDay();
        LocalDateTime currentStartMonth = currentDate.minusMonths(2).toLocalDate().atStartOfDay();

        List<PendingIndentReportModel> pendingIndentReports = fofoOrderRepository
                .selectPendingIndentReport(fofoDetails.getFofoId(), currentStartMonth, currentDate);
        LOGGER.info("pendingIndentReports {}", pendingIndentReports);

        model.addAttribute("startDate", currentDate.minusMonths(2).toLocalDate());
        model.addAttribute("endDate", LocalDate.now());
        model.addAttribute("pendingIndentReports", pendingIndentReports);
        model.addAttribute("isAdmin", isAdmin);


        return "pending-indent-report";
    }

    @RequestMapping(value = "/pendingIndentFetchReportByDate", method = RequestMethod.GET)
    public String getpendingIndentFetchReport(
            HttpServletRequest request,
            @RequestParam(defaultValue = "0") int fofoId,
            @RequestParam(name = "startDate", required = true, defaultValue = "") LocalDate startDate,
            @RequestParam(name = "endDate", required = true, defaultValue = "") LocalDate endDate,
            Model model
    ) throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
            endDate = LocalDate.now();
        }
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(fofoDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);

        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("isAdmin", isAdmin);
        if (isAdmin) {
            if (fofoId == 0) {
                model.addAttribute("pendingIndentReports", new ArrayList<>());
                return "pending-indent-report";
            } else {
                List<PendingIndentReportModel> pendingIndentReports = fofoOrderRepository
                        .selectPendingIndentReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
                model.addAttribute("pendingIndentReports", pendingIndentReports);
                return "pending-indent-report";
            }
        } else {
            LocalDateTime currentDate = LocalDate.now().atStartOfDay();
            List<PendingIndentReportModel> pendingIndentReports = fofoOrderRepository
                    .selectPendingIndentReport(fofoDetails.getFofoId(), startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
            model.addAttribute("pendingIndentReports", pendingIndentReports);
            return "pending-indent-report";

        }
    }


    @RequestMapping(value = "/pendingIndentReportDownload", method = RequestMethod.GET)
    public ResponseEntity<?> getPendingIndentReportDownload(HttpServletRequest request,
                                                            @RequestParam(defaultValue = "0") int fofoId,
                                                            @RequestParam(name = "startDate") LocalDate startDate,
                                                            @RequestParam(name = "endDate") LocalDate endDate, Model model)
            throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        /*LocalDateTime currentDate = LocalDate.now().atStartOfDay();
        LocalDateTime currentStartMonth = currentDate.minusMonths(2).toLocalDate().atStartOfDay();*/
        List<PendingIndentReportModel> pendingIndentReports = null;
        List<List<?>> rows = new ArrayList<>();
        if (isAdmin) {
            if (fofoId == 0)
                pendingIndentReports = new ArrayList<>();
            else
                pendingIndentReports = fofoOrderRepository
                        .selectPendingIndentReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        } else {
            pendingIndentReports = fofoOrderRepository
                    .selectPendingIndentReport(fofoDetails.getFofoId(), startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));

        }
        LOGGER.info("pendingIndentReports {}", pendingIndentReports);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");

        for (PendingIndentReportModel pir : pendingIndentReports) {

            rows.add(Arrays.asList(pir.getTransactionId(), pir.getOrderId(),
                    pir.getCreatTimestamp().format(dateTimeFormatter), pir.getItemId(), pir.getBrand(),
                    pir.getModelName(), pir.getModelNumber(), pir.getColor(), pir.getQuantity(), pir.getUnitPrice(),
                    pir.getWalletAmount(), pir.getStatus(), pir.getInvoiceNumber(),
                    pir.getBillingTimestamp() == null ? "" : pir.getBillingTimestamp().format(dateTimeFormatter)));

        }

        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil.getCSVByteStream(Arrays.asList(
                "Transaction Id", "Order Id", "Created_At", "Item_Id", "Brand", "Model Name", "Model Number", "Color",
                "Quantity", "Unit Price", "Wallet Deduction", "Status", "Invoice Number", "Billing Timestamp"), rows);

        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows, "Order Status Summary Report");

        return responseEntity;
    }

    @RequestMapping(value = "/schemePayoutReport", method = RequestMethod.GET)
    public String getschemePayoutReport(HttpServletRequest request, Model model,
                                        @RequestParam(required = false) LocalDate startDate, @RequestParam(required = false) LocalDate endDate)
            throws ProfitMandiBusinessException {

        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
            endDate = LocalDate.now();
        }
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("isAdmin", isAdmin);
        //LOGGER.info("schemePayoutReports {}", schemePayoutReports);
        List<SchemePayoutReportModel> schemePayoutReports = fofoOrderRepository
                .selectSchemePayoutReport(loginDetails.getFofoId(), startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        model.addAttribute("schemePayoutReports", schemePayoutReports);
        return "scheme-payout-report";

    }

    @RequestMapping(value = "/schemePayoutFetchReportByDate", method = RequestMethod.GET)
    public String getschemePayoutFetchReportByDate(
            HttpServletRequest request,
            Model model,
            @RequestParam(defaultValue = "0") int fofoId,
            @RequestParam(required = false) LocalDate startDate,
            @RequestParam(required = false) LocalDate endDate)
            throws ProfitMandiBusinessException {
        //LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
            endDate = LocalDate.now();
        }
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                List<Integer> fofoIds = pp.get(authUser.getId());
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }

        model.addAttribute("isRBM", isRBM);
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("isAdmin", isAdmin);

        LOGGER.info("q {}, starDate - {}, endDate - {}", fofoId, startDate, endDate);
        if (isAdmin) {
            if (fofoId == 0) {
                //No need to pull any data
                model.addAttribute("schemePayoutReports", new ArrayList<>());
                return "scheme-payout-report";

            } else {
                List<SchemePayoutReportModel> schemePayoutReports = fofoOrderRepository
                        .selectSchemePayoutReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));

                model.addAttribute("schemePayoutReports", schemePayoutReports);
                return "scheme-payout-report";
            }
        } else {
            fofoId = loginDetails.getFofoId();

            List<SchemePayoutReportModel> schemePayoutReports = fofoOrderRepository
                    .selectSchemePayoutReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));

            model.addAttribute("schemePayoutReports", schemePayoutReports);
            return "scheme-payout-report";
        }

    }

    @RequestMapping(value = "/offerPayoutReport", method = RequestMethod.GET)
    public String getOfferPayoutReport(HttpServletRequest request, Model model, @RequestParam(required = false) LocalDate startDate, @RequestParam(required = false) LocalDate endDate) throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(fofoDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
            endDate = LocalDate.now();
        }
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);


        List<OfferPayoutDumpReportModel> offerPayoutDumpReports = fofoOrderRepository
                .selectOfferPayoutDumpReport(fofoDetails.getFofoId(), startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        LOGGER.info("offerPayoutDumpReports {}", offerPayoutDumpReports);

        model.addAttribute("offerPayoutDumpReports", offerPayoutDumpReports);
        model.addAttribute("isAdmin", isAdmin);

        return "offer-payout-dump-report";
    }

    @RequestMapping(value = "/offerPayoutFetchReportByDate", method = RequestMethod.GET)
    public String getofferPayoutFetchReportByDate(HttpServletRequest request, Model model, @RequestParam(defaultValue = "0") int fofoId,
                                                  @RequestParam(required = false) LocalDate startDate, @RequestParam(required = false) LocalDate endDate)
            throws ProfitMandiBusinessException {

        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
            endDate = LocalDate.now();
        }
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("isAdmin", isAdmin);
        LOGGER.info("q {}, starDate - {}, endDate - {}", fofoId, startDate, endDate);
        if (isAdmin) {
            if (fofoId == 0) {
                //No need to pull any data
                model.addAttribute("offerPayoutReports", new ArrayList<>());
                return "offer-payout-dump-report";

            } else {
                List<OfferPayoutDumpReportModel> offerPayoutDumpReports = fofoOrderRepository
                        .selectOfferPayoutDumpReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));

                model.addAttribute("offerPayoutDumpReports", offerPayoutDumpReports);


                return "offer-payout-dump-report";

            }
        } else {
            fofoId = loginDetails.getFofoId();
            List<OfferPayoutDumpReportModel> offerPayoutDumpReports = fofoOrderRepository
                    .selectOfferPayoutDumpReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));

            model.addAttribute("offerPayoutDumpReports", offerPayoutDumpReports);


            return "offer-payout-dump-report";
        }
    }


    @RequestMapping(value = "/selectPartnerBillingSummaryReport", method = RequestMethod.GET)
    public String getselectPartnerBillingSummaryReport(HttpServletRequest request, Model model) throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);

        LocalDateTime currentDate = LocalDate.now().atStartOfDay();
        LocalDateTime currentStartMonth = currentDate.minusMonths(3).toLocalDate().atStartOfDay();

        List<PartnerBillingSummaryModel> partnerBillingSummaryReports = fofoOrderRepository
                .selectPartnerBillingSummaryReport(fofoDetails.getFofoId(), currentStartMonth, currentDate);

        model.addAttribute("startDate", currentDate.minusMonths(3).toLocalDate());
        model.addAttribute("endDate", LocalDate.now());
        model.addAttribute("partnerBillingSummaryReports", partnerBillingSummaryReports);

        return "partner-billing-summary-report";
    }

    @RequestMapping(value = "/priceDropReport", method = RequestMethod.GET)
    public String getSelectPriceDropReport(HttpServletRequest request, @RequestParam(name = "startDate", required = true, defaultValue = "") LocalDate startDate,
                                           @RequestParam(name = "endDate", required = true, defaultValue = "") LocalDate endDate, Model model) throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
            endDate = LocalDate.now();
        }
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(fofoDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailer(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("isAdmin", isAdmin);
        List<PriceDropReportModel> priceDropReports = orderRepository.selectPriceDropReport(fofoDetails.getFofoId(),
                startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));

        model.addAttribute("priceDropReports", priceDropReports);

        return "price-drop-report";
    }

    @RequestMapping(value = "/priceDropFetchReportByDate", method = RequestMethod.GET)
    public String getpriceDropFetchReportByDate(HttpServletRequest request,
                                                @RequestParam(defaultValue = "0") int fofoId,
                                                @RequestParam(name = "startDate", required = true, defaultValue = "") LocalDate startDate,
                                                @RequestParam(name = "endDate", required = true, defaultValue = "") LocalDate endDate, Model model)
            throws Exception {

        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
            endDate = LocalDate.now();
        }
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(fofoDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailer(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("isAdmin", isAdmin);
        if (isAdmin) {
            if (fofoId == 0) {
                model.addAttribute("priceDropReports", new ArrayList<>());
                return "price-drop-report";
            } else {
                List<PriceDropReportModel> priceDropReports = orderRepository.selectPriceDropReport(fofoId,
                        startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
                model.addAttribute("priceDropReports", priceDropReports);
                return "price-drop-report";
            }

        } else {
            List<PriceDropReportModel> priceDropReports = orderRepository.selectPriceDropReport(fofoDetails.getFofoId(),
                    startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
            model.addAttribute("priceDropReports", priceDropReports);
            return "price-drop-report";
        }
    }


    @RequestMapping(value = "/downloadPriceDropReport", method = RequestMethod.GET)
    public ResponseEntity<?> getSelectDownloadPriceDropReport(HttpServletRequest request,
                                                              @RequestParam(defaultValue = "0") int fofoId,
                                                              @RequestParam(name = "startDate") LocalDate startDate,
                                                              @RequestParam(name = "endDate") LocalDate endDate, Model model)
            throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        List<List<?>> rows = new ArrayList<>();
        List<PriceDropReportModel> priceDropReports = null;
        if (isAdmin) {
            if (fofoId == 0)
                priceDropReports = new ArrayList<>();
            else
                priceDropReports = orderRepository.selectPriceDropReport(fofoId,
                        startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        } else {
            fofoId = fofoDetails.getFofoId();
            priceDropReports = orderRepository.selectPriceDropReport(fofoId,
                    startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        }
        for (PriceDropReportModel pdr : priceDropReports) {

            rows.add(Arrays.asList(pdr.getCode(), pdr.getId(), pdr.getBrand(), pdr.getModelName(), pdr.getModelNumber(),
                    FormattingUtils.formatDate(pdr.getAffectedOn()), pdr.getAmount(), FormattingUtils.format(pdr.getCreditTimestamp()), pdr.getImei(), pdr.getStatus(),
                    FormattingUtils.format(pdr.getRejectedTimestamp()), pdr.getRejectionReason()));

        }
        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil
                .getCSVByteStream(Arrays.asList("code", "Price_Drop_Id", "brand", "model_name", "model_number",
                        "affected_on", "amount", "Credit Date", "Imei", "status", "Rejected Date", "Rejected Reason"), rows);

        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows, "price drop report");

        return responseEntity;

    }

    @RequestMapping(value = "/downloadPartnerBillingSummaryReport", method = RequestMethod.GET)
    public ResponseEntity<?> getdownloadPartnerBillingSummaryReport(HttpServletRequest request,
                                                                    @RequestParam(name = "startDate") LocalDate startDate,
                                                                    @RequestParam(name = "endDate") LocalDate endDate, Model model)
            throws Exception {

        List<List<?>> rows = new ArrayList<>();
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);

        LocalDateTime currentDate = LocalDate.now().atStartOfDay();
        LocalDateTime currentStartMonth = currentDate.minusMonths(3).toLocalDate().atStartOfDay();

        List<PartnerBillingSummaryModel> partnerBillingSummaryReports = fofoOrderRepository
                .selectPartnerBillingSummaryReport(fofoDetails.getFofoId(), startDate.atStartOfDay(),
                        endDate.atTime(LocalTime.MAX));

        for (PartnerBillingSummaryModel pbsr : partnerBillingSummaryReports) {

            rows.add(Arrays.asList(pbsr.getId(),
                    FormattingUtils.format(pbsr.getCreateTimestamp()),
                    FormattingUtils.format(pbsr.getBillingTimestamp()),
                    FormattingUtils.format(pbsr.getDeliveryTimestamp()),
                    FormattingUtils.format(pbsr.getPartnerGrnTimestamp()),
                    pbsr.getTransactionId(),
                    pbsr.getLogisticsTransactionId(), pbsr.getAirwayBillNumber(), pbsr.getStatusSubGroup(),
                    pbsr.getStatusName(), pbsr.getRetailerId(), pbsr.getRetailerName(), pbsr.getItemId(),
                    pbsr.getBrand(), pbsr.getModelName(), pbsr.getModelNumber(), pbsr.getColor(), pbsr.getUnitPrice(),
                    pbsr.getQuantity(), pbsr.getTotalPrice(), pbsr.getInvoiceNumber(), pbsr.getSellerName(), pbsr.getGstNumber(), pbsr.getHsnCode(), pbsr.getIgstRate(),
                    pbsr.getCgstRate(), pbsr.getSgstRate()));

        }

        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil.getCSVByteStream(Arrays.asList("OrderId",
                "Created On", "Billed On", "Delivered On", "Grned On", "Transaction_id", "master_order_id",
                "airwaybill_no", "statusSubGroupp", "statusName", "customer_id", "customer_name", "Item_Id", "brand",
                "model_name", "model_number", "color", "selling_price", "Quantity", "total_price", "invoice_number",
                "seller_name", "gst_number", "hsn_code", "igstrate", "cgstrate", "sgstrate"), rows);

        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows, "Billing Statement Report");

        return responseEntity;


    }

    @RequestMapping(value = "/invoiceSchemeOutSummaryReport", method = RequestMethod.GET)
    public String getInvoiceSchemeOutSummaryReport(HttpServletRequest request, Model model) throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);

        LocalDateTime currentDate = LocalDate.now().atStartOfDay();
        LocalDateTime currentStartMonth = currentDate.minusMonths(3).toLocalDate().atStartOfDay();

        List<FocoSchemeOutReportModel> focoSchemeOutReports = fofoOrderRepository
                .selectInvoiceSchemeOutSummaryReport(fofoDetails.getFofoId(), currentStartMonth, currentDate);
        LOGGER.info("focoSchemeOutReportModel {}", focoSchemeOutReports);

        model.addAttribute("startDate", currentDate.minusMonths(3).toLocalDate());
        model.addAttribute("endDate", LocalDate.now());
        model.addAttribute("focoSchemeOutReports", focoSchemeOutReports);

        return "invoicewise-scheme-out-report";
    }

    @RequestMapping(value = "/downloadInvoiceSchemeOutSummaryReport", method = RequestMethod.GET)
    public ResponseEntity<?> getDownloadInvoiceSchemeOutSummaryReport(HttpServletRequest request, Model model)
            throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);

        List<List<?>> rows = new ArrayList<>();
        LocalDateTime currentDate = LocalDate.now().atStartOfDay();
        LocalDateTime currentStartMonth = currentDate.minusMonths(3).toLocalDate().atStartOfDay();

        List<FocoSchemeOutReportModel> focoSchemeOutReports = fofoOrderRepository
                .selectInvoiceSchemeOutSummaryReport(fofoDetails.getFofoId(), currentStartMonth, currentDate);
        LOGGER.info("focoSchemeOutReportModel {}", focoSchemeOutReports);

        for (FocoSchemeOutReportModel fsor : focoSchemeOutReports) {
            rows.add(Arrays.asList(fsor.getInvoiceNumber(), fsor.getQuantity(), fsor.getBrand(), fsor.getModelName(),
                    fsor.getModelNumber(), fsor.getColor(), fsor.getAmount()));

        }

        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil.getCSVByteStream(
                Arrays.asList("InvoiceNumber", "Quantity", "Brand", "Model Name", "Model Number", "Color", "Amount"),
                rows);

        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows,
                "invoice wise scheme out Summary Report");

        return responseEntity;
    }

    @RequestMapping(value = "/schemePayoutReportDownload", method = RequestMethod.GET)
    public ResponseEntity<?> getSchemePayoutReportDownload(HttpServletRequest request,
                                                           @RequestParam(defaultValue = "0") int fofoId,
                                                           @RequestParam(name = "startDate") LocalDate startDate,
                                                           @RequestParam(name = "endDate") LocalDate endDate, Model model)
            throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);

        List<List<?>> rows = new ArrayList<>();

        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());

        List<SchemePayoutReportModel> schemePayoutReports = null;
        if (isAdmin) {
            if (fofoId == 0)
                schemePayoutReports = new ArrayList<>();
            else
                schemePayoutReports = fofoOrderRepository
                        .selectSchemePayoutReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        } else {
            fofoId = fofoDetails.getFofoId();
            schemePayoutReports = fofoOrderRepository
                    .selectSchemePayoutReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        }
        LOGGER.info("schemePayoutReports {}", schemePayoutReports);

        for (SchemePayoutReportModel spr : schemePayoutReports) {

            rows.add(Arrays.asList(spr.getId(), spr.getSerialNumber(), spr.getBrand(), spr.getModelName(),
                    spr.getModelNumber(), spr.getColor(), spr.getSchemeInDp(), spr.getSchemeOutDp(), spr.getSchemeId(),
                    spr.getName(), spr.getType(), spr.getAmount(), spr.getAmountType(), spr.getSioAmount(), spr.getPurchaseReference(),
                    spr.getInvoiceNumber(), spr.getStatus(), spr.getStatusDescription(),
                    FormattingUtils.formatDateTime(spr.getCreateTimestamp()), FormattingUtils.formatDateTime(spr.getRolledBackTimestamp())));

        }
        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil.getCSVByteStream(Arrays.asList("Item Id",
                "Serial No", "Brand", "Model Name", "Model Number", "Color", "Scheme In Dp", "Scheme Out Dp",
                "Scheme Id", "Name", "Scheme Type", "Amount", "Amount Type", "Amount Paid", "Purchase Invoice", "Sale Invoice", "Status",
                "Description", "Created on", "Reversed On"), rows);

        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows, "Scheme Payout Summary Report");

        return responseEntity;
    }


    @RequestMapping(value = "/offerPayoutDumpReportDownload", method = RequestMethod.GET)
    public ResponseEntity<?> getOfferPayoutDumpReportDownload(HttpServletRequest request,
                                                              @RequestParam(defaultValue = "0") int fofoId,
                                                              @RequestParam(name = "startDate") LocalDate startDate,
                                                              @RequestParam(name = "endDate") LocalDate endDate, Model model)
            throws Exception {
        LoginDetails fofoDetails = cookiesProcessor.getCookiesObject(request);
        List<List<?>> rows = new ArrayList<>();
        boolean isAdmin = roleManager.isAdmin(fofoDetails.getRoleIds());
        List<OfferPayoutDumpReportModel> offerPayoutReports = null;
        if (isAdmin) {
            if (fofoId == 0)
                offerPayoutReports = new ArrayList<>();
            else
                offerPayoutReports = fofoOrderRepository
                        .selectOfferPayoutDumpReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        } else {
            fofoId = fofoDetails.getFofoId();
            offerPayoutReports = fofoOrderRepository
                    .selectOfferPayoutDumpReport(fofoId, startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        }


        for (OfferPayoutDumpReportModel opdr : offerPayoutReports) {

            rows.add(Arrays.asList(opdr.getId(), opdr.getBrand(), opdr.getModelName(),
                    opdr.getModelNumber(), opdr.getColor(), opdr.getSerialNumber(), opdr.getOfferId(),
                    opdr.getName(), opdr.getType(),
                    opdr.getSlabAmount(), opdr.getAmount(), opdr.getDescription(),
                    opdr.getCreateTimestamp(), opdr.getRejectTimestamp()));

        }
        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil.getCSVByteStream(Arrays.asList("Id",
                "Brand", "Model Name", "Model Number", "Color", "Serial number",
                "Offer Id", "Name", "Type", "Slab Amount", "Amount",
                "Description", "Credited On", "Rejected On"), rows);

        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows, "Offer Payout Summary Report");

        return responseEntity;
    }


    @GetMapping("/getAllOnlineOrder")
    public String getAllOrders(HttpServletRequest request, @RequestParam(required = false) LocalDate date, Model model)
            throws ProfitMandiBusinessException {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        if (date == null) {
            date = LocalDate.now().minusDays(3);
        }

        LOGGER.info("date" + date);
        List<Integer> fofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId())
                .collect(Collectors.toList());

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

        Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> customRetailerMap.get(x))
                .filter(x -> x != null).collect(Collectors.toList()).stream()
                .collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));

        model.addAttribute("customRetailersMap", customRetailersMap);

        List<PendingOrderItem> pendingOrderItem = null;

        pendingOrderItem = pendingOrderItemRepository.selectAll(date.atStartOfDay(), LocalDateTime.now());

        Map<String, Object> map = pendingOrderService.getItemOrders(pendingOrderItem, 0);

        model.addAttribute("pendingOrderItem", map.get("pendingOrderItem"));
        model.addAttribute("partnerInventoryMap", map.get("partnerInventoryMap"));
        model.addAttribute("date", date);
        model.addAttribute("isAdmin", isAdmin);
        return "online-all-order-item";
    }


    @RequestMapping(value = "/reports", method = RequestMethod.GET)
    public String reports(HttpServletRequest httpServletRequest, Model model) throws ProfitMandiBusinessException, UnsupportedOperationException, IOException {
        //LoginDetails loginDetails = cookiesProcessor.getCookiesObject(httpServletRequest);
        Map<ReporticoProject, List<ReporticoUrlInfo>> returnMap = ReporticoProject.reporticoProjectMap;
                /*if(fofoStoreRepository.getWarehousePartnerMap().get(7720).stream().filter(x->x.getId()==loginDetails.getFofoId()).count() > 0) {
                        Map<ReporticoProject, List<ReporticoUrlInfo>> returnMap1 = new HashMap<ReporticoProject, List<ReporticoUrlInfo>>();
                        returnMap1.put(ReporticoProject.FOCO, returnMap.get(ReporticoProject.FOCO));
                        returnMap1.put(ReporticoProject.FOCOR, returnMap.get(ReporticoProject.FOCOR).stream().skip(1).collect(Collectors.toList()));
                        returnMap = returnMap1;
                }*/
        model.addAttribute("reporticoProjectMap", returnMap);
        return "reports";
    }

    @RequestMapping(value = "/account-statement", method = RequestMethod.GET)
    public String accountStatement(HttpServletRequest request, Model model, @RequestParam(defaultValue = "0") int fofoId,
                                   @RequestParam(required = false) LocalDate startDate,
                                   @RequestParam(required = false) LocalDate endDate)
            throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());

        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                Set<Integer> fofoIds = new HashSet<>(pp.get(authUser.getId()));
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(x -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(x);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }

        model.addAttribute("isAdmin", isAdmin);
        model.addAttribute("isRBM", isRBM);

        return "partner-account-statement";

    }

    @RequestMapping(value = "/account-statement-report", method = RequestMethod.GET)
    public String getPartnerAccountStatement(HttpServletRequest request, @RequestParam LocalDateTime startDate, @RequestParam LocalDateTime endDate, Model model, @RequestParam(defaultValue = "0") int fofoId) throws Exception {
        boolean isAdmin = roleManager.isAdmin(cookiesProcessor.getCookiesObject(request).getRoleIds());
        if (fofoId > 0) {
            if (!isAdmin) {
                throw new ProfitMandiBusinessException("Unauthorised access", "PartnerId", "Permission Denied");
            }
        } else {
            fofoId = cookiesProcessor.getCookiesObject(request).getFofoId();
        }
        float openingBalance = walletService.getOpeningTill(fofoId, startDate);
        float closingBalance = walletService.getOpeningTill(fofoId, endDate);
        UserWallet uw = walletService.getUserWallet(fofoId);
        LOGGER.info("Start date - {}, end Date - {}", startDate, endDate);

        List<UserWalletHistory> history = userWalletHistoryRepository.selectPaginatedByWalletId(uw.getId(), startDate, endDate, 0, 0);

        history = history.stream().filter(x -> !x.getReferenceType().equals(WalletReferenceType.PURCHASE))
                .filter(x -> !WalletService.CN_WALLET_REFERENCES.contains(x.getReferenceType())).sorted(Comparator.comparing(UserWalletHistory::getId)).collect(Collectors.toList());
        Map<LocalDate, List<UserWalletHistory>> dateWalletMap = history.stream().collect(Collectors.groupingBy(x -> x.getTimestamp().toLocalDate()));
        CustomRetailer customRetailer = retailerService.getAllFofoRetailers().get(fofoId);
        List<StatementDetailModel> billedStatementDetails = orderRepository.selectDetailsBetween(fofoId, startDate, endDate);
        Map<Integer, Float> openingAmountMap = transactionService.getPendingIndentValueMap(startDate, Optional.of(fofoId));
        Map<Integer, Float> closingAmountMap = transactionService.getPendingIndentValueMap(endDate, Optional.of(fofoId));

        float openingPendingAmount = openingAmountMap.get(fofoId) == null ? 0 : openingAmountMap.get(fofoId);
        float closingPendingAmount = closingAmountMap.get(fofoId) == null ? 0 : closingAmountMap.get(fofoId);
        LOGGER.info("Opening - {}, Closing - {}", openingPendingAmount, closingPendingAmount);

        double grandTotalDebit = 0;
        double grandTotalCredit = 0;

        for (UserWalletHistory walletEntry : history) {
            if (walletEntry.getAmount() < 0) {
                grandTotalDebit += Math.abs(walletEntry.getAmount());
            } else {
                grandTotalCredit += walletEntry.getAmount();
            }
        }

        for (StatementDetailModel statement : billedStatementDetails) {
            if (statement.getAmount() < 0) {
                grandTotalCredit += Math.abs(statement.getAmount());
            } else {
                grandTotalDebit += statement.getAmount();
            }
        }

        model.addAttribute("billedStatementDetails", billedStatementDetails);
        model.addAttribute("customRetailer", customRetailer);
        model.addAttribute("wallethistory", history);
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        model.addAttribute("dateWalletMap", dateWalletMap);
        model.addAttribute("openingBalance", (openingBalance + openingPendingAmount));
        model.addAttribute("closingBalance", (closingBalance + closingPendingAmount));
        model.addAttribute("grandTotalDebit", grandTotalDebit);
        model.addAttribute("grandTotalCredit", grandTotalCredit);

        return "account-statement-list";
    }

    @RequestMapping(value = "/loan/loan-statement", method = RequestMethod.GET)
    public String loanStatement(HttpServletRequest request, Model model)
            throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                List<Integer> fofoIds = pp.get(authUser.getId());
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(fofoId -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(fofoId);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        model.addAttribute("isAdmin", isAdmin);

        return "partner-loan-statement";

    }

    @RequestMapping(value = "/loan/partner-loan-statement-report", method = RequestMethod.GET)
    public String partnerLoanStatement(HttpServletRequest request, Model model, @RequestParam(defaultValue = "0") int fofoId,
                                       @RequestParam(required = false) LocalDateTime startDate,
                                       @RequestParam(required = false) LocalDateTime endDate)
            throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        int partnerId = 0;

        if (fofoId > 0) {
            partnerId = fofoId;
        } else {
            partnerId = loginDetails.getFofoId();
        }

        FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(partnerId);

        List<LoanStatementReportModel> loanStatementReportModels = loanStatementRepository.selectByDatesAndStoreCode(startDate, endDate, fofoStore.getCode());

        model.addAttribute("isAdmin", isAdmin);
        model.addAttribute("loanStatementReportModels", loanStatementReportModels);

        return "partner-loan-statement-summary";

    }

    @RequestMapping(value = "/loan/download-partner-loan-statement-report", method = RequestMethod.GET)
    public ResponseEntity<?> downloadPartnerLoanStatement(HttpServletRequest request, Model model, @RequestParam(defaultValue = "0") int fofoId,
                                                          @RequestParam(required = false) LocalDateTime startDate,
                                                          @RequestParam(required = false) LocalDateTime endDate)
            throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());

        int partnerId = 0;

        if (fofoId > 0) {
            partnerId = fofoId;
        } else {
            partnerId = loginDetails.getFofoId();
        }

        FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(partnerId);

        List<List<?>> rows = new ArrayList<>();

        List<LoanStatementReportModel> loanStatementReportModels = loanStatementRepository.selectByDatesAndStoreCode(startDate, endDate, fofoStore.getCode());// Extract the store name from the first loan statement
        String storeName = loanStatementReportModels.get(0).getStoreName();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yy");
        for (LoanStatementReportModel loanStatement : loanStatementReportModels) {
            rows.add(Arrays.asList(
                    loanStatement.getCode(),  // Code
                    String.valueOf(loanStatement.getId()),  // ID (convert int to string)
                    loanStatement.getStoreName(),  // Store Name
                    loanStatement.getState(),  // State
                    loanStatement.getZone(),  // Zone
                    loanStatement.getArea(),  // Area
                    loanStatement.getTerritory(),  // Territory
                    String.valueOf(loanStatement.getLoanId()),  // Loan ID
                    loanStatement.getInterestRate().toString(),  // Interest Rate (BigDecimal to String)
                    loanStatement.getIntialAmount().toString(),  // Initial Amount (BigDecimal to String)
                    loanStatement.getPendingAmount().toString(),  // Pending Amount (BigDecimal to String)
                    loanStatement.getInvoiceNumber() != null ? loanStatement.getInvoiceNumber() : "-", // Invoice Number
                    loanStatement.getCreatedOn().format(dateTimeFormatter),  // Created On (format LocalDateTime)
                    loanStatement.getDueDate().format(dateTimeFormatter),  // Due Date (format LocalDateTime)
                    loanStatement.getInterestAccrued().toString(),  // Interest Accrued (BigDecimal to String)
                    loanStatement.getInterestPaid().toString(),  // Interest Paid (BigDecimal to String)
                    String.valueOf(loanStatement.getFreeDays()),  // Free Days (convert int to string)
                    loanStatement.getLoanReferenceType().toString(),  // Loan Reference Type (enum or string)
                    loanStatement.getAmount().toString(),  // Amount (BigDecimal to String)
                    loanStatement.getBusinessDate().format(dateTimeFormatter),  // Business Date (format LocalDateTime)
                    loanStatement.getCreatedAt().format(dateTimeFormatter),  // Created At (format LocalDateTime)
                    loanStatement.getDescription(),  // Description
                    loanStatement.getStatus()  // Status (calculated value)
            ));
        }

        // Set up the headers and create the CSV
        List<String> headers = Arrays.asList("Code", "ID", "Store Name", "State", "Zone", "Area", "Territory", "Credit ID",
                "Interest Rate", "Initial Amount", "Pending Amount", "Invoice Number", "Created On", "Due Date",
                "Interest Accrued", "Interest Paid", "Free Days", "Credit Reference Type",
                "Amount", "Business Date", "Created At", "Description", "Status");

        // Create the CSV byte stream
        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil.getCSVByteStream(headers, rows);
        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows, "Partner Credit Summary Report");

        return responseEntity;

    }

    @RequestMapping(value = "/report/credit-note", method = RequestMethod.GET)
    public String creditNote(HttpServletRequest request, Model model)
            throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        boolean isRBM = false;
        if (isAdmin) {
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
            List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId());
            isRBM = positions.stream()
                    .anyMatch(position ->
                            ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId());
            Map<Integer, List<Integer>> pp = csService.getAuthUserIdPartnerIdMapping();
            if (isRBM && pp.containsKey(authUser.getId())) {
                List<Integer> fofoIds = pp.get(authUser.getId());
                Map<Integer, CustomRetailer> customRetailersMap = fofoIds.stream().map(fofoId -> {
                    try {
                        return retailerService.getFofoRetailers(true).get(fofoId);
                    } catch (ProfitMandiBusinessException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                }).filter(x -> x != null).collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
                model.addAttribute("customRetailersMap", customRetailersMap);
            }
        }
        model.addAttribute("isRBM", isRBM);
        model.addAttribute("isAdmin", isAdmin);

        return "credit-note";

    }


    @RequestMapping(value = "/credit/credit-note-report", method = RequestMethod.GET)
    public String creditNoteReport(HttpServletRequest request, Model model, @RequestParam(defaultValue = "0") int fofoId,
                                   @RequestParam(required = false) YearMonth yearMonth)
            throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
        int partnerId = 0;

        if (fofoId > 0) {
            partnerId = fofoId;
        } else {
            partnerId = loginDetails.getFofoId();
        }

        LOGGER.info("partnerId: " + partnerId + " yearMonth: " + yearMonth);

        List<CreditNote> creditNotes = creditNoteRepository.selectAll(partnerId, yearMonth);

        model.addAttribute("isAdmin", isAdmin);
        model.addAttribute("creditNotes", creditNotes);

        return "credit-note-list";

    }

    @RequestMapping(value = "/credit-note/download", method = RequestMethod.GET)
    public ResponseEntity<?> downloadCreditNote(@RequestParam("cnNumber") String cnNumber) {
        try {
            CreditNote creditNote = creditNoteRepository.selectByCreditNoteNumber(cnNumber);

            YearMonth yearMonth = YearMonth.from(creditNote.getCnDate());
            int fofoId = creditNote.getFofoId();

            Utils.Attachment attachment = creditNoteService.downloadCN(creditNote, yearMonth, fofoId);

            return ResponseEntity.ok()
                    .contentType(MediaType.APPLICATION_PDF)
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + attachment.getFileName() + "\"")
                    .body(attachment.getInputStreamSource());
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error generating PDF: " + e.getMessage());
        }
    }

    @RequestMapping(value = "/credit-note/attachements", method = RequestMethod.GET)
    public ResponseEntity<?> getCnAttachements(@RequestParam("cnNumber") String cnNumber) throws Exception {
        CreditNote creditNote = creditNoteRepository.selectByCreditNoteNumber(cnNumber);
        YearMonth yearMonth = YearMonth.from(creditNote.getCnDate());
        int fofoId = creditNote.getFofoId();

        List<InventoryMarginModel> allOffers = offerPayoutRepository.getPaidOffers(yearMonth, fofoId);
        List<InventoryMarginModel> allPriceDrops = priceDropIMEIRepository.selectPaidPriceDrops(yearMonth, fofoId);
        List<InventoryMarginModel> schemeMarginsInventoryModel = schemeInOutRepository.getPaidMargins(yearMonth, fofoId);

        List<InventoryMarginModel> allInventoryMarginModels = new ArrayList<>();
        allInventoryMarginModels.addAll(schemeMarginsInventoryModel);
        allInventoryMarginModels.addAll(allPriceDrops);
        allInventoryMarginModels.addAll(allOffers);

        List<List<?>> rows = allInventoryMarginModels.stream().map(InventoryMarginModel::toRow).collect(Collectors.toList());

        // Add CN Number Header Row
        List<List<?>> finalRows = new ArrayList<>();
        finalRows.add(Arrays.asList("CN Number:", cnNumber));  // First row with CN Number
        finalRows.add(Collections.emptyList());  // Blank row for separation
        finalRows.addAll(rows);  // Add actual data

        // Generate CSV
        org.apache.commons.io.output.ByteArrayOutputStream byteArrayOutputStream = FileUtil.getCSVByteStream(
                Arrays.asList("FofoId", "InvoiceNo", "SerialNumber", "Margin", "Description", "CGST", "IGST", "SGST", "Credited On"),
                finalRows
        );

        return orderService.downloadReportInCsv(byteArrayOutputStream, finalRows, "CN Detail Report");
    }



}