Subversion Repositories SmartDukaan

Rev

Rev 33357 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
33354 amit.gupta 1
package com.spice.profitmandi.dao.service;
2
 
3
import com.spice.profitmandi.common.util.Utils;
4
import com.spice.profitmandi.dao.entity.transaction.FofoSidbiSanction;
5
import com.spice.profitmandi.dao.repository.dtr.CreditAccountRepository;
6
import com.spice.profitmandi.dao.repository.transaction.FofoSidbiSanctionRepository;
7
import org.apache.logging.log4j.LogManager;
8
import org.springframework.beans.factory.annotation.Autowired;
9
import org.springframework.stereotype.Component;
10
 
11
import java.math.BigDecimal;
12
import java.time.LocalDate;
13
import java.time.LocalDateTime;
14
import java.time.temporal.ChronoUnit;
15
import java.util.*;
16
import java.util.stream.Collectors;
17
 
18
@Component
19
public class SidbiService {
20
 
21
    private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(SidbiService.class);
22
 
23
    @Autowired
24
    FofoSidbiSanctionRepository fofoSidbiSanctionRepository;
25
 
26
    @Autowired
27
    CreditAccountRepository creditAccountRepository;
28
 
29
    private static final double ONE_LAC = 100000d;
30
 
31
    private static final double PROCESSING_FEE = 1.18;
32
 
33
    private static final double STAMP_FEE = 200;
34
 
35
    private static final String WALLET_DEDUCTION_NARRATION = "SIDBI Processing Fee @1% + GST@18% + STAMP DUTY(Rs.200)";
36
 
37
    //Logic specific to Sidbi Related Sanctions
38
    //Assumptions that 1Lac upto 12 months
39
    private static final List<Integer> PRINCIPAL_DEDUCTIONS_PER_LAC = Arrays.asList(2115, 2147, 2179, 2212, 2245, 2279, 2313, 2348, 2383, 2419, 2455, 2492);
40
    private static final int CUTOFF_DATE = 10;
41
 
42
    public Map<Integer, BigDecimal> getSuggestedLimitMap() {
43
        Map<Integer, BigDecimal> fofoSuggetedLimitMap = new HashMap<>();
44
        List<FofoSidbiSanction> fofoSidbiSanctions = fofoSidbiSanctionRepository.selectAllUnsettled();
45
        Map<Integer, List<FofoSidbiSanction>> fofoSidbiSanctionMap = fofoSidbiSanctions.stream().collect(Collectors.groupingBy(x -> x.getFofoId()));
46
        for (Map.Entry<Integer, List<FofoSidbiSanction>> fofoSactionEntry : fofoSidbiSanctionMap.entrySet()) {
47
            List<FofoSidbiSanction> fofoSidbiSanctionList = fofoSactionEntry.getValue();
48
            int fofoId = fofoSactionEntry.getKey();
49
            BigDecimal suggestedLimit = BigDecimal.valueOf(fofoSidbiSanctionList.stream().mapToDouble(x -> x.getUnsettledAmount()).sum());
50
            fofoSuggetedLimitMap.put(fofoId, suggestedLimit);
51
        }
52
        return fofoSuggetedLimitMap;
53
    }
54
 
55
    private double getActualLoan(double receivedAmount) {
56
        double number = Math.ceil(receivedAmount / ONE_LAC);
57
        return number * ONE_LAC;
58
    }
59
 
60
    private double getProcessingDeductions(FofoSidbiSanction fofoSidbiSanction) {
61
        double processingDeductions = (fofoSidbiSanction.getLoanAmount() * PROCESSING_FEE / 100) + STAMP_FEE;
62
        System.out.println("Processing deductions  " + processingDeductions);
63
        return processingDeductions;
64
    }
65
 
66
    //When advance is deducted from Original disbursements then deduction happens from next month
67
    private double getAdvancePaid(FofoSidbiSanction fofoSidbiSanction) {
68
        return fofoSidbiSanction.getLoanAmount() - fofoSidbiSanction.getSanctionAmount() - this.getProcessingDeductions(fofoSidbiSanction);
69
    }
70
 
71
    private double getDeduction(FofoSidbiSanction fofoSidbiSanction) {
72
        double deduction = 0d;
73
        LocalDate loanStartDate = fofoSidbiSanction.getCreatedOn().withDayOfMonth(5).toLocalDate();
74
        if (fofoSidbiSanction.getAdvanceInterestAmount() > 0d) {
75
            loanStartDate = loanStartDate.plusMonths(1);
76
        }
77
        int monthsBetween = (int) ChronoUnit.MONTHS.between(loanStartDate, LocalDate.now());
78
        LOGGER.info("loanStartDate - {}, now - {}, monthsBetween - {} ", loanStartDate, LocalDateTime.now(), monthsBetween);
79
        if (LocalDate.now().getDayOfMonth() < 5) {
80
            monthsBetween -= 1;
81
        }
82
        if (monthsBetween > 0) {
83
            for (int month = 1; month <= monthsBetween; month++) {
84
                deduction += PRINCIPAL_DEDUCTIONS_PER_LAC.get(monthsBetween - 1) * (fofoSidbiSanction.getLoanAmount() / ONE_LAC);
85
            }
86
        }
87
        LOGGER.info("loanStartDate-  {}, Loan Amount - {}, Deduction - {}", loanStartDate, fofoSidbiSanction.getLoanAmount(), deduction);
88
        return deduction;
89
    }
90
 
91
    public void processDeductions() {
92
        List<FofoSidbiSanction> fofoSidbiSanctions = fofoSidbiSanctionRepository.selectAllUnsettled();
93
        LOGGER.info("Sanctions Count - {}", fofoSidbiSanctions);
94
        Map<Integer, List<FofoSidbiSanction>> fofoSidbiSanctionMap = fofoSidbiSanctions.stream().collect(Collectors.groupingBy(x -> x.getFofoId()));
95
        for (Map.Entry<Integer, List<FofoSidbiSanction>> fofoSactionEntry : fofoSidbiSanctionMap.entrySet()) {
96
            for (FofoSidbiSanction fofoSidbiSanction : fofoSactionEntry.getValue()) {
97
                fofoSidbiSanction.setSettledAmount(0);
98
                fofoSidbiSanction.setSettledAmount(this.getDeduction(fofoSidbiSanction));
99
                if (Utils.compareDouble(fofoSidbiSanction.getSettledAmount(), fofoSidbiSanction.getLoanAmount()) == 0) {
100
                    fofoSidbiSanction.setSettledOn(LocalDateTime.now());
101
                }
102
            }
103
        }
104
    }
105
 
106
    public void createSanction(int fofoId, LocalDateTime createTimestamp, double receivedAmount) {
107
        //Add table here
108
        FofoSidbiSanction fofoSidbiSanction = new FofoSidbiSanction();
109
        fofoSidbiSanction.setCreatedOn(createTimestamp);
110
        fofoSidbiSanction.setFofoId(fofoId);
111
        fofoSidbiSanction.setSanctionAmount(receivedAmount);
112
        fofoSidbiSanction.setLoanAmount(this.getActualLoan(receivedAmount));
113
        fofoSidbiSanction.setAdvanceInterestAmount(this.getAdvancePaid(fofoSidbiSanction));
114
        fofoSidbiSanctionRepository.persist(fofoSidbiSanction);
115
    }
116
 
117
    public void migrateSanctions() {
118
        List<FofoSidbiSanction> fofoSidbiSanctions = fofoSidbiSanctionRepository.selectAll(Optional.empty());
119
        for (FofoSidbiSanction fofoSidbiSanction : fofoSidbiSanctions) {
120
            fofoSidbiSanction.setLoanAmount(this.getActualLoan(fofoSidbiSanction.getSanctionAmount()));
121
            fofoSidbiSanction.setAdvanceInterestAmount(this.getAdvancePaid(fofoSidbiSanction));
122
            fofoSidbiSanction.setIssuedOn(fofoSidbiSanction.getCreatedOn().plusDays(2));
123
        }
124
    }
125
}