Not so atomic, sorry

This commit is contained in:
Alexandre Iooss 2019-07-16 12:43:23 +02:00
parent ab616b3f64
commit fbe2e7f59a
No known key found for this signature in database
GPG Key ID: 6C79278F3FCDCC02
30 changed files with 885 additions and 332 deletions

View File

@ -1,11 +1,14 @@
[run]
source =
adherents
activity
member
note
theme
omit =
adherents/tests/*.py
adherents/migrations/*.py
activity/tests/*.py
activity/migrations/*.py
member/tests/*.py
member/migrations/*.py
note/tests/*.py
note/migrations/*.py
theme/tests/*.py

View File

@ -2,4 +2,4 @@
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'adherents.apps.AdherentsConfig'
default_app_config = 'activity.apps.ActivityConfig'

3
activity/admin.py Normal file
View File

@ -0,0 +1,3 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later

View File

@ -6,6 +6,6 @@ from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class AdherentsConfig(AppConfig):
name = 'adherents'
verbose_name = _('adherents')
class ActivityConfig(AppConfig):
name = 'activity'
verbose_name = _('activity')

View File

@ -0,0 +1,54 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-16 12:37+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: apps.py:11
msgid "activity"
msgstr "activité"
#: models.py:12 models.py:25
msgid "name"
msgstr "nom"
#: models.py:16
msgid "can invite"
msgstr "peut inviter"
#: models.py:19
msgid "guest entry fee"
msgstr "cotisation de l'entrée invité"
#: models.py:29
msgid "description"
msgstr "description"
#: models.py:35
msgid "type"
msgstr "type"
#: models.py:41
msgid "organizer"
msgstr "organisateur"
#: models.py:47
msgid "attendees club"
msgstr ""
#: models.py:50
msgid "start date"
msgstr "date de début"
#: models.py:53
msgid "end date"
msgstr "date de fin"

View File

@ -0,0 +1,64 @@
# Generated by Django 2.2.3 on 2019-07-16 10:33
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('note', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('member', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Activity',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='name')),
('description', models.TextField(verbose_name='description')),
('date_start', models.DateTimeField(verbose_name='start date')),
('date_end', models.DateTimeField(verbose_name='end date')),
],
),
migrations.CreateModel(
name='ActivityType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='name')),
('can_invite', models.BooleanField(verbose_name='can invite')),
('guest_entry_fee', models.PositiveIntegerField(verbose_name='guest entry fee')),
],
),
migrations.CreateModel(
name='Guest',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('entry', models.DateTimeField(null=True)),
('activity', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='activity.Activity')),
('entry_transaction', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='note.Transaction')),
('inviter', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.AUTH_USER_MODEL)),
],
),
migrations.AddField(
model_name='activity',
name='activity_type',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='activity.ActivityType', verbose_name='type'),
),
migrations.AddField(
model_name='activity',
name='attendees_club',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='member.Club', verbose_name='attendees club'),
),
migrations.AddField(
model_name='activity',
name='organizer',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='member.Club', verbose_name='organizer'),
),
]

77
activity/models.py Normal file
View File

@ -0,0 +1,77 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.conf import settings
class ActivityType(models.Model):
name = models.CharField(
verbose_name=_('name'),
max_length=255,
)
can_invite = models.BooleanField(
verbose_name=_('can invite'),
)
guest_entry_fee = models.PositiveIntegerField(
verbose_name=_('guest entry fee'),
)
class Activity(models.Model):
name = models.CharField(
verbose_name=_('name'),
max_length=255,
)
description = models.TextField(
verbose_name=_('description'),
)
activity_type = models.ForeignKey(
ActivityType,
on_delete=models.PROTECT,
related_name='+',
verbose_name=_('type'),
)
organizer = models.ForeignKey(
'member.Club',
on_delete=models.PROTECT,
related_name='+',
verbose_name=_('organizer'),
)
attendees_club = models.ForeignKey(
'member.Club',
on_delete=models.PROTECT,
related_name='+',
verbose_name=_('attendees club'),
)
date_start = models.DateTimeField(
verbose_name=_('start date'),
)
date_end = models.DateTimeField(
verbose_name=_('end date'),
)
class Guest(models.Model):
activity = models.ForeignKey(
Activity,
on_delete=models.PROTECT,
related_name='+',
)
name = models.CharField(
max_length=255,
)
inviter = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
related_name='+',
)
entry = models.DateTimeField(
null=True,
)
entry_transaction = models.ForeignKey(
'note.Transaction',
on_delete=models.PROTECT,
)

View File

@ -1,51 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-08 13:45+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: models.py:26
msgid "phone number"
msgstr "numéro de téléphone"
#: models.py:30
msgid "section"
msgstr "section"
#: models.py:31
msgid "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
msgstr "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
#: models.py:35 models.py:36
msgid "user profile"
msgstr "profil utilisateur"
#: models.py:52
msgid "date"
msgstr "date"
#: models.py:57
msgid "amount"
msgstr "montant"
#: models.py:61
msgid "membership fee"
msgstr "cotisation"
#: models.py:62
msgid "membership fees"
msgstr "cotisations"

View File

@ -1,49 +0,0 @@
# Generated by Django 2.2.3 on 2019-07-16 07:17
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('avatar', models.ImageField(blank=True, max_length=255, upload_to='', verbose_name='profile picture')),
('phone_number', models.CharField(blank=True, default='', max_length=50, null=True, verbose_name='phone number')),
('section', models.CharField(help_text='e.g. "1A0", "9A♥", "SAPHIRE"', max_length=255, verbose_name='section')),
('genre', models.CharField(blank=True, choices=[(None, 'ND'), ('M', 'M'), ('F', 'F')], max_length=1, null=True)),
('address', models.TextField(blank=True, null=True)),
('paid', models.BooleanField(default=False, verbose_name='paid')),
('is_active', models.BooleanField(default=True, verbose_name='is active')),
('is_deleted', models.BooleanField(default=False, verbose_name='is deleted')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'user profile',
'verbose_name_plural': 'user profile',
},
),
migrations.CreateModel(
name='MembershipFee',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateField(max_length=255, verbose_name='date')),
('amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='amount')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'membership fee',
'verbose_name_plural': 'membership fees',
},
),
]

View File

@ -1,105 +0,0 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
class Profile(models.Model):
"""
An user profile
We do not want to patch the Django Contrib Auth User class
so this model add an user profile with additional information.
"""
GENRES = [
(None, "ND"),
("M", "M"),
("F", "F"),
]
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
avatar = models.ImageField(
max_length=255,
blank=True,
verbose_name=_('profile picture'),
)
phone_number = models.CharField(
max_length=50,
blank=True,
null=True,
default='',
verbose_name=_('phone number'),
)
section = models.CharField(
max_length=255,
verbose_name=_('section'),
help_text=_('e.g. "1A0", "9A♥", "SAPHIRE"'),
)
genre = models.CharField(
max_length=1,
blank=True,
null=True,
choices=GENRES,
)
address = models.TextField(
blank=True,
null=True,
)
paid = models.BooleanField(
verbose_name=_("paid"),
default=False,
)
is_active = models.BooleanField(
verbose_name=_("is active"),
default=True,
)
is_deleted = models.BooleanField(
verbose_name=_("is deleted"),
default=False,
)
class Meta:
verbose_name = _('user profile')
verbose_name_plural = _('user profile')
class MembershipFee(models.Model):
"""
User can become member by paying a membership fee
"""
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
)
date = models.DateField(
max_length=255,
verbose_name=_('date'),
)
amount = models.DecimalField(
max_digits=5, # Max 999.99 €
decimal_places=2,
verbose_name=_('amount'),
)
class Meta:
verbose_name = _('membership fee')
verbose_name_plural = _('membership fees')
@receiver(post_save, sender=User)
def save_user_profile(instance, created, **_kwargs):
"""
Hook to save an user profile when an user is updated
"""
if created:
Profile.objects.create(user=instance)
instance.profile.save()

5
member/__init__.py Normal file
View File

@ -0,0 +1,5 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
default_app_config = 'member.apps.MemberConfig'

11
member/apps.py Normal file
View File

@ -0,0 +1,11 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class MemberConfig(AppConfig):
name = 'member'
verbose_name = _('member')

View File

@ -0,0 +1,119 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-16 12:37+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: apps.py:11
msgid "member"
msgstr "adhérent"
#: models.py:24
msgid "profile picture"
msgstr "image de profil"
#: models.py:29
msgid "phone number"
msgstr "numéro de téléphone"
#: models.py:36
msgid "section"
msgstr "section"
#: models.py:37
msgid "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
msgstr "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
#: models.py:41
msgid "address"
msgstr "adresse"
#: models.py:47 models.py:61
msgid "paid"
msgstr "payé"
#: models.py:52 models.py:53
msgid "user profile"
msgstr "profil utilisateur"
#: models.py:65
msgid "email"
msgstr "courriel"
#: models.py:70
msgid "membership fee"
msgstr "cotisation"
#: models.py:74
msgid "membership duration"
msgstr "durée de l'adhésion"
#: models.py:75
msgid "The longest time a membership can last (NULL = infinite)."
msgstr "La durée maximale d'une adhésion (NULL = infinie)."
#: models.py:79
msgid "membership start"
msgstr "début de l'adhésion"
#: models.py:80
msgid "How long after January 1st the members can renew their membership."
msgstr ""
#: models.py:84
msgid "membership end"
msgstr "fin de l'adhésion"
#: models.py:85
msgid ""
"How long the membership can last after January 1st of the next year after "
"members can renew their membership."
msgstr ""
#: models.py:95
msgid "name"
msgstr "nom"
#: models.py:100
msgid "role"
msgstr "rôle"
#: models.py:101
msgid "roles"
msgstr "rôles"
#: models.py:118
msgid "membership starts on"
msgstr "l'adhésion commence le"
#: models.py:121
#, fuzzy
#| msgid "membership fees"
msgid "membership ends on"
msgstr "l'adhésion finie le"
#: models.py:125
msgid "fee"
msgstr "cotisation"
#: models.py:129
msgid "membership"
msgstr "adhésion"
#: models.py:130
msgid "memberships"
msgstr "adhésions"

View File

@ -0,0 +1,72 @@
# Generated by Django 2.2.3 on 2019-07-16 10:33
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Club',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='paid')),
('email', models.EmailField(max_length=254, verbose_name='email')),
('membership_fee', models.PositiveIntegerField(verbose_name='membership fee')),
('membership_duration', models.DurationField(help_text='The longest time a membership can last (NULL = infinite).', null=True, verbose_name='membership duration')),
('membership_start', models.DurationField(help_text='How long after January 1st the members can renew their membership.', null=True, verbose_name='membership start')),
('membership_end', models.DurationField(help_text='How long the membership can last after January 1st of the next year after members can renew their membership.', null=True, verbose_name='membership end')),
],
),
migrations.CreateModel(
name='Role',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='name')),
],
options={
'verbose_name': 'role',
'verbose_name_plural': 'roles',
},
),
migrations.CreateModel(
name='Profile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('profile_picture', models.ImageField(blank=True, max_length=255, upload_to='', verbose_name='profile picture')),
('phone_number', models.CharField(blank=True, default='', max_length=50, null=True, verbose_name='phone number')),
('section', models.CharField(help_text='e.g. "1A0", "9A♥", "SAPHIRE"', max_length=255, verbose_name='section')),
('address', models.CharField(blank=True, max_length=255, null=True, verbose_name='address')),
('paid', models.BooleanField(default=False, verbose_name='paid')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'user profile',
'verbose_name_plural': 'user profile',
},
),
migrations.CreateModel(
name='Membership',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date_start', models.DateField(verbose_name='membership starts on')),
('date_end', models.DateField(null=True, verbose_name='membership ends on')),
('fee', models.PositiveIntegerField(verbose_name='fee')),
('club', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='member.Club')),
('roles', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='member.Role')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'membership',
'verbose_name_plural': 'memberships',
},
),
]

View File

140
member/models.py Normal file
View File

@ -0,0 +1,140 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
class Profile(models.Model):
"""
An user profile
We do not want to patch the Django Contrib Auth User class
so this model add an user profile with additional information.
"""
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
profile_picture = models.ImageField(
verbose_name=_('profile picture'),
max_length=255,
blank=True,
)
phone_number = models.CharField(
verbose_name=_('phone number'),
max_length=50,
blank=True,
null=True,
default='',
)
section = models.CharField(
verbose_name=_('section'),
help_text=_('e.g. "1A0", "9A♥", "SAPHIRE"'),
max_length=255,
)
address = models.CharField(
verbose_name=_('address'),
max_length=255,
blank=True,
null=True,
)
paid = models.BooleanField(
verbose_name=_("paid"),
default=False,
)
class Meta:
verbose_name = _('user profile')
verbose_name_plural = _('user profile')
class Club(models.Model):
"""
A student club
"""
name = models.CharField(
verbose_name=_('paid'),
max_length=255,
)
email = models.EmailField(
verbose_name=_('email'),
)
# Memberships
membership_fee = models.PositiveIntegerField(
verbose_name=_('membership fee'),
)
membership_duration = models.DurationField(
null=True,
verbose_name=_('membership duration'),
help_text=_('The longest time a membership can last (NULL = infinite).'),
)
membership_start = models.DurationField(
null=True,
verbose_name=_('membership start'),
help_text=_('How long after January 1st the members can renew their membership.'),
)
membership_end = models.DurationField(
null=True,
verbose_name=_('membership end'),
help_text=_('How long the membership can last after January 1st of the next year '
'after members can renew their membership.'),
)
class Role(models.Model):
"""
Role that an user can have in a club
"""
name = models.CharField(
verbose_name=_('name'),
max_length=255,
)
class Meta:
verbose_name = _('role')
verbose_name_plural = _('roles')
class Membership(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.PROTECT
)
club = models.ForeignKey(
Club,
on_delete=models.PROTECT
)
roles = models.ForeignKey(
Role,
on_delete=models.PROTECT
)
date_start = models.DateField(
verbose_name=_('membership starts on'),
)
date_end = models.DateField(
verbose_name=_('membership ends on'),
null=True,
)
fee = models.PositiveIntegerField(
verbose_name=_('fee'),
)
class Meta:
verbose_name = _('membership')
verbose_name_plural = _('memberships')
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def save_user_profile(instance, created, **_kwargs):
"""
Hook to save an user profile when an user is updated
"""
if created:
Profile.objects.create(user=instance)
instance.profile.save()

0
member/tests/__init__.py Normal file
View File

View File

@ -1,10 +1,9 @@
from django.contrib import admin
from .models import NoteClub, NoteSpec, NoteUser
from .models import Alias
from .models.notes import NoteClub, NoteUser, NoteSpecial, Alias
# Register your models here.
admin.site.register(NoteClub)
admin.site.register(NoteSpec)
admin.site.register(NoteUser)
admin.site.register(NoteSpecial)
admin.site.register(Alias)

View File

@ -0,0 +1,91 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-16 12:42+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: apps.py:11
msgid "note"
msgstr "note"
#: models/notes.py:19
msgid "account balance"
msgstr "solde du compte"
#: models/notes.py:20
msgid "in centimes, money credited for this instance"
msgstr "en centimes, argent crédité pour cette instance"
#: models/notes.py:23
msgid "active"
msgstr "actif"
#: models/notes.py:26
msgid ""
"Designates whether this note should be treated as active. Unselect this "
"instead of deleting notes."
msgstr ""
"Indique si la note est active. Désactiver cela plutôt que supprimer la note."
#: models/notes.py:43
msgid "one's note"
msgstr "note d'un utilisateur"
#: models/notes.py:44
msgid "users note"
msgstr "notes des utilisateurs"
#: models/notes.py:58
msgid "club note"
msgstr "note d'un club"
#: models/notes.py:59
msgid "clubs notes"
msgstr "notes des clubs"
#: models/notes.py:72 models/transactions.py:31 models/transactions.py:60
msgid "type"
msgstr "type"
#: models/notes.py:83 models/transactions.py:18
msgid "name"
msgstr "nom"
#: models/transactions.py:25 models/transactions.py:47
#: models/transactions.py:50
msgid "destination"
msgstr "destination"
#: models/transactions.py:28 models/transactions.py:57
msgid "amount"
msgstr "montant"
#: models/transactions.py:41
msgid "source"
msgstr "source"
#: models/transactions.py:54
msgid "quantity"
msgstr "quantité"
#: models/transactions.py:64
msgid "description"
msgstr "description"
#: models/transactions.py:67
msgid "valid"
msgstr "valide"

View File

@ -1,8 +1,9 @@
# Generated by Django 2.2.3 on 2019-07-16 07:17
# Generated by Django 2.2.3 on 2019-07-16 10:33
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
@ -10,54 +11,89 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('member', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='NoteClub',
name='Note',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('balance', models.DecimalField(decimal_places=2, default=0, help_text='money credited for this instance', max_digits=8, verbose_name='account balance')),
('is_active', models.BooleanField(default=True, verbose_name='is active')),
('balance', models.IntegerField(help_text='in centimes, money credited for this instance', verbose_name='account balance')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this note should be treated as active. Unselect this instead of deleting notes.', verbose_name='active')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='NoteSpec',
name='Transaction',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('balance', models.DecimalField(decimal_places=2, default=0, help_text='money credited for this instance', max_digits=8, verbose_name='account balance')),
('is_active', models.BooleanField(default=True, verbose_name='is active')),
('account_type', models.CharField(choices=[('CH', 'bank check'), ('CB', 'credit card'), ('VB', 'bank transfer'), ('CA', 'cash'), ('RB', 'refund')], max_length=2, unique=True)),
('datetime', models.DateTimeField(default=django.utils.timezone.now, verbose_name='destination')),
('quantity', models.PositiveSmallIntegerField(verbose_name='quantity')),
('amount', models.PositiveIntegerField(verbose_name='amount')),
('transaction_type', models.CharField(max_length=31, verbose_name='type')),
('description', models.TextField(verbose_name='description')),
('valid', models.NullBooleanField(verbose_name='valid')),
('destination', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='note.Note', verbose_name='destination')),
('source', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='note.Note', verbose_name='source')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='NoteUser',
name='NoteSpecial',
fields=[
('note_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='note.Note')),
('special_type', models.CharField(max_length=255, unique=True, verbose_name='type')),
],
bases=('note.note',),
),
migrations.CreateModel(
name='TransactionTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('balance', models.DecimalField(decimal_places=2, default=0, help_text='money credited for this instance', max_digits=8, verbose_name='account balance')),
('is_active', models.BooleanField(default=True, verbose_name='is active')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('name', models.CharField(max_length=255, verbose_name='name')),
('amount', models.PositiveIntegerField(verbose_name='amount')),
('template_type', models.CharField(max_length=31, verbose_name='type')),
('destination', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='note.Note', verbose_name='destination')),
],
options={
'verbose_name': "one's note",
'verbose_name_plural': 'users note',
},
),
migrations.CreateModel(
name='Alias',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('alias', models.TextField(unique=True, verbose_name='alias')),
('owner_id', models.PositiveIntegerField()),
('owner_type', models.ForeignKey(limit_choices_to=models.Q(models.Q(('app_label', 'note'), ('model', 'NoteUser')), models.Q(('app_label', 'note'), ('model', 'NoteClub')), _connector='OR'), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
('name', models.CharField(max_length=255, unique=True, verbose_name='name')),
('note', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='note.Note')),
],
),
migrations.CreateModel(
name='NoteUser',
fields=[
('note_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='note.Note')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='note', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': "one's note",
'verbose_name_plural': 'users note',
},
bases=('note.note',),
),
migrations.CreateModel(
name='NoteClub',
fields=[
('note_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='note.Note')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='note', to='member.Club')),
],
options={
'verbose_name': 'club note',
'verbose_name_plural': 'clubs notes',
},
bases=('note.note',),
),
migrations.CreateModel(
name='MembershipTransaction',
fields=[
('transaction_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='note.Transaction')),
('membership', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='transaction', to='member.Membership')),
],
bases=('note.transaction',),
),
]

View File

@ -1,89 +0,0 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
class Alias(models.Model):
"""
A alias labels a Note instance, only for user and clubs
"""
alias = models.TextField(
"alias",
unique=True,
blank=False,
null=False,
)
# Owner can be linked to an user note or a club note
limit = models.Q(app_label="note", model="NoteUser") | models.Q(app_label="note", model="NoteClub")
owner_id = models.PositiveIntegerField()
owner_type = models.ForeignKey(
ContentType,
on_delete=models.CASCADE,
limit_choices_to=limit
)
owner = GenericForeignKey('owner_type', 'owner_id')
class Note(models.Model):
"""
An abstract model, use to add transactions capabilities to a user
"""
balance = models.DecimalField(
verbose_name=_('account balance'),
help_text=_("money credited for this instance"),
decimal_places=2, # Limit to centimes
max_digits=8, # Limit to 999999,99€
default=0,
)
is_active = models.BooleanField(
default=True,
verbose_name=_('is active')
)
class Meta:
abstract = True
class NoteUser(Note):
"""
A Note associated to an User
"""
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
class Meta:
verbose_name = _("one's note")
verbose_name_plural = _("users note")
class NoteSpec(Note):
"""
A Note for special account, where real money enter or leave the system
"""
account_type = models.CharField(
max_length=2,
choices=(
("CH", _("bank check")),
("CB", _("credit card")),
("VB", _("bank transfer")),
("CA", _("cash")),
("RB", _("refund")),
),
unique=True,
)
class NoteClub(Note):
# to be added
pass

6
note/models/__init__.py Normal file
View File

@ -0,0 +1,6 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .notes import *
from .transactions import *

90
note/models/notes.py Normal file
View File

@ -0,0 +1,90 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _
"""
Defines each note types
"""
class Note(models.Model):
"""
An abstract model, use to add transactions capabilities to a user
"""
balance = models.IntegerField(
verbose_name=_('account balance'),
help_text=_('in centimes, money credited for this instance'),
)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this note should be treated as active. '
'Unselect this instead of deleting notes.'
),
)
class NoteUser(Note):
"""
A Note associated to an User
"""
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
related_name='note',
)
class Meta:
verbose_name = _("one's note")
verbose_name_plural = _("users note")
class NoteClub(Note):
"""
A Note associated to a Club
"""
user = models.OneToOneField(
'member.Club',
on_delete=models.PROTECT,
related_name='note',
)
class Meta:
verbose_name = _("club note")
verbose_name_plural = _("clubs notes")
class NoteSpecial(Note):
"""
A Note for special account, where real money enter or leave the system
- bank check
- credit card
- bank transfer
- cash
- refund
"""
special_type = models.CharField(
verbose_name=_('type'),
max_length=255,
unique=True,
)
class Alias(models.Model):
"""
An alias labels a Note instance, only for user and clubs
"""
name = models.CharField(
verbose_name=_('name'),
max_length=255,
unique=True,
)
note = models.ForeignKey(
Note,
on_delete=models.PROTECT,
)

View File

@ -0,0 +1,76 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from .notes import Note
"""
Defines transactions
"""
class TransactionTemplate(models.Model):
name = models.CharField(
verbose_name=_('name'),
max_length=255,
)
destination = models.ForeignKey(
Note,
on_delete=models.PROTECT,
related_name='+', # no reverse
verbose_name=_('destination'),
)
amount = models.PositiveIntegerField(
verbose_name=_('amount'),
)
template_type = models.CharField(
verbose_name=_('type'),
max_length=31
)
class Transaction(models.Model):
source = models.ForeignKey(
Note,
on_delete=models.PROTECT,
related_name='+',
verbose_name=_('source'),
)
destination = models.ForeignKey(
Note,
on_delete=models.PROTECT,
related_name='+',
verbose_name=_('destination'),
)
datetime = models.DateTimeField(
verbose_name=_('destination'),
default=timezone.now,
)
quantity = models.PositiveSmallIntegerField(
verbose_name=_('quantity'),
)
amount = models.PositiveIntegerField(
verbose_name=_('amount'),
)
transaction_type = models.CharField(
verbose_name=_('type'),
max_length=31,
)
description = models.TextField(
verbose_name=_('description'),
)
valid = models.NullBooleanField(
verbose_name=_('valid'),
)
class MembershipTransaction(Transaction):
membership = models.OneToOneField(
'member.Membership',
on_delete=models.PROTECT,
related_name='transaction',
)

View File

@ -46,7 +46,8 @@ INSTALLED_APPS = [
'guardian',
# Note apps
'adherents',
'activity',
'member',
'note',
]

View File

@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-07-08 13:45+0200\n"
"POT-Creation-Date: 2019-07-16 12:36+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"