diff --git a/apps/treasury/forms.py b/apps/treasury/forms.py index 3189694d..a06601b1 100644 --- a/apps/treasury/forms.py +++ b/apps/treasury/forms.py @@ -8,7 +8,7 @@ from crispy_forms.layout import Submit from django import forms from django.utils.translation import gettext_lazy as _ -from .models import Invoice, Product, Remittance +from .models import Invoice, Product, Remittance, SpecialTransactionProxy class InvoiceForm(forms.ModelForm): @@ -51,3 +51,38 @@ class RemittanceForm(forms.ModelForm): class Meta: model = Remittance fields = ('type', 'comment', ) + + +class LinkTransactionToRemittanceForm(forms.ModelForm): + last_name = forms.CharField(label=_("Last name")) + + first_name = forms.Field(label=_("First name")) + + bank = forms.Field(label=_("Bank")) + + amount = forms.IntegerField(label=_("Amount"), min_value=0) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper() + self.helper.add_input(Submit('submit', _("Submit"), attr={'class': 'btn btn-block btn-primary'})) + + def clean_last_name(self): + self.instance.transaction.last_name = self.data.get("last_name") + self.instance.transaction.clean() + + def clean_first_name(self): + self.instance.transaction.first_name = self.data.get("first_name") + self.instance.transaction.clean() + + def clean_bank(self): + self.instance.transaction.bank = self.data.get("bank") + self.instance.transaction.clean() + + def clean_amount(self): + self.instance.transaction.amount = self.data.get("amount") + self.instance.transaction.clean() + + class Meta: + model = SpecialTransactionProxy + fields = ('remittance', ) diff --git a/apps/treasury/models.py b/apps/treasury/models.py index 569fc07f..e2be5af7 100644 --- a/apps/treasury/models.py +++ b/apps/treasury/models.py @@ -126,8 +126,7 @@ class Remittance(models.Model): def transactions(self): return SpecialTransaction.objects.filter(specialtransactionproxy__remittance=self) - @property - def size(self): + def count(self): return self.transactions.count() @property @@ -142,6 +141,9 @@ class Remittance(models.Model): return ret + def __str__(self): + return _("Remittance #{:d}: {}").format(self.id, self.comment, ) + class SpecialTransactionProxy(models.Model): """ diff --git a/apps/treasury/tables.py b/apps/treasury/tables.py index bcbbd8a4..3c302813 100644 --- a/apps/treasury/tables.py +++ b/apps/treasury/tables.py @@ -43,32 +43,38 @@ class RemittanceTable(tables.Table): 'a': {'class': 'btn btn-primary'} }, ) + def render_amount(self, value): + return pretty_money(value) + class Meta: attrs = { 'class': 'table table-condensed table-striped table-hover' } model = Remittance template_name = 'django_tables2/bootstrap4.html' - fields = ('id', 'date', 'type', 'comment', 'size', 'amount', 'edit',) + fields = ('id', 'date', 'type', 'comment', 'count', 'amount', 'edit',) class SpecialTransactionTable(tables.Table): - remittance_add = tables.LinkColumn("treasury:remittance_update", + remittance_add = tables.LinkColumn("treasury:link_transaction", verbose_name=_("Remittance"), - args=[A("pk")], + args=[A("specialtransactionproxy.pk")], text=_("Add"), attrs={ 'a': {'class': 'btn btn-primary'} }, ) - remittance_remove = tables.LinkColumn("treasury:remittance_update", + remittance_remove = tables.LinkColumn("treasury:unlink_transaction", verbose_name=_("Remittance"), - args=[A("pk")], + args=[A("specialtransactionproxy.pk")], text=_("Remove"), attrs={ 'a': {'class': 'btn btn-primary btn-danger'} }, ) + def render_id(self, record): + return record.specialtransactionproxy.pk + def render_amount(self, value): return pretty_money(value) @@ -78,4 +84,4 @@ class SpecialTransactionTable(tables.Table): } model = SpecialTransaction template_name = 'django_tables2/bootstrap4.html' - fields = ('id', 'source', 'destination', 'amount', 'last_name', 'first_name', 'bank',) + fields = ('id', 'source', 'destination', 'last_name', 'first_name', 'bank', 'amount', 'reason',) diff --git a/apps/treasury/urls.py b/apps/treasury/urls.py index 1901732b..fa5ef0e4 100644 --- a/apps/treasury/urls.py +++ b/apps/treasury/urls.py @@ -4,7 +4,7 @@ from django.urls import path from .views import InvoiceCreateView, InvoiceListView, InvoiceUpdateView, InvoiceRenderView, RemittanceListView,\ - RemittanceCreateView, RemittanceUpdateView + RemittanceCreateView, RemittanceUpdateView, LinkTransactionToRemittanceView, UnlinkTransactionToRemittanceView app_name = 'treasury' urlpatterns = [ @@ -16,4 +16,7 @@ urlpatterns = [ path('remittance/', RemittanceListView.as_view(), name='remittance_list'), path('remittance/create/', RemittanceCreateView.as_view(), name='remittance_create'), path('remittance//', RemittanceUpdateView.as_view(), name='remittance_update'), + path('remittance/link_transaction//', LinkTransactionToRemittanceView.as_view(), name='link_transaction'), + path('remittance/unlink_transaction//', UnlinkTransactionToRemittanceView.as_view(), + name='unlink_transaction'), ] diff --git a/apps/treasury/views.py b/apps/treasury/views.py index 3415a2b2..89a009cf 100644 --- a/apps/treasury/views.py +++ b/apps/treasury/views.py @@ -8,8 +8,10 @@ from tempfile import mkdtemp from crispy_forms.helper import FormHelper from django.contrib.auth.mixins import LoginRequiredMixin +from django.core.exceptions import ValidationError from django.db.models import Q from django.http import HttpResponse +from django.shortcuts import redirect from django.template.loader import render_to_string from django.urls import reverse_lazy from django.views.generic import CreateView, UpdateView @@ -18,8 +20,8 @@ from django_tables2 import SingleTableView from note.models import SpecialTransaction from note_kfet.settings.base import BASE_DIR -from .forms import InvoiceForm, ProductFormSet, ProductFormSetHelper, RemittanceForm -from .models import Invoice, Product, Remittance +from .forms import InvoiceForm, ProductFormSet, ProductFormSetHelper, RemittanceForm, LinkTransactionToRemittanceForm +from .models import Invoice, Product, Remittance, SpecialTransactionProxy from .tables import InvoiceTable, RemittanceTable, SpecialTransactionTable @@ -240,3 +242,38 @@ class RemittanceUpdateView(LoginRequiredMixin, UpdateView): exclude=('remittance_add', )) return ctx + + +class LinkTransactionToRemittanceView(LoginRequiredMixin, UpdateView): + model = SpecialTransactionProxy + form_class = LinkTransactionToRemittanceForm + + def get_success_url(self): + return reverse_lazy('treasury:remittance_list') + + def get_context_data(self, **kwargs): + ctx = super().get_context_data(**kwargs) + + form = ctx["form"] + form.fields["last_name"].initial = self.object.transaction.last_name + form.fields["first_name"].initial = self.object.transaction.first_name + form.fields["bank"].initial = self.object.transaction.bank + form.fields["amount"].initial = self.object.transaction.amount + form.fields["remittance"].queryset = form.fields["remittance"] \ + .queryset.filter(type=self.object.transaction.source) + + return ctx + + +class UnlinkTransactionToRemittanceView(LoginRequiredMixin, View): + def get(self, *args, **kwargs): + pk = kwargs["pk"] + transaction = SpecialTransactionProxy.objects.get(pk=pk) + + if transaction.remittance and transaction.remittance.closed: + raise ValidationError("Remittance is already closed.") + + transaction.remittance = None + transaction.save() + + return redirect('treasury:remittance_list') diff --git a/templates/treasury/remittance_list.html b/templates/treasury/remittance_list.html index dfada279..cb06bbd0 100644 --- a/templates/treasury/remittance_list.html +++ b/templates/treasury/remittance_list.html @@ -4,19 +4,37 @@ {% block content %}

{% trans "Opened remittances" %}

- {% render_table opened_remittances %} + {% if opened_remittances.data %} + {% render_table opened_remittances %} + {% else %} +
+ {% trans "There is no opened remittance." %} +
+ {% endif %} {% trans "New remittance" %}

{% trans "Transfers without remittances" %}

- {% render_table special_transactions_no_remittance %} + {% if special_transactions_no_remittance.data %} + {% render_table special_transactions_no_remittance %} + {% else %} +
+ {% trans "There is no transaction without any linked remittance." %} +
+ {% endif %}

{% trans "Transfers with opened remittances" %}

- {% render_table special_transactions_with_remittance %} + {% if special_transactions_with_remittance.data %} + {% render_table special_transactions_with_remittance %} + {% else %} +
+ {% trans "There is no transaction without an opened linked remittance." %} +
+ {% endif %}
diff --git a/templates/treasury/specialtransactionproxy_form.html b/templates/treasury/specialtransactionproxy_form.html new file mode 100644 index 00000000..4e7758ae --- /dev/null +++ b/templates/treasury/specialtransactionproxy_form.html @@ -0,0 +1,9 @@ +{% extends "base.html" %} +{% load static %} +{% load i18n %} +{% load crispy_forms_tags pretty_money %} +{% load render_table from django_tables2 %} +{% block content %} +

{% trans "Remittances list" %}

+ {% crispy form %} +{% endblock %}