Subversion Repositories SmartDukaan

Rev

Rev 34704 | Rev 34719 | 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
 
34701 ranu 463
        List<Integer> retailerIds = Arrays.asList(175139615,175139391,175135707);
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();
34699 ranu 482
        LocalDateTime currentMonthEndDate = LocalDateTime.now().minusDays(1);
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()))));
512
 
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()))));
34606 ranu 515
 
34648 ranu 516
        Map<Integer , String> assessmentMap = new HashMap<>();
517
        Map<Integer , String> zeroBillingMap = new HashMap<>();
518
        Map<Integer , Float> billingNeededMap = new HashMap<>();
519
        Map<Integer , Integer> countAMap = new HashMap<>();
34606 ranu 520
 
34619 ranu 521
        Map<Integer , BIRetailerModel> biRetailerModelMap = new HashMap<>();
34606 ranu 522
 
34641 ranu 523
        Map<Integer , FofoInvestmentModel> biInvestmentModelMap = new HashMap<>();
524
 
34619 ranu 525
        Map<Integer, Map<YearMonth, BiSecondaryModel>> allRetailerMonthlyData = new HashMap<>();
34606 ranu 526
 
34619 ranu 527
        Map<Integer,Double> fofoTotalStockPriceMap = new HashMap<>();
528
 
529
        Map<Integer,Map<String, BrandStockPrice>> fofoBrandStockPriceMap = new HashMap<>();
530
 
34641 ranu 531
        Map<Integer,Long> fofoTotalMtdSecondaryMap = new HashMap<>();
34619 ranu 532
 
533
 
34641 ranu 534
        Map<Integer,Map<String, Long>> fofoBrandWiseMtdSecondaryMap = new HashMap<>();
34619 ranu 535
 
34641 ranu 536
        Map<Integer,Double> fofoTotalMtdTertiaryMap = new HashMap<>();
537
 
538
        Map<Integer,Map<String, Double>> fofoBrandMtdTertiaryMap = new HashMap<>();
539
 
34606 ranu 540
        for(Integer fofoId: retailerIds){
34619 ranu 541
            String rbmName = "";
34606 ranu 542
            int rbmL1 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM,EscalationType.L1,fofoId);
34619 ranu 543
            if(rbmL1 != 0){
544
                 rbmName = authRepository.selectById(rbmL1).getFullName();
34677 ranu 545
            }else {
546
                int rbmL2 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM, EscalationType.L2, fofoId);
547
                if(rbmL2 != 0){
548
                    rbmName = authRepository.selectById(rbmL2).getFullName();
549
                }
34619 ranu 550
            }
551
            String bmName ="";
34606 ranu 552
            int bmId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L2,fofoId);
34619 ranu 553
            if(bmId !=0){
554
                bmName = authRepository.selectById(bmId).getFullName();
555
            }
34606 ranu 556
 
557
            int managerId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L1,fofoId);
558
            String managerName = " ";
559
            if(managerId != 0){
560
                 managerName = authRepository.selectById(managerId).getFullName();
561
            }else {
562
                managerName = bmName;
563
            }
564
 
565
            AST ast = astRepository.selectById(customRetailers.get(fofoId).getAstId());
566
 
567
            PartnerType partnerTypeThisMonth = partnerTypeChangeService.getTypeOnMonth(fofoId, YearMonth.now());
568
 
569
//            generate retaile detail
570
 
571
            BIRetailerModel biRetailerModel = new BIRetailerModel();
572
            biRetailerModel.setBmName(bmName);
573
            biRetailerModel.setCode(customRetailers.get(fofoId).getCode());
34619 ranu 574
            if(ast != null){
575
                biRetailerModel.setArea(ast.getArea());
576
            }else {
577
                biRetailerModel.setArea("-");
578
            }
34606 ranu 579
            biRetailerModel.setCity(customRetailers.get(fofoId).getAddress().getCity());
580
            biRetailerModel.setStoreName(customRetailers.get(fofoId).getBusinessName());
34619 ranu 581
            biRetailerModel.setStatus(String.valueOf(customRetailers.get(fofoId).getActivationType()));
34606 ranu 582
            biRetailerModel.setCategory(String.valueOf(partnerTypeThisMonth));
583
            biRetailerModel.setSalesManager(managerName);
584
            biRetailerModel.setRbm(rbmName);
585
 
34619 ranu 586
            biRetailerModelMap.put(fofoId,biRetailerModel);
587
 
34641 ranu 588
 
34606 ranu 589
//            generate secondary data
590
 
34641 ranu 591
            List<PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledMonthlyTotals = activatedImeiRepository.getTotalMonthlyActivatedNotBilled(fofoId,twoMonthsAgoStartDate);
592
            Map<YearMonth , PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledTotalMap = partnerWiseActivatedNotBilledMonthlyTotals.stream().collect(Collectors.toMap(x-> YearMonth.parse(x.getYearMonth()),x->x));
593
 
34606 ranu 594
//            this month secondary target
595
 
34619 ranu 596
            double currentSecondaryTarget =  monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId).getPurchaseTarget() : 0;
34606 ranu 597
 
34619 ranu 598
 
599
            long currentMonthReturn = currentMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId, 0L) + currentMonthRtoRefundOrderMap.getOrDefault(fofoId, 0L);
600
 
601
 
34715 ranu 602
            Map<Integer, Double> secondaryMtd = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34699 ranu 603
                    startOfToday.withDayOfMonth(1), startOfToday.with(LocalTime.MAX).minusDays(1)).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
34606 ranu 604
 
605
            double secondaryAchievedMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
606
 
34619 ranu 607
            double currentMonthNetSecondary = secondaryAchievedMtd - currentMonthReturn;
34606 ranu 608
 
34701 ranu 609
            double currentMonthSecondaryPercent = currentSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((secondaryAchievedMtd / currentSecondaryTarget) * 100));
34619 ranu 610
 
34641 ranu 611
            double currentMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(currentMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(currentMonth).getTotalUnbilledAmount() : 0d;
34619 ranu 612
 
613
//          this month tertiary----------
614
 
615
            LocalDateTime now = LocalDateTime.now();
616
            double todaySale = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday, now, fofoId, false).get(fofoId);
617
            double mtdSaleTillYesterDay = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday.withDayOfMonth(1), startOfToday, fofoId, false).get(fofoId);
618
            double mtdSale = mtdSaleTillYesterDay + todaySale;
619
 
620
 
34606 ranu 621
//            last month secondary target
622
 
34619 ranu 623
            double lastMonthSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId) != null ?  monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 624
 
34619 ranu 625
            long lastMonthReturn = (lastMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + lastMonthRtoRefundOrderMap.getOrDefault(fofoId,0L));
626
 
34715 ranu 627
            Map<Integer, Double> lastMonthSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 628
                    lastMontStartDate, lastMonthEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
629
 
630
            double lastMonthSecondaryAchieved = lastMonthSecondary.getOrDefault(fofoId, 0.0);
631
 
34619 ranu 632
            double lastMonthNetSecondary = lastMonthSecondaryAchieved - lastMonthReturn;
34606 ranu 633
 
34701 ranu 634
            double lastMonthSecondaryPercent = lastMonthSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((lastMonthSecondaryAchieved / lastMonthSecondaryTarget) * 100));
34606 ranu 635
 
34641 ranu 636
            double lastMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(lastMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(lastMonth).getTotalUnbilledAmount() : 0d;
34606 ranu 637
 
34619 ranu 638
//           last month tertiary
639
            Double lastMonthSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
640
                    lastMontStartDate, lastMonthEndDate, fofoId, false).get(fofoId);
641
 
642
 
643
//            two month ago secondary target
644
 
34703 ranu 645
            double twoMonthAgoSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId).getPurchaseTarget() : 0;
34619 ranu 646
 
647
            long twoMonthAgoReturn = (twoMonthAgoPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + twoMonthAgoRtoRefundOrderMap.getOrDefault(fofoId,0L));
648
 
34715 ranu 649
            Map<Integer, Double> twoMonthAgoSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 650
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
651
 
652
            double twoMonthAgoSecondaryAchieved = twoMonthAgoSecondary.getOrDefault(fofoId, 0.0);
653
 
34619 ranu 654
            double twoMonthAgoNetSecondary = twoMonthAgoSecondaryAchieved - twoMonthAgoReturn;
34606 ranu 655
 
34701 ranu 656
            double twoMonthAgoSecondaryPercent = twoMonthAgoSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((twoMonthAgoSecondaryAchieved / twoMonthAgoSecondaryTarget) * 100));
34619 ranu 657
 
34641 ranu 658
            double twoMonthAgoUnbilled = partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo) != null ? partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo).getTotalUnbilledAmount() : 0d;
34619 ranu 659
 
660
//          second Month Tertiary
661
            double twoMonthAgoSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
662
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate, fofoId, false).get(fofoId);
663
 
664
 
665
            Map<YearMonth, BiSecondaryModel> monthlySecondaryModels = new HashMap<>();
666
 
667
            BiSecondaryModel currentMonthSecondaryModel = new BiSecondaryModel(
668
                    currentSecondaryTarget,
669
                    secondaryAchievedMtd,
670
                    currentMonthReturn,
671
                    currentMonthNetSecondary,
672
                    currentMonthSecondaryPercent,
673
                    mtdSale,
674
                    currentMonthUnbilled // for now, unbilled tertiary value
675
            );
676
 
677
            BiSecondaryModel lastMonthSecondaryModel = new BiSecondaryModel(
678
                    lastMonthSecondaryTarget,
679
                    lastMonthSecondaryAchieved,
680
                    lastMonthReturn,
681
                    lastMonthNetSecondary,
682
                    lastMonthSecondaryPercent,
683
                    lastMonthSale,
684
                    lastMonthUnbilled // for now, unbilled tertiary value
685
            );
686
 
687
            BiSecondaryModel twoMonthAgoSecondaryModel = new BiSecondaryModel(
688
                    twoMonthAgoSecondaryTarget,
689
                    twoMonthAgoSecondaryAchieved,
690
                    twoMonthAgoReturn,
691
                    twoMonthAgoNetSecondary,
692
                    twoMonthAgoSecondaryPercent,
693
                    twoMonthAgoSale,
694
                    twoMonthAgoUnbilled // for now, unbilled tertiary value
695
            );
696
 
697
            monthlySecondaryModels.put(currentMonth, currentMonthSecondaryModel);
698
            monthlySecondaryModels.put(lastMonth, lastMonthSecondaryModel);
699
            monthlySecondaryModels.put(twoMonthsAgo, twoMonthAgoSecondaryModel);
700
 
701
            allRetailerMonthlyData.put(fofoId, monthlySecondaryModels);
702
 
703
//            brandwiseStock value price
704
 
705
            Map<String, BrandStockPrice> brandStockPriceMap = inventoryService.getBrandWiseStockValue(fofoId);
706
 
707
            fofoBrandStockPriceMap.put(fofoId,brandStockPriceMap);
708
 
709
            double totalStockPrice = brandStockPriceMap.values().stream().mapToDouble(x->x.getTotalValue()).sum();
710
 
711
            fofoTotalStockPriceMap.put(fofoId,totalStockPrice);
712
 
713
            Map<String, Double> brandMtdTertiaryAmount = fofoOrderItemRepository.selectSumAmountGroupByBrand(
714
                    currentMonthStartDate, currentMonthEndDate, fofoId);
715
 
34641 ranu 716
            fofoBrandMtdTertiaryMap.put(fofoId,brandMtdTertiaryAmount);
34619 ranu 717
 
718
            double totalMtdTertiaryAmount = brandMtdTertiaryAmount.values().stream().mapToDouble(Double::doubleValue).sum();
719
 
34641 ranu 720
            fofoTotalMtdTertiaryMap.put(fofoId,totalMtdTertiaryAmount);
34619 ranu 721
 
34641 ranu 722
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledOrderGroupByBrandFofoId(fofoId, currentMonthStartDate);
723
            Map<String,Long> brandWiseMtdSecondaryMap = brandWiseMtdSecondary.stream().collect(Collectors.toMap(BrandWiseModel::getBrand,BrandWiseModel::getAmount));
724
            fofoBrandWiseMtdSecondaryMap.put(fofoId,brandWiseMtdSecondaryMap);
34619 ranu 725
 
34641 ranu 726
            long mtdTotalSecondary = brandWiseMtdSecondary.stream().mapToLong(x -> x.getAmount() != 0 ? x.getAmount() : 0L).sum();
34619 ranu 727
 
34641 ranu 728
            fofoTotalMtdSecondaryMap.put(fofoId,mtdTotalSecondary);
729
 
730
            //            generate investment info
731
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
732
            float shortInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getShortInvestment() : 0f;
733
            float agreedInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getMinInvestment() : 0f;
34677 ranu 734
            float investmentLevel = partnerDailyInvestmentMap.get(fofoId) != null
735
                    ? Math.abs(((shortInvestment - agreedInvestment) / agreedInvestment) * 100)
736
                    : 0f;
34641 ranu 737
 
34677 ranu 738
 
34641 ranu 739
            List<Loan> fofoDefaultLoans = new ArrayList<>();
740
            if(defaultLoanMap != null){
741
                 fofoDefaultLoans  =  defaultLoanMap.get(fofoId);
742
                LOGGER.info("fofoDefaultLoans {}",fofoDefaultLoans);
743
            }
744
 
745
            float defaultLoanAmount = 0f;
746
            if(fofoDefaultLoans != null ){
747
                if (!fofoDefaultLoans.isEmpty()) {
748
                    defaultLoanAmount =  fofoDefaultLoans.stream().map(Loan::getPendingAmount).reduce(BigDecimal.ZERO, BigDecimal::add).floatValue(); // or .floatValue() directly
749
                }
750
            }
751
 
752
            float activeLoan = loanRepository.selectActiveLoan(fofoId).stream().map(Loan::getPendingAmount).reduce(BigDecimal.ZERO,BigDecimal::add).floatValue();
753
 
754
 
755
            float poValue = partnerDailyInvestmentMap.get(fofoId) != null ?  partnerDailyInvestmentMap.get(fofoId).getUnbilledAmount() : 0f;
756
 
34677 ranu 757
            List<Order> billedAndPoOrder = orderRepository.selectOrders(Arrays.asList(fofoId),Arrays.asList(OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.ACCEPTED, OrderStatus.BILLED, OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERY_SUCCESS),currentMonthStartDate,startOfToday.plusDays(1));
34641 ranu 758
            float poAndBilledValue = (float) billedAndPoOrder.stream().map(Order::getTotalAmount).reduce(0f,Float::sum);
759
 
760
            double purchaseMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
761
 
762
            double todayRequiredDrr = rbmTargetService.calculateFofoIdTodayTarget(fofoId, purchaseMtd,LocalDate.now());
763
 
764
            double monthDay1Drr = rbmTargetService.calculateFofoIdTodayTarget(fofoId,0d,YearMonth.now().atDay(1));
765
 
766
 
767
            double gotDrrPercent = (todayRequiredDrr / monthDay1Drr) * 100;
768
 
34701 ranu 769
            long drrPercentDisplay = Math.round(Math.abs(gotDrrPercent));
770
 
771
 
34641 ranu 772
            int orderId = orderRepository.getLastOrderByFofoId(fofoId);
773
 
34644 ranu 774
            // Determine alert level
775
            String alertLevel = "-";
776
            int lastPurchaseDays = 0;
34641 ranu 777
            if (orderId != 0) {
778
                Order order = orderRepository.selectById(orderId);
779
 
34715 ranu 780
                LOGGER.info("last billing order - {}",order);
781
 
34641 ranu 782
                // Calculate the number of days since the last purchase (billing)
34644 ranu 783
                lastPurchaseDays = (int) Duration.between(order.getCreateTimestamp().plusDays(1), LocalDateTime.now()).toDays();
34641 ranu 784
 
785
                if (lastPurchaseDays >= 11) {
786
                    alertLevel = "Alert for Management";
34676 ranu 787
                } else if (lastPurchaseDays >= 10) {
34641 ranu 788
                    alertLevel = " Alert for RSM/SH";
34676 ranu 789
                } else if (lastPurchaseDays >= 7) {
34641 ranu 790
                    alertLevel = "Must be Billed";
791
                } else if (lastPurchaseDays >= 3) {
792
                    alertLevel = "OK";
793
                } else {
34676 ranu 794
                    alertLevel = "OK";
34641 ranu 795
                }
34644 ranu 796
            }
34641 ranu 797
 
34644 ranu 798
            //investment modal set all related value
799
            FofoInvestmentModel fofoInvestmentModel = new FofoInvestmentModel();
34641 ranu 800
 
34644 ranu 801
            fofoInvestmentModel.setCounterPotential(fofoStore.getCounterPotential());
802
            fofoInvestmentModel.setShortInvestment(shortInvestment);
803
            fofoInvestmentModel.setDefaultLoan(defaultLoanAmount);
804
            fofoInvestmentModel.setInvestmentLevel(investmentLevel);
805
            fofoInvestmentModel.setActiveLoan(activeLoan);
806
            fofoInvestmentModel.setPoValue(poValue);
807
            fofoInvestmentModel.setPoAndBilled(poAndBilledValue);
808
            fofoInvestmentModel.setAgreedInvestment(agreedInvestment);
809
            fofoInvestmentModel.setWallet(partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getWalletAmount() : 0);
810
            fofoInvestmentModel.setMonthBeginingDrr(monthDay1Drr);
811
            fofoInvestmentModel.setRequiredDrr(todayRequiredDrr);
34701 ranu 812
            fofoInvestmentModel.setDrrPercent(drrPercentDisplay);
34644 ranu 813
            fofoInvestmentModel.setLastBillingDone(lastPurchaseDays);
814
            fofoInvestmentModel.setSlab(alertLevel);
34641 ranu 815
 
34644 ranu 816
            biInvestmentModelMap.put(fofoId, fofoInvestmentModel);
34641 ranu 817
                String assessment = "";
818
                if(defaultLoanAmount > 0 ){
819
                    assessment = "Loan Default";
820
                }else if(investmentLevel <= 75 && defaultLoanAmount < 1){
821
                    assessment = "Low Invest";
822
                }else {
823
                    assessment = "-";
824
                }
825
                assessmentMap.put(fofoId,assessment);
826
 
827
                String zeroBilling = "";
828
                if(currentMonthNetSecondary <= 100000 ){
829
                    zeroBilling = "Zero Billing";
830
                }else {
831
                    zeroBilling = "-";
832
                }
833
                zeroBillingMap.put(fofoId,zeroBilling);
834
 
835
                float billingNeeded = 0f;
34701 ranu 836
                if(drrPercentDisplay >= 110 ){
34641 ranu 837
                    billingNeeded = (float) todayRequiredDrr;
838
                }else {
839
                    billingNeeded = 0f;
840
                }
841
                billingNeededMap.put(fofoId,billingNeeded);
842
 
843
                int counta = 0;
34701 ranu 844
                if(defaultLoanAmount > 0 || investmentLevel <= 75 || currentMonthNetSecondary <= 100000 || drrPercentDisplay >= 110 ){
34641 ranu 845
                    counta = 1;
846
                }else {
847
                    counta = 0;
848
                }
849
                countAMap.put(fofoId,counta);
850
 
34606 ranu 851
        }
852
 
34619 ranu 853
        LOGGER.info("Total BI Retailers processed: {}", biRetailerModelMap.size());
34606 ranu 854
 
34619 ranu 855
        //generate excel and sent to mail
856
        List<List<String>> headerGroup = new ArrayList<>();
34606 ranu 857
 
34619 ranu 858
        List<String> headers1 = Arrays.asList(
34641 ranu 859
                "","","","",
34715 ranu 860
                "Retailer Detail", "","", "", "", "", "", "", "", "","","","",
34677 ranu 861
 
862
                twoMonthAgoStringValue, "", "", "", "", "", "",
863
                lastMonthStringValue, "", "", "", "", "", "",
34619 ranu 864
                currentMonthStringValue, "", "", "", "", "", "",
34641 ranu 865
 
866
                "","", "", "", "", "", "", "", "", "", "", "", "", "",
867
 
868
                "", "", "", "", "", "", "", "", "", "", "", "", "",
869
                "", "", "", "", "", "", "", "", "", "", "", "", ""
870
 
34619 ranu 871
        );
34606 ranu 872
 
34619 ranu 873
        List<String> headers2 = Arrays.asList(
34641 ranu 874
                "Assessment","Zero billing","Billing needed","Counta",
34715 ranu 875
                "BM","Partner Id","Link","Wallet Date","Creation Date","Code","Area",  "City", "Store Name", "Status","Category","Sales Manager", "RBM",
34619 ranu 876
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
877
                "Tertiary Sale", "Unbilled",
878
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
879
                "Tertiary Sale", "Unbilled",
880
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
881
                "Tertiary Sale", "Unbilled",
34641 ranu 882
                "Counter Potential", "Short investment", "Default", "INVESTMENT LEVEL", "Loan", "PO value", "Agreed investment",
883
                "Wallet", "po+bill", "MONTH BEGINNING DRR", "REQ DRR", "Drr %", "Last billing Done", "Slab",
34606 ranu 884
 
34641 ranu 885
              "Total Stock",  "Apple","Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "Poco", "Lava", "Itel", "Almost New",
886
              "Total Secondary", "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "Poco", "Lava", "Itel", "Almost New",
887
              "Total Tertiary",  "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "Poco", "Lava", "Itel", "Almost New"
34619 ranu 888
        );
889
 
890
        headerGroup.add(headers1);
891
        headerGroup.add(headers2);
892
 
893
 
894
        List<List<?>> rows = new ArrayList<>();
895
        for (Map.Entry<Integer, BIRetailerModel> entry : biRetailerModelMap.entrySet()) {
896
            Integer fofoId = entry.getKey();
34715 ranu 897
            User user = userRepository.selectById(fofoId);
898
            LocalDateTime walletCreationDate = userWalletHistoryRepository.selectFirstCreatedDate(fofoId);
34619 ranu 899
            BIRetailerModel retailer = entry.getValue();
34641 ranu 900
 
34619 ranu 901
            Map<YearMonth, BiSecondaryModel> monthlyData = allRetailerMonthlyData.get(fofoId);
902
 
903
            BiSecondaryModel current = monthlyData.getOrDefault(YearMonth.now(), new BiSecondaryModel(0,0,0,0,0,0,0));
904
            BiSecondaryModel last = monthlyData.getOrDefault(YearMonth.now().minusMonths(1), new BiSecondaryModel(0,0,0,0,0,0,0));
905
            BiSecondaryModel twoAgo = monthlyData.getOrDefault(YearMonth.now().minusMonths(2), new BiSecondaryModel(0,0,0,0,0,0,0));
906
 
907
            List<Object> row = new ArrayList<>();
908
            row.addAll(Arrays.asList(
34641 ranu 909
                    assessmentMap.get(fofoId),zeroBillingMap.get(fofoId),billingNeededMap.get(fofoId),countAMap.get(fofoId),
34715 ranu 910
                    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 911
                    retailer.getCategory(),  retailer.getSalesManager(), retailer.getRbm()
912
 
34619 ranu 913
            ));
914
 
34677 ranu 915
 
916
            // Two Months Ago
34619 ranu 917
            row.addAll(Arrays.asList(
34677 ranu 918
                    twoAgo.getSecondaryTarget(),
919
                    twoAgo.getSecondaryAchieved(),
920
                    twoAgo.getSecondaryReturn(),
921
                    twoAgo.getNetSecondary(),
34704 ranu 922
                    twoAgo.getSecondaryAchievedPercent()+"%",
34677 ranu 923
                    twoAgo.getTertiary(),
924
                    twoAgo.getTertiaryUnBilled()
34619 ranu 925
            ));
926
 
927
            // Last Month
928
            row.addAll(Arrays.asList(
929
                    last.getSecondaryTarget(),
930
                    last.getSecondaryAchieved(),
931
                    last.getSecondaryReturn(),
932
                    last.getNetSecondary(),
34704 ranu 933
                    last.getSecondaryAchievedPercent()+"%",
34619 ranu 934
                    last.getTertiary(),
935
                    last.getTertiaryUnBilled()
936
            ));
937
 
34677 ranu 938
            // Current Month
34619 ranu 939
            row.addAll(Arrays.asList(
34677 ranu 940
                    current.getSecondaryTarget(),
941
                    current.getSecondaryAchieved(),
942
                    current.getSecondaryReturn(),
943
                    current.getNetSecondary(),
34704 ranu 944
                    current.getSecondaryAchievedPercent()+"%",
34677 ranu 945
                    current.getTertiary(),
946
                    current.getTertiaryUnBilled()
34619 ranu 947
            ));
34677 ranu 948
 
949
 
950
 
34641 ranu 951
            FofoInvestmentModel fofoInvestmentModelValue = biInvestmentModelMap.get(fofoId);
952
            if(fofoInvestmentModelValue != null){
953
                row.addAll(Arrays.asList(
954
                        fofoInvestmentModelValue.getCounterPotential(),
955
                        fofoInvestmentModelValue.getShortInvestment(),
956
                        fofoInvestmentModelValue.getDefaultLoan(),
957
                        fofoInvestmentModelValue.getInvestmentLevel(),
34715 ranu 958
                       "-"+fofoInvestmentModelValue.getActiveLoan(),
34641 ranu 959
                        fofoInvestmentModelValue.getPoValue(),
960
                        fofoInvestmentModelValue.getAgreedInvestment(),
961
                        fofoInvestmentModelValue.getWallet(),
962
                        fofoInvestmentModelValue.getPoAndBilled(),
963
                        fofoInvestmentModelValue.getMonthBeginingDrr(),
964
                        fofoInvestmentModelValue.getRequiredDrr(),
34704 ranu 965
                        fofoInvestmentModelValue.getDrrPercent()+"%",
34641 ranu 966
                        fofoInvestmentModelValue.getLastBillingDone(),
967
                        fofoInvestmentModelValue.getSlab()
968
                ));
969
            }else {
970
                row.addAll(Arrays.asList(
971
                        "-","-","-","-","-","-","-","-","-","-","-",""
972
                ));
973
            }
974
 
975
            Map<String, BrandStockPrice> brandStockMap = fofoBrandStockPriceMap.get(fofoId);
34619 ranu 976
            row.addAll(Arrays.asList(
977
                    fofoTotalStockPriceMap.getOrDefault(fofoId, 0.0),
34641 ranu 978
                    brandStockMap.get("Apple") != null ? brandStockMap.get("Apple").getTotalValue() : 0.0,
979
                    brandStockMap.get("Xiaomi") != null ? brandStockMap.get("Xiaomi").getTotalValue() : 0.0,
980
                    brandStockMap.get("Vivo") != null ? brandStockMap.get("Vivo").getTotalValue() : 0.0,
981
                    brandStockMap.get("Tecno") != null ? brandStockMap.get("Tecno").getTotalValue() : 0.0,
982
                    brandStockMap.get("Samsung") != null ? brandStockMap.get("Samsung").getTotalValue() : 0.0,
983
                    brandStockMap.get("Realme") != null ? brandStockMap.get("Realme").getTotalValue() : 0.0,
984
                    brandStockMap.get("Oppo") != null ? brandStockMap.get("Oppo").getTotalValue() : 0.0,
985
                    brandStockMap.get("OnePlus") != null ? brandStockMap.get("OnePlus").getTotalValue() : 0.0,
986
                    brandStockMap.get("Poco") != null ? brandStockMap.get("Poco").getTotalValue() : 0.0,
987
                    brandStockMap.get("Lava") != null ? brandStockMap.get("Lava").getTotalValue() : 0.0,
988
                    brandStockMap.get("Itel") != null ? brandStockMap.get("Itel").getTotalValue() : 0.0,
989
                    brandStockMap.get("Almost New") != null ? brandStockMap.get("Almost New").getTotalValue() : 0.0
34619 ranu 990
            ));
991
 
34641 ranu 992
            Map<String, Long> brandSecondaryMap = fofoBrandWiseMtdSecondaryMap.get(fofoId);
993
            row.addAll(Arrays.asList(
34648 ranu 994
                    fofoTotalMtdSecondaryMap.get(fofoId),
34641 ranu 995
                    brandSecondaryMap.getOrDefault("Apple", 0L),
996
                    brandSecondaryMap.getOrDefault("Xiaomi", 0L),
997
                    brandSecondaryMap.getOrDefault("Vivo", 0L),
998
                    brandSecondaryMap.getOrDefault("Tecno", 0L),
999
                    brandSecondaryMap.getOrDefault("Samsung", 0L),
1000
                    brandSecondaryMap.getOrDefault("Realme", 0L),
1001
                    brandSecondaryMap.getOrDefault("Oppo", 0L),
1002
                    brandSecondaryMap.getOrDefault("OnePlus", 0L),
1003
                    brandSecondaryMap.getOrDefault("Poco", 0L),
1004
                    brandSecondaryMap.getOrDefault("Lava", 0L),
1005
                    brandSecondaryMap.getOrDefault("Itel", 0L),
1006
                    brandSecondaryMap.getOrDefault("Almost New", 0L)
1007
            ));
1008
 
1009
            Map<String, Double> brandTertiaryMap = fofoBrandMtdTertiaryMap.get(fofoId);
1010
            row.addAll(Arrays.asList(
34648 ranu 1011
                    fofoTotalMtdTertiaryMap.get(fofoId),
34641 ranu 1012
                    brandTertiaryMap.getOrDefault("Apple", 0d),
1013
                    brandTertiaryMap.getOrDefault("Xiaomi", 0d),
1014
                    brandTertiaryMap.getOrDefault("Vivo", 0d),
1015
                    brandTertiaryMap.getOrDefault("Tecno", 0d),
1016
                    brandTertiaryMap.getOrDefault("Samsung", 0d),
1017
                    brandTertiaryMap.getOrDefault("Realme", 0d),
1018
                    brandTertiaryMap.getOrDefault("Oppo", 0d),
1019
                    brandTertiaryMap.getOrDefault("OnePlus", 0d),
1020
                    brandTertiaryMap.getOrDefault("Poco", 0d),
1021
                    brandTertiaryMap.getOrDefault("Lava", 0d),
1022
                    brandTertiaryMap.getOrDefault("Itel", 0d),
1023
                    brandTertiaryMap.getOrDefault("Almost New", 0d)
1024
            ));
1025
            rows.add(row);
34619 ranu 1026
        }
1027
 
1028
 
34641 ranu 1029
        // Send to email
1030
//        ByteArrayOutputStream csvStream = FileUtil.getCSVByteStreamWithMultiHeaders(headerGroup, rows);
1031
        ByteArrayOutputStream csvStream = getExcelStreamWithMultiHeaders(headerGroup, rows);
1032
        String fileName = "BI-Retailer-Monthly-Report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".xlsx";
34702 ranu 1033
        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com","ashutosh.verma@smartdukaan.com","sm@smartdukaan.com","raj.singh@smartdukaan.com"};
1034
//        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com"};
34619 ranu 1035
 
1036
        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()));
1037
 
1038
 
34606 ranu 1039
    }
1040
 
34641 ranu 1041
    public static ByteArrayOutputStream getExcelStreamWithMultiHeaders(List<List<String>> headerGroup, List<List<?>> rows) {
1042
        Workbook workbook = new XSSFWorkbook();
1043
        Sheet sheet = workbook.createSheet("BI Report");
34715 ranu 1044
        CreationHelper creationHelper = workbook.getCreationHelper();
34641 ranu 1045
        int rowIndex = 0;
34606 ranu 1046
 
34641 ranu 1047
        CellStyle centeredStyle = workbook.createCellStyle();
1048
        centeredStyle.setAlignment(HorizontalAlignment.CENTER); // Center horizontally
1049
        centeredStyle.setVerticalAlignment(VerticalAlignment.CENTER); // Center vertically
34606 ranu 1050
 
34641 ranu 1051
    // Optional: bold font
1052
        Font font1 = workbook.createFont();
1053
        font1.setBold(true);
1054
        centeredStyle.setFont(font1);
34606 ranu 1055
 
34619 ranu 1056
 
34641 ranu 1057
 
1058
        // Create styles
1059
        Map<String, CellStyle> headerStyles = new HashMap<>();
1060
 
1061
        // fontPurpleStyle
1062
        CellStyle purpleStyle = workbook.createCellStyle();
1063
        purpleStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
1064
        purpleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1065
        purpleStyle.setFont(font1);
1066
        headerStyles.put("Assessment", purpleStyle);
1067
        headerStyles.put("Zero billing", purpleStyle);
1068
        headerStyles.put("Billing needed", purpleStyle);
1069
        headerStyles.put("Counta", purpleStyle);
1070
        headerStyles.put("MONTH BEGINNING DRR", purpleStyle);
1071
        headerStyles.put("REQ DRR", purpleStyle);
1072
        headerStyles.put("Drr %", purpleStyle);
1073
 
1074
        // Light Blue
1075
        CellStyle blueStyle = workbook.createCellStyle();
1076
        blueStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
1077
        blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1078
        blueStyle.setFont(font1);
1079
        headerStyles.put("Code", blueStyle);
1080
        headerStyles.put("Store Name", blueStyle);
1081
        headerStyles.put("City", blueStyle);
1082
        headerStyles.put("Area", blueStyle);
1083
        headerStyles.put("BM", blueStyle);
1084
        headerStyles.put("RBM", blueStyle);
1085
        headerStyles.put("Sales Manager", blueStyle);
1086
        headerStyles.put("Status", blueStyle);
1087
        headerStyles.put("Category", blueStyle);
34715 ranu 1088
        headerStyles.put("Wallet Date", blueStyle);
1089
        headerStyles.put("Creation Date", blueStyle);
1090
        headerStyles.put("Partner Id", blueStyle);
34641 ranu 1091
 
34715 ranu 1092
        //for link
1093
        // Create hyperlink style
1094
        CellStyle hyperlinkStyle = workbook.createCellStyle();
1095
        Font hlinkFont = workbook.createFont();
1096
        hlinkFont.setUnderline(Font.U_SINGLE);
1097
        hlinkFont.setColor(IndexedColors.BLUE.getIndex());
1098
        hyperlinkStyle.setFont(hlinkFont);
1099
 
1100
 
34641 ranu 1101
        // Light Yellow
1102
        CellStyle yellowStyle = workbook.createCellStyle();
1103
        yellowStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
1104
        yellowStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1105
        yellowStyle.setFont(font1);
1106
        headerStyles.put("Last billing Done", yellowStyle);
1107
        headerStyles.put("Total Stock", yellowStyle);
1108
 
1109
        // Light Orange
1110
        CellStyle orangeStyle = workbook.createCellStyle();
1111
        orangeStyle.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
1112
        orangeStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1113
        orangeStyle.setFont(font1);
1114
        headerStyles.put("Total Tertiary", orangeStyle);
1115
        headerStyles.put("Total Secondary", orangeStyle);
1116
        headerStyles.put("Default", orangeStyle);
1117
 
1118
 
1119
        // Light green
1120
        CellStyle lightGreenStyle = workbook.createCellStyle();
1121
        lightGreenStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
1122
        lightGreenStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1123
        lightGreenStyle.setFont(font1);
1124
        headerStyles.put("Short investment", lightGreenStyle);
1125
        headerStyles.put("INVESTMENT LEVEL", lightGreenStyle);
1126
        headerStyles.put("Loan", lightGreenStyle);
1127
        headerStyles.put("PO value", lightGreenStyle);
1128
        headerStyles.put("Agreed investment", lightGreenStyle);
1129
        headerStyles.put("Wallet", lightGreenStyle);
1130
        headerStyles.put("po+bill", lightGreenStyle);
1131
 
1132
        // Light Green
1133
        CellStyle secondary1 = createStyle(workbook, IndexedColors.LIGHT_GREEN);
1134
        CellStyle secondary2 = createStyle(workbook, IndexedColors.LIGHT_YELLOW);
1135
        CellStyle secondary3 = createStyle(workbook, IndexedColors.LIGHT_ORANGE);
1136
 
1137
        Map<String, CellStyle> brandStyles = new HashMap<>();
1138
        brandStyles.put("Apple", createStyle(workbook, IndexedColors.GREY_25_PERCENT));
1139
        brandStyles.put("Xiaomi", createStyle(workbook, IndexedColors.ORANGE));
1140
        brandStyles.put("Vivo", createStyle(workbook, IndexedColors.SKY_BLUE));
1141
        brandStyles.put("Tecno", createStyle(workbook, IndexedColors.LIGHT_BLUE));
1142
        brandStyles.put("Samsung", createStyle(workbook, IndexedColors.ROYAL_BLUE));
1143
        brandStyles.put("Realme", createStyle(workbook, IndexedColors.YELLOW));
1144
        brandStyles.put("Oppo", createStyle(workbook, IndexedColors.LIGHT_GREEN));
1145
        brandStyles.put("OnePlus", createStyle(workbook, IndexedColors.RED));
1146
        brandStyles.put("Poco", createStyle(workbook, IndexedColors.ORANGE));
1147
        brandStyles.put("Lava", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1148
        brandStyles.put("Itel", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1149
        brandStyles.put("Almost New", createStyle(workbook, IndexedColors.WHITE));
1150
 
1151
 
1152
        CellStyle defaultHeaderStyle = workbook.createCellStyle();
1153
        defaultHeaderStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
1154
        defaultHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1155
        defaultHeaderStyle.setFont(font1);
1156
 
1157
 
1158
        Map<String, Integer> headerCount = new HashMap<>();
1159
 
1160
        for (int headerRowIndex = 0; headerRowIndex < headerGroup.size(); headerRowIndex++) {
1161
            List<String> headerRow = headerGroup.get(headerRowIndex);
1162
            Row row = sheet.createRow(rowIndex++);
1163
 
1164
            for (int i = 0; i < headerRow.size(); i++) {
1165
                String headerText = headerRow.get(i);
1166
                sheet.setColumnWidth(i, 25 * 256);
1167
                row.setHeightInPoints(20); // 25-point height
1168
                Cell cell = row.createCell(i);
1169
                cell.setCellValue(headerText);
1170
                cell.setCellStyle(centeredStyle);
1171
                // Count how many times this header has appeared
1172
                int count = headerCount.getOrDefault(headerText, 0) + 1;
1173
                headerCount.put(headerText, count);
1174
                // Apply special style for repeated headers
1175
                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")) {
1176
                    if (count == 1) {
1177
                        cell.setCellStyle(secondary1);
1178
                    } else if (count == 2) {
1179
                        cell.setCellStyle(secondary2);
1180
                    } else if (count == 3) {
1181
                        cell.setCellStyle(secondary3);
1182
                    }
1183
                }
1184
                // Brand header styling (apply only for the 2nd row of headers)
1185
                else if (headerRowIndex == 1 && brandStyles.containsKey(headerText)) {
1186
                    cell.setCellStyle(brandStyles.get(headerText));
1187
                }else if (headerStyles.containsKey(headerText)) {
1188
                    cell.setCellStyle(headerStyles.get(headerText));
1189
                } else {
1190
                    cell.setCellStyle(defaultHeaderStyle); // default style for others
1191
                }
1192
            }
1193
        }
1194
 
1195
        // Write data rows
1196
        for (List<?> dataRow : rows) {
1197
            Row row = sheet.createRow(rowIndex++);
1198
            for (int i = 0; i < dataRow.size(); i++) {
1199
                Cell cell = row.createCell(i);
1200
                Object value = dataRow.get(i);
1201
                if (value instanceof Number) {
1202
                    cell.setCellValue(((Number) value).doubleValue());
1203
                } else {
1204
                    cell.setCellValue(value != null ? value.toString() : "");
1205
                }
34715 ranu 1206
 
1207
                if (i == 6 && value != null) { // Assuming column 6 is "Link"
1208
                    Hyperlink hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
1209
                    hyperlink.setAddress(value.toString());
1210
                    cell.setCellValue("View Link"); // Text to display in Excel
1211
                    cell.setHyperlink(hyperlink);
1212
                    cell.setCellStyle(hyperlinkStyle);
1213
                } else {
1214
                    cell.setCellValue(value != null ? value.toString() : "");
1215
                }
34641 ranu 1216
            }
1217
        }
1218
 
1219
        // Auto-size columns
1220
        if (!rows.isEmpty()) {
1221
            for (int i = 0; i < rows.get(0).size(); i++) {
1222
                sheet.autoSizeColumn(i);
1223
            }
1224
        }
1225
 
1226
        // Output as ByteArray
1227
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
1228
            workbook.write(outputStream);
1229
            workbook.close();
1230
            return outputStream;
1231
        } catch (IOException e) {
1232
            throw new RuntimeException("Failed to generate Excel file", e);
1233
        }
1234
    }
1235
 
1236
 
1237
    private static CellStyle createStyle(Workbook workbook, IndexedColors color) {
1238
        CellStyle style = workbook.createCellStyle();
1239
        style.setFillForegroundColor(color.getIndex());
1240
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1241
        Font font = workbook.createFont();
1242
        font.setBold(true);
1243
        style.setFont(font);
1244
        return style;
1245
    }
1246
 
1247
 
1248
 
1249
 
34306 ranu 1250
}