Subversion Repositories SmartDukaan

Rev

Rev 34098 | Rev 34282 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.service;

import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.dao.entity.inventory.RbmAchievements;
import com.spice.profitmandi.dao.entity.inventory.RbmTargets;
import com.spice.profitmandi.dao.model.*;
import com.spice.profitmandi.dao.repository.catalog.RbmAchievementsRepository;
import com.spice.profitmandi.dao.repository.catalog.RbmTargetsRepository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.NativeQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.persistence.TypedQuery;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
public class RbmTargetServiceImpl implements RbmTargetService {
    private static final Logger LOGGER = LogManager.getLogger(RbmTargetServiceImpl.class);

    @Autowired
    SessionFactory sessionFactory;

    @Autowired
    RbmTargetsRepository rbmTargetsRepository;

    @Autowired
    RbmAchievementsRepository rbmAchievementsRepository;

    @Override
    public List<WarehouseRbmTargetModel> getWarehouseWiseRbmMonthlyTarget() {
        Session session = sessionFactory.getCurrentSession();
        final TypedQuery<WarehouseRbmTargetModel> typedQuerySimilar = session.createNamedQuery("RbmTarget.getWarehouseWiseMonthlyTarget", WarehouseRbmTargetModel.class);

        return typedQuerySimilar.getResultList();

    }

    @Override
    public List<MTDAchievedTargetModel> getDateWiseAchievedTargetOfRbm(LocalDate startDate, LocalDate endDate) {
        Session session = sessionFactory.getCurrentSession();
        final TypedQuery<MTDAchievedTargetModel> typedQuerySimilar = session.createNamedQuery("RbmTarget.getRbmAchievedMonthlyTarget", MTDAchievedTargetModel.class);
        typedQuerySimilar.setParameter("startDate", startDate);
        typedQuerySimilar.setParameter("endDate", endDate);
        return typedQuerySimilar.getResultList();

    }

    @Override
    public List<TodayAchievedMovementModel> getMovementWiseAchievementByDate(LocalDate startDate, LocalDate endDate) {
        LOGGER.info("start date {}, end date {}", startDate, endDate);
        Session session = sessionFactory.getCurrentSession();
        final TypedQuery<TodayAchievedMovementModel> typedQuerySimilar = session.createNamedQuery("RBMTarget.TodayAchivementByMovement", TodayAchievedMovementModel.class);
        typedQuerySimilar.setParameter("startDate", startDate);
        typedQuerySimilar.setParameter("endDate", endDate);
        return typedQuerySimilar.getResultList();

    }

    @Override
    public List<WarehouseMobileStockByMovementModel> getWarehouseMobileStockByMovement() {
        Session session = sessionFactory.getCurrentSession();
        final TypedQuery<WarehouseMobileStockByMovementModel> typedQuerySimilar = session.createNamedQuery("WarehouseStock.MovementWiseMobileStock", WarehouseMobileStockByMovementModel.class);

        return typedQuerySimilar.getResultList();

    }

    @Override
    public List<SoldCatalogsReportModel> getCatalogSoldReport(LocalDate startDate, LocalDate endDate) {
        Session session = sessionFactory.getCurrentSession();
        final TypedQuery<SoldCatalogsReportModel> typedQuerySimilar = session.createNamedQuery("CatalogsReport.SoldCatalogsReport", SoldCatalogsReportModel.class);
        typedQuerySimilar.setParameter("startDate", startDate);
        typedQuerySimilar.setParameter("endDate", endDate);
        return typedQuerySimilar.getResultList();

    }


    public int getWorkingDaysCount(LocalDate startDate) {
        Session session = sessionFactory.getCurrentSession();

        // Convert the LocalDate to a format MySQL can interpret
        String startDateString = startDate.toString();

        final NativeQuery<?> nativeQuery = session.createNativeQuery(
                "SELECT (DATEDIFF(LAST_DAY(:startDate), :startDate) + 1) " +
                        " - (FLOOR((DATEDIFF(LAST_DAY(:startDate), :startDate) + (WEEKDAY(:startDate) + 1)) / 7)) " +
                        " - (CASE WHEN WEEKDAY(:startDate) = 6 THEN 1 ELSE 0 END) " +
                        " - (SELECT COUNT(*) " +
                        " FROM logistics.publicholidays " +
                        " WHERE date BETWEEN :startDate AND LAST_DAY(:startDate) " +
                        " AND WEEKDAY(date) != 6) AS working_days"
        );

        // Set the start date parameter for each placeholder
        nativeQuery.setParameter("startDate", startDateString);

        Object result = nativeQuery.getSingleResult();
        return result != null ? ((Number) result).intValue() : 0;
    }


    @Override
    public List<RbmArrViewModel> getRbmTodayArr() throws Exception {
        LocalDate todayDate = LocalDate.now();
        return getRbmTodayArr(todayDate);
    }

    @Override
    public List<RbmTargetAndAchievementsModel> getRbmTargetsAndAchievemnts(LocalDate startDate, LocalDate endDate) {

        List<RbmTargetsModel> rbmTargetsList = rbmTargetsRepository.selectTargetsModelListByDates(startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));

        LOGGER.info("rbmTargetsList {}", rbmTargetsList);
        // Group Targtes by RBM and Warehouse
        Map<String, RbmTargetsModel> targetsMap = rbmTargetsList.stream()
                .collect(Collectors.toMap(
                        a -> a.getRbmAuthId() + "-" + a.getWarehouseId(),
                        a -> a,
                        (a1, a2) -> mergeTargets(a1, a2) // Handle duplicates by merging
                ));


        List<RbmAchievementsModel> rbmAchievements = rbmAchievementsRepository.selectAchievementsModelListByDates(startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
        LOGGER.info("rbmTargetsList {}", rbmAchievements);
        // Group achievements by RBM and Warehouse
        Map<String, RbmAchievementsModel> achievementMap = rbmAchievements.stream()
                .collect(Collectors.toMap(
                        a -> a.getRbmAuthId() + "-" + a.getWarehouseId(),
                        a -> a,
                        (a1, a2) -> mergeAchievements(a1, a2) // Handle duplicates by merging
                ));

        return targetsMap.keySet().stream()
                .map(key -> {
                    String[] parts = key.split("-");
                    int rbmAuthId = Integer.parseInt(parts[0]);
                    int warehouseId = Integer.parseInt(parts[1]);

                    RbmTargetsModel target = targetsMap.get(key);
                    RbmAchievementsModel achievement = achievementMap.getOrDefault(key, new RbmAchievementsModel());

                    RbmTargetAndAchievementsModel model = new RbmTargetAndAchievementsModel();
                    model.setAuthId(rbmAuthId);
                    model.setRbmName(target.getRbmName());
                    model.setWarehouseName(ProfitMandiConstants.WAREHOUSE_MAP.getOrDefault(warehouseId, "Unknown"));

                    // Set target values
                    model.setHidTarget((long) target.getHidTarget());
                    model.setRunningTarget((long) target.getRunningTarget());
                    model.setFastMovingTarget((long) target.getFastMovingTarget());
                    model.setSlowMovingTarget((long) target.getSlowMovingTarget());
                    model.setOtherMovingTarget((long) target.getOtherTarget());

                    // Set achievement values
                    model.setAchievedHid((long) achievement.getAchievedHidTarget());
                    model.setAchievedRunning((long) achievement.getAchievedRunningTarget());
                    model.setAchievedFastMoving((long) achievement.getAchievedFastMovingTarget());
                    model.setAchievedSlowMoving((long) achievement.getAchievedSlowMovingTarget());
                    model.setAchievedOtherMoving((long) achievement.getAchievedOtherTarget());

                    model.setTotalTarget(
                            (long) target.getHidTarget() +
                                    (long) target.getRunningTarget() +
                                    (long) target.getFastMovingTarget() +
                                    (long) target.getSlowMovingTarget() +
                                    (long) target.getOtherTarget()
                    );
                    model.setTotalAchievemnt(
                            (long) achievement.getAchievedHidTarget() +
                                    (long) achievement.getAchievedRunningTarget() +
                                    (long) achievement.getAchievedFastMovingTarget() +
                                    (long) achievement.getAchievedSlowMovingTarget() +
                                    (long) achievement.getAchievedOtherTarget()
                    );

                    return model;
                })
                .collect(Collectors.toList());

    }

    private RbmTargetsModel mergeTargets(RbmTargetsModel a1, RbmTargetsModel a2) {

        // Merge logic for achievements (aggregate the target and achieved values)
        a1.setHidTarget((a1.getHidTarget()) +
                (a2.getHidTarget()));

        a1.setFastMovingTarget((a1.getFastMovingTarget()) +
                (a2.getFastMovingTarget()));

        a1.setSlowMovingTarget((a1.getSlowMovingTarget()) +
                (a2.getSlowMovingTarget()));

        a1.setRunningTarget((a1.getRunningTarget()) +
                (a2.getRunningTarget()));

        a1.setOtherTarget((a1.getOtherTarget()) +
                (a2.getOtherTarget()));
        return a1;
    }

    private RbmAchievementsModel mergeAchievements(RbmAchievementsModel a1, RbmAchievementsModel a2) {
        // Merge logic for achievements (aggregate the target and achieved values)
        a1.setAchievedHidTarget((a1.getAchievedHidTarget()) +
                (a2.getAchievedHidTarget()));

        a1.setAchievedRunningTarget((a1.getAchievedRunningTarget()) +
                (a2.getAchievedRunningTarget()));

        a1.setAchievedFastMovingTarget((a1.getAchievedFastMovingTarget()) +
                (a2.getAchievedFastMovingTarget()));

        a1.setAchievedSlowMovingTarget((a1.getAchievedSlowMovingTarget()) +
                (a2.getAchievedSlowMovingTarget()));

        a1.setAchievedOtherTarget((a1.getAchievedOtherTarget()) +
                (a2.getAchievedOtherTarget()));

        return a1;
    }

    @Override
    public List<RbmArrViewModel> getRbmTodayArr(LocalDate todayDate) throws Exception {

        LocalDate startDateOfMonthDay1 = LocalDate.now().withDayOfMonth(1);

        List<WarehouseRbmTargetModel> warehouseRbmTargetModels = this.getWarehouseWiseRbmMonthlyTarget();

        List<TodayAchievedMovementModel> todayAchievedMovementModels = getMovementWiseAchievementByDate(todayDate, todayDate.plusDays(1));

        List<MTDAchievedTargetModel> mtdAchievedTargetModels = getDateWiseAchievedTargetOfRbm(startDateOfMonthDay1, todayDate);

        int remainingWorkingDaysCount = getWorkingDaysCount(todayDate);

        List<RbmTargets> todayRbmTargetsList = rbmTargetsRepository.selectTargetsByDates(todayDate.atStartOfDay(), todayDate.atTime(LocalTime.MAX));

        LOGGER.info("todayRbmTargetsList {}", todayRbmTargetsList);

        List<RbmArrViewModel> rbmArrViewModels = new ArrayList<>();

        if (!todayRbmTargetsList.isEmpty()) {

            for (WarehouseRbmTargetModel rbmTarget : warehouseRbmTargetModels) {

                float monthlyTarget = rbmTarget.getMonthlyTarget();
                float achievedSoFar = (float) mtdAchievedTargetModels.stream()
                        .filter(x -> x.getAuthId() == rbmTarget.getAuthId() && x.getWarehouseId() == rbmTarget.getWarehouseId())
                        .mapToDouble(MTDAchievedTargetModel::getAcheivedMonthlyTarget)
                        .sum();

                float remainingTarget = monthlyTarget - achievedSoFar;

                float todayTarget = (remainingWorkingDaysCount > 0 && remainingTarget > 0) ? remainingTarget / remainingWorkingDaysCount : 0;

                String warehouseName = ProfitMandiConstants.WAREHOUSE_MAP.getOrDefault(rbmTarget.getWarehouseId(), "Unknown");

                TodayAchievedMovementModel todayAchievedMovementModel = todayAchievedMovementModels.stream().filter(x -> x.getAuthId() == rbmTarget.getAuthId() && x.getWarehouseId() == rbmTarget.getWarehouseId()).findFirst().get();

                Optional<RbmTargets> optionalTodayRbmTargets = todayRbmTargetsList.stream()
                        .filter(x -> x.getRbmAuthId() == rbmTarget.getAuthId() && x.getWarehouseId() == rbmTarget.getWarehouseId())
                        .findFirst();

                if (optionalTodayRbmTargets.isPresent()) {
                    RbmTargets todayRbmTargets = optionalTodayRbmTargets.get();
                    LOGGER.info("todayRbmTargets {}", todayRbmTargets);
                    RbmArrViewModel viewModel = new RbmArrViewModel();

                    viewModel.setAuthId(rbmTarget.getAuthId());
                    viewModel.setRbmName(rbmTarget.getRbmName());
                    viewModel.setWarehouseName(warehouseName);
                    viewModel.setTodayTarget(Math.round(todayTarget));
                    viewModel.setMonthlyTarget(Math.round(monthlyTarget));
                    viewModel.setMtdAchievedTarget(Math.round(achievedSoFar));

                    viewModel.setTodayHidTarget(Math.round((todayRbmTargets.getHidTarget())));
                    viewModel.setTodayFastMovingTarget(Math.round(todayRbmTargets.getFastMovingTarget()));
                    viewModel.setTodaySlowMovingTarget(Math.round(todayRbmTargets.getSlowMovingtarget()));
                    viewModel.setTodayRunningTarget(Math.round(todayRbmTargets.getRunningtarget()));
                    viewModel.setTodayOtherMovingTarget(Math.round(todayRbmTargets.getOtherTarget()));

                    viewModel.setTodayAchievedHidTarget(Math.round(todayAchievedMovementModel.getHidBilled()));
                    viewModel.setTodayAchievedFastMovingTarget(Math.round(todayAchievedMovementModel.getFastMovingBilled()));
                    viewModel.setTodayAchievedSlowMovingTarget(Math.round(todayAchievedMovementModel.getSlowMovinBilled()));
                    viewModel.setTodayAchievedRunningTarget(Math.round(todayAchievedMovementModel.getRunningBilled()));
                    viewModel.setTodayAchievedOtherMovingTarget(Math.round(todayAchievedMovementModel.getOtherBilled()));
                    viewModel.setTotalAchievedTarget(Math.round(todayAchievedMovementModel.getHidBilled() + todayAchievedMovementModel.getFastMovingBilled() + todayAchievedMovementModel.getSlowMovinBilled() + todayAchievedMovementModel.getRunningBilled() + todayAchievedMovementModel.getOtherBilled()));

                    rbmArrViewModels.add(viewModel);
                } else {
                    LOGGER.info("No matching RbmTargets found for AuthId: {} and rbmname {} and WarehouseId: {}", rbmTarget.getAuthId(), rbmTarget.getRbmName(), rbmTarget.getWarehouseId());
                }



            }
        }

        LOGGER.info("rbmArrViewModels {}", rbmArrViewModels);
        return rbmArrViewModels;
    }

    @Override
    public void setMovementWiseRbmTargets() {
        LocalDate todayDate = LocalDate.now();

        LocalDate startDateOfMonthDay1 = LocalDate.now().withDayOfMonth(1);

        List<WarehouseRbmTargetModel> warehouseRbmTargetModels = this.getWarehouseWiseRbmMonthlyTarget();

        List<MTDAchievedTargetModel> mtdAchievedTargetModels = getDateWiseAchievedTargetOfRbm(startDateOfMonthDay1, todayDate);


        int remainingWorkingDaysCount = getWorkingDaysCount(todayDate);

        List<WarehouseMobileStockByMovementModel> warehouseMobileStockByMovementModels = getWarehouseMobileStockByMovement();

        for (WarehouseRbmTargetModel rbmTarget : warehouseRbmTargetModels) {

            float monthlyTarget = rbmTarget.getMonthlyTarget();
            float achievedSoFar = (float) mtdAchievedTargetModels.stream()
                    .filter(x -> x.getAuthId() == rbmTarget.getAuthId() && x.getWarehouseId() == rbmTarget.getWarehouseId())
                    .mapToDouble(MTDAchievedTargetModel::getAcheivedMonthlyTarget)
                    .sum();


            float remainingTarget = monthlyTarget - achievedSoFar;
            LOGGER.info("remainingTarget {}", remainingTarget);

            float todayTarget = (remainingWorkingDaysCount > 0 && remainingTarget > 0) ? remainingTarget / remainingWorkingDaysCount : 0;
            LOGGER.info("todayTarget {}", todayTarget);

            // Get the warehouse stock data
            WarehouseMobileStockByMovementModel warehouseMobileStockByMovementModel = warehouseMobileStockByMovementModels.stream()
                    .filter(x -> x.getWarehouseId() == rbmTarget.getWarehouseId()).findFirst().orElse(null);


            if (warehouseMobileStockByMovementModel != null) {

                // Total stock value for this warehouse
                float totalStockValue = warehouseMobileStockByMovementModel.getTotalAvailabilityPrice();

                // Calculate target allocation based on stock value proportion
                float hidTarget = (warehouseMobileStockByMovementModel.getTotalHidCatalogPrice() / totalStockValue) * todayTarget;
                float fastMovingTarget = (warehouseMobileStockByMovementModel.getTotalFastMovingCatalogPrice() / totalStockValue) * todayTarget;
                float slowMovingTarget = (warehouseMobileStockByMovementModel.getTotalSlowMovingCatalogPrice() / totalStockValue) * todayTarget;
                float runningTarget = (warehouseMobileStockByMovementModel.getTotalRunningCatalogPrice() / totalStockValue) * todayTarget;
                float otherTarget = (warehouseMobileStockByMovementModel.getTotalOtherCategoryCatalogPrice() / totalStockValue) * todayTarget;

                RbmTargets rbmTargets = new RbmTargets();
                rbmTargets.setWarehouseId(rbmTarget.getWarehouseId());
                rbmTargets.setRbmAuthId(rbmTarget.getAuthId());
                rbmTargets.setRbmName(rbmTarget.getRbmName());
                rbmTargets.setRunningtarget(runningTarget);
                rbmTargets.setHidTarget(hidTarget);
                rbmTargets.setFastMovingTarget(fastMovingTarget);
                rbmTargets.setSlowMovingtarget(slowMovingTarget);
                rbmTargets.setOtherTarget(otherTarget);
                rbmTargets.setCreateTimestamp(LocalDateTime.now());

                rbmTargetsRepository.persist(rbmTargets);

            }
        }

    }


    @Override
    public void setMovementWiseRbmAchievement() {
        LocalDate todayDate = LocalDate.now();

        List<TodayAchievedMovementModel> todayAchievedMovementModels = getMovementWiseAchievementByDate(todayDate, todayDate.plusDays(1));


        for (TodayAchievedMovementModel achievement : todayAchievedMovementModels) {

            RbmAchievements rbmAchievements = new RbmAchievements();

            rbmAchievements.setRbmAuthId(achievement.getAuthId());
            rbmAchievements.setRbmName(achievement.getRbmName());
            rbmAchievements.setWarehouseId(achievement.getWarehouseId());
            rbmAchievements.setAchievedHidTarget(achievement.getHidBilled());
            rbmAchievements.setAchievedFastMovingTarget(achievement.getFastMovingBilled());
            rbmAchievements.setAchievedSlowMovingTarget(achievement.getSlowMovinBilled());
            rbmAchievements.setAchievedRunningTarget(achievement.getRunningBilled());
            rbmAchievements.setAchievedOtherTarget(achievement.getOtherBilled());
            rbmAchievements.setCreateTimestamp(LocalDateTime.now());

            rbmAchievementsRepository.persist(rbmAchievements);

        }

    }

    @Override
    public List<Sold15daysOldAgingModel> getAgingSale(LocalDate startDate, LocalDate endDate) {
        Session session = sessionFactory.getCurrentSession();
        final TypedQuery<Sold15daysOldAgingModel> typedQuerySimilar = session.createNamedQuery("Aging.SoldAgingModel", Sold15daysOldAgingModel.class);
        typedQuerySimilar.setParameter("startDate", startDate);
        typedQuerySimilar.setParameter("endDate", endDate);
        return typedQuerySimilar.getResultList();

    }

    @Override
    public List<RbmBilledFofoIdsModel> getDateWiseBilledFofoIdByRbm(LocalDate startDate, LocalDate endDate) {
        Session session = sessionFactory.getCurrentSession();
        final TypedQuery<RbmBilledFofoIdsModel> typedQuerySimilar = session.createNamedQuery("RBM.RbmBilledFofoId", RbmBilledFofoIdsModel.class);
        typedQuerySimilar.setParameter("startDate", startDate);
        typedQuerySimilar.setParameter("endDate", endDate);
        return typedQuerySimilar.getResultList();

    }

    public List<Our15DaysOldAgingStock> our15DaysAgingStock() {
        Session session = sessionFactory.getCurrentSession();
        final TypedQuery<Our15DaysOldAgingStock> typedQuerySimilar = session.createNamedQuery("Aging.15DaysOurStock", Our15DaysOldAgingStock.class);
        return typedQuerySimilar.getResultList();

    }


}