Subversion Repositories SmartDukaan

Rev

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

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