From 078b63d970417b714b0cd9a92f71fac83ae6591d Mon Sep 17 00:00:00 2001 From: Skia Date: Wed, 24 Aug 2016 19:50:22 +0200 Subject: [PATCH] Migrate accounting --- accounting/admin.py | 1 + .../migrations/0003_auto_20160824_1732.py | 104 ++++++ accounting/models.py | 75 +++- .../accounting/accountingtype_list.jinja | 5 + .../accounting/bank_account_details.jinja | 14 +- .../accounting/bank_account_list.jinja | 17 +- .../accounting/club_account_details.jinja | 6 + .../accounting/journal_details.jinja | 8 +- .../templates/accounting/operation_edit.jinja | 55 +++ .../simplifiedaccountingtype_list.jinja | 25 ++ accounting/urls.py | 4 + accounting/views.py | 136 ++++++-- club/templates/club/club_list.jinja | 4 +- club/templates/club/club_tools.jinja | 17 +- core/lookups.py | 21 ++ core/static/core/style.css | 5 + core/templates/core/user_tools.jinja | 19 +- core/urls.py | 2 + core/views/__init__.py | 11 + locale/fr/LC_MESSAGES/django.mo | Bin 29034 -> 30357 bytes locale/fr/LC_MESSAGES/django.po | 324 +++++++++++------- migrate.py | 251 +++++++++++++- 22 files changed, 904 insertions(+), 200 deletions(-) create mode 100644 accounting/migrations/0003_auto_20160824_1732.py create mode 100644 accounting/templates/accounting/operation_edit.jinja create mode 100644 accounting/templates/accounting/simplifiedaccountingtype_list.jinja diff --git a/accounting/admin.py b/accounting/admin.py index a2a32380..ac13cdb5 100644 --- a/accounting/admin.py +++ b/accounting/admin.py @@ -7,6 +7,7 @@ admin.site.register(BankAccount) admin.site.register(ClubAccount) admin.site.register(GeneralJournal) admin.site.register(AccountingType) +admin.site.register(SimplifiedAccountingType) admin.site.register(Operation) diff --git a/accounting/migrations/0003_auto_20160824_1732.py b/accounting/migrations/0003_auto_20160824_1732.py new file mode 100644 index 00000000..45256c7e --- /dev/null +++ b/accounting/migrations/0003_auto_20160824_1732.py @@ -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'), + ), + ] diff --git a/accounting/models.py b/accounting/models.py index a5c3d6bd..44508a4d 100644 --- a/accounting/models.py +++ b/accounting/models.py @@ -1,5 +1,6 @@ from django.core.urlresolvers import reverse from django.core.exceptions import ValidationError +from django.core import validators from django.db.models import Count from django.db import models from django.conf import settings @@ -45,7 +46,7 @@ class BankAccount(models.Model): name = models.CharField(_('name'), max_length=30) iban = models.CharField(_('iban'), 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): """ @@ -66,8 +67,8 @@ class BankAccount(models.Model): class ClubAccount(models.Model): name = models.CharField(_('name'), max_length=30) - club = models.OneToOneField(Club, related_name="club_account") - bank_account = models.ForeignKey(BankAccount, related_name="club_accounts") + club = models.ForeignKey(Club, related_name="club_account", verbose_name=_("club")) + bank_account = models.ForeignKey(BankAccount, related_name="club_accounts", verbose_name=_("bank account")) def is_owned_by(self, user): """ @@ -92,6 +93,9 @@ class ClubAccount(models.Model): return True return False + def get_open_journal(self): + return self.journals.filter(closed=False).first() + def get_absolute_url(self): 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')) 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) - 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) effective_amount = CurrencyField(_('effective_amount'), default=0) @@ -134,7 +138,7 @@ class GeneralJournal(models.Model): self.amount = 0 self.effective_amount = 0 for o in self.operations.all(): - if o.accounting_type.movement_type == "credit": + if o.accounting_type.movement_type == "CREDIT": if o.done: self.effective_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 """ 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')) date = models.DateField(_('date')) - label = models.CharField(_('label'), max_length=50) - remark = models.TextField(_('remark'), max_length=255) + remark = models.CharField(_('comment'), max_length=128) 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) 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, 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) + linked_operation = models.OneToOneField('self', related_name='operation_linked_to', verbose_name=_("linked operation"), + null=True, blank=True, default=None) class Meta: unique_together = ('number', 'journal') @@ -183,6 +191,14 @@ class Operation(models.Model): 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")) + 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): tar = None @@ -237,9 +253,13 @@ class AccountingType(models.Model): Thoses are numbers used in accounting to classify operations """ - code = models.CharField(_('code'), max_length=16) # TODO: add number validator - label = models.CharField(_('label'), max_length=60) - movement_type = models.CharField(_('movement type'), choices=[('credit', 'Credit'), ('debit', 'Debit'), ('neutral', 'Neutral')], max_length=12) + code = models.CharField(_('code'), max_length=16, + validators=[ + 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: verbose_name = _("accounting type") @@ -256,4 +276,29 @@ class AccountingType(models.Model): return reverse('accounting:type_list') 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() + diff --git a/accounting/templates/accounting/accountingtype_list.jinja b/accounting/templates/accounting/accountingtype_list.jinja index 6c84529d..c1d4b570 100644 --- a/accounting/templates/accounting/accountingtype_list.jinja +++ b/accounting/templates/accounting/accountingtype_list.jinja @@ -5,6 +5,11 @@ {% endblock %} {% block content %} +

+ {% trans %}Accounting{% endtrans %} > + {% trans %}Accounting types{% endtrans %} +

+

{% trans %}New accounting type{% endtrans %}

{% if accountingtype_list %}

{% trans %}Accounting type list{% endtrans %}

diff --git a/accounting/templates/accounting/bank_account_details.jinja b/accounting/templates/accounting/bank_account_details.jinja index 96ef7b30..19a121ef 100644 --- a/accounting/templates/accounting/bank_account_details.jinja +++ b/accounting/templates/accounting/bank_account_details.jinja @@ -1,10 +1,15 @@ {% extends "core/base.jinja" %} +{% block title %} +{% trans %}Bank account: {% endtrans %}{{ object.name }} +{% endblock %} + {% block content %}

{% trans %}Accounting{% endtrans %} > {{ object.name }}

+

{% trans %}Bank account: {% endtrans %}{{ object.name }}

{% trans %}Infos{% endtrans %}


diff --git a/core/urls.py b/core/urls.py index d4093f55..baeae800 100644 --- a/core/urls.py +++ b/core/urls.py @@ -4,6 +4,8 @@ from core.views import * urlpatterns = [ url(r'^$', index, name='index'), + + # Search url(r'^search/$', search_view, name='search'), url(r'^search_json/$', search_json, name='search_json'), url(r'^search_user/$', search_user_json, name='search_user'), diff --git a/core/views/__init__.py b/core/views/__init__.py index f866fe97..3aaf9d00 100644 --- a/core/views/__init__.py +++ b/core/views/__init__.py @@ -99,6 +99,17 @@ class CanViewMixin(View): except: pass 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 .page import * from .files import * diff --git a/locale/fr/LC_MESSAGES/django.mo b/locale/fr/LC_MESSAGES/django.mo index 0a5a5fcbbabf4aee5b67f0d0146f487978ef1515..c00c34dbc3e181afbf92b73a8ff35607ad5973d2 100644 GIT binary patch delta 11735 zcmaLb3w)0C|Htub8yj;Pb3WcqYi5iMbC~1iOyzuvnYl5xd+b1{Zj@3AwVXSNoKj(( zNPeUfsrVHlhvZNs6{Vy6U+??+EFL}n|Nr&y+4KATUf=6`zV3T=@#~<)-v{|mRw%aE z;kpv!I5lxoImcNQ>^MnvRO&dp8aYk_+>KT7JXXOQW|bJnsYE``?24_(k3gDqp1`vB zq`4aT=WOK%P57M?B$`kV*4S~Pu_bcD8HGJ@9){t6k+C_)Faj@PIR1$hF*MdKuYsk= z$6_e9Mm^sV%V2j5!9f^7|IRQHYG5K3N5AFgq8eC%C2$pLpc_#$_yW~n2!*Ow9;;zh zEQaw|8WT|iPeHBBK&*iCu@e0|&yXmOucDUfebfjKp&CAl8o*bm1}|9t8fs=YtURo# zyA>5t&&6OFY;JZ$wc8ifPCxXk;wTatu@{w}h#KJ()R}kywL+^2797z^hYhtFmnRxHJXO%a60mKI`^UW zayDwfb1?!RL)Ci*wW6z0GvAEb!tJP;e~RkIf6OXez{(U{wS0KI-11te`pr-?PC%`22jrjAl^-LR5vYMyLe-1L zX4n+96{*Ms{mwWN>M##AfcsD*d;~Rvg{T28wfu9IUvF-~DDH1ZE&XZKS-FPlI4sFs zkusxHItAQCL4CPVQlC(uwug$U9S@Q|m=7<$c%$7o!HU2bOA@Ns9`&C0Lhbng)Br}J zIvj)Q(1%*mdr&ib%I>eTe4)7$^*OK?_1rO3``@D4{RvCz{l7*+4LLpBr74A~P{Z_? z4Ka-J7}NmcEuUoh6x5-*9W@~@s@)vabN8ZFYA&k%`B;+vokb)x!xiRQ-5|deHG>^k z0zXDIa2VC#an$Q~7FGWmYNk3c>YyyDJQ72(7V7y1sQzNmuaUMQQ4*6;BkqfOU?}R) zq@wEiEI$*~z$2Dlf_m-+R0o?;1AN`eccPx(YaT`&!ZSTte^tCnfgb!5)nQOCcg7K@ z@@iNT>sWas)C}WM15HHL>wx+WNI|tb%uGYAOa_*~X&8dDda?eR$paMVqj3>xWSdYO z>_C05??%nw2!`WX)Yklf`e1Q-yIT>78fZf^4)t6cEQQ@r1MQD$XQ-0Q8T=Rx8ZfO;qCkvoqS(xf%jt+zKM6?Db$uE-QoU9mW=wvWHgq+JgkOuuq^X) zo+6=+UPL{(1GRU1P)qlb<-b6EYkh_Kr2G@LLXmg64c0dR;! z>ba5wT+3qx^3~9sE4Q!hE5SAjp6m_asqn_Jf=e$)&X zp(eB%HL#7S`mdn+d1D~!uf5z&K{B4eIIKI!{hIBEs<^{^A9ackpay;t>)|)(!SKQE zThtiUVG|6-c+^(5L=B(~YGR%JR?yE1hM5`Yp~7@5k1MbuZnFEk?fyZmMEMnr!V*K= z0mY$Kq(5pU(oqALin%xgS!~CDnS>5cm!bTr3`bx*K8YIX2dD-F>9jg*TvNsk2*G1J%(8)RL!L z`E=A7c@(whOHhY*CEkYXu>l@HZQ(Dd_QUzO4A%Q!nuHoIhZ;x~)CfIT9ivbWcE*}G z7*#(P)zM6I9%`u}e+Mt$G2~O*IfnX@i5=~p?h&X%nuqGpk6Pgcs3l*A+S2W)eh#TZO%fMTGY(60oC#PK zbrz2Zx3+jVur{(vfIy#Da&woa(M2|7{ODYDD_j^gGjqox?VO6jDm&}eBO@0#U{*%}ccVaxAMIEv#8g z8_>TKG~VqX3N_Nc7>cP_7ssInHqXjeqZ-ZhaSQ?NPt9+O!AE+l49pgn&ZwTF?Je8^xoY>5w*eGLQfn@exsj6BN8E#U7MiJz!20YTn1{dW}s&HFlsLsnoCh< z#ZhsD_7Pd7Ol;@m?&AucO-CgS6*&J|$6}f-g`FU&J!_C#qt}9Jhl?sF~EVd@NQV z-vZTfce4*_VEs@78;Y91Xw(EIq1wqqkKX_LNvNYWsEV6W72m>=_%5o!Pf&;H5b8BL zit6A;)bqcgCQvNb9Z)6ImQ_d9^Ps-0qEYR3!18+kdyr7W!%-cLLOtL`twa{;wVH_) za1m+-t5F?pMLo9%BXJ+Sr92fv_JqWDyI zW+dr4gsxwRABf|` zPRhpP7pQ&iY;`K&$Cjoz@IR^LxSg_N#3Z6JQJuK;(wEsax4`ez1=8WBs}P5w1vJ#jlxoVZ9V=H4vS^*7Pj(#kI&-O=*@A^$)SFYfQU z!_}^!U){)p(RGU{{1d6Bw_4YIqz4h@2z?#tI!AgS5k|aE{xpsv$`jv{?~A$~CH4`U z2>m|w5#_yzKS}o>bTuIVCNY-a4bbHe{MW%vyFVL3OCp|1b#Vylx{Ek$=^dzFXUpP; zR;D^{66-AAn{+1We#BXVlNflpUnG5$XhYQ0=i*6joFJ1y+)q>@x>DAH7(+S%U&W$J zpYkQh&%!164zZo|gP4L3p{^4|DbiakA1JgRddC8n-iyJ+aw@$`)FNh+*KYwwh#SOT z#8P4<_jGyjDg1yqK)MDolX#raH3tu3J`TY|D}U5ng9|C|f$HDcWjF31U5s=x(T?~^ zH|^SOuA=-|(mxm7z$Yk+$1K!u3;K;9h_tT9h(w|av6<*d=sLyyz3Tr5C5Zbeyo_h@ z8@!-eTpdX3y3fUVo&0etTZjWJy&GR3zNX&WM7ovRV*#GAG7ml;C}IAGNO%I7n?JrF zc@Lov&z4kfYY)!A`NSS#0r&Kor_Z^kiK1%^i9tjs>eM5AMA45pUh7b zw!%WY(b;^T@}{I4p{|NVFma6dkw~GuuhLjRJZ1GB#^J;{?)4)skX}vb`)~zObOrkF z#*N;@OT=74R}*3paVPmFRbW?t@)Jpah1adDgSnNm8J4bWip`YQCwx|xNBU)=nfAXP zg=@*^>S8M0i0E@mUS+!OCW;ZCbMH3Yw>tAk?k99Lr)(ImCt8u_FA+{Ev6iSxRHUp6 zHrM%2C9{&uM?`xfl>BeF3A+*viT{#cLKJORGU=jg8j1IcGMGU9(L@gE7-B5(5HX$5 zpRV6hdqfHH|1_9JfxeJ+btmp2A52UpvdA|kCXk*&=sJi?i91QZ6e!_OSEl%n)vH7L z67d}QKkzWojP$3(YSR9DNvt6eMf4|Ts*th?28C}E^N6nrU5^ltk?w`xVw9DCNd5}( z9Wl+yo*;e6(%+I!Bjym3i5G~0gs$_{If|cI-N8Y&p-)q=(F#?uKGDSTWw14|i?Roa z??|shFQIEIQH8Q{AJ3@yr-+0^-jc#n9V&{fi$KzgX9pC|nsp(}^7eMDgX_foLmDh2NH;{cIgl);U} zaN>2M4RM(m!81EBn>cCDe{f4Xhb*0Ieo4I$(l25JF+GTnl21r1qOd3GdXn@RH|Z=R zy_g8G{3tw4L=qz@*YysOWa)xH3GcY&`;Z?={G{^2GSQ=htEXq@`|>h;<2`xPC-WbV z&gm2=-_}zwF(xn8=Sfq^%_^Ss?6F>c`0~;+e7T-%U*>d=FF$LHHz&97cua}nC9@}c zbJFrMvVDao<6?tLOw7*D@ug+9Eewk97hEyTmp0z($<4@`oS88$!#h^J7Tn(A*OLE~ z6t-$7N*RtTL_rFClmMyy`VuH>YMW6K~!GZw{4j8PmUKoE^BIm*yLrmNWKW z>rpta^VHyQ-=w1Af}_bvRWtL)6y+T)7eBJHyuQ4`sww?~!fZtfCUk96F2gs8;oMxZ zXS=2b6%_A2q9qI94b0Q|zXz6k>pg8>;mGbyg2GyOnzw4(GO_US9xsK|8Avg^l{Gmp zZA_-uNp@2inHhO|Hh9?M_I(yK9ps}%U{kG{$LH>F24nV2$@hB3dULhOdp6``=N9hk z(;>9fZP}B_x%>Qg|5d@Ik~7nCbG`XFG+Ow~po_sZx^thE&E(O*(fVhF_iQM9aA=31 zf=$CpgcnVYvYo@W7LV=2PP^Ux`%StgXQnc@%qN*cs=8jhX)pybL8_BoSW3Q8cWFHaRS)%n>(MDkyDtE`AkrWbX%r^16iHR-CRSCI7?8@ c_i9kV{_HVLwP`n(#?e~*Kl#Gg$sL0J2M+%HyZ`_I delta 10512 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 diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 304184da..f96cb336 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "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" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -16,125 +16,146 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: accounting/models.py:33 accounting/models.py:45 accounting/models.py:68 -#: accounting/models.py:111 club/models.py:18 counter/models.py:52 +#: accounting/models.py:34 accounting/models.py:46 accounting/models.py:69 +#: accounting/models.py:115 club/models.py:18 counter/models.py:52 #: counter/models.py:77 counter/models.py:111 launderette/models.py:15 #: launderette/models.py:60 launderette/models.py:85 msgid "name" msgstr "nom" -#: accounting/models.py:36 +#: accounting/models.py:37 msgid "company" msgstr "entreprise" -#: accounting/models.py:46 +#: accounting/models.py:47 msgid "iban" msgstr "IBAN" -#: accounting/models.py:47 +#: accounting/models.py:48 msgid "account number" 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 msgid "%(club_account)s on %(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 msgid "start date" 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" msgstr "date de fin" -#: accounting/models.py:112 +#: accounting/models.py:116 msgid "is closed" 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 msgid "amount" msgstr "montant" -#: accounting/models.py:115 +#: accounting/models.py:119 msgid "effective_amount" msgstr "montant effectif" -#: accounting/models.py:151 +#: accounting/models.py:155 msgid "number" 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 #: eboutic/models.py:47 msgid "date" msgstr "date" -#: accounting/models.py:155 accounting/models.py:241 counter/models.py:253 -msgid "label" -msgstr "intitulé" +#: accounting/models.py:159 +msgid "comment" +msgstr "commentaire" -#: accounting/models.py:156 -msgid "remark" -msgstr "remarque" - -#: accounting/models.py:157 counter/models.py:216 counter/models.py:262 +#: accounting/models.py:160 counter/models.py:216 counter/models.py:262 #: subscription/models.py:34 msgid "payment method" msgstr "méthode de paiement" -#: accounting/models.py:158 +#: accounting/models.py:161 msgid "cheque number" msgstr "numéro de chèque" -#: accounting/models.py:159 eboutic/models.py:115 +#: accounting/models.py:162 eboutic/models.py:115 msgid "invoice" msgstr "facture" -#: accounting/models.py:160 +#: accounting/models.py:163 msgid "is done" 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" msgstr "type comptable" -#: accounting/models.py:162 +#: accounting/models.py:168 msgid "target type" msgstr "type de cible" -#: accounting/models.py:163 +#: accounting/models.py:169 #: launderette/templates/launderette/launderette_admin.jinja:44 msgid "User" 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" 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" msgstr "Compte" -#: accounting/models.py:163 +#: accounting/models.py:169 msgid "Company" 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" msgstr "Autre" -#: accounting/models.py:164 +#: accounting/models.py:170 msgid "target id" msgstr "id de la cible" -#: accounting/models.py:165 +#: accounting/models.py:171 msgid "target label" 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 msgid "" "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" "%(start_date)s." -#: accounting/models.py:183 +#: accounting/models.py:191 msgid "Target does not exists" 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" msgstr "" "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" 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" 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:10 +#: accounting/templates/accounting/accountingtype_list.jinja:15 msgid "Accounting type list" msgstr "Liste des types comptable" -#: accounting/templates/accounting/accountingtype_list.jinja:8 -msgid "New accounting type" -msgstr "Nouveau type comptable" - -#: accounting/templates/accounting/accountingtype_list.jinja:17 -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:5 -#: accounting/templates/accounting/club_account_details.jinja:5 -#: accounting/templates/accounting/journal_details.jinja:5 +#: accounting/templates/accounting/accountingtype_list.jinja:9 +#: accounting/templates/accounting/bank_account_details.jinja:9 +#: accounting/templates/accounting/bank_account_list.jinja:9 +#: accounting/templates/accounting/club_account_details.jinja:9 +#: accounting/templates/accounting/journal_details.jinja:9 +#: accounting/templates/accounting/simplifiedaccountingtype_list.jinja:9 #: core/templates/core/user_tools.jinja:39 msgid "Accounting" 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 msgid "Bank account: " 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 msgid "Infos" msgstr "Infos" -#: accounting/templates/accounting/bank_account_details.jinja:11 +#: accounting/templates/accounting/bank_account_details.jinja:16 msgid "IBAN: " msgstr "IBAN : " -#: accounting/templates/accounting/bank_account_details.jinja:12 +#: accounting/templates/accounting/bank_account_details.jinja:17 msgid "Number: " msgstr "Numéro : " -#: accounting/templates/accounting/bank_account_details.jinja:14 +#: accounting/templates/accounting/bank_account_details.jinja:19 msgid "New club account" msgstr "Nouveau compte club" -#: accounting/templates/accounting/bank_account_details.jinja:18 -#: accounting/templates/accounting/bank_account_list.jinja:15 -#: accounting/templates/accounting/club_account_details.jinja:44 -#: accounting/templates/accounting/journal_details.jinja:62 +#: accounting/templates/accounting/bank_account_details.jinja:23 +#: accounting/templates/accounting/bank_account_list.jinja:21 +#: accounting/templates/accounting/club_account_details.jinja:50 +#: accounting/templates/accounting/journal_details.jinja:68 #: 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/user_tools.jinja:33 @@ -214,8 +268,8 @@ msgstr "Nouveau compte club" msgid "Edit" msgstr "Éditer" -#: accounting/templates/accounting/bank_account_details.jinja:19 -#: accounting/templates/accounting/bank_account_list.jinja:16 +#: accounting/templates/accounting/bank_account_details.jinja:25 +#: accounting/templates/accounting/bank_account_list.jinja:23 #: core/templates/core/file_detail.jinja:43 #: core/templates/core/group_list.jinja:13 #: core/templates/core/user_edit.jinja:18 @@ -225,144 +279,184 @@ msgid "Delete" msgstr "Supprimer" #: 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" 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" 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" 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." 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:" msgstr "Compte club : " -#: accounting/templates/accounting/club_account_details.jinja:10 +#: accounting/templates/accounting/club_account_details.jinja:16 msgid "New journal" 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" 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 msgid "Name" msgstr "Nom" -#: accounting/templates/accounting/club_account_details.jinja:18 +#: accounting/templates/accounting/club_account_details.jinja:24 msgid "Start" msgstr "Début" -#: accounting/templates/accounting/club_account_details.jinja:19 +#: accounting/templates/accounting/club_account_details.jinja:25 msgid "End" msgstr "Fin" -#: accounting/templates/accounting/club_account_details.jinja:20 -#: accounting/templates/accounting/journal_details.jinja:23 +#: accounting/templates/accounting/club_account_details.jinja:26 +#: accounting/templates/accounting/journal_details.jinja:29 #: core/templates/core/user_account.jinja:19 #: core/templates/core/user_account.jinja:78 msgid "Amount" msgstr "Montant" -#: accounting/templates/accounting/club_account_details.jinja:21 +#: accounting/templates/accounting/club_account_details.jinja:27 msgid "Effective amount" msgstr "Montant effectif" -#: accounting/templates/accounting/club_account_details.jinja:22 +#: accounting/templates/accounting/club_account_details.jinja:28 msgid "Closed" msgstr "Fermé" -#: accounting/templates/accounting/club_account_details.jinja:23 -#: accounting/templates/accounting/journal_details.jinja:31 +#: accounting/templates/accounting/club_account_details.jinja:29 +#: accounting/templates/accounting/journal_details.jinja:37 msgid "Actions" msgstr "Actions" -#: accounting/templates/accounting/club_account_details.jinja:39 -#: accounting/templates/accounting/journal_details.jinja:50 +#: accounting/templates/accounting/club_account_details.jinja:45 +#: accounting/templates/accounting/journal_details.jinja:56 msgid "Yes" msgstr "Oui" -#: accounting/templates/accounting/club_account_details.jinja:41 -#: accounting/templates/accounting/journal_details.jinja:52 +#: accounting/templates/accounting/club_account_details.jinja:47 +#: accounting/templates/accounting/journal_details.jinja:58 msgid "No" 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 msgid "View" 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 #: counter/templates/counter/counter_click.jinja:31 msgid "Amount: " msgstr "Montant: " -#: accounting/templates/accounting/journal_details.jinja:11 +#: accounting/templates/accounting/journal_details.jinja:17 msgid "Effective amount: " 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" 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" msgstr "Nouvelle opération" -#: accounting/templates/accounting/journal_details.jinja:20 +#: accounting/templates/accounting/journal_details.jinja:26 msgid "Nb" 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:44 #: core/templates/core/user_account.jinja:76 msgid "Date" msgstr "Date" -#: accounting/templates/accounting/journal_details.jinja:22 +#: accounting/templates/accounting/journal_details.jinja:28 #: core/templates/core/user_account.jinja:47 msgid "Label" msgstr "Intitulé" -#: accounting/templates/accounting/journal_details.jinja:24 +#: accounting/templates/accounting/journal_details.jinja:30 msgid "Payment mode" msgstr "Méthode de paiement" -#: accounting/templates/accounting/journal_details.jinja:25 +#: accounting/templates/accounting/journal_details.jinja:31 msgid "Target" msgstr "Cible" -#: accounting/templates/accounting/journal_details.jinja:26 +#: accounting/templates/accounting/journal_details.jinja:32 msgid "Code" msgstr "Code" -#: accounting/templates/accounting/journal_details.jinja:27 +#: accounting/templates/accounting/journal_details.jinja:33 msgid "Nature" msgstr "Nature" -#: accounting/templates/accounting/journal_details.jinja:28 +#: accounting/templates/accounting/journal_details.jinja:34 msgid "Done" msgstr "Effectué" -#: accounting/templates/accounting/journal_details.jinja:29 +#: accounting/templates/accounting/journal_details.jinja:35 msgid "Comment" msgstr "Commentaire" -#: accounting/templates/accounting/journal_details.jinja:30 +#: accounting/templates/accounting/journal_details.jinja:36 msgid "File" 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 msgid "unix name" msgstr "nom unix" @@ -400,10 +494,6 @@ msgstr "Un club avec ce nom UNIX existe déjà." msgid "user" msgstr "nom d'utilisateur" -#: club/models.py:146 counter/models.py:86 -msgid "club" -msgstr "club" - #: club/models.py:149 core/models.py:135 msgid "role" msgstr "rôle" @@ -443,17 +533,6 @@ msgstr "Membres" msgid "Edit 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 msgid "Edit club properties" msgstr "Éditer les propriétés du club" @@ -481,7 +560,7 @@ msgid "Add" msgstr "Ajouter" #: club/templates/club/club_tools.jinja:4 -#: core/templates/core/user_tools.jinja:57 +#: core/templates/core/user_tools.jinja:58 msgid "Club tools" msgstr "Outils club" @@ -489,7 +568,11 @@ msgstr "Outils club" msgid "Counters:" 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" msgstr "Gestion des laveries" @@ -1354,7 +1437,7 @@ msgstr "Profil actuel : " #: core/templates/core/user_edit.jinja:24 msgid "Take picture" -msgstr "" +msgstr "Prendre une photo" #: core/templates/core/user_edit.jinja:29 msgid "Current avatar: " @@ -1447,7 +1530,7 @@ msgstr "Gestion des types de produit" msgid "General accounting" msgstr "Comptabilité générale" -#: core/templates/core/user_tools.jinja:50 +#: core/templates/core/user_tools.jinja:51 msgid "Club account: " 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 msgid "User already has a profile picture" -msgstr "" +msgstr "L'utilisateur a déjà une photo de profil" #: counter/models.py:24 msgid "account id" @@ -2135,8 +2218,5 @@ msgid "You must either choose an existing user or create a new one properly" msgstr "" "Vous devez soit choisir un utilisateur existant, ou en créer un proprement." -#~ msgid "Products: " -#~ msgstr "Produits : " - -#~ msgid "Club: " -#~ msgstr "Club : " +#~ msgid "remark" +#~ msgstr "remarque" diff --git a/migrate.py b/migrate.py index bac234a5..327bf39e 100644 --- a/migrate.py +++ b/migrate.py @@ -24,6 +24,7 @@ from club.models import Club, Membership from counter.models import Customer, Counter, Selling, Refilling, Product, ProductType, Permanency from subscription.models import Subscription, Subscriber from eboutic.models import Invoice, InvoiceItem +from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType, Company, SimplifiedAccountingType db = MySQLdb.connect( host="ae-db", @@ -467,7 +468,6 @@ def migrate_product_pict(): WHERE id_file IS NOT NULL """) for r in cur: - print(r['nom_prod']) try: prod = Product.objects.filter(id=r['id_produit']).first() if prod: @@ -602,24 +602,241 @@ def migrate_permanencies(): print("FAIL to migrate permanency: %s" % (repr(e))) 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(): - migrate_users() - migrate_profile_pict() - migrate_clubs() - migrate_club_memberships() - migrate_subscriptions() - update_customer_account() - migrate_counters() - migrate_permanencies() - migrate_typeproducts() - migrate_products() - migrate_product_pict() - migrate_products_to_counter() + start = datetime.datetime.now() + print("Start at %s" % start) + # migrate_users() + # migrate_profile_pict() + # migrate_clubs() + # migrate_club_memberships() + # migrate_subscriptions() + # update_customer_account() + # migrate_counters() + # migrate_permanencies() + # migrate_typeproducts() + # migrate_products() + # migrate_product_pict() + # migrate_products_to_counter() # reset_customer_amount() - migrate_invoices() - migrate_refillings() - migrate_sellings() - reset_index('core', 'club', 'subscription', 'accounting', 'eboutic', 'launderette', 'counter') + # migrate_invoices() + # migrate_refillings() + # migrate_sellings() + # 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__": main()