Subversion Repositories SmartDukaan

Rev

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

package com.spice.profitmandi.web.controller;


import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.CustomAddress;
import com.spice.profitmandi.common.model.CustomPaymentOption;
import com.spice.profitmandi.common.model.InsuranceModel;
import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.common.util.FileUtil;
import com.spice.profitmandi.common.web.util.ResponseSender;
import com.spice.profitmandi.dao.entity.auth.AuthUser;
import com.spice.profitmandi.dao.entity.catalog.Item;
import com.spice.profitmandi.dao.entity.dtr.InsurancePolicy;
import com.spice.profitmandi.dao.entity.dtr.PaymentOptionTransaction;
import com.spice.profitmandi.dao.entity.fofo.*;
import com.spice.profitmandi.dao.entity.inventory.State;
import com.spice.profitmandi.dao.entity.user.User;
import com.spice.profitmandi.dao.enumuration.dtr.PaymentOptionReferenceType;
import com.spice.profitmandi.dao.enumuration.transaction.UpSaleCallStatus;
import com.spice.profitmandi.dao.model.PaymentLinkDetailModel;
import com.spice.profitmandi.dao.model.UpsellingReportModel;
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
import com.spice.profitmandi.dao.repository.cs.CsService;
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
import com.spice.profitmandi.dao.repository.dtr.InsurancePolicyRepository;
import com.spice.profitmandi.dao.repository.dtr.PaymentOptionTransactionRepository;
import com.spice.profitmandi.dao.repository.fofo.*;
import com.spice.profitmandi.dao.repository.inventory.StateRepository;
import com.spice.profitmandi.dao.repository.user.UserRepository;
import com.spice.profitmandi.service.NotificationService;
import com.spice.profitmandi.service.authentication.RoleManager;
import com.spice.profitmandi.service.integrations.RazorpayPaymentService;
import com.spice.profitmandi.service.integrations.kommuno.KommunoService;
import com.spice.profitmandi.service.integrations.zest.InsuranceService;
import com.spice.profitmandi.service.integrations.zest.MobileInsurancePlan;
import com.spice.profitmandi.service.order.OrderService;
import com.spice.profitmandi.web.model.LoginDetails;
import com.spice.profitmandi.web.util.CookiesProcessor;
import com.spice.profitmandi.web.util.MVCResponseSender;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.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.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


@Controller
@Transactional(rollbackFor = Throwable.class)
public class UpSaleController {
    private static final Logger LOGGER = LogManager.getLogger(UpSaleController.class);
    @Autowired
    AuthRepository authRepository;
    @Autowired
    UpsellRazorpayPaymentStatusRepository upsellRazorpayPaymentStatusRepository;
    @Autowired
    private CookiesProcessor cookiesProcessor;
    @Autowired
    private RoleManager roleManager;
    @Autowired
    private FofoOrderRepository fofoOrderRepository;
    @Autowired
    private InsurancePolicyRepository insurancePolicyRepository;
    @Autowired
    private CustomerRepository customerRepository;
    @Autowired
    private UpSaleCallRepository upSaleCallRepository;
    @Autowired
    private UpSaleOrderRepository upSaleOrderRepository;
    @Autowired
    private MVCResponseSender mvcResponseSender;
    @Autowired
    private InsuranceService insuranceService;
    @Autowired
    private FofoOrderItemRepository fofoOrderItemRepository;
    @Autowired
    private ResponseSender responseSender;
    @Autowired
    private StateRepository stateRepository;
    @Autowired
    private NotificationService notificationService;
    @Autowired
    private ItemRepository itemRepository;
    @Autowired
    private RazorpayPaymentService razorpayPaymentService;
    @Autowired
    private TagListingRepository tagListingRepository;
    @Autowired
    private PaymentOptionTransactionRepository paymentOptionTransactionRepository;
    @Autowired
    private OrderService orderService;
    @Autowired
    private FofoLineItemRepository fofoLineItemRepository;
    @Autowired
    private UpSaleAgentCollectionRepository upSaleAgentCollectionRepository;
    @Autowired
    private KommunoService kommunoService;
    @Autowired
    private UpSellCallDetailRepository upsellCallDetailRepository;

    @Autowired
    private CsService csService;

    @Autowired
    private FofoStoreRepository fofoStoreRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private CustomerAddressRepository customerAddressRepository;

    @RequestMapping(value = "/upsaleProductslist", method = RequestMethod.GET)
    public String upsaleProductslist(HttpServletRequest request, Model model) throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        AuthUser user = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
        List<UpSaleAgentCollection> upSaleAgentCollections = upSaleAgentCollectionRepository.selectByAgentId(user.getId());
        // Calculate the total product sale amount
        double totalProductSaleAmount = upSaleAgentCollections.stream()
                .mapToDouble(UpSaleAgentCollection::getProductSaleAmount)
                .sum();

        // Add the total amount to the model

        List<UpSaleCallStatus> upSaleCallStatuses = new ArrayList<>(Arrays.asList(UpSaleCallStatus.values()));
        LOGGER.info("upSaleCallStatuses {}", upSaleCallStatuses);

        model.addAttribute("upSaleCallStatuses", upSaleCallStatuses);
        model.addAttribute("totalProductSaleAmount", totalProductSaleAmount);
        model.addAttribute("upSaleAgentCollections", upSaleAgentCollections);
        return "up-sale-call";
    }

    @RequestMapping(value = "/razorpapPaymentStatus", method = RequestMethod.GET)
    public String razorpapPaymentStatusAgainstOrderID(HttpServletRequest request, Model model, @RequestParam int orderId) throws Exception {
        List<UpsellRazorpayPaymentStatus> upSellRazorpayPaymentStatusList = upsellRazorpayPaymentStatusRepository.selectByOrderId(orderId);
        LOGGER.info("upSellRazorpayPaymentStatusList {}", upSellRazorpayPaymentStatusList);
        model.addAttribute("upSellRazorpayPaymentStatusList", upSellRazorpayPaymentStatusList);

        return "upsell-payment-confirmation";
    }

    @RequestMapping(value = "/fetchMobileNumberForUpSale", method = RequestMethod.GET)
    public String fetchMobileNumberForUpSale(HttpServletRequest request, Model model) throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        AuthUser user = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());

        Map<String, Set<Integer>> pp = csService.getAuthUserPartnerIdMappingByCategoryIds(Arrays.asList(ProfitMandiConstants.UPSELLING), true);
        Set<Integer> fofoIds = new HashSet<>(pp.get(user.getEmailId()));

        List<UpSaleAgentCollection> upSaleAgentCollections = upSaleAgentCollectionRepository.selectByAgentId(user.getId());
        double totalProductSaleAmount = upSaleAgentCollections.stream()
                .mapToDouble(UpSaleAgentCollection::getProductSaleAmount)
                .sum();

        try {
            // Fetch all rescheduled calls and filter them in-memory
            List<UpSaleCall> upSaleCalls = upSaleCallRepository.selectAllByDispostion(UpSaleCallStatus.RESCHEDULED);
            LOGGER.info("UpSaleCall {}", upSaleCalls);

            List<UpSaleCall> filteredUpSaleCalls = upSaleCalls.stream()
                    .filter(call -> call.getRescheduledTimestamp() != null
                            && call.getRescheduledTimestamp().isBefore(LocalDateTime.now())
                            && call.getCreatedTimestamp() != null
                            && call.getCreatedTimestamp().isAfter(LocalDateTime.now().minusHours(48)))
                    .collect(Collectors.toList());

            if (!filteredUpSaleCalls.isEmpty()) {
                for (UpSaleCall upSaleCall : filteredUpSaleCalls) {
                    FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(upSaleCall.getOriginalOrderId());
                    User fofoUser = userRepository.selectById(fofoOrder.getFofoId());

                    Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
                    if (fofoIds.contains(fofoOrder.getFofoId())) {
                        if (customer != null) {
                            upSaleCall.setStatus(UpSaleCallStatus.FETCHED);
                            upSaleCall.setRescheduledTimestamp(null);

                            List<Map<String, Object>> itemDetails = new ArrayList<>();
                            List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());

                            for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
                                Item item = itemRepository.selectById(fofoOrderItem.getItemId());
                                if (item.isSmartPhone()) {
                                    Map<String, List<MobileInsurancePlan>> plans = this.getPlans(fofoOrderItem.getSellingPrice(), item.getId());
                                    Map<String, Object> itemDetail = new HashMap<>();
                                    itemDetail.put("item", item);
                                    itemDetail.put("fofoOrderItem", fofoOrderItem);
                                    itemDetail.put("plans", plans);
                                    itemDetails.add(itemDetail);
                                }
                            }

                            Set<Integer> fofoOrderItemIds = fofoOrderItems.stream().map(FofoOrderItem::getId).collect(Collectors.toSet());
                            List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIds);

                            Map<Integer, List<FofoLineItem>> fofoLineItemMap = fofoLineItems.stream()
                                    .collect(Collectors.groupingBy(FofoLineItem::getFofoOrderItemId));

                            List<UpSaleCallStatus> upSaleCallStatuses = new ArrayList<>(Arrays.asList(UpSaleCallStatus.values()));

                            model.addAttribute("upSaleCallStatuses", upSaleCallStatuses);
                            model.addAttribute("fofoOrder", fofoOrder);
                            model.addAttribute("fofoUser", fofoUser);
                            model.addAttribute("customer", customer);
                            model.addAttribute("itemDetails", itemDetails);
                            model.addAttribute("fofoLineItemMap", fofoLineItemMap);
                            model.addAttribute("upsaleCallId", upSaleCall.getId());
                            model.addAttribute("stateNames",
                                    stateRepository.selectAll().stream().map(x -> x.getName()).collect(Collectors.toList()));
                            model.addAttribute("totalProductSaleAmount", totalProductSaleAmount);

                            return "up-sale-call";
                        }
                    }
                }
            } else {
                throw new RuntimeException("No filtered calls available for processing");
            }
        } catch (Exception e) {
            // If no rescheduled calls found, fall back to original logic
            UpSaleOrder TMinus2UpsaleOrder = this.getTMinus2UpSaleOrderByFofoIds(fofoIds);

            TMinus2UpsaleOrder.setFetched(true);

            LOGGER.info("last48hourLatestOrder {}", TMinus2UpsaleOrder);
            if (TMinus2UpsaleOrder != null) {
                boolean exists = upSaleCallRepository.existsOrderId(TMinus2UpsaleOrder.getOrderId());
                if (!exists) {
                    FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(TMinus2UpsaleOrder.getOrderId());
                    User fofoUser = userRepository.selectById(fofoOrder.getFofoId());
                    if (fofoIds.contains(fofoOrder.getFofoId())) {
                        Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
                        if (customer != null) {
                            String mobile = customer.getMobileNumber();
                            UpSaleCall upSaleCall = new UpSaleCall();
                            upSaleCall.setAgentId(user.getId());
                            upSaleCall.setMobile(mobile);
                            upSaleCall.setOriginalOrderId(fofoOrder.getId());
                            upSaleCall.setStatus(UpSaleCallStatus.FETCHED);
                            upSaleCall.setCreatedTimestamp(LocalDateTime.now());
                            upSaleCallRepository.persist(upSaleCall);

                            LOGGER.info("Processing UpSaleOrder {}", TMinus2UpsaleOrder);

                            List<Map<String, Object>> itemDetails = new ArrayList<>();
                            List<FofoOrderItem> fofoOrderItems = fofoOrderItemRepository.selectByOrderId(fofoOrder.getId());

                            for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
                                Item item = itemRepository.selectById(fofoOrderItem.getItemId());
                                if (item.isSmartPhone()) {
                                    float sellingPrice = tagListingRepository.selectByItemId(item.getId()).getSellingPrice();
                                    Map<String, List<MobileInsurancePlan>> plans = this.getPlans(fofoOrderItem.getSellingPrice(), item.getId());
                                    Map<String, Object> itemDetail = new HashMap<>();
                                    itemDetail.put("item", item);
                                    itemDetail.put("fofoOrderItem", fofoOrderItem);
                                    itemDetail.put("plans", plans);
                                    itemDetails.add(itemDetail);
                                }
                            }

                            Set<Integer> fofoOrderItemIds = fofoOrderItems.stream().map(FofoOrderItem::getId).collect(Collectors.toSet());
                            List<FofoLineItem> fofoLineItems = fofoLineItemRepository.selectByFofoOrderItemIds(fofoOrderItemIds);

                            Map<Integer, List<FofoLineItem>> fofoLineItemMap = fofoLineItems.stream()
                                    .collect(Collectors.groupingBy(FofoLineItem::getFofoOrderItemId));

                            List<UpSaleCallStatus> upSaleCallStatuses = new ArrayList<>(Arrays.asList(UpSaleCallStatus.values()));

                            model.addAttribute("upSaleCallStatuses", upSaleCallStatuses);
                            model.addAttribute("fofoOrder", fofoOrder);
                            model.addAttribute("fofoUser", fofoUser);
                            model.addAttribute("customer", customer);
                            model.addAttribute("itemDetails", itemDetails);
                            model.addAttribute("fofoLineItemMap", fofoLineItemMap);
                            model.addAttribute("upsaleCallId", upSaleCall.getId());
                            model.addAttribute("stateNames",
                                    stateRepository.selectAll().stream().map(State::getName).collect(Collectors.toList()));
                            model.addAttribute("totalProductSaleAmount", totalProductSaleAmount);

                            return "up-sale-call";

                        }
                    }
                }
            }

        }


        LOGGER.info("No valid UpSaleOrder found for up-sale call.");
        model.addAttribute("totalProductSaleAmount", totalProductSaleAmount);
        model.addAttribute("message", "No valid UpSaleOrder found.");

        return "up-sale-call";
    }

    UpSaleOrder getTMinus2UpSaleOrderByFofoIds(Set<Integer> fofoIds) {
        LocalDateTime startDateTime = LocalDateTime.now().minusDays(2); // 48 hours ago
        return upSaleOrderRepository.getTMinus2UpSaleOrderByFofoIds(fofoIds, startDateTime);
    }

    @RequestMapping(value = "/generatePaymentLink", method = RequestMethod.POST)
    public ResponseEntity<String> generatePaymentLink(HttpServletRequest request, Model model, @RequestBody PaymentLinkDetailModel paymentLinkDetailModel) {
        double amount;
        LOGGER.info("paymnetlinkmodel {}", paymentLinkDetailModel);
        try {
            String paymentLink = razorpayPaymentService.createPaymentLink(paymentLinkDetailModel);

            LOGGER.info("paymentLink {}", paymentLink);
            String message = "Dear Customer,\n" +
                    "Here is a payment link for your recent purchased product.\n" +
                    "Please do your payment with this link\n" +
                    paymentLink + "\n" +
                    "Team SmartDukaan";
            LOGGER.info("message- {}", message);
            notificationService.sendPaymentWhatsappMessage(paymentLinkDetailModel.getMobile(), message);
//            notificationService.sendPaymentWhatsappMessage("7082253510", message);

//            model.addAttribute("message", "Payment link generated and sent successfully!");
            return responseSender.ok(true);
        } catch (Exception e) {
//            model.addAttribute("message", "Failed to generate payment link: " + e.getMessage());
            return responseSender.ok(false);
        }


    }

    private Map<String, List<MobileInsurancePlan>> getPlans(float sellingPrice, int itemId)
            throws ProfitMandiBusinessException {
        try {
            Map<String, List<MobileInsurancePlan>> productDurationPlans = new HashMap<>();
            productDurationPlans = insuranceService.getAllPlans(itemId,
                    sellingPrice, false);

            return productDurationPlans;
        } catch (Exception e) {
            LOGGER.info(e, e);
            throw new ProfitMandiBusinessException("Fetch Insurance Plans", "Insurance",
                    "Could not fetch insurance Plans");
        }

    }

    @RequestMapping(value = "/upsell/clickToCall/{toMobile}/{upsellCallId}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> upsellClickToCall(HttpServletRequest request, @PathVariable String toMobile, @PathVariable int upsellCallId) throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        AuthUser user = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
        kommunoService.upsellClickToCallKommuno(toMobile, loginDetails.getEmailId(), upsellCallId);
        return responseSender.ok(true);
    }

    @RequestMapping(value = "/upsell/disposition/{upsellCallId}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> upsellDisposition(HttpServletRequest request,
                                               @PathVariable String upsellCallId,
                                               @RequestParam(name = "disposition", required = false) UpSaleCallStatus disposition,
                                               @RequestParam(name = "scheduleTime", required = false) String scheduleTime) throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        AuthUser user = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());

        UpsellCallDetail upsellCallDetail = upsellCallDetailRepository.selectByUpSellCallId(upsellCallId);
        LOGGER.info("upsellCallDetail {}", upsellCallDetail);
        upsellCallDetail.setAgentId(user.getEmailId());
        upsellCallDetail.setDisposition(disposition);
        upsellCallDetail.setRemark(disposition.getValue());


        if (scheduleTime != null && !scheduleTime.isEmpty()) {
            UpSaleCall upSaleCall = upSaleCallRepository.selectById(Integer.parseInt(upsellCallId));
            Instant instant = Instant.parse(scheduleTime);
            LocalDateTime scheduledDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
            upSaleCall.setRescheduledTimestamp(scheduledDateTime);
            upSaleCall.setStatus(disposition);
        }

        // Generate session id with 16 digits as kommuno service
        Long newId = (long) upsellCallDetail.getId();
        String sessionId = String.format("%014d", newId);
        upsellCallDetail.setDiallerSessionId(sessionId);

//        fill diposition on kommuno service
        kommunoService.upsellFillDispositionWithKommuno(disposition.getValue(), sessionId);

        return responseSender.ok(true);
    }

    @RequestMapping(value = "/generatePlanDetail", method = RequestMethod.POST)
    public String generatePlanDetail(HttpServletRequest request, Model model, @RequestBody PaymentLinkDetailModel paymentLinkDetailModel) throws Exception {
        FofoOrderItem foi = fofoOrderItemRepository.selectById(Integer.parseInt(paymentLinkDetailModel.getOrderItemId()));

        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(Integer.parseInt(paymentLinkDetailModel.getOrderId()));
        float deviceSellingPrice = tagListingRepository.selectByItemId(foi.getItemId()).getSellingPrice();
        MobileInsurancePlan mobileInsurancePlan = insuranceService.getPlanById(paymentLinkDetailModel.getPlanId(), foi.getSellingPrice(), paymentLinkDetailModel.getPlanName());
        Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());

        model.addAttribute("fofoOrder", fofoOrder);
        model.addAttribute("fofoOrderItem", foi);
        model.addAttribute("deviceSellinnPrice", deviceSellingPrice);
        model.addAttribute("mobileInsurancePlan", mobileInsurancePlan);
        model.addAttribute("serialNumber", paymentLinkDetailModel.getSerialNumber());
        model.addAttribute("customer", customer);
        model.addAttribute("customerAddress", customer.getCustomerAddress());
        return "upsale-create-insurance-model";
    }

    @RequestMapping(value = "/create-insurance", method = RequestMethod.POST)
    public ResponseEntity<?> createInsurance(HttpServletRequest request, @RequestBody InsuranceModel insuranceModel, Model model) throws Exception {
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
        AuthUser user = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
        LOGGER.info("request at uri {} body {}", request.getRequestURI(), insuranceModel);
        FofoOrderItem foi = fofoOrderItemRepository.selectById(insuranceModel.getFofoOrderItemId());
        float deviceSellingPrice = tagListingRepository.selectByItemId(foi.getItemId()).getSellingPrice();
        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(foi.getOrderId());
        FofoStore fs = fofoStoreRepository.selectByRetailerId(fofoOrder.getFofoId());

        Customer customer = customerRepository.selectById(fofoOrder.getCustomerId());
        LOGGER.info("customer {}", customer);
        LOGGER.info("customerAddress {}", customer.getCustomerAddress());
        if (fofoOrder.getCustomerAddressId() == 0) {
            throw new Exception("Please select a address or add new address");
        }
        customer.setDob(insuranceModel.getDob());

        fofoOrder.setDateOfBirth(insuranceModel.getDob());
        insuranceModel.setBrand(foi.getBrand());
        insuranceModel.setMfgDate(insuranceModel.getWmfgDate().atStartOfDay());
        insuranceModel.setColor(foi.getColor());
        insuranceModel.setInsuranceUId(insuranceModel.getInsuranceId());
        insuranceModel.setInsuranceId(String.valueOf(insuranceService.getOneAssistPremiumByVariantId(insuranceModel.getInsuranceId()).getId()));
        insuranceModel.setModelName(String.join(" ", foi.getModelName(), foi.getModelNumber()));
        insuranceModel.setDeviceSellingPrice(deviceSellingPrice);

        InsurancePolicy insurancePolicy = insuranceService.createInsurance(fofoOrder, insuranceModel, true);
        String documentNumber = orderService.getInvoiceNumber(fofoOrder.getFofoId(), fs.getCode());
        insurancePolicy.setInvoiceNumber(documentNumber);
        insurancePolicy.setDeviceInvoiceNumber(fofoOrder.getInvoiceNumber());

        FofoOrder fo = this.createAndGetFofoOrder(customer.getId(), fofoOrder.getCustomerGstNumber(), fofoOrder.getFofoId(), insurancePolicy.getInvoiceNumber(), insuranceModel.getInsuranceAmount(), fofoOrder.getCustomerAddressId());

        this.createPaymentOptions(fo, insuranceModel.getPaymentOptions());

//        agent collection persistance

        UpSaleAgentCollection upSaleAgentCollection = new UpSaleAgentCollection();
        upSaleAgentCollection.setAgentId(user.getId());
        upSaleAgentCollection.setOrderId(fofoOrder.getId());
        upSaleAgentCollection.setProductId(insuranceModel.getInsuranceId());
        upSaleAgentCollection.setInsurancePolicyId(insurancePolicy.getId());
        upSaleAgentCollection.setProductSaleAmount(insurancePolicy.getSaleAmount());
//        if insurance plan is selling than is insurance will be true
        upSaleAgentCollection.setInsurance(true);
        upSaleAgentCollection.setCreatedTimestamp(LocalDateTime.now());
        upSaleAgentCollectionRepository.persist(upSaleAgentCollection);

        return responseSender.ok(true);
    }

    private void createPaymentOptions(FofoOrder fofoOrder, Set<CustomPaymentOption> customPaymentOptions) throws ProfitMandiBusinessException {
        for (CustomPaymentOption customPaymentOption : customPaymentOptions) {
            if (customPaymentOption.getAmount() > 0) {
                PaymentOptionTransaction paymentOptionTransaction = new PaymentOptionTransaction();
                paymentOptionTransaction.setReferenceId(fofoOrder.getId());
                paymentOptionTransaction.setPaymentOptionId(customPaymentOption.getPaymentOptionId());
                paymentOptionTransaction.setReferenceType(PaymentOptionReferenceType.INSURANCE);
                paymentOptionTransaction.setAmount(customPaymentOption.getAmount());
                paymentOptionTransaction.setFofoId(fofoOrder.getFofoId());
                paymentOptionTransactionRepository.persist(paymentOptionTransaction);
            }
        }
    }

    private FofoOrder createAndGetFofoOrder(int customerId, String customerGstNumber, int fofoId, String documentNumber, float totalAmount, int customerAddressId) {
        FofoOrder fofoOrder = new FofoOrder();
        fofoOrder.setCustomerGstNumber(customerGstNumber);
        fofoOrder.setCustomerId(customerId);
        fofoOrder.setFofoId(fofoId);
        fofoOrder.setInvoiceNumber(documentNumber);
        fofoOrder.setTotalAmount(totalAmount);
        fofoOrder.setCustomerAddressId(customerAddressId);
        fofoOrderRepository.persist(fofoOrder);
        return fofoOrder;
    }

    @RequestMapping(value = "/customer/addaddress", method = RequestMethod.POST)
    public ResponseEntity<?> addAddress(HttpServletRequest request, @RequestParam int customerId,
                                        @RequestBody CustomAddress customAddress) {
        CustomerAddress customerAddress = this.toCustomerAddress(customerId, customAddress);
        customerAddressRepository.persist(customerAddress);
        return responseSender.ok(this.toCustomAddress(customerAddress));

    }

    private CustomAddress toCustomAddress(CustomerAddress customerAddress) {
        CustomAddress customAddress = new CustomAddress();
        customAddress.setCity(customerAddress.getCity());
        customAddress.setCountry(customerAddress.getCountry());
        customAddress.setLandmark(customerAddress.getLandmark());
        customAddress.setLine1(customerAddress.getLine1());
        customAddress.setLine2(customerAddress.getLine2());
        customAddress.setName(customerAddress.getName());
        customAddress.setLastName(customerAddress.getLastName());
        customAddress.setPhoneNumber(customerAddress.getPhoneNumber());
        customAddress.setPinCode(customerAddress.getPinCode());
        customAddress.setState(customerAddress.getState());
        customAddress.setId(customerAddress.getId());
        return customAddress;
    }

    private CustomerAddress toCustomerAddress(int customerId, CustomAddress customAddress) {
        CustomerAddress customerAddress = new CustomerAddress();
        customerAddress.setCustomerId(customerId);
        customerAddress.setName(customAddress.getName());
        customerAddress.setLastName(customAddress.getLastName());
        customerAddress.setLine1(customAddress.getLine1());
        customerAddress.setLine2(customAddress.getLine2());
        customerAddress.setLandmark(customAddress.getLandmark());
        customerAddress.setCity(customAddress.getCity());
        customerAddress.setPinCode(customAddress.getPinCode());
        customerAddress.setState(customAddress.getState());
        customerAddress.setCountry(customAddress.getCountry());
        customerAddress.setPhoneNumber(customAddress.getPhoneNumber());

        return customerAddress;
    }


    @RequestMapping(value = "/update-fofoOrder-addressId", method = RequestMethod.POST)
    public ResponseEntity<?> updateFofoOrderAddresId(HttpServletRequest request, @RequestParam(name = "orderId", defaultValue = "0") int orderId, @RequestParam(name = "addressId", defaultValue = "0") int addressId, Model model) throws Exception {
        FofoOrder fofoOrder = fofoOrderRepository.selectByOrderId(orderId);
        fofoOrder.setCustomerAddressId(addressId);
        return responseSender.ok(true);
    }

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

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

        LocalDate startLocalDate = startDate.toLocalDate();
        LocalDate endLocalDate = endDate.toLocalDate();

        List<UpsellingReportModel> upsellingReportModels = upSaleCallRepository.getUpsellingReport(startLocalDate, endLocalDate.plusDays(1));

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");

        for (
                UpsellingReportModel report : upsellingReportModels) {

            rows.add(Arrays.asList(
                    report.getAgentEmail(),
                    report.getPartnerName(),
                    report.getPartnerMobile(),
                    report.getState(),
                    report.getPartnerName(),
                    report.getOrderId(),
                    report.getCustomerNumber(),
                    report.getCallingDate(),
                    report.getDisposition(),
                    report.getRemark(),
                    report.getPaymentStatus(),
                    report.getInsuranceStatus(),
                    report.getPolicySoldAmount(),
                    report.getInvoiceNumber(),
                    report.getSerialNumber()
            ));

        }


        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil
                .getCSVByteStream(Arrays.asList("Agent Email", "Partner Name", "Partner Mobile Number", "Partner State", "Order Id", "Customer Mobile Number", "Calling Date", "Disposition", "Remark", "Payment Status", "Insurance Status", "Policy Sold Amount", "Invoice Number", "Serial Number"), rows);
        ResponseEntity<?> responseEntity = orderService.downloadReportInCsv(baos, rows, " Upselling Report");

        return responseEntity;

    }

    @RequestMapping(value = "/getUpsellingReport", method = RequestMethod.GET)
    public String getUpsellingReport(
            HttpServletRequest request,
            @RequestParam(name = "startDate") LocalDateTime startDate,
            @RequestParam(name = "endDate") LocalDateTime endDate, Model model
    ) throws Exception {

        LocalDate startLocalDate = startDate.toLocalDate();
        LocalDate endLocalDate = endDate.toLocalDate();

        List<UpsellingReportModel> upsellingReportModels = upSaleCallRepository.getUpsellingReport(startLocalDate, endLocalDate.plusDays(1));

        model.addAttribute("upsellingReportModels", upsellingReportModels);

        return "upselling-report";
    }

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

        return "upselling-calling-list";
    }

}