Subversion Repositories SmartDukaan

Rev

Rev 34922 | Rev 34926 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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