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.
Files changed (91) hide show
  1. {netbox_contract-2.4.0/netbox_contract.egg-info → netbox_contract-2.4.2}/PKG-INFO +8 -3
  2. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/README.md +7 -2
  3. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/__init__.py +1 -1
  4. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/api/serializers.py +45 -41
  5. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/constants.py +1 -0
  6. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/filtersets.py +8 -1
  7. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/forms.py +45 -33
  8. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/locale/en/LC_MESSAGES/django.po +9 -9
  9. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/locale/fr/LC_MESSAGES/django.po +9 -9
  10. netbox_contract-2.4.2/netbox_contract/migrations/0042_remove_contract_netbox_cont_externa_6343fb_idx_and_more.py +42 -0
  11. netbox_contract-2.4.2/netbox_contract/migrations/0043_invoice_status.py +21 -0
  12. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/models.py +33 -10
  13. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/tables.py +24 -19
  14. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/template_content.py +23 -1
  15. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/contract.html +7 -7
  16. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/invoice.html +4 -0
  17. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/urls.py +2 -6
  18. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/views.py +11 -29
  19. {netbox_contract-2.4.0 → netbox_contract-2.4.2/netbox_contract.egg-info}/PKG-INFO +8 -3
  20. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract.egg-info/SOURCES.txt +2 -0
  21. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/pyproject.toml +1 -1
  22. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/CONTRIBUTING.md +0 -0
  23. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/LICENSE +0 -0
  24. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/MANIFEST.in +0 -0
  25. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/accounting_dimensions.png +0 -0
  26. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/contract.png +0 -0
  27. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/contract_linked_objects.png +0 -0
  28. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/invoice.png +0 -0
  29. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/invoice_line.png +0 -0
  30. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/docs/img/invoice_linked_objects.png +0 -0
  31. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/api/__init__.py +0 -0
  32. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/api/urls.py +0 -0
  33. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/api/views.py +0 -0
  34. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/locale/en/LC_MESSAGES/django.mo +0 -0
  35. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/locale/fr/LC_MESSAGES/django.mo +0 -0
  36. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0001_initial.py +0 -0
  37. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0002_alter_contract_circuit_and_more.py +0 -0
  38. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0003_alter_contract_custom_field_data_and_more.py +0 -0
  39. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0004_contract_currency_invoice_currency.py +0 -0
  40. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0005_contract_accounting_dimensions_and_more.py +0 -0
  41. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0006_alter_contract_circuit.py +0 -0
  42. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0007_invoice_date.py +0 -0
  43. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0008_invoice_comments.py +0 -0
  44. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0009_contract_external_reference.py +0 -0
  45. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0010_invoice_contracts.py +0 -0
  46. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0011_auto_20230122_2112.py +0 -0
  47. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0012_remove_invoice_contract.py +0 -0
  48. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0013_contract_documents_invoice_documents.py +0 -0
  49. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0014_contract_end_date.py +0 -0
  50. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0015_contractassignement.py +0 -0
  51. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0016_contract_parent.py +0 -0
  52. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0017_alter_contract_accounting_dimensions.py +0 -0
  53. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0018_contract_external_partie_object_id_and_more.py +0 -0
  54. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0019_auto_20230924_1813.py +0 -0
  55. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0020_alter_contract_external_partie.py +0 -0
  56. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0021_alter_contract_external_partie.py +0 -0
  57. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0022_alter_contract_internal_partie_alter_contract_parent.py +0 -0
  58. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0023_rename_contractassignement_contractassignment_and_more.py +0 -0
  59. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0024_remove_contract_external_partie.py +0 -0
  60. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0025_remove_contract_circuit_and_more.py +0 -0
  61. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0026_auto_20240421_1550.py +0 -0
  62. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0027_invoiceline.py +0 -0
  63. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0028_invoiceline_accounting_dimensions.py +0 -0
  64. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0029_remove_invoiceline_accounting_dimensions_and_more.py +0 -0
  65. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0030_alter_invoiceline_accounting_dimensions.py +0 -0
  66. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0031_contract_invoice_template_invoice_template.py +0 -0
  67. {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
  68. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0033_remove_contract_invoice_template.py +0 -0
  69. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0034_contract_yrc_alter_contract_mrc.py +0 -0
  70. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0035_accountingdimension_status_and_more.py +0 -0
  71. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0036_alter_invoiceline_accounting_dimensions.py +0 -0
  72. {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
  73. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0038_alter_accountingdimension_options_and_more.py +0 -0
  74. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0039_alter_accountingdimension_status_and_more.py +0 -0
  75. {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
  76. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/0041_contracttype_contract_contract_type.py +0 -0
  77. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/migrations/__init__.py +0 -0
  78. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/navigation.py +0 -0
  79. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/search.py +0 -0
  80. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/contract_assignments_bottom.html +0 -0
  81. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/contract_list_bottom.html +0 -0
  82. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/accountingdimension.html +0 -0
  83. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/contractassignment.html +0 -0
  84. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/contracttype.html +0 -0
  85. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/invoiceline.html +0 -0
  86. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract/templates/netbox_contract/serviceprovider.html +0 -0
  87. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract.egg-info/dependency_links.txt +0 -0
  88. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract.egg-info/requires.txt +0 -0
  89. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/netbox_contract.egg-info/top_level.txt +0 -0
  90. {netbox_contract-2.4.0 → netbox_contract-2.4.2}/setup.cfg +0 -0
  91. {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.0
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 partie reference the legal entity of your organization that is a partie to the contract.
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.internal_partie': (
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 partie reference the legal entity of your organization that is a partie to the contract.
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.internal_partie': (
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.0'
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
- external_partie_object_type = ContentTypeField(queryset=ContentType.objects.all())
28
- external_partie_object = serializers.SerializerMethodField(read_only=True)
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
- 'external_partie_object_type',
38
- 'external_partie_object_id',
39
- 'external_partie_object',
37
+ 'contract_type',
38
+ 'external_party_object_type',
39
+ 'external_party_object_id',
40
+ 'external_party_object',
40
41
  'external_reference',
41
- 'internal_partie',
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 get_external_partie_object(self, instance):
58
+ def get_external_party_object(self, instance):
58
59
  serializer = get_serializer_for_model(
59
- instance.external_partie_object_type.model_class()
60
+ instance.external_party_object_type.model_class()
60
61
  )
61
62
  context = {'request': self.context['request']}
62
63
  return serializer(
63
- instance.external_partie_object, nested=True, context=context
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
- external_partie_object_type = ContentTypeField(queryset=ContentType.objects.all())
97
- external_partie_object = serializers.SerializerMethodField(read_only=True)
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
- 'external_partie_object_type',
107
- 'external_partie_object_id',
108
- 'external_partie_object',
127
+ 'contract_type',
128
+ 'external_party_object_type',
129
+ 'external_party_object_id',
130
+ 'external_party_object',
109
131
  'external_reference',
110
- 'internal_partie',
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
- 'external_partie_object_type',
135
- 'external_partie_object_id',
136
- 'external_partie_object',
156
+ 'contract_type',
157
+ 'external_party_object_type',
158
+ 'external_party_object_id',
159
+ 'external_party_object',
137
160
  'external_reference',
138
- 'internal_partie',
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 get_external_partie_object(self, instance):
178
+ def get_external_party_object(self, instance):
156
179
  serializer = get_serializer_for_model(
157
- instance.external_partie_object_type.model_class()
180
+ instance.external_party_object_type.model_class()
158
181
  )
159
182
  context = {'request': self.context['request']}
160
183
  return serializer(
161
- instance.external_partie_object, nested=True, context=context
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
- internal_partie = django_filters.MultipleChoiceFilter(
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
- external_partie_object_type = ContentTypeChoiceField(
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 partie object type'),
59
+ label=_('External party object type'),
59
60
  )
60
- external_partie_object = forms.ModelChoiceField(queryset=None, label=_('External partie object'))
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 'external_partie_object_type' in initial:
78
- external_partie_object_type = ContentType.objects.get_for_id(initial['external_partie_object_type'])
79
- external_partie_class = external_partie_object_type.model_class()
80
- self.fields['external_partie_object'].queryset = external_partie_class.objects.all()
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.external_partie_object_type
83
- and self.instance.external_partie_object_type.id == external_partie_object_type.id
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['external_partie_object'].initial = self.instance.external_partie_object
86
+ self.fields['external_party_object'].initial = self.instance.external_party_object
86
87
  else:
87
- self.fields['external_partie_object'].initial = None
88
- elif self.instance.external_partie_object_type:
89
- external_partie_class = self.instance.external_partie_object_type.model_class()
90
- self.fields['external_partie_object'].queryset = external_partie_class.objects.all()
91
- self.fields['external_partie_object'].initial = self.instance.external_partie_object
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['external_partie_object'].queryset = ServiceProvider.objects.all()
94
- self.fields['external_partie_object'].initial = None
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
- 'external_partie_object_type',
111
- 'external_partie_object',
111
+ 'external_party_object_type',
112
+ 'external_party_object',
112
113
  'external_reference',
113
- 'internal_partie',
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
- internal_partie = forms.ChoiceField(choices=InternalEntityChoices, required=False, label=_('Internal partie'))
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
- external_partie_object_type = CSVContentTypeField(
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
- external_partie_object_id = forms.CharField(
173
- help_text='service provider object name', label=_('External partie name')
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
- 'external_partie_object_type',
204
- 'external_partie_object_id',
204
+ 'external_party_object_type',
205
+ 'external_party_object_id',
205
206
  'external_reference',
206
- 'internal_partie',
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 clean_external_partie_object_id(self):
224
- name = self.cleaned_data.get('external_partie_object_id')
225
- external_partie_object_type = self.cleaned_data.get('external_partie_object_type')
226
- external_partie_object = external_partie_object_type.get_object_for_this_type(name=name)
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 external_partie_object.id
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
- internal_partie = forms.ChoiceField(choices=InternalEntityChoices, required=False, label=_('Internal partie'))
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',
@@ -23,11 +23,11 @@ msgid "Comments"
23
23
  msgstr ""
24
24
 
25
25
  #: forms.py:69
26
- msgid "External partie object type"
26
+ msgid "External party object type"
27
27
  msgstr ""
28
28
 
29
29
  #: forms.py:71
30
- msgid "External partie object"
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 partie"
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 partie name"
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 partie object type"
226
+ msgid "external party object type"
227
227
  msgstr ""
228
228
 
229
229
  #: models.py:183
230
- msgid "external partie object ID"
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 partie"
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 partie type"
392
+ msgid "External party type"
393
393
  msgstr ""
394
394
 
395
395
  #: templates/netbox_contract/contract.html:24
396
- msgid "External partie"
396
+ msgid "External party"
397
397
  msgstr ""
398
398
 
399
399
  #: templates/netbox_contract/contract.html:49
@@ -27,11 +27,11 @@ msgid "Comments"
27
27
  msgstr "Commentaires"
28
28
 
29
29
  #: forms.py:69
30
- msgid "External partie object type"
30
+ msgid "External party object type"
31
31
  msgstr "Type de prestataire "
32
32
 
33
33
  #: forms.py:71
34
- msgid "External partie object"
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 partie"
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 partie name"
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 partie object type"
230
+ msgid "external party object type"
231
231
  msgstr "type de prestataire "
232
232
 
233
233
  #: models.py:183
234
- msgid "external partie object ID"
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 partie"
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 partie type"
396
+ msgid "External party type"
397
397
  msgstr "Type de prestataire "
398
398
 
399
399
  #: templates/netbox_contract/contract.html:24
400
- msgid "External partie"
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
+ ]