Finish labels in accounting

This commit is contained in:
Skia
2016-10-05 15:54:00 +02:00
parent e169e4ff6f
commit 7fdcb0c815
13 changed files with 292 additions and 69 deletions

View File

@ -9,5 +9,6 @@ admin.site.register(GeneralJournal)
admin.site.register(AccountingType)
admin.site.register(SimplifiedAccountingType)
admin.site.register(Operation)
admin.site.register(Label)

View File

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('accounting', '0003_auto_20160824_2203'),
]
operations = [
migrations.CreateModel(
name='Label',
fields=[
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True, serialize=False)),
('name', models.CharField(max_length=64, verbose_name='label')),
('club_account', models.ForeignKey(related_name='labels', verbose_name='club account', to='accounting.ClubAccount')),
],
),
migrations.AddField(
model_name='operation',
name='label',
field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, related_name='operations', null=True, blank=True, verbose_name='label', to='accounting.Label'),
),
migrations.AlterUniqueTogether(
name='label',
unique_together=set([('name', 'club_account')]),
),
]

View File

@ -100,7 +100,16 @@ class ClubAccount(models.Model):
Method to see if that object can be edited by the given user
"""
m = self.club.get_membership_for(user)
if m is not None and m.role >= 7:
if m and m.role == 7:
return True
return False
def can_be_viewed_by(self, user):
"""
Method to see if that object can be viewed by the given user
"""
m = self.club.get_membership_for(user)
if m and m.role >= 7:
return True
return False
@ -149,6 +158,9 @@ class GeneralJournal(models.Model):
return True
return False
def can_be_viewed_by(self, user):
return self.club_account.can_be_edited_by(user)
def get_absolute_url(self):
return reverse('accounting:journal_details', kwargs={'j_id': self.id})
@ -186,6 +198,8 @@ class Operation(models.Model):
verbose_name=_("simple type"), null=True, blank=True)
accounting_type = models.ForeignKey('AccountingType', related_name="operations",
verbose_name=_("accounting type"), null=True, blank=True)
label = models.ForeignKey('Label', related_name="operations",
verbose_name=_("label"), null=True, blank=True, on_delete=models.SET_NULL)
target_type = models.CharField(_('target type'), max_length=10,
choices=[('USER', _('User')), ('CLUB', _('Club')), ('ACCOUNT', _('Account')), ('COMPANY', _('Company')), ('OTHER', _('Other'))])
target_id = models.IntegerField(_('target id'), null=True, blank=True)
@ -326,3 +340,26 @@ class SimplifiedAccountingType(models.Model):
def __str__(self):
return self.get_movement_type_display()+" - "+self.accounting_type.code+" - "+self.label
class Label(models.Model):
"""Label allow a club to sort its operations"""
name = models.CharField(_('label'), max_length=64)
club_account = models.ForeignKey(ClubAccount, related_name="labels", verbose_name=_("club account"))
class Meta:
unique_together = ('name', 'club_account')
def __str__(self):
return "%s (%s)" % (self.name, self.club_account.name)
def get_absolute_url(self):
return reverse('accounting:label_list', kwargs={'clubaccount_id': self.club_account.id})
def is_owned_by(self, user):
return self.club_account.is_owned_by(user)
def can_be_edited_by(self, user):
return self.club_account.can_be_edited_by(user)
def can_be_viewed_by(self, user):
return self.club_account.can_be_viewed_by(user)

View File

@ -15,6 +15,8 @@
{% if user.is_root and not object.journals.exists() %}
<a href="{{ url('accounting:club_delete', c_account_id=object.id) }}">{% trans %}Delete{% endtrans %}</a>
{% endif %}
<p><a href="{{ url('accounting:label_new') }}?parent={{ object.id }}">{% trans %}New label{% endtrans %}</a></p>
<p><a href="{{ url('accounting:label_list', clubaccount_id=object.id) }}">{% trans %}Label list{% endtrans %}</a></p>
{% if not object.has_open_journal() %}
<p><a href="{{ url('accounting:journal_new') }}?parent={{ object.id }}">{% trans %}New journal{% endtrans %}</a></p>
{% else %}

View File

@ -25,6 +25,7 @@
<tr>
<td>{% trans %}Nb{% endtrans %}</td>
<td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Label{% endtrans %}</td>
<td>{% trans %}Amount{% endtrans %}</td>
<td>{% trans %}Payment mode{% endtrans %}</td>
<td>{% trans %}Target{% endtrans %}</td>
@ -41,6 +42,7 @@
<tr>
<td>{{ o.number }}</td>
<td>{{ o.date }}</td>
<td>{{ o.label or "" }}</td>
<td>{{ o.amount }} €</td>
<td>{{ o.get_mode_display() }}</td>
{% if o.target_type == "OTHER" %}

View File

@ -0,0 +1,29 @@
{% extends "core/base.jinja" %}
{% block title %}
{% trans %}Label list{% endtrans %}
{% endblock %}
{% block content %}
<p>
<a href="{{ url('accounting:bank_list') }}">{% trans %}Accounting{% endtrans %}</a> >
<a href="{{ url('accounting:bank_details', b_account_id=object.bank_account.id) }}">{{object.bank_account }}</a> >
<a href="{{ url('accounting:club_details', c_account_id=object.id) }}">{{ object }}</a>
</p>
<hr>
<p><a href="{{ url('accounting:club_details', c_account_id=object.id) }}">{% trans %}Back to club account{% endtrans %}</a></p>
<p><a href="{{ url('accounting:label_new') }}?parent={{ object.id }}">{% trans %}New label{% endtrans %}</a></p>
{% if object.labels.all() %}
<h3>{% trans %}Label list{% endtrans %}</h3>
<ul>
{% for l in object.labels.all() %}
<li><a href="{{ url('accounting:label_edit', label_id=l.id) }}">{{ l }}</a> -
<a href="{{ url('accounting:label_delete', label_id=l.id) }}">{% trans %}Delete{% endtrans %}</a>
</li>
{% endfor %}
</ul>
{% else %}
{% trans %}There is no label in this club account.{% endtrans %}
{% endif %}
{% endblock %}

View File

@ -35,6 +35,7 @@
form.simpleaccounting_type.label }}</label> {{ form.simpleaccounting_type }}</p>
<p>{{ form.accounting_type.errors }}<label for="{{ form.accounting_type.name }}">{{ form.accounting_type.label }}</label> {{
form.accounting_type }}</p>
<p>{{ form.label.errors }}<label for="{{ form.label.name }}">{{ form.label.label }}</label> {{ form.label }}</p>
<p>{{ form.done.errors }}<label for="{{ form.done.name }}">{{ form.done.label }}</label> {{ form.done }}</p>
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p>
</form>

View File

@ -32,6 +32,11 @@ urlpatterns = [
# Companies
url(r'^company/create$', CompanyCreateView.as_view(), name='co_new'),
url(r'^company/(?P<co_id>[0-9]+)$', CompanyEditView.as_view(), name='co_edit'),
# Labels
url(r'^label/new$', LabelCreateView.as_view(), name='label_new'),
url(r'^label/(?P<clubaccount_id>[0-9]+)$', LabelListView.as_view(), name='label_list'),
url(r'^label/(?P<label_id>[0-9]+)/edit$', LabelEditView.as_view(), name='label_edit'),
url(r'^label/(?P<label_id>[0-9]+)/delete$', LabelDeleteView.as_view(), name='label_delete'),
]

View File

@ -10,7 +10,7 @@ from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultip
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
from core.views.forms import SelectFile, SelectDate
from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType, Company, SimplifiedAccountingType
from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType, Company, SimplifiedAccountingType, Label
# Main accounting view
@ -196,7 +196,7 @@ class OperationForm(forms.ModelForm):
class Meta:
model = Operation
fields = ['amount', 'remark', 'journal', 'target_type', 'target_id', 'target_label', 'date', 'mode',
'cheque_number', 'invoice', 'simpleaccounting_type', 'accounting_type', 'done']
'cheque_number', 'invoice', 'simpleaccounting_type', 'accounting_type', 'label', 'done']
widgets = {
'journal': HiddenInput,
'target_id': HiddenInput,
@ -210,6 +210,7 @@ class OperationForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(OperationForm, self).__init__(*args, **kwargs)
self.fields['label'].queryset = self.instance.journal.club_account.labels.order_by('name').all()
if self.instance.target_type == "USER":
self.fields['user'].initial = self.instance.target_id
elif self.instance.target_type == "ACCOUNT":
@ -316,3 +317,39 @@ class CompanyEditView(CanCreateMixin, UpdateView):
fields = ['name']
template_name = 'core/edit.jinja'
# Label views
class LabelListView(CanViewMixin, DetailView):
model = ClubAccount
pk_url_kwarg = "clubaccount_id"
template_name = 'accounting/label_list.jinja'
class LabelCreateView(CanEditMixin, CreateView): # FIXME we need to check the rights before creating the object
model = Label
form_class = modelform_factory(Label, fields=['name', 'club_account'], widgets={
'club_account': HiddenInput,
})
template_name = 'core/create.jinja'
def get_initial(self):
ret = super(LabelCreateView, self).get_initial()
if 'parent' in self.request.GET.keys():
obj = ClubAccount.objects.filter(id=int(self.request.GET['parent'])).first()
if obj is not None:
ret['club_account'] = obj.id
return ret
class LabelEditView(CanEditMixin, UpdateView):
model = Label
pk_url_kwarg = "label_id"
fields = ['name']
template_name = 'core/edit.jinja'
class LabelDeleteView(CanEditMixin, DeleteView):
model = Label
pk_url_kwarg = "label_id"
template_name = 'core/delete_confirm.jinja'
def get_success_url(self):
return self.object.get_absolute_url()