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()
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)
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
def is_type_for_faculty(self) -> bool: return self.container_type in LearningContainerYearType.for_faculty()
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)
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
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)
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)
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)
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()
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)