mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-04 09:12:11 +01:00 
			
		
		
		
	Link transactions and remittances
This commit is contained in:
		@@ -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', )
 | 
			
		||||
 
 | 
			
		||||
@@ -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):
 | 
			
		||||
    """
 | 
			
		||||
 
 | 
			
		||||
@@ -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',)
 | 
			
		||||
 
 | 
			
		||||
@@ -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'),
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
@@ -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')
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								templates/treasury/specialtransactionproxy_form.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								templates/treasury/specialtransactionproxy_form.html
									
									
									
									
									
										Normal file
									
								
							@@ -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 %}
 | 
			
		||||
		Reference in New Issue
	
	Block a user