Subversion Repositories SmartDukaan

Rev

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