Subversion Repositories SmartDukaan

Rev

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