Migrate accounting

This commit is contained in:
Skia 2016-08-24 19:50:22 +02:00
parent a4df1ae9a5
commit 078b63d970
22 changed files with 904 additions and 200 deletions

View File

@ -7,6 +7,7 @@ admin.site.register(BankAccount)
admin.site.register(ClubAccount) admin.site.register(ClubAccount)
admin.site.register(GeneralJournal) admin.site.register(GeneralJournal)
admin.site.register(AccountingType) admin.site.register(AccountingType)
admin.site.register(SimplifiedAccountingType)
admin.site.register(Operation) admin.site.register(Operation)

View File

@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.core.validators
class Migration(migrations.Migration):
dependencies = [
('accounting', '0002_auto_20160814_1634'),
]
operations = [
migrations.CreateModel(
name='SimplifiedAccountingType',
fields=[
('id', models.AutoField(auto_created=True, verbose_name='ID', serialize=False, primary_key=True)),
('label', models.CharField(max_length=128, verbose_name='label')),
],
options={
'verbose_name': 'simplified type',
},
),
migrations.RemoveField(
model_name='operation',
name='label',
),
migrations.AddField(
model_name='operation',
name='linked_operation',
field=models.OneToOneField(to='accounting.Operation', default=None, null=True, blank=True, verbose_name='linked operation', related_name='operation_linked_to'),
),
migrations.AlterField(
model_name='accountingtype',
name='code',
field=models.CharField(max_length=16, verbose_name='code', validators=[django.core.validators.RegexValidator('^[0-9]*$', 'An accounting type code contains only numbers')]),
),
migrations.AlterField(
model_name='accountingtype',
name='label',
field=models.CharField(max_length=128, verbose_name='label'),
),
migrations.AlterField(
model_name='accountingtype',
name='movement_type',
field=models.CharField(max_length=12, verbose_name='movement type', choices=[('CREDIT', 'Credit'), ('DEBIT', 'Debit'), ('NEUTRAL', 'Neutral')]),
),
migrations.AlterField(
model_name='bankaccount',
name='club',
field=models.ForeignKey(related_name='bank_accounts', verbose_name='club', to='club.Club'),
),
migrations.AlterField(
model_name='clubaccount',
name='bank_account',
field=models.ForeignKey(related_name='club_accounts', verbose_name='bank account', to='accounting.BankAccount'),
),
migrations.AlterField(
model_name='clubaccount',
name='club',
field=models.ForeignKey(related_name='club_account', verbose_name='club', to='club.Club'),
),
migrations.AlterField(
model_name='generaljournal',
name='club_account',
field=models.ForeignKey(related_name='journals', verbose_name='club account', to='accounting.ClubAccount'),
),
migrations.AlterField(
model_name='generaljournal',
name='name',
field=models.CharField(max_length=40, verbose_name='name'),
),
migrations.AlterField(
model_name='operation',
name='accounting_type',
field=models.ForeignKey(related_name='operations', null=True, blank=True, verbose_name='accounting type', to='accounting.AccountingType'),
),
migrations.AlterField(
model_name='operation',
name='cheque_number',
field=models.CharField(verbose_name='cheque number', null=True, max_length=32, blank=True, default=''),
),
migrations.AlterField(
model_name='operation',
name='journal',
field=models.ForeignKey(related_name='operations', verbose_name='journal', to='accounting.GeneralJournal'),
),
migrations.AlterField(
model_name='operation',
name='remark',
field=models.CharField(max_length=128, verbose_name='comment'),
),
migrations.AddField(
model_name='simplifiedaccountingtype',
name='accounting_type',
field=models.ForeignKey(related_name='simplified_types', verbose_name='simplified accounting types', to='accounting.AccountingType'),
),
migrations.AddField(
model_name='operation',
name='simpleaccounting_type',
field=models.ForeignKey(related_name='operations', null=True, blank=True, verbose_name='simple type', to='accounting.SimplifiedAccountingType'),
),
]

View File

@ -1,5 +1,6 @@
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core import validators
from django.db.models import Count from django.db.models import Count
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
@ -45,7 +46,7 @@ class BankAccount(models.Model):
name = models.CharField(_('name'), max_length=30) name = models.CharField(_('name'), max_length=30)
iban = models.CharField(_('iban'), max_length=255, blank=True) iban = models.CharField(_('iban'), max_length=255, blank=True)
number = models.CharField(_('account number'), max_length=255, blank=True) number = models.CharField(_('account number'), max_length=255, blank=True)
club = models.ForeignKey(Club, related_name="bank_accounts") club = models.ForeignKey(Club, related_name="bank_accounts", verbose_name=_("club"))
def is_owned_by(self, user): def is_owned_by(self, user):
""" """
@ -66,8 +67,8 @@ class BankAccount(models.Model):
class ClubAccount(models.Model): class ClubAccount(models.Model):
name = models.CharField(_('name'), max_length=30) name = models.CharField(_('name'), max_length=30)
club = models.OneToOneField(Club, related_name="club_account") club = models.ForeignKey(Club, related_name="club_account", verbose_name=_("club"))
bank_account = models.ForeignKey(BankAccount, related_name="club_accounts") bank_account = models.ForeignKey(BankAccount, related_name="club_accounts", verbose_name=_("bank account"))
def is_owned_by(self, user): def is_owned_by(self, user):
""" """
@ -92,6 +93,9 @@ class ClubAccount(models.Model):
return True return True
return False return False
def get_open_journal(self):
return self.journals.filter(closed=False).first()
def get_absolute_url(self): def get_absolute_url(self):
return reverse('accounting:club_details', kwargs={'c_account_id': self.id}) return reverse('accounting:club_details', kwargs={'c_account_id': self.id})
@ -108,9 +112,9 @@ class GeneralJournal(models.Model):
""" """
start_date = models.DateField(_('start date')) start_date = models.DateField(_('start date'))
end_date = models.DateField(_('end date'), null=True, blank=True, default=None) end_date = models.DateField(_('end date'), null=True, blank=True, default=None)
name = models.CharField(_('name'), max_length=30) name = models.CharField(_('name'), max_length=40)
closed = models.BooleanField(_('is closed'), default=False) closed = models.BooleanField(_('is closed'), default=False)
club_account = models.ForeignKey(ClubAccount, related_name="journals", null=False) club_account = models.ForeignKey(ClubAccount, related_name="journals", null=False, verbose_name=_("club account"))
amount = CurrencyField(_('amount'), default=0) amount = CurrencyField(_('amount'), default=0)
effective_amount = CurrencyField(_('effective_amount'), default=0) effective_amount = CurrencyField(_('effective_amount'), default=0)
@ -134,7 +138,7 @@ class GeneralJournal(models.Model):
self.amount = 0 self.amount = 0
self.effective_amount = 0 self.effective_amount = 0
for o in self.operations.all(): for o in self.operations.all():
if o.accounting_type.movement_type == "credit": if o.accounting_type.movement_type == "CREDIT":
if o.done: if o.done:
self.effective_amount += o.amount self.effective_amount += o.amount
self.amount += o.amount self.amount += o.amount
@ -149,20 +153,24 @@ class Operation(models.Model):
An operation is a line in the journal, a debit or a credit An operation is a line in the journal, a debit or a credit
""" """
number = models.IntegerField(_('number')) number = models.IntegerField(_('number'))
journal = models.ForeignKey(GeneralJournal, related_name="operations", null=False) journal = models.ForeignKey(GeneralJournal, related_name="operations", null=False, verbose_name=_("journal"))
amount = CurrencyField(_('amount')) amount = CurrencyField(_('amount'))
date = models.DateField(_('date')) date = models.DateField(_('date'))
label = models.CharField(_('label'), max_length=50) remark = models.CharField(_('comment'), max_length=128)
remark = models.TextField(_('remark'), max_length=255)
mode = models.CharField(_('payment method'), max_length=255, choices=settings.SITH_ACCOUNTING_PAYMENT_METHOD) mode = models.CharField(_('payment method'), max_length=255, choices=settings.SITH_ACCOUNTING_PAYMENT_METHOD)
cheque_number = models.IntegerField(_('cheque number'), default=-1) cheque_number = models.CharField(_('cheque number'), max_length=32, default="", null=True, blank=True)
invoice = models.ForeignKey(SithFile, related_name='operations', verbose_name=_("invoice"), null=True, blank=True) invoice = models.ForeignKey(SithFile, related_name='operations', verbose_name=_("invoice"), null=True, blank=True)
done = models.BooleanField(_('is done'), default=False) done = models.BooleanField(_('is done'), default=False)
accounting_type = models.ForeignKey('AccountingType', related_name="operations", verbose_name=_("accounting type")) simpleaccounting_type = models.ForeignKey('SimplifiedAccountingType', related_name="operations",
verbose_name=_("simple type"), null=True, blank=True)
accounting_type = models.ForeignKey('AccountingType', related_name="operations",
verbose_name=_("accounting type"), null=True, blank=True)
target_type = models.CharField(_('target type'), max_length=10, target_type = models.CharField(_('target type'), max_length=10,
choices=[('USER', _('User')), ('CLUB', _('Club')), ('ACCOUNT', _('Account')), ('COMPANY', _('Company')), ('OTHER', _('Other'))]) choices=[('USER', _('User')), ('CLUB', _('Club')), ('ACCOUNT', _('Account')), ('COMPANY', _('Company')), ('OTHER', _('Other'))])
target_id = models.IntegerField(_('target id'), null=True, blank=True) target_id = models.IntegerField(_('target id'), null=True, blank=True)
target_label = models.CharField(_('target label'), max_length=32, default="", blank=True) target_label = models.CharField(_('target label'), max_length=32, default="", blank=True)
linked_operation = models.OneToOneField('self', related_name='operation_linked_to', verbose_name=_("linked operation"),
null=True, blank=True, default=None)
class Meta: class Meta:
unique_together = ('number', 'journal') unique_together = ('number', 'journal')
@ -183,6 +191,14 @@ class Operation(models.Model):
raise ValidationError(_("Target does not exists")) raise ValidationError(_("Target does not exists"))
if self.target_type == "OTHER" and self.target_label == "": if self.target_type == "OTHER" and self.target_label == "":
raise ValidationError(_("Please add a target label if you set no existing target")) raise ValidationError(_("Please add a target label if you set no existing target"))
if not self.accounting_type and not self.simpleaccounting_type:
raise ValidationError(_("You need to provide ether a simplified accounting type or a standard accounting type"))
if self.simpleaccounting_type:
self.accounting_type = self.simpleaccounting_type.accounting_type
@property
def target(self):
return self.get_target()
def get_target(self): def get_target(self):
tar = None tar = None
@ -237,9 +253,13 @@ class AccountingType(models.Model):
Thoses are numbers used in accounting to classify operations Thoses are numbers used in accounting to classify operations
""" """
code = models.CharField(_('code'), max_length=16) # TODO: add number validator code = models.CharField(_('code'), max_length=16,
label = models.CharField(_('label'), max_length=60) validators=[
movement_type = models.CharField(_('movement type'), choices=[('credit', 'Credit'), ('debit', 'Debit'), ('neutral', 'Neutral')], max_length=12) validators.RegexValidator(r'^[0-9]*$', _('An accounting type code contains only numbers')),
],
)
label = models.CharField(_('label'), max_length=128)
movement_type = models.CharField(_('movement type'), choices=[('CREDIT', 'Credit'), ('DEBIT', 'Debit'), ('NEUTRAL', 'Neutral')], max_length=12)
class Meta: class Meta:
verbose_name = _("accounting type") verbose_name = _("accounting type")
@ -256,4 +276,29 @@ class AccountingType(models.Model):
return reverse('accounting:type_list') return reverse('accounting:type_list')
def __str__(self): def __str__(self):
return self.movement_type+" - "+self.code+" - "+self.label return self.code+" - "+self.movement_type+" - "+self.label
class SimplifiedAccountingType(models.Model):
"""
Class describing the simplified accounting types.
"""
label = models.CharField(_('label'), max_length=128)
accounting_type = models.ForeignKey(AccountingType, related_name="simplified_types",
verbose_name=_("simplified accounting types"))
class Meta:
verbose_name = _("simplified type")
@property
def movement_type(self):
return self.accounting_type.movement_type
def get_movement_type_display(self):
return self.accounting_type.get_movement_type_display()
def get_absolute_url(self):
return reverse('accounting:simple_type_list')
def __str__(self):
return self.label+" - "+self.accounting_type.code+" - "+self.get_movement_type_display()

View File

@ -5,6 +5,11 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<p>
<a href="{{ url('accounting:bank_list') }}">{% trans %}Accounting{% endtrans %}</a> >
{% trans %}Accounting types{% endtrans %}
</p>
<hr>
<p><a href="{{ url('accounting:type_new') }}">{% trans %}New accounting type{% endtrans %}</a></p> <p><a href="{{ url('accounting:type_new') }}">{% trans %}New accounting type{% endtrans %}</a></p>
{% if accountingtype_list %} {% if accountingtype_list %}
<h3>{% trans %}Accounting type list{% endtrans %}</h3> <h3>{% trans %}Accounting type list{% endtrans %}</h3>

View File

@ -1,10 +1,15 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% block title %}
{% trans %}Bank account: {% endtrans %}{{ object.name }}
{% endblock %}
{% block content %} {% block content %}
<p> <p>
<a href="{{ url('accounting:bank_list') }}">{% trans %}Accounting{% endtrans %}</a> > <a href="{{ url('accounting:bank_list') }}">{% trans %}Accounting{% endtrans %}</a> >
{{ object.name }} {{ object.name }}
</p> </p>
<hr>
<h2>{% trans %}Bank account: {% endtrans %}{{ object.name }}</h2> <h2>{% trans %}Bank account: {% endtrans %}{{ object.name }}</h2>
<h4>{% trans %}Infos{% endtrans %}</h4> <h4>{% trans %}Infos{% endtrans %}</h4>
<ul> <ul>
@ -14,9 +19,12 @@
<p><a href="{{ url('accounting:club_new') }}?parent={{ object.id }}">{% trans %}New club account{% endtrans %}</a></p> <p><a href="{{ url('accounting:club_new') }}?parent={{ object.id }}">{% trans %}New club account{% endtrans %}</a></p>
<ul> <ul>
{% for c in object.club_accounts.all() %} {% for c in object.club_accounts.all() %}
<li><a href="{{ url('accounting:club_details', c_account_id=c.id) }}">{{ c }}</a> - <li><a href="{{ url('accounting:club_details', c_account_id=c.id) }}">{{ c }}</a>
<a href="{{ url('accounting:club_edit', c_account_id=c.id) }}">{% trans %}Edit{% endtrans %}</a> - - <a href="{{ url('accounting:club_edit', c_account_id=c.id) }}">{% trans %}Edit{% endtrans %}</a>
<a href="{{ url('accounting:club_delete', c_account_id=c.id) }}">{% trans %}Delete{% endtrans %}</a></li> {% if user.is_root %}
- <a href="{{ url('accounting:club_delete', c_account_id=c.id) }}">{% trans %}Delete{% endtrans %}</a>
{% endif %}
</li>
{% endfor %} {% endfor %}
</ul> </ul>

View File

@ -5,15 +5,24 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h4>
{% trans %}Accounting{% endtrans %}
</h4>
{% if user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name']) %}
<p><a href="{{ url('accounting:simple_type_list') }}">{% trans %}Manage simplified types{% endtrans %}</a></p>
<p><a href="{{ url('accounting:type_list') }}">{% trans %}Manage accounting types{% endtrans %}</a></p> <p><a href="{{ url('accounting:type_list') }}">{% trans %}Manage accounting types{% endtrans %}</a></p>
<p><a href="{{ url('accounting:bank_new') }}">{% trans %}New bank account{% endtrans %}</a></p> <p><a href="{{ url('accounting:bank_new') }}">{% trans %}New bank account{% endtrans %}</a></p>
{% endif %}
{% if bankaccount_list %} {% if bankaccount_list %}
<h3>{% trans %}Bank account list{% endtrans %}</h3> <h3>{% trans %}Bank account list{% endtrans %}</h3>
<ul> <ul>
{% for a in bankaccount_list %} {% for a in object_list %}
<li><a href="{{ url('accounting:bank_details', b_account_id=a.id) }}">{{ a }}</a> - <li><a href="{{ url('accounting:bank_details', b_account_id=a.id) }}">{{ a }}</a>
<a href="{{ url('accounting:bank_edit', b_account_id=a.id) }}">{% trans %}Edit{% endtrans %}</a> - - <a href="{{ url('accounting:bank_edit', b_account_id=a.id) }}">{% trans %}Edit{% endtrans %}</a>
<a href="{{ url('accounting:bank_delete', b_account_id=a.id) }}">{% trans %}Delete{% endtrans %}</a></li> {% if user.is_root %}
- <a href="{{ url('accounting:bank_delete', b_account_id=a.id) }}">{% trans %}Delete{% endtrans %}</a>
{% endif %}
</li>
{% endfor %} {% endfor %}
</ul> </ul>
{% else %} {% else %}

View File

@ -1,10 +1,16 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% block title %}
{% trans %}Club account:{% endtrans %} {{ object.name }}
{% endblock %}
{% block content %} {% block content %}
<p> <p>
<a href="{{ url('accounting:bank_list') }}">{% trans %}Accounting{% endtrans %}</a> > <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:bank_details', b_account_id=object.bank_account.id) }}">{{object.bank_account }}</a> >
{{ object }} {{ object }}
</p>
<hr>
<h2>{% trans %}Club account:{% endtrans %} {{ object.name }}</h2> <h2>{% trans %}Club account:{% endtrans %} {{ object.name }}</h2>
{% if not object.has_open_journal() %} {% if not object.has_open_journal() %}
<p><a href="{{ url('accounting:journal_new') }}?parent={{ object.id }}">{% trans %}New journal{% endtrans %}</a></p> <p><a href="{{ url('accounting:journal_new') }}?parent={{ object.id }}">{% trans %}New journal{% endtrans %}</a></p>

View File

@ -1,5 +1,9 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% block title %}
{% trans %}General journal:{% endtrans %} {{ object.name }}
{% endblock %}
{% block content %} {% block content %}
<p> <p>
<a href="{{ url('accounting:bank_list') }}">{% trans %}Accounting{% endtrans %}</a> > <a href="{{ url('accounting:bank_list') }}">{% trans %}Accounting{% endtrans %}</a> >
@ -7,6 +11,8 @@
<a href="{{ url('accounting:club_details', c_account_id=object.club_account.id) }}">{{ object.club_account }}</a> > <a href="{{ url('accounting:club_details', c_account_id=object.club_account.id) }}">{{ object.club_account }}</a> >
{{ object.name }} {{ object.name }}
</p> </p>
<hr>
<h2>{% trans %}General journal:{% endtrans %} {{ object.name }}</h2>
<p><strong>{% trans %}Amount: {% endtrans %}</strong>{{ object.amount }} € - <p><strong>{% trans %}Amount: {% endtrans %}</strong>{{ object.amount }} € -
<strong>{% trans %}Effective amount: {% endtrans %}</strong>{{ object.effective_amount }} €</p> <strong>{% trans %}Effective amount: {% endtrans %}</strong>{{ object.effective_amount }} €</p>
{% if object.closed %} {% if object.closed %}
@ -19,7 +25,6 @@
<tr> <tr>
<td>{% trans %}Nb{% endtrans %}</td> <td>{% trans %}Nb{% endtrans %}</td>
<td>{% trans %}Date{% endtrans %}</td> <td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Label{% endtrans %}</td>
<td>{% trans %}Amount{% endtrans %}</td> <td>{% trans %}Amount{% endtrans %}</td>
<td>{% trans %}Payment mode{% endtrans %}</td> <td>{% trans %}Payment mode{% endtrans %}</td>
<td>{% trans %}Target{% endtrans %}</td> <td>{% trans %}Target{% endtrans %}</td>
@ -36,7 +41,6 @@
<tr> <tr>
<td>{{ o.number }}</td> <td>{{ o.number }}</td>
<td>{{ o.date }}</td> <td>{{ o.date }}</td>
<td>{{ o.label }}</td>
<td>{{ o.amount }} €</td> <td>{{ o.amount }} €</td>
<td>{{ o.get_mode_display() }}</td> <td>{{ o.get_mode_display() }}</td>
{% if o.target_type == "OTHER" %} {% if o.target_type == "OTHER" %}

View File

@ -0,0 +1,55 @@
{% extends "core/base.jinja" %}
{% block title %}
{% trans %}Edit operation{% endtrans %}
{% endblock %}
{% block content %}
<h2>{% trans %}Edit operation{% endtrans %}</h2>
<form action="" method="post">
{% csrf_token %}
{{ form.journal }}
{{ form.target_id }}
<p>{{ form.amount.errors }}<label for="{{ form.amount.name }}">{{ form.amount.label }}</label> {{ form.amount }}</p>
<p>{{ form.remark.errors }}<label for="{{ form.remark.name }}">{{ form.remark.label }}</label> {{ form.remark }}</p>
<p>{{ form.target_type.errors }}<label for="{{ form.target_type.name }}">{{ form.target_type.label }}</label> </p>
{% for choice in form.target_type %}
{% if choice.choice_value != "" %}
{{ choice }}
{% if choice.choice_value == "USER" %}
{{ form.user }}
{% elif choice.choice_value == "CLUB" %}
{{ form.club }}
{% elif choice.choice_value == "ACCOUNT" %}
{{ form.club_account }}
{% elif choice.choice_value == "COMPANY" %}
{{ form.company }}
{% elif choice.choice_value == "OTHER" %}
{{ form.target_label }}
{% endif %}
{% else %}
{% endif %}
{% endfor %}
<p>{{ form.date.errors }}<label for="{{ form.date.name }}">{{ form.date.label }}</label> {{ form.date }}</p>
<p>{{ form.mode.errors }}<label for="{{ form.mode.name }}">{{ form.mode.label }}</label> {{ form.mode }}</p>
<p>{{ form.cheque_number.errors }}<label for="{{ form.cheque_number.name }}">{{ form.cheque_number.label }}</label> {{
form.cheque_number }}</p>
<p>{{ form.invoice.errors }}<label for="{{ form.invoice.name }}">{{ form.invoice.label }}</label> {{ form.invoice }}</p>
<p>{{ form.simpleaccounting_type.errors }}<label for="{{ form.simpleaccounting_type.name }}">{{
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.done.errors }}<label for="{{ form.done.name }}">{{ form.done.label }}</label> {{ form.done }}</p>
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p>
</form>
{% endblock %}
{% block script %}
{{ super() }}
<script>
$( function() {
} );
</script>
{% endblock %}

View File

@ -0,0 +1,25 @@
{% extends "core/base.jinja" %}
{% block title %}
{% trans %}Simplified type list{% endtrans %}
{% endblock %}
{% block content %}
<p>
<a href="{{ url('accounting:bank_list') }}">{% trans %}Accounting{% endtrans %}</a> >
{% trans %}Simplified types{% endtrans %}
</p>
<hr>
<p><a href="{{ url('accounting:simple_type_new') }}">{% trans %}New simplified type{% endtrans %}</a></p>
{% if simplifiedaccountingtype_list %}
<h3>{% trans %}Simplified type list{% endtrans %}</h3>
<ul>
{% for a in simplifiedaccountingtype_list %}
<li><a href="{{ url('accounting:simple_type_edit', type_id=a.id) }}">{{ a }}</a></li>
{% endfor %}
</ul>
{% else %}
{% trans %}There is no types in this website.{% endtrans %}
{% endif %}
{% endblock %}

View File

@ -3,6 +3,10 @@ from django.conf.urls import url, include
from accounting.views import * from accounting.views import *
urlpatterns = [ urlpatterns = [
# Accounting types
url(r'^simple_type$', SimplifiedAccountingTypeListView.as_view(), name='simple_type_list'),
url(r'^simple_type/create$', SimplifiedAccountingTypeCreateView.as_view(), name='simple_type_new'),
url(r'^simple_type/(?P<type_id>[0-9]+)/edit$', SimplifiedAccountingTypeEditView.as_view(), name='simple_type_edit'),
# Accounting types # Accounting types
url(r'^type$', AccountingTypeListView.as_view(), name='type_list'), url(r'^type$', AccountingTypeListView.as_view(), name='type_list'),
url(r'^type/create$', AccountingTypeCreateView.as_view(), name='type_new'), url(r'^type/create$', AccountingTypeCreateView.as_view(), name='type_new'),

View File

@ -4,10 +4,49 @@ from django.shortcuts import render
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy
from django.forms.models import modelform_factory from django.forms.models import modelform_factory
from django.forms import HiddenInput from django.forms import HiddenInput
from django import forms
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
from core.views.forms import SelectFile, SelectDate from core.views.forms import SelectFile, SelectDate
from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType, Company from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType, Company, SimplifiedAccountingType
# Main accounting view
class BankAccountListView(CanViewMixin, ListView):
"""
A list view for the admins
"""
model = BankAccount
template_name = 'accounting/bank_account_list.jinja'
ordering = ['name']
# Simplified accounting types
class SimplifiedAccountingTypeListView(CanViewMixin, ListView):
"""
A list view for the admins
"""
model = SimplifiedAccountingType
template_name = 'accounting/simplifiedaccountingtype_list.jinja'
class SimplifiedAccountingTypeEditView(CanViewMixin, UpdateView):
"""
An edit view for the admins
"""
model = SimplifiedAccountingType
pk_url_kwarg = "type_id"
fields = ['label', 'accounting_type']
template_name = 'core/edit.jinja'
class SimplifiedAccountingTypeCreateView(CanCreateMixin, CreateView):
"""
Create an accounting type (for the admins)
"""
model = SimplifiedAccountingType
fields = ['label', 'accounting_type']
template_name = 'core/create.jinja'
# Accounting types # Accounting types
@ -37,20 +76,13 @@ class AccountingTypeCreateView(CanCreateMixin, CreateView):
# BankAccount views # BankAccount views
class BankAccountListView(CanViewMixin, ListView):
"""
A list view for the admins
"""
model = BankAccount
template_name = 'accounting/bank_account_list.jinja'
class BankAccountEditView(CanViewMixin, UpdateView): class BankAccountEditView(CanViewMixin, UpdateView):
""" """
An edit view for the admins An edit view for the admins
""" """
model = BankAccount model = BankAccount
pk_url_kwarg = "b_account_id" pk_url_kwarg = "b_account_id"
fields = ['name', 'iban', 'number'] fields = ['name', 'iban', 'number', 'club']
template_name = 'core/edit.jinja' template_name = 'core/edit.jinja'
class BankAccountDetailView(CanViewMixin, DetailView): class BankAccountDetailView(CanViewMixin, DetailView):
@ -129,7 +161,8 @@ class JournalCreateView(CanCreateMixin, CreateView):
Create a general journal Create a general journal
""" """
model = GeneralJournal model = GeneralJournal
fields = ['name', 'start_date', 'club_account'] form_class = modelform_factory(GeneralJournal, fields=['name', 'start_date', 'club_account'],
widgets={ 'start_date': SelectDate, })
template_name = 'core/create.jinja' template_name = 'core/create.jinja'
def get_initial(self): def get_initial(self):
@ -159,16 +192,82 @@ class JournalEditView(CanEditMixin, UpdateView):
# Operation views # Operation views
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']
widgets = {
'journal': HiddenInput,
'target_id': HiddenInput,
'date': SelectDate,
'invoice': SelectFile,
'target_type': forms.RadioSelect,
}
user = AutoCompleteSelectField('users', help_text=None, required=False)
club_account = AutoCompleteSelectField('club_accounts', help_text=None, required=False)
club = AutoCompleteSelectField('clubs', help_text=None, required=False)
company = AutoCompleteSelectField('companies', help_text=None, required=False)
def __init__(self, *args, **kwargs):
super(OperationForm, self).__init__(*args, **kwargs)
if self.instance.target_type == "USER":
self.fields['user'].initial = self.instance.target_id
elif self.instance.target_type == "ACCOUNT":
self.fields['club_account'].initial = self.instance.target_id
elif self.instance.target_type == "CLUB":
self.fields['club'].initial = self.instance.target_id
elif self.instance.target_type == "COMPANY":
self.fields['company'].initial = self.instance.target_id
def clean(self):
self.cleaned_data = super(OperationForm, self).clean()
print(self.errors)
if self.cleaned_data['target_type'] == "USER":
self.cleaned_data['target_id'] = self.cleaned_data['user'].id
elif self.cleaned_data['target_type'] == "ACCOUNT":
self.cleaned_data['target_id'] = self.cleaned_data['club_account'].id
elif self.cleaned_data['target_type'] == "CLUB":
self.cleaned_data['target_id'] = self.cleaned_data['club'].id
elif self.cleaned_data['target_type'] == "COMPANY":
self.cleaned_data['target_id'] = self.cleaned_data['company'].id
return self.cleaned_data
def save(self):
ret = super(OperationForm, self).save()
if self.instance.target_type == "ACCOUNT" and not self.instance.linked_operation and self.instance.target.has_open_journal():
inst = self.instance
club_account = inst.target
acc_type = AccountingType.objects.exclude(movement_type="NEUTRAL").exclude(
movement_type=inst.accounting_type.movement_type).first() # Select a random opposite accounting type
op = Operation(
journal=club_account.get_open_journal(),
amount=inst.amount,
date=inst.date,
remark=inst.remark,
mode=inst.mode,
cheque_number=inst.cheque_number,
invoice=inst.invoice,
done=False, # Has to be checked by hand
simpleaccounting_type=None,
accounting_type=acc_type,
target_type="ACCOUNT",
target_id=inst.journal.club_account.id,
target_label="",
linked_operation=inst,
)
op.save()
self.instance.linked_operation = op
self.save()
return ret
class OperationCreateView(CanCreateMixin, CreateView): class OperationCreateView(CanCreateMixin, CreateView):
""" """
Create an operation Create an operation
""" """
model = Operation model = Operation
form_class = modelform_factory(Operation, form_class = OperationForm
fields=['amount', 'label', 'remark', 'journal', 'target_type', 'target_id', 'target_label', 'date', 'mode', template_name = 'accounting/operation_edit.jinja'
'cheque_number', 'invoice', 'accounting_type', 'done'],
widgets={'journal': HiddenInput, 'date': SelectDate, 'invoice': SelectFile})
template_name = 'core/create.jinja'
def get_initial(self): def get_initial(self):
ret = super(OperationCreateView, self).get_initial() ret = super(OperationCreateView, self).get_initial()
@ -184,11 +283,8 @@ class OperationEditView(CanEditMixin, UpdateView):
""" """
model = Operation model = Operation
pk_url_kwarg = "op_id" pk_url_kwarg = "op_id"
form_class = modelform_factory(Operation, form_class = OperationForm
fields = ['amount', 'label', 'remark', 'target_type', 'target_id', 'target_label', 'date', 'mode', 'cheque_number', template_name = 'accounting/operation_edit.jinja'
'invoice', 'accounting_type', 'done'],
widgets={'date': SelectDate, 'invoice': SelectFile})
template_name = 'core/edit.jinja'
# Company views # Company views

View File

@ -8,7 +8,7 @@
<li><a href="{{ url('club:club_view', club_id=club.id) }}">{{ club.name }}</a> <li><a href="{{ url('club:club_view', club_id=club.id) }}">{{ club.name }}</a>
{%- if club.children.all()|length != 0 %} {%- if club.children.all()|length != 0 %}
<ul> <ul>
{%- for c in club.children.all() %} {%- for c in club.children.order_by('name') %}
{{ display_club(c) }} {{ display_club(c) }}
{%- endfor %} {%- endfor %}
</ul> </ul>
@ -23,7 +23,7 @@
{% if club_list %} {% if club_list %}
<h3>{% trans %}Club list{% endtrans %}</h3> <h3>{% trans %}Club list{% endtrans %}</h3>
<ul> <ul>
{%- for c in club_list if c.parent is none %} {%- for c in club_list.order_by('name') if c.parent is none %}
{{ display_club(c) }} {{ display_club(c) }}
{%- endfor %} {%- endfor %}
</ul> </ul>

View File

@ -3,11 +3,11 @@
{% block content %} {% block content %}
<h3>{% trans %}Club tools{% endtrans %}</h3> <h3>{% trans %}Club tools{% endtrans %}</h3>
<p><a href="{{ url('club:club_view', club_id=object.id) }}">Back to club</a></p> <p><a href="{{ url('club:club_view', club_id=object.id) }}">Back to club</a></p>
<ul> <div>
{% if object.counters.all()|count > 0 %} {% if object.counters.filter(type="OFFICE")|count > 0 %}
<h4>{% trans %}Counters:{% endtrans %}</h4> <h4>{% trans %}Counters:{% endtrans %}</h4>
<ul> <ul>
{% for c in object.counters.all() %} {% for c in object.counters.filter(type="OFFICE") %}
<li>{{ c }}: <li>{{ c }}:
<a href="{{ url('counter:details', counter_id=c.id) }}">View</a> <a href="{{ url('counter:details', counter_id=c.id) }}">View</a>
<a href="{{ url('counter:admin', counter_id=c.id) }}">Edit</a> <a href="{{ url('counter:admin', counter_id=c.id) }}">Edit</a>
@ -15,13 +15,18 @@
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}
{% if object.club_account %} {% if object.club_account.exists() %}
<li>Accouting: <a href="{{ url('accounting:club_details', c_account_id=object.club_account.id) }}">{{ object }}</a></li> <h4>{% trans %}Accouting: {% endtrans %}</h4>
<ul>
{% for ca in object.club_account.all() %}
<li><a href="{{ url('accounting:club_details', c_account_id=ca.id) }}">{{ ca }}</a></li>
{% endfor %}
</ul>
{% endif %} {% endif %}
{% if object.unix_name == settings.SITH_LAUNDERETTE_MANAGER['unix_name'] %} {% if object.unix_name == settings.SITH_LAUNDERETTE_MANAGER['unix_name'] %}
<li><a href="{{ url('launderette:launderette_list') }}">{% trans %}Manage launderettes{% endtrans %}</a></li> <li><a href="{{ url('launderette:launderette_list') }}">{% trans %}Manage launderettes{% endtrans %}</a></li>
{% endif %} {% endif %}
</ul> </div>
{% endblock %} {% endblock %}

View File

@ -4,6 +4,7 @@ from core.views.site import search_user
from core.models import User, Group from core.models import User, Group
from club.models import Club from club.models import Club
from counter.models import Product, Counter from counter.models import Product, Counter
from accounting.models import ClubAccount, Company
@register('users') @register('users')
class UsersLookup(LookupChannel): class UsersLookup(LookupChannel):
@ -63,3 +64,23 @@ class ProductsLookup(LookupChannel):
def format_item_display(self, item): def format_item_display(self, item):
return item.name return item.name
@register('club_accounts')
class ClubAccountLookup(LookupChannel):
model = ClubAccount
def get_query(self, q, request):
return self.model.objects.filter(name__icontains=q)[:50]
def format_item_display(self, item):
return item.name
@register('companies')
class CompaniesLookup(LookupChannel):
model = Company
def get_query(self, q, request):
return self.model.objects.filter(name__icontains=q)[:50]
def format_item_display(self, item):
return item.name

View File

@ -36,6 +36,11 @@ header form {
margin: 0px auto; margin: 0px auto;
padding: 0.3em 1%; padding: 0.3em 1%;
} }
#language_chooser {
position: absolute;
left: 5px;
top: 5px;
}
/*---------------------------------NAV---------------------------------*/ /*---------------------------------NAV---------------------------------*/
nav { nav {

View File

@ -41,16 +41,17 @@
{% if user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name']) or user.is_root %} {% if user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name']) or user.is_root %}
<li><a href="{{ url('accounting:bank_list') }}">{% trans %}General accounting{% endtrans %}</a></li> <li><a href="{{ url('accounting:bank_list') }}">{% trans %}General accounting{% endtrans %}</a></li>
{% endif %} {% endif %}
{% for m in user.membership.filter(end_date=None).filter(role__gte=7).all() %} {% for m in user.membership.filter(end_date=None).filter(role__gte=7).all() -%}
{% for b in m.club.bank_accounts.all() %} {%- for b in m.club.bank_accounts.all() %}
<li><strong>{% trans %}Bank account: {% endtrans %}</strong> <li><strong>{% trans %}Bank account: {% endtrans %}</strong>
<a href="{{ url('accounting:bank_details', b_account_id=b.id) }}">{{ b.club }}</a></li> <a href="{{ url('accounting:bank_details', b_account_id=b.id) }}">{{ b }}</a></li>
{% endfor %} {%- endfor %}
{% if m.club.club_account %} {% if m.club.club_account.exists() -%}
<li><strong>{% trans %}Club account: {% endtrans %}</strong> {% for ca in m.club.club_account.all() %}
<a href="{{ url('accounting:club_details', c_account_id=m.club.club_account.id) }}">{{ m.club.club_account }}</a></li> <li><strong>{% trans %}Club account: {% endtrans %}</strong> <a href="{{ url('accounting:club_details', c_account_id=ca.id) }}">{{ ca }}</a></li>
{% endif %} {%- endfor %}
{% endfor %} {%- endif -%}
{%- endfor %}
</ul> </ul>
<hr> <hr>

View File

@ -4,6 +4,8 @@ from core.views import *
urlpatterns = [ urlpatterns = [
url(r'^$', index, name='index'), url(r'^$', index, name='index'),
# Search
url(r'^search/$', search_view, name='search'), url(r'^search/$', search_view, name='search'),
url(r'^search_json/$', search_json, name='search_json'), url(r'^search_json/$', search_json, name='search_json'),
url(r'^search_user/$', search_user_json, name='search_user'), url(r'^search_user/$', search_user_json, name='search_user'),

View File

@ -99,6 +99,17 @@ class CanViewMixin(View):
except: pass except: pass
raise PermissionDenied raise PermissionDenied
def get_context_data(self, **kwargs):
context = super(CanViewMixin, self).get_context_data(**kwargs)
if hasattr(self, 'object_list'):
ba_list = list(self.object_list)
l = []
for ba in ba_list:
if self.request.user.can_view(ba):
l.append(ba)
context['object_list'] = l
return context
from .user import * from .user import *
from .page import * from .page import *
from .files import * from .files import *

Binary file not shown.

View File

@ -6,7 +6,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-08-22 18:13+0200\n" "POT-Creation-Date: 2016-08-24 16:57+0200\n"
"PO-Revision-Date: 2016-07-18\n" "PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Skia <skia@libskia.so>\n" "Last-Translator: Skia <skia@libskia.so>\n"
"Language-Team: AE info <ae.info@utbm.fr>\n" "Language-Team: AE info <ae.info@utbm.fr>\n"
@ -16,125 +16,146 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: accounting/models.py:33 accounting/models.py:45 accounting/models.py:68 #: accounting/models.py:34 accounting/models.py:46 accounting/models.py:69
#: accounting/models.py:111 club/models.py:18 counter/models.py:52 #: accounting/models.py:115 club/models.py:18 counter/models.py:52
#: counter/models.py:77 counter/models.py:111 launderette/models.py:15 #: counter/models.py:77 counter/models.py:111 launderette/models.py:15
#: launderette/models.py:60 launderette/models.py:85 #: launderette/models.py:60 launderette/models.py:85
msgid "name" msgid "name"
msgstr "nom" msgstr "nom"
#: accounting/models.py:36 #: accounting/models.py:37
msgid "company" msgid "company"
msgstr "entreprise" msgstr "entreprise"
#: accounting/models.py:46 #: accounting/models.py:47
msgid "iban" msgid "iban"
msgstr "IBAN" msgstr "IBAN"
#: accounting/models.py:47 #: accounting/models.py:48
msgid "account number" msgid "account number"
msgstr "numero de compte" msgstr "numero de compte"
#: accounting/models.py:102 #: accounting/models.py:49 accounting/models.py:70 club/models.py:146
#: counter/models.py:86
msgid "club"
msgstr "club"
#: accounting/models.py:71
msgid "bank account"
msgstr "compte en banque"
#: accounting/models.py:106
#, python-format #, python-format
msgid "%(club_account)s on %(bank_account)s" msgid "%(club_account)s on %(bank_account)s"
msgstr "%(club_account)s sur %(bank_account)s" msgstr "%(club_account)s sur %(bank_account)s"
#: accounting/models.py:109 club/models.py:147 counter/models.py:297 #: accounting/models.py:113 club/models.py:147 counter/models.py:297
#: launderette/models.py:122 #: launderette/models.py:122
msgid "start date" msgid "start date"
msgstr "date de début" msgstr "date de début"
#: accounting/models.py:110 club/models.py:148 counter/models.py:298 #: accounting/models.py:114 club/models.py:148 counter/models.py:298
msgid "end date" msgid "end date"
msgstr "date de fin" msgstr "date de fin"
#: accounting/models.py:112 #: accounting/models.py:116
msgid "is closed" msgid "is closed"
msgstr "est fermé" msgstr "est fermé"
#: accounting/models.py:114 accounting/models.py:153 counter/models.py:25 #: accounting/models.py:117
msgid "club account"
msgstr "compte club"
#: accounting/models.py:118 accounting/models.py:157 counter/models.py:25
#: counter/models.py:212 #: counter/models.py:212
msgid "amount" msgid "amount"
msgstr "montant" msgstr "montant"
#: accounting/models.py:115 #: accounting/models.py:119
msgid "effective_amount" msgid "effective_amount"
msgstr "montant effectif" msgstr "montant effectif"
#: accounting/models.py:151 #: accounting/models.py:155
msgid "number" msgid "number"
msgstr "numéro" msgstr "numéro"
#: accounting/models.py:154 core/models.py:430 core/models.py:706 #: accounting/models.py:156
msgid "journal"
msgstr "classeur"
#: accounting/models.py:158 core/models.py:430 core/models.py:706
#: counter/models.py:215 counter/models.py:261 eboutic/models.py:14 #: counter/models.py:215 counter/models.py:261 eboutic/models.py:14
#: eboutic/models.py:47 #: eboutic/models.py:47
msgid "date" msgid "date"
msgstr "date" msgstr "date"
#: accounting/models.py:155 accounting/models.py:241 counter/models.py:253 #: accounting/models.py:159
msgid "label" msgid "comment"
msgstr "intitulé" msgstr "commentaire"
#: accounting/models.py:156 #: accounting/models.py:160 counter/models.py:216 counter/models.py:262
msgid "remark"
msgstr "remarque"
#: accounting/models.py:157 counter/models.py:216 counter/models.py:262
#: subscription/models.py:34 #: subscription/models.py:34
msgid "payment method" msgid "payment method"
msgstr "méthode de paiement" msgstr "méthode de paiement"
#: accounting/models.py:158 #: accounting/models.py:161
msgid "cheque number" msgid "cheque number"
msgstr "numéro de chèque" msgstr "numéro de chèque"
#: accounting/models.py:159 eboutic/models.py:115 #: accounting/models.py:162 eboutic/models.py:115
msgid "invoice" msgid "invoice"
msgstr "facture" msgstr "facture"
#: accounting/models.py:160 #: accounting/models.py:163
msgid "is done" msgid "is done"
msgstr "est fait" msgstr "est fait"
#: accounting/models.py:161 accounting/models.py:245 #: accounting/models.py:165
msgid "simple type"
msgstr "type simplifié"
#: accounting/models.py:167 accounting/models.py:265
msgid "accounting type" msgid "accounting type"
msgstr "type comptable" msgstr "type comptable"
#: accounting/models.py:162 #: accounting/models.py:168
msgid "target type" msgid "target type"
msgstr "type de cible" msgstr "type de cible"
#: accounting/models.py:163 #: accounting/models.py:169
#: launderette/templates/launderette/launderette_admin.jinja:44 #: launderette/templates/launderette/launderette_admin.jinja:44
msgid "User" msgid "User"
msgstr "Utilisateur" msgstr "Utilisateur"
#: accounting/models.py:163 club/templates/club/club_detail.jinja:4 #: accounting/models.py:169 club/templates/club/club_detail.jinja:4
msgid "Club" msgid "Club"
msgstr "Club" msgstr "Club"
#: accounting/models.py:163 core/templates/core/user_base.jinja:18 #: accounting/models.py:169 core/templates/core/user_base.jinja:18
msgid "Account" msgid "Account"
msgstr "Compte" msgstr "Compte"
#: accounting/models.py:163 #: accounting/models.py:169
msgid "Company" msgid "Company"
msgstr "Entreprise" msgstr "Entreprise"
#: accounting/models.py:163 sith/settings.py:284 sith/settings_sample.py:267 #: accounting/models.py:169 sith/settings.py:284 sith/settings_sample.py:267
msgid "Other" msgid "Other"
msgstr "Autre" msgstr "Autre"
#: accounting/models.py:164 #: accounting/models.py:170
msgid "target id" msgid "target id"
msgstr "id de la cible" msgstr "id de la cible"
#: accounting/models.py:165 #: accounting/models.py:171
msgid "target label" msgid "target label"
msgstr "nom de la cible" msgstr "nom de la cible"
#: accounting/models.py:180 #: accounting/models.py:172
msgid "linked operation"
msgstr "opération liée"
#: accounting/models.py:188
#, python-format #, python-format
msgid "" msgid ""
"The date can not be before the start date of the journal, which is\n" "The date can not be before the start date of the journal, which is\n"
@ -143,69 +164,102 @@ msgstr ""
"La date ne peut pas être avant la date de début du journal, qui est\n" "La date ne peut pas être avant la date de début du journal, qui est\n"
"%(start_date)s." "%(start_date)s."
#: accounting/models.py:183 #: accounting/models.py:191
msgid "Target does not exists" msgid "Target does not exists"
msgstr "La cible n'existe pas." msgstr "La cible n'existe pas."
#: accounting/models.py:185 #: accounting/models.py:193
msgid "Please add a target label if you set no existing target" msgid "Please add a target label if you set no existing target"
msgstr "" msgstr ""
"Merci d'ajouter un nom de cible si vous ne spécifiez pas de cible existante" "Merci d'ajouter un nom de cible si vous ne spécifiez pas de cible existante"
#: accounting/models.py:240 counter/models.py:81 #: accounting/models.py:195
msgid ""
"You need to provide ether a simplified accounting type or a standard "
"accounting type"
msgstr ""
"Vous devez fournir soit un type comptable simplifié ou un type comptable "
"standard"
#: accounting/models.py:256 counter/models.py:81
msgid "code" msgid "code"
msgstr "code" msgstr "code"
#: accounting/models.py:242 #: accounting/models.py:258
msgid "An accounting type code contains only numbers"
msgstr "Un code comptable ne contient que des numéros"
#: accounting/models.py:261 accounting/models.py:285 counter/models.py:253
msgid "label"
msgstr "intitulé"
#: accounting/models.py:262
msgid "movement type" msgid "movement type"
msgstr "type de mouvement" msgstr "type de mouvement"
#: accounting/models.py:287
msgid "simplified accounting types"
msgstr "type simplifié"
#: accounting/models.py:290
msgid "simplified type"
msgstr "type simplifié"
#: accounting/templates/accounting/accountingtype_list.jinja:4 #: accounting/templates/accounting/accountingtype_list.jinja:4
#: accounting/templates/accounting/accountingtype_list.jinja:10 #: accounting/templates/accounting/accountingtype_list.jinja:15
msgid "Accounting type list" msgid "Accounting type list"
msgstr "Liste des types comptable" msgstr "Liste des types comptable"
#: accounting/templates/accounting/accountingtype_list.jinja:8 #: accounting/templates/accounting/accountingtype_list.jinja:9
msgid "New accounting type" #: accounting/templates/accounting/bank_account_details.jinja:9
msgstr "Nouveau type comptable" #: accounting/templates/accounting/bank_account_list.jinja:9
#: accounting/templates/accounting/club_account_details.jinja:9
#: accounting/templates/accounting/accountingtype_list.jinja:17 #: accounting/templates/accounting/journal_details.jinja:9
msgid "There is no types in this website." #: accounting/templates/accounting/simplifiedaccountingtype_list.jinja:9
msgstr "Il n'y a pas de types comptable dans ce site web."
#: accounting/templates/accounting/bank_account_details.jinja:5
#: accounting/templates/accounting/club_account_details.jinja:5
#: accounting/templates/accounting/journal_details.jinja:5
#: core/templates/core/user_tools.jinja:39 #: core/templates/core/user_tools.jinja:39
msgid "Accounting" msgid "Accounting"
msgstr "Comptabilité" msgstr "Comptabilité"
#: accounting/templates/accounting/bank_account_details.jinja:8 #: accounting/templates/accounting/accountingtype_list.jinja:10
msgid "Accounting types"
msgstr "Type comptable"
#: accounting/templates/accounting/accountingtype_list.jinja:13
msgid "New accounting type"
msgstr "Nouveau type comptable"
#: accounting/templates/accounting/accountingtype_list.jinja:22
#: accounting/templates/accounting/simplifiedaccountingtype_list.jinja:22
msgid "There is no types in this website."
msgstr "Il n'y a pas de types comptable dans ce site web."
#: accounting/templates/accounting/bank_account_details.jinja:4
#: accounting/templates/accounting/bank_account_details.jinja:13
#: core/templates/core/user_tools.jinja:46 #: core/templates/core/user_tools.jinja:46
msgid "Bank account: " msgid "Bank account: "
msgstr "Compte en banque : " msgstr "Compte en banque : "
#: accounting/templates/accounting/bank_account_details.jinja:9 #: accounting/templates/accounting/bank_account_details.jinja:14
#: core/templates/core/user_base.jinja:7 #: core/templates/core/user_base.jinja:7
msgid "Infos" msgid "Infos"
msgstr "Infos" msgstr "Infos"
#: accounting/templates/accounting/bank_account_details.jinja:11 #: accounting/templates/accounting/bank_account_details.jinja:16
msgid "IBAN: " msgid "IBAN: "
msgstr "IBAN : " msgstr "IBAN : "
#: accounting/templates/accounting/bank_account_details.jinja:12 #: accounting/templates/accounting/bank_account_details.jinja:17
msgid "Number: " msgid "Number: "
msgstr "Numéro : " msgstr "Numéro : "
#: accounting/templates/accounting/bank_account_details.jinja:14 #: accounting/templates/accounting/bank_account_details.jinja:19
msgid "New club account" msgid "New club account"
msgstr "Nouveau compte club" msgstr "Nouveau compte club"
#: accounting/templates/accounting/bank_account_details.jinja:18 #: accounting/templates/accounting/bank_account_details.jinja:23
#: accounting/templates/accounting/bank_account_list.jinja:15 #: accounting/templates/accounting/bank_account_list.jinja:21
#: accounting/templates/accounting/club_account_details.jinja:44 #: accounting/templates/accounting/club_account_details.jinja:50
#: accounting/templates/accounting/journal_details.jinja:62 #: accounting/templates/accounting/journal_details.jinja:68
#: club/templates/club/club_detail.jinja:7 core/templates/core/file.jinja:38 #: club/templates/club/club_detail.jinja:7 core/templates/core/file.jinja:38
#: core/templates/core/page.jinja:31 core/templates/core/user_base.jinja:10 #: core/templates/core/page.jinja:31 core/templates/core/user_base.jinja:10
#: core/templates/core/user_tools.jinja:33 #: core/templates/core/user_tools.jinja:33
@ -214,8 +268,8 @@ msgstr "Nouveau compte club"
msgid "Edit" msgid "Edit"
msgstr "Éditer" msgstr "Éditer"
#: accounting/templates/accounting/bank_account_details.jinja:19 #: accounting/templates/accounting/bank_account_details.jinja:25
#: accounting/templates/accounting/bank_account_list.jinja:16 #: accounting/templates/accounting/bank_account_list.jinja:23
#: core/templates/core/file_detail.jinja:43 #: core/templates/core/file_detail.jinja:43
#: core/templates/core/group_list.jinja:13 #: core/templates/core/group_list.jinja:13
#: core/templates/core/user_edit.jinja:18 #: core/templates/core/user_edit.jinja:18
@ -225,144 +279,184 @@ msgid "Delete"
msgstr "Supprimer" msgstr "Supprimer"
#: accounting/templates/accounting/bank_account_list.jinja:4 #: accounting/templates/accounting/bank_account_list.jinja:4
#: accounting/templates/accounting/bank_account_list.jinja:11 #: accounting/templates/accounting/bank_account_list.jinja:17
msgid "Bank account list" msgid "Bank account list"
msgstr "Liste des comptes en banque" msgstr "Liste des comptes en banque"
#: accounting/templates/accounting/bank_account_list.jinja:8 #: accounting/templates/accounting/bank_account_list.jinja:12
msgid "Manage simplified types"
msgstr "Gérer les types simplifiés"
#: accounting/templates/accounting/bank_account_list.jinja:13
msgid "Manage accounting types" msgid "Manage accounting types"
msgstr "Gérer les types comptable" msgstr "Gérer les types comptable"
#: accounting/templates/accounting/bank_account_list.jinja:9 #: accounting/templates/accounting/bank_account_list.jinja:14
msgid "New bank account" msgid "New bank account"
msgstr "Nouveau compte en banque" msgstr "Nouveau compte en banque"
#: accounting/templates/accounting/bank_account_list.jinja:20 #: accounting/templates/accounting/bank_account_list.jinja:29
msgid "There is no accounts in this website." msgid "There is no accounts in this website."
msgstr "Il n'y a pas de comptes dans ce site web." msgstr "Il n'y a pas de comptes dans ce site web."
#: accounting/templates/accounting/club_account_details.jinja:8 #: accounting/templates/accounting/club_account_details.jinja:4
#: accounting/templates/accounting/club_account_details.jinja:14
msgid "Club account:" msgid "Club account:"
msgstr "Compte club : " msgstr "Compte club : "
#: accounting/templates/accounting/club_account_details.jinja:10 #: accounting/templates/accounting/club_account_details.jinja:16
msgid "New journal" msgid "New journal"
msgstr "Nouveau classeur" msgstr "Nouveau classeur"
#: accounting/templates/accounting/club_account_details.jinja:12 #: accounting/templates/accounting/club_account_details.jinja:18
msgid "You can not create new journal while you still have one opened" msgid "You can not create new journal while you still have one opened"
msgstr "Vous ne pouvez pas créer de journal tant qu'il y en a un d'ouvert" msgstr "Vous ne pouvez pas créer de journal tant qu'il y en a un d'ouvert"
#: accounting/templates/accounting/club_account_details.jinja:17 #: accounting/templates/accounting/club_account_details.jinja:23
#: launderette/templates/launderette/launderette_admin.jinja:43 #: launderette/templates/launderette/launderette_admin.jinja:43
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
#: accounting/templates/accounting/club_account_details.jinja:18 #: accounting/templates/accounting/club_account_details.jinja:24
msgid "Start" msgid "Start"
msgstr "Début" msgstr "Début"
#: accounting/templates/accounting/club_account_details.jinja:19 #: accounting/templates/accounting/club_account_details.jinja:25
msgid "End" msgid "End"
msgstr "Fin" msgstr "Fin"
#: accounting/templates/accounting/club_account_details.jinja:20 #: accounting/templates/accounting/club_account_details.jinja:26
#: accounting/templates/accounting/journal_details.jinja:23 #: accounting/templates/accounting/journal_details.jinja:29
#: core/templates/core/user_account.jinja:19 #: core/templates/core/user_account.jinja:19
#: core/templates/core/user_account.jinja:78 #: core/templates/core/user_account.jinja:78
msgid "Amount" msgid "Amount"
msgstr "Montant" msgstr "Montant"
#: accounting/templates/accounting/club_account_details.jinja:21 #: accounting/templates/accounting/club_account_details.jinja:27
msgid "Effective amount" msgid "Effective amount"
msgstr "Montant effectif" msgstr "Montant effectif"
#: accounting/templates/accounting/club_account_details.jinja:22 #: accounting/templates/accounting/club_account_details.jinja:28
msgid "Closed" msgid "Closed"
msgstr "Fermé" msgstr "Fermé"
#: accounting/templates/accounting/club_account_details.jinja:23 #: accounting/templates/accounting/club_account_details.jinja:29
#: accounting/templates/accounting/journal_details.jinja:31 #: accounting/templates/accounting/journal_details.jinja:37
msgid "Actions" msgid "Actions"
msgstr "Actions" msgstr "Actions"
#: accounting/templates/accounting/club_account_details.jinja:39 #: accounting/templates/accounting/club_account_details.jinja:45
#: accounting/templates/accounting/journal_details.jinja:50 #: accounting/templates/accounting/journal_details.jinja:56
msgid "Yes" msgid "Yes"
msgstr "Oui" msgstr "Oui"
#: accounting/templates/accounting/club_account_details.jinja:41 #: accounting/templates/accounting/club_account_details.jinja:47
#: accounting/templates/accounting/journal_details.jinja:52 #: accounting/templates/accounting/journal_details.jinja:58
msgid "No" msgid "No"
msgstr "Non" msgstr "Non"
#: accounting/templates/accounting/club_account_details.jinja:43 #: accounting/templates/accounting/club_account_details.jinja:49
#: core/templates/core/file.jinja:36 core/templates/core/page.jinja:28 #: core/templates/core/file.jinja:36 core/templates/core/page.jinja:28
msgid "View" msgid "View"
msgstr "Voir" msgstr "Voir"
#: accounting/templates/accounting/journal_details.jinja:10 #: accounting/templates/accounting/journal_details.jinja:4
#: accounting/templates/accounting/journal_details.jinja:15
msgid "General journal:"
msgstr "Classeur : "
#: accounting/templates/accounting/journal_details.jinja:16
#: core/templates/core/user_account.jinja:10 #: core/templates/core/user_account.jinja:10
#: counter/templates/counter/counter_click.jinja:31 #: counter/templates/counter/counter_click.jinja:31
msgid "Amount: " msgid "Amount: "
msgstr "Montant: " msgstr "Montant: "
#: accounting/templates/accounting/journal_details.jinja:11 #: accounting/templates/accounting/journal_details.jinja:17
msgid "Effective amount: " msgid "Effective amount: "
msgstr "Montant effectif: " msgstr "Montant effectif: "
#: accounting/templates/accounting/journal_details.jinja:13 #: accounting/templates/accounting/journal_details.jinja:19
msgid "Journal is closed, you can not create operation" msgid "Journal is closed, you can not create operation"
msgstr "Le classeur est fermé, vous ne pouvez pas créer d'opération" msgstr "Le classeur est fermé, vous ne pouvez pas créer d'opération"
#: accounting/templates/accounting/journal_details.jinja:15 #: accounting/templates/accounting/journal_details.jinja:21
msgid "New operation" msgid "New operation"
msgstr "Nouvelle opération" msgstr "Nouvelle opération"
#: accounting/templates/accounting/journal_details.jinja:20 #: accounting/templates/accounting/journal_details.jinja:26
msgid "Nb" msgid "Nb"
msgstr "No" msgstr "No"
#: accounting/templates/accounting/journal_details.jinja:21 #: accounting/templates/accounting/journal_details.jinja:27
#: core/templates/core/user_account.jinja:16 #: core/templates/core/user_account.jinja:16
#: core/templates/core/user_account.jinja:44 #: core/templates/core/user_account.jinja:44
#: core/templates/core/user_account.jinja:76 #: core/templates/core/user_account.jinja:76
msgid "Date" msgid "Date"
msgstr "Date" msgstr "Date"
#: accounting/templates/accounting/journal_details.jinja:22 #: accounting/templates/accounting/journal_details.jinja:28
#: core/templates/core/user_account.jinja:47 #: core/templates/core/user_account.jinja:47
msgid "Label" msgid "Label"
msgstr "Intitulé" msgstr "Intitulé"
#: accounting/templates/accounting/journal_details.jinja:24 #: accounting/templates/accounting/journal_details.jinja:30
msgid "Payment mode" msgid "Payment mode"
msgstr "Méthode de paiement" msgstr "Méthode de paiement"
#: accounting/templates/accounting/journal_details.jinja:25 #: accounting/templates/accounting/journal_details.jinja:31
msgid "Target" msgid "Target"
msgstr "Cible" msgstr "Cible"
#: accounting/templates/accounting/journal_details.jinja:26 #: accounting/templates/accounting/journal_details.jinja:32
msgid "Code" msgid "Code"
msgstr "Code" msgstr "Code"
#: accounting/templates/accounting/journal_details.jinja:27 #: accounting/templates/accounting/journal_details.jinja:33
msgid "Nature" msgid "Nature"
msgstr "Nature" msgstr "Nature"
#: accounting/templates/accounting/journal_details.jinja:28 #: accounting/templates/accounting/journal_details.jinja:34
msgid "Done" msgid "Done"
msgstr "Effectué" msgstr "Effectué"
#: accounting/templates/accounting/journal_details.jinja:29 #: accounting/templates/accounting/journal_details.jinja:35
msgid "Comment" msgid "Comment"
msgstr "Commentaire" msgstr "Commentaire"
#: accounting/templates/accounting/journal_details.jinja:30 #: accounting/templates/accounting/journal_details.jinja:36
msgid "File" msgid "File"
msgstr "Fichier" msgstr "Fichier"
#: accounting/templates/accounting/operation_edit.jinja:4
#: accounting/templates/accounting/operation_edit.jinja:8
msgid "Edit operation"
msgstr "Éditer l'opération"
#: accounting/templates/accounting/operation_edit.jinja:43
#: club/templates/club/club_edit.jinja:8
#: club/templates/club/club_edit_prop.jinja:8
#: core/templates/core/create.jinja:12 core/templates/core/edit.jinja:12
#: core/templates/core/file_edit.jinja:8 core/templates/core/page_prop.jinja:8
#: core/templates/core/pagerev_edit.jinja:24
#: counter/templates/counter/counter_edit.jinja:12
#: counter/templates/counter/counter_edit.jinja:14
#: subscription/templates/subscription/subscription.jinja:22
msgid "Save"
msgstr "Sauver"
#: accounting/templates/accounting/simplifiedaccountingtype_list.jinja:4
#: accounting/templates/accounting/simplifiedaccountingtype_list.jinja:15
msgid "Simplified type list"
msgstr "Liste des types simplifiés"
#: accounting/templates/accounting/simplifiedaccountingtype_list.jinja:10
msgid "Simplified types"
msgstr "Types simplifiés"
#: accounting/templates/accounting/simplifiedaccountingtype_list.jinja:13
msgid "New simplified type"
msgstr "Nouveau type simplifié"
#: club/models.py:20 #: club/models.py:20
msgid "unix name" msgid "unix name"
msgstr "nom unix" msgstr "nom unix"
@ -400,10 +494,6 @@ msgstr "Un club avec ce nom UNIX existe déjà."
msgid "user" msgid "user"
msgstr "nom d'utilisateur" msgstr "nom d'utilisateur"
#: club/models.py:146 counter/models.py:86
msgid "club"
msgstr "club"
#: club/models.py:149 core/models.py:135 #: club/models.py:149 core/models.py:135
msgid "role" msgid "role"
msgstr "rôle" msgstr "rôle"
@ -443,17 +533,6 @@ msgstr "Membres"
msgid "Edit club" msgid "Edit club"
msgstr "Éditer le club" msgstr "Éditer le club"
#: club/templates/club/club_edit.jinja:8
#: club/templates/club/club_edit_prop.jinja:8
#: core/templates/core/create.jinja:12 core/templates/core/edit.jinja:12
#: core/templates/core/file_edit.jinja:8 core/templates/core/page_prop.jinja:8
#: core/templates/core/pagerev_edit.jinja:24
#: counter/templates/counter/counter_edit.jinja:12
#: counter/templates/counter/counter_edit.jinja:14
#: subscription/templates/subscription/subscription.jinja:22
msgid "Save"
msgstr "Sauver"
#: club/templates/club/club_edit_prop.jinja:4 #: club/templates/club/club_edit_prop.jinja:4
msgid "Edit club properties" msgid "Edit club properties"
msgstr "Éditer les propriétés du club" msgstr "Éditer les propriétés du club"
@ -481,7 +560,7 @@ msgid "Add"
msgstr "Ajouter" msgstr "Ajouter"
#: club/templates/club/club_tools.jinja:4 #: club/templates/club/club_tools.jinja:4
#: core/templates/core/user_tools.jinja:57 #: core/templates/core/user_tools.jinja:58
msgid "Club tools" msgid "Club tools"
msgstr "Outils club" msgstr "Outils club"
@ -489,7 +568,11 @@ msgstr "Outils club"
msgid "Counters:" msgid "Counters:"
msgstr "Comptoirs : " msgstr "Comptoirs : "
#: club/templates/club/club_tools.jinja:22 #: club/templates/club/club_tools.jinja:19
msgid "Accouting: "
msgstr "Comptabilité : "
#: club/templates/club/club_tools.jinja:27
msgid "Manage launderettes" msgid "Manage launderettes"
msgstr "Gestion des laveries" msgstr "Gestion des laveries"
@ -1354,7 +1437,7 @@ msgstr "Profil actuel : "
#: core/templates/core/user_edit.jinja:24 #: core/templates/core/user_edit.jinja:24
msgid "Take picture" msgid "Take picture"
msgstr "" msgstr "Prendre une photo"
#: core/templates/core/user_edit.jinja:29 #: core/templates/core/user_edit.jinja:29
msgid "Current avatar: " msgid "Current avatar: "
@ -1447,7 +1530,7 @@ msgstr "Gestion des types de produit"
msgid "General accounting" msgid "General accounting"
msgstr "Comptabilité générale" msgstr "Comptabilité générale"
#: core/templates/core/user_tools.jinja:50 #: core/templates/core/user_tools.jinja:51
msgid "Club account: " msgid "Club account: "
msgstr "Compte club : " msgstr "Compte club : "
@ -1495,7 +1578,7 @@ msgstr "Mauvais format d'image, seuls les jpeg, png, et gif sont acceptés"
#: core/views/user.py:178 #: core/views/user.py:178
msgid "User already has a profile picture" msgid "User already has a profile picture"
msgstr "" msgstr "L'utilisateur a déjà une photo de profil"
#: counter/models.py:24 #: counter/models.py:24
msgid "account id" msgid "account id"
@ -2135,8 +2218,5 @@ msgid "You must either choose an existing user or create a new one properly"
msgstr "" msgstr ""
"Vous devez soit choisir un utilisateur existant, ou en créer un proprement." "Vous devez soit choisir un utilisateur existant, ou en créer un proprement."
#~ msgid "Products: " #~ msgid "remark"
#~ msgstr "Produits : " #~ msgstr "remarque"
#~ msgid "Club: "
#~ msgstr "Club : "

View File

@ -24,6 +24,7 @@ from club.models import Club, Membership
from counter.models import Customer, Counter, Selling, Refilling, Product, ProductType, Permanency from counter.models import Customer, Counter, Selling, Refilling, Product, ProductType, Permanency
from subscription.models import Subscription, Subscriber from subscription.models import Subscription, Subscriber
from eboutic.models import Invoice, InvoiceItem from eboutic.models import Invoice, InvoiceItem
from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType, Company, SimplifiedAccountingType
db = MySQLdb.connect( db = MySQLdb.connect(
host="ae-db", host="ae-db",
@ -467,7 +468,6 @@ def migrate_product_pict():
WHERE id_file IS NOT NULL WHERE id_file IS NOT NULL
""") """)
for r in cur: for r in cur:
print(r['nom_prod'])
try: try:
prod = Product.objects.filter(id=r['id_produit']).first() prod = Product.objects.filter(id=r['id_produit']).first()
if prod: if prod:
@ -602,24 +602,241 @@ def migrate_permanencies():
print("FAIL to migrate permanency: %s" % (repr(e))) print("FAIL to migrate permanency: %s" % (repr(e)))
cur.close() cur.close()
### Accounting
def migrate_bank_accounts():
cur = db.cursor(MySQLdb.cursors.SSDictCursor)
cur.execute("""
SELECT *
FROM cpta_cpbancaire
""")
BankAccount.objects.all().delete()
print("Bank accounts deleted")
ae = Club.objects.filter(unix_name='ae').first()
for r in cur:
try:
new = BankAccount(
id=r['id_cptbc'],
club=ae,
name=to_unicode(r['nom_cptbc']),
)
new.save()
except Exception as e:
print("FAIL to migrate bank account: %s" % (repr(e)))
cur.close()
def migrate_club_accounts():
cur = db.cursor(MySQLdb.cursors.SSDictCursor)
cur.execute("""
SELECT *
FROM cpta_cpasso
""")
ClubAccount.objects.all().delete()
print("Club accounts deleted")
ae = Club.objects.filter(id=1).first()
for r in cur:
try:
club = Club.objects.filter(id=r['id_asso']).first() or ae
bank_acc = BankAccount.objects.filter(id=r['id_cptbc']).first()
new = ClubAccount(
id=r['id_cptasso'],
club=club,
name=club.name[:30],
bank_account=bank_acc,
)
new.save()
except Exception as e:
print("FAIL to migrate club account: %s" % (repr(e)))
cur.close()
def migrate_journals():
cur = db.cursor(MySQLdb.cursors.SSDictCursor)
cur.execute("""
SELECT *
FROM cpta_classeur
""")
GeneralJournal.objects.all().delete()
print("General journals deleted")
for r in cur:
try:
club_acc = ClubAccount.objects.filter(id=r['id_cptasso']).first()
new = GeneralJournal(
id=r['id_classeur'],
club_account=club_acc,
name=to_unicode(r['nom_classeur']),
start_date=r['date_debut_classeur'],
end_date=r['date_fin_classeur'],
closed=bool(r['ferme']),
)
new.save()
except Exception as e:
print("FAIL to migrate general journal: %s" % (repr(e)))
cur.close()
def migrate_accounting_types():
MOVEMENT = {
-1: "DEBIT",
0: "NEUTRAL",
1: "CREDIT",
}
cur = db.cursor(MySQLdb.cursors.SSDictCursor)
cur.execute("""
SELECT *
FROM cpta_op_plcptl
""")
AccountingType.objects.all().delete()
print("Accounting types deleted")
for r in cur:
try:
new = AccountingType(
id=r['id_opstd'],
code=str(r['code_plan']),
label=to_unicode(r['libelle_plan']).capitalize(),
movement_type=MOVEMENT[r['type_mouvement']],
)
new.save()
except Exception as e:
print("FAIL to migrate accounting type: %s" % (repr(e)))
cur.close()
def migrate_simpleaccounting_types():
cur = db.cursor(MySQLdb.cursors.SSDictCursor)
cur.execute("""
SELECT *
FROM cpta_op_clb
WHERE id_asso IS NULL
""")
SimplifiedAccountingType.objects.all().delete()
print("Simple accounting types deleted")
for r in cur:
try:
at = AccountingType.objects.filter(id=r['id_opstd']).first()
new = SimplifiedAccountingType(
id=r['id_opclb'],
label=to_unicode(r['libelle_opclb']).capitalize(),
accounting_type=at,
)
new.save()
except Exception as e:
print("FAIL to migrate simple type: %s" % (repr(e)))
cur.close()
def migrate_operations():
MODE = {
1: "CHECK",
2: "CASH",
3: "TRANSFERT",
4: "CARD",
0: "CASH",
None: "CASH",
}
cur = db.cursor(MySQLdb.cursors.SSDictCursor)
cur.execute("""
SELECT *
FROM cpta_operation
""")
Operation.objects.all().delete()
print("Operation deleted")
for r in cur:
try:
simple_type = None
accounting_type = None
if r['id_opclb']:
simple_type = SimplifiedAccountingType.objects.filter(id=r['id_opclb']).first()
if r['id_opstd']:
accounting_type = AccountingType.objects.filter(id=r['id_opstd']).first()
if not accounting_type and simple_type:
accounting_type = simple_type.accounting_type
if not accounting_type:
accounting_type = AccountingType.objects.filter(movement_type="NEUTRAL").first()
journal = GeneralJournal.objects.filter(id=r['id_classeur']).first()
def get_target_type():
if r['id_utilisateur']:
return "USER"
if r['id_asso']:
return "CLUB"
if r['id_ent']:
return "COMPANY"
if r['id_classeur']:
return "ACCOUNT"
def get_target_id():
return int(r['id_utilisateur'] or r['id_asso'] or r['id_ent'] or r['id_classeur']) or None
new = Operation(
id=r['id_op'],
journal=journal,
amount=r['montant_op']/100,
date=r['date_op'] or journal.end_date,
remark=to_unicode(r['commentaire_op']),
mode=MODE[r['mode_op']],
cheque_number=str(r['num_cheque_op']),
done=bool(r['op_effctue']),
simpleaccounting_type=simple_type,
accounting_type=accounting_type,
target_type=get_target_type(),
target_id=get_target_id(),
target_label="-",
)
try:
new.clean()
except:
new.target_id = get_target_id()
new.target_type = "OTHER"
new.save()
except Exception as e:
print("FAIL to migrate operation: %s" % (repr(e)))
cur.close()
def make_operation_links():
cur = db.cursor(MySQLdb.cursors.SSDictCursor)
cur.execute("""
SELECT *
FROM cpta_operation
""")
for r in cur:
if r['id_op_liee']:
try:
op1 = Operation.objects.filter(id=r['id_op']).first()
op2 = Operation.objects.filter(id=r['id_op_liee']).first()
op1.linked_operation = op2
op1.save()
op2.linked_operation = op1
op2.save()
except Exception as e:
print("FAIL to link operations: %s" % (repr(e)))
cur.close()
def main(): def main():
migrate_users() start = datetime.datetime.now()
migrate_profile_pict() print("Start at %s" % start)
migrate_clubs() # migrate_users()
migrate_club_memberships() # migrate_profile_pict()
migrate_subscriptions() # migrate_clubs()
update_customer_account() # migrate_club_memberships()
migrate_counters() # migrate_subscriptions()
migrate_permanencies() # update_customer_account()
migrate_typeproducts() # migrate_counters()
migrate_products() # migrate_permanencies()
migrate_product_pict() # migrate_typeproducts()
migrate_products_to_counter() # migrate_products()
# migrate_product_pict()
# migrate_products_to_counter()
# reset_customer_amount() # reset_customer_amount()
migrate_invoices() # migrate_invoices()
migrate_refillings() # migrate_refillings()
migrate_sellings() # migrate_sellings()
reset_index('core', 'club', 'subscription', 'accounting', 'eboutic', 'launderette', 'counter') # reset_index('core', 'club', 'subscription', 'accounting', 'eboutic', 'launderette', 'counter')
# migrate_accounting_types()
# migrate_simpleaccounting_types()
# migrate_bank_accounts()
# migrate_club_accounts()
# migrate_journals()
# migrate_operations()
make_operation_links()
end = datetime.datetime.now()
print("End at %s" % end)
print("Running time: %s" % (end-start))
if __name__ == "__main__": if __name__ == "__main__":
main() main()