package eu.reply.lea.services.yms.task.transitlocationtracker.integration.yms;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

import java.util.Optional;

import eu.reply.lea.services.yms.task.locationaware.LocationAwareTask;
import eu.reply.lea.services.yms.task.sequence.LocationAwareTasksSequence;
import eu.reply.lea.services.yms.task.sequence.repository.AbstractTasksSequenceRepository;
import eu.reply.lea.services.yms.task.transitlocationtracker.NextTaskProvider;
import eu.reply.sce.backend.core.entity.EntityReference;

@ApplicationScoped
public class TasksSequenceNextTaskProvider implements NextTaskProvider {

    @Inject
    private AbstractTasksSequenceRepository abstractTasksSequenceRepository;

    @Override
    public Optional<LocationAwareTask<?, ?, ?>> getNextActiveTask(EntityReference logisticUnitReference) {
        LocationAwareTasksSequence<LocationAwareTask<?, ?, ?>> tasksSequence =
            abstractTasksSequenceRepository.findByLogisticUnitReference(logisticUnitReference);

        if (tasksSequence != null && !tasksSequence.getActiveTasks().isEmpty()) {
            return Optional.of(tasksSequence.getActiveTasks().get(0));
        }

        return Optional.empty();
    }
}
package eu.reply.lea.services.yms.task.transitlocationtracker;


import java.util.Optional;

import eu.reply.lea.services.yms.task.locationaware.LocationAwareTask;
import eu.reply.sce.backend.core.entity.EntityReference;

public interface NextTaskProvider {
    Optional<LocationAwareTask<?, ?, ?>> getNextActiveTask(EntityReference logisticUnitReference);
}
package eu.reply.lea.services.yms.task.transitlocationtracker;

import java.util.Optional;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Inject;

import eu.reply.lea.services.yms.task.locationaware.LocationAwareTask;
import eu.reply.lea.services.yms.task.transitlocationtracker.event.LogisticUnitLocationUpdateCommand;
import eu.reply.sce.backend.core.entity.EntityReference;
import eu.reply.sce.backend.core.jee.event.Producer;

public class LogisticUnitLocationTrackerService {

    @Inject
    private LogisticUnitLocationTrackerRepository logisticUnitLocationTrackerRepository;

    @Inject
    private Producer<LogisticUnitLocationUpdateCommand> logisticUnitLocationUpdateCommandProducer;

    @Inject
    private NextTaskProvider nextTaskProvider;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void updateLocation(final EntityReference logisticUnitRef,
                               final QueueingStatusDTO queueingStatusDTO) {
        LogisticsUnitLocationTracker
            logisticsUnitLocationTracker = logisticUnitLocationTrackerRepository.getOrCreateLogisticUnitLocationTracker(logisticUnitRef);
        Optional<LocationAwareTask<?, ?, ?>> optionalNextActiveTask = nextTaskProvider.getNextActiveTask(logisticUnitRef);

        if (optionalNextActiveTask.isEmpty()) {
            return;
        }
        LocationAwareTask<?, ?, ?> nextActiveTask = optionalNextActiveTask.get();

        QueueingStatus queueingStatus = new QueueingStatus(
            queueingStatusDTO.getExecutionLocationRef(),
            queueingStatusDTO.getCurrentLocationRef(),
            queueingStatusDTO.getCurrentLocationAreaType(),
            queueingStatusDTO.getEventInstant()
        );

        logisticsUnitLocationTracker.updateQueueingStatus(nextActiveTask.getLocation(), queueingStatus);
        Optional<LogisticUnitLocationUpdateCommand> updateCommand = logisticsUnitLocationTracker.generateCommandToUpdateLocation();
        updateCommand.ifPresent(logisticUnitLocationUpdateCommandProducer::fire);

    }



    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void commandTransitToUpdateLoadingUnitPosition(final EntityReference logisticUnitRef) {
        Optional<LocationAwareTask<?, ?, ?>> optionalNextActiveTask = nextTaskProvider.getNextActiveTask(logisticUnitRef);

        if (optionalNextActiveTask.isEmpty()) {
            return;
        }
        LocationAwareTask<?, ?, ?> nextActiveTask = optionalNextActiveTask.get();

        // Get the TransitLocationTracker
        LogisticsUnitLocationTracker
            logisticsUnitLocationTracker = logisticUnitLocationTrackerRepository.findByLogisticUnitReference(logisticUnitRef);

        // Update the next execution location
        logisticsUnitLocationTracker.updateNextExecutionLocation(nextActiveTask.getLocation());

        // Command transit to update location
        Optional<LogisticUnitLocationUpdateCommand> updateCommand = logisticsUnitLocationTracker.generateCommandToUpdateLocation();
        updateCommand.ifPresent(logisticUnitLocationUpdateCommandProducer::fire);
    }

}

can you provide javadoc