def others_edit_view(request, model_name, **kwargs):

    perm = getattr(get_user_profile(request.user), model_name + '_permission') or request.user.is_superuser
    form_class = crispy_form_factory(model=model_name_dict[model_name],
                                     widgets=widgets_dict[model_name],
                                     disabled=[],
                                     exclude=[],
                                     )

    if request.method == 'GET':
        edit_form = form_class(instance=get_object_or_404(model_name_dict[model_name], id=kwargs['id']))
        request_context = csrf(request)
        form_html = render_crispy_form(edit_form, context=request_context)
        return HttpResponse(json.dumps({'form_html': form_html}))

    if request.method == 'POST':
        if perm:
            edit_form = form_class(request.POST, instance=get_object_or_404(model_name_dict[model_name],
                                                                            id=kwargs['id']))
            if edit_form.is_valid():
                edit_form.save()
                return HttpResponse(json.dumps({'success': True}))
            else:
                request_context = csrf(request)
                form_html = render_crispy_form(edit_form, context=request_context)
                return HttpResponse(json.dumps({'success': False, 'permission': True, 'form_html': form_html}))
        else:
            return HttpResponse(json.dumps({'success': False, 'permission': False}))
def others_add_view(request, model_name):

    # this view is for non-leveled model

    perm = getattr(get_user_profile(request.user), model_name + '_permission') or request.user.is_superuser
    form_class = crispy_form_factory(model=model_name_dict[model_name],
                                     widgets=widgets_dict[model_name],
                                     disabled=[],
                                     exclude=[],
                                     )
    if request.method == 'GET':
        add_form = form_class()
        request_context = csrf(request)
        form_html = render_crispy_form(add_form, context=request_context)
        return HttpResponse(json.dumps({'form_html': form_html}))

    if request.method == 'POST':
        if perm:
            add_form = form_class(request.POST)
            if add_form.is_valid():
                add_form.save()
                return HttpResponse(json.dumps({'success': True}))
            else:
                request_context = csrf(request)
                form_html = render_crispy_form(add_form, context=request_context)
                return HttpResponse(json.dumps({'success': False, 'permission': True, 'form_html': form_html}))
        else:
            return HttpResponse(json.dumps({'success': False, 'permission': False}))
def schedule_view(request, **kwargs):
    objs_and_perm = get_objs_and_perm(request.user, **kwargs)
    profile = get_user_profile(request.user)
    if objs_and_perm['perm']:
        query_set = Schedule.objects.filter(program=objs_and_perm['program'])
    else:
        query_set = profile.schedule_permission.filter(program=objs_and_perm['program'])
    context = update_context(query_set, objs_and_perm['perm'], **kwargs)
    return render(request, "records_schedule.html", context)
def program_view(request, **kwargs):
    objs_and_perm = get_objs_and_perm(request.user, **kwargs)
    profile = get_user_profile(request.user)
    if objs_and_perm['perm']:
        query_set = Program.objects.filter(zone=objs_and_perm['zone'])
    else:
        query_set = Program.objects.filter(
            Q(id__in=profile.program_permission.filter(zone=objs_and_perm['zone']).values('id')) |
            Q(schedule__in=profile.schedule_permission.filter(program__zone=objs_and_perm['zone']))
        ).distinct()
    context = update_context(query_set, objs_and_perm['perm'], **kwargs)
    return render(request, "records_program.html", context)
def get_objs_and_perm(user, **kwargs):
    # this function is to find the users permission for current page
    # given following record architecture
    # zone1-program1-schedule1
    # if a user has permission of program1 he will be able to see zone1 in zone page,
    # he is also able to see program1 in program page, however he doesnt have permission to edit zone1 or program1
    # but he is able to edit schedule1 in schedule page,
    # if zone1 has another program called program2, he is not able to see it.

    res_map = {}
    perm = user.is_superuser
    profile = get_user_profile(user)

    # depending the page user is requesting, we will have a list of obj as argument

    if 'zone_name' in kwargs:
        # user is requesting program page
        zone_name = unquote(kwargs['zone_name'])
        zone = Zone.objects.get(name=zone_name)
        perm = perm or profile.zone_permission.filter(id=zone.id).exists()
        res_map.update({'zone': zone})
        if 'program_name' in kwargs:
            # user is requesting schedule page
            program_name = unquote(kwargs['program_name'])
            program = Program.objects.get(name=program_name, zone=zone)
            perm = perm or profile.program_permission.filter(id=program.id).exists()
            res_map.update({'program': program})
            if 'session_name' in kwargs:
                # user is requesting enrollment page or canceled_date page
                session_name = unquote(kwargs['session_name'])
                schedule = Schedule.objects.get(program=program, session__name=session_name)
                perm = perm or profile.schedule_permission.filter(id=schedule.id).exists()
                res_map.update({'schedule': schedule})
                if 'student_id' in kwargs:
                    student_id = kwargs['student_id']
                    enrollment = get_object_or_404(Enrollment, schedule=schedule, student__id=student_id)
                    res_map.update({'enrollment': enrollment})
                if 'canceled_date' in kwargs:
                    canceled_date = kwargs['canceled_date']
                    canceled_date = get_object_or_404(CanceledDate, schedule=schedule, date=canceled_date)
                    res_map.update({'canceled_date': canceled_date})

    # we return a dict of objects representing this page. i.e. user is requesting a schedule page,
    # we will return the zone and program of these schedules we are about to show

    res_map.update({'perm': perm})
    return res_map
def others_delete_view(request, model_name, **kwargs):

    perm = getattr(get_user_profile(request.user), model_name + '_permission') or request.user.is_superuser
    obj = get_object_or_404(model_name_dict[model_name], id=kwargs['id'])
    if request.method == 'GET':
        delete_form = DeleteForm()
        request_context = csrf(request)
        form_html = render_crispy_form(delete_form, context=request_context)
        return HttpResponse(json.dumps({'form_html': "<p>You are going to delete following record: <strong>" +
                                                     str(obj) + "</strong></p>" + form_html}))
    if request.method == 'POST':
        if perm:
            delete_form = DeleteForm(request.POST)
            if delete_form.is_valid():
                obj.delete()
                return HttpResponse(json.dumps({'success': True, 'permission': True}))
        else:
            return HttpResponse(json.dumps({'success': False, 'permission': False}))
def partner_view(request, **kwargs):
    profile = get_user_profile(request.user)
    perm = profile.partner_permission or request.user.is_superuser
    query_set = Partner.objects.all()
    return render(request, "records_partner.html", {'perm': perm, 'query_set': query_set})