def setup_learning_unit_year(academic_year, learning_unit, learning_container_year, learning_unit_year_subtype, periodicity): create = False result = None end_year = learning_unit.end_year or compute_max_academic_year_adjournment( ) if learning_unit.start_year <= academic_year.year <= end_year: if periodicity == learning_unit_year_periodicity.BIENNIAL_ODD: if not (academic_year.year % 2): create = True elif periodicity == learning_unit_year_periodicity.BIENNIAL_EVEN: if academic_year.year % 2: create = True elif periodicity == learning_unit_year_periodicity.ANNUAL: create = True if create: if not learning_container_year: learning_container_year = LearningUnitsMixin.setup_learning_container_year( academic_year, learning_container_year_types.COURSE) result = LearningUnitYearFactory( academic_year=academic_year, learning_unit=learning_unit, learning_container_year=learning_container_year, subtype=learning_unit_year_subtype, periodicity=periodicity) return result
def fetch_learning_unit_to_postpone(queryset=None): if not queryset: queryset = LearningUnitYear.objects_with_container.all() # Fetch N+6 and N+5 academic_years last_academic_year = AcademicYear.objects.get( year=compute_max_academic_year_adjournment()) penultimate_academic_year = last_academic_year.past() # We take all learning unit years from N+5 academic year qs_luy = queryset.filter(academic_year=penultimate_academic_year) # Create filters to know which luys must be copied to N+6 luys_already_duplicated = qs_luy.filter( learning_unit__learningunityear__academic_year=last_academic_year) luys_to_not_duplicate = qs_luy.filter( learning_unit__end_year__lt=last_academic_year.year) luys_to_duplicate = qs_luy.difference(luys_already_duplicated, luys_to_not_duplicate) # send statistics to the managers send_mail_before_annual_procedure_of_automatic_postponement( last_academic_year, luys_to_duplicate, luys_already_duplicated, luys_to_not_duplicate) result, errors = extend_learning_units_until_last_academic_year( last_academic_year, luys_to_duplicate) # send statistics with results to the managers send_mail_after_annual_procedure_of_automatic_postponement( last_academic_year, result, luys_already_duplicated, luys_to_not_duplicate, errors) return result, errors
def _compute_max_postponement_year(self): max_postponement_year = academic_year.compute_max_academic_year_adjournment( ) end_year = self.end_postponement.year if self.end_postponement else None return min( end_year, max_postponement_year) if end_year else max_postponement_year
def _get_actual_end_year(learning_unit_to_edit): proposal = ProposalLearningUnit.objects.filter( learning_unit_year__learning_unit=learning_unit_to_edit).first() end_year_lu = proposal.initial_data.get('learning_unit').get('end_year') if proposal \ else learning_unit_to_edit.end_year return end_year_lu or academic_year.find_academic_year_by_year( compute_max_academic_year_adjournment() + 1)
def academic_year_validator(value): academic = AcademicYear.objects.get(pk=value) academic_year_max = compute_max_academic_year_adjournment() if academic.year > academic_year_max: raise ValidationError( _('Please select an academic year lower than %(academic_year_max)d.' ) % { 'academic_year_max': academic_year_max, })
def _check_extend_partim(last_learning_unit_year, new_academic_year): if not new_academic_year: # If there is no selected academic_year, we take the maximal value new_academic_year = AcademicYear.objects.get( year=compute_max_academic_year_adjournment() + 1) lu_parent = last_learning_unit_year.parent if last_learning_unit_year.is_partim() and lu_parent: if _get_actual_end_year( lu_parent.learning_unit) < new_academic_year.year: raise IntegrityError( _('parent_greater_than_partim') % { 'partim_end_year': new_academic_year, 'lu_parent': lu_parent.acronym })
def _compute_max_postponement_year(self) -> int: """ Compute the maximal year for the postponement of the learning unit If the learning unit is a partim, the max year is the max year of the full """ if self.subtype == learning_unit_year_subtypes.PARTIM: max_postponement_year = self.learning_unit_full_instance.learningunityear_set.aggregate( Max('academic_year__year') )['academic_year__year__max'] else: max_postponement_year = academic_year.compute_max_academic_year_adjournment() end_year = self.end_postponement.year if self.end_postponement else None return min(end_year, max_postponement_year) if end_year else max_postponement_year
def _compute_max_postponement_year(self) -> int: """ Compute the maximal year for the postponement of the learning unit If the learning unit is a partim, the max year is the max year of the full """ if self.subtype == learning_unit_year_subtypes.PARTIM: max_postponement_year = self.learning_unit_full_instance.learningunityear_set.aggregate( Max('academic_year__year') )['academic_year__year__max'] else: max_postponement_year = academic_year.compute_max_academic_year_adjournment() end_year = self.end_postponement.year if self.end_postponement else None return min(end_year, max_postponement_year) if end_year else max_postponement_year
def __init__(self, queryset=None): # Fetch the N and N+6 academic_years self.last_academic_year = AcademicYear.objects.get( year=compute_max_academic_year_adjournment()) self.current_year = current_academic_year() self.queryset = self.get_queryset(queryset) self.already_duplicated = self.get_already_duplicated() self.to_not_duplicate = self.get_to_not_duplicated() self.to_duplicate = self.queryset.difference(self.already_duplicated, self.to_not_duplicate) self.result = [] # Contains the list of postponed objects. self.errors = []
def extend_learning_unit(learning_unit_to_edit, new_academic_year): result = [] last_learning_unit_year = LearningUnitYear.objects.filter( learning_unit=learning_unit_to_edit).order_by('academic_year').last() _check_extend_partim(last_learning_unit_year, new_academic_year) if not new_academic_year: # If there is no selected academic_year, we take the maximal value new_academic_year = AcademicYear.objects.get( year=compute_max_academic_year_adjournment()) with transaction.atomic(): for ac_year in get_next_academic_years(learning_unit_to_edit, new_academic_year.year): new_luy = duplicate_learning_unit_year(last_learning_unit_year, ac_year) result.append(create_learning_unit_year_creation_message(new_luy)) return result
def __init__(self, *args, instance=None, initial=None, **kwargs): super().__init__(*args, instance=instance, initial=initial, external=True, **kwargs) self.fields['internship_subtype'].disabled = True if instance: self.fields["country_external_institution"].initial = instance.campus.organization.country and \ instance.campus.organization.country.pk elif initial.get("campus"): self.fields["country_external_institution"].initial = initial["campus"].organization.country and\ initial["campus"].organization.country.pk if not self.instance.pk: self.data['acronym_0'] = LearningUnitExternalSite.E.value self.fields['academic_year'].queryset = AcademicYear.objects.filter( year__gt=settings.YEAR_LIMIT_LUE_MODIFICATION, year__lte=compute_max_academic_year_adjournment()).order_by('year') self.fields['academic_year'].empty_label = None else: self.data['acronym_0'] = self.instance.acronym[0] self.fields['attribution_procedure'].disabled = True self.fields['attribution_procedure'].required = False
def _get_academic_years(self, max_year): current_academic_year = academic_year.starting_academic_year() min_year = current_academic_year.year if not max_year: max_year = compute_max_academic_year_adjournment() if self.learning_unit.start_year > min_year: min_year = self.learning_unit.start_year if self.learning_unit.is_past(): 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 AcademicYear.objects.min_max_years(min_year, max_year)
def setup_learning_unit_year(academic_year, learning_unit, learning_container_year, learning_unit_year_subtype, periodicity): create = False result = None end_year = learning_unit.end_year or AcademicYearFactory( year=compute_max_academic_year_adjournment()) if learning_unit.start_year.year <= academic_year.year <= end_year.year: create = LearningUnitsMixin._has_to_be_created( academic_year, create, periodicity) if create: if not learning_container_year: learning_container_year = LearningUnitsMixin.setup_learning_container_year( academic_year, learning_container_year_types.COURSE) result = LearningUnitYearFactory( academic_year=academic_year, learning_unit=learning_unit, learning_container_year=learning_container_year, subtype=learning_unit_year_subtype, periodicity=periodicity) return result
def _get_actual_end_year(learning_unit_to_edit): return learning_unit_to_edit.end_year or compute_max_academic_year_adjournment( ) + 1
def academic_year_validator(value): academic = AcademicYear.objects.get(pk=value) academic_year_max = compute_max_academic_year_adjournment() if academic.year > academic_year_max: raise ValidationError(_('learning_unit_creation_academic_year_max_error').format(academic_year_max))
def _get_actual_end_year(learning_unit_to_edit): return learning_unit_to_edit.end_year or compute_max_academic_year_adjournment() + 1