예제 #1
0
    def test_get_option_list_case_ignore_finality_list_choice(self):
        """
        This test ensure that the tree will be pruned when a child if type of finality list choice and option
        isn't considered as part of tree
        """
        option_1 = EducationGroupYearFactory(
            academic_year=self.academic_year,
            education_group_type__name=MiniTrainingType.OPTION.name)
        GroupElementYearFactory(parent=self.root, child_branch=option_1)

        for finality_type in [
                GroupType.FINALITY_120_LIST_CHOICE.name,
                GroupType.FINALITY_180_LIST_CHOICE.name
        ]:
            finality_group = EducationGroupYearFactory(
                academic_year=self.academic_year,
                education_group_type__name=finality_type)
            GroupElementYearFactory(parent=self.root,
                                    child_branch=finality_group)
            GroupElementYearFactory(
                parent=finality_group,
                child_branch=EducationGroupYearFactory(
                    academic_year=self.academic_year,
                    education_group_type__name=MiniTrainingType.OPTION.name))

        node = EducationGroupHierarchy(self.root)
        self.assertListEqual(node.get_option_list(), [option_1])
예제 #2
0
    def test_tree_luy_has_and_is_prerequisite(self):
        # self.learning_unit_year_1 is prerequisite
        PrerequisiteItemFactory(
            learning_unit=self.learning_unit_year_1.learning_unit,
            prerequisite=PrerequisiteFactory(education_group_year=self.parent)
        )
        # self.learning_unit_year_1 has prerequisite
        PrerequisiteItemFactory(
            prerequisite=PrerequisiteFactory(
                learning_unit_year=self.learning_unit_year_1,
                education_group_year=self.parent
            )
        )

        node = EducationGroupHierarchy(self.parent)
        json = node.to_json()

        self.assertEqual(
            json['children'][1]['children'][0]['a_attr']['title'],
            "{}\n{}".format(
                self.learning_unit_year_1.complete_title,
                _("The learning unit has prerequisites and is a prerequisite")
            )
        )
        self.assertEqual(
            json['children'][1]['children'][0]['icon'],
            'fa fa-exchange-alt'
        )
예제 #3
0
파일: attach.py 프로젝트: ultrasound/osis
    def _get_missing_options(self):
        """
            In context of MA/MD/MS when we add an option [or group which contains options],
            this options must exist in parent context (2m)
        """
        options_missing_by_finality = {}

        options_to_add = EducationGroupHierarchy(
            root=self.child).get_option_list()
        if self.child.education_group_type.name == MiniTrainingType.OPTION.name:
            options_to_add += [self.child]

        finalities_qs = self.parents | EducationGroupYear.objects.filter(
            pk=self.parent.pk)
        finalities_pks = finalities_qs.filter(
            education_group_type__name__in=TrainingType.finality_types(
            )).values_list('pk', flat=True)
        if self.child.education_group_type.name in TrainingType.finality_types(
        ):
            finalities_pks = list(finalities_pks) + [self.parent.pk]
        if finalities_pks:
            root_2m_qs = EducationGroupYear.hierarchy.filter(
                pk__in=finalities_pks).get_parents().filter(
                    education_group_type__name__in=TrainingType.
                    root_master_2m_types())

            for root in root_2m_qs:
                options_in_2m = EducationGroupHierarchy(
                    root=root).get_option_list()
                options_missing_by_finality[root] = set(options_to_add) - set(
                    options_in_2m)
        return options_missing_by_finality
예제 #4
0
    def test_node_to_list_flat(self):
        node = EducationGroupHierarchy(self.parent)
        list_children = node.to_list(flat=True)

        self.assertCountEqual(list_children, [
            self.group_element_year_1, self.group_element_year_1_1,
            self.group_element_year_2, self.group_element_year_2_1
        ])
예제 #5
0
    def test_get_option_list_case_result_found(self):
        option_1 = EducationGroupYearFactory(
            academic_year=self.academic_year,
            education_group_type__name=MiniTrainingType.OPTION.name)
        GroupElementYearFactory(parent=self.root, child_branch=option_1)
        node = EducationGroupHierarchy(self.root)

        self.assertListEqual(node.get_option_list(), [option_1])
예제 #6
0
    def test_node_to_list_with_pruning_function(self):
        """
        This test ensure that if the parameter pruning function is specified we only get the tree
        without node which has been pruned
        """
        node = EducationGroupHierarchy(self.parent)
        list_children = node.to_list(
            flat=True,
            pruning_function=lambda child: child.group_element_year.pk == self.group_element_year_2.pk
        )

        self.assertCountEqual(list_children, [self.group_element_year_2])
예제 #7
0
    def test_tree_to_json(self):
        node = EducationGroupHierarchy(self.parent)

        json = node.to_json()
        self.assertEqual(json['text'], self.parent.verbose)

        self.assertEqual(json['a_attr']['href'], reverse('education_group_read', args=[
            self.parent.pk, self.parent.pk]) + "?group_to_parent=0")

        self.assertEqual(
            json['children'][1]['children'][0]['a_attr']['href'],
            reverse(
                'learning_unit_utilization',
                args=[self.parent.pk, self.group_element_year_2_1.child_leaf.pk]
            ) + "?group_to_parent={}".format(self.group_element_year_2_1.pk))
예제 #8
0
파일: detach.py 프로젝트: aelwhishi/osis
    def _check_detatch_options_rules(self):
        """
        In context of 2M when we detach an option [or group which contains option], we must ensure that
        these options are not present in MA/MD/MS
        """
        options_to_detach = self._get_options_to_detach()

        errors = []
        for master_2m in self.get_parents_program_master():
            master_2m_tree = EducationGroupHierarchy(root=master_2m)

            counter_options = Counter(master_2m_tree.get_option_list())
            counter_options.subtract(options_to_detach)
            options_to_check = [
                opt for opt, count in counter_options.items() if count == 0
            ]
            if not options_to_check:
                continue

            finality_list = [
                elem.child for elem in master_2m_tree.to_list(flat=True)
                if isinstance(elem.child, EducationGroupYear) and elem.child.
                education_group_type.name in TrainingType.finality_types()
            ]
            for finality in finality_list:
                mandatory_options = EducationGroupHierarchy(
                    root=finality).get_option_list()
                missing_options = set(options_to_check) & set(
                    mandatory_options)

                if missing_options:
                    errors.append(
                        ValidationError(
                            ngettext(
                                "Option \"%(acronym)s\" cannot be detach because it is contained in"
                                " %(finality_acronym)s program.",
                                "Options \"%(acronym)s\" cannot be detach because they are contained in"
                                " %(finality_acronym)s program.",
                                len(missing_options)) % {
                                    "acronym":
                                    ', '.join(option.acronym
                                              for option in missing_options),
                                    "finality_acronym":
                                    finality.acronym
                                }))

        if errors:
            raise ValidationError(errors)
예제 #9
0
    def test_get_verbose_children(self):
        result = EducationGroupHierarchy(self.education_group_year_1).to_list()
        context_waiting = [
            self.group_element_year_1, [self.group_element_year_2],
            self.group_element_year_3, [self.group_element_year_4]
        ]
        self.assertEqual(result, context_waiting)

        credits = self.group_element_year_1.relative_credits or self.group_element_year_1.child_branch.credits or 0
        verbose_branch = "{} ({} {})".format(
            self.group_element_year_1.child.title, credits, _("credits"))

        self.assertEqual(self.group_element_year_1.verbose, verbose_branch)

        components = LearningComponentYear.objects.filter(
            learning_unit_year=self.group_element_year_2.child_leaf).annotate(
                total=Case(When(hourly_volume_total_annual=None, then=0),
                           default=F('hourly_volume_total_annual'))).values(
                               'type', 'total')

        verbose_leaf = "{} {} [{}] ({} {})".format(
            self.group_element_year_2.child_leaf.acronym,
            self.group_element_year_2.child_leaf.complete_title,
            volume_total_verbose(components),
            self.group_element_year_2.relative_credits
            or self.group_element_year_2.child_leaf.credits or 0,
            _("credits"),
        )
        self.assertEqual(self.group_element_year_2.verbose, verbose_leaf)
예제 #10
0
    def test_build_tree_reference(self):
        """
        This tree contains a reference link.
        """
        self.group_element_year_1.link_type = LinkTypes.REFERENCE.name
        self.group_element_year_1.save()

        node = EducationGroupHierarchy(self.parent)

        self.assertEqual(node.children[0]._get_icon(), static('img/reference.jpg'))

        list_children = node.to_list()
        self.assertEqual(list_children, [
            self.group_element_year_1_1,
            self.group_element_year_2, [self.group_element_year_2_1]
        ])
예제 #11
0
파일: detail.py 프로젝트: ultrasound/osis
class LearningUnitGenericDetailView(PermissionRequiredMixin, DetailView):
    model = LearningUnitYear
    context_object_name = "learning_unit_year"
    pk_url_kwarg = 'learning_unit_year_id'

    permission_required = 'base.can_access_education_group'
    raise_exception = True

    def get_person(self):
        return get_object_or_404(Person, user=self.request.user)

    def get_root(self):
        return get_object_or_404(EducationGroupYear,
                                 pk=self.kwargs.get("root_id"))

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        root = self.get_root()
        self.hierarchy = EducationGroupHierarchy(
            root, tab_to_show=self.request.GET.get("tab_to_show"))

        # TODO remove parent in context
        context['person'] = self.get_person()
        context['root'] = root
        context['root_id'] = root.pk
        context['parent'] = root
        context['tree'] = json.dumps(self.hierarchy.to_json())
        context['group_to_parent'] = self.request.GET.get(
            "group_to_parent") or '0'
        context['show_prerequisites'] = self.show_prerequisites(root)
        return context

    def show_prerequisites(self, education_group_year):
        return education_group_year.education_group_type.name not in NO_PREREQUISITES
예제 #12
0
파일: detail.py 프로젝트: ultrasound/osis
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        root = self.get_root()
        self.hierarchy = EducationGroupHierarchy(
            root, tab_to_show=self.request.GET.get("tab_to_show"))

        # TODO remove parent in context
        context['person'] = self.get_person()
        context['root'] = root
        context['root_id'] = root.pk
        context['parent'] = root
        context['tree'] = json.dumps(self.hierarchy.to_json())
        context['group_to_parent'] = self.request.GET.get(
            "group_to_parent") or '0'
        context['show_prerequisites'] = self.show_prerequisites(root)
        return context
예제 #13
0
    def test_get_option_list_case_multiple_result_found_on_different_children(
            self):
        list_option = []
        for _ in range(5):
            group_child = EducationGroupYearFactory(
                academic_year=self.academic_year,
                education_group_type__name=GroupType.SUB_GROUP.name)
            GroupElementYearFactory(parent=self.root, child_branch=group_child)

            option = EducationGroupYearFactory(
                academic_year=self.academic_year,
                education_group_type__name=MiniTrainingType.OPTION.name)
            list_option.append(option)
            GroupElementYearFactory(parent=group_child, child_branch=option)

        node = EducationGroupHierarchy(self.root)
        self.assertCountEqual(node.get_option_list(), list_option)
예제 #14
0
    def test_tree_to_json_a_attr(self):
        """In this test, we ensure that a attr contains some url for tree contextual menu"""
        node = EducationGroupHierarchy(self.parent)
        json = node.to_json()
        child = self.group_element_year_1.child_branch

        expected_modify_url = reverse('group_element_year_update', args=[
            self.parent.pk, child.pk, self.group_element_year_1.pk
        ])
        self.assertEqual(json['children'][0]['a_attr']['modify_url'], expected_modify_url)

        expected_attach_url = reverse('education_group_attach', args=[self.parent.pk, child.pk])
        self.assertEqual(json['children'][0]['a_attr']['attach_url'], expected_attach_url)

        expected_detach_url = reverse('group_element_year_delete', args=[
            self.parent.pk, child.pk, self.group_element_year_1.pk
        ])
        self.assertEqual(json['children'][0]['a_attr']['detach_url'], expected_detach_url)
예제 #15
0
 def test_build_pdf_tree_with_mandatory(self):
     tree = EducationGroupHierarchy(self.education_group_year_1).to_list()
     out = Template(
         "{% load education_group_pdf %}"
         "{{ tree|pdf_tree_list }}"
     ).render(Context({
         'tree': tree
     }))
     self.assertEqual(out, _build_correct_tree_list(tree))
예제 #16
0
    def test_tree_to_json_ids(self):
        node = EducationGroupHierarchy(self.parent)
        json = node.to_json()

        self.assertEquals(
            json['children'][1]['id'],
            "id_{}_{}".format(
                node.children[1].education_group_year.pk,
                node.children[1].group_element_year.pk if node.children[1].group_element_year else '#'
            )
        )

        self.assertEquals(
            json['children'][1]['children'][0]['id'],
            "id_{}_{}".format(
                node.children[1].children[0].learning_unit_year.pk,
                node.children[1].children[0].group_element_year.pk if node.children[1].group_element_year else '#'
            )
        )
예제 #17
0
    def test_tree_get_url(self):
        test_cases = [
            {'name': 'with tab',
             'node': EducationGroupHierarchy(self.parent, tab_to_show='show_identification'),
             'correct_url': reverse('education_group_read', args=[self.parent.pk, self.parent.pk]) +
             "?group_to_parent=0&tab_to_show=show_identification"},
            {'name': 'without tab',
             'node': EducationGroupHierarchy(self.parent),
             'correct_url': reverse('education_group_read',
                                    args=[self.parent.pk, self.parent.pk]) + "?group_to_parent=0"},
            {'name': 'with wrong tab',
             'node': EducationGroupHierarchy(self.parent, tab_to_show='not_existing'),
             'correct_url': reverse('education_group_read',
                                    args=[self.parent.pk, self.parent.pk]) + "?group_to_parent=0"},
        ]

        for case in test_cases:
            with self.subTest(type=case['name']):
                self.assertEqual(case['correct_url'], case['node'].get_url())
예제 #18
0
    def test_build_pdf_tree_with_optional(self):
        self.group_element_year_1.is_mandatory = False
        self.group_element_year_1.save()
        self.group_element_year_2.is_mandatory = False
        self.group_element_year_2.save()

        tree = EducationGroupHierarchy(self.education_group_year_1).to_list()
        out = Template("{% load education_group_pdf %}"
                       "{{ tree|pdf_tree_list }}").render(
                           Context({'tree': tree}))
        self.assertEqual(out, _build_correct_tree_list(tree))
예제 #19
0
파일: detach.py 프로젝트: uclouvain/osis
    def _check_detatch_options_rules(self):
        """
        In context of 2M when we detach an option [or group which contains option], we must ensure that
        these options are not present in MA/MD/MS
        """
        options_to_detach = self._get_options_to_detach()

        errors = []
        for master_2m in self.get_parents_program_master():
            master_2m_tree = EducationGroupHierarchy(root=master_2m)

            counter_options = Counter(master_2m_tree.get_option_list())
            counter_options.subtract(options_to_detach)
            options_to_check = [opt for opt, count in counter_options.items() if count == 0]
            if not options_to_check:
                continue

            finality_list = [elem.child for elem in master_2m_tree.to_list(flat=True)
                             if isinstance(elem.child, EducationGroupYear)
                             and elem.child.education_group_type.name in TrainingType.finality_types()]
            for finality in finality_list:
                mandatory_options = EducationGroupHierarchy(root=finality).get_option_list()
                missing_options = set(options_to_check) & set(mandatory_options)

                if missing_options:
                    errors.append(
                        ValidationError(
                            ngettext(
                                "Option \"%(acronym)s\" cannot be detach because it is contained in"
                                " %(finality_acronym)s program.",
                                "Options \"%(acronym)s\" cannot be detach because they are contained in"
                                " %(finality_acronym)s program.",
                                len(missing_options)
                            ) % {
                                "acronym": ', '.join(option.acronym for option in missing_options),
                                "finality_acronym": finality.acronym
                            })
                    )

        if errors:
            raise ValidationError(errors)
예제 #20
0
    def test_get_option_list_case_reference_link(self):
        """
          This test ensure that the tree will not be pruned when the link of child is reference
        """
        reference_group_child = EducationGroupYearFactory(
            academic_year=self.academic_year,
            education_group_type__name=GroupType.SUB_GROUP.name)
        GroupElementYearFactory(
            parent=self.root,
            child_branch=reference_group_child,
            link_type=LinkTypes.REFERENCE.name,
        )

        option_1 = EducationGroupYearFactory(
            academic_year=self.academic_year,
            education_group_type__name=MiniTrainingType.OPTION.name)
        GroupElementYearFactory(parent=reference_group_child,
                                child_branch=option_1)
        node = EducationGroupHierarchy(self.root)

        self.assertListEqual(node.get_option_list(), [option_1])
예제 #21
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        root = self.get_root()
        context['person'] = self.get_person()
        context['root'] = root
        context['root_id'] = self.kwargs.get("root_id")
        context['parent'] = root
        context['tree'] = json.dumps(EducationGroupHierarchy(root).to_json())

        context['group_to_parent'] = self.request.GET.get("group_to_parent") or '0'
        return context
예제 #22
0
    def test_init_tree(self):
        node = EducationGroupHierarchy(self.parent)

        self.assertEqual(node.education_group_year, self.parent)
        self.assertEqual(len(node.children), 2)
        self.assertEqual(node.children[0].group_element_year, self.group_element_year_1)
        self.assertEqual(node.children[1].group_element_year, self.group_element_year_2)

        self.assertEqual(node.children[0].children[0].group_element_year, self.group_element_year_1_1)
        self.assertEqual(node.children[1].children[0].group_element_year, self.group_element_year_2_1)

        self.assertEqual(node.children[0].children[0].education_group_year, self.group_element_year_1_1.child_branch)
        self.assertEqual(node.children[1].children[0].education_group_year, None)
        self.assertEqual(node.children[1].children[0].learning_unit_year, self.group_element_year_2_1.child_leaf)
예제 #23
0
파일: detach.py 프로젝트: ultrasound/osis
    def _check_detach_prerequisite_rules(self):
        for formation in self._parents:
            luys_inside_formation = Counter(
                EducationGroupHierarchy(
                    root=formation).get_learning_unit_year_list())
            luys_to_detach = Counter(self._learning_units_year_to_detach)
            luys_inside_formation_after_detach = luys_inside_formation - luys_to_detach

            luys_that_are_prerequisites = LearningUnitYear.objects.filter(
                learning_unit__prerequisiteitem__prerequisite__learning_unit_year__in
                =list(luys_inside_formation_after_detach.keys()),
                learning_unit__prerequisiteitem__prerequisite__education_group_year
                =formation,
                id__in=[luy.id for luy in self._learning_units_year_to_detach])
            luys_that_cannot_be_detached = [
                luy for luy in luys_that_are_prerequisites
                if luy not in luys_inside_formation_after_detach
            ]
            if luys_that_cannot_be_detached:
                self.errors.append(
                    _("Cannot detach education group year %(acronym)s as the following learning units "
                      "are prerequisite in %(formation)s: %(learning_units)s")
                    % {
                        "acronym":
                        self.education_group_year.acronym,
                        "formation":
                        formation.acronym,
                        "learning_units":
                        ", ".join([
                            luy.acronym for luy in luys_that_cannot_be_detached
                        ])
                    })

        luys_that_have_prerequisites = LearningUnitYear.objects.filter(
            id__in=Prerequisite.objects.filter(
                education_group_year__in=self._parents,
                learning_unit_year__in=self._learning_units_year_to_detach).
            values("learning_unit_year__id"))
        if luys_that_have_prerequisites:
            self.warnings.append(
                _("The prerequisites for the following learning units contained in education group year "
                  "%(acronym)s will we deleted: %(learning_units)s") %
                {
                    "acronym":
                    self.education_group_year.acronym,
                    "learning_units":
                    ", ".join(
                        [luy.acronym for luy in luys_that_have_prerequisites])
                })
예제 #24
0
파일: read.py 프로젝트: ultrasound/osis
def pdf_content(request, root_id, education_group_year_id, language):
    education_group_year = get_object_or_404(EducationGroupYear,
                                             pk=education_group_year_id)
    tree = EducationGroupHierarchy(education_group_year).to_list()
    context = {
        'root': education_group_year,
        'tree': tree,
        'language': language,
        'created': datetime.datetime.now(),
    }
    with translation.override(language):
        return render_pdf(
            request,
            context=context,
            filename=education_group_year.acronym,
            template='education_group/pdf_content.html',
        )
예제 #25
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # This objects are mandatory for all education group views
        context['person'] = self.person

        # FIXME same param
        context['root'] = self.root
        context['root_id'] = self.root.pk
        context['parent'] = self.root
        context['parent_training'] = self.object.parent_by_training()

        if self.with_tree:
            context['tree'] = json.dumps(
                EducationGroupHierarchy(self.root).to_json())

        context['group_to_parent'] = self.request.GET.get(
            "group_to_parent") or '0'
        context[
            'can_change_education_group'] = perms.is_eligible_to_change_education_group(
                person=self.person,
                education_group=context['object'],
            )
        context[
            'can_change_coorganization'] = perms.is_eligible_to_change_coorganization(
                person=self.person,
                education_group=context['object'],
            )
        context['enums'] = mdl.enums.education_group_categories
        context['current_academic_year'] = self.current_academic_year

        context["show_identification"] = self.show_identification()
        context["show_diploma"] = self.show_diploma()
        context["show_general_information"] = self.show_general_information()
        context[
            "show_skills_and_achievements"] = self.show_skills_and_achievements(
            )
        context["show_administrative"] = self.show_administrative()
        context["show_content"] = self.show_content()
        context["show_utilization"] = self.show_utilization()
        context["show_admission_conditions"] = self.show_admission_conditions()
        return context
예제 #26
0
 def test_get_option_list_case_no_result(self):
     node = EducationGroupHierarchy(self.root)
     self.assertListEqual(node.get_option_list(), [])
예제 #27
0
파일: detach.py 프로젝트: aelwhishi/osis
 def _get_options_to_detach(self):
     options_to_detach = EducationGroupHierarchy(
         root=self.education_group_year).get_option_list()
     if self.education_group_year.education_group_type.name == MiniTrainingType.OPTION.name:
         options_to_detach += [self.education_group_year]
     return options_to_detach
예제 #28
0
파일: detach.py 프로젝트: ultrasound/osis
 def _learning_units_year_to_detach(self):
     return EducationGroupHierarchy(
         root=self.education_group_year).get_learning_unit_year_list()