Subversion Repositories SmartDukaan

Rev

Rev 34920 | Rev 34925 | 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
 
34922 ranu 480
        Map<Integer, CustomRetailer> customRetailers = retailerService.getAllFofoRetailersInternalFalse();
34912 ranu 481
 
34903 ranu 482
        List<Integer> retailerIds = customRetailers.values().stream()
483
                .filter(retailer -> {
484
                    String storeCode = retailer.getCode(); // adjust method name if different
485
                    return !storeCode.equalsIgnoreCase("UPGBN640") && !storeCode.equalsIgnoreCase("HRYN039");
486
                })
487
                .map(CustomRetailer::getPartnerId)
34922 ranu 488
                .collect(Collectors.toList());
34606 ranu 489
 
34903 ranu 490
//        List<Integer> retailerIds = customRetailers.values().stream().map(CustomRetailer::getPartnerId).collect(Collectors.toList());
491
 
34922 ranu 492
/*        List<Integer> retailerIds = Arrays.asList(175139440,175139441,175139442);
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 = "";
34920 ranu 605
            int rbmL1 = csService.getAuthUserIdWithoutTicketAssignee(ProfitMandiConstants.TICKET_CATEGORY_RBM,EscalationType.L1,fofoId);
34619 ranu 606
            if(rbmL1 != 0){
607
                 rbmName = authRepository.selectById(rbmL1).getFullName();
34677 ranu 608
            }else {
34920 ranu 609
                int rbmL2 = csService.getAuthUserIdWithoutTicketAssignee(ProfitMandiConstants.TICKET_CATEGORY_RBM, EscalationType.L2, fofoId);
34677 ranu 610
                if(rbmL2 != 0){
611
                    rbmName = authRepository.selectById(rbmL2).getFullName();
612
                }
34619 ranu 613
            }
614
            String bmName ="";
34920 ranu 615
            int bmId = csService.getAuthUserIdWithoutTicketAssignee(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L2,fofoId);
34619 ranu 616
            if(bmId !=0){
617
                bmName = authRepository.selectById(bmId).getFullName();
618
            }
34606 ranu 619
 
34920 ranu 620
            int managerId = csService.getAuthUserIdWithoutTicketAssignee(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L1,fofoId);
34606 ranu 621
            String managerName = " ";
34919 ranu 622
            LOGGER.info("managerId {}",managerId);
34606 ranu 623
            if(managerId != 0){
624
                 managerName = authRepository.selectById(managerId).getFullName();
625
            }else {
626
                managerName = bmName;
627
            }
34915 ranu 628
            String abmName ="";
34920 ranu 629
            int abmId = csService.getAuthUserIdWithoutTicketAssignee(ProfitMandiConstants.TICKET_CATEGORY_ABM,EscalationType.L1,fofoId);
630
            int abmL2Id = csService.getAuthUserIdWithoutTicketAssignee(ProfitMandiConstants.TICKET_CATEGORY_ABM,EscalationType.L2,fofoId);
631
            int abmL3Id = csService.getAuthUserIdWithoutTicketAssignee(ProfitMandiConstants.TICKET_CATEGORY_ABM,EscalationType.L3,fofoId);
34915 ranu 632
            if(abmId !=0){
633
                abmName = authRepository.selectById(abmId).getFullName();
34918 ranu 634
            }else if(abmL2Id != 0){
34916 ranu 635
                abmName = authRepository.selectById(abmL2Id).getFullName();
34919 ranu 636
            }else if(abmL3Id != 0){
34918 ranu 637
                abmName = authRepository.selectById(abmL3Id).getFullName();
34915 ranu 638
            }
34606 ranu 639
            AST ast = astRepository.selectById(customRetailers.get(fofoId).getAstId());
640
 
34741 ranu 641
            PartnerType partnerTypeThisMonth = partnerTypeChangeService.getTypeOnMonth(fofoId, currentMonth);
34606 ranu 642
 
643
//            generate retaile detail
644
 
645
            BIRetailerModel biRetailerModel = new BIRetailerModel();
646
            biRetailerModel.setBmName(bmName);
647
            biRetailerModel.setCode(customRetailers.get(fofoId).getCode());
34619 ranu 648
            if(ast != null){
649
                biRetailerModel.setArea(ast.getArea());
650
            }else {
651
                biRetailerModel.setArea("-");
652
            }
34738 ranu 653
            String retailerStatus = "";
654
            FofoStore fofoStore1 = fofoStoreRepository.selectByRetailerId(fofoId);
655
            if(!fofoStore1.isActive()){
656
                retailerStatus = "INACTIVE";
657
            }else{
658
                retailerStatus =  String.valueOf(fofoStore1.getActivationType());
659
            }
34606 ranu 660
            biRetailerModel.setCity(customRetailers.get(fofoId).getAddress().getCity());
661
            biRetailerModel.setStoreName(customRetailers.get(fofoId).getBusinessName());
34738 ranu 662
            biRetailerModel.setStatus(retailerStatus);
34606 ranu 663
            biRetailerModel.setCategory(String.valueOf(partnerTypeThisMonth));
664
            biRetailerModel.setSalesManager(managerName);
665
            biRetailerModel.setRbm(rbmName);
34915 ranu 666
            biRetailerModel.setAbm(abmName);
34606 ranu 667
 
34619 ranu 668
            biRetailerModelMap.put(fofoId,biRetailerModel);
669
 
34641 ranu 670
 
34606 ranu 671
//            generate secondary data
672
 
34641 ranu 673
            List<PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledMonthlyTotals = activatedImeiRepository.getTotalMonthlyActivatedNotBilled(fofoId,twoMonthsAgoStartDate);
674
            Map<YearMonth , PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledTotalMap = partnerWiseActivatedNotBilledMonthlyTotals.stream().collect(Collectors.toMap(x-> YearMonth.parse(x.getYearMonth()),x->x));
675
 
34606 ranu 676
//            this month secondary target
677
 
34741 ranu 678
            double currentSecondaryTarget =  monthlyTargetRepository.selectByDateAndFofoId(currentMonth, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(currentMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 679
 
34619 ranu 680
 
681
            long currentMonthReturn = currentMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId, 0L) + currentMonthRtoRefundOrderMap.getOrDefault(fofoId, 0L);
682
 
683
 
34715 ranu 684
            Map<Integer, Double> secondaryMtd = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34741 ranu 685
                    startOfToday.withDayOfMonth(1), previousDay).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
34606 ranu 686
 
34749 ranu 687
 
688
            //yesterday secondary
689
            Map<Integer, Double> dayBeforeYesterdaySecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
690
                    previousDay.toLocalDate().atStartOfDay().minusDays(1), previousDay.minusDays(1)).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
691
            double dayBeforeYesterdayAfterReturnSecondary = dayBeforeYesterdaySecondary.getOrDefault(fofoId,0d) - (dayBeforeYesterdayReturnOrderInfoModelMap.getOrDefault(fofoId,0l) + dayBeforeYesterdayRtoRefundOrderMap.getOrDefault(fofoId,0l));
692
            fofoDayBeforeYesterdaySecondaryMap.put(fofoId, (long) dayBeforeYesterdayAfterReturnSecondary);
693
 
694
 
695
            //day before secondary
696
            Map<Integer, Double> yesterDaySecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
697
                    previousDay.toLocalDate().atStartOfDay(), previousDay).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
698
            double yesterDayAfterReturnSecondary = yesterDaySecondary.getOrDefault(fofoId,0d) - (yesterdayReturnOrderInfoModelMap.getOrDefault(fofoId,0l) + yesterdayRtoRefundOrderMap.getOrDefault(fofoId,0l));
699
            fofoYesterdaySecondaryMap.put(fofoId, (long) yesterDayAfterReturnSecondary);
700
 
34606 ranu 701
            double secondaryAchievedMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
702
 
34619 ranu 703
            double currentMonthNetSecondary = secondaryAchievedMtd - currentMonthReturn;
34606 ranu 704
 
34701 ranu 705
            double currentMonthSecondaryPercent = currentSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((secondaryAchievedMtd / currentSecondaryTarget) * 100));
34619 ranu 706
 
34641 ranu 707
            double currentMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(currentMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(currentMonth).getTotalUnbilledAmount() : 0d;
34619 ranu 708
 
709
//          this month tertiary----------
710
 
711
            LocalDateTime now = LocalDateTime.now();
712
            double todaySale = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday, now, fofoId, false).get(fofoId);
34741 ranu 713
            double mtdSaleTillYesterDay = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday.withDayOfMonth(1), previousDay, fofoId, false).get(fofoId);
34724 ranu 714
            double mtdSale = mtdSaleTillYesterDay;
34619 ranu 715
 
716
 
34606 ranu 717
//            last month secondary target
718
 
34619 ranu 719
            double lastMonthSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId) != null ?  monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 720
 
34619 ranu 721
            long lastMonthReturn = (lastMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + lastMonthRtoRefundOrderMap.getOrDefault(fofoId,0L));
722
 
34715 ranu 723
            Map<Integer, Double> lastMonthSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 724
                    lastMontStartDate, lastMonthEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
725
 
726
            double lastMonthSecondaryAchieved = lastMonthSecondary.getOrDefault(fofoId, 0.0);
727
 
34619 ranu 728
            double lastMonthNetSecondary = lastMonthSecondaryAchieved - lastMonthReturn;
34606 ranu 729
 
34701 ranu 730
            double lastMonthSecondaryPercent = lastMonthSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((lastMonthSecondaryAchieved / lastMonthSecondaryTarget) * 100));
34606 ranu 731
 
34641 ranu 732
            double lastMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(lastMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(lastMonth).getTotalUnbilledAmount() : 0d;
34606 ranu 733
 
34619 ranu 734
//           last month tertiary
735
            Double lastMonthSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
736
                    lastMontStartDate, lastMonthEndDate, fofoId, false).get(fofoId);
737
 
738
 
739
//            two month ago secondary target
740
 
34703 ranu 741
            double twoMonthAgoSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(twoMonthsAgo, fofoId).getPurchaseTarget() : 0;
34619 ranu 742
 
743
            long twoMonthAgoReturn = (twoMonthAgoPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + twoMonthAgoRtoRefundOrderMap.getOrDefault(fofoId,0L));
744
 
34715 ranu 745
            Map<Integer, Double> twoMonthAgoSecondary = orderRepository.selectOrderValueBetweenBillingDatesGroupByFofoId(Arrays.asList(fofoId),
34606 ranu 746
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
747
 
748
            double twoMonthAgoSecondaryAchieved = twoMonthAgoSecondary.getOrDefault(fofoId, 0.0);
749
 
34619 ranu 750
            double twoMonthAgoNetSecondary = twoMonthAgoSecondaryAchieved - twoMonthAgoReturn;
34606 ranu 751
 
34701 ranu 752
            double twoMonthAgoSecondaryPercent = twoMonthAgoSecondaryTarget == 0 ? 0.0 : Math.round(Math.abs((twoMonthAgoSecondaryAchieved / twoMonthAgoSecondaryTarget) * 100));
34619 ranu 753
 
34641 ranu 754
            double twoMonthAgoUnbilled = partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo) != null ? partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo).getTotalUnbilledAmount() : 0d;
34619 ranu 755
 
756
//          second Month Tertiary
757
            double twoMonthAgoSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
758
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate, fofoId, false).get(fofoId);
759
 
760
 
761
            Map<YearMonth, BiSecondaryModel> monthlySecondaryModels = new HashMap<>();
762
 
763
            BiSecondaryModel currentMonthSecondaryModel = new BiSecondaryModel(
764
                    currentSecondaryTarget,
765
                    secondaryAchievedMtd,
766
                    currentMonthReturn,
767
                    currentMonthNetSecondary,
768
                    currentMonthSecondaryPercent,
769
                    mtdSale,
770
                    currentMonthUnbilled // for now, unbilled tertiary value
771
            );
772
 
773
            BiSecondaryModel lastMonthSecondaryModel = new BiSecondaryModel(
774
                    lastMonthSecondaryTarget,
775
                    lastMonthSecondaryAchieved,
776
                    lastMonthReturn,
777
                    lastMonthNetSecondary,
778
                    lastMonthSecondaryPercent,
779
                    lastMonthSale,
780
                    lastMonthUnbilled // for now, unbilled tertiary value
781
            );
782
 
783
            BiSecondaryModel twoMonthAgoSecondaryModel = new BiSecondaryModel(
784
                    twoMonthAgoSecondaryTarget,
785
                    twoMonthAgoSecondaryAchieved,
786
                    twoMonthAgoReturn,
787
                    twoMonthAgoNetSecondary,
788
                    twoMonthAgoSecondaryPercent,
789
                    twoMonthAgoSale,
790
                    twoMonthAgoUnbilled // for now, unbilled tertiary value
791
            );
792
 
793
            monthlySecondaryModels.put(currentMonth, currentMonthSecondaryModel);
794
            monthlySecondaryModels.put(lastMonth, lastMonthSecondaryModel);
795
            monthlySecondaryModels.put(twoMonthsAgo, twoMonthAgoSecondaryModel);
796
 
797
            allRetailerMonthlyData.put(fofoId, monthlySecondaryModels);
798
 
799
//            brandwiseStock value price
800
 
801
            Map<String, BrandStockPrice> brandStockPriceMap = inventoryService.getBrandWiseStockValue(fofoId);
802
 
803
            fofoBrandStockPriceMap.put(fofoId,brandStockPriceMap);
804
 
805
            double totalStockPrice = brandStockPriceMap.values().stream().mapToDouble(x->x.getTotalValue()).sum();
806
 
807
            fofoTotalStockPriceMap.put(fofoId,totalStockPrice);
808
 
809
            Map<String, Double> brandMtdTertiaryAmount = fofoOrderItemRepository.selectSumAmountGroupByBrand(
34722 ranu 810
                    currentMonthStartDate, currentMonthEndDate, fofoId);
34619 ranu 811
 
34719 ranu 812
 
34641 ranu 813
            fofoBrandMtdTertiaryMap.put(fofoId,brandMtdTertiaryAmount);
34619 ranu 814
 
815
            double totalMtdTertiaryAmount = brandMtdTertiaryAmount.values().stream().mapToDouble(Double::doubleValue).sum();
816
 
34641 ranu 817
            fofoTotalMtdTertiaryMap.put(fofoId,totalMtdTertiaryAmount);
34619 ranu 818
 
34849 ranu 819
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledByCategoryOrderGroupByBrandFofoId(fofoId, currentMonthStartDate,currentMonthEndDate, Arrays.asList(10006,10001));
34641 ranu 820
            Map<String,Long> brandWiseMtdSecondaryMap = brandWiseMtdSecondary.stream().collect(Collectors.toMap(BrandWiseModel::getBrand,BrandWiseModel::getAmount));
34619 ranu 821
 
34730 ranu 822
            //retrunInfo
823
            List<BrandWiseReturnInfo> brandWiseReturnInfos = returnOrderInfoRepository.selectAllBrandWiseByBetweenDate(currentMonthStartDate,currentMonthEndDate.plusDays(1),fofoId);
824
            Map<String,Double> brandWiseReturnInfoMap = brandWiseReturnInfos.stream().collect(Collectors.toMap(BrandWiseReturnInfo::getBrand, x->x.getReturnAmount()));
34619 ranu 825
 
34730 ranu 826
            LOGGER.info("brandWiseReturnInfos {}",brandWiseReturnInfos);
34758 ranu 827
 
34730 ranu 828
            //Rto retrunInfo
829
            List<BrandWiseReturnInfo> brandWiseRTOReturnInfos = returnOrderInfoRepository.selectAllBrandWiseRTORefundByBetweenDate(currentMonthStartDate,currentMonthEndDate.plusDays(1),fofoId);
830
            Map<String,Double> brandWiseRTOReturnInfoMap = brandWiseRTOReturnInfos.stream().collect(Collectors.toMap(BrandWiseReturnInfo::getBrand, x->x.getReturnAmount()));
831
 
832
            // Step 1: Get union of all brand keys
833
            Set<String> allBrands = new HashSet<>();
834
            allBrands.addAll(brandWiseMtdSecondaryMap.keySet());
835
            allBrands.addAll(brandWiseReturnInfoMap.keySet());
836
            allBrands.addAll(brandWiseRTOReturnInfoMap.keySet());
837
 
838
            // Step 2: Calculate net secondary for each brand
839
            Map<String, Long> brandWiseMtdNetSecondaryMap = new HashMap<>();
840
 
841
            for (String brand : allBrands) {
842
                Long billedAmount = brandWiseMtdSecondaryMap.getOrDefault(brand, 0L);
843
                Double returnAmount = brandWiseReturnInfoMap.getOrDefault(brand, 0d);
844
                Double rtoReturnAmount = brandWiseRTOReturnInfoMap.getOrDefault(brand, 0d);
845
 
846
                double netSecondary = billedAmount - (returnAmount + rtoReturnAmount);
847
                brandWiseMtdNetSecondaryMap.put(brand, (long) Math.round(netSecondary));
848
            }
849
 
850
 
851
            LOGGER.info("brandWiseMtdNetSecondaryMap {}",brandWiseMtdNetSecondaryMap );
852
 
853
 
854
            fofoBrandWiseMtdSecondaryMap.put(fofoId,brandWiseMtdNetSecondaryMap);
855
 
856
            long mtdTotalSecondary = brandWiseMtdNetSecondaryMap.values().stream().mapToLong(Long::longValue).sum();
857
 
34641 ranu 858
            fofoTotalMtdSecondaryMap.put(fofoId,mtdTotalSecondary);
859
 
860
            //            generate investment info
861
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
862
            float shortInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getShortInvestment() : 0f;
863
            float agreedInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getMinInvestment() : 0f;
34677 ranu 864
            float investmentLevel = partnerDailyInvestmentMap.get(fofoId) != null
865
                    ? Math.abs(((shortInvestment - agreedInvestment) / agreedInvestment) * 100)
866
                    : 0f;
34641 ranu 867
 
34677 ranu 868
 
34641 ranu 869
            List<Loan> fofoDefaultLoans = new ArrayList<>();
870
            if(defaultLoanMap != null){
871
                 fofoDefaultLoans  =  defaultLoanMap.get(fofoId);
872
                LOGGER.info("fofoDefaultLoans {}",fofoDefaultLoans);
873
            }
874
 
875
            float defaultLoanAmount = 0f;
876
            if(fofoDefaultLoans != null ){
877
                if (!fofoDefaultLoans.isEmpty()) {
34743 ranu 878
                    for (Loan entry : fofoDefaultLoans) {
879
 
880
                        List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());
881
 
882
                        double amount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));
883
 
884
                        defaultLoanAmount += amount;
885
                    }
34641 ranu 886
                }
887
            }
888
 
34719 ranu 889
            List<Loan> activeLoans = loanRepository.selectAllActiveLoan(fofoId);
34641 ranu 890
 
34719 ranu 891
            LOGGER.info("activeLoans- {}",activeLoans);
34641 ranu 892
 
34743 ranu 893
            float activeLoan = 0f;
34719 ranu 894
 
34743 ranu 895
            for (Loan entry : activeLoans) {
896
 
897
                List<LoanStatement> loanStatements = loanStatementRepository.selectByLoanId(entry.getId());
898
 
899
                double pendingAmount = loanStatements.stream().map(x -> x.getAmount()).collect(Collectors.summingDouble(x -> x.doubleValue()));
900
 
901
                activeLoan += pendingAmount;
902
            }
903
 
34641 ranu 904
            float poValue = partnerDailyInvestmentMap.get(fofoId) != null ?  partnerDailyInvestmentMap.get(fofoId).getUnbilledAmount() : 0f;
905
 
34719 ranu 906
            float poAndBilledValue = (float) (currentMonthNetSecondary + poValue);
34641 ranu 907
 
34741 ranu 908
            double monthDay1Drr = rbmTargetService.calculateFofoIdTodayTarget(fofoId,0d,currentMonth.atDay(1));
34897 ranu 909
            double todayRequiredDrr = 0;
34641 ranu 910
 
34897 ranu 911
            if(monthDay1Drr != 0d){
912
                todayRequiredDrr = rbmTargetService.calculateFofoIdTodayTarget(fofoId, currentMonthNetSecondary,startOfToday.toLocalDate());
913
            }
34641 ranu 914
 
915
            double gotDrrPercent = (todayRequiredDrr / monthDay1Drr) * 100;
916
 
34701 ranu 917
            long drrPercentDisplay = Math.round(Math.abs(gotDrrPercent));
918
 
919
 
34641 ranu 920
            int orderId = orderRepository.getLastOrderByFofoId(fofoId);
921
 
34644 ranu 922
            // Determine alert level
923
            String alertLevel = "-";
924
            int lastPurchaseDays = 0;
34641 ranu 925
            if (orderId != 0) {
926
                Order order = orderRepository.selectById(orderId);
927
 
34715 ranu 928
                LOGGER.info("last billing order - {}",order);
929
 
34641 ranu 930
                // Calculate the number of days since the last purchase (billing)
34644 ranu 931
                lastPurchaseDays = (int) Duration.between(order.getCreateTimestamp().plusDays(1), LocalDateTime.now()).toDays();
34641 ranu 932
 
933
                if (lastPurchaseDays >= 11) {
934
                    alertLevel = "Alert for Management";
34676 ranu 935
                } else if (lastPurchaseDays >= 10) {
34641 ranu 936
                    alertLevel = " Alert for RSM/SH";
34676 ranu 937
                } else if (lastPurchaseDays >= 7) {
34641 ranu 938
                    alertLevel = "Must be Billed";
939
                } else if (lastPurchaseDays >= 3) {
940
                    alertLevel = "OK";
941
                } else {
34676 ranu 942
                    alertLevel = "OK";
34641 ranu 943
                }
34644 ranu 944
            }
34641 ranu 945
 
34644 ranu 946
            //investment modal set all related value
947
            FofoInvestmentModel fofoInvestmentModel = new FofoInvestmentModel();
34641 ranu 948
 
34644 ranu 949
            fofoInvestmentModel.setCounterPotential(fofoStore.getCounterPotential());
950
            fofoInvestmentModel.setShortInvestment(shortInvestment);
951
            fofoInvestmentModel.setDefaultLoan(defaultLoanAmount);
952
            fofoInvestmentModel.setInvestmentLevel(investmentLevel);
953
            fofoInvestmentModel.setActiveLoan(activeLoan);
954
            fofoInvestmentModel.setPoValue(poValue);
955
            fofoInvestmentModel.setPoAndBilled(poAndBilledValue);
956
            fofoInvestmentModel.setAgreedInvestment(agreedInvestment);
957
            fofoInvestmentModel.setWallet(partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getWalletAmount() : 0);
958
            fofoInvestmentModel.setMonthBeginingDrr(monthDay1Drr);
959
            fofoInvestmentModel.setRequiredDrr(todayRequiredDrr);
34701 ranu 960
            fofoInvestmentModel.setDrrPercent(drrPercentDisplay);
34644 ranu 961
            fofoInvestmentModel.setLastBillingDone(lastPurchaseDays);
962
            fofoInvestmentModel.setSlab(alertLevel);
34641 ranu 963
 
34644 ranu 964
            biInvestmentModelMap.put(fofoId, fofoInvestmentModel);
34641 ranu 965
                String assessment = "";
34763 ranu 966
                if(defaultLoanAmount < 0 ){
34641 ranu 967
                    assessment = "Loan Default";
34763 ranu 968
                }else if(investmentLevel <= 75 && defaultLoanAmount >= 0){
34641 ranu 969
                    assessment = "Low Invest";
970
                }else {
971
                    assessment = "-";
972
                }
973
                assessmentMap.put(fofoId,assessment);
974
 
975
                String zeroBilling = "";
976
                if(currentMonthNetSecondary <= 100000 ){
977
                    zeroBilling = "Zero Billing";
978
                }else {
979
                    zeroBilling = "-";
980
                }
981
                zeroBillingMap.put(fofoId,zeroBilling);
982
 
983
                float billingNeeded = 0f;
34749 ranu 984
                if(drrPercentDisplay >= 110 && todayRequiredDrr > 0 ){
34641 ranu 985
                    billingNeeded = (float) todayRequiredDrr;
986
                }else {
987
                    billingNeeded = 0f;
988
                }
989
                billingNeededMap.put(fofoId,billingNeeded);
990
 
991
                int counta = 0;
34701 ranu 992
                if(defaultLoanAmount > 0 || investmentLevel <= 75 || currentMonthNetSecondary <= 100000 || drrPercentDisplay >= 110 ){
34641 ranu 993
                    counta = 1;
994
                }else {
995
                    counta = 0;
996
                }
997
                countAMap.put(fofoId,counta);
998
 
34606 ranu 999
        }
1000
 
34619 ranu 1001
        LOGGER.info("Total BI Retailers processed: {}", biRetailerModelMap.size());
34606 ranu 1002
 
34619 ranu 1003
        //generate excel and sent to mail
1004
        List<List<String>> headerGroup = new ArrayList<>();
34606 ranu 1005
 
34619 ranu 1006
        List<String> headers1 = Arrays.asList(
34641 ranu 1007
                "","","","",
34916 ranu 1008
                "Retailer Detail", "","", "", "", "", "", "", "", "","","","","",
34677 ranu 1009
 
1010
                twoMonthAgoStringValue, "", "", "", "", "", "",
1011
                lastMonthStringValue, "", "", "", "", "", "",
34619 ranu 1012
                currentMonthStringValue, "", "", "", "", "", "",
34641 ranu 1013
 
1014
                "","", "", "", "", "", "", "", "", "", "", "", "", "",
1015
 
1016
                "", "", "", "", "", "", "", "", "", "", "", "", "",
34749 ranu 1017
                "", "", "", "", "", "", "", "", "", "", "", "", "","",""
34641 ranu 1018
 
34619 ranu 1019
        );
34606 ranu 1020
 
34619 ranu 1021
        List<String> headers2 = Arrays.asList(
34641 ranu 1022
                "Assessment","Zero billing","Billing needed","Counta",
34916 ranu 1023
                "BM","Partner Id","Link","Wallet Date","Creation Date","Code","Area",  "City", "Store Name", "Status","Category","Sales Manager", "RBM","ABM",
34619 ranu 1024
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
1025
                "Tertiary Sale", "Unbilled",
1026
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
1027
                "Tertiary Sale", "Unbilled",
1028
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
1029
                "Tertiary Sale", "Unbilled",
34641 ranu 1030
                "Counter Potential", "Short investment", "Default", "INVESTMENT LEVEL", "Loan", "PO value", "Agreed investment",
1031
                "Wallet", "po+bill", "MONTH BEGINNING DRR", "REQ DRR", "Drr %", "Last billing Done", "Slab",
34606 ranu 1032
 
34721 ranu 1033
              "Total Stock",  "Apple","Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
1034
              "Total Secondary", "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
34749 ranu 1035
              "Total Tertiary",  "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "POCO", "Lava", "Itel", "Almost New",
1036
                "YesterDay Seconday","Day Before Yesterday Secondary"
34619 ranu 1037
        );
1038
 
1039
        headerGroup.add(headers1);
1040
        headerGroup.add(headers2);
1041
 
1042
 
1043
        List<List<?>> rows = new ArrayList<>();
1044
        for (Map.Entry<Integer, BIRetailerModel> entry : biRetailerModelMap.entrySet()) {
34749 ranu 1045
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
34619 ranu 1046
            Integer fofoId = entry.getKey();
34715 ranu 1047
            User user = userRepository.selectById(fofoId);
1048
            LocalDateTime walletCreationDate = userWalletHistoryRepository.selectFirstCreatedDate(fofoId);
34758 ranu 1049
            if(walletCreationDate == null){
1050
                walletCreationDate = user.getCreateTimestamp();
1051
            }
34619 ranu 1052
            BIRetailerModel retailer = entry.getValue();
34641 ranu 1053
 
34619 ranu 1054
            Map<YearMonth, BiSecondaryModel> monthlyData = allRetailerMonthlyData.get(fofoId);
1055
 
34741 ranu 1056
            BiSecondaryModel current = monthlyData.getOrDefault(currentMonth, new BiSecondaryModel(0,0,0,0,0,0,0));
1057
            BiSecondaryModel last = monthlyData.getOrDefault(currentMonth.minusMonths(1), new BiSecondaryModel(0,0,0,0,0,0,0));
1058
            BiSecondaryModel twoAgo = monthlyData.getOrDefault(currentMonth.minusMonths(2), new BiSecondaryModel(0,0,0,0,0,0,0));
34619 ranu 1059
 
1060
            List<Object> row = new ArrayList<>();
34758 ranu 1061
            LOGGER.info("fofoId-11 {}",fofoId);
1062
 
34619 ranu 1063
            row.addAll(Arrays.asList(
34758 ranu 1064
                    assessmentMap.get(fofoId),
1065
                    zeroBillingMap.get(fofoId),
1066
                    billingNeededMap.get(fofoId),
1067
                    countAMap.get(fofoId),
1068
                    retailer.getBmName(),
1069
                    fofoId ,
1070
                    "https://partners.smartdukaan.com/partnerPerformance?fofoId="+fofoId,
1071
                    walletCreationDate.format(formatter),
1072
                    user.getCreateTimestamp() != null ? (user.getCreateTimestamp()).format(formatter) : "-",
1073
                    retailer.getCode(),
1074
                    retailer.getArea(),
1075
                    retailer.getCity(),
1076
                    retailer.getStoreName(),
1077
                    retailer.getStatus(),
1078
                    retailer.getCategory(),
1079
                    retailer.getSalesManager(),
34915 ranu 1080
                    retailer.getRbm(),
1081
                    retailer.getAbm()
34677 ranu 1082
 
34619 ranu 1083
            ));
1084
 
34677 ranu 1085
 
1086
            // Two Months Ago
34619 ranu 1087
            row.addAll(Arrays.asList(
34677 ranu 1088
                    twoAgo.getSecondaryTarget(),
1089
                    twoAgo.getSecondaryAchieved(),
1090
                    twoAgo.getSecondaryReturn(),
1091
                    twoAgo.getNetSecondary(),
34704 ranu 1092
                    twoAgo.getSecondaryAchievedPercent()+"%",
34677 ranu 1093
                    twoAgo.getTertiary(),
1094
                    twoAgo.getTertiaryUnBilled()
34619 ranu 1095
            ));
1096
 
1097
            // Last Month
1098
            row.addAll(Arrays.asList(
1099
                    last.getSecondaryTarget(),
1100
                    last.getSecondaryAchieved(),
1101
                    last.getSecondaryReturn(),
1102
                    last.getNetSecondary(),
34704 ranu 1103
                    last.getSecondaryAchievedPercent()+"%",
34619 ranu 1104
                    last.getTertiary(),
1105
                    last.getTertiaryUnBilled()
1106
            ));
1107
 
34677 ranu 1108
            // Current Month
34619 ranu 1109
            row.addAll(Arrays.asList(
34677 ranu 1110
                    current.getSecondaryTarget(),
1111
                    current.getSecondaryAchieved(),
1112
                    current.getSecondaryReturn(),
1113
                    current.getNetSecondary(),
34704 ranu 1114
                    current.getSecondaryAchievedPercent()+"%",
34677 ranu 1115
                    current.getTertiary(),
1116
                    current.getTertiaryUnBilled()
34619 ranu 1117
            ));
34677 ranu 1118
 
1119
 
1120
 
34641 ranu 1121
            FofoInvestmentModel fofoInvestmentModelValue = biInvestmentModelMap.get(fofoId);
1122
            if(fofoInvestmentModelValue != null){
1123
                row.addAll(Arrays.asList(
1124
                        fofoInvestmentModelValue.getCounterPotential(),
1125
                        fofoInvestmentModelValue.getShortInvestment(),
1126
                        fofoInvestmentModelValue.getDefaultLoan(),
34730 ranu 1127
                        fofoInvestmentModelValue.getInvestmentLevel() +"%",
34743 ranu 1128
                        fofoInvestmentModelValue.getActiveLoan(),
34641 ranu 1129
                        fofoInvestmentModelValue.getPoValue(),
1130
                        fofoInvestmentModelValue.getAgreedInvestment(),
1131
                        fofoInvestmentModelValue.getWallet(),
1132
                        fofoInvestmentModelValue.getPoAndBilled(),
1133
                        fofoInvestmentModelValue.getMonthBeginingDrr(),
1134
                        fofoInvestmentModelValue.getRequiredDrr(),
34704 ranu 1135
                        fofoInvestmentModelValue.getDrrPercent()+"%",
34641 ranu 1136
                        fofoInvestmentModelValue.getLastBillingDone(),
1137
                        fofoInvestmentModelValue.getSlab()
1138
                ));
1139
            }else {
1140
                row.addAll(Arrays.asList(
1141
                        "-","-","-","-","-","-","-","-","-","-","-",""
1142
                ));
1143
            }
1144
 
1145
            Map<String, BrandStockPrice> brandStockMap = fofoBrandStockPriceMap.get(fofoId);
34619 ranu 1146
            row.addAll(Arrays.asList(
1147
                    fofoTotalStockPriceMap.getOrDefault(fofoId, 0.0),
34641 ranu 1148
                    brandStockMap.get("Apple") != null ? brandStockMap.get("Apple").getTotalValue() : 0.0,
1149
                    brandStockMap.get("Xiaomi") != null ? brandStockMap.get("Xiaomi").getTotalValue() : 0.0,
1150
                    brandStockMap.get("Vivo") != null ? brandStockMap.get("Vivo").getTotalValue() : 0.0,
1151
                    brandStockMap.get("Tecno") != null ? brandStockMap.get("Tecno").getTotalValue() : 0.0,
1152
                    brandStockMap.get("Samsung") != null ? brandStockMap.get("Samsung").getTotalValue() : 0.0,
1153
                    brandStockMap.get("Realme") != null ? brandStockMap.get("Realme").getTotalValue() : 0.0,
1154
                    brandStockMap.get("Oppo") != null ? brandStockMap.get("Oppo").getTotalValue() : 0.0,
1155
                    brandStockMap.get("OnePlus") != null ? brandStockMap.get("OnePlus").getTotalValue() : 0.0,
34721 ranu 1156
                    brandStockMap.get("POCO") != null ? brandStockMap.get("POCO").getTotalValue() : 0.0,
34641 ranu 1157
                    brandStockMap.get("Lava") != null ? brandStockMap.get("Lava").getTotalValue() : 0.0,
1158
                    brandStockMap.get("Itel") != null ? brandStockMap.get("Itel").getTotalValue() : 0.0,
1159
                    brandStockMap.get("Almost New") != null ? brandStockMap.get("Almost New").getTotalValue() : 0.0
34619 ranu 1160
            ));
1161
 
34641 ranu 1162
            Map<String, Long> brandSecondaryMap = fofoBrandWiseMtdSecondaryMap.get(fofoId);
1163
            row.addAll(Arrays.asList(
34648 ranu 1164
                    fofoTotalMtdSecondaryMap.get(fofoId),
34641 ranu 1165
                    brandSecondaryMap.getOrDefault("Apple", 0L),
1166
                    brandSecondaryMap.getOrDefault("Xiaomi", 0L),
1167
                    brandSecondaryMap.getOrDefault("Vivo", 0L),
1168
                    brandSecondaryMap.getOrDefault("Tecno", 0L),
1169
                    brandSecondaryMap.getOrDefault("Samsung", 0L),
1170
                    brandSecondaryMap.getOrDefault("Realme", 0L),
1171
                    brandSecondaryMap.getOrDefault("Oppo", 0L),
1172
                    brandSecondaryMap.getOrDefault("OnePlus", 0L),
34721 ranu 1173
                    brandSecondaryMap.getOrDefault("POCO", 0L),
34641 ranu 1174
                    brandSecondaryMap.getOrDefault("Lava", 0L),
1175
                    brandSecondaryMap.getOrDefault("Itel", 0L),
1176
                    brandSecondaryMap.getOrDefault("Almost New", 0L)
1177
            ));
1178
 
1179
            Map<String, Double> brandTertiaryMap = fofoBrandMtdTertiaryMap.get(fofoId);
1180
            row.addAll(Arrays.asList(
34648 ranu 1181
                    fofoTotalMtdTertiaryMap.get(fofoId),
34641 ranu 1182
                    brandTertiaryMap.getOrDefault("Apple", 0d),
1183
                    brandTertiaryMap.getOrDefault("Xiaomi", 0d),
1184
                    brandTertiaryMap.getOrDefault("Vivo", 0d),
1185
                    brandTertiaryMap.getOrDefault("Tecno", 0d),
1186
                    brandTertiaryMap.getOrDefault("Samsung", 0d),
1187
                    brandTertiaryMap.getOrDefault("Realme", 0d),
1188
                    brandTertiaryMap.getOrDefault("Oppo", 0d),
1189
                    brandTertiaryMap.getOrDefault("OnePlus", 0d),
34721 ranu 1190
                    brandTertiaryMap.getOrDefault("POCO", 0d),
34641 ranu 1191
                    brandTertiaryMap.getOrDefault("Lava", 0d),
1192
                    brandTertiaryMap.getOrDefault("Itel", 0d),
1193
                    brandTertiaryMap.getOrDefault("Almost New", 0d)
1194
            ));
34749 ranu 1195
 
1196
            row.addAll(Arrays.asList(
1197
                    fofoYesterdaySecondaryMap.get(fofoId),
1198
                    fofoDayBeforeYesterdaySecondaryMap.get(fofoId)
1199
            ));
34641 ranu 1200
            rows.add(row);
34619 ranu 1201
        }
1202
 
34912 ranu 1203
        Map<String, Set<Integer>> storeGuyMap = this.generateBiReportHierarchyWise();
34619 ranu 1204
 
34922 ranu 1205
        for (Map.Entry<String, Set<Integer>> storeGuyEntry : storeGuyMap.entrySet()) {
34912 ranu 1206
            String storeGuyEmail = storeGuyEntry.getKey();
1207
            Set<Integer> fofoIds = storeGuyEntry.getValue();
1208
            String[] sendToArray = new String[]{storeGuyEmail};
34911 ranu 1209
 
34912 ranu 1210
            List<List<?>> filteredRows = rows.stream()
1211
                    .filter(row -> row.size() > 5 && fofoIds.contains((Integer) row.get(5)))
1212
                    .collect(Collectors.toList());
1213
            this.sendMailToUser(headerGroup,filteredRows,sendToArray);
34922 ranu 1214
        }
34912 ranu 1215
 
1216
        this.sendMailToUser(headerGroup,rows,new String[]{"ranu.rajput@smartdukaan.com"});
1217
 
1218
 
34911 ranu 1219
    }
1220
 
1221
    private  void sendMailToUser(List<List<String>> headerGroup,List<List<?>> rows, String[] sendToArray ) throws Exception {
34641 ranu 1222
        // Send to email
1223
//        ByteArrayOutputStream csvStream = FileUtil.getCSVByteStreamWithMultiHeaders(headerGroup, rows);
1224
        ByteArrayOutputStream csvStream = getExcelStreamWithMultiHeaders(headerGroup, rows);
1225
        String fileName = "BI-Retailer-Monthly-Report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".xlsx";
34619 ranu 1226
        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 1227
    }
34619 ranu 1228
 
1229
 
34641 ranu 1230
    public static ByteArrayOutputStream getExcelStreamWithMultiHeaders(List<List<String>> headerGroup, List<List<?>> rows) {
1231
        Workbook workbook = new XSSFWorkbook();
1232
        Sheet sheet = workbook.createSheet("BI Report");
34715 ranu 1233
        CreationHelper creationHelper = workbook.getCreationHelper();
34641 ranu 1234
        int rowIndex = 0;
34606 ranu 1235
 
34641 ranu 1236
        CellStyle centeredStyle = workbook.createCellStyle();
1237
        centeredStyle.setAlignment(HorizontalAlignment.CENTER); // Center horizontally
1238
        centeredStyle.setVerticalAlignment(VerticalAlignment.CENTER); // Center vertically
34606 ranu 1239
 
34641 ranu 1240
    // Optional: bold font
1241
        Font font1 = workbook.createFont();
1242
        font1.setBold(true);
1243
        centeredStyle.setFont(font1);
34606 ranu 1244
 
34619 ranu 1245
 
34641 ranu 1246
 
1247
        // Create styles
1248
        Map<String, CellStyle> headerStyles = new HashMap<>();
1249
 
1250
        // fontPurpleStyle
1251
        CellStyle purpleStyle = workbook.createCellStyle();
1252
        purpleStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
1253
        purpleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1254
        purpleStyle.setFont(font1);
1255
        headerStyles.put("Assessment", purpleStyle);
1256
        headerStyles.put("Zero billing", purpleStyle);
1257
        headerStyles.put("Billing needed", purpleStyle);
1258
        headerStyles.put("Counta", purpleStyle);
1259
        headerStyles.put("MONTH BEGINNING DRR", purpleStyle);
1260
        headerStyles.put("REQ DRR", purpleStyle);
1261
        headerStyles.put("Drr %", purpleStyle);
1262
 
1263
        // Light Blue
1264
        CellStyle blueStyle = workbook.createCellStyle();
1265
        blueStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
1266
        blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1267
        blueStyle.setFont(font1);
1268
        headerStyles.put("Code", blueStyle);
1269
        headerStyles.put("Store Name", blueStyle);
1270
        headerStyles.put("City", blueStyle);
1271
        headerStyles.put("Area", blueStyle);
1272
        headerStyles.put("BM", blueStyle);
1273
        headerStyles.put("RBM", blueStyle);
1274
        headerStyles.put("Sales Manager", blueStyle);
1275
        headerStyles.put("Status", blueStyle);
1276
        headerStyles.put("Category", blueStyle);
34715 ranu 1277
        headerStyles.put("Wallet Date", blueStyle);
1278
        headerStyles.put("Creation Date", blueStyle);
1279
        headerStyles.put("Partner Id", blueStyle);
34641 ranu 1280
 
34715 ranu 1281
        //for link
1282
        // Create hyperlink style
1283
        CellStyle hyperlinkStyle = workbook.createCellStyle();
1284
        Font hlinkFont = workbook.createFont();
1285
        hlinkFont.setUnderline(Font.U_SINGLE);
1286
        hlinkFont.setColor(IndexedColors.BLUE.getIndex());
1287
        hyperlinkStyle.setFont(hlinkFont);
1288
 
1289
 
34641 ranu 1290
        // Light Yellow
1291
        CellStyle yellowStyle = workbook.createCellStyle();
1292
        yellowStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
1293
        yellowStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1294
        yellowStyle.setFont(font1);
1295
        headerStyles.put("Last billing Done", yellowStyle);
1296
        headerStyles.put("Total Stock", yellowStyle);
1297
 
1298
        // Light Orange
1299
        CellStyle orangeStyle = workbook.createCellStyle();
1300
        orangeStyle.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
1301
        orangeStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1302
        orangeStyle.setFont(font1);
1303
        headerStyles.put("Total Tertiary", orangeStyle);
1304
        headerStyles.put("Total Secondary", orangeStyle);
1305
        headerStyles.put("Default", orangeStyle);
1306
 
1307
 
1308
        // Light green
1309
        CellStyle lightGreenStyle = workbook.createCellStyle();
1310
        lightGreenStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
1311
        lightGreenStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1312
        lightGreenStyle.setFont(font1);
1313
        headerStyles.put("Short investment", lightGreenStyle);
1314
        headerStyles.put("INVESTMENT LEVEL", lightGreenStyle);
1315
        headerStyles.put("Loan", lightGreenStyle);
1316
        headerStyles.put("PO value", lightGreenStyle);
1317
        headerStyles.put("Agreed investment", lightGreenStyle);
1318
        headerStyles.put("Wallet", lightGreenStyle);
1319
        headerStyles.put("po+bill", lightGreenStyle);
1320
 
1321
        // Light Green
1322
        CellStyle secondary1 = createStyle(workbook, IndexedColors.LIGHT_GREEN);
1323
        CellStyle secondary2 = createStyle(workbook, IndexedColors.LIGHT_YELLOW);
1324
        CellStyle secondary3 = createStyle(workbook, IndexedColors.LIGHT_ORANGE);
1325
 
1326
        Map<String, CellStyle> brandStyles = new HashMap<>();
1327
        brandStyles.put("Apple", createStyle(workbook, IndexedColors.GREY_25_PERCENT));
1328
        brandStyles.put("Xiaomi", createStyle(workbook, IndexedColors.ORANGE));
1329
        brandStyles.put("Vivo", createStyle(workbook, IndexedColors.SKY_BLUE));
1330
        brandStyles.put("Tecno", createStyle(workbook, IndexedColors.LIGHT_BLUE));
1331
        brandStyles.put("Samsung", createStyle(workbook, IndexedColors.ROYAL_BLUE));
1332
        brandStyles.put("Realme", createStyle(workbook, IndexedColors.YELLOW));
1333
        brandStyles.put("Oppo", createStyle(workbook, IndexedColors.LIGHT_GREEN));
1334
        brandStyles.put("OnePlus", createStyle(workbook, IndexedColors.RED));
34721 ranu 1335
        brandStyles.put("POCO", createStyle(workbook, IndexedColors.ORANGE));
34641 ranu 1336
        brandStyles.put("Lava", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1337
        brandStyles.put("Itel", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1338
        brandStyles.put("Almost New", createStyle(workbook, IndexedColors.WHITE));
1339
 
1340
 
1341
        CellStyle defaultHeaderStyle = workbook.createCellStyle();
1342
        defaultHeaderStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
1343
        defaultHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1344
        defaultHeaderStyle.setFont(font1);
1345
 
34749 ranu 1346
        CellStyle numberStyle = workbook.createCellStyle();
1347
        DataFormat format = workbook.createDataFormat();
1348
        numberStyle.setDataFormat(format.getFormat("#,##0")); // or "#,##0.00" for two decimals
34641 ranu 1349
 
34749 ranu 1350
 
1351
 
34641 ranu 1352
        Map<String, Integer> headerCount = new HashMap<>();
1353
 
1354
        for (int headerRowIndex = 0; headerRowIndex < headerGroup.size(); headerRowIndex++) {
1355
            List<String> headerRow = headerGroup.get(headerRowIndex);
1356
            Row row = sheet.createRow(rowIndex++);
1357
 
1358
            for (int i = 0; i < headerRow.size(); i++) {
1359
                String headerText = headerRow.get(i);
1360
                sheet.setColumnWidth(i, 25 * 256);
1361
                row.setHeightInPoints(20); // 25-point height
1362
                Cell cell = row.createCell(i);
1363
                cell.setCellValue(headerText);
1364
                cell.setCellStyle(centeredStyle);
1365
                // Count how many times this header has appeared
1366
                int count = headerCount.getOrDefault(headerText, 0) + 1;
1367
                headerCount.put(headerText, count);
1368
                // Apply special style for repeated headers
1369
                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")) {
1370
                    if (count == 1) {
1371
                        cell.setCellStyle(secondary1);
1372
                    } else if (count == 2) {
1373
                        cell.setCellStyle(secondary2);
1374
                    } else if (count == 3) {
1375
                        cell.setCellStyle(secondary3);
1376
                    }
1377
                }
1378
                // Brand header styling (apply only for the 2nd row of headers)
1379
                else if (headerRowIndex == 1 && brandStyles.containsKey(headerText)) {
1380
                    cell.setCellStyle(brandStyles.get(headerText));
1381
                }else if (headerStyles.containsKey(headerText)) {
1382
                    cell.setCellStyle(headerStyles.get(headerText));
1383
                } else {
1384
                    cell.setCellStyle(defaultHeaderStyle); // default style for others
1385
                }
1386
            }
1387
        }
1388
 
1389
        // Write data rows
1390
        for (List<?> dataRow : rows) {
1391
            Row row = sheet.createRow(rowIndex++);
1392
            for (int i = 0; i < dataRow.size(); i++) {
1393
                Cell cell = row.createCell(i);
1394
                Object value = dataRow.get(i);
34715 ranu 1395
 
1396
                if (i == 6 && value != null) { // Assuming column 6 is "Link"
1397
                    Hyperlink hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
1398
                    hyperlink.setAddress(value.toString());
34719 ranu 1399
                    cell.setCellValue("View Link"); // Display text
34715 ranu 1400
                    cell.setHyperlink(hyperlink);
1401
                    cell.setCellStyle(hyperlinkStyle);
34719 ranu 1402
                } else if (value instanceof Number) {
34749 ranu 1403
                    double numeric = ((Number) value).doubleValue();
1404
                    cell.setCellValue(Math.round(numeric));
1405
                    cell.setCellStyle(numberStyle);
34715 ranu 1406
                } else {
1407
                    cell.setCellValue(value != null ? value.toString() : "");
1408
                }
34641 ranu 1409
            }
34719 ranu 1410
 
34641 ranu 1411
        }
1412
 
1413
        // Auto-size columns
1414
        if (!rows.isEmpty()) {
1415
            for (int i = 0; i < rows.get(0).size(); i++) {
1416
                sheet.autoSizeColumn(i);
1417
            }
1418
        }
1419
 
1420
        // Output as ByteArray
1421
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
1422
            workbook.write(outputStream);
1423
            workbook.close();
1424
            return outputStream;
1425
        } catch (IOException e) {
1426
            throw new RuntimeException("Failed to generate Excel file", e);
1427
        }
1428
    }
1429
 
1430
 
1431
    private static CellStyle createStyle(Workbook workbook, IndexedColors color) {
1432
        CellStyle style = workbook.createCellStyle();
1433
        style.setFillForegroundColor(color.getIndex());
1434
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1435
        Font font = workbook.createFont();
1436
        font.setBold(true);
1437
        style.setFont(font);
1438
        return style;
1439
    }
1440
 
1441
 
34758 ranu 1442
    public void stockAlertMailToRetailer() throws Exception {
1443
 
1444
        Map<Integer, CustomRetailer> customRetailers = retailerService.getFofoRetailers(true);
1445
 
1446
        List<Integer> retailerIds = customRetailers.values().stream().map(CustomRetailer::getPartnerId).collect(Collectors.toList());
1447
 
1448
        for(Integer fofoId : retailerIds){
1449
            List<String> statusOrder = Arrays.asList("HID", "FASTMOVING", "RUNNING", "SLOWMOVING", "OTHER");
1450
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
1451
            List<PartnerWarehouseStockSummaryModel> partnerWarehouseStockSummaryModels = saholicInventoryService.getSaholicAndPartnerStock(fofoId, fofoStore.getWarehouseId());
1452
 
1453
            List<PartnerWarehouseStockAgingSummaryModel> partnerWarehouseStockAgingSummaryModelList = new ArrayList<>();
1454
 
1455
            Set<Integer> catalogIds = partnerWarehouseStockSummaryModels.stream().map(x -> x.getCatalogId()).collect(Collectors.toSet());
1456
 
1457
            List<Integer> catalogsList = new ArrayList<>(catalogIds);
1458
 
1459
            Map<Integer, TagListing> tagListingsMap = tagListingRepository.selectAllByCatalogIds(catalogsList);
1460
 
1461
            List<CatalogAgingModel> catalogAgingModels = ageingService.getCatalogsAgingByWarehouse(catalogIds, fofoStore.getWarehouseId());
1462
 
1463
            Map<Integer, CatalogAgingModel> catalogAgingModelMap = catalogAgingModels.stream().collect(Collectors.toMap(x -> x.getCatalogId(), x -> x));
1464
 
1465
            for (PartnerWarehouseStockSummaryModel stockSummary : partnerWarehouseStockSummaryModels) {
1466
 
1467
                PartnerWarehouseStockAgingSummaryModel partnerWarehouseStockAgingSummaryModel = new PartnerWarehouseStockAgingSummaryModel();
1468
                partnerWarehouseStockAgingSummaryModel.setCatalogId(stockSummary.getCatalogId());
1469
                partnerWarehouseStockAgingSummaryModel.setBrand(stockSummary.getBrand());
1470
                partnerWarehouseStockAgingSummaryModel.setModelNumber(stockSummary.getModelNumber());
1471
                partnerWarehouseStockAgingSummaryModel.setNetAvailability(stockSummary.getShaholicNetAvailability());
1472
                partnerWarehouseStockAgingSummaryModel.setPartnerStockAvailability(stockSummary.getPartnerFullFilledQty());
1473
                partnerWarehouseStockAgingSummaryModel.setPartnerCurrentAvailability(stockSummary.getPartnerCurrentQty());
1474
                partnerWarehouseStockAgingSummaryModel.setPartnerShortageStock(stockSummary.getPartnerShortageQty());
1475
                if (catalogAgingModelMap.get(stockSummary.getCatalogId()) != null) {
1476
                    partnerWarehouseStockAgingSummaryModel.setExceedDays(catalogAgingModelMap.get(stockSummary.getCatalogId()).getExceedDays());
1477
                } else {
1478
                    partnerWarehouseStockAgingSummaryModel.setExceedDays(0);
1479
 
1480
                }
1481
                partnerWarehouseStockAgingSummaryModel.setStatus(stockSummary.getStatus());
1482
 
1483
                partnerWarehouseStockAgingSummaryModelList.add(partnerWarehouseStockAgingSummaryModel);
1484
            }
1485
 
1486
            Set<Integer> existingCatalogIdsInAgingSummaryList = partnerWarehouseStockAgingSummaryModelList.stream()
1487
                    .map(PartnerWarehouseStockAgingSummaryModel::getCatalogId)
1488
                    .collect(Collectors.toSet());
1489
        }
1490
 
1491
    }
1492
 
1493
 
34306 ranu 1494
}