def insert_new_level(request): level_data = copy.copy(request.data) program = Program.objects.get(id=request.data['program']) role = request.user.tola_user.program_role(program.id) if request.user.is_anonymous or role != 'high': return HttpResponseRedirect('/') # Update new Level data in preparation for saving if request.data['parent'] == "root": parent = None else: parent = Level.objects.get(id=request.data['parent']) level_data['parent'] = parent level_data['program'] = program if 'ontology' in request.data: del level_data['ontology'] del level_data['level_depth'] # First update the customsort values of all Levels that getting pushed down by the new Level. # No need to do it if the top tier level is being saved if request.data['parent'] != "root": levels_to_shift = Level.objects\ .filter(program=program, parent_id=parent.id, customsort__gte=request.data['customsort'])\ .order_by('-customsort') for s_level in levels_to_shift: s_level.customsort += 1 s_level.save() new_level = Level(**level_data) try: new_level.full_clean() except ValidationError as e: return Response(e.message_dict, status=400) # Now the new level can be saved new_level.save() # Return all Levels for the program. There shouldn't be so much that it slows things down much. # Also return the newly created Level. all_data = LevelSerializer(Level.objects.filter(program=program), many=True).data return Response({ 'all_data': all_data, 'new_level': LevelSerializer(new_level).data })
def create_levels(program_id, level_data): fixture_data = deepcopy(level_data) tier_labels = LevelTier.get_templates()['mc_standard']['tiers'] for i, tier in enumerate(tier_labels): t = LevelTier(name=tier, tier_depth=i+1, program_id=program_id) t.save() level_map = {} for level_fix in fixture_data: parent = None if 'parent_id' in level_fix['fields']: parent = level_map[level_fix['fields'].pop('parent_id')] level = Level(**level_fix['fields']) level.parent = parent level.program = Program.objects.get(id=program_id) level.save() level_map[level_fix['pk']] = level
def __init__(self, *args, **kwargs): indicator = kwargs.get('instance', None) self.request = kwargs.pop('request') if indicator and not indicator.unit_of_measure_type: kwargs['initial'][ 'unit_of_measure_type'] = Indicator.UNIT_OF_MEASURE_TYPES[0][0] if indicator and indicator.lop_target: lop_stripped = str(indicator.lop_target) lop_stripped = lop_stripped.rstrip('0').rstrip( '.') if '.' in lop_stripped else lop_stripped kwargs['initial']['lop_target'] = lop_stripped self.programval = kwargs.pop('program') self.prefilled_level = kwargs.pop( 'level') if 'level' in kwargs else False super(IndicatorForm, self).__init__(*args, **kwargs) # program_display here is to display the program without interfering in the logic that # assigns a program to an indicator (and doesn't update it) - but it looks like other fields self.fields['program_display'] = forms.ChoiceField( choices=[ ('', self.programval.name), ], required=False, ) self.fields['program_display'].disabled = True self.fields['program_display'].label = _('Program') # level is here the new "result level" (RF) level option (FK to model Level) # Translators: This is a form field label that allows users to select which Level object to associate with the Result that's being entered into the form self.fields['level'].label = _('Result level') self.fields['level'].label_from_instance = lambda obj: obj.display_name # in cases where the user was sent here via CREATE from the RF BUILDER screen: if self.prefilled_level: # prefill level with only the level they clicked "add indicator" from: self.fields['level'].queryset = Level.objects.filter( pk=self.prefilled_level) self.fields['level'].initial = self.prefilled_level # do not allow the user to update (it is being "added to" that level) self.fields['level'].disabled = True else: # populate with all levels for the indicator's program: # self.fields['level'].queryset = Level.objects.filter(program_id=self.programval) self.fields['level'].choices = [('', '------')] + \ [(l.id, l.display_name) for l in Level.sort_by_ontology(Level.objects.filter(program_id=self.programval))] if self.programval.results_framework and not self.programval.manual_numbering: # in this (the default) case, the number field is removed (values not updated): self.fields.pop('number') elif self.programval.results_framework: # in this case the number field gets this special help text (added as a popover): self.fields['number'].label = _('Display number') # Translators: a "number" in this context is a kind of label. This is help text to explain why a user is seeing customized numbers instead of auto-generated ones that can derived from the indicator's place in the hierarchy self.fields['number'].help_text = _( "This number is displayed in place of the indicator number automatically generated through the results framework. An admin can turn on auto-numbering in program settings" ) if self.programval.results_framework: # no need to update the old_level field if they are using the results framework: self.fields.pop('old_level') self.fields['level'].required = True else: # pre-migration to RF, all fields remain unchanged in this regard (still required): self.fields['old_level'].required = True # Translators: Indicator objects are assigned to Levels, which are in a hierarchy. We recently changed how we organize Levels. This is a field label for the indicator-associated Level in the old level system self.fields['old_level'].label = _('Old indicator level') # Translators: We recently changed how we organize Levels. The new system is called the "results framework". This is help text for users to let them know that they can use the new system now. self.fields['old_level'].help_text = _( "Indicators are currently grouped by an older version of indicator levels. To group indicators according to the results framework, an admin will need to adjust program settings." ) if not self.request.has_write_access: for name, field in self.fields.items(): field.disabled = True countries = getCountry(self.request.user) self.fields['disaggregation'].queryset = DisaggregationType.objects\ .filter(country__in=countries, standard=False) if self.programval._using_results_framework == Program.NOT_MIGRATED and Objective.objects.filter( program_id=self.programval.id).exists(): self.fields['objectives'].queryset = Objective.objects.filter( program__id__in=[self.programval.id]) else: self.fields.pop('objectives') self.fields[ 'strategic_objectives'].queryset = StrategicObjective.objects.filter( country__in=countries) self.fields['approved_by'].queryset = TolaUser.objects.filter( country__in=countries).distinct() self.fields[ 'approval_submitted_by'].queryset = TolaUser.objects.filter( country__in=countries).distinct() self.fields['name'].label = _('Indicator') self.fields['name'].required = True self.fields['name'].widget = forms.Textarea(attrs={'rows': 3}) self.fields['unit_of_measure'].required = True self.fields['target_frequency'].required = True # self.fields['is_cumulative'].widget = forms.RadioSelect() if self.instance.target_frequency and self.instance.target_frequency != Indicator.LOP: self.fields['target_frequency'].widget.attrs['readonly'] = True