Subversion Repositories SmartDukaan

Rev

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

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