netbos 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. netbos-0.0.1/LICENSE.txt +17 -0
  2. netbos-0.0.1/PKG-INFO +43 -0
  3. netbos-0.0.1/README.md +21 -0
  4. netbos-0.0.1/__init__.py +1 -0
  5. netbos-0.0.1/api/__init__.py +1 -0
  6. netbos-0.0.1/api/serializers.py +95 -0
  7. netbos-0.0.1/api/urls.py +24 -0
  8. netbos-0.0.1/api/views.py +71 -0
  9. netbos-0.0.1/filtersets.py +81 -0
  10. netbos-0.0.1/forms.py +218 -0
  11. netbos-0.0.1/graphql.py +0 -0
  12. netbos-0.0.1/jobs.py +0 -0
  13. netbos-0.0.1/middleware.py +0 -0
  14. netbos-0.0.1/migrations/0001_initial.py +291 -0
  15. netbos-0.0.1/migrations/0002_alter_alarmloop_organisation_alter_gssi_organisation_and_more.py +119 -0
  16. netbos-0.0.1/migrations/0003_alarmloop_comments_firmwareversion_comments_and_more.py +114 -0
  17. netbos-0.0.1/migrations/0004_radiodevice_contact.py +27 -0
  18. netbos-0.0.1/migrations/0005_remove_radiodevice_issi_remove_organisation_address_and_more.py +92 -0
  19. netbos-0.0.1/migrations/0006_alter_radiodevice_tei.py +18 -0
  20. netbos-0.0.1/migrations/0007_alter_radiodevice_tei_alter_sika_issi.py +23 -0
  21. netbos-0.0.1/migrations/0008_repair_sika_schema.py +60 -0
  22. netbos-0.0.1/migrations/0009_remove_organisation_tags_and_more.py +111 -0
  23. netbos-0.0.1/migrations/0010_repair_radiodevice_schema.py +62 -0
  24. netbos-0.0.1/migrations/0011_alter_radiodevice_owner_vehicletype.py +44 -0
  25. netbos-0.0.1/migrations/0012_alter_vehicle_vehicle_type.py +73 -0
  26. netbos-0.0.1/migrations/0013_sync_vehicle_location_field.py +26 -0
  27. netbos-0.0.1/migrations/0014_remove_vehicle_location.py +25 -0
  28. netbos-0.0.1/migrations/0015_alter_pager_options_remove_pager_manufacturer_and_more.py +78 -0
  29. netbos-0.0.1/migrations/0016_alter_sika_options.py +17 -0
  30. netbos-0.0.1/migrations/0017_alter_pager_tei_alter_radiodevice_tei.py +23 -0
  31. netbos-0.0.1/migrations/0018_remove_ric_loops_remove_gssi_tags_remove_ric_tags_and_more.py +91 -0
  32. netbos-0.0.1/migrations/0019_group_tags.py +20 -0
  33. netbos-0.0.1/migrations/0020_firmwareversion_cutoff_date_and_more.py +28 -0
  34. netbos-0.0.1/migrations/0021_alter_sika_issi.py +19 -0
  35. netbos-0.0.1/migrations/0022_battery_pager_battery_radiodevice_battery.py +53 -0
  36. netbos-0.0.1/migrations/0023_alter_battery_production_week.py +19 -0
  37. netbos-0.0.1/migrations/0024_remove_pager_battery_remove_radiodevice_battery_and_more.py +57 -0
  38. netbos-0.0.1/migrations/0025_battery_status.py +18 -0
  39. netbos-0.0.1/migrations/0026_pager_vehicle.py +19 -0
  40. netbos-0.0.1/migrations/0027_vehicle_name_alter_vehicle_callsign_and_more.py +44 -0
  41. netbos-0.0.1/migrations/0028_alter_vehicle_options_sika_funkrufname_berechtigung_and_more.py +51 -0
  42. netbos-0.0.1/migrations/0029_sika_funkrufname_tel_alter_sika_funkrufname.py +23 -0
  43. netbos-0.0.1/migrations/0030_radiodevice_gateway_radiodevice_repeater.py +23 -0
  44. netbos-0.0.1/migrations/0031_remove_radiodevice_gateway_and_more.py +21 -0
  45. netbos-0.0.1/migrations/0032_radiooption_radiodevice_radio_options.py +51 -0
  46. netbos-0.0.1/migrations/0033_alter_radiodevice_radio_options_delete_radiooption.py +22 -0
  47. netbos-0.0.1/migrations/0034_seed_radio_option_tags.py +36 -0
  48. netbos-0.0.1/migrations/0035_rename_radio_options_radiodevice_licence.py +18 -0
  49. netbos-0.0.1/migrations/__init__.py +0 -0
  50. netbos-0.0.1/models.py +599 -0
  51. netbos-0.0.1/navigation.py +98 -0
  52. netbos-0.0.1/netbos.egg-info/PKG-INFO +43 -0
  53. netbos-0.0.1/netbos.egg-info/SOURCES.txt +107 -0
  54. netbos-0.0.1/netbos.egg-info/dependency_links.txt +1 -0
  55. netbos-0.0.1/netbos.egg-info/top_level.txt +1 -0
  56. netbos-0.0.1/plugin.py +17 -0
  57. netbos-0.0.1/pyproject.toml +46 -0
  58. netbos-0.0.1/setup.cfg +4 -0
  59. netbos-0.0.1/signals.py +0 -0
  60. netbos-0.0.1/tables.py +106 -0
  61. netbos-0.0.1/template_content.py +9 -0
  62. netbos-0.0.1/templates/netbos/battery.html +1 -0
  63. netbos-0.0.1/templates/netbos/berechtigung.html +1 -0
  64. netbos-0.0.1/templates/netbos/firmwareversion.html +1 -0
  65. netbos-0.0.1/templates/netbos/group.html +1 -0
  66. netbos-0.0.1/templates/netbos/index.html +9 -0
  67. netbos-0.0.1/templates/netbos/issi.html +1 -0
  68. netbos-0.0.1/templates/netbos/maintenancerecord.html +1 -0
  69. netbos-0.0.1/templates/netbos/organisation.html +1 -0
  70. netbos-0.0.1/templates/netbos/pager.html +1 -0
  71. netbos-0.0.1/templates/netbos/person.html +1 -0
  72. netbos-0.0.1/templates/netbos/radiodevice.html +1 -0
  73. netbos-0.0.1/templates/netbos/radiodevice_extra.html +27 -0
  74. netbos-0.0.1/templates/netbos/sika.html +1 -0
  75. netbos-0.0.1/templates/netbos/vehicle.html +1 -0
  76. netbos-0.0.1/templates/netbos/vehicletype.html +1 -0
  77. netbos-0.0.1/ui/__init__.py +0 -0
  78. netbos-0.0.1/ui/panels.py +86 -0
  79. netbos-0.0.1/urls.py +99 -0
  80. netbos-0.0.1/views.py +286 -0
@@ -0,0 +1,17 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright 2026 Tobias Wild
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
netbos-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.4
2
+ Name: netbos
3
+ Version: 0.0.1
4
+ Summary: A Netbox plugin to manage BOS assets
5
+ License-Expression: Apache-2.0
6
+ Project-URL: Homepage, https://code.brknl.de/700180738/netbos
7
+ Project-URL: Documentation, https://code.brknl.de/700180738/netbos#readme
8
+ Project-URL: Source, https://code.brknl.de/700180738/netbos
9
+ Project-URL: Issues, https://code.brknl.de/700180738/netbos/issues
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Framework :: Django
12
+ Classifier: Natural Language :: English
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Requires-Python: >=3.12
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE.txt
21
+ Dynamic: license-file
22
+
23
+ # netbos
24
+
25
+ A Netbox plugin to manage BOS assets.
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ pip install netbos
31
+ ```
32
+
33
+ ## Netbox Configuration
34
+
35
+ Add the plugin to your Netbox configuration:
36
+
37
+ ```python
38
+ PLUGINS = ["netbos"]
39
+ ```
40
+
41
+ ## Source
42
+
43
+ https://code.brknl.de/700180738/netbos
netbos-0.0.1/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # netbos
2
+
3
+ A Netbox plugin to manage BOS assets.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install netbos
9
+ ```
10
+
11
+ ## Netbox Configuration
12
+
13
+ Add the plugin to your Netbox configuration:
14
+
15
+ ```python
16
+ PLUGINS = ["netbos"]
17
+ ```
18
+
19
+ ## Source
20
+
21
+ https://code.brknl.de/700180738/netbos
@@ -0,0 +1 @@
1
+ from .plugin import config
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,95 @@
1
+ from netbox.api.serializers import NetBoxModelSerializer
2
+ from ..models import (
3
+ VehicleType,
4
+ Vehicle,
5
+ Group,
6
+ FirmwareVersion, Berechtigung, SIKA, Battery,
7
+ RadioDevice, Pager,
8
+ MaintenanceRecord,
9
+ )
10
+
11
+ class VehicleTypeSerializer(NetBoxModelSerializer):
12
+ class Meta:
13
+ model = VehicleType
14
+ fields = ('id', 'url', 'display', 'type', 'type_short', 'tags', 'created', 'last_updated')
15
+
16
+
17
+ class VehicleSerializer(NetBoxModelSerializer):
18
+ class Meta:
19
+ model = Vehicle
20
+ fields = ('id', 'url', 'display', 'callsign', 'license_plate', 'vehicle_type', 'tags', 'created', 'last_updated')
21
+
22
+
23
+ class GroupSerializer(NetBoxModelSerializer):
24
+ class Meta:
25
+ model = Group
26
+ fields = ('id', 'url', 'display', 'group', 'name', 'mode', 'purpose', 'tags', 'created', 'last_updated')
27
+
28
+
29
+ class FirmwareVersionSerializer(NetBoxModelSerializer):
30
+ class Meta:
31
+ model = FirmwareVersion
32
+ fields = (
33
+ 'id', 'url', 'display',
34
+ 'version', 'mandatory_update', 'device_type',
35
+ 'release_date', 'release_date_l_ttb', 'cutoff_date',
36
+ 'changelog', 'tags', 'created', 'last_updated'
37
+ )
38
+
39
+
40
+ class BerechtigungSerializer(NetBoxModelSerializer):
41
+ class Meta:
42
+ model = Berechtigung
43
+ fields = ('id', 'url', 'display', 'name', 'description', 'tags', 'created', 'last_updated')
44
+
45
+
46
+ class SIKASerializer(NetBoxModelSerializer):
47
+ class Meta:
48
+ model = SIKA
49
+ fields = (
50
+ 'id', 'url', 'display',
51
+ 'card_number', 'funkrufname', 'berechtigung', 'status', 'issi', 'org_block',
52
+ 'tags', 'created', 'last_updated'
53
+ )
54
+
55
+
56
+ class BatterySerializer(NetBoxModelSerializer):
57
+ class Meta:
58
+ model = Battery
59
+ fields = (
60
+ 'id', 'url', 'display',
61
+ 'capacity', 'serial_number', 'status', 'production_week', 'production_year', 'device_type',
62
+ 'tags', 'created', 'last_updated'
63
+ )
64
+
65
+
66
+ class RadioDeviceSerializer(NetBoxModelSerializer):
67
+ class Meta:
68
+ model = RadioDevice
69
+ fields = (
70
+ 'id', 'url', 'display',
71
+ 'name', 'model', 'serial_number',
72
+ 'owner', 'possessor_org', 'possessor_con', 'vehicle',
73
+ 'sika', 'firmware', 'battery', 'licence',
74
+ 'tei', 'status', 'notes', 'description', 'comments',
75
+ 'tags', 'created', 'last_updated',
76
+ )
77
+
78
+
79
+ class PagerSerializer(NetBoxModelSerializer):
80
+ class Meta:
81
+ model = Pager
82
+ fields = (
83
+ 'id', 'url', 'display',
84
+ 'name', 'model', 'serial_number',
85
+ 'tei', 'owner', 'possessor_org', 'possessor_con', 'sika', 'firmware', 'battery',
86
+ 'status', 'notes',
87
+ 'tags', 'created', 'last_updated',
88
+ )
89
+
90
+
91
+ class MaintenanceRecordSerializer(NetBoxModelSerializer):
92
+ class Meta:
93
+ model = MaintenanceRecord
94
+ fields = ('id', 'url', 'display', 'device', 'date', 'maintenance_type', 'description', 'tags', 'created', 'last_updated')
95
+
@@ -0,0 +1,24 @@
1
+ from netbox.api.routers import NetBoxRouter
2
+
3
+ from .views import (
4
+ VehicleTypeViewSet,
5
+ VehicleViewSet,
6
+ GroupViewSet,
7
+ FirmwareVersionViewSet, BerechtigungViewSet, SIKAViewSet, BatteryViewSet,
8
+ RadioDeviceViewSet, PagerViewSet,
9
+ MaintenanceRecordViewSet,
10
+ )
11
+
12
+ router = NetBoxRouter()
13
+ router.register('vehicle-types', VehicleTypeViewSet)
14
+ router.register('vehicles', VehicleViewSet)
15
+ router.register('groups', GroupViewSet)
16
+ router.register('firmware', FirmwareVersionViewSet)
17
+ router.register('berechtigungen', BerechtigungViewSet)
18
+ router.register('sikas', SIKAViewSet)
19
+ router.register('batteries', BatteryViewSet)
20
+ router.register('radiodevices', RadioDeviceViewSet)
21
+ router.register('pagers', PagerViewSet)
22
+ router.register('maintenance', MaintenanceRecordViewSet)
23
+
24
+ urlpatterns = router.urls
@@ -0,0 +1,71 @@
1
+ from netbox.api.viewsets import NetBoxModelViewSet
2
+ from .. import filtersets
3
+
4
+ from ..models import (
5
+ VehicleType,
6
+ Vehicle,
7
+ Group,
8
+ FirmwareVersion, Berechtigung, SIKA, Battery,
9
+ RadioDevice, Pager,
10
+ MaintenanceRecord,
11
+ )
12
+ from .serializers import (
13
+ VehicleTypeSerializer,
14
+ VehicleSerializer,
15
+ GroupSerializer,
16
+ FirmwareVersionSerializer, BerechtigungSerializer, SIKASerializer, BatterySerializer,
17
+ RadioDeviceSerializer, PagerSerializer,
18
+ MaintenanceRecordSerializer,
19
+ )
20
+
21
+
22
+ class VehicleTypeViewSet(NetBoxModelViewSet):
23
+ queryset = VehicleType.objects.all()
24
+ serializer_class = VehicleTypeSerializer
25
+
26
+ class VehicleViewSet(NetBoxModelViewSet):
27
+ queryset = Vehicle.objects.all()
28
+ serializer_class = VehicleSerializer
29
+
30
+
31
+ class GroupViewSet(NetBoxModelViewSet):
32
+ queryset = Group.objects.all()
33
+ serializer_class = GroupSerializer
34
+
35
+
36
+ class FirmwareVersionViewSet(NetBoxModelViewSet):
37
+ queryset = FirmwareVersion.objects.all()
38
+ serializer_class = FirmwareVersionSerializer
39
+ filterset_class = filtersets.FirmwareVersionFilterSet
40
+
41
+
42
+ class BerechtigungViewSet(NetBoxModelViewSet):
43
+ queryset = Berechtigung.objects.all()
44
+ serializer_class = BerechtigungSerializer
45
+ filterset_class = filtersets.BerechtigungFilterSet
46
+
47
+
48
+ class SIKAViewSet(NetBoxModelViewSet):
49
+ queryset = SIKA.objects.all()
50
+ serializer_class = SIKASerializer
51
+
52
+
53
+ class BatteryViewSet(NetBoxModelViewSet):
54
+ queryset = Battery.objects.all()
55
+ serializer_class = BatterySerializer
56
+ filterset_class = filtersets.BatteryFilterSet
57
+
58
+
59
+ class RadioDeviceViewSet(NetBoxModelViewSet):
60
+ queryset = RadioDevice.objects.all()
61
+ serializer_class = RadioDeviceSerializer
62
+
63
+
64
+ class PagerViewSet(NetBoxModelViewSet):
65
+ queryset = Pager.objects.all()
66
+ serializer_class = PagerSerializer
67
+
68
+
69
+ class MaintenanceRecordViewSet(NetBoxModelViewSet):
70
+ queryset = MaintenanceRecord.objects.all()
71
+ serializer_class = MaintenanceRecordSerializer
@@ -0,0 +1,81 @@
1
+ import django_filters
2
+
3
+ from netbox.filtersets import NetBoxModelFilterSet
4
+ from .models import (
5
+ VehicleType, Vehicle,
6
+ Group,
7
+ FirmwareVersion, Berechtigung, SIKA, Battery,
8
+ RadioDevice, Pager,
9
+ MaintenanceRecord,
10
+ )
11
+
12
+
13
+ class VehicleTypeFilterSet(NetBoxModelFilterSet):
14
+ class Meta:
15
+ model = VehicleType
16
+ fields = ('type', 'type_short')
17
+
18
+
19
+ class VehicleFilterSet(NetBoxModelFilterSet):
20
+ class Meta:
21
+ model = Vehicle
22
+ fields = ('callsign', 'vehicle_type')
23
+
24
+
25
+ class GroupFilterSet(NetBoxModelFilterSet):
26
+ class Meta:
27
+ model = Group
28
+ fields = ('mode',)
29
+
30
+
31
+ class FirmwareVersionFilterSet(NetBoxModelFilterSet):
32
+ model_id = django_filters.NumberFilter(method='filter_model_id')
33
+
34
+ def filter_model_id(self, queryset, name, value):
35
+ return queryset.filter(device_type=value)
36
+
37
+ class Meta:
38
+ model = FirmwareVersion
39
+ fields = ('device_type', 'model_id')
40
+
41
+
42
+ class BerechtigungFilterSet(NetBoxModelFilterSet):
43
+ class Meta:
44
+ model = Berechtigung
45
+ fields = ('name',)
46
+
47
+
48
+ class SIKAFilterSet(NetBoxModelFilterSet):
49
+ class Meta:
50
+ model = SIKA
51
+ fields = ('status', 'org_block', 'berechtigung')
52
+
53
+
54
+ class BatteryFilterSet(NetBoxModelFilterSet):
55
+ model_id = django_filters.NumberFilter(method='filter_model_id')
56
+
57
+ def filter_model_id(self, queryset, name, value):
58
+ return queryset.filter(device_type=value)
59
+
60
+ class Meta:
61
+ model = Battery
62
+ fields = ('serial_number', 'status', 'device_type', 'model_id')
63
+
64
+
65
+ class RadioDeviceFilterSet(NetBoxModelFilterSet):
66
+ class Meta:
67
+ model = RadioDevice
68
+ fields = ('model', 'status')
69
+
70
+
71
+ class PagerFilterSet(NetBoxModelFilterSet):
72
+ class Meta:
73
+ model = Pager
74
+ fields = ('name', 'model', 'status')
75
+
76
+
77
+ class MaintenanceRecordFilterSet(NetBoxModelFilterSet):
78
+ class Meta:
79
+ model = MaintenanceRecord
80
+ fields = ('device', 'maintenance_type')
81
+
netbos-0.0.1/forms.py ADDED
@@ -0,0 +1,218 @@
1
+ from django.db.models import Q
2
+ from dcim.models import DeviceType
3
+ from extras.models import Tag
4
+ from netbox.forms import NetBoxModelForm
5
+ from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField
6
+ from .models import (
7
+ VehicleType, Vehicle,
8
+ Group,
9
+ FirmwareVersion, Berechtigung, SIKA, Battery,
10
+ OrgBlockChoices,
11
+ RadioDevice, Pager,
12
+ MaintenanceRecord,
13
+ )
14
+
15
+
16
+ def _get_available_sika_queryset(org_block, instance=None):
17
+ """Return unassigned SIKAs for an org block, plus the instance's current SIKA while editing."""
18
+ queryset = SIKA.objects.filter(
19
+ org_block=org_block,
20
+ radio_device__isnull=True,
21
+ pager__isnull=True,
22
+ )
23
+
24
+ current_sika_id = getattr(instance, 'sika_id', None)
25
+ if current_sika_id:
26
+ queryset = queryset | SIKA.objects.filter(pk=current_sika_id, org_block=org_block)
27
+
28
+ return queryset.distinct().order_by('issi')
29
+
30
+
31
+ class VehicleTypeForm(NetBoxModelForm):
32
+ class Meta:
33
+ model = VehicleType
34
+ fields = ('type', 'type_short', 'tags')
35
+
36
+
37
+ class VehicleForm(NetBoxModelForm):
38
+ class Meta:
39
+ model = Vehicle
40
+ fields = ('name', 'callsign', 'license_plate', 'vehicle_type', 'description', 'comments', 'tags')
41
+
42
+
43
+ class GroupForm(NetBoxModelForm):
44
+ class Meta:
45
+ model = Group
46
+ fields = ('group', 'name', 'mode', 'purpose', 'tags')
47
+
48
+
49
+ class FirmwareVersionForm(NetBoxModelForm):
50
+ def __init__(self, *args, **kwargs):
51
+ super().__init__(*args, **kwargs)
52
+ self.fields['device_type'].queryset = DeviceType.objects.filter(
53
+ Q(tags__name='RadioDevice') | Q(tags__slug='radiodevice') | Q(tags__name='Pager') | Q(tags__slug='pager')
54
+ ).distinct()
55
+
56
+ class Meta:
57
+ model = FirmwareVersion
58
+ fields = (
59
+ 'version', 'mandatory_update', 'device_type',
60
+ 'release_date', 'release_date_l_ttb', 'cutoff_date',
61
+ 'changelog', 'tags'
62
+ )
63
+
64
+
65
+ class BerechtigungForm(NetBoxModelForm):
66
+ class Meta:
67
+ model = Berechtigung
68
+ fields = ('name', 'description', 'comments', 'tags')
69
+
70
+
71
+ class SIKAForm(NetBoxModelForm):
72
+ class Meta:
73
+ model = SIKA
74
+ fields = ('issi', 'card_number', 'funkrufname', 'funkrufname_tel', 'berechtigung', 'org_block', 'version', 'status', 'tags')
75
+
76
+
77
+ class BatteryForm(NetBoxModelForm):
78
+ def __init__(self, *args, **kwargs):
79
+ super().__init__(*args, **kwargs)
80
+ self.fields['device_type'].queryset = DeviceType.objects.filter(
81
+ Q(tags__name='RadioDevice') | Q(tags__slug='radiodevice') | Q(tags__name='Pager') | Q(tags__slug='pager')
82
+ ).distinct()
83
+
84
+ class Meta:
85
+ model = Battery
86
+ fields = (
87
+ 'capacity', 'serial_number', 'status', 'production_week', 'production_year',
88
+ 'device_type', 'tags',
89
+ )
90
+
91
+
92
+ class RadioDeviceForm(NetBoxModelForm):
93
+ firmware = DynamicModelChoiceField(
94
+ queryset=FirmwareVersion.objects.order_by('version'),
95
+ required=False,
96
+ label='Firmware',
97
+ query_params={'model_id': '$model'},
98
+ )
99
+
100
+ battery = DynamicModelMultipleChoiceField(
101
+ queryset=Battery.objects.order_by('serial_number'),
102
+ required=False,
103
+ label='Akkus',
104
+ query_params={'model_id': '$model'},
105
+ )
106
+
107
+ def _get_selected_model_id(self):
108
+ model_key = self.add_prefix('model')
109
+ model_id = self.data.get(model_key) if self.is_bound else self.initial.get('model')
110
+ if model_id in (None, '') and getattr(self.instance, 'model_id', None):
111
+ model_id = self.instance.model_id
112
+ return model_id
113
+
114
+ def __init__(self, *args, **kwargs):
115
+ super().__init__(*args, **kwargs)
116
+ self.fields['model'].queryset = DeviceType.objects.filter(
117
+ Q(tags__name='RadioDevice') | Q(tags__slug='radiodevice')
118
+ ).distinct()
119
+ self.fields['sika'].queryset = _get_available_sika_queryset(
120
+ OrgBlockChoices.SPEECH,
121
+ instance=self.instance,
122
+ )
123
+ self.fields['licence'].queryset = Tag.objects.filter(
124
+ slug__in=('repeater', 'gateway', 'bluetooth')
125
+ ).order_by('name')
126
+ model_id = self._get_selected_model_id()
127
+ if model_id:
128
+ self.fields['firmware'].queryset = FirmwareVersion.objects.filter(device_type=model_id).distinct()
129
+ self.fields['battery'].queryset = Battery.objects.filter(device_type=model_id).distinct().order_by('serial_number')
130
+ else:
131
+ self.fields['firmware'].queryset = FirmwareVersion.objects.none()
132
+ self.fields['battery'].queryset = Battery.objects.none()
133
+
134
+ def clean(self):
135
+ super().clean()
136
+ model = self.cleaned_data.get('model')
137
+ firmware = self.cleaned_data.get('firmware')
138
+ batteries = self.cleaned_data.get('battery')
139
+ if model and firmware and not firmware.device_type.filter(pk=model.pk).exists():
140
+ self.add_error('firmware', 'Diese Firmware ist für den gewählten Gerätetyp nicht freigegeben.')
141
+ if model and batteries and batteries.exclude(device_type=model.pk).exists():
142
+ self.add_error('battery', 'Mindestens ein Akku ist für den gewählten Gerätetyp nicht freigegeben.')
143
+ return self.cleaned_data
144
+
145
+ class Meta:
146
+ model = RadioDevice
147
+ fields = (
148
+ 'name', 'model', 'serial_number', 'tei',
149
+ 'owner', 'possessor_org', 'possessor_con', 'vehicle',
150
+ 'sika', 'firmware', 'battery', 'licence', 'status', 'notes', 'description', 'comments',
151
+ 'tags',
152
+ )
153
+
154
+
155
+ class PagerForm(NetBoxModelForm):
156
+ firmware = DynamicModelChoiceField(
157
+ queryset=FirmwareVersion.objects.order_by('version'),
158
+ required=False,
159
+ label='Firmware',
160
+ query_params={'model_id': '$model'},
161
+ )
162
+
163
+ battery = DynamicModelMultipleChoiceField(
164
+ queryset=Battery.objects.order_by('serial_number'),
165
+ required=False,
166
+ label='Akkus',
167
+ query_params={'model_id': '$model'},
168
+ )
169
+
170
+ def _get_selected_model_id(self):
171
+ model_key = self.add_prefix('model')
172
+ model_id = self.data.get(model_key) if self.is_bound else self.initial.get('model')
173
+ if model_id in (None, '') and getattr(self.instance, 'model_id', None):
174
+ model_id = self.instance.model_id
175
+ return model_id
176
+
177
+ def __init__(self, *args, **kwargs):
178
+ super().__init__(*args, **kwargs)
179
+ self.fields['model'].queryset = DeviceType.objects.filter(
180
+ Q(tags__name='Pager') | Q(tags__slug='pager')
181
+ ).distinct()
182
+ self.fields['sika'].queryset = _get_available_sika_queryset(
183
+ OrgBlockChoices.ALARM,
184
+ instance=self.instance,
185
+ )
186
+ model_id = self._get_selected_model_id()
187
+ if model_id:
188
+ self.fields['firmware'].queryset = FirmwareVersion.objects.filter(device_type=model_id).distinct()
189
+ self.fields['battery'].queryset = Battery.objects.filter(device_type=model_id).distinct().order_by('serial_number')
190
+ else:
191
+ self.fields['firmware'].queryset = FirmwareVersion.objects.none()
192
+ self.fields['battery'].queryset = Battery.objects.none()
193
+
194
+ def clean(self):
195
+ super().clean()
196
+ model = self.cleaned_data.get('model')
197
+ firmware = self.cleaned_data.get('firmware')
198
+ batteries = self.cleaned_data.get('battery')
199
+ if model and firmware and not firmware.device_type.filter(pk=model.pk).exists():
200
+ self.add_error('firmware', 'Diese Firmware ist für den gewählten Gerätetyp nicht freigegeben.')
201
+ if model and batteries and batteries.exclude(device_type=model.pk).exists():
202
+ self.add_error('battery', 'Mindestens ein Akku ist für den gewählten Gerätetyp nicht freigegeben.')
203
+ return self.cleaned_data
204
+
205
+ class Meta:
206
+ model = Pager
207
+ fields = (
208
+ 'name', 'model', 'serial_number',
209
+ 'tei', 'owner', 'possessor_org', 'possessor_con', 'vehicle', 'sika', 'firmware', 'battery', 'status', 'notes',
210
+ 'tags',
211
+ )
212
+
213
+
214
+ class MaintenanceRecordForm(NetBoxModelForm):
215
+ class Meta:
216
+ model = MaintenanceRecord
217
+ fields = ('device', 'date', 'maintenance_type', 'description', 'tags')
218
+
File without changes
netbos-0.0.1/jobs.py ADDED
File without changes
File without changes