Update accounting to have a target

This commit is contained in:
Skia
2016-08-07 20:10:50 +02:00
parent d824d0d928
commit a0f7150c55
11 changed files with 318 additions and 102 deletions

View File

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounting', '0012_auto_20160720_1847'),
]
operations = [
migrations.CreateModel(
name='Company',
fields=[
('id', models.AutoField(primary_key=True, serialize=False, auto_created=True, verbose_name='ID')),
('name', models.CharField(max_length=60, verbose_name='name')),
],
options={
'verbose_name': 'company',
},
),
migrations.AddField(
model_name='operation',
name='target_id',
field=models.IntegerField(blank=True, null=True, verbose_name='target id'),
),
migrations.AddField(
model_name='operation',
name='target_label',
field=models.CharField(max_length=32, blank=True, default='', verbose_name='target label'),
),
migrations.AddField(
model_name='operation',
name='target_type',
field=models.CharField(max_length=10, default='OTHER', choices=[('USER', 'User'), ('CLUB', 'Club'), ('ACCOUNT', 'Account'), ('COMPANY', 'Company'), ('OTHER', 'Other')], verbose_name='target type'),
preserve_default=False,
),
]

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounting', '0014_auto_20160807_1954'),
]
operations = [
migrations.AlterField(
model_name='operation',
name='accounting_type',
field=models.ForeignKey(related_name='operations', verbose_name='accounting type', to='accounting.AccountingType'),
),
migrations.AlterField(
model_name='operation',
name='invoice',
field=models.FileField(upload_to='invoices', verbose_name='invoice', null=True, blank=True),
),
]

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounting', '0015_auto_20160807_1959'),
]
operations = [
migrations.AlterModelOptions(
name='accountingtype',
options={'verbose_name': 'accounting type'},
),
]

View File

@ -27,6 +27,19 @@ class CurrencyField(models.DecimalField):
except AttributeError:
return None
# Accounting classes
class Company(models.Model):
name = models.CharField(_('name'), max_length=60)
class Meta:
verbose_name = _("company")
def get_absolute_url(self):
return reverse('accounting:co_edit', kwargs={'co_id': self.id})
def get_display_name(self):
return self.name
class BankAccount(models.Model):
name = models.CharField(_('name'), max_length=30)
@ -85,6 +98,10 @@ class ClubAccount(models.Model):
def __str__(self):
return self.name
def get_display_name(self):
return _("%(club_account)s on %(bank_account)s") % {"club_account": self.name, "bank_account": self.bank_account}
class GeneralJournal(models.Model):
"""
Class storing all the operations for a period of time
@ -139,19 +156,45 @@ class Operation(models.Model):
remark = models.TextField(_('remark'), max_length=255)
mode = models.CharField(_('payment method'), max_length=255, choices=settings.SITH_ACCOUNTING_PAYMENT_METHOD)
cheque_number = models.IntegerField(_('cheque number'), default=-1)
invoice = models.FileField(upload_to='invoices', null=True, blank=True)
invoice = models.FileField(upload_to='invoices', verbose_name=_("invoice"), null=True, blank=True)
done = models.BooleanField(_('is done'), default=False)
accounting_type = models.ForeignKey('AccountingType', related_name="operations")
accounting_type = models.ForeignKey('AccountingType', related_name="operations", verbose_name=_("accounting type"))
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)
target_label = models.CharField(_('target label'), max_length=32, default="", blank=True)
class Meta:
unique_together = ('number', 'journal')
ordering = ['-number']
def __getattribute__(self, attr):
if attr == "target":
return self.get_target()
else:
return object.__getattribute__(self, attr)
def clean(self):
super(Operation, self).clean()
if self.date < self.journal.start_date:
raise ValidationError(_("""The date can not be before the start date of the journal, which is
%(start_date)s.""") % {'start_date': defaultfilters.date(self.journal.start_date, settings.DATE_FORMAT)})
if self.target_type != "OTHER" and self.get_target() is None:
raise ValidationError(_("Target does not exists"))
if self.target_type == "OTHER" and self.target_label == "":
raise ValidationError(_("Please add a target label if you set no existing target"))
def get_target(self):
tar = None
if self.target_type == "USER":
tar = User.objects.filter(id=self.target_id).first()
elif self.target_type == "CLUB":
tar = Club.objects.filter(id=self.target_id).first()
elif self.target_type == "ACCOUNT":
tar = ClubAccount.objects.filter(id=self.target_id).first()
elif self.target_type == "COMPANY":
tar = Company.objects.filter(id=self.target_id).first()
return tar
def save(self):
if self.number is None:
@ -198,6 +241,9 @@ class AccountingType(models.Model):
label = models.CharField(_('label'), max_length=60)
movement_type = models.CharField(_('movement type'), choices=[('credit', 'Credit'), ('debit', 'Debit'), ('neutral', 'Neutral')], max_length=12)
class Meta:
verbose_name = _("accounting type")
def is_owned_by(self, user):
"""
Method to see if that object can be edited by the given user
@ -211,4 +257,3 @@ class AccountingType(models.Model):
def __str__(self):
return self.movement_type+" - "+self.code+" - "+self.label

View File

@ -22,7 +22,7 @@
<td>{% trans %}Label{% endtrans %}</td>
<td>{% trans %}Amount{% endtrans %}</td>
<td>{% trans %}Payment mode{% endtrans %}</td>
<!-- TODO: <td>Target</td> -->
<td>{% trans %}Target{% endtrans %}</td>
<td>{% trans %}Code{% endtrans %}</td>
<td>{% trans %}Nature{% endtrans %}</td>
<td>{% trans %}Done{% endtrans %}</td>
@ -37,7 +37,12 @@
<td>{{ o.date }}</td>
<td>{{ o.label }}</td>
<td>{{ o.amount }} €</td>
<td>{{ o.mode }}</td>
<td>{{ o.get_mode_display() }}</td>
{% if o.target_type == "OTHER" %}
<td>{{ o.target_label }}</td>
{% else %}
<td><a href="{{ o.target.get_absolute_url() }}">{{ o.target.get_display_name() }}</a></td>
{% endif %}
<td>{{ o.accounting_type.code }}</td>
<td>{{ o.accounting_type.label }}</td>
{% if o.done %}

View File

@ -25,6 +25,9 @@ urlpatterns = [
# Operations
url(r'^operation/create$', OperationCreateView.as_view(), name='op_new'),
url(r'^operation/(?P<op_id>[0-9]+)$', OperationEditView.as_view(), name='op_edit'),
# 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'),
]

View File

@ -6,7 +6,7 @@ from django.forms.models import modelform_factory
from django.forms import HiddenInput
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType
from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType, Company
# Accounting types
@ -164,7 +164,8 @@ class OperationCreateView(CanCreateMixin, CreateView):
"""
model = Operation
form_class = modelform_factory(Operation,
fields=['amount', 'label', 'remark', 'journal', 'date', 'mode', 'cheque_number', 'accounting_type', 'done'],
fields=['amount', 'label', 'remark', 'journal', 'target_type', 'target_id', 'target_label', 'date', 'mode',
'cheque_number', 'invoice', 'accounting_type', 'done'],
widgets={'journal': HiddenInput})
template_name = 'core/create.jinja'
@ -182,6 +183,26 @@ class OperationEditView(CanEditMixin, UpdateView):
"""
model = Operation
pk_url_kwarg = "op_id"
fields = ['amount', 'label', 'remark', 'date', 'mode', 'cheque_number', 'accounting_type', 'done']
fields = ['amount', 'label', 'remark', 'target_type', 'target_id', 'target_label', 'date', 'mode', 'cheque_number',
'invoice', 'accounting_type', 'done']
template_name = 'core/edit.jinja'
# Company views
class CompanyCreateView(CanCreateMixin, CreateView):
"""
Create a company
"""
model = Company
fields = ['name']
template_name = 'core/create.jinja'
class CompanyEditView(CanCreateMixin, UpdateView):
"""
Edit a company
"""
model = Company
pk_url_kwarg = "co_id"
fields = ['name']
template_name = 'core/edit.jinja'