mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-10 03:49:24 +00:00
Update accounting to have a target
This commit is contained in:
40
accounting/migrations/0013_auto_20160807_1923.py
Normal file
40
accounting/migrations/0013_auto_20160807_1923.py
Normal 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,
|
||||
),
|
||||
]
|
24
accounting/migrations/0015_auto_20160807_1959.py
Normal file
24
accounting/migrations/0015_auto_20160807_1959.py
Normal 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),
|
||||
),
|
||||
]
|
18
accounting/migrations/0016_auto_20160807_2000.py
Normal file
18
accounting/migrations/0016_auto_20160807_2000.py
Normal 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'},
|
||||
),
|
||||
]
|
@ -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
|
||||
|
||||
|
@ -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 %}
|
||||
|
@ -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'),
|
||||
]
|
||||
|
||||
|
||||
|
@ -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'
|
||||
|
||||
|
Reference in New Issue
Block a user