Filtrer les factures (#73918) #25
|
@ -19,7 +19,7 @@ import django_filters
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext_lazy as _
|
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):
|
class CampaignForm(forms.ModelForm):
|
||||||
|
@ -51,17 +51,74 @@ def regie_queryset(request):
|
||||||
return Regie.objects.all()
|
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):
|
class AbstractLineFilterSet(django_filters.FilterSet):
|
||||||
regie = django_filters.ModelChoiceFilter(
|
regie = django_filters.ModelChoiceFilter(
|
||||||
label=_('Regie'),
|
label=_('Regie'),
|
||||||
queryset=regie_queryset,
|
queryset=regie_queryset,
|
||||||
field_name='invoice__regie',
|
field_name='invoice__regie',
|
||||||
)
|
)
|
||||||
|
# for InvoiceLine
|
||||||
invoice_number = django_filters.CharFilter(
|
invoice_number = django_filters.CharFilter(
|
||||||
label=_('Invoice number'),
|
label=_('Invoice number'),
|
||||||
field_name='invoice__formatted_number',
|
field_name='invoice__formatted_number',
|
||||||
lookup_expr='contains',
|
lookup_expr='contains',
|
||||||
)
|
)
|
||||||
|
# for DraftInvoiceLine
|
||||||
invoice_id = django_filters.NumberFilter(
|
invoice_id = django_filters.NumberFilter(
|
||||||
label=_('Invoice number'),
|
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 %}
|
{% for line in object_list %}
|
||||||
<li class="line" data-invoice-id="{{ line.invoice_id }}">
|
<li class="line" data-invoice-id="{{ line.invoice_id }}">
|
||||||
<a href="{{ journal_url }}?pk={{ line.pk }}">#{{ line.pk }}</a>
|
<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 }})
|
- {{ line.event_date|date:"d/m/Y" }} - {{ line.label }} ({{ line.total_amount }})
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -25,7 +25,27 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% 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>
|
<div>
|
||||||
<ul class="objects-list">
|
<ul class="objects-list">
|
||||||
{% for invoice in object_list %}
|
{% for invoice in object_list %}
|
||||||
|
|
|
@ -39,7 +39,13 @@ from django.views.generic import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from lingo.agendas.models import Agenda
|
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 (
|
from lingo.invoicing.models import (
|
||||||
Campaign,
|
Campaign,
|
||||||
DraftInvoice,
|
DraftInvoice,
|
||||||
|
@ -313,13 +319,21 @@ class PoolDetailView(ListView):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
invoice_model = Invoice
|
invoice_model = Invoice
|
||||||
|
filter_model = InvoiceFilterSet
|
||||||
if self.object.draft:
|
if self.object.draft:
|
||||||
invoice_model = DraftInvoice
|
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):
|
def get_context_data(self, **kwargs):
|
||||||
kwargs['object'] = self.campaign
|
kwargs['object'] = self.campaign
|
||||||
kwargs['pool'] = self.object
|
kwargs['pool'] = self.object
|
||||||
|
kwargs['filterset'] = self.filterset
|
||||||
line_model = InvoiceLine
|
line_model = InvoiceLine
|
||||||
line_values = ['status', 'error_status']
|
line_values = ['status', 'error_status']
|
||||||
if self.object.draft:
|
if self.object.draft:
|
||||||
|
@ -461,16 +475,21 @@ class InvoiceLineListView(ListView):
|
||||||
template_name = 'lingo/invoicing/manager_invoice_lines.html'
|
template_name = 'lingo/invoicing/manager_invoice_lines.html'
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
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
|
invoice_model = Invoice
|
||||||
if pool.draft:
|
if self.pool.draft:
|
||||||
invoice_model = DraftInvoice
|
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)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return self.invoice.lines.all().order_by('user_external_id', 'event_date', 'pk')
|
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()
|
invoice_line_list = InvoiceLineListView.as_view()
|
||||||
|
|
||||||
|
|
|
@ -540,12 +540,13 @@ def test_detail_pool_invoices(app, admin_user, draft):
|
||||||
draft=draft,
|
draft=draft,
|
||||||
status='completed',
|
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(
|
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(
|
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:
|
if not draft:
|
||||||
invoice1.set_number()
|
invoice1.set_number()
|
||||||
|
@ -627,7 +628,7 @@ def test_detail_pool_invoices(app, admin_user, draft):
|
||||||
assert resp.pyquery(
|
assert resp.pyquery(
|
||||||
'li[data-invoice-id="%s"]' % invoice1.pk
|
'li[data-invoice-id="%s"]' % invoice1.pk
|
||||||
).text() == 'Invoice F%02s-%s-0000001 addressed to payer:1, amount 6.00€' % (
|
).text() == 'Invoice F%02s-%s-0000001 addressed to payer:1, amount 6.00€' % (
|
||||||
regie.pk,
|
regie1.pk,
|
||||||
invoice1.created_at.strftime('%y-%m'),
|
invoice1.created_at.strftime('%y-%m'),
|
||||||
)
|
)
|
||||||
lines_url = resp.pyquery('li[data-invoice-id="%s"]' % invoice1.pk).attr('data-invoice-lines-url')
|
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 len(lines_resp.pyquery('li')) == 3
|
||||||
assert (
|
assert (
|
||||||
lines_resp.pyquery('li:nth-child(1)').text()
|
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 (
|
assert (
|
||||||
lines_resp.pyquery('li:nth-child(2)').text()
|
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 (
|
assert (
|
||||||
lines_resp.pyquery('li:nth-child(3)').text()
|
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:
|
if draft:
|
||||||
assert (
|
assert (
|
||||||
|
@ -658,8 +659,8 @@ def test_detail_pool_invoices(app, admin_user, draft):
|
||||||
else:
|
else:
|
||||||
assert resp.pyquery(
|
assert resp.pyquery(
|
||||||
'li[data-invoice-id="%s"]' % invoice2.pk
|
'li[data-invoice-id="%s"]' % invoice2.pk
|
||||||
).text() == 'Invoice F%02d-%s-0000002 addressed to payer:2, amount 1.00€' % (
|
).text() == 'Invoice F%02d-%s-0000001 addressed to payer:2, amount 1.00€' % (
|
||||||
regie.pk,
|
regie2.pk,
|
||||||
invoice2.created_at.strftime('%y-%m'),
|
invoice2.created_at.strftime('%y-%m'),
|
||||||
)
|
)
|
||||||
lines_url = resp.pyquery('li[data-invoice-id="%s"]' % invoice2.pk).attr('data-invoice-lines-url')
|
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 len(lines_resp.pyquery('li')) == 1
|
||||||
assert (
|
assert (
|
||||||
lines_resp.pyquery('li:nth-child(1)').text()
|
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):
|
def test_journal_pool(app, admin_user):
|
||||||
campaign = Campaign.objects.create(
|
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