netbox-contract 2.4.0__tar.gz → 2.4.2__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.
- {netbox_contract-2.4.0/netbox_contract.egg-info → netbox_contract-2.4.2}/PKG-INFO +8 -3
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/README.md +7 -2
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/__init__.py +1 -1
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/api/serializers.py +45 -41
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/constants.py +1 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/filtersets.py +8 -1
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/forms.py +45 -33
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/locale/en/LC_MESSAGES/django.po +9 -9
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/locale/fr/LC_MESSAGES/django.po +9 -9
- netbox_contract-2.4.2/netbox_contract/migrations/0042_remove_contract_netbox_cont_externa_6343fb_idx_and_more.py +42 -0
- netbox_contract-2.4.2/netbox_contract/migrations/0043_invoice_status.py +21 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/models.py +33 -10
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/tables.py +24 -19
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/template_content.py +23 -1
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/contract.html +7 -7
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/invoice.html +4 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/urls.py +2 -6
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/views.py +11 -29
- {netbox_contract-2.4.0 → netbox_contract-2.4.2/netbox_contract.egg-info}/PKG-INFO +8 -3
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract.egg-info/SOURCES.txt +2 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/pyproject.toml +1 -1
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/CONTRIBUTING.md +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/LICENSE +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/MANIFEST.in +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/accounting_dimensions.png +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/contract.png +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/contract_linked_objects.png +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/invoice.png +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/invoice_line.png +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/invoice_linked_objects.png +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/api/__init__.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/api/urls.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/api/views.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/locale/en/LC_MESSAGES/django.mo +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/locale/fr/LC_MESSAGES/django.mo +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0001_initial.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0002_alter_contract_circuit_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0003_alter_contract_custom_field_data_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0004_contract_currency_invoice_currency.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0005_contract_accounting_dimensions_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0006_alter_contract_circuit.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0007_invoice_date.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0008_invoice_comments.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0009_contract_external_reference.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0010_invoice_contracts.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0011_auto_20230122_2112.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0012_remove_invoice_contract.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0013_contract_documents_invoice_documents.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0014_contract_end_date.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0015_contractassignement.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0016_contract_parent.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0017_alter_contract_accounting_dimensions.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0018_contract_external_partie_object_id_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0019_auto_20230924_1813.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0020_alter_contract_external_partie.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0021_alter_contract_external_partie.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0022_alter_contract_internal_partie_alter_contract_parent.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0023_rename_contractassignement_contractassignment_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0024_remove_contract_external_partie.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0025_remove_contract_circuit_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0026_auto_20240421_1550.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0027_invoiceline.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0028_invoiceline_accounting_dimensions.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0029_remove_invoiceline_accounting_dimensions_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0030_alter_invoiceline_accounting_dimensions.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0031_contract_invoice_template_invoice_template.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0032_alter_invoice_period_end_alter_invoice_period_start_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0033_remove_contract_invoice_template.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0034_contract_yrc_alter_contract_mrc.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0035_accountingdimension_status_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0036_alter_invoiceline_accounting_dimensions.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0037_contract_notice_period_alter_contract_currency_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0038_alter_accountingdimension_options_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0039_alter_accountingdimension_status_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0040_alter_contract_currency_alter_invoice_currency_and_more.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0041_contracttype_contract_contract_type.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/__init__.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/navigation.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/search.py +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/contract_assignments_bottom.html +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/contract_list_bottom.html +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/accountingdimension.html +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/contractassignment.html +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/contracttype.html +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/invoiceline.html +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/serviceprovider.html +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract.egg-info/dependency_links.txt +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract.egg-info/requires.txt +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract.egg-info/top_level.txt +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/setup.cfg +0 -0
- {netbox_contract-2.4.0 → netbox_contract-2.4.2}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: netbox-contract
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.2
|
|
4
4
|
Summary: Contract management plugin for Netbox
|
|
5
5
|
Author-email: Marc Lebreuil <marc@famillelebreuil.net>
|
|
6
6
|
Project-URL: Homepage, https://github.com/mlebreuil/netbox-contract
|
|
@@ -101,13 +101,13 @@ PLUGINS_CONFIG = {
|
|
|
101
101
|
|
|
102
102
|
### Customize the plugin fields choices
|
|
103
103
|
|
|
104
|
-
Internal
|
|
104
|
+
Internal party reference the legal entity of your organization that is a party to the contract.
|
|
105
105
|
The first currency will also be the default currency for contracts.
|
|
106
106
|
|
|
107
107
|
```python
|
|
108
108
|
# configuration.py
|
|
109
109
|
FIELD_CHOICES = {
|
|
110
|
-
'netbox_contract.Contract.
|
|
110
|
+
'netbox_contract.Contract.internal_party': (
|
|
111
111
|
('default', 'Default entity', 'green'),
|
|
112
112
|
('entity1', 'Entity 1', 'green'),
|
|
113
113
|
('entity2', 'Entity 2', 'yellow'),
|
|
@@ -122,6 +122,11 @@ FIELD_CHOICES = {
|
|
|
122
122
|
('active', 'Active', 'green'),
|
|
123
123
|
('canceled', 'Canceled', 'red'),
|
|
124
124
|
)
|
|
125
|
+
'netbox_contract.Invoice.status': (
|
|
126
|
+
('draft', 'Draft', 'yellow'),
|
|
127
|
+
('posted', 'Posted', 'green'),
|
|
128
|
+
('canceled', 'Canceled', 'red'),
|
|
129
|
+
)
|
|
125
130
|
}
|
|
126
131
|
|
|
127
132
|
```
|
|
@@ -74,13 +74,13 @@ PLUGINS_CONFIG = {
|
|
|
74
74
|
|
|
75
75
|
### Customize the plugin fields choices
|
|
76
76
|
|
|
77
|
-
Internal
|
|
77
|
+
Internal party reference the legal entity of your organization that is a party to the contract.
|
|
78
78
|
The first currency will also be the default currency for contracts.
|
|
79
79
|
|
|
80
80
|
```python
|
|
81
81
|
# configuration.py
|
|
82
82
|
FIELD_CHOICES = {
|
|
83
|
-
'netbox_contract.Contract.
|
|
83
|
+
'netbox_contract.Contract.internal_party': (
|
|
84
84
|
('default', 'Default entity', 'green'),
|
|
85
85
|
('entity1', 'Entity 1', 'green'),
|
|
86
86
|
('entity2', 'Entity 2', 'yellow'),
|
|
@@ -95,6 +95,11 @@ FIELD_CHOICES = {
|
|
|
95
95
|
('active', 'Active', 'green'),
|
|
96
96
|
('canceled', 'Canceled', 'red'),
|
|
97
97
|
)
|
|
98
|
+
'netbox_contract.Invoice.status': (
|
|
99
|
+
('draft', 'Draft', 'yellow'),
|
|
100
|
+
('posted', 'Posted', 'green'),
|
|
101
|
+
('canceled', 'Canceled', 'red'),
|
|
102
|
+
)
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
```
|
|
@@ -5,7 +5,7 @@ class ContractsConfig(PluginConfig):
|
|
|
5
5
|
name = 'netbox_contract'
|
|
6
6
|
verbose_name = 'Netbox contract'
|
|
7
7
|
description = 'Contract management plugin for Netbox'
|
|
8
|
-
version = '2.4.
|
|
8
|
+
version = '2.4.2'
|
|
9
9
|
author = 'Marc Lebreuil'
|
|
10
10
|
author_email = 'marc@famillelebreuil.net'
|
|
11
11
|
base_url = 'contracts'
|
|
@@ -24,8 +24,8 @@ class NestedContractSerializer(WritableNestedSerializer):
|
|
|
24
24
|
)
|
|
25
25
|
yrc = serializers.DecimalField(max_digits=10, decimal_places=2, read_only=True)
|
|
26
26
|
tenant = TenantSerializer(nested=True, required=False, allow_null=True)
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
external_party_object_type = ContentTypeField(queryset=ContentType.objects.all())
|
|
28
|
+
external_party_object = serializers.SerializerMethodField(read_only=True)
|
|
29
29
|
|
|
30
30
|
class Meta:
|
|
31
31
|
model = Contract
|
|
@@ -34,11 +34,12 @@ class NestedContractSerializer(WritableNestedSerializer):
|
|
|
34
34
|
'url',
|
|
35
35
|
'display',
|
|
36
36
|
'name',
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
37
|
+
'contract_type',
|
|
38
|
+
'external_party_object_type',
|
|
39
|
+
'external_party_object_id',
|
|
40
|
+
'external_party_object',
|
|
40
41
|
'external_reference',
|
|
41
|
-
'
|
|
42
|
+
'internal_party',
|
|
42
43
|
'tenant',
|
|
43
44
|
'status',
|
|
44
45
|
'start_date',
|
|
@@ -54,13 +55,13 @@ class NestedContractSerializer(WritableNestedSerializer):
|
|
|
54
55
|
)
|
|
55
56
|
|
|
56
57
|
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
|
|
57
|
-
def
|
|
58
|
+
def get_external_party_object(self, instance):
|
|
58
59
|
serializer = get_serializer_for_model(
|
|
59
|
-
instance.
|
|
60
|
+
instance.external_party_object_type.model_class()
|
|
60
61
|
)
|
|
61
62
|
context = {'request': self.context['request']}
|
|
62
63
|
return serializer(
|
|
63
|
-
instance.
|
|
64
|
+
instance.external_party_object, nested=True, context=context
|
|
64
65
|
).data
|
|
65
66
|
|
|
66
67
|
|
|
@@ -86,15 +87,35 @@ class NestedAccountingDimensionSerializer(WritableNestedSerializer):
|
|
|
86
87
|
brief_fields = ('id', 'url', 'display', 'name', 'value')
|
|
87
88
|
|
|
88
89
|
|
|
90
|
+
class ContractTypeSerializer(NetBoxModelSerializer):
|
|
91
|
+
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_contract-api:contracttype-detail')
|
|
92
|
+
|
|
93
|
+
class Meta:
|
|
94
|
+
model = ContractType
|
|
95
|
+
fields = (
|
|
96
|
+
'id',
|
|
97
|
+
'url',
|
|
98
|
+
'display',
|
|
99
|
+
'name',
|
|
100
|
+
'description',
|
|
101
|
+
'tags',
|
|
102
|
+
'custom_fields',
|
|
103
|
+
'created',
|
|
104
|
+
'last_updated',
|
|
105
|
+
)
|
|
106
|
+
brief_fields = ('id', 'name', 'description', 'url', 'display')
|
|
107
|
+
|
|
108
|
+
|
|
89
109
|
class ContractSerializer(NetBoxModelSerializer):
|
|
90
110
|
url = serializers.HyperlinkedIdentityField(
|
|
91
111
|
view_name='plugins-api:netbox_contract-api:contract-detail'
|
|
92
112
|
)
|
|
113
|
+
contract_type = ContractTypeSerializer(nested=True, required=False, allow_null=True)
|
|
93
114
|
yrc = serializers.DecimalField(max_digits=10, decimal_places=2, read_only=True)
|
|
94
115
|
parent = NestedContractSerializer(many=False, required=False)
|
|
95
116
|
tenant = TenantSerializer(nested=True, required=False, allow_null=True)
|
|
96
|
-
|
|
97
|
-
|
|
117
|
+
external_party_object_type = ContentTypeField(queryset=ContentType.objects.all())
|
|
118
|
+
external_party_object = serializers.SerializerMethodField(read_only=True)
|
|
98
119
|
|
|
99
120
|
class Meta:
|
|
100
121
|
model = Contract
|
|
@@ -103,11 +124,12 @@ class ContractSerializer(NetBoxModelSerializer):
|
|
|
103
124
|
'url',
|
|
104
125
|
'display',
|
|
105
126
|
'name',
|
|
106
|
-
'
|
|
107
|
-
'
|
|
108
|
-
'
|
|
127
|
+
'contract_type',
|
|
128
|
+
'external_party_object_type',
|
|
129
|
+
'external_party_object_id',
|
|
130
|
+
'external_party_object',
|
|
109
131
|
'external_reference',
|
|
110
|
-
'
|
|
132
|
+
'internal_party',
|
|
111
133
|
'tenant',
|
|
112
134
|
'status',
|
|
113
135
|
'start_date',
|
|
@@ -131,11 +153,12 @@ class ContractSerializer(NetBoxModelSerializer):
|
|
|
131
153
|
'url',
|
|
132
154
|
'display',
|
|
133
155
|
'name',
|
|
134
|
-
'
|
|
135
|
-
'
|
|
136
|
-
'
|
|
156
|
+
'contract_type',
|
|
157
|
+
'external_party_object_type',
|
|
158
|
+
'external_party_object_id',
|
|
159
|
+
'external_party_object',
|
|
137
160
|
'external_reference',
|
|
138
|
-
'
|
|
161
|
+
'internal_party',
|
|
139
162
|
'tenant',
|
|
140
163
|
'status',
|
|
141
164
|
'start_date',
|
|
@@ -152,13 +175,13 @@ class ContractSerializer(NetBoxModelSerializer):
|
|
|
152
175
|
)
|
|
153
176
|
|
|
154
177
|
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
|
|
155
|
-
def
|
|
178
|
+
def get_external_party_object(self, instance):
|
|
156
179
|
serializer = get_serializer_for_model(
|
|
157
|
-
instance.
|
|
180
|
+
instance.external_party_object_type.model_class()
|
|
158
181
|
)
|
|
159
182
|
context = {'request': self.context['request']}
|
|
160
183
|
return serializer(
|
|
161
|
-
instance.
|
|
184
|
+
instance.external_party_object, nested=True, context=context
|
|
162
185
|
).data
|
|
163
186
|
|
|
164
187
|
|
|
@@ -396,22 +419,3 @@ class AccountingDimensionSerializer(NetBoxModelSerializer):
|
|
|
396
419
|
'last_updated',
|
|
397
420
|
)
|
|
398
421
|
brief_fields = ('id', 'name', 'value', 'url', 'display')
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
class ContractTypeSerializer(NetBoxModelSerializer):
|
|
402
|
-
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_contract-api:contracttype-detail')
|
|
403
|
-
|
|
404
|
-
class Meta:
|
|
405
|
-
model = ContractType
|
|
406
|
-
fields = (
|
|
407
|
-
'id',
|
|
408
|
-
'url',
|
|
409
|
-
'display',
|
|
410
|
-
'name',
|
|
411
|
-
'description',
|
|
412
|
-
'tags',
|
|
413
|
-
'custom_fields',
|
|
414
|
-
'created',
|
|
415
|
-
'last_updated',
|
|
416
|
-
)
|
|
417
|
-
brief_fields = ('id', 'name', 'description', 'url', 'display')
|
|
@@ -7,6 +7,7 @@ SERVICE_PROVIDER_MODELS = Q(
|
|
|
7
7
|
|
|
8
8
|
ASSIGNEMENT_MODELS = Q(
|
|
9
9
|
Q(app_label='circuits', model__in=('circuit',))
|
|
10
|
+
| Q(app_label='circuits', model__in=('virtualcircuit',))
|
|
10
11
|
| Q(app_label='dcim', model__in=('site',))
|
|
11
12
|
| Q(app_label='dcim', model__in=('device',))
|
|
12
13
|
| Q(app_label='virtualization', model__in=('virtualmachine',))
|
|
@@ -15,12 +15,13 @@ from .models import (
|
|
|
15
15
|
InvoiceLine,
|
|
16
16
|
ServiceProvider,
|
|
17
17
|
StatusChoices,
|
|
18
|
+
InvoiceStatusChoices,
|
|
18
19
|
)
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class ContractFilterSet(ContactModelFilterSet, NetBoxModelFilterSet, TenancyFilterSet):
|
|
22
23
|
status = django_filters.MultipleChoiceFilter(choices=StatusChoices, null_value=None)
|
|
23
|
-
|
|
24
|
+
internal_party = django_filters.MultipleChoiceFilter(
|
|
24
25
|
choices=InternalEntityChoices, null_value=None
|
|
25
26
|
)
|
|
26
27
|
currency = django_filters.MultipleChoiceFilter(
|
|
@@ -53,9 +54,15 @@ class ContractFilterSet(ContactModelFilterSet, NetBoxModelFilterSet, TenancyFilt
|
|
|
53
54
|
|
|
54
55
|
|
|
55
56
|
class InvoiceFilterSet(NetBoxModelFilterSet):
|
|
57
|
+
status = django_filters.MultipleChoiceFilter(choices=InvoiceStatusChoices, null_value=None)
|
|
56
58
|
currency = django_filters.MultipleChoiceFilter(
|
|
57
59
|
choices=CurrencyChoices, null_value=None
|
|
58
60
|
)
|
|
61
|
+
accounting_dimensions = django_filters.ModelChoiceFilter(
|
|
62
|
+
field_name='invoicelines__accounting_dimensions',
|
|
63
|
+
queryset=AccountingDimension.objects.all(),
|
|
64
|
+
label='Accounting Dimension'
|
|
65
|
+
)
|
|
59
66
|
|
|
60
67
|
class Meta:
|
|
61
68
|
model = Invoice
|
|
@@ -40,6 +40,7 @@ from .models import (
|
|
|
40
40
|
InvoiceLine,
|
|
41
41
|
ServiceProvider,
|
|
42
42
|
StatusChoices,
|
|
43
|
+
InvoiceStatusChoices,
|
|
43
44
|
)
|
|
44
45
|
|
|
45
46
|
plugin_settings = settings.PLUGINS_CONFIG['netbox_contract']
|
|
@@ -51,13 +52,13 @@ plugin_settings = settings.PLUGINS_CONFIG['netbox_contract']
|
|
|
51
52
|
class ContractForm(NetBoxModelForm):
|
|
52
53
|
comments = CommentField(label=_('Comments'))
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
external_party_object_type = ContentTypeChoiceField(
|
|
55
56
|
queryset=ContentType.objects.all(),
|
|
56
57
|
limit_choices_to=SERVICE_PROVIDER_MODELS,
|
|
57
58
|
widget=HTMXSelect(),
|
|
58
|
-
label=_('External
|
|
59
|
+
label=_('External party object type'),
|
|
59
60
|
)
|
|
60
|
-
|
|
61
|
+
external_party_object = forms.ModelChoiceField(queryset=None, label=_('External party object'))
|
|
61
62
|
tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False, selector=True, label=_('Tenant'))
|
|
62
63
|
parent = DynamicModelChoiceField(
|
|
63
64
|
queryset=Contract.objects.all(),
|
|
@@ -74,24 +75,24 @@ class ContractForm(NetBoxModelForm):
|
|
|
74
75
|
super().__init__(*args, **kwargs)
|
|
75
76
|
|
|
76
77
|
# Initialize the external party object gfk
|
|
77
|
-
if initial and '
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
self.fields['
|
|
78
|
+
if initial and 'external_party_object_type' in initial:
|
|
79
|
+
external_party_object_type = ContentType.objects.get_for_id(initial['external_party_object_type'])
|
|
80
|
+
external_party_class = external_party_object_type.model_class()
|
|
81
|
+
self.fields['external_party_object'].queryset = external_party_class.objects.all()
|
|
81
82
|
if (
|
|
82
|
-
self.instance.
|
|
83
|
-
and self.instance.
|
|
83
|
+
self.instance.external_party_object_type
|
|
84
|
+
and self.instance.external_party_object_type.id == external_party_object_type.id
|
|
84
85
|
):
|
|
85
|
-
self.fields['
|
|
86
|
+
self.fields['external_party_object'].initial = self.instance.external_party_object
|
|
86
87
|
else:
|
|
87
|
-
self.fields['
|
|
88
|
-
elif self.instance.
|
|
89
|
-
|
|
90
|
-
self.fields['
|
|
91
|
-
self.fields['
|
|
88
|
+
self.fields['external_party_object'].initial = None
|
|
89
|
+
elif self.instance.external_party_object_type:
|
|
90
|
+
external_party_class = self.instance.external_party_object_type.model_class()
|
|
91
|
+
self.fields['external_party_object'].queryset = external_party_class.objects.all()
|
|
92
|
+
self.fields['external_party_object'].initial = self.instance.external_party_object
|
|
92
93
|
else:
|
|
93
|
-
self.fields['
|
|
94
|
-
self.fields['
|
|
94
|
+
self.fields['external_party_object'].queryset = ServiceProvider.objects.all()
|
|
95
|
+
self.fields['external_party_object'].initial = None
|
|
95
96
|
|
|
96
97
|
# Initialise fields settings
|
|
97
98
|
mandatory_fields = plugin_settings.get('mandatory_contract_fields')
|
|
@@ -107,10 +108,10 @@ class ContractForm(NetBoxModelForm):
|
|
|
107
108
|
fields = (
|
|
108
109
|
'name',
|
|
109
110
|
'contract_type',
|
|
110
|
-
'
|
|
111
|
-
'
|
|
111
|
+
'external_party_object_type',
|
|
112
|
+
'external_party_object',
|
|
112
113
|
'external_reference',
|
|
113
|
-
'
|
|
114
|
+
'internal_party',
|
|
114
115
|
'tenant',
|
|
115
116
|
'status',
|
|
116
117
|
'start_date',
|
|
@@ -151,7 +152,7 @@ class ContractFilterForm(ContactModelFilterForm, TenancyFilterForm, NetBoxModelF
|
|
|
151
152
|
label=_('Contract type'),
|
|
152
153
|
)
|
|
153
154
|
external_reference = forms.CharField(required=False, label=_('External reference'))
|
|
154
|
-
|
|
155
|
+
internal_party = forms.ChoiceField(choices=InternalEntityChoices, required=False, label=_('Internal party'))
|
|
155
156
|
status = forms.ChoiceField(choices=StatusChoices, required=False, label=_('Status'))
|
|
156
157
|
currency = forms.ChoiceField(choices=CurrencyChoices, required=False, label=_('Currency'))
|
|
157
158
|
parent = DynamicModelChoiceField(
|
|
@@ -164,13 +165,13 @@ class ContractFilterForm(ContactModelFilterForm, TenancyFilterForm, NetBoxModelF
|
|
|
164
165
|
|
|
165
166
|
|
|
166
167
|
class ContractCSVForm(NetBoxModelImportForm):
|
|
167
|
-
|
|
168
|
+
external_party_object_type = CSVContentTypeField(
|
|
168
169
|
queryset=ContentType.objects.all(),
|
|
169
170
|
limit_choices_to=SERVICE_PROVIDER_MODELS,
|
|
170
171
|
help_text='service provider object type in the form <app>.<model>',
|
|
171
172
|
)
|
|
172
|
-
|
|
173
|
-
help_text='service provider object name', label=_('External
|
|
173
|
+
external_party_object_id = forms.CharField(
|
|
174
|
+
help_text='service provider object name', label=_('External party name')
|
|
174
175
|
)
|
|
175
176
|
tenant = CSVModelChoiceField(
|
|
176
177
|
queryset=Tenant.objects.all(),
|
|
@@ -200,10 +201,10 @@ class ContractCSVForm(NetBoxModelImportForm):
|
|
|
200
201
|
fields = [
|
|
201
202
|
'name',
|
|
202
203
|
'contract_type',
|
|
203
|
-
'
|
|
204
|
-
'
|
|
204
|
+
'external_party_object_type',
|
|
205
|
+
'external_party_object_id',
|
|
205
206
|
'external_reference',
|
|
206
|
-
'
|
|
207
|
+
'internal_party',
|
|
207
208
|
'tenant',
|
|
208
209
|
'status',
|
|
209
210
|
'start_date',
|
|
@@ -220,12 +221,12 @@ class ContractCSVForm(NetBoxModelImportForm):
|
|
|
220
221
|
'parent',
|
|
221
222
|
]
|
|
222
223
|
|
|
223
|
-
def
|
|
224
|
-
name = self.cleaned_data.get('
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
def clean_external_party_object_id(self):
|
|
225
|
+
name = self.cleaned_data.get('external_party_object_id')
|
|
226
|
+
external_party_object_type = self.cleaned_data.get('external_party_object_type')
|
|
227
|
+
external_party_object = external_party_object_type.get_object_for_this_type(name=name)
|
|
227
228
|
|
|
228
|
-
return
|
|
229
|
+
return external_party_object.id
|
|
229
230
|
|
|
230
231
|
|
|
231
232
|
class ContractBulkEditForm(NetBoxModelBulkEditForm):
|
|
@@ -237,7 +238,7 @@ class ContractBulkEditForm(NetBoxModelBulkEditForm):
|
|
|
237
238
|
label=_('Contract Type')
|
|
238
239
|
)
|
|
239
240
|
external_reference = forms.CharField(max_length=100, required=False, label=_('External reference'))
|
|
240
|
-
|
|
241
|
+
internal_party = forms.ChoiceField(choices=InternalEntityChoices, required=False, label=_('Internal party'))
|
|
241
242
|
tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False, selector=True, label=_('Tenant'))
|
|
242
243
|
comments = CommentField(required=False, label=_('Comments'))
|
|
243
244
|
parent = DynamicModelChoiceField(
|
|
@@ -380,6 +381,7 @@ class InvoiceForm(NetBoxModelForm):
|
|
|
380
381
|
'date',
|
|
381
382
|
'contracts',
|
|
382
383
|
'template',
|
|
384
|
+
'status',
|
|
383
385
|
'period_start',
|
|
384
386
|
'period_end',
|
|
385
387
|
'currency',
|
|
@@ -406,6 +408,7 @@ class InvoiceFilterForm(NetBoxModelFilterSetForm):
|
|
|
406
408
|
widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES),
|
|
407
409
|
label=_('Template'),
|
|
408
410
|
)
|
|
411
|
+
status = forms.ChoiceField(choices=InvoiceStatusChoices, required=False, label=_('Status'))
|
|
409
412
|
currency = forms.ChoiceField(choices=CurrencyChoices, required=False, label=_('Currency'))
|
|
410
413
|
contracts = DynamicModelMultipleChoiceField(
|
|
411
414
|
queryset=Contract.objects.all(),
|
|
@@ -413,6 +416,13 @@ class InvoiceFilterForm(NetBoxModelFilterSetForm):
|
|
|
413
416
|
selector=True,
|
|
414
417
|
label=_('Contracts'),
|
|
415
418
|
)
|
|
419
|
+
accounting_dimensions = DynamicModelMultipleChoiceField(
|
|
420
|
+
queryset=AccountingDimension.objects.all(),
|
|
421
|
+
required=False,
|
|
422
|
+
selector=True,
|
|
423
|
+
label=_('Accounting Dimensions'),
|
|
424
|
+
)
|
|
425
|
+
|
|
416
426
|
tag = TagFilterField(model)
|
|
417
427
|
|
|
418
428
|
|
|
@@ -423,6 +433,7 @@ class InvoiceCSVForm(NetBoxModelImportForm):
|
|
|
423
433
|
help_text='Related Contracts',
|
|
424
434
|
label=_('Contracts'),
|
|
425
435
|
)
|
|
436
|
+
status = CSVChoiceField(choices=InvoiceStatusChoices, help_text='Invoice status', label=_('Status'))
|
|
426
437
|
|
|
427
438
|
class Meta:
|
|
428
439
|
model = Invoice
|
|
@@ -431,6 +442,7 @@ class InvoiceCSVForm(NetBoxModelImportForm):
|
|
|
431
442
|
'date',
|
|
432
443
|
'contracts',
|
|
433
444
|
'template',
|
|
445
|
+
'status',
|
|
434
446
|
'period_start',
|
|
435
447
|
'period_end',
|
|
436
448
|
'currency',
|
{netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/locale/en/LC_MESSAGES/django.po
RENAMED
|
@@ -23,11 +23,11 @@ msgid "Comments"
|
|
|
23
23
|
msgstr ""
|
|
24
24
|
|
|
25
25
|
#: forms.py:69
|
|
26
|
-
msgid "External
|
|
26
|
+
msgid "External party object type"
|
|
27
27
|
msgstr ""
|
|
28
28
|
|
|
29
29
|
#: forms.py:71
|
|
30
|
-
msgid "External
|
|
30
|
+
msgid "External party object"
|
|
31
31
|
msgstr ""
|
|
32
32
|
|
|
33
33
|
#: forms.py:73 forms.py:173 forms.py:199 forms.py:267
|
|
@@ -53,7 +53,7 @@ msgid "External reference"
|
|
|
53
53
|
msgstr ""
|
|
54
54
|
|
|
55
55
|
#: forms.py:176 forms.py:261 templates/netbox_contract/contract.html:38
|
|
56
|
-
msgid "Internal
|
|
56
|
+
msgid "Internal party"
|
|
57
57
|
msgstr ""
|
|
58
58
|
|
|
59
59
|
#: forms.py:177 forms.py:204 forms.py:716
|
|
@@ -71,7 +71,7 @@ msgid "Currency"
|
|
|
71
71
|
msgstr ""
|
|
72
72
|
|
|
73
73
|
#: forms.py:192
|
|
74
|
-
msgid "External
|
|
74
|
+
msgid "External party name"
|
|
75
75
|
msgstr ""
|
|
76
76
|
|
|
77
77
|
#: forms.py:252 forms.py:523 forms.py:540 forms.py:711 forms.py:735
|
|
@@ -223,11 +223,11 @@ msgid "contract assignments"
|
|
|
223
223
|
msgstr ""
|
|
224
224
|
|
|
225
225
|
#: models.py:178
|
|
226
|
-
msgid "external
|
|
226
|
+
msgid "external party object type"
|
|
227
227
|
msgstr ""
|
|
228
228
|
|
|
229
229
|
#: models.py:183
|
|
230
|
-
msgid "external
|
|
230
|
+
msgid "external party object ID"
|
|
231
231
|
msgstr ""
|
|
232
232
|
|
|
233
233
|
#: models.py:193
|
|
@@ -235,7 +235,7 @@ msgid "external reference"
|
|
|
235
235
|
msgstr ""
|
|
236
236
|
|
|
237
237
|
#: models.py:198
|
|
238
|
-
msgid "internal
|
|
238
|
+
msgid "internal party"
|
|
239
239
|
msgstr ""
|
|
240
240
|
|
|
241
241
|
#: models.py:206
|
|
@@ -389,11 +389,11 @@ msgid "Accounting dimension"
|
|
|
389
389
|
msgstr ""
|
|
390
390
|
|
|
391
391
|
#: templates/netbox_contract/contract.html:20
|
|
392
|
-
msgid "External
|
|
392
|
+
msgid "External party type"
|
|
393
393
|
msgstr ""
|
|
394
394
|
|
|
395
395
|
#: templates/netbox_contract/contract.html:24
|
|
396
|
-
msgid "External
|
|
396
|
+
msgid "External party"
|
|
397
397
|
msgstr ""
|
|
398
398
|
|
|
399
399
|
#: templates/netbox_contract/contract.html:49
|
{netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/locale/fr/LC_MESSAGES/django.po
RENAMED
|
@@ -27,11 +27,11 @@ msgid "Comments"
|
|
|
27
27
|
msgstr "Commentaires"
|
|
28
28
|
|
|
29
29
|
#: forms.py:69
|
|
30
|
-
msgid "External
|
|
30
|
+
msgid "External party object type"
|
|
31
31
|
msgstr "Type de prestataire "
|
|
32
32
|
|
|
33
33
|
#: forms.py:71
|
|
34
|
-
msgid "External
|
|
34
|
+
msgid "External party object"
|
|
35
35
|
msgstr "Prestataire"
|
|
36
36
|
|
|
37
37
|
#: forms.py:73 forms.py:173 forms.py:199 forms.py:267
|
|
@@ -57,7 +57,7 @@ msgid "External reference"
|
|
|
57
57
|
msgstr "Reference externe"
|
|
58
58
|
|
|
59
59
|
#: forms.py:176 forms.py:261 templates/netbox_contract/contract.html:38
|
|
60
|
-
msgid "Internal
|
|
60
|
+
msgid "Internal party"
|
|
61
61
|
msgstr "Entité interne"
|
|
62
62
|
|
|
63
63
|
#: forms.py:177 forms.py:204 forms.py:716
|
|
@@ -75,7 +75,7 @@ msgid "Currency"
|
|
|
75
75
|
msgstr "Devise"
|
|
76
76
|
|
|
77
77
|
#: forms.py:192
|
|
78
|
-
msgid "External
|
|
78
|
+
msgid "External party name"
|
|
79
79
|
msgstr "Nom du prestataire"
|
|
80
80
|
|
|
81
81
|
#: forms.py:252 forms.py:523 forms.py:540 forms.py:711 forms.py:735
|
|
@@ -227,11 +227,11 @@ msgid "contract assignments"
|
|
|
227
227
|
msgstr "objets du contrat"
|
|
228
228
|
|
|
229
229
|
#: models.py:178
|
|
230
|
-
msgid "external
|
|
230
|
+
msgid "external party object type"
|
|
231
231
|
msgstr "type de prestataire "
|
|
232
232
|
|
|
233
233
|
#: models.py:183
|
|
234
|
-
msgid "external
|
|
234
|
+
msgid "external party object ID"
|
|
235
235
|
msgstr "identifiant du prestataire "
|
|
236
236
|
|
|
237
237
|
#: models.py:193
|
|
@@ -239,7 +239,7 @@ msgid "external reference"
|
|
|
239
239
|
msgstr "réference externe"
|
|
240
240
|
|
|
241
241
|
#: models.py:198
|
|
242
|
-
msgid "internal
|
|
242
|
+
msgid "internal party"
|
|
243
243
|
msgstr "entité interne"
|
|
244
244
|
|
|
245
245
|
#: models.py:206
|
|
@@ -393,11 +393,11 @@ msgid "Accounting dimension"
|
|
|
393
393
|
msgstr "Dimension comptable"
|
|
394
394
|
|
|
395
395
|
#: templates/netbox_contract/contract.html:20
|
|
396
|
-
msgid "External
|
|
396
|
+
msgid "External party type"
|
|
397
397
|
msgstr "Type de prestataire "
|
|
398
398
|
|
|
399
399
|
#: templates/netbox_contract/contract.html:24
|
|
400
|
-
msgid "External
|
|
400
|
+
msgid "External party"
|
|
401
401
|
msgstr "Prestataire"
|
|
402
402
|
|
|
403
403
|
#: templates/netbox_contract/contract.html:49
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Generated by Django 5.2.3 on 2025-08-14 09:46
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("contenttypes", "0002_remove_content_type_name"),
|
|
10
|
+
("extras", "0129_fix_script_paths"),
|
|
11
|
+
("netbox_contract", "0041_contracttype_contract_contract_type"),
|
|
12
|
+
("tenancy", "0020_remove_contactgroupmembership"),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
operations = [
|
|
16
|
+
migrations.RemoveIndex(
|
|
17
|
+
model_name="contract",
|
|
18
|
+
name="netbox_cont_externa_6343fb_idx",
|
|
19
|
+
),
|
|
20
|
+
migrations.RenameField(
|
|
21
|
+
model_name="contract",
|
|
22
|
+
old_name="external_partie_object_id",
|
|
23
|
+
new_name="external_party_object_id",
|
|
24
|
+
),
|
|
25
|
+
migrations.RenameField(
|
|
26
|
+
model_name="contract",
|
|
27
|
+
old_name="external_partie_object_type",
|
|
28
|
+
new_name="external_party_object_type",
|
|
29
|
+
),
|
|
30
|
+
migrations.RenameField(
|
|
31
|
+
model_name="contract",
|
|
32
|
+
old_name="internal_partie",
|
|
33
|
+
new_name="internal_party",
|
|
34
|
+
),
|
|
35
|
+
migrations.AddIndex(
|
|
36
|
+
model_name="contract",
|
|
37
|
+
index=models.Index(
|
|
38
|
+
fields=["external_party_object_type", "external_party_object_id"],
|
|
39
|
+
name="netbox_cont_externa_e3f507_idx",
|
|
40
|
+
),
|
|
41
|
+
),
|
|
42
|
+
]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Generated by Django 5.2.3 on 2025-08-14 14:24
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
(
|
|
10
|
+
"netbox_contract",
|
|
11
|
+
"0042_remove_contract_netbox_cont_externa_6343fb_idx_and_more",
|
|
12
|
+
),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
operations = [
|
|
16
|
+
migrations.AddField(
|
|
17
|
+
model_name="invoice",
|
|
18
|
+
name="status",
|
|
19
|
+
field=models.CharField(default="posted", max_length=50),
|
|
20
|
+
),
|
|
21
|
+
]
|