Subversion Repositories SmartDukaan

Rev

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