Subversion Repositories SmartDukaan

Rev

Rev 34848 | Rev 34880 | 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 {
34366 ranu 164
        System.out.println("test start");
34699 ranu 165
        //partnerStatsService.getAllPartnerStats();
166
        this.generateBiReportExcel();
34366 ranu 167
        System.out.println("test end");
34306 ranu 168
 
169
    }
170
 
34648 ranu 171
    public void generateBiReport() throws Exception {
34846 ranu 172
        System.out.println("bi report started");
34648 ranu 173
        this.generateBiReportExcel();
34846 ranu 174
        System.out.println("bi report ended {-----}");
34648 ranu 175
    }
176
 
34308 ranu 177
    public void createLoanForBillingByTransactionIdAndInvoiceNumber(int transactionId, double invoiceAmount, String invoiceNumber) throws Exception {
178
        sdCreditService.createLoanForBilling(transactionId, invoiceAmount, invoiceNumber);
34306 ranu 179
 
34308 ranu 180
    }
34306 ranu 181
 
34619 ranu 182
    public void loanSettle() throws Exception {
183
        List<Integer> refrences = Arrays.asList(25807,36003,38938,39506,42219,45084);
184
        for(Integer ref : refrences){
185
            List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(ref);
186
            double amountSum = loanStatements.stream().map(LoanStatement::getAmount).mapToDouble(BigDecimal::doubleValue).sum();
187
            if(amountSum > 0){
188
                walletService.addAmountToWallet(loanStatements.get(0).getFofoId(),ref, WalletReferenceType.CREDIT_LIMIT,"Amount reversal against credit limit deduction",(float) amountSum,LocalDateTime.now());
34308 ranu 189
 
34619 ranu 190
//                Loan statement entry
191
                    BigDecimal adjustAmount = BigDecimal.valueOf(amountSum).negate(); // or multiply by -1
192
                    LoanStatement loanStatement = new LoanStatement();
193
                    loanStatement.setAmount(adjustAmount);
194
                    loanStatement.setFofoId(loanStatements.get(0).getFofoId());
195
                    loanStatement.setLoanReferenceType(LoanReferenceType.PRINCIPAL);
196
                    loanStatement.setCreatedAt(LocalDateTime.now());
197
                    loanStatement.setDescription("Amount reversal due to access debit against limit");
198
                    loanStatement.setLoanId(ref);
199
                    loanStatement.setBusinessDate(LocalDateTime.now());
200
                    loanStatementRepository.persist(loanStatement);
201
 
202
                    Loan loan = loanRepository.selectByLoanId(ref);
203
                    loan.setPendingAmount(BigDecimal.valueOf(0));
204
                    loan.setSettledOn(LocalDateTime.now());
205
                }
206
 
207
 
208
        }
209
    }
210
 
211
 
212
 
34321 ranu 213
    private void sendMailHtmlFormat(String email[], String body, String cc[], String bcc[], String subject)
214
            throws MessagingException, ProfitMandiBusinessException, IOException {
215
        MimeMessage message = mailSender.createMimeMessage();
216
        MimeMessageHelper helper = new MimeMessageHelper(message);
217
        helper.setSubject(subject);
218
        helper.setText(body, true);
219
        helper.setTo(email);
220
        if (cc != null) {
221
            helper.setCc(cc);
222
        }
223
        if (bcc != null) {
224
            helper.setBcc(bcc);
34308 ranu 225
 
34321 ranu 226
        }
227
 
228
        InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smart Dukaan");
229
        helper.setFrom(senderAddress);
230
        mailSender.send(message);
231
    }
232
 
34307 ranu 233
    public Map<Integer,Integer> findLoanTransactionMapingAccordingLoan(List<Integer> loanIds) throws ProfitMandiBusinessException {
34306 ranu 234
 
235
        Map<Integer, Integer> transactionLoanMap = new HashMap<>();
236
 
237
        for(int loanId : loanIds){
238
            Transaction transaction = null;
239
            Loan loan = loanRepository.selectByLoanId(loanId);
240
            List<Transaction> transactions = transactionRepository.selectByRetailerId(loan.getFofoId());
241
 
242
            LocalDateTime nearestDateTime = transactions.stream().map(x -> x.getCreateTimestamp())
243
                    .min(Comparator.comparingLong(x -> Math.abs(ChronoUnit.MILLIS.between(x, loan.getCreatedOn()))))
244
                    .orElse(null);
245
 
246
            if (nearestDateTime != null && loan.getCreatedOn().plusMinutes(2).isAfter(nearestDateTime) &&
247
                    loan.getCreatedOn().minusMinutes(1).isBefore(nearestDateTime)) {
248
                // Here transaction is still null
249
                transaction = transactions.stream()
250
                        .filter(x -> x.getCreateTimestamp().equals(nearestDateTime))
251
                        .findFirst().get();
252
                transactionLoanMap.put(transaction.getId(), loanId);
253
            }
254
 
255
        }
256
        LOGGER.info("transactionLoanMap {}",transactionLoanMap);
257
        return transactionLoanMap;
258
    }
34321 ranu 259
 
260
 
261
 
262
    public void sendRbmFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
263
        LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
264
        LocalDateTime endOfMonth = LocalDateTime.now();
34323 ranu 265
        String[] bcc = {"tarun.verma@smartdukaan.com"};
34321 ranu 266
 
267
        // Get all RBM users
268
        List<AuthUser> authUsers = csService.getAuthUserIds(
269
                ProfitMandiConstants.TICKET_CATEGORY_RBM,
270
                Arrays.asList(EscalationType.L1)
271
        );
272
 
273
        if (authUsers.isEmpty()) {
274
            LOGGER.info("No RBMs found.");
275
            return;
276
        }
277
 
278
        List<Integer> rbmIds = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
279
 
280
        // Fetch ratings for all RBMs for current month
281
        List<RbmRating> feedbackList = rbmRatingRepository.selectByRbmIdsAndDateRange(rbmIds, startOfMonth, endOfMonth);
282
 
283
        if (feedbackList.isEmpty()) {
284
            LOGGER.info("No feedback entries found for RBMs.");
285
            return;
286
        }
287
 
288
        // Sort feedback by createTimeStamp DESC
289
        feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
290
 
291
        // Fetch and map FOFO (partner) names
292
        Map<Integer, String> fofoNameMap = new HashMap<>();
293
        for (RbmRating rating : feedbackList) {
294
            int fofoId = rating.getFofoId();
295
            if (!fofoNameMap.containsKey(fofoId)) {
296
                User fofoUser = userRepository.selectById(fofoId);
297
                FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
298
 
299
                String partnerName = fofoUser != null ? fofoUser.getName() : "Unknown Partner";
300
                String storeCode = fofoStore != null ? fofoStore.getCode() : "Unknown Code";
301
 
302
                String displayName = partnerName + " (" + storeCode + ")";
303
                fofoNameMap.put(fofoId, displayName);
304
            }
305
        }
306
 
307
        // Map RBM ID to name for quick lookup
308
        Map<Integer, String> rbmNameMap = authUsers.stream()
309
                .collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
310
 
311
        // Generate HTML content
312
        StringBuilder emailContent = new StringBuilder();
313
        emailContent.append("<html><body>");
314
        emailContent.append("<p>Dear Team,</p>");
315
        emailContent.append("<p>Here is the <b>latest RBM Rating and Feedback Summary</b> for ")
316
                .append(LocalDate.now().getMonth()).append(":</p>");
317
 
318
        emailContent.append("<table border='1' cellspacing='0' cellpadding='5'>");
319
        emailContent.append("<tr>")
320
                .append("<th>RBM Name</th>")
321
                .append("<th>Partner Name</th>")
322
                .append("<th>Rating</th>")
323
                .append("<th>Comment</th>")
324
                .append("<th>Date</th>")
325
                .append("</tr>");
326
 
327
        for (RbmRating rating : feedbackList) {
328
            String rbmName = rbmNameMap.getOrDefault(rating.getRbmId(), "Unknown RBM");
329
            String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
330
            emailContent.append("<tr>")
331
                    .append("<td>").append(rbmName).append("</td>")
332
                    .append("<td>").append(partnerName).append("</td>")
333
                    .append("<td>").append(rating.getRating()).append("</td>")
334
                    .append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
335
                    .append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
336
                    .append("</tr>");
337
        }
338
 
339
        emailContent.append("</table>");
340
        emailContent.append("<br><p>Regards,<br>Smart Dukaan Team</p>");
341
        emailContent.append("</body></html>");
342
 
343
        String subject = "Monthly RBM Feedback Summary - " + LocalDate.now().getMonth();
344
 
345
        List<String> sendTo = new ArrayList<>();
34323 ranu 346
        sendTo.add("sm@smartdukaan.com"); //
347
        sendTo.add("chiranjib.sarkar@smartdukaan.com"); //
348
        sendTo.add("kamini.sharma@smartdukaan.com"); //
34321 ranu 349
 
350
        String[] emailRecipients = sendTo.toArray(new String[0]);
351
 
352
 
353
        this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
354
 
355
        LOGGER.info("Consolidated RBM feedback summary email sent.");
356
    }
357
 
358
 
359
    public void sendSalesFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
360
        LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
361
        LocalDateTime endOfMonth = LocalDateTime.now();
34323 ranu 362
        String[] bcc = {"tarun.verma@smartdukaan.com"};
34411 tejus.loha 363
//        String[] bcc = {"tejus.lohani@smartdukaan.com"};
34321 ranu 364
 
365
        // Get all RBM users
366
        List<AuthUser> authUsers = csService.getAuthUserIds(
367
                ProfitMandiConstants.TICKET_CATEGORY_SALES,
368
                Arrays.asList(EscalationType.L1)
369
        );
370
 
371
        if (authUsers.isEmpty()) {
372
            LOGGER.info("No sales person found.");
373
            return;
374
        }
375
 
376
        List<Integer> salesL1Ids = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
377
 
378
        // Fetch ratings for all RBMs for current month
379
        List<SalesRating> feedbackList = salesRatingRepository.selectBySalesL1IdsAndDateRange(salesL1Ids, startOfMonth, endOfMonth);
380
 
381
        if (feedbackList.isEmpty()) {
382
            LOGGER.info("No feedback entries found for Sales.");
383
            return;
384
        }
385
 
386
        // Sort feedback by createTimeStamp DESC
387
        feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
388
 
389
        // Fetch and map FOFO (partner) names
390
        Map<Integer, String> fofoNameMap = new HashMap<>();
391
        for (SalesRating rating : feedbackList) {
392
            int fofoId = rating.getFofoId();
393
            if (!fofoNameMap.containsKey(fofoId)) {
394
                User fofoUser = userRepository.selectById(fofoId);
395
                FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
396
 
397
                String partnerName = fofoUser != null ? fofoUser.getName() : "Unknown Partner";
398
                String storeCode = fofoStore != null ? fofoStore.getCode() : "Unknown Code";
399
 
400
                String displayName = partnerName + " (" + storeCode + ")";
401
                fofoNameMap.put(fofoId, displayName);
402
            }
403
        }
404
 
405
        // Map RBM ID to name for quick lookup
406
        Map<Integer, String> salesL1NameMap = authUsers.stream()
407
                .collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
408
 
409
        // Generate HTML content
410
        StringBuilder emailContent = new StringBuilder();
411
        emailContent.append("<html><body>");
412
        emailContent.append("<p>Dear Team,</p>");
413
        emailContent.append("<p>Here is the <b>latest Sales L1 Rating and Feedback Summary</b> for ")
414
                .append(LocalDate.now().getMonth()).append(":</p>");
415
 
416
        emailContent.append("<table border='1' cellspacing='0' cellpadding='5'>");
417
        emailContent.append("<tr>")
418
                .append("<th>Sales L1 Name</th>")
419
                .append("<th>Partner Name</th>")
34411 tejus.loha 420
                .append("<th>Partner Category</th>")
34321 ranu 421
                .append("<th>Rating</th>")
422
                .append("<th>Comment</th>")
423
                .append("<th>Date</th>")
424
                .append("</tr>");
425
 
426
        for (SalesRating rating : feedbackList) {
427
            String salesL1 = salesL1NameMap.getOrDefault(rating.getSalesL1Id(), "Unknown Sales Person");
428
            String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
34844 ranu 429
            LOGGER.info("partnerName11- {}",partnerName);
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
 
34844 ranu 481
/*        List<Integer> retailerIds = Arrays.asList(175139247,175139660);
34784 ranu 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
 
34849 ranu 796
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledByCategoryOrderGroupByBrandFofoId(fofoId, currentMonthStartDate,currentMonthEndDate, 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
}