Subversion Repositories SmartDukaan

Rev

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