mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-12-23 07:52:23 +00:00
Not so atomic, sorry
This commit is contained in:
parent
ab616b3f64
commit
fbe2e7f59a
@ -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
|
@ -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
3
activity/admin.py
Normal 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
|
@ -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')
|
54
activity/locale/fr/LC_MESSAGES/django.po
Normal file
54
activity/locale/fr/LC_MESSAGES/django.po
Normal 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"
|
64
activity/migrations/0001_initial.py
Normal file
64
activity/migrations/0001_initial.py
Normal 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
77
activity/models.py
Normal 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,
|
||||
)
|
@ -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"
|
@ -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',
|
||||
},
|
||||
),
|
||||
]
|
@ -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
5
member/__init__.py
Normal 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
11
member/apps.py
Normal 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')
|
119
member/locale/fr/LC_MESSAGES/django.po
Normal file
119
member/locale/fr/LC_MESSAGES/django.po
Normal 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"
|
72
member/migrations/0001_initial.py
Normal file
72
member/migrations/0001_initial.py
Normal 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',
|
||||
},
|
||||
),
|
||||
]
|
0
member/migrations/__init__.py
Normal file
0
member/migrations/__init__.py
Normal file
140
member/models.py
Normal file
140
member/models.py
Normal 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
0
member/tests/__init__.py
Normal 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)
|
||||
|
91
note/locale/fr/LC_MESSAGES/django.po
Normal file
91
note/locale/fr/LC_MESSAGES/django.po
Normal 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"
|
@ -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',),
|
||||
),
|
||||
]
|
||||
|
@ -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
6
note/models/__init__.py
Normal 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
90
note/models/notes.py
Normal 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,
|
||||
)
|
76
note/models/transactions.py
Normal file
76
note/models/transactions.py
Normal 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',
|
||||
)
|
@ -46,7 +46,8 @@ INSTALLED_APPS = [
|
||||
'guardian',
|
||||
|
||||
# Note apps
|
||||
'adherents',
|
||||
'activity',
|
||||
'member',
|
||||
'note',
|
||||
]
|
||||
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user