Filtrer les factures (#73918) #25
|
@ -19,7 +19,7 @@ import django_filters
|
|||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from lingo.invoicing.models import Campaign, DraftInvoiceLine, InvoiceLine, Regie
|
||||
from lingo.invoicing.models import Campaign, DraftInvoice, DraftInvoiceLine, Invoice, InvoiceLine, Regie
|
||||
|
||||
|
||||
class CampaignForm(forms.ModelForm):
|
||||
|
@ -51,17 +51,74 @@ def regie_queryset(request):
|
|||
return Regie.objects.all()
|
||||
|
||||
|
||||
class AbstractInvoiceFilterSet(django_filters.FilterSet):
|
||||
regie = django_filters.ModelChoiceFilter(
|
||||
label=_('Regie'),
|
||||
queryset=regie_queryset,
|
||||
)
|
||||
# for Invoice
|
||||
lguerin marked this conversation as resolved
Outdated
|
||||
number = django_filters.CharFilter(
|
||||
label=_('Invoice number'),
|
||||
field_name='formatted_number',
|
||||
lookup_expr='contains',
|
||||
)
|
||||
# for DraftInvoice
|
||||
pk = django_filters.NumberFilter(
|
||||
label=_('Invoice number'),
|
||||
)
|
||||
payer_external_id = django_filters.CharFilter(
|
||||
label=_('Payer (external ID)'),
|
||||
field_name='payer',
|
||||
)
|
||||
user_external_id = django_filters.CharFilter(
|
||||
label=_('User (external ID)'),
|
||||
method='filter_user_external_id',
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.pool = kwargs.pop('pool')
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
if self.pool.draft:
|
||||
del self.filters['number']
|
||||
else:
|
||||
del self.filters['pk']
|
||||
|
||||
def filter_user_external_id(self, queryset, name, value):
|
||||
if not value:
|
||||
return queryset
|
||||
line_model = InvoiceLine
|
||||
if self.pool.draft:
|
||||
line_model = DraftInvoiceLine
|
||||
lines = line_model.objects.filter(user_external_id=value).values('invoice')
|
||||
return queryset.filter(pk__in=lines)
|
||||
|
||||
|
||||
class DraftInvoiceFilterSet(AbstractInvoiceFilterSet):
|
||||
class Meta:
|
||||
model = DraftInvoice
|
||||
fields = []
|
||||
|
||||
|
||||
class InvoiceFilterSet(AbstractInvoiceFilterSet):
|
||||
class Meta:
|
||||
model = Invoice
|
||||
fields = []
|
||||
|
||||
|
||||
class AbstractLineFilterSet(django_filters.FilterSet):
|
||||
regie = django_filters.ModelChoiceFilter(
|
||||
label=_('Regie'),
|
||||
queryset=regie_queryset,
|
||||
field_name='invoice__regie',
|
||||
)
|
||||
# for InvoiceLine
|
||||
invoice_number = django_filters.CharFilter(
|
||||
label=_('Invoice number'),
|
||||
field_name='invoice__formatted_number',
|
||||
lookup_expr='contains',
|
||||
)
|
||||
# for DraftInvoiceLine
|
||||
invoice_id = django_filters.NumberFilter(
|
||||
label=_('Invoice number'),
|
||||
)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{% url 'lingo-manager-invoicing-pool-journal' pk=object.pk pool_pk=pool.pk as journal_url %}
|
||||
{% for line in object_list %}
|
||||
<li class="line" data-invoice-id="{{ line.invoice_id }}">
|
||||
<a href="{{ journal_url }}?pk={{ line.pk }}">#{{ line.pk }}</a>
|
||||
<a href="{{ journal_url }}?user_external_id={{ line.user_external_id }}">{{ line.user_name }}</a>
|
||||
<a href="{{ journal_url }}?user_external_id={{ line.user_external_id }}">{{ line.user_name }} ({{ line.user_external_id }})</a>
|
||||
- {{ line.event_date|date:"d/m/Y" }} - {{ line.label }} ({{ line.total_amount }})
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
|
|
@ -25,7 +25,27 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% url 'lingo-manager-invoicing-pool-journal' pk=object.pk pool_pk=pool.pk as journal_url %}
|
||||
<div class="section">
|
||||
<div>
|
||||
<form class="invoice-filters">
|
||||
<fieldset class="gadjo-foldable gadjo-folded" id="filters">
|
||||
<legend class="gadjo-foldable-widget">{% trans "Invoice Filtering" %}</legend>
|
||||
<div class="gadjo-folding">
|
||||
{{ filterset.form.as_p }}
|
||||
</div>
|
||||
</fieldset>
|
||||
<script>
|
||||
$(function() {
|
||||
$('form.invoice-filters input,select').on('change',
|
||||
function() {
|
||||
$(this).parents('form').submit();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% url 'lingo-manager-invoicing-pool-journal' pk=object.pk pool_pk=pool.pk as journal_url %}
|
||||
<div>
|
||||
<ul class="objects-list">
|
||||
{% for invoice in object_list %}
|
||||
|
|
|
@ -39,7 +39,13 @@ from django.views.generic import (
|
|||
)
|
||||
|
||||
from lingo.agendas.models import Agenda
|
||||
from lingo.invoicing.forms import CampaignForm, DraftInvoiceLineFilterSet, InvoiceLineFilterSet
|
||||
from lingo.invoicing.forms import (
|
||||
CampaignForm,
|
||||
DraftInvoiceFilterSet,
|
||||
DraftInvoiceLineFilterSet,
|
||||
InvoiceFilterSet,
|
||||
InvoiceLineFilterSet,
|
||||
)
|
||||
from lingo.invoicing.models import (
|
||||
Campaign,
|
||||
DraftInvoice,
|
||||
|
@ -313,13 +319,21 @@ class PoolDetailView(ListView):
|
|||
|
||||
def get_queryset(self):
|
||||
invoice_model = Invoice
|
||||
filter_model = InvoiceFilterSet
|
||||
if self.object.draft:
|
||||
invoice_model = DraftInvoice
|
||||
return invoice_model.objects.filter(pool=self.object)
|
||||
filter_model = DraftInvoiceFilterSet
|
||||
|
||||
data = self.request.GET or None
|
||||
self.filterset = filter_model(
|
||||
data=data, queryset=invoice_model.objects.filter(pool=self.object), pool=self.object
|
||||
)
|
||||
return self.filterset.qs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs['object'] = self.campaign
|
||||
kwargs['pool'] = self.object
|
||||
kwargs['filterset'] = self.filterset
|
||||
line_model = InvoiceLine
|
||||
line_values = ['status', 'error_status']
|
||||
if self.object.draft:
|
||||
|
@ -461,16 +475,21 @@ class InvoiceLineListView(ListView):
|
|||
template_name = 'lingo/invoicing/manager_invoice_lines.html'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
pool = get_object_or_404(Pool, pk=kwargs['pool_pk'], campaign_id=kwargs['pk'])
|
||||
self.pool = get_object_or_404(Pool, pk=kwargs['pool_pk'], campaign_id=kwargs['pk'])
|
||||
invoice_model = Invoice
|
||||
if pool.draft:
|
||||
if self.pool.draft:
|
||||
invoice_model = DraftInvoice
|
||||
self.invoice = get_object_or_404(invoice_model, pk=kwargs['invoice_pk'], pool=pool)
|
||||
self.invoice = get_object_or_404(invoice_model, pk=kwargs['invoice_pk'], pool=self.pool)
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_queryset(self):
|
||||
return self.invoice.lines.all().order_by('user_external_id', 'event_date', 'pk')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs['object'] = self.pool.campaign
|
||||
kwargs['pool'] = self.pool
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
invoice_line_list = InvoiceLineListView.as_view()
|
||||
|
||||
|
|
|
@ -540,12 +540,13 @@ def test_detail_pool_invoices(app, admin_user, draft):
|
|||
draft=draft,
|
||||
status='completed',
|
||||
)
|
||||
regie = Regie.objects.create(label='Foo')
|
||||
regie1 = Regie.objects.create(label='Foo1')
|
||||
regie2 = Regie.objects.create(label='Foo1')
|
||||
invoice1 = invoice_model.objects.create(
|
||||
date_issue=datetime.date.today(), regie=regie, pool=pool, payer='payer:1'
|
||||
date_issue=datetime.date.today(), regie=regie1, pool=pool, payer='payer:1'
|
||||
)
|
||||
invoice2 = invoice_model.objects.create(
|
||||
date_issue=datetime.date.today(), regie=regie, pool=pool, payer='payer:2'
|
||||
date_issue=datetime.date.today(), regie=regie2, pool=pool, payer='payer:2'
|
||||
)
|
||||
if not draft:
|
||||
invoice1.set_number()
|
||||
|
@ -627,7 +628,7 @@ def test_detail_pool_invoices(app, admin_user, draft):
|
|||
assert resp.pyquery(
|
||||
'li[data-invoice-id="%s"]' % invoice1.pk
|
||||
).text() == 'Invoice F%02s-%s-0000001 addressed to payer:1, amount 6.00€' % (
|
||||
regie.pk,
|
||||
regie1.pk,
|
||||
invoice1.created_at.strftime('%y-%m'),
|
||||
)
|
||||
lines_url = resp.pyquery('li[data-invoice-id="%s"]' % invoice1.pk).attr('data-invoice-lines-url')
|
||||
|
@ -640,15 +641,15 @@ def test_detail_pool_invoices(app, admin_user, draft):
|
|||
assert len(lines_resp.pyquery('li')) == 3
|
||||
assert (
|
||||
lines_resp.pyquery('li:nth-child(1)').text()
|
||||
== '#%s User1 Name1 - 01/09/2022 - Label 11 (1.00)' % line11.pk
|
||||
== '#%s User1 Name1 (user:1) - 01/09/2022 - Label 11 (1.00)' % line11.pk
|
||||
)
|
||||
assert (
|
||||
lines_resp.pyquery('li:nth-child(2)').text()
|
||||
== '#%s User1 Name1 - 03/09/2022 - Label 13 (3.00)' % line13.pk
|
||||
== '#%s User1 Name1 (user:1) - 03/09/2022 - Label 13 (3.00)' % line13.pk
|
||||
)
|
||||
assert (
|
||||
lines_resp.pyquery('li:nth-child(3)').text()
|
||||
== '#%s User2 Name2 - 02/09/2022 - Label 12 (2.00)' % line12.pk
|
||||
== '#%s User2 Name2 (user:2) - 02/09/2022 - Label 12 (2.00)' % line12.pk
|
||||
)
|
||||
if draft:
|
||||
assert (
|
||||
|
@ -658,8 +659,8 @@ def test_detail_pool_invoices(app, admin_user, draft):
|
|||
else:
|
||||
assert resp.pyquery(
|
||||
'li[data-invoice-id="%s"]' % invoice2.pk
|
||||
).text() == 'Invoice F%02d-%s-0000002 addressed to payer:2, amount 1.00€' % (
|
||||
regie.pk,
|
||||
).text() == 'Invoice F%02d-%s-0000001 addressed to payer:2, amount 1.00€' % (
|
||||
regie2.pk,
|
||||
invoice2.created_at.strftime('%y-%m'),
|
||||
)
|
||||
lines_url = resp.pyquery('li[data-invoice-id="%s"]' % invoice2.pk).attr('data-invoice-lines-url')
|
||||
|
@ -672,9 +673,53 @@ def test_detail_pool_invoices(app, admin_user, draft):
|
|||
assert len(lines_resp.pyquery('li')) == 1
|
||||
assert (
|
||||
lines_resp.pyquery('li:nth-child(1)').text()
|
||||
== '#%s User1 Name1 - 01/09/2022 - Label 21 (1.00)' % line21.pk
|
||||
== '#%s User1 Name1 (user:1) - 01/09/2022 - Label 21 (1.00)' % line21.pk
|
||||
)
|
||||
|
||||
# test filters
|
||||
resp = app.get(
|
||||
'/manage/invoicing/campaign/%s/pool/%s/' % (campaign.pk, pool.pk),
|
||||
params={'regie': regie1.pk},
|
||||
)
|
||||
assert len(resp.pyquery('li.invoice')) == 1
|
||||
if draft:
|
||||
resp = app.get(
|
||||
'/manage/invoicing/campaign/%s/pool/%s/' % (campaign.pk, pool.pk),
|
||||
params={'pk': invoice1.pk},
|
||||
)
|
||||
assert len(resp.pyquery('li.invoice')) == 1
|
||||
else:
|
||||
resp = app.get(
|
||||
'/manage/invoicing/campaign/%s/pool/%s/' % (campaign.pk, pool.pk),
|
||||
params={'number': invoice1.formatted_number},
|
||||
)
|
||||
assert len(resp.pyquery('li.invoice')) == 1
|
||||
resp = app.get(
|
||||
'/manage/invoicing/campaign/%s/pool/%s/' % (campaign.pk, pool.pk),
|
||||
params={'number': invoice1.created_at.strftime('%y-%m')},
|
||||
)
|
||||
assert len(resp.pyquery('li.invoice')) == 2
|
||||
resp = app.get(
|
||||
'/manage/invoicing/campaign/%s/pool/%s/' % (campaign.pk, pool.pk),
|
||||
params={'payer_external_id': 'payer:1'},
|
||||
)
|
||||
assert len(resp.pyquery('li.invoice')) == 1
|
||||
resp = app.get(
|
||||
'/manage/invoicing/campaign/%s/pool/%s/' % (campaign.pk, pool.pk),
|
||||
params={'payer_external_id': 'payer:2'},
|
||||
)
|
||||
assert len(resp.pyquery('li.invoice')) == 1
|
||||
resp = app.get(
|
||||
'/manage/invoicing/campaign/%s/pool/%s/' % (campaign.pk, pool.pk),
|
||||
params={'user_external_id': 'user:1'},
|
||||
)
|
||||
assert len(resp.pyquery('li.invoice')) == 2
|
||||
resp = app.get(
|
||||
'/manage/invoicing/campaign/%s/pool/%s/' % (campaign.pk, pool.pk),
|
||||
params={'user_external_id': 'user:2'},
|
||||
)
|
||||
assert len(resp.pyquery('li.invoice')) == 1
|
||||
|
||||
|
||||
def test_journal_pool(app, admin_user):
|
||||
campaign = Campaign.objects.create(
|
||||
|
|
Loading…
Reference in New Issue
peut-être un commentaire ici qui explique que number et pk ne seront jamais affichés ensemble, que number est pour les vraies factures et pk pour les brouillons ?
commentaires ajoutés