Subversion Repositories SmartDukaan

Rev

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