Subversion Repositories SmartDukaan

Rev

Rev 37166 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.service;

import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.dao.entity.user.AgendaInstance;
import com.spice.profitmandi.dao.entity.user.AgendaVisitLog;
import com.spice.profitmandi.dao.enumuration.dtr.AgendaSource;
import com.spice.profitmandi.dao.enumuration.dtr.AgendaStatus;
import com.spice.profitmandi.dao.repository.dtr.AgendaInstanceRepository;
import com.spice.profitmandi.dao.repository.dtr.AgendaVisitLogRepository;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;

@Service
@Transactional
public class AgendaInstanceServiceImpl implements AgendaInstanceService {

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

    @Autowired
    AgendaInstanceRepository agendaInstanceRepository;

    @Autowired
    AgendaVisitLogRepository agendaVisitLogRepository;

    @Override
    public AgendaInstance open(int fofoId, String agendaType, AgendaSource source, Integer openedBy,
                               String openMetricJson) throws ProfitMandiBusinessException {
        AgendaInstance existing = agendaInstanceRepository.selectOpenByFofoIdAndType(fofoId, agendaType);
        if (existing != null) return existing;

        AgendaInstance instance = new AgendaInstance();
        instance.setFofoId(fofoId);
        instance.setAgendaType(agendaType);
        instance.setSource(source.name());
        instance.setStatus(AgendaStatus.OPEN.name());
        instance.setOpenedOn(LocalDateTime.now());
        instance.setOpenedBy(openedBy);
        instance.setOpenMetric(openMetricJson);
        try {
            agendaInstanceRepository.persist(instance);
            return instance;
        } catch (Exception e) {
            // uq_one_open race: someone opened it between select and insert.
            AgendaInstance winner = agendaInstanceRepository.selectOpenByFofoIdAndType(fofoId, agendaType);
            if (winner != null) {
                LOGGER.info("Agenda open race for fofoId={} type={} — using existing instance {}",
                        fofoId, agendaType, winner.getId());
                return winner;
            }
            throw new ProfitMandiBusinessException("agendaType", agendaType,
                    "Could not open agenda instance for fofoId " + fofoId + ": " + e.getMessage());
        }
    }

    @Override
    public void closeByMetric(AgendaInstance instance, String closeMetricJson) {
        instance.setStatus(AgendaStatus.CLOSED.name());
        instance.setClosedOn(LocalDateTime.now());
        instance.setClosedBy(null);
        instance.setCloseMetric(closeMetricJson);
        agendaInstanceRepository.persist(instance);
    }

    @Override
    public void closeManual(AgendaInstance instance, int closedBy, String remark)
            throws ProfitMandiBusinessException {
        if (AgendaSource.AUTO.name().equals(instance.getSource())) {
            throw new ProfitMandiBusinessException("instanceId", instance.getId(),
                    "Auto agendas close only when the metric normalizes");
        }
        if (!AgendaStatus.OPEN.name().equals(instance.getStatus())) {
            throw new ProfitMandiBusinessException("instanceId", instance.getId(),
                    "Agenda instance is already closed");
        }
        instance.setStatus(AgendaStatus.CLOSED.name());
        instance.setClosedOn(LocalDateTime.now());
        instance.setClosedBy(closedBy);
        instance.setCloseRemark(remark);
        agendaInstanceRepository.persist(instance);
    }

    @Override
    public java.util.List<AgendaInstance> filterVisibleForVisit(java.util.List<AgendaInstance> openInstances) {
        return filterVisibleForVisitStatic(openInstances);
    }

    // Static + pure for unit tests. Input must be one store's OPEN instances.
    static java.util.List<AgendaInstance> filterVisibleForVisitStatic(java.util.List<AgendaInstance> openInstances) {
        if (openInstances == null || openInstances.isEmpty()) return openInstances;
        boolean revivalOpen = false;
        for (AgendaInstance ai : openInstances) {
            if (com.spice.profitmandi.dao.enumuration.dtr.AgendaType.REVIVAL.name().equals(ai.getAgendaType())) {
                revivalOpen = true;
                break;
            }
        }
        if (!revivalOpen) return openInstances;
        java.util.List<AgendaInstance> visible = new java.util.ArrayList<>();
        for (AgendaInstance ai : openInstances) {
            boolean keep = AgendaSource.MANUAL.name().equals(ai.getSource())
                    || com.spice.profitmandi.dao.enumuration.dtr.AgendaType.REVIVAL.name().equals(ai.getAgendaType())
                    || com.spice.profitmandi.dao.enumuration.dtr.AgendaType.CREDIT_DUES.name().equals(ai.getAgendaType());
            if (keep) visible.add(ai);
        }
        return visible;
    }

    @Override
    public void logVisit(int instanceId, Integer locationTrackingId, int visitorUserId,
                         LocalDate visitDate, String discussion) throws ProfitMandiBusinessException {
        AgendaInstance instance = agendaInstanceRepository.selectById(instanceId);
        if (instance == null) {
            throw new ProfitMandiBusinessException("instanceId", instanceId, "Agenda instance not found");
        }
        if (!AgendaStatus.OPEN.name().equals(instance.getStatus())) {
            throw new ProfitMandiBusinessException("instanceId", instanceId,
                    "Agenda instance is closed — discussions attach to open agendas only");
        }
        AgendaVisitLog log = new AgendaVisitLog();
        log.setAgendaInstanceId(instanceId);
        log.setLocationTrackingId(locationTrackingId);
        log.setVisitorUserId(visitorUserId);
        log.setVisitDate(visitDate != null ? visitDate : LocalDate.now());
        log.setDiscussion(discussion);
        agendaVisitLogRepository.persist(log);
    }
}