Subversion Repositories SmartDukaan

Rev

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

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