Ejemplo n.º 1
0
    def __init__(self, *args, **kwargs):
        self.component = kwargs.pop('component')
        self.learning_unit_year = kwargs.pop('learning_unit_year')
        self.entities = kwargs.pop('entities', [])
        self.is_faculty_manager = kwargs.pop('is_faculty_manager', False)

        self.title = self.component.acronym
        self.title_help = _(self.component.type) + ' ' if self.component.type else ''
        self.title_help += self.component.acronym

        super().__init__(*args, **kwargs)
        help_volume_global = "{} = {} * {}".format(_('volume total global'),
                                                   _('Volume total annual'),
                                                   _('Planned classes'))

        # Append dynamic fields
        entities_to_add = [entity for entity in REQUIREMENT_ENTITIES if entity in self.entities]
        for i, key in enumerate(entities_to_add):
            entity = self.entities[key]
            self.fields["volume_" + key.lower()] = VolumeField(
                label=entity.acronym,
                help_text=entity.title,
                widget=StepHalfIntegerWidget(),
            )
            if i != len(entities_to_add) - 1:
                self.fields["add" + key.lower()] = EmptyField(label='+')

        if self.is_faculty_manager \
                and self.learning_unit_year.is_full() \
                and self.learning_unit_year.learning_container_year.container_type \
                in LEARNING_CONTAINER_YEAR_TYPES_CANT_UPDATE_BY_FACULTY:
            self._disable_central_manager_fields()
Ejemplo n.º 2
0
    def __init__(self, *args, **kwargs):
        self.component = kwargs.pop('component')
        self.learning_unit_year = kwargs.pop('learning_unit_year')
        self.entities = kwargs.pop('entities', [])
        self.is_faculty_manager = kwargs.pop('is_faculty_manager', False)

        self.title = _(self.component.get_type_display(
        )) + ' ' if self.component.type else self.component.acronym
        self.title_help = _(self.component.get_type_display()
                            ) + ' ' if self.component.type else ''
        self.title_help += self.component.acronym

        super().__init__(*args, **kwargs)
        help_volume_global = "{} = {} * {}".format(_('volume total global'),
                                                   _('Volume total annual'),
                                                   _('Planned classes'))

        # Append dynamic fields
        entities_to_add = [
            entity for entity in REQUIREMENT_ENTITIES
            if entity in self.entities
        ]
        size_entities_to_add = len(entities_to_add)
        if size_entities_to_add > 1:
            self.fields["opening_brackets_entities_field"] = EmptyField(
                label='[')
        for i, key in enumerate(entities_to_add):
            entity = self.entities[key]
            if entity:
                self.fields["volume_" + key.lower()] = VolumeField(
                    label=entity.acronym,
                    help_text=entity.title,
                    widget=DecimalFormatInput(render_value=True),
                    required=False)
                if i != len(entities_to_add) - 1:
                    self.fields["add" + key.lower()] = EmptyField(label='+')
        if size_entities_to_add > 1:
            self.fields["closing_brackets_entities_field"] = EmptyField(
                label=']')

        if self.is_faculty_manager \
                and self.learning_unit_year.is_full() \
                and self.learning_unit_year.learning_container_year.container_type \
                in LEARNING_CONTAINER_YEAR_TYPES_CANT_UPDATE_BY_FACULTY:
            self._disable_central_manager_fields()
Ejemplo n.º 3
0
    def __init__(self, *args, **kwargs):
        self.component = kwargs.pop('component')
        self.learning_unit_year = kwargs.pop('learning_unit_year')
        self.entities = kwargs.pop('entities', [])
        self.is_faculty_manager = kwargs.pop('is_faculty_manager', False)

        self.title = _(self.component.get_type_display(
        )) + ' ' if self.component.type else self.component.acronym
        self.title_help = _(self.component.get_type_display()
                            ) + ' ' if self.component.type else ''
        self.title_help += self.component.acronym

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

        # Append dynamic fields
        entities_to_add = [
            entity for entity in REQUIREMENT_ENTITIES
            if entity in self.entities
        ]
        size_entities_to_add = len(entities_to_add)
        if size_entities_to_add > 1:
            self.fields["opening_brackets_entities_field"] = EmptyField(
                label='[')
        for i, key in enumerate(entities_to_add):
            entity = self.entities[key]
            if entity:
                self.fields["volume_" + key.lower()] = VolumeField(
                    label=entity.acronym,
                    help_text=entity.title,
                    widget=DecimalFormatInput(render_value=True),
                    required=False)
                if i != len(entities_to_add) - 1:
                    self.fields["add" + key.lower()] = EmptyField(label='+')
        if size_entities_to_add > 1:
            self.fields["closing_brackets_entities_field"] = EmptyField(
                label=']')

        if self.is_faculty_manager \
                and self.learning_unit_year.is_full() \
                and self.learning_unit_year.learning_container_year.container_type \
                in LCY_TYPES_WITH_FIXED_ACRONYM:
            self._disable_central_manager_fields()
Ejemplo n.º 4
0
class MailReminderRow(forms.Form):
    responsible = EmptyField(label='')
    learning_unit_years = EmptyField(label='')
    check = forms.BooleanField(required=False, label='')
    person_id = forms.IntegerField(widget=forms.HiddenInput(), required=False)

    def __init__(self, *args, **kwargs):
        self.person = kwargs.pop('person', None)
        self.learning_unit_years = kwargs.pop('learning_unit_years', [])
        super().__init__(*args, **kwargs)

        self.initial['check'] = True
        self.initial['responsible'] = self.person
        if self.person:
            self.initial['person_id'] = self.person.id
            self.fields["responsible"].label = "{}  {}".format(
                self.person.last_name, self.person.first_name)

        acronym_list = _get_acronyms_concatenation(self.learning_unit_years)
        self.initial['learning_unit_years'] = acronym_list
        self.fields["learning_unit_years"].label = acronym_list
        self.fields["responsible"].widget.attrs['class'] = 'no_label'
Ejemplo n.º 5
0
    def __init__(self, *args, **kwargs):
        self.component = kwargs.pop('component')
        self.learning_unit_year = kwargs.pop('learning_unit_year')
        self.entities = kwargs.pop('entities')
        self.is_faculty_manager = kwargs.pop('is_faculty_manager', False)

        self.title = self.component.acronym
        self.title_help = _(
            self.component.type) + ' ' if self.component.type else ''
        self.title_help += self.component.acronym

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

        # Append dynamic fields
        for key in ENTITY_TYPES_VOLUME:
            self._add_entity_fields(key)

        self.fields['equal_field_3'] = EmptyField(label='=')

        self.fields['volume_total_requirement_entities'] = VolumeField(
            label=_('vol_charge'), help_text=_('total_volume_charge'))

        if self.is_faculty_manager and self.learning_unit_year.is_full():
            self._disable_central_manager_fields()
Ejemplo n.º 6
0
class VolumeEditionForm(forms.Form):
    requirement_entity_key = 'volume_' + entity_types.REQUIREMENT_ENTITY.lower(
    )
    additional_requirement_entity_1_key = 'volume_' + entity_types.ADDITIONAL_REQUIREMENT_ENTITY_1.lower(
    )
    additional_requirement_entity_2_key = 'volume_' + entity_types.ADDITIONAL_REQUIREMENT_ENTITY_2.lower(
    )

    opening_brackets_field = EmptyField(label='[')
    opening_parenthesis_field = EmptyField(label='(')
    volume_q1 = VolumeField(
        label=_('Q1'),
        help_text=_('Volume Q1'),
        widget=DecimalFormatInput(render_value=True),
        required=False,
    )
    add_field = EmptyField(label='+')
    volume_q2 = VolumeField(
        label=_('Q2'),
        help_text=_('Volume Q2'),
        widget=DecimalFormatInput(render_value=True),
        required=False,
    )
    closing_parenthesis_field = EmptyField(label=')')
    equal_field_1 = EmptyField(label='=')
    volume_total = VolumeField(
        label=_('Vol. annual'),
        help_text=
        _('The annual volume must be equal to the sum of the volumes Q1 and Q2'
          ),
        widget=DecimalFormatInput(render_value=True),
        required=False,
    )
    help_volume_total = "{} = {} + {}".format(_('Volume total annual'),
                                              _('Volume Q1'), _('Volume Q2'))
    closing_brackets_field = EmptyField(label=']')
    mult_field = EmptyField(label='*')
    planned_classes = forms.IntegerField(label=_('Planned classes'),
                                         help_text=_('Planned classes'),
                                         min_value=0,
                                         widget=forms.TextInput(),
                                         required=False)
    equal_field_2 = EmptyField(label='=')

    _post_errors = []
    _parent_data = {}
    _faculty_manager_fields = ['volume_q1', 'volume_q2']

    def __init__(self, *args, **kwargs):
        self.component = kwargs.pop('component')
        self.learning_unit_year = kwargs.pop('learning_unit_year')
        self.entities = kwargs.pop('entities', [])
        self.is_faculty_manager = kwargs.pop('is_faculty_manager', False)

        self.title = _(self.component.get_type_display(
        )) + ' ' if self.component.type else self.component.acronym
        self.title_help = _(self.component.get_type_display()
                            ) + ' ' if self.component.type else ''
        self.title_help += self.component.acronym

        super().__init__(*args, **kwargs)
        help_volume_global = "{} = {} * {}".format(_('volume total global'),
                                                   _('Volume total annual'),
                                                   _('Planned classes'))

        # Append dynamic fields
        entities_to_add = [
            entity for entity in REQUIREMENT_ENTITIES
            if entity in self.entities
        ]
        size_entities_to_add = len(entities_to_add)
        if size_entities_to_add > 1:
            self.fields["opening_brackets_entities_field"] = EmptyField(
                label='[')
        for i, key in enumerate(entities_to_add):
            entity = self.entities[key]
            if entity:
                self.fields["volume_" + key.lower()] = VolumeField(
                    label=entity.acronym,
                    help_text=entity.title,
                    widget=DecimalFormatInput(render_value=True),
                    required=False)
                if i != len(entities_to_add) - 1:
                    self.fields["add" + key.lower()] = EmptyField(label='+')
        if size_entities_to_add > 1:
            self.fields["closing_brackets_entities_field"] = EmptyField(
                label=']')

        if self.is_faculty_manager \
                and self.learning_unit_year.is_full() \
                and self.learning_unit_year.learning_container_year.container_type \
                in LEARNING_CONTAINER_YEAR_TYPES_CANT_UPDATE_BY_FACULTY:
            self._disable_central_manager_fields()

    def _disable_central_manager_fields(self):
        for key, field in self.fields.items():
            if key not in self._faculty_manager_fields:
                field.disabled = True

    def clean(self):
        """
        Prevent faculty users to a volume to 0 if there was a value other than 0.
        Also, prevent the faculty user from putting a volume if its value was 0.
        """
        cleaned_data = super().clean()

        input_names = {
            'volume_q1':
            'volume_q1',
            'volume_q2':
            'volume_q2',
            'volume_total':
            'volume_total',
            'planned_classes':
            'planned_classes',
            'volume_requirement_entity':
            'volume_requirement_entity',
            'volume_additional_requirement_entity_1':
            'volume_additional_requirement_entity_1',
            'volume_additional_requirement_entity_2':
            'volume_additional_requirement_entity_2',
        }

        strategy = {
            True: CompleteVolumeEditionFacultyStrategy,
            False: VolumeEditionNoFacultyStrategy,
        }

        strategy[self.is_faculty_manager](self, input_names).is_valid()

        return cleaned_data

    def get_entity_fields(self):
        entity_keys = [
            self.requirement_entity_key,
            self.additional_requirement_entity_1_key,
            self.additional_requirement_entity_2_key
        ]
        return [self.fields[key] for key in entity_keys if key in self.fields]

    def save(self, postponement):
        if not self.changed_data:
            return None

        conflict_report = {}
        if postponement:
            conflict_report = edition.get_postponement_conflict_report(
                self.learning_unit_year)
            luy_to_update_list = conflict_report['luy_without_conflict']
        else:
            luy_to_update_list = [self.learning_unit_year]

        with transaction.atomic():
            for component in self._find_learning_components_year(
                    luy_to_update_list):
                self._save(component)

        # Show conflict error if exists
        check_postponement_conflict_report_errors(conflict_report)

    def _save(self, component):
        component.hourly_volume_total_annual = self.cleaned_data[
            'volume_total']
        component.hourly_volume_partial_q1 = self.cleaned_data['volume_q1']
        component.hourly_volume_partial_q2 = self.cleaned_data['volume_q2']
        component.planned_classes = self.cleaned_data['planned_classes']
        self._set_requirement_entities(component)
        return component.save()

    def _set_requirement_entities(self, component):
        updated_repartition_volumes = {}
        for entity_container_type in component.repartition_volumes.keys():
            repartition_volume = self.cleaned_data.get(
                'volume_' + entity_container_type.lower())
            updated_repartition_volumes[
                entity_container_type] = repartition_volume

        component.set_repartition_volumes(updated_repartition_volumes)

    def _find_learning_components_year(self, luy_to_update_list):
        return [
            lcy for lcy in LearningComponentYear.objects.filter(
                learning_unit_year__in=luy_to_update_list)
            if lcy.type == self.component.type
        ]
Ejemplo n.º 7
0
class SimplifiedVolumeForm(forms.ModelForm):
    _learning_unit_year = None

    add_field = EmptyField(label="+")
    equal_field = EmptyField(label='=')

    def __init__(self,
                 component_type,
                 index,
                 *args,
                 is_faculty_manager=False,
                 proposal=False,
                 **kwargs):
        component_type = component_type
        self.is_faculty_manager = is_faculty_manager
        self.index = index
        self.proposal = proposal
        super().__init__(*args, **kwargs)
        self.label = component_type[1]
        self.instance.type = component_type[0]
        self.instance.acronym = DEFAULT_ACRONYM_COMPONENT[self.instance.type]

    class Meta:
        model = LearningComponentYear
        fields = ('hourly_volume_total_annual', 'hourly_volume_partial_q1',
                  'hourly_volume_partial_q2', 'planned_classes',
                  'repartition_volume_requirement_entity',
                  'repartition_volume_additional_entity_1',
                  'repartition_volume_additional_entity_2')
        widgets = {
            'hourly_volume_total_annual':
            DecimalFormatInput(attrs={
                'title':
                _("The annual volume must be equal to the sum of the volumes Q1 and Q2"
                  )
            },
                               render_value=True),
            'hourly_volume_partial_q1':
            DecimalFormatInput(attrs={
                'title': _("Volume Q1"),
                'style': STYLE_MIN_WIDTH_VOLUME
            },
                               render_value=True),
            'hourly_volume_partial_q2':
            DecimalFormatInput(attrs={
                'title': _("Volume Q2"),
                'style': STYLE_MIN_WIDTH_VOLUME
            },
                               render_value=True),
            'planned_classes':
            forms.TextInput(attrs={'title': _("Planned classes")}),
            'repartition_volume_requirement_entity':
            DecimalFormatInput(attrs={'style': STYLE_MIN_WIDTH_VOLUME},
                               render_value=True),
            'repartition_volume_additional_entity_1':
            DecimalFormatInput(attrs={'style': STYLE_MIN_WIDTH_VOLUME},
                               render_value=True),
            'repartition_volume_additional_entity_2':
            DecimalFormatInput(attrs={'style': STYLE_MIN_WIDTH_VOLUME},
                               render_value=True),
        }

    def clean(self):
        """
        Prevent faculty users to a volume to 0 if there was a value other than 0.
        Also, prevent the faculty user from putting a volume if its value was 0.
        """
        cleaned_data = super().clean()

        input_names = {
            'volume_q1':
            'hourly_volume_partial_q1',
            'volume_q2':
            'hourly_volume_partial_q2',
            'volume_total':
            'hourly_volume_total_annual',
            'planned_classes':
            'planned_classes',
            'volume_requirement_entity':
            'repartition_volume_requirement_entity',
            'volume_additional_requirement_entity_1':
            'repartition_volume_additional_entity_1',
            'volume_additional_requirement_entity_2':
            'repartition_volume_additional_entity_2',
        }

        strategy = {
            True: {
                False: SimpleVolumeEditionFacultyStrategy,
                True: VolumeEditionNoFacultyStrategy
            },
            False: {
                False: VolumeEditionNoFacultyStrategy,
                True: VolumeEditionNoFacultyStrategy
            },
        }

        strategy[self.is_faculty_manager][self.proposal](
            self, input_names).is_valid()

        return cleaned_data

    def save(self, commit=True):
        if self.need_to_create_untyped_component():
            self.instance.acronym = DEFAULT_ACRONYM_COMPONENT[None]
            self.instance.type = None
            # In case of untyped component, we just need to create only 1 component (not more)
            if self.index != 0:
                return None

        self.instance.learning_unit_year = self._learning_unit_year
        self._assert_repartition_volumes_consistency()
        return super().save(commit)

    def _assert_repartition_volumes_consistency(self):
        """In case EntityContainer link is not set, need to reset repartition volumes to None."""
        container_year = self._learning_unit_year.learning_container_year
        existing_entity_container_types = {
            link_type
            for link_type, entity_id in
            container_year.get_map_entity_by_type().items() if entity_id
        }
        for entity_container_type in LearningComponentYear.repartition_volume_attrs_by_entity_container_type(
        ).keys():
            if entity_container_type not in existing_entity_container_types:
                self.instance.set_repartition_volume(entity_container_type,
                                                     None)

    def need_to_create_untyped_component(self):
        container_type = self._learning_unit_year.learning_container_year.container_type
        return container_type not in CONTAINER_TYPE_WITH_DEFAULT_COMPONENT
Ejemplo n.º 8
0
class VolumeEditionForm(forms.Form):

    requirement_entity_key = 'volume_' + entity_types.REQUIREMENT_ENTITY.lower(
    )
    additional_requirement_entity_1_key = 'volume_' + entity_types.ADDITIONAL_REQUIREMENT_ENTITY_1.lower(
    )
    additional_requirement_entity_2_key = 'volume_' + entity_types.ADDITIONAL_REQUIREMENT_ENTITY_2.lower(
    )

    volume_total = VolumeField(label=_('total_volume_voltot'),
                               help_text=_('total_volume'))
    equal_field_1 = EmptyField(label='=')
    volume_q1 = VolumeField(label=_('partial_volume_1Q'),
                            help_text=_('partial_volume_1'))
    add_field = EmptyField(label='+')
    volume_q2 = VolumeField(label=_('partial_volume_2Q'),
                            help_text=_('partial_volume_2'))
    mult_field = EmptyField(label='*')
    planned_classes = forms.IntegerField(label=_('planned_classes_pc'),
                                         help_text=_('planned_classes'),
                                         min_value=0)
    equal_field_2 = EmptyField(label='=')

    _post_errors = []
    _parent_data = {}
    _faculty_manager_fields = ['volume_q1', 'volume_q2']

    def __init__(self, *args, **kwargs):
        self.component = kwargs.pop('component')
        self.learning_unit_year = kwargs.pop('learning_unit_year')
        self.entities = kwargs.pop('entities')
        self.is_faculty_manager = kwargs.pop('is_faculty_manager', False)

        self.title = self.component.acronym
        self.title_help = _(
            self.component.type) + ' ' if self.component.type else ''
        self.title_help += self.component.acronym

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

        # Append dynamic fields
        for key in ENTITY_TYPES_VOLUME:
            self._add_entity_fields(key)

        self.fields['equal_field_3'] = EmptyField(label='=')

        self.fields['volume_total_requirement_entities'] = VolumeField(
            label=_('vol_charge'), help_text=_('total_volume_charge'))

        if self.is_faculty_manager and self.learning_unit_year.is_full():
            self._disable_central_manager_fields()

    def _disable_central_manager_fields(self):
        for key, field in self.fields.items():
            if key not in self._faculty_manager_fields:
                field.disabled = True

    def _add_entity_fields(self, key):
        if key in self.entities:
            entity = self.entities[key]
            self.fields["volume_" + key.lower()] = VolumeField(
                label=entity.acronym, help_text=entity.title)

    def clean(self):
        cleaned_data = super().clean().copy()

        self._check_tot_annual_equal_to_q1_q2(cleaned_data)
        self._check_tot_req_entities_equal_to_tot_annual_mult_cp(cleaned_data)
        self._check_tot_req_entities_equal_to_vol_req_entity(cleaned_data)

    def _check_tot_annual_equal_to_q1_q2(self, cleaned_data):
        total_annual = cleaned_data.get('volume_total', 0)
        q1 = cleaned_data.get('volume_q1', 0)
        q2 = cleaned_data.get('volume_q2', 0)

        if total_annual != (q1 + q2):
            self.add_error("volume_total", _('vol_tot_not_equal_to_q1_q2'))

    def _check_tot_req_entities_equal_to_vol_req_entity(self, cleaned_data):
        requirement_entity = cleaned_data.get(self.requirement_entity_key, 0)
        # Optional fields
        additional_requirement_entity_1 = cleaned_data.get(
            self.additional_requirement_entity_1_key, 0)
        additional_requirement_entity_2 = cleaned_data.get(
            self.additional_requirement_entity_2_key, 0)
        total = requirement_entity + additional_requirement_entity_1 + additional_requirement_entity_2

        if cleaned_data.get('volume_total_requirement_entities') != total:
            error_msg = ' + '.join([
                self.entities.get(t).acronym for t in ENTITY_TYPES_VOLUME
                if self.entities.get(t)
            ])
            error_msg += ' = {}'.format(_('vol_charge'))
            self.add_error("volume_total_requirement_entities", error_msg)

    def _check_tot_req_entities_equal_to_tot_annual_mult_cp(
            self, cleaned_data):
        total_annual = cleaned_data.get('volume_total', 0)
        cp = cleaned_data.get('planned_classes', 0)
        total_requirement_entities = cleaned_data.get(
            'volume_total_requirement_entities', 0)

        if total_requirement_entities != (total_annual * cp):
            self.add_error(
                'volume_total_requirement_entities',
                _('vol_tot_req_entities_not_equal_to_vol_tot_mult_cp'))

    def validate_parent_partim_component(self, parent_data):
        self._parent_data = parent_data

        self._compare_parent_partim('volume_total',
                                    'vol_tot_full_must_be_greater_than_partim',
                                    lower_or_equal=True)
        self._compare_parent_partim(
            'volume_q1', 'vol_q1_full_must_be_greater_or_equal_to_partim')
        self._compare_parent_partim(
            'volume_q2', 'vol_q2_full_must_be_greater_or_equal_to_partim')
        self._compare_parent_partim(
            'planned_classes',
            'planned_classes_full_must_be_greater_or_equal_to_partim')
        self._compare_parent_partim(
            self.requirement_entity_key,
            'entity_requirement_full_must_be_greater_or_equal_to_partim')
        self._compare_additional_entities(
            self.additional_requirement_entity_1_key)
        self._compare_additional_entities(
            self.additional_requirement_entity_2_key)

        return self.errors

    def _compare_additional_entities(self, key):
        # Verify if we have additional_requirement entity
        if key in self._parent_data and key in self.cleaned_data:
            self._compare_parent_partim(
                key,
                'entity_requirement_full_must_be_greater_or_equal_to_partim')

    def _compare_parent_partim(self, key, msg, lower_or_equal=False):
        partim_data = self.cleaned_data or self.initial
        condition = self._compare(self._parent_data[key], partim_data[key],
                                  lower_or_equal)

        if condition:
            self.add_error(key, _(msg))

    @staticmethod
    def _compare(value_parent, value_partim, lower_or_equal):
        if value_parent == 0 and value_partim == 0:
            condition = False
        elif lower_or_equal:
            condition = value_parent <= value_partim
        else:
            condition = value_parent < value_partim
        return condition

    def save(self, postponement):
        if not self.changed_data:
            return None

        conflict_report = {}
        if postponement:
            conflict_report = edition.get_postponement_conflict_report(
                self.learning_unit_year)
            luy_to_update_list = conflict_report['luy_without_conflict']
        else:
            luy_to_update_list = [self.learning_unit_year]

        with transaction.atomic():
            for component in self._find_learning_components_year(
                    luy_to_update_list):
                self._save(component)

        # Show conflict error if exists
        check_postponement_conflict_report_errors(conflict_report)

    def _save(self, component):
        component.hourly_volume_partial = self.cleaned_data['volume_q1']
        component.planned_classes = self.cleaned_data['planned_classes']
        component.save()
        self._save_requirement_entities(component.entity_components_year)

    def _save_requirement_entities(self, entity_components_year):
        for ecy in entity_components_year:
            link_type = ecy.entity_container_year.type
            repartition_volume = self.cleaned_data.get('volume_' +
                                                       link_type.lower())

            if repartition_volume is None:
                continue

            ecy.repartition_volume = repartition_volume
            ecy.save()

    def _find_learning_components_year(self, luy_to_update_list):
        prefetch = Prefetch('learning_component_year__entitycomponentyear_set',
                            queryset=EntityComponentYear.objects.all(),
                            to_attr='entity_components_year')
        return [
            luc.learning_component_year
            for luc in LearningUnitComponent.objects.filter(
                learning_unit_year__in=luy_to_update_list).prefetch_related(
                    prefetch)
            if luc.learning_component_year.type == self.component.type
        ]
Ejemplo n.º 9
0
class VolumeEditionForm(forms.Form):
    requirement_entity_key = 'volume_' + entity_types.REQUIREMENT_ENTITY.lower()
    additional_requirement_entity_1_key = 'volume_' + entity_types.ADDITIONAL_REQUIREMENT_ENTITY_1.lower()
    additional_requirement_entity_2_key = 'volume_' + entity_types.ADDITIONAL_REQUIREMENT_ENTITY_2.lower()

    opening_parenthesis_field = EmptyField(label='(')
    volume_q1 = VolumeField(
        label=_('Q1'),
        help_text=_('Volume Q1'),
        widget=StepHalfIntegerWidget(),
        required=False,
    )
    add_field = EmptyField(label='+')
    volume_q2 = VolumeField(
        label=_('Q2'),
        help_text=_('Volume Q2'),
        widget=StepHalfIntegerWidget(),
        required=False,
    )
    equal_field_1 = EmptyField(label='=')
    volume_total = VolumeField(
        label=_('Vol. annual'),
        help_text=_('The annual volume must be equal to the sum of the volumes Q1 and Q2'),
        widget=StepHalfIntegerWidget(),
        required=False,
    )
    help_volume_total = "{} = {} + {}".format(_('Volume total annual'), _('Volume Q1'), _('Volume Q2'))
    closing_parenthesis_field = EmptyField(label=')')
    mult_field = EmptyField(label='*')
    planned_classes = forms.IntegerField(label=_('P.C.'), help_text=_('Planned classes'), min_value=0)
    equal_field_2 = EmptyField(label='=')

    _post_errors = []
    _parent_data = {}
    _faculty_manager_fields = ['volume_q1', 'volume_q2']

    def __init__(self, *args, **kwargs):
        self.component = kwargs.pop('component')
        self.learning_unit_year = kwargs.pop('learning_unit_year')
        self.entities = kwargs.pop('entities', [])
        self.is_faculty_manager = kwargs.pop('is_faculty_manager', False)

        self.title = self.component.acronym
        self.title_help = _(self.component.type) + ' ' if self.component.type else ''
        self.title_help += self.component.acronym

        super().__init__(*args, **kwargs)
        help_volume_global = "{} = {} * {}".format(_('volume total global'),
                                                   _('Volume total annual'),
                                                   _('Planned classes'))

        # Append dynamic fields
        entities_to_add = [entity for entity in REQUIREMENT_ENTITIES if entity in self.entities]
        for i, key in enumerate(entities_to_add):
            entity = self.entities[key]
            self.fields["volume_" + key.lower()] = VolumeField(
                label=entity.acronym,
                help_text=entity.title,
                widget=StepHalfIntegerWidget(),
            )
            if i != len(entities_to_add) - 1:
                self.fields["add" + key.lower()] = EmptyField(label='+')

        if self.is_faculty_manager \
                and self.learning_unit_year.is_full() \
                and self.learning_unit_year.learning_container_year.container_type \
                in LEARNING_CONTAINER_YEAR_TYPES_CANT_UPDATE_BY_FACULTY:
            self._disable_central_manager_fields()

    def _disable_central_manager_fields(self):
        for key, field in self.fields.items():
            if key not in self._faculty_manager_fields:
                field.disabled = True

    def clean(self):
        """
        Prevent faculty users to a volume to 0 if there was a value other than 0.
        Also, prevent the faculty user from putting a volume if its value was 0.
        """
        cleaned_data = super().clean()

        volume_q1 = self.cleaned_data.get("volume_q1") or 0
        volume_q2 = self.cleaned_data.get("volume_q2") or 0
        volume_total = self.cleaned_data.get("volume_total") or 0

        if (self.cleaned_data.get("volume_q1") is not None or self.cleaned_data.get(
                "volume_q2") is not None) and volume_total != volume_q1 + volume_q2:
            self.add_error("volume_total", _('The annual volume must be equal to the sum of the volumes Q1 and Q2'))
            self.add_error("volume_q1", "")
            self.add_error("volume_q2", "")

        if self.is_faculty_manager:

            if 0 in [self.initial.get("volume_q1"), self.initial.get("volume_q2")]:
                if 0 not in [self.cleaned_data.get("volume_q1"), self.cleaned_data.get("volume_q2")]:
                    self.add_error("volume_q1", _("One of the partial volumes must have a value to 0."))
                    self.add_error("volume_q2", _("One of the partial volumes must have a value to 0."))

            else:
                if volume_q1 == 0:
                    self.add_error("volume_q1", _("The volume can not be set to 0."))
                if volume_q2 == 0:
                    self.add_error("volume_q2", _("The volume can not be set to 0."))

        return cleaned_data

    def get_entity_fields(self):
        entity_keys = [self.requirement_entity_key, self.additional_requirement_entity_1_key,
                       self.additional_requirement_entity_2_key]
        return [self.fields[key] for key in entity_keys if key in self.fields]

    def save(self, postponement):
        if not self.changed_data:
            return None

        conflict_report = {}
        if postponement:
            conflict_report = edition.get_postponement_conflict_report(self.learning_unit_year)
            luy_to_update_list = conflict_report['luy_without_conflict']
        else:
            luy_to_update_list = [self.learning_unit_year]

        with transaction.atomic():
            for component in self._find_learning_components_year(luy_to_update_list):
                self._save(component)

        # Show conflict error if exists
        check_postponement_conflict_report_errors(conflict_report)

    def _save(self, component):
        component.hourly_volume_total_annual = self.cleaned_data['volume_total']
        component.hourly_volume_partial_q1 = self.cleaned_data['volume_q1']
        component.hourly_volume_partial_q2 = self.cleaned_data['volume_q2']
        component.planned_classes = self.cleaned_data['planned_classes']
        component.save()
        self._save_requirement_entities(component.entity_components_year)

    def _save_requirement_entities(self, entity_components_year):
        for ecy in entity_components_year:
            link_type = ecy.entity_container_year.type
            repartition_volume = self.cleaned_data.get('volume_' + link_type.lower())

            if repartition_volume is None:
                continue

            ecy.repartition_volume = repartition_volume
            ecy.save()

    def _find_learning_components_year(self, luy_to_update_list):
        prefetch = Prefetch(
            'learning_component_year__entitycomponentyear_set',
            queryset=EntityComponentYear.objects.all(),
            to_attr='entity_components_year'
        )
        return [
            luc.learning_component_year
            for luc in LearningUnitComponent.objects.filter(
                learning_unit_year__in=luy_to_update_list).prefetch_related(prefetch)
            if luc.learning_component_year.type == self.component.type
        ]
Ejemplo n.º 10
0
class SimplifiedVolumeForm(forms.ModelForm):
    _learning_unit_year = None
    _entity_containers = []

    add_field = EmptyField(label="+")
    equal_field = EmptyField(label='=')

    def __init__(self, component_type, index, *args, is_faculty_manager=False, **kwargs):
        component_type = component_type
        self.is_faculty_manager = is_faculty_manager
        self.index = index
        super().__init__(*args, **kwargs)
        self.label = component_type[1]
        self.instance.type = component_type[0]
        self.instance.acronym = DEFAULT_ACRONYM_COMPONENT[self.instance.type]

    class Meta:
        model = LearningComponentYear
        fields = (
            'hourly_volume_total_annual',
            'hourly_volume_partial_q1',
            'hourly_volume_partial_q2'
        )
        widgets = {
            'hourly_volume_total_annual': StepHalfIntegerWidget,
            'hourly_volume_partial_q1': StepHalfIntegerWidget,
            'hourly_volume_partial_q2': StepHalfIntegerWidget,
        }

    def clean(self):
        """
        Prevent faculty users to a volume to 0 if there was a value other than 0.
        Also, prevent the faculty user from putting a volume if its value was 0.
        # FIXME Refactor this method with the clean of VolumeEditionForm
        """
        cleaned_data = super().clean()
        if self.is_faculty_manager:
            if 0 in [self.instance.hourly_volume_partial_q1, self.instance.hourly_volume_partial_q2]:
                if 0 not in [self.cleaned_data.get("hourly_volume_partial_q1"),
                             self.cleaned_data.get("hourly_volume_partial_q2")]:
                    self.add_error("hourly_volume_partial_q1", _("One of the partial volumes must have a value to 0."))
                    self.add_error("hourly_volume_partial_q2", _("One of the partial volumes must have a value to 0."))

            else:
                if self.cleaned_data.get("hourly_volume_partial_q1") == 0:
                    self.add_error("hourly_volume_partial_q1", _("The volume can not be set to 0."))
                if self.cleaned_data.get("hourly_volume_partial_q2") == 0:
                    self.add_error("hourly_volume_partial_q2", _("The volume can not be set to 0."))

        volume_q1 = self.cleaned_data.get("hourly_volume_partial_q1") or 0
        volume_q2 = self.cleaned_data.get("hourly_volume_partial_q2") or 0
        volume_total = self.cleaned_data.get("hourly_volume_total_annual") or 0

        if (self.cleaned_data.get("hourly_volume_partial_q1") is not None or self.cleaned_data.get(
                "hourly_volume_partial_q2") is not None) and volume_total != volume_q1 + volume_q2:
            self.add_error("hourly_volume_total_annual",
                           _('The annual volume must be equal to the sum of the volumes Q1 and Q2'))
            self.add_error("hourly_volume_partial_q1", "")
            self.add_error("hourly_volume_partial_q2", "")

        return cleaned_data

    def save(self, commit=True):
        if self.need_to_create_untyped_component():
            self.instance.acronym = DEFAULT_ACRONYM_COMPONENT[None]
            self.instance.type = None
            # In case of untyped component, we just need to create only 1 component (not more)
            if self.index != 0:
                return None
        return self._create_structure_components(commit)

    def need_to_create_untyped_component(self):
        container_type = self._learning_unit_year.learning_container_year.container_type
        return container_type not in CONTAINER_TYPE_WITH_DEFAULT_COMPONENT

    def _create_structure_components(self, commit):
        self.instance.learning_container_year = self._learning_unit_year.learning_container_year

        if self.instance.hourly_volume_total_annual is None or self.instance.hourly_volume_total_annual == 0:
            self.instance.planned_classes = 0
        else:
            self.instance.planned_classes = 1
        instance = super().save(commit)

        LearningUnitComponent.objects.update_or_create(
            learning_unit_year=self._learning_unit_year,
            learning_component_year=instance
        )

        requirement_entity_containers = self._get_requirement_entity_container()
        for requirement_entity_container in requirement_entity_containers:
            learning_unit_components = LearningUnitComponent.objects.filter(
                learning_unit_year__learning_container_year=self._learning_unit_year.learning_container_year
            )
            self._create_entity_component_years(learning_unit_components, requirement_entity_container)
        return instance

    @staticmethod
    def _create_entity_component_years(learning_unit_components, requirement_entity_container):
        for learning_unit_component in learning_unit_components:
            EntityComponentYear.objects.update_or_create(
                entity_container_year=requirement_entity_container,
                learning_component_year=learning_unit_component.learning_component_year
            )

    def _get_requirement_entity_container(self):
        requirement_entity_containers = []
        for entity_container_year in self._entity_containers:
            if entity_container_year and entity_container_year.type != entity_types.ALLOCATION_ENTITY:
                requirement_entity_containers.append(entity_container_year)
        return requirement_entity_containers
Ejemplo n.º 11
0
class VolumeEditionForm(forms.Form):

    requirement_entity_key = 'volume_' + entity_types.REQUIREMENT_ENTITY.lower(
    )
    additional_requirement_entity_1_key = 'volume_' + entity_types.ADDITIONAL_REQUIREMENT_ENTITY_1.lower(
    )
    additional_requirement_entity_2_key = 'volume_' + entity_types.ADDITIONAL_REQUIREMENT_ENTITY_2.lower(
    )

    opening_parenthesis_field = EmptyField(label='(')
    volume_q1 = VolumeField(
        label=_('partial_volume_1Q'),
        help_text=_('partial_volume_1'),
        widget=forms.NumberInput(attrs={'step': STEP_HALF_INTEGER}),
    )
    add_field = EmptyField(label='+')
    volume_q2 = VolumeField(
        label=_('partial_volume_2Q'),
        help_text=_('partial_volume_2'),
        widget=forms.NumberInput(attrs={'step': STEP_HALF_INTEGER}),
    )
    equal_field_1 = EmptyField(label='=')
    volume_total = VolumeField(
        label=_('Vol. annual'),
        help_text=
        _('The annual volume must be equal to the sum of the volumes Q1 and Q2'
          ),
        widget=forms.NumberInput(attrs={'step': STEP_HALF_INTEGER}),
    )
    help_volume_total = "{} = {} + {}".format(_('Volume total annual'),
                                              _('partial_volume_1'),
                                              _('partial_volume_2'))
    closing_parenthesis_field = EmptyField(label=')')
    mult_field = EmptyField(label='*')
    planned_classes = forms.IntegerField(label=_('planned_classes_pc'),
                                         help_text=_('planned_classes'),
                                         min_value=0)
    equal_field_2 = EmptyField(label='=')

    _post_errors = []
    _parent_data = {}
    _faculty_manager_fields = ['volume_q1', 'volume_q2']

    def __init__(self, *args, **kwargs):
        self.component = kwargs.pop('component')
        self.learning_unit_year = kwargs.pop('learning_unit_year')
        self.entities = kwargs.pop('entities')
        self.is_faculty_manager = kwargs.pop('is_faculty_manager', False)

        self.title = self.component.acronym
        self.title_help = _(
            self.component.type) + ' ' if self.component.type else ''
        self.title_help += self.component.acronym

        super().__init__(*args, **kwargs)
        help_volume_global = "{} = {} * {}".format(_('volume_global'),
                                                   _('Volume total annual'),
                                                   _('planned_classes'))

        # Append dynamic fields
        entities_to_add = [
            entity for entity in ENTITY_TYPES_VOLUME if entity in self.entities
        ]
        for i, key in enumerate(entities_to_add):
            entity = self.entities[key]
            self.fields["volume_" + key.lower()] = VolumeField(
                label=entity.acronym,
                help_text=entity.title,
                widget=forms.NumberInput(attrs={'step': STEP_HALF_INTEGER}),
            )
            if i != len(entities_to_add) - 1:
                self.fields["add" + key.lower()] = EmptyField(label='+')

        if self.is_faculty_manager \
                and self.learning_unit_year.is_full() \
                and self.learning_unit_year.learning_container_year.container_type \
                in LEARNING_CONTAINER_YEAR_TYPES_CANT_UPDATE_BY_FACULTY:
            self._disable_central_manager_fields()

    def _disable_central_manager_fields(self):
        for key, field in self.fields.items():
            if key not in self._faculty_manager_fields:
                field.disabled = True

    def get_entity_fields(self):
        entity_keys = [
            self.requirement_entity_key,
            self.additional_requirement_entity_1_key,
            self.additional_requirement_entity_2_key
        ]
        return [self.fields[key] for key in entity_keys if key in self.fields]

    def save(self, postponement):
        if not self.changed_data:
            return None

        conflict_report = {}
        if postponement:
            conflict_report = edition.get_postponement_conflict_report(
                self.learning_unit_year)
            luy_to_update_list = conflict_report['luy_without_conflict']
        else:
            luy_to_update_list = [self.learning_unit_year]

        with transaction.atomic():
            for component in self._find_learning_components_year(
                    luy_to_update_list):
                self._save(component)

        # Show conflict error if exists
        check_postponement_conflict_report_errors(conflict_report)

    def _save(self, component):
        component.hourly_volume_total_annual = self.cleaned_data[
            'volume_total']
        component.hourly_volume_partial_q1 = self.cleaned_data['volume_q1']
        component.hourly_volume_partial_q2 = self.cleaned_data['volume_q2']
        component.planned_classes = self.cleaned_data['planned_classes']
        component.save()
        self._save_requirement_entities(component.entity_components_year)

    def _save_requirement_entities(self, entity_components_year):
        for ecy in entity_components_year:
            link_type = ecy.entity_container_year.type
            repartition_volume = self.cleaned_data.get('volume_' +
                                                       link_type.lower())

            if repartition_volume is None:
                continue

            ecy.repartition_volume = repartition_volume
            ecy.save()

    def _find_learning_components_year(self, luy_to_update_list):
        prefetch = Prefetch('learning_component_year__entitycomponentyear_set',
                            queryset=EntityComponentYear.objects.all(),
                            to_attr='entity_components_year')
        return [
            luc.learning_component_year
            for luc in LearningUnitComponent.objects.filter(
                learning_unit_year__in=luy_to_update_list).prefetch_related(
                    prefetch)
            if luc.learning_component_year.type == self.component.type
        ]
Ejemplo n.º 12
0
class SimplifiedVolumeForm(forms.ModelForm):
    _learning_unit_year = None
    _entity_containers = []

    add_field = EmptyField(label="+")
    equal_field = EmptyField(label='=')

    def __init__(self, *args, **kwargs):
        self.component_type = kwargs.pop('component_type')
        super().__init__(*args, **kwargs)
        self.instance.type = self.component_type
        self.instance.acronym = DEFAULT_ACRONYM_COMPONENT[self.component_type]

    class Meta:
        model = LearningComponentYear
        fields = ('planned_classes', 'hourly_volume_total_annual',
                  'hourly_volume_partial_q1', 'hourly_volume_partial_q2')
        widgets = {
            'hourly_volume_total_annual':
            forms.NumberInput(attrs={'step': STEP_HALF_INTEGER}),
            'hourly_volume_partial_q1':
            forms.NumberInput(attrs={'step': STEP_HALF_INTEGER}),
            'hourly_volume_partial_q2':
            forms.NumberInput(attrs={'step': STEP_HALF_INTEGER}),
            'volume_declared_vacant':
            forms.NumberInput(attrs={'step': STEP_HALF_INTEGER}),
        }

    def save(self, commit=True):
        if self.need_to_create_untyped_component():
            self.instance.acronym = DEFAULT_ACRONYM_COMPONENT[None]
            self.instance.type = None
            # In case of untyped component, we just need to create only 1 component (not more)
            if not self.is_first_form_in_formset():
                return None
        return self._create_structure_components(commit)

    def need_to_create_untyped_component(self):
        container_type = self._learning_unit_year.learning_container_year.container_type
        return container_type not in CONTAINER_TYPE_WITH_DEFAULT_COMPONENT

    def is_first_form_in_formset(self):
        return self.prefix == "form-0"

    def _create_structure_components(self, commit):
        self.instance.learning_container_year = self._learning_unit_year.learning_container_year

        if self.instance.hourly_volume_total_annual is None or self.instance.hourly_volume_total_annual == 0:
            self.instance.planned_classes = 0
        else:
            self.instance.planned_classes = 1
        instance = super().save(commit)
        LearningUnitComponent.objects.get_or_create(
            learning_unit_year=self._learning_unit_year,
            learning_component_year=instance)
        requirement_entity_containers = self._get_requirement_entity_container(
        )
        for requirement_entity_container in requirement_entity_containers:
            if not self.instance.hourly_volume_total_annual and self.initial:
                self._get_initial_volume_data()
            learning_unit_components = LearningUnitComponent.objects.filter(
                learning_unit_year__learning_container_year=self.
                _learning_unit_year.learning_container_year)
            self._create_entity_component_years(learning_unit_components,
                                                requirement_entity_container)
        return instance

    def _create_entity_component_years(self, learning_unit_components,
                                       requirement_entity_container):
        for learning_unit_component in learning_unit_components:
            EntityComponentYear.objects.get_or_create(
                entity_container_year=requirement_entity_container,
                learning_component_year=learning_unit_component.
                learning_component_year)

    def _get_initial_volume_data(self):
        self.instance.hourly_volume_total_annual = self.initial.get(
            'hourly_volume_total_annual')
        self.instance.hourly_volume_partial_q1 = self.initial.get(
            'hourly_volume_partial_q1')
        self.instance.hourly_volume_partial_q2 = self.initial.get(
            'hourly_volume_partial_q2')
        self.instance.save()

    def _get_requirement_entity_container(self):
        requirement_entity_containers = []
        for entity_container_year in self._entity_containers:
            if entity_container_year and entity_container_year.type != entity_types.ALLOCATION_ENTITY:
                requirement_entity_containers.append(entity_container_year)
        return requirement_entity_containers