Subversion Repositories SmartDukaan

Rev

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