def save_custom_template(request):
    program = Program.objects.get(id=request.data['program_id'])
    role = request.user.tola_user.program_role(program.id)
    if request.user.is_anonymous or role != 'high':
        return HttpResponseRedirect('/')
    if not request.data['tiers']:
        LevelTierTemplate.objects.filter(program=program).delete()
        return JsonResponse({'message': 'update successful'}, status=200)

    try:
        # Replace both the template and the program-associated level tiers, since there is only
        # one form and it does both.  May need to split this later if custom template creation and
        # tierset saving is split.
        with transaction.atomic():
            LevelTierTemplate.objects.filter(program=program).delete()
            LevelTierTemplate.objects.create(program=program,
                                             names=request.data['tiers'])

    except Exception:
        logger.exception("Trouble in RF template paradise")
        return JsonResponse(
            {'message': _('Your request could not be processed.')}, status=400)

    new_template = LevelTierTemplateSerializer(
        LevelTierTemplate.objects.filter(program=program), many=True)
    return JsonResponse(new_template.data, safe=False)
    def get(self, request, *args, **kwargs):
        # TODO:  put in a try block
        program = Program.objects.prefetch_related('level_tiers').get(
            pk=int(self.kwargs['program_id']))
        role = request.user.tola_user.program_role(program.id)

        if not role or (role in ['low', 'medium']
                        and program.level_tiers.count() == 0):
            return HttpResponseRedirect('/')

        tiers = LevelTier.objects.filter(program=program)
        try:
            custom_tiers = LevelTierTemplate.objects.get(program=program)
        except LevelTierTemplate.DoesNotExist:
            custom_tiers = None
        levels = Level.objects.filter(program=program)
        # All indicators associated with the program should be passed to the front-end, not just the ones
        # associated with the rf levels.  The front-end uses the overall count to determine whether
        # the program name in the header should be plain text or a link.
        indicators = Indicator.objects.filter(program=program,
                                              deleted__isnull=True)

        translated_templates = json.dumps(LevelTier.get_templates(),
                                          cls=LazyEncoder)
        old_lang = translation.get_language()
        translation.activate('en')
        untranslated_templates = json.dumps(LevelTier.get_templates(),
                                            cls=LazyEncoder)
        translation.activate(old_lang)
        js_context = {
            'program':
            ResultsFrameworkProgramSerializer(program).data,
            'levels':
            LevelSerializer(levels, many=True).data,
            'indicators':
            IndicatorSerializerMinimal(indicators, many=True).data,
            'levelTiers':
            LevelTierSerializer(tiers, many=True).data,
            'tierTemplates':
            translated_templates,
            'englishTemplates':
            untranslated_templates,
            'customTemplates':
            LevelTierTemplateSerializer(custom_tiers).data,
            'programObjectives':
            ProgramObjectiveSerializer(program.objective_set.all(),
                                       many=True).data,
            'accessLevel':
            role,
            'usingResultsFramework':
            program.results_framework,
        }

        context_data = {
            'program': program,
            'indicator_count': indicators.count(),
            'js_context': js_context,
        }
        return render(request, self.template_name, context_data)
def save_custom_tiers(request):
    program = Program.objects.get(id=request.data['program_id'])
    role = request.user.tola_user.program_role(program.id)
    if request.user.is_anonymous or role != 'high':
        return HttpResponseRedirect('/')
    try:
        # Replace both the template and the program-associated level tiers, since there is only
        # one form and it does both.  May need to split this later if custom template creation and
        # tierset saving is split.
        with transaction.atomic():
            LevelTierTemplate.objects.filter(program=program).delete()
            LevelTier.objects.filter(program=program).delete()

            tier_count = len(request.data['tiers'])
            if tier_count != len(set(request.data['tiers'])):
                raise NotImplementedError(
                    _("Result levels must have unique names."))

            if Level.objects.filter(level_depth=tier_count) > 0:
                raise NotImplementedError(
                    _("This level is being used in the results framework."))

            for n, template_tier in enumerate(request.data['tiers']):
                if not template_tier:
                    # Translators:  This is a warning message when users have left an input field blank.
                    raise NotImplementedError(
                        _("Level names should not be blank"))

                LevelTier.objects.create(program=program,
                                         tier_depth=n + 1,
                                         name=template_tier)
            LevelTierTemplate.objects.create(program=program,
                                             names=request.data['tiers'])

    except NotImplementedError as e:
        logger.exception("Trouble in RF Tier saving paradise")
        return JsonResponse({'message': e.message}, status=400)
    except Exception as e:
        logger.exception("Trouble in RF Tier saving paradise")
        return JsonResponse(
            {'message': _('Your request could not be processed.')}, status=400)

    new_template = LevelTierTemplateSerializer(
        LevelTierTemplate.objects.filter(program=program), many=True)
    return JsonResponse(new_template.data, safe=False)