Subversion Repositories SmartDukaan

Rev

Rev 34916 | Rev 34919 | 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
 
34912 ranu 480
        Map<Integer, CustomRetailer> customRetailers = retailerService.getAllFofoRetailersInternalFalse();
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)
488
                .collect(Collectors.toList());
34606 ranu 489
 
34903 ranu 490
//        List<Integer> retailerIds = customRetailers.values().stream().map(CustomRetailer::getPartnerId).collect(Collectors.toList());
491
 
34844 ranu 492
/*        List<Integer> retailerIds = Arrays.asList(175139247,175139660);
34784 ranu 493
        Map<Integer,CustomRetailer> customRetailers = retailerService.getFofoRetailers(retailerIds);*/
34758 ranu 494
 
34641 ranu 495
        //partner daily investment
34729 amit.gupta 496
        List<Loan> defaultLoans = sdCreditService.getDefaultLoans();
34641 ranu 497
        Map<Integer,List<Loan>> defaultLoanMap = defaultLoans.stream().collect(Collectors.groupingBy(Loan::getFofoId));
34619 ranu 498
 
34641 ranu 499
        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = new HashMap<>();
500
        List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository
34741 ranu 501
                .selectAll(new ArrayList<>(retailerIds), previousDay.toLocalDate());
34641 ranu 502
        if (!partnerDailyInvestments.isEmpty()) {
503
            partnerDailyInvestmentMap = partnerDailyInvestments.stream()
504
                    .collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
505
        }
506
 
34741 ranu 507
 
508
 
34648 ranu 509
    //  this month return data
34741 ranu 510
 
511
        YearMonth currentMonth;
512
        LocalDateTime currentMonthStartDate;
513
        LocalDateTime currentMonthEndDate;
514
 
515
        if (LocalDate.now().getDayOfMonth() == 1) {
516
            // If today is the 1st, use previous month
517
            currentMonth = YearMonth.now().minusMonths(1);
518
            currentMonthStartDate = currentMonth.atDay(1).atStartOfDay();
519
            currentMonthEndDate = currentMonth.atEndOfMonth().atTime(23, 59, 59);
520
        } else {
521
            // Otherwise, use this month up to yesterday
522
            currentMonth = YearMonth.now();
523
            currentMonthStartDate = currentMonth.atDay(1).atStartOfDay();
524
            currentMonthEndDate = LocalDate.now().minusDays(1).atTime(23, 59, 59);
525
        }
526
 
34619 ranu 527
        String currentMonthStringValue = String.valueOf(currentMonth);
34606 ranu 528
 
529
        List<ReturnOrderInfoModel> currentMonthReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(currentMonthStartDate, currentMonthEndDate);
530
        Map<Integer, Long> currentMonthPartnerReturnOrderInfoModelMap = currentMonthReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
531
 
34782 ranu 532
        List<Order> currentMonthRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(currentMonthStartDate, currentMonthEndDate);
34606 ranu 533
        Map<Integer, Long> currentMonthRtoRefundOrderMap = currentMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
534
 
34749 ranu 535
 
536
        List<ReturnOrderInfoModel> yesterdayReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(previousDay.toLocalDate().atStartOfDay(), previousDay);
537
        Map<Integer, Long> yesterdayReturnOrderInfoModelMap = yesterdayReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
538
 
34782 ranu 539
        List<Order> yesterdayRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(previousDay.toLocalDate().atStartOfDay(), previousDay);
34749 ranu 540
        Map<Integer, Long> yesterdayRtoRefundOrderMap = yesterdayRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
541
 
542
        List<ReturnOrderInfoModel> dayBeforeYesterdayReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(previousDay.toLocalDate().atStartOfDay().minusDays(1), previousDay.minusDays(1));
543
        Map<Integer, Long> dayBeforeYesterdayReturnOrderInfoModelMap = dayBeforeYesterdayReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
544
 
34782 ranu 545
        List<Order> dayBeforeYesterdayRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(previousDay.toLocalDate().atStartOfDay().minusDays(1), previousDay.minusDays(1));
34749 ranu 546
        Map<Integer, Long> dayBeforeYesterdayRtoRefundOrderMap = dayBeforeYesterdayRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
547
 
548
 
549
 
550
        //  last month return data
34741 ranu 551
        YearMonth lastMonth = currentMonth.minusMonths(1);
34619 ranu 552
        String lastMonthStringValue = String.valueOf(lastMonth);
34606 ranu 553
        LocalDateTime lastMontStartDate = lastMonth.atDay(1).atStartOfDay();
554
        LocalDateTime lastMonthEndDate = lastMonth.atEndOfMonth().atTime(23, 59, 59);
555
 
556
        List<ReturnOrderInfoModel> lastMonthReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(lastMontStartDate, lastMonthEndDate);
557
        Map<Integer, Long> lastMonthPartnerReturnOrderInfoModelMap = lastMonthReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
558
 
34782 ranu 559
        List<Order> lastMonthRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(lastMontStartDate, lastMonthEndDate);
34606 ranu 560
        Map<Integer, Long> lastMonthRtoRefundOrderMap = lastMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
561
 
562
 
34741 ranu 563
    //  twoMonthsAgo return data
564
        YearMonth twoMonthsAgo = currentMonth.minusMonths(2);
34619 ranu 565
        String twoMonthAgoStringValue = String.valueOf(twoMonthsAgo);
34606 ranu 566
        LocalDateTime twoMonthsAgoStartDate = twoMonthsAgo.atDay(1).atStartOfDay();
567
        LocalDateTime twoMonthsAgoEndDate = twoMonthsAgo.atEndOfMonth().atTime(23, 59, 59);
568
 
569
        List<ReturnOrderInfoModel> twoMonthAgoReturnOrderInfoModels = returnOrderInfoRepository.selectAllByBetweenDate(twoMonthsAgoStartDate, twoMonthsAgoEndDate);
570
        Map<Integer, Long> twoMonthAgoPartnerReturnOrderInfoModelMap = twoMonthAgoReturnOrderInfoModels.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getRefundAmount()))));
34749 ranu 571
 
34782 ranu 572
        List<Order> twoMonthRtoRefundOrders = orderRepository.selectAllRefundOrderDatesBetween(twoMonthsAgoStartDate, twoMonthsAgoEndDate);
34619 ranu 573
        Map<Integer, Long> twoMonthAgoRtoRefundOrderMap = twoMonthRtoRefundOrders.stream().collect(Collectors.groupingBy(x -> x.getRetailerId(), Collectors.summingLong(x -> Math.round(x.getTotalAmount()))));
34606 ranu 574
 
34749 ranu 575
 
34648 ranu 576
        Map<Integer , String> assessmentMap = new HashMap<>();
577
        Map<Integer , String> zeroBillingMap = new HashMap<>();
578
        Map<Integer , Float> billingNeededMap = new HashMap<>();
579
        Map<Integer , Integer> countAMap = new HashMap<>();
34606 ranu 580
 
34619 ranu 581
        Map<Integer , BIRetailerModel> biRetailerModelMap = new HashMap<>();
34606 ranu 582
 
34641 ranu 583
        Map<Integer , FofoInvestmentModel> biInvestmentModelMap = new HashMap<>();
584
 
34619 ranu 585
        Map<Integer, Map<YearMonth, BiSecondaryModel>> allRetailerMonthlyData = new HashMap<>();
34606 ranu 586
 
34619 ranu 587
        Map<Integer,Double> fofoTotalStockPriceMap = new HashMap<>();
588
 
589
        Map<Integer,Map<String, BrandStockPrice>> fofoBrandStockPriceMap = new HashMap<>();
590
 
34641 ranu 591
        Map<Integer,Long> fofoTotalMtdSecondaryMap = new HashMap<>();
34619 ranu 592
 
34749 ranu 593
        Map<Integer,Long> fofoYesterdaySecondaryMap = new HashMap<>();
34619 ranu 594
 
34749 ranu 595
        Map<Integer,Long> fofoDayBeforeYesterdaySecondaryMap = new HashMap<>();
596
 
34641 ranu 597
        Map<Integer,Map<String, Long>> fofoBrandWiseMtdSecondaryMap = new HashMap<>();
34619 ranu 598
 
34641 ranu 599
        Map<Integer,Double> fofoTotalMtdTertiaryMap = new HashMap<>();
600
 
601
        Map<Integer,Map<String, Double>> fofoBrandMtdTertiaryMap = new HashMap<>();
602
 
34606 ranu 603
        for(Integer fofoId: retailerIds){
34619 ranu 604
            String rbmName = "";
34606 ranu 605
            int rbmL1 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM,EscalationType.L1,fofoId);
34619 ranu 606
            if(rbmL1 != 0){
607
                 rbmName = authRepository.selectById(rbmL1).getFullName();
34677 ranu 608
            }else {
609
                int rbmL2 = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_RBM, EscalationType.L2, fofoId);
610
                if(rbmL2 != 0){
611
                    rbmName = authRepository.selectById(rbmL2).getFullName();
612
                }
34619 ranu 613
            }
614
            String bmName ="";
34606 ranu 615
            int bmId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L2,fofoId);
34619 ranu 616
            if(bmId !=0){
617
                bmName = authRepository.selectById(bmId).getFullName();
618
            }
34606 ranu 619
 
620
            int managerId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L1,fofoId);
621
            String managerName = " ";
622
            if(managerId != 0){
623
                 managerName = authRepository.selectById(managerId).getFullName();
624
            }else {
625
                managerName = bmName;
626
            }
34915 ranu 627
            String abmName ="";
628
            int abmId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_ABM,EscalationType.L1,fofoId);
34918 ranu 629
            int abmL2Id = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_ABM,EscalationType.L2,fofoId);
630
            int abmL3Id = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_ABM,EscalationType.L3,fofoId);
34915 ranu 631
            if(abmId !=0){
632
                abmName = authRepository.selectById(abmId).getFullName();
34918 ranu 633
            }else if(abmL2Id != 0){
34916 ranu 634
                abmName = authRepository.selectById(abmL2Id).getFullName();
34918 ranu 635
            }else {
636
                abmName = authRepository.selectById(abmL3Id).getFullName();
34915 ranu 637
            }
34606 ranu 638
            AST ast = astRepository.selectById(customRetailers.get(fofoId).getAstId());
639
 
34741 ranu 640
            PartnerType partnerTypeThisMonth = partnerTypeChangeService.getTypeOnMonth(fofoId, currentMonth);
34606 ranu 641
 
642
//            generate retaile detail
643
 
644
            BIRetailerModel biRetailerModel = new BIRetailerModel();
645
            biRetailerModel.setBmName(bmName);
646
            biRetailerModel.setCode(customRetailers.get(fofoId).getCode());
34619 ranu 647
            if(ast != null){
648
                biRetailerModel.setArea(ast.getArea());
649
            }else {
650
                biRetailerModel.setArea("-");
651
            }
34738 ranu 652
            String retailerStatus = "";
653
            FofoStore fofoStore1 = fofoStoreRepository.selectByRetailerId(fofoId);
654
            if(!fofoStore1.isActive()){
655
                retailerStatus = "INACTIVE";
656
            }else{
657
                retailerStatus =  String.valueOf(fofoStore1.getActivationType());
658
            }
34606 ranu 659
            biRetailerModel.setCity(customRetailers.get(fofoId).getAddress().getCity());
660
            biRetailerModel.setStoreName(customRetailers.get(fofoId).getBusinessName());
34738 ranu 661
            biRetailerModel.setStatus(retailerStatus);
34606 ranu 662
            biRetailerModel.setCategory(String.valueOf(partnerTypeThisMonth));
663
            biRetailerModel.setSalesManager(managerName);
664
            biRetailerModel.setRbm(rbmName);
34915 ranu 665
            biRetailerModel.setAbm(abmName);
34606 ranu 666
 
34619 ranu 667
            biRetailerModelMap.put(fofoId,biRetailerModel);
668
 
34641 ranu 669
 
34606 ranu 670
//            generate secondary data
671
 
34641 ranu 672
            List<PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledMonthlyTotals = activatedImeiRepository.getTotalMonthlyActivatedNotBilled(fofoId,twoMonthsAgoStartDate);
673
            Map<YearMonth , PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledTotalMap = partnerWiseActivatedNotBilledMonthlyTotals.stream().collect(Collectors.toMap(x-> YearMonth.parse(x.getYearMonth()),x->x));
674
 
34606 ranu 675
//            this month secondary target
676
 
34741 ranu 677
            double currentSecondaryTarget =  monthlyTargetRepository.selectByDateAndFofoId(currentMonth, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(currentMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 678
 
34619 ranu 679
 
680
            long currentMonthReturn = currentMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId, 0L) + currentMonthRtoRefundOrderMap.getOrDefault(fofoId, 0L);
681
 
682
 
34715 ranu 683
            Map<Integer, Double> secondaryMtd = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34741 ranu 684
                    startOfToday.withDayOfMonth(1), previousDay).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
34606 ranu 685
 
34749 ranu 686
 
687
            //yesterday secondary
688
            Map<Integer, Double> dayBeforeYesterdaySecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
689
                    previousDay.toLocalDate().atStartOfDay().minusDays(1), previousDay.minusDays(1)).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
690
            double dayBeforeYesterdayAfterReturnSecondary = dayBeforeYesterdaySecondary.getOrDefault(fofoId,0d) - (dayBeforeYesterdayReturnOrderInfoModelMap.getOrDefault(fofoId,0l) + dayBeforeYesterdayRtoRefundOrderMap.getOrDefault(fofoId,0l));
691
            fofoDayBeforeYesterdaySecondaryMap.put(fofoId, (long) dayBeforeYesterdayAfterReturnSecondary);
692
 
693
 
694
            //day before secondary
695
            Map<Integer, Double> yesterDaySecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
696
                    previousDay.toLocalDate().atStartOfDay(), previousDay).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
697
            double yesterDayAfterReturnSecondary = yesterDaySecondary.getOrDefault(fofoId,0d) - (yesterdayReturnOrderInfoModelMap.getOrDefault(fofoId,0l) + yesterdayRtoRefundOrderMap.getOrDefault(fofoId,0l));
698
            fofoYesterdaySecondaryMap.put(fofoId, (long) yesterDayAfterReturnSecondary);
699
 
34606 ranu 700
            double secondaryAchievedMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
701
 
34619 ranu 702
            double currentMonthNetSecondary = secondaryAchievedMtd - currentMonthReturn;
34606 ranu 703
 
34701 ranu 704
            double currentMonthSecondaryPercent = currentSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((secondaryAchievedMtd / currentSecondaryTarget) * 100));
34619 ranu 705
 
34641 ranu 706
            double currentMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(currentMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(currentMonth).getTotalUnbilledAmount() : 0d;
34619 ranu 707
 
708
//          this month tertiary----------
709
 
710
            LocalDateTime now = LocalDateTime.now();
711
            double todaySale = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday, now, fofoId, false).get(fofoId);
34741 ranu 712
            double mtdSaleTillYesterDay = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday.withDayOfMonth(1), previousDay, fofoId, false).get(fofoId);
34724 ranu 713
            double mtdSale = mtdSaleTillYesterDay;
34619 ranu 714
 
715
 
34606 ranu 716
//            last month secondary target
717
 
34619 ranu 718
            double lastMonthSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId) != null ?  monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 719
 
34619 ranu 720
            long lastMonthReturn = (lastMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + lastMonthRtoRefundOrderMap.getOrDefault(fofoId,0L));
721
 
34715 ranu 722
            Map<Integer, Double> lastMonthSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 723
                    lastMontStartDate, lastMonthEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
724
 
725
            double lastMonthSecondaryAchieved = lastMonthSecondary.getOrDefault(fofoId, 0.0);
726
 
34619 ranu 727
            double lastMonthNetSecondary = lastMonthSecondaryAchieved - lastMonthReturn;
34606 ranu 728
 
34701 ranu 729
            double lastMonthSecondaryPercent = lastMonthSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((lastMonthSecondaryAchieved / lastMonthSecondaryTarget) * 100));
34606 ranu 730
 
34641 ranu 731
            double lastMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(lastMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(lastMonth).getTotalUnbilledAmount() : 0d;
34606 ranu 732
 
34619 ranu 733
//           last month tertiary
734
            Double lastMonthSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
735
                    lastMontStartDate, lastMonthEndDate, fofoId, false).get(fofoId);
736
 
737
 
738
//            two month ago secondary target
739
 
34703 ranu 740
            double twoMonthAgoSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId).getPurchaseTarget() : 0;
34619 ranu 741
 
742
            long twoMonthAgoReturn = (twoMonthAgoPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + twoMonthAgoRtoRefundOrderMap.getOrDefault(fofoId,0L));
743
 
34715 ranu 744
            Map<Integer, Double> twoMonthAgoSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 745
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
746
 
747
            double twoMonthAgoSecondaryAchieved = twoMonthAgoSecondary.getOrDefault(fofoId, 0.0);
748
 
34619 ranu 749
            double twoMonthAgoNetSecondary = twoMonthAgoSecondaryAchieved - twoMonthAgoReturn;
34606 ranu 750
 
34701 ranu 751
            double twoMonthAgoSecondaryPercent = twoMonthAgoSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((twoMonthAgoSecondaryAchieved / twoMonthAgoSecondaryTarget) * 100));
34619 ranu 752
 
34641 ranu 753
            double twoMonthAgoUnbilled = partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo) != null ? partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo).getTotalUnbilledAmount() : 0d;
34619 ranu 754
 
755
//          second Month Tertiary
756
            double twoMonthAgoSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
757
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate, fofoId, false).get(fofoId);
758
 
759
 
760
            Map<YearMonth, BiSecondaryModel> monthlySecondaryModels = new HashMap<>();
761
 
762
            BiSecondaryModel currentMonthSecondaryModel = new BiSecondaryModel(
763
                    currentSecondaryTarget,
764
                    secondaryAchievedMtd,
765
                    currentMonthReturn,
766
                    currentMonthNetSecondary,
767
                    currentMonthSecondaryPercent,
768
                    mtdSale,
769
                    currentMonthUnbilled // for now, unbilled tertiary value
770
            );
771
 
772
            BiSecondaryModel lastMonthSecondaryModel = new BiSecondaryModel(
773
                    lastMonthSecondaryTarget,
774
                    lastMonthSecondaryAchieved,
775
                    lastMonthReturn,
776
                    lastMonthNetSecondary,
777
                    lastMonthSecondaryPercent,
778
                    lastMonthSale,
779
                    lastMonthUnbilled // for now, unbilled tertiary value
780
            );
781
 
782
            BiSecondaryModel twoMonthAgoSecondaryModel = new BiSecondaryModel(
783
                    twoMonthAgoSecondaryTarget,
784
                    twoMonthAgoSecondaryAchieved,
785
                    twoMonthAgoReturn,
786
                    twoMonthAgoNetSecondary,
787
                    twoMonthAgoSecondaryPercent,
788
                    twoMonthAgoSale,
789
                    twoMonthAgoUnbilled // for now, unbilled tertiary value
790
            );
791
 
792
            monthlySecondaryModels.put(currentMonth, currentMonthSecondaryModel);
793
            monthlySecondaryModels.put(lastMonth, lastMonthSecondaryModel);
794
            monthlySecondaryModels.put(twoMonthsAgo, twoMonthAgoSecondaryModel);
795
 
796
            allRetailerMonthlyData.put(fofoId, monthlySecondaryModels);
797
 
798
//            brandwiseStock value price
799
 
800
            Map<String, BrandStockPrice> brandStockPriceMap = inventoryService.getBrandWiseStockValue(fofoId);
801
 
802
            fofoBrandStockPriceMap.put(fofoId,brandStockPriceMap);
803
 
804
            double totalStockPrice = brandStockPriceMap.values().stream().mapToDouble(x->x.getTotalValue()).sum();
805
 
806
            fofoTotalStockPriceMap.put(fofoId,totalStockPrice);
807
 
808
            Map<String, Double> brandMtdTertiaryAmount = fofoOrderItemRepository.selectSumAmountGroupByBrand(
34722 ranu 809
                    currentMonthStartDate, currentMonthEndDate, fofoId);
34619 ranu 810
 
34719 ranu 811
 
34641 ranu 812
            fofoBrandMtdTertiaryMap.put(fofoId,brandMtdTertiaryAmount);
34619 ranu 813
 
814
            double totalMtdTertiaryAmount = brandMtdTertiaryAmount.values().stream().mapToDouble(Double::doubleValue).sum();
815
 
34641 ranu 816
            fofoTotalMtdTertiaryMap.put(fofoId,totalMtdTertiaryAmount);
34619 ranu 817
 
34849 ranu 818
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledByCategoryOrderGroupByBrandFofoId(fofoId, currentMonthStartDate,currentMonthEndDate, Arrays.asList(10006,10001));
34641 ranu 819
            Map<String,Long> brandWiseMtdSecondaryMap = brandWiseMtdSecondary.stream().collect(Collectors.toMap(BrandWiseModel::getBrand,BrandWiseModel::getAmount));
34619 ranu 820
 
34730 ranu 821
            //retrunInfo
822
            List<BrandWiseReturnInfo> brandWiseReturnInfos = returnOrderInfoRepository.selectAllBrandWiseByBetweenDate(currentMonthStartDate,currentMonthEndDate.plusDays(1),fofoId);
823
            Map<String,Double> brandWiseReturnInfoMap = brandWiseReturnInfos.stream().collect(Collectors.toMap(BrandWiseReturnInfo::getBrand, x->x.getReturnAmount()));
34619 ranu 824
 
34730 ranu 825
            LOGGER.info("brandWiseReturnInfos {}",brandWiseReturnInfos);
34758 ranu 826
 
34730 ranu 827
            //Rto retrunInfo
828
            List<BrandWiseReturnInfo> brandWiseRTOReturnInfos = returnOrderInfoRepository.selectAllBrandWiseRTORefundByBetweenDate(currentMonthStartDate,currentMonthEndDate.plusDays(1),fofoId);
829
            Map<String,Double> brandWiseRTOReturnInfoMap = brandWiseRTOReturnInfos.stream().collect(Collectors.toMap(BrandWiseReturnInfo::getBrand, x->x.getReturnAmount()));
830
 
831
            // Step 1: Get union of all brand keys
832
            Set<String> allBrands = new HashSet<>();
833
            allBrands.addAll(brandWiseMtdSecondaryMap.keySet());
834
            allBrands.addAll(brandWiseReturnInfoMap.keySet());
835
            allBrands.addAll(brandWiseRTOReturnInfoMap.keySet());
836
 
837
            // Step 2: Calculate net secondary for each brand
838
            Map<String, Long> brandWiseMtdNetSecondaryMap = new HashMap<>();
839
 
840
            for (String brand : allBrands) {
841
                Long billedAmount = brandWiseMtdSecondaryMap.getOrDefault(brand, 0L);
842
                Double returnAmount = brandWiseReturnInfoMap.getOrDefault(brand, 0d);
843
                Double rtoReturnAmount = brandWiseRTOReturnInfoMap.getOrDefault(brand, 0d);
844
 
845
                double netSecondary = billedAmount - (returnAmount + rtoReturnAmount);
846
                brandWiseMtdNetSecondaryMap.put(brand, (long) Math.round(netSecondary));
847
            }
848
 
849
 
850
            LOGGER.info("brandWiseMtdNetSecondaryMap {}",brandWiseMtdNetSecondaryMap );
851
 
852
 
853
            fofoBrandWiseMtdSecondaryMap.put(fofoId,brandWiseMtdNetSecondaryMap);
854
 
855
            long mtdTotalSecondary = brandWiseMtdNetSecondaryMap.values().stream().mapToLong(Long::longValue).sum();
856
 
34641 ranu 857
            fofoTotalMtdSecondaryMap.put(fofoId,mtdTotalSecondary);
858
 
859
            //            generate investment info
860
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
861
            float shortInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getShortInvestment() : 0f;
862
            float agreedInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getMinInvestment() : 0f;
34677 ranu 863
            float investmentLevel = partnerDailyInvestmentMap.get(fofoId) != null
864
                    ? Math.abs(((shortInvestment - agreedInvestment) / agreedInvestment) * 100)
865
                    : 0f;
34641 ranu 866
 
34677 ranu 867
 
34641 ranu 868
            List<Loan> fofoDefaultLoans = new ArrayList<>();
869
            if(defaultLoanMap != null){
870
                 fofoDefaultLoans  =  defaultLoanMap.get(fofoId);
871
                LOGGER.info("fofoDefaultLoans {}",fofoDefaultLoans);
872
            }
873
 
874
            float defaultLoanAmount = 0f;
875
            if(fofoDefaultLoans != null ){
876
                if (!fofoDefaultLoans.isEmpty()) {
34743 ranu 877
                    for (Loan entry : fofoDefaultLoans) {
878
 
879
                        List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());
880
 
881
                        double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));
882
 
883
                        defaultLoanAmount += amount;
884
                    }
34641 ranu 885
                }
886
            }
887
 
34719 ranu 888
            List<Loan> activeLoans = loanRepository.selectAllActiveLoan(fofoId);
34641 ranu 889
 
34719 ranu 890
            LOGGER.info("activeLoans- {}",activeLoans);
34641 ranu 891
 
34743 ranu 892
            float activeLoan = 0f;
34719 ranu 893
 
34743 ranu 894
            for (Loan entry : activeLoans) {
895
 
896
                List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());
897
 
898
                double pendingAmount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));
899
 
900
                activeLoan += pendingAmount;
901
            }
902
 
34641 ranu 903
            float poValue = partnerDailyInvestmentMap.get(fofoId) != null ?  partnerDailyInvestmentMap.get(fofoId).getUnbilledAmount() : 0f;
904
 
34719 ranu 905
            float poAndBilledValue = (float) (currentMonthNetSecondary + poValue);
34641 ranu 906
 
34741 ranu 907
            double monthDay1Drr = rbmTargetService.calculateFofoIdTodayTarget(fofoId,0d,currentMonth.atDay(1));
34897 ranu 908
            double todayRequiredDrr = 0;
34641 ranu 909
 
34897 ranu 910
            if(monthDay1Drr != 0d){
911
                todayRequiredDrr = rbmTargetService.calculateFofoIdTodayTarget(fofoId, currentMonthNetSecondary,startOfToday.toLocalDate());
912
            }
34641 ranu 913
 
914
            double gotDrrPercent = (todayRequiredDrr / monthDay1Drr) * 100;
915
 
34701 ranu 916
            long drrPercentDisplay = Math.round(Math.abs(gotDrrPercent));
917
 
918
 
34641 ranu 919
            int orderId = orderRepository.getLastOrderByFofoId(fofoId);
920
 
34644 ranu 921
            // Determine alert level
922
            String alertLevel = "-";
923
            int lastPurchaseDays = 0;
34641 ranu 924
            if (orderId != 0) {
925
                Order order = orderRepository.selectById(orderId);
926
 
34715 ranu 927
                LOGGER.info("last billing order - {}",order);
928
 
34641 ranu 929
                // Calculate the number of days since the last purchase (billing)
34644 ranu 930
                lastPurchaseDays = (int) Duration.between(order.getCreateTimestamp().plusDays(1), LocalDateTime.now()).toDays();
34641 ranu 931
 
932
                if (lastPurchaseDays >= 11) {
933
                    alertLevel = "Alert for Management";
34676 ranu 934
                } else if (lastPurchaseDays >= 10) {
34641 ranu 935
                    alertLevel = " Alert for RSM/SH";
34676 ranu 936
                } else if (lastPurchaseDays >= 7) {
34641 ranu 937
                    alertLevel = "Must be Billed";
938
                } else if (lastPurchaseDays >= 3) {
939
                    alertLevel = "OK";
940
                } else {
34676 ranu 941
                    alertLevel = "OK";
34641 ranu 942
                }
34644 ranu 943
            }
34641 ranu 944
 
34644 ranu 945
            //investment modal set all related value
946
            FofoInvestmentModel fofoInvestmentModel = new FofoInvestmentModel();
34641 ranu 947
 
34644 ranu 948
            fofoInvestmentModel.setCounterPotential(fofoStore.getCounterPotential());
949
            fofoInvestmentModel.setShortInvestment(shortInvestment);
950
            fofoInvestmentModel.setDefaultLoan(defaultLoanAmount);
951
            fofoInvestmentModel.setInvestmentLevel(investmentLevel);
952
            fofoInvestmentModel.setActiveLoan(activeLoan);
953
            fofoInvestmentModel.setPoValue(poValue);
954
            fofoInvestmentModel.setPoAndBilled(poAndBilledValue);
955
            fofoInvestmentModel.setAgreedInvestment(agreedInvestment);
956
            fofoInvestmentModel.setWallet(partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getWalletAmount() : 0);
957
            fofoInvestmentModel.setMonthBeginingDrr(monthDay1Drr);
958
            fofoInvestmentModel.setRequiredDrr(todayRequiredDrr);
34701 ranu 959
            fofoInvestmentModel.setDrrPercent(drrPercentDisplay);
34644 ranu 960
            fofoInvestmentModel.setLastBillingDone(lastPurchaseDays);
961
            fofoInvestmentModel.setSlab(alertLevel);
34641 ranu 962
 
34644 ranu 963
            biInvestmentModelMap.put(fofoId, fofoInvestmentModel);
34641 ranu 964
                String assessment = "";
34763 ranu 965
                if(defaultLoanAmount < 0 ){
34641 ranu 966
                    assessment = "Loan Default";
34763 ranu 967
                }else if(investmentLevel <= 75 && defaultLoanAmount >= 0){
34641 ranu 968
                    assessment = "Low Invest";
969
                }else {
970
                    assessment = "-";
971
                }
972
                assessmentMap.put(fofoId,assessment);
973
 
974
                String zeroBilling = "";
975
                if(currentMonthNetSecondary <= 100000 ){
976
                    zeroBilling = "Zero Billing";
977
                }else {
978
                    zeroBilling = "-";
979
                }
980
                zeroBillingMap.put(fofoId,zeroBilling);
981
 
982
                float billingNeeded = 0f;
34749 ranu 983
                if(drrPercentDisplay >= 110 && todayRequiredDrr > 0 ){
34641 ranu 984
                    billingNeeded = (float) todayRequiredDrr;
985
                }else {
986
                    billingNeeded = 0f;
987
                }
988
                billingNeededMap.put(fofoId,billingNeeded);
989
 
990
                int counta = 0;
34701 ranu 991
                if(defaultLoanAmount > 0 || investmentLevel <= 75 || currentMonthNetSecondary <= 100000 || drrPercentDisplay >= 110 ){
34641 ranu 992
                    counta = 1;
993
                }else {
994
                    counta = 0;
995
                }
996
                countAMap.put(fofoId,counta);
997
 
34606 ranu 998
        }
999
 
34619 ranu 1000
        LOGGER.info("Total BI Retailers processed: {}", biRetailerModelMap.size());
34606 ranu 1001
 
34619 ranu 1002
        //generate excel and sent to mail
1003
        List<List<String>> headerGroup = new ArrayList<>();
34606 ranu 1004
 
34619 ranu 1005
        List<String> headers1 = Arrays.asList(
34641 ranu 1006
                "","","","",
34916 ranu 1007
                "Retailer Detail", "","", "", "", "", "", "", "", "","","","","",
34677 ranu 1008
 
1009
                twoMonthAgoStringValue, "", "", "", "", "", "",
1010
                lastMonthStringValue, "", "", "", "", "", "",
34619 ranu 1011
                currentMonthStringValue, "", "", "", "", "", "",
34641 ranu 1012
 
1013
                "","", "", "", "", "", "", "", "", "", "", "", "", "",
1014
 
1015
                "", "", "", "", "", "", "", "", "", "", "", "", "",
34749 ranu 1016
                "", "", "", "", "", "", "", "", "", "", "", "", "","",""
34641 ranu 1017
 
34619 ranu 1018
        );
34606 ranu 1019
 
34619 ranu 1020
        List<String> headers2 = Arrays.asList(
34641 ranu 1021
                "Assessment","Zero billing","Billing needed","Counta",
34916 ranu 1022
                "BM","Partner Id","Link","Wallet Date","Creation Date","Code","Area",  "City", "Store Name", "Status","Category","Sales Manager", "RBM","ABM",
34619 ranu 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",
1027
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
1028
                "Tertiary Sale", "Unbilled",
34641 ranu 1029
                "Counter Potential", "Short investment", "Default", "INVESTMENT LEVEL", "Loan", "PO value", "Agreed investment",
1030
                "Wallet", "po+bill", "MONTH BEGINNING DRR", "REQ DRR", "Drr %", "Last billing Done", "Slab",
34606 ranu 1031
 
34721 ranu 1032
              "Total Stock",  "Apple","Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
1033
              "Total Secondary", "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
34749 ranu 1034
              "Total Tertiary",  "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
1035
                "YesterDay Seconday","Day Before Yesterday Secondary"
34619 ranu 1036
        );
1037
 
1038
        headerGroup.add(headers1);
1039
        headerGroup.add(headers2);
1040
 
1041
 
1042
        List<List<?>> rows = new ArrayList<>();
1043
        for (Map.Entry<Integer, BIRetailerModel> entry : biRetailerModelMap.entrySet()) {
34749 ranu 1044
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
34619 ranu 1045
            Integer fofoId = entry.getKey();
34715 ranu 1046
            User user = userRepository.selectById(fofoId);
1047
            LocalDateTime walletCreationDate = userWalletHistoryRepository.selectFirstCreatedDate(fofoId);
34758 ranu 1048
            if(walletCreationDate == null){
1049
                walletCreationDate = user.getCreateTimestamp();
1050
            }
34619 ranu 1051
            BIRetailerModel retailer = entry.getValue();
34641 ranu 1052
 
34619 ranu 1053
            Map<YearMonth, BiSecondaryModel> monthlyData = allRetailerMonthlyData.get(fofoId);
1054
 
34741 ranu 1055
            BiSecondaryModel current = monthlyData.getOrDefault(currentMonth, new BiSecondaryModel(0,0,0,0,0,0,0));
1056
            BiSecondaryModel last = monthlyData.getOrDefault(currentMonth.minusMonths(1), new BiSecondaryModel(0,0,0,0,0,0,0));
1057
            BiSecondaryModel twoAgo = monthlyData.getOrDefault(currentMonth.minusMonths(2), new BiSecondaryModel(0,0,0,0,0,0,0));
34619 ranu 1058
 
1059
            List<Object> row = new ArrayList<>();
34758 ranu 1060
            LOGGER.info("fofoId-11 {}",fofoId);
1061
 
34619 ranu 1062
            row.addAll(Arrays.asList(
34758 ranu 1063
                    assessmentMap.get(fofoId),
1064
                    zeroBillingMap.get(fofoId),
1065
                    billingNeededMap.get(fofoId),
1066
                    countAMap.get(fofoId),
1067
                    retailer.getBmName(),
1068
                    fofoId ,
1069
                    "https://partners.smartdukaan.com/partnerPerformance?fofoId="+fofoId,
1070
                    walletCreationDate.format(formatter),
1071
                    user.getCreateTimestamp() != null ? (user.getCreateTimestamp()).format(formatter) : "-",
1072
                    retailer.getCode(),
1073
                    retailer.getArea(),
1074
                    retailer.getCity(),
1075
                    retailer.getStoreName(),
1076
                    retailer.getStatus(),
1077
                    retailer.getCategory(),
1078
                    retailer.getSalesManager(),
34915 ranu 1079
                    retailer.getRbm(),
1080
                    retailer.getAbm()
34677 ranu 1081
 
34619 ranu 1082
            ));
1083
 
34677 ranu 1084
 
1085
            // Two Months Ago
34619 ranu 1086
            row.addAll(Arrays.asList(
34677 ranu 1087
                    twoAgo.getSecondaryTarget(),
1088
                    twoAgo.getSecondaryAchieved(),
1089
                    twoAgo.getSecondaryReturn(),
1090
                    twoAgo.getNetSecondary(),
34704 ranu 1091
                    twoAgo.getSecondaryAchievedPercent()+"%",
34677 ranu 1092
                    twoAgo.getTertiary(),
1093
                    twoAgo.getTertiaryUnBilled()
34619 ranu 1094
            ));
1095
 
1096
            // Last Month
1097
            row.addAll(Arrays.asList(
1098
                    last.getSecondaryTarget(),
1099
                    last.getSecondaryAchieved(),
1100
                    last.getSecondaryReturn(),
1101
                    last.getNetSecondary(),
34704 ranu 1102
                    last.getSecondaryAchievedPercent()+"%",
34619 ranu 1103
                    last.getTertiary(),
1104
                    last.getTertiaryUnBilled()
1105
            ));
1106
 
34677 ranu 1107
            // Current Month
34619 ranu 1108
            row.addAll(Arrays.asList(
34677 ranu 1109
                    current.getSecondaryTarget(),
1110
                    current.getSecondaryAchieved(),
1111
                    current.getSecondaryReturn(),
1112
                    current.getNetSecondary(),
34704 ranu 1113
                    current.getSecondaryAchievedPercent()+"%",
34677 ranu 1114
                    current.getTertiary(),
1115
                    current.getTertiaryUnBilled()
34619 ranu 1116
            ));
34677 ranu 1117
 
1118
 
1119
 
34641 ranu 1120
            FofoInvestmentModel fofoInvestmentModelValue = biInvestmentModelMap.get(fofoId);
1121
            if(fofoInvestmentModelValue != null){
1122
                row.addAll(Arrays.asList(
1123
                        fofoInvestmentModelValue.getCounterPotential(),
1124
                        fofoInvestmentModelValue.getShortInvestment(),
1125
                        fofoInvestmentModelValue.getDefaultLoan(),
34730 ranu 1126
                        fofoInvestmentModelValue.getInvestmentLevel() +"%",
34743 ranu 1127
                        fofoInvestmentModelValue.getActiveLoan(),
34641 ranu 1128
                        fofoInvestmentModelValue.getPoValue(),
1129
                        fofoInvestmentModelValue.getAgreedInvestment(),
1130
                        fofoInvestmentModelValue.getWallet(),
1131
                        fofoInvestmentModelValue.getPoAndBilled(),
1132
                        fofoInvestmentModelValue.getMonthBeginingDrr(),
1133
                        fofoInvestmentModelValue.getRequiredDrr(),
34704 ranu 1134
                        fofoInvestmentModelValue.getDrrPercent()+"%",
34641 ranu 1135
                        fofoInvestmentModelValue.getLastBillingDone(),
1136
                        fofoInvestmentModelValue.getSlab()
1137
                ));
1138
            }else {
1139
                row.addAll(Arrays.asList(
1140
                        "-","-","-","-","-","-","-","-","-","-","-",""
1141
                ));
1142
            }
1143
 
1144
            Map<String, BrandStockPrice> brandStockMap = fofoBrandStockPriceMap.get(fofoId);
34619 ranu 1145
            row.addAll(Arrays.asList(
1146
                    fofoTotalStockPriceMap.getOrDefault(fofoId, 0.0),
34641 ranu 1147
                    brandStockMap.get("Apple") != null ? brandStockMap.get("Apple").getTotalValue() : 0.0,
1148
                    brandStockMap.get("Xiaomi") != null ? brandStockMap.get("Xiaomi").getTotalValue() : 0.0,
1149
                    brandStockMap.get("Vivo") != null ? brandStockMap.get("Vivo").getTotalValue() : 0.0,
1150
                    brandStockMap.get("Tecno") != null ? brandStockMap.get("Tecno").getTotalValue() : 0.0,
1151
                    brandStockMap.get("Samsung") != null ? brandStockMap.get("Samsung").getTotalValue() : 0.0,
1152
                    brandStockMap.get("Realme") != null ? brandStockMap.get("Realme").getTotalValue() : 0.0,
1153
                    brandStockMap.get("Oppo") != null ? brandStockMap.get("Oppo").getTotalValue() : 0.0,
1154
                    brandStockMap.get("OnePlus") != null ? brandStockMap.get("OnePlus").getTotalValue() : 0.0,
34721 ranu 1155
                    brandStockMap.get("POCO") != null ? brandStockMap.get("POCO").getTotalValue() : 0.0,
34641 ranu 1156
                    brandStockMap.get("Lava") != null ? brandStockMap.get("Lava").getTotalValue() : 0.0,
1157
                    brandStockMap.get("Itel") != null ? brandStockMap.get("Itel").getTotalValue() : 0.0,
1158
                    brandStockMap.get("Almost New") != null ? brandStockMap.get("Almost New").getTotalValue() : 0.0
34619 ranu 1159
            ));
1160
 
34641 ranu 1161
            Map<String, Long> brandSecondaryMap = fofoBrandWiseMtdSecondaryMap.get(fofoId);
1162
            row.addAll(Arrays.asList(
34648 ranu 1163
                    fofoTotalMtdSecondaryMap.get(fofoId),
34641 ranu 1164
                    brandSecondaryMap.getOrDefault("Apple", 0L),
1165
                    brandSecondaryMap.getOrDefault("Xiaomi", 0L),
1166
                    brandSecondaryMap.getOrDefault("Vivo", 0L),
1167
                    brandSecondaryMap.getOrDefault("Tecno", 0L),
1168
                    brandSecondaryMap.getOrDefault("Samsung", 0L),
1169
                    brandSecondaryMap.getOrDefault("Realme", 0L),
1170
                    brandSecondaryMap.getOrDefault("Oppo", 0L),
1171
                    brandSecondaryMap.getOrDefault("OnePlus", 0L),
34721 ranu 1172
                    brandSecondaryMap.getOrDefault("POCO", 0L),
34641 ranu 1173
                    brandSecondaryMap.getOrDefault("Lava", 0L),
1174
                    brandSecondaryMap.getOrDefault("Itel", 0L),
1175
                    brandSecondaryMap.getOrDefault("Almost New", 0L)
1176
            ));
1177
 
1178
            Map<String, Double> brandTertiaryMap = fofoBrandMtdTertiaryMap.get(fofoId);
1179
            row.addAll(Arrays.asList(
34648 ranu 1180
                    fofoTotalMtdTertiaryMap.get(fofoId),
34641 ranu 1181
                    brandTertiaryMap.getOrDefault("Apple", 0d),
1182
                    brandTertiaryMap.getOrDefault("Xiaomi", 0d),
1183
                    brandTertiaryMap.getOrDefault("Vivo", 0d),
1184
                    brandTertiaryMap.getOrDefault("Tecno", 0d),
1185
                    brandTertiaryMap.getOrDefault("Samsung", 0d),
1186
                    brandTertiaryMap.getOrDefault("Realme", 0d),
1187
                    brandTertiaryMap.getOrDefault("Oppo", 0d),
1188
                    brandTertiaryMap.getOrDefault("OnePlus", 0d),
34721 ranu 1189
                    brandTertiaryMap.getOrDefault("POCO", 0d),
34641 ranu 1190
                    brandTertiaryMap.getOrDefault("Lava", 0d),
1191
                    brandTertiaryMap.getOrDefault("Itel", 0d),
1192
                    brandTertiaryMap.getOrDefault("Almost New", 0d)
1193
            ));
34749 ranu 1194
 
1195
            row.addAll(Arrays.asList(
1196
                    fofoYesterdaySecondaryMap.get(fofoId),
1197
                    fofoDayBeforeYesterdaySecondaryMap.get(fofoId)
1198
            ));
34641 ranu 1199
            rows.add(row);
34619 ranu 1200
        }
1201
 
34912 ranu 1202
        Map<String, Set<Integer>> storeGuyMap = this.generateBiReportHierarchyWise();
34619 ranu 1203
 
34912 ranu 1204
        for (Map.Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {
1205
            String storeGuyEmail = storeGuyEntry.getKey();
1206
            Set<Integer> fofoIds = storeGuyEntry.getValue();
1207
            String[] sendToArray = new String[]{storeGuyEmail};
34911 ranu 1208
 
34912 ranu 1209
            List<List<?>> filteredRows = rows.stream()
1210
                    .filter(row -> row.size() > 5 && fofoIds.contains((Integer) row.get(5)))
1211
                    .collect(Collectors.toList());
1212
            this.sendMailToUser(headerGroup,filteredRows,sendToArray);
1213
        }
1214
 
1215
        this.sendMailToUser(headerGroup,rows,new String[]{"ranu.rajput@smartdukaan.com"});
1216
 
1217
 
34911 ranu 1218
    }
1219
 
1220
    private  void sendMailToUser(List<List<String>> headerGroup,List<List<?>> rows, String[] sendToArray ) throws Exception {
34641 ranu 1221
        // Send to email
1222
//        ByteArrayOutputStream csvStream = FileUtil.getCSVByteStreamWithMultiHeaders(headerGroup, rows);
1223
        ByteArrayOutputStream csvStream = getExcelStreamWithMultiHeaders(headerGroup, rows);
1224
        String fileName = "BI-Retailer-Monthly-Report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".xlsx";
34619 ranu 1225
        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 1226
    }
34619 ranu 1227
 
1228
 
34641 ranu 1229
    public static ByteArrayOutputStream getExcelStreamWithMultiHeaders(List<List<String>> headerGroup, List<List<?>> rows) {
1230
        Workbook workbook = new XSSFWorkbook();
1231
        Sheet sheet = workbook.createSheet("BI Report");
34715 ranu 1232
        CreationHelper creationHelper = workbook.getCreationHelper();
34641 ranu 1233
        int rowIndex = 0;
34606 ranu 1234
 
34641 ranu 1235
        CellStyle centeredStyle = workbook.createCellStyle();
1236
        centeredStyle.setAlignment(HorizontalAlignment.CENTER); // Center horizontally
1237
        centeredStyle.setVerticalAlignment(VerticalAlignment.CENTER); // Center vertically
34606 ranu 1238
 
34641 ranu 1239
    // Optional: bold font
1240
        Font font1 = workbook.createFont();
1241
        font1.setBold(true);
1242
        centeredStyle.setFont(font1);
34606 ranu 1243
 
34619 ranu 1244
 
34641 ranu 1245
 
1246
        // Create styles
1247
        Map<String, CellStyle> headerStyles = new HashMap<>();
1248
 
1249
        // fontPurpleStyle
1250
        CellStyle purpleStyle = workbook.createCellStyle();
1251
        purpleStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
1252
        purpleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1253
        purpleStyle.setFont(font1);
1254
        headerStyles.put("Assessment", purpleStyle);
1255
        headerStyles.put("Zero billing", purpleStyle);
1256
        headerStyles.put("Billing needed", purpleStyle);
1257
        headerStyles.put("Counta", purpleStyle);
1258
        headerStyles.put("MONTH BEGINNING DRR", purpleStyle);
1259
        headerStyles.put("REQ DRR", purpleStyle);
1260
        headerStyles.put("Drr %", purpleStyle);
1261
 
1262
        // Light Blue
1263
        CellStyle blueStyle = workbook.createCellStyle();
1264
        blueStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
1265
        blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1266
        blueStyle.setFont(font1);
1267
        headerStyles.put("Code", blueStyle);
1268
        headerStyles.put("Store Name", blueStyle);
1269
        headerStyles.put("City", blueStyle);
1270
        headerStyles.put("Area", blueStyle);
1271
        headerStyles.put("BM", blueStyle);
1272
        headerStyles.put("RBM", blueStyle);
1273
        headerStyles.put("Sales Manager", blueStyle);
1274
        headerStyles.put("Status", blueStyle);
1275
        headerStyles.put("Category", blueStyle);
34715 ranu 1276
        headerStyles.put("Wallet Date", blueStyle);
1277
        headerStyles.put("Creation Date", blueStyle);
1278
        headerStyles.put("Partner Id", blueStyle);
34641 ranu 1279
 
34715 ranu 1280
        //for link
1281
        // Create hyperlink style
1282
        CellStyle hyperlinkStyle = workbook.createCellStyle();
1283
        Font hlinkFont = workbook.createFont();
1284
        hlinkFont.setUnderline(Font.U_SINGLE);
1285
        hlinkFont.setColor(IndexedColors.BLUE.getIndex());
1286
        hyperlinkStyle.setFont(hlinkFont);
1287
 
1288
 
34641 ranu 1289
        // Light Yellow
1290
        CellStyle yellowStyle = workbook.createCellStyle();
1291
        yellowStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
1292
        yellowStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1293
        yellowStyle.setFont(font1);
1294
        headerStyles.put("Last billing Done", yellowStyle);
1295
        headerStyles.put("Total Stock", yellowStyle);
1296
 
1297
        // Light Orange
1298
        CellStyle orangeStyle = workbook.createCellStyle();
1299
        orangeStyle.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
1300
        orangeStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1301
        orangeStyle.setFont(font1);
1302
        headerStyles.put("Total Tertiary", orangeStyle);
1303
        headerStyles.put("Total Secondary", orangeStyle);
1304
        headerStyles.put("Default", orangeStyle);
1305
 
1306
 
1307
        // Light green
1308
        CellStyle lightGreenStyle = workbook.createCellStyle();
1309
        lightGreenStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
1310
        lightGreenStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1311
        lightGreenStyle.setFont(font1);
1312
        headerStyles.put("Short investment", lightGreenStyle);
1313
        headerStyles.put("INVESTMENT LEVEL", lightGreenStyle);
1314
        headerStyles.put("Loan", lightGreenStyle);
1315
        headerStyles.put("PO value", lightGreenStyle);
1316
        headerStyles.put("Agreed investment", lightGreenStyle);
1317
        headerStyles.put("Wallet", lightGreenStyle);
1318
        headerStyles.put("po+bill", lightGreenStyle);
1319
 
1320
        // Light Green
1321
        CellStyle secondary1 = createStyle(workbook, IndexedColors.LIGHT_GREEN);
1322
        CellStyle secondary2 = createStyle(workbook, IndexedColors.LIGHT_YELLOW);
1323
        CellStyle secondary3 = createStyle(workbook, IndexedColors.LIGHT_ORANGE);
1324
 
1325
        Map<String, CellStyle> brandStyles = new HashMap<>();
1326
        brandStyles.put("Apple", createStyle(workbook, IndexedColors.GREY_25_PERCENT));
1327
        brandStyles.put("Xiaomi", createStyle(workbook, IndexedColors.ORANGE));
1328
        brandStyles.put("Vivo", createStyle(workbook, IndexedColors.SKY_BLUE));
1329
        brandStyles.put("Tecno", createStyle(workbook, IndexedColors.LIGHT_BLUE));
1330
        brandStyles.put("Samsung", createStyle(workbook, IndexedColors.ROYAL_BLUE));
1331
        brandStyles.put("Realme", createStyle(workbook, IndexedColors.YELLOW));
1332
        brandStyles.put("Oppo", createStyle(workbook, IndexedColors.LIGHT_GREEN));
1333
        brandStyles.put("OnePlus", createStyle(workbook, IndexedColors.RED));
34721 ranu 1334
        brandStyles.put("POCO", createStyle(workbook, IndexedColors.ORANGE));
34641 ranu 1335
        brandStyles.put("Lava", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1336
        brandStyles.put("Itel", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1337
        brandStyles.put("Almost New", createStyle(workbook, IndexedColors.WHITE));
1338
 
1339
 
1340
        CellStyle defaultHeaderStyle = workbook.createCellStyle();
1341
        defaultHeaderStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
1342
        defaultHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1343
        defaultHeaderStyle.setFont(font1);
1344
 
34749 ranu 1345
        CellStyle numberStyle = workbook.createCellStyle();
1346
        DataFormat format = workbook.createDataFormat();
1347
        numberStyle.setDataFormat(format.getFormat("#,##0")); // or "#,##0.00" for two decimals
34641 ranu 1348
 
34749 ranu 1349
 
1350
 
34641 ranu 1351
        Map<String, Integer> headerCount = new HashMap<>();
1352
 
1353
        for (int headerRowIndex = 0; headerRowIndex < headerGroup.size(); headerRowIndex++) {
1354
            List<String> headerRow = headerGroup.get(headerRowIndex);
1355
            Row row = sheet.createRow(rowIndex++);
1356
 
1357
            for (int i = 0; i < headerRow.size(); i++) {
1358
                String headerText = headerRow.get(i);
1359
                sheet.setColumnWidth(i, 25 * 256);
1360
                row.setHeightInPoints(20); // 25-point height
1361
                Cell cell = row.createCell(i);
1362
                cell.setCellValue(headerText);
1363
                cell.setCellStyle(centeredStyle);
1364
                // Count how many times this header has appeared
1365
                int count = headerCount.getOrDefault(headerText, 0) + 1;
1366
                headerCount.put(headerText, count);
1367
                // Apply special style for repeated headers
1368
                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")) {
1369
                    if (count == 1) {
1370
                        cell.setCellStyle(secondary1);
1371
                    } else if (count == 2) {
1372
                        cell.setCellStyle(secondary2);
1373
                    } else if (count == 3) {
1374
                        cell.setCellStyle(secondary3);
1375
                    }
1376
                }
1377
                // Brand header styling (apply only for the 2nd row of headers)
1378
                else if (headerRowIndex == 1 && brandStyles.containsKey(headerText)) {
1379
                    cell.setCellStyle(brandStyles.get(headerText));
1380
                }else if (headerStyles.containsKey(headerText)) {
1381
                    cell.setCellStyle(headerStyles.get(headerText));
1382
                } else {
1383
                    cell.setCellStyle(defaultHeaderStyle); // default style for others
1384
                }
1385
            }
1386
        }
1387
 
1388
        // Write data rows
1389
        for (List<?> dataRow : rows) {
1390
            Row row = sheet.createRow(rowIndex++);
1391
            for (int i = 0; i < dataRow.size(); i++) {
1392
                Cell cell = row.createCell(i);
1393
                Object value = dataRow.get(i);
34715 ranu 1394
 
1395
                if (i == 6 && value != null) { // Assuming column 6 is "Link"
1396
                    Hyperlink hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
1397
                    hyperlink.setAddress(value.toString());
34719 ranu 1398
                    cell.setCellValue("View Link"); // Display text
34715 ranu 1399
                    cell.setHyperlink(hyperlink);
1400
                    cell.setCellStyle(hyperlinkStyle);
34719 ranu 1401
                } else if (value instanceof Number) {
34749 ranu 1402
                    double numeric = ((Number) value).doubleValue();
1403
                    cell.setCellValue(Math.round(numeric));
1404
                    cell.setCellStyle(numberStyle);
34715 ranu 1405
                } else {
1406
                    cell.setCellValue(value != null ? value.toString() : "");
1407
                }
34641 ranu 1408
            }
34719 ranu 1409
 
34641 ranu 1410
        }
1411
 
1412
        // Auto-size columns
1413
        if (!rows.isEmpty()) {
1414
            for (int i = 0; i < rows.get(0).size(); i++) {
1415
                sheet.autoSizeColumn(i);
1416
            }
1417
        }
1418
 
1419
        // Output as ByteArray
1420
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
1421
            workbook.write(outputStream);
1422
            workbook.close();
1423
            return outputStream;
1424
        } catch (IOException e) {
1425
            throw new RuntimeException("Failed to generate Excel file", e);
1426
        }
1427
    }
1428
 
1429
 
1430
    private static CellStyle createStyle(Workbook workbook, IndexedColors color) {
1431
        CellStyle style = workbook.createCellStyle();
1432
        style.setFillForegroundColor(color.getIndex());
1433
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1434
        Font font = workbook.createFont();
1435
        font.setBold(true);
1436
        style.setFont(font);
1437
        return style;
1438
    }
1439
 
1440
 
34758 ranu 1441
    public void stockAlertMailToRetailer() throws Exception {
1442
 
1443
        Map<Integer, CustomRetailer> customRetailers = retailerService.getFofoRetailers(true);
1444
 
1445
        List<Integer> retailerIds = customRetailers.values().stream().map(CustomRetailer::getPartnerId).collect(Collectors.toList());
1446
 
1447
        for(Integer fofoId : retailerIds){
1448
            List<String> statusOrder = Arrays.asList("HID", "FASTMOVING", "RUNNING", "SLOWMOVING", "OTHER");
1449
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
1450
            List<PartnerWarehouseStockSummaryModel> partnerWarehouseStockSummaryModels = saholicInventoryService.getSaholicAndPartnerStock(fofoId, fofoStore.getWarehouseId());
1451
 
1452
            List<PartnerWarehouseStockAgingSummaryModel> partnerWarehouseStockAgingSummaryModelList = new ArrayList<>();
1453
 
1454
            Set<Integer> catalogIds = partnerWarehouseStockSummaryModels.stream().map(x -> x.getCatalogId()).collect(Collectors.toSet());
1455
 
1456
            List<Integer> catalogsList = new ArrayList<>(catalogIds);
1457
 
1458
            Map<Integer, TagListing> tagListingsMap = tagListingRepository.selectAllByCatalogIds(catalogsList);
1459
 
1460
            List<CatalogAgingModel> catalogAgingModels = ageingService.getCatalogsAgingByWarehouse(catalogIds, fofoStore.getWarehouseId());
1461
 
1462
            Map<Integer, CatalogAgingModel> catalogAgingModelMap = catalogAgingModels.stream().collect(Collectors.toMap(x -> x.getCatalogId(), x -> x));
1463
 
1464
            for (PartnerWarehouseStockSummaryModel stockSummary : partnerWarehouseStockSummaryModels) {
1465
 
1466
                PartnerWarehouseStockAgingSummaryModel partnerWarehouseStockAgingSummaryModel = new PartnerWarehouseStockAgingSummaryModel();
1467
                partnerWarehouseStockAgingSummaryModel.setCatalogId(stockSummary.getCatalogId());
1468
                partnerWarehouseStockAgingSummaryModel.setBrand(stockSummary.getBrand());
1469
                partnerWarehouseStockAgingSummaryModel.setModelNumber(stockSummary.getModelNumber());
1470
                partnerWarehouseStockAgingSummaryModel.setNetAvailability(stockSummary.getShaholicNetAvailability());
1471
                partnerWarehouseStockAgingSummaryModel.setPartnerStockAvailability(stockSummary.getPartnerFullFilledQty());
1472
                partnerWarehouseStockAgingSummaryModel.setPartnerCurrentAvailability(stockSummary.getPartnerCurrentQty());
1473
                partnerWarehouseStockAgingSummaryModel.setPartnerShortageStock(stockSummary.getPartnerShortageQty());
1474
                if (catalogAgingModelMap.get(stockSummary.getCatalogId()) != null) {
1475
                    partnerWarehouseStockAgingSummaryModel.setExceedDays(catalogAgingModelMap.get(stockSummary.getCatalogId()).getExceedDays());
1476
                } else {
1477
                    partnerWarehouseStockAgingSummaryModel.setExceedDays(0);
1478
 
1479
                }
1480
                partnerWarehouseStockAgingSummaryModel.setStatus(stockSummary.getStatus());
1481
 
1482
                partnerWarehouseStockAgingSummaryModelList.add(partnerWarehouseStockAgingSummaryModel);
1483
            }
1484
 
1485
            Set<Integer> existingCatalogIdsInAgingSummaryList = partnerWarehouseStockAgingSummaryModelList.stream()
1486
                    .map(PartnerWarehouseStockAgingSummaryModel::getCatalogId)
1487
                    .collect(Collectors.toSet());
1488
        }
1489
 
1490
    }
1491
 
1492
 
34306 ranu 1493
}