Subversion Repositories SmartDukaan

Rev

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