Subversion Repositories SmartDukaan

Rev

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

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