Subversion Repositories SmartDukaan

Rev

Rev 34619 | Rev 34644 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 34619 Rev 34641
Line 16... Line 16...
16
import com.spice.profitmandi.dao.entity.logistics.AreaRepository;
16
import com.spice.profitmandi.dao.entity.logistics.AreaRepository;
17
import com.spice.profitmandi.dao.entity.transaction.*;
17
import com.spice.profitmandi.dao.entity.transaction.*;
18
import com.spice.profitmandi.dao.entity.user.User;
18
import com.spice.profitmandi.dao.entity.user.User;
19
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
19
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
20
import com.spice.profitmandi.dao.enumuration.transaction.LoanReferenceType;
20
import com.spice.profitmandi.dao.enumuration.transaction.LoanReferenceType;
21
import com.spice.profitmandi.dao.model.BIRetailerModel;
-
 
22
import com.spice.profitmandi.dao.model.BiSecondaryModel;
-
 
23
import com.spice.profitmandi.dao.model.BrandWiseModel;
21
import com.spice.profitmandi.dao.model.*;
24
import com.spice.profitmandi.dao.model.ReturnOrderInfoModel;
-
 
25
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
22
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
26
import com.spice.profitmandi.dao.repository.cs.CsService;
23
import com.spice.profitmandi.dao.repository.cs.CsService;
27
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
24
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
28
import com.spice.profitmandi.dao.repository.fofo.*;
25
import com.spice.profitmandi.dao.repository.fofo.*;
29
import com.spice.profitmandi.dao.repository.inventory.StateRepository;
26
import com.spice.profitmandi.dao.repository.inventory.StateRepository;
30
import com.spice.profitmandi.dao.repository.transaction.*;
27
import com.spice.profitmandi.dao.repository.transaction.*;
31
import com.spice.profitmandi.dao.repository.user.UserRepository;
28
import com.spice.profitmandi.dao.repository.user.UserRepository;
-
 
29
import com.spice.profitmandi.service.RbmTargetService;
32
import com.spice.profitmandi.service.inventory.InventoryService;
30
import com.spice.profitmandi.service.inventory.InventoryService;
33
import com.spice.profitmandi.service.transaction.SDCreditService;
31
import com.spice.profitmandi.service.transaction.SDCreditService;
34
import com.spice.profitmandi.service.user.RetailerService;
32
import com.spice.profitmandi.service.user.RetailerService;
35
import com.spice.profitmandi.service.wallet.WalletService;
33
import com.spice.profitmandi.service.wallet.WalletService;
36
import in.shop2020.model.v1.order.OrderStatus;
34
import in.shop2020.model.v1.order.OrderStatus;
37
import in.shop2020.model.v1.order.WalletReferenceType;
35
import in.shop2020.model.v1.order.WalletReferenceType;
38
import org.apache.commons.io.output.ByteArrayOutputStream;
36
import org.apache.commons.io.output.ByteArrayOutputStream;
39
import org.apache.logging.log4j.LogManager;
37
import org.apache.logging.log4j.LogManager;
40
import org.apache.logging.log4j.Logger;
38
import org.apache.logging.log4j.Logger;
41
import org.apache.poi.ss.usermodel.Row;
39
import org.apache.poi.ss.usermodel.*;
42
import org.apache.poi.ss.usermodel.Sheet;
-
 
43
import org.apache.poi.ss.usermodel.Workbook;
40
import org.apache.poi.xssf.usermodel.XSSFColor;
44
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
41
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
45
import org.springframework.beans.factory.annotation.Autowired;
42
import org.springframework.beans.factory.annotation.Autowired;
46
import org.springframework.beans.factory.annotation.Qualifier;
43
import org.springframework.beans.factory.annotation.Qualifier;
47
import org.springframework.beans.factory.annotation.Value;
44
import org.springframework.beans.factory.annotation.Value;
48
import org.springframework.core.io.ByteArrayResource;
45
import org.springframework.core.io.ByteArrayResource;
Line 54... Line 51...
54
import javax.mail.MessagingException;
51
import javax.mail.MessagingException;
55
import javax.mail.internet.InternetAddress;
52
import javax.mail.internet.InternetAddress;
56
import javax.mail.internet.MimeMessage;
53
import javax.mail.internet.MimeMessage;
57
import java.io.*;
54
import java.io.*;
58
import java.math.BigDecimal;
55
import java.math.BigDecimal;
59
import java.time.LocalDate;
-
 
60
import java.time.LocalDateTime;
-
 
61
import java.time.LocalTime;
-
 
62
import java.time.YearMonth;
56
import java.time.*;
63
import java.time.temporal.ChronoUnit;
57
import java.time.temporal.ChronoUnit;
64
import java.util.*;
58
import java.util.*;
65
import java.util.stream.Collectors;
59
import java.util.stream.Collectors;
66
import java.util.stream.Stream;
60
import java.util.stream.Stream;
67
 
61
 
Line 140... Line 134...
140
 
134
 
141
    @Autowired
135
    @Autowired
142
    LoanStatementRepository loanStatementRepository;
136
    LoanStatementRepository loanStatementRepository;
143
 
137
 
144
    @Autowired
138
    @Autowired
-
 
139
    ActivatedImeiRepository activatedImeiRepository;
-
 
140
 
-
 
141
    @Autowired
-
 
142
    PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;
-
 
143
 
-
 
144
    @Autowired
145
    WalletService walletService;
145
    WalletService walletService;
146
 
146
 
-
 
147
    @Autowired
-
 
148
    RbmTargetService rbmTargetService;
-
 
149
 
147
    public void test() throws Exception {
150
    public void test() throws Exception {
148
        System.out.println("test start");
151
        System.out.println("test start");
149
        //this.generateBiReportExcel();
152
        this.generateBiReportExcel();
150
        this.loanSettle();
-
 
151
        System.out.println("test end");
153
        System.out.println("test end");
152
 
154
 
153
    }
155
    }
154
 
156
 
155
    public void createLoanForBillingByTransactionIdAndInvoiceNumber(int transactionId, double invoiceAmount, String invoiceNumber) throws Exception {
157
    public void createLoanForBillingByTransactionIdAndInvoiceNumber(int transactionId, double invoiceAmount, String invoiceNumber) throws Exception {
Line 441... Line 443...
441
 
443
 
442
        Map<Integer, CustomRetailer> customRetailers = retailerService.getAllFofoRetailersInternalFalse();
444
        Map<Integer, CustomRetailer> customRetailers = retailerService.getAllFofoRetailersInternalFalse();
443
 
445
 
444
        List<Integer> retailerIds = customRetailers.values().stream().map(CustomRetailer::getPartnerId).collect(Collectors.toList());
446
        List<Integer> retailerIds = customRetailers.values().stream().map(CustomRetailer::getPartnerId).collect(Collectors.toList());
445
 
447
 
-
 
448
        //partner daily investment
-
 
449
        List<Loan> defaultLoans = sdCreditService.getDefaultLoan();
-
 
450
        Map<Integer,List<Loan>> defaultLoanMap = defaultLoans.stream().collect(Collectors.groupingBy(Loan::getFofoId));
-
 
451
 
-
 
452
        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = new HashMap<>();
-
 
453
        List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository
-
 
454
                .selectAll(new ArrayList<>(retailerIds), LocalDate.now().minusDays(1));
-
 
455
        if (!partnerDailyInvestments.isEmpty()) {
-
 
456
            partnerDailyInvestmentMap = partnerDailyInvestments.stream()
-
 
457
                    .collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
-
 
458
        }
446
 
459
 
447
//  this month return data
460
//  this month return data
448
        YearMonth currentMonth = YearMonth.now();
461
        YearMonth currentMonth = YearMonth.now();
449
        String currentMonthStringValue = String.valueOf(currentMonth);
462
        String currentMonthStringValue = String.valueOf(currentMonth);
450
        LocalDateTime currentMonthStartDate = YearMonth.now().atDay(1).atStartOfDay();
463
        LocalDateTime currentMonthStartDate = YearMonth.now().atDay(1).atStartOfDay();
Line 483... Line 496...
483
        Map<Integer, Long> twoMonthAgoRtoRefundOrderMap = twoMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
496
        Map<Integer, Long> twoMonthAgoRtoRefundOrderMap = twoMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
484
 
497
 
485
 
498
 
486
        Map<Integer , BIRetailerModel> biRetailerModelMap = new HashMap<>();
499
        Map<Integer , BIRetailerModel> biRetailerModelMap = new HashMap<>();
487
 
500
 
-
 
501
        Map<Integer , FofoInvestmentModel> biInvestmentModelMap = new HashMap<>();
-
 
502
 
488
        Map<Integer, Map<YearMonth, BiSecondaryModel>> allRetailerMonthlyData = new HashMap<>();
503
        Map<Integer, Map<YearMonth, BiSecondaryModel>> allRetailerMonthlyData = new HashMap<>();
489
 
504
 
490
        Map<Integer,Double> fofoTotalStockPriceMap = new HashMap<>();
505
        Map<Integer,Double> fofoTotalStockPriceMap = new HashMap<>();
491
 
506
 
492
        Map<Integer,Map<String, BrandStockPrice>> fofoBrandStockPriceMap = new HashMap<>();
507
        Map<Integer,Map<String, BrandStockPrice>> fofoBrandStockPriceMap = new HashMap<>();
493
 
508
 
-
 
509
        Map<Integer,Long> fofoTotalMtdSecondaryMap = new HashMap<>();
-
 
510
 
-
 
511
        Map<Integer , String> assessmentMap = new HashMap<>();
-
 
512
        Map<Integer , String> zeroBillingMap = new HashMap<>();
-
 
513
        Map<Integer , Float> billingNeededMap = new HashMap<>();
-
 
514
        Map<Integer , Integer> countAMap = new HashMap<>();
-
 
515
 
-
 
516
        Map<Integer,Map<String, Long>> fofoBrandWiseMtdSecondaryMap = new HashMap<>();
494
 
517
 
495
        Map<Integer,Double> fofoTotalTertiaryMap = new HashMap<>();
-
 
496
 
518
 
-
 
519
 
-
 
520
        Map<Integer,Double> fofoTotalMtdTertiaryMap = new HashMap<>();
-
 
521
 
497
        Map<Integer,Map<String, Double>> fofoBrandTertiaryMap = new HashMap<>();
522
        Map<Integer,Map<String, Double>> fofoBrandMtdTertiaryMap = new HashMap<>();
498
 
523
 
499
        for(Integer fofoId: retailerIds){
524
        for(Integer fofoId: retailerIds){
500
            String rbmName = "";
525
            String rbmName = "";
501
            int rbmL1 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM,EscalationType.L1,fofoId);
526
            int rbmL1 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM,EscalationType.L1,fofoId);
502
            if(rbmL1 != 0){
527
            if(rbmL1 != 0){
Line 537... Line 562...
537
            biRetailerModel.setSalesManager(managerName);
562
            biRetailerModel.setSalesManager(managerName);
538
            biRetailerModel.setRbm(rbmName);
563
            biRetailerModel.setRbm(rbmName);
539
 
564
 
540
            biRetailerModelMap.put(fofoId,biRetailerModel);
565
            biRetailerModelMap.put(fofoId,biRetailerModel);
541
 
566
 
-
 
567
 
542
//            generate secondary data
568
//            generate secondary data
543
 
569
 
-
 
570
            List<PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledMonthlyTotals = activatedImeiRepository.getTotalMonthlyActivatedNotBilled(fofoId,twoMonthsAgoStartDate);
-
 
571
            Map<YearMonth , PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledTotalMap = partnerWiseActivatedNotBilledMonthlyTotals.stream().collect(Collectors.toMap(x-> YearMonth.parse(x.getYearMonth()),x->x));
-
 
572
 
544
//            this month secondary target
573
//            this month secondary target
545
 
574
 
546
            double currentSecondaryTarget =  monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId).getPurchaseTarget() : 0;
575
            double currentSecondaryTarget =  monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId).getPurchaseTarget() : 0;
547
 
576
 
548
 
577
 
Line 557... Line 586...
557
 
586
 
558
            double currentMonthNetSecondary = secondaryAchievedMtd - currentMonthReturn;
587
            double currentMonthNetSecondary = secondaryAchievedMtd - currentMonthReturn;
559
 
588
 
560
            double currentMonthSecondaryPercent = currentSecondaryTarget == 0 ? 0.0 : (secondaryAchievedMtd / currentSecondaryTarget) * 100;
589
            double currentMonthSecondaryPercent = currentSecondaryTarget == 0 ? 0.0 : (secondaryAchievedMtd / currentSecondaryTarget) * 100;
561
 
590
 
562
            double currentMonthUnbilled = 0;
591
            double currentMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(currentMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(currentMonth).getTotalUnbilledAmount() : 0d;
563
 
592
 
564
//          this month tertiary----------
593
//          this month tertiary----------
565
 
594
 
566
            LocalDateTime now = LocalDateTime.now();
595
            LocalDateTime now = LocalDateTime.now();
567
            double todaySale = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday, now, fofoId, false).get(fofoId);
596
            double todaySale = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday, now, fofoId, false).get(fofoId);
Line 583... Line 612...
583
 
612
 
584
            double lastMonthNetSecondary = lastMonthSecondaryAchieved - lastMonthReturn;
613
            double lastMonthNetSecondary = lastMonthSecondaryAchieved - lastMonthReturn;
585
 
614
 
586
            double lastMonthSecondaryPercent = lastMonthSecondaryTarget == 0 ? 0.0 : (lastMonthSecondaryAchieved / lastMonthSecondaryTarget) * 100;
615
            double lastMonthSecondaryPercent = lastMonthSecondaryTarget == 0 ? 0.0 : (lastMonthSecondaryAchieved / lastMonthSecondaryTarget) * 100;
587
 
616
 
588
            double lastMonthUnbilled = 0;
617
            double lastMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(lastMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(lastMonth).getTotalUnbilledAmount() : 0d;
589
 
618
 
590
//           last month tertiary
619
//           last month tertiary
591
            Double lastMonthSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
620
            Double lastMonthSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
592
                    lastMontStartDate, lastMonthEndDate, fofoId, false).get(fofoId);
621
                    lastMontStartDate, lastMonthEndDate, fofoId, false).get(fofoId);
593
 
622
 
Line 606... Line 635...
606
 
635
 
607
            double twoMonthAgoNetSecondary = twoMonthAgoSecondaryAchieved - twoMonthAgoReturn;
636
            double twoMonthAgoNetSecondary = twoMonthAgoSecondaryAchieved - twoMonthAgoReturn;
608
 
637
 
609
            double twoMonthAgoSecondaryPercent = twoMonthAgoSecondaryTarget == 0 ? 0.0 : (twoMonthAgoSecondaryAchieved / twoMonthAgoSecondaryTarget) * 100;
638
            double twoMonthAgoSecondaryPercent = twoMonthAgoSecondaryTarget == 0 ? 0.0 : (twoMonthAgoSecondaryAchieved / twoMonthAgoSecondaryTarget) * 100;
610
 
639
 
611
            double twoMonthAgoUnbilled = 0;
640
            double twoMonthAgoUnbilled = partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo) != null ? partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo).getTotalUnbilledAmount() : 0d;
612
 
641
 
613
//          second Month Tertiary
642
//          second Month Tertiary
614
            double twoMonthAgoSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
643
            double twoMonthAgoSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
615
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate, fofoId, false).get(fofoId);
644
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate, fofoId, false).get(fofoId);
616
 
645
 
Line 664... Line 693...
664
            fofoTotalStockPriceMap.put(fofoId,totalStockPrice);
693
            fofoTotalStockPriceMap.put(fofoId,totalStockPrice);
665
 
694
 
666
            Map<String, Double> brandMtdTertiaryAmount = fofoOrderItemRepository.selectSumAmountGroupByBrand(
695
            Map<String, Double> brandMtdTertiaryAmount = fofoOrderItemRepository.selectSumAmountGroupByBrand(
667
                    currentMonthStartDate, currentMonthEndDate, fofoId);
696
                    currentMonthStartDate, currentMonthEndDate, fofoId);
668
 
697
 
669
            fofoBrandTertiaryMap.put(fofoId,brandMtdTertiaryAmount);
698
            fofoBrandMtdTertiaryMap.put(fofoId,brandMtdTertiaryAmount);
670
 
699
 
671
            double totalMtdTertiaryAmount = brandMtdTertiaryAmount.values().stream().mapToDouble(Double::doubleValue).sum();
700
            double totalMtdTertiaryAmount = brandMtdTertiaryAmount.values().stream().mapToDouble(Double::doubleValue).sum();
672
 
701
 
673
            fofoTotalTertiaryMap.put(fofoId,totalMtdTertiaryAmount);
702
            fofoTotalMtdTertiaryMap.put(fofoId,totalMtdTertiaryAmount);
-
 
703
 
-
 
704
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledOrderGroupByBrandFofoId(fofoId, currentMonthStartDate);
-
 
705
            Map<String,Long> brandWiseMtdSecondaryMap = brandWiseMtdSecondary.stream().collect(Collectors.toMap(BrandWiseModel::getBrand,BrandWiseModel::getAmount));
-
 
706
            fofoBrandWiseMtdSecondaryMap.put(fofoId,brandWiseMtdSecondaryMap);
-
 
707
 
-
 
708
            long mtdTotalSecondary = brandWiseMtdSecondary.stream().mapToLong(x -> x.getAmount() != 0 ? x.getAmount() : 0L).sum();
-
 
709
 
-
 
710
            fofoTotalMtdSecondaryMap.put(fofoId,mtdTotalSecondary);
-
 
711
 
-
 
712
            //            generate investment info
-
 
713
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
-
 
714
            float shortInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getShortInvestment() : 0f;
-
 
715
            float agreedInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getMinInvestment() : 0f;
-
 
716
            float investmentLevel = partnerDailyInvestmentMap.get(fofoId) != null ? ((shortInvestment-agreedInvestment)/agreedInvestment)*100 : 0f;
-
 
717
 
-
 
718
            List<Loan> fofoDefaultLoans = new ArrayList<>();
-
 
719
            if(defaultLoanMap != null){
-
 
720
                 fofoDefaultLoans  =  defaultLoanMap.get(fofoId);
-
 
721
                LOGGER.info("fofoDefaultLoans {}",fofoDefaultLoans);
-
 
722
            }
-
 
723
 
-
 
724
            float defaultLoanAmount = 0f;
-
 
725
            if(fofoDefaultLoans != null ){
-
 
726
                if (!fofoDefaultLoans.isEmpty()) {
-
 
727
                    defaultLoanAmount =  fofoDefaultLoans.stream().map(Loan::getPendingAmount).reduce(BigDecimal.ZERO, BigDecimal::add).floatValue(); // or .floatValue() directly
-
 
728
                }
-
 
729
            }
-
 
730
 
-
 
731
            float activeLoan = loanRepository.selectActiveLoan(fofoId).stream().map(Loan::getPendingAmount).reduce(BigDecimal.ZERO,BigDecimal::add).floatValue();
-
 
732
 
-
 
733
 
-
 
734
            float poValue = partnerDailyInvestmentMap.get(fofoId) != null ?  partnerDailyInvestmentMap.get(fofoId).getUnbilledAmount() : 0f;
-
 
735
 
-
 
736
            List<Order> billedAndPoOrder = orderRepository.selectOrders(Arrays.asList(fofoId),Arrays.asList(OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.ACCEPTED, OrderStatus.BILLED, OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERY_SUCCESS),startOfToday,startOfToday.plusDays(1));
-
 
737
            float poAndBilledValue = (float) billedAndPoOrder.stream().map(Order::getTotalAmount).reduce(0f,Float::sum);
-
 
738
 
-
 
739
            double purchaseMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
-
 
740
 
-
 
741
            double todayRequiredDrr = rbmTargetService.calculateFofoIdTodayTarget(fofoId, purchaseMtd,LocalDate.now());
-
 
742
 
-
 
743
            double monthDay1Drr = rbmTargetService.calculateFofoIdTodayTarget(fofoId,0d,YearMonth.now().atDay(1));
-
 
744
 
-
 
745
 
-
 
746
            double gotDrrPercent = (todayRequiredDrr / monthDay1Drr) * 100;
-
 
747
 
-
 
748
            int orderId = orderRepository.getLastOrderByFofoId(fofoId);
674
 
749
 
-
 
750
            if (orderId != 0) {
675
//            List<BrandWiseModel> brandMtdSecondary = orderRepository.selectAllBilledOrderGroupByBrandFofoId(fofoId, curDate.withDayOfMonth(1).minusMonths(6));
751
                Order order = orderRepository.selectById(orderId);
676
 
752
 
-
 
753
                // Calculate the number of days since the last purchase (billing)
-
 
754
                int lastPurchaseDays = (int) Duration.between(order.getCreateTimestamp().plusDays(1), LocalDateTime.now()).toDays();
-
 
755
 
-
 
756
                // Determine alert level
-
 
757
                String alertLevel = "";
-
 
758
                if (lastPurchaseDays >= 11) {
-
 
759
                    alertLevel = "Alert for Management";
-
 
760
                } else if (lastPurchaseDays >= 8) {
-
 
761
                    alertLevel = " Alert for RSM/SH";
-
 
762
                } else if (lastPurchaseDays >= 6) {
-
 
763
                    alertLevel = "Must be Billed";
-
 
764
                } else if (lastPurchaseDays >= 3) {
-
 
765
                    alertLevel = "OK";
-
 
766
                } else {
-
 
767
                    alertLevel = "No Action Needed";
-
 
768
                }
-
 
769
 
-
 
770
 
-
 
771
                //          investment modal set all related value
-
 
772
                FofoInvestmentModel fofoInvestmentModel = new FofoInvestmentModel();
-
 
773
 
-
 
774
                fofoInvestmentModel.setCounterPotential(fofoStore.getCounterPotential());
-
 
775
                fofoInvestmentModel.setShortInvestment(shortInvestment);
-
 
776
                fofoInvestmentModel.setDefaultLoan(defaultLoanAmount);
-
 
777
                fofoInvestmentModel.setInvestmentLevel(investmentLevel);
-
 
778
                fofoInvestmentModel.setActiveLoan(activeLoan);
-
 
779
                fofoInvestmentModel.setPoValue(poValue);
-
 
780
                fofoInvestmentModel.setPoAndBilled(poAndBilledValue);
-
 
781
                fofoInvestmentModel.setAgreedInvestment(agreedInvestment);
-
 
782
                fofoInvestmentModel.setWallet(partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getWalletAmount() : 0);
-
 
783
                fofoInvestmentModel.setMonthBeginingDrr(monthDay1Drr);
-
 
784
                fofoInvestmentModel.setRequiredDrr(todayRequiredDrr);
-
 
785
                fofoInvestmentModel.setDrrPercent(gotDrrPercent);
-
 
786
                fofoInvestmentModel.setLastBillingDone(lastPurchaseDays);
-
 
787
                fofoInvestmentModel.setSlab(alertLevel);
-
 
788
 
-
 
789
                biInvestmentModelMap.put(fofoId, fofoInvestmentModel);
-
 
790
            }
-
 
791
                String assessment = "";
-
 
792
                if(defaultLoanAmount > 0 ){
-
 
793
                    assessment = "Loan Default";
-
 
794
                }else if(investmentLevel <= 75 && defaultLoanAmount < 1){
-
 
795
                    assessment = "Low Invest";
-
 
796
                }else {
-
 
797
                    assessment = "-";
-
 
798
                }
-
 
799
                assessmentMap.put(fofoId,assessment);
-
 
800
 
-
 
801
                String zeroBilling = "";
-
 
802
                if(currentMonthNetSecondary <= 100000 ){
-
 
803
                    zeroBilling = "Zero Billing";
-
 
804
                }else {
-
 
805
                    zeroBilling = "-";
-
 
806
                }
-
 
807
                zeroBillingMap.put(fofoId,zeroBilling);
-
 
808
 
-
 
809
                float billingNeeded = 0f;
-
 
810
                if(gotDrrPercent >= 110 ){
-
 
811
                    billingNeeded = (float) todayRequiredDrr;
-
 
812
                }else {
-
 
813
                    billingNeeded = 0f;
-
 
814
                }
-
 
815
                billingNeededMap.put(fofoId,billingNeeded);
-
 
816
 
-
 
817
                int counta = 0;
-
 
818
                if(defaultLoanAmount > 0 || investmentLevel <= 75 || currentMonthNetSecondary <= 100000 || gotDrrPercent >= 110 ){
-
 
819
                    counta = 1;
-
 
820
                }else {
-
 
821
                    counta = 0;
-
 
822
                }
-
 
823
                countAMap.put(fofoId,counta);
677
 
824
 
678
        }
825
        }
679
 
826
 
680
        LOGGER.info("Total BI Retailers processed: {}", biRetailerModelMap.size());
827
        LOGGER.info("Total BI Retailers processed: {}", biRetailerModelMap.size());
681
 
828
 
682
        //generate excel and sent to mail
829
        //generate excel and sent to mail
683
        List<List<String>> headerGroup = new ArrayList<>();
830
        List<List<String>> headerGroup = new ArrayList<>();
684
 
831
 
685
        List<String> headers1 = Arrays.asList(
832
        List<String> headers1 = Arrays.asList(
-
 
833
                "","","","",
686
                "Retailer Detail", "", "", "", "", "", "", "", "", "",
834
                "Retailer Detail", "", "", "", "", "", "", "", "",
687
                currentMonthStringValue, "", "", "", "", "", "",
835
                currentMonthStringValue, "", "", "", "", "", "",
688
                lastMonthStringValue, "", "", "", "", "", "",
836
                lastMonthStringValue, "", "", "", "", "", "",
689
                twoMonthAgoStringValue, "", "", "", "", "", ""
837
                twoMonthAgoStringValue, "", "", "", "", "", "",
-
 
838
 
-
 
839
                "","", "", "", "", "", "", "", "", "", "", "", "", "",
-
 
840
 
-
 
841
                "", "", "", "", "", "", "", "", "", "", "", "", "",
-
 
842
                "", "", "", "", "", "", "", "", "", "", "", "", ""
-
 
843
 
690
        );
844
        );
691
 
845
 
692
        List<String> headers2 = Arrays.asList(
846
        List<String> headers2 = Arrays.asList(
-
 
847
                "Assessment","Zero billing","Billing needed","Counta",
693
                "Code", "Store Name", "City", "Area", "BM", "Sales Manager", "RBM", "Status", "Category",
848
                "Code", "Store Name", "City", "Area", "BM", "Sales Manager", "RBM", "Status", "Category",
694
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
849
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
695
                "Tertiary Sale", "Unbilled",
850
                "Tertiary Sale", "Unbilled",
696
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
851
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
697
                "Tertiary Sale", "Unbilled",
852
                "Tertiary Sale", "Unbilled",
698
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
853
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
699
                "Tertiary Sale", "Unbilled",
854
                "Tertiary Sale", "Unbilled",
-
 
855
                "Counter Potential", "Short investment", "Default", "INVESTMENT LEVEL", "Loan", "PO value", "Agreed investment",
-
 
856
                "Wallet", "po+bill", "MONTH BEGINNING DRR", "REQ DRR", "Drr %", "Last billing Done", "Slab",
700
 
857
 
701
              "Total Stock",  "Apple","Xiaomi","Vivo","Tecno","Samsung","Realme","Oppo","OnePlus","Poco","Lava","Itel","Almost New"
858
              "Total Stock",  "Apple","Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "Poco", "Lava", "Itel", "Almost New",
-
 
859
              "Total Secondary", "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "Poco", "Lava", "Itel", "Almost New",
-
 
860
              "Total Tertiary",  "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "Poco", "Lava", "Itel", "Almost New"
702
        );
861
        );
703
 
862
 
704
        headerGroup.add(headers1);
863
        headerGroup.add(headers1);
705
        headerGroup.add(headers2);
864
        headerGroup.add(headers2);
706
 
865
 
707
 
866
 
708
        List<List<?>> rows = new ArrayList<>();
867
        List<List<?>> rows = new ArrayList<>();
709
        for (Map.Entry<Integer, BIRetailerModel> entry : biRetailerModelMap.entrySet()) {
868
        for (Map.Entry<Integer, BIRetailerModel> entry : biRetailerModelMap.entrySet()) {
710
            Integer fofoId = entry.getKey();
869
            Integer fofoId = entry.getKey();
711
            BIRetailerModel retailer = entry.getValue();
870
            BIRetailerModel retailer = entry.getValue();
-
 
871
 
712
            Map<YearMonth, BiSecondaryModel> monthlyData = allRetailerMonthlyData.get(fofoId);
872
            Map<YearMonth, BiSecondaryModel> monthlyData = allRetailerMonthlyData.get(fofoId);
713
 
873
 
714
            BiSecondaryModel current = monthlyData.getOrDefault(YearMonth.now(), new BiSecondaryModel(0,0,0,0,0,0,0));
874
            BiSecondaryModel current = monthlyData.getOrDefault(YearMonth.now(), new BiSecondaryModel(0,0,0,0,0,0,0));
715
            BiSecondaryModel last = monthlyData.getOrDefault(YearMonth.now().minusMonths(1), new BiSecondaryModel(0,0,0,0,0,0,0));
875
            BiSecondaryModel last = monthlyData.getOrDefault(YearMonth.now().minusMonths(1), new BiSecondaryModel(0,0,0,0,0,0,0));
716
            BiSecondaryModel twoAgo = monthlyData.getOrDefault(YearMonth.now().minusMonths(2), new BiSecondaryModel(0,0,0,0,0,0,0));
876
            BiSecondaryModel twoAgo = monthlyData.getOrDefault(YearMonth.now().minusMonths(2), new BiSecondaryModel(0,0,0,0,0,0,0));
717
 
877
 
718
            List<Object> row = new ArrayList<>();
878
            List<Object> row = new ArrayList<>();
719
            row.addAll(Arrays.asList(
879
            row.addAll(Arrays.asList(
-
 
880
                    assessmentMap.get(fofoId),zeroBillingMap.get(fofoId),billingNeededMap.get(fofoId),countAMap.get(fofoId),
720
                    retailer.getCode(), retailer.getStoreName(), retailer.getCity(), retailer.getArea(),
881
                    retailer.getCode(), retailer.getStoreName(), retailer.getCity(), retailer.getArea(),
721
                    retailer.getBmName(), retailer.getSalesManager(), retailer.getRbm(),
882
                    retailer.getBmName(), retailer.getSalesManager(), retailer.getRbm(),
722
                    retailer.getStatus(), retailer.getCategory()
883
                    retailer.getStatus(), retailer.getCategory()
723
            ));
884
            ));
724
 
885
 
Line 752... Line 913...
752
                    twoAgo.getNetSecondary(),
913
                    twoAgo.getNetSecondary(),
753
                    twoAgo.getSecondaryAchievedPercent(),
914
                    twoAgo.getSecondaryAchievedPercent(),
754
                    twoAgo.getTertiary(),
915
                    twoAgo.getTertiary(),
755
                    twoAgo.getTertiaryUnBilled()
916
                    twoAgo.getTertiaryUnBilled()
756
            ));
917
            ));
-
 
918
            FofoInvestmentModel fofoInvestmentModelValue = biInvestmentModelMap.get(fofoId);
-
 
919
            if(fofoInvestmentModelValue != null){
-
 
920
                row.addAll(Arrays.asList(
-
 
921
                        fofoInvestmentModelValue.getCounterPotential(),
-
 
922
                        fofoInvestmentModelValue.getShortInvestment(),
-
 
923
                        fofoInvestmentModelValue.getDefaultLoan(),
-
 
924
                        fofoInvestmentModelValue.getInvestmentLevel(),
-
 
925
                        fofoInvestmentModelValue.getActiveLoan(),
-
 
926
                        fofoInvestmentModelValue.getPoValue(),
-
 
927
                        fofoInvestmentModelValue.getAgreedInvestment(),
-
 
928
                        fofoInvestmentModelValue.getWallet(),
-
 
929
                        fofoInvestmentModelValue.getPoAndBilled(),
-
 
930
                        fofoInvestmentModelValue.getMonthBeginingDrr(),
-
 
931
                        fofoInvestmentModelValue.getRequiredDrr(),
-
 
932
                        fofoInvestmentModelValue.getDrrPercent(),
-
 
933
                        fofoInvestmentModelValue.getLastBillingDone(),
-
 
934
                        fofoInvestmentModelValue.getSlab()
-
 
935
                ));
-
 
936
            }else {
-
 
937
                row.addAll(Arrays.asList(
-
 
938
                        "-","-","-","-","-","-","-","-","-","-","-",""
-
 
939
                ));
-
 
940
            }
-
 
941
 
757
            Map<String, BrandStockPrice> brandMap = fofoBrandStockPriceMap.get(fofoId);
942
            Map<String, BrandStockPrice> brandStockMap = fofoBrandStockPriceMap.get(fofoId);
758
            row.addAll(Arrays.asList(
943
            row.addAll(Arrays.asList(
759
                    fofoTotalStockPriceMap.getOrDefault(fofoId, 0.0),
944
                    fofoTotalStockPriceMap.getOrDefault(fofoId, 0.0),
760
                    brandMap.get("Apple") != null ? brandMap.get("Apple").getTotalValue() : 0.0,
945
                    brandStockMap.get("Apple") != null ? brandStockMap.get("Apple").getTotalValue() : 0.0,
761
                    brandMap.get("Xiaomi") != null ? brandMap.get("Xiaomi").getTotalValue() : 0.0,
946
                    brandStockMap.get("Xiaomi") != null ? brandStockMap.get("Xiaomi").getTotalValue() : 0.0,
762
                    brandMap.get("Vivo") != null ? brandMap.get("Vivo").getTotalValue() : 0.0,
947
                    brandStockMap.get("Vivo") != null ? brandStockMap.get("Vivo").getTotalValue() : 0.0,
763
                    brandMap.get("Tecno") != null ? brandMap.get("Tecno").getTotalValue() : 0.0,
948
                    brandStockMap.get("Tecno") != null ? brandStockMap.get("Tecno").getTotalValue() : 0.0,
764
                    brandMap.get("Samsung") != null ? brandMap.get("Samsung").getTotalValue() : 0.0,
949
                    brandStockMap.get("Samsung") != null ? brandStockMap.get("Samsung").getTotalValue() : 0.0,
765
                    brandMap.get("Realme") != null ? brandMap.get("Realme").getTotalValue() : 0.0,
950
                    brandStockMap.get("Realme") != null ? brandStockMap.get("Realme").getTotalValue() : 0.0,
766
                    brandMap.get("Oppo") != null ? brandMap.get("Oppo").getTotalValue() : 0.0,
951
                    brandStockMap.get("Oppo") != null ? brandStockMap.get("Oppo").getTotalValue() : 0.0,
767
                    brandMap.get("OnePlus") != null ? brandMap.get("OnePlus").getTotalValue() : 0.0,
952
                    brandStockMap.get("OnePlus") != null ? brandStockMap.get("OnePlus").getTotalValue() : 0.0,
768
                    brandMap.get("Poco") != null ? brandMap.get("Poco").getTotalValue() : 0.0,
953
                    brandStockMap.get("Poco") != null ? brandStockMap.get("Poco").getTotalValue() : 0.0,
769
                    brandMap.get("Lava") != null ? brandMap.get("Lava").getTotalValue() : 0.0,
954
                    brandStockMap.get("Lava") != null ? brandStockMap.get("Lava").getTotalValue() : 0.0,
770
                    brandMap.get("Itel") != null ? brandMap.get("Itel").getTotalValue() : 0.0,
955
                    brandStockMap.get("Itel") != null ? brandStockMap.get("Itel").getTotalValue() : 0.0,
771
                    brandMap.get("Almost New") != null ? brandMap.get("Almost New").getTotalValue() : 0.0
956
                    brandStockMap.get("Almost New") != null ? brandStockMap.get("Almost New").getTotalValue() : 0.0
772
            ));
957
            ));
773
 
958
 
-
 
959
            Map<String, Long> brandSecondaryMap = fofoBrandWiseMtdSecondaryMap.get(fofoId);
-
 
960
            row.addAll(Arrays.asList(
-
 
961
                    current.getSecondaryAchieved(),
-
 
962
                    brandSecondaryMap.getOrDefault("Apple", 0L),
-
 
963
                    brandSecondaryMap.getOrDefault("Xiaomi", 0L),
-
 
964
                    brandSecondaryMap.getOrDefault("Vivo", 0L),
-
 
965
                    brandSecondaryMap.getOrDefault("Tecno", 0L),
-
 
966
                    brandSecondaryMap.getOrDefault("Samsung", 0L),
-
 
967
                    brandSecondaryMap.getOrDefault("Realme", 0L),
-
 
968
                    brandSecondaryMap.getOrDefault("Oppo", 0L),
-
 
969
                    brandSecondaryMap.getOrDefault("OnePlus", 0L),
-
 
970
                    brandSecondaryMap.getOrDefault("Poco", 0L),
-
 
971
                    brandSecondaryMap.getOrDefault("Lava", 0L),
-
 
972
                    brandSecondaryMap.getOrDefault("Itel", 0L),
-
 
973
                    brandSecondaryMap.getOrDefault("Almost New", 0L)
-
 
974
            ));
-
 
975
            rows.add(row);
-
 
976
 
-
 
977
            Map<String, Double> brandTertiaryMap = fofoBrandMtdTertiaryMap.get(fofoId);
-
 
978
            row.addAll(Arrays.asList(
-
 
979
                    current.getTertiary(),
-
 
980
                    brandTertiaryMap.getOrDefault("Apple", 0d),
-
 
981
                    brandTertiaryMap.getOrDefault("Xiaomi", 0d),
-
 
982
                    brandTertiaryMap.getOrDefault("Vivo", 0d),
-
 
983
                    brandTertiaryMap.getOrDefault("Tecno", 0d),
-
 
984
                    brandTertiaryMap.getOrDefault("Samsung", 0d),
-
 
985
                    brandTertiaryMap.getOrDefault("Realme", 0d),
-
 
986
                    brandTertiaryMap.getOrDefault("Oppo", 0d),
-
 
987
                    brandTertiaryMap.getOrDefault("OnePlus", 0d),
-
 
988
                    brandTertiaryMap.getOrDefault("Poco", 0d),
-
 
989
                    brandTertiaryMap.getOrDefault("Lava", 0d),
-
 
990
                    brandTertiaryMap.getOrDefault("Itel", 0d),
-
 
991
                    brandTertiaryMap.getOrDefault("Almost New", 0d)
-
 
992
            ));
774
            rows.add(row);
993
            rows.add(row);
775
        }
994
        }
776
 
995
 
777
 
996
 
778
// Send to email
997
        // Send to email
779
        ByteArrayOutputStream csvStream = FileUtil.getCSVByteStreamWithMultiHeaders(headerGroup, rows);
998
//        ByteArrayOutputStream csvStream = FileUtil.getCSVByteStreamWithMultiHeaders(headerGroup, rows);
-
 
999
        ByteArrayOutputStream csvStream = getExcelStreamWithMultiHeaders(headerGroup, rows);
780
        String fileName = "BI-Retailer-Monthly-Report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".csv";
1000
        String fileName = "BI-Retailer-Monthly-Report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".xlsx";
781
        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com"};
1001
        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com"};
782
 
1002
 
783
        Utils.sendMailWithAttachment(googleMailSender, sendToArray, new String[]{}, "BI Retailer Monthly Report", "Please find attached the BI retailer secondary/tertiary monthly report.", fileName, new ByteArrayResource(csvStream.toByteArray()));
1003
        Utils.sendMailWithAttachment(googleMailSender, sendToArray, new String[]{}, "BI Retailer Monthly Report", "Please find attached the BI retailer secondary/tertiary monthly report.", fileName, new ByteArrayResource(csvStream.toByteArray()));
784
 
1004
 
785
 
1005
 
786
    }
1006
    }
787
 
1007
 
-
 
1008
    public static ByteArrayOutputStream getExcelStreamWithMultiHeaders(List<List<String>> headerGroup, List<List<?>> rows) {
-
 
1009
        Workbook workbook = new XSSFWorkbook();
-
 
1010
        Sheet sheet = workbook.createSheet("BI Report");
-
 
1011
        int rowIndex = 0;
-
 
1012
 
-
 
1013
        CellStyle centeredStyle = workbook.createCellStyle();
-
 
1014
        centeredStyle.setAlignment(HorizontalAlignment.CENTER); // Center horizontally
-
 
1015
        centeredStyle.setVerticalAlignment(VerticalAlignment.CENTER); // Center vertically
-
 
1016
 
-
 
1017
    // Optional: bold font
-
 
1018
        Font font1 = workbook.createFont();
-
 
1019
        font1.setBold(true);
-
 
1020
        centeredStyle.setFont(font1);
-
 
1021
 
-
 
1022
 
-
 
1023
 
-
 
1024
        // Create styles
-
 
1025
        Map<String, CellStyle> headerStyles = new HashMap<>();
-
 
1026
 
-
 
1027
        // fontPurpleStyle
-
 
1028
        CellStyle purpleStyle = workbook.createCellStyle();
-
 
1029
        purpleStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
-
 
1030
        purpleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
-
 
1031
        purpleStyle.setFont(font1);
-
 
1032
        headerStyles.put("Assessment", purpleStyle);
-
 
1033
        headerStyles.put("Zero billing", purpleStyle);
-
 
1034
        headerStyles.put("Billing needed", purpleStyle);
-
 
1035
        headerStyles.put("Counta", purpleStyle);
-
 
1036
        headerStyles.put("MONTH BEGINNING DRR", purpleStyle);
-
 
1037
        headerStyles.put("REQ DRR", purpleStyle);
-
 
1038
        headerStyles.put("Drr %", purpleStyle);
-
 
1039
 
-
 
1040
        // Light Blue
-
 
1041
        CellStyle blueStyle = workbook.createCellStyle();
-
 
1042
        blueStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
-
 
1043
        blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
-
 
1044
        blueStyle.setFont(font1);
-
 
1045
        headerStyles.put("Code", blueStyle);
-
 
1046
        headerStyles.put("Store Name", blueStyle);
-
 
1047
        headerStyles.put("City", blueStyle);
-
 
1048
        headerStyles.put("Area", blueStyle);
-
 
1049
        headerStyles.put("BM", blueStyle);
-
 
1050
        headerStyles.put("RBM", blueStyle);
-
 
1051
        headerStyles.put("Sales Manager", blueStyle);
-
 
1052
        headerStyles.put("Status", blueStyle);
-
 
1053
        headerStyles.put("Category", blueStyle);
-
 
1054
 
-
 
1055
        // Light Yellow
-
 
1056
        CellStyle yellowStyle = workbook.createCellStyle();
-
 
1057
        yellowStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
-
 
1058
        yellowStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
-
 
1059
        yellowStyle.setFont(font1);
-
 
1060
        headerStyles.put("Last billing Done", yellowStyle);
-
 
1061
        headerStyles.put("Total Stock", yellowStyle);
-
 
1062
 
-
 
1063
        // Light Orange
-
 
1064
        CellStyle orangeStyle = workbook.createCellStyle();
-
 
1065
        orangeStyle.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
-
 
1066
        orangeStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
-
 
1067
        orangeStyle.setFont(font1);
-
 
1068
        headerStyles.put("Total Tertiary", orangeStyle);
-
 
1069
        headerStyles.put("Total Secondary", orangeStyle);
-
 
1070
        headerStyles.put("Default", orangeStyle);
-
 
1071
 
-
 
1072
 
-
 
1073
        // Light green
-
 
1074
        CellStyle lightGreenStyle = workbook.createCellStyle();
-
 
1075
        lightGreenStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
-
 
1076
        lightGreenStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
-
 
1077
        lightGreenStyle.setFont(font1);
-
 
1078
        headerStyles.put("Short investment", lightGreenStyle);
-
 
1079
        headerStyles.put("INVESTMENT LEVEL", lightGreenStyle);
-
 
1080
        headerStyles.put("Loan", lightGreenStyle);
-
 
1081
        headerStyles.put("PO value", lightGreenStyle);
-
 
1082
        headerStyles.put("Agreed investment", lightGreenStyle);
-
 
1083
        headerStyles.put("Wallet", lightGreenStyle);
-
 
1084
        headerStyles.put("po+bill", lightGreenStyle);
-
 
1085
 
-
 
1086
        // Light Green
-
 
1087
        CellStyle secondary1 = createStyle(workbook, IndexedColors.LIGHT_GREEN);
-
 
1088
        CellStyle secondary2 = createStyle(workbook, IndexedColors.LIGHT_YELLOW);
-
 
1089
        CellStyle secondary3 = createStyle(workbook, IndexedColors.LIGHT_ORANGE);
-
 
1090
 
-
 
1091
        Map<String, CellStyle> brandStyles = new HashMap<>();
-
 
1092
        brandStyles.put("Apple", createStyle(workbook, IndexedColors.GREY_25_PERCENT));
-
 
1093
        brandStyles.put("Xiaomi", createStyle(workbook, IndexedColors.ORANGE));
-
 
1094
        brandStyles.put("Vivo", createStyle(workbook, IndexedColors.SKY_BLUE));
-
 
1095
        brandStyles.put("Tecno", createStyle(workbook, IndexedColors.LIGHT_BLUE));
-
 
1096
        brandStyles.put("Samsung", createStyle(workbook, IndexedColors.ROYAL_BLUE));
-
 
1097
        brandStyles.put("Realme", createStyle(workbook, IndexedColors.YELLOW));
-
 
1098
        brandStyles.put("Oppo", createStyle(workbook, IndexedColors.LIGHT_GREEN));
-
 
1099
        brandStyles.put("OnePlus", createStyle(workbook, IndexedColors.RED));
-
 
1100
        brandStyles.put("Poco", createStyle(workbook, IndexedColors.ORANGE));
-
 
1101
        brandStyles.put("Lava", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
-
 
1102
        brandStyles.put("Itel", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
-
 
1103
        brandStyles.put("Almost New", createStyle(workbook, IndexedColors.WHITE));
-
 
1104
 
-
 
1105
 
-
 
1106
        CellStyle defaultHeaderStyle = workbook.createCellStyle();
-
 
1107
        defaultHeaderStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
-
 
1108
        defaultHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
-
 
1109
        defaultHeaderStyle.setFont(font1);
-
 
1110
 
-
 
1111
 
-
 
1112
        Map<String, Integer> headerCount = new HashMap<>();
-
 
1113
 
-
 
1114
        for (int headerRowIndex = 0; headerRowIndex < headerGroup.size(); headerRowIndex++) {
-
 
1115
            List<String> headerRow = headerGroup.get(headerRowIndex);
-
 
1116
            Row row = sheet.createRow(rowIndex++);
-
 
1117
 
-
 
1118
            for (int i = 0; i < headerRow.size(); i++) {
-
 
1119
                String headerText = headerRow.get(i);
-
 
1120
                sheet.setColumnWidth(i, 25 * 256);
-
 
1121
                row.setHeightInPoints(20); // 25-point height
-
 
1122
                Cell cell = row.createCell(i);
-
 
1123
                cell.setCellValue(headerText);
-
 
1124
                cell.setCellStyle(centeredStyle);
-
 
1125
                // Count how many times this header has appeared
-
 
1126
                int count = headerCount.getOrDefault(headerText, 0) + 1;
-
 
1127
                headerCount.put(headerText, count);
-
 
1128
                // Apply special style for repeated headers
-
 
1129
                if (headerText.equals("Secondary Target") || headerText.equals("Secondary Achieved") || headerText.equals("Returns") || headerText.equals("Net Secondary") || headerText.equals("Secondary %") || headerText.equals("Tertiary Sale") || headerText.equals("Unbilled")) {
-
 
1130
                    if (count == 1) {
-
 
1131
                        cell.setCellStyle(secondary1);
-
 
1132
                    } else if (count == 2) {
-
 
1133
                        cell.setCellStyle(secondary2);
-
 
1134
                    } else if (count == 3) {
-
 
1135
                        cell.setCellStyle(secondary3);
-
 
1136
                    }
-
 
1137
                }
-
 
1138
                // Brand header styling (apply only for the 2nd row of headers)
-
 
1139
                else if (headerRowIndex == 1 && brandStyles.containsKey(headerText)) {
-
 
1140
                    cell.setCellStyle(brandStyles.get(headerText));
-
 
1141
                }else if (headerStyles.containsKey(headerText)) {
-
 
1142
                    cell.setCellStyle(headerStyles.get(headerText));
-
 
1143
                } else {
-
 
1144
                    cell.setCellStyle(defaultHeaderStyle); // default style for others
-
 
1145
                }
-
 
1146
            }
-
 
1147
        }
-
 
1148
 
-
 
1149
        // Write data rows
-
 
1150
        for (List<?> dataRow : rows) {
-
 
1151
            Row row = sheet.createRow(rowIndex++);
-
 
1152
            for (int i = 0; i < dataRow.size(); i++) {
-
 
1153
                Cell cell = row.createCell(i);
-
 
1154
                Object value = dataRow.get(i);
-
 
1155
                if (value instanceof Number) {
-
 
1156
                    cell.setCellValue(((Number) value).doubleValue());
-
 
1157
                } else {
-
 
1158
                    cell.setCellValue(value != null ? value.toString() : "");
-
 
1159
                }
-
 
1160
            }
-
 
1161
        }
-
 
1162
 
-
 
1163
        // Auto-size columns
-
 
1164
        if (!rows.isEmpty()) {
-
 
1165
            for (int i = 0; i < rows.get(0).size(); i++) {
-
 
1166
                sheet.autoSizeColumn(i);
-
 
1167
            }
-
 
1168
        }
-
 
1169
 
-
 
1170
        // Output as ByteArray
-
 
1171
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
-
 
1172
            workbook.write(outputStream);
-
 
1173
            workbook.close();
-
 
1174
            return outputStream;
-
 
1175
        } catch (IOException e) {
-
 
1176
            throw new RuntimeException("Failed to generate Excel file", e);
-
 
1177
        }
-
 
1178
    }
-
 
1179
 
-
 
1180
 
-
 
1181
    private static CellStyle createStyle(Workbook workbook, IndexedColors color) {
-
 
1182
        CellStyle style = workbook.createCellStyle();
-
 
1183
        style.setFillForegroundColor(color.getIndex());
-
 
1184
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
-
 
1185
        Font font = workbook.createFont();
-
 
1186
        font.setBold(true);
-
 
1187
        style.setFont(font);
-
 
1188
        return style;
-
 
1189
    }
788
 
1190
 
789
 
1191
 
790
 
1192
 
791
 
1193
 
792
}
1194
}