def test_when_link_major_to_major_list_choice(self): major_list_choice = GroupFactory( education_group_type__name=GroupType.MAJOR_LIST_CHOICE.name) major = MiniTrainingFactory( education_group_type__name=MiniTrainingType.FSA_SPECIALITY.name) link = GroupElementYear(parent=major_list_choice, child_branch=major, link_type=None) link._clean_link_type() self.assertEqual(link.link_type, LinkTypes.REFERENCE.name)
def test_when_link_minor_to_minor_list_choice(self): minor_list_choice = GroupFactory( education_group_type__name=GroupType.MINOR_LIST_CHOICE.name) minor = MiniTrainingFactory(education_group_type__name=random.choice( MiniTrainingType.minors())) link = GroupElementYear(parent=minor_list_choice, child_branch=minor, link_type=None) link._clean_link_type() self.assertEqual(link.link_type, LinkTypes.REFERENCE.name)
def test_when_link_deepening_to_minor_list_choice(self): minor_list_choice = GroupFactory( education_group_type__name=GroupType.MINOR_LIST_CHOICE.name) deepening = MiniTrainingFactory( education_group_type__name=MiniTrainingType.DEEPENING.name) link = GroupElementYear(parent=minor_list_choice, child_branch=deepening, link_type=None) link._clean_link_type() self.assertEqual(link.link_type, LinkTypes.REFERENCE.name)
def _postpone_child_branch(self, old_gr: GroupElementYear, new_gr: GroupElementYear) -> GroupElementYear: """ Unlike child leaf, the child branch must be postponed (recursively) """ old_egy = old_gr.child_branch new_egy = old_egy.next_year() if new_egy: is_empty = self._is_empty(new_egy) if new_gr.link_type == LinkTypes.REFERENCE.name and is_empty: self.warnings.append(ReferenceLinkEmptyWarning(new_egy)) elif not is_empty: if not (new_egy.is_training() or new_egy.education_group_type.name in MiniTrainingType.to_postpone()): self.warnings.append( EducationGroupYearNotEmptyWarning( new_egy, self.next_academic_year)) else: self._postpone(old_egy, new_egy) else: # If the education group does not exists for the next year, we have to postpone. new_egy = self._duplication_education_group_year(old_gr, old_egy) self.number_elements_created += 1 new_gr.child_branch = new_egy if new_egy and new_egy.education_group_type.name == MiniTrainingType.OPTION.name: self.postponed_options[new_egy.id] = new_gr if new_egy and new_gr.parent.education_group_type.name in TrainingType.finality_types( ): self.postponed_finalities.append(new_gr) return new_gr
def _postpone_child_branch(self, old_gr: GroupElementYear, new_gr: GroupElementYear) -> GroupElementYear: """ Unlike child leaf, the child branch must be postponed (recursively) """ old_egy = old_gr.child_branch new_egy = old_egy.next_year() if new_egy: is_empty = self._is_empty(new_egy) if new_gr.link_type == LinkTypes.REFERENCE.name and is_empty: self.warnings.append(ReferenceLinkEmptyWarning(new_egy)) elif not is_empty: if not (new_egy.is_training() or new_egy.is_mini_training()): self.warnings.append(EducationGroupYearNotEmptyWarning(new_egy, self.next_academic_year)) else: self._postpone(old_egy, new_egy) else: # If the education group does not exists for the next year, we have to postpone. new_egy = self._duplication_education_group_year(old_gr, old_egy) new_gr.child_branch = new_egy if new_egy and new_egy.education_group_type.name == MiniTrainingType.OPTION.name: self.postponed_options[new_egy.id] = new_gr if new_egy and new_gr.parent.education_group_type.name in TrainingType.finality_types(): self.postponed_finalities.append(new_gr) return new_gr
def is_valid(self): if self.parent.education_group_type.name in TrainingType.root_master_2m_types() or \ self.parents.filter(education_group_type__name__in=TrainingType.root_master_2m_types()).exists(): self._check_end_year_constraints_on_2m() self._check_attach_options_rules() if not self.instance: self._check_new_attach_is_not_duplication() GroupElementYear(parent=self.parent, child_branch=self.child, child_leaf=None).clean() return True
def clean_link_type(self): """ All of these controls only work with child branch. The validation with learning_units (child_leaf) is in the model. """ data_cleaned = self.cleaned_data.get('link_type') if not self.instance.child_branch: return data_cleaned new_link = GroupElementYear(child_branch=self.instance.child_branch, link_type=data_cleaned) check = CheckAuthorizedRelationshipAttach(self.instance.parent, link_to_attach=new_link) if not check.is_valid(): raise ValidationError(check.errors) return data_cleaned
def is_valid(self): if not self.instance: self._check_new_attach_is_not_duplication() GroupElementYear(parent=self.parent, child_branch=None, child_leaf=self.child).clean() if not self.parent.education_group_type.learning_unit_child_allowed: raise ValidationError( gettext( "You can not add a learning unit to a %(category)s of type %(type)s." ) % { 'category': self.parent.education_group_type.get_category_display(), 'type': self.parent.education_group_type.get_name_display() }) return True
def clean_link_type(self): """ All of these controls only work with child branch. The validation with learning_units (child_leaf) is in the model. """ data_cleaned = self.cleaned_data.get('link_type') if not self.instance.child_branch: return data_cleaned try: new_link = GroupElementYear( child_branch=self.instance.child_branch, link_type=data_cleaned) check_authorized_relationship(self.instance.parent, new_link) except AuthorizedRelationshipNotRespectedException as e: raise ValidationError(e.errors) return data_cleaned