From 05bd177a9d074bd5430adb779bc5381e56906e81 Mon Sep 17 00:00:00 2001 From: Skia Date: Thu, 18 Aug 2016 19:52:20 +0200 Subject: [PATCH] Migrate invoices and lot of eboutic improvements --- core/templates/core/user_account.jinja | 20 +- counter/migrations/0009_auto_20160818_1709.py | 19 ++ counter/migrations/0010_auto_20160818_1716.py | 19 ++ counter/migrations/0011_auto_20160818_1722.py | 41 ++++ .../migrations/0012_selling_payment_method.py | 19 ++ counter/migrations/0013_auto_20160818_1736.py | 19 ++ counter/models.py | 23 ++- counter/views.py | 3 +- eboutic/migrations/0002_auto_20160818_1635.py | 34 +++ eboutic/migrations/0003_auto_20160818_1738.py | 19 ++ .../0004_remove_invoice_payment_method.py | 18 ++ eboutic/models.py | 51 +++-- eboutic/templates/eboutic/eboutic_main.jinja | 15 +- .../eboutic/eboutic_makecommand.jinja | 6 +- eboutic/views.py | 30 +-- locale/fr/LC_MESSAGES/django.mo | Bin 27857 -> 28020 bytes locale/fr/LC_MESSAGES/django.po | 195 +++++++++--------- migrate.py | 91 ++++++-- sith/settings_sample.py | 4 + 19 files changed, 470 insertions(+), 156 deletions(-) create mode 100644 counter/migrations/0009_auto_20160818_1709.py create mode 100644 counter/migrations/0010_auto_20160818_1716.py create mode 100644 counter/migrations/0011_auto_20160818_1722.py create mode 100644 counter/migrations/0012_selling_payment_method.py create mode 100644 counter/migrations/0013_auto_20160818_1736.py create mode 100644 eboutic/migrations/0002_auto_20160818_1635.py create mode 100644 eboutic/migrations/0003_auto_20160818_1738.py create mode 100644 eboutic/migrations/0004_remove_invoice_payment_method.py diff --git a/core/templates/core/user_account.jinja b/core/templates/core/user_account.jinja index 50a4d8ab..ca5093f5 100644 --- a/core/templates/core/user_account.jinja +++ b/core/templates/core/user_account.jinja @@ -14,48 +14,56 @@ {% trans %}Date{% endtrans %} + {% trans %}Counter{% endtrans %} {% trans %}Barman{% endtrans %} {% trans %}Amount{% endtrans %} + {% trans %}Payment method{% endtrans %} - {% for i in customer.refillings.all() %} + {% for i in customer.refillings.order_by('-date').all() %} {{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }} + {{ i.counter }} {{ i.operator.get_display_name() }} {{ i.amount }} € + {{ i.get_payment_method_display() }} {% endfor %} {% endif %} {% if customer.buyings.exists() %} -

{% trans %}Buyings{% endtrans %}

+

{% trans %}Account buyings{% endtrans %}

+ + - {% for i in customer.buyings.all() %} + {% for i in customer.buyings.order_by('-date').all() %} - + + + {% endfor %}
{% trans %}Date{% endtrans %}{% trans %}Counter{% endtrans %} {% trans %}Barman{% endtrans %} {% trans %}Label{% endtrans %} {% trans %}Quantity{% endtrans %} {% trans %}Total{% endtrans %}{% trans %}Payment method{% endtrans %}
{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}{{ i.seller }}{{ i.counter }}{{ i.seller.get_display_name() }} {{ i.label }} {{ i.quantity }} {{ i.quantity * i.unit_price }} €{{ i.get_payment_method_display() }}
{% endif %} {% if customer.user.invoices.exists() %} -

{% trans %}Invoices{% endtrans %}

+

{% trans %}Eboutic invoices{% endtrans %}

@@ -65,7 +73,7 @@ - {% for i in customer.user.invoices.all() %} + {% for i in customer.user.invoices.order_by('-date').all() %}
{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }} diff --git a/counter/migrations/0009_auto_20160818_1709.py b/counter/migrations/0009_auto_20160818_1709.py new file mode 100644 index 00000000..f6c9ccbf --- /dev/null +++ b/counter/migrations/0009_auto_20160818_1709.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('counter', '0008_auto_20160818_0231'), + ] + + operations = [ + migrations.AlterField( + model_name='refilling', + name='payment_method', + field=models.CharField(verbose_name='payment method', default='CASH', choices=[('CHECK', 'Check'), ('CASH', 'Cash'), ('EBOUTIC', 'Eboutic')], max_length=255), + ), + ] diff --git a/counter/migrations/0010_auto_20160818_1716.py b/counter/migrations/0010_auto_20160818_1716.py new file mode 100644 index 00000000..cb92c366 --- /dev/null +++ b/counter/migrations/0010_auto_20160818_1716.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('counter', '0009_auto_20160818_1709'), + ] + + operations = [ + migrations.AlterField( + model_name='refilling', + name='payment_method', + field=models.CharField(default='CASH', max_length=255, verbose_name='payment method', choices=[('CHECK', 'Check'), ('CASH', 'Cash'), ('CARD', 'Credit card')]), + ), + ] diff --git a/counter/migrations/0011_auto_20160818_1722.py b/counter/migrations/0011_auto_20160818_1722.py new file mode 100644 index 00000000..391f475d --- /dev/null +++ b/counter/migrations/0011_auto_20160818_1722.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + ('counter', '0010_auto_20160818_1716'), + ] + + operations = [ + migrations.AlterField( + model_name='selling', + name='club', + field=models.ForeignKey(related_name='sellings', null=True, on_delete=django.db.models.deletion.SET_NULL, to='club.Club'), + ), + migrations.AlterField( + model_name='selling', + name='counter', + field=models.ForeignKey(related_name='sellings', null=True, on_delete=django.db.models.deletion.SET_NULL, to='counter.Counter'), + ), + migrations.AlterField( + model_name='selling', + name='customer', + field=models.ForeignKey(related_name='buyings', null=True, on_delete=django.db.models.deletion.SET_NULL, to='counter.Customer'), + ), + migrations.AlterField( + model_name='selling', + name='product', + field=models.ForeignKey(related_name='sellings', null=True, on_delete=django.db.models.deletion.SET_NULL, blank=True, to='counter.Product'), + ), + migrations.AlterField( + model_name='selling', + name='seller', + field=models.ForeignKey(related_name='sellings_as_operator', null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/counter/migrations/0012_selling_payment_method.py b/counter/migrations/0012_selling_payment_method.py new file mode 100644 index 00000000..6f56d94e --- /dev/null +++ b/counter/migrations/0012_selling_payment_method.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('counter', '0011_auto_20160818_1722'), + ] + + operations = [ + migrations.AddField( + model_name='selling', + name='payment_method', + field=models.CharField(default='SITH_ACCOUNT', max_length=255, verbose_name='payment method', choices=[('SITH_ACCOUNT', 'Compte AE'), ('CARD', 'Credit card')]), + ), + ] diff --git a/counter/migrations/0013_auto_20160818_1736.py b/counter/migrations/0013_auto_20160818_1736.py new file mode 100644 index 00000000..d509ec9d --- /dev/null +++ b/counter/migrations/0013_auto_20160818_1736.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('counter', '0012_selling_payment_method'), + ] + + operations = [ + migrations.AlterField( + model_name='selling', + name='payment_method', + field=models.CharField(max_length=255, default='SITH_ACCOUNT', verbose_name='payment method', choices=[('SITH_ACCOUNT', 'Sith account'), ('CARD', 'Credit card')]), + ), + ] diff --git a/counter/models.py b/counter/models.py index 7a76c1e3..066f6bbc 100644 --- a/counter/models.py +++ b/counter/models.py @@ -5,7 +5,8 @@ from django.conf import settings from django.core.urlresolvers import reverse from django.forms import ValidationError -from datetime import timedelta +from datetime import timedelta, datetime +from pytz import timezone import random import string @@ -206,7 +207,7 @@ class Refilling(models.Model): amount = CurrencyField(_('amount')) operator = models.ForeignKey(User, related_name="refillings_as_operator", blank=False) customer = models.ForeignKey(Customer, related_name="refillings", blank=False) - date = models.DateTimeField(_('date'), auto_now=True) + date = models.DateTimeField(_('date')) payment_method = models.CharField(_('payment method'), max_length=255, choices=settings.SITH_COUNTER_PAYMENT_METHOD, default='CASH') bank = models.CharField(_('bank'), max_length=255, @@ -223,6 +224,8 @@ class Refilling(models.Model): # return reverse('counter:details', kwargs={'counter_id': self.id}) def save(self, *args, **kwargs): + if not self.date: + self.date = datetime.now().replace(tzinfo=timezone(settings.TIME_ZONE)) self.full_clean() if not self.is_validated: self.customer.amount += self.amount @@ -235,14 +238,16 @@ class Selling(models.Model): Handle the sellings """ label = models.CharField(_("label"), max_length=64) - product = models.ForeignKey(Product, related_name="sellings", null=True, blank=True) - counter = models.ForeignKey(Counter, related_name="sellings", blank=False) - club = models.ForeignKey(Club, related_name="sellings", blank=False) + product = models.ForeignKey(Product, related_name="sellings", null=True, blank=True, on_delete=models.SET_NULL) + counter = models.ForeignKey(Counter, related_name="sellings", null=True, blank=False, on_delete=models.SET_NULL) + club = models.ForeignKey(Club, related_name="sellings", null=True, blank=False, on_delete=models.SET_NULL) unit_price = CurrencyField(_('unit price')) quantity = models.IntegerField(_('quantity')) - seller = models.ForeignKey(User, related_name="sellings_as_operator", blank=False) - customer = models.ForeignKey(Customer, related_name="buyings", blank=False) - date = models.DateTimeField(_('date'), auto_now=True) + seller = models.ForeignKey(User, related_name="sellings_as_operator", null=True, blank=False, on_delete=models.SET_NULL) + customer = models.ForeignKey(Customer, related_name="buyings", null=True, blank=False, on_delete=models.SET_NULL) + date = models.DateTimeField(_('date')) + payment_method = models.CharField(_('payment method'), max_length=255, + choices=[('SITH_ACCOUNT', _('Sith account')), ('CARD', _('Credit card'))], default='SITH_ACCOUNT') is_validated = models.BooleanField(_('is validated'), default=False) class Meta: @@ -253,6 +258,8 @@ class Selling(models.Model): self.quantity*self.unit_price, self.customer.user.get_display_name()) def save(self, *args, **kwargs): + if not self.date: + self.date = datetime.now().replace(tzinfo=timezone(settings.TIME_ZONE)) self.full_clean() if not self.is_validated: self.customer.amount -= self.quantity * self.unit_price diff --git a/counter/views.py b/counter/views.py index 361e4833..f6298df0 100644 --- a/counter/views.py +++ b/counter/views.py @@ -44,7 +44,8 @@ class GetUserForm(forms.Form): elif cleaned_data['id'] is not None: cus = Customer.objects.filter(user=cleaned_data['id']).first() sub = get_subscriber(cus.user) if cus is not None else None - if cus is None or sub is None or (date.today() - sub.subscriptions.last().subscription_end) > timedelta(days=90): + if (cus is None or sub is None or not sub.subscriptions.last() or + (date.today() - sub.subscriptions.last().subscription_end) > timedelta(days=90)): raise forms.ValidationError(_("User not found")) cleaned_data['user_id'] = cus.user.id cleaned_data['user'] = cus.user diff --git a/eboutic/migrations/0002_auto_20160818_1635.py b/eboutic/migrations/0002_auto_20160818_1635.py new file mode 100644 index 00000000..f1a52223 --- /dev/null +++ b/eboutic/migrations/0002_auto_20160818_1635.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('eboutic', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='basketitem', + name='type', + ), + migrations.RemoveField( + model_name='invoiceitem', + name='type', + ), + migrations.AddField( + model_name='basketitem', + name='type_id', + field=models.IntegerField(default=1, verbose_name='product type id'), + preserve_default=False, + ), + migrations.AddField( + model_name='invoiceitem', + name='type_id', + field=models.IntegerField(default=1, verbose_name='product type id'), + preserve_default=False, + ), + ] diff --git a/eboutic/migrations/0003_auto_20160818_1738.py b/eboutic/migrations/0003_auto_20160818_1738.py new file mode 100644 index 00000000..0b72703a --- /dev/null +++ b/eboutic/migrations/0003_auto_20160818_1738.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('eboutic', '0002_auto_20160818_1635'), + ] + + operations = [ + migrations.AlterField( + model_name='invoice', + name='payment_method', + field=models.CharField(verbose_name='payment method', max_length=20, choices=[('CARD', 'Credit card'), ('SITH_ACCOUNT', 'Sith account')]), + ), + ] diff --git a/eboutic/migrations/0004_remove_invoice_payment_method.py b/eboutic/migrations/0004_remove_invoice_payment_method.py new file mode 100644 index 00000000..27241c1e --- /dev/null +++ b/eboutic/migrations/0004_remove_invoice_payment_method.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('eboutic', '0003_auto_20160818_1738'), + ] + + operations = [ + migrations.RemoveField( + model_name='invoice', + name='payment_method', + ), + ] diff --git a/eboutic/models.py b/eboutic/models.py index 58ee1063..2f4bc61b 100644 --- a/eboutic/models.py +++ b/eboutic/models.py @@ -1,8 +1,9 @@ from django.db import models, DataError from django.utils.translation import ugettext_lazy as _ +from django.conf import settings from accounting.models import CurrencyField -from counter.models import Counter, Product, Customer +from counter.models import Counter, Product, Customer, Selling, Refilling from core.models import User class Basket(models.Model): @@ -15,7 +16,7 @@ class Basket(models.Model): def add_product(self, p, q = 1): item = self.items.filter(product_id=p.id).first() if item is None: - BasketItem(basket=self, product_id=p.id, product_name=p.name, type=p.product_type.name, + BasketItem(basket=self, product_id=p.id, product_name=p.name, type_id=p.product_type.id, quantity=q, product_unit_price=p.selling_price).save() else: item.quantity += q @@ -44,10 +45,11 @@ class Invoice(models.Model): """ user = models.ForeignKey(User, related_name='invoices', verbose_name=_('user'), blank=False) date = models.DateTimeField(_('date'), auto_now=True) - payment_method = models.CharField(choices=[('CREDIT_CARD', _('Credit card')), ('SITH_ACCOUNT', _('Sith account'))], - max_length=20, verbose_name=_('payment method')) validated = models.BooleanField(_("validated"), default=False) + def __str__(self): + return "%s - %s - %s" % (self.user, self.get_total(), self.date) + def get_total(self): total = 0 for i in self.items.all(): @@ -59,23 +61,44 @@ class Invoice(models.Model): raise DataError(_("Invoice already validated")) from counter.models import Customer if not Customer.objects.filter(user=self.user).exists(): - number = Customer.objects.last().account_id[:-1] + number = Customer.objects.count() + 1 Customer(user=self.user, account_id=Customer.generate_account_id(number), amount=0).save() - if self.payment_method == "SITH_ACCOUNT": - self.user.customer.amount -= self.get_total() - self.user.customer.save() - else: - for i in self.items.filter(type="REFILLING").all(): - self.user.customer.amount += i.product_unit_price * i.quantity - self.user.customer.save() - + eboutic = Counter.objects.filter(type="EBOUTIC").first() + for i in self.items.all(): + if i.type_id == settings.SITH_COUNTER_PRODUCTTYPE_REFILLING: + new = Refilling( + counter=eboutic, + customer=self.user.customer, + operator=self.user, + amount=i.product_unit_price * i.quantity, + payment_method="CARD", + bank="OTHER", + date=self.date, + ) + new.save() + else: + product = Product.objects.filter(id=i.product_id).first() + new = Selling( + label=i.product_name, + counter=eboutic, + club=product.club, + product=product, + seller=self.user, + customer=self.user.customer, + unit_price=i.product_unit_price, + quantity=i.quantity, + payment_method="CARD", + is_validated=True, + date=self.date, + ) + new.save() self.validated = True self.save() class AbstractBaseItem(models.Model): product_id = models.IntegerField(_('product id')) product_name = models.CharField(_('product name'), max_length=255) - type = models.CharField(_('product type'), max_length=255) + type_id = models.IntegerField(_('product type id')) product_unit_price = CurrencyField(_('unit price')) quantity = models.IntegerField(_('quantity')) diff --git a/eboutic/templates/eboutic/eboutic_main.jinja b/eboutic/templates/eboutic/eboutic_main.jinja index 68d4f7e8..cce2caf3 100644 --- a/eboutic/templates/eboutic/eboutic_main.jinja +++ b/eboutic/templates/eboutic/eboutic_main.jinja @@ -1,5 +1,9 @@ {% extends "core/base.jinja" %} +{% block title %} +{% trans %}Eboutic{% endtrans %} +{% endblock %} + {% macro add_product(id, content) %}
{% csrf_token %} @@ -34,11 +38,14 @@
-

{% trans %}Products: {% endtrans %} - {% for p in eboutic.products.all() %} - {{ add_product(p.id, p.name) }} + {% for t in categories %} + {% if eboutic.products.filter(product_type=t).exists() %} +

{{ t }}
+ {% for p in eboutic.products.filter(product_type=t).all() %} + {{ add_product(p.id, p.name) }} + {% endfor %} + {% endif %} {% endfor %} -

{% endblock %} diff --git a/eboutic/templates/eboutic/eboutic_makecommand.jinja b/eboutic/templates/eboutic/eboutic_makecommand.jinja index 33e93a6c..f60986ce 100644 --- a/eboutic/templates/eboutic/eboutic_makecommand.jinja +++ b/eboutic/templates/eboutic/eboutic_makecommand.jinja @@ -1,5 +1,9 @@ {% extends "core/base.jinja" %} +{% block title %} +{% trans %}Basket state{% endtrans %} +{% endblock %} + {% block content %}

{% trans %}Eboutic{% endtrans %}

@@ -30,7 +34,7 @@ {% endfor %} - {% if basket.items.filter(type="REFILLING").exists() %} + {% if basket.items.filter(type_id=settings.SITH_COUNTER_PRODUCTTYPE_REFILLING).exists() %}

{% trans %}AE account payment disabled because your basket contains refilling items.{% endtrans %}

{% else %}
diff --git a/eboutic/views.py b/eboutic/views.py index 18f5eaae..f698b9b0 100644 --- a/eboutic/views.py +++ b/eboutic/views.py @@ -14,10 +14,9 @@ from django.db import transaction, DataError from django.utils.translation import ugettext as _ from django.conf import settings -from counter.models import Product, Customer, Counter +from counter.models import Product, Customer, Counter, ProductType, Selling from eboutic.models import Basket, Invoice, BasketItem, InvoiceItem -# Create your views here. class EbouticMain(TemplateView): template_name = 'eboutic/eboutic_main.jinja' @@ -72,6 +71,7 @@ class EbouticMain(TemplateView): kwargs = super(EbouticMain, self).get_context_data(**kwargs) kwargs['basket'] = self.basket kwargs['eboutic'] = Counter.objects.filter(type="EBOUTIC").first() + kwargs['categories'] = ProductType.objects.all() return kwargs class EbouticCommand(TemplateView): @@ -125,7 +125,7 @@ class EbouticPayWithSith(TemplateView): if 'basket_id' not in request.session.keys() or not request.user.is_authenticated(): return HttpResponseRedirect(reverse_lazy('eboutic:main', args=self.args, kwargs=kwargs)) b = Basket.objects.filter(id=request.session['basket_id']).first() - if b is None or b.items.filter(type="REFILLING").exists(): + if b is None or b.items.filter(type_id=settings.SITH_COUNTER_PRODUCTTYPE_REFILLING).exists(): return HttpResponseRedirect(reverse_lazy('eboutic:main', args=self.args, kwargs=kwargs)) c = Customer.objects.filter(user__id=b.user.id).first() if c is None: @@ -134,14 +134,20 @@ class EbouticPayWithSith(TemplateView): if c.amount < b.get_total(): raise DataError(_("You do not have enough money to buy the basket")) else: - i = Invoice() - i.user = b.user - i.payment_method = "SITH_ACCOUNT" - i.save() + eboutic = Counter.objects.filter(type="EBOUTIC").first() for it in b.items.all(): - InvoiceItem(invoice=i, product_id=it.product_id, product_name=it.product_name, type=it.type, - product_unit_price=it.product_unit_price, quantity=it.quantity).save() - i.validate() + product = Product.objects.filter(id=it.product_id).first() + Selling( + label=it.product_name, + counter=eboutic, + club=product.club, + product=product, + seller=c.user, + customer=c, + unit_price=it.product_unit_price, + quantity=it.quantity, + payment_method="SITH_ACCOUNT", + ).save() b.delete() kwargs['not_enough'] = False request.session.pop('basket_id', None) @@ -172,10 +178,10 @@ class EtransactionAutoAnswer(View): return HttpResponse("Basket does not exists", status=400) i = Invoice() i.user = b.user - i.payment_method = "CREDIT_CARD" + i.payment_method = "CARD" i.save() for it in b.items.all(): - InvoiceItem(invoice=i, product_id=it.product_id, product_name=it.product_name, type=it.type, + InvoiceItem(invoice=i, product_id=it.product_id, product_name=it.product_name, type_id=it.type_id, product_unit_price=it.product_unit_price, quantity=it.quantity).save() i.validate() b.delete() diff --git a/locale/fr/LC_MESSAGES/django.mo b/locale/fr/LC_MESSAGES/django.mo index 78b0da2afa380902761ca487e4890b815daadbe5..4600b1d2966b4651654d8e77daab58244cec9dd4 100644 GIT binary patch delta 10158 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 delta 10031 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 diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 114dfca7..464a1138 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-15 21:41+0200\n" +"POT-Creation-Date: 2016-08-18 17:40+0200\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -40,12 +40,12 @@ msgstr "numero de compte" 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:268 +#: accounting/models.py:109 club/models.py:147 counter/models.py:271 #: launderette/models.py:122 msgid "start date" msgstr "date de début" -#: accounting/models.py:110 club/models.py:148 counter/models.py:269 +#: accounting/models.py:110 club/models.py:148 counter/models.py:272 msgid "end date" msgstr "date de fin" @@ -67,8 +67,8 @@ msgid "number" msgstr "numéro" #: accounting/models.py:154 core/models.py:404 core/models.py:680 -#: counter/models.py:209 counter/models.py:244 eboutic/models.py:13 -#: eboutic/models.py:46 +#: counter/models.py:209 counter/models.py:245 eboutic/models.py:14 +#: eboutic/models.py:47 msgid "date" msgstr "date" @@ -80,8 +80,8 @@ msgstr "intitulé" msgid "remark" msgstr "remarque" -#: accounting/models.py:157 counter/models.py:210 eboutic/models.py:48 -#: subscription/models.py:34 +#: accounting/models.py:157 counter/models.py:210 counter/models.py:247 +#: eboutic/models.py:49 subscription/models.py:34 msgid "payment method" msgstr "méthode de paiement" @@ -89,7 +89,7 @@ msgstr "méthode de paiement" msgid "cheque number" msgstr "numéro de chèque" -#: accounting/models.py:159 eboutic/models.py:92 +#: accounting/models.py:159 eboutic/models.py:119 msgid "invoice" msgstr "facture" @@ -268,8 +268,8 @@ msgstr "Fin" #: accounting/templates/accounting/club_account_details.jinja:20 #: accounting/templates/accounting/journal_details.jinja:23 -#: core/templates/core/user_account.jinja:18 -#: core/templates/core/user_account.jinja:64 +#: core/templates/core/user_account.jinja:19 +#: core/templates/core/user_account.jinja:72 msgid "Amount" msgstr "Montant" @@ -324,13 +324,13 @@ msgstr "No" #: accounting/templates/accounting/journal_details.jinja:21 #: core/templates/core/user_account.jinja:16 -#: core/templates/core/user_account.jinja:37 -#: core/templates/core/user_account.jinja:62 +#: core/templates/core/user_account.jinja:41 +#: core/templates/core/user_account.jinja:70 msgid "Date" msgstr "Date" #: accounting/templates/accounting/journal_details.jinja:22 -#: core/templates/core/user_account.jinja:39 +#: core/templates/core/user_account.jinja:44 msgid "Label" msgstr "Intitulé" @@ -394,7 +394,7 @@ msgstr "Vous ne pouvez pas faire de boucles dans les clubs" msgid "A club with that unix_name already exists" msgstr "Un club avec ce nom UNIX existe déjà." -#: club/models.py:145 eboutic/models.py:12 eboutic/models.py:45 +#: club/models.py:145 eboutic/models.py:13 eboutic/models.py:46 #: launderette/models.py:89 launderette/models.py:126 msgid "user" msgstr "nom d'utilisateur" @@ -447,7 +447,6 @@ msgstr "Éditer le club" #: 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:8 #: subscription/templates/subscription/subscription.jinja:22 msgid "Save" msgstr "Sauver" @@ -1234,31 +1233,43 @@ msgid "Refillings" msgstr "Rechargements" #: core/templates/core/user_account.jinja:17 -#: core/templates/core/user_account.jinja:38 +#: core/templates/core/user_account.jinja:42 +#: counter/templates/counter/counter_click.jinja:24 +msgid "Counter" +msgstr "Comptoir" + +#: core/templates/core/user_account.jinja:18 +#: core/templates/core/user_account.jinja:43 msgid "Barman" msgstr "Barman" -#: core/templates/core/user_account.jinja:33 -msgid "Buyings" -msgstr "Achats" +#: core/templates/core/user_account.jinja:20 +#: core/templates/core/user_account.jinja:47 +#: core/templates/core/user_account.jinja:73 +msgid "Payment method" +msgstr "Méthode de paiement" -#: core/templates/core/user_account.jinja:40 +#: core/templates/core/user_account.jinja:37 +msgid "Account buyings" +msgstr "Achat sur compte utilisateur" + +#: core/templates/core/user_account.jinja:45 msgid "Quantity" msgstr "Quantité" -#: core/templates/core/user_account.jinja:41 +#: core/templates/core/user_account.jinja:46 msgid "Total" msgstr "Total" -#: core/templates/core/user_account.jinja:58 -msgid "Invoices" -msgstr "Factures" +#: core/templates/core/user_account.jinja:66 +msgid "Eboutic invoices" +msgstr "Facture eboutic" -#: core/templates/core/user_account.jinja:63 +#: core/templates/core/user_account.jinja:71 msgid "Items" msgstr "Articles" -#: core/templates/core/user_account.jinja:85 +#: core/templates/core/user_account.jinja:95 msgid "User has no account" msgstr "L'utilisateur n'a pas de compte" @@ -1459,7 +1470,7 @@ msgstr "clients" msgid "Not enough money" msgstr "Solde insuffisant" -#: counter/models.py:57 eboutic/models.py:78 +#: counter/models.py:57 msgid "product type" msgstr "type du produit" @@ -1491,8 +1502,9 @@ msgstr "Bar" msgid "Office" msgstr "Bureau" -#: counter/models.py:110 eboutic/templates/eboutic/eboutic_main.jinja:20 -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:4 +#: counter/models.py:110 eboutic/templates/eboutic/eboutic_main.jinja:4 +#: eboutic/templates/eboutic/eboutic_main.jinja:24 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:8 #: eboutic/templates/eboutic/eboutic_payment_result.jinja:4 #: sith/settings.py:279 sith/settings_sample.py:265 msgid "Eboutic" @@ -1510,7 +1522,7 @@ msgstr "comptoir" msgid "bank" msgstr "banque" -#: counter/models.py:214 counter/models.py:245 +#: counter/models.py:214 counter/models.py:246 msgid "is validated" msgstr "est validé" @@ -1518,26 +1530,32 @@ msgstr "est validé" msgid "refilling" msgstr "rechargement" -#: counter/models.py:240 eboutic/models.py:79 +#: counter/models.py:241 eboutic/models.py:106 msgid "unit price" msgstr "prix unitaire" -#: counter/models.py:241 eboutic/models.py:80 +#: counter/models.py:242 eboutic/models.py:107 msgid "quantity" msgstr "quantité" -#: counter/models.py:248 +#: counter/models.py:248 eboutic/models.py:48 +msgid "Sith account" +msgstr "Compte utilisateur" + +#: counter/models.py:248 eboutic/models.py:48 sith/settings.py:272 +#: sith/settings.py:277 sith/settings.py:298 sith/settings_sample.py:258 +#: sith/settings_sample.py:263 sith/settings_sample.py:284 +msgid "Credit card" +msgstr "Carte banquaire" + +#: counter/models.py:251 msgid "selling" msgstr "vente" -#: counter/models.py:272 +#: counter/models.py:275 msgid "permanency" msgstr "permanence" -#: counter/templates/counter/counter_click.jinja:24 -msgid "Counter" -msgstr "Comptoir" - #: counter/templates/counter/counter_click.jinja:26 msgid "Club: " msgstr "Club : " @@ -1563,14 +1581,14 @@ msgid "Selling" msgstr "Vente" #: counter/templates/counter/counter_click.jinja:54 -#: eboutic/templates/eboutic/eboutic_main.jinja:23 -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:7 +#: eboutic/templates/eboutic/eboutic_main.jinja:27 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:11 msgid "Basket: " msgstr "Panier : " #: counter/templates/counter/counter_click.jinja:62 #: counter/templates/counter/counter_main.jinja:24 -#: eboutic/templates/eboutic/eboutic_main.jinja:30 +#: eboutic/templates/eboutic/eboutic_main.jinja:34 msgid "Total: " msgstr "Total : " @@ -1579,14 +1597,10 @@ msgid "Finish" msgstr "Terminer" #: counter/templates/counter/counter_click.jinja:73 -#: eboutic/templates/eboutic/eboutic_main.jinja:37 +#: eboutic/templates/eboutic/eboutic_main.jinja:41 msgid "Products: " msgstr "Produits : " -#: counter/templates/counter/counter_edit.jinja:4 -msgid "Edit counter" -msgstr "Éditer le comptoir" - #: counter/templates/counter/counter_list.jinja:4 #: counter/templates/counter/counter_list.jinja:10 msgid "Counter admin list" @@ -1664,67 +1678,66 @@ msgstr "Nouveau type de produit" msgid "There is no product types in this website." msgstr "Il n'y a pas de types de produit dans ce site web." -#: counter/views.py:48 +#: counter/views.py:49 msgid "User not found" msgstr "Utilisateur non trouvé" -#: counter/views.py:211 +#: counter/views.py:212 msgid "END" msgstr "FIN" -#: counter/views.py:213 +#: counter/views.py:214 msgid "CAN" msgstr "ANN" -#: counter/views.py:243 +#: counter/views.py:244 msgid "You have not enough money to buy all the basket" msgstr "Vous n'avez pas assez d'argent pour acheter le panier" -#: eboutic/models.py:47 sith/settings.py:272 sith/settings.py:277 -#: sith/settings_sample.py:258 sith/settings_sample.py:263 -msgid "Credit card" -msgstr "Carte banquaire" - -#: eboutic/models.py:47 -msgid "Sith account" -msgstr "Compte utilisateur" - -#: eboutic/models.py:49 +#: eboutic/models.py:50 msgid "validated" msgstr "validé" -#: eboutic/models.py:59 +#: eboutic/models.py:60 msgid "Invoice already validated" msgstr "Facture déjà validée" -#: eboutic/models.py:76 +#: eboutic/models.py:103 msgid "product id" msgstr "ID du produit" -#: eboutic/models.py:77 +#: eboutic/models.py:104 msgid "product name" msgstr "nom du produit" -#: eboutic/models.py:89 +#: eboutic/models.py:105 +msgid "product type id" +msgstr "id du type du produit" + +#: eboutic/models.py:116 msgid "basket" msgstr "panier" -#: eboutic/templates/eboutic/eboutic_main.jinja:33 +#: eboutic/templates/eboutic/eboutic_main.jinja:37 msgid "Proceed to command" msgstr "Procéder à la commande" -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:31 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:4 +msgid "Basket state" +msgstr "État du panier" + +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:35 msgid "Pay with credit card" msgstr "Payer avec une carte banquaire" -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:34 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:38 msgid "" "AE account payment disabled because your basket contains refilling items." msgstr "" "Paiement par compte AE désactivé parce que votre panier contient des bons de " "rechargement." -#: eboutic/templates/eboutic/eboutic_makecommand.jinja:39 +#: eboutic/templates/eboutic/eboutic_makecommand.jinja:43 msgid "Pay with Sith account" msgstr "Payer avec un compte AE" @@ -1829,12 +1842,12 @@ msgid "Washing and drying" msgstr "Lavage et séchage" #: launderette/templates/launderette/launderette_book.jinja:26 -#: sith/settings.py:398 sith/settings_sample.py:384 +#: sith/settings.py:408 sith/settings_sample.py:394 msgid "Washing" msgstr "Lavage" #: launderette/templates/launderette/launderette_book.jinja:30 -#: sith/settings.py:398 sith/settings_sample.py:384 +#: sith/settings.py:408 sith/settings_sample.py:394 msgid "Drying" msgstr "Séchage" @@ -1917,80 +1930,80 @@ msgstr "Sevenans" msgid "Montbéliard" msgstr "Montbéliard" -#: sith/settings.py:311 sith/settings_sample.py:297 +#: sith/settings.py:321 sith/settings_sample.py:307 msgid "One semester" msgstr "Un semestre" -#: sith/settings.py:316 sith/settings_sample.py:302 +#: sith/settings.py:326 sith/settings_sample.py:312 msgid "Two semesters" msgstr "Deux semestres" -#: sith/settings.py:321 sith/settings_sample.py:307 +#: sith/settings.py:331 sith/settings_sample.py:317 msgid "Common core cursus" msgstr "Cursus tronc commun" -#: sith/settings.py:326 sith/settings.py:331 sith/settings_sample.py:312 -#: sith/settings_sample.py:317 +#: sith/settings.py:336 sith/settings.py:341 sith/settings_sample.py:322 +#: sith/settings_sample.py:327 msgid "Branch cursus" msgstr "Cursus branche" -#: sith/settings.py:336 sith/settings_sample.py:322 +#: sith/settings.py:346 sith/settings_sample.py:332 msgid "Honorary member" msgstr "Membre honoraire" -#: sith/settings.py:341 sith/settings_sample.py:327 +#: sith/settings.py:351 sith/settings_sample.py:337 msgid "Assidu member" msgstr "Membre d'Assidu" -#: sith/settings.py:346 sith/settings_sample.py:332 +#: sith/settings.py:356 sith/settings_sample.py:342 msgid "Amicale/DOCEO member" msgstr "Membre de l'Amicale/DOCEO" -#: sith/settings.py:351 sith/settings_sample.py:337 +#: sith/settings.py:361 sith/settings_sample.py:347 msgid "UT network member" msgstr "Cotisant du réseau UT" -#: sith/settings.py:356 sith/settings_sample.py:342 +#: sith/settings.py:366 sith/settings_sample.py:352 msgid "CROUS member" msgstr "Membres du CROUS" -#: sith/settings.py:361 sith/settings_sample.py:347 +#: sith/settings.py:371 sith/settings_sample.py:357 msgid "Sbarro/ESTA member" msgstr "Membre de Sbarro ou de l'ESTA" -#: sith/settings.py:369 sith/settings_sample.py:355 +#: sith/settings.py:379 sith/settings_sample.py:365 msgid "President" msgstr "Président" -#: sith/settings.py:370 sith/settings_sample.py:356 +#: sith/settings.py:380 sith/settings_sample.py:366 msgid "Vice-President" msgstr "Vice-Président" -#: sith/settings.py:371 sith/settings_sample.py:357 +#: sith/settings.py:381 sith/settings_sample.py:367 msgid "Treasurer" msgstr "Trésorier" -#: sith/settings.py:372 sith/settings_sample.py:358 +#: sith/settings.py:382 sith/settings_sample.py:368 msgid "Communication supervisor" msgstr "Responsable com" -#: sith/settings.py:373 sith/settings_sample.py:359 +#: sith/settings.py:383 sith/settings_sample.py:369 msgid "Secretary" msgstr "Secrétaire" -#: sith/settings.py:374 sith/settings_sample.py:360 +#: sith/settings.py:384 sith/settings_sample.py:370 msgid "IT supervisor" msgstr "Responsable info" -#: sith/settings.py:375 sith/settings_sample.py:361 +#: sith/settings.py:385 sith/settings_sample.py:371 msgid "Board member" msgstr "Membre du bureau" -#: sith/settings.py:376 sith/settings_sample.py:362 +#: sith/settings.py:386 sith/settings_sample.py:372 msgid "Active member" msgstr "Membre actif" -#: sith/settings.py:377 sith/settings_sample.py:363 +#: sith/settings.py:387 sith/settings_sample.py:373 msgid "Curious" msgstr "Curieux" @@ -2035,5 +2048,3 @@ 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 "User Profile" -#~ msgstr "Profil de l'utilisateur" diff --git a/migrate.py b/migrate.py index fb51f37d..76b61843 100644 --- a/migrate.py +++ b/migrate.py @@ -20,6 +20,7 @@ from core.models import User, SithFile from club.models import Club, Membership from counter.models import Customer, Counter, Selling, Refilling, Product, ProductType from subscription.models import Subscription, Subscriber +from eboutic.models import Invoice, InvoiceItem db = MySQLdb.connect( host="ae-db", @@ -142,7 +143,6 @@ def migrate_users(): except Exception as e: print("FAIL for user %s: %s" % (u['id_utilisateur'], repr(e))) c.close() - reset_index('core') def migrate_profile_pict(): PROFILE_ROOT = "/data/matmatronch/" @@ -357,8 +357,8 @@ def migrate_refillings(): SELECT * FROM cpt_rechargements """) - Refilling.objects.all().delete() - print("Refillings deleted") + Refilling.objects.filter(payment_method="SITH_ACCOUNT").delete() + print("Sith account refillings deleted") for c in Customer.objects.all(): c.amount = 0 c.save() @@ -386,11 +386,8 @@ def migrate_refillings(): operator=op or root_cust.user, amount=r['montant_rech']/100, bank=BANK[r['banque_rech']], + date=r['date_rech'].replace(tzinfo=timezone('Europe/Paris')), ) - for f in new._meta.local_fields: - if f.name == "date": - f.auto_now = False - new.date = r['date_rech'].replace(tzinfo=timezone('Europe/Paris')) new.save() except Exception as e: print("FAIL to migrate refilling %s for %s: %s" % (r['id_rechargement'], r['id_utilisateur'], repr(e))) @@ -434,9 +431,9 @@ def migrate_products(): name=to_unicode(r['nom_prod']), description=to_unicode(r['description_prod']), code=to_unicode(r['cbarre_prod']), - purchase_price=r['prix_achat_prod'], - selling_price=r['prix_vente_prod'], - special_selling_price=r['prix_vente_barman_prod'], + purchase_price=r['prix_achat_prod']/100, + selling_price=r['prix_vente_prod']/100, + special_selling_price=r['prix_vente_barman_prod']/100, club=club, ) new.save() @@ -444,6 +441,62 @@ def migrate_products(): print("FAIL to migrate product %s: %s" % (r['nom_prod'], repr(e))) cur.close() +def migrate_products_to_counter(): + cur = db.cursor(MySQLdb.cursors.SSDictCursor) + cur.execute(""" + SELECT * + FROM cpt_mise_en_vente + """) + for r in cur: + try: + product = Product.objects.filter(id=r['id_produit']).first() + counter = Counter.objects.filter(id=r['id_comptoir']).first() + counter.products.add(product) + counter.save() + except Exception as e: + print("FAIL to set product %s in counter %s: %s" % (product, counter, repr(e))) + cur.close() + +def migrate_invoices(): + cur = db.cursor(MySQLdb.cursors.SSDictCursor) + cur.execute(""" + SELECT * + FROM cpt_vendu ven + LEFT JOIN cpt_debitfacture fac + ON ven.id_facture = fac.id_facture + WHERE fac.mode_paiement = 'SG' + """) + Invoice.objects.all().delete() + print("Invoices deleted") + Refilling.objects.filter(payment_method="CARD").delete() + print("Card refillings deleted") + Selling.objects.filter(payment_method="CARD").delete() + print("Card sellings deleted") + root = User.objects.filter(id=0).first() + for r in cur: + try: + product = Product.objects.filter(id=r['id_produit']).first() + user = User.objects.filter(id=r['id_utilisateur_client']).first() + i = Invoice.objects.filter(id=r['id_facture']).first() or Invoice(id=r['id_facture']) + i.user = user or root + for f in i._meta.local_fields: + if f.name == "date": + f.auto_now = False + i.date = r['date_facture'].replace(tzinfo=timezone('Europe/Paris')) + i.save() + InvoiceItem(invoice=i, product_id=product.id, product_name=product.name, type_id=product.product_type.id, + product_unit_price=r['prix_unit']/100, quantity=r['quantite']).save() + except ValidationError as e: + print(repr(e) + " for %s (%s)" % (customer, customer.user.id)) + except Exception as e: + print("FAIL to migrate invoice %s: %s" % (r['id_facture'], repr(e))) + cur.close() + for i in Invoice.objects.all(): + for f in i._meta.local_fields: + if f.name == "date": + f.auto_now = False + i.validate() + def migrate_sellings(): cur = db.cursor(MySQLdb.cursors.SSDictCursor) cur.execute(""" @@ -453,8 +506,8 @@ def migrate_sellings(): ON ven.id_facture = fac.id_facture WHERE fac.mode_paiement = 'AE' """) - Selling.objects.all().delete() - print("Selling deleted") + Selling.objects.filter(payment_method="SITH_ACCOUNT").delete() + print("Sith account selling deleted") for r in cur: try: product = Product.objects.filter(id=r['id_produit']).first() @@ -471,11 +524,9 @@ def migrate_sellings(): customer=customer, unit_price=r['prix_unit']/100, quantity=r['quantite'], + payment_method="SITH_ACCOUNT", + date=r['date_facture'].replace(tzinfo=timezone('Europe/Paris')), ) - for f in new._meta.local_fields: - if f.name == "date": - f.auto_now = False - new.date = r['date_facture'].replace(tzinfo=timezone('Europe/Paris')) new.save() except ValidationError as e: print(repr(e) + " for %s (%s)" % (customer, customer.user.id)) @@ -483,6 +534,7 @@ def migrate_sellings(): print("FAIL to migrate selling %s: %s" % (r['id_facture'], repr(e))) cur.close() + def main(): # migrate_users() # migrate_profile_pict() @@ -491,10 +543,13 @@ def main(): # migrate_subscriptions() # update_customer_account() # migrate_counters() + # migrate_typeproducts() + # migrate_products() + # migrate_products_to_counter() + migrate_invoices() migrate_refillings() - migrate_typeproducts() - migrate_products() migrate_sellings() + reset_index('core', 'counter') if __name__ == "__main__": main() diff --git a/sith/settings_sample.py b/sith/settings_sample.py index 4262d26e..d7c53edb 100644 --- a/sith/settings_sample.py +++ b/sith/settings_sample.py @@ -281,6 +281,7 @@ SITH_COUNTER_BARS = [ SITH_COUNTER_PAYMENT_METHOD = [ ('CHECK', _('Check')), ('CASH', _('Cash')), + ('CARD', _('Credit card')), ] SITH_COUNTER_BANK = [ @@ -296,6 +297,9 @@ SITH_COUNTER_BANK = [ ('LA-POSTE', 'La Poste'), ] +# Defines which product type is the refilling type, and thus increases the account amount +SITH_COUNTER_PRODUCTTYPE_REFILLING = 11 + # Subscription durations are in semestres # Be careful, modifying this parameter will need a migration to be applied SITH_SUBSCRIPTIONS = {