From 8864dfd35244bb3d2564852bda045b29f3deca10 Mon Sep 17 00:00:00 2001 From: Marc Lebreuil Date: Sun, 8 Sep 2024 17:30:56 +0000 Subject: [PATCH] Improve filtering --- CHANGELOG.md | 1 + src/netbox_contract/api/views.py | 2 ++ src/netbox_contract/filtersets.py | 47 ++++++++++++++++++++++++++++--- src/netbox_contract/forms.py | 20 ++++++++++--- 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac8d2e0..8184b0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Version 2.2.5 * [178](https://github.com/mlebreuil/netbox-contract/issues/178) Add the possibility to filter on invoice number, and contract name through the API. +* Generally improve filtering options ### Version 2.2.4 diff --git a/src/netbox_contract/api/views.py b/src/netbox_contract/api/views.py index 904270c..eb65d33 100644 --- a/src/netbox_contract/api/views.py +++ b/src/netbox_contract/api/views.py @@ -21,6 +21,7 @@ class ContractViewSet(NetBoxModelViewSet): ) ) serializer_class = ContractSerializer + filterset_class = filtersets.ContractFilterSet class InvoiceViewSet(NetBoxModelViewSet): @@ -44,6 +45,7 @@ class InvoiceLineViewSet(NetBoxModelViewSet): 'invoice', 'accounting_dimensions', 'tags' ) serializer_class = InvoiceLineSerializer + filterset_class = filtersets.InvoiceLineFilterSet class AccountingDimensionViewSet(NetBoxModelViewSet): diff --git a/src/netbox_contract/filtersets.py b/src/netbox_contract/filtersets.py index daf3426..493c602 100644 --- a/src/netbox_contract/filtersets.py +++ b/src/netbox_contract/filtersets.py @@ -1,11 +1,15 @@ import django_filters from django.db.models import Q from netbox.filtersets import NetBoxModelFilterSet +from tenancy.filtersets import TenancyFilterSet from .models import ( AccountingDimension, + AccountingDimensionStatusChoices, Contract, ContractAssignment, + CurrencyChoices, + InternalEntityChoices, Invoice, InvoiceLine, ServiceProvider, @@ -13,12 +17,26 @@ ) -class ContractFilterSet(NetBoxModelFilterSet): +class ContractFilterSet(NetBoxModelFilterSet, TenancyFilterSet): status = django_filters.MultipleChoiceFilter(choices=StatusChoices, null_value=None) + internal_partie = django_filters.MultipleChoiceFilter( + choices=InternalEntityChoices, null_value=None + ) + currency = django_filters.MultipleChoiceFilter( + choices=CurrencyChoices, null_value=None + ) class Meta: model = Contract - fields = ('id', 'name', 'internal_partie', 'external_reference', 'parent') + fields = ( + 'id', + 'name', + 'external_reference', + 'start_date', + 'end_date', + 'initial_term', + 'parent', + ) def search(self, queryset, name, value): return queryset.filter( @@ -30,9 +48,22 @@ def search(self, queryset, name, value): class InvoiceFilterSet(NetBoxModelFilterSet): + currency = django_filters.MultipleChoiceFilter( + choices=CurrencyChoices, null_value=None + ) + class Meta: model = Invoice - fields = ('id', 'number', 'template', 'contracts') + fields = ( + 'id', + 'number', + 'template', + 'date', + 'contracts', + 'period_start', + 'period_end', + 'amount', + ) def search(self, queryset, name, value): return queryset.filter( @@ -59,9 +90,13 @@ def search(self, queryset, name, value): class InvoiceLineFilterSet(NetBoxModelFilterSet): + currency = django_filters.MultipleChoiceFilter( + choices=CurrencyChoices, null_value=None + ) + class Meta: model = InvoiceLine - fields = ('id', 'invoice') + fields = ('id', 'invoice', 'accounting_dimensions') def search(self, queryset, name, value): return queryset.filter( @@ -70,6 +105,10 @@ def search(self, queryset, name, value): class AccountingDimensionFilterSet(NetBoxModelFilterSet): + status = django_filters.MultipleChoiceFilter( + choices=AccountingDimensionStatusChoices, null_value=None + ) + class Meta: model = AccountingDimension fields = ('name', 'value') diff --git a/src/netbox_contract/forms.py b/src/netbox_contract/forms.py index 27b71e7..c4185be 100644 --- a/src/netbox_contract/forms.py +++ b/src/netbox_contract/forms.py @@ -2,7 +2,6 @@ from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist, ValidationError -from extras.filters import TagFilter from netbox.forms import ( NetBoxModelBulkEditForm, NetBoxModelFilterSetForm, @@ -10,6 +9,7 @@ NetBoxModelImportForm, ) from tenancy.models import Tenant +from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES from utilities.forms.fields import ( CommentField, ContentTypeChoiceField, @@ -21,6 +21,7 @@ DynamicModelMultipleChoiceField, JSONField, SlugField, + TagFilterField, ) from utilities.forms.widgets import DatePicker, HTMXSelect @@ -161,9 +162,11 @@ class ContractFilterSetForm(NetBoxModelFilterSetForm): tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False) external_reference = forms.CharField(required=False) - internal_partie = forms.CharField(required=False) + internal_partie = forms.ChoiceField(choices=InternalEntityChoices, required=False) status = forms.ChoiceField(choices=StatusChoices, required=False) + currency = forms.ChoiceField(choices=CurrencyChoices, required=False) parent = DynamicModelChoiceField(queryset=Contract.objects.all(), required=False) + tag = TagFilterField(model) class ContractCSVForm(NetBoxModelImportForm): @@ -359,9 +362,15 @@ class Meta: class InvoiceFilterSetForm(NetBoxModelFilterSetForm): model = Invoice + number = forms.CharField(required=False) + template = forms.NullBooleanField( + required=False, widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES) + ) + currency = forms.ChoiceField(choices=CurrencyChoices, required=False) contracts = DynamicModelMultipleChoiceField( queryset=Contract.objects.all(), required=False ) + tag = TagFilterField(model) class InvoiceCSVForm(NetBoxModelImportForm): @@ -425,7 +434,8 @@ class Meta: class ServiceProviderFilterSetForm(NetBoxModelFilterSetForm): model = ServiceProvider - tag = TagFilter() + name = forms.CharField(required=False) + tag = TagFilterField(model) class ServiceProviderCSVForm(NetBoxModelImportForm): @@ -514,9 +524,11 @@ class Meta: class InvoiceLineFilterSetForm(NetBoxModelFilterSetForm): model = InvoiceLine invoice = DynamicModelChoiceField(queryset=Invoice.objects.all(), required=False) - accounting_dimensions = DynamicModelChoiceField( + accounting_dimensions = DynamicModelMultipleChoiceField( queryset=AccountingDimension.objects.all(), required=False ) + currency = forms.ChoiceField(choices=CurrencyChoices, required=False) + tag = TagFilterField(model) class InvoiceLineImportForm(NetBoxModelImportForm):