Example #1
0
def _get_data_from_initial_data(initial_data):
    learning_unit_yr = get_by_id(initial_data.get('learning_unit_year')['id'])
    requirement_entity = find_by_id(initial_data.get('entities')['REQUIREMENT_ENTITY'])
    allocation_entity = find_by_id(initial_data.get('entities')['ALLOCATION_ENTITY'])
    add1_requirement_entity = find_by_id(initial_data.get('entities')['ADDITIONAL_REQUIREMENT_ENTITY_1'])
    add2_requirement_entity = find_by_id(initial_data.get('entities')['ADDITIONAL_REQUIREMENT_ENTITY_2'])
    campus = find_campus_by_id(initial_data.get('learning_unit_year')['campus'])

    organization = get_organization_from_learning_unit_year(learning_unit_yr)
    language = find_language_by_id(initial_data.get('learning_unit_year')['language'])
    lu_initial = initial_data.get('learning_unit', None)
    luy_initial = initial_data.get('learning_unit_year', None)
    lcy_initial = initial_data.get('learning_container_year', None)

    data = [
        str(_('Initial data')),
        luy_initial['acronym'],
        learning_unit_yr.academic_year.name,
        dict(LearningContainerYearType.choices())[lcy_initial['container_type']] if
        lcy_initial['container_type'] else '-',
        translate_status(luy_initial['status']),
        learning_unit_yr.get_subtype_display(),
        get_translation(luy_initial['internship_subtype']),
        volume_format(luy_initial['credits']),
        language.name if language else EMPTY_VALUE,
        dict(PERIODICITY_TYPES)[luy_initial['periodicity']] if luy_initial['periodicity'] else BLANK_VALUE,
        get_translation(luy_initial['quadrimester']),
        get_translation(luy_initial['session']),
        get_representing_string(lcy_initial['common_title']),
        get_representing_string(luy_initial['specific_title']),
        get_representing_string(lcy_initial['common_title_english']),
        get_representing_string(luy_initial['specific_title_english']),
        requirement_entity.most_recent_acronym if requirement_entity else BLANK_VALUE,
        allocation_entity.most_recent_acronym if allocation_entity else BLANK_VALUE,
        add1_requirement_entity.most_recent_acronym if add1_requirement_entity else BLANK_VALUE,
        add2_requirement_entity.most_recent_acronym if add2_requirement_entity else BLANK_VALUE,
        _('Yes') if luy_initial['professional_integration'] else _('No'),
        organization.name if organization else BLANK_VALUE,
        campus if campus else BLANK_VALUE,
        get_representing_string(lu_initial['faculty_remark']),
        get_representing_string(lu_initial['other_remark']),
        _('Yes') if lcy_initial.get('team') else _('No'),
        _('Yes') if lcy_initial.get('is_vacant') else _('No'),
        dict(vacant_declaration_type.DECLARATION_TYPE)[lcy_initial.get('type_declaration_vacant')] if lcy_initial.get(
            'type_declaration_vacant') else BLANK_VALUE,
        dict(attribution_procedure.ATTRIBUTION_PROCEDURES)[luy_initial.get('attribution_procedure')] if luy_initial.get(
            'attribution_procedure') else BLANK_VALUE,
    ]
    return _get_data_from_components_initial_data(data, initial_data)
 def is_type_for_faculty(self) -> bool:
     return self.container_type in LearningContainerYearType.for_faculty()
Example #3
0
def learning_units_search(request, search_type):
    service_course_search = search_type == SERVICE_COURSES_SEARCH
    borrowed_course_search = search_type == BORROWED_COURSE

    form = LearningUnitYearForm(request.GET or None,
                                service_course_search=service_course_search,
                                borrowed_course_search=borrowed_course_search,
                                initial={
                                    'academic_year_id':
                                    starting_academic_year(),
                                    'with_entity_subordinated': True
                                })
    found_learning_units = LearningUnitYear.objects.none()
    try:
        if form.is_valid():
            found_learning_units = form.get_activity_learning_units()
            check_if_display_message(request, found_learning_units)

    except TooManyResultsException:
        display_error_messages(request, _('Too many results'))
    if request.POST.get('xls_status') == "xls":
        return create_xls(request.user, found_learning_units,
                          _get_filter(form, search_type))

    if request.POST.get('xls_status') == "xls_comparison":
        return create_xls_comparison(request.user, found_learning_units,
                                     _get_filter(form, search_type),
                                     request.POST.get('comparison_year'))

    if request.POST.get('xls_status') == "xls_with_parameters":
        return create_xls_with_parameters(
            request.user, found_learning_units, _get_filter(form, search_type),
            {
                WITH_GRP: request.POST.get('with_grp') == 'true',
                WITH_ATTRIBUTIONS: request.POST.get('with_attributions')
                == 'true'
            })

    if request.POST.get('xls_status') == "xls_attributions":
        return create_xls_attributions(request.user, found_learning_units,
                                       _get_filter(form, search_type))

    form_comparison = SelectComparisonYears(
        academic_year=get_academic_year_of_reference(found_learning_units))
    starting_ac = starting_academic_year()
    context = {
        'form':
        form,
        'academic_years':
        get_last_academic_years(),
        'container_types':
        LearningContainerYearType.choices(),
        'types':
        learning_unit_year_subtypes.LEARNING_UNIT_YEAR_SUBTYPES,
        'learning_units_count':
        len(found_learning_units) if isinstance(found_learning_units, list)
        else found_learning_units.count(),
        'current_academic_year':
        starting_ac,
        'proposal_academic_year':
        starting_ac.next(),
        'search_type':
        search_type,
        'is_faculty_manager':
        request.user.person.is_faculty_manager,
        'form_comparison':
        form_comparison,
        'page_obj':
        paginate_queryset(found_learning_units,
                          request.GET,
                          items_per_page=ITEMS_PER_PAGES),
    }

    return render(request, "learning_units.html", context)
Example #4
0
class LearningContainerYear(SerializableModel):
    external_id = models.CharField(max_length=100, blank=True, null=True, db_index=True)
    academic_year = models.ForeignKey('AcademicYear', on_delete=models.PROTECT)
    learning_container = models.ForeignKey('LearningContainer', on_delete=models.CASCADE)

    container_type = models.CharField(
        verbose_name=_('Type'),
        db_index=True,
        max_length=20,
        choices=LearningContainerYearType.choices(),
    )

    common_title = models.CharField(max_length=255, blank=True, null=True, verbose_name=_('Common title'))
    common_title_english = models.CharField(max_length=250, blank=True, null=True,
                                            verbose_name=_('Common English title'))
    acronym = models.CharField(max_length=10)
    changed = models.DateTimeField(null=True, auto_now=True)
    team = models.BooleanField(default=False, verbose_name=_('Team management'))
    is_vacant = models.BooleanField(default=False, verbose_name=_('Vacant'))
    type_declaration_vacant = models.CharField(max_length=100, blank=True, null=True,
                                               verbose_name=_('Decision'),
                                               choices=vacant_declaration_type.DECLARATION_TYPE)
    in_charge = models.BooleanField(default=False)

    requirement_entity = models.ForeignKey(
        to="base.Entity",
        null=True, blank=False,
        related_name='requirement_entities',
        on_delete=models.PROTECT,
    )
    allocation_entity = models.ForeignKey(
        to="base.Entity",
        null=True, blank=True,
        related_name='allocation_entities',
        on_delete=models.PROTECT,
    )
    additional_entity_1 = models.ForeignKey(
        to="base.Entity",
        null=True, blank=True,
        related_name='additional_entities_1',
        on_delete=models.PROTECT,
    )
    additional_entity_2 = models.ForeignKey(
        to="base.Entity",
        null=True, blank=True,
        related_name='additional_entities_2',
        on_delete=models.PROTECT,
    )

    _warnings = None

    def __str__(self):
        return u"%s - %s" % (self.acronym, self.common_title)

    class Meta:
        unique_together = ("learning_container", "academic_year",)
        permissions = (
            ("can_access_learningcontaineryear", "Can access learning container year"),
        )

    @property
    def warnings(self):
        if self._warnings is None:
            self._warnings = get_learning_container_year_warnings(self)
        return self._warnings

    def get_partims_related(self):
        return learning_unit_year.search(learning_container_year_id=self,
                                         subtype=learning_unit_year_subtypes.PARTIM).order_by('acronym')

    def is_type_for_faculty(self) -> bool:
        return self.container_type in LearningContainerYearType.for_faculty()

    @staticmethod
    def get_attrs_by_entity_container_type():
        return {
            REQUIREMENT_ENTITY: 'requirement_entity',
            ALLOCATION_ENTITY: 'allocation_entity',
            ADDITIONAL_REQUIREMENT_ENTITY_1: 'additional_entity_1',
            ADDITIONAL_REQUIREMENT_ENTITY_2: 'additional_entity_2',
        }

    def get_entity_from_type(self, entity_container_type):
        attr = LearningContainerYear.get_attrs_by_entity_container_type()[entity_container_type]
        return getattr(self, attr, None)

    def get_map_entity_by_type(self) -> dict:
        return {
            link_type: self.get_entity_from_type(link_type)
            for link_type in LearningContainerYear.get_attrs_by_entity_container_type()
        }

    def set_entity(self, entity_container_type, new_entity):
        attr = LearningContainerYear.get_attrs_by_entity_container_type()[entity_container_type]
        setattr(self, attr, new_entity)

    def set_entities(self, entities_by_type_to_set):
        for link_type, new_entity in entities_by_type_to_set.items():
            self.set_entity(link_type, new_entity)

    def get_most_recent_entity_acronym(self, entity_container_type):
        entity = self.get_entity_from_type(entity_container_type)
        return entity.most_recent_acronym if entity else None
Example #5
0
 def is_type_for_faculty(self) -> bool:
     return self.container_type in LearningContainerYearType.for_faculty()
Example #6
0
class LearningUnitYearForm(LearningUnitSearchForm):
    MAX_RECORDS = 2000
    container_type = forms.ChoiceField(
        label=_('Type'),
        choices=LearningUnitSearchForm.ALL_CHOICES +
        LearningContainerYearType.choices() +
        LearningUnitSearchForm.MOBILITY_CHOICE,
    )

    subtype = forms.ChoiceField(
        label=_('Subtype'),
        choices=LearningUnitSearchForm.ALL_CHOICES +
        learning_unit_year_subtypes.LEARNING_UNIT_YEAR_SUBTYPES,
    )

    status = forms.ChoiceField(
        label=_('Status'),
        choices=LearningUnitSearchForm.ALL_CHOICES +
        active_status.ACTIVE_STATUS_LIST[:-1],
    )

    title = forms.CharField(max_length=20, label=_('Title'))

    allocation_entity_acronym = forms.CharField(max_length=20,
                                                label=_('Alloc. Ent.'))

    faculty_borrowing_acronym = forms.CharField(max_length=20,
                                                label=_("Faculty borrowing"))

    def __init__(self, *args, **kwargs):
        self.service_course_search = kwargs.pop('service_course_search', False)
        self.borrowed_course_search = kwargs.pop('borrowed_course_search',
                                                 False)

        super().__init__(*args, **kwargs)

        if self.borrowed_course_search:
            self.fields["academic_year_id"].required = True
            self.fields["academic_year_id"].empty_label = None

        self.fields["with_entity_subordinated"].initial = True

    def clean_acronym(self):
        acronym = self.cleaned_data.get('acronym')
        acronym = treat_empty_or_str_none_as_none(acronym)
        if acronym and not learning_unit_year.check_if_acronym_regex_is_valid(
                acronym):
            raise ValidationError(_('LU_ERRORS_INVALID_REGEX_SYNTAX'))
        return acronym

    def clean(self):
        return get_clean_data(self.cleaned_data)

    def get_activity_learning_units(self):
        if self.service_course_search:
            return self._get_service_course_learning_units()
        elif self.borrowed_course_search:
            return self.get_learning_units()
        else:
            # Simple search
            return self.get_queryset()

    def _get_service_course_learning_units(self):
        learning_units = self.get_learning_units(service_course_search=True)
        # FIXME Ugly method to keep a queryset, we must simplify the db structure to easily fetch the service course
        return learning_units.filter(pk__in=[
            lu.pk for lu in learning_units if lu.entities.get(SERVICE_COURSE)
        ])

    def get_learning_units(self, service_course_search=None):
        service_course_search = service_course_search or self.service_course_search

        learning_units = self.get_queryset()
        if not service_course_search and self.cleaned_data and learning_units.count(
        ) > self.MAX_RECORDS:
            raise TooManyResultsException

        learning_units = learning_units.prefetch_related(
            build_entity_container_prefetch([
                entity_container_year_link_type.ALLOCATION_ENTITY,
                entity_container_year_link_type.REQUIREMENT_ENTITY
            ]))

        if self.borrowed_course_search:
            # TODO must return a queryset
            learning_units = list(
                self._filter_borrowed_learning_units(learning_units))

        for learning_unit in learning_units:
            append_latest_entities(learning_unit, service_course_search)

        return learning_units

    def get_learning_units_and_summary_status(self,
                                              requirement_entities=None,
                                              luy_status=None):
        self.cleaned_data['status'] = self._set_status(luy_status)

        if requirement_entities:
            self.cleaned_data['requirement_entities'] = requirement_entities

        queryset = self.get_queryset()
        if self.cleaned_data and queryset.count() > self.MAX_RECORDS:
            raise TooManyResultsException

        queryset = queryset.prefetch_related(
            build_entity_container_prefetch([
                entity_container_year_link_type.ALLOCATION_ENTITY,
                entity_container_year_link_type.REQUIREMENT_ENTITY
            ]),
            Prefetch(
                'attribution_set',
                queryset=Attribution.objects.filter(summary_responsible=True),
                to_attr='summary_responsibles'))

        cms_list = TranslatedText.objects.filter(
            entity=LEARNING_UNIT_YEAR,
            text_label__label__in=CMS_LABEL_PEDAGOGY,
            changed__isnull=False,
            reference__in=queryset.values_list(
                'pk', flat=True)).select_related('text_label')

        for learning_unit_yr in queryset:
            append_latest_entities(learning_unit_yr)
            _set_summary_status_on_luy(cms_list, learning_unit_yr)

        return queryset

    def _set_status(self, luy_status):
        return convert_status_bool(
            luy_status) if luy_status else self.cleaned_data['status']

    def _filter_borrowed_learning_units(self, qs_learning_units):
        faculty_borrowing_id = None
        faculty_borrowing_acronym = self.cleaned_data.get(
            'faculty_borrowing_acronym')
        academic_year = self.cleaned_data["academic_year_id"]

        if faculty_borrowing_acronym:
            try:
                faculty_borrowing_id = EntityVersion.objects.current(academic_year.start_date). \
                    get(acronym=faculty_borrowing_acronym).entity.id
            except EntityVersion.DoesNotExist:
                return []

        return filter_is_borrowed_learning_unit_year(
            qs_learning_units,
            academic_year.start_date,
            faculty_borrowing=faculty_borrowing_id)
Example #7
0
class LearningUnitDescriptionFicheFilter(FilterSet):
    academic_year = filters.ModelChoiceFilter(
        queryset=AcademicYear.objects.all(), required=True, label=_('Ac yr.'))
    acronym = filters.CharFilter(
        field_name="acronym",
        lookup_expr='icontains',
        max_length=40,
        required=False,
        label=_('Code'),
    )
    learning_unit_title = filters.CharFilter(
        field_name='full_title',
        lookup_expr='icontains',
        label=_('Title'),
    )
    container_type = filters.ChoiceFilter(
        field_name='learning_container_year__container_type',
        choices=LearningContainerYearType.choices() +
        ((MOBILITY, _('Mobility')), ),
        label=_('Type'),
        empty_label=pgettext_lazy("plural", "All"))
    subtype = filters.ChoiceFilter(
        choices=learning_unit_year_subtypes.LEARNING_UNIT_YEAR_SUBTYPES,
        label=_('Subtype'),
        empty_label=pgettext_lazy("plural", "All"))
    status = filters.TypedChoiceFilter(
        choices=(('', _("All")), ('true', _("Active")), ('false',
                                                         _("Inactive"))),
        label=_('Status'),
        coerce=strtobool,
    )
    quadrimester = filters.ChoiceFilter(
        choices=quadrimesters.LEARNING_UNIT_YEAR_QUADRIMESTERS,
        label=_('Quadri'),
        empty_label=pgettext_lazy("plural", "All"))
    tutor = filters.CharFilter(
        method='filter_tutor',
        label=_('Tutor'),
    )
    requirement_entity = filters.CharFilter(
        method='filter_requirement_entity_with_entity_subordinated',
        label=_('Req. Entity'))
    allocation_entity = filters.CharFilter(
        method='filter_allocation_entity_with_entity_subordinated',
        label=_('Alloc. Ent.'))
    with_entity_subordinated = filters.BooleanFilter(
        method=lambda queryset, *args, **kwargs: queryset,
        label=_('Include subordinate entities'),
        widget=forms.CheckboxInput)

    class Meta:
        model = LearningUnitYear
        fields = []

    def __init__(self, data=None, queryset=None, *, request=None, prefix=None):
        translated_text_qs = TranslatedText.objects.filter(
            entity=LEARNING_UNIT_YEAR,
            text_label__label__in=CMS_LABEL_PEDAGOGY,
            changed__isnull=False,
            reference=OuterRef('pk')).order_by("-changed")

        queryset = LearningUnitYear.objects.all().annotate(
            full_title=Case(
                When(Q(learning_container_year__common_title__isnull=True)
                     | Q(learning_container_year__common_title__exact=''),
                     then='specific_title'),
                When(Q(specific_title__isnull=True)
                     | Q(specific_title__exact=''),
                     then='learning_container_year__common_title'),
                default=Concat('learning_container_year__common_title',
                               Value(' - '), 'specific_title'),
                output_field=CharField(),
            ),
            last_translated_text_changed=Subquery(
                translated_text_qs.values('changed')[:1]),
        )
        super(LearningUnitDescriptionFicheFilter, self).__init__(
            data=data,
            queryset=queryset,
            request=request,
            prefix=prefix,
        )
        self.form.fields['academic_year'].initial = starting_academic_year()
        self.form.fields['with_entity_subordinated'].initial = True

    def filter_tutor(self, queryset, name, value):
        return queryset.filter(
            Q(learningcomponentyear__attributionchargenew__attribution__tutor__person__first_name__icontains
              =value)
            |
            Q(learningcomponentyear__attributionchargenew__attribution__tutor__person__last_name__icontains
              =value))

    def filter_requirement_entity_with_entity_subordinated(
            self, queryset, name, value):
        with_subordinated = self.form.cleaned_data['with_entity_subordinated']
        if value:
            entity_ids = get_entities_ids(value, with_subordinated)
            queryset = queryset.filter(
                learning_container_year__requirement_entity__in=entity_ids)
        return queryset

    def filter_allocation_entity_with_entity_subordinated(
            self, queryset, name, value):
        with_subordinated = self.form.cleaned_data['with_entity_subordinated']
        if value:
            entity_ids = get_entities_ids(value, with_subordinated)
            queryset = queryset.filter(
                learning_container_year__allocation_entity__in=entity_ids)
        return queryset

    @property
    def qs(self):
        queryset = super(LearningUnitDescriptionFicheFilter, self).qs
        if self.is_bound:
            queryset = self._compute_summary_status(queryset)
            queryset = queryset.select_related(
                'learning_container_year__academic_year', 'academic_year')
        return queryset

    def _compute_summary_status(self, queryset):
        """
        This function will compute the summary status. First, we will take the entity calendar
        (or entity calendar parent and so one) of the requirement entity. If not found, the summary status is
        computed with the general Academic Calendar Object
        """
        entity_calendars_computed = entity_calendar.build_calendar_by_entities(
            self.form.cleaned_data['academic_year'].past(),
            SUMMARY_COURSE_SUBMISSION,
        )
        requirement_entities_ids = queryset.values_list(
            'learning_container_year__requirement_entity', flat=True)

        summary_status_case_statment = [
            When(last_translated_text_changed__isnull=True, then=False)
        ]
        for requirement_entity_id in set(requirement_entities_ids):
            start_summary_course_submission = entity_calendars_computed.get(
                requirement_entity_id, {}).get('start_date')
            if start_summary_course_submission is None:
                continue

            summary_status_case_statment.append(
                When(learning_container_year__requirement_entity=
                     requirement_entity_id,
                     last_translated_text_changed__gte=
                     start_summary_course_submission,
                     then=True))

        queryset = queryset.annotate(
            summary_status=Case(*summary_status_case_statment,
                                default=Value(False),
                                output_field=BooleanField()))
        return queryset
Example #8
0
class LearningUnitYearForm(LearningUnitSearchForm):
    MAX_RECORDS = 2000
    container_type = forms.ChoiceField(
        label=_('Type'),
        choices=LearningUnitSearchForm.ALL_CHOICES +
        LearningContainerYearType.choices() +
        LearningUnitSearchForm.MOBILITY_CHOICE,
    )

    subtype = forms.ChoiceField(
        label=_('Subtype'),
        choices=LearningUnitSearchForm.ALL_CHOICES +
        learning_unit_year_subtypes.LEARNING_UNIT_YEAR_SUBTYPES,
    )

    status = forms.ChoiceField(
        label=_('Status'),
        choices=LearningUnitSearchForm.ALL_CHOICES +
        active_status.ACTIVE_STATUS_LIST[:-1],
    )

    title = forms.CharField(max_length=20, label=_('Title'))

    allocation_entity_acronym = forms.CharField(max_length=20,
                                                label=_('Alloc. Ent.'))

    faculty_borrowing_acronym = forms.CharField(max_length=20,
                                                label=_("Faculty borrowing"))

    def __init__(self, *args, **kwargs):
        self.service_course_search = kwargs.pop('service_course_search', False)
        self.borrowed_course_search = kwargs.pop('borrowed_course_search',
                                                 False)

        super().__init__(*args, **kwargs)

        if self.borrowed_course_search:
            self.fields["academic_year_id"].empty_label = None

        self.fields["with_entity_subordinated"].initial = True

    def clean_acronym(self):
        acronym = self.cleaned_data.get('acronym')
        acronym = treat_empty_or_str_none_as_none(acronym)
        if acronym and not learning_unit_year.check_if_acronym_regex_is_valid(
                acronym):
            raise ValidationError(_('LU_ERRORS_INVALID_REGEX_SYNTAX'))
        return acronym

    def clean_faculty_borrowing_acronym(self):
        data_cleaned = self.cleaned_data.get('faculty_borrowing_acronym')
        if data_cleaned:
            return data_cleaned.upper()

    def clean(self):
        return get_clean_data(self.cleaned_data)

    def get_activity_learning_units(self):
        if self.service_course_search:
            return self._get_service_course_learning_units()
        elif self.borrowed_course_search:
            return self.get_learning_units()
        else:
            # Simple search
            return self.get_queryset()

    def _get_service_course_learning_units(self):
        learning_units = self.get_learning_units(service_course_search=True)
        # FIXME Ugly method to keep a queryset, we must simplify the db structure to easily fetch the service course
        return learning_units.filter(pk__in=[
            lu.pk for lu in learning_units if lu.entities.get(SERVICE_COURSE)
        ])

    def get_learning_units(self, service_course_search=None):
        service_course_search = service_course_search or self.service_course_search

        learning_units = self.get_queryset()

        # FIXME: use one queryset for service cource search and borrowed course search instead of filtering in python
        if not service_course_search and not self.borrowed_course_search \
                and self.cleaned_data and learning_units.count() > self.MAX_RECORDS:
            raise TooManyResultsException

        if self.borrowed_course_search:
            learning_units = self._filter_borrowed_learning_units(
                learning_units)

        learning_units = learning_units.prefetch_related(
            build_entity_container_prefetch(
                entity_container_year_link_type.ALLOCATION_ENTITY),
            build_entity_container_prefetch(
                entity_container_year_link_type.REQUIREMENT_ENTITY),
        )
        for learning_unit in learning_units:
            append_latest_entities(learning_unit, service_course_search)

        return learning_units

    def _filter_borrowed_learning_units(self, qs_learning_units):
        faculty_borrowing_id = None
        faculty_borrowing_acronym = self.cleaned_data.get(
            'faculty_borrowing_acronym')
        academic_year = self.cleaned_data["academic_year_id"]

        if faculty_borrowing_acronym:
            try:
                faculty_borrowing_id = EntityVersion.objects.current(academic_year.start_date). \
                    get(acronym=faculty_borrowing_acronym).entity.id
            except EntityVersion.DoesNotExist:
                return LearningUnitYear.objects.none()

        ids = filter_is_borrowed_learning_unit_year(
            qs_learning_units,
            academic_year.start_date,
            faculty_borrowing=faculty_borrowing_id)
        return self.get_queryset().filter(id__in=ids)
Example #9
0
class LearningUnitFilter(FilterSet):
    academic_year = filters.ModelChoiceFilter(
        queryset=AcademicYear.objects.all(),
        required=False,
        label=_('Ac yr.'),
        empty_label=pgettext_lazy("plural", "All"),
    )
    acronym = filters.CharFilter(
        field_name="acronym",
        lookup_expr="iregex",
        max_length=40,
        required=False,
        label=_('Code'),
    )
    requirement_entity = filters.CharFilter(
        method='filter_entity',
        max_length=20,
        label=_('Req. Entity'),
    )
    allocation_entity = filters.CharFilter(
        method='filter_entity',
        max_length=20,
        label=_('Alloc. Entity'),
    )
    with_entity_subordinated = filters.BooleanFilter(
        method=lambda queryset, *args, **kwargs: queryset,
        label=_('Include subordinate entities'),
        widget=forms.CheckboxInput,
        initial='True'
    )
    tutor = filters.CharFilter(
        method="filter_tutor",
        max_length=40,
        label=_('Tutor'),
    )
    quadrimester = filters.ChoiceFilter(
        choices=quadrimesters.LEARNING_UNIT_YEAR_QUADRIMESTERS,
        required=False,
        field_name="quadrimester",
        label=_('Quadri'),
        empty_label=pgettext_lazy("plural", "All"),
    )

    container_type = filters.ChoiceFilter(
        choices=LearningContainerYearType.choices() + MOBILITY_CHOICE,
        required=False,
        field_name="learning_container_year__container_type",
        label=_('Type'),
        empty_label=pgettext_lazy("plural", "All"),
        method="filter_container_type"
    )
    subtype = filters.ChoiceFilter(
        choices=learning_unit_year_subtypes.LEARNING_UNIT_YEAR_SUBTYPES,
        required=False,
        field_name="subtype",
        label=_('Subtype'),
        empty_label=pgettext_lazy("plural", "All")
    )
    status = filters.ChoiceFilter(
        choices=active_status.ACTIVE_STATUS_LIST_FOR_FILTER,
        required=False,
        label=_('Status'),
        field_name="status",
        empty_label=pgettext_lazy("plural", "All")
    )
    title = filters.CharFilter(
        field_name="full_title",
        method="filter_learning_unit_year_field",
        max_length=40,
        label=_('Title'),
    )
    search_type = filters.CharFilter(
        field_name="acronym",
        method=lambda request, *args, **kwargs: request,
        widget=forms.HiddenInput,
        required=False,
        initial=SearchTypes.SIMPLE_SEARCH.value
    )

    order_by_field = 'ordering'
    ordering = OrderingFilter(
        fields=(
            ('academic_year__year', 'academic_year'),
            ('acronym', 'acronym'),
            ('full_title', 'title'),
            ('learning_container_year__container_type', 'type'),
            ('subtype', 'subtype'),
            ('entity_requirement', 'requirement_entity'),
            ('entity_allocation', 'allocation_entity'),
            ('credits', 'credits'),
            ('status', 'status'),
            ('has_proposal', 'has_proposal'),
        ),
        widget=forms.HiddenInput
    )

    class Meta:
        model = LearningUnitYear
        fields = [
            "academic_year",
            "acronym",
            "title",
            "container_type",
            "subtype",
            "requirement_entity",
            "allocation_entity",
            "credits",
            "status",
        ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.queryset = self.get_queryset()
        self.form.fields["academic_year"].initial = starting_academic_year()

    def filter_tutor(self, queryset, name, value):
        for tutor_name in value.split():
            queryset = queryset.filter(
                Q(learningcomponentyear__attributionchargenew__attribution__tutor__person__first_name__iregex=tutor_name
                  ) |
                Q(learningcomponentyear__attributionchargenew__attribution__tutor__person__last_name__iregex=tutor_name)
            ).distinct()
        return queryset

    def filter_container_type(self, queryset, name, value):
        if value == MOBILITY:
            return queryset.filter(externallearningunityear__mobility=True)
        elif value == learning_container_year_types.EXTERNAL:
            return queryset.filter(externallearningunityear__co_graduation=True)
        return queryset.filter(learning_container_year__container_type=value)

    def filter_entity(self, queryset, name, value):
        return filter_by_entities(name, queryset, value, self.form.cleaned_data['with_entity_subordinated'])

    def get_queryset(self):
        # Need this close so as to return empty query by default when form is unbound
        if not self.data:
            return LearningUnitYear.objects.none()

        has_proposal = ProposalLearningUnit.objects.filter(
            learning_unit_year=OuterRef('pk'),
        )

        queryset = LearningUnitYear.objects_with_container.select_related(
            'academic_year',
            'learning_container_year__academic_year',
            'language',
            'proposallearningunit',
            'externallearningunityear'
        ).order_by('academic_year__year', 'acronym').annotate(
            has_proposal=Exists(has_proposal),
        )
        queryset = LearningUnitYearQuerySet.annotate_full_title_class_method(queryset)
        queryset = LearningUnitYearQuerySet.annotate_entities_allocation_and_requirement_acronym(queryset)
        return queryset

    def filter_learning_unit_year_field(self, queryset, name, value):
        return filter_field_by_regex(queryset, name, value)
Example #10
0
def _get_data_from_initial_data(initial_data):
    learning_unit_yr = get_by_id(initial_data.get('learning_unit_year')['id'])
    requirement_entity = find_by_id(
        initial_data.get('entities')['REQUIREMENT_ENTITY'])
    allocation_entity = find_by_id(
        initial_data.get('entities')['ALLOCATION_ENTITY'])
    add1_requirement_entity = find_by_id(
        initial_data.get('entities')['ADDITIONAL_REQUIREMENT_ENTITY_1'])
    add2_requirement_entity = find_by_id(
        initial_data.get('entities')['ADDITIONAL_REQUIREMENT_ENTITY_2'])
    campus = find_campus_by_id(
        initial_data.get('learning_unit_year')['campus'])

    organization = get_organization_from_learning_unit_year(learning_unit_yr)
    language = find_language_by_id(
        initial_data.get('learning_unit_year')['language'])
    lu_initial = initial_data.get('learning_unit', None)
    luy_initial = initial_data.get('learning_unit_year', None)
    lcy_initial = initial_data.get('learning_container_year', None)

    data = [
        str(_('Initial data')),
        luy_initial['acronym'],
        learning_unit_yr.academic_year.name,
        dict(
            LearningContainerYearType.choices())[lcy_initial['container_type']]
        if lcy_initial['container_type'] else '-',
        translate_status(luy_initial['status']),
        learning_unit_yr.get_subtype_display(),
        get_translation(luy_initial['internship_subtype']),
        volume_format(luy_initial['credits']),
        language.name if language else EMPTY_VALUE,
        dict(PERIODICITY_TYPES)[luy_initial['periodicity']]
        if luy_initial['periodicity'] else BLANK_VALUE,
        get_translation(luy_initial['quadrimester']),
        get_translation(luy_initial['session']),
        get_representing_string(lcy_initial['common_title']),
        get_representing_string(luy_initial['specific_title']),
        get_representing_string(lcy_initial['common_title_english']),
        get_representing_string(luy_initial['specific_title_english']),
        requirement_entity.most_recent_acronym
        if requirement_entity else BLANK_VALUE,
        allocation_entity.most_recent_acronym
        if allocation_entity else BLANK_VALUE,
        add1_requirement_entity.most_recent_acronym
        if add1_requirement_entity else BLANK_VALUE,
        add2_requirement_entity.most_recent_acronym
        if add2_requirement_entity else BLANK_VALUE,
        _('Yes') if luy_initial['professional_integration'] else _('No'),
        organization.name if organization else BLANK_VALUE,
        campus if campus else BLANK_VALUE,
        get_representing_string(lu_initial['faculty_remark']),
        get_representing_string(lu_initial['other_remark']),
        _('Yes') if lcy_initial.get('team') else _('No'),
        _('Yes') if lcy_initial.get('is_vacant') else _('No'),
        dict(vacant_declaration_type.DECLARATION_TYPE)[lcy_initial.get(
            'type_declaration_vacant')]
        if lcy_initial.get('type_declaration_vacant') else BLANK_VALUE,
        dict(attribution_procedure.ATTRIBUTION_PROCEDURES)[luy_initial.get(
            'attribution_procedure')]
        if luy_initial.get('attribution_procedure') else BLANK_VALUE,
    ]
    return _get_data_from_components_initial_data(data, initial_data)
Example #11
0
class LearningContainerYear(SerializableModel):
    external_id = models.CharField(max_length=100,
                                   blank=True,
                                   null=True,
                                   db_index=True)
    academic_year = models.ForeignKey('AcademicYear')
    learning_container = models.ForeignKey('LearningContainer')

    container_type = models.CharField(
        verbose_name=_('Type'),
        db_index=True,
        max_length=20,
        choices=LearningContainerYearType.choices(),
    )

    common_title = models.CharField(max_length=255,
                                    blank=True,
                                    null=True,
                                    verbose_name=_('Common title'))
    common_title_english = models.CharField(
        max_length=250,
        blank=True,
        null=True,
        verbose_name=_('Common English title'))
    acronym = models.CharField(max_length=10)
    changed = models.DateTimeField(null=True, auto_now=True)
    team = models.BooleanField(default=False,
                               verbose_name=_('Team management'))
    is_vacant = models.BooleanField(default=False, verbose_name=_('Vacant'))
    type_declaration_vacant = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        verbose_name=_('Decision'),
        choices=vacant_declaration_type.DECLARATION_TYPE)
    in_charge = models.BooleanField(default=False)

    _warnings = None

    def __str__(self):
        return u"%s - %s" % (self.acronym, self.common_title)

    class Meta:
        unique_together = (
            "learning_container",
            "academic_year",
        )
        permissions = (("can_access_learningcontaineryear",
                        "Can access learning container year"), )

    @property
    def warnings(self):
        if self._warnings is None:
            self._warnings = get_learning_container_year_warnings(self)
        return self._warnings

    def get_partims_related(self):
        return learning_unit_year.search(
            learning_container_year_id=self,
            subtype=learning_unit_year_subtypes.PARTIM).order_by('acronym')

    def is_type_for_faculty(self) -> bool:
        return self.container_type in LearningContainerYearType.for_faculty()
Example #12
0
def _get_data_from_initial_data(initial_data, proposal_comparison=False):
    luy_initial = initial_data.get('learning_unit_year', {})
    lcy_initial = initial_data.get('learning_container_year', {})
    lu_initial = initial_data.get('learning_unit', {})

    if luy_initial.get('id'):
        learning_unit_yr = get_by_id(luy_initial.get('id'))
    else:
        learning_unit_yr = None

    requirement_entity = find_by_id(lcy_initial.get('requirement_entity'))
    allocation_entity = find_by_id(lcy_initial.get('allocation_entity'))
    add1_requirement_entity = find_by_id(lcy_initial.get('additional_entity_1'))
    add2_requirement_entity = find_by_id(lcy_initial.get('additional_entity_2'))
    campus = find_campus_by_id(luy_initial.get('campus'))

    organization = None
    if learning_unit_yr:
        organization = get_organization_from_learning_unit_year(learning_unit_yr)
    language = find_language_by_id(luy_initial.get('language'))

    if proposal_comparison:
        academic_year = _format_academic_year(learning_unit_yr.academic_year.name,
                                              find_academic_year_by_id(lu_initial.get('end_year'))
                                              if lu_initial.get('end_year') else None)
    else:
        academic_year = learning_unit_yr.academic_year.name

    data = [
        str(_('Initial data')),
        luy_initial.get('acronym', ''),
        academic_year,
        dict(LearningContainerYearType.choices())[lcy_initial.get('container_type')] if
        lcy_initial.get('container_type') else BLANK_VALUE,
        translate_status(luy_initial.get('status')),
        learning_unit_yr.get_subtype_display()
        if learning_unit_yr and learning_unit_yr.get_subtype_display() else BLANK_VALUE,
        get_translation(luy_initial.get('internship_subtype')),
        volume_format(Decimal(luy_initial['credits'])) if luy_initial.get('credits') else BLANK_VALUE,
        language.name if language else BLANK_VALUE,
        dict(PERIODICITY_TYPES)[luy_initial['periodicity']] if luy_initial.get('periodicity') else BLANK_VALUE,
        get_translation(luy_initial.get('quadrimester')),
        get_translation(luy_initial.get('session')),
        get_representing_string(lcy_initial.get('common_title')),
        get_representing_string(luy_initial.get('specific_title')),
        get_representing_string(lcy_initial.get('common_title_english')),
        get_representing_string(luy_initial.get('specific_title_english')),
        requirement_entity.most_recent_acronym if requirement_entity else BLANK_VALUE,
        allocation_entity.most_recent_acronym if allocation_entity else BLANK_VALUE,
        add1_requirement_entity.most_recent_acronym if add1_requirement_entity else BLANK_VALUE,
        add2_requirement_entity.most_recent_acronym if add2_requirement_entity else BLANK_VALUE,
        _('Yes') if luy_initial.get('professional_integration') else _('No'),
        organization.name if organization else BLANK_VALUE,
        campus if campus else BLANK_VALUE,
        get_representing_string(lu_initial.get('faculty_remark')),
        get_representing_string(lu_initial.get('other_remark')),
        _('Yes') if lcy_initial.get('team') else _('No'),
        _('Yes') if lcy_initial.get('is_vacant') else _('No'),
        dict(vacant_declaration_type.DECLARATION_TYPE)[lcy_initial.get('type_declaration_vacant')] if lcy_initial.get(
            'type_declaration_vacant') else BLANK_VALUE,
        dict(attribution_procedure.ATTRIBUTION_PROCEDURES)[luy_initial.get('attribution_procedure')] if luy_initial.get(
            'attribution_procedure') else BLANK_VALUE,
    ]
    return _get_data_from_components_initial_data(data, initial_data)