Subversion Repositories SmartDukaan

Rev

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

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