Subversion Repositories SmartDukaan

Rev

Rev 34849 | Rev 34897 | 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();
34880 ranu 166
        this.rbmTargetService.getRemainingDaysInMonth(LocalDate.now().atStartOfDay().toLocalDate());
167
        this.rbmTargetService.getRemainingDaysInMonth(YearMonth.now().atDay(1));
34366 ranu 168
        System.out.println("test end");
34306 ranu 169
 
170
    }
171
 
34648 ranu 172
    public void generateBiReport() throws Exception {
34846 ranu 173
        System.out.println("bi report started");
34648 ranu 174
        this.generateBiReportExcel();
34846 ranu 175
        System.out.println("bi report ended {-----}");
34648 ranu 176
    }
177
 
34308 ranu 178
    public void createLoanForBillingByTransactionIdAndInvoiceNumber(int transactionId, double invoiceAmount, String invoiceNumber) throws Exception {
179
        sdCreditService.createLoanForBilling(transactionId, invoiceAmount, invoiceNumber);
34306 ranu 180
 
34308 ranu 181
    }
34306 ranu 182
 
34619 ranu 183
    public void loanSettle() throws Exception {
184
        List<Integer> refrences = Arrays.asList(25807,36003,38938,39506,42219,45084);
185
        for(Integer ref : refrences){
186
            List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(ref);
187
            double amountSum = loanStatements.stream().map(LoanStatement::getAmount).mapToDouble(BigDecimal::doubleValue).sum();
188
            if(amountSum > 0){
189
                walletService.addAmountToWallet(loanStatements.get(0).getFofoId(),ref, WalletReferenceType.CREDIT_LIMIT,"Amount reversal against credit limit deduction",(float) amountSum,LocalDateTime.now());
34308 ranu 190
 
34619 ranu 191
//                Loan statement entry
192
                    BigDecimal adjustAmount = BigDecimal.valueOf(amountSum).negate(); // or multiply by -1
193
                    LoanStatement loanStatement = new LoanStatement();
194
                    loanStatement.setAmount(adjustAmount);
195
                    loanStatement.setFofoId(loanStatements.get(0).getFofoId());
196
                    loanStatement.setLoanReferenceType(LoanReferenceType.PRINCIPAL);
197
                    loanStatement.setCreatedAt(LocalDateTime.now());
198
                    loanStatement.setDescription("Amount reversal due to access debit against limit");
199
                    loanStatement.setLoanId(ref);
200
                    loanStatement.setBusinessDate(LocalDateTime.now());
201
                    loanStatementRepository.persist(loanStatement);
202
 
203
                    Loan loan = loanRepository.selectByLoanId(ref);
204
                    loan.setPendingAmount(BigDecimal.valueOf(0));
205
                    loan.setSettledOn(LocalDateTime.now());
206
                }
207
 
208
 
209
        }
210
    }
211
 
212
 
213
 
34321 ranu 214
    private void sendMailHtmlFormat(String email[], String body, String cc[], String bcc[], String subject)
215
            throws MessagingException, ProfitMandiBusinessException, IOException {
216
        MimeMessage message = mailSender.createMimeMessage();
217
        MimeMessageHelper helper = new MimeMessageHelper(message);
218
        helper.setSubject(subject);
219
        helper.setText(body, true);
220
        helper.setTo(email);
221
        if (cc != null) {
222
            helper.setCc(cc);
223
        }
224
        if (bcc != null) {
225
            helper.setBcc(bcc);
34308 ranu 226
 
34321 ranu 227
        }
228
 
229
        InternetAddress senderAddress = new InternetAddress("noreply@smartdukaan.com", "Smart Dukaan");
230
        helper.setFrom(senderAddress);
231
        mailSender.send(message);
232
    }
233
 
34307 ranu 234
    public Map<Integer,Integer> findLoanTransactionMapingAccordingLoan(List<Integer> loanIds) throws ProfitMandiBusinessException {
34306 ranu 235
 
236
        Map<Integer, Integer> transactionLoanMap = new HashMap<>();
237
 
238
        for(int loanId : loanIds){
239
            Transaction transaction = null;
240
            Loan loan = loanRepository.selectByLoanId(loanId);
241
            List<Transaction> transactions = transactionRepository.selectByRetailerId(loan.getFofoId());
242
 
243
            LocalDateTime nearestDateTime = transactions.stream().map(x -> x.getCreateTimestamp())
244
                    .min(Comparator.comparingLong(x -> Math.abs(ChronoUnit.MILLIS.between(x, loan.getCreatedOn()))))
245
                    .orElse(null);
246
 
247
            if (nearestDateTime != null && loan.getCreatedOn().plusMinutes(2).isAfter(nearestDateTime) &&
248
                    loan.getCreatedOn().minusMinutes(1).isBefore(nearestDateTime)) {
249
                // Here transaction is still null
250
                transaction = transactions.stream()
251
                        .filter(x -> x.getCreateTimestamp().equals(nearestDateTime))
252
                        .findFirst().get();
253
                transactionLoanMap.put(transaction.getId(), loanId);
254
            }
255
 
256
        }
257
        LOGGER.info("transactionLoanMap {}",transactionLoanMap);
258
        return transactionLoanMap;
259
    }
34321 ranu 260
 
261
 
262
 
263
    public void sendRbmFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
264
        LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
265
        LocalDateTime endOfMonth = LocalDateTime.now();
34323 ranu 266
        String[] bcc = {"tarun.verma@smartdukaan.com"};
34321 ranu 267
 
268
        // Get all RBM users
269
        List<AuthUser> authUsers = csService.getAuthUserIds(
270
                ProfitMandiConstants.TICKET_CATEGORY_RBM,
271
                Arrays.asList(EscalationType.L1)
272
        );
273
 
274
        if (authUsers.isEmpty()) {
275
            LOGGER.info("No RBMs found.");
276
            return;
277
        }
278
 
279
        List<Integer> rbmIds = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
280
 
281
        // Fetch ratings for all RBMs for current month
282
        List<RbmRating> feedbackList = rbmRatingRepository.selectByRbmIdsAndDateRange(rbmIds, startOfMonth, endOfMonth);
283
 
284
        if (feedbackList.isEmpty()) {
285
            LOGGER.info("No feedback entries found for RBMs.");
286
            return;
287
        }
288
 
289
        // Sort feedback by createTimeStamp DESC
290
        feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
291
 
292
        // Fetch and map FOFO (partner) names
293
        Map<Integer, String> fofoNameMap = new HashMap<>();
294
        for (RbmRating rating : feedbackList) {
295
            int fofoId = rating.getFofoId();
296
            if (!fofoNameMap.containsKey(fofoId)) {
297
                User fofoUser = userRepository.selectById(fofoId);
298
                FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
299
 
300
                String partnerName = fofoUser != null ? fofoUser.getName() : "Unknown Partner";
301
                String storeCode = fofoStore != null ? fofoStore.getCode() : "Unknown Code";
302
 
303
                String displayName = partnerName + " (" + storeCode + ")";
304
                fofoNameMap.put(fofoId, displayName);
305
            }
306
        }
307
 
308
        // Map RBM ID to name for quick lookup
309
        Map<Integer, String> rbmNameMap = authUsers.stream()
310
                .collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
311
 
312
        // Generate HTML content
313
        StringBuilder emailContent = new StringBuilder();
314
        emailContent.append("<html><body>");
315
        emailContent.append("<p>Dear Team,</p>");
316
        emailContent.append("<p>Here is the <b>latest RBM Rating and Feedback Summary</b> for ")
317
                .append(LocalDate.now().getMonth()).append(":</p>");
318
 
319
        emailContent.append("<table border='1' cellspacing='0' cellpadding='5'>");
320
        emailContent.append("<tr>")
321
                .append("<th>RBM Name</th>")
322
                .append("<th>Partner Name</th>")
323
                .append("<th>Rating</th>")
324
                .append("<th>Comment</th>")
325
                .append("<th>Date</th>")
326
                .append("</tr>");
327
 
328
        for (RbmRating rating : feedbackList) {
329
            String rbmName = rbmNameMap.getOrDefault(rating.getRbmId(), "Unknown RBM");
330
            String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
331
            emailContent.append("<tr>")
332
                    .append("<td>").append(rbmName).append("</td>")
333
                    .append("<td>").append(partnerName).append("</td>")
334
                    .append("<td>").append(rating.getRating()).append("</td>")
335
                    .append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
336
                    .append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
337
                    .append("</tr>");
338
        }
339
 
340
        emailContent.append("</table>");
341
        emailContent.append("<br><p>Regards,<br>Smart Dukaan Team</p>");
342
        emailContent.append("</body></html>");
343
 
344
        String subject = "Monthly RBM Feedback Summary - " + LocalDate.now().getMonth();
345
 
346
        List<String> sendTo = new ArrayList<>();
34323 ranu 347
        sendTo.add("sm@smartdukaan.com"); //
348
        sendTo.add("chiranjib.sarkar@smartdukaan.com"); //
349
        sendTo.add("kamini.sharma@smartdukaan.com"); //
34321 ranu 350
 
351
        String[] emailRecipients = sendTo.toArray(new String[0]);
352
 
353
 
354
        this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
355
 
356
        LOGGER.info("Consolidated RBM feedback summary email sent.");
357
    }
358
 
359
 
360
    public void sendSalesFeedbackSummaryEmail() throws MessagingException, ProfitMandiBusinessException, IOException {
361
        LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
362
        LocalDateTime endOfMonth = LocalDateTime.now();
34323 ranu 363
        String[] bcc = {"tarun.verma@smartdukaan.com"};
34411 tejus.loha 364
//        String[] bcc = {"tejus.lohani@smartdukaan.com"};
34321 ranu 365
 
366
        // Get all RBM users
367
        List<AuthUser> authUsers = csService.getAuthUserIds(
368
                ProfitMandiConstants.TICKET_CATEGORY_SALES,
369
                Arrays.asList(EscalationType.L1)
370
        );
371
 
372
        if (authUsers.isEmpty()) {
373
            LOGGER.info("No sales person found.");
374
            return;
375
        }
376
 
377
        List<Integer> salesL1Ids = authUsers.stream().map(AuthUser::getId).collect(Collectors.toList());
378
 
379
        // Fetch ratings for all RBMs for current month
380
        List<SalesRating> feedbackList = salesRatingRepository.selectBySalesL1IdsAndDateRange(salesL1Ids, startOfMonth, endOfMonth);
381
 
382
        if (feedbackList.isEmpty()) {
383
            LOGGER.info("No feedback entries found for Sales.");
384
            return;
385
        }
386
 
387
        // Sort feedback by createTimeStamp DESC
388
        feedbackList.sort((a, b) -> b.getCreateTimeStamp().compareTo(a.getCreateTimeStamp()));
389
 
390
        // Fetch and map FOFO (partner) names
391
        Map<Integer, String> fofoNameMap = new HashMap<>();
392
        for (SalesRating rating : feedbackList) {
393
            int fofoId = rating.getFofoId();
394
            if (!fofoNameMap.containsKey(fofoId)) {
395
                User fofoUser = userRepository.selectById(fofoId);
396
                FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
397
 
398
                String partnerName = fofoUser != null ? fofoUser.getName() : "Unknown Partner";
399
                String storeCode = fofoStore != null ? fofoStore.getCode() : "Unknown Code";
400
 
401
                String displayName = partnerName + " (" + storeCode + ")";
402
                fofoNameMap.put(fofoId, displayName);
403
            }
404
        }
405
 
406
        // Map RBM ID to name for quick lookup
407
        Map<Integer, String> salesL1NameMap = authUsers.stream()
408
                .collect(Collectors.toMap(AuthUser::getId, AuthUser::getFullName));
409
 
410
        // Generate HTML content
411
        StringBuilder emailContent = new StringBuilder();
412
        emailContent.append("<html><body>");
413
        emailContent.append("<p>Dear Team,</p>");
414
        emailContent.append("<p>Here is the <b>latest Sales L1 Rating and Feedback Summary</b> for ")
415
                .append(LocalDate.now().getMonth()).append(":</p>");
416
 
417
        emailContent.append("<table border='1' cellspacing='0' cellpadding='5'>");
418
        emailContent.append("<tr>")
419
                .append("<th>Sales L1 Name</th>")
420
                .append("<th>Partner Name</th>")
34411 tejus.loha 421
                .append("<th>Partner Category</th>")
34321 ranu 422
                .append("<th>Rating</th>")
423
                .append("<th>Comment</th>")
424
                .append("<th>Date</th>")
425
                .append("</tr>");
426
 
427
        for (SalesRating rating : feedbackList) {
428
            String salesL1 = salesL1NameMap.getOrDefault(rating.getSalesL1Id(), "Unknown Sales Person");
429
            String partnerName = fofoNameMap.getOrDefault(rating.getFofoId(), "Unknown Partner");
34844 ranu 430
            LOGGER.info("partnerName11- {}",partnerName);
34411 tejus.loha 431
            PartnerType partnerType = partnerTypeChangeService.getTypeOnDate(rating.getFofoId(), LocalDate.now());
34321 ranu 432
            emailContent.append("<tr>")
433
                    .append("<td>").append(salesL1).append("</td>")
434
                    .append("<td>").append(partnerName).append("</td>")
34411 tejus.loha 435
                    .append("<td>").append(partnerType).append("</td>")
34321 ranu 436
                    .append("<td>").append(rating.getRating()).append("</td>")
437
                    .append("<td>").append(rating.getComment() != null ? rating.getComment() : "-").append("</td>")
438
                    .append("<td>").append(rating.getCreateTimeStamp().toLocalDate()).append("</td>")
439
                    .append("</tr>");
440
        }
441
 
442
        emailContent.append("</table>");
443
        emailContent.append("<br><p>Regards,<br>Smartdukaan Team</p>");
444
        emailContent.append("</body></html>");
445
 
34411 tejus.loha 446
        String subject = "Monthly Sales L1 Feedback Summary Test test - " + LocalDate.now().getMonth();
34321 ranu 447
 
448
        List<String> sendTo = new ArrayList<>();
34323 ranu 449
         sendTo.add("sm@smartdukaan.com"); //
450
         sendTo.add("chiranjib.sarkar@smartdukaan.com"); //
34606 ranu 451
         sendTo.add("kamini.sharma@smartdukaan.com"); //
34321 ranu 452
 
453
        String[] emailRecipients = sendTo.toArray(new String[0]);
454
 
455
 
456
        this.sendMailHtmlFormat(emailRecipients, emailContent.toString(), null, bcc, subject);
457
 
458
        LOGGER.info("Consolidated Sales L1 feedback summary email sent.");
459
    }
460
 
461
 
34606 ranu 462
    public void generateBiReportExcel() throws Exception {
34619 ranu 463
 
34741 ranu 464
        LocalDateTime startOfToday;
465
        LocalDateTime previousDay;
34321 ranu 466
 
34741 ranu 467
        if (LocalDate.now().getDayOfMonth() == 1) {
468
            // If today is 1st, go to yesterday (i.e., last day of previous month)
469
            startOfToday = LocalDate.now().minusDays(1).atStartOfDay();
470
            previousDay = startOfToday.with(LocalTime.MAX);
471
 
472
        } else {
473
            // Otherwise, use today
474
            startOfToday = LocalDate.now().atStartOfDay();
475
            previousDay = startOfToday.with(LocalTime.MAX).minusDays(1);
476
        }
477
 
34784 ranu 478
        Map<Integer, CustomRetailer> customRetailers = retailerService.getAllFofoRetailersInternalFalse();
34321 ranu 479
 
34784 ranu 480
        List<Integer> retailerIds = customRetailers.values().stream().map(CustomRetailer::getPartnerId).collect(Collectors.toList());
34606 ranu 481
 
34844 ranu 482
/*        List<Integer> retailerIds = Arrays.asList(175139247,175139660);
34784 ranu 483
        Map<Integer,CustomRetailer> customRetailers = retailerService.getFofoRetailers(retailerIds);*/
34758 ranu 484
 
34641 ranu 485
        //partner daily investment
34729 amit.gupta 486
        List<Loan> defaultLoans = sdCreditService.getDefaultLoans();
34641 ranu 487
        Map<Integer,List<Loan>> defaultLoanMap = defaultLoans.stream().collect(Collectors.groupingBy(Loan::getFofoId));
34619 ranu 488
 
34641 ranu 489
        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = new HashMap<>();
490
        List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository
34741 ranu 491
                .selectAll(new ArrayList<>(retailerIds), previousDay.toLocalDate());
34641 ranu 492
        if (!partnerDailyInvestments.isEmpty()) {
493
            partnerDailyInvestmentMap = partnerDailyInvestments.stream()
494
                    .collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
495
        }
496
 
34741 ranu 497
 
498
 
34648 ranu 499
    //  this month return data
34741 ranu 500
 
501
        YearMonth currentMonth;
502
        LocalDateTime currentMonthStartDate;
503
        LocalDateTime currentMonthEndDate;
504
 
505
        if (LocalDate.now().getDayOfMonth() == 1) {
506
            // If today is the 1st, use previous month
507
            currentMonth = YearMonth.now().minusMonths(1);
508
            currentMonthStartDate = currentMonth.atDay(1).atStartOfDay();
509
            currentMonthEndDate = currentMonth.atEndOfMonth().atTime(23, 59, 59);
510
        } else {
511
            // Otherwise, use this month up to yesterday
512
            currentMonth = YearMonth.now();
513
            currentMonthStartDate = currentMonth.atDay(1).atStartOfDay();
514
            currentMonthEndDate = LocalDate.now().minusDays(1).atTime(23, 59, 59);
515
        }
516
 
34619 ranu 517
        String currentMonthStringValue = String.valueOf(currentMonth);
34606 ranu 518
 
519
        List<ReturnOrderInfoModel> currentMonthReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(currentMonthStartDate, currentMonthEndDate);
520
        Map<Integer, Long> currentMonthPartnerReturnOrderInfoModelMap = currentMonthReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
521
 
34782 ranu 522
        List<Order> currentMonthRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(currentMonthStartDate, currentMonthEndDate);
34606 ranu 523
        Map<Integer, Long> currentMonthRtoRefundOrderMap = currentMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
524
 
34749 ranu 525
 
526
        List<ReturnOrderInfoModel> yesterdayReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(previousDay.toLocalDate().atStartOfDay(), previousDay);
527
        Map<Integer, Long> yesterdayReturnOrderInfoModelMap = yesterdayReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
528
 
34782 ranu 529
        List<Order> yesterdayRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(previousDay.toLocalDate().atStartOfDay(), previousDay);
34749 ranu 530
        Map<Integer, Long> yesterdayRtoRefundOrderMap = yesterdayRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
531
 
532
        List<ReturnOrderInfoModel> dayBeforeYesterdayReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(previousDay.toLocalDate().atStartOfDay().minusDays(1), previousDay.minusDays(1));
533
        Map<Integer, Long> dayBeforeYesterdayReturnOrderInfoModelMap = dayBeforeYesterdayReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
534
 
34782 ranu 535
        List<Order> dayBeforeYesterdayRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(previousDay.toLocalDate().atStartOfDay().minusDays(1), previousDay.minusDays(1));
34749 ranu 536
        Map<Integer, Long> dayBeforeYesterdayRtoRefundOrderMap = dayBeforeYesterdayRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
537
 
538
 
539
 
540
        //  last month return data
34741 ranu 541
        YearMonth lastMonth = currentMonth.minusMonths(1);
34619 ranu 542
        String lastMonthStringValue = String.valueOf(lastMonth);
34606 ranu 543
        LocalDateTime lastMontStartDate = lastMonth.atDay(1).atStartOfDay();
544
        LocalDateTime lastMonthEndDate = lastMonth.atEndOfMonth().atTime(23, 59, 59);
545
 
546
        List<ReturnOrderInfoModel> lastMonthReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(lastMontStartDate, lastMonthEndDate);
547
        Map<Integer, Long> lastMonthPartnerReturnOrderInfoModelMap = lastMonthReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
548
 
34782 ranu 549
        List<Order> lastMonthRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(lastMontStartDate, lastMonthEndDate);
34606 ranu 550
        Map<Integer, Long> lastMonthRtoRefundOrderMap = lastMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
551
 
552
 
34741 ranu 553
    //  twoMonthsAgo return data
554
        YearMonth twoMonthsAgo = currentMonth.minusMonths(2);
34619 ranu 555
        String twoMonthAgoStringValue = String.valueOf(twoMonthsAgo);
34606 ranu 556
        LocalDateTime twoMonthsAgoStartDate = twoMonthsAgo.atDay(1).atStartOfDay();
557
        LocalDateTime twoMonthsAgoEndDate = twoMonthsAgo.atEndOfMonth().atTime(23, 59, 59);
558
 
559
        List<ReturnOrderInfoModel> twoMonthAgoReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(twoMonthsAgoStartDate, twoMonthsAgoEndDate);
560
        Map<Integer, Long> twoMonthAgoPartnerReturnOrderInfoModelMap = twoMonthAgoReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
34749 ranu 561
 
34782 ranu 562
        List<Order> twoMonthRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(twoMonthsAgoStartDate, twoMonthsAgoEndDate);
34619 ranu 563
        Map<Integer, Long> twoMonthAgoRtoRefundOrderMap = twoMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
34606 ranu 564
 
34749 ranu 565
 
34648 ranu 566
        Map<Integer , String> assessmentMap = new HashMap<>();
567
        Map<Integer , String> zeroBillingMap = new HashMap<>();
568
        Map<Integer , Float> billingNeededMap = new HashMap<>();
569
        Map<Integer , Integer> countAMap = new HashMap<>();
34606 ranu 570
 
34619 ranu 571
        Map<Integer , BIRetailerModel> biRetailerModelMap = new HashMap<>();
34606 ranu 572
 
34641 ranu 573
        Map<Integer , FofoInvestmentModel> biInvestmentModelMap = new HashMap<>();
574
 
34619 ranu 575
        Map<Integer, Map<YearMonth, BiSecondaryModel>> allRetailerMonthlyData = new HashMap<>();
34606 ranu 576
 
34619 ranu 577
        Map<Integer,Double> fofoTotalStockPriceMap = new HashMap<>();
578
 
579
        Map<Integer,Map<String, BrandStockPrice>> fofoBrandStockPriceMap = new HashMap<>();
580
 
34641 ranu 581
        Map<Integer,Long> fofoTotalMtdSecondaryMap = new HashMap<>();
34619 ranu 582
 
34749 ranu 583
        Map<Integer,Long> fofoYesterdaySecondaryMap = new HashMap<>();
34619 ranu 584
 
34749 ranu 585
        Map<Integer,Long> fofoDayBeforeYesterdaySecondaryMap = new HashMap<>();
586
 
34641 ranu 587
        Map<Integer,Map<String, Long>> fofoBrandWiseMtdSecondaryMap = new HashMap<>();
34619 ranu 588
 
34641 ranu 589
        Map<Integer,Double> fofoTotalMtdTertiaryMap = new HashMap<>();
590
 
591
        Map<Integer,Map<String, Double>> fofoBrandMtdTertiaryMap = new HashMap<>();
592
 
34606 ranu 593
        for(Integer fofoId: retailerIds){
34619 ranu 594
            String rbmName = "";
34606 ranu 595
            int rbmL1 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM,EscalationType.L1,fofoId);
34619 ranu 596
            if(rbmL1 != 0){
597
                 rbmName = authRepository.selectById(rbmL1).getFullName();
34677 ranu 598
            }else {
599
                int rbmL2 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM, EscalationType.L2, fofoId);
600
                if(rbmL2 != 0){
601
                    rbmName = authRepository.selectById(rbmL2).getFullName();
602
                }
34619 ranu 603
            }
604
            String bmName ="";
34606 ranu 605
            int bmId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L2,fofoId);
34619 ranu 606
            if(bmId !=0){
607
                bmName = authRepository.selectById(bmId).getFullName();
608
            }
34606 ranu 609
 
610
            int managerId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L1,fofoId);
611
            String managerName = " ";
612
            if(managerId != 0){
613
                 managerName = authRepository.selectById(managerId).getFullName();
614
            }else {
615
                managerName = bmName;
616
            }
617
 
618
            AST ast = astRepository.selectById(customRetailers.get(fofoId).getAstId());
619
 
34741 ranu 620
            PartnerType partnerTypeThisMonth = partnerTypeChangeService.getTypeOnMonth(fofoId, currentMonth);
34606 ranu 621
 
622
//            generate retaile detail
623
 
624
            BIRetailerModel biRetailerModel = new BIRetailerModel();
625
            biRetailerModel.setBmName(bmName);
626
            biRetailerModel.setCode(customRetailers.get(fofoId).getCode());
34619 ranu 627
            if(ast != null){
628
                biRetailerModel.setArea(ast.getArea());
629
            }else {
630
                biRetailerModel.setArea("-");
631
            }
34738 ranu 632
            String retailerStatus = "";
633
            FofoStore fofoStore1 = fofoStoreRepository.selectByRetailerId(fofoId);
634
            if(!fofoStore1.isActive()){
635
                retailerStatus = "INACTIVE";
636
            }else{
637
                retailerStatus =  String.valueOf(fofoStore1.getActivationType());
638
            }
34606 ranu 639
            biRetailerModel.setCity(customRetailers.get(fofoId).getAddress().getCity());
640
            biRetailerModel.setStoreName(customRetailers.get(fofoId).getBusinessName());
34738 ranu 641
            biRetailerModel.setStatus(retailerStatus);
34606 ranu 642
            biRetailerModel.setCategory(String.valueOf(partnerTypeThisMonth));
643
            biRetailerModel.setSalesManager(managerName);
644
            biRetailerModel.setRbm(rbmName);
645
 
34619 ranu 646
            biRetailerModelMap.put(fofoId,biRetailerModel);
647
 
34641 ranu 648
 
34606 ranu 649
//            generate secondary data
650
 
34641 ranu 651
            List<PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledMonthlyTotals = activatedImeiRepository.getTotalMonthlyActivatedNotBilled(fofoId,twoMonthsAgoStartDate);
652
            Map<YearMonth , PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledTotalMap = partnerWiseActivatedNotBilledMonthlyTotals.stream().collect(Collectors.toMap(x-> YearMonth.parse(x.getYearMonth()),x->x));
653
 
34606 ranu 654
//            this month secondary target
655
 
34741 ranu 656
            double currentSecondaryTarget =  monthlyTargetRepository.selectByDateAndFofoId(currentMonth, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(currentMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 657
 
34619 ranu 658
 
659
            long currentMonthReturn = currentMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId, 0L) + currentMonthRtoRefundOrderMap.getOrDefault(fofoId, 0L);
660
 
661
 
34715 ranu 662
            Map<Integer, Double> secondaryMtd = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34741 ranu 663
                    startOfToday.withDayOfMonth(1), previousDay).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
34606 ranu 664
 
34749 ranu 665
 
666
            //yesterday secondary
667
            Map<Integer, Double> dayBeforeYesterdaySecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
668
                    previousDay.toLocalDate().atStartOfDay().minusDays(1), previousDay.minusDays(1)).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
669
            double dayBeforeYesterdayAfterReturnSecondary = dayBeforeYesterdaySecondary.getOrDefault(fofoId,0d) - (dayBeforeYesterdayReturnOrderInfoModelMap.getOrDefault(fofoId,0l) + dayBeforeYesterdayRtoRefundOrderMap.getOrDefault(fofoId,0l));
670
            fofoDayBeforeYesterdaySecondaryMap.put(fofoId, (long) dayBeforeYesterdayAfterReturnSecondary);
671
 
672
 
673
            //day before secondary
674
            Map<Integer, Double> yesterDaySecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
675
                    previousDay.toLocalDate().atStartOfDay(), previousDay).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
676
            double yesterDayAfterReturnSecondary = yesterDaySecondary.getOrDefault(fofoId,0d) - (yesterdayReturnOrderInfoModelMap.getOrDefault(fofoId,0l) + yesterdayRtoRefundOrderMap.getOrDefault(fofoId,0l));
677
            fofoYesterdaySecondaryMap.put(fofoId, (long) yesterDayAfterReturnSecondary);
678
 
34606 ranu 679
            double secondaryAchievedMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
680
 
34619 ranu 681
            double currentMonthNetSecondary = secondaryAchievedMtd - currentMonthReturn;
34606 ranu 682
 
34701 ranu 683
            double currentMonthSecondaryPercent = currentSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((secondaryAchievedMtd / currentSecondaryTarget) * 100));
34619 ranu 684
 
34641 ranu 685
            double currentMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(currentMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(currentMonth).getTotalUnbilledAmount() : 0d;
34619 ranu 686
 
687
//          this month tertiary----------
688
 
689
            LocalDateTime now = LocalDateTime.now();
690
            double todaySale = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday, now, fofoId, false).get(fofoId);
34741 ranu 691
            double mtdSaleTillYesterDay = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday.withDayOfMonth(1), previousDay, fofoId, false).get(fofoId);
34724 ranu 692
            double mtdSale = mtdSaleTillYesterDay;
34619 ranu 693
 
694
 
34606 ranu 695
//            last month secondary target
696
 
34619 ranu 697
            double lastMonthSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId) != null ?  monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 698
 
34619 ranu 699
            long lastMonthReturn = (lastMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + lastMonthRtoRefundOrderMap.getOrDefault(fofoId,0L));
700
 
34715 ranu 701
            Map<Integer, Double> lastMonthSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 702
                    lastMontStartDate, lastMonthEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
703
 
704
            double lastMonthSecondaryAchieved = lastMonthSecondary.getOrDefault(fofoId, 0.0);
705
 
34619 ranu 706
            double lastMonthNetSecondary = lastMonthSecondaryAchieved - lastMonthReturn;
34606 ranu 707
 
34701 ranu 708
            double lastMonthSecondaryPercent = lastMonthSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((lastMonthSecondaryAchieved / lastMonthSecondaryTarget) * 100));
34606 ranu 709
 
34641 ranu 710
            double lastMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(lastMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(lastMonth).getTotalUnbilledAmount() : 0d;
34606 ranu 711
 
34619 ranu 712
//           last month tertiary
713
            Double lastMonthSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
714
                    lastMontStartDate, lastMonthEndDate, fofoId, false).get(fofoId);
715
 
716
 
717
//            two month ago secondary target
718
 
34703 ranu 719
            double twoMonthAgoSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId).getPurchaseTarget() : 0;
34619 ranu 720
 
721
            long twoMonthAgoReturn = (twoMonthAgoPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + twoMonthAgoRtoRefundOrderMap.getOrDefault(fofoId,0L));
722
 
34715 ranu 723
            Map<Integer, Double> twoMonthAgoSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 724
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
725
 
726
            double twoMonthAgoSecondaryAchieved = twoMonthAgoSecondary.getOrDefault(fofoId, 0.0);
727
 
34619 ranu 728
            double twoMonthAgoNetSecondary = twoMonthAgoSecondaryAchieved - twoMonthAgoReturn;
34606 ranu 729
 
34701 ranu 730
            double twoMonthAgoSecondaryPercent = twoMonthAgoSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((twoMonthAgoSecondaryAchieved / twoMonthAgoSecondaryTarget) * 100));
34619 ranu 731
 
34641 ranu 732
            double twoMonthAgoUnbilled = partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo) != null ? partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo).getTotalUnbilledAmount() : 0d;
34619 ranu 733
 
734
//          second Month Tertiary
735
            double twoMonthAgoSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
736
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate, fofoId, false).get(fofoId);
737
 
738
 
739
            Map<YearMonth, BiSecondaryModel> monthlySecondaryModels = new HashMap<>();
740
 
741
            BiSecondaryModel currentMonthSecondaryModel = new BiSecondaryModel(
742
                    currentSecondaryTarget,
743
                    secondaryAchievedMtd,
744
                    currentMonthReturn,
745
                    currentMonthNetSecondary,
746
                    currentMonthSecondaryPercent,
747
                    mtdSale,
748
                    currentMonthUnbilled // for now, unbilled tertiary value
749
            );
750
 
751
            BiSecondaryModel lastMonthSecondaryModel = new BiSecondaryModel(
752
                    lastMonthSecondaryTarget,
753
                    lastMonthSecondaryAchieved,
754
                    lastMonthReturn,
755
                    lastMonthNetSecondary,
756
                    lastMonthSecondaryPercent,
757
                    lastMonthSale,
758
                    lastMonthUnbilled // for now, unbilled tertiary value
759
            );
760
 
761
            BiSecondaryModel twoMonthAgoSecondaryModel = new BiSecondaryModel(
762
                    twoMonthAgoSecondaryTarget,
763
                    twoMonthAgoSecondaryAchieved,
764
                    twoMonthAgoReturn,
765
                    twoMonthAgoNetSecondary,
766
                    twoMonthAgoSecondaryPercent,
767
                    twoMonthAgoSale,
768
                    twoMonthAgoUnbilled // for now, unbilled tertiary value
769
            );
770
 
771
            monthlySecondaryModels.put(currentMonth, currentMonthSecondaryModel);
772
            monthlySecondaryModels.put(lastMonth, lastMonthSecondaryModel);
773
            monthlySecondaryModels.put(twoMonthsAgo, twoMonthAgoSecondaryModel);
774
 
775
            allRetailerMonthlyData.put(fofoId, monthlySecondaryModels);
776
 
777
//            brandwiseStock value price
778
 
779
            Map<String, BrandStockPrice> brandStockPriceMap = inventoryService.getBrandWiseStockValue(fofoId);
780
 
781
            fofoBrandStockPriceMap.put(fofoId,brandStockPriceMap);
782
 
783
            double totalStockPrice = brandStockPriceMap.values().stream().mapToDouble(x->x.getTotalValue()).sum();
784
 
785
            fofoTotalStockPriceMap.put(fofoId,totalStockPrice);
786
 
787
            Map<String, Double> brandMtdTertiaryAmount = fofoOrderItemRepository.selectSumAmountGroupByBrand(
34722 ranu 788
                    currentMonthStartDate, currentMonthEndDate, fofoId);
34619 ranu 789
 
34719 ranu 790
 
34641 ranu 791
            fofoBrandMtdTertiaryMap.put(fofoId,brandMtdTertiaryAmount);
34619 ranu 792
 
793
            double totalMtdTertiaryAmount = brandMtdTertiaryAmount.values().stream().mapToDouble(Double::doubleValue).sum();
794
 
34641 ranu 795
            fofoTotalMtdTertiaryMap.put(fofoId,totalMtdTertiaryAmount);
34619 ranu 796
 
34849 ranu 797
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledByCategoryOrderGroupByBrandFofoId(fofoId, currentMonthStartDate,currentMonthEndDate, Arrays.asList(10006,10001));
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
}