<commit_before>package org.innovateuk.ifs.application.validation;

import org.innovateuk.ifs.application.domain.Application;
import org.innovateuk.ifs.application.domain.FormInputResponse;
import org.innovateuk.ifs.application.repository.FormInputResponseRepository;
import org.innovateuk.ifs.commons.error.ValidationMessages;
import org.innovateuk.ifs.application.validator.ApplicationDetailsMarkAsCompleteValidator;
import org.innovateuk.ifs.commons.error.Error;
import org.innovateuk.ifs.finance.domain.ApplicationFinance;
import org.innovateuk.ifs.finance.handler.item.FinanceRowHandler;
import org.innovateuk.ifs.finance.resource.cost.FinanceRowItem;
import org.innovateuk.ifs.finance.transactional.FinanceRowCostsService;
import org.innovateuk.ifs.finance.transactional.FinanceService;
import org.innovateuk.ifs.finance.transactional.ProjectFinanceRowService;
import org.innovateuk.ifs.form.domain.FormInput;
import org.innovateuk.ifs.form.domain.Question;
import org.innovateuk.ifs.form.repository.FormInputRepository;
import org.innovateuk.ifs.form.resource.FormInputType;
import org.innovateuk.ifs.organisation.resource.OrganisationResource;
import org.innovateuk.ifs.organisation.resource.OrganisationTypeEnum;
import org.innovateuk.ifs.organisation.transactional.OrganisationService;
import org.innovateuk.ifs.security.LoggedInUserSupplier;
import org.innovateuk.ifs.transactional.BaseTransactionalService;
import org.innovateuk.ifs.user.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.innovateuk.ifs.commons.error.Error.fieldError;
import static org.innovateuk.ifs.commons.error.ValidationMessages.fromBindingResult;
import static org.innovateuk.ifs.commons.error.ValidationMessages.noErrors;
import static org.innovateuk.ifs.util.CollectionFunctions.simpleFindFirst;

/**
 * Class to validate several objects
 */
@Service
public class ApplicationValidatorServiceImpl extends BaseTransactionalService implements ApplicationValidatorService {

    @Autowired
    private FormInputResponseRepository formInputResponseRepository;

    @Autowired
    private FormInputRepository formInputRepository;

    @Autowired
    private FinanceRowCostsService financeRowCostsService;

    @Autowired
    private FinanceService financeService;

    @Autowired
    private ProjectFinanceRowService projectFinanceRowService;

    @Autowired
    private ApplicationValidationUtil applicationValidationUtil;

    @Autowired
    private OrganisationService organisationService;

    @Autowired
    private LoggedInUserSupplier loggedInUserSupplier;

    @Override
    public List<BindingResult> validateFormInputResponse(Long applicationId, Long formInputId) {
        List<BindingResult> results = new ArrayList<>();
        List<FormInputResponse> responses = formInputResponseRepository.findByApplicationIdAndFormInputId(applicationId, formInputId);
        if (!responses.isEmpty()) {
            results.addAll(responses.stream().map(formInputResponse -> applicationValidationUtil.validateResponse(formInputResponse, false)).collect(Collectors.toList()));
        } else {
            FormInputResponse emptyResponse = new FormInputResponse();
            emptyResponse.setFormInput(formInputRepository.findOne(formInputId));
            results.add(applicationValidationUtil.validateResponse(emptyResponse, false));
        }

        FormInput formInput = formInputRepository.findOne(formInputId);
        if (formInput.getType().equals(FormInputType.APPLICATION_DETAILS)) {
            Application application = applicationRepository.findOne(applicationId);
            results.add(applicationValidationUtil.addValidation(application, new ApplicationDetailsMarkAsCompleteValidator()));
        }

        return results;
    }

    @Override
    public ValidationMessages validateFormInputResponse(Application application, Long formInputId, Long markedAsCompleteById) {
        FormInputResponse response = formInputResponseRepository.findByApplicationIdAndUpdatedByIdAndFormInputId(application.getId(), markedAsCompleteById, formInputId);
        BindingResult result = applicationValidationUtil.validateResponse(response, false);

        ValidationMessages validationMessages = fromBindingResult(result);
        validationMessages.addAll(validateFileUploads(application, formInputId));

        return validationMessages;
    }


    @Override
    public List<ValidationMessages> validateCostItem(Long applicationId, Question question, Long markedAsCompleteById) {
        return getProcessRole(markedAsCompleteById).andOnSuccess(role ->
                financeService.financeDetails(applicationId, role.getOrganisationId()).andOnSuccess(financeDetails ->
                        financeRowCostsService.getCostItems(financeDetails.getId(), question.getId()).andOnSuccessReturn(costItems ->
                                applicationValidationUtil.validateCostItem(costItems, question)
                        )
                )
        ).getSuccess();
    }

    @Override
    public FinanceRowHandler getCostHandler(FinanceRowItem costItem) {
        return financeRowCostsService.getCostHandler(costItem.getId());
    }

    @Override
    public FinanceRowHandler getProjectCostHandler(FinanceRowItem costItem) {
        return projectFinanceRowService.getCostHandler(costItem);
    }

    private ValidationMessages validateFileUploads(Application application, Long formInputId) {
        FormInput formInput = formInputRepository.findOne(formInputId);

        if(FormInputType.FINANCE_UPLOAD.equals(formInput.getType()) && isResearchUser(application.getId())) {
            if (financeFileIsEmpty(application)) {
                Error error = fieldError("jesFileUpload", null, "validation.application.jes.upload.required");
                return new ValidationMessages(error);
            }
        }

        return noErrors(formInputId);
    }

    private boolean isResearchUser(long applicationId) {
        Optional<User> userResult = getCurrentlyLoggedInUser().getOptionalSuccessObject();
        if(userResult.isPresent()) {
            Optional<OrganisationResource> organisationResult = organisationService.getByUserAndApplicationId(userResult.get().getId(), applicationId).getOptionalSuccessObject();
            if(organisationResult.isPresent()) {
                return OrganisationTypeEnum.RESEARCH.getId() == organisationResult.get().getOrganisationType();
            }
        }

        return false;
    }

    private boolean financeFileIsEmpty(Application application) {
        List<ApplicationFinance> applicationFinances = application.getApplicationFinances();
        Optional<OrganisationResource> organisationOpt = organisationService.getPrimaryForUser(loggedInUserSupplier.get().getId()).getOptionalSuccessObject();

        if (applicationFinances == null || !organisationOpt.isPresent()) {
            return true;
        }

        Optional<ApplicationFinance> applicationFinanceOpt =
                simpleFindFirst(applicationFinances, af -> af.getOrganisation().getId().equals(organisationOpt.get().getId()));

        return applicationFinanceOpt.map(applicationFinance -> applicationFinance.getFinanceFileEntry() == null).orElse(true);
    }
}<commit_msg>IFS-3405 fixed removal of findbyprimary function<commit_after>package org.innovateuk.ifs.application.validation;

import org.innovateuk.ifs.application.domain.Application;
import org.innovateuk.ifs.application.domain.FormInputResponse;
import org.innovateuk.ifs.application.repository.FormInputResponseRepository;
import org.innovateuk.ifs.commons.error.ValidationMessages;
import org.innovateuk.ifs.application.validator.ApplicationDetailsMarkAsCompleteValidator;
import org.innovateuk.ifs.commons.error.Error;
import org.innovateuk.ifs.finance.domain.ApplicationFinance;
import org.innovateuk.ifs.finance.handler.item.FinanceRowHandler;
import org.innovateuk.ifs.finance.resource.cost.FinanceRowItem;
import org.innovateuk.ifs.finance.transactional.FinanceRowCostsService;
import org.innovateuk.ifs.finance.transactional.FinanceService;
import org.innovateuk.ifs.finance.transactional.ProjectFinanceRowService;
import org.innovateuk.ifs.form.domain.FormInput;
import org.innovateuk.ifs.form.domain.Question;
import org.innovateuk.ifs.form.repository.FormInputRepository;
import org.innovateuk.ifs.form.resource.FormInputType;
import org.innovateuk.ifs.organisation.resource.OrganisationResource;
import org.innovateuk.ifs.organisation.resource.OrganisationTypeEnum;
import org.innovateuk.ifs.organisation.transactional.OrganisationService;
import org.innovateuk.ifs.security.LoggedInUserSupplier;
import org.innovateuk.ifs.transactional.BaseTransactionalService;
import org.innovateuk.ifs.user.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.innovateuk.ifs.commons.error.Error.fieldError;
import static org.innovateuk.ifs.commons.error.ValidationMessages.fromBindingResult;
import static org.innovateuk.ifs.commons.error.ValidationMessages.noErrors;
import static org.innovateuk.ifs.util.CollectionFunctions.simpleFindFirst;

/**
 * Class to validate several objects
 */
@Service
public class ApplicationValidatorServiceImpl extends BaseTransactionalService implements ApplicationValidatorService {

    @Autowired
    private FormInputResponseRepository formInputResponseRepository;

    @Autowired
    private FormInputRepository formInputRepository;

    @Autowired
    private FinanceRowCostsService financeRowCostsService;

    @Autowired
    private FinanceService financeService;

    @Autowired
    private ProjectFinanceRowService projectFinanceRowService;

    @Autowired
    private ApplicationValidationUtil applicationValidationUtil;

    @Autowired
    private OrganisationService organisationService;

    @Autowired
    private LoggedInUserSupplier loggedInUserSupplier;

    @Override
    public List<BindingResult> validateFormInputResponse(Long applicationId, Long formInputId) {
        List<BindingResult> results = new ArrayList<>();
        List<FormInputResponse> responses = formInputResponseRepository.findByApplicationIdAndFormInputId(applicationId, formInputId);
        if (!responses.isEmpty()) {
            results.addAll(responses.stream().map(formInputResponse -> applicationValidationUtil.validateResponse(formInputResponse, false)).collect(Collectors.toList()));
        } else {
            FormInputResponse emptyResponse = new FormInputResponse();
            emptyResponse.setFormInput(formInputRepository.findOne(formInputId));
            results.add(applicationValidationUtil.validateResponse(emptyResponse, false));
        }

        FormInput formInput = formInputRepository.findOne(formInputId);
        if (formInput.getType().equals(FormInputType.APPLICATION_DETAILS)) {
            Application application = applicationRepository.findOne(applicationId);
            results.add(applicationValidationUtil.addValidation(application, new ApplicationDetailsMarkAsCompleteValidator()));
        }

        return results;
    }

    @Override
    public ValidationMessages validateFormInputResponse(Application application, Long formInputId, Long markedAsCompleteById) {
        FormInputResponse response = formInputResponseRepository.findByApplicationIdAndUpdatedByIdAndFormInputId(application.getId(), markedAsCompleteById, formInputId);
        BindingResult result = applicationValidationUtil.validateResponse(response, false);

        ValidationMessages validationMessages = fromBindingResult(result);
        validationMessages.addAll(validateFileUploads(application, formInputId));

        return validationMessages;
    }


    @Override
    public List<ValidationMessages> validateCostItem(Long applicationId, Question question, Long markedAsCompleteById) {
        return getProcessRole(markedAsCompleteById).andOnSuccess(role ->
                financeService.financeDetails(applicationId, role.getOrganisationId()).andOnSuccess(financeDetails ->
                        financeRowCostsService.getCostItems(financeDetails.getId(), question.getId()).andOnSuccessReturn(costItems ->
                                applicationValidationUtil.validateCostItem(costItems, question)
                        )
                )
        ).getSuccess();
    }

    @Override
    public FinanceRowHandler getCostHandler(FinanceRowItem costItem) {
        return financeRowCostsService.getCostHandler(costItem.getId());
    }

    @Override
    public FinanceRowHandler getProjectCostHandler(FinanceRowItem costItem) {
        return projectFinanceRowService.getCostHandler(costItem);
    }

    private ValidationMessages validateFileUploads(Application application, Long formInputId) {
        FormInput formInput = formInputRepository.findOne(formInputId);

        if(FormInputType.FINANCE_UPLOAD.equals(formInput.getType()) && isResearchUser(application.getId())) {
            if (financeFileIsEmpty(application)) {
                Error error = fieldError("jesFileUpload", null, "validation.application.jes.upload.required");
                return new ValidationMessages(error);
            }
        }

        return noErrors(formInputId);
    }

    private boolean isResearchUser(long applicationId) {
        Optional<User> userResult = getCurrentlyLoggedInUser().getOptionalSuccessObject();
        if(userResult.isPresent()) {
            Optional<OrganisationResource> organisationResult = organisationService.getByUserAndApplicationId(userResult.get().getId(), applicationId).getOptionalSuccessObject();
            if(organisationResult.isPresent()) {
                return OrganisationTypeEnum.RESEARCH.getId() == organisationResult.get().getOrganisationType();
            }
        }

        return false;
    }

    private boolean financeFileIsEmpty(Application application) {
        List<ApplicationFinance> applicationFinances = application.getApplicationFinances();
        Optional<User> userResult = getCurrentlyLoggedInUser().getOptionalSuccessObject();
        Optional<OrganisationResource> organisationOpt = organisationService.getByUserAndApplicationId(userResult.get().getId(), application.getId()).getOptionalSuccessObject();
        
        if (applicationFinances == null || !organisationOpt.isPresent()) {
            return true;
        }

        Optional<ApplicationFinance> applicationFinanceOpt =
                simpleFindFirst(applicationFinances, af -> af.getOrganisation().getId().equals(organisationOpt.get().getId()));

        return applicationFinanceOpt.map(applicationFinance -> applicationFinance.getFinanceFileEntry() == null).orElse(true);
    }
}
{'fraction_non_alphanumeric': 0.0835156094651024, 'fraction_numerical': 0.00026512891893683304, 'mean_word_length': 4.579881656804734, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1096037', 'n_tokens_mistral': 3795, 'n_tokens_neox': 3762, 'n_words': 571}