Subversion Repositories SmartDukaan

Rev

Rev 34846 | Rev 34849 | 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
 
34741 ranu 796
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledByCategoryOrderGroupByBrandFofoId(fofoId, currentMonthStartDate,Arrays.asList(10006,10001));
34848 ranu 797
            LOGGER.info("brandWiseMtdSecondary {}", brandWiseMtdSecondary);
34641 ranu 798
            Map<String,Long> brandWiseMtdSecondaryMap = brandWiseMtdSecondary.stream().collect(Collectors.toMap(BrandWiseModel::getBrand,BrandWiseModel::getAmount));
34619 ranu 799
 
34730 ranu 800
            //retrunInfo
801
            List<BrandWiseReturnInfo> brandWiseReturnInfos = returnOrderInfoRepository.selectAllBrandWiseByBetweenDate(currentMonthStartDate,currentMonthEndDate.plusDays(1),fofoId);
802
            Map<String,Double> brandWiseReturnInfoMap = brandWiseReturnInfos.stream().collect(Collectors.toMap(BrandWiseReturnInfo::getBrand, x->x.getReturnAmount()));
34619 ranu 803
 
34730 ranu 804
            LOGGER.info("brandWiseReturnInfos {}",brandWiseReturnInfos);
34758 ranu 805
 
34730 ranu 806
            //Rto retrunInfo
807
            List<BrandWiseReturnInfo> brandWiseRTOReturnInfos = returnOrderInfoRepository.selectAllBrandWiseRTORefundByBetweenDate(currentMonthStartDate,currentMonthEndDate.plusDays(1),fofoId);
808
            Map<String,Double> brandWiseRTOReturnInfoMap = brandWiseRTOReturnInfos.stream().collect(Collectors.toMap(BrandWiseReturnInfo::getBrand, x->x.getReturnAmount()));
809
 
810
            // Step 1: Get union of all brand keys
811
            Set<String> allBrands = new HashSet<>();
812
            allBrands.addAll(brandWiseMtdSecondaryMap.keySet());
813
            allBrands.addAll(brandWiseReturnInfoMap.keySet());
814
            allBrands.addAll(brandWiseRTOReturnInfoMap.keySet());
815
 
816
            // Step 2: Calculate net secondary for each brand
817
            Map<String, Long> brandWiseMtdNetSecondaryMap = new HashMap<>();
818
 
819
            for (String brand : allBrands) {
820
                Long billedAmount = brandWiseMtdSecondaryMap.getOrDefault(brand, 0L);
821
                Double returnAmount = brandWiseReturnInfoMap.getOrDefault(brand, 0d);
822
                Double rtoReturnAmount = brandWiseRTOReturnInfoMap.getOrDefault(brand, 0d);
823
 
824
                double netSecondary = billedAmount - (returnAmount + rtoReturnAmount);
825
                brandWiseMtdNetSecondaryMap.put(brand, (long) Math.round(netSecondary));
826
            }
827
 
828
 
829
            LOGGER.info("brandWiseMtdNetSecondaryMap {}",brandWiseMtdNetSecondaryMap );
830
 
831
 
832
            fofoBrandWiseMtdSecondaryMap.put(fofoId,brandWiseMtdNetSecondaryMap);
833
 
834
            long mtdTotalSecondary = brandWiseMtdNetSecondaryMap.values().stream().mapToLong(Long::longValue).sum();
835
 
34641 ranu 836
            fofoTotalMtdSecondaryMap.put(fofoId,mtdTotalSecondary);
837
 
838
            //            generate investment info
839
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
840
            float shortInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getShortInvestment() : 0f;
841
            float agreedInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getMinInvestment() : 0f;
34677 ranu 842
            float investmentLevel = partnerDailyInvestmentMap.get(fofoId) != null
843
                    ? Math.abs(((shortInvestment - agreedInvestment) / agreedInvestment) * 100)
844
                    : 0f;
34641 ranu 845
 
34677 ranu 846
 
34641 ranu 847
            List<Loan> fofoDefaultLoans = new ArrayList<>();
848
            if(defaultLoanMap != null){
849
                 fofoDefaultLoans  =  defaultLoanMap.get(fofoId);
850
                LOGGER.info("fofoDefaultLoans {}",fofoDefaultLoans);
851
            }
852
 
853
            float defaultLoanAmount = 0f;
854
            if(fofoDefaultLoans != null ){
855
                if (!fofoDefaultLoans.isEmpty()) {
34743 ranu 856
                    for (Loan entry : fofoDefaultLoans) {
857
 
858
                        List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());
859
 
860
                        double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));
861
 
862
                        defaultLoanAmount += amount;
863
                    }
34641 ranu 864
                }
865
            }
866
 
34719 ranu 867
            List<Loan> activeLoans = loanRepository.selectAllActiveLoan(fofoId);
34641 ranu 868
 
34719 ranu 869
            LOGGER.info("activeLoans- {}",activeLoans);
34641 ranu 870
 
34743 ranu 871
            float activeLoan = 0f;
34719 ranu 872
 
34743 ranu 873
            for (Loan entry : activeLoans) {
874
 
875
                List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());
876
 
877
                double pendingAmount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));
878
 
879
                activeLoan += pendingAmount;
880
            }
881
 
34641 ranu 882
            float poValue = partnerDailyInvestmentMap.get(fofoId) != null ?  partnerDailyInvestmentMap.get(fofoId).getUnbilledAmount() : 0f;
883
 
34719 ranu 884
            float poAndBilledValue = (float) (currentMonthNetSecondary + poValue);
34641 ranu 885
 
34741 ranu 886
            double todayRequiredDrr = rbmTargetService.calculateFofoIdTodayTarget(fofoId, currentMonthNetSecondary,startOfToday.toLocalDate());
34641 ranu 887
 
34741 ranu 888
            double monthDay1Drr = rbmTargetService.calculateFofoIdTodayTarget(fofoId,0d,currentMonth.atDay(1));
34641 ranu 889
 
890
 
891
            double gotDrrPercent = (todayRequiredDrr / monthDay1Drr) * 100;
892
 
34701 ranu 893
            long drrPercentDisplay = Math.round(Math.abs(gotDrrPercent));
894
 
895
 
34641 ranu 896
            int orderId = orderRepository.getLastOrderByFofoId(fofoId);
897
 
34644 ranu 898
            // Determine alert level
899
            String alertLevel = "-";
900
            int lastPurchaseDays = 0;
34641 ranu 901
            if (orderId != 0) {
902
                Order order = orderRepository.selectById(orderId);
903
 
34715 ranu 904
                LOGGER.info("last billing order - {}",order);
905
 
34641 ranu 906
                // Calculate the number of days since the last purchase (billing)
34644 ranu 907
                lastPurchaseDays = (int) Duration.between(order.getCreateTimestamp().plusDays(1), LocalDateTime.now()).toDays();
34641 ranu 908
 
909
                if (lastPurchaseDays >= 11) {
910
                    alertLevel = "Alert for Management";
34676 ranu 911
                } else if (lastPurchaseDays >= 10) {
34641 ranu 912
                    alertLevel = " Alert for RSM/SH";
34676 ranu 913
                } else if (lastPurchaseDays >= 7) {
34641 ranu 914
                    alertLevel = "Must be Billed";
915
                } else if (lastPurchaseDays >= 3) {
916
                    alertLevel = "OK";
917
                } else {
34676 ranu 918
                    alertLevel = "OK";
34641 ranu 919
                }
34644 ranu 920
            }
34641 ranu 921
 
34644 ranu 922
            //investment modal set all related value
923
            FofoInvestmentModel fofoInvestmentModel = new FofoInvestmentModel();
34641 ranu 924
 
34644 ranu 925
            fofoInvestmentModel.setCounterPotential(fofoStore.getCounterPotential());
926
            fofoInvestmentModel.setShortInvestment(shortInvestment);
927
            fofoInvestmentModel.setDefaultLoan(defaultLoanAmount);
928
            fofoInvestmentModel.setInvestmentLevel(investmentLevel);
929
            fofoInvestmentModel.setActiveLoan(activeLoan);
930
            fofoInvestmentModel.setPoValue(poValue);
931
            fofoInvestmentModel.setPoAndBilled(poAndBilledValue);
932
            fofoInvestmentModel.setAgreedInvestment(agreedInvestment);
933
            fofoInvestmentModel.setWallet(partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getWalletAmount() : 0);
934
            fofoInvestmentModel.setMonthBeginingDrr(monthDay1Drr);
935
            fofoInvestmentModel.setRequiredDrr(todayRequiredDrr);
34701 ranu 936
            fofoInvestmentModel.setDrrPercent(drrPercentDisplay);
34644 ranu 937
            fofoInvestmentModel.setLastBillingDone(lastPurchaseDays);
938
            fofoInvestmentModel.setSlab(alertLevel);
34641 ranu 939
 
34644 ranu 940
            biInvestmentModelMap.put(fofoId, fofoInvestmentModel);
34641 ranu 941
                String assessment = "";
34763 ranu 942
                if(defaultLoanAmount < 0 ){
34641 ranu 943
                    assessment = "Loan Default";
34763 ranu 944
                }else if(investmentLevel <= 75 && defaultLoanAmount >= 0){
34641 ranu 945
                    assessment = "Low Invest";
946
                }else {
947
                    assessment = "-";
948
                }
949
                assessmentMap.put(fofoId,assessment);
950
 
951
                String zeroBilling = "";
952
                if(currentMonthNetSecondary <= 100000 ){
953
                    zeroBilling = "Zero Billing";
954
                }else {
955
                    zeroBilling = "-";
956
                }
957
                zeroBillingMap.put(fofoId,zeroBilling);
958
 
959
                float billingNeeded = 0f;
34749 ranu 960
                if(drrPercentDisplay >= 110 && todayRequiredDrr > 0 ){
34641 ranu 961
                    billingNeeded = (float) todayRequiredDrr;
962
                }else {
963
                    billingNeeded = 0f;
964
                }
965
                billingNeededMap.put(fofoId,billingNeeded);
966
 
967
                int counta = 0;
34701 ranu 968
                if(defaultLoanAmount > 0 || investmentLevel <= 75 || currentMonthNetSecondary <= 100000 || drrPercentDisplay >= 110 ){
34641 ranu 969
                    counta = 1;
970
                }else {
971
                    counta = 0;
972
                }
973
                countAMap.put(fofoId,counta);
974
 
34606 ranu 975
        }
976
 
34619 ranu 977
        LOGGER.info("Total BI Retailers processed: {}", biRetailerModelMap.size());
34606 ranu 978
 
34619 ranu 979
        //generate excel and sent to mail
980
        List<List<String>> headerGroup = new ArrayList<>();
34606 ranu 981
 
34619 ranu 982
        List<String> headers1 = Arrays.asList(
34641 ranu 983
                "","","","",
34715 ranu 984
                "Retailer Detail", "","", "", "", "", "", "", "", "","","","",
34677 ranu 985
 
986
                twoMonthAgoStringValue, "", "", "", "", "", "",
987
                lastMonthStringValue, "", "", "", "", "", "",
34619 ranu 988
                currentMonthStringValue, "", "", "", "", "", "",
34641 ranu 989
 
990
                "","", "", "", "", "", "", "", "", "", "", "", "", "",
991
 
992
                "", "", "", "", "", "", "", "", "", "", "", "", "",
34749 ranu 993
                "", "", "", "", "", "", "", "", "", "", "", "", "","",""
34641 ranu 994
 
34619 ranu 995
        );
34606 ranu 996
 
34619 ranu 997
        List<String> headers2 = Arrays.asList(
34641 ranu 998
                "Assessment","Zero billing","Billing needed","Counta",
34715 ranu 999
                "BM","Partner Id","Link","Wallet Date","Creation Date","Code","Area",  "City", "Store Name", "Status","Category","Sales Manager", "RBM",
34619 ranu 1000
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
1001
                "Tertiary Sale", "Unbilled",
1002
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
1003
                "Tertiary Sale", "Unbilled",
1004
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
1005
                "Tertiary Sale", "Unbilled",
34641 ranu 1006
                "Counter Potential", "Short investment", "Default", "INVESTMENT LEVEL", "Loan", "PO value", "Agreed investment",
1007
                "Wallet", "po+bill", "MONTH BEGINNING DRR", "REQ DRR", "Drr %", "Last billing Done", "Slab",
34606 ranu 1008
 
34721 ranu 1009
              "Total Stock",  "Apple","Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
1010
              "Total Secondary", "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
34749 ranu 1011
              "Total Tertiary",  "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
1012
                "YesterDay Seconday","Day Before Yesterday Secondary"
34619 ranu 1013
        );
1014
 
1015
        headerGroup.add(headers1);
1016
        headerGroup.add(headers2);
1017
 
1018
 
1019
        List<List<?>> rows = new ArrayList<>();
1020
        for (Map.Entry<Integer, BIRetailerModel> entry : biRetailerModelMap.entrySet()) {
34749 ranu 1021
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
34619 ranu 1022
            Integer fofoId = entry.getKey();
34715 ranu 1023
            User user = userRepository.selectById(fofoId);
1024
            LocalDateTime walletCreationDate = userWalletHistoryRepository.selectFirstCreatedDate(fofoId);
34758 ranu 1025
            if(walletCreationDate == null){
1026
                walletCreationDate = user.getCreateTimestamp();
1027
            }
34619 ranu 1028
            BIRetailerModel retailer = entry.getValue();
34641 ranu 1029
 
34619 ranu 1030
            Map<YearMonth, BiSecondaryModel> monthlyData = allRetailerMonthlyData.get(fofoId);
1031
 
34741 ranu 1032
            BiSecondaryModel current = monthlyData.getOrDefault(currentMonth, new BiSecondaryModel(0,0,0,0,0,0,0));
1033
            BiSecondaryModel last = monthlyData.getOrDefault(currentMonth.minusMonths(1), new BiSecondaryModel(0,0,0,0,0,0,0));
1034
            BiSecondaryModel twoAgo = monthlyData.getOrDefault(currentMonth.minusMonths(2), new BiSecondaryModel(0,0,0,0,0,0,0));
34619 ranu 1035
 
1036
            List<Object> row = new ArrayList<>();
34758 ranu 1037
            LOGGER.info("fofoId-11 {}",fofoId);
1038
 
34619 ranu 1039
            row.addAll(Arrays.asList(
34758 ranu 1040
                    assessmentMap.get(fofoId),
1041
                    zeroBillingMap.get(fofoId),
1042
                    billingNeededMap.get(fofoId),
1043
                    countAMap.get(fofoId),
1044
                    retailer.getBmName(),
1045
                    fofoId ,
1046
                    "https://partners.smartdukaan.com/partnerPerformance?fofoId="+fofoId,
1047
                    walletCreationDate.format(formatter),
1048
                    user.getCreateTimestamp() != null ? (user.getCreateTimestamp()).format(formatter) : "-",
1049
                    retailer.getCode(),
1050
                    retailer.getArea(),
1051
                    retailer.getCity(),
1052
                    retailer.getStoreName(),
1053
                    retailer.getStatus(),
1054
                    retailer.getCategory(),
1055
                    retailer.getSalesManager(),
1056
                    retailer.getRbm()
34677 ranu 1057
 
34619 ranu 1058
            ));
1059
 
34677 ranu 1060
 
1061
            // Two Months Ago
34619 ranu 1062
            row.addAll(Arrays.asList(
34677 ranu 1063
                    twoAgo.getSecondaryTarget(),
1064
                    twoAgo.getSecondaryAchieved(),
1065
                    twoAgo.getSecondaryReturn(),
1066
                    twoAgo.getNetSecondary(),
34704 ranu 1067
                    twoAgo.getSecondaryAchievedPercent()+"%",
34677 ranu 1068
                    twoAgo.getTertiary(),
1069
                    twoAgo.getTertiaryUnBilled()
34619 ranu 1070
            ));
1071
 
1072
            // Last Month
1073
            row.addAll(Arrays.asList(
1074
                    last.getSecondaryTarget(),
1075
                    last.getSecondaryAchieved(),
1076
                    last.getSecondaryReturn(),
1077
                    last.getNetSecondary(),
34704 ranu 1078
                    last.getSecondaryAchievedPercent()+"%",
34619 ranu 1079
                    last.getTertiary(),
1080
                    last.getTertiaryUnBilled()
1081
            ));
1082
 
34677 ranu 1083
            // Current Month
34619 ranu 1084
            row.addAll(Arrays.asList(
34677 ranu 1085
                    current.getSecondaryTarget(),
1086
                    current.getSecondaryAchieved(),
1087
                    current.getSecondaryReturn(),
1088
                    current.getNetSecondary(),
34704 ranu 1089
                    current.getSecondaryAchievedPercent()+"%",
34677 ranu 1090
                    current.getTertiary(),
1091
                    current.getTertiaryUnBilled()
34619 ranu 1092
            ));
34677 ranu 1093
 
1094
 
1095
 
34641 ranu 1096
            FofoInvestmentModel fofoInvestmentModelValue = biInvestmentModelMap.get(fofoId);
1097
            if(fofoInvestmentModelValue != null){
1098
                row.addAll(Arrays.asList(
1099
                        fofoInvestmentModelValue.getCounterPotential(),
1100
                        fofoInvestmentModelValue.getShortInvestment(),
1101
                        fofoInvestmentModelValue.getDefaultLoan(),
34730 ranu 1102
                        fofoInvestmentModelValue.getInvestmentLevel() +"%",
34743 ranu 1103
                        fofoInvestmentModelValue.getActiveLoan(),
34641 ranu 1104
                        fofoInvestmentModelValue.getPoValue(),
1105
                        fofoInvestmentModelValue.getAgreedInvestment(),
1106
                        fofoInvestmentModelValue.getWallet(),
1107
                        fofoInvestmentModelValue.getPoAndBilled(),
1108
                        fofoInvestmentModelValue.getMonthBeginingDrr(),
1109
                        fofoInvestmentModelValue.getRequiredDrr(),
34704 ranu 1110
                        fofoInvestmentModelValue.getDrrPercent()+"%",
34641 ranu 1111
                        fofoInvestmentModelValue.getLastBillingDone(),
1112
                        fofoInvestmentModelValue.getSlab()
1113
                ));
1114
            }else {
1115
                row.addAll(Arrays.asList(
1116
                        "-","-","-","-","-","-","-","-","-","-","-",""
1117
                ));
1118
            }
1119
 
1120
            Map<String, BrandStockPrice> brandStockMap = fofoBrandStockPriceMap.get(fofoId);
34619 ranu 1121
            row.addAll(Arrays.asList(
1122
                    fofoTotalStockPriceMap.getOrDefault(fofoId, 0.0),
34641 ranu 1123
                    brandStockMap.get("Apple") != null ? brandStockMap.get("Apple").getTotalValue() : 0.0,
1124
                    brandStockMap.get("Xiaomi") != null ? brandStockMap.get("Xiaomi").getTotalValue() : 0.0,
1125
                    brandStockMap.get("Vivo") != null ? brandStockMap.get("Vivo").getTotalValue() : 0.0,
1126
                    brandStockMap.get("Tecno") != null ? brandStockMap.get("Tecno").getTotalValue() : 0.0,
1127
                    brandStockMap.get("Samsung") != null ? brandStockMap.get("Samsung").getTotalValue() : 0.0,
1128
                    brandStockMap.get("Realme") != null ? brandStockMap.get("Realme").getTotalValue() : 0.0,
1129
                    brandStockMap.get("Oppo") != null ? brandStockMap.get("Oppo").getTotalValue() : 0.0,
1130
                    brandStockMap.get("OnePlus") != null ? brandStockMap.get("OnePlus").getTotalValue() : 0.0,
34721 ranu 1131
                    brandStockMap.get("POCO") != null ? brandStockMap.get("POCO").getTotalValue() : 0.0,
34641 ranu 1132
                    brandStockMap.get("Lava") != null ? brandStockMap.get("Lava").getTotalValue() : 0.0,
1133
                    brandStockMap.get("Itel") != null ? brandStockMap.get("Itel").getTotalValue() : 0.0,
1134
                    brandStockMap.get("Almost New") != null ? brandStockMap.get("Almost New").getTotalValue() : 0.0
34619 ranu 1135
            ));
1136
 
34641 ranu 1137
            Map<String, Long> brandSecondaryMap = fofoBrandWiseMtdSecondaryMap.get(fofoId);
1138
            row.addAll(Arrays.asList(
34648 ranu 1139
                    fofoTotalMtdSecondaryMap.get(fofoId),
34641 ranu 1140
                    brandSecondaryMap.getOrDefault("Apple", 0L),
1141
                    brandSecondaryMap.getOrDefault("Xiaomi", 0L),
1142
                    brandSecondaryMap.getOrDefault("Vivo", 0L),
1143
                    brandSecondaryMap.getOrDefault("Tecno", 0L),
1144
                    brandSecondaryMap.getOrDefault("Samsung", 0L),
1145
                    brandSecondaryMap.getOrDefault("Realme", 0L),
1146
                    brandSecondaryMap.getOrDefault("Oppo", 0L),
1147
                    brandSecondaryMap.getOrDefault("OnePlus", 0L),
34721 ranu 1148
                    brandSecondaryMap.getOrDefault("POCO", 0L),
34641 ranu 1149
                    brandSecondaryMap.getOrDefault("Lava", 0L),
1150
                    brandSecondaryMap.getOrDefault("Itel", 0L),
1151
                    brandSecondaryMap.getOrDefault("Almost New", 0L)
1152
            ));
1153
 
1154
            Map<String, Double> brandTertiaryMap = fofoBrandMtdTertiaryMap.get(fofoId);
1155
            row.addAll(Arrays.asList(
34648 ranu 1156
                    fofoTotalMtdTertiaryMap.get(fofoId),
34641 ranu 1157
                    brandTertiaryMap.getOrDefault("Apple", 0d),
1158
                    brandTertiaryMap.getOrDefault("Xiaomi", 0d),
1159
                    brandTertiaryMap.getOrDefault("Vivo", 0d),
1160
                    brandTertiaryMap.getOrDefault("Tecno", 0d),
1161
                    brandTertiaryMap.getOrDefault("Samsung", 0d),
1162
                    brandTertiaryMap.getOrDefault("Realme", 0d),
1163
                    brandTertiaryMap.getOrDefault("Oppo", 0d),
1164
                    brandTertiaryMap.getOrDefault("OnePlus", 0d),
34721 ranu 1165
                    brandTertiaryMap.getOrDefault("POCO", 0d),
34641 ranu 1166
                    brandTertiaryMap.getOrDefault("Lava", 0d),
1167
                    brandTertiaryMap.getOrDefault("Itel", 0d),
1168
                    brandTertiaryMap.getOrDefault("Almost New", 0d)
1169
            ));
34749 ranu 1170
 
1171
            row.addAll(Arrays.asList(
1172
                    fofoYesterdaySecondaryMap.get(fofoId),
1173
                    fofoDayBeforeYesterdaySecondaryMap.get(fofoId)
1174
            ));
34641 ranu 1175
            rows.add(row);
34619 ranu 1176
        }
1177
 
1178
 
34641 ranu 1179
        // Send to email
1180
//        ByteArrayOutputStream csvStream = FileUtil.getCSVByteStreamWithMultiHeaders(headerGroup, rows);
1181
        ByteArrayOutputStream csvStream = getExcelStreamWithMultiHeaders(headerGroup, rows);
1182
        String fileName = "BI-Retailer-Monthly-Report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".xlsx";
34758 ranu 1183
        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com","ashutosh.verma@smartdukaan.com","sm@smartdukaan.com","raj.singh@smartdukaan.com"};
1184
//        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com"};
34619 ranu 1185
 
1186
        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()));
1187
 
1188
 
34606 ranu 1189
    }
1190
 
34641 ranu 1191
    public static ByteArrayOutputStream getExcelStreamWithMultiHeaders(List<List<String>> headerGroup, List<List<?>> rows) {
1192
        Workbook workbook = new XSSFWorkbook();
1193
        Sheet sheet = workbook.createSheet("BI Report");
34715 ranu 1194
        CreationHelper creationHelper = workbook.getCreationHelper();
34641 ranu 1195
        int rowIndex = 0;
34606 ranu 1196
 
34641 ranu 1197
        CellStyle centeredStyle = workbook.createCellStyle();
1198
        centeredStyle.setAlignment(HorizontalAlignment.CENTER); // Center horizontally
1199
        centeredStyle.setVerticalAlignment(VerticalAlignment.CENTER); // Center vertically
34606 ranu 1200
 
34641 ranu 1201
    // Optional: bold font
1202
        Font font1 = workbook.createFont();
1203
        font1.setBold(true);
1204
        centeredStyle.setFont(font1);
34606 ranu 1205
 
34619 ranu 1206
 
34641 ranu 1207
 
1208
        // Create styles
1209
        Map<String, CellStyle> headerStyles = new HashMap<>();
1210
 
1211
        // fontPurpleStyle
1212
        CellStyle purpleStyle = workbook.createCellStyle();
1213
        purpleStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
1214
        purpleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1215
        purpleStyle.setFont(font1);
1216
        headerStyles.put("Assessment", purpleStyle);
1217
        headerStyles.put("Zero billing", purpleStyle);
1218
        headerStyles.put("Billing needed", purpleStyle);
1219
        headerStyles.put("Counta", purpleStyle);
1220
        headerStyles.put("MONTH BEGINNING DRR", purpleStyle);
1221
        headerStyles.put("REQ DRR", purpleStyle);
1222
        headerStyles.put("Drr %", purpleStyle);
1223
 
1224
        // Light Blue
1225
        CellStyle blueStyle = workbook.createCellStyle();
1226
        blueStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
1227
        blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1228
        blueStyle.setFont(font1);
1229
        headerStyles.put("Code", blueStyle);
1230
        headerStyles.put("Store Name", blueStyle);
1231
        headerStyles.put("City", blueStyle);
1232
        headerStyles.put("Area", blueStyle);
1233
        headerStyles.put("BM", blueStyle);
1234
        headerStyles.put("RBM", blueStyle);
1235
        headerStyles.put("Sales Manager", blueStyle);
1236
        headerStyles.put("Status", blueStyle);
1237
        headerStyles.put("Category", blueStyle);
34715 ranu 1238
        headerStyles.put("Wallet Date", blueStyle);
1239
        headerStyles.put("Creation Date", blueStyle);
1240
        headerStyles.put("Partner Id", blueStyle);
34641 ranu 1241
 
34715 ranu 1242
        //for link
1243
        // Create hyperlink style
1244
        CellStyle hyperlinkStyle = workbook.createCellStyle();
1245
        Font hlinkFont = workbook.createFont();
1246
        hlinkFont.setUnderline(Font.U_SINGLE);
1247
        hlinkFont.setColor(IndexedColors.BLUE.getIndex());
1248
        hyperlinkStyle.setFont(hlinkFont);
1249
 
1250
 
34641 ranu 1251
        // Light Yellow
1252
        CellStyle yellowStyle = workbook.createCellStyle();
1253
        yellowStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
1254
        yellowStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1255
        yellowStyle.setFont(font1);
1256
        headerStyles.put("Last billing Done", yellowStyle);
1257
        headerStyles.put("Total Stock", yellowStyle);
1258
 
1259
        // Light Orange
1260
        CellStyle orangeStyle = workbook.createCellStyle();
1261
        orangeStyle.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
1262
        orangeStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1263
        orangeStyle.setFont(font1);
1264
        headerStyles.put("Total Tertiary", orangeStyle);
1265
        headerStyles.put("Total Secondary", orangeStyle);
1266
        headerStyles.put("Default", orangeStyle);
1267
 
1268
 
1269
        // Light green
1270
        CellStyle lightGreenStyle = workbook.createCellStyle();
1271
        lightGreenStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
1272
        lightGreenStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1273
        lightGreenStyle.setFont(font1);
1274
        headerStyles.put("Short investment", lightGreenStyle);
1275
        headerStyles.put("INVESTMENT LEVEL", lightGreenStyle);
1276
        headerStyles.put("Loan", lightGreenStyle);
1277
        headerStyles.put("PO value", lightGreenStyle);
1278
        headerStyles.put("Agreed investment", lightGreenStyle);
1279
        headerStyles.put("Wallet", lightGreenStyle);
1280
        headerStyles.put("po+bill", lightGreenStyle);
1281
 
1282
        // Light Green
1283
        CellStyle secondary1 = createStyle(workbook, IndexedColors.LIGHT_GREEN);
1284
        CellStyle secondary2 = createStyle(workbook, IndexedColors.LIGHT_YELLOW);
1285
        CellStyle secondary3 = createStyle(workbook, IndexedColors.LIGHT_ORANGE);
1286
 
1287
        Map<String, CellStyle> brandStyles = new HashMap<>();
1288
        brandStyles.put("Apple", createStyle(workbook, IndexedColors.GREY_25_PERCENT));
1289
        brandStyles.put("Xiaomi", createStyle(workbook, IndexedColors.ORANGE));
1290
        brandStyles.put("Vivo", createStyle(workbook, IndexedColors.SKY_BLUE));
1291
        brandStyles.put("Tecno", createStyle(workbook, IndexedColors.LIGHT_BLUE));
1292
        brandStyles.put("Samsung", createStyle(workbook, IndexedColors.ROYAL_BLUE));
1293
        brandStyles.put("Realme", createStyle(workbook, IndexedColors.YELLOW));
1294
        brandStyles.put("Oppo", createStyle(workbook, IndexedColors.LIGHT_GREEN));
1295
        brandStyles.put("OnePlus", createStyle(workbook, IndexedColors.RED));
34721 ranu 1296
        brandStyles.put("POCO", createStyle(workbook, IndexedColors.ORANGE));
34641 ranu 1297
        brandStyles.put("Lava", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1298
        brandStyles.put("Itel", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1299
        brandStyles.put("Almost New", createStyle(workbook, IndexedColors.WHITE));
1300
 
1301
 
1302
        CellStyle defaultHeaderStyle = workbook.createCellStyle();
1303
        defaultHeaderStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
1304
        defaultHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1305
        defaultHeaderStyle.setFont(font1);
1306
 
34749 ranu 1307
        CellStyle numberStyle = workbook.createCellStyle();
1308
        DataFormat format = workbook.createDataFormat();
1309
        numberStyle.setDataFormat(format.getFormat("#,##0")); // or "#,##0.00" for two decimals
34641 ranu 1310
 
34749 ranu 1311
 
1312
 
34641 ranu 1313
        Map<String, Integer> headerCount = new HashMap<>();
1314
 
1315
        for (int headerRowIndex = 0; headerRowIndex < headerGroup.size(); headerRowIndex++) {
1316
            List<String> headerRow = headerGroup.get(headerRowIndex);
1317
            Row row = sheet.createRow(rowIndex++);
1318
 
1319
            for (int i = 0; i < headerRow.size(); i++) {
1320
                String headerText = headerRow.get(i);
1321
                sheet.setColumnWidth(i, 25 * 256);
1322
                row.setHeightInPoints(20); // 25-point height
1323
                Cell cell = row.createCell(i);
1324
                cell.setCellValue(headerText);
1325
                cell.setCellStyle(centeredStyle);
1326
                // Count how many times this header has appeared
1327
                int count = headerCount.getOrDefault(headerText, 0) + 1;
1328
                headerCount.put(headerText, count);
1329
                // Apply special style for repeated headers
1330
                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")) {
1331
                    if (count == 1) {
1332
                        cell.setCellStyle(secondary1);
1333
                    } else if (count == 2) {
1334
                        cell.setCellStyle(secondary2);
1335
                    } else if (count == 3) {
1336
                        cell.setCellStyle(secondary3);
1337
                    }
1338
                }
1339
                // Brand header styling (apply only for the 2nd row of headers)
1340
                else if (headerRowIndex == 1 && brandStyles.containsKey(headerText)) {
1341
                    cell.setCellStyle(brandStyles.get(headerText));
1342
                }else if (headerStyles.containsKey(headerText)) {
1343
                    cell.setCellStyle(headerStyles.get(headerText));
1344
                } else {
1345
                    cell.setCellStyle(defaultHeaderStyle); // default style for others
1346
                }
1347
            }
1348
        }
1349
 
1350
        // Write data rows
1351
        for (List<?> dataRow : rows) {
1352
            Row row = sheet.createRow(rowIndex++);
1353
            for (int i = 0; i < dataRow.size(); i++) {
1354
                Cell cell = row.createCell(i);
1355
                Object value = dataRow.get(i);
34715 ranu 1356
 
1357
                if (i == 6 && value != null) { // Assuming column 6 is "Link"
1358
                    Hyperlink hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
1359
                    hyperlink.setAddress(value.toString());
34719 ranu 1360
                    cell.setCellValue("View Link"); // Display text
34715 ranu 1361
                    cell.setHyperlink(hyperlink);
1362
                    cell.setCellStyle(hyperlinkStyle);
34719 ranu 1363
                } else if (value instanceof Number) {
34749 ranu 1364
                    double numeric = ((Number) value).doubleValue();
1365
                    cell.setCellValue(Math.round(numeric));
1366
                    cell.setCellStyle(numberStyle);
34715 ranu 1367
                } else {
1368
                    cell.setCellValue(value != null ? value.toString() : "");
1369
                }
34641 ranu 1370
            }
34719 ranu 1371
 
34641 ranu 1372
        }
1373
 
1374
        // Auto-size columns
1375
        if (!rows.isEmpty()) {
1376
            for (int i = 0; i < rows.get(0).size(); i++) {
1377
                sheet.autoSizeColumn(i);
1378
            }
1379
        }
1380
 
1381
        // Output as ByteArray
1382
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
1383
            workbook.write(outputStream);
1384
            workbook.close();
1385
            return outputStream;
1386
        } catch (IOException e) {
1387
            throw new RuntimeException("Failed to generate Excel file", e);
1388
        }
1389
    }
1390
 
1391
 
1392
    private static CellStyle createStyle(Workbook workbook, IndexedColors color) {
1393
        CellStyle style = workbook.createCellStyle();
1394
        style.setFillForegroundColor(color.getIndex());
1395
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1396
        Font font = workbook.createFont();
1397
        font.setBold(true);
1398
        style.setFont(font);
1399
        return style;
1400
    }
1401
 
1402
 
34758 ranu 1403
    public void stockAlertMailToRetailer() throws Exception {
1404
 
1405
        Map<Integer, CustomRetailer> customRetailers = retailerService.getFofoRetailers(true);
1406
 
1407
        List<Integer> retailerIds = customRetailers.values().stream().map(CustomRetailer::getPartnerId).collect(Collectors.toList());
1408
 
1409
        for(Integer fofoId : retailerIds){
1410
            List<String> statusOrder = Arrays.asList("HID", "FASTMOVING", "RUNNING", "SLOWMOVING", "OTHER");
1411
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
1412
            List<PartnerWarehouseStockSummaryModel> partnerWarehouseStockSummaryModels = saholicInventoryService.getSaholicAndPartnerStock(fofoId, fofoStore.getWarehouseId());
1413
 
1414
            List<PartnerWarehouseStockAgingSummaryModel> partnerWarehouseStockAgingSummaryModelList = new ArrayList<>();
1415
 
1416
            Set<Integer> catalogIds = partnerWarehouseStockSummaryModels.stream().map(x -> x.getCatalogId()).collect(Collectors.toSet());
1417
 
1418
            List<Integer> catalogsList = new ArrayList<>(catalogIds);
1419
 
1420
            Map<Integer, TagListing> tagListingsMap = tagListingRepository.selectAllByCatalogIds(catalogsList);
1421
 
1422
            List<CatalogAgingModel> catalogAgingModels = ageingService.getCatalogsAgingByWarehouse(catalogIds, fofoStore.getWarehouseId());
1423
 
1424
            Map<Integer, CatalogAgingModel> catalogAgingModelMap = catalogAgingModels.stream().collect(Collectors.toMap(x -> x.getCatalogId(), x -> x));
1425
 
1426
            for (PartnerWarehouseStockSummaryModel stockSummary : partnerWarehouseStockSummaryModels) {
1427
 
1428
                PartnerWarehouseStockAgingSummaryModel partnerWarehouseStockAgingSummaryModel = new PartnerWarehouseStockAgingSummaryModel();
1429
                partnerWarehouseStockAgingSummaryModel.setCatalogId(stockSummary.getCatalogId());
1430
                partnerWarehouseStockAgingSummaryModel.setBrand(stockSummary.getBrand());
1431
                partnerWarehouseStockAgingSummaryModel.setModelNumber(stockSummary.getModelNumber());
1432
                partnerWarehouseStockAgingSummaryModel.setNetAvailability(stockSummary.getShaholicNetAvailability());
1433
                partnerWarehouseStockAgingSummaryModel.setPartnerStockAvailability(stockSummary.getPartnerFullFilledQty());
1434
                partnerWarehouseStockAgingSummaryModel.setPartnerCurrentAvailability(stockSummary.getPartnerCurrentQty());
1435
                partnerWarehouseStockAgingSummaryModel.setPartnerShortageStock(stockSummary.getPartnerShortageQty());
1436
                if (catalogAgingModelMap.get(stockSummary.getCatalogId()) != null) {
1437
                    partnerWarehouseStockAgingSummaryModel.setExceedDays(catalogAgingModelMap.get(stockSummary.getCatalogId()).getExceedDays());
1438
                } else {
1439
                    partnerWarehouseStockAgingSummaryModel.setExceedDays(0);
1440
 
1441
                }
1442
                partnerWarehouseStockAgingSummaryModel.setStatus(stockSummary.getStatus());
1443
 
1444
                partnerWarehouseStockAgingSummaryModelList.add(partnerWarehouseStockAgingSummaryModel);
1445
            }
1446
 
1447
            Set<Integer> existingCatalogIdsInAgingSummaryList = partnerWarehouseStockAgingSummaryModelList.stream()
1448
                    .map(PartnerWarehouseStockAgingSummaryModel::getCatalogId)
1449
                    .collect(Collectors.toSet());
1450
        }
1451
 
1452
    }
1453
 
1454
 
34306 ranu 1455
}