From af664e481fc5aec921ad6050475e2b8ce0503839 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Thu, 26 Nov 2020 01:01:08 +0100 Subject: [PATCH 01/11] Initial setup for Sphinx --- docs/Makefile | 20 ++++++++++++++++ docs/conf.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 20 ++++++++++++++++ docs/make.bat | 35 ++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+) create mode 100644 docs/Makefile create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 docs/make.bat diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..d4bb2cbb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 00000000..3bb978fa --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,62 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'Note Kfet 2020' +copyright = '2020, BDE ENS Paris-Saclay' +author = 'BDE ENS Paris-Saclay' + +# The full version, including alpha/beta/rc tags +release = '1.0.1' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'fr' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 00000000..9e5048d3 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,20 @@ +.. Note Kfet 2020 documentation master file, created by + sphinx-quickstart on Thu Nov 26 00:58:58 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Note Kfet 2020's documentation! +========================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..2119f510 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd From 0b4a95525b4a767b81300537c312e561ff7fec8e Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Thu, 26 Nov 2020 01:07:18 +0100 Subject: [PATCH 02/11] Use RTD theme --- docs/conf.py | 3 ++- docs/requirements.txt | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 docs/requirements.txt diff --git a/docs/conf.py b/docs/conf.py index 3bb978fa..51010fc0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -31,6 +31,7 @@ release = '1.0.1' # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ + "sphinx_rtd_theme", ] # Add any paths that contain templates here, relative to this directory. @@ -54,7 +55,7 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +html_theme = 'sphinx_rtd_theme' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..8d6f607e --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +sphinx~=3.3 +sphinx-rtd-theme~=0.5 From 3af2ec71b63b493178a76b0fe1dd53e1423a1ab3 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Thu, 26 Nov 2020 02:29:51 +0100 Subject: [PATCH 03/11] Extract documentation from the Gitlab wiki and convert it to reStructuredText --- docs/_static/img/graphs/activity.svg | 344 ++++++++++ docs/_static/img/graphs/logs.svg | 108 ++++ docs/_static/img/graphs/member.svg | 279 ++++++++ docs/_static/img/graphs/note.svg | 588 +++++++++++++++++ docs/_static/img/graphs/permission.svg | 171 +++++ docs/_static/img/graphs/treasury.svg | 324 ++++++++++ docs/_static/img/graphs/wei.svg | 603 ++++++++++++++++++ .../img/treasury_validate_sogecredit.png | Bin 0 -> 52471 bytes docs/apps/activity.rst | 110 ++++ docs/apps/api.rst | 170 +++++ docs/apps/index.rst | 71 +++ docs/apps/logs.rst | 50 ++ docs/apps/member.rst | 144 +++++ docs/apps/note/consumptions.rst | 88 +++ docs/apps/note/index.rst | 23 + docs/apps/note/transfers.rst | 34 + docs/apps/permission.rst | 151 +++++ docs/apps/registration.rst | 61 ++ docs/apps/treasury.rst | 221 +++++++ docs/apps/wei.rst | 332 ++++++++++ docs/index.rst | 24 +- docs/make.bat | 35 - 22 files changed, 3881 insertions(+), 50 deletions(-) create mode 100644 docs/_static/img/graphs/activity.svg create mode 100644 docs/_static/img/graphs/logs.svg create mode 100644 docs/_static/img/graphs/member.svg create mode 100644 docs/_static/img/graphs/note.svg create mode 100644 docs/_static/img/graphs/permission.svg create mode 100644 docs/_static/img/graphs/treasury.svg create mode 100644 docs/_static/img/graphs/wei.svg create mode 100644 docs/_static/img/treasury_validate_sogecredit.png create mode 100644 docs/apps/activity.rst create mode 100644 docs/apps/api.rst create mode 100644 docs/apps/index.rst create mode 100644 docs/apps/logs.rst create mode 100644 docs/apps/member.rst create mode 100644 docs/apps/note/consumptions.rst create mode 100644 docs/apps/note/index.rst create mode 100644 docs/apps/note/transfers.rst create mode 100644 docs/apps/permission.rst create mode 100644 docs/apps/registration.rst create mode 100644 docs/apps/treasury.rst create mode 100644 docs/apps/wei.rst delete mode 100644 docs/make.bat diff --git a/docs/_static/img/graphs/activity.svg b/docs/_static/img/graphs/activity.svg new file mode 100644 index 00000000..22971f1e --- /dev/null +++ b/docs/_static/img/graphs/activity.svg @@ -0,0 +1,344 @@ + + + + + + +model_graph + + + +activity_models_ActivityType + + +     +    ActivityType     +     +id +     +     +AutoField +     +     +can_invite +     +     +BooleanField +     +     +guest_entry_fee +     +     +PositiveIntegerField +     +     +manage_entries +     +     +BooleanField +     +     +name +     +     +CharField +     + + + + +activity_models_Activity + + +     +    Activity     +     +id +     +     +AutoField +     +     +activity_type +     +     +ForeignKey (id) +     +     +attendees_club +     +     +ForeignKey (id) +     +     +creater +     +     +ForeignKey (id) +     +     +organizer +     +     +ForeignKey (id) +     +     +date_end +     +     +DateTimeField +     +     +date_start +     +     +DateTimeField +     +     +description +     +     +TextField +     +     +location +     +     +CharField +     +     +name +     +     +CharField +     +     +open +     +     +BooleanField +     +     +valid +     +     +BooleanField +     + + + + +activity_models_Activity->activity_models_ActivityType + + + activity_type (+) + + + +django_contrib_auth_models_User + + +   +User +   + + + +activity_models_Activity->django_contrib_auth_models_User + + + creater (activity) + + + +member_models_Club + + +   +Club +   + + + +activity_models_Activity->member_models_Club + + + organizer (+) + + + +activity_models_Activity->member_models_Club + + + attendees_club (+) + + + +activity_models_Entry + + +     +    Entry     +     +id +     +     +AutoField +     +     +activity +     +     +ForeignKey (id) +     +     +guest +     +     +OneToOneField (id) +     +     +note +     +     +ForeignKey (note_ptr) +     +     +time +     +     +DateTimeField +     + + + + +activity_models_Entry->activity_models_Activity + + + activity (entries) + + + +activity_models_Guest + + +     +    Guest     +     +id +     +     +AutoField +     +     +activity +     +     +ForeignKey (id) +     +     +inviter +     +     +ForeignKey (note_ptr) +     +     +first_name +     +     +CharField +     +     +last_name +     +     +CharField +     + + + + +activity_models_Entry->activity_models_Guest + + guest (entry) + + + +note_models_notes_NoteUser + + +   +NoteUser +   + + + +activity_models_Entry->note_models_notes_NoteUser + + + note (entry) + + + +activity_models_Guest->activity_models_Activity + + + activity (+) + + + +activity_models_Guest->note_models_notes_NoteUser + + + inviter (guests) + + + +activity_models_GuestTransaction + + +     +    GuestTransaction     +     +transaction_ptr +     +     +OneToOneField (id) +     +     +entry +     +     +OneToOneField (id) +     + + + + +activity_models_GuestTransaction->activity_models_Entry + + entry (guesttransaction) + + + +note_models_transactions_Transaction + + +   +Transaction +   + + + +activity_models_GuestTransaction->note_models_transactions_Transaction + + + multi-table +inheritance + + + diff --git a/docs/_static/img/graphs/logs.svg b/docs/_static/img/graphs/logs.svg new file mode 100644 index 00000000..e451eda4 --- /dev/null +++ b/docs/_static/img/graphs/logs.svg @@ -0,0 +1,108 @@ + + + + + + +model_graph + + + +logs_models_Changelog + + +     +    Changelog     +     +id +     +     +AutoField +     +     +model +     +     +ForeignKey (id) +     +     +user +     +     +ForeignKey (id) +     +     +action +     +     +CharField +     +     +data +     +     +TextField +     +     +instance_pk +     +     +CharField +     +     +ip +     +     +GenericIPAddressField +     +     +previous +     +     +TextField +     +     +timestamp +     +     +DateTimeField +     + + + + +django_contrib_auth_models_User + + +   +User +   + + + +logs_models_Changelog->django_contrib_auth_models_User + + + user (changelog) + + + +django_contrib_contenttypes_models_ContentType + + +   +ContentType +   + + + +logs_models_Changelog->django_contrib_contenttypes_models_ContentType + + + model (changelog) + + + diff --git a/docs/_static/img/graphs/member.svg b/docs/_static/img/graphs/member.svg new file mode 100644 index 00000000..9057b40c --- /dev/null +++ b/docs/_static/img/graphs/member.svg @@ -0,0 +1,279 @@ + + + + + + +model_graph + + + +member_models_Profile + + +     +    Profile     +     +id +     +     +AutoField +     +     +user +     +     +OneToOneField (id) +     +     +address +     +     +CharField +     +     +department +     +     +CharField +     +     +email_confirmed +     +     +BooleanField +     +     +last_report +     +     +DateTimeField +     +     +ml_art_registration +     +     +BooleanField +     +     +ml_events_registration +     +     +CharField +     +     +ml_sport_registration +     +     +BooleanField +     +     +paid +     +     +BooleanField +     +     +phone_number +     +     +PhoneNumberField +     +     +promotion +     +     +PositiveSmallIntegerField +     +     +registration_valid +     +     +BooleanField +     +     +report_frequency +     +     +PositiveSmallIntegerField +     +     +section +     +     +CharField +     + + + + +django_contrib_auth_models_User + + +   +User +   + + + +member_models_Profile->django_contrib_auth_models_User + + user (profile) + + + +member_models_Club + + +     +    Club     +     +id +     +     +AutoField +     +     +parent_club +     +     +ForeignKey (id) +     +     +email +     +     +EmailField +     +     +membership_duration +     +     +PositiveIntegerField +     +     +membership_end +     +     +DateField +     +     +membership_fee_paid +     +     +PositiveIntegerField +     +     +membership_fee_unpaid +     +     +PositiveIntegerField +     +     +membership_start +     +     +DateField +     +     +name +     +     +CharField +     +     +require_memberships +     +     +BooleanField +     + + + + +member_models_Club->member_models_Club + + + parent_club (club) + + + +member_models_Membership + + +     +    Membership     +     +id +     +     +AutoField +     +     +club +     +     +ForeignKey (id) +     +     +user +     +     +ForeignKey (id) +     +     +date_end +     +     +DateField +     +     +date_start +     +     +DateField +     +     +fee +     +     +PositiveIntegerField +     + + + + +member_models_Membership->member_models_Club + + + club (membership) + + + +member_models_Membership->django_contrib_auth_models_User + + + user (memberships) + + + +permission_models_Role + + +   +Role +   + + + +member_models_Membership->permission_models_Role + + + + roles (membership) + + + diff --git a/docs/_static/img/graphs/note.svg b/docs/_static/img/graphs/note.svg new file mode 100644 index 00000000..ac066243 --- /dev/null +++ b/docs/_static/img/graphs/note.svg @@ -0,0 +1,588 @@ + + + + + + +model_graph + + + +polymorphic_models_PolymorphicModel + + +     +    PolymorphicModel     +     +polymorphic_ctype +     +     +ForeignKey (id) +     + + + + +django_contrib_contenttypes_models_ContentType + + +   +ContentType +   + + + +polymorphic_models_PolymorphicModel->django_contrib_contenttypes_models_ContentType + + + polymorphic_ctype (polymorphic_%(app_label)s.%(class)s_set+) + + + +note_models_notes_Note + + +     +    Note +< +PolymorphicModel +>     +     +id +     +     +AutoField +     +     +polymorphic_ctype +     +     +ForeignKey (id) +     +     +balance +     +     +BigIntegerField +     +     +created_at +     +     +DateTimeField +     +     +display_image +     +     +ImageField +     +     +inactivity_reason +     +     +CharField +     +     +is_active +     +     +BooleanField +     +     +last_negative +     +     +DateTimeField +     + + + + +note_models_notes_Note->polymorphic_models_PolymorphicModel + + + abstract +inheritance + + + +note_models_notes_NoteUser + + +     +    NoteUser     +     +note_ptr +     +     +OneToOneField (id) +     +     +user +     +     +OneToOneField (id) +     + + + + +note_models_notes_NoteUser->note_models_notes_Note + + + multi-table +inheritance + + + +django_contrib_auth_models_User + + +   +User +   + + + +note_models_notes_NoteUser->django_contrib_auth_models_User + + user (note) + + + +note_models_notes_NoteClub + + +     +    NoteClub     +     +note_ptr +     +     +OneToOneField (id) +     +     +club +     +     +OneToOneField (id) +     + + + + +note_models_notes_NoteClub->note_models_notes_Note + + + multi-table +inheritance + + + +member_models_Club + + +   +Club +   + + + +note_models_notes_NoteClub->member_models_Club + + club (note) + + + +note_models_notes_NoteSpecial + + +     +    NoteSpecial     +     +note_ptr +     +     +OneToOneField (id) +     +     +special_type +     +     +CharField +     + + + + +note_models_notes_NoteSpecial->note_models_notes_Note + + + multi-table +inheritance + + + +note_models_notes_Alias + + +     +    Alias     +     +id +     +     +AutoField +     +     +note +     +     +ForeignKey (id) +     +     +name +     +     +CharField +     +     +normalized_name +     +     +CharField +     + + + + +note_models_notes_Alias->note_models_notes_Note + + + note (alias) + + + +note_models_transactions_TemplateCategory + + +     +    TemplateCategory     +     +id +     +     +AutoField +     +     +name +     +     +CharField +     + + + + +note_models_transactions_TransactionTemplate + + +     +    TransactionTemplate     +     +id +     +     +AutoField +     +     +category +     +     +ForeignKey (id) +     +     +destination +     +     +ForeignKey (note_ptr) +     +     +amount +     +     +PositiveIntegerField +     +     +description +     +     +CharField +     +     +display +     +     +BooleanField +     +     +highlighted +     +     +BooleanField +     +     +name +     +     +CharField +     + + + + +note_models_transactions_TransactionTemplate->note_models_notes_NoteClub + + + destination (+) + + + +note_models_transactions_TransactionTemplate->note_models_transactions_TemplateCategory + + + category (templates) + + + +note_models_transactions_Transaction + + +     +    Transaction +< +PolymorphicModel +>     +     +id +     +     +AutoField +     +     +destination +     +     +ForeignKey (id) +     +     +polymorphic_ctype +     +     +ForeignKey (id) +     +     +source +     +     +ForeignKey (id) +     +     +amount +     +     +PositiveIntegerField +     +     +created_at +     +     +DateTimeField +     +     +destination_alias +     +     +CharField +     +     +invalidity_reason +     +     +CharField +     +     +quantity +     +     +PositiveIntegerField +     +     +reason +     +     +CharField +     +     +source_alias +     +     +CharField +     +     +valid +     +     +BooleanField +     + + + + +note_models_transactions_Transaction->polymorphic_models_PolymorphicModel + + + abstract +inheritance + + + +note_models_transactions_Transaction->note_models_notes_Note + + + source (+) + + + +note_models_transactions_Transaction->note_models_notes_Note + + + destination (+) + + + +note_models_transactions_RecurrentTransaction + + +     +    RecurrentTransaction     +     +transaction_ptr +     +     +OneToOneField (id) +     +     +template +     +     +ForeignKey (id) +     + + + + +note_models_transactions_RecurrentTransaction->note_models_transactions_TransactionTemplate + + + template (recurrenttransaction) + + + +note_models_transactions_RecurrentTransaction->note_models_transactions_Transaction + + + multi-table +inheritance + + + +note_models_transactions_SpecialTransaction + + +     +    SpecialTransaction     +     +transaction_ptr +     +     +OneToOneField (id) +     +     +bank +     +     +CharField +     +     +first_name +     +     +CharField +     +     +last_name +     +     +CharField +     + + + + +note_models_transactions_SpecialTransaction->note_models_transactions_Transaction + + + multi-table +inheritance + + + +note_models_transactions_MembershipTransaction + + +     +    MembershipTransaction     +     +transaction_ptr +     +     +OneToOneField (id) +     +     +membership +     +     +OneToOneField (id) +     + + + + +note_models_transactions_MembershipTransaction->note_models_transactions_Transaction + + + multi-table +inheritance + + + +member_models_Membership + + +   +Membership +   + + + +note_models_transactions_MembershipTransaction->member_models_Membership + + membership (transaction) + + + diff --git a/docs/_static/img/graphs/permission.svg b/docs/_static/img/graphs/permission.svg new file mode 100644 index 00000000..e7fd7350 --- /dev/null +++ b/docs/_static/img/graphs/permission.svg @@ -0,0 +1,171 @@ + + + + + + +model_graph + + + +permission_models_PermissionMask + + +     +    PermissionMask     +     +id +     +     +AutoField +     +     +description +     +     +CharField +     +     +rank +     +     +PositiveSmallIntegerField +     + + + + +permission_models_Permission + + +     +    Permission     +     +id +     +     +AutoField +     +     +mask +     +     +ForeignKey (id) +     +     +model +     +     +ForeignKey (id) +     +     +description +     +     +CharField +     +     +field +     +     +CharField +     +     +permanent +     +     +BooleanField +     +     +query +     +     +TextField +     +     +type +     +     +CharField +     + + + + +permission_models_Permission->permission_models_PermissionMask + + + mask (permissions) + + + +django_contrib_contenttypes_models_ContentType + + +   +ContentType +   + + + +permission_models_Permission->django_contrib_contenttypes_models_ContentType + + + model (+) + + + +permission_models_Role + + +     +    Role     +     +id +     +     +AutoField +     +     +for_club +     +     +ForeignKey (id) +     +     +name +     +     +CharField +     + + + + +permission_models_Role->permission_models_Permission + + + + permissions (role) + + + +member_models_Club + + +   +Club +   + + + +permission_models_Role->member_models_Club + + + for_club (role) + + + diff --git a/docs/_static/img/graphs/treasury.svg b/docs/_static/img/graphs/treasury.svg new file mode 100644 index 00000000..c2fca750 --- /dev/null +++ b/docs/_static/img/graphs/treasury.svg @@ -0,0 +1,324 @@ + + + + + + +model_graph + + + +treasury_models_Invoice + + +     +    Invoice     +     +id +     +     +PositiveIntegerField +     +     +acquitted +     +     +BooleanField +     +     +address +     +     +TextField +     +     +bde +     +     +CharField +     +     +date +     +     +DateField +     +     +description +     +     +TextField +     +     +locked +     +     +BooleanField +     +     +name +     +     +CharField +     +     +object +     +     +CharField +     +     +tex +     +     +TextField +     + + + + +treasury_models_Product + + +     +    Product     +     +id +     +     +AutoField +     +     +invoice +     +     +ForeignKey (id) +     +     +amount +     +     +IntegerField +     +     +designation +     +     +CharField +     +     +quantity +     +     +PositiveIntegerField +     + + + + +treasury_models_Product->treasury_models_Invoice + + + invoice (products) + + + +treasury_models_RemittanceType + + +     +    RemittanceType     +     +id +     +     +AutoField +     +     +note +     +     +OneToOneField (note_ptr) +     + + + + +note_models_notes_NoteSpecial + + +   +NoteSpecial +   + + + +treasury_models_RemittanceType->note_models_notes_NoteSpecial + + note (remittancetype) + + + +treasury_models_Remittance + + +     +    Remittance     +     +id +     +     +AutoField +     +     +remittance_type +     +     +ForeignKey (id) +     +     +closed +     +     +BooleanField +     +     +comment +     +     +CharField +     +     +date +     +     +DateTimeField +     + + + + +treasury_models_Remittance->treasury_models_RemittanceType + + + remittance_type (remittance) + + + +treasury_models_SpecialTransactionProxy + + +     +    SpecialTransactionProxy     +     +id +     +     +AutoField +     +     +remittance +     +     +ForeignKey (id) +     +     +transaction +     +     +OneToOneField (transaction_ptr) +     + + + + +treasury_models_SpecialTransactionProxy->treasury_models_Remittance + + + remittance (specialtransactionproxy) + + + +note_models_transactions_SpecialTransaction + + +   +SpecialTransaction +   + + + +treasury_models_SpecialTransactionProxy->note_models_transactions_SpecialTransaction + + transaction (specialtransactionproxy) + + + +treasury_models_SogeCredit + + +     +    SogeCredit     +     +id +     +     +AutoField +     +     +credit_transaction +     +     +OneToOneField (transaction_ptr) +     +     +user +     +     +OneToOneField (id) +     + + + + +treasury_models_SogeCredit->note_models_transactions_SpecialTransaction + + credit_transaction (sogecredit) + + + +django_contrib_auth_models_User + + +   +User +   + + + +treasury_models_SogeCredit->django_contrib_auth_models_User + + user (sogecredit) + + + +note_models_transactions_MembershipTransaction + + +   +MembershipTransaction +   + + + +treasury_models_SogeCredit->note_models_transactions_MembershipTransaction + + + + transactions (_sogecredit_transactions_+) + + + diff --git a/docs/_static/img/graphs/wei.svg b/docs/_static/img/graphs/wei.svg new file mode 100644 index 00000000..8167b426 --- /dev/null +++ b/docs/_static/img/graphs/wei.svg @@ -0,0 +1,603 @@ + + + + + + +model_graph + + + +wei_models_WEIClub + + +     +    WEIClub     +     +club_ptr +     +     +OneToOneField (id) +     +     +date_end +     +     +DateField +     +     +date_start +     +     +DateField +     +     +year +     +     +PositiveIntegerField +     + + + + +member_models_Club + + +     +    Club     +     +id +     +     +AutoField +     +     +parent_club +     +     +ForeignKey (id) +     +     +email +     +     +EmailField +     +     +membership_duration +     +     +PositiveIntegerField +     +     +membership_end +     +     +DateField +     +     +membership_fee_paid +     +     +PositiveIntegerField +     +     +membership_fee_unpaid +     +     +PositiveIntegerField +     +     +membership_start +     +     +DateField +     +     +name +     +     +CharField +     +     +require_memberships +     +     +BooleanField +     + + + + +wei_models_WEIClub->member_models_Club + + + multi-table +inheritance + + + +wei_models_Bus + + +     +    Bus     +     +id +     +     +AutoField +     +     +wei +     +     +ForeignKey (club_ptr) +     +     +description +     +     +TextField +     +     +information_json +     +     +TextField +     +     +name +     +     +CharField +     + + + + +wei_models_Bus->wei_models_WEIClub + + + wei (buses) + + + +wei_models_BusTeam + + +     +    BusTeam     +     +id +     +     +AutoField +     +     +bus +     +     +ForeignKey (id) +     +     +color +     +     +PositiveIntegerField +     +     +description +     +     +TextField +     +     +name +     +     +CharField +     + + + + +wei_models_BusTeam->wei_models_Bus + + + bus (teams) + + + +wei_models_WEIRole + + +     +    WEIRole     +     +role_ptr +     +     +OneToOneField (id) +     + + + + +permission_models_Role + + +   +Role +   + + + +wei_models_WEIRole->permission_models_Role + + + multi-table +inheritance + + + +wei_models_WEIRegistration + + +     +    WEIRegistration     +     +id +     +     +AutoField +     +     +user +     +     +ForeignKey (id) +     +     +wei +     +     +ForeignKey (club_ptr) +     +     +birth_date +     +     +DateField +     +     +caution_check +     +     +BooleanField +     +     +clothing_cut +     +     +CharField +     +     +clothing_size +     +     +CharField +     +     +emergency_contact_name +     +     +CharField +     +     +emergency_contact_phone +     +     +PhoneNumberField +     +     +first_year +     +     +BooleanField +     +     +gender +     +     +CharField +     +     +health_issues +     +     +TextField +     +     +information_json +     +     +TextField +     +     +soge_credit +     +     +BooleanField +     + + + + +wei_models_WEIRegistration->wei_models_WEIClub + + + wei (users) + + + +django_contrib_auth_models_User + + +   +User +   + + + +wei_models_WEIRegistration->django_contrib_auth_models_User + + + user (wei) + + + +wei_models_WEIMembership + + +     +    WEIMembership     +     +membership_ptr +     +     +OneToOneField (id) +     +     +bus +     +     +ForeignKey (id) +     +     +registration +     +     +OneToOneField (id) +     +     +team +     +     +ForeignKey (id) +     + + + + +wei_models_WEIMembership->wei_models_Bus + + + bus (memberships) + + + +wei_models_WEIMembership->wei_models_BusTeam + + + team (memberships) + + + +wei_models_WEIMembership->wei_models_WEIRegistration + + registration (membership) + + + +member_models_Membership + + +     +    Membership     +     +id +     +     +AutoField +     +     +club +     +     +ForeignKey (id) +     +     +user +     +     +ForeignKey (id) +     +     +date_end +     +     +DateField +     +     +date_start +     +     +DateField +     +     +fee +     +     +PositiveIntegerField +     + + + + +wei_models_WEIMembership->member_models_Membership + + + multi-table +inheritance + + + +member_models_Profile + + +     +    Profile     +     +id +     +     +AutoField +     +     +user +     +     +OneToOneField (id) +     +     +address +     +     +CharField +     +     +department +     +     +CharField +     +     +email_confirmed +     +     +BooleanField +     +     +last_report +     +     +DateTimeField +     +     +ml_art_registration +     +     +BooleanField +     +     +ml_events_registration +     +     +CharField +     +     +ml_sport_registration +     +     +BooleanField +     +     +paid +     +     +BooleanField +     +     +phone_number +     +     +PhoneNumberField +     +     +promotion +     +     +PositiveSmallIntegerField +     +     +registration_valid +     +     +BooleanField +     +     +report_frequency +     +     +PositiveSmallIntegerField +     +     +section +     +     +CharField +     + + + + +member_models_Profile->django_contrib_auth_models_User + + user (profile) + + + +member_models_Club->member_models_Club + + + parent_club (club) + + + +member_models_Membership->member_models_Club + + + club (membership) + + + +member_models_Membership->permission_models_Role + + + + roles (membership) + + + +member_models_Membership->django_contrib_auth_models_User + + + user (memberships) + + + diff --git a/docs/_static/img/treasury_validate_sogecredit.png b/docs/_static/img/treasury_validate_sogecredit.png new file mode 100644 index 0000000000000000000000000000000000000000..2902c87082e90d13941e0cb0d666974033ddd9e6 GIT binary patch literal 52471 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�?0c2PJkMvtEV+L*l!DnmiM3g z`$40&1=@D9*gHh$^b$qwL6>tbU0D0fJte^4J--Z?4tLuXYTxOfa?J)i`N#H5E1o${(*xe)|SQ=w!w7&s4ml zOx3R6?3XHg-JY$kne{x!|A2VZ`Z<2@;1k_jx9J7!x~Epqw&wHm??02pa#2b9L7{V) zky7*3v5f_Un9o=m^lM>ZS7;)p5hl(na{t5ipNrO1(!n7iSzU36tlZVLvAYi+;^3}z zO3KP;3<}494Z8jffe^53zAht2<5^3{z+j(ba z2ft?{cexmap%;7|Sd(lIlln1rr#_rXG|llvcfPG=|{a(958+cDU22OsC7n;LYg&PJ>Cj)|dN7g)@~6 zE;u^(5vqh?jgf+RxNUI1vhzv+=5WPUZ5K7vm%m8H;>ag| z&|bcL=YC@&p2{2ShBuWTs)$kV>?yDT%U>3TPxq!bsq&#p{u)J_73-Ct_t)=5#l+l@ zuJph?f4Iy*BX`+*dzZ~U>l(r^w)6dUuGrP}6}iix##ER1oS3`XIuH6^&YnUd0%agd zWMuOX2d;b^K_7TYgH9NEiB#3g#U-V?dt3M4k5#&7`Kae;9vvMSSG~8#md*nb25dxD zh)S}!Z`k#p(=H%?#l+~?VB4naKiXr9VBK%droo@)cucSixPBFQWXZ2yz5^JLK^-0N zCB{@ZF+;4+)v}yuiKQQ0;mH#+iBx7UKQ&dJ^{l}iY<8TzVO_^p}-FOeUa!%xn!rf8a6Mb%e;bu zUmo)E@8xJ1%S29P>^Qo z9`rr-fyLk!ggNirEtFXiMh$A$n~tX*q!epc7e#C`u(Pwj3c$y2h+*nxc=IZNh`7M* zrr0O5t*>v4(`)1GTYlHnW<|a09!@+eDW`e*k=&aEnt_1mFJIJ;(Cc0H%1y`7M7vl- z21Oh`-N*P}U;7T1`WXJ1wosV-8y*i9M>4!$L00!0ABp&i=*~y^hz`uoh9@!edDFyd zIUJ4AiG~E%C;Rz5aQrbQD+G+9j(FQv6!^6oF$IO|Gv)zVJwbWu0F`|Ew6CJP^e|MJ zd~BwND5wxnqnVhP{Jj+*5>W+IT91pmuUJYI5J-IIkNf7dIMdV9Gg98raN{N}F5US` zv?UvPM2K z_4hx604o855?EVAt5ZJ=baZYCM)Mw{+~xEp*x1w;R)}p9EN-$I4yc7SD`?_b`iaJMB87~eDO`q&8FwxSU zw{@eEr}6B=*>>)39OUP~LC+Mr*>iQaw`Ow=@`#(Y9&-Hmw19U7B3!WwSn^sIS63CprBmTPs z|MT+yhcm?g-2VS)68ist#DA>df36@%Fd);`>U%*`mQ5-8`jp^L0r&U1_+FO7s2BKC ztYt*mmtuyFzN%6KzDl#SjT8R>@_i{cA=&8}UEx@9%YI#4AWZr|Rn%G?^pw%wSwl z_`k0lEVe>M=o{uHZG-qHU<$#u#m;cR^Eif;C3uGS@+JW`^&+pGMO z{LAHc3B1(p zkHO8pUJQ@de}k(YP@4F|`O=&|d0X_ItybH@V=LdCdUKchwPR7&B9ik1xv$ntQvY z+g@Oh!WS1UjN49;%G%UWpQ%9w9#uUNJ>Jvv9*TP7rUw0E^EdEQ2c@_j#P&GgkO%Ea z-sz>tE5hROg`suE2BWW+I_LsbgR8xhaeQO1ympTK@ala_y8Rr=Q}0e?Shg#gG9)%w zHi(j^Ctv@BP77QTB~H`Or>H09uPTlN=K7>)TFd45ahi`b949z#)BJlXtE1@Rw1K_X zBI!zT;m<$&^gL;1s+jB4z5U$4?pTk`PFZS8S%iA^STx~r8p`F_yA@T*@Y1Yeru_PY z#noIXGHpKN7E9!3J(w+{eyFhik@q{MLZxMK3Vjo6OCGNt4>H{qt*B>^>`mSMiM6Z> zjx?8DHuttM%*Nn*Q*%RS<4!?M>?34XPtt+Se4fO$yf-hk$jB>aHKzsw=6kTE2ZQ+T=X1wyIVGLspq0`utm+IGxBzDOkG zSdZ|R+LO$pAv(&TS@HA8f2V+54QqiXK* zK`ucBwV7a?3;rif#nQ>&V# z75YV7XJFlY9IBwoXZ|?39|DA>?4rtSt9v_HCep%MJMiuTY$O`HOxR-nTrR<=lwKn& zdhoF>LDxp{ez^f2i*>qxB?n?MvbOpJ&0{h6d2R>r%9Zz02+vm{o>PL=M? z7hD>!D}jip8e>cLm&NXg!i>5%imKaem>B)Ra$22BmNl7lAG;EgzC7KodqQ_1&iwVx zd)q5)d*M{sb^(G(!o$N_1#NKW|Iy29dD%kzARs!<(^tsVIx#1rw>Pi)86=cPE+P@p zIx<1cuxD@*I!;{h-kKoq-O75(RUa!mf;wQX$>CsmE8<~iDX;gZ_j2oay54bB8Ac5# z9ykZ1w0zBkqE_w3DB~8=OyNpFyOm zd}(3Ol;o;r{My6$WNSx;&H??tGK(RVC4BlGiSUg_Ph5y6xt+eW(91X563W|ox$*Sm zIqOfiWNVuh?aucVlfdv_h?8j_3a&{O9HjV_!SrWYZXQ0R5BPLEa_1-&?_0l10<7Cc zuC3`Yu)JmT6R$Ot*8yO&Ck)!k)!-_gFb@t*^@x1>tY3c@5WTA&#lu9*|8e(da|O<; zv&UB9@+KhdP!O`+wp~=)@Lb^HTMmsWuZUl)xbI;7W#YGS_G87OyMV8v=WjRmAw zM7zq}A$u)N9;wgoIr)4#N@KjpZm+AUN+oRud*#;9Pv#rM{`LH@Zh2hrElr?KaBG6N zKzw8>%SOyhMDus=M&MO7#Yf~SS(7Ox#JJziJBbtX#-UFt>Pc7LAYh!UpAjb}q$D{B z#P*wBS8k7%w?>C}qo)dm5pEJWZ}KmUHj_eL3v=H<$0meZ2~)ubh-~CE#YkKatR!7I z$6#~Q9*258t93j*SaY0(h8-2}>aS%3L zAalf!3NM*}?8#N-HdV9HcAPevX8QN$_dJ7bY1o5S!D{v8UTn~@B# z5SG+wr+XLUrCDpgk{HL)pTEhKE8S4)j;eM_pB?Rq%~W`nQ$kAK2>4pw`U`A?p&y@M z^d)g4pHI0nI#d5x4j!-(h@kgM_C#KVhB?HDQ6X&~Hs{g%fZ(=4HDP8Z954Mkeqw;E z&UbI9OTA!qG+rBfQ32g5uSYJx#Z?qFyuZoIWwf|AxThDoMkT4g&S8 zZK!KHBSsKzvhsVOtkZaVhnl39}%2(0;v993EZHOloxx7b2E#e(?cblZweU?g>Zbesok zpKW}q?`+IZqE>V8L*HIK_RT`iLd1}IV(jw2FBVsiEoSjo)b{k~YnRzBw^IAl7(O?zP9wog}xVmLdASZLJK~iefI5nXYGYn8W25 z4QpHYy}QfjlAdoGylz*G_p!-K;zX7&A+JR?)(X6RjdMlDI9P26uT(2OpDVw18c$>% zIPyQRJVB!6^$j_Xs9LUV>yKwdIv`@Bo{MqmA2pxtwRBYN@_xPIF+~15SxO#}TAMP2 z-91KJ*v)!^+~yQ6Cy!&*6Jb};u2Z!n`1qKSn_)%55TrtUnu8}8{U+*qP7$iWqJz9* zL5j9%#7w0CJ{ow2K>(m9Lxq{17BP9*AAyvD>VtuZf==W0<_nFh08Ack=7% zg?iSQOn0$JvDDgI=wF44Gubq$zl}=YkIU~7~S$AhQ}pD5dzhTg4*&4f+ew$t|c`X7D0sd~4X zQxv;kZKQc}d%By$f=;`;2f|c@rn$7p*$d1UnB2k1F&_8rD?3!Vc1d@=bbcjE-9pU; z(p22_Wu8`ej!)NAgJ>o&Nv>%Y1gW%@PMFWzvy%0g>TpHncJD4#w_BU22*0F|EzlSn zkCmxLsWjF=*WE7UOZA0_SzV^1L#@KX(Lf4d0?&*r{vtp@PQ-0H_g(10JO8Z6;s(dP zH;{nVwdbPDDf46WZW>X)!m8_=yL+b^eZoQ$=ZD@~wKjcA`E+Z1a;O@B6NIn!>Fl69 zV24)BV~|Mr(hiTKzR_1c&o*HFQ{{dKS#_m7v9Nn1w|ul0%lgy+1!+BkSU{kmGo6Bh zS~p~>`ZL;+<;j`AWaOjsBz})|7f-3u-WY9sECb|J(cr=3fau{xYb4hyZP1BiGdu)1~pl>*$L~^wYDC&+0ah^U*9?3i( zcSr0UU9PK(508$TXK`>ySL?1E)lS z_v<;g-RFi~o!)+4UL@Ryqr)6>?`vLZ$9~6wXPND8?hY!vQjLWN3Cuo<3gNF(stU_s zGuBYGNKsnfB>8FT=u(_`!Mmm8o*3V!e-91|tJM#e6nrA8XK2=(y#`oB|De_l7v9>2xs_%7AMy6}+7=6%xd_StU zf7XW-$V;)--X+U5V`0yfRCeHtaHU7$`sU%rmdL&}BTvsV=fsW2+v`_yKLL2l;Q2CKCbE4%FQSVT4XG7Kc0e$ZZ z)v!bGa^H&4>a>ryi72nh`g7d~HMHE4#HfD*IuW+TuHMORET zq^c_N?PN6VkXZ%a%aZuW61MRETIWj~NcQ=UMMfLlBChqMC+IWaCxPm%3V&m}Ewl(?1OGnxj)k%SXs_ zo2AnyfH4|)o9%3p96!2B_0e_I7g29=`{-DC6{WksKl*-+kK1Zk==QRa$DMer`P@#T ze9GE2O+i%p{GEux`PMfLPV-Lr8V*g+sr!$@k2eciY@YeBo ziKDaeRwe-q3xc8fww7Pj&dsJix+{ahc%oB`%#gN>n5aBo9`s}yG=qgEhk(w>J>dh- z*`QSBR5DQy*}OW+b^LhTXXwZd3hZ6Mf%&{RSflpj-6CJzqt%UETu}{cEcNiorrF7= z$o{F9`-pG4E|GfgglH1AxUE+g`15D8ud4@@yd{_WM`Z<38XtNjYVdN}T}$|PgjK_T z@M+C>>57KD{rJ}V<44=I&3)3I@n!eNCzJsi({-FqXB(EsAg03K5U!auzY4%1kfFz| z#v(T`wuJXjVs3N4)7C!tea2VEif8wIVwekUi>rUE+`uTRs>z1Fmh|72Pd%puHA(fx zCfU5Th#xKotlZV-HuH9EUz?e1MCj>zG}EJ-391G_bhaerpBZZzp83@%@%twzkHXQ9 z3+A`}cw}$w^TdOBANA6Yc;QbXnVIGq{0ltZsW0HqJk_iWl(2hln`$|2|E=CGzpU0< zxtSRh?Q^vr8aj${HXp4`cL;gk%4mNyHl6G$mIaxJsPsEM4^0bu`yw`lZ_haMNhgKM?4gq{voS2~xK zyY2{Y28V@}2PEV6xxZ#%5DIJ^w_RWCpXyu4%`i*DZFb%kO2Ii|Kfgkd{$8CK>FO&Pd1-G!u(>(%Z~w66>O@ahUwjYlWz$<> zVMgvwgr)*?#CC1~t?$ldCV6#p;H6f-vCp#mYT>jAX#q zD`;uCeLOD8S$u4#&vkY*-QNdG!dc#)SEP&)bpI51b*?xfQ6Rp&j;Cay1Q$DOCpY0hK7x{6Yl^woD32CKY9|*@;o+sms_g!jx7^YZp0!b+fXpisbf`-+b&Vu7jdA@`)|Or%AfTSl!ufl^xya#3q~7 zxzsTJy4+exb*;~^_iZnL(-81<`Qh>j$#(FxB>v3%ih(6_Y)+M=3EG!4AdqgR=VH0u z`*f_i+cnFE)Pr7xe1P?vS-JxII7UFbA+G3LqX5wPKGn?F3PZpq*$u}NlkSj zaCfF?B~eT!);1->_V5+#E-vCuf-$E=9}q>lMT%pSHAAg)+i+NmTB< zgj?zAi8RNwe_QS^?@r(K)b8c9EO*!z@1-=@jCnrr^U7FuKp+=|5^#KvY~JOH-`u&< z%LLjLoKp|0Qr4|Nb5@mB<7u%=@CnzH&pDKqSQB_mN;%S`sSQ1)Sf-zodPZH8&p)oU z0A*zWj*K?pG<{Pf`KfMvfy6`Q@E|GIyQu~n5!#J^!1Gxnc(0>aB3GLu5Ce6scD1G< zWNRIXtqv$lg5zxf)rbN7x3UC?p+?H}lUq^wzT*~~B>dNoymMsmPS5JyrPY@o%`L@* zd@kts9)$PXe>%$L2CI)Hrw7tQk=NHE&JhqP-j__GAvqB`k*Fs!;TFxh*)`WLb>63+ z3+UE+fVcy8Jk5J>?k$B$uT8*IV1kO>SOs%mu`h zZxh$8$fCd@t_eAl>YSLT5BpmWTixBMyP-kT{m1gfxSttxXtO zI4W?Yvr&-{)+5625gDO2|dE`P2e~CK(u}SHOx&rFg#pAs`A$PtkkJAxT ztR)LYg#F4Z!ph4}rS2qb>}_=OXl)-QHAb(fNDVl>4Z1Amr&N5e=FyWmZDS(S_F}C) z(7oIjW~!az^bQsZ4OOAX+3bx+bvk(lp;R2cPOs@<%fOVSW=j3p4>ua=?*f`F5T1Nf zVn&*Jc}1l`vGp@|`YMQkD$kCa8)4>HBcK*(gql}W6oAu$x7i(kaDfy_fW_m8o)x9_ zTy4mFEKm{s1CFKJI<2B(gwO-U4+f`~T{=&G79JWl<|BU~-?g?zSs?CpIX3|xo?YX4 z!`zp(KNg)5(z0Rs+d()CLtRGuPQTzpY@xf^QCucmUr`TAXsW4MR`M&@C4fa;Ym@c6 zgZGn?b>{giUo(@H?@j_oSC{i3F}inoI1?CAa57$uQXA_?yFb;gOj>t#KQRucl289* z-l?a`##Vo`6e?^cId6yh^8@`o5)X%(8A8g5#Rw5edIq~5pm=n3zK3Eqh~M|ASlWxA zL7~|JI9TeQ7hjuK27(vE1?=xu`5zkf0$l^2xq6JT+KEjks^ zT@)(~SMptg@m9HpLB)0onS4oiPTj>(xl)j-3RC({11h9^>)W{iy^2}E*V-N&(EtfM z%Co!e5k~1Va)QTPyOe9H&B_X;oUuK1B8B{G#zI03w*re3w^zOharwm$l(-BxXH`8* z%80BJgNkxPa%7g89QU_^$_MTgEwtPV3XZ6qa|b;M%v@G!SAKAR$RV60O$%eYb?avI zU)7`;`fIGZ74|WdI(qrM5k>{gj3mTnNtT({bsVzabdFYaj&gIa^_b-Wm14}Wi>1y>LJ%FEsGB$sD)oiM%%LL(_O}D z=De-Eq|nV&@}~}pDdy)>YBW5cgSXNZ29VMMYjWN`UUJd5mzXX=;3>y4vrcM|>rXBW z*YAA3?`9dBC|Sj2g;lzH5ri}0`_%M@UD5dISA;%)+^^*%Uqc=PJ7c9j%q(fLpsH5; z+jv-9H8~-Ie~YG<>9rRuse#bsB~$Di1w7%Nd<`{O%)PN zk3;-Javp=qDSl-V-3L_&4C00FXd|55dWijUbG|(I#z9v|xiAVJR>)gWr$*2C)!S2( zhTgzj8&UcAi0x)G?~?{2CC{Gf-C(r_MqZK6Z#3+buL-JrpK7yM_gV}cZ&03IJjQxM z$1L68L(gp(5t*9NGubra{?%<^xP1|BBEPM_F2hAU-f6@0TXCeFJ0pvP(^k$#?L^+( zGM3VL zD>KVq-)>9noMd?6^VKP*-3}AOg7hT}G zzuU|s(hzSKltwrPV1>84oMHhTWQzL)4pMS*;f%4PLIUX^%dR0J_M$?`l;_XFdwK&s zo=`Zn4UN&Hx2CTwi8S{6nivj$ww0PRC8NT=yARcA;M z?SCpFzpoGE95D~stX%wYYq%9TwGETsZn8*E@PjWNm|b~)w}*O8kb25Yp6PF=m8Us4 z-<~%^4-4AUzp6U_WXw9M!9W1vc(lN!b7rbh*65u3g-MP)xt@@x+g8DCvoD)R+0Bzb zsqdEf*p%-07OSe+I`1U(zNFmo&}vfu_MKfZhO;p}og0NZ$7N~VR**3aYaBm+chTzj zDyC_MeR30u{sT&BP_|1h6!RmbE<(D$qcGB~YLkStjQg~^7^FxwZdDs}i*MeFe4`C0 zz)*qUP#>L2zos9an1H|{tQq=awqN+mYw9+J7glB;D30Xh-Wg0_?U#!P(Ar6D5FDNB z%BafP&GNe8ujY^@&m?N`D)}jkw2xS z5K~V6+7?b1x{-Y4oNEhV#(NezCvI_7QE%tKvD$f#_JN56N3@)MVX>GVSG`N`n~A}E zKIVIYDeGgr~0iy^xAKNh`V z=8Nr(_TMcfNOpVVfO|^B2w6Q9 z(Jb}(&5ltY5)cUbVA5@C0XU%j{y7~2{C>F+U3xEyqD3e-vX$%oa=&r_>sJ#|)C_?V zaV14P=H*+wBx#L{H(Myq*U3q1vK=kC&%*oP-{-r~9z3d}fi~~bAZ7JBva-+Zeshg|z^5kgnc`IeTJtd|qCKOWxpW#if3 zn6j}-HfAJhZ{V{ut3w)`yBx+|AWk1nl+eqgaN1{a>JT8Rem2)Are~I&E!>ot7Pmco zbBnL4ik>aXZE5*1X4AV>^@Lgdj6}DNF<#_l>+~=p`0E$K_Y`U-g6p3UUu5^_bye~D zgjO1BR)8^hV%)_n!CSUnVklm46>h54D=SoR78ZPXz3PB4scxX23wf1Y-ciS$X>7Rk z3OC%ORKLI5i_-J`kEH+ZwLG6zxZK_~PJItb9;wKi@2|v`)v1NEUHp~Q#vgD5?*C`I z_0lFaY&#c4#WE|{T>-5{w~_yDSCit&*1==q&5onyW4i6pDG zSEWz?q=qHA`Q&qj>)itdo1WaPfT;DIVfUEv(!(Rk!z!~DE|ft%G8n* zRvZJf3h(5}iYj(6U$xp(2xQ<1t-1NRK8=l(9Jc*s$aTEq!E&czJHauH-p6Q7>WFaX zVcuo%NIqWu1>3~)<#Mr0Nw|&O*OnE-vjXawdRCQ)w;L0~-V$hmcAKWVp$Mg^d4pQy z;6QF{wm}_;?0b4VYpZ%Mn!9s;R;yB!)hvVF21hEbAhZt05uESIAVm;fYzj_4IZ3{B zt|zEqSi0&istnFMzmI{%Sa0MnH@+_ZH;9I|O)q>QHSPAuS+eKw;1VdwEO;;+Q9&#ozQx-Kr;kvCM7!dis$1@yKi04wKx~q+q%8~#`nazT8QQzoN;!_( z)zb!m<~X1Yz6+HLUXQOlbscD=c!VR0T2|%Q`@!?upS3P=`|h+AIQIyzl@3n98v{kQ zQzSsC`4Z*#bp({gf36K9TfzhzF2?Q__06*JS966LNKd!d9(qdI1IA*$H$j{{VZ1qad2b=pnVW9NgM;I}oJY^G!Ioa>u5z}7p=-lt|yro2*hBItb z;fMle<&CwPMXd=hZfK2Yiec&Jj6X%|y3JJ>13l##Q#v^huoknXxAG}GIz582p&~!r zU5*;R@zidWawwJPPnmtRHZiwe+uXIY*m1C)ln3kPlYG8?x7XD#6FlGKp}`lhy%r*> zpZ;T_#DD|j()mUV{l%o+3-yZQC|mn@^za~HNZsmUK^@UPFKkkJ++u2M+Rb6j6f+q+ zlK?(h+R2@3CQH2A-5(8}%#19laj;FcOZLI27{upEi#DUPABLz^7GOpcJDq&N zvlCbO8V=xqL2^C%WR$Gl<)|o0PZx|m2qgPJ_6$@|XbvN(!ZjW%%fjlVk>#{k#A@S@ z#9;2=uIGl=O7zGgK3IddfeMeB-|%L{7Bd3f&TTcAmwAa9p8b056R_0p32)hUSeT?hen zY&&f>Erb1U`9cB8%}c7KXWlA5iBQalM7qw`F+xjCy^JlvEUQlgw4m5D_CI+s&!a-U zPLJD`rdENbJoZDdN3r+CX9ei6>WKaptoar7>_OW)7T@8M&Awl%92I?sv>RV$)QcK3 zyG^*1&^;rBhN1QJ1_0(I*85QGuiRDew$`__eMc(DviC<=39B^qvJHdeq9WG~l@c9L z_DK*-d($cZey?;4P6%aK(06C!RCBsis&CLfgEkQVGIRtA23@HMdEY3^kN$CH!!1xG z&+Vj|x_fKv?UB8-)q=MIc%Y8umxcbvS&^T})Y$iA#8f+kZvnw(%nt-XDs7jSGxTn5 zI(-8hQMO-_D>|F!KZBHPPm>2R`9uG^jy6_GCHH!p{;XQ00d9PtY}}nuf+~N(>Jn+v zCn3YdjzpmJ)p75kxW!OXTPvJ5tQSjYU5HwBIxN{;DeyoP0g-5&&vFZvhNIZMgU^ z=q?>!cmVa9ghW&5LrAV#;7L*k;ig2I#-GR~HP{AF35E0bu#UN@IiG_7RW{m*T`d8{ zbfcj$mLl(j(q|CRP`1qdG(}i}xU4IqoeY7719cRL+qOm9=y(aH?;3;dyqG*X14l_K z-T6T>AVyo9weV!TxoFv!#EF7F}8)5h9+vqWOj+Yp6v;Q(+-6T z)@0Y@|NJ>sZnL>L@r#N`DHLaUsH?j3_vPV+tG-}GO#AvbZ9Z?lEBUqM47ooZ%-Ka9 zP&?zH6=jLHzn{U49&8zDEjoR0XN7sy_XR*k+1)p+T+T-s7SEtpzTY*g`1 zzw{L&L3lec=s1J6dvH}B69WSqdzl3(f3C#!JNkzOl94!~tJf$^1D%6GKQwF?eu2)J zfK%ElZ8hM+R%h6=&rfQ;>AJ2&YE9R=kY3!biv))jEFPxYVGyeg!}gR6hT&t^M^Pl* zoQD`M`7QcSk3Eg#Zd7%?u?(?svbk=uxi#%hus$hCeP@QnI5M)%<8ptX2dT?8b*%Kj zNTqOgYA<(B!H6jS*HezkD?tXK<)q2z%NUf@J4F6m)JyA>0BzAmm#r>SbZn|vR%3Cx zoE5k<99>wqv@AUy48XH7_e;ls?V)#a{Es^Wa9S)&on_VRI75V`cPP=?Sv$S z_H-N75AA#8GRtmg_;mO92zPaEBdlg!@%bjPH=D=dG*z!l5xJSUA>NqHGU(nF5Ja`B zRX-?5JA86k^UGa5`j-B*>8MnwkngW+%R9r(L6IcnZM}Gx!ILNB#kE4!8XaZ%L}D_E zBhMwxpi;kcH?gwz-LH{hTvr9U$k(#8}H$44pssd!8XpV)`L;~f4M zuBdhD!a~Qaap=7PNRv8`$CI{g+x(yY`6og{m}RW__MdGtn{oZe2Xq?M>5BpG!JK61 z|9qC8@0YpGQF;$sFooL#rFFJ>EBXB*1$TP0Oy$C=vG8<_Th|Y|oxKztha)iI`$PfPYVo2m#5A(TQ5o|&vOXH<4p8-w3&E}#? zL-9UHJW{aIxHa<~8oCwrj-B4j{dJ!j*E7G!n}XsC;a$tIs_i`nnfO6Uv3slS5)%c@ zbuRcsmWq_HFqLPyD@$VWMzP{&w1U(ZcWuYG*@H> zuyS z8Dh4sv`c0go7THC##2+&Q-P#7K(B(^jqI^lM)m`k$ z43e6zx9^y3_~Me%sinmeFWojsvDkoLyCth<3V0Ay2nfm{3_VtEAxZF&%WYCEr#pwp zvP2=sYucSHAQREvYurMb8u$ynRiUd|eODgo?UTb31gv&cX;Me-v{?=rSC-Xag_v!c zB2_3egg4BZ1)DY!QpMH*!!!6&YtFYX4fKD;=r5ZPK4Z4<>sn5ozpIQLkQr6V&W%97 zHslV5Gim34Z^n4|50|Pl5g=QNpMVw}K(zq+&xNoyH{I%LDC3rYi#oilI#Mx~xqbRB zt^N15zC1Uo#Zb087zZ%t=U1>2P9RY^hM3=;-=#5fSsga+;JTOU0}5uQZ7ze{@YKBk z$c}v{#;{)MWe094_6a~_=hy?4`J;x9m1iVf z_oP|>ho2vhXbtuPGhSjeCBx%9iVNVUu)H?2onP9@IttS6Saci*G*S7wo^DGsl{p@* zJ0O&w4<;l$15#lm^8+qHaYQ$*1Z*Io)adtY9mOdhgRHZ60eRhwx)@m6nVze{*iy3X z(Fp?cL#J=mF@sc>4MuwTO*2dn(?n&oA1f7zQ<^#oJH1cSyb+OCg&N!JVJoXxbN^A= z|AOFDxwedi&kEMiysb{LvLoxPoOkM$3Srs#m10Gb-_RaH3RIT&N4u*s@@_<7m%Xh2 zC@8B2vu(eu_8{})FCr5RlGQ6M|IRQpG64xNSD&aDqa62+R@$LQDwFHn=5;-R07bp8 zSa{N|A1+m;D0{E*Aa{{1kin30tyZJI~O zh*@4q;eJUoO@o(5GEOW|k-ljPfZE!T%hI#@!Li)_ZGS6IrE*$gA`7xpvZxm-PoVxa zS(6Wt*uREz9z$NApB`iSg0SyC9}#|?meXcoaX9bI@4U_7-)<=Le+P<&l1S0a3*z|- z18$o-p|`^MWOvN7ZdWE76o!hlYGygq=uQ}dNx|R~Ah!~t7fGQ3(Ok`^79*Soy==gX zpr6`_q}yx~iAn>p4A8OcqvYipi~u`|6r#}*)>@%`u)glFT&UoY~y4>^1yR(CcRo5|e4is`w~ z>!%~v$)3*{v8yM`qsD|V43O!jI_-P`w88FhRmO2}R+pU1(wBckyMR29Dp0kX9LR=d zuOP>RrM}bA-iUSy#(;E$>-m->#fR$!#f%sLS?9BNrS4H~ncLcFK}i$vV~RouG!@+3 z;J=r~HpH|y07~RfTcWsdu6Gj(5Z{G$GZK>7N;GnsUaq<^xSkU0cYNKLE-(mXe;93` zJkjjtbPT2#M7uy#fHdY+o8J#-@neL3KieI+3^|=njG}%XnuBl*-q#o4JW|c~24B29 zy{eR?cjeiWNPTMUa=X?Okn#bv5Y$`%0(DDu$Wpl&_&L>6x<`2D_wYrmsBld9!n*jb z_QCQYQ`6hQYG?h+{=%5%fHHz!;LZlpwC;Zo)GoIO3O%gI?XQ32LN0^(4&PELF`svP zswY7n2?_{Mq-r@4ZH^XVw+;(=i7^$WphB*B23`f6P}JX~X`~2~-;EZD7_Jz#t{ry` zPp9<=T$V`0XPn6igFvn#`Ia6Rq|jR+Ab>m=MVD$L*ALK>=7*0G2CP-yJapIM%U1inq93f$N}>8$`5M54;}c*?X)=L=2_eQC+lM+#d!Q1F zXX2|dkyA8S=&}fldQ`|!WVlI83?&i!mm!^@qo+92Av8zekr;cS=I%H$X*^0KqjoO6 zUeKUMNx8y;n$w#)gCc5J_30Yq&AfA6k3YS>CVUYJghDGllC=WgvJaCetQd5}%wntE zlZJIo)}1}}TP*vE77H2I0ieX((i*tWtxL+ha_Cz=aE_Dh+ZDU^rotgI&ZdFEp4sUw zEIM|{)0n!vSj!ahl?U@49BwW8IwfcG7kE#r`|hr0A6`ikyyQ;6aoFz)1K#$W_-+Tl zwC6V8Y>}&L>tqgG9#YE@qbjJi(*>YgG_Yprx+#1J^!Jse<5_2Nz*+04(SM21@HF44 z*6&}CKy{BxDD%9<2Qn2zD39R9ddf_-f{r5jh?Qm95_;tBH=e8HJsJw0iOcB%Ad_(( znhO}tNEV1Y&^b6>%yh48?2q!4e{`&&R6GnE^*w)ilU0_um(#_RhkdiZ`aJ!B@$-LJ zS>V#aj(VZ~H6=;|NWckN)Uc5AJ0acI^xGVUeyJJLU?%45PROQ@XBJ3z4A~3Qt-a(6 z;aEF7vu%C*9XYq2_o>1zE;Shin88`jJo_~jQXi9}6=wv&Kc`*s?j>Sltv8&vqiQyWdq(DQ+(W>hrm6x_VVi3q^UI$%cjm0k z&TAba4y*dAs%4E}=9pfI7H`t#!-HplVPlSg+UW_`xVD}Y9Lv*>316lQHi%_Lmf}A{ zcSrFS4FRp0o8gG)ROM$7T9Nh1H$ z|Cff2N{z*-Yu3K^sK_hh)*}|e0XGPH-FssvWmt!@Q0vAZIY&bLoXdUv(&_UfR}=m< zeIo?tW<*}({>d@+UFRyXiAno$o)FJ-8{cHjF_;@u(V<)Zg1 zun)P=Y}Z=O@-*_M8XB*%9reo`KL)e6d2_ix54h{mpdeu3N8U_;WX#^ablCe!1d$H@MRi>2$-@5GZoij5YNTp{xoV!mr? z>es}1JVZRDi3?_3{ybm4dkODN?GD}}Ry!wcYp=N!OG>s)_N8-3cnd4V<|=HuV=3-R z&(p89s&*1wAu9=KdTFPZ%`}2{h)pNxLyYS>lBm)*>YjOhH&sWoDaq@YFZpWUtwdhC zFl!@z3u&_zsy~BSmX_=0MZT4Bw-h;1-J?Ezl6Bi8ljE$)Z*r>EzQ;Rlzav)+SE7OQ z)IdLMH`}lA&|=wHeV>{?>;5%wl~lRAv_hD#bpBOInWXRHN}cFuzSCPMY+`dQYvhp5 zc@#Q6GAMHKt3U*{QCkV7uqZIGqU^oJKPxlT8J}5I^}z`(a{O`X&vfms+}C9;Yd0SH z@614vQ@{Er7jM3e8j=L7(yLe|LHz`%Gc_V~wIuRL;NEyIj*5zBtdL2F4gD<#F*RHt>0siLY+LThVqF8DEy`Dq?npT{YFv~lqG8nB_D%Mm09fTn^Ti4 zq^H%|zvlxl7rE|YEN5w@l;Xszy?7WG0Urm+dsuYs&TAt%sDc zF6#>OR}t29obPw-uf>qnd+g%kltxKHCnw)iAJPO!aTigfP34?_I~k*T?5;^!zEbTj z-1I=KQxGq1DAzq%_%>KbO--wa$IbovNk~YVKG`gK{UXl*mxud2=h>wPTYuKF7FOfl zba{E~{4C*Y6ITMv1?g+%*7&IL7hLQ-8JJt`7?qqrYQz80+SUZND~y_XOb=>k#$(nLxK5FpYaG^I#yp?9PjAcWpY?pDtG8+Y8l z?zrQ--}u%a8GG!#ve(+H%sHPq*IEy`Dy!*+=!Z`b{#-+kpphU2H3917i3V{X09=zG z8>FbFW-}s|W!8L=jU)JdtHbPOw$Am|+&Y;`o^`3shL)VQ-z6~#SG?M>FBMde3{!W0 z;&)^svH12=h~wUsh1}sm3;N16|Am%KziUxcwFiuXuCvigzG8URQtK03ZjoPA<7)#0 z%Ye4eZ1hiENfrrVhnN4346CYYBm}cnEpf1_x0Q?~R9P%c6~mmI{d@YqwjbV_cD9|g z-At^QMH35uxVe}=@tgJ|!e!a!lX?RQ(<@hC`xBq2cV^TjVE@2)DaY%)6m}|M*u7dI zP_b2#v_1+-)N#{^pPLSg!&ThQI~Ic$ja4+ zP-;b8xtZ~FxxxFU0zay(PoRQ^fGIQJ={SLx)l1cR*AJW9CJ#a7LT2_02^yGJu@nv&w1h6naC$RIIFnux|+h6D|2g#;)@@-Y_h>xmI@TCW z_p2Xv7^GueWi!gpQ~JDl+0>|#Xw7Yn+C}SsP#?y5zBSjGpvS36-Ae0)2ak@fzQ-;@ z?JI`xV6f`wZTQrv%;T@>EuOMW-F;GULEq5h5ki7Ets=BBa1&Um4-wLNwD-4$1dzZK(dxvpW8 zDN?=hVsoE?p?OVBVy_WDP(FCIH*Ks)@LS&MR#ExHBw@TEM}D$_P&>n5BwD=k#$T2( zg<}u&vvLCMJetqeul;%AHVomX9JL1W>_pIDCS6O}P$Rlr7Q^%=@(Q99F{;nXt&0eR z;Por9sHYnpdv>pWVA+ps$M~&c)B#uP=wiDwH=iRwPq)B z%-ZF}KW*@0y~rk%$xf&mooQ7Ia0rn6;n3IqsdZ#g^l-{2kNQD#qYz!A>LT0K%T6fm zC{yF#0@0O9{i&XRD!6tTwDembhT{+^`?=xEx~5gI9k<*A6)x6B`en zlp5XD^`mR$z8uVgJhlqEUIhbAIQ%%!WsDL%y!!q@Jq-Ov7A`QE*8Ykd-1qR4ok$L9 zEI#C5BYYxw+@*}iwu>~54>)@lah)$rscfX4wkN=Lrb@@Sl9<$A?(SoG6aAPWy(FAFL?31edP-9h@#z)@bJ7exmD_+8Z?K!BiO64D?2}dCDYFV)Mp- zZc)TYc`tvJ{n1G#*`E08YrXocbDhqXbN5QnS&VZgr7P*}lA7fz{!F}{g*5Lj-Xn$R#p10y58|FSySDO5X)tSUC(T`m{8>Td?GI^#B8OZ2mY#((Qy z-$6}^uiL5y>G@akYK^;ct}eZniC)o;G3d6UU|4Q$6U864B?jl7G9c224Q>^$DhM~6 zY+(d((Toz+M{?WyfI@XPmO*z_RPA{mO~$4V+bK)9f3>P@*w-ko#b;z0`SozCANL#F z14$sYAC+rzEpE17`5Ai+Fi=KIR(PXQOsS|Rn>@|y;=hS|F3@`e1sPpXBl9nZX9$Yt@VU+u^54s3<53`V1AgRdjX4z;z? z)GCd-T`4BV0rnyL3Z$ii*ALst?36W$sj=b0o{Gkz!^(C@e~#5bwE`iVTUrZA^VsT} z9fG2(0X#!Cejb=;P{caFj~N-3R%^*L!d^$yTQ_#J9+=s8x zMLEbjLJH+lwrg%4V%-VaCff4I7YNKgTy6XUi(KvK8%FdzU6Clau6hw6~ z#bCfjvN(BIz?ju);>WkAgrVQ4FUKFsQHmwGwb)hU-F)KklnIKkbFL)}{4mi=iI2r) zP9keHQ_FeC)a_vO`$;<}-ixuz@Z2a`eI#5AEYisk$I900x=N^f%}-#lx>4T|VeDSj zqys4Y!Be{kb(BoCeN>h6Kk+S0AW#00Orn=I^81I$TT1mfEa9-O?rh3y(8#DD`>Mzp zX-xyr?`!)bl^@ChDpxfEuYp5Qm*nXazmrNZ_7#z+QfnrvE_Z9gY`V^o*?2|!l>kLE zh<9qFTxJ$LHX~jU5iMK^W{lEiT?G;THG;xx3L$u~n#CZf6NWtYQN??>s2VPbn|2{Q z5k`2>0B$3E`E6(?;@u<*a^@wZ@upUHWo<*Z)}B!>w{cNOUI4$y7ho{;o_X1YZd851 z9yGpvPDvAaRKW?7ET6QEd#5WW2k5$0=KI)%stg)ca!jka(?Btig6;F>?VHmzzTb}@ zWl%8fK_b0Ij}9+0$&?S1n#Wq@FE<3HOmLlSXHuWg&%O}{f+}FT+E2ov_rTW!0{&u@ z+1lcU8*7`qtoTHhK*pSLM~<(H2X%-9Xr<)7YIH`Imyg*Akg@Y?QRoIwlP?eX2lq!= zm}gbST>^@N{c6TzER?k}!@5rwDW_XySPhG4D7hZD>x~;mEq!5UEzkmVFdytk;yr4f z)RW~APa&%K#IVWKZV!CR;w^cKU#^%X0$WWc zdy`C98~3MA=y8!6g{*J3}eCczFvv)Pm*y_hhk!;uoZ(Fw=3te%!>U=OmZ@ zL_swpr$j#PLNz#u+qhEnbo(fIp?3bkBgV1%T=_|91^$ezCP^d~RcaeFV0`lO2kdH& zk?pisKvut65(1H@uc8y!JI`!pH&cnh^}Uj)%IcJItEeD~IJEt!!RISBt^VL-9(%UE zF>0DLAXtcNa#TCnDSBV@Ktflmtx9**CgHA@zU^qC6d9aE4~7&EJrya+n$jI!2X`4TOO4$Q|VXAmdt~K7q4U=)W>s6a_VwYZ#3VfbcVty^Pf(d%{2H0 zWx5ju2(@}Xmj3^|tR|R%_^=5S{!HZ?!If@1TQ}~+zFIH~`%t`DcA4ds07wE|!jSf< z3%uht$Vh&<1Q>nDSb;Wo6VwTb^8YRkXP1#- zdkiUA_V+!CP%7zAV?>`@#SUlQv3T5&{A8x9|5pAWz4#u}bpFAwrg!U7#z}>Sr{(a)ZQhp4}zgt?vpjo_zLw_5E{4} z<16Ls`36M~xI;#Gbl0BVqvUs%X=`XE+};Ixq(#_4#%DJ^n%U3)YBissz*3_J+8B9P zNKCJC{x8a{{VlW|_iD(p-Io~_g;tSK{4PgQE^bs*v+IKFLOw(<kj(& zD!CIQleuJQbRB&Q%1tSYmh!jy$;k`ohT=)}Bf)ae1jO0p5$n%b3byQ2hKYKHYh2bnW0E5XVwU<4RiNnkAH@369Cnc?iZzvNmO~=2+E?DT;)Pq>KYAn4Z{>$ zEAwav1IWFIfh}Ix*(&?fwRP+VVEZ^^L!<58l?HMQC%jd+h^9%Y$skq*=UEy;@mjydVNF6atF{T`*ZuXWGFZ4&$+0UhPM!H{ zYk|CFU*)608TdDvPHJzh?&B@qLG4@PD^F<_fs;(r@|jUSqaV;;+kGO(14s^~1j12S z$38w_V5_Ld>XBZguw-c_A!Fc|aodt~O8c?e-jyH%?YJDEF27e^;|J;Y%Uldh@4 zvi+eKP39DS{7|wu02N#e&Yp%EJ3u~n%p3hj+ptFL_3+DGPi z!7MA5xePPLq#zCeA6|(H1Uo+&Q@>74dYcJYb&r_Gd~AqVj&Lal3VY=eWxfza`Ni%M z88<;~h5g2sK~-Dzdpi zQbZX1pI^c-=NS8;23%ap*4_<}S9OZG_ms8+p5cjM;%h;xZFgPDQy_|>w2(Qqf#zY^_ zq|RS!dTHK{=+)NNC9#gikFVhGE45eVm5{yYw44VA5ZP9jh0=@=*1Jq}8J|-eDiUU? z-8xNYDH&%$5<99kK7~@Q>Ax-ov8~^zCg_po0WAXNS!yvmS##%7ys3cc-yAEb%qlL| zzqEHt%XzbacJL{1_-T!z+-ln+JGz%Pk_`{g^#fg;kJ$y!=1cCx0(R7d8Kh#VWFQc0 z%cBt$O6p^P?s-mob;28T2lD)axKk6A&*Bf9CF`7F|7aRCzfPBzLvDn-K{fxFWqCO8 z8W;d$n8aEUe#vrcLX<^@PV&(DP{e1+?bsm}oc;zcZ z-u?&BQ<}q!{2!py>hrJVrgiURE+;Pd8{b%A++1FEL9c;6Lc<_O7j z6Gub2su{KI8gJ%<_7ZniAweu4XyX?EB;$G+czD{qjzJum6@ZA3;k~i#-bW^_#o(=D z0H~CqqRi*@A7<v{l z{OBE?{JTO;#Ar$>-?e-msmF5T~ArO6|4h>ds=NM@;2DnElrK zI*Q&o>C!JHiy$1-vNjSt)F1)pn;5CJw6f%}$(#L@OoDSg11{!KULh z2GyCz8Ujc5DP(@ImuvCY+ub{#*@_LMw@0*sj>Er}D8u!~`w2w0z69%1a_#3}xGD&TkGU@Xcla}cmin$epzEivTWzbDs_=C6`hf@Vci{2rY|rGb0JT}Ws*ICB zl2|TA`vdUzh+(XK*9-Kp8_8iCa9EVDCy7U)g2I07h5+3t0rbD#aXxgp?iC-e_s-McK&uO4J*}~KQ7WG3~I`o+TifQBfjO#9;DcDRhN>n`5ysOXgn^m*@i8*PDnkb5LH^;mW?f<9ojx#G zRZx`2O&I=yyS0_lP{k}!?gaq>#?>~?b9pm?hIM(J0rRW|-nI>B zkjA1@aZc_Y5@J8GP5s16I1%+jmTVpEj9kP15jw7=hoSn3eXy>*9lP7ba_l8Aa^ViA zw^Q0|DGYv6W}C43`SHPJP!Js_nDHYRshj&uU9%vuCOMybnT(OIU3<}#Ro0hLc_x&E zc!r!TXr|cL^C0(9M;HCFT5mA+tY+aCJ)7GY2Geo@E}*Olp@M#cIe6{^w8IO30Z^2f zaDg@n!6%yV*figEHcuOBSRZNFc1!CV0#?NM@7ZOGFPSM2z~2cUOF>C2y16*F+_bTs z9tkSkv}qUgyWOTjV{g3z|0zjENG8y7?2tCS!7gqr+qh9;gmgMkaG5CLIPBk^mv21M zGgar8GSF44(`Ssh%MjSsg{EncAWmAV2G?AC{z}bw59{ns%`3qPng=GbFCne#`(NiN5Vw~vlSZKv@e_E)7IvhFQV(O0ck9(4~LKRw~V4G*ckxI{ePb%q z=bgQKqbli6XB%U6eiK{GlN%=os!+0u%;&pCqP>naHLEh~TF}OCx-yMPaF%A7CxyPL z_9wT}^BT&4NOV!+Q2a>>`@YMxrjp#cX-r^=FX6y=w5Pk)WyWUr)~%vhB+)V5Z)$bf z8p=?<@$_r?P`Pish>Ye`kW0VEYA2d)^z9Za)9sD}W;GsOu3Oj8vnL_&F;p$ue%5hpTR2hw~wXIqA+xuTE;9m}U|B~%muJe>8*rb2-6P?|PE9%UD`WYl& zppGa1TMd@tlWZ_vz~=fc>EelL85fWq9q6}9R; z$mUBc=rFFiYLfPN*jGzhxk4xZKFD5|_!KgbCqGIOm8k^ew~R<%OoXF=Ww#KtL2SmP zr2hIXw2afdA}|l;QoV@-;e3Kvd>*{cH1OJLf7Q&B`D>^a@_bS8{#}(-ud)u0pKIP6 z2?%OY+wp}E%6Rz->@8-DaOoFqig(S~gh<^9mdaHZSwrQmW#Pe5zN4{G(LBSonbGOp zFvn@|)%y=(h@VbohYbiAMi2P&z>#@F%>55Dj^Y%nUekve)^#tR`lwJFGf5CosfmN& zg$`}xa$do2`KCLe#@mZx+}rosIoTLyG6`3*ku!mqL;`x_cS!V17J)?#(dONJZBj#c z0|6D?MK~Gd8*va%Dsrkf=Zc4~dKUpB>0kjW;g|=+kB)Eqd+ekT$zzg@W~yaCz)8)& zvF>v1hv}*qsOF3KX!+cC{n!m_mpmxLIIRwzPS=Ki(@x(4p=QIcfD}M^of}nG*H-UWp_L9q{M?XVp5_es&}mbEc&%f(WcC)N+a_ON zu87BXSXLPE0*n03OB&nTyX|OPP3l0&^EWQ&{?>C?WQLg3(p5O^q-eL901*zv2RjDo zTt!yaxBx4<??LZK2Z&S`&gQr@S3UD z<~}7;?&#W{U%fi2tkGpDxea-#TAVObnFB}YRGe6Ns#)YwWhIJYn zeYcRs9Jt>MRRA$rPYDq6P4BfUS(ZMrBRG^Oynq-!5^Kr*^Yj8~WS2Fud);VKujlIs zr0M)--etXXb)JgdkFJ6L9ra8Kzv&%+r~hwP{}8r>4;`4r;C7)`O&cE!`)s}y=t>>3 z{ZhV>ODQAOZ&w&LHM5&rpAC1d?G|Dr*SPdsCvjH+h60%Y*4#d;o(TVH&Hgg++Zd#`PZ8X%UzEv7fj?Mx?3C5jAW{x&yIQr+Ep4cG-3rZ zXJ-nVJ80GQQrZ*UYt5!eW>HI&0JYoQ0b;{EwW-Wn88IS;VUX@-plMtaNnqwaqbCVL z9&Q?OU*Q|^^&f5ux$q?snBJP`Wgx<)lKoaHOT0*?c9`_49B$c$ErOEHWO=#Rq0jOk z#UX>Aqr4*$fF8};aT@wo<%lllgz^~dpb7C=(QaMw-nM0O?=x!z)2yVZ*D3hP~zEVuP_<~iBdT$`@{y>9 z9Hhan+D(0AW$+Y(|211QxV5IJAT6ZKeD9O^mNMpj_2D=)S3N**w|Ag{V3b6?^2=VQupF zHwzyc>NgXWbBCRQ0@G(vf%_Uxs?|=Oow-wSb)#5yC#sqCtywds%H0NygFYWYJPF9A z8|PQQ7T+WLKp-pa6GI4})oaRY@LwC)G@N?$F)?8F@)BI8dH$+_MWq;x8Z< z>?Thax?neFL|gVs>(y>L;&Rl3eA|*D+lP9bqm7R+vwcLV*d#&nVT9~>o8J&IFF`#A z>Qm*XoIxbN+NqI=2523&iOh)xU#i_>xZi>fkkXJ3~>`uOH=0<;ZQUqMp|9 z1Rf3$f-y*^2-%x`tC;p|Xg~y5i5RPZOQnx;ZTc>b`fqLPlZ^s4!z%I~JL5qx&AH&q zDk^G^$YiGN95#oFOt5qg)9b;b!M`bkSHC#ZqtBQTb&|Y1_|Hg4Mp{+ z2GIq0MglUeNGQN%y*#Fgxfa@ml|Q*9p38P6NZ;YCvvC6R%!5nJjPyZW#jGJLfkDE` z-@cc-|HvmYDapI+$NZAjgqN*}rZ2Kj<{Z08PWpqLPT~N7( zUpob7T$JJi;Yy#JmDH6#hnYO?z=WRxOn&+?xCNA3Oh#wAnEnb;-+Nm|_QyYS#@xa-cI;saL?Bb9bfFcZuf$iX$amOBs3 z{YMbs-?avm{^lDil!)ZyR)*~S2~)dr@fxiNamJ>y zvrd~ex0IFg+V1tQ@VoOmZTn3$=#)DAUb9#mqrRBVN3R-hKmnUreNeEllrvmKJ`b+w zPdM5deJ)#kU^`OnLuM%fmco_6(Fc28CdSP7eDD>G8DR!DB0*=XeP5+6N)c*CRpPim zM1pnbXfGbxv&dckc1d+PYY8Q~8%bcIx?dr>=CU0e&w6(bppLtYT!PD}M%Yj@->>Ii z3)5z8<4>cBZR!6ZA+#SJ_8djLGXSc6rZ0EvH8XcfLdenIli8-3(%<#a$RTZ`X8$XI z2ymf{nPz^vc&x*=A!xlaCbJtILmgY%%|j`$LhBh(?99I)VJk6V7F9ajqO>~raRmp4?WLS7rdbdUoUnk>ifKPZ$z-#~K zhCkOATW?p@u+={E))>kB^u|xa)8|RWL)d)CioNq~fJ__l*!o8rAi~WX0yu%IxNJ_( zEA<+YxhxCLywW~7E`wf_T+%MjHnE?jds6RlGVc&)S~2eaZNpKXY)u=rY|b5EKnHvr zXuhF`shZ74Z4YO>;(c8A#M$)_=565S7P-&3T>#}b#|0s6@wOUI`2N})eGzv3jkSZ? zY`W1Wvp)WStq$QzV7)A#WW`Yr=fteP&WlE=21%K!4#v zwHpGNo1VOB(_U>X>qP&mklu-xix&_x$pV}QZNb`l9IUjT-&Yr*6~Jv4x`40!fw>5>iiR)^7ES*A%-ZggdU{jS+{Ztzv#6*k$@ z>Fur=hxX**^e@c0QgW|A{HNVldgb4T;sG#Zh8e`K^PAxLEu#N5XYC&TkDa<;_=l=i zlRg?MQ~CgU@tf|u^E&`}uf9IGp@p{ty*mHf&|m4pAgs~#ts$i_P`89! z;Yf-S-T9-6X4b5j|De+yhn2!shod!2(iG&soZE~h0= zkDi$R7oyBGT*HrdnnjvKDs5*}xolskqSEU~CY^d&mGO$VacdAh2v^}c0x0oN>pHj>#EL@d$5yUc(bm z5nJnV>8^w38H3&Kcg^t=r6_0l4wbVi>JZez61dmhKdmM}gq> zLtXB$rC#>%>v1|_+Z!B5FU!K(C;S&DLReY7Ih1i%w-r-%!;-Ubdgyp_|{=-)*svm(8{E|$N>?|eIvq{cp^ zufEiIHFc?84Pn{f{^4}?0{%Yl%$4yBJ{|q`&TPA`s^|o%7$r>K(rEl$S{`SLID2|9 zBeU3NUg9Z7hGP=hgtHII$!ZQWWP-919TM6v_}YKGX~*$)rc^>LmnUhsZ7PR>ksW$7 zsUeDe^wITPNDeCw{kG1nzC7w~keOFHBA?sx?3!r!?DX^8-NY*_Zmf!CP<|-!4y9;t ze%$bhMAslJ$LYnWyxsd!KpLRQJwSG$FIht9!*71vxxBq#mRxFLKL*gW z{qq}(zp=BSVL`cdLK~%&Ht_6Jw4KhV9H@n_ci6q8j+IHPF%LuG=h2p(&5`Vr>^)6Z zOMf37eeobecEx>3;=m)L2ICGO*!6x-TG+q?vc zcE8^hi_r?KQ5j)O3WO@VCQl72FVFJz%no=2rG^Day$FaB+?D7M*ExAv@ZRlRz$nmWuvn4Nw3_ zVu9C)rE*f$c5cdb2Wdr(9JT~0a3ZH)W1ZzpFtKla)o z396@B?E2}JX|TNR&Zmkf+_!s}aWmdqw6o0^sr;!C&Gq?FG)jp;Z(~)BzQ`{i3VlYY0UJ+po9SP9` z+j1I50kw-XD#`K@J#ku(S-0newM{s@N$k0Tl(Drdo#R|?)^Vq^;uUI1hB>y?yT{#P z*Dc%+7)l~?Xv4x7dJ{rxJKu2Fu@q>Rm6QJ|RRcyX>-H%qc}Ui;rE9%Dr885u{FGR= zoeb?Twz4irYfo&_7C=O_8a1Q_rGT|z_ygS|j~qqXu06HIpH6P%ch{9$hhhVxmVU~Y zu6_z@Z;rHdDciY2|y@u4)GX)sn+!fIqyW>b`deN0zU~}b?XCqK);O!UY(rc_ z;F7UMuLpC+-Po`TzV07ABI94qM&7W_e`Hk&ZnN>l#*|0glfi7?Za(Gi3+g$&Bv=vi z{;(rXw)AI?gV@6B8&7ob)_nwl~$t>YRd6sKiiTb>l|Gv%3)Ti1eUA4 zT_3czf6^ER%6WZ8cygxcjI8AVO}co;!{2QjIU4$MA zMLG6Smfb|-0IthgAlwdaO~^MZX=+f*jPW7L&9c)ixu*6-C&|ow2zvdpxGN7Z53U?3 z88yhx+No7HK6w#{)iDULr)xmYY782=I`4@ z82WdvaF4&ET?kB&vZdA&`%Fkva*BO_tb54btzk2r#yZbE0mzexE;TB~qfeXi_AU;H!ZRX^_GAcZh5N~R$Z2*e#O8WJX zZc3FTp-ICWx9o{DdovG8RabuB2#mU{Aj^4S90wS;jWkX8+rE0XAGG~53OL>$c=LnM zj-n!@N}^oJC(R!dsrzIwSaaWmI|+ErB`(y5l-^7ZDYcgL!s7V~EW zzvg>^84YV5XKq8(>8!S(8kXKoH*m8W|OTvo6+G&!m%GZ}^72C7(?)P&K->Rf{=Lk!Vk+G^y}_KRwf=L%H_3Qlf*T|nAP zIPC&Fzq&g+&kX~VW|(+XZYk#~bMPY4SdWPRaK z$f-icELB`Awa7{^TpW$Ztwe5HQ^Oie#ecMSUdtNoXbKYatm&rn$BX`ru)No4>b|%~ zZ)qX{j0lcy#1)q9=KF>Lp&rL$XCReZUG{5B!xy(l9vb>+k_0rEh%Dp{T_$fG?@WVY zvXNPhncgg0pqU%1@n`5GDB%uea*grE>cdFlN3zpL+R^rJ&Wk>62B`0%PtmBlevNM6P;m7SHSe95+eB~W zH%XEMDx_%@b<3_xH!Me(MCqOwQ_l{+%-79np~FC;FsAln-5+j*DbNHvD7N zm5xGzyUU#TqteYUs)oy0HK0A^|DWNe0)32G1r>!a+b_Y_z=ZsrKF944>+CT88&fr5 zn@<3+GrHy}o_-e0{iiR04FBsRD*$Ez>r;gTk^o3wyy)z>J9Pj+aQvL6WJIp%&)o}o zyn5l+%ZGY%?bzjn9SveXC;yA3;MRWW-B@H^Vx=xsxYq{}41@lCx|b}P=YfOGs_ao^ z%QsfThfO1~%M;^SB_TM%9Y<-&k}n~5&wcXW5bvSChZ&IGgqmL0!h49LXwM7%mXRqi z-@*e--`{CSBwc;wemU#^U_JL+TCPd|I{*3DMqT39IQ@`-N&Y*%=~8;6ht!Au=358S zVLXUJ9ABYYasH7P3Z7g1QYP+J5a8JZHYEmjg8t|Es^biKXtD<$QwOORJ7la)^Zi^~ z(}6%BW#fPU$?y%)Whr=cd@K&jyO&q6S?zH`zDObk1L^W*J#+;}8DJg(=?!;Ot2tMD zA3q4ReX!$sU7V{ZiyH(gHM1-+SSK47jl64WnxDU0Hg4koZ^3UG#e%-iEi5q35dnA$ z#3;-#Rb*$foZPyzd`lhxcy*8t7(&M3$a}rv7Hrwfn z=qm5}Q}YXlXqN~|F{xMJM;uFDo}(TgqE()?=9IUf(pYsKSeu>~IY(^YQ;->WlGN!* zhq6q!*2=F#M1JRLJ4{$8*qqw-hZaI2gOe z19A;l7DzvDues|BekbWVE}i&_>PX`nwag~|;~J+vrewDhG+aEi_B2fSzu)TdU}KLe zbX*sVmJlomSP{84dU)^qAF6Ty_kodGAgyX*pRH%@HvQRD?|Yo?>33-qN;ACn@LtT9 z^J-OZ=Siw|+V&=BCxC5vCygx-xpG{*-T#f;nNXN8b3D54oa8#8OnKsz}_`k8yxy}Wzz&IQaXq0R! zTy1%-*Bg{4R$j^ZH{KuSb;OQ_Q6&K34@_c4(A_q0pit` zaU4ob^VNXI>5}#;|5U^IwECv|0>+0}yMZ`N7<&PkcM3_srExJmKY!>ltPOvRm>dPq ciZ`6WSrkODOu3rMzk63%UR|#E#mjg97h}R}CIA2c literal 0 HcmV?d00001 diff --git a/docs/apps/activity.rst b/docs/apps/activity.rst new file mode 100644 index 00000000..52f51cbb --- /dev/null +++ b/docs/apps/activity.rst @@ -0,0 +1,110 @@ +Application Activités +===================== + +L'application activités gère les différentes activités liées au BDE. Elle permet entre autres de créer des activités qui +peuvent être diffusées via des calendriers ou la mailing list d'événements. Elle permet aussi de réguler l'accès aux +événements, en s'assurant que leur note est positive. Elle permet enfin de gérer les invités. + +Modèles +------- + +L'application comporte 5 modèles : activités, types d'activité, invités, entrées et transactions d'invitation. + +Types d'activité +~~~~~~~~~~~~~~~~ + +Les activités sont triées par type (pots, soirées de club, ...), et chaque type regroupe diverses informations : + +* Nom du type +* Possibilité d'inviter des non-adhérents (booléen) +* Prix d'invitation (entier, centimes à débiter sur la note de l'hôte) + +Activités +~~~~~~~~~ + +Le modèle d'activité regroupe les informations liées à l'activité même : + +* Nom de l'activité +* Description de l'activité +* Créateur, personne qui a proposé l'activité +* Club ayant organisé l'activité +* Note sur laquelle verser les crédits d'invitation (peut être nul si non concerné) +* Club invité (généralement le club Kfet) +* Date et heure de début +* Date et heure de fin +* Activité valide (booléen) +* Activité ouverte (booléen) + +Entrées +~~~~~~~ + +Une instance de ce modèle est créé dès que quelqu'un est inscrit à l'activité. Sont stockées les informations suivantes : + +* Activité concernée (clé étrangère) +* Heure d'entrée +* Note de la personne entrée, ou hôte s'il s'agit d'un invité (clé étrangère vers ``NoteUser``) +* Invité (``OneToOneField`` vers ``Guest``, ``None`` si c'est la personne elle-même qui rentre et non son invité) + +Il n'est pas possible de créer une entrée si la note est en négatif. + +Invités +~~~~~~~ + +Les adhérents ont la possibilité d'inviter des amis. Pour cela, les différentes informations sont enregistrées : + +* Activité concernée (clé étrangère) +* Nom de famille +* Prénom +* Note de la personne ayant invité + +Certaines contraintes s'appliquent : + +* Une personne ne peut pas être invitée plus de 5 fois par an (coupe nom/prénom) +* Un adhérent ne peut pas inviter plus de 3 personnes par activité. + +Transactions d'invitation +~~~~~~~~~~~~~~~~~~~~~~~~~ + +On étend le modèle ``Transaction`` de l'application note afin de supporter les transactions d'invitation. Elles ne +comportent qu'un champ supplémentaire, de type ``OneToOneField`` vers ``Guest``. + +Ce modèle aurait pu appartenir à l'application ``note``, mais afin de rester modulaire et que l'application ``note`` +ne dépende pas de cette application, on procède de cette manière. + +Graphe +~~~~~~ + +.. image:: /_static/img/graphs/activity.svg + :alt: Graphe de l'application activités + +UI +-- + +Création d'activités +~~~~~~~~~~~~~~~~~~~~ + +N'importe quel adhérent Kfet peut suggérer l'ajout d'une activité via un formulaire. + +Gestion des activités +~~~~~~~~~~~~~~~~~~~~~ + +Les ayant-droit (Res[pot] et respos infos) peuvent valider les activités proposées. Ils peuvent également la modifier +si besoin. Ils peuvent enfin la déclarer ouvertes pour lancer l'accès aux entrées. + +N'importe qui peut inviter des amis non adhérents, tant que les contraintes de nombre (un adhérent n'invite pas plus de +trois personnes par activité et une personne ne peut pas être invitée plus de 5 fois par an). L'invitation est +facturée à l'entrée. + +Entrées aux soirées +~~~~~~~~~~~~~~~~~~~ + +L'interface d'entrées est simple et ergonomique. Elle contient un champ de texte. À chaque fois que le champ est +modifié, un tableau est affiché comprenant la liste des invités et des adhérents dont le prénom, le nom ou un alias +de la note est acceptée par le texte entré. + +En cliquant sur la ligne de la personne qui souhaite rentrée, s'il s'agit d'un adhérent, alors la personne est comptée +comme entrée à l'activité, sous réserve que sa note soit positive. S'il s'agit d'un invité, alors 3 boutons +apparaîssent, afin de régler la taxe d'invitation : l'un prélève directement depuis la note de l'hôte, les deux autres +permettent un paiement par espèces ou par carte bancaire. En réalité, les deux derniers boutons enregistrent +automatiquement un crédit sur la note de l'hôte, puis une transaction (de type ``GuestTransaction``) est faite depuis +la note de l'hôte vers la note de l'organisateur de l'événement. diff --git a/docs/apps/api.rst b/docs/apps/api.rst new file mode 100644 index 00000000..56d6b5df --- /dev/null +++ b/docs/apps/api.rst @@ -0,0 +1,170 @@ +API +=== + +La NoteKfet2020 dispose d'une API REST. Elle est accessible sur `/api/ `_. +Elle supporte les requêtes GET, POST, HEAD, PUT, PATCH et DELETE (peut varier selon les pages). + +Pages de l'API +-------------- + +Il suffit d'ajouter le préfixe ``/api/`` pour arriver sur ces pages. + +* ``models`` (liste des différents modèles enregistrés en base de données) +* ``user`` (liste des différents utilisateurs enregistrés) +* ``members/profile`` (liste des différents profils associés à des utilisateurs) +* ``members/club`` (liste des différents clubs enregistrés) +* ``members/role`` (liste des différents rôles au sein des clubs existant) +* ``members/membership`` (liste des adhésions enregistrées) +* ``activity/activity`` (liste des activités recensées) +* ``activity/type`` (liste des différents types d'activités : pots, soirées de club, ...) +* ``activity/guest`` (liste des personnes invitées lors d'une activité) +* ``activity/entry`` (liste des entrées effectuées lors des activités) +* ``note/note`` (liste des notes enregistrées) +* ``note/alias`` (liste des alias enregistrés) +* ``note/transaction/category`` (liste des différentes catégories de boutons : soft, alcool, ...) +* ``note/transaction/transaction`` (liste des transactions effectuées) +* ``note/transaction/template`` (liste des boutons enregistrés) +* ``treasury/invoice`` (liste des factures générées) +* ``treasury/product`` (liste des produits associés à des factures) +* ``treasury/remittance_type`` (liste des types de remises supportés : chèque) +* ``treasury/remittance`` (liste des différentes remises enregistrées) +* ``permission/permission`` (liste de toutes les permissions enregistrées) +* ``permission/roles`` (liste des permissions octroyées pour chacun des rôles) +* ``logs`` (liste des modifications enregistrées en base de données) + +Utilisation de l'API +-------------------- + +La page ``/api//`` affiche la liste de tous les éléments enregistrés. La page ``/api///`` affiche +les attributs d'un objet uniquement. + +L'affichage des données peut se faire sous deux formes : via une interface HTML propre ou directement en affichant +le JSON brut. Le changement peut se faire en ajoutant en paramètre de l'URL ``format=json`` ou ``format=api`, ou bien +en plaçant en en-tête de la requête ``Accept: application/json`` ou ``text/html``. + +L'API Web propose des formulaires facilitant l'ajout et la modification d'éléments. + +GET +~~~ + +Une requête GET affiche un ou des éléments. Si on veut la liste de tous les éléments d'un modèle, la réponse +est de cette forme : + +.. code:: json + + { + "count": "", + "next": "/api//?page=", + "previous": "/api//?page=", + "results": [ ] + } + +Où ```` est le nombre d'éléments trouvés. La page n'affiche les informations que 20 par 20 pour ne pas +augmenter inutilement la taille de la réponse. Les champs ``next`` et ``previous`` contiennent les URL des pages +suivantes et précédentes (``null`` si première ou dernière page). Le champ ``results`` contient enfin l'ensemble des +objets trouvés, au format JSON. + +Certaines pages disposent de filtres, permettant de sélectionner les objets recherchés. Par exemple, il est possible +de chercher une note d'un certain type matchant avec un certain alias. + +Le résultat est déjà par défaut filtré : seuls les éléments que l'utilisateur à le droit de voir sont affichés. +Cela est possible grâce à la structure des permissions, générant justement des filtres de requêtes de base de données. + +Une requête à l'adresse ``/api//pk/`` affiche directement les informations du modèle demandé au format JSON. + +POST +~~~~ + +Une requête POST permet d'ajouter des éléments. Cette requête n'est possible que sur la page ``/api//``, +la requête POST n'est pas supportée sur les pages de détails (car cette requête permet ... l'ajout). + +Des exceptions sont faites sur certaines pages : les pages de logs et de contenttypes sont en lecture uniquement. + +Les formats supportés sont multiples : ``application/json``, ``application/x-www-url-encoded``, ``multipart/form-data``. +Cela facilite l'envoi de requêtes. Le module construit ensuite l'instance du modèle et le sauvegarde dans la base de +données. L'application ``permission`` s'assure que l'utilisateur à le droit de faire ce type de modification. La réponse +renvoyée est l'objet enregistré au format JSON si l'ajout s'est bien déroulé, sinon un message d'erreur au format JSON. + +PATCH +~~~~~ + +Une requête PATCH permet de modifier un élément. Ce type de requête n'est disponible que sur la page de détails d'un +élément : ``/api//pk/``. + +Comme pour la requête POST, les formats supportés sont multiples : ``application/json``, +``application/x-www-url-encoded``, ``multipart/form-data``. + +Il n'est pas utile d'indiquer tous les champs du modèle : seuls ceux qui sont à modifier suffisent. + +Attention : pour les modèles polymorphiques (``Note``, ``Transaction``), il faut toujours spécifier le type de modèle +pour que l'API arrive à s'y retrouver. Par exemple, si on veut rendre la transaction n°42 non valide, on effectue une +requête ``PATCH`` sur ``/api/note/transaction/transaction/42/`` avec les données suivantes : + +.. code:: json + + { + "valid": false, + "resourcetype": "RecurrentTransaction" + } + +PUT +~~~ + +Une requête PUT permet de remplacer un élément. Ce type de requête n'est disponible que sur la page de détails d'un +élément : ``/api//pk/``. + +Comme pour les requêtes POST ou PATCH, les formats supportés sont multiples : ``application/json``, +``application/x-www-url-encoded``, ``multipart/form-data``. + +Contrairement à la requête PATCH, l'intégralité du modèle est remplacé. L'ancien modèle est détruit, on en recrée un +nouveau avec la même clé primaire. Le fonctionnement est similaire à une requête POST. + +DELETE +~~~~~~ + +Une requête de type DELETE permet de supprimer un élément. Ce type de requête n'est disponible que sur la page de +détails d'un élément : ``/api//pk/``. + +Aucune donnée n'est nécessaire. Le module de permissions vérifiera que la suppression est possible. Une erreur +est sinon renvoyée. + +OPTIONS +~~~~~~~ + +Une reqête OPTIONS affiche l'ensemble des opérations possibles sur un modèle ou une instance. Prototype d'une réponse : + +.. code:: json + + { + "name": "", + "description": "", + "renders": [ + "application/json", + "text/html" + ], + "parses": [ + "application/json", + "application/x-www-form-urlencoded", + "multipart/form-data" + ], + "actions": { + "": { + "": { + "type": "", + "required": "", + "read_only": "", + "label": "