Subversion Repositories SmartDukaan

Rev

Rev 34880 | Rev 34903 | 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;
34
import in.shop2020.model.v1.order.WalletReferenceType;
35
import org.apache.commons.io.output.ByteArrayOutputStream;
34306 ranu 36
import org.apache.logging.log4j.LogManager;
37
import org.apache.logging.log4j.Logger;
34715 ranu 38
import org.apache.poi.common.usermodel.HyperlinkType;
34641 ranu 39
import org.apache.poi.ss.usermodel.*;
34619 ranu 40
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
34306 ranu 41
import org.springframework.beans.factory.annotation.Autowired;
34619 ranu 42
import org.springframework.beans.factory.annotation.Qualifier;
43
import org.springframework.core.io.ByteArrayResource;
34321 ranu 44
import org.springframework.mail.javamail.JavaMailSender;
45
import org.springframework.mail.javamail.MimeMessageHelper;
34306 ranu 46
import org.springframework.stereotype.Component;
47
import org.springframework.transaction.annotation.Transactional;
48
 
34321 ranu 49
import javax.mail.MessagingException;
50
import javax.mail.internet.InternetAddress;
51
import javax.mail.internet.MimeMessage;
34619 ranu 52
import java.io.*;
53
import java.math.BigDecimal;
34641 ranu 54
import java.time.*;
34749 ranu 55
import java.time.format.DateTimeFormatter;
34306 ranu 56
import java.time.temporal.ChronoUnit;
57
import java.util.*;
34321 ranu 58
import java.util.stream.Collectors;
34306 ranu 59
 
60
@Component
61
@Transactional(rollbackFor = {Throwable.class, ProfitMandiBusinessException.class})
62
public class ScheduledTasksTest {
63
 
64
    private static final Logger LOGGER = LogManager.getLogger(ScheduledTasksTest.class);
65
 
66
    @Autowired
67
    TransactionRepository transactionRepository;
68
 
69
    @Autowired
34619 ranu 70
    @Qualifier(value = "googleMailSender")
71
    private JavaMailSender googleMailSender;
72
 
73
    @Autowired
34306 ranu 74
    LoanRepository loanRepository;
75
 
34308 ranu 76
    @Autowired
77
    SDCreditService sdCreditService;
78
 
34321 ranu 79
    @Autowired
80
    UserRepository userRepository;
81
 
82
    @Autowired
83
    CsService csService;
84
 
85
    @Autowired
86
    RbmRatingRepository rbmRatingRepository;
87
 
88
    @Autowired
89
    private JavaMailSender mailSender;
90
 
91
    @Autowired
92
    SalesRatingRepository salesRatingRepository;
93
 
94
    @Autowired
95
    FofoStoreRepository fofoStoreRepository;
96
 
34450 ranu 97
    @Autowired
98
    SmartCartService smartCartService;
99
 
34606 ranu 100
    @Autowired
101
    RetailerService retailerService;
102
 
103
    @Autowired
104
    ASTRepository astRepository;
105
 
106
    @Autowired
107
    AuthRepository authRepository;
108
 
109
    @Autowired
110
    StateRepository stateRepository;
111
 
112
    @Autowired
113
    MonthlyTargetRepository monthlyTargetRepository;
114
 
115
    @Autowired
116
    PartnerTypeChangeService partnerTypeChangeService;
117
 
118
    @Autowired
119
    ReturnOrderInfoRepository returnOrderInfoRepository;
120
 
121
    @Autowired
122
    OrderRepository orderRepository;
123
 
34619 ranu 124
    @Autowired
125
    FofoOrderItemRepository fofoOrderItemRepository;
126
 
127
    @Autowired
128
    InventoryService inventoryService;
129
 
130
    @Autowired
131
    UserWalletRepository userWalletRepository;
132
 
133
    @Autowired
134
    LoanStatementRepository loanStatementRepository;
135
 
136
    @Autowired
34641 ranu 137
    ActivatedImeiRepository activatedImeiRepository;
138
 
139
    @Autowired
140
    PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;
141
 
142
    @Autowired
34758 ranu 143
    SaholicInventoryService saholicInventoryService;
144
 
145
    @Autowired
34619 ranu 146
    WalletService walletService;
147
 
34641 ranu 148
    @Autowired
149
    RbmTargetService rbmTargetService;
150
 
34655 ranu 151
    @Autowired
152
    PartnerStatsService partnerStatsService;
153
 
34715 ranu 154
    @Autowired
34758 ranu 155
    AgeingService ageingService;
156
 
157
    @Autowired
158
    TagListingRepository tagListingRepository;
159
 
160
    @Autowired
34715 ranu 161
    UserWalletHistoryRepository userWalletHistoryRepository;
162
 
34321 ranu 163
    public void test() throws Exception {
34897 ranu 164
        generateBiReport();
34366 ranu 165
        System.out.println("test end");
34306 ranu 166
 
167
    }
168
 
34648 ranu 169
    public void generateBiReport() throws Exception {
34846 ranu 170
        System.out.println("bi report started");
34648 ranu 171
        this.generateBiReportExcel();
34846 ranu 172
        System.out.println("bi report ended {-----}");
34648 ranu 173
    }
174
 
34308 ranu 175
    public void createLoanForBillingByTransactionIdAndInvoiceNumber(int transactionId, double invoiceAmount, String invoiceNumber) throws Exception {
176
        sdCreditService.createLoanForBilling(transactionId, invoiceAmount, invoiceNumber);
34306 ranu 177
 
34308 ranu 178
    }
34306 ranu 179
 
34619 ranu 180
    public void loanSettle() throws Exception {
181
        List<Integer> refrences = Arrays.asList(25807,36003,38938,39506,42219,45084);
182
        for(Integer ref : refrences){
183
            List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(ref);
184
            double amountSum = loanStatements.stream().map(LoanStatement::getAmount).mapToDouble(BigDecimal::doubleValue).sum();
185
            if(amountSum > 0){
186
                walletService.addAmountToWallet(loanStatements.get(0).getFofoId(),ref, WalletReferenceType.CREDIT_LIMIT,"Amount reversal against credit limit deduction",(float) amountSum,LocalDateTime.now());
34308 ranu 187
 
34619 ranu 188
//                Loan statement entry
189
                    BigDecimal adjustAmount = BigDecimal.valueOf(amountSum).negate(); // or multiply by -1
190
                    LoanStatement loanStatement = new LoanStatement();
191
                    loanStatement.setAmount(adjustAmount);
192
                    loanStatement.setFofoId(loanStatements.get(0).getFofoId());
193
                    loanStatement.setLoanReferenceType(LoanReferenceType.PRINCIPAL);
194
                    loanStatement.setCreatedAt(LocalDateTime.now());
195
                    loanStatement.setDescription("Amount reversal due to access debit against limit");
196
                    loanStatement.setLoanId(ref);
197
                    loanStatement.setBusinessDate(LocalDateTime.now());
198
                    loanStatementRepository.persist(loanStatement);
199
 
200
                    Loan loan = loanRepository.selectByLoanId(ref);
201
                    loan.setPendingAmount(BigDecimal.valueOf(0));
202
                    loan.setSettledOn(LocalDateTime.now());
203
                }
204
 
205
 
206
        }
207
    }
208
 
209
 
210
 
34321 ranu 211
    private void sendMailHtmlFormat(String email[], String body, String cc[], String bcc[], String subject)
212
            throws MessagingException, ProfitMandiBusinessException, IOException {
213
        MimeMessage message = mailSender.createMimeMessage();
214
        MimeMessageHelper helper = new MimeMessageHelper(message);
215
        helper.setSubject(subject);
216
        helper.setText(body, true);
217
        helper.setTo(email);
218
        if (cc != null) {
219
            helper.setCc(cc);
220
        }
221
        if (bcc != null) {
222
            helper.setBcc(bcc);
34308 ranu 223
 
34321 ranu 224
        }
225
 
226
        InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smart Dukaan");
227
        helper.setFrom(senderAddress);
228
        mailSender.send(message);
229
    }
230
 
34307 ranu 231
    public Map<Integer,Integer> findLoanTransactionMapingAccordingLoan(List<Integer> loanIds) throws ProfitMandiBusinessException {
34306 ranu 232
 
233
        Map<Integer, Integer> transactionLoanMap = new HashMap<>();
234
 
235
        for(int loanId : loanIds){
236
            Transaction transaction = null;
237
            Loan loan = loanRepository.selectByLoanId(loanId);
238
            List<Transaction> transactions = transactionRepository.selectByRetailerId(loan.getFofoId());
239
 
240
            LocalDateTime nearestDateTime = transactions.stream().map(x -> x.getCreateTimestamp())
241
                    .min(Comparator.comparingLong(x -> Math.abs(ChronoUnit.MILLIS.between(x, loan.getCreatedOn()))))
242
                    .orElse(null);
243
 
244
            if (nearestDateTime != null && loan.getCreatedOn().plusMinutes(2).isAfter(nearestDateTime) &&
245
                    loan.getCreatedOn().minusMinutes(1).isBefore(nearestDateTime)) {
246
                // Here transaction is still null
247
                transaction = transactions.stream()
248
                        .filter(x -> x.getCreateTimestamp().equals(nearestDateTime))
249
                        .findFirst().get();
250
                transactionLoanMap.put(transaction.getId(), loanId);
251
            }
252
 
253
        }
254
        LOGGER.info("transactionLoanMap {}",transactionLoanMap);
255
        return transactionLoanMap;
256
    }
34321 ranu 257
 
258
 
259
 
260
    public void sendRbmFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
261
        LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
262
        LocalDateTime endOfMonth = LocalDateTime.now();
34323 ranu 263
        String[] bcc = {"tarun.verma@smartdukaan.com"};
34321 ranu 264
 
265
        // Get all RBM users
266
        List<AuthUser> authUsers = csService.getAuthUserIds(
267
                ProfitMandiConstants.TICKET_CATEGORY_RBM,
268
                Arrays.asList(EscalationType.L1)
269
        );
270
 
271
        if (authUsers.isEmpty()) {
272
            LOGGER.info("No RBMs found.");
273
            return;
274
        }
275
 
276
        List<Integer> rbmIds = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
277
 
278
        // Fetch ratings for all RBMs for current month
279
        List<RbmRating> feedbackList = rbmRatingRepository.selectByRbmIdsAndDateRange(rbmIds, startOfMonth, endOfMonth);
280
 
281
        if (feedbackList.isEmpty()) {
282
            LOGGER.info("No feedback entries found for RBMs.");
283
            return;
284
        }
285
 
286
        // Sort feedback by createTimeStamp DESC
287
        feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
288
 
289
        // Fetch and map FOFO (partner) names
290
        Map<Integer, String> fofoNameMap = new HashMap<>();
291
        for (RbmRating rating : feedbackList) {
292
            int fofoId = rating.getFofoId();
293
            if (!fofoNameMap.containsKey(fofoId)) {
294
                User fofoUser = userRepository.selectById(fofoId);
295
                FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
296
 
297
                String partnerName = fofoUser != null ? fofoUser.getName() : "Unknown Partner";
298
                String storeCode = fofoStore != null ? fofoStore.getCode() : "Unknown Code";
299
 
300
                String displayName = partnerName + " (" + storeCode + ")";
301
                fofoNameMap.put(fofoId, displayName);
302
            }
303
        }
304
 
305
        // Map RBM ID to name for quick lookup
306
        Map<Integer, String> rbmNameMap = authUsers.stream()
307
                .collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
308
 
309
        // Generate HTML content
310
        StringBuilder emailContent = new StringBuilder();
311
        emailContent.append("<html><body>");
312
        emailContent.append("<p>Dear Team,</p>");
313
        emailContent.append("<p>Here is the <b>latest RBM Rating and Feedback Summary</b> for ")
314
                .append(LocalDate.now().getMonth()).append(":</p>");
315
 
316
        emailContent.append("<table border='1' cellspacing='0' cellpadding='5'>");
317
        emailContent.append("<tr>")
318
                .append("<th>RBM Name</th>")
319
                .append("<th>Partner Name</th>")
320
                .append("<th>Rating</th>")
321
                .append("<th>Comment</th>")
322
                .append("<th>Date</th>")
323
                .append("</tr>");
324
 
325
        for (RbmRating rating : feedbackList) {
326
            String rbmName = rbmNameMap.getOrDefault(rating.getRbmId(), "Unknown RBM");
327
            String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
328
            emailContent.append("<tr>")
329
                    .append("<td>").append(rbmName).append("</td>")
330
                    .append("<td>").append(partnerName).append("</td>")
331
                    .append("<td>").append(rating.getRating()).append("</td>")
332
                    .append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
333
                    .append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
334
                    .append("</tr>");
335
        }
336
 
337
        emailContent.append("</table>");
338
        emailContent.append("<br><p>Regards,<br>Smart Dukaan Team</p>");
339
        emailContent.append("</body></html>");
340
 
341
        String subject = "Monthly RBM Feedback Summary - " + LocalDate.now().getMonth();
342
 
343
        List<String> sendTo = new ArrayList<>();
34323 ranu 344
        sendTo.add("sm@smartdukaan.com"); //
345
        sendTo.add("chiranjib.sarkar@smartdukaan.com"); //
346
        sendTo.add("kamini.sharma@smartdukaan.com"); //
34321 ranu 347
 
348
        String[] emailRecipients = sendTo.toArray(new String[0]);
349
 
350
 
351
        this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
352
 
353
        LOGGER.info("Consolidated RBM feedback summary email sent.");
354
    }
355
 
356
 
357
    public void sendSalesFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
358
        LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
359
        LocalDateTime endOfMonth = LocalDateTime.now();
34323 ranu 360
        String[] bcc = {"tarun.verma@smartdukaan.com"};
34411 tejus.loha 361
//        String[] bcc = {"tejus.lohani@smartdukaan.com"};
34321 ranu 362
 
363
        // Get all RBM users
364
        List<AuthUser> authUsers = csService.getAuthUserIds(
365
                ProfitMandiConstants.TICKET_CATEGORY_SALES,
366
                Arrays.asList(EscalationType.L1)
367
        );
368
 
369
        if (authUsers.isEmpty()) {
370
            LOGGER.info("No sales person found.");
371
            return;
372
        }
373
 
374
        List<Integer> salesL1Ids = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
375
 
376
        // Fetch ratings for all RBMs for current month
377
        List<SalesRating> feedbackList = salesRatingRepository.selectBySalesL1IdsAndDateRange(salesL1Ids, startOfMonth, endOfMonth);
378
 
379
        if (feedbackList.isEmpty()) {
380
            LOGGER.info("No feedback entries found for Sales.");
381
            return;
382
        }
383
 
384
        // Sort feedback by createTimeStamp DESC
385
        feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
386
 
387
        // Fetch and map FOFO (partner) names
388
        Map<Integer, String> fofoNameMap = new HashMap<>();
389
        for (SalesRating rating : feedbackList) {
390
            int fofoId = rating.getFofoId();
391
            if (!fofoNameMap.containsKey(fofoId)) {
392
                User fofoUser = userRepository.selectById(fofoId);
393
                FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
394
 
395
                String partnerName = fofoUser != null ? fofoUser.getName() : "Unknown Partner";
396
                String storeCode = fofoStore != null ? fofoStore.getCode() : "Unknown Code";
397
 
398
                String displayName = partnerName + " (" + storeCode + ")";
399
                fofoNameMap.put(fofoId, displayName);
400
            }
401
        }
402
 
403
        // Map RBM ID to name for quick lookup
404
        Map<Integer, String> salesL1NameMap = authUsers.stream()
405
                .collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
406
 
407
        // Generate HTML content
408
        StringBuilder emailContent = new StringBuilder();
409
        emailContent.append("<html><body>");
410
        emailContent.append("<p>Dear Team,</p>");
411
        emailContent.append("<p>Here is the <b>latest Sales L1 Rating and Feedback Summary</b> for ")
412
                .append(LocalDate.now().getMonth()).append(":</p>");
413
 
414
        emailContent.append("<table border='1' cellspacing='0' cellpadding='5'>");
415
        emailContent.append("<tr>")
416
                .append("<th>Sales L1 Name</th>")
417
                .append("<th>Partner Name</th>")
34411 tejus.loha 418
                .append("<th>Partner Category</th>")
34321 ranu 419
                .append("<th>Rating</th>")
420
                .append("<th>Comment</th>")
421
                .append("<th>Date</th>")
422
                .append("</tr>");
423
 
424
        for (SalesRating rating : feedbackList) {
425
            String salesL1 = salesL1NameMap.getOrDefault(rating.getSalesL1Id(), "Unknown Sales Person");
426
            String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
34844 ranu 427
            LOGGER.info("partnerName11- {}",partnerName);
34411 tejus.loha 428
            PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(rating.getFofoId(), LocalDate.now());
34321 ranu 429
            emailContent.append("<tr>")
430
                    .append("<td>").append(salesL1).append("</td>")
431
                    .append("<td>").append(partnerName).append("</td>")
34411 tejus.loha 432
                    .append("<td>").append(partnerType).append("</td>")
34321 ranu 433
                    .append("<td>").append(rating.getRating()).append("</td>")
434
                    .append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
435
                    .append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
436
                    .append("</tr>");
437
        }
438
 
439
        emailContent.append("</table>");
440
        emailContent.append("<br><p>Regards,<br>Smartdukaan Team</p>");
441
        emailContent.append("</body></html>");
442
 
34411 tejus.loha 443
        String subject = "Monthly Sales L1 Feedback Summary Test test - " + LocalDate.now().getMonth();
34321 ranu 444
 
445
        List<String> sendTo = new ArrayList<>();
34323 ranu 446
         sendTo.add("sm@smartdukaan.com"); //
447
         sendTo.add("chiranjib.sarkar@smartdukaan.com"); //
34606 ranu 448
         sendTo.add("kamini.sharma@smartdukaan.com"); //
34321 ranu 449
 
450
        String[] emailRecipients = sendTo.toArray(new String[0]);
451
 
452
 
453
        this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
454
 
455
        LOGGER.info("Consolidated Sales L1 feedback summary email sent.");
456
    }
457
 
458
 
34606 ranu 459
    public void generateBiReportExcel() throws Exception {
34619 ranu 460
 
34741 ranu 461
        LocalDateTime startOfToday;
462
        LocalDateTime previousDay;
34321 ranu 463
 
34741 ranu 464
        if (LocalDate.now().getDayOfMonth() == 1) {
465
            // If today is 1st, go to yesterday (i.e., last day of previous month)
466
            startOfToday = LocalDate.now().minusDays(1).atStartOfDay();
467
            previousDay = startOfToday.with(LocalTime.MAX);
468
 
469
        } else {
470
            // Otherwise, use today
471
            startOfToday = LocalDate.now().atStartOfDay();
472
            previousDay = startOfToday.with(LocalTime.MAX).minusDays(1);
473
        }
474
 
34784 ranu 475
        Map<Integer, CustomRetailer> customRetailers = retailerService.getAllFofoRetailersInternalFalse();
34321 ranu 476
 
34784 ranu 477
        List<Integer> retailerIds = customRetailers.values().stream().map(CustomRetailer::getPartnerId).collect(Collectors.toList());
34606 ranu 478
 
34844 ranu 479
/*        List<Integer> retailerIds = Arrays.asList(175139247,175139660);
34784 ranu 480
        Map<Integer,CustomRetailer> customRetailers = retailerService.getFofoRetailers(retailerIds);*/
34758 ranu 481
 
34641 ranu 482
        //partner daily investment
34729 amit.gupta 483
        List<Loan> defaultLoans = sdCreditService.getDefaultLoans();
34641 ranu 484
        Map<Integer,List<Loan>> defaultLoanMap = defaultLoans.stream().collect(Collectors.groupingBy(Loan::getFofoId));
34619 ranu 485
 
34641 ranu 486
        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = new HashMap<>();
487
        List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository
34741 ranu 488
                .selectAll(new ArrayList<>(retailerIds), previousDay.toLocalDate());
34641 ranu 489
        if (!partnerDailyInvestments.isEmpty()) {
490
            partnerDailyInvestmentMap = partnerDailyInvestments.stream()
491
                    .collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
492
        }
493
 
34741 ranu 494
 
495
 
34648 ranu 496
    //  this month return data
34741 ranu 497
 
498
        YearMonth currentMonth;
499
        LocalDateTime currentMonthStartDate;
500
        LocalDateTime currentMonthEndDate;
501
 
502
        if (LocalDate.now().getDayOfMonth() == 1) {
503
            // If today is the 1st, use previous month
504
            currentMonth = YearMonth.now().minusMonths(1);
505
            currentMonthStartDate = currentMonth.atDay(1).atStartOfDay();
506
            currentMonthEndDate = currentMonth.atEndOfMonth().atTime(23, 59, 59);
507
        } else {
508
            // Otherwise, use this month up to yesterday
509
            currentMonth = YearMonth.now();
510
            currentMonthStartDate = currentMonth.atDay(1).atStartOfDay();
511
            currentMonthEndDate = LocalDate.now().minusDays(1).atTime(23, 59, 59);
512
        }
513
 
34619 ranu 514
        String currentMonthStringValue = String.valueOf(currentMonth);
34606 ranu 515
 
516
        List<ReturnOrderInfoModel> currentMonthReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(currentMonthStartDate, currentMonthEndDate);
517
        Map<Integer, Long> currentMonthPartnerReturnOrderInfoModelMap = currentMonthReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
518
 
34782 ranu 519
        List<Order> currentMonthRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(currentMonthStartDate, currentMonthEndDate);
34606 ranu 520
        Map<Integer, Long> currentMonthRtoRefundOrderMap = currentMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
521
 
34749 ranu 522
 
523
        List<ReturnOrderInfoModel> yesterdayReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(previousDay.toLocalDate().atStartOfDay(), previousDay);
524
        Map<Integer, Long> yesterdayReturnOrderInfoModelMap = yesterdayReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
525
 
34782 ranu 526
        List<Order> yesterdayRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(previousDay.toLocalDate().atStartOfDay(), previousDay);
34749 ranu 527
        Map<Integer, Long> yesterdayRtoRefundOrderMap = yesterdayRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
528
 
529
        List<ReturnOrderInfoModel> dayBeforeYesterdayReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(previousDay.toLocalDate().atStartOfDay().minusDays(1), previousDay.minusDays(1));
530
        Map<Integer, Long> dayBeforeYesterdayReturnOrderInfoModelMap = dayBeforeYesterdayReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
531
 
34782 ranu 532
        List<Order> dayBeforeYesterdayRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(previousDay.toLocalDate().atStartOfDay().minusDays(1), previousDay.minusDays(1));
34749 ranu 533
        Map<Integer, Long> dayBeforeYesterdayRtoRefundOrderMap = dayBeforeYesterdayRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
534
 
535
 
536
 
537
        //  last month return data
34741 ranu 538
        YearMonth lastMonth = currentMonth.minusMonths(1);
34619 ranu 539
        String lastMonthStringValue = String.valueOf(lastMonth);
34606 ranu 540
        LocalDateTime lastMontStartDate = lastMonth.atDay(1).atStartOfDay();
541
        LocalDateTime lastMonthEndDate = lastMonth.atEndOfMonth().atTime(23, 59, 59);
542
 
543
        List<ReturnOrderInfoModel> lastMonthReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(lastMontStartDate, lastMonthEndDate);
544
        Map<Integer, Long> lastMonthPartnerReturnOrderInfoModelMap = lastMonthReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
545
 
34782 ranu 546
        List<Order> lastMonthRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(lastMontStartDate, lastMonthEndDate);
34606 ranu 547
        Map<Integer, Long> lastMonthRtoRefundOrderMap = lastMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
548
 
549
 
34741 ranu 550
    //  twoMonthsAgo return data
551
        YearMonth twoMonthsAgo = currentMonth.minusMonths(2);
34619 ranu 552
        String twoMonthAgoStringValue = String.valueOf(twoMonthsAgo);
34606 ranu 553
        LocalDateTime twoMonthsAgoStartDate = twoMonthsAgo.atDay(1).atStartOfDay();
554
        LocalDateTime twoMonthsAgoEndDate = twoMonthsAgo.atEndOfMonth().atTime(23, 59, 59);
555
 
556
        List<ReturnOrderInfoModel> twoMonthAgoReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(twoMonthsAgoStartDate, twoMonthsAgoEndDate);
557
        Map<Integer, Long> twoMonthAgoPartnerReturnOrderInfoModelMap = twoMonthAgoReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
34749 ranu 558
 
34782 ranu 559
        List<Order> twoMonthRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(twoMonthsAgoStartDate, twoMonthsAgoEndDate);
34619 ranu 560
        Map<Integer, Long> twoMonthAgoRtoRefundOrderMap = twoMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
34606 ranu 561
 
34749 ranu 562
 
34648 ranu 563
        Map<Integer , String> assessmentMap = new HashMap<>();
564
        Map<Integer , String> zeroBillingMap = new HashMap<>();
565
        Map<Integer , Float> billingNeededMap = new HashMap<>();
566
        Map<Integer , Integer> countAMap = new HashMap<>();
34606 ranu 567
 
34619 ranu 568
        Map<Integer , BIRetailerModel> biRetailerModelMap = new HashMap<>();
34606 ranu 569
 
34641 ranu 570
        Map<Integer , FofoInvestmentModel> biInvestmentModelMap = new HashMap<>();
571
 
34619 ranu 572
        Map<Integer, Map<YearMonth, BiSecondaryModel>> allRetailerMonthlyData = new HashMap<>();
34606 ranu 573
 
34619 ranu 574
        Map<Integer,Double> fofoTotalStockPriceMap = new HashMap<>();
575
 
576
        Map<Integer,Map<String, BrandStockPrice>> fofoBrandStockPriceMap = new HashMap<>();
577
 
34641 ranu 578
        Map<Integer,Long> fofoTotalMtdSecondaryMap = new HashMap<>();
34619 ranu 579
 
34749 ranu 580
        Map<Integer,Long> fofoYesterdaySecondaryMap = new HashMap<>();
34619 ranu 581
 
34749 ranu 582
        Map<Integer,Long> fofoDayBeforeYesterdaySecondaryMap = new HashMap<>();
583
 
34641 ranu 584
        Map<Integer,Map<String, Long>> fofoBrandWiseMtdSecondaryMap = new HashMap<>();
34619 ranu 585
 
34641 ranu 586
        Map<Integer,Double> fofoTotalMtdTertiaryMap = new HashMap<>();
587
 
588
        Map<Integer,Map<String, Double>> fofoBrandMtdTertiaryMap = new HashMap<>();
589
 
34606 ranu 590
        for(Integer fofoId: retailerIds){
34619 ranu 591
            String rbmName = "";
34606 ranu 592
            int rbmL1 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM,EscalationType.L1,fofoId);
34619 ranu 593
            if(rbmL1 != 0){
594
                 rbmName = authRepository.selectById(rbmL1).getFullName();
34677 ranu 595
            }else {
596
                int rbmL2 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM, EscalationType.L2, fofoId);
597
                if(rbmL2 != 0){
598
                    rbmName = authRepository.selectById(rbmL2).getFullName();
599
                }
34619 ranu 600
            }
601
            String bmName ="";
34606 ranu 602
            int bmId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L2,fofoId);
34619 ranu 603
            if(bmId !=0){
604
                bmName = authRepository.selectById(bmId).getFullName();
605
            }
34606 ranu 606
 
607
            int managerId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L1,fofoId);
608
            String managerName = " ";
609
            if(managerId != 0){
610
                 managerName = authRepository.selectById(managerId).getFullName();
611
            }else {
612
                managerName = bmName;
613
            }
614
 
615
            AST ast = astRepository.selectById(customRetailers.get(fofoId).getAstId());
616
 
34741 ranu 617
            PartnerType partnerTypeThisMonth = partnerTypeChangeService.getTypeOnMonth(fofoId, currentMonth);
34606 ranu 618
 
619
//            generate retaile detail
620
 
621
            BIRetailerModel biRetailerModel = new BIRetailerModel();
622
            biRetailerModel.setBmName(bmName);
623
            biRetailerModel.setCode(customRetailers.get(fofoId).getCode());
34619 ranu 624
            if(ast != null){
625
                biRetailerModel.setArea(ast.getArea());
626
            }else {
627
                biRetailerModel.setArea("-");
628
            }
34738 ranu 629
            String retailerStatus = "";
630
            FofoStore fofoStore1 = fofoStoreRepository.selectByRetailerId(fofoId);
631
            if(!fofoStore1.isActive()){
632
                retailerStatus = "INACTIVE";
633
            }else{
634
                retailerStatus =  String.valueOf(fofoStore1.getActivationType());
635
            }
34606 ranu 636
            biRetailerModel.setCity(customRetailers.get(fofoId).getAddress().getCity());
637
            biRetailerModel.setStoreName(customRetailers.get(fofoId).getBusinessName());
34738 ranu 638
            biRetailerModel.setStatus(retailerStatus);
34606 ranu 639
            biRetailerModel.setCategory(String.valueOf(partnerTypeThisMonth));
640
            biRetailerModel.setSalesManager(managerName);
641
            biRetailerModel.setRbm(rbmName);
642
 
34619 ranu 643
            biRetailerModelMap.put(fofoId,biRetailerModel);
644
 
34641 ranu 645
 
34606 ranu 646
//            generate secondary data
647
 
34641 ranu 648
            List<PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledMonthlyTotals = activatedImeiRepository.getTotalMonthlyActivatedNotBilled(fofoId,twoMonthsAgoStartDate);
649
            Map<YearMonth , PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledTotalMap = partnerWiseActivatedNotBilledMonthlyTotals.stream().collect(Collectors.toMap(x-> YearMonth.parse(x.getYearMonth()),x->x));
650
 
34606 ranu 651
//            this month secondary target
652
 
34741 ranu 653
            double currentSecondaryTarget =  monthlyTargetRepository.selectByDateAndFofoId(currentMonth, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(currentMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 654
 
34619 ranu 655
 
656
            long currentMonthReturn = currentMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId, 0L) + currentMonthRtoRefundOrderMap.getOrDefault(fofoId, 0L);
657
 
658
 
34715 ranu 659
            Map<Integer, Double> secondaryMtd = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34741 ranu 660
                    startOfToday.withDayOfMonth(1), previousDay).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
34606 ranu 661
 
34749 ranu 662
 
663
            //yesterday secondary
664
            Map<Integer, Double> dayBeforeYesterdaySecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
665
                    previousDay.toLocalDate().atStartOfDay().minusDays(1), previousDay.minusDays(1)).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
666
            double dayBeforeYesterdayAfterReturnSecondary = dayBeforeYesterdaySecondary.getOrDefault(fofoId,0d) - (dayBeforeYesterdayReturnOrderInfoModelMap.getOrDefault(fofoId,0l) + dayBeforeYesterdayRtoRefundOrderMap.getOrDefault(fofoId,0l));
667
            fofoDayBeforeYesterdaySecondaryMap.put(fofoId, (long) dayBeforeYesterdayAfterReturnSecondary);
668
 
669
 
670
            //day before secondary
671
            Map<Integer, Double> yesterDaySecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
672
                    previousDay.toLocalDate().atStartOfDay(), previousDay).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
673
            double yesterDayAfterReturnSecondary = yesterDaySecondary.getOrDefault(fofoId,0d) - (yesterdayReturnOrderInfoModelMap.getOrDefault(fofoId,0l) + yesterdayRtoRefundOrderMap.getOrDefault(fofoId,0l));
674
            fofoYesterdaySecondaryMap.put(fofoId, (long) yesterDayAfterReturnSecondary);
675
 
34606 ranu 676
            double secondaryAchievedMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
677
 
34619 ranu 678
            double currentMonthNetSecondary = secondaryAchievedMtd - currentMonthReturn;
34606 ranu 679
 
34701 ranu 680
            double currentMonthSecondaryPercent = currentSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((secondaryAchievedMtd / currentSecondaryTarget) * 100));
34619 ranu 681
 
34641 ranu 682
            double currentMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(currentMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(currentMonth).getTotalUnbilledAmount() : 0d;
34619 ranu 683
 
684
//          this month tertiary----------
685
 
686
            LocalDateTime now = LocalDateTime.now();
687
            double todaySale = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday, now, fofoId, false).get(fofoId);
34741 ranu 688
            double mtdSaleTillYesterDay = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday.withDayOfMonth(1), previousDay, fofoId, false).get(fofoId);
34724 ranu 689
            double mtdSale = mtdSaleTillYesterDay;
34619 ranu 690
 
691
 
34606 ranu 692
//            last month secondary target
693
 
34619 ranu 694
            double lastMonthSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId) != null ?  monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 695
 
34619 ranu 696
            long lastMonthReturn = (lastMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + lastMonthRtoRefundOrderMap.getOrDefault(fofoId,0L));
697
 
34715 ranu 698
            Map<Integer, Double> lastMonthSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 699
                    lastMontStartDate, lastMonthEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
700
 
701
            double lastMonthSecondaryAchieved = lastMonthSecondary.getOrDefault(fofoId, 0.0);
702
 
34619 ranu 703
            double lastMonthNetSecondary = lastMonthSecondaryAchieved - lastMonthReturn;
34606 ranu 704
 
34701 ranu 705
            double lastMonthSecondaryPercent = lastMonthSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((lastMonthSecondaryAchieved / lastMonthSecondaryTarget) * 100));
34606 ranu 706
 
34641 ranu 707
            double lastMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(lastMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(lastMonth).getTotalUnbilledAmount() : 0d;
34606 ranu 708
 
34619 ranu 709
//           last month tertiary
710
            Double lastMonthSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
711
                    lastMontStartDate, lastMonthEndDate, fofoId, false).get(fofoId);
712
 
713
 
714
//            two month ago secondary target
715
 
34703 ranu 716
            double twoMonthAgoSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId).getPurchaseTarget() : 0;
34619 ranu 717
 
718
            long twoMonthAgoReturn = (twoMonthAgoPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + twoMonthAgoRtoRefundOrderMap.getOrDefault(fofoId,0L));
719
 
34715 ranu 720
            Map<Integer, Double> twoMonthAgoSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 721
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
722
 
723
            double twoMonthAgoSecondaryAchieved = twoMonthAgoSecondary.getOrDefault(fofoId, 0.0);
724
 
34619 ranu 725
            double twoMonthAgoNetSecondary = twoMonthAgoSecondaryAchieved - twoMonthAgoReturn;
34606 ranu 726
 
34701 ranu 727
            double twoMonthAgoSecondaryPercent = twoMonthAgoSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((twoMonthAgoSecondaryAchieved / twoMonthAgoSecondaryTarget) * 100));
34619 ranu 728
 
34641 ranu 729
            double twoMonthAgoUnbilled = partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo) != null ? partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo).getTotalUnbilledAmount() : 0d;
34619 ranu 730
 
731
//          second Month Tertiary
732
            double twoMonthAgoSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
733
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate, fofoId, false).get(fofoId);
734
 
735
 
736
            Map<YearMonth, BiSecondaryModel> monthlySecondaryModels = new HashMap<>();
737
 
738
            BiSecondaryModel currentMonthSecondaryModel = new BiSecondaryModel(
739
                    currentSecondaryTarget,
740
                    secondaryAchievedMtd,
741
                    currentMonthReturn,
742
                    currentMonthNetSecondary,
743
                    currentMonthSecondaryPercent,
744
                    mtdSale,
745
                    currentMonthUnbilled // for now, unbilled tertiary value
746
            );
747
 
748
            BiSecondaryModel lastMonthSecondaryModel = new BiSecondaryModel(
749
                    lastMonthSecondaryTarget,
750
                    lastMonthSecondaryAchieved,
751
                    lastMonthReturn,
752
                    lastMonthNetSecondary,
753
                    lastMonthSecondaryPercent,
754
                    lastMonthSale,
755
                    lastMonthUnbilled // for now, unbilled tertiary value
756
            );
757
 
758
            BiSecondaryModel twoMonthAgoSecondaryModel = new BiSecondaryModel(
759
                    twoMonthAgoSecondaryTarget,
760
                    twoMonthAgoSecondaryAchieved,
761
                    twoMonthAgoReturn,
762
                    twoMonthAgoNetSecondary,
763
                    twoMonthAgoSecondaryPercent,
764
                    twoMonthAgoSale,
765
                    twoMonthAgoUnbilled // for now, unbilled tertiary value
766
            );
767
 
768
            monthlySecondaryModels.put(currentMonth, currentMonthSecondaryModel);
769
            monthlySecondaryModels.put(lastMonth, lastMonthSecondaryModel);
770
            monthlySecondaryModels.put(twoMonthsAgo, twoMonthAgoSecondaryModel);
771
 
772
            allRetailerMonthlyData.put(fofoId, monthlySecondaryModels);
773
 
774
//            brandwiseStock value price
775
 
776
            Map<String, BrandStockPrice> brandStockPriceMap = inventoryService.getBrandWiseStockValue(fofoId);
777
 
778
            fofoBrandStockPriceMap.put(fofoId,brandStockPriceMap);
779
 
780
            double totalStockPrice = brandStockPriceMap.values().stream().mapToDouble(x->x.getTotalValue()).sum();
781
 
782
            fofoTotalStockPriceMap.put(fofoId,totalStockPrice);
783
 
784
            Map<String, Double> brandMtdTertiaryAmount = fofoOrderItemRepository.selectSumAmountGroupByBrand(
34722 ranu 785
                    currentMonthStartDate, currentMonthEndDate, fofoId);
34619 ranu 786
 
34719 ranu 787
 
34641 ranu 788
            fofoBrandMtdTertiaryMap.put(fofoId,brandMtdTertiaryAmount);
34619 ranu 789
 
790
            double totalMtdTertiaryAmount = brandMtdTertiaryAmount.values().stream().mapToDouble(Double::doubleValue).sum();
791
 
34641 ranu 792
            fofoTotalMtdTertiaryMap.put(fofoId,totalMtdTertiaryAmount);
34619 ranu 793
 
34849 ranu 794
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledByCategoryOrderGroupByBrandFofoId(fofoId, currentMonthStartDate,currentMonthEndDate, Arrays.asList(10006,10001));
34641 ranu 795
            Map<String,Long> brandWiseMtdSecondaryMap = brandWiseMtdSecondary.stream().collect(Collectors.toMap(BrandWiseModel::getBrand,BrandWiseModel::getAmount));
34619 ranu 796
 
34730 ranu 797
            //retrunInfo
798
            List<BrandWiseReturnInfo> brandWiseReturnInfos = returnOrderInfoRepository.selectAllBrandWiseByBetweenDate(currentMonthStartDate,currentMonthEndDate.plusDays(1),fofoId);
799
            Map<String,Double> brandWiseReturnInfoMap = brandWiseReturnInfos.stream().collect(Collectors.toMap(BrandWiseReturnInfo::getBrand, x->x.getReturnAmount()));
34619 ranu 800
 
34730 ranu 801
            LOGGER.info("brandWiseReturnInfos {}",brandWiseReturnInfos);
34758 ranu 802
 
34730 ranu 803
            //Rto retrunInfo
804
            List<BrandWiseReturnInfo> brandWiseRTOReturnInfos = returnOrderInfoRepository.selectAllBrandWiseRTORefundByBetweenDate(currentMonthStartDate,currentMonthEndDate.plusDays(1),fofoId);
805
            Map<String,Double> brandWiseRTOReturnInfoMap = brandWiseRTOReturnInfos.stream().collect(Collectors.toMap(BrandWiseReturnInfo::getBrand, x->x.getReturnAmount()));
806
 
807
            // Step 1: Get union of all brand keys
808
            Set<String> allBrands = new HashSet<>();
809
            allBrands.addAll(brandWiseMtdSecondaryMap.keySet());
810
            allBrands.addAll(brandWiseReturnInfoMap.keySet());
811
            allBrands.addAll(brandWiseRTOReturnInfoMap.keySet());
812
 
813
            // Step 2: Calculate net secondary for each brand
814
            Map<String, Long> brandWiseMtdNetSecondaryMap = new HashMap<>();
815
 
816
            for (String brand : allBrands) {
817
                Long billedAmount = brandWiseMtdSecondaryMap.getOrDefault(brand, 0L);
818
                Double returnAmount = brandWiseReturnInfoMap.getOrDefault(brand, 0d);
819
                Double rtoReturnAmount = brandWiseRTOReturnInfoMap.getOrDefault(brand, 0d);
820
 
821
                double netSecondary = billedAmount - (returnAmount + rtoReturnAmount);
822
                brandWiseMtdNetSecondaryMap.put(brand, (long) Math.round(netSecondary));
823
            }
824
 
825
 
826
            LOGGER.info("brandWiseMtdNetSecondaryMap {}",brandWiseMtdNetSecondaryMap );
827
 
828
 
829
            fofoBrandWiseMtdSecondaryMap.put(fofoId,brandWiseMtdNetSecondaryMap);
830
 
831
            long mtdTotalSecondary = brandWiseMtdNetSecondaryMap.values().stream().mapToLong(Long::longValue).sum();
832
 
34641 ranu 833
            fofoTotalMtdSecondaryMap.put(fofoId,mtdTotalSecondary);
834
 
835
            //            generate investment info
836
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
837
            float shortInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getShortInvestment() : 0f;
838
            float agreedInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getMinInvestment() : 0f;
34677 ranu 839
            float investmentLevel = partnerDailyInvestmentMap.get(fofoId) != null
840
                    ? Math.abs(((shortInvestment - agreedInvestment) / agreedInvestment) * 100)
841
                    : 0f;
34641 ranu 842
 
34677 ranu 843
 
34641 ranu 844
            List<Loan> fofoDefaultLoans = new ArrayList<>();
845
            if(defaultLoanMap != null){
846
                 fofoDefaultLoans  =  defaultLoanMap.get(fofoId);
847
                LOGGER.info("fofoDefaultLoans {}",fofoDefaultLoans);
848
            }
849
 
850
            float defaultLoanAmount = 0f;
851
            if(fofoDefaultLoans != null ){
852
                if (!fofoDefaultLoans.isEmpty()) {
34743 ranu 853
                    for (Loan entry : fofoDefaultLoans) {
854
 
855
                        List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());
856
 
857
                        double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));
858
 
859
                        defaultLoanAmount += amount;
860
                    }
34641 ranu 861
                }
862
            }
863
 
34719 ranu 864
            List<Loan> activeLoans = loanRepository.selectAllActiveLoan(fofoId);
34641 ranu 865
 
34719 ranu 866
            LOGGER.info("activeLoans- {}",activeLoans);
34641 ranu 867
 
34743 ranu 868
            float activeLoan = 0f;
34719 ranu 869
 
34743 ranu 870
            for (Loan entry : activeLoans) {
871
 
872
                List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());
873
 
874
                double pendingAmount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));
875
 
876
                activeLoan += pendingAmount;
877
            }
878
 
34641 ranu 879
            float poValue = partnerDailyInvestmentMap.get(fofoId) != null ?  partnerDailyInvestmentMap.get(fofoId).getUnbilledAmount() : 0f;
880
 
34719 ranu 881
            float poAndBilledValue = (float) (currentMonthNetSecondary + poValue);
34641 ranu 882
 
34741 ranu 883
            double monthDay1Drr = rbmTargetService.calculateFofoIdTodayTarget(fofoId,0d,currentMonth.atDay(1));
34897 ranu 884
            double todayRequiredDrr = 0;
34641 ranu 885
 
34897 ranu 886
            if(monthDay1Drr != 0d){
887
                todayRequiredDrr = rbmTargetService.calculateFofoIdTodayTarget(fofoId, currentMonthNetSecondary,startOfToday.toLocalDate());
888
            }
34641 ranu 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
}