Subversion Repositories SmartDukaan

Rev

Rev 30767 | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.smartdukaan.cron.scheduled;

import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.util.FormattingUtils;
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
import com.spice.profitmandi.dao.entity.fofo.PartnerDailyInvestment;
import com.spice.profitmandi.dao.entity.fofo.SchemeInOut;
import com.spice.profitmandi.dao.enumuration.catalog.SchemeType;
import com.spice.profitmandi.dao.enumuration.transaction.SchemePayoutStatus;
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
import com.spice.profitmandi.dao.repository.fofo.PartnerDailyInvestmentRepository;
import com.spice.profitmandi.dao.repository.fofo.SchemeInOutRepository;
import com.spice.profitmandi.dao.repository.transaction.TransactionRepository;
import com.spice.profitmandi.service.user.RetailerService;
import com.spice.profitmandi.service.wallet.WalletService;
import in.shop2020.model.v1.order.WalletReferenceType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

;

@Component
@Transactional(rollbackFor = Throwable.class)
public class InvestmentRelatedTasks {
        @Autowired
        RetailerService retailerService;
        @Autowired
        SchemeInOutRepository schemeInOutRepository;

        private static final Logger LOGGER = LogManager.getLogger(InvestmentRelatedTasks.class);

        @Autowired
        InventoryItemRepository inventoryItemRepository;

        @Autowired
        PartnerDailyInvestmentRepository partnerDailyInvestmentRepository;


        @Autowired
        TransactionRepository transactionRepository;

        @Autowired
        WalletService walletService;

        public void payMonthlyInvestment() throws ProfitMandiBusinessException {
                LocalDate firstDateOfCurrentMonth = LocalDateTime.now().withDayOfMonth(1).toLocalDate();
                LocalDate startOfPreviousMonth = firstDateOfCurrentMonth.minusMonths(1);
                int referenceId = Integer.parseInt(FormattingUtils.getYearMonth(startOfPreviousMonth.atStartOfDay()));
                LocalDate lastOfPreviousMonth = firstDateOfCurrentMonth.minusDays(1);
                List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository
                                .selectAll(startOfPreviousMonth, lastOfPreviousMonth);
                Map<Integer, Long> investmentMaintainedDaysMap = partnerDailyInvestments.stream()
                                .filter(x -> x.getShortPercentage() <= 10)
                                .collect(Collectors.groupingBy(x -> x.getFofoId(), Collectors.counting()));
                LOGGER.info("investmentMaintainedDaysMap {}", investmentMaintainedDaysMap);
                List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectAllPending(SchemeType.INVESTMENT,
                                startOfPreviousMonth.atStartOfDay(), firstDateOfCurrentMonth.atStartOfDay());
                Map<Integer, List<SchemeInOut>> inventoryItemIdSchemeMap = schemeInOuts.stream()
                                .collect(Collectors.groupingBy(x -> x.getInventoryItemId()));
                List<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIdSchemeMap.keySet());
                Map<Integer, List<Integer>> retailerInventoryItemIdMap = inventoryItems.stream().collect(
                                Collectors.groupingBy(x -> x.getFofoId(), Collectors.mapping(x -> x.getId(), Collectors.toList())));
                System.out.println("Fofo Id\tInvestment Maintained Days\tEligible payout");
                for (Map.Entry<Integer, List<Integer>> retailerEntry : retailerInventoryItemIdMap.entrySet()) {
                        int fofoId = retailerEntry.getKey();
                        long investmentMaintainedDays = investmentMaintainedDaysMap.get(fofoId) == null ? 0
                                        : investmentMaintainedDaysMap.get(fofoId);

                        List<SchemeInOut> schemeInouts = retailerEntry.getValue().stream().map(x -> inventoryItemIdSchemeMap.get(x))
                                        .flatMap(List::stream).filter(x -> x.getRolledBackTimestamp() == null).collect(Collectors.toList());
                        float totalAmount = 0;
                        LocalDateTime firstBillingDate = transactionRepository.getFirstBillingDate(fofoId);
                        boolean sameYearMonth = firstBillingDate.getMonth() == startOfPreviousMonth.getMonth() && firstBillingDate.getYear() == startOfPreviousMonth.getYear();
                        for (SchemeInOut sio : schemeInouts) {
                                if (sameYearMonth) {
                                        sio.setStatusDescription("Investment payout fully disbursed for first month");
                                        sio.setStatus(SchemePayoutStatus.CREDITED);
                                        sio.setCreditTimestamp(LocalDateTime.now());
                                        totalAmount += sio.getAmount();
                                } else {
                                        if (investmentMaintainedDays < 8) {
                                                sio.setStatus(SchemePayoutStatus.REJECTED);
                                                //sio.setRolledBackTimestamp(LocalDateTime.now());
                                                sio.setStatusDescription("Investment maintained for " + investmentMaintainedDays + "(< 8) days");
                                        } else if (investmentMaintainedDays < 12) {
                                                sio.setStatus(SchemePayoutStatus.CREDITED);
                                                sio.setAmount(sio.getAmount() / 2);
                                                sio.setCreditTimestamp(LocalDateTime.now());
                                                sio.setStatusDescription("Investment maintained for " + investmentMaintainedDays + "(< 12) days");
                                                totalAmount += sio.getAmount();
                                        } else {
                                                sio.setStatus(SchemePayoutStatus.CREDITED);
                                                sio.setCreditTimestamp(LocalDateTime.now());
                                                totalAmount += sio.getAmount();
                                        }
                                }
                        }
                        if (totalAmount > 0) {
                                String description = "Investment margin paid for " + FormattingUtils.formatYearMonth(startOfPreviousMonth.atStartOfDay());
                                if (investmentMaintainedDays < 12) {
                                        description += ", as maintained for " + investmentMaintainedDays + "(< 12) days";
                                }
                                walletService.addAmountToWallet(fofoId, referenceId, WalletReferenceType.INVESTMENT_PAYOUT, description, totalAmount, lastOfPreviousMonth.atTime(LocalTime.MAX));
                        }
                        System.out.printf("%d\t%d\t%f%n", fofoId, investmentMaintainedDays, totalAmount);
                }
        }

        public void evaluateActualInvestmentPayout() throws ProfitMandiBusinessException {
                LocalDate firstDateOfCurrentMonth = LocalDateTime.now().withDayOfMonth(1).toLocalDate();
                LocalDate startOfPreviousMonth = firstDateOfCurrentMonth.minusMonths(1);
                LocalDate lastOfPreviousMonth = firstDateOfCurrentMonth.minusDays(1);
                List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository
                                .selectAll(startOfPreviousMonth, lastOfPreviousMonth);
                Map<Integer, Long> investmentMaintainedDaysMap = partnerDailyInvestments.stream()
                                .filter(x -> x.getShortPercentage() <= 10)
                                .collect(Collectors.groupingBy(x -> x.getFofoId(), Collectors.counting()));
                LOGGER.info("investmentMaintainedDaysMap {}", investmentMaintainedDaysMap);
                List<SchemeInOut> schemeInOuts = schemeInOutRepository.selectAllPending(SchemeType.INVESTMENT,
                                startOfPreviousMonth.atStartOfDay(), firstDateOfCurrentMonth.atStartOfDay());
                Map<Integer, List<SchemeInOut>> inventoryItemIdSchemeMap = schemeInOuts.stream()
                                .collect(Collectors.groupingBy(x -> x.getInventoryItemId()));
                List<InventoryItem> inventoryItems = inventoryItemRepository.selectByIds(inventoryItemIdSchemeMap.keySet());
                Map<Integer, List<Integer>> retailerInventoryItemIdMap = inventoryItems.stream().collect(
                                Collectors.groupingBy(x -> x.getFofoId(), Collectors.mapping(x -> x.getId(), Collectors.toList())));
                System.out.println("Fofo Id\tInvestment Maintained Days\tEligible payout");
                for (Map.Entry<Integer, List<Integer>> retailerEntry : retailerInventoryItemIdMap.entrySet()) {
                        int fofoId = retailerEntry.getKey();
                        List<SchemeInOut> schemeInouts = retailerEntry.getValue().stream().map(x -> inventoryItemIdSchemeMap.get(x))
                                        .flatMap(List::stream).collect(Collectors.toList());
                        double totalAmount = schemeInouts.stream().filter(x -> x.getRolledBackTimestamp() == null)
                                        .collect(Collectors.summingDouble(x -> x.getAmount()));
                        long investmentMaintainedDays = investmentMaintainedDaysMap.get(fofoId) == null ? 0
                                        : investmentMaintainedDaysMap.get(fofoId);
                        if (investmentMaintainedDays < 8) {
                                totalAmount = 0;
                        } else if (investmentMaintainedDays < 12) {
                                totalAmount = totalAmount / 2;
                        }
                        System.out.printf("%d\t%d\t%f%n", fofoId, investmentMaintainedDays, totalAmount);
                }
        }

}