diff --git a/apps/treasury/forms.py b/apps/treasury/forms.py index 3189694dc1fbbba9dbd91bc76e7548f2391861c9..a06601b1383d62b9ed5d8ecbafc027a16c0ea15c 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 569fc07f401d065361845ba6e32b2de5105f23c3..e2be5af7fd5d4452f0a24c44a6a3a4e8d09af6e2 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 bcbbd8a48966898032e1352afbdb3f381def91d4..3c30281341e6d0a15c043dc5d4cd5be0c2f78b02 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 1901732b767d35d8fcecaeb1748eb0c41a771d28..fa5ef0e40555e988ed7065e90f449e7f3875b288 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/<int:pk>/', RemittanceUpdateView.as_view(), name='remittance_update'), + path('remittance/link_transaction/<int:pk>/', LinkTransactionToRemittanceView.as_view(), name='link_transaction'), + path('remittance/unlink_transaction/<int:pk>/', UnlinkTransactionToRemittanceView.as_view(), + name='unlink_transaction'), ] diff --git a/apps/treasury/views.py b/apps/treasury/views.py index 3415a2b25c39ab538e47dec7b20961cec84c03d2..89a009cf914d12215d3597c27304d698905866c7 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 dfada279fa581686ecc692c2f7d91f8461c81c6a..cb06bbd0109a0a03f9266df3f00b629f5e36e841 100644 --- a/templates/treasury/remittance_list.html +++ b/templates/treasury/remittance_list.html @@ -4,19 +4,37 @@ {% block content %} <h2>{% trans "Opened remittances" %}</h2> - {% render_table opened_remittances %} + {% if opened_remittances.data %} + {% render_table opened_remittances %} + {% else %} + <div class="alert alert-warning"> + {% trans "There is no opened remittance." %} + </div> + {% endif %} <a class="btn btn-primary" href="{% url 'treasury:remittance_create' %}">{% trans "New remittance" %}</a> <hr> <h2>{% trans "Transfers without remittances" %}</h2> - {% render_table special_transactions_no_remittance %} + {% if special_transactions_no_remittance.data %} + {% render_table special_transactions_no_remittance %} + {% else %} + <div class="alert alert-warning"> + {% trans "There is no transaction without any linked remittance." %} + </div> + {% endif %} <hr> <h2>{% trans "Transfers with opened remittances" %}</h2> - {% render_table special_transactions_with_remittance %} + {% if special_transactions_with_remittance.data %} + {% render_table special_transactions_with_remittance %} + {% else %} + <div class="alert alert-warning"> + {% trans "There is no transaction without an opened linked remittance." %} + </div> + {% endif %} <hr> diff --git a/templates/treasury/specialtransactionproxy_form.html b/templates/treasury/specialtransactionproxy_form.html new file mode 100644 index 0000000000000000000000000000000000000000..4e7758ae4fb966b08be32046af19aaff9a04a1df --- /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 %} + <p><a class="btn btn-default" href="{% url 'treasury:remittance_list' %}">{% trans "Remittances list" %}</a></p> + {% crispy form %} +{% endblock %}