<commit_before>package com.worth.ifs.application.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.worth.ifs.ViewModel;
import com.worth.ifs.application.form.ApplicationForm;
import com.worth.ifs.application.resource.ApplicationResource;
import com.worth.ifs.application.resource.QuestionResource;
import com.worth.ifs.application.resource.QuestionStatusResource;
import com.worth.ifs.application.resource.SectionResource;
import com.worth.ifs.application.resource.SectionType;
import com.worth.ifs.commons.rest.RestResult;
import com.worth.ifs.competition.resource.CompetitionResource;
import com.worth.ifs.invite.constant.InviteStatusConstants;
import com.worth.ifs.invite.resource.InviteOrganisationResource;
import com.worth.ifs.invite.resource.InviteResource;
import com.worth.ifs.profiling.ProfileExecution;
import com.worth.ifs.user.resource.OrganisationResource;
import com.worth.ifs.user.resource.ProcessRoleResource;
import com.worth.ifs.user.resource.UserResource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ui.Model;

import static com.worth.ifs.application.AbstractApplicationController.FORM_MODEL_ATTRIBUTE;
import static com.worth.ifs.util.CollectionFunctions.simpleFilter;

public class ApplicationOverviewModel implements ViewModel{
    private static final Log LOG = LogFactory.getLog(ApplicationOverviewModel.class);
    private final Long applicationId;
    private final Model model;
    private final Long userId;
    private final Services s;

    private ApplicationResource application ;
    private CompetitionResource competition;
    private List<ProcessRoleResource> userApplicationRoles;
    private Optional<OrganisationResource> userOrganisation;
    private ApplicationForm form;

    public ApplicationOverviewModel(Long applicationId, Long userId, ApplicationForm form, Model model, Services s){
        this.model = model;
        this.userId = userId;
        this.applicationId = applicationId;
        this.form = form;
        this.s = s;
    }

    @Override
    public Model getModel(){
        populateModel();
        return model;
    }
    
    private void populateModel(){
        this.application = s.applicationService.getById(applicationId);
        this.competition = s.competitionService.getById(application.getCompetition());
        this.userApplicationRoles = s.processRoleService.findProcessRolesByApplicationId(applicationId);
        this.userOrganisation = s.organisationService.getUserForOrganisation(userId, userApplicationRoles);

        if(form == null){
            form = new ApplicationForm();
        }
        form.setApplication(application);
        userOrganisation.ifPresent(org -> model.addAttribute("completedSections", s.sectionService.getCompleted(application.getId(), org.getId())));
        addUserDetails(model, application, userId);

        addAssignableDetails(model, application, userOrganisation.orElse(null), userId);
        addCompletedDetails(model, application, userOrganisation);
        addSections();

        model.addAttribute(FORM_MODEL_ATTRIBUTE, form);
        model.addAttribute("currentApplication", application);
        model.addAttribute("currentCompetition", competition);
        model.addAttribute("userOrganisation", userOrganisation.orElse(null));
        model.addAttribute("completedQuestionsPercentage", s.applicationService.getCompleteQuestionsPercentage(application.getId()));
    }
    @ProfileExecution
    private void addSections() {
        final List<SectionResource> allSections = s.sectionService.getAllByCompetitionId(competition.getId());
        final List<SectionResource> parentSections = s.sectionService.filterParentSections(allSections);
        final List<QuestionResource> questions = s.questionService.findByCompetition(competition.getId());

        final Map<Long, SectionResource> sections =
            parentSections.stream().collect(Collectors.toMap(SectionResource::getId,
                Function.identity()));

        final Map<Long, List<SectionResource>>   subSections = parentSections.stream()
            .collect(Collectors.toMap(
                SectionResource::getId, s -> getSectionsFromListByIdList(s.getChildSections(), allSections)
            ));

        final Map<Long, List<QuestionResource>> sectionQuestions = parentSections.stream()
            .collect(Collectors.toMap(
                SectionResource::getId,
                s -> getQuestionsBySection(s.getQuestions(), questions)
            ));
        model.addAttribute("sections", sections);
        model.addAttribute("subSections", subSections);
        model.addAttribute("sectionQuestions", sectionQuestions);
    }
    
    private List<SectionResource> getSectionsFromListByIdList(final List<Long> childSections, final List<SectionResource> allSections) {
        return simpleFilter(allSections, section -> childSections.contains(section.getId()));
    }

    private List<QuestionResource> getQuestionsBySection(final List<Long> questionIds, final List<QuestionResource> questions) {
        return simpleFilter(questions, q -> questionIds.contains(q.getId()));
    }

    private void addUserDetails(Model model, ApplicationResource application, Long userId) {
        Boolean userIsLeadApplicant = s.userService.isLeadApplicant(userId, application);
        ProcessRoleResource leadApplicantProcessRole = s.userService.getLeadApplicantProcessRoleOrNull(application);
        UserResource leadApplicant = s.userService.findById(leadApplicantProcessRole.getUser());

        model.addAttribute("userIsLeadApplicant", userIsLeadApplicant);
        model.addAttribute("leadApplicant", leadApplicant);
    }

    private void addAssignableDetails(Model model, ApplicationResource application, OrganisationResource userOrganisation,
        Long userId) {

        if (isApplicationInViewMode(model, application, userOrganisation))
            return;

        Map<Long, QuestionStatusResource> questionAssignees = s.questionService.getQuestionStatusesForApplicationAndOrganisation(application.getId(), userOrganisation.getId());

        List<QuestionStatusResource> notifications = s.questionService.getNotificationsForUser(questionAssignees.values(), userId);
        s.questionService.removeNotifications(notifications);
        List<InviteResource> pendingAssignableUsers = pendingInvitations(application);

        model.addAttribute("assignableUsers", s.processRoleService.findAssignableProcessRoles(applicationId));
        model.addAttribute("pendingAssignableUsers", pendingAssignableUsers);
        model.addAttribute("questionAssignees", questionAssignees);
        model.addAttribute("notifications", notifications);
    }

    private boolean isApplicationInViewMode(Model model, ApplicationResource application, OrganisationResource userOrganisation) {
        if(!application.isOpen() || userOrganisation == null){
            //Application Not open, so add empty lists
            model.addAttribute("assignableUsers", new ArrayList<ProcessRoleResource>());
            model.addAttribute("pendingAssignableUsers", new ArrayList<InviteResource>());
            model.addAttribute("questionAssignees", new HashMap<Long, QuestionStatusResource>());
            model.addAttribute("notifications", new ArrayList<QuestionStatusResource>());
            return true;
        }
        return false;
    }

    private List<InviteResource> pendingInvitations(ApplicationResource application) {
        RestResult<List<InviteOrganisationResource>> pendingAssignableUsersResult = s.inviteRestService.getInvitesByApplication(application.getId());

        return pendingAssignableUsersResult.handleSuccessOrFailure(
            failure -> new ArrayList<>(0),
            success -> success.stream().flatMap(item -> item.getInviteResources().stream())
                .filter(item -> !InviteStatusConstants.ACCEPTED.equals(item.getStatus()))
                .collect(Collectors.toList()));
    }

    private void addCompletedDetails(Model model, ApplicationResource application, Optional<OrganisationResource> userOrganisation) {
        final Future<Set<Long>> markedAsComplete = getMarkedAsCompleteDetails(application, userOrganisation); // List of question ids
        final Map<Long, Set<Long>> completedSectionsByOrganisation = s.sectionService.getCompletedSectionsByOrganisation(application.getId());
        final Set<Long> sectionsMarkedAsComplete = new TreeSet<>(completedSectionsByOrganisation.get(completedSectionsByOrganisation.keySet().stream().findFirst().get()));
        final List<SectionResource> financeSections = s.sectionService.getSectionsForCompetitionByType(application.getCompetition(), SectionType.FINANCE);

        boolean hasFinanceSection;
        Long financeSectionId;
        if(financeSections.isEmpty()) {
            hasFinanceSection = false;
            financeSectionId = null;
        } else {
            hasFinanceSection = true;
            financeSectionId = financeSections.get(0).getId();
        }

        model.addAttribute("sectionsMarkedAsComplete", sectionsMarkedAsComplete);
        model.addAttribute("allQuestionsCompleted", s.sectionService.allSectionsMarkedAsComplete(application.getId()));
        model.addAttribute("markedAsComplete", markedAsComplete);
        model.addAttribute("hasFinanceSection", hasFinanceSection);
        model.addAttribute("financeSectionId", financeSectionId);

    }

    private Future<Set<Long>> getMarkedAsCompleteDetails(ApplicationResource application, Optional<OrganisationResource> userOrganisation) {
        Long organisationId=0L;
        if(userOrganisation.isPresent()) {
            organisationId = userOrganisation.get().getId();
        }
        return s.questionService.getMarkedAsComplete(application.getId(), organisationId);
    }
}
<commit_msg>INFUND-2731 remove unnecessary fields from ApplicationOverviewModel<commit_after>package com.worth.ifs.application.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.worth.ifs.ViewModel;
import com.worth.ifs.application.form.ApplicationForm;
import com.worth.ifs.application.resource.ApplicationResource;
import com.worth.ifs.application.resource.QuestionResource;
import com.worth.ifs.application.resource.QuestionStatusResource;
import com.worth.ifs.application.resource.SectionResource;
import com.worth.ifs.application.resource.SectionType;
import com.worth.ifs.commons.rest.RestResult;
import com.worth.ifs.competition.resource.CompetitionResource;
import com.worth.ifs.invite.constant.InviteStatusConstants;
import com.worth.ifs.invite.resource.InviteOrganisationResource;
import com.worth.ifs.invite.resource.InviteResource;
import com.worth.ifs.user.resource.OrganisationResource;
import com.worth.ifs.user.resource.ProcessRoleResource;
import com.worth.ifs.user.resource.UserResource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ui.Model;

import static com.worth.ifs.application.AbstractApplicationController.FORM_MODEL_ATTRIBUTE;
import static com.worth.ifs.util.CollectionFunctions.simpleFilter;

public class ApplicationOverviewModel implements ViewModel{
    private static final Log LOG = LogFactory.getLog(ApplicationOverviewModel.class);
    private final Model model;
    private final Services s;

    public ApplicationOverviewModel(Long applicationId, Long userId, ApplicationForm form, Model model, Services s){
        this.model = model;
        this.s = s;
        ApplicationResource application = s.applicationService.getById(applicationId);
        CompetitionResource competition = s.competitionService.getById(application.getCompetition());
        List<ProcessRoleResource> userApplicationRoles = s.processRoleService.findProcessRolesByApplicationId(applicationId);
        Optional<OrganisationResource> userOrganisation = s.organisationService.getUserForOrganisation(userId, userApplicationRoles);

        if(form == null){
            form = new ApplicationForm();
        }
        form.setApplication(application);
        userOrganisation.ifPresent(org -> model.addAttribute("completedSections", s.sectionService.getCompleted(application.getId(), org.getId())));
        addUserDetails(model, application, userId);

        addAssignableDetails(model, application, userOrganisation.orElse(null), userId);
        addCompletedDetails(model, application, userOrganisation);
        addSections(competition);

        model.addAttribute(FORM_MODEL_ATTRIBUTE, form);
        model.addAttribute("currentApplication", application);
        model.addAttribute("currentCompetition", competition);
        model.addAttribute("userOrganisation", userOrganisation.orElse(null));
        model.addAttribute("completedQuestionsPercentage", s.applicationService.getCompleteQuestionsPercentage(application.getId()));
    }

    @Override
    public Model getModel(){
        return model;
    }
    
    private void addSections(CompetitionResource competition) {
        final List<SectionResource> allSections = s.sectionService.getAllByCompetitionId(competition.getId());
        final List<SectionResource> parentSections = s.sectionService.filterParentSections(allSections);
        final List<QuestionResource> questions = s.questionService.findByCompetition(competition.getId());

        final Map<Long, SectionResource> sections =
            parentSections.stream().collect(Collectors.toMap(SectionResource::getId,
                Function.identity()));

        final Map<Long, List<SectionResource>>   subSections = parentSections.stream()
            .collect(Collectors.toMap(
                SectionResource::getId, s -> getSectionsFromListByIdList(s.getChildSections(), allSections)
            ));

        final Map<Long, List<QuestionResource>> sectionQuestions = parentSections.stream()
            .collect(Collectors.toMap(
                SectionResource::getId,
                s -> getQuestionsBySection(s.getQuestions(), questions)
            ));
        model.addAttribute("sections", sections);
        model.addAttribute("subSections", subSections);
        model.addAttribute("sectionQuestions", sectionQuestions);
    }
    
    private List<SectionResource> getSectionsFromListByIdList(final List<Long> childSections, final List<SectionResource> allSections) {
        return simpleFilter(allSections, section -> childSections.contains(section.getId()));
    }

    private List<QuestionResource> getQuestionsBySection(final List<Long> questionIds, final List<QuestionResource> questions) {
        return simpleFilter(questions, q -> questionIds.contains(q.getId()));
    }

    private void addUserDetails(Model model, ApplicationResource application, Long userId) {
        Boolean userIsLeadApplicant = s.userService.isLeadApplicant(userId, application);
        ProcessRoleResource leadApplicantProcessRole = s.userService.getLeadApplicantProcessRoleOrNull(application);
        UserResource leadApplicant = s.userService.findById(leadApplicantProcessRole.getUser());

        model.addAttribute("userIsLeadApplicant", userIsLeadApplicant);
        model.addAttribute("leadApplicant", leadApplicant);
    }

    private void addAssignableDetails(Model model, ApplicationResource application, OrganisationResource userOrganisation,
        Long userId) {

        if (isApplicationInViewMode(model, application, userOrganisation))
            return;

        Map<Long, QuestionStatusResource> questionAssignees = s.questionService.getQuestionStatusesForApplicationAndOrganisation(application.getId(), userOrganisation.getId());

        List<QuestionStatusResource> notifications = s.questionService.getNotificationsForUser(questionAssignees.values(), userId);
        s.questionService.removeNotifications(notifications);
        List<InviteResource> pendingAssignableUsers = pendingInvitations(application);

        model.addAttribute("assignableUsers", s.processRoleService.findAssignableProcessRoles(application.getId()));
        model.addAttribute("pendingAssignableUsers", pendingAssignableUsers);
        model.addAttribute("questionAssignees", questionAssignees);
        model.addAttribute("notifications", notifications);
    }

    private boolean isApplicationInViewMode(Model model, ApplicationResource application, OrganisationResource userOrganisation) {
        if(!application.isOpen() || userOrganisation == null){
            //Application Not open, so add empty lists
            model.addAttribute("assignableUsers", new ArrayList<ProcessRoleResource>());
            model.addAttribute("pendingAssignableUsers", new ArrayList<InviteResource>());
            model.addAttribute("questionAssignees", new HashMap<Long, QuestionStatusResource>());
            model.addAttribute("notifications", new ArrayList<QuestionStatusResource>());
            return true;
        }
        return false;
    }

    private List<InviteResource> pendingInvitations(ApplicationResource application) {
        RestResult<List<InviteOrganisationResource>> pendingAssignableUsersResult = s.inviteRestService.getInvitesByApplication(application.getId());

        return pendingAssignableUsersResult.handleSuccessOrFailure(
            failure -> new ArrayList<>(0),
            success -> success.stream().flatMap(item -> item.getInviteResources().stream())
                .filter(item -> !InviteStatusConstants.ACCEPTED.equals(item.getStatus()))
                .collect(Collectors.toList()));
    }

    private void addCompletedDetails(Model model, ApplicationResource application, Optional<OrganisationResource> userOrganisation) {
        final Future<Set<Long>> markedAsComplete = getMarkedAsCompleteDetails(application, userOrganisation); // List of question ids
        final Map<Long, Set<Long>> completedSectionsByOrganisation = s.sectionService.getCompletedSectionsByOrganisation(application.getId());
        final Set<Long> sectionsMarkedAsComplete = new TreeSet<>(completedSectionsByOrganisation.get(completedSectionsByOrganisation.keySet().stream().findFirst().get()));
        final List<SectionResource> financeSections = s.sectionService.getSectionsForCompetitionByType(application.getCompetition(), SectionType.FINANCE);

        boolean hasFinanceSection;
        Long financeSectionId;
        if(financeSections.isEmpty()) {
            hasFinanceSection = false;
            financeSectionId = null;
        } else {
            hasFinanceSection = true;
            financeSectionId = financeSections.get(0).getId();
        }

        model.addAttribute("sectionsMarkedAsComplete", sectionsMarkedAsComplete);
        model.addAttribute("allQuestionsCompleted", s.sectionService.allSectionsMarkedAsComplete(application.getId()));
        model.addAttribute("markedAsComplete", markedAsComplete);
        model.addAttribute("hasFinanceSection", hasFinanceSection);
        model.addAttribute("financeSectionId", financeSectionId);

    }

    private Future<Set<Long>> getMarkedAsCompleteDetails(ApplicationResource application, Optional<OrganisationResource> userOrganisation) {
        Long organisationId=0L;
        if(userOrganisation.isPresent()) {
            organisationId = userOrganisation.get().getId();
        }
        return s.questionService.getMarkedAsComplete(application.getId(), organisationId);
    }
}

{'fraction_non_alphanumeric': 0.09529809000655143, 'fraction_numerical': 0.0005039560550320012, 'mean_word_length': 4.40708446866485, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 97, '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': '6446109', 'n_tokens_mistral': 4956, 'n_tokens_neox': 4881, 'n_words': 838}