Subversion Repositories SmartDukaan

Rev

Rev 34653 | Rev 34676 | 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");
34655 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
 
34655 ranu 459
   /*     List<Integer> retailerIds = Arrays.asList(175139401,175139400,175139381,175139667,175139662,175139661,175130896,175139323,175139452);
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();
478
        LocalDateTime currentMonthEndDate = LocalDateTime.now();
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();
541
            }
542
            String bmName ="";
34606 ranu 543
            int bmId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L2,fofoId);
34619 ranu 544
            if(bmId !=0){
545
                bmName = authRepository.selectById(bmId).getFullName();
546
            }
34606 ranu 547
 
548
            int managerId = csService.getAuthUserId(ProfitMandiConstants.TICKET_CATEGORY_SALES,EscalationType.L1,fofoId);
549
            String managerName = " ";
550
            if(managerId != 0){
551
                 managerName = authRepository.selectById(managerId).getFullName();
552
            }else {
553
                managerName = bmName;
554
            }
555
 
556
            AST ast = astRepository.selectById(customRetailers.get(fofoId).getAstId());
557
 
558
            PartnerType partnerTypeThisMonth = partnerTypeChangeService.getTypeOnMonth(fofoId, YearMonth.now());
559
 
560
//            generate retaile detail
561
 
562
            BIRetailerModel biRetailerModel = new BIRetailerModel();
563
            biRetailerModel.setBmName(bmName);
564
            biRetailerModel.setCode(customRetailers.get(fofoId).getCode());
34619 ranu 565
            if(ast != null){
566
                biRetailerModel.setArea(ast.getArea());
567
            }else {
568
                biRetailerModel.setArea("-");
569
            }
34606 ranu 570
            biRetailerModel.setCity(customRetailers.get(fofoId).getAddress().getCity());
571
            biRetailerModel.setStoreName(customRetailers.get(fofoId).getBusinessName());
34619 ranu 572
            biRetailerModel.setStatus(String.valueOf(customRetailers.get(fofoId).getActivationType()));
34606 ranu 573
            biRetailerModel.setCategory(String.valueOf(partnerTypeThisMonth));
574
            biRetailerModel.setSalesManager(managerName);
575
            biRetailerModel.setRbm(rbmName);
576
 
34619 ranu 577
            biRetailerModelMap.put(fofoId,biRetailerModel);
578
 
34641 ranu 579
 
34606 ranu 580
//            generate secondary data
581
 
34641 ranu 582
            List<PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledMonthlyTotals = activatedImeiRepository.getTotalMonthlyActivatedNotBilled(fofoId,twoMonthsAgoStartDate);
583
            Map<YearMonth , PartnerWiseActivatedNotBilledTotal> partnerWiseActivatedNotBilledTotalMap = partnerWiseActivatedNotBilledMonthlyTotals.stream().collect(Collectors.toMap(x-> YearMonth.parse(x.getYearMonth()),x->x));
584
 
34606 ranu 585
//            this month secondary target
586
 
34619 ranu 587
            double currentSecondaryTarget =  monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId).getPurchaseTarget() : 0;
34606 ranu 588
 
34619 ranu 589
 
590
            long currentMonthReturn = currentMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId, 0L) + currentMonthRtoRefundOrderMap.getOrDefault(fofoId, 0L);
591
 
592
 
34606 ranu 593
            Map<Integer, Double> secondaryMtd = orderRepository.selectOrderValueBetweenDatesGroupByFofoId(Arrays.asList(fofoId),
594
                    Arrays.asList(OrderStatus.BILLED, OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.DELIVERY_SUCCESS, OrderStatus.ACCEPTED, OrderStatus.SUBMITTED_FOR_PROCESSING),
595
                    startOfToday.withDayOfMonth(1), startOfToday.with(LocalTime.MAX)).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
596
 
597
            double secondaryAchievedMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
598
 
34619 ranu 599
            double currentMonthNetSecondary = secondaryAchievedMtd - currentMonthReturn;
34606 ranu 600
 
34619 ranu 601
            double currentMonthSecondaryPercent = currentSecondaryTarget == 0 ? 0.0 : (secondaryAchievedMtd / currentSecondaryTarget) * 100;
602
 
34641 ranu 603
            double currentMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(currentMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(currentMonth).getTotalUnbilledAmount() : 0d;
34619 ranu 604
 
605
//          this month tertiary----------
606
 
607
            LocalDateTime now = LocalDateTime.now();
608
            double todaySale = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday, now, fofoId, false).get(fofoId);
609
            double mtdSaleTillYesterDay = fofoOrderItemRepository.selectSumMopGroupByRetailer(startOfToday.withDayOfMonth(1), startOfToday, fofoId, false).get(fofoId);
610
            double mtdSale = mtdSaleTillYesterDay + todaySale;
611
 
612
 
34606 ranu 613
//            last month secondary target
614
 
34619 ranu 615
            double lastMonthSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId) != null ?  monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId).getPurchaseTarget() : 0;
34606 ranu 616
 
34619 ranu 617
            long lastMonthReturn = (lastMonthPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + lastMonthRtoRefundOrderMap.getOrDefault(fofoId,0L));
618
 
34606 ranu 619
            Map<Integer, Double> lastMonthSecondary = orderRepository.selectOrderValueBetweenDatesGroupByFofoId(Arrays.asList(fofoId),
620
                    Arrays.asList(OrderStatus.BILLED, OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.DELIVERY_SUCCESS, OrderStatus.ACCEPTED, OrderStatus.SUBMITTED_FOR_PROCESSING),
621
                    lastMontStartDate, lastMonthEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
622
 
623
            double lastMonthSecondaryAchieved = lastMonthSecondary.getOrDefault(fofoId, 0.0);
624
 
34619 ranu 625
            double lastMonthNetSecondary = lastMonthSecondaryAchieved - lastMonthReturn;
34606 ranu 626
 
34619 ranu 627
            double lastMonthSecondaryPercent = lastMonthSecondaryTarget == 0 ? 0.0 : (lastMonthSecondaryAchieved / lastMonthSecondaryTarget) * 100;
34606 ranu 628
 
34641 ranu 629
            double lastMonthUnbilled = partnerWiseActivatedNotBilledTotalMap.get(lastMonth) != null ? partnerWiseActivatedNotBilledTotalMap.get(lastMonth).getTotalUnbilledAmount() : 0d;
34606 ranu 630
 
34619 ranu 631
//           last month tertiary
632
            Double lastMonthSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
633
                    lastMontStartDate, lastMonthEndDate, fofoId, false).get(fofoId);
634
 
635
 
636
//            two month ago secondary target
637
 
638
            double twoMonthAgoSecondaryTarget = monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId) != null ? monthlyTargetRepository.selectByDateAndFofoId(lastMonth, fofoId).getPurchaseTarget() : 0;
639
 
640
            long twoMonthAgoReturn = (twoMonthAgoPartnerReturnOrderInfoModelMap.getOrDefault(fofoId,0L) + twoMonthAgoRtoRefundOrderMap.getOrDefault(fofoId,0L));
641
 
34606 ranu 642
            Map<Integer, Double> twoMonthAgoSecondary = orderRepository.selectOrderValueBetweenDatesGroupByFofoId(Arrays.asList(fofoId),
643
                    Arrays.asList(OrderStatus.BILLED, OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.DELIVERY_SUCCESS, OrderStatus.ACCEPTED, OrderStatus.SUBMITTED_FOR_PROCESSING),
644
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate).stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getAmount()));
645
 
646
            double twoMonthAgoSecondaryAchieved = twoMonthAgoSecondary.getOrDefault(fofoId, 0.0);
647
 
34619 ranu 648
            double twoMonthAgoNetSecondary = twoMonthAgoSecondaryAchieved - twoMonthAgoReturn;
34606 ranu 649
 
34619 ranu 650
            double twoMonthAgoSecondaryPercent = twoMonthAgoSecondaryTarget == 0 ? 0.0 : (twoMonthAgoSecondaryAchieved / twoMonthAgoSecondaryTarget) * 100;
651
 
34641 ranu 652
            double twoMonthAgoUnbilled = partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo) != null ? partnerWiseActivatedNotBilledTotalMap.get(twoMonthsAgo).getTotalUnbilledAmount() : 0d;
34619 ranu 653
 
654
//          second Month Tertiary
655
            double twoMonthAgoSale = fofoOrderItemRepository.selectSumMopGroupByRetailer(
656
                    twoMonthsAgoStartDate, twoMonthsAgoEndDate, fofoId, false).get(fofoId);
657
 
658
 
659
            Map<YearMonth, BiSecondaryModel> monthlySecondaryModels = new HashMap<>();
660
 
661
            BiSecondaryModel currentMonthSecondaryModel = new BiSecondaryModel(
662
                    currentSecondaryTarget,
663
                    secondaryAchievedMtd,
664
                    currentMonthReturn,
665
                    currentMonthNetSecondary,
666
                    currentMonthSecondaryPercent,
667
                    mtdSale,
668
                    currentMonthUnbilled // for now, unbilled tertiary value
669
            );
670
 
671
            BiSecondaryModel lastMonthSecondaryModel = new BiSecondaryModel(
672
                    lastMonthSecondaryTarget,
673
                    lastMonthSecondaryAchieved,
674
                    lastMonthReturn,
675
                    lastMonthNetSecondary,
676
                    lastMonthSecondaryPercent,
677
                    lastMonthSale,
678
                    lastMonthUnbilled // for now, unbilled tertiary value
679
            );
680
 
681
            BiSecondaryModel twoMonthAgoSecondaryModel = new BiSecondaryModel(
682
                    twoMonthAgoSecondaryTarget,
683
                    twoMonthAgoSecondaryAchieved,
684
                    twoMonthAgoReturn,
685
                    twoMonthAgoNetSecondary,
686
                    twoMonthAgoSecondaryPercent,
687
                    twoMonthAgoSale,
688
                    twoMonthAgoUnbilled // for now, unbilled tertiary value
689
            );
690
 
691
            monthlySecondaryModels.put(currentMonth, currentMonthSecondaryModel);
692
            monthlySecondaryModels.put(lastMonth, lastMonthSecondaryModel);
693
            monthlySecondaryModels.put(twoMonthsAgo, twoMonthAgoSecondaryModel);
694
 
695
            allRetailerMonthlyData.put(fofoId, monthlySecondaryModels);
696
 
697
//            brandwiseStock value price
698
 
699
            Map<String, BrandStockPrice> brandStockPriceMap = inventoryService.getBrandWiseStockValue(fofoId);
700
 
701
            fofoBrandStockPriceMap.put(fofoId,brandStockPriceMap);
702
 
703
            double totalStockPrice = brandStockPriceMap.values().stream().mapToDouble(x->x.getTotalValue()).sum();
704
 
705
            fofoTotalStockPriceMap.put(fofoId,totalStockPrice);
706
 
707
            Map<String, Double> brandMtdTertiaryAmount = fofoOrderItemRepository.selectSumAmountGroupByBrand(
708
                    currentMonthStartDate, currentMonthEndDate, fofoId);
709
 
34641 ranu 710
            fofoBrandMtdTertiaryMap.put(fofoId,brandMtdTertiaryAmount);
34619 ranu 711
 
712
            double totalMtdTertiaryAmount = brandMtdTertiaryAmount.values().stream().mapToDouble(Double::doubleValue).sum();
713
 
34641 ranu 714
            fofoTotalMtdTertiaryMap.put(fofoId,totalMtdTertiaryAmount);
34619 ranu 715
 
34641 ranu 716
            List<BrandWiseModel> brandWiseMtdSecondary = orderRepository.selectAllBilledOrderGroupByBrandFofoId(fofoId, currentMonthStartDate);
717
            Map<String,Long> brandWiseMtdSecondaryMap = brandWiseMtdSecondary.stream().collect(Collectors.toMap(BrandWiseModel::getBrand,BrandWiseModel::getAmount));
718
            fofoBrandWiseMtdSecondaryMap.put(fofoId,brandWiseMtdSecondaryMap);
34619 ranu 719
 
34641 ranu 720
            long mtdTotalSecondary = brandWiseMtdSecondary.stream().mapToLong(x -> x.getAmount() != 0 ? x.getAmount() : 0L).sum();
34619 ranu 721
 
34641 ranu 722
            fofoTotalMtdSecondaryMap.put(fofoId,mtdTotalSecondary);
723
 
724
            //            generate investment info
725
            FofoStore fofoStore = fofoStoreRepository.selectByRetailerId(fofoId);
726
            float shortInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getShortInvestment() : 0f;
727
            float agreedInvestment = partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getMinInvestment() : 0f;
728
            float investmentLevel = partnerDailyInvestmentMap.get(fofoId) != null ? ((shortInvestment-agreedInvestment)/agreedInvestment)*100 : 0f;
729
 
730
            List<Loan> fofoDefaultLoans = new ArrayList<>();
731
            if(defaultLoanMap != null){
732
                 fofoDefaultLoans  =  defaultLoanMap.get(fofoId);
733
                LOGGER.info("fofoDefaultLoans {}",fofoDefaultLoans);
734
            }
735
 
736
            float defaultLoanAmount = 0f;
737
            if(fofoDefaultLoans != null ){
738
                if (!fofoDefaultLoans.isEmpty()) {
739
                    defaultLoanAmount =  fofoDefaultLoans.stream().map(Loan::getPendingAmount).reduce(BigDecimal.ZERO, BigDecimal::add).floatValue(); // or .floatValue() directly
740
                }
741
            }
742
 
743
            float activeLoan = loanRepository.selectActiveLoan(fofoId).stream().map(Loan::getPendingAmount).reduce(BigDecimal.ZERO,BigDecimal::add).floatValue();
744
 
745
 
746
            float poValue = partnerDailyInvestmentMap.get(fofoId) != null ?  partnerDailyInvestmentMap.get(fofoId).getUnbilledAmount() : 0f;
747
 
748
            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),startOfToday,startOfToday.plusDays(1));
749
            float poAndBilledValue = (float) billedAndPoOrder.stream().map(Order::getTotalAmount).reduce(0f,Float::sum);
750
 
751
            double purchaseMtd = secondaryMtd.getOrDefault(fofoId, 0.0);
752
 
753
            double todayRequiredDrr = rbmTargetService.calculateFofoIdTodayTarget(fofoId, purchaseMtd,LocalDate.now());
754
 
755
            double monthDay1Drr = rbmTargetService.calculateFofoIdTodayTarget(fofoId,0d,YearMonth.now().atDay(1));
756
 
757
 
758
            double gotDrrPercent = (todayRequiredDrr / monthDay1Drr) * 100;
759
 
760
            int orderId = orderRepository.getLastOrderByFofoId(fofoId);
761
 
34644 ranu 762
            // Determine alert level
763
            String alertLevel = "-";
764
            int lastPurchaseDays = 0;
34641 ranu 765
            if (orderId != 0) {
766
                Order order = orderRepository.selectById(orderId);
767
 
768
                // Calculate the number of days since the last purchase (billing)
34644 ranu 769
                lastPurchaseDays = (int) Duration.between(order.getCreateTimestamp().plusDays(1), LocalDateTime.now()).toDays();
34641 ranu 770
 
771
                if (lastPurchaseDays >= 11) {
772
                    alertLevel = "Alert for Management";
773
                } else if (lastPurchaseDays >= 8) {
774
                    alertLevel = " Alert for RSM/SH";
775
                } else if (lastPurchaseDays >= 6) {
776
                    alertLevel = "Must be Billed";
777
                } else if (lastPurchaseDays >= 3) {
778
                    alertLevel = "OK";
779
                } else {
780
                    alertLevel = "No Action Needed";
781
                }
34644 ranu 782
            }
34641 ranu 783
 
34644 ranu 784
            //investment modal set all related value
785
            FofoInvestmentModel fofoInvestmentModel = new FofoInvestmentModel();
34641 ranu 786
 
34644 ranu 787
            fofoInvestmentModel.setCounterPotential(fofoStore.getCounterPotential());
788
            fofoInvestmentModel.setShortInvestment(shortInvestment);
789
            fofoInvestmentModel.setDefaultLoan(defaultLoanAmount);
790
            fofoInvestmentModel.setInvestmentLevel(investmentLevel);
791
            fofoInvestmentModel.setActiveLoan(activeLoan);
792
            fofoInvestmentModel.setPoValue(poValue);
793
            fofoInvestmentModel.setPoAndBilled(poAndBilledValue);
794
            fofoInvestmentModel.setAgreedInvestment(agreedInvestment);
795
            fofoInvestmentModel.setWallet(partnerDailyInvestmentMap.get(fofoId) != null ? partnerDailyInvestmentMap.get(fofoId).getWalletAmount() : 0);
796
            fofoInvestmentModel.setMonthBeginingDrr(monthDay1Drr);
797
            fofoInvestmentModel.setRequiredDrr(todayRequiredDrr);
798
            fofoInvestmentModel.setDrrPercent(gotDrrPercent);
799
            fofoInvestmentModel.setLastBillingDone(lastPurchaseDays);
800
            fofoInvestmentModel.setSlab(alertLevel);
34641 ranu 801
 
34644 ranu 802
            biInvestmentModelMap.put(fofoId, fofoInvestmentModel);
34641 ranu 803
                String assessment = "";
804
                if(defaultLoanAmount > 0 ){
805
                    assessment = "Loan Default";
806
                }else if(investmentLevel <= 75 && defaultLoanAmount < 1){
807
                    assessment = "Low Invest";
808
                }else {
809
                    assessment = "-";
810
                }
811
                assessmentMap.put(fofoId,assessment);
812
 
813
                String zeroBilling = "";
814
                if(currentMonthNetSecondary <= 100000 ){
815
                    zeroBilling = "Zero Billing";
816
                }else {
817
                    zeroBilling = "-";
818
                }
819
                zeroBillingMap.put(fofoId,zeroBilling);
820
 
821
                float billingNeeded = 0f;
822
                if(gotDrrPercent >= 110 ){
823
                    billingNeeded = (float) todayRequiredDrr;
824
                }else {
825
                    billingNeeded = 0f;
826
                }
827
                billingNeededMap.put(fofoId,billingNeeded);
828
 
829
                int counta = 0;
830
                if(defaultLoanAmount > 0 || investmentLevel <= 75 || currentMonthNetSecondary <= 100000 || gotDrrPercent >= 110 ){
831
                    counta = 1;
832
                }else {
833
                    counta = 0;
834
                }
835
                countAMap.put(fofoId,counta);
836
 
34606 ranu 837
        }
838
 
34619 ranu 839
        LOGGER.info("Total BI Retailers processed: {}", biRetailerModelMap.size());
34606 ranu 840
 
34619 ranu 841
        //generate excel and sent to mail
842
        List<List<String>> headerGroup = new ArrayList<>();
34606 ranu 843
 
34619 ranu 844
        List<String> headers1 = Arrays.asList(
34641 ranu 845
                "","","","",
846
                "Retailer Detail", "", "", "", "", "", "", "", "",
34619 ranu 847
                currentMonthStringValue, "", "", "", "", "", "",
848
                lastMonthStringValue, "", "", "", "", "", "",
34641 ranu 849
                twoMonthAgoStringValue, "", "", "", "", "", "",
850
 
851
                "","", "", "", "", "", "", "", "", "", "", "", "", "",
852
 
853
                "", "", "", "", "", "", "", "", "", "", "", "", "",
854
                "", "", "", "", "", "", "", "", "", "", "", "", ""
855
 
34619 ranu 856
        );
34606 ranu 857
 
34619 ranu 858
        List<String> headers2 = Arrays.asList(
34641 ranu 859
                "Assessment","Zero billing","Billing needed","Counta",
34619 ranu 860
                "Code", "Store Name", "City", "Area", "BM", "Sales Manager", "RBM", "Status", "Category",
861
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
862
                "Tertiary Sale", "Unbilled",
863
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
864
                "Tertiary Sale", "Unbilled",
865
                "Secondary Target", "Secondary Achieved", "Returns", "Net Secondary", "Secondary %",
866
                "Tertiary Sale", "Unbilled",
34641 ranu 867
                "Counter Potential", "Short investment", "Default", "INVESTMENT LEVEL", "Loan", "PO value", "Agreed investment",
868
                "Wallet", "po+bill", "MONTH BEGINNING DRR", "REQ DRR", "Drr %", "Last billing Done", "Slab",
34606 ranu 869
 
34641 ranu 870
              "Total Stock",  "Apple","Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "Poco", "Lava", "Itel", "Almost New",
871
              "Total Secondary", "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "Poco", "Lava", "Itel", "Almost New",
872
              "Total Tertiary",  "Apple", "Xiaomi", "Vivo", "Tecno", "Samsung", "Realme", "Oppo", "OnePlus", "Poco", "Lava", "Itel", "Almost New"
34619 ranu 873
        );
874
 
875
        headerGroup.add(headers1);
876
        headerGroup.add(headers2);
877
 
878
 
879
        List<List<?>> rows = new ArrayList<>();
880
        for (Map.Entry<Integer, BIRetailerModel> entry : biRetailerModelMap.entrySet()) {
881
            Integer fofoId = entry.getKey();
882
            BIRetailerModel retailer = entry.getValue();
34641 ranu 883
 
34619 ranu 884
            Map<YearMonth, BiSecondaryModel> monthlyData = allRetailerMonthlyData.get(fofoId);
885
 
886
            BiSecondaryModel current = monthlyData.getOrDefault(YearMonth.now(), new BiSecondaryModel(0,0,0,0,0,0,0));
887
            BiSecondaryModel last = monthlyData.getOrDefault(YearMonth.now().minusMonths(1), new BiSecondaryModel(0,0,0,0,0,0,0));
888
            BiSecondaryModel twoAgo = monthlyData.getOrDefault(YearMonth.now().minusMonths(2), new BiSecondaryModel(0,0,0,0,0,0,0));
889
 
890
            List<Object> row = new ArrayList<>();
891
            row.addAll(Arrays.asList(
34641 ranu 892
                    assessmentMap.get(fofoId),zeroBillingMap.get(fofoId),billingNeededMap.get(fofoId),countAMap.get(fofoId),
34619 ranu 893
                    retailer.getCode(), retailer.getStoreName(), retailer.getCity(), retailer.getArea(),
894
                    retailer.getBmName(), retailer.getSalesManager(), retailer.getRbm(),
895
                    retailer.getStatus(), retailer.getCategory()
896
            ));
897
 
898
            // Current Month
899
            row.addAll(Arrays.asList(
900
                    current.getSecondaryTarget(),
901
                    current.getSecondaryAchieved(),
902
                    current.getSecondaryReturn(),
903
                    current.getNetSecondary(),
904
                    current.getSecondaryAchievedPercent(),
905
                    current.getTertiary(),
906
                    current.getTertiaryUnBilled()
907
            ));
908
 
909
            // Last Month
910
            row.addAll(Arrays.asList(
911
                    last.getSecondaryTarget(),
912
                    last.getSecondaryAchieved(),
913
                    last.getSecondaryReturn(),
914
                    last.getNetSecondary(),
915
                    last.getSecondaryAchievedPercent(),
916
                    last.getTertiary(),
917
                    last.getTertiaryUnBilled()
918
            ));
919
 
920
            // Two Months Ago
921
            row.addAll(Arrays.asList(
922
                    twoAgo.getSecondaryTarget(),
923
                    twoAgo.getSecondaryAchieved(),
924
                    twoAgo.getSecondaryReturn(),
925
                    twoAgo.getNetSecondary(),
926
                    twoAgo.getSecondaryAchievedPercent(),
927
                    twoAgo.getTertiary(),
928
                    twoAgo.getTertiaryUnBilled()
929
            ));
34641 ranu 930
            FofoInvestmentModel fofoInvestmentModelValue = biInvestmentModelMap.get(fofoId);
931
            if(fofoInvestmentModelValue != null){
932
                row.addAll(Arrays.asList(
933
                        fofoInvestmentModelValue.getCounterPotential(),
934
                        fofoInvestmentModelValue.getShortInvestment(),
935
                        fofoInvestmentModelValue.getDefaultLoan(),
936
                        fofoInvestmentModelValue.getInvestmentLevel(),
937
                        fofoInvestmentModelValue.getActiveLoan(),
938
                        fofoInvestmentModelValue.getPoValue(),
939
                        fofoInvestmentModelValue.getAgreedInvestment(),
940
                        fofoInvestmentModelValue.getWallet(),
941
                        fofoInvestmentModelValue.getPoAndBilled(),
942
                        fofoInvestmentModelValue.getMonthBeginingDrr(),
943
                        fofoInvestmentModelValue.getRequiredDrr(),
944
                        fofoInvestmentModelValue.getDrrPercent(),
945
                        fofoInvestmentModelValue.getLastBillingDone(),
946
                        fofoInvestmentModelValue.getSlab()
947
                ));
948
            }else {
949
                row.addAll(Arrays.asList(
950
                        "-","-","-","-","-","-","-","-","-","-","-",""
951
                ));
952
            }
953
 
954
            Map<String, BrandStockPrice> brandStockMap = fofoBrandStockPriceMap.get(fofoId);
34619 ranu 955
            row.addAll(Arrays.asList(
956
                    fofoTotalStockPriceMap.getOrDefault(fofoId, 0.0),
34641 ranu 957
                    brandStockMap.get("Apple") != null ? brandStockMap.get("Apple").getTotalValue() : 0.0,
958
                    brandStockMap.get("Xiaomi") != null ? brandStockMap.get("Xiaomi").getTotalValue() : 0.0,
959
                    brandStockMap.get("Vivo") != null ? brandStockMap.get("Vivo").getTotalValue() : 0.0,
960
                    brandStockMap.get("Tecno") != null ? brandStockMap.get("Tecno").getTotalValue() : 0.0,
961
                    brandStockMap.get("Samsung") != null ? brandStockMap.get("Samsung").getTotalValue() : 0.0,
962
                    brandStockMap.get("Realme") != null ? brandStockMap.get("Realme").getTotalValue() : 0.0,
963
                    brandStockMap.get("Oppo") != null ? brandStockMap.get("Oppo").getTotalValue() : 0.0,
964
                    brandStockMap.get("OnePlus") != null ? brandStockMap.get("OnePlus").getTotalValue() : 0.0,
965
                    brandStockMap.get("Poco") != null ? brandStockMap.get("Poco").getTotalValue() : 0.0,
966
                    brandStockMap.get("Lava") != null ? brandStockMap.get("Lava").getTotalValue() : 0.0,
967
                    brandStockMap.get("Itel") != null ? brandStockMap.get("Itel").getTotalValue() : 0.0,
968
                    brandStockMap.get("Almost New") != null ? brandStockMap.get("Almost New").getTotalValue() : 0.0
34619 ranu 969
            ));
970
 
34641 ranu 971
            Map<String, Long> brandSecondaryMap = fofoBrandWiseMtdSecondaryMap.get(fofoId);
972
            row.addAll(Arrays.asList(
34648 ranu 973
                    fofoTotalMtdSecondaryMap.get(fofoId),
34641 ranu 974
                    brandSecondaryMap.getOrDefault("Apple", 0L),
975
                    brandSecondaryMap.getOrDefault("Xiaomi", 0L),
976
                    brandSecondaryMap.getOrDefault("Vivo", 0L),
977
                    brandSecondaryMap.getOrDefault("Tecno", 0L),
978
                    brandSecondaryMap.getOrDefault("Samsung", 0L),
979
                    brandSecondaryMap.getOrDefault("Realme", 0L),
980
                    brandSecondaryMap.getOrDefault("Oppo", 0L),
981
                    brandSecondaryMap.getOrDefault("OnePlus", 0L),
982
                    brandSecondaryMap.getOrDefault("Poco", 0L),
983
                    brandSecondaryMap.getOrDefault("Lava", 0L),
984
                    brandSecondaryMap.getOrDefault("Itel", 0L),
985
                    brandSecondaryMap.getOrDefault("Almost New", 0L)
986
            ));
987
 
988
            Map<String, Double> brandTertiaryMap = fofoBrandMtdTertiaryMap.get(fofoId);
989
            row.addAll(Arrays.asList(
34648 ranu 990
                    fofoTotalMtdTertiaryMap.get(fofoId),
34641 ranu 991
                    brandTertiaryMap.getOrDefault("Apple", 0d),
992
                    brandTertiaryMap.getOrDefault("Xiaomi", 0d),
993
                    brandTertiaryMap.getOrDefault("Vivo", 0d),
994
                    brandTertiaryMap.getOrDefault("Tecno", 0d),
995
                    brandTertiaryMap.getOrDefault("Samsung", 0d),
996
                    brandTertiaryMap.getOrDefault("Realme", 0d),
997
                    brandTertiaryMap.getOrDefault("Oppo", 0d),
998
                    brandTertiaryMap.getOrDefault("OnePlus", 0d),
999
                    brandTertiaryMap.getOrDefault("Poco", 0d),
1000
                    brandTertiaryMap.getOrDefault("Lava", 0d),
1001
                    brandTertiaryMap.getOrDefault("Itel", 0d),
1002
                    brandTertiaryMap.getOrDefault("Almost New", 0d)
1003
            ));
1004
            rows.add(row);
34619 ranu 1005
        }
1006
 
1007
 
34641 ranu 1008
        // Send to email
1009
//        ByteArrayOutputStream csvStream = FileUtil.getCSVByteStreamWithMultiHeaders(headerGroup, rows);
1010
        ByteArrayOutputStream csvStream = getExcelStreamWithMultiHeaders(headerGroup, rows);
1011
        String fileName = "BI-Retailer-Monthly-Report-" + FormattingUtils.formatDate(LocalDateTime.now()) + ".xlsx";
34644 ranu 1012
        String[] sendToArray = new String[]{"ranu.rajput@smartdukaan.com","ashutosh.verma@smartdukaan.com"};
34619 ranu 1013
 
1014
        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()));
1015
 
1016
 
34606 ranu 1017
    }
1018
 
34641 ranu 1019
    public static ByteArrayOutputStream getExcelStreamWithMultiHeaders(List<List<String>> headerGroup, List<List<?>> rows) {
1020
        Workbook workbook = new XSSFWorkbook();
1021
        Sheet sheet = workbook.createSheet("BI Report");
1022
        int rowIndex = 0;
34606 ranu 1023
 
34641 ranu 1024
        CellStyle centeredStyle = workbook.createCellStyle();
1025
        centeredStyle.setAlignment(HorizontalAlignment.CENTER); // Center horizontally
1026
        centeredStyle.setVerticalAlignment(VerticalAlignment.CENTER); // Center vertically
34606 ranu 1027
 
34641 ranu 1028
    // Optional: bold font
1029
        Font font1 = workbook.createFont();
1030
        font1.setBold(true);
1031
        centeredStyle.setFont(font1);
34606 ranu 1032
 
34619 ranu 1033
 
34641 ranu 1034
 
1035
        // Create styles
1036
        Map<String, CellStyle> headerStyles = new HashMap<>();
1037
 
1038
        // fontPurpleStyle
1039
        CellStyle purpleStyle = workbook.createCellStyle();
1040
        purpleStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
1041
        purpleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1042
        purpleStyle.setFont(font1);
1043
        headerStyles.put("Assessment", purpleStyle);
1044
        headerStyles.put("Zero billing", purpleStyle);
1045
        headerStyles.put("Billing needed", purpleStyle);
1046
        headerStyles.put("Counta", purpleStyle);
1047
        headerStyles.put("MONTH BEGINNING DRR", purpleStyle);
1048
        headerStyles.put("REQ DRR", purpleStyle);
1049
        headerStyles.put("Drr %", purpleStyle);
1050
 
1051
        // Light Blue
1052
        CellStyle blueStyle = workbook.createCellStyle();
1053
        blueStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
1054
        blueStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1055
        blueStyle.setFont(font1);
1056
        headerStyles.put("Code", blueStyle);
1057
        headerStyles.put("Store Name", blueStyle);
1058
        headerStyles.put("City", blueStyle);
1059
        headerStyles.put("Area", blueStyle);
1060
        headerStyles.put("BM", blueStyle);
1061
        headerStyles.put("RBM", blueStyle);
1062
        headerStyles.put("Sales Manager", blueStyle);
1063
        headerStyles.put("Status", blueStyle);
1064
        headerStyles.put("Category", blueStyle);
1065
 
1066
        // Light Yellow
1067
        CellStyle yellowStyle = workbook.createCellStyle();
1068
        yellowStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
1069
        yellowStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1070
        yellowStyle.setFont(font1);
1071
        headerStyles.put("Last billing Done", yellowStyle);
1072
        headerStyles.put("Total Stock", yellowStyle);
1073
 
1074
        // Light Orange
1075
        CellStyle orangeStyle = workbook.createCellStyle();
1076
        orangeStyle.setFillForegroundColor(IndexedColors.LIGHT_ORANGE.getIndex());
1077
        orangeStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1078
        orangeStyle.setFont(font1);
1079
        headerStyles.put("Total Tertiary", orangeStyle);
1080
        headerStyles.put("Total Secondary", orangeStyle);
1081
        headerStyles.put("Default", orangeStyle);
1082
 
1083
 
1084
        // Light green
1085
        CellStyle lightGreenStyle = workbook.createCellStyle();
1086
        lightGreenStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
1087
        lightGreenStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1088
        lightGreenStyle.setFont(font1);
1089
        headerStyles.put("Short investment", lightGreenStyle);
1090
        headerStyles.put("INVESTMENT LEVEL", lightGreenStyle);
1091
        headerStyles.put("Loan", lightGreenStyle);
1092
        headerStyles.put("PO value", lightGreenStyle);
1093
        headerStyles.put("Agreed investment", lightGreenStyle);
1094
        headerStyles.put("Wallet", lightGreenStyle);
1095
        headerStyles.put("po+bill", lightGreenStyle);
1096
 
1097
        // Light Green
1098
        CellStyle secondary1 = createStyle(workbook, IndexedColors.LIGHT_GREEN);
1099
        CellStyle secondary2 = createStyle(workbook, IndexedColors.LIGHT_YELLOW);
1100
        CellStyle secondary3 = createStyle(workbook, IndexedColors.LIGHT_ORANGE);
1101
 
1102
        Map<String, CellStyle> brandStyles = new HashMap<>();
1103
        brandStyles.put("Apple", createStyle(workbook, IndexedColors.GREY_25_PERCENT));
1104
        brandStyles.put("Xiaomi", createStyle(workbook, IndexedColors.ORANGE));
1105
        brandStyles.put("Vivo", createStyle(workbook, IndexedColors.SKY_BLUE));
1106
        brandStyles.put("Tecno", createStyle(workbook, IndexedColors.LIGHT_BLUE));
1107
        brandStyles.put("Samsung", createStyle(workbook, IndexedColors.ROYAL_BLUE));
1108
        brandStyles.put("Realme", createStyle(workbook, IndexedColors.YELLOW));
1109
        brandStyles.put("Oppo", createStyle(workbook, IndexedColors.LIGHT_GREEN));
1110
        brandStyles.put("OnePlus", createStyle(workbook, IndexedColors.RED));
1111
        brandStyles.put("Poco", createStyle(workbook, IndexedColors.ORANGE));
1112
        brandStyles.put("Lava", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1113
        brandStyles.put("Itel", createStyle(workbook, IndexedColors.LIGHT_YELLOW));
1114
        brandStyles.put("Almost New", createStyle(workbook, IndexedColors.WHITE));
1115
 
1116
 
1117
        CellStyle defaultHeaderStyle = workbook.createCellStyle();
1118
        defaultHeaderStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
1119
        defaultHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1120
        defaultHeaderStyle.setFont(font1);
1121
 
1122
 
1123
        Map<String, Integer> headerCount = new HashMap<>();
1124
 
1125
        for (int headerRowIndex = 0; headerRowIndex < headerGroup.size(); headerRowIndex++) {
1126
            List<String> headerRow = headerGroup.get(headerRowIndex);
1127
            Row row = sheet.createRow(rowIndex++);
1128
 
1129
            for (int i = 0; i < headerRow.size(); i++) {
1130
                String headerText = headerRow.get(i);
1131
                sheet.setColumnWidth(i, 25 * 256);
1132
                row.setHeightInPoints(20); // 25-point height
1133
                Cell cell = row.createCell(i);
1134
                cell.setCellValue(headerText);
1135
                cell.setCellStyle(centeredStyle);
1136
                // Count how many times this header has appeared
1137
                int count = headerCount.getOrDefault(headerText, 0) + 1;
1138
                headerCount.put(headerText, count);
1139
                // Apply special style for repeated headers
1140
                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")) {
1141
                    if (count == 1) {
1142
                        cell.setCellStyle(secondary1);
1143
                    } else if (count == 2) {
1144
                        cell.setCellStyle(secondary2);
1145
                    } else if (count == 3) {
1146
                        cell.setCellStyle(secondary3);
1147
                    }
1148
                }
1149
                // Brand header styling (apply only for the 2nd row of headers)
1150
                else if (headerRowIndex == 1 && brandStyles.containsKey(headerText)) {
1151
                    cell.setCellStyle(brandStyles.get(headerText));
1152
                }else if (headerStyles.containsKey(headerText)) {
1153
                    cell.setCellStyle(headerStyles.get(headerText));
1154
                } else {
1155
                    cell.setCellStyle(defaultHeaderStyle); // default style for others
1156
                }
1157
            }
1158
        }
1159
 
1160
        // Write data rows
1161
        for (List<?> dataRow : rows) {
1162
            Row row = sheet.createRow(rowIndex++);
1163
            for (int i = 0; i < dataRow.size(); i++) {
1164
                Cell cell = row.createCell(i);
1165
                Object value = dataRow.get(i);
1166
                if (value instanceof Number) {
1167
                    cell.setCellValue(((Number) value).doubleValue());
1168
                } else {
1169
                    cell.setCellValue(value != null ? value.toString() : "");
1170
                }
1171
            }
1172
        }
1173
 
1174
        // Auto-size columns
1175
        if (!rows.isEmpty()) {
1176
            for (int i = 0; i < rows.get(0).size(); i++) {
1177
                sheet.autoSizeColumn(i);
1178
            }
1179
        }
1180
 
1181
        // Output as ByteArray
1182
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
1183
            workbook.write(outputStream);
1184
            workbook.close();
1185
            return outputStream;
1186
        } catch (IOException e) {
1187
            throw new RuntimeException("Failed to generate Excel file", e);
1188
        }
1189
    }
1190
 
1191
 
1192
    private static CellStyle createStyle(Workbook workbook, IndexedColors color) {
1193
        CellStyle style = workbook.createCellStyle();
1194
        style.setFillForegroundColor(color.getIndex());
1195
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1196
        Font font = workbook.createFont();
1197
        font.setBold(true);
1198
        style.setFont(font);
1199
        return style;
1200
    }
1201
 
1202
 
1203
 
1204
 
34306 ranu 1205
}