def _find_consistency_errors(self): form_kwargs = { 'learning_unit_instance': self.learning_unit_instance, 'start_year': self.learning_unit_instance.start_year } current_form = self._get_learning_unit_base_form( self.start_postponement, **form_kwargs) if self._has_proposal(self.learning_unit_instance) and \ (self.person.is_faculty_manager and not self.person.is_central_manager): max_postponement_year = self._compute_max_postponement_year() academic_years = academic_year.find_academic_years( start_year=self.start_postponement.year, end_year=max_postponement_year) else: academic_years = sorted([ form.instance.academic_year for form in self._forms_to_upsert if form.instance ], key=lambda ac_year: ac_year.year) self.consistency_errors = OrderedDict() for ac_year in academic_years: next_form = self._get_learning_unit_base_form( ac_year, **form_kwargs) self._check_postponement_proposal_state( next_form.learning_unit_year_form.instance, ac_year) self._check_postponement_repartition_volume( next_form.learning_unit_year_form.instance) self._check_differences(current_form, next_form, ac_year) return self.consistency_errors
class EducationGroupFilter(forms.Form): academic_year = forms.ModelChoiceField( queryset=academic_year.find_academic_years(), required=False, empty_label=pgettext_lazy("plural", "All"), label=_('Ac yr.')) category = forms.ChoiceField( choices=[("", pgettext_lazy("plural", "All"))] + list(Categories.choices()), required=False, label=_('Category')) education_group_type = ModelChoiceFieldWithData( queryset=EducationGroupType.objects.none(), required=False, empty_label=pgettext_lazy("plural", "All"), label=_('Type')) acronym = forms.CharField(max_length=40, required=False, label=_('Acronym')) title = forms.CharField(max_length=255, required=False, label=_('Title')) requirement_entity_acronym = forms.CharField(max_length=20, required=False, label=_('Entity')) partial_acronym = forms.CharField(max_length=15, required=False, label=_('Code')) with_entity_subordinated = forms.BooleanField(required=False) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields[ "education_group_type"].queryset = EducationGroupType.objects.all( ).order_by_translated_name() self.fields["education_group_type"].set_data_attrs() def clean_category(self): data_cleaned = self.cleaned_data.get('category') if data_cleaned: return data_cleaned def get_object_list(self): clean_data = { key: value for key, value in self.cleaned_data.items() if value is not None } result = education_group_year.search(**clean_data) if clean_data.get('requirement_entity_acronym'): result = _get_filter_entity_management( result, clean_data['requirement_entity_acronym'], clean_data.get('with_entity_subordinated', False)) # TODO User should choice the order return result.order_by('acronym')
def test_find_academic_years(self): today = datetime.date.today() academic_yrs = academic_year.find_academic_years(start_date=today, end_date=today) nb_of_academic_yrs = academic_yrs.count() if self.starting_academic_yr != self.current_academic_yr: self.assertEqual(nb_of_academic_yrs, 2) else: self.assertEqual(nb_of_academic_yrs, 1)
def _restrict_academic_years_choice(self): current_academic_year = academic_year.current_academic_year() end_year_range = MAX_ACADEMIC_YEAR_FACULTY if self.person.is_faculty_manager( ) else MAX_ACADEMIC_YEAR_CENTRAL self.fields[ "academic_year"].queryset = academic_year.find_academic_years( start_year=current_academic_year.year, end_year=current_academic_year.year + end_year_range)
def form_valid(self, form, form_year): partnership = form.save(commit=False) partnership.author = self.request.user.person if partnership.partnership_type in PartnershipType.with_synced_dates(): start_academic_year = form_year.cleaned_data['start_academic_year'] end_academic_year = form_year.cleaned_data['end_academic_year'] partnership.start_date = start_academic_year.start_date partnership.end_date = end_academic_year.end_date else: years = find_academic_years( # We need academic years surrounding this time range start_date=partnership.end_date, end_date=partnership.start_date, ) start_academic_year = years.first() end_academic_year = years.last() # Resume saving partnership.save() form.save_m2m() # Create years start_year = start_academic_year.year end_year = end_academic_year.year academic_years = find_academic_years(start_year=start_year, end_year=end_year) for academic_year in academic_years: partnership_year = form_year.save(commit=False) partnership_year.id = None # Force the creation of a new PartnershipYear partnership_year.partnership = partnership partnership_year.academic_year = academic_year partnership_year.save() form_year.save_m2m() messages.success(self.request, _('partnership_success')) if not is_linked_to_adri_entity(self.request.user): title = '{} - {}'.format( _('partnership_created'), partnership.ucl_entity.most_recent_acronym ) self.notify_admin_mail(title, 'partnership_creation.html', { 'partnership': partnership, }) return redirect(partnership)
def manager_dissertations_search(request): person = mdl.person.find_by_user(request.user) adv = adviser.search_by_person(person) offers = faculty_adviser.search_by_adviser(adv) disserts = dissertation.search(terms=request.GET.get('search', ''), active=True) disserts = disserts.filter(offer_year_start__offer__in=offers) offer_prop_search = request.GET.get('offer_prop_search', '') academic_year_search = request.GET.get('academic_year', '') status_search = request.GET.get('status_search', '') if offer_prop_search != '': offer_prop_search = int(offer_prop_search) offer_prop = offer_proposition.find_by_id(offer_prop_search) disserts = disserts.filter(offer_year_start__offer=offer_prop.offer) if academic_year_search != '': academic_year_search = int(academic_year_search) disserts = disserts.filter( offer_year_start__academic_year=academic_year. find_academic_year_by_id(academic_year_search)) if status_search != '': disserts = disserts.filter(status=status_search) offer_props = offer_proposition.search_by_offer(offers) show_validation_commission = offer_proposition.show_validation_commission( offer_props) show_evaluation_first_year = offer_proposition.show_evaluation_first_year( offer_props) start_date = timezone.now().replace(year=timezone.now().year - 10) end_date = timezone.now().replace(year=timezone.now().year + 1) academic_year_10y = academic_year.find_academic_years(end_date, start_date) if 'bt_xlsx' in request.GET: xls = generate_xls(disserts) filename = 'dissertations_{}.xlsx'.format( time.strftime("%Y-%m-%d_%H:%M")) response = HttpResponse( xls, content_type= 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) response['Content-Disposition'] = "%s%s" % ("attachment; filename=", filename) return response else: return layout.render( request, "manager_dissertations_list.html", { 'dissertations': disserts, 'show_validation_commission': show_validation_commission, 'show_evaluation_first_year': show_evaluation_first_year, 'academic_year_10y': academic_year_10y, 'offer_props': offer_props, 'offer_prop_search': offer_prop_search, 'academic_year_search': academic_year_search, 'status_search': status_search })
def _restrict_academic_years_choice(self, postposal): if postposal: starting_academic_year = academic_year.starting_academic_year() end_year_range = MAX_ACADEMIC_YEAR_FACULTY if self.person.is_faculty_manager \ else MAX_ACADEMIC_YEAR_CENTRAL self.fields[ "academic_year"].queryset = academic_year.find_academic_years( start_year=starting_academic_year.year, end_year=starting_academic_year.year + end_year_range)
def clean(self): super().clean() years = find_academic_years( # We need academic years surrounding this time range start_date=self.cleaned_data['end_date'], end_date=self.cleaned_data['start_date'], ) self.cleaned_data['start_academic_year'] = years.first() self.cleaned_data['end_academic_year'] = years.last() return self.cleaned_data
class EducationGroupFilter(forms.Form): academic_year = forms.ModelChoiceField( queryset=academic_year.find_academic_years(), required=False, widget=forms.Select(attrs={'class': 'form-control'}), empty_label=_('all_label')) education_group_type = forms.ModelChoiceField( queryset=offer_type.find_all(), required=False, widget=forms.Select(attrs={'class': 'form-control'}), empty_label=_('all_label')) category = forms.ChoiceField( EDUCATION_GROUP_CATEGORIES, required=False, widget=forms.Select(attrs={'class': 'form-control'})) acronym = title = entity_management = forms.CharField( widget=forms.TextInput(attrs={ 'size': '10', 'class': 'form-control' }), max_length=20, required=False) def clean_category(self): data_cleaned = self.cleaned_data.get('category') if data_cleaned: return data_cleaned return None def get_object_list(self): clean_data = { key: value for key, value in self.cleaned_data.items() if value is not None } offer_year_entity_prefetch = models.Prefetch( 'offeryearentity_set', queryset=offer_year_entity.search(type=offer_year_entity_type.ENTITY_MANAGEMENT)\ .prefetch_related( models.Prefetch('entity__entityversion_set', to_attr='entity_versions') ), to_attr='offer_year_entities' ) if clean_data.get('entity_management'): clean_data['id'] = _get_filter_entity_management( clean_data['entity_management']) education_groups = education_group_year.search(**clean_data)[:MAX_RECORDS + 1]\ .prefetch_related(offer_year_entity_prefetch) return [ _append_entity_management(education_group) for education_group in education_groups ]
class EducationGroupFilter(BootstrapForm): academic_year = forms.ModelChoiceField( queryset=academic_year.find_academic_years(), required=False, empty_label=_('all_label'), label=_('academic_year_small')) category = forms.ChoiceField(choices=[("", _('all_label'))] + list(education_group_categories.CATEGORIES), required=False, label=_('category')) education_group_type = ModelChoiceFieldWithData( queryset=EducationGroupType.objects.all(), required=False, empty_label=_('all_label'), label=_('type')) acronym = forms.CharField(max_length=40, required=False, label=_('acronym')) title = forms.CharField(max_length=255, required=False, label=_('title')) requirement_entity_acronym = forms.CharField(max_length=20, required=False, label=_('entity')) partial_acronym = forms.CharField(max_length=15, required=False, label=_('code')) with_entity_subordinated = forms.BooleanField(required=False) def clean_category(self): data_cleaned = self.cleaned_data.get('category') if data_cleaned: return data_cleaned def get_object_list(self): clean_data = { key: value for key, value in self.cleaned_data.items() if value is not None } result = education_group_year.search(**clean_data) if clean_data.get('requirement_entity_acronym'): result = _get_filter_entity_management( result, clean_data['requirement_entity_acronym'], clean_data.get('with_entity_subordinated', False)) # TODO User should choice the order return result.order_by('acronym')
def _restrict_academic_years_choice_for_proposal_creation_suppression(self, proposal_type): if proposal_type in (ProposalType.CREATION.name, ProposalType.SUPPRESSION): if self.person.is_faculty_manager and proposal_type == ProposalType.CREATION.name: starting_academic_year = academic_year.current_academic_year().next() else: starting_academic_year = academic_year.starting_academic_year() end_year_range = MAX_ACADEMIC_YEAR_CENTRAL - 1 if self.person.is_faculty_manager \ else MAX_ACADEMIC_YEAR_CENTRAL self.fields["academic_year"].queryset = academic_year.find_academic_years( start_year=starting_academic_year.year, end_year=starting_academic_year.year + end_year_range )
def test_academic_year_range_creation_proposal_faculty_manager(self): LanguageFactory(code="FR") faculty_manager = FacultyManagerFactory() form = learning_unit_create_2.FullForm( faculty_manager, self.learning_unit_year.academic_year, start_year=self.learning_unit_year.academic_year, proposal_type=ProposalType.CREATION.name ) self.assertCountEqual( list(form.fields['academic_year'].queryset), list(academic_year_mdl.find_academic_years( start_year=self.current_academic_year.year + 1, end_year=self.current_academic_year.year + 6 )) )
class EducationGroupFilter(BootstrapForm): academic_year = forms.ModelChoiceField( queryset=academic_year.find_academic_years(), required=False, empty_label=_('all_label')) category = forms.ChoiceField(choices=[("", _('all_label'))] + list(education_group_categories.CATEGORIES), required=False) education_group_type = ModelChoiceFieldWithData( queryset=EducationGroupType.objects.all(), required=False, empty_label=_('all_label')) acronym = title = requirement_entity_acronym = partial_acronym = forms.CharField( max_length=20, required=False) with_entity_subordinated = forms.BooleanField(required=False) def clean_category(self): data_cleaned = self.cleaned_data.get('category') if data_cleaned: return data_cleaned def get_object_list(self): clean_data = { key: value for key, value in self.cleaned_data.items() if value is not None } entity_versions_prefetch = models.Prefetch('entity__entityversion_set', to_attr='entity_versions') offer_year_entity_prefetch = models.Prefetch('offeryearentity_set', queryset=offer_year_entity.search(type=offer_year_entity_type.ENTITY_MANAGEMENT)\ .prefetch_related(entity_versions_prefetch), to_attr='offer_year_entities') if clean_data.get('requirement_entity_acronym'): clean_data['id'] = _get_filter_entity_management( clean_data['requirement_entity_acronym'], clean_data.get('with_entity_subordinated', False)) education_groups = education_group_year.search( **clean_data).prefetch_related(offer_year_entity_prefetch) return [ _append_entity_management(education_group) for education_group in education_groups ]
def _restrict_academic_years_choice_for_proposal_creation_suppression( self, proposal_type): if proposal_type in (ProposalType.CREATION.name, ProposalType.SUPPRESSION): if self.person.is_faculty_manager and proposal_type == ProposalType.CREATION.name: starting_academic_year = academic_year.starting_academic_year( ).next() else: starting_academic_year = academic_year.starting_academic_year() end_year_range = MAX_ACADEMIC_YEAR_CENTRAL - 1 if self.person.is_faculty_manager \ else MAX_ACADEMIC_YEAR_CENTRAL self.fields[ "academic_year"].queryset = academic_year.find_academic_years( start_year=starting_academic_year.year, end_year=starting_academic_year.year + end_year_range)
def _compute_forms_to_insert_update_delete(self, data): max_postponement_year = self._compute_max_postponement_year() ac_year_postponement_range = academic_year.find_academic_years( start_year=self.start_postponement.year, end_year=max_postponement_year) existing_learn_unit_years = learning_unit_year.LearningUnitYear.objects \ .filter(academic_year__year__gte=self.start_postponement.year)\ .filter(learning_unit=self.learning_unit_instance) \ .select_related('learning_container_year', 'learning_unit', 'academic_year') \ .order_by('academic_year__year') to_delete = to_update = to_insert = [] if self.start_postponement.is_past(): to_update = self._init_forms_in_past(existing_learn_unit_years, data) else: if self._is_update_action(): to_delete = [ self._instantiate_base_form_as_update(luy, index_form=index) for index, luy in enumerate(existing_learn_unit_years) if luy.academic_year.year > max_postponement_year ] to_update = [ self._instantiate_base_form_as_update(luy, index_form=index, data=data) for index, luy in enumerate(existing_learn_unit_years) if luy.academic_year.year <= max_postponement_year ] existing_ac_years = [ luy.academic_year for luy in existing_learn_unit_years ] to_insert = [ self._instantiate_base_form_as_insert(ac_year, data) for index, ac_year in enumerate(ac_year_postponement_range) if ac_year not in existing_ac_years ] else: to_insert = [ self._instantiate_base_form_as_insert(ac_year, data) for index, ac_year in enumerate(ac_year_postponement_range) ] self._forms_to_delete = to_delete self._forms_to_upsert = to_update + to_insert
def manager_dissertations_list(request): person = mdl.person.find_by_user(request.user) adv = adviser.search_by_person(person) offers = faculty_adviser.search_by_adviser(adv) disserts = dissertation.search_by_offer(offers) offer_props = offer_proposition.search_by_offer(offers) start_date=timezone.now().replace(year=timezone.now().year - 10) end_date=timezone.now().replace(year=timezone.now().year + 1) academic_year_10y=find_academic_years(end_date,start_date) show_validation_commission = offer_proposition.show_validation_commission(offer_props) show_evaluation_first_year = offer_proposition.show_evaluation_first_year(offer_props) return layout.render(request, 'manager_dissertations_list.html', {'dissertations': disserts, 'show_validation_commission': show_validation_commission, 'show_evaluation_first_year': show_evaluation_first_year, 'academic_year_10y': academic_year_10y, 'offer_props':offer_props})
def _get_academic_years(self): current_academic_year = academic_year.current_academic_year() min_year = current_academic_year.year max_year = compute_max_academic_year_adjournment() if self.learning_unit.start_year > min_year: min_year = self.learning_unit.start_year if is_old_learning_unit(self.learning_unit): raise ValueError( 'Learning_unit.end_year {} cannot be less than the current academic_year {}'.format( self.learning_unit.end_year, current_academic_year) ) if min_year > max_year: raise ValueError('Learning_unit {} cannot be modify'.format(self.learning_unit)) return academic_year.find_academic_years(start_year=min_year, end_year=max_year)
def _find_consistency_errors(self): form_kwargs = {'learning_unit_instance': self.learning_unit_instance, 'start_year': self.learning_unit_instance.start_year} current_form = self._get_learning_unit_base_form(self.start_postponement, **form_kwargs) if self._has_proposal(self.learning_unit_instance) and \ (self.person.is_faculty_manager and not self.person.is_central_manager): max_postponement_year = self._compute_max_postponement_year() academic_years = academic_year.find_academic_years(start_year=self.start_postponement.year, end_year=max_postponement_year) else: academic_years = sorted([form.instance.academic_year for form in self._forms_to_upsert if form.instance], key=lambda ac_year: ac_year.year) self.consistency_errors = OrderedDict() for ac_year in academic_years: next_form = self._get_learning_unit_base_form(ac_year, **form_kwargs) self._check_postponement_proposal_state(next_form.learning_unit_year_form.instance, ac_year) self._check_postponement_repartition_volume(next_form.learning_unit_year_form.instance) self._check_differences(current_form, next_form, ac_year) return self.consistency_errors
def form_valid(self, form, form_year): partnership = form.save() year_data = form_year.cleaned_data new_end_year = year_data.get('end_academic_year') if (new_end_year and new_end_year != self.object.end_academic_year and not is_linked_to_adri_entity(self.request.user)): title = _( 'partnership_end_year_updated_{partner}_{faculty}').format( partner=partnership.first_partner_name, faculty=partnership.ucl_entity.most_recent_acronym, ) self.notify_admin_mail(title, 'partnership_update.html', { 'partnership': partnership, }) start_year = None start_academic_year = year_data.get('start_academic_year', None) # Create missing start year if needed if start_academic_year is not None: start_year = start_academic_year.year first_year = partnership.years.order_by( 'academic_year__year').select_related('academic_year').first() if first_year is not None: first_year_education_fields = first_year.education_fields.all() first_year_education_levels = first_year.education_levels.all() first_year_entities = first_year.entities.all() first_year_offers = first_year.offers.all() academic_years = find_academic_years( start_year=start_year, end_year=first_year.academic_year.year - 1) for academic_year in academic_years: first_year.id = None first_year.academic_year = academic_year first_year.save() first_year.education_fields.set( first_year_education_fields) first_year.education_levels.set( first_year_education_levels) first_year.entities.set(first_year_entities) first_year.offers.set(first_year_offers) # Update years if partnership.partnership_type in PartnershipType.with_synced_dates(): from_year = year_data['from_academic_year'].year end_year = year_data['end_academic_year'].year academic_years = find_academic_years( start_year=from_year, end_year=end_year, ) else: academic_years = find_academic_years( # We need academic years surrounding this time range start_date=partnership.end_date, end_date=partnership.start_date, ) end_year = academic_years.last().year for academic_year in academic_years: partnership_year = form_year.save(commit=False) existing_year = PartnershipYear.objects.filter( partnership=partnership, academic_year=academic_year).first() partnership_year.pk = existing_year.pk if existing_year else None partnership_year.partnership = partnership partnership_year.academic_year = academic_year partnership_year.save() form_year.save_m2m() # Delete no longer used years if partnership.partnership_type in PartnershipType.with_synced_dates(): query = Q(academic_year__year__gt=end_year) if start_academic_year is not None: query |= Q(academic_year__year__lt=start_year) else: query = Q(academic_year__start_date__gt=partnership.end_date) query |= Q(academic_year__end_date__lt=partnership.start_date) partnership.years.filter(query).delete() # Sync dates if not form.cleaned_data.get('start_date') and start_academic_year: partnership.start_date = start_academic_year.start_date partnership.save() if not form.cleaned_data.get('end_date'): partnership.end_date = year_data['end_academic_year'].end_date partnership.save() messages.success(self.request, _('partnership_success')) return redirect(partnership)
def _compute_forms_to_insert_update_delete(self, data): max_postponement_year = self._compute_max_postponement_year() ac_year_postponement_range = academic_year.find_academic_years( start_year=self.start_postponement.year, end_year=max_postponement_year) existing_learn_unit_years = learning_unit_year.LearningUnitYear.objects \ .filter(academic_year__year__gte=self.start_postponement.year)\ .filter(learning_unit=self.learning_unit_instance) \ .select_related('learning_container_year', 'learning_unit', 'academic_year') \ .order_by('academic_year__year') to_delete = to_update = to_insert = [] if self.start_postponement.is_past(): to_update = self._init_forms_in_past(existing_learn_unit_years, data) else: if self._is_update_action(): to_delete = [ self._instantiate_base_form_as_update(luy, index_form=index) for index, luy in enumerate(existing_learn_unit_years) if luy.academic_year.year > max_postponement_year ] to_update = [ self._instantiate_base_form_as_update(luy, index_form=index, data=data) for index, luy in enumerate(existing_learn_unit_years) if luy.academic_year.year <= max_postponement_year ] existing_ac_years = [ luy.academic_year for luy in existing_learn_unit_years ] to_insert = [] # FIXME: We use data copy because data is immuniable and acronym, academic_year and container_type # is not in data with edition form for index, ac_year in enumerate(ac_year_postponement_range): if ac_year not in existing_ac_years: data_to_insert = None if data and existing_learn_unit_years: data_to_insert = data.copy() data_to_insert[ "acronym_0"] = existing_learn_unit_years[ 0].acronym[0] data_to_insert[ "acronym_1"] = existing_learn_unit_years[ 0].acronym[1:] data_to_insert["container_type"] = \ existing_learn_unit_years[0].learning_container_year.container_type data_to_insert["academic_year"] = str(ac_year.id) to_insert.append( self._instantiate_base_form_as_insert( ac_year, data_to_insert)) else: to_insert.append( self._instantiate_base_form_as_insert( ac_year, data)) else: to_insert = [ self._instantiate_base_form_as_insert(ac_year, data) for index, ac_year in enumerate(ac_year_postponement_range) ] self._forms_to_delete = to_delete self._forms_to_upsert = to_update + to_insert