Subversion Repositories SmartDukaan

Rev

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