Subversion Repositories SmartDukaan

Rev

Rev 34721 | Rev 34724 | 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()))));
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(
34722 ranu 714
                    currentMonthStartDate, currentMonthEndDate, fofoId);
34619 ranu 715
 
34719 ranu 716
 
34641 ranu 717
            fofoBrandMtdTertiaryMap.put(fofoId,brandMtdTertiaryAmount);
34619 ranu 718
 
719
            double totalMtdTertiaryAmount = brandMtdTertiaryAmount.values().stream().mapToDouble(Double::doubleValue).sum();
720
 
34641 ranu 721
            fofoTotalMtdTertiaryMap.put(fofoId,totalMtdTertiaryAmount);
34619 ranu 722
 
34719 ranu 723
            LOGGER.info("fofoTotalMtdTertiaryMap- {}",fofoTotalMtdTertiaryMap);
724
            LOGGER.info("fofoBrandMtdTertiaryMap- {}",fofoBrandMtdTertiaryMap);
725
 
726
 
34721 ranu 727
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledByCategoryOrderGroupByBrandFofoId(fofoId, currentMonthStartDate,Arrays.asList(10006,10009,10010));
34641 ranu 728
            Map<String,Long> brandWiseMtdSecondaryMap = brandWiseMtdSecondary.stream().collect(Collectors.toMap(BrandWiseModel::getBrand,BrandWiseModel::getAmount));
729
            fofoBrandWiseMtdSecondaryMap.put(fofoId,brandWiseMtdSecondaryMap);
34619 ranu 730
 
34641 ranu 731
            long mtdTotalSecondary = brandWiseMtdSecondary.stream().mapToLong(x -> x.getAmount() != 0 ? x.getAmount() : 0L).sum();
34619 ranu 732
 
34641 ranu 733
            fofoTotalMtdSecondaryMap.put(fofoId,mtdTotalSecondary);
734
 
735
            //            generate investment info
736
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
737
            float shortInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getShortInvestment() : 0f;
738
            float agreedInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getMinInvestment() : 0f;
34677 ranu 739
            float investmentLevel = partnerDailyInvestmentMap.get(fofoId) != null
740
                    ? Math.abs(((shortInvestment - agreedInvestment) / agreedInvestment) * 100)
741
                    : 0f;
34641 ranu 742
 
34677 ranu 743
 
34641 ranu 744
            List<Loan> fofoDefaultLoans = new ArrayList<>();
745
            if(defaultLoanMap != null){
746
                 fofoDefaultLoans  =  defaultLoanMap.get(fofoId);
747
                LOGGER.info("fofoDefaultLoans {}",fofoDefaultLoans);
748
            }
749
 
750
            float defaultLoanAmount = 0f;
751
            if(fofoDefaultLoans != null ){
752
                if (!fofoDefaultLoans.isEmpty()) {
753
                    defaultLoanAmount =  fofoDefaultLoans.stream().map(Loan::getPendingAmount).reduce(BigDecimal.ZERO, BigDecimal::add).floatValue(); // or .floatValue() directly
754
                }
755
            }
756
 
34719 ranu 757
            List<Loan> activeLoans = loanRepository.selectAllActiveLoan(fofoId);
34641 ranu 758
 
34719 ranu 759
            LOGGER.info("activeLoans- {}",activeLoans);
34641 ranu 760
 
34719 ranu 761
            float activeLoan = activeLoans.stream().map(Loan::getPendingAmount).reduce(BigDecimal.ZERO,BigDecimal::add).floatValue();
762
 
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
 
768
            double purchaseMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
769
 
770
            double todayRequiredDrr = rbmTargetService.calculateFofoIdTodayTarget(fofoId, purchaseMtd,LocalDate.now());
771
 
772
            double monthDay1Drr = rbmTargetService.calculateFofoIdTodayTarget(fofoId,0d,YearMonth.now().atDay(1));
773
 
774
 
775
            double gotDrrPercent = (todayRequiredDrr / monthDay1Drr) * 100;
776
 
34701 ranu 777
            long drrPercentDisplay = Math.round(Math.abs(gotDrrPercent));
778
 
779
 
34641 ranu 780
            int orderId = orderRepository.getLastOrderByFofoId(fofoId);
781
 
34644 ranu 782
            // Determine alert level
783
            String alertLevel = "-";
784
            int lastPurchaseDays = 0;
34641 ranu 785
            if (orderId != 0) {
786
                Order order = orderRepository.selectById(orderId);
787
 
34715 ranu 788
                LOGGER.info("last billing order - {}",order);
789
 
34641 ranu 790
                // Calculate the number of days since the last purchase (billing)
34644 ranu 791
                lastPurchaseDays = (int) Duration.between(order.getCreateTimestamp().plusDays(1), LocalDateTime.now()).toDays();
34641 ranu 792
 
793
                if (lastPurchaseDays >= 11) {
794
                    alertLevel = "Alert for Management";
34676 ranu 795
                } else if (lastPurchaseDays >= 10) {
34641 ranu 796
                    alertLevel = " Alert for RSM/SH";
34676 ranu 797
                } else if (lastPurchaseDays >= 7) {
34641 ranu 798
                    alertLevel = "Must be Billed";
799
                } else if (lastPurchaseDays >= 3) {
800
                    alertLevel = "OK";
801
                } else {
34676 ranu 802
                    alertLevel = "OK";
34641 ranu 803
                }
34644 ranu 804
            }
34641 ranu 805
 
34644 ranu 806
            //investment modal set all related value
807
            FofoInvestmentModel fofoInvestmentModel = new FofoInvestmentModel();
34641 ranu 808
 
34644 ranu 809
            fofoInvestmentModel.setCounterPotential(fofoStore.getCounterPotential());
810
            fofoInvestmentModel.setShortInvestment(shortInvestment);
811
            fofoInvestmentModel.setDefaultLoan(defaultLoanAmount);
812
            fofoInvestmentModel.setInvestmentLevel(investmentLevel);
813
            fofoInvestmentModel.setActiveLoan(activeLoan);
814
            fofoInvestmentModel.setPoValue(poValue);
815
            fofoInvestmentModel.setPoAndBilled(poAndBilledValue);
816
            fofoInvestmentModel.setAgreedInvestment(agreedInvestment);
817
            fofoInvestmentModel.setWallet(partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getWalletAmount() : 0);
818
            fofoInvestmentModel.setMonthBeginingDrr(monthDay1Drr);
819
            fofoInvestmentModel.setRequiredDrr(todayRequiredDrr);
34701 ranu 820
            fofoInvestmentModel.setDrrPercent(drrPercentDisplay);
34644 ranu 821
            fofoInvestmentModel.setLastBillingDone(lastPurchaseDays);
822
            fofoInvestmentModel.setSlab(alertLevel);
34641 ranu 823
 
34644 ranu 824
            biInvestmentModelMap.put(fofoId, fofoInvestmentModel);
34641 ranu 825
                String assessment = "";
826
                if(defaultLoanAmount > 0 ){
827
                    assessment = "Loan Default";
828
                }else if(investmentLevel <= 75 && defaultLoanAmount < 1){
829
                    assessment = "Low Invest";
830
                }else {
831
                    assessment = "-";
832
                }
833
                assessmentMap.put(fofoId,assessment);
834
 
835
                String zeroBilling = "";
836
                if(currentMonthNetSecondary <= 100000 ){
837
                    zeroBilling = "Zero Billing";
838
                }else {
839
                    zeroBilling = "-";
840
                }
841
                zeroBillingMap.put(fofoId,zeroBilling);
842
 
843
                float billingNeeded = 0f;
34701 ranu 844
                if(drrPercentDisplay >= 110 ){
34641 ranu 845
                    billingNeeded = (float) todayRequiredDrr;
846
                }else {
847
                    billingNeeded = 0f;
848
                }
849
                billingNeededMap.put(fofoId,billingNeeded);
850
 
851
                int counta = 0;
34701 ranu 852
                if(defaultLoanAmount > 0 || investmentLevel <= 75 || currentMonthNetSecondary <= 100000 || drrPercentDisplay >= 110 ){
34641 ranu 853
                    counta = 1;
854
                }else {
855
                    counta = 0;
856
                }
857
                countAMap.put(fofoId,counta);
858
 
34606 ranu 859
        }
860
 
34619 ranu 861
        LOGGER.info("Total BI Retailers processed: {}", biRetailerModelMap.size());
34606 ranu 862
 
34619 ranu 863
        //generate excel and sent to mail
864
        List<List<String>> headerGroup = new ArrayList<>();
34606 ranu 865
 
34619 ranu 866
        List<String> headers1 = Arrays.asList(
34641 ranu 867
                "","","","",
34715 ranu 868
                "Retailer Detail", "","", "", "", "", "", "", "", "","","","",
34677 ranu 869
 
870
                twoMonthAgoStringValue, "", "", "", "", "", "",
871
                lastMonthStringValue, "", "", "", "", "", "",
34619 ranu 872
                currentMonthStringValue, "", "", "", "", "", "",
34641 ranu 873
 
874
                "","", "", "", "", "", "", "", "", "", "", "", "", "",
875
 
876
                "", "", "", "", "", "", "", "", "", "", "", "", "",
877
                "", "", "", "", "", "", "", "", "", "", "", "", ""
878
 
34619 ranu 879
        );
34606 ranu 880
 
34619 ranu 881
        List<String> headers2 = Arrays.asList(
34641 ranu 882
                "Assessment","Zero billing","Billing needed","Counta",
34715 ranu 883
                "BM","Partner Id","Link","Wallet Date","Creation Date","Code","Area",  "City", "Store Name", "Status","Category","Sales Manager", "RBM",
34619 ranu 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",
888
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
889
                "Tertiary Sale", "Unbilled",
34641 ranu 890
                "Counter Potential", "Short investment", "Default", "INVESTMENT LEVEL", "Loan", "PO value", "Agreed investment",
891
                "Wallet", "po+bill", "MONTH BEGINNING DRR", "REQ DRR", "Drr %", "Last billing Done", "Slab",
34606 ranu 892
 
34721 ranu 893
              "Total Stock",  "Apple","Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
894
              "Total Secondary", "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
895
              "Total Tertiary",  "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New"
34619 ranu 896
        );
897
 
898
        headerGroup.add(headers1);
899
        headerGroup.add(headers2);
900
 
901
 
902
        List<List<?>> rows = new ArrayList<>();
903
        for (Map.Entry<Integer, BIRetailerModel> entry : biRetailerModelMap.entrySet()) {
904
            Integer fofoId = entry.getKey();
34715 ranu 905
            User user = userRepository.selectById(fofoId);
906
            LocalDateTime walletCreationDate = userWalletHistoryRepository.selectFirstCreatedDate(fofoId);
34619 ranu 907
            BIRetailerModel retailer = entry.getValue();
34641 ranu 908
 
34619 ranu 909
            Map<YearMonth, BiSecondaryModel> monthlyData = allRetailerMonthlyData.get(fofoId);
910
 
911
            BiSecondaryModel current = monthlyData.getOrDefault(YearMonth.now(), new BiSecondaryModel(0,0,0,0,0,0,0));
912
            BiSecondaryModel last = monthlyData.getOrDefault(YearMonth.now().minusMonths(1), new BiSecondaryModel(0,0,0,0,0,0,0));
913
            BiSecondaryModel twoAgo = monthlyData.getOrDefault(YearMonth.now().minusMonths(2), new BiSecondaryModel(0,0,0,0,0,0,0));
914
 
915
            List<Object> row = new ArrayList<>();
916
            row.addAll(Arrays.asList(
34641 ranu 917
                    assessmentMap.get(fofoId),zeroBillingMap.get(fofoId),billingNeededMap.get(fofoId),countAMap.get(fofoId),
34715 ranu 918
                    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 919
                    retailer.getCategory(),  retailer.getSalesManager(), retailer.getRbm()
920
 
34619 ranu 921
            ));
922
 
34677 ranu 923
 
924
            // Two Months Ago
34619 ranu 925
            row.addAll(Arrays.asList(
34677 ranu 926
                    twoAgo.getSecondaryTarget(),
927
                    twoAgo.getSecondaryAchieved(),
928
                    twoAgo.getSecondaryReturn(),
929
                    twoAgo.getNetSecondary(),
34704 ranu 930
                    twoAgo.getSecondaryAchievedPercent()+"%",
34677 ranu 931
                    twoAgo.getTertiary(),
932
                    twoAgo.getTertiaryUnBilled()
34619 ranu 933
            ));
934
 
935
            // Last Month
936
            row.addAll(Arrays.asList(
937
                    last.getSecondaryTarget(),
938
                    last.getSecondaryAchieved(),
939
                    last.getSecondaryReturn(),
940
                    last.getNetSecondary(),
34704 ranu 941
                    last.getSecondaryAchievedPercent()+"%",
34619 ranu 942
                    last.getTertiary(),
943
                    last.getTertiaryUnBilled()
944
            ));
945
 
34677 ranu 946
            // Current Month
34619 ranu 947
            row.addAll(Arrays.asList(
34677 ranu 948
                    current.getSecondaryTarget(),
949
                    current.getSecondaryAchieved(),
950
                    current.getSecondaryReturn(),
951
                    current.getNetSecondary(),
34704 ranu 952
                    current.getSecondaryAchievedPercent()+"%",
34677 ranu 953
                    current.getTertiary(),
954
                    current.getTertiaryUnBilled()
34619 ranu 955
            ));
34677 ranu 956
 
957
 
958
 
34641 ranu 959
            FofoInvestmentModel fofoInvestmentModelValue = biInvestmentModelMap.get(fofoId);
960
            if(fofoInvestmentModelValue != null){
961
                row.addAll(Arrays.asList(
962
                        fofoInvestmentModelValue.getCounterPotential(),
963
                        fofoInvestmentModelValue.getShortInvestment(),
964
                        fofoInvestmentModelValue.getDefaultLoan(),
965
                        fofoInvestmentModelValue.getInvestmentLevel(),
34715 ranu 966
                       "-"+fofoInvestmentModelValue.getActiveLoan(),
34641 ranu 967
                        fofoInvestmentModelValue.getPoValue(),
968
                        fofoInvestmentModelValue.getAgreedInvestment(),
969
                        fofoInvestmentModelValue.getWallet(),
970
                        fofoInvestmentModelValue.getPoAndBilled(),
971
                        fofoInvestmentModelValue.getMonthBeginingDrr(),
972
                        fofoInvestmentModelValue.getRequiredDrr(),
34704 ranu 973
                        fofoInvestmentModelValue.getDrrPercent()+"%",
34641 ranu 974
                        fofoInvestmentModelValue.getLastBillingDone(),
975
                        fofoInvestmentModelValue.getSlab()
976
                ));
977
            }else {
978
                row.addAll(Arrays.asList(
979
                        "-","-","-","-","-","-","-","-","-","-","-",""
980
                ));
981
            }
982
 
983
            Map<String, BrandStockPrice> brandStockMap = fofoBrandStockPriceMap.get(fofoId);
34619 ranu 984
            row.addAll(Arrays.asList(
985
                    fofoTotalStockPriceMap.getOrDefault(fofoId, 0.0),
34641 ranu 986
                    brandStockMap.get("Apple") != null ? brandStockMap.get("Apple").getTotalValue() : 0.0,
987
                    brandStockMap.get("Xiaomi") != null ? brandStockMap.get("Xiaomi").getTotalValue() : 0.0,
988
                    brandStockMap.get("Vivo") != null ? brandStockMap.get("Vivo").getTotalValue() : 0.0,
989
                    brandStockMap.get("Tecno") != null ? brandStockMap.get("Tecno").getTotalValue() : 0.0,
990
                    brandStockMap.get("Samsung") != null ? brandStockMap.get("Samsung").getTotalValue() : 0.0,
991
                    brandStockMap.get("Realme") != null ? brandStockMap.get("Realme").getTotalValue() : 0.0,
992
                    brandStockMap.get("Oppo") != null ? brandStockMap.get("Oppo").getTotalValue() : 0.0,
993
                    brandStockMap.get("OnePlus") != null ? brandStockMap.get("OnePlus").getTotalValue() : 0.0,
34721 ranu 994
                    brandStockMap.get("POCO") != null ? brandStockMap.get("POCO").getTotalValue() : 0.0,
34641 ranu 995
                    brandStockMap.get("Lava") != null ? brandStockMap.get("Lava").getTotalValue() : 0.0,
996
                    brandStockMap.get("Itel") != null ? brandStockMap.get("Itel").getTotalValue() : 0.0,
997
                    brandStockMap.get("Almost New") != null ? brandStockMap.get("Almost New").getTotalValue() : 0.0
34619 ranu 998
            ));
999
 
34641 ranu 1000
            Map<String, Long> brandSecondaryMap = fofoBrandWiseMtdSecondaryMap.get(fofoId);
1001
            row.addAll(Arrays.asList(
34648 ranu 1002
                    fofoTotalMtdSecondaryMap.get(fofoId),
34641 ranu 1003
                    brandSecondaryMap.getOrDefault("Apple", 0L),
1004
                    brandSecondaryMap.getOrDefault("Xiaomi", 0L),
1005
                    brandSecondaryMap.getOrDefault("Vivo", 0L),
1006
                    brandSecondaryMap.getOrDefault("Tecno", 0L),
1007
                    brandSecondaryMap.getOrDefault("Samsung", 0L),
1008
                    brandSecondaryMap.getOrDefault("Realme", 0L),
1009
                    brandSecondaryMap.getOrDefault("Oppo", 0L),
1010
                    brandSecondaryMap.getOrDefault("OnePlus", 0L),
34721 ranu 1011
                    brandSecondaryMap.getOrDefault("POCO", 0L),
34641 ranu 1012
                    brandSecondaryMap.getOrDefault("Lava", 0L),
1013
                    brandSecondaryMap.getOrDefault("Itel", 0L),
1014
                    brandSecondaryMap.getOrDefault("Almost New", 0L)
1015
            ));
1016
 
1017
            Map<String, Double> brandTertiaryMap = fofoBrandMtdTertiaryMap.get(fofoId);
1018
            row.addAll(Arrays.asList(
34648 ranu 1019
                    fofoTotalMtdTertiaryMap.get(fofoId),
34641 ranu 1020
                    brandTertiaryMap.getOrDefault("Apple", 0d),
1021
                    brandTertiaryMap.getOrDefault("Xiaomi", 0d),
1022
                    brandTertiaryMap.getOrDefault("Vivo", 0d),
1023
                    brandTertiaryMap.getOrDefault("Tecno", 0d),
1024
                    brandTertiaryMap.getOrDefault("Samsung", 0d),
1025
                    brandTertiaryMap.getOrDefault("Realme", 0d),
1026
                    brandTertiaryMap.getOrDefault("Oppo", 0d),
1027
                    brandTertiaryMap.getOrDefault("OnePlus", 0d),
34721 ranu 1028
                    brandTertiaryMap.getOrDefault("POCO", 0d),
34641 ranu 1029
                    brandTertiaryMap.getOrDefault("Lava", 0d),
1030
                    brandTertiaryMap.getOrDefault("Itel", 0d),
1031
                    brandTertiaryMap.getOrDefault("Almost New", 0d)
1032
            ));
1033
            rows.add(row);
34619 ranu 1034
        }
1035
 
1036
 
34641 ranu 1037
        // Send to email
1038
//        ByteArrayOutputStream csvStream = FileUtil.getCSVByteStreamWithMultiHeaders(headerGroup, rows);
1039
        ByteArrayOutputStream csvStream = getExcelStreamWithMultiHeaders(headerGroup, rows);
1040
        String fileName = "BI-Retailer-Monthly-Report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".xlsx";
34722 ranu 1041
        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com","ashutosh.verma@smartdukaan.com","sm@smartdukaan.com","raj.singh@smartdukaan.com"};
1042
//        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com"};
34619 ranu 1043
 
1044
        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()));
1045
 
1046
 
34606 ranu 1047
    }
1048
 
34641 ranu 1049
    public static ByteArrayOutputStream getExcelStreamWithMultiHeaders(List<List<String>> headerGroup, List<List<?>> rows) {
1050
        Workbook workbook = new XSSFWorkbook();
1051
        Sheet sheet = workbook.createSheet("BI Report");
34715 ranu 1052
        CreationHelper creationHelper = workbook.getCreationHelper();
34641 ranu 1053
        int rowIndex = 0;
34606 ranu 1054
 
34641 ranu 1055
        CellStyle centeredStyle = workbook.createCellStyle();
1056
        centeredStyle.setAlignment(HorizontalAlignment.CENTER); // Center horizontally
1057
        centeredStyle.setVerticalAlignment(VerticalAlignment.CENTER); // Center vertically
34606 ranu 1058
 
34641 ranu 1059
    // Optional: bold font
1060
        Font font1 = workbook.createFont();
1061
        font1.setBold(true);
1062
        centeredStyle.setFont(font1);
34606 ranu 1063
 
34619 ranu 1064
 
34641 ranu 1065
 
1066
        // Create styles
1067
        Map<String, CellStyle> headerStyles = new HashMap<>();
1068
 
1069
        // fontPurpleStyle
1070
        CellStyle purpleStyle = workbook.createCellStyle();
1071
        purpleStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
1072
        purpleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1073
        purpleStyle.setFont(font1);
1074
        headerStyles.put("Assessment", purpleStyle);
1075
        headerStyles.put("Zero billing", purpleStyle);
1076
        headerStyles.put("Billing needed", purpleStyle);
1077
        headerStyles.put("Counta", purpleStyle);
1078
        headerStyles.put("MONTH BEGINNING DRR", purpleStyle);
1079
        headerStyles.put("REQ DRR", purpleStyle);
1080
        headerStyles.put("Drr %", purpleStyle);
1081
 
1082
        // Light Blue
1083
        CellStyle blueStyle = workbook.createCellStyle();
1084
        blueStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
1085
        blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1086
        blueStyle.setFont(font1);
1087
        headerStyles.put("Code", blueStyle);
1088
        headerStyles.put("Store Name", blueStyle);
1089
        headerStyles.put("City", blueStyle);
1090
        headerStyles.put("Area", blueStyle);
1091
        headerStyles.put("BM", blueStyle);
1092
        headerStyles.put("RBM", blueStyle);
1093
        headerStyles.put("Sales Manager", blueStyle);
1094
        headerStyles.put("Status", blueStyle);
1095
        headerStyles.put("Category", blueStyle);
34715 ranu 1096
        headerStyles.put("Wallet Date", blueStyle);
1097
        headerStyles.put("Creation Date", blueStyle);
1098
        headerStyles.put("Partner Id", blueStyle);
34641 ranu 1099
 
34715 ranu 1100
        //for link
1101
        // Create hyperlink style
1102
        CellStyle hyperlinkStyle = workbook.createCellStyle();
1103
        Font hlinkFont = workbook.createFont();
1104
        hlinkFont.setUnderline(Font.U_SINGLE);
1105
        hlinkFont.setColor(IndexedColors.BLUE.getIndex());
1106
        hyperlinkStyle.setFont(hlinkFont);
1107
 
1108
 
34641 ranu 1109
        // Light Yellow
1110
        CellStyle yellowStyle = workbook.createCellStyle();
1111
        yellowStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
1112
        yellowStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1113
        yellowStyle.setFont(font1);
1114
        headerStyles.put("Last billing Done", yellowStyle);
1115
        headerStyles.put("Total Stock", yellowStyle);
1116
 
1117
        // Light Orange
1118
        CellStyle orangeStyle = workbook.createCellStyle();
1119
        orangeStyle.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
1120
        orangeStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1121
        orangeStyle.setFont(font1);
1122
        headerStyles.put("Total Tertiary", orangeStyle);
1123
        headerStyles.put("Total Secondary", orangeStyle);
1124
        headerStyles.put("Default", orangeStyle);
1125
 
1126
 
1127
        // Light green
1128
        CellStyle lightGreenStyle = workbook.createCellStyle();
1129
        lightGreenStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
1130
        lightGreenStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1131
        lightGreenStyle.setFont(font1);
1132
        headerStyles.put("Short investment", lightGreenStyle);
1133
        headerStyles.put("INVESTMENT LEVEL", lightGreenStyle);
1134
        headerStyles.put("Loan", lightGreenStyle);
1135
        headerStyles.put("PO value", lightGreenStyle);
1136
        headerStyles.put("Agreed investment", lightGreenStyle);
1137
        headerStyles.put("Wallet", lightGreenStyle);
1138
        headerStyles.put("po+bill", lightGreenStyle);
1139
 
1140
        // Light Green
1141
        CellStyle secondary1 = createStyle(workbook, IndexedColors.LIGHT_GREEN);
1142
        CellStyle secondary2 = createStyle(workbook, IndexedColors.LIGHT_YELLOW);
1143
        CellStyle secondary3 = createStyle(workbook, IndexedColors.LIGHT_ORANGE);
1144
 
1145
        Map<String, CellStyle> brandStyles = new HashMap<>();
1146
        brandStyles.put("Apple", createStyle(workbook, IndexedColors.GREY_25_PERCENT));
1147
        brandStyles.put("Xiaomi", createStyle(workbook, IndexedColors.ORANGE));
1148
        brandStyles.put("Vivo", createStyle(workbook, IndexedColors.SKY_BLUE));
1149
        brandStyles.put("Tecno", createStyle(workbook, IndexedColors.LIGHT_BLUE));
1150
        brandStyles.put("Samsung", createStyle(workbook, IndexedColors.ROYAL_BLUE));
1151
        brandStyles.put("Realme", createStyle(workbook, IndexedColors.YELLOW));
1152
        brandStyles.put("Oppo", createStyle(workbook, IndexedColors.LIGHT_GREEN));
1153
        brandStyles.put("OnePlus", createStyle(workbook, IndexedColors.RED));
34721 ranu 1154
        brandStyles.put("POCO", createStyle(workbook, IndexedColors.ORANGE));
34641 ranu 1155
        brandStyles.put("Lava", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1156
        brandStyles.put("Itel", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1157
        brandStyles.put("Almost New", createStyle(workbook, IndexedColors.WHITE));
1158
 
1159
 
1160
        CellStyle defaultHeaderStyle = workbook.createCellStyle();
1161
        defaultHeaderStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
1162
        defaultHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1163
        defaultHeaderStyle.setFont(font1);
1164
 
1165
 
1166
        Map<String, Integer> headerCount = new HashMap<>();
1167
 
1168
        for (int headerRowIndex = 0; headerRowIndex < headerGroup.size(); headerRowIndex++) {
1169
            List<String> headerRow = headerGroup.get(headerRowIndex);
1170
            Row row = sheet.createRow(rowIndex++);
1171
 
1172
            for (int i = 0; i < headerRow.size(); i++) {
1173
                String headerText = headerRow.get(i);
1174
                sheet.setColumnWidth(i, 25 * 256);
1175
                row.setHeightInPoints(20); // 25-point height
1176
                Cell cell = row.createCell(i);
1177
                cell.setCellValue(headerText);
1178
                cell.setCellStyle(centeredStyle);
1179
                // Count how many times this header has appeared
1180
                int count = headerCount.getOrDefault(headerText, 0) + 1;
1181
                headerCount.put(headerText, count);
1182
                // Apply special style for repeated headers
1183
                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")) {
1184
                    if (count == 1) {
1185
                        cell.setCellStyle(secondary1);
1186
                    } else if (count == 2) {
1187
                        cell.setCellStyle(secondary2);
1188
                    } else if (count == 3) {
1189
                        cell.setCellStyle(secondary3);
1190
                    }
1191
                }
1192
                // Brand header styling (apply only for the 2nd row of headers)
1193
                else if (headerRowIndex == 1 && brandStyles.containsKey(headerText)) {
1194
                    cell.setCellStyle(brandStyles.get(headerText));
1195
                }else if (headerStyles.containsKey(headerText)) {
1196
                    cell.setCellStyle(headerStyles.get(headerText));
1197
                } else {
1198
                    cell.setCellStyle(defaultHeaderStyle); // default style for others
1199
                }
1200
            }
1201
        }
1202
 
1203
        // Write data rows
1204
        for (List<?> dataRow : rows) {
1205
            Row row = sheet.createRow(rowIndex++);
1206
            for (int i = 0; i < dataRow.size(); i++) {
1207
                Cell cell = row.createCell(i);
1208
                Object value = dataRow.get(i);
34715 ranu 1209
 
1210
                if (i == 6 && value != null) { // Assuming column 6 is "Link"
1211
                    Hyperlink hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
1212
                    hyperlink.setAddress(value.toString());
34719 ranu 1213
                    cell.setCellValue("View Link"); // Display text
34715 ranu 1214
                    cell.setHyperlink(hyperlink);
1215
                    cell.setCellStyle(hyperlinkStyle);
34719 ranu 1216
                } else if (value instanceof Number) {
1217
                    cell.setCellValue(((Number) value).doubleValue());
34715 ranu 1218
                } else {
1219
                    cell.setCellValue(value != null ? value.toString() : "");
1220
                }
34641 ranu 1221
            }
34719 ranu 1222
 
34641 ranu 1223
        }
1224
 
1225
        // Auto-size columns
1226
        if (!rows.isEmpty()) {
1227
            for (int i = 0; i < rows.get(0).size(); i++) {
1228
                sheet.autoSizeColumn(i);
1229
            }
1230
        }
1231
 
1232
        // Output as ByteArray
1233
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
1234
            workbook.write(outputStream);
1235
            workbook.close();
1236
            return outputStream;
1237
        } catch (IOException e) {
1238
            throw new RuntimeException("Failed to generate Excel file", e);
1239
        }
1240
    }
1241
 
1242
 
1243
    private static CellStyle createStyle(Workbook workbook, IndexedColors color) {
1244
        CellStyle style = workbook.createCellStyle();
1245
        style.setFillForegroundColor(color.getIndex());
1246
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1247
        Font font = workbook.createFont();
1248
        font.setBold(true);
1249
        style.setFont(font);
1250
        return style;
1251
    }
1252
 
1253
 
1254
 
1255
 
34306 ranu 1256
}