Subversion Repositories SmartDukaan

Rev

Rev 34729 | Rev 34738 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
34306 ranu 1
package com.smartdukaan.cron.scheduled;
2
 
3
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
34619 ranu 4
import com.spice.profitmandi.common.model.BrandStockPrice;
34606 ranu 5
import com.spice.profitmandi.common.model.CustomRetailer;
34321 ranu 6
import com.spice.profitmandi.common.model.ProfitMandiConstants;
34619 ranu 7
import com.spice.profitmandi.common.util.FormattingUtils;
8
import com.spice.profitmandi.common.util.Utils;
34450 ranu 9
import com.spice.profitmandi.dao.cart.SmartCartService;
34321 ranu 10
import com.spice.profitmandi.dao.entity.auth.AuthUser;
34606 ranu 11
import com.spice.profitmandi.dao.entity.fofo.*;
12
import com.spice.profitmandi.dao.entity.logistics.AST;
13
import com.spice.profitmandi.dao.entity.logistics.ASTRepository;
34619 ranu 14
import com.spice.profitmandi.dao.entity.transaction.*;
34321 ranu 15
import com.spice.profitmandi.dao.entity.user.User;
16
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
34619 ranu 17
import com.spice.profitmandi.dao.enumuration.transaction.LoanReferenceType;
34641 ranu 18
import com.spice.profitmandi.dao.model.*;
34606 ranu 19
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
34321 ranu 20
import com.spice.profitmandi.dao.repository.cs.CsService;
21
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
34606 ranu 22
import com.spice.profitmandi.dao.repository.fofo.*;
23
import com.spice.profitmandi.dao.repository.inventory.StateRepository;
34619 ranu 24
import com.spice.profitmandi.dao.repository.transaction.*;
34321 ranu 25
import com.spice.profitmandi.dao.repository.user.UserRepository;
34655 ranu 26
import com.spice.profitmandi.service.PartnerStatsService;
34641 ranu 27
import com.spice.profitmandi.service.RbmTargetService;
34619 ranu 28
import com.spice.profitmandi.service.inventory.InventoryService;
34308 ranu 29
import com.spice.profitmandi.service.transaction.SDCreditService;
34606 ranu 30
import com.spice.profitmandi.service.user.RetailerService;
34619 ranu 31
import com.spice.profitmandi.service.wallet.WalletService;
34606 ranu 32
import in.shop2020.model.v1.order.OrderStatus;
34619 ranu 33
import in.shop2020.model.v1.order.WalletReferenceType;
34
import org.apache.commons.io.output.ByteArrayOutputStream;
34306 ranu 35
import org.apache.logging.log4j.LogManager;
36
import org.apache.logging.log4j.Logger;
34715 ranu 37
import org.apache.poi.common.usermodel.HyperlinkType;
34641 ranu 38
import org.apache.poi.ss.usermodel.*;
34619 ranu 39
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
34306 ranu 40
import org.springframework.beans.factory.annotation.Autowired;
34619 ranu 41
import org.springframework.beans.factory.annotation.Qualifier;
42
import org.springframework.core.io.ByteArrayResource;
34321 ranu 43
import org.springframework.mail.javamail.JavaMailSender;
44
import org.springframework.mail.javamail.MimeMessageHelper;
34306 ranu 45
import org.springframework.stereotype.Component;
46
import org.springframework.transaction.annotation.Transactional;
47
 
34321 ranu 48
import javax.mail.MessagingException;
49
import javax.mail.internet.InternetAddress;
50
import javax.mail.internet.MimeMessage;
34619 ranu 51
import java.io.*;
52
import java.math.BigDecimal;
34641 ranu 53
import java.time.*;
34306 ranu 54
import java.time.temporal.ChronoUnit;
55
import java.util.*;
34321 ranu 56
import java.util.stream.Collectors;
34306 ranu 57
 
58
@Component
59
@Transactional(rollbackFor = {Throwable.class, ProfitMandiBusinessException.class})
60
public class ScheduledTasksTest {
61
 
62
    private static final Logger LOGGER = LogManager.getLogger(ScheduledTasksTest.class);
63
 
64
    @Autowired
65
    TransactionRepository transactionRepository;
66
 
67
    @Autowired
34619 ranu 68
    @Qualifier(value = "googleMailSender")
69
    private JavaMailSender googleMailSender;
70
 
71
    @Autowired
34306 ranu 72
    LoanRepository loanRepository;
73
 
34308 ranu 74
    @Autowired
75
    SDCreditService sdCreditService;
76
 
34321 ranu 77
    @Autowired
78
    UserRepository userRepository;
79
 
80
    @Autowired
81
    CsService csService;
82
 
83
    @Autowired
84
    RbmRatingRepository rbmRatingRepository;
85
 
86
    @Autowired
87
    private JavaMailSender mailSender;
88
 
89
    @Autowired
90
    SalesRatingRepository salesRatingRepository;
91
 
92
    @Autowired
93
    FofoStoreRepository fofoStoreRepository;
94
 
34450 ranu 95
    @Autowired
96
    SmartCartService smartCartService;
97
 
34606 ranu 98
    @Autowired
99
    RetailerService retailerService;
100
 
101
    @Autowired
102
    ASTRepository astRepository;
103
 
104
    @Autowired
105
    AuthRepository authRepository;
106
 
107
    @Autowired
108
    StateRepository stateRepository;
109
 
110
    @Autowired
111
    MonthlyTargetRepository monthlyTargetRepository;
112
 
113
    @Autowired
114
    PartnerTypeChangeService partnerTypeChangeService;
115
 
116
    @Autowired
117
    ReturnOrderInfoRepository returnOrderInfoRepository;
118
 
119
    @Autowired
120
    OrderRepository orderRepository;
121
 
34619 ranu 122
    @Autowired
123
    FofoOrderItemRepository fofoOrderItemRepository;
124
 
125
    @Autowired
126
    InventoryService inventoryService;
127
 
128
    @Autowired
129
    UserWalletRepository userWalletRepository;
130
 
131
    @Autowired
132
    LoanStatementRepository loanStatementRepository;
133
 
134
    @Autowired
34641 ranu 135
    ActivatedImeiRepository activatedImeiRepository;
136
 
137
    @Autowired
138
    PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;
139
 
140
    @Autowired
34619 ranu 141
    WalletService walletService;
142
 
34641 ranu 143
    @Autowired
144
    RbmTargetService rbmTargetService;
145
 
34655 ranu 146
    @Autowired
147
    PartnerStatsService partnerStatsService;
148
 
34715 ranu 149
    @Autowired
150
    UserWalletHistoryRepository userWalletHistoryRepository;
151
 
34321 ranu 152
    public void test() throws Exception {
34366 ranu 153
        System.out.println("test start");
34699 ranu 154
        //partnerStatsService.getAllPartnerStats();
155
        this.generateBiReportExcel();
34366 ranu 156
        System.out.println("test end");
34306 ranu 157
 
158
    }
159
 
34648 ranu 160
    public void generateBiReport() throws Exception {
161
        LOGGER.info("bi report started {-----}");
162
        this.generateBiReportExcel();
163
        LOGGER.info("bi report ended {-----}");
164
    }
165
 
34308 ranu 166
    public void createLoanForBillingByTransactionIdAndInvoiceNumber(int transactionId, double invoiceAmount, String invoiceNumber) throws Exception {
167
        sdCreditService.createLoanForBilling(transactionId, invoiceAmount, invoiceNumber);
34306 ranu 168
 
34308 ranu 169
    }
34306 ranu 170
 
34619 ranu 171
    public void loanSettle() throws Exception {
172
        List<Integer> refrences = Arrays.asList(25807,36003,38938,39506,42219,45084);
173
        for(Integer ref : refrences){
174
            List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(ref);
175
            double amountSum = loanStatements.stream().map(LoanStatement::getAmount).mapToDouble(BigDecimal::doubleValue).sum();
176
            if(amountSum > 0){
177
                walletService.addAmountToWallet(loanStatements.get(0).getFofoId(),ref, WalletReferenceType.CREDIT_LIMIT,"Amount reversal against credit limit deduction",(float) amountSum,LocalDateTime.now());
34308 ranu 178
 
34619 ranu 179
//                Loan statement entry
180
                    BigDecimal adjustAmount = BigDecimal.valueOf(amountSum).negate(); // or multiply by -1
181
                    LoanStatement loanStatement = new LoanStatement();
182
                    loanStatement.setAmount(adjustAmount);
183
                    loanStatement.setFofoId(loanStatements.get(0).getFofoId());
184
                    loanStatement.setLoanReferenceType(LoanReferenceType.PRINCIPAL);
185
                    loanStatement.setCreatedAt(LocalDateTime.now());
186
                    loanStatement.setDescription("Amount reversal due to access debit against limit");
187
                    loanStatement.setLoanId(ref);
188
                    loanStatement.setBusinessDate(LocalDateTime.now());
189
                    loanStatementRepository.persist(loanStatement);
190
 
191
                    Loan loan = loanRepository.selectByLoanId(ref);
192
                    loan.setPendingAmount(BigDecimal.valueOf(0));
193
                    loan.setSettledOn(LocalDateTime.now());
194
                }
195
 
196
 
197
        }
198
    }
199
 
200
 
201
 
34321 ranu 202
    private void sendMailHtmlFormat(String email[], String body, String cc[], String bcc[], String subject)
203
            throws MessagingException, ProfitMandiBusinessException, IOException {
204
        MimeMessage message = mailSender.createMimeMessage();
205
        MimeMessageHelper helper = new MimeMessageHelper(message);
206
        helper.setSubject(subject);
207
        helper.setText(body, true);
208
        helper.setTo(email);
209
        if (cc != null) {
210
            helper.setCc(cc);
211
        }
212
        if (bcc != null) {
213
            helper.setBcc(bcc);
34308 ranu 214
 
34321 ranu 215
        }
216
 
217
        InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smart Dukaan");
218
        helper.setFrom(senderAddress);
219
        mailSender.send(message);
220
    }
221
 
34307 ranu 222
    public Map<Integer,Integer> findLoanTransactionMapingAccordingLoan(List<Integer> loanIds) throws ProfitMandiBusinessException {
34306 ranu 223
 
224
        Map<Integer, Integer> transactionLoanMap = new HashMap<>();
225
 
226
        for(int loanId : loanIds){
227
            Transaction transaction = null;
228
            Loan loan = loanRepository.selectByLoanId(loanId);
229
            List<Transaction> transactions = transactionRepository.selectByRetailerId(loan.getFofoId());
230
 
231
            LocalDateTime nearestDateTime = transactions.stream().map(x -> x.getCreateTimestamp())
232
                    .min(Comparator.comparingLong(x -> Math.abs(ChronoUnit.MILLIS.between(x, loan.getCreatedOn()))))
233
                    .orElse(null);
234
 
235
            if (nearestDateTime != null && loan.getCreatedOn().plusMinutes(2).isAfter(nearestDateTime) &&
236
                    loan.getCreatedOn().minusMinutes(1).isBefore(nearestDateTime)) {
237
                // Here transaction is still null
238
                transaction = transactions.stream()
239
                        .filter(x -> x.getCreateTimestamp().equals(nearestDateTime))
240
                        .findFirst().get();
241
                transactionLoanMap.put(transaction.getId(), loanId);
242
            }
243
 
244
        }
245
        LOGGER.info("transactionLoanMap {}",transactionLoanMap);
246
        return transactionLoanMap;
247
    }
34321 ranu 248
 
249
 
250
 
251
    public void sendRbmFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
252
        LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
253
        LocalDateTime endOfMonth = LocalDateTime.now();
34323 ranu 254
        String[] bcc = {"tarun.verma@smartdukaan.com"};
34321 ranu 255
 
256
        // Get all RBM users
257
        List<AuthUser> authUsers = csService.getAuthUserIds(
258
                ProfitMandiConstants.TICKET_CATEGORY_RBM,
259
                Arrays.asList(EscalationType.L1)
260
        );
261
 
262
        if (authUsers.isEmpty()) {
263
            LOGGER.info("No RBMs found.");
264
            return;
265
        }
266
 
267
        List<Integer> rbmIds = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
268
 
269
        // Fetch ratings for all RBMs for current month
270
        List<RbmRating> feedbackList = rbmRatingRepository.selectByRbmIdsAndDateRange(rbmIds, startOfMonth, endOfMonth);
271
 
272
        if (feedbackList.isEmpty()) {
273
            LOGGER.info("No feedback entries found for RBMs.");
274
            return;
275
        }
276
 
277
        // Sort feedback by createTimeStamp DESC
278
        feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
279
 
280
        // Fetch and map FOFO (partner) names
281
        Map<Integer, String> fofoNameMap = new HashMap<>();
282
        for (RbmRating rating : feedbackList) {
283
            int fofoId = rating.getFofoId();
284
            if (!fofoNameMap.containsKey(fofoId)) {
285
                User fofoUser = userRepository.selectById(fofoId);
286
                FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
287
 
288
                String partnerName = fofoUser != null ? fofoUser.getName() : "Unknown Partner";
289
                String storeCode = fofoStore != null ? fofoStore.getCode() : "Unknown Code";
290
 
291
                String displayName = partnerName + " (" + storeCode + ")";
292
                fofoNameMap.put(fofoId, displayName);
293
            }
294
        }
295
 
296
        // Map RBM ID to name for quick lookup
297
        Map<Integer, String> rbmNameMap = authUsers.stream()
298
                .collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
299
 
300
        // Generate HTML content
301
        StringBuilder emailContent = new StringBuilder();
302
        emailContent.append("<html><body>");
303
        emailContent.append("<p>Dear Team,</p>");
304
        emailContent.append("<p>Here is the <b>latest RBM Rating and Feedback Summary</b> for ")
305
                .append(LocalDate.now().getMonth()).append(":</p>");
306
 
307
        emailContent.append("<table border='1' cellspacing='0' cellpadding='5'>");
308
        emailContent.append("<tr>")
309
                .append("<th>RBM Name</th>")
310
                .append("<th>Partner Name</th>")
311
                .append("<th>Rating</th>")
312
                .append("<th>Comment</th>")
313
                .append("<th>Date</th>")
314
                .append("</tr>");
315
 
316
        for (RbmRating rating : feedbackList) {
317
            String rbmName = rbmNameMap.getOrDefault(rating.getRbmId(), "Unknown RBM");
318
            String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
319
            emailContent.append("<tr>")
320
                    .append("<td>").append(rbmName).append("</td>")
321
                    .append("<td>").append(partnerName).append("</td>")
322
                    .append("<td>").append(rating.getRating()).append("</td>")
323
                    .append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
324
                    .append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
325
                    .append("</tr>");
326
        }
327
 
328
        emailContent.append("</table>");
329
        emailContent.append("<br><p>Regards,<br>Smart Dukaan Team</p>");
330
        emailContent.append("</body></html>");
331
 
332
        String subject = "Monthly RBM Feedback Summary - " + LocalDate.now().getMonth();
333
 
334
        List<String> sendTo = new ArrayList<>();
34323 ranu 335
        sendTo.add("sm@smartdukaan.com"); //
336
        sendTo.add("chiranjib.sarkar@smartdukaan.com"); //
337
        sendTo.add("kamini.sharma@smartdukaan.com"); //
34321 ranu 338
 
339
        String[] emailRecipients = sendTo.toArray(new String[0]);
340
 
341
 
342
        this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
343
 
344
        LOGGER.info("Consolidated RBM feedback summary email sent.");
345
    }
346
 
347
 
348
    public void sendSalesFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
349
        LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
350
        LocalDateTime endOfMonth = LocalDateTime.now();
34323 ranu 351
        String[] bcc = {"tarun.verma@smartdukaan.com"};
34411 tejus.loha 352
//        String[] bcc = {"tejus.lohani@smartdukaan.com"};
34321 ranu 353
 
354
        // Get all RBM users
355
        List<AuthUser> authUsers = csService.getAuthUserIds(
356
                ProfitMandiConstants.TICKET_CATEGORY_SALES,
357
                Arrays.asList(EscalationType.L1)
358
        );
359
 
360
        if (authUsers.isEmpty()) {
361
            LOGGER.info("No sales person found.");
362
            return;
363
        }
364
 
365
        List<Integer> salesL1Ids = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
366
 
367
        // Fetch ratings for all RBMs for current month
368
        List<SalesRating> feedbackList = salesRatingRepository.selectBySalesL1IdsAndDateRange(salesL1Ids, startOfMonth, endOfMonth);
369
 
370
        if (feedbackList.isEmpty()) {
371
            LOGGER.info("No feedback entries found for Sales.");
372
            return;
373
        }
374
 
375
        // Sort feedback by createTimeStamp DESC
376
        feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
377
 
378
        // Fetch and map FOFO (partner) names
379
        Map<Integer, String> fofoNameMap = new HashMap<>();
380
        for (SalesRating rating : feedbackList) {
381
            int fofoId = rating.getFofoId();
382
            if (!fofoNameMap.containsKey(fofoId)) {
383
                User fofoUser = userRepository.selectById(fofoId);
384
                FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
385
 
386
                String partnerName = fofoUser != null ? fofoUser.getName() : "Unknown Partner";
387
                String storeCode = fofoStore != null ? fofoStore.getCode() : "Unknown Code";
388
 
389
                String displayName = partnerName + " (" + storeCode + ")";
390
                fofoNameMap.put(fofoId, displayName);
391
            }
392
        }
393
 
394
        // Map RBM ID to name for quick lookup
395
        Map<Integer, String> salesL1NameMap = authUsers.stream()
396
                .collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
397
 
398
        // Generate HTML content
399
        StringBuilder emailContent = new StringBuilder();
400
        emailContent.append("<html><body>");
401
        emailContent.append("<p>Dear Team,</p>");
402
        emailContent.append("<p>Here is the <b>latest Sales L1 Rating and Feedback Summary</b> for ")
403
                .append(LocalDate.now().getMonth()).append(":</p>");
404
 
405
        emailContent.append("<table border='1' cellspacing='0' cellpadding='5'>");
406
        emailContent.append("<tr>")
407
                .append("<th>Sales L1 Name</th>")
408
                .append("<th>Partner Name</th>")
34411 tejus.loha 409
                .append("<th>Partner Category</th>")
34321 ranu 410
                .append("<th>Rating</th>")
411
                .append("<th>Comment</th>")
412
                .append("<th>Date</th>")
413
                .append("</tr>");
414
 
415
        for (SalesRating rating : feedbackList) {
416
            String salesL1 = salesL1NameMap.getOrDefault(rating.getSalesL1Id(), "Unknown Sales Person");
417
            String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
34411 tejus.loha 418
            PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(rating.getFofoId(), LocalDate.now());
34321 ranu 419
            emailContent.append("<tr>")
420
                    .append("<td>").append(salesL1).append("</td>")
421
                    .append("<td>").append(partnerName).append("</td>")
34411 tejus.loha 422
                    .append("<td>").append(partnerType).append("</td>")
34321 ranu 423
                    .append("<td>").append(rating.getRating()).append("</td>")
424
                    .append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
425
                    .append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
426
                    .append("</tr>");
427
        }
428
 
429
        emailContent.append("</table>");
430
        emailContent.append("<br><p>Regards,<br>Smartdukaan Team</p>");
431
        emailContent.append("</body></html>");
432
 
34411 tejus.loha 433
        String subject = "Monthly Sales L1 Feedback Summary Test test - " + LocalDate.now().getMonth();
34321 ranu 434
 
435
        List<String> sendTo = new ArrayList<>();
34323 ranu 436
         sendTo.add("sm@smartdukaan.com"); //
437
         sendTo.add("chiranjib.sarkar@smartdukaan.com"); //
34606 ranu 438
         sendTo.add("kamini.sharma@smartdukaan.com"); //
34321 ranu 439
 
440
        String[] emailRecipients = sendTo.toArray(new String[0]);
441
 
442
 
443
        this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
444
 
445
        LOGGER.info("Consolidated Sales L1 feedback summary email sent.");
446
    }
447
 
448
 
34606 ranu 449
    public void generateBiReportExcel() throws Exception {
34619 ranu 450
 
34606 ranu 451
        LocalDateTime startOfToday = LocalDate.now().atStartOfDay();
34321 ranu 452
 
34701 ranu 453
        /*Map<Integer, CustomRetailer> customRetailers = retailerService.getAllFofoRetailersInternalFalse();
34321 ranu 454
 
34701 ranu 455
        List<Integer> retailerIds = customRetailers.values().stream().map(CustomRetailer::getPartnerId).collect(Collectors.toList());*/
34606 ranu 456
 
34730 ranu 457
        List<Integer> retailerIds = Arrays.asList(175139178,175139391,175139651,175139287,175139507,175139314,175139311,175139302,175139273,175138814,175138867,175138541,175139583,175139218,175139308,175139615,175139266,175139247,175139158,175139253);
34701 ranu 458
        Map<Integer,CustomRetailer> customRetailers = retailerService.getFofoRetailers(retailerIds);
34648 ranu 459
 
34641 ranu 460
        //partner daily investment
34729 amit.gupta 461
        List<Loan> defaultLoans = sdCreditService.getDefaultLoans();
34641 ranu 462
        Map<Integer,List<Loan>> defaultLoanMap = defaultLoans.stream().collect(Collectors.groupingBy(Loan::getFofoId));
34619 ranu 463
 
34641 ranu 464
        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = new HashMap<>();
465
        List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository
466
                .selectAll(new ArrayList<>(retailerIds), LocalDate.now().minusDays(1));
467
        if (!partnerDailyInvestments.isEmpty()) {
468
            partnerDailyInvestmentMap = partnerDailyInvestments.stream()
469
                    .collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
470
        }
471
 
34648 ranu 472
    //  this month return data
34619 ranu 473
        YearMonth currentMonth = YearMonth.now();
474
        String currentMonthStringValue = String.valueOf(currentMonth);
34606 ranu 475
        LocalDateTime currentMonthStartDate = YearMonth.now().atDay(1).atStartOfDay();
34722 ranu 476
        LocalDateTime currentMonthEndDate = LocalDateTime.now().minusDays(1).toLocalDate().atTime(23, 59, 59);
34606 ranu 477
 
478
        List<ReturnOrderInfoModel> currentMonthReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(currentMonthStartDate, currentMonthEndDate);
479
        Map<Integer, Long> currentMonthPartnerReturnOrderInfoModelMap = currentMonthReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
480
 
481
        List<Order> currentMonthRtoRefundOrders = orderRepository.selectAllOrderDatesBetweenByStatus(currentMonthStartDate, currentMonthEndDate, OrderStatus.RTO_REFUNDED);
482
        Map<Integer, Long> currentMonthRtoRefundOrderMap = currentMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
483
 
34619 ranu 484
//  last month return data
34606 ranu 485
        YearMonth lastMonth = YearMonth.now().minusMonths(1);
34619 ranu 486
        String lastMonthStringValue = String.valueOf(lastMonth);
34606 ranu 487
        LocalDateTime lastMontStartDate = lastMonth.atDay(1).atStartOfDay();
488
        LocalDateTime lastMonthEndDate = lastMonth.atEndOfMonth().atTime(23, 59, 59);
489
 
490
        List<ReturnOrderInfoModel> lastMonthReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(lastMontStartDate, lastMonthEndDate);
491
        Map<Integer, Long> lastMonthPartnerReturnOrderInfoModelMap = lastMonthReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
492
 
493
        List<Order> lastMonthRtoRefundOrders = orderRepository.selectAllOrderDatesBetweenByStatus(lastMontStartDate, lastMonthEndDate, OrderStatus.RTO_REFUNDED);
494
        Map<Integer, Long> lastMonthRtoRefundOrderMap = lastMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
495
 
496
 
34619 ranu 497
//  twoMonthsAgo return data
34606 ranu 498
        YearMonth twoMonthsAgo = YearMonth.now().minusMonths(2);
34619 ranu 499
        String twoMonthAgoStringValue = String.valueOf(twoMonthsAgo);
34606 ranu 500
        LocalDateTime twoMonthsAgoStartDate = twoMonthsAgo.atDay(1).atStartOfDay();
501
        LocalDateTime twoMonthsAgoEndDate = twoMonthsAgo.atEndOfMonth().atTime(23, 59, 59);
502
 
503
        List<ReturnOrderInfoModel> twoMonthAgoReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(twoMonthsAgoStartDate, twoMonthsAgoEndDate);
504
        Map<Integer, Long> twoMonthAgoPartnerReturnOrderInfoModelMap = twoMonthAgoReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
34724 ranu 505
LOGGER.info("twoMonthAgoReturnOrderInfoModels {}",twoMonthAgoReturnOrderInfoModels);
34606 ranu 506
        List<Order> twoMonthRtoRefundOrders = orderRepository.selectAllOrderDatesBetweenByStatus(twoMonthsAgoStartDate, twoMonthsAgoEndDate, OrderStatus.RTO_REFUNDED);
34619 ranu 507
        Map<Integer, Long> twoMonthAgoRtoRefundOrderMap = twoMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
34724 ranu 508
        LOGGER.info("twoMonthRtoRefundOrders {}",twoMonthRtoRefundOrders);
34606 ranu 509
 
34648 ranu 510
        Map<Integer , String> assessmentMap = new HashMap<>();
511
        Map<Integer , String> zeroBillingMap = new HashMap<>();
512
        Map<Integer , Float> billingNeededMap = new HashMap<>();
513
        Map<Integer , Integer> countAMap = new HashMap<>();
34606 ranu 514
 
34619 ranu 515
        Map<Integer , BIRetailerModel> biRetailerModelMap = new HashMap<>();
34606 ranu 516
 
34641 ranu 517
        Map<Integer , FofoInvestmentModel> biInvestmentModelMap = new HashMap<>();
518
 
34619 ranu 519
        Map<Integer, Map<YearMonth, BiSecondaryModel>> allRetailerMonthlyData = new HashMap<>();
34606 ranu 520
 
34619 ranu 521
        Map<Integer,Double> fofoTotalStockPriceMap = new HashMap<>();
522
 
523
        Map<Integer,Map<String, BrandStockPrice>> fofoBrandStockPriceMap = new HashMap<>();
524
 
34641 ranu 525
        Map<Integer,Long> fofoTotalMtdSecondaryMap = new HashMap<>();
34619 ranu 526
 
527
 
34641 ranu 528
        Map<Integer,Map<String, Long>> fofoBrandWiseMtdSecondaryMap = new HashMap<>();
34619 ranu 529
 
34641 ranu 530
        Map<Integer,Double> fofoTotalMtdTertiaryMap = new HashMap<>();
531
 
532
        Map<Integer,Map<String, Double>> fofoBrandMtdTertiaryMap = new HashMap<>();
533
 
34606 ranu 534
        for(Integer fofoId: retailerIds){
34619 ranu 535
            String rbmName = "";
34606 ranu 536
            int rbmL1 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM,EscalationType.L1,fofoId);
34619 ranu 537
            if(rbmL1 != 0){
538
                 rbmName = authRepository.selectById(rbmL1).getFullName();
34677 ranu 539
            }else {
540
                int rbmL2 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM, EscalationType.L2, fofoId);
541
                if(rbmL2 != 0){
542
                    rbmName = authRepository.selectById(rbmL2).getFullName();
543
                }
34619 ranu 544
            }
545
            String bmName ="";
34606 ranu 546
            int bmId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L2,fofoId);
34619 ranu 547
            if(bmId !=0){
548
                bmName = authRepository.selectById(bmId).getFullName();
549
            }
34606 ranu 550
 
551
            int managerId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L1,fofoId);
552
            String managerName = " ";
553
            if(managerId != 0){
554
                 managerName = authRepository.selectById(managerId).getFullName();
555
            }else {
556
                managerName = bmName;
557
            }
558
 
559
            AST ast = astRepository.selectById(customRetailers.get(fofoId).getAstId());
560
 
561
            PartnerType partnerTypeThisMonth = partnerTypeChangeService.getTypeOnMonth(fofoId, YearMonth.now());
562
 
563
//            generate retaile detail
564
 
565
            BIRetailerModel biRetailerModel = new BIRetailerModel();
566
            biRetailerModel.setBmName(bmName);
567
            biRetailerModel.setCode(customRetailers.get(fofoId).getCode());
34619 ranu 568
            if(ast != null){
569
                biRetailerModel.setArea(ast.getArea());
570
            }else {
571
                biRetailerModel.setArea("-");
572
            }
34606 ranu 573
            biRetailerModel.setCity(customRetailers.get(fofoId).getAddress().getCity());
574
            biRetailerModel.setStoreName(customRetailers.get(fofoId).getBusinessName());
34619 ranu 575
            biRetailerModel.setStatus(String.valueOf(customRetailers.get(fofoId).getActivationType()));
34606 ranu 576
            biRetailerModel.setCategory(String.valueOf(partnerTypeThisMonth));
577
            biRetailerModel.setSalesManager(managerName);
578
            biRetailerModel.setRbm(rbmName);
579
 
34619 ranu 580
            biRetailerModelMap.put(fofoId,biRetailerModel);
581
 
34641 ranu 582
 
34606 ranu 583
//            generate secondary data
584
 
34641 ranu 585
            List<PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledMonthlyTotals = activatedImeiRepository.getTotalMonthlyActivatedNotBilled(fofoId,twoMonthsAgoStartDate);
586
            Map<YearMonth , PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledTotalMap = partnerWiseActivatedNotBilledMonthlyTotals.stream().collect(Collectors.toMap(x-> YearMonth.parse(x.getYearMonth()),x->x));
587
 
34606 ranu 588
//            this month secondary target
589
 
34619 ranu 590
            double currentSecondaryTarget =  monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId).getPurchaseTarget() : 0;
34606 ranu 591
 
34619 ranu 592
 
593
            long currentMonthReturn = currentMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId, 0L) + currentMonthRtoRefundOrderMap.getOrDefault(fofoId, 0L);
594
 
595
 
34715 ranu 596
            Map<Integer, Double> secondaryMtd = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34699 ranu 597
                    startOfToday.withDayOfMonth(1), startOfToday.with(LocalTime.MAX).minusDays(1)).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
34606 ranu 598
 
599
            double secondaryAchievedMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
600
 
34619 ranu 601
            double currentMonthNetSecondary = secondaryAchievedMtd - currentMonthReturn;
34606 ranu 602
 
34701 ranu 603
            double currentMonthSecondaryPercent = currentSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((secondaryAchievedMtd / currentSecondaryTarget) * 100));
34619 ranu 604
 
34641 ranu 605
            double currentMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(currentMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(currentMonth).getTotalUnbilledAmount() : 0d;
34619 ranu 606
 
607
//          this month tertiary----------
608
 
609
            LocalDateTime now = LocalDateTime.now();
610
            double todaySale = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday, now, fofoId, false).get(fofoId);
611
            double mtdSaleTillYesterDay = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday.withDayOfMonth(1), startOfToday, fofoId, false).get(fofoId);
34724 ranu 612
            double mtdSale = mtdSaleTillYesterDay;
34619 ranu 613
 
614
 
34606 ranu 615
//            last month secondary target
616
 
34619 ranu 617
            double lastMonthSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId) != null ?  monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 618
 
34619 ranu 619
            long lastMonthReturn = (lastMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + lastMonthRtoRefundOrderMap.getOrDefault(fofoId,0L));
620
 
34715 ranu 621
            Map<Integer, Double> lastMonthSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 622
                    lastMontStartDate, lastMonthEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
623
 
624
            double lastMonthSecondaryAchieved = lastMonthSecondary.getOrDefault(fofoId, 0.0);
625
 
34619 ranu 626
            double lastMonthNetSecondary = lastMonthSecondaryAchieved - lastMonthReturn;
34606 ranu 627
 
34701 ranu 628
            double lastMonthSecondaryPercent = lastMonthSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((lastMonthSecondaryAchieved / lastMonthSecondaryTarget) * 100));
34606 ranu 629
 
34641 ranu 630
            double lastMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(lastMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(lastMonth).getTotalUnbilledAmount() : 0d;
34606 ranu 631
 
34619 ranu 632
//           last month tertiary
633
            Double lastMonthSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
634
                    lastMontStartDate, lastMonthEndDate, fofoId, false).get(fofoId);
635
 
636
 
637
//            two month ago secondary target
638
 
34703 ranu 639
            double twoMonthAgoSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId).getPurchaseTarget() : 0;
34619 ranu 640
 
641
            long twoMonthAgoReturn = (twoMonthAgoPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + twoMonthAgoRtoRefundOrderMap.getOrDefault(fofoId,0L));
642
 
34715 ranu 643
            Map<Integer, Double> twoMonthAgoSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 644
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
645
 
646
            double twoMonthAgoSecondaryAchieved = twoMonthAgoSecondary.getOrDefault(fofoId, 0.0);
647
 
34619 ranu 648
            double twoMonthAgoNetSecondary = twoMonthAgoSecondaryAchieved - twoMonthAgoReturn;
34606 ranu 649
 
34701 ranu 650
            double twoMonthAgoSecondaryPercent = twoMonthAgoSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((twoMonthAgoSecondaryAchieved / twoMonthAgoSecondaryTarget) * 100));
34619 ranu 651
 
34641 ranu 652
            double twoMonthAgoUnbilled = partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo) != null ? partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo).getTotalUnbilledAmount() : 0d;
34619 ranu 653
 
654
//          second Month Tertiary
655
            double twoMonthAgoSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
656
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate, fofoId, false).get(fofoId);
657
 
658
 
659
            Map<YearMonth, BiSecondaryModel> monthlySecondaryModels = new HashMap<>();
660
 
661
            BiSecondaryModel currentMonthSecondaryModel = new BiSecondaryModel(
662
                    currentSecondaryTarget,
663
                    secondaryAchievedMtd,
664
                    currentMonthReturn,
665
                    currentMonthNetSecondary,
666
                    currentMonthSecondaryPercent,
667
                    mtdSale,
668
                    currentMonthUnbilled // for now, unbilled tertiary value
669
            );
670
 
671
            BiSecondaryModel lastMonthSecondaryModel = new BiSecondaryModel(
672
                    lastMonthSecondaryTarget,
673
                    lastMonthSecondaryAchieved,
674
                    lastMonthReturn,
675
                    lastMonthNetSecondary,
676
                    lastMonthSecondaryPercent,
677
                    lastMonthSale,
678
                    lastMonthUnbilled // for now, unbilled tertiary value
679
            );
680
 
681
            BiSecondaryModel twoMonthAgoSecondaryModel = new BiSecondaryModel(
682
                    twoMonthAgoSecondaryTarget,
683
                    twoMonthAgoSecondaryAchieved,
684
                    twoMonthAgoReturn,
685
                    twoMonthAgoNetSecondary,
686
                    twoMonthAgoSecondaryPercent,
687
                    twoMonthAgoSale,
688
                    twoMonthAgoUnbilled // for now, unbilled tertiary value
689
            );
690
 
691
            monthlySecondaryModels.put(currentMonth, currentMonthSecondaryModel);
692
            monthlySecondaryModels.put(lastMonth, lastMonthSecondaryModel);
693
            monthlySecondaryModels.put(twoMonthsAgo, twoMonthAgoSecondaryModel);
694
 
695
            allRetailerMonthlyData.put(fofoId, monthlySecondaryModels);
696
 
697
//            brandwiseStock value price
698
 
699
            Map<String, BrandStockPrice> brandStockPriceMap = inventoryService.getBrandWiseStockValue(fofoId);
700
 
701
            fofoBrandStockPriceMap.put(fofoId,brandStockPriceMap);
702
 
703
            double totalStockPrice = brandStockPriceMap.values().stream().mapToDouble(x->x.getTotalValue()).sum();
704
 
705
            fofoTotalStockPriceMap.put(fofoId,totalStockPrice);
706
 
707
            Map<String, Double> brandMtdTertiaryAmount = fofoOrderItemRepository.selectSumAmountGroupByBrand(
34722 ranu 708
                    currentMonthStartDate, currentMonthEndDate, fofoId);
34619 ranu 709
 
34719 ranu 710
 
34641 ranu 711
            fofoBrandMtdTertiaryMap.put(fofoId,brandMtdTertiaryAmount);
34619 ranu 712
 
713
            double totalMtdTertiaryAmount = brandMtdTertiaryAmount.values().stream().mapToDouble(Double::doubleValue).sum();
714
 
34641 ranu 715
            fofoTotalMtdTertiaryMap.put(fofoId,totalMtdTertiaryAmount);
34619 ranu 716
 
34719 ranu 717
            LOGGER.info("fofoBrandMtdTertiaryMap- {}",fofoBrandMtdTertiaryMap);
718
 
719
 
34721 ranu 720
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledByCategoryOrderGroupByBrandFofoId(fofoId, currentMonthStartDate,Arrays.asList(10006,10009,10010));
34641 ranu 721
            Map<String,Long> brandWiseMtdSecondaryMap = brandWiseMtdSecondary.stream().collect(Collectors.toMap(BrandWiseModel::getBrand,BrandWiseModel::getAmount));
34619 ranu 722
 
34730 ranu 723
            //retrunInfo
724
            List<BrandWiseReturnInfo> brandWiseReturnInfos = returnOrderInfoRepository.selectAllBrandWiseByBetweenDate(currentMonthStartDate,currentMonthEndDate.plusDays(1),fofoId);
725
            Map<String,Double> brandWiseReturnInfoMap = brandWiseReturnInfos.stream().collect(Collectors.toMap(BrandWiseReturnInfo::getBrand, x->x.getReturnAmount()));
34619 ranu 726
 
34730 ranu 727
            LOGGER.info("brandWiseReturnInfos {}",brandWiseReturnInfos);
728
            LOGGER.info("brandWiseReturnInfoMap {}",brandWiseReturnInfoMap);
729
            //Rto retrunInfo
730
            List<BrandWiseReturnInfo> brandWiseRTOReturnInfos = returnOrderInfoRepository.selectAllBrandWiseRTORefundByBetweenDate(currentMonthStartDate,currentMonthEndDate.plusDays(1),fofoId);
731
            Map<String,Double> brandWiseRTOReturnInfoMap = brandWiseRTOReturnInfos.stream().collect(Collectors.toMap(BrandWiseReturnInfo::getBrand, x->x.getReturnAmount()));
732
 
733
            // Step 1: Get union of all brand keys
734
            Set<String> allBrands = new HashSet<>();
735
            allBrands.addAll(brandWiseMtdSecondaryMap.keySet());
736
            allBrands.addAll(brandWiseReturnInfoMap.keySet());
737
            allBrands.addAll(brandWiseRTOReturnInfoMap.keySet());
738
 
739
            // Step 2: Calculate net secondary for each brand
740
            Map<String, Long> brandWiseMtdNetSecondaryMap = new HashMap<>();
741
 
742
            for (String brand : allBrands) {
743
                Long billedAmount = brandWiseMtdSecondaryMap.getOrDefault(brand, 0L);
744
                Double returnAmount = brandWiseReturnInfoMap.getOrDefault(brand, 0d);
745
                Double rtoReturnAmount = brandWiseRTOReturnInfoMap.getOrDefault(brand, 0d);
746
 
747
                double netSecondary = billedAmount - (returnAmount + rtoReturnAmount);
748
                brandWiseMtdNetSecondaryMap.put(brand, (long) Math.round(netSecondary));
749
            }
750
 
751
 
752
            LOGGER.info("brandWiseMtdNetSecondaryMap {}",brandWiseMtdNetSecondaryMap );
753
 
754
 
755
            fofoBrandWiseMtdSecondaryMap.put(fofoId,brandWiseMtdNetSecondaryMap);
756
 
757
            long mtdTotalSecondary = brandWiseMtdNetSecondaryMap.values().stream().mapToLong(Long::longValue).sum();
758
 
34641 ranu 759
            fofoTotalMtdSecondaryMap.put(fofoId,mtdTotalSecondary);
760
 
761
            //            generate investment info
762
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
763
            float shortInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getShortInvestment() : 0f;
764
            float agreedInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getMinInvestment() : 0f;
34677 ranu 765
            float investmentLevel = partnerDailyInvestmentMap.get(fofoId) != null
766
                    ? Math.abs(((shortInvestment - agreedInvestment) / agreedInvestment) * 100)
767
                    : 0f;
34641 ranu 768
 
34677 ranu 769
 
34641 ranu 770
            List<Loan> fofoDefaultLoans = new ArrayList<>();
771
            if(defaultLoanMap != null){
772
                 fofoDefaultLoans  =  defaultLoanMap.get(fofoId);
773
                LOGGER.info("fofoDefaultLoans {}",fofoDefaultLoans);
774
            }
775
 
776
            float defaultLoanAmount = 0f;
777
            if(fofoDefaultLoans != null ){
778
                if (!fofoDefaultLoans.isEmpty()) {
779
                    defaultLoanAmount =  fofoDefaultLoans.stream().map(Loan::getPendingAmount).reduce(BigDecimal.ZERO, BigDecimal::add).floatValue(); // or .floatValue() directly
780
                }
781
            }
782
 
34719 ranu 783
            List<Loan> activeLoans = loanRepository.selectAllActiveLoan(fofoId);
34641 ranu 784
 
34719 ranu 785
            LOGGER.info("activeLoans- {}",activeLoans);
34641 ranu 786
 
34719 ranu 787
            float activeLoan = activeLoans.stream().map(Loan::getPendingAmount).reduce(BigDecimal.ZERO,BigDecimal::add).floatValue();
788
 
34641 ranu 789
            float poValue = partnerDailyInvestmentMap.get(fofoId) != null ?  partnerDailyInvestmentMap.get(fofoId).getUnbilledAmount() : 0f;
790
 
34719 ranu 791
            float poAndBilledValue = (float) (currentMonthNetSecondary + poValue);
34641 ranu 792
 
34724 ranu 793
            double todayRequiredDrr = rbmTargetService.calculateFofoIdTodayTarget(fofoId, currentMonthNetSecondary,LocalDate.now());
34641 ranu 794
 
795
            double monthDay1Drr = rbmTargetService.calculateFofoIdTodayTarget(fofoId,0d,YearMonth.now().atDay(1));
796
 
797
 
798
            double gotDrrPercent = (todayRequiredDrr / monthDay1Drr) * 100;
799
 
34701 ranu 800
            long drrPercentDisplay = Math.round(Math.abs(gotDrrPercent));
801
 
802
 
34641 ranu 803
            int orderId = orderRepository.getLastOrderByFofoId(fofoId);
804
 
34644 ranu 805
            // Determine alert level
806
            String alertLevel = "-";
807
            int lastPurchaseDays = 0;
34641 ranu 808
            if (orderId != 0) {
809
                Order order = orderRepository.selectById(orderId);
810
 
34715 ranu 811
                LOGGER.info("last billing order - {}",order);
812
 
34641 ranu 813
                // Calculate the number of days since the last purchase (billing)
34644 ranu 814
                lastPurchaseDays = (int) Duration.between(order.getCreateTimestamp().plusDays(1), LocalDateTime.now()).toDays();
34641 ranu 815
 
816
                if (lastPurchaseDays >= 11) {
817
                    alertLevel = "Alert for Management";
34676 ranu 818
                } else if (lastPurchaseDays >= 10) {
34641 ranu 819
                    alertLevel = " Alert for RSM/SH";
34676 ranu 820
                } else if (lastPurchaseDays >= 7) {
34641 ranu 821
                    alertLevel = "Must be Billed";
822
                } else if (lastPurchaseDays >= 3) {
823
                    alertLevel = "OK";
824
                } else {
34676 ranu 825
                    alertLevel = "OK";
34641 ranu 826
                }
34644 ranu 827
            }
34641 ranu 828
 
34644 ranu 829
            //investment modal set all related value
830
            FofoInvestmentModel fofoInvestmentModel = new FofoInvestmentModel();
34641 ranu 831
 
34644 ranu 832
            fofoInvestmentModel.setCounterPotential(fofoStore.getCounterPotential());
833
            fofoInvestmentModel.setShortInvestment(shortInvestment);
834
            fofoInvestmentModel.setDefaultLoan(defaultLoanAmount);
835
            fofoInvestmentModel.setInvestmentLevel(investmentLevel);
836
            fofoInvestmentModel.setActiveLoan(activeLoan);
837
            fofoInvestmentModel.setPoValue(poValue);
838
            fofoInvestmentModel.setPoAndBilled(poAndBilledValue);
839
            fofoInvestmentModel.setAgreedInvestment(agreedInvestment);
840
            fofoInvestmentModel.setWallet(partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getWalletAmount() : 0);
841
            fofoInvestmentModel.setMonthBeginingDrr(monthDay1Drr);
842
            fofoInvestmentModel.setRequiredDrr(todayRequiredDrr);
34701 ranu 843
            fofoInvestmentModel.setDrrPercent(drrPercentDisplay);
34644 ranu 844
            fofoInvestmentModel.setLastBillingDone(lastPurchaseDays);
845
            fofoInvestmentModel.setSlab(alertLevel);
34641 ranu 846
 
34644 ranu 847
            biInvestmentModelMap.put(fofoId, fofoInvestmentModel);
34641 ranu 848
                String assessment = "";
849
                if(defaultLoanAmount > 0 ){
850
                    assessment = "Loan Default";
851
                }else if(investmentLevel <= 75 && defaultLoanAmount < 1){
852
                    assessment = "Low Invest";
853
                }else {
854
                    assessment = "-";
855
                }
856
                assessmentMap.put(fofoId,assessment);
857
 
858
                String zeroBilling = "";
859
                if(currentMonthNetSecondary <= 100000 ){
860
                    zeroBilling = "Zero Billing";
861
                }else {
862
                    zeroBilling = "-";
863
                }
864
                zeroBillingMap.put(fofoId,zeroBilling);
865
 
866
                float billingNeeded = 0f;
34701 ranu 867
                if(drrPercentDisplay >= 110 ){
34641 ranu 868
                    billingNeeded = (float) todayRequiredDrr;
869
                }else {
870
                    billingNeeded = 0f;
871
                }
872
                billingNeededMap.put(fofoId,billingNeeded);
873
 
874
                int counta = 0;
34701 ranu 875
                if(defaultLoanAmount > 0 || investmentLevel <= 75 || currentMonthNetSecondary <= 100000 || drrPercentDisplay >= 110 ){
34641 ranu 876
                    counta = 1;
877
                }else {
878
                    counta = 0;
879
                }
880
                countAMap.put(fofoId,counta);
881
 
34606 ranu 882
        }
883
 
34619 ranu 884
        LOGGER.info("Total BI Retailers processed: {}", biRetailerModelMap.size());
34606 ranu 885
 
34619 ranu 886
        //generate excel and sent to mail
887
        List<List<String>> headerGroup = new ArrayList<>();
34606 ranu 888
 
34619 ranu 889
        List<String> headers1 = Arrays.asList(
34641 ranu 890
                "","","","",
34715 ranu 891
                "Retailer Detail", "","", "", "", "", "", "", "", "","","","",
34677 ranu 892
 
893
                twoMonthAgoStringValue, "", "", "", "", "", "",
894
                lastMonthStringValue, "", "", "", "", "", "",
34619 ranu 895
                currentMonthStringValue, "", "", "", "", "", "",
34641 ranu 896
 
897
                "","", "", "", "", "", "", "", "", "", "", "", "", "",
898
 
899
                "", "", "", "", "", "", "", "", "", "", "", "", "",
900
                "", "", "", "", "", "", "", "", "", "", "", "", ""
901
 
34619 ranu 902
        );
34606 ranu 903
 
34619 ranu 904
        List<String> headers2 = Arrays.asList(
34641 ranu 905
                "Assessment","Zero billing","Billing needed","Counta",
34715 ranu 906
                "BM","Partner Id","Link","Wallet Date","Creation Date","Code","Area",  "City", "Store Name", "Status","Category","Sales Manager", "RBM",
34619 ranu 907
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
908
                "Tertiary Sale", "Unbilled",
909
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
910
                "Tertiary Sale", "Unbilled",
911
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
912
                "Tertiary Sale", "Unbilled",
34641 ranu 913
                "Counter Potential", "Short investment", "Default", "INVESTMENT LEVEL", "Loan", "PO value", "Agreed investment",
914
                "Wallet", "po+bill", "MONTH BEGINNING DRR", "REQ DRR", "Drr %", "Last billing Done", "Slab",
34606 ranu 915
 
34721 ranu 916
              "Total Stock",  "Apple","Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
917
              "Total Secondary", "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
918
              "Total Tertiary",  "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New"
34619 ranu 919
        );
920
 
921
        headerGroup.add(headers1);
922
        headerGroup.add(headers2);
923
 
924
 
925
        List<List<?>> rows = new ArrayList<>();
926
        for (Map.Entry<Integer, BIRetailerModel> entry : biRetailerModelMap.entrySet()) {
927
            Integer fofoId = entry.getKey();
34715 ranu 928
            User user = userRepository.selectById(fofoId);
929
            LocalDateTime walletCreationDate = userWalletHistoryRepository.selectFirstCreatedDate(fofoId);
34619 ranu 930
            BIRetailerModel retailer = entry.getValue();
34641 ranu 931
 
34619 ranu 932
            Map<YearMonth, BiSecondaryModel> monthlyData = allRetailerMonthlyData.get(fofoId);
933
 
934
            BiSecondaryModel current = monthlyData.getOrDefault(YearMonth.now(), new BiSecondaryModel(0,0,0,0,0,0,0));
935
            BiSecondaryModel last = monthlyData.getOrDefault(YearMonth.now().minusMonths(1), new BiSecondaryModel(0,0,0,0,0,0,0));
936
            BiSecondaryModel twoAgo = monthlyData.getOrDefault(YearMonth.now().minusMonths(2), new BiSecondaryModel(0,0,0,0,0,0,0));
937
 
938
            List<Object> row = new ArrayList<>();
939
            row.addAll(Arrays.asList(
34641 ranu 940
                    assessmentMap.get(fofoId),zeroBillingMap.get(fofoId),billingNeededMap.get(fofoId),countAMap.get(fofoId),
34715 ranu 941
                    retailer.getBmName(),fofoId ,"https://partners.smartdukaan.com/partnerPerformance?fofoId="+fofoId,walletCreationDate,user.getCreateTimestamp(), retailer.getCode(), retailer.getArea(), retailer.getCity(),  retailer.getStoreName(), retailer.getStatus(),
34677 ranu 942
                    retailer.getCategory(),  retailer.getSalesManager(), retailer.getRbm()
943
 
34619 ranu 944
            ));
945
 
34677 ranu 946
 
947
            // Two Months Ago
34619 ranu 948
            row.addAll(Arrays.asList(
34677 ranu 949
                    twoAgo.getSecondaryTarget(),
950
                    twoAgo.getSecondaryAchieved(),
951
                    twoAgo.getSecondaryReturn(),
952
                    twoAgo.getNetSecondary(),
34704 ranu 953
                    twoAgo.getSecondaryAchievedPercent()+"%",
34677 ranu 954
                    twoAgo.getTertiary(),
955
                    twoAgo.getTertiaryUnBilled()
34619 ranu 956
            ));
957
 
958
            // Last Month
959
            row.addAll(Arrays.asList(
960
                    last.getSecondaryTarget(),
961
                    last.getSecondaryAchieved(),
962
                    last.getSecondaryReturn(),
963
                    last.getNetSecondary(),
34704 ranu 964
                    last.getSecondaryAchievedPercent()+"%",
34619 ranu 965
                    last.getTertiary(),
966
                    last.getTertiaryUnBilled()
967
            ));
968
 
34677 ranu 969
            // Current Month
34619 ranu 970
            row.addAll(Arrays.asList(
34677 ranu 971
                    current.getSecondaryTarget(),
972
                    current.getSecondaryAchieved(),
973
                    current.getSecondaryReturn(),
974
                    current.getNetSecondary(),
34704 ranu 975
                    current.getSecondaryAchievedPercent()+"%",
34677 ranu 976
                    current.getTertiary(),
977
                    current.getTertiaryUnBilled()
34619 ranu 978
            ));
34677 ranu 979
 
980
 
981
 
34641 ranu 982
            FofoInvestmentModel fofoInvestmentModelValue = biInvestmentModelMap.get(fofoId);
983
            if(fofoInvestmentModelValue != null){
984
                row.addAll(Arrays.asList(
985
                        fofoInvestmentModelValue.getCounterPotential(),
986
                        fofoInvestmentModelValue.getShortInvestment(),
987
                        fofoInvestmentModelValue.getDefaultLoan(),
34730 ranu 988
                        fofoInvestmentModelValue.getInvestmentLevel() +"%",
34715 ranu 989
                       "-"+fofoInvestmentModelValue.getActiveLoan(),
34641 ranu 990
                        fofoInvestmentModelValue.getPoValue(),
991
                        fofoInvestmentModelValue.getAgreedInvestment(),
992
                        fofoInvestmentModelValue.getWallet(),
993
                        fofoInvestmentModelValue.getPoAndBilled(),
994
                        fofoInvestmentModelValue.getMonthBeginingDrr(),
995
                        fofoInvestmentModelValue.getRequiredDrr(),
34704 ranu 996
                        fofoInvestmentModelValue.getDrrPercent()+"%",
34641 ranu 997
                        fofoInvestmentModelValue.getLastBillingDone(),
998
                        fofoInvestmentModelValue.getSlab()
999
                ));
1000
            }else {
1001
                row.addAll(Arrays.asList(
1002
                        "-","-","-","-","-","-","-","-","-","-","-",""
1003
                ));
1004
            }
1005
 
1006
            Map<String, BrandStockPrice> brandStockMap = fofoBrandStockPriceMap.get(fofoId);
34619 ranu 1007
            row.addAll(Arrays.asList(
1008
                    fofoTotalStockPriceMap.getOrDefault(fofoId, 0.0),
34641 ranu 1009
                    brandStockMap.get("Apple") != null ? brandStockMap.get("Apple").getTotalValue() : 0.0,
1010
                    brandStockMap.get("Xiaomi") != null ? brandStockMap.get("Xiaomi").getTotalValue() : 0.0,
1011
                    brandStockMap.get("Vivo") != null ? brandStockMap.get("Vivo").getTotalValue() : 0.0,
1012
                    brandStockMap.get("Tecno") != null ? brandStockMap.get("Tecno").getTotalValue() : 0.0,
1013
                    brandStockMap.get("Samsung") != null ? brandStockMap.get("Samsung").getTotalValue() : 0.0,
1014
                    brandStockMap.get("Realme") != null ? brandStockMap.get("Realme").getTotalValue() : 0.0,
1015
                    brandStockMap.get("Oppo") != null ? brandStockMap.get("Oppo").getTotalValue() : 0.0,
1016
                    brandStockMap.get("OnePlus") != null ? brandStockMap.get("OnePlus").getTotalValue() : 0.0,
34721 ranu 1017
                    brandStockMap.get("POCO") != null ? brandStockMap.get("POCO").getTotalValue() : 0.0,
34641 ranu 1018
                    brandStockMap.get("Lava") != null ? brandStockMap.get("Lava").getTotalValue() : 0.0,
1019
                    brandStockMap.get("Itel") != null ? brandStockMap.get("Itel").getTotalValue() : 0.0,
1020
                    brandStockMap.get("Almost New") != null ? brandStockMap.get("Almost New").getTotalValue() : 0.0
34619 ranu 1021
            ));
1022
 
34641 ranu 1023
            Map<String, Long> brandSecondaryMap = fofoBrandWiseMtdSecondaryMap.get(fofoId);
1024
            row.addAll(Arrays.asList(
34648 ranu 1025
                    fofoTotalMtdSecondaryMap.get(fofoId),
34641 ranu 1026
                    brandSecondaryMap.getOrDefault("Apple", 0L),
1027
                    brandSecondaryMap.getOrDefault("Xiaomi", 0L),
1028
                    brandSecondaryMap.getOrDefault("Vivo", 0L),
1029
                    brandSecondaryMap.getOrDefault("Tecno", 0L),
1030
                    brandSecondaryMap.getOrDefault("Samsung", 0L),
1031
                    brandSecondaryMap.getOrDefault("Realme", 0L),
1032
                    brandSecondaryMap.getOrDefault("Oppo", 0L),
1033
                    brandSecondaryMap.getOrDefault("OnePlus", 0L),
34721 ranu 1034
                    brandSecondaryMap.getOrDefault("POCO", 0L),
34641 ranu 1035
                    brandSecondaryMap.getOrDefault("Lava", 0L),
1036
                    brandSecondaryMap.getOrDefault("Itel", 0L),
1037
                    brandSecondaryMap.getOrDefault("Almost New", 0L)
1038
            ));
1039
 
1040
            Map<String, Double> brandTertiaryMap = fofoBrandMtdTertiaryMap.get(fofoId);
1041
            row.addAll(Arrays.asList(
34648 ranu 1042
                    fofoTotalMtdTertiaryMap.get(fofoId),
34641 ranu 1043
                    brandTertiaryMap.getOrDefault("Apple", 0d),
1044
                    brandTertiaryMap.getOrDefault("Xiaomi", 0d),
1045
                    brandTertiaryMap.getOrDefault("Vivo", 0d),
1046
                    brandTertiaryMap.getOrDefault("Tecno", 0d),
1047
                    brandTertiaryMap.getOrDefault("Samsung", 0d),
1048
                    brandTertiaryMap.getOrDefault("Realme", 0d),
1049
                    brandTertiaryMap.getOrDefault("Oppo", 0d),
1050
                    brandTertiaryMap.getOrDefault("OnePlus", 0d),
34721 ranu 1051
                    brandTertiaryMap.getOrDefault("POCO", 0d),
34641 ranu 1052
                    brandTertiaryMap.getOrDefault("Lava", 0d),
1053
                    brandTertiaryMap.getOrDefault("Itel", 0d),
1054
                    brandTertiaryMap.getOrDefault("Almost New", 0d)
1055
            ));
1056
            rows.add(row);
34619 ranu 1057
        }
1058
 
1059
 
34641 ranu 1060
        // Send to email
1061
//        ByteArrayOutputStream csvStream = FileUtil.getCSVByteStreamWithMultiHeaders(headerGroup, rows);
1062
        ByteArrayOutputStream csvStream = getExcelStreamWithMultiHeaders(headerGroup, rows);
1063
        String fileName = "BI-Retailer-Monthly-Report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".xlsx";
34722 ranu 1064
        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com","ashutosh.verma@smartdukaan.com","sm@smartdukaan.com","raj.singh@smartdukaan.com"};
1065
//        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com"};
34619 ranu 1066
 
1067
        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()));
1068
 
1069
 
34606 ranu 1070
    }
1071
 
34641 ranu 1072
    public static ByteArrayOutputStream getExcelStreamWithMultiHeaders(List<List<String>> headerGroup, List<List<?>> rows) {
1073
        Workbook workbook = new XSSFWorkbook();
1074
        Sheet sheet = workbook.createSheet("BI Report");
34715 ranu 1075
        CreationHelper creationHelper = workbook.getCreationHelper();
34641 ranu 1076
        int rowIndex = 0;
34606 ranu 1077
 
34641 ranu 1078
        CellStyle centeredStyle = workbook.createCellStyle();
1079
        centeredStyle.setAlignment(HorizontalAlignment.CENTER); // Center horizontally
1080
        centeredStyle.setVerticalAlignment(VerticalAlignment.CENTER); // Center vertically
34606 ranu 1081
 
34641 ranu 1082
    // Optional: bold font
1083
        Font font1 = workbook.createFont();
1084
        font1.setBold(true);
1085
        centeredStyle.setFont(font1);
34606 ranu 1086
 
34619 ranu 1087
 
34641 ranu 1088
 
1089
        // Create styles
1090
        Map<String, CellStyle> headerStyles = new HashMap<>();
1091
 
1092
        // fontPurpleStyle
1093
        CellStyle purpleStyle = workbook.createCellStyle();
1094
        purpleStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
1095
        purpleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1096
        purpleStyle.setFont(font1);
1097
        headerStyles.put("Assessment", purpleStyle);
1098
        headerStyles.put("Zero billing", purpleStyle);
1099
        headerStyles.put("Billing needed", purpleStyle);
1100
        headerStyles.put("Counta", purpleStyle);
1101
        headerStyles.put("MONTH BEGINNING DRR", purpleStyle);
1102
        headerStyles.put("REQ DRR", purpleStyle);
1103
        headerStyles.put("Drr %", purpleStyle);
1104
 
1105
        // Light Blue
1106
        CellStyle blueStyle = workbook.createCellStyle();
1107
        blueStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
1108
        blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1109
        blueStyle.setFont(font1);
1110
        headerStyles.put("Code", blueStyle);
1111
        headerStyles.put("Store Name", blueStyle);
1112
        headerStyles.put("City", blueStyle);
1113
        headerStyles.put("Area", blueStyle);
1114
        headerStyles.put("BM", blueStyle);
1115
        headerStyles.put("RBM", blueStyle);
1116
        headerStyles.put("Sales Manager", blueStyle);
1117
        headerStyles.put("Status", blueStyle);
1118
        headerStyles.put("Category", blueStyle);
34715 ranu 1119
        headerStyles.put("Wallet Date", blueStyle);
1120
        headerStyles.put("Creation Date", blueStyle);
1121
        headerStyles.put("Partner Id", blueStyle);
34641 ranu 1122
 
34715 ranu 1123
        //for link
1124
        // Create hyperlink style
1125
        CellStyle hyperlinkStyle = workbook.createCellStyle();
1126
        Font hlinkFont = workbook.createFont();
1127
        hlinkFont.setUnderline(Font.U_SINGLE);
1128
        hlinkFont.setColor(IndexedColors.BLUE.getIndex());
1129
        hyperlinkStyle.setFont(hlinkFont);
1130
 
1131
 
34641 ranu 1132
        // Light Yellow
1133
        CellStyle yellowStyle = workbook.createCellStyle();
1134
        yellowStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
1135
        yellowStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1136
        yellowStyle.setFont(font1);
1137
        headerStyles.put("Last billing Done", yellowStyle);
1138
        headerStyles.put("Total Stock", yellowStyle);
1139
 
1140
        // Light Orange
1141
        CellStyle orangeStyle = workbook.createCellStyle();
1142
        orangeStyle.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
1143
        orangeStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1144
        orangeStyle.setFont(font1);
1145
        headerStyles.put("Total Tertiary", orangeStyle);
1146
        headerStyles.put("Total Secondary", orangeStyle);
1147
        headerStyles.put("Default", orangeStyle);
1148
 
1149
 
1150
        // Light green
1151
        CellStyle lightGreenStyle = workbook.createCellStyle();
1152
        lightGreenStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
1153
        lightGreenStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1154
        lightGreenStyle.setFont(font1);
1155
        headerStyles.put("Short investment", lightGreenStyle);
1156
        headerStyles.put("INVESTMENT LEVEL", lightGreenStyle);
1157
        headerStyles.put("Loan", lightGreenStyle);
1158
        headerStyles.put("PO value", lightGreenStyle);
1159
        headerStyles.put("Agreed investment", lightGreenStyle);
1160
        headerStyles.put("Wallet", lightGreenStyle);
1161
        headerStyles.put("po+bill", lightGreenStyle);
1162
 
1163
        // Light Green
1164
        CellStyle secondary1 = createStyle(workbook, IndexedColors.LIGHT_GREEN);
1165
        CellStyle secondary2 = createStyle(workbook, IndexedColors.LIGHT_YELLOW);
1166
        CellStyle secondary3 = createStyle(workbook, IndexedColors.LIGHT_ORANGE);
1167
 
1168
        Map<String, CellStyle> brandStyles = new HashMap<>();
1169
        brandStyles.put("Apple", createStyle(workbook, IndexedColors.GREY_25_PERCENT));
1170
        brandStyles.put("Xiaomi", createStyle(workbook, IndexedColors.ORANGE));
1171
        brandStyles.put("Vivo", createStyle(workbook, IndexedColors.SKY_BLUE));
1172
        brandStyles.put("Tecno", createStyle(workbook, IndexedColors.LIGHT_BLUE));
1173
        brandStyles.put("Samsung", createStyle(workbook, IndexedColors.ROYAL_BLUE));
1174
        brandStyles.put("Realme", createStyle(workbook, IndexedColors.YELLOW));
1175
        brandStyles.put("Oppo", createStyle(workbook, IndexedColors.LIGHT_GREEN));
1176
        brandStyles.put("OnePlus", createStyle(workbook, IndexedColors.RED));
34721 ranu 1177
        brandStyles.put("POCO", createStyle(workbook, IndexedColors.ORANGE));
34641 ranu 1178
        brandStyles.put("Lava", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1179
        brandStyles.put("Itel", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1180
        brandStyles.put("Almost New", createStyle(workbook, IndexedColors.WHITE));
1181
 
1182
 
1183
        CellStyle defaultHeaderStyle = workbook.createCellStyle();
1184
        defaultHeaderStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
1185
        defaultHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1186
        defaultHeaderStyle.setFont(font1);
1187
 
1188
 
1189
        Map<String, Integer> headerCount = new HashMap<>();
1190
 
1191
        for (int headerRowIndex = 0; headerRowIndex < headerGroup.size(); headerRowIndex++) {
1192
            List<String> headerRow = headerGroup.get(headerRowIndex);
1193
            Row row = sheet.createRow(rowIndex++);
1194
 
1195
            for (int i = 0; i < headerRow.size(); i++) {
1196
                String headerText = headerRow.get(i);
1197
                sheet.setColumnWidth(i, 25 * 256);
1198
                row.setHeightInPoints(20); // 25-point height
1199
                Cell cell = row.createCell(i);
1200
                cell.setCellValue(headerText);
1201
                cell.setCellStyle(centeredStyle);
1202
                // Count how many times this header has appeared
1203
                int count = headerCount.getOrDefault(headerText, 0) + 1;
1204
                headerCount.put(headerText, count);
1205
                // Apply special style for repeated headers
1206
                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")) {
1207
                    if (count == 1) {
1208
                        cell.setCellStyle(secondary1);
1209
                    } else if (count == 2) {
1210
                        cell.setCellStyle(secondary2);
1211
                    } else if (count == 3) {
1212
                        cell.setCellStyle(secondary3);
1213
                    }
1214
                }
1215
                // Brand header styling (apply only for the 2nd row of headers)
1216
                else if (headerRowIndex == 1 && brandStyles.containsKey(headerText)) {
1217
                    cell.setCellStyle(brandStyles.get(headerText));
1218
                }else if (headerStyles.containsKey(headerText)) {
1219
                    cell.setCellStyle(headerStyles.get(headerText));
1220
                } else {
1221
                    cell.setCellStyle(defaultHeaderStyle); // default style for others
1222
                }
1223
            }
1224
        }
1225
 
1226
        // Write data rows
1227
        for (List<?> dataRow : rows) {
1228
            Row row = sheet.createRow(rowIndex++);
1229
            for (int i = 0; i < dataRow.size(); i++) {
1230
                Cell cell = row.createCell(i);
1231
                Object value = dataRow.get(i);
34715 ranu 1232
 
1233
                if (i == 6 && value != null) { // Assuming column 6 is "Link"
1234
                    Hyperlink hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
1235
                    hyperlink.setAddress(value.toString());
34719 ranu 1236
                    cell.setCellValue("View Link"); // Display text
34715 ranu 1237
                    cell.setHyperlink(hyperlink);
1238
                    cell.setCellStyle(hyperlinkStyle);
34719 ranu 1239
                } else if (value instanceof Number) {
1240
                    cell.setCellValue(((Number) value).doubleValue());
34715 ranu 1241
                } else {
1242
                    cell.setCellValue(value != null ? value.toString() : "");
1243
                }
34641 ranu 1244
            }
34719 ranu 1245
 
34641 ranu 1246
        }
1247
 
1248
        // Auto-size columns
1249
        if (!rows.isEmpty()) {
1250
            for (int i = 0; i < rows.get(0).size(); i++) {
1251
                sheet.autoSizeColumn(i);
1252
            }
1253
        }
1254
 
1255
        // Output as ByteArray
1256
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
1257
            workbook.write(outputStream);
1258
            workbook.close();
1259
            return outputStream;
1260
        } catch (IOException e) {
1261
            throw new RuntimeException("Failed to generate Excel file", e);
1262
        }
1263
    }
1264
 
1265
 
1266
    private static CellStyle createStyle(Workbook workbook, IndexedColors color) {
1267
        CellStyle style = workbook.createCellStyle();
1268
        style.setFillForegroundColor(color.getIndex());
1269
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1270
        Font font = workbook.createFont();
1271
        font.setBold(true);
1272
        style.setFont(font);
1273
        return style;
1274
    }
1275
 
1276
 
1277
 
1278
 
34306 ranu 1279
}