• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

chiefonboarding / ChiefOnboarding / 18481185920

13 Oct 2025 11:53PM UTC coverage: 89.613% (-0.006%) from 89.619%
18481185920

Pull #572

github

web-flow
Merge f5b8970dc into f01e5ecbf
Pull Request #572: Add permissions based on department

7057 of 7875 relevant lines covered (89.61%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.31
back/admin/resources/forms.py
1
from crispy_forms.helper import FormHelper
1✔
2
from crispy_forms.layout import HTML, Div, Field, Layout
1✔
3
from django import forms
1✔
4
from django.db import transaction
1✔
5
from django.utils.translation import gettext_lazy as _
1✔
6

7
from admin.templates.forms import (
1✔
8
    FieldWithExtraContext,
9
    ModelChoiceFieldWithCreate,
10
    MultiSelectField,
11
    TagModelForm,
12
)
13
from misc.mixins import FilterDepartmentsFieldByUserMixin
1✔
14

15
from .models import Category, Chapter, Resource
1✔
16
from .serializers import ChapterSerializer
1✔
17

18

19
class ChapterField(FieldWithExtraContext):
1✔
20
    template = "chapter_field.html"
1✔
21

22

23
class ResourceForm(FilterDepartmentsFieldByUserMixin, TagModelForm):
1✔
24
    category = ModelChoiceFieldWithCreate(
1✔
25
        label=_("Category"),
26
        queryset=Category.objects.all(),
27
        to_field_name="name",
28
        required=False,
29
    )
30
    counter = 0
1✔
31

32
    def _create_or_update_chapter(self, resource, parent, chapter):
1✔
33
        if isinstance(chapter["id"], int):
1✔
34
            chap = Chapter.objects.get(id=chapter["id"])
1✔
35
            chap.name = chapter["name"]
1✔
36
            chap.content = chapter["content"]
1✔
37
            chap.resource = resource
1✔
38
            chap.order = self.counter
1✔
39
            chap.save()
1✔
40
        else:
41
            chap = Chapter.objects.create(
1✔
42
                resource=resource,
43
                name=chapter["name"],
44
                content=chapter["content"],
45
                type=chapter["type"],
46
                order=self.counter,
47
            )
48
            if parent is not None:
1✔
49
                chap.parent_chapter = Chapter.objects.get(id=parent)
1✔
50
                chap.save()
1✔
51
        self.counter += 1
1✔
52

53
        # Return new/updated item id
54
        return chap.id
1✔
55

56
    def _get_child_chapters(self, resource, parent, children):
1✔
57
        if len(children) == 0:
1✔
58
            return
1✔
59

60
        for chapter in children:
1✔
61
            # Save or update item
62
            parent_id = self._create_or_update_chapter(resource, parent, chapter)
1✔
63

64
            # Go one level deeper - check and create chapters
65
            self._get_child_chapters(resource, parent_id, chapter["children"])
1✔
66

67
    def __init__(self, *args, **kwargs):
1✔
68
        super(ResourceForm, self).__init__(*args, **kwargs)
1✔
69
        self.fields["chapters"] = forms.JSONField()
1✔
70
        self.helper = FormHelper()
1✔
71
        self.helper.form_tag = False
1✔
72
        none_class = "d-none"
1✔
73
        if (self.instance is not None and self.instance.course) or (
1✔
74
            "course" in self.data and self.data["course"] == "on"
75
        ):
76
            none_class = ""
×
77

78
        if self.instance.pk is None:
1✔
79
            chapters = []
1✔
80
        else:
81
            chapters = ChapterSerializer(
1✔
82
                self.instance.chapters.filter(parent_chapter__isnull=True),
83
                many=True,
84
            ).data
85

86
        self.helper.layout = Layout(
1✔
87
            Div(
88
                Div(
89
                    Field("name"),
90
                    css_class="col-6",
91
                ),
92
                Div(
93
                    MultiSelectField("departments"),
94
                    css_class="col-3",
95
                ),
96
                Div(
97
                    MultiSelectField("tags"),
98
                    css_class="col-3",
99
                ),
100
                css_class="row",
101
            ),
102
            Div(
103
                Div(
104
                    Field("category", css_class="add"),
105
                    HTML(
106
                        "<small style='top: -11px; position: relative;'>"
107
                        + _(
108
                            "Do not use only numbers as a category. Always add some "
109
                            "text."
110
                        )
111
                        + "</small>"
112
                    ),
113
                    css_class="col-6",
114
                ),
115
                Div(
116
                    Field("course"),
117
                    css_class="col-2",
118
                ),
119
                Div(
120
                    Field("on_day"),
121
                    css_class="col-2 " + none_class,
122
                ),
123
                Div(
124
                    Field("remove_on_complete"),
125
                    css_class="col-2 " + none_class,
126
                ),
127
                css_class="row",
128
            ),
129
            Div(
130
                Div(
131
                    ChapterField(
132
                        "chapters",
133
                        extra_context={"chapters": chapters},
134
                    ),
135
                    css_class="col-12",
136
                ),
137
            ),
138
        )
139

140
    class Meta:
1✔
141
        model = Resource
1✔
142
        fields = (
1✔
143
            "name",
144
            "tags",
145
            "category",
146
            "course",
147
            "on_day",
148
            "remove_on_complete",
149
            "departments",
150
        )
151
        help_texts = {
1✔
152
            "course": _("When enabled, new hires will have to walk through this"),
153
            "remove_on_complete": _(
154
                "If disabled, it will turn into a normal resource after completing"
155
            ),
156
        }
157

158
    @transaction.atomic
1✔
159
    def save(self, commit=True):
1✔
160
        chapters = self.cleaned_data.pop("chapters", [])
1✔
161
        instance = super(ResourceForm, self).save(commit=commit)
1✔
162

163
        Chapter.objects.filter(resource=instance).update(resource=None)
1✔
164
        # Root chapters
165
        for chapter in chapters:
1✔
166
            parent_id = self._create_or_update_chapter(instance, None, chapter)
1✔
167

168
            self._get_child_chapters(instance, parent_id, chapter["children"])
1✔
169
        return instance
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc