Subversion Repositories SmartDukaan

Rev

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