facturation: valider un bordereau de remise de règlements (#88700) #179

Merged
lguerin merged 2 commits from wip/88700-invoicing-docket-validate into main 2024-04-08 09:58:29 +02:00
8 changed files with 92 additions and 10 deletions

View File

@ -85,6 +85,7 @@
<h3>{% trans "Actions" %}</h3>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-regie-docket-edit' regie.pk object.pk %}">{% trans "Edit" %}</a>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-regie-docket-validate' regie.pk object.pk %}" rel="popup">{% trans "Validate" %}</a>
</aside>
{% endif %}
{% endblock %}

View File

@ -1,6 +1,8 @@
{% extends "lingo/invoicing/manager_docket_payment_list.html" %}
{% extends "lingo/invoicing/manager_regie_detail.html" %}
{% load gadjo i18n %}
{% block page-title-extra-label %}{% trans "Dockets" %} | {{ block.super }}{% endblock %}
{% block breadcrumb %}
{{ block.super }}
<a href="{% url 'lingo-manager-invoicing-regie-docket-list' regie_pk=regie.pk %}">{% trans "Dockets" %}</a>
@ -52,4 +54,10 @@
{% endblock %}
{% block sidebar %}
<aside id="sidebar">
<h3>{% trans "Navigation" %}</h3>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-regie-docket-payment-list' regie_pk=regie.pk %}">{% trans "Payments outside dockets" %}</a>
</aside>
{% endblock %}

View File

@ -1,8 +1,6 @@
{% extends "lingo/invoicing/manager_regie_detail.html" %}
{% extends "lingo/invoicing/manager_docket_list.html" %}
{% load gadjo i18n %}
{% block page-title-extra-label %}{% trans "Dockets" %} | {{ block.super }}{% endblock %}
{% block breadcrumb %}
{{ block.super }}
<a href="{% url 'lingo-manager-invoicing-regie-docket-payment-list' regie_pk=regie.pk %}">{% trans "Payments outside dockets" %}</a>
@ -53,8 +51,5 @@
</div>
{% endif %}
<h3>{% trans "Navigation" %}</h3>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-regie-docket-list' regie_pk=regie.pk %}">{% trans "Dockets" %}</a>
</aside>
{% endblock %}

View File

@ -0,0 +1,22 @@
{% extends "lingo/invoicing/manager_docket_detail.html" %}
{% load i18n %}
{% block breadcrumb %}
{{ block.super }}
<a href="{% url 'lingo-manager-invoicing-regie-docket-validate' regie_pk=regie.pk pk=object.pk %}">{% trans "Validate" %}</a>
{% endblock %}
{% block appbar %}
<h2>{% trans "Validate" %}</h2>
{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
<p>{% trans "Are you sure you want to validate this docket ?" %}</p>
<div class="buttons">
<button class="submit-button">{% trans "Validate" %}</button>
<a class="cancel" href="{% url 'lingo-manager-invoicing-regie-docket-detail' regie_pk=regie.pk pk=object.pk %}">{% trans 'Cancel' %}</a>
</div>
</form>
{% endblock %}

View File

@ -50,7 +50,7 @@
<h3>{% trans "Navigation" %}</h3>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-regie-invoice-list' regie_pk=regie.pk %}">{% trans 'Invoices' %}</a>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-regie-payment-list' regie_pk=regie.pk %}">{% trans 'Payments' %}</a>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-regie-docket-payment-list' regie_pk=regie.pk %}">{% trans 'Dockets' %}</a>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-regie-docket-list' regie_pk=regie.pk %}">{% trans 'Dockets' %}</a>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-regie-credit-list' regie_pk=regie.pk %}">{% trans 'Credits' %}</a>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-regie-refund-list' regie_pk=regie.pk %}">{% trans 'Refunds' %}</a>
<a class="button button-paragraph" href="{% url 'lingo-manager-invoicing-non-invoiced-line-list' regie_pk=regie.pk %}">{% trans 'Non invoiced lines' %}</a>

View File

@ -238,6 +238,11 @@ urlpatterns = [
regie_views.regie_docket_payment_type_edit,
name='lingo-manager-invoicing-regie-docket-payment-type-edit',
),
path(
'regie/<int:regie_pk>/docket/<int:pk>/validate/',
regie_views.regie_docket_validate,
name='lingo-manager-invoicing-regie-docket-validate',
),
path(
'regie/<int:regie_pk>/docket/<int:pk>/delete/',
regie_views.regie_docket_delete,

View File

@ -34,11 +34,11 @@ from django.db.models import (
)
from django.db.models.functions import Coalesce
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404
from django.shortcuts import get_object_or_404, redirect
from django.template.defaultfilters import yesno
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DeleteView, DetailView, ListView, UpdateView
from django.views.generic import CreateView, DeleteView, DetailView, FormView, ListView, UpdateView
from lingo.agendas.models import Agenda
from lingo.export_import.views import WithApplicationsMixin
@ -950,6 +950,37 @@ class RegieDocketPaymentTypeEditView(UpdateView):
regie_docket_payment_type_edit = RegieDocketPaymentTypeEditView.as_view()
class RegieDocketValidateView(FormView):
template_name = 'lingo/invoicing/manager_docket_validate.html'
def dispatch(self, request, *args, **kwargs):
self.regie = get_object_or_404(Regie, pk=kwargs['regie_pk'])
self.object = get_object_or_404(
PaymentDocket,
regie=self.regie,
pk=kwargs['pk'],
draft=True,
)
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
kwargs['form'] = None
kwargs['regie'] = self.regie
kwargs['object'] = self.object
return super().get_context_data(**kwargs)
def post(self, request, *args, **kwargs):
self.object.draft = False
self.object.set_number()
self.object.save()
return redirect(
reverse('lingo-manager-invoicing-regie-docket-detail', args=[self.regie.pk, self.object.pk])
)
regie_docket_validate = RegieDocketValidateView.as_view()
class RegieDocketDeleteView(DeleteView):
template_name = 'lingo/manager_confirm_delete.html'
model = PaymentDocket

View File

@ -90,6 +90,7 @@ def test_regie_payments_outside_dockets(app, admin_user):
app = login(app)
resp = app.get('/manage/invoicing/regie/%s/' % regie.pk)
resp = resp.click('Dockets')
resp = resp.click('Payments outside dockets')
assert [PyQuery(tr).text() for tr in resp.pyquery('tr')] == [
'Payment R%02d-%s-0000003 dated %s from First3 Name3, amount 2.00€ (Credit card)'
% (regie.pk, payment3.created_at.strftime('%y-%m'), payment3.created_at.strftime('%d/%m/%Y')),
@ -263,6 +264,7 @@ def test_regie_docket_add(app, admin_user):
assert docket.regie == regie
assert docket.draft is True
assert docket.date_end == now().date()
assert docket.formatted_number == ''
assert list(docket.payment_types.all()) == list(PaymentType.objects.all())
assert list(docket.payment_set.all().order_by('-pk')) == [payment3, payment2, payment1]
@ -522,6 +524,7 @@ def test_regie_docket_edit(app, admin_user):
docket.refresh_from_db()
assert docket.draft is True
assert docket.date_end == now().date()
assert docket.formatted_number == ''
assert list(docket.payment_types.all()) == list(PaymentType.objects.filter(slug__in=['cash', 'check']))
assert list(docket.payment_set.all().order_by('-pk')) == [payment2, payment1]
@ -608,6 +611,23 @@ def test_regie_docket_payment_type_edit(app, admin_user):
}
def test_regie_docket_validate(app, admin_user):
regie = Regie.objects.create(label='Foo')
PaymentType.create_defaults(regie)
docket = PaymentDocket.objects.create(regie=regie, date_end=now().date(), draft=True)
app = login(app)
resp = app.get('/manage/invoicing/regie/%s/docket/%s/' % (regie.pk, docket.pk))
resp = resp.click('Validate')
resp = resp.form.submit()
assert resp.location.endswith('/manage/invoicing/regie/%s/docket/%s/' % (regie.pk, docket.pk))
docket.refresh_from_db()
assert docket.draft is False
assert docket.formatted_number == 'B%02d-%s-0000001' % (regie.pk, docket.created_at.strftime('%y-%m'))
app.get('/manage/invoicing/regie/%s/docket/%s/validate/' % (regie.pk, docket.pk), status=404)
def test_regie_docket_delete(app, admin_user):
regie = Regie.objects.create(label='Foo')
PaymentType.create_defaults(regie)