epayment: display list of transactions on epayment page (#83206)
gitea/lingo/pipeline/head This commit looks good Details

This commit is contained in:
Frédéric Péters 2023-11-07 15:02:10 +01:00
parent 6b380cc0b1
commit 87828eb1cc
8 changed files with 180 additions and 11 deletions

View File

@ -14,11 +14,14 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import django_filters
from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from .models import PaymentBackend
from lingo.invoicing.forms import DateFromToRangeFilter
from .models import PaymentBackend, Transaction
TYPE_FIELD_MAPPING = {
str: forms.CharField,
@ -107,3 +110,60 @@ class PaymentBackendForm(forms.ModelForm):
)
instance.save()
return instance
class TransactionFilterSet(django_filters.FilterSet):
order_id = django_filters.CharFilter(
label=_('Order Identifier'),
field_name='order_id',
lookup_expr='contains',
)
bank_transaction_id = django_filters.CharFilter(
label=_('Bank Transaction Identifier'),
field_name='bank_transaction_id',
lookup_expr='contains',
)
date = DateFromToRangeFilter(
label=_('Date'),
field_name='start_date',
)
amount_min = django_filters.LookupChoiceFilter(
label=_('Amount min'),
field_name='amount',
field_class=forms.DecimalField,
empty_label=None,
lookup_choices=[
('gt', '>'),
('gte', '>='),
],
)
amount_max = django_filters.LookupChoiceFilter(
label=_('Amount max'),
field_name='amount',
field_class=forms.DecimalField,
empty_label=None,
lookup_choices=[
('lt', '<'),
('lte', '<='),
],
)
status = django_filters.ChoiceFilter(
label=_('Status'),
widget=forms.RadioSelect,
empty_label=_('All'),
choices=[
('running', _('Running')),
('paid', _('Paid')),
('others', _('Others')),
],
method='filter_status',
)
def filter_status(self, queryset, name, value):
if value == 'running':
return queryset.filter(status__in=Transaction.RUNNING_STATUSES)
if value == 'paid':
return queryset.filter(status__in=Transaction.PAID_STATUSES)
if value == 'others':
return queryset.exclude(status__in=Transaction.RUNNING_STATUSES + Transaction.PAID_STATUSES)
return queryset

View File

@ -95,6 +95,19 @@ class Transaction(models.Model):
RUNNING_STATUSES = [0, eopayment.WAITING, eopayment.RECEIVED]
PAID_STATUSES = [eopayment.PAID, eopayment.ACCEPTED]
def status_label(self):
return {
0: _('Running'),
eopayment.RECEIVED: _('Running'),
eopayment.ACCEPTED: _('Paid (accepted)'),
eopayment.PAID: _('Paid'),
eopayment.DENIED: _('Denied'),
eopayment.CANCELLED: _('Cancelled'),
eopayment.WAITING: _('Running'),
eopayment.EXPIRED: _('Expired'),
eopayment.ERROR: _('Error'),
}.get(self.status) or _('Unknown (%s)') % self.status
def is_paid(self):
return self.status in self.PAID_STATUSES

View File

@ -1,15 +1,13 @@
{% extends "lingo/manager_homepage.html" %}
{% extends "lingo/epayment/transaction_list.html" %}
{% load i18n %}
{% block page-title-extra-label %}{% trans "E-Payment" %}{% endblock %}
{% block breadcrumb %}
{{ block.super }}
<a href="{% url 'lingo-manager-epayment-backend-list' %}">{% trans "E-Payment" %}</a>
<a href="{% url 'lingo-manager-epayment-backend-list' %}">{% trans "Payment backends" %}</a>
{% endblock %}
{% block appbar %}
<h2>{% trans 'E-Payment' %}</h2>
<h2>{% trans 'Payment backends' %}</h2>
<span class="actions">
<a rel="popup" href="{% url 'lingo-manager-epayment-backend-add' %}">{% trans 'New payment backend' %}</a>
</span>

View File

@ -0,0 +1,66 @@
{% extends "lingo/manager_homepage.html" %}
{% load i18n %}
{% block page-title-extra-label %}{% trans "E-Payment" %}{% endblock %}
{% block breadcrumb %}
{{ block.super }}
<a href="{% url 'lingo-manager-epayment-transaction-list' %}">{% trans "E-Payment" %}</a>
{% endblock %}
{% block appbar %}
<h2>{% trans 'E-Payment' %}</h2>
<span class="actions">
<a href="{% url 'lingo-manager-epayment-backend-list' %}">{% trans 'Configure payment backends' %}</a>
</span>
{% endblock %}
{% block content %}
{% if object_list or request.GET %}
<div class="section">
<div>
<form class="transaction-element-filters">
<fieldset class="gadjo-foldable gadjo-folded" id="filters">
<legend class="gadjo-foldable-widget">{% trans "Transaction Filtering" %}</legend>
<div class="gadjo-folding">
{{ filterset.form.as_p }}
<button class="submit-button">{% trans "Filter" context 'form filtering action' %}</button>
</div>
</fieldset>
</form>
</div>
</div>
<div>
<table class="main">
<thead>
<tr>
<th>{% trans 'Status' %}</th>
<th>{% trans 'Date' %}</th>
<th>{% trans 'Order Identifier' %}</th>
<th>{% trans 'Bank Transaction Identifier' %}</th>
<th>{% trans 'Amount' %}</th>
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr>
<td>{{ object.status_label }}</td>
<td>{{ object.start_date }}</td>
<td>{{ object.order_id }}</td>
<td>{{ object.bank_transaction_id }}</td>
<td>{{ object.amount }}%€</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "gadjo/pagination.html" %}
</div>
{% else %}
<div class="big-msg-info">
{% blocktrans %}
There are no transactions yet.
{% endblocktrans %}
</div>
{% endif %}
{% endblock %}

View File

@ -19,7 +19,8 @@ from django.urls import path
from . import views
manager_urlpatterns = [
path('', views.backend_list, name='lingo-manager-epayment-backend-list'),
path('', views.transaction_list, name='lingo-manager-epayment-transaction-list'),
path('backend/', views.backend_list, name='lingo-manager-epayment-backend-list'),
path('backend/add/', views.backend_add, name='lingo-manager-epayment-backend-add'),
path('backend/<int:pk>/edit/', views.backend_edit, name='lingo-manager-epayment-backend-edit'),
path('backend/<int:pk>/delete/', views.backend_delete, name='lingo-manager-epayment-backend-delete'),

View File

@ -28,7 +28,7 @@ from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DeleteView, ListView, TemplateView, UpdateView
from .forms import PaymentBackendCreateForm, PaymentBackendForm
from .forms import PaymentBackendCreateForm, PaymentBackendForm, TransactionFilterSet
from .models import PaymentBackend, Transaction
@ -72,6 +72,26 @@ class BackendDeleteView(DeleteView):
backend_delete = BackendDeleteView.as_view()
class TransactionListView(ListView):
model = Transaction
template_name = 'lingo/epayment/transaction_list.html'
paginate_by = 5
def get_queryset(self):
self.filterset = TransactionFilterSet(
data=self.request.GET or None,
queryset=super().get_queryset().order_by('-start_date'),
)
return self.filterset.qs
def get_context_data(self, **kwargs):
kwargs['filterset'] = self.filterset
return super().get_context_data(**kwargs)
transaction_list = TransactionListView.as_view()
def pay(request, *, amount, backend, next_url):
transaction = Transaction.objects.create(status=0, amount=amount, backend=backend, next_url=next_url)
eopayment_kwargs = {

View File

@ -102,7 +102,9 @@ div.test-tool-result .infonotice h3 {
}
form.journal-filters li,
form.invoicing-element-filters li {
form.invoicing-element-filters li,
form.transaction-element-filters li,
{
display: inline;
margin-right: 10px;
}

View File

@ -7,11 +7,20 @@ from tests.utils import login
pytestmark = pytest.mark.django_db
def test_manager_epayment_backend_list_empty(app, admin_user):
def test_manager_epayment_transaction_list_empty(app, admin_user):
app = login(app)
resp = app.get(reverse('lingo-manager-epayment-backend-list'))
resp = app.get(reverse('lingo-manager-epayment-transaction-list'))
h2 = resp.pyquery('div#appbar h2')
assert h2.text() == 'E-Payment'
assert 'There are no transactions yet.'
def test_manager_epayment_backend_list_empty(app, admin_user):
app = login(app)
resp = app.get(reverse('lingo-manager-epayment-transaction-list'))
resp = resp.click('Configure payment backends')
h2 = resp.pyquery('div#appbar h2')
assert h2.text() == 'Payment backends'
assert 'There are no payment backend yet.' in resp.text