<commit_before>package org.innovateuk.ifs.finance.domain;

import org.innovateuk.ifs.application.domain.Application;
import org.innovateuk.ifs.application.repository.ApplicationRepository;
import org.innovateuk.ifs.category.domain.ResearchCategory;
import org.innovateuk.ifs.category.repository.ResearchCategoryRepository;
import org.innovateuk.ifs.commons.BaseIntegrationTest;
import org.innovateuk.ifs.competition.publiccontent.resource.FundingType;
import org.innovateuk.ifs.finance.repository.ApplicationFinanceRepository;
import org.innovateuk.ifs.finance.repository.OrganisationSizeRepository;
import org.innovateuk.ifs.finance.resource.ApplicationFinanceResource;
import org.innovateuk.ifs.finance.transactional.FinanceRowService;
import org.innovateuk.ifs.testdata.builders.ApplicationDataBuilder;
import org.innovateuk.ifs.testdata.builders.ApplicationFinanceDataBuilder;
import org.innovateuk.ifs.testdata.builders.CompetitionDataBuilder;
import org.innovateuk.ifs.testdata.builders.ServiceLocator;
import org.innovateuk.ifs.testdata.builders.data.ApplicationData;
import org.innovateuk.ifs.testdata.builders.data.CompetitionData;
import org.innovateuk.ifs.user.domain.Organisation;
import org.innovateuk.ifs.user.repository.OrganisationRepository;
import org.innovateuk.ifs.user.resource.OrganisationTypeEnum;
import org.innovateuk.ifs.user.resource.RoleResource;
import org.innovateuk.ifs.user.resource.UserResource;
import org.innovateuk.ifs.user.resource.UserRoleType;
import org.innovateuk.ifs.user.transactional.UserService;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.math.BigDecimal;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Optional;

import static java.util.Collections.singletonList;
import static org.innovateuk.ifs.testdata.builders.ApplicationDataBuilder.newApplicationData;
import static org.innovateuk.ifs.testdata.builders.CompetitionDataBuilder.newCompetitionData;
import static org.innovateuk.ifs.user.builder.RoleResourceBuilder.newRoleResource;
import static org.innovateuk.ifs.user.builder.UserResourceBuilder.newUserResource;
import static org.junit.Assert.assertEquals;

public class GrantClaimMaximumIntegrationTest extends BaseIntegrationTest {

    private static final Optional<Long> SMALL_SIZE = Optional.of(1L);
    private static final Optional<Long> MEDIUM_SIZE = Optional.of(2L);
    private static final Optional<Long> LARGE_SIZE = Optional.of(3L);
    private static final Optional<Long> NO_SIZE = Optional.empty();

    @Autowired
    private GenericApplicationContext applicationContext;

    @Autowired
    private UserService userService;

    @Autowired
    private FinanceRowService financeRowService;

    @Autowired
    private EntityManager entityManager;

    @Autowired
    private ResearchCategoryRepository researchCategoryRepository;

    @Autowired
    private OrganisationSizeRepository organisationSizeRepository;

    @Autowired
    private ApplicationFinanceRepository applicationFinanceRepository;

    @Autowired
    private OrganisationRepository organisationRepository;

    @Autowired
    private ApplicationRepository applicationRepository;

    private CompetitionDataBuilder competitionDataBuilder;
    private ApplicationDataBuilder applicationDataBuilder;

    @Before
    public void setupData() {

        ServiceLocator serviceLocator = new ServiceLocator(applicationContext, "<EMAIL>", "<EMAIL>");
        competitionDataBuilder = newCompetitionData(serviceLocator);
        applicationDataBuilder = newApplicationData(serviceLocator);
    }

    @Test
    @Transactional
    @Rollback
    public void testApcMaximumGrantClaimsForBusiness() {

        // For speed, all of these tests are combined in the same test method so that we don't have to continually recreate the
        // APC competition
        CompetitionData competitionData = createApcCompetition("Feasibility studies");

        // test business types
        ApplicationData businessApplicationData = createApplication(competitionData, "<EMAIL>", "Empire Ltd", SMALL_SIZE, false);

        // test business types - small
        assertApcMaximumGrant(businessApplicationData, "Feasibility studies", SMALL_SIZE, 70);
        assertApcMaximumGrant(businessApplicationData, "Industrial research", SMALL_SIZE, 70);
        assertApcMaximumGrant(businessApplicationData, "Experimental development", SMALL_SIZE, 45);

        // test business types - medium
        assertApcMaximumGrant(businessApplicationData, "Feasibility studies", MEDIUM_SIZE, 60);
        assertApcMaximumGrant(businessApplicationData, "Industrial research", MEDIUM_SIZE, 60);
        assertApcMaximumGrant(businessApplicationData, "Experimental development", MEDIUM_SIZE, 35);

        // test business types - large
        assertApcMaximumGrant(businessApplicationData, "Feasibility studies", LARGE_SIZE, 50);
        assertApcMaximumGrant(businessApplicationData, "Industrial research", LARGE_SIZE, 50);
        assertApcMaximumGrant(businessApplicationData, "Experimental development", LARGE_SIZE, 25);

        // test research types
        ApplicationData researchApplicationData = createApplication(competitionData, "<EMAIL>", "EGGS", Optional.empty(), true);

        assertApcMaximumGrant(researchApplicationData, "Feasibility studies", NO_SIZE, 100);
        assertApcMaximumGrant(researchApplicationData, "Industrial research", NO_SIZE, 100);
        assertApcMaximumGrant(researchApplicationData, "Experimental development", NO_SIZE, 100);
    }

    private void assertApcMaximumGrant(ApplicationData applicationData, String researchCategoryName, Optional<Long> organisationSize, int expectedMaximumGrant) {

        UserResource leadApplicant = applicationData.getLeadApplicant();
        Organisation leadOrganisation = organisationRepository.findOneByName(applicationData.getApplication().getLeadOrganisationName());

        Long applicationId = applicationData.getApplication().getId();
        Long leadOrganisationId = leadOrganisation.getId();

        ResearchCategory researchCategory = researchCategoryRepository.findByName(researchCategoryName);
        Application application = applicationRepository.findOne(applicationId);
        application.setResearchCategory(researchCategory);
        applicationRepository.save(application);

        organisationSize.ifPresent(sizeId -> {
            OrganisationSize size = organisationSizeRepository.findOne(sizeId);
            ApplicationFinance applicationFinance = applicationFinanceRepository.findByApplicationIdAndOrganisationId(applicationId, leadOrganisationId);
            applicationFinance.setOrganisationSize(size);
            applicationFinanceRepository.save(applicationFinance);

        });

        ApplicationFinanceResource financeDetails = getFinanceDetails(leadApplicant, applicationId, leadOrganisationId);

        assertEquals(Integer.valueOf(expectedMaximumGrant), financeDetails.getMaximumFundingLevel());
    }

    private ApplicationData createApplication(CompetitionData competitionData, String applicantEmailAddress, String organisationName, Optional<Long> organisationSize, boolean academic) {

        UserResource applicant = getUser(applicantEmailAddress);
        Organisation applicantOrganisation = organisationRepository.findOneByName(organisationName);

        ApplicationData applicationData = createApcApplication(competitionData, applicant, organisationSize, applicantOrganisation, academic);
        applicationData.getApplication().setLeadOrganisationName(applicantOrganisation.getName());
        return applicationData;<commit_msg>IFS-2439 - removed unnecessary save<commit_after>package org.innovateuk.ifs.finance.domain;

import org.innovateuk.ifs.application.domain.Application;
import org.innovateuk.ifs.application.repository.ApplicationRepository;
import org.innovateuk.ifs.category.domain.ResearchCategory;
import org.innovateuk.ifs.category.repository.ResearchCategoryRepository;
import org.innovateuk.ifs.commons.BaseIntegrationTest;
import org.innovateuk.ifs.competition.publiccontent.resource.FundingType;
import org.innovateuk.ifs.finance.repository.ApplicationFinanceRepository;
import org.innovateuk.ifs.finance.repository.OrganisationSizeRepository;
import org.innovateuk.ifs.finance.resource.ApplicationFinanceResource;
import org.innovateuk.ifs.finance.transactional.FinanceRowService;
import org.innovateuk.ifs.testdata.builders.ApplicationDataBuilder;
import org.innovateuk.ifs.testdata.builders.ApplicationFinanceDataBuilder;
import org.innovateuk.ifs.testdata.builders.CompetitionDataBuilder;
import org.innovateuk.ifs.testdata.builders.ServiceLocator;
import org.innovateuk.ifs.testdata.builders.data.ApplicationData;
import org.innovateuk.ifs.testdata.builders.data.CompetitionData;
import org.innovateuk.ifs.user.domain.Organisation;
import org.innovateuk.ifs.user.repository.OrganisationRepository;
import org.innovateuk.ifs.user.resource.OrganisationTypeEnum;
import org.innovateuk.ifs.user.resource.RoleResource;
import org.innovateuk.ifs.user.resource.UserResource;
import org.innovateuk.ifs.user.resource.UserRoleType;
import org.innovateuk.ifs.user.transactional.UserService;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.math.BigDecimal;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Optional;

import static java.util.Collections.singletonList;
import static org.innovateuk.ifs.testdata.builders.ApplicationDataBuilder.newApplicationData;
import static org.innovateuk.ifs.testdata.builders.CompetitionDataBuilder.newCompetitionData;
import static org.innovateuk.ifs.user.builder.RoleResourceBuilder.newRoleResource;
import static org.innovateuk.ifs.user.builder.UserResourceBuilder.newUserResource;
import static org.junit.Assert.assertEquals;

public class GrantClaimMaximumIntegrationTest extends BaseIntegrationTest {

    private static final Optional<Long> SMALL_SIZE = Optional.of(1L);
    private static final Optional<Long> MEDIUM_SIZE = Optional.of(2L);
    private static final Optional<Long> LARGE_SIZE = Optional.of(3L);
    private static final Optional<Long> NO_SIZE = Optional.empty();

    @Autowired
    private GenericApplicationContext applicationContext;

    @Autowired
    private UserService userService;

    @Autowired
    private FinanceRowService financeRowService;

    @Autowired
    private EntityManager entityManager;

    @Autowired
    private ResearchCategoryRepository researchCategoryRepository;

    @Autowired
    private OrganisationSizeRepository organisationSizeRepository;

    @Autowired
    private ApplicationFinanceRepository applicationFinanceRepository;

    @Autowired
    private OrganisationRepository organisationRepository;

    @Autowired
    private ApplicationRepository applicationRepository;

    private CompetitionDataBuilder competitionDataBuilder;
    private ApplicationDataBuilder applicationDataBuilder;

    @Before
    public void setupData() {

        ServiceLocator serviceLocator = new ServiceLocator(applicationContext, "<EMAIL>", "<EMAIL>");
        competitionDataBuilder = newCompetitionData(serviceLocator);
        applicationDataBuilder = newApplicationData(serviceLocator);
    }

    @Test
    @Transactional
    @Rollback
    public void testApcMaximumGrantClaimsForBusiness() {

        // For speed, all of these tests are combined in the same test method so that we don't have to continually recreate the
        // APC competition
        CompetitionData competitionData = createApcCompetition("Feasibility studies");

        // test business types
        ApplicationData businessApplicationData = createApplication(competitionData, "<EMAIL>", "Empire Ltd", SMALL_SIZE, false);

        // test business types - small
        assertApcMaximumGrant(businessApplicationData, "Feasibility studies", SMALL_SIZE, 70);
        assertApcMaximumGrant(businessApplicationData, "Industrial research", SMALL_SIZE, 70);
        assertApcMaximumGrant(businessApplicationData, "Experimental development", SMALL_SIZE, 45);

        // test business types - medium
        assertApcMaximumGrant(businessApplicationData, "Feasibility studies", MEDIUM_SIZE, 60);
        assertApcMaximumGrant(businessApplicationData, "Industrial research", MEDIUM_SIZE, 60);
        assertApcMaximumGrant(businessApplicationData, "Experimental development", MEDIUM_SIZE, 35);

        // test business types - large
        assertApcMaximumGrant(businessApplicationData, "Feasibility studies", LARGE_SIZE, 50);
        assertApcMaximumGrant(businessApplicationData, "Industrial research", LARGE_SIZE, 50);
        assertApcMaximumGrant(businessApplicationData, "Experimental development", LARGE_SIZE, 25);

        // test research types
        ApplicationData researchApplicationData = createApplication(competitionData, "<EMAIL>", "EGGS", Optional.empty(), true);

        assertApcMaximumGrant(researchApplicationData, "Feasibility studies", NO_SIZE, 100);
        assertApcMaximumGrant(researchApplicationData, "Industrial research", NO_SIZE, 100);
        assertApcMaximumGrant(researchApplicationData, "Experimental development", NO_SIZE, 100);
    }

    private void assertApcMaximumGrant(ApplicationData applicationData, String researchCategoryName, Optional<Long> organisationSize, int expectedMaximumGrant) {

        UserResource leadApplicant = applicationData.getLeadApplicant();
        Organisation leadOrganisation = organisationRepository.findOneByName(applicationData.getApplication().getLeadOrganisationName());

        Long applicationId = applicationData.getApplication().getId();
        Long leadOrganisationId = leadOrganisation.getId();

        ResearchCategory researchCategory = researchCategoryRepository.findByName(researchCategoryName);
        Application application = applicationRepository.findOne(applicationId);
        application.setResearchCategory(researchCategory);

        organisationSize.ifPresent(sizeId -> {
            OrganisationSize size = organisationSizeRepository.findOne(sizeId);
            ApplicationFinance applicationFinance = applicationFinanceRepository.findByApplicationIdAndOrganisationId(applicationId, leadOrganisationId);
            applicationFinance.setOrganisationSize(size);
            applicationFinanceRepository.save(applicationFinance);

        });

        ApplicationFinanceResource financeDetails = getFinanceDetails(leadApplicant, applicationId, leadOrganisationId);

        assertEquals(Integer.valueOf(expectedMaximumGrant), financeDetails.getMaximumFundingLevel());
    }

    private ApplicationData createApplication(CompetitionData competitionData, String applicantEmailAddress, String organisationName, Optional<Long> organisationSize, boolean academic) {

        UserResource applicant = getUser(applicantEmailAddress);
        Organisation applicantOrganisation = organisationRepository.findOneByName(organisationName);

        ApplicationData applicationData = createApcApplication(competitionData, applicant, organisationSize, applicantOrganisation, academic);
        applicationData.getApplication().setLeadOrganisationName(applicantOrganisation.getName());
        return applicationData;
{'fraction_non_alphanumeric': 0.07551704509518689, 'fraction_numerical': 0.004047814812472329, 'mean_word_length': 5.56917324470295, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 25, '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': '5716819', 'n_tokens_mistral': 4138, 'n_tokens_neox': 3898, 'n_words': 751}