From 84364d9018e71b59d3ba190e5e9a2261feaf4607 Mon Sep 17 00:00:00 2001 From: Skia Date: Thu, 18 Aug 2016 03:04:50 +0200 Subject: [PATCH] Improve counter app and migrate products/producttypes/refillings/sellings --- core/templates/core/user_account.jinja | 2 +- counter/migrations/0004_auto_20160817_1655.py | 29 +++ counter/migrations/0005_auto_20160817_2251.py | 24 +++ counter/migrations/0006_auto_20160817_2253.py | 19 ++ counter/migrations/0007_selling_club.py | 21 ++ counter/migrations/0008_auto_20160818_0231.py | 19 ++ counter/models.py | 13 +- counter/templates/counter/counter_edit.jinja | 13 -- counter/views.py | 6 +- launderette/views.py | 2 +- locale/fr/LC_MESSAGES/django.mo | Bin 27811 -> 27857 bytes locale/fr/LC_MESSAGES/django.po | 23 +- migrate.py | 200 ++++++++++++++++-- sith/settings_sample.py | 16 +- 14 files changed, 337 insertions(+), 50 deletions(-) create mode 100644 counter/migrations/0004_auto_20160817_1655.py create mode 100644 counter/migrations/0005_auto_20160817_2251.py create mode 100644 counter/migrations/0006_auto_20160817_2253.py create mode 100644 counter/migrations/0007_selling_club.py create mode 100644 counter/migrations/0008_auto_20160818_0231.py delete mode 100644 counter/templates/counter/counter_edit.jinja diff --git a/core/templates/core/user_account.jinja b/core/templates/core/user_account.jinja index d3c94889..50a4d8ab 100644 --- a/core/templates/core/user_account.jinja +++ b/core/templates/core/user_account.jinja @@ -22,7 +22,7 @@ {% for i in customer.refillings.all() %} {{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }} - {{ i.operator }} + {{ i.operator.get_display_name() }} {{ i.amount }} € {% endfor %} diff --git a/counter/migrations/0004_auto_20160817_1655.py b/counter/migrations/0004_auto_20160817_1655.py new file mode 100644 index 00000000..8229a195 --- /dev/null +++ b/counter/migrations/0004_auto_20160817_1655.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('counter', '0003_auto_20160814_1634'), + ] + + operations = [ + migrations.AlterField( + model_name='counter', + name='type', + field=models.CharField(choices=[('BAR', 'Bar'), ('OFFICE', 'Office'), ('EBOUTIC', 'Eboutic')], verbose_name='counter type', max_length=255), + ), + migrations.AlterField( + model_name='refilling', + name='bank', + field=models.CharField(default='OTHER', choices=[('OTHER', 'Autre'), ('SOCIETE-GENERALE', 'Société générale'), ('BANQUE-POPULAIRE', 'Banque populaire'), ('BNP', 'BNP'), ('CAISSE-EPARGNE', "Caisse d'épargne"), ('CIC', 'CIC'), ('CREDIT-AGRICOLE', 'Crédit Agricole'), ('CREDIT-MUTUEL', 'Credit Mutuel'), ('CREDIT-LYONNAIS', 'Credit Lyonnais'), ('LA-POSTE', 'La Poste')], verbose_name='bank', max_length=255), + ), + migrations.AlterField( + model_name='refilling', + name='payment_method', + field=models.CharField(default='CASH', choices=[('CHECK', 'Check'), ('CASH', 'Cash')], verbose_name='payment method', max_length=255), + ), + ] diff --git a/counter/migrations/0005_auto_20160817_2251.py b/counter/migrations/0005_auto_20160817_2251.py new file mode 100644 index 00000000..c3f04290 --- /dev/null +++ b/counter/migrations/0005_auto_20160817_2251.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('counter', '0004_auto_20160817_1655'), + ] + + operations = [ + migrations.AlterField( + model_name='product', + name='code', + field=models.CharField(verbose_name='code', max_length=10, blank=True), + ), + migrations.AlterField( + model_name='product', + name='name', + field=models.CharField(verbose_name='name', max_length=64), + ), + ] diff --git a/counter/migrations/0006_auto_20160817_2253.py b/counter/migrations/0006_auto_20160817_2253.py new file mode 100644 index 00000000..a9aa10f3 --- /dev/null +++ b/counter/migrations/0006_auto_20160817_2253.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', '0005_auto_20160817_2251'), + ] + + operations = [ + migrations.AlterField( + model_name='product', + name='code', + field=models.CharField(blank=True, max_length=16, verbose_name='code'), + ), + ] diff --git a/counter/migrations/0007_selling_club.py b/counter/migrations/0007_selling_club.py new file mode 100644 index 00000000..231a92e7 --- /dev/null +++ b/counter/migrations/0007_selling_club.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('club', '0004_auto_20160813_1551'), + ('counter', '0006_auto_20160817_2253'), + ] + + operations = [ + migrations.AddField( + model_name='selling', + name='club', + field=models.ForeignKey(default=1, related_name='sellings', to='club.Club'), + preserve_default=False, + ), + ] diff --git a/counter/migrations/0008_auto_20160818_0231.py b/counter/migrations/0008_auto_20160818_0231.py new file mode 100644 index 00000000..efe59a61 --- /dev/null +++ b/counter/migrations/0008_auto_20160818_0231.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', '0007_selling_club'), + ] + + operations = [ + migrations.AlterField( + model_name='selling', + name='label', + field=models.CharField(max_length=64, verbose_name='label'), + ), + ] diff --git a/counter/models.py b/counter/models.py index c9fa9829..7a76c1e3 100644 --- a/counter/models.py +++ b/counter/models.py @@ -74,10 +74,10 @@ class Product(models.Model): """ This describes a product, with all its related informations """ - name = models.CharField(_('name'), max_length=30) + name = models.CharField(_('name'), max_length=64) description = models.TextField(_('description'), blank=True) product_type = models.ForeignKey(ProductType, related_name='products', null=True, blank=True) - code = models.CharField(_('code'), max_length=10) + code = models.CharField(_('code'), max_length=16, blank=True) purchase_price = CurrencyField(_('purchase price')) selling_price = CurrencyField(_('selling price')) special_selling_price = CurrencyField(_('special selling price')) @@ -105,7 +105,7 @@ class Counter(models.Model): name = models.CharField(_('name'), max_length=30) club = models.ForeignKey(Club, related_name="counters") products = models.ManyToManyField(Product, related_name="counters", blank=True) - type = models.CharField(_('subscription type'), + type = models.CharField(_('counter type'), max_length=255, choices=[('BAR',_('Bar')), ('OFFICE',_('Office')), ('EBOUTIC',_('Eboutic'))]) sellers = models.ManyToManyField(Subscriber, verbose_name=_('sellers'), related_name='counters', blank=True) @@ -208,9 +208,9 @@ class Refilling(models.Model): customer = models.ForeignKey(Customer, related_name="refillings", blank=False) date = models.DateTimeField(_('date'), auto_now=True) payment_method = models.CharField(_('payment method'), max_length=255, - choices=settings.SITH_COUNTER_PAYMENT_METHOD, default='cash') + choices=settings.SITH_COUNTER_PAYMENT_METHOD, default='CASH') bank = models.CharField(_('bank'), max_length=255, - choices=settings.SITH_COUNTER_BANK, default='other') + choices=settings.SITH_COUNTER_BANK, default='OTHER') is_validated = models.BooleanField(_('is validated'), default=False) class Meta: @@ -234,9 +234,10 @@ class Selling(models.Model): """ Handle the sellings """ - label = models.CharField(_("label"), max_length=30) + 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) unit_price = CurrencyField(_('unit price')) quantity = models.IntegerField(_('quantity')) seller = models.ForeignKey(User, related_name="sellings_as_operator", blank=False) diff --git a/counter/templates/counter/counter_edit.jinja b/counter/templates/counter/counter_edit.jinja deleted file mode 100644 index 865ed1f3..00000000 --- a/counter/templates/counter/counter_edit.jinja +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "core/base.jinja" %} - -{% block content %} -

{% trans %}Edit counter{% endtrans %}

-
- {% csrf_token %} - {{ form.as_p() }} -

-
-{% endblock %} - - - diff --git a/counter/views.py b/counter/views.py index 0a8a0fa6..361e4833 100644 --- a/counter/views.py +++ b/counter/views.py @@ -242,7 +242,7 @@ class CounterClick(DetailView): if uprice * infos['qty'] > self.customer.amount: raise DataError(_("You have not enough money to buy all the basket")) request.session['last_basket'].append("%d x %s" % (infos['qty'], p.name)) - s = Selling(label=p.name, product=p, counter=self.object, unit_price=uprice, + s = Selling(label=p.name, product=p, club=p.club, counter=self.object, unit_price=uprice, quantity=infos['qty'], seller=self.operator, customer=self.customer) s.save() request.session['last_customer'] = self.customer.user.get_display_name() @@ -336,7 +336,7 @@ class CounterEditView(CanEditPropMixin, UpdateView): 'products':CheckboxSelectMultiple, 'sellers':CheckboxSelectMultiple}) pk_url_kwarg = "counter_id" - template_name = 'counter/counter_edit.jinja' + template_name = 'core/edit.jinja' class CounterCreateView(CanEditMixin, CreateView): """ @@ -345,7 +345,7 @@ class CounterCreateView(CanEditMixin, CreateView): model = Counter form_class = modelform_factory(Counter, fields=['name', 'club', 'type', 'products'], widgets={'products':CheckboxSelectMultiple}) - template_name = 'counter/counter_edit.jinja' + template_name = 'core/create.jinja' class CounterDeleteView(CanEditMixin, DeleteView): """ diff --git a/launderette/views.py b/launderette/views.py index 11a0467c..36f49624 100644 --- a/launderette/views.py +++ b/launderette/views.py @@ -291,7 +291,7 @@ class ClickTokenForm(forms.BaseForm): t.borrow_date = datetime.now().replace(tzinfo=pytz.UTC) t.save() price = settings.SITH_LAUNDERETTE_PRICES[t.type] - s = Selling(label="Jeton "+t.get_type_display()+" N°"+t.name, product=None, counter=counter, unit_price=price, + s = Selling(label="Jeton "+t.get_type_display()+" N°"+t.name, club=counter.club, product=None, counter=counter, unit_price=price, quantity=1, seller=operator, customer=customer) s.save() total += price diff --git a/locale/fr/LC_MESSAGES/django.mo b/locale/fr/LC_MESSAGES/django.mo index f33d73d12bc5138919a7f4298be84324da7b4437..78b0da2afa380902761ca487e4890b815daadbe5 100644 GIT binary patch delta 8357 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 LZvW-}?Lq$s00`1x delta 8332 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 diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 95ba7aad..114dfca7 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-14 16:36+0200\n" +"POT-Creation-Date: 2016-08-15 21:41+0200\n" "PO-Revision-Date: 2016-07-18\n" "Last-Translator: Skia \n" "Language-Team: AE info \n" @@ -444,11 +444,11 @@ msgstr "Éditer le club" #: club/templates/club/club_edit.jinja:8 #: club/templates/club/club_edit_prop.jinja:8 -#: core/templates/core/create.jinja:8 core/templates/core/edit.jinja:12 +#: 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:12 +#: subscription/templates/subscription/subscription.jinja:22 msgid "Save" msgstr "Sauver" @@ -929,11 +929,11 @@ msgstr "Clubs" msgid "Services" msgstr "Services" -#: core/templates/core/base.jinja:55 +#: core/templates/core/base.jinja:56 msgid "Site made by good people" msgstr "Site réalisé par des gens bons" -#: core/templates/core/create.jinja:4 +#: core/templates/core/create.jinja:4 core/templates/core/create.jinja.py:8 #, python-format msgid "Create %(name)s" msgstr "Créer %(name)s" @@ -1274,10 +1274,12 @@ msgstr "Profil de %(user_name)s" #: core/templates/core/user_detail.jinja:12 #: core/templates/core/user_edit.jinja:15 +#: core/templates/core/user_mini.jinja:4 msgid "Profile" msgstr "Profil" #: core/templates/core/user_detail.jinja:21 +#: core/templates/core/user_mini.jinja:12 msgid "Born: " msgstr "Né le : " @@ -1286,6 +1288,7 @@ msgid "Option: " msgstr "Filière : " #: core/templates/core/user_detail.jinja:32 +#: core/templates/core/user_mini.jinja:16 msgid "Promo: " msgstr "Promo : " @@ -1476,9 +1479,9 @@ msgstr "prix de vente spécial" msgid "product" msgstr "produit" -#: counter/models.py:108 subscription/models.py:29 -msgid "subscription type" -msgstr "type d'inscription" +#: counter/models.py:108 +msgid "counter type" +msgstr "type de comptoir" #: counter/models.py:110 msgid "Bar" @@ -1999,6 +2002,10 @@ msgstr "Mauvais type de cotisation" msgid "Bad payment method" msgstr "Mauvais type de paiement" +#: subscription/models.py:29 +msgid "subscription type" +msgstr "type d'inscription" + #: subscription/models.py:32 msgid "subscription start" msgstr "début de la cotisation" diff --git a/migrate.py b/migrate.py index dd615028..0bdfacac 100644 --- a/migrate.py +++ b/migrate.py @@ -3,6 +3,7 @@ import os import django import random from io import StringIO +from pytz import timezone os.environ["DJANGO_SETTINGS_MODULE"] = "sith.settings" os.environ['DJANGO_COLORS'] = 'nocolor' @@ -12,11 +13,12 @@ from django.db import IntegrityError from django.conf import settings from django.core.management import call_command from django.db import connection +from django.forms import ValidationError from core.models import User, SithFile from club.models import Club, Membership -from counter.models import Customer +from counter.models import Customer, Counter, Selling, Refilling, Product, ProductType from subscription.models import Subscription, Subscriber db = MySQLdb.connect( @@ -85,7 +87,7 @@ def migrate_users(): email = "no_email_%s@git.an" % random.randrange(4000, 40000) return email - c = db.cursor(MySQLdb.cursors.DictCursor) + c = db.cursor(MySQLdb.cursors.SSDictCursor) c.execute(""" SELECT * FROM utilisateurs utl @@ -97,7 +99,7 @@ def migrate_users(): ON uxtra.id_utilisateur = utl.id_utilisateur LEFT JOIN loc_ville ville ON utl.id_ville = ville.id_ville - -- WHERE utl.id_utilisateur = 9248 + -- WHERE utl.id_utilisateur = 9360 """) User.objects.filter(id__gt=0).delete() print("Users deleted") @@ -178,7 +180,7 @@ def migrate_profile_pict(): print(repr(e)) def migrate_clubs(): - cur = db.cursor(MySQLdb.cursors.DictCursor) + cur = db.cursor(MySQLdb.cursors.SSDictCursor) cur.execute(""" SELECT * FROM asso asso @@ -213,7 +215,7 @@ def migrate_clubs(): cur.close() def migrate_club_memberships(): - cur = db.cursor(MySQLdb.cursors.DictCursor) + cur = db.cursor(MySQLdb.cursors.SSDictCursor) cur.execute(""" SELECT * FROM asso_membre @@ -268,7 +270,7 @@ def migrate_subscriptions(): 5: "EBOUTIC", 0: "OTHER", } - cur = db.cursor(MySQLdb.cursors.DictCursor) + cur = db.cursor(MySQLdb.cursors.SSDictCursor) cur.execute(""" SELECT * FROM ae_cotisations @@ -297,7 +299,7 @@ def migrate_subscriptions(): cur.close() def update_customer_account(): - cur = db.cursor(MySQLdb.cursors.DictCursor) + cur = db.cursor(MySQLdb.cursors.SSDictCursor) cur.execute(""" SELECT * FROM ae_carte carte @@ -314,13 +316,185 @@ def update_customer_account(): print("FAIL to update customer account for %s: %s" % (r['id_cotisation'], repr(e))) cur.close() +def migrate_counters(): + cur = db.cursor(MySQLdb.cursors.SSDictCursor) + cur.execute(""" + SELECT * + FROM cpt_comptoir + """) + Counter.objects.all().delete() + for r in cur.fetchall(): + try: + club = Club.objects.filter(id=r['id_assocpt']).first() + new = Counter( + id=r['id_comptoir'], + name=to_unicode(r['nom_cpt']), + club=club, + type="OFFICE", + ) + new.save() + except Exception as e: + print("FAIL to migrate counter %s: %s" % (r['id_comptoir'], repr(e))) + cur.close() + +def migrate_refillings(): + BANK = { + 0: "OTHER", + 1: "SOCIETE-GENERALE", + 2: "BANQUE-POPULAIRE", + 3: "BNP", + 4: "CAISSE-EPARGNE", + 5: "CIC", + 6: "CREDIT-AGRICOLE", + 7: "CREDIT-MUTUEL", + 8: "CREDIT-LYONNAIS", + 9: "LA-POSTE", + 100: "OTHER", + None: "OTHER", + } + cur = db.cursor(MySQLdb.cursors.SSDictCursor) + cur.execute(""" + SELECT * + FROM cpt_rechargements + """) + Refilling.objects.all().delete() + print("Refillings deleted") + for c in Customer.objects.all(): + c.amount = 0 + c.save() + print("Customer amount reset") + fail = 100 + root_cust = Customer.objects.filter(user__id=0).first() + mde = Counter.objects.filter(id=1).first() + for r in cur.fetchall(): + try: + cust = Customer.objects.filter(user__id=r['id_utilisateur']).first() + user = User.objects.filter(id=r['id_utilisateur']).first() + if not cust: + if not user: + cust = root_cust + else: + cust = Customer(user=user, amount=0, account_id=Customer.generate_account_id(fail)) + cust.save() + fail += 1 + op = User.objects.filter(id=r['id_utilisateur_operateur']).first() + counter = Counter.objects.filter(id=r['id_comptoir']).first() + new = Refilling( + id=r['id_rechargement'], + counter=counter or mde, + customer=cust, + operator=op or root_cust.user, + amount=r['montant_rech']/100, + bank=BANK[r['banque_rech']], + ) + 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))) + cur.close() + +def migrate_typeproducts(): + cur = db.cursor(MySQLdb.cursors.SSDictCursor) + cur.execute(""" + SELECT * + FROM cpt_type_produit + """) + ProductType.objects.all().delete() + print("Product types deleted") + for r in cur.fetchall(): + try: + new = ProductType( + id=r['id_typeprod'], + name=to_unicode(r['nom_typeprod']), + description=to_unicode(r['description_typeprod']), + ) + new.save() + except Exception as e: + print("FAIL to migrate product type %s: %s" % (r['nom_typeprod'], repr(e))) + cur.close() + +def migrate_products(): + cur = db.cursor(MySQLdb.cursors.SSDictCursor) + cur.execute(""" + SELECT * + FROM cpt_produits + """) + Product.objects.all().delete() + print("Product deleted") + for r in cur.fetchall(): + try: + type = ProductType.objects.filter(id=r['id_typeprod']).first() + club = Club.objects.filter(id=r['id_assocpt']).first() + new = Product( + id=r['id_produit'], + product_type=type, + 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'], + club=club, + ) + new.save() + except Exception as e: + print("FAIL to migrate product %s: %s" % (r['nom_prod'], repr(e))) + cur.close() + +def migrate_sellings(): + 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 = 'AE' + """) + Selling.objects.all().delete() + print("Selling deleted") + for r in cur: + try: + product = Product.objects.filter(id=r['id_produit']).first() + club = Club.objects.filter(id=r['id_assocpt']).first() + counter = Counter.objects.filter(id=r['id_comptoir']).first() + op = User.objects.filter(id=r['id_utilisateur']).first() + customer = Customer.objects.filter(user__id=r['id_utilisateur_client']).first() + new = Selling( + label=product.name, + counter=counter, + club=club, + product=product, + seller=op, + customer=customer, + unit_price=r['prix_unit']/100, + quantity=r['quantite'], + ) + 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)) + except Exception as e: + print("FAIL to migrate selling %s: %s" % (r['id_facture'], repr(e))) + cur.close() + def main(): - migrate_users() - migrate_profile_pict() - migrate_clubs() - migrate_club_memberships() - migrate_subscriptions() - update_customer_account() + # migrate_users() + # migrate_profile_pict() + # migrate_clubs() + # migrate_club_memberships() + # migrate_subscriptions() + # update_customer_account() + # migrate_counters() + migrate_refillings() + migrate_typeproducts() + migrate_products() + migrate_sellings() if __name__ == "__main__": main() diff --git a/sith/settings_sample.py b/sith/settings_sample.py index 29ff73e3..4262d26e 100644 --- a/sith/settings_sample.py +++ b/sith/settings_sample.py @@ -273,9 +273,9 @@ SITH_SUBSCRIPTION_LOCATIONS = [ ] SITH_COUNTER_BARS = [ - (1, "Foyer"), - (2, "MDE"), - (3, "La Gommette"), + (1, "MDE"), + (2, "Foyer"), + (35, "La Gommette"), ] SITH_COUNTER_PAYMENT_METHOD = [ @@ -285,9 +285,15 @@ SITH_COUNTER_PAYMENT_METHOD = [ SITH_COUNTER_BANK = [ ('OTHER', 'Autre'), - ('LA-POSTE', 'La Poste'), - ('CREDIT-AGRICOLE', 'Credit Agricole'), + ('SOCIETE-GENERALE', 'Société générale'), + ('BANQUE-POPULAIRE', 'Banque populaire'), + ('BNP', 'BNP'), + ('CAISSE-EPARGNE', 'Caisse d\'épargne'), + ('CIC', 'CIC'), + ('CREDIT-AGRICOLE', 'Crédit Agricole'), ('CREDIT-MUTUEL', 'Credit Mutuel'), + ('CREDIT-LYONNAIS', 'Credit Lyonnais'), + ('LA-POSTE', 'La Poste'), ] # Subscription durations are in semestres