Subversion Repositories SmartDukaan

Rev

Rev 34111 | Rev 34131 | 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.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.getOrderId(),
                    report.getCustomerNumber(),
                    report.getCallingDate(),
                    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", "Order Id", "Customer Mobile Number", "Calling Date", "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";
    }

}