Skip to content

Commit

Permalink
Merge pull request #159 from mlebreuil/develop
Browse files Browse the repository at this point in the history
v2.2.2
  • Loading branch information
mlebreuil authored Aug 18, 2024
2 parents 2296dcf + 298137c commit 0858c5f
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 22 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@

## Version 2

### Version 2.2.2

* [154](https://github.com/mlebreuil/netbox-contract/issues/154) Fix edit and delete bulk operations on dimensions and invoice lines.
* [153](https://github.com/mlebreuil/netbox-contract/issues/153) Enforce uniquness of accounting dimensions.
* Adds a status ( Active or Inactive ) to accounitng dimensions.
* [151](https://github.com/mlebreuil/netbox-contract/issues/151) Fix accounting line and dimensions search.

### Version 2.2.1

* [142](https://github.com/mlebreuil/netbox-contract/issues/142) Gives the option to enter contract yearly recuring costs instead of only monthly recuring costs.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "netbox-contract"
version = "2.2.1"
version = "2.2.2"
authors = [
{ name="Marc Lebreuil", email="[email protected]" },
]
Expand Down
2 changes: 1 addition & 1 deletion src/netbox_contract/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class ContractsConfig(PluginConfig):
name = 'netbox_contract'
verbose_name = 'Netbox contract'
description = 'Contract management plugin for Netbox'
version = '2.2.1'
version = '2.2.2'
author = 'Marc Lebreuil'
author_email = '[email protected]'
base_url = 'contracts'
Expand Down
31 changes: 25 additions & 6 deletions src/netbox_contract/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Meta:

class NestedContractAssignmentSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_contract-api:ContractAssignment-detail'
view_name='plugins-api:netbox_contract-api:contractassignment-detail'
)

class Meta:
Expand All @@ -61,18 +61,25 @@ class Meta:

class NestedInvoicelineSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_contract-api:InvoiceLine-detail'
view_name='plugins-api:netbox_contract-api:invoiceline-detail'
)

class Meta:
model = InvoiceLine
fields = ('id', 'url', 'display', 'invoice', 'amount')
brief_fields = ('id', 'url', 'display', 'invoice', 'amount')
fields = ('id', 'url', 'display', 'invoice', 'accounting_dimensions', 'amount')
brief_fields = (
'id',
'url',
'display',
'invoice',
'accounting_dimensions',
'amount',
)


class NestedAccountingDimensionSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_contract-api:AccountingDimension-detail'
view_name='plugins-api:netbox_contract-api:accountingdimension-detail'
)

class Meta:
Expand Down Expand Up @@ -227,6 +234,10 @@ class InvoiceLineSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_contract-api:invoiceline-detail'
)
invoice = NestedInvoiceSerializer(many=False, required=False)
accounting_dimensions = NestedAccountingDimensionSerializer(
many=True, required=False
)

class Meta:
model = InvoiceLine
Expand All @@ -237,13 +248,21 @@ class Meta:
'invoice',
'amount',
'currency',
'accounting_dimensions',
'comments',
'tags',
'custom_fields',
'created',
'last_updated',
)
brief_fields = ('invoice', 'amount', 'url', 'display', 'name')
brief_fields = (
'invoice',
'accounting_dimensions',
'amount',
'url',
'display',
'name',
)


class AccountingDimensionSerializer(NetBoxModelSerializer):
Expand Down
4 changes: 3 additions & 1 deletion src/netbox_contract/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ class ContractAssignmentViewSet(NetBoxModelViewSet):


class InvoiceLineViewSet(NetBoxModelViewSet):
queryset = models.InvoiceLine.objects.prefetch_related('invoice', 'tags')
queryset = models.InvoiceLine.objects.prefetch_related(
'invoice', 'accounting_dimensions', 'tags'
)
serializer_class = InvoiceLineSerializer


Expand Down
6 changes: 2 additions & 4 deletions src/netbox_contract/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class Meta:

def search(self, queryset, name, value):
return queryset.filter(
Q(comments__icontains=value) | Q(invoice__name__icontains=value)
Q(comments__icontains=value) | Q(invoice__number__icontains=value)
)


Expand All @@ -71,6 +71,4 @@ class Meta:
fields = ('name', 'value')

def search(self, queryset, name, value):
return queryset.filter(
Q(comments__icontains=value) | Q(invoice__name__icontains=value)
)
return queryset.filter(Q(comments__icontains=value) | Q(name__icontains=value))
21 changes: 15 additions & 6 deletions src/netbox_contract/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from .constants import SERVICE_PROVIDER_MODELS
from .models import (
AccountingDimension,
AccountingDimensionStatusChoices,
Contract,
ContractAssignment,
InternalEntityChoices,
Expand Down Expand Up @@ -147,7 +148,7 @@ class Meta:
def clean(self):
super().clean()

if self.cleaned_data['mrc'] and self.cleaned_data['mrc']:
if self.cleaned_data['mrc'] and self.cleaned_data['yrc']:
raise ValidationError(
'you should set monthly OR yearly recuring costs not both'
)
Expand Down Expand Up @@ -488,10 +489,7 @@ class Meta:

class InvoiceLineFilterSetForm(NetBoxModelFilterSetForm):
model = InvoiceLine
invoice = DynamicModelChoiceField(queryset=Invoice.objects.all())
accounting_dimensions = DynamicModelMultipleChoiceField(
queryset=AccountingDimension.objects.all()
)
invoice = DynamicModelChoiceField(queryset=Invoice.objects.all(), required=False)


class InvoiceLineImportForm(NetBoxModelImportForm):
Expand All @@ -502,7 +500,8 @@ class InvoiceLineImportForm(NetBoxModelImportForm):
)
accounting_dimensions = CSVModelChoiceField(
queryset=AccountingDimension.objects.all(),
help_text='accounting dimention in the form name, value',
to_field_name='id',
help_text='accounting dimension id',
)

class Meta:
Expand Down Expand Up @@ -534,6 +533,7 @@ class Meta:
fields = [
'name',
'value',
'status',
'comments',
'tags',
]
Expand All @@ -542,17 +542,26 @@ class Meta:
class AccountingDimensionFilterSetForm(NetBoxModelFilterSetForm):
model = AccountingDimension

name = forms.CharField(required=False)
value = forms.CharField(required=False)
status = forms.ChoiceField(choices=AccountingDimensionStatusChoices, required=False)


class AccountingDimensionImportForm(NetBoxModelImportForm):
status = CSVChoiceField(choices=StatusChoices, help_text='Contract status')

class Meta:
model = AccountingDimension
fields = [
'name',
'value',
'status',
'comments',
'tags',
]


class AccountingDimensionBulkEditForm(NetBoxModelBulkEditForm):
name = forms.CharField(max_length=20, required=False)
value = forms.CharField(max_length=20, required=False)
model = AccountingDimension
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 5.0.6 on 2024-08-18 10:03

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
('extras', '0115_convert_dashboard_widgets'),
('netbox_contract', '0034_contract_yrc_alter_contract_mrc'),
]

operations = [
migrations.AddField(
model_name='accountingdimension',
name='status',
field=models.CharField(default='Active', max_length=50),
),
migrations.AddConstraint(
model_name='accountingdimension',
constraint=models.UniqueConstraint(
fields=('name', 'value'), name='unique_accounting_dimension'
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 5.0.6 on 2024-08-18 19:37

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
('netbox_contract', '0035_accountingdimension_status_and_more'),
]

operations = [
migrations.AlterField(
model_name='invoiceline',
name='accounting_dimensions',
field=models.ManyToManyField(
blank=True, to='netbox_contract.accountingdimension'
),
),
]
28 changes: 25 additions & 3 deletions src/netbox_contract/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ class StatusChoices(ChoiceSet):
]


class AccountingDimensionStatusChoices(ChoiceSet):
key = 'AccountingDimension.status'

STATUS_ACTIVE = 'Active'
STATUS_INACTIVE = 'Inactive'

CHOICES = [
(STATUS_ACTIVE, 'Active', 'green'),
(STATUS_INACTIVE, 'Inactive', 'red'),
]


class InternalEntityChoices(ChoiceSet):
key = 'Contract.internal_partie'

Expand All @@ -44,6 +56,11 @@ class CurrencyChoices(ChoiceSet):
class AccountingDimension(NetBoxModel):
name = models.CharField(max_length=20)
value = models.CharField(max_length=20)
status = models.CharField(
max_length=50,
choices=AccountingDimensionStatusChoices,
default=StatusChoices.STATUS_ACTIVE,
)
comments = models.TextField(blank=True)

def get_absolute_url(self):
Expand All @@ -56,6 +73,13 @@ def dimension(self):
def __str__(self):
return self.dimension

class Meta:
constraints = [
models.UniqueConstraint(
fields=['name', 'value'], name='unique_accounting_dimension'
)
]


class ServiceProvider(ContactsMixin, NetBoxModel):
name = models.CharField(max_length=100)
Expand Down Expand Up @@ -215,9 +239,7 @@ class InvoiceLine(NetBoxModel):
max_length=3, choices=CurrencyChoices, default=CurrencyChoices.CURRENCY_USD
)
amount = models.DecimalField(max_digits=10, decimal_places=2)
accounting_dimensions = models.ManyToManyField(
AccountingDimension, related_name='invoicelines', blank=True
)
accounting_dimensions = models.ManyToManyField(AccountingDimension, blank=True)
comments = models.TextField(blank=True)

def get_absolute_url(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ <h5 class="card-header">Accounting dimension</h5>
<th scope="row">value</th>
<td>{{ object.value }}</td>
</tr>
<tr>
<th scope="row">status</th>
<td>{{ object.status }}</td>
</tr>
</table>
</div>
{% include 'inc/panels/custom_fields.html' %}
Expand Down
20 changes: 20 additions & 0 deletions src/netbox_contract/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@
views.InvoiceLineBulkImportView.as_view(),
name='invoiceline_import',
),
path(
'invoiceline/edit/',
views.InvoiceLineBulkEditView.as_view(),
name='invoiceline_bulk_edit',
),
path(
'invoiceline/delete/',
views.InvoiceLineBulkDeleteView.as_view(),
name='invoiceline_bulk_delete',
),
path(
'invoiceline/<int:pk>/',
views.InvoiceLineView.as_view(),
Expand Down Expand Up @@ -219,6 +229,16 @@
views.AccountingDimensionBulkImportView.as_view(),
name='accountingdimension_import',
),
path(
'accountingdimension/edit/',
views.AccountingDimensionBulkEditView.as_view(),
name='accountingdimension_bulk_edit',
),
path(
'accountingdimension/delete/',
views.AccountingDimensionBulkDeleteView.as_view(),
name='accountingdimension_bulk_delete',
),
path(
'accountingdimension/<int:pk>/',
views.AccountingDimensionView.as_view(),
Expand Down

0 comments on commit 0858c5f

Please sign in to comment.