<commit_before>package org.innovateuk.ifs.cofunder.transactional;

import org.innovateuk.ifs.application.domain.Application;
import org.innovateuk.ifs.cofunder.domain.CofunderAssignment;
import org.innovateuk.ifs.cofunder.domain.CofunderOutcome;
import org.innovateuk.ifs.cofunder.repository.CofunderAssignmentRepository;
import org.innovateuk.ifs.cofunder.resource.*;
import org.innovateuk.ifs.cofunder.workflow.CofunderAssignmentWorkflowHandler;
import org.innovateuk.ifs.commons.exception.ObjectNotFoundException;
import org.innovateuk.ifs.commons.service.ServiceResult;
import org.innovateuk.ifs.notifications.resource.*;
import org.innovateuk.ifs.notifications.service.NotificationService;
import org.innovateuk.ifs.organisation.domain.SimpleOrganisation;
import org.innovateuk.ifs.profile.domain.Profile;
import org.innovateuk.ifs.profile.repository.ProfileRepository;
import org.innovateuk.ifs.transactional.BaseTransactionalService;
import org.innovateuk.ifs.user.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.lang.String.format;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;
import static org.innovateuk.ifs.commons.error.CommonErrors.notFoundError;
import static org.innovateuk.ifs.commons.error.CommonFailureKeys.COFUNDER_ASSIGNMENT_ALREADY_EXISTS;
import static org.innovateuk.ifs.commons.error.CommonFailureKeys.COFUNDER_WORKFLOW_TRANSITION_FAILURE;
import static org.innovateuk.ifs.commons.service.ServiceResult.serviceFailure;
import static org.innovateuk.ifs.commons.service.ServiceResult.serviceSuccess;
import static org.innovateuk.ifs.util.EntityLookupCallbacks.find;

@Service
public class CofunderAssignmentServiceImpl extends BaseTransactionalService implements CofunderAssignmentService {

    enum Notifications {
        ASSIGN_COFUNDER,
        REMOVE_COFUNDER
    }

    @Value("${ifs.web.baseURL}")
    private String webBaseUrl;

    @Autowired
    private CofunderAssignmentWorkflowHandler cofunderAssignmentWorkflowHandler;

    @Autowired
    private CofunderAssignmentRepository cofunderAssignmentRepository;

    @Autowired
    private ProfileRepository profileRepository;

    @Autowired
    private NotificationService notificationService;

    @Autowired
    private SystemNotificationSource systemNotificationSource;

    @Override
    public ServiceResult<CofunderAssignmentResource> getAssignment(long userId, long applicationId) {
        return findCofunderAssignmentByUserAndApplication(userId, applicationId)
                .andOnSuccessReturn(this::map);
    }

    @Override
    @Transactional
    public ServiceResult<CofunderAssignmentResource> assign(long userId, long applicationId) {
        boolean exists = cofunderAssignmentRepository.existsByParticipantIdAndTargetId(userId, applicationId);
        if (exists) {
            return serviceFailure(COFUNDER_ASSIGNMENT_ALREADY_EXISTS);
        }
        return doAssign(userId, applicationId);
    }

    private ServiceResult<CofunderAssignmentResource> doAssign(long userId, long applicationId) {
        return find(application(applicationId), user(userId)).andOnSuccess(
                (application, user) ->
                        serviceSuccess(map(cofunderAssignmentRepository.save(new CofunderAssignment(application, user))))
                                .andOnSuccess(resource ->
                                     notifyUserAssignedAsCofunder(user, application)
                                             .andOnSuccessReturn(() -> resource)
                                )
        );
    }

    @Override
    @Transactional
    public ServiceResult<Void> assign(List<Long> userIds, long applicationId) {
        userIds.forEach(userId -> {
            boolean exists = cofunderAssignmentRepository.existsByParticipantIdAndTargetId(userId, applicationId);
            if (!exists) {
                doAssign(userId, applicationId);
            }
        });
        return serviceSuccess();
    }

    private ServiceResult<Void> notifyUserAssignedAsCofunder(User user, Application application) {
        NotificationTarget recipient = new UserNotificationTarget(user.getName(), user.getEmail());
        Map<String, Object> notificationArguments = new HashMap<>();
        notificationArguments.put("applicationId", application.getId());
        notificationArguments.put("applicationName", application.getName());
        notificationArguments.put("link", format("%s/application/%d", webBaseUrl, application.getId()));
        Notification notification = new Notification(systemNotificationSource, recipient, Notifications.ASSIGN_COFUNDER, notificationArguments);
        return notificationService.sendNotificationWithFlush(notification, NotificationMedium.EMAIL);
    }
<commit_msg>IFS-8404 failing if any assignments fail<commit_after>package org.innovateuk.ifs.cofunder.transactional;

import org.innovateuk.ifs.application.domain.Application;
import org.innovateuk.ifs.cofunder.domain.CofunderAssignment;
import org.innovateuk.ifs.cofunder.domain.CofunderOutcome;
import org.innovateuk.ifs.cofunder.repository.CofunderAssignmentRepository;
import org.innovateuk.ifs.cofunder.resource.*;
import org.innovateuk.ifs.cofunder.workflow.CofunderAssignmentWorkflowHandler;
import org.innovateuk.ifs.commons.exception.ObjectNotFoundException;
import org.innovateuk.ifs.commons.service.ServiceResult;
import org.innovateuk.ifs.notifications.resource.*;
import org.innovateuk.ifs.notifications.service.NotificationService;
import org.innovateuk.ifs.organisation.domain.SimpleOrganisation;
import org.innovateuk.ifs.profile.domain.Profile;
import org.innovateuk.ifs.profile.repository.ProfileRepository;
import org.innovateuk.ifs.transactional.BaseTransactionalService;
import org.innovateuk.ifs.user.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.lang.String.format;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;
import static org.innovateuk.ifs.commons.error.CommonErrors.notFoundError;
import static org.innovateuk.ifs.commons.error.CommonFailureKeys.COFUNDER_ASSIGNMENT_ALREADY_EXISTS;
import static org.innovateuk.ifs.commons.error.CommonFailureKeys.COFUNDER_WORKFLOW_TRANSITION_FAILURE;
import static org.innovateuk.ifs.commons.service.ServiceResult.serviceFailure;
import static org.innovateuk.ifs.commons.service.ServiceResult.serviceSuccess;
import static org.innovateuk.ifs.util.EntityLookupCallbacks.find;

@Service
public class CofunderAssignmentServiceImpl extends BaseTransactionalService implements CofunderAssignmentService {

    enum Notifications {
        ASSIGN_COFUNDER,
        REMOVE_COFUNDER
    }

    @Value("${ifs.web.baseURL}")
    private String webBaseUrl;

    @Autowired
    private CofunderAssignmentWorkflowHandler cofunderAssignmentWorkflowHandler;

    @Autowired
    private CofunderAssignmentRepository cofunderAssignmentRepository;

    @Autowired
    private ProfileRepository profileRepository;

    @Autowired
    private NotificationService notificationService;

    @Autowired
    private SystemNotificationSource systemNotificationSource;

    @Override
    public ServiceResult<CofunderAssignmentResource> getAssignment(long userId, long applicationId) {
        return findCofunderAssignmentByUserAndApplication(userId, applicationId)
                .andOnSuccessReturn(this::map);
    }

    @Override
    @Transactional
    public ServiceResult<CofunderAssignmentResource> assign(long userId, long applicationId) {
        boolean exists = cofunderAssignmentRepository.existsByParticipantIdAndTargetId(userId, applicationId);
        if (exists) {
            return serviceFailure(COFUNDER_ASSIGNMENT_ALREADY_EXISTS);
        }
        return doAssign(userId, applicationId);
    }

    private ServiceResult<CofunderAssignmentResource> doAssign(long userId, long applicationId) {
        return find(application(applicationId), user(userId)).andOnSuccess(
                (application, user) ->
                        serviceSuccess(map(cofunderAssignmentRepository.save(new CofunderAssignment(application, user))))
                                .andOnSuccess(resource ->
                                     notifyUserAssignedAsCofunder(user, application)
                                             .andOnSuccessReturn(() -> resource)
                                )
        );
    }

    @Override
    @Transactional
    public ServiceResult<Void> assign(List<Long> userIds, long applicationId) {
        for(Long userId: userIds)  {
            boolean exists = cofunderAssignmentRepository.existsByParticipantIdAndTargetId(userId, applicationId);
            if (!exists) {
                ServiceResult<CofunderAssignmentResource> assignmentResult = doAssign(userId, applicationId);
                if (assignmentResult.isFailure()) {
                    return serviceFailure(assignmentResult.getFailure());
                }
            }
        }
        return serviceSuccess();
    }

    private ServiceResult<Void> notifyUserAssignedAsCofunder(User user, Application application) {
        NotificationTarget recipient = new UserNotificationTarget(user.getName(), user.getEmail());
        Map<String, Object> notificationArguments = new HashMap<>();
        notificationArguments.put("applicationId", application.getId());
        notificationArguments.put("applicationName", application.getName());
        notificationArguments.put("link", format("%s/application/%d", webBaseUrl, application.getId()));
        Notification notification = new Notification(systemNotificationSource, recipient, Notifications.ASSIGN_COFUNDER, notificationArguments);
        return notificationService.sendNotificationWithFlush(notification, NotificationMedium.EMAIL);
    }

{'fraction_non_alphanumeric': 0.08267604295353036, 'fraction_numerical': 0.000380119737717381, 'mean_word_length': 4.204747774480712, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3116412', 'n_tokens_mistral': 2727, 'n_tokens_neox': 2760, 'n_words': 443}