Subversion Repositories SmartDukaan

Rev

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