Compare commits
156 Commits
feature/ea
...
fix/licens
Author | SHA1 | Date | |
---|---|---|---|
6169d09ac0 | |||
f876bc3599 | |||
147b3619f5 | |||
d97602e60b | |||
a5cbac1f97 | |||
3143d3d91a | |||
9bdf3fc4ac | |||
e06bc7dba3 | |||
a8b9f38000 | |||
ca27b89a8b | |||
e1bf7caa9a | |||
e681c17a0f | |||
5416d88c97 | |||
ee437649f0 | |||
4303d51c0a | |||
d16bf12611 | |||
4231a7972d | |||
c436d39014 | |||
51a12814f9 | |||
00ae6e4623 | |||
4b587e8711 | |||
d2f377b54f | |||
193c820757 | |||
b9298792ae | |||
aaf30ab965 | |||
2db66e6154 | |||
38295e591d | |||
544b0248b2 | |||
2bccf633d5 | |||
4f9d5ae7b1 | |||
259337dff1 | |||
84768eb74e | |||
8852ef990e | |||
87295ad9b7 | |||
288764b551 | |||
5ab5ef681c | |||
c9e70889dd | |||
b30ee0a27a | |||
ef968f3673 | |||
96dede5077 | |||
66fcb76cb5 | |||
63c8e51137 | |||
12bec5c553 | |||
08460a6964 | |||
b5a40cfda9 | |||
c78953b036 | |||
427f7ceaff | |||
1055385bcc | |||
c1022642a2 | |||
910a6f8b34 | |||
06253f029c | |||
fa6527b24f | |||
0501e6417a | |||
a198f5252d | |||
d83842af27 | |||
f605f7dcc6 | |||
e638bc04ed | |||
4830c3ea2d | |||
8e7c025e47 | |||
1bfe929ab3 | |||
93cc2c883e | |||
44290a20a6 | |||
1f10a284f2 | |||
28f397574f | |||
6c1fa6de0b | |||
f0a08afd31 | |||
982fc09908 | |||
9e0b5b0b82 | |||
b12e8dc147 | |||
25c5a3297c | |||
dd3ad42eb5 | |||
5ea181829e | |||
0cf203669f | |||
559bfcac60 | |||
db8a1ed0ab | |||
16150905a0 | |||
9a376887ac | |||
773808fa59 | |||
c1e59a0676 | |||
05febc60bd | |||
a73fe598ef | |||
b7f20fed6c | |||
585923c827 | |||
394e17d599 | |||
59136850b8 | |||
d726f4b1e8 | |||
705b9b1e6a | |||
31e8ad8a3e | |||
99827e005b | |||
751c8a8bc6 | |||
73305c0b28 | |||
37216cd16b | |||
dae68638cf | |||
7cadc0bc28 | |||
cce686f3a8 | |||
4fe46fbcef | |||
fe8b8f46aa | |||
310f1a2283 | |||
7079761ffe | |||
f681c981c6 | |||
5d97146d14 | |||
7b56bd697d | |||
14cd268d69 | |||
754be1c9c9 | |||
da2c155254 | |||
ceb2888f82 | |||
ce3e2bb32b | |||
26c94c9ec6 | |||
7b6eed9a47 | |||
639197f4c8 | |||
13bae8d2fa | |||
6b2027550c | |||
022b365bb2 | |||
d8867fc9ea | |||
118c58b5fa | |||
faccc1367f | |||
22b83b0814 | |||
1d82e2a7d9 | |||
823bd578f2 | |||
3e5c36b39e | |||
8fb0897160 | |||
b8a72c57e1 | |||
6a0a8e8ab4 | |||
9188565a86 | |||
4d7d22c337 | |||
b58116b023 | |||
fe9e5ce861 | |||
e43d53e564 | |||
d4a5039efc | |||
35506e0175 | |||
1c27831f92 | |||
cdbf07a835 | |||
b92580943a | |||
60eff1000f | |||
96510b270d | |||
1281104d96 | |||
3c1724fa81 | |||
1630af4fbd | |||
e76e2b1537 | |||
6c276dc596 | |||
d3c115e3f9 | |||
c245ef7149 | |||
8b09ba2924 | |||
52eb310f95 | |||
5bff38fc7b | |||
2813a59323 | |||
eef33fa263 | |||
241d3cea53 | |||
89d6db4208 | |||
e0ad288cf4 | |||
f4d7fae8ca | |||
95a7493fc1 | |||
8243dbcbef | |||
c3a4071627 | |||
cef3f22e0d | |||
c206b965ad |
8
.github/actions/compile_messages/action.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
name: "Compile messages"
|
||||||
|
description: "Compile the gettext translation messages"
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Setup project
|
||||||
|
run: poetry run ./manage.py compilemessages
|
||||||
|
shell: bash
|
57
.github/actions/setup_project/action.yml
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
name: "Setup project"
|
||||||
|
description: "Setup Python and Poetry"
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Install apt packages
|
||||||
|
uses: awalsh128/cache-apt-pkgs-action@latest
|
||||||
|
with:
|
||||||
|
packages: gettext libgraphviz-dev
|
||||||
|
version: 1.0 # increment to reset cache
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install gettext libgraphviz-dev
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Set up python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: "3.10"
|
||||||
|
|
||||||
|
- name: Load cached Poetry installation
|
||||||
|
id: cached-poetry
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ~/.local
|
||||||
|
key: poetry-0 # increment to reset cache
|
||||||
|
|
||||||
|
- name: Install Poetry
|
||||||
|
if: steps.cached-poetry.outputs.cache-hit != 'true'
|
||||||
|
shell: bash
|
||||||
|
run: curl -sSL https://install.python-poetry.org | python3 -
|
||||||
|
|
||||||
|
- name: Check pyproject.toml syntax
|
||||||
|
shell: bash
|
||||||
|
run: poetry check
|
||||||
|
|
||||||
|
- name: Load cached dependencies
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ~/.cache/pypoetry
|
||||||
|
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-poetry-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: poetry install --with docs,tests
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Install xapian
|
||||||
|
run: poetry run ./manage.py install_xapian
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Compile gettext messages
|
||||||
|
run: poetry run ./manage.py compilemessages
|
||||||
|
shell: bash
|
10
.github/actions/setup_xapian/action.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
name: "Setup xapian"
|
||||||
|
description: "Setup the xapian indexes"
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Setup xapian index
|
||||||
|
run: |
|
||||||
|
mkdir -p /dev/shm/search_indexes
|
||||||
|
ln -s /dev/shm/search_indexes sith/search_indexes
|
||||||
|
shell: bash
|
18
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "pip" # See documentation for possible values
|
||||||
|
directory: "/" # Location of package manifests
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
# Raise pull requests for version updates
|
||||||
|
# to pip against the `develop` branch
|
||||||
|
target-branch: "taiste"
|
||||||
|
reviewers:
|
||||||
|
- "ae-utbm/developpers-v3"
|
||||||
|
commit-message:
|
||||||
|
prefix: "[UPDATE] "
|
42
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
name: Sith 3 CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master, taiste]
|
||||||
|
pull_request:
|
||||||
|
branches: [master, taiste]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ruff:
|
||||||
|
name: Ruff lint & format
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: ruff format
|
||||||
|
uses: chartboost/ruff-action@v1 # format
|
||||||
|
with:
|
||||||
|
args: format --diff
|
||||||
|
- name: ruff check
|
||||||
|
uses: chartboost/ruff-action@v1 # lint
|
||||||
|
|
||||||
|
tests:
|
||||||
|
name: Run tests and generate coverage report
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- uses: ./.github/actions/setup_project
|
||||||
|
- uses: ./.github/actions/setup_xapian
|
||||||
|
- uses: ./.github/actions/compile_messages
|
||||||
|
- name: Run tests
|
||||||
|
run: poetry run coverage run -m pytest
|
||||||
|
- name: Generate coverage report
|
||||||
|
run: |
|
||||||
|
poetry run coverage report
|
||||||
|
poetry run coverage html
|
||||||
|
- name: Archive code coverage results
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: coverage-report
|
||||||
|
path: coverage_report
|
4
.github/workflows/deploy.yml
vendored
@ -33,11 +33,11 @@ jobs:
|
|||||||
|
|
||||||
# See https://github.com/ae-utbm/sith3/wiki/GitHub-Actions#deployment-action
|
# See https://github.com/ae-utbm/sith3/wiki/GitHub-Actions#deployment-action
|
||||||
script: |
|
script: |
|
||||||
export PATH="$HOME/.poetry/bin:$PATH"
|
export PATH="/home/sith/.local/bin:$PATH"
|
||||||
pushd ${{secrets.SITH_PATH}}
|
pushd ${{secrets.SITH_PATH}}
|
||||||
|
|
||||||
git pull
|
git pull
|
||||||
poetry update
|
poetry install
|
||||||
poetry run ./manage.py migrate
|
poetry run ./manage.py migrate
|
||||||
echo "yes" | poetry run ./manage.py collectstatic
|
echo "yes" | poetry run ./manage.py collectstatic
|
||||||
poetry run ./manage.py compilestatic
|
poetry run ./manage.py compilestatic
|
||||||
|
63
.github/workflows/taiste.yml
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
name: Sith3 taiste
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [taiste]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deployment:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: taiste
|
||||||
|
timeout-minutes: 30
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: SSH Remote Commands
|
||||||
|
uses: appleboy/ssh-action@dce9d565de8d876c11d93fa4fe677c0285a66d78
|
||||||
|
with:
|
||||||
|
# Proxy
|
||||||
|
proxy_host : ${{secrets.PROXY_HOST}}
|
||||||
|
proxy_port : ${{secrets.PROXY_PORT}}
|
||||||
|
proxy_username : ${{secrets.PROXY_USER}}
|
||||||
|
proxy_passphrase: ${{secrets.PROXY_PASSPHRASE}}
|
||||||
|
proxy_key: ${{secrets.PROXY_KEY}}
|
||||||
|
|
||||||
|
# Serveur web
|
||||||
|
host: ${{secrets.HOST}}
|
||||||
|
port : ${{secrets.PORT}}
|
||||||
|
username : ${{secrets.USER}}
|
||||||
|
key: ${{secrets.KEY}}
|
||||||
|
|
||||||
|
script_stop: true
|
||||||
|
|
||||||
|
# See https://github.com/ae-utbm/sith3/wiki/GitHub-Actions#deployment-action
|
||||||
|
script: |
|
||||||
|
export PATH="$HOME/.poetry/bin:$PATH"
|
||||||
|
pushd ${{secrets.SITH_PATH}}
|
||||||
|
|
||||||
|
git pull
|
||||||
|
poetry install
|
||||||
|
poetry run ./manage.py migrate
|
||||||
|
echo "yes" | poetry run ./manage.py collectstatic
|
||||||
|
poetry run ./manage.py compilestatic
|
||||||
|
poetry run ./manage.py compilemessages
|
||||||
|
|
||||||
|
sudo systemctl restart uwsgi
|
||||||
|
|
||||||
|
sentry:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: taiste
|
||||||
|
timeout-minutes: 30
|
||||||
|
needs: deployment
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Sentry Release
|
||||||
|
uses: getsentry/action-release@v1.2.0
|
||||||
|
env:
|
||||||
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
|
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
|
||||||
|
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
||||||
|
SENTRY_URL: ${{ secrets.SENTRY_URL }}
|
||||||
|
with:
|
||||||
|
environment: taiste
|
83
.github/workflows/unittests.yml
vendored
@ -1,83 +0,0 @@
|
|||||||
name: Sith3 CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
unittests:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 30
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
# Skip unit testing if no diff on .py files
|
|
||||||
- name: Check file diff
|
|
||||||
uses: technote-space/get-diff-action@v6
|
|
||||||
id: git-diff
|
|
||||||
with:
|
|
||||||
PATTERNS: |
|
|
||||||
**/*.py
|
|
||||||
|
|
||||||
- name: Set up python
|
|
||||||
if: steps.git-diff.outputs.diff
|
|
||||||
uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: '3.8'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
if: steps.git-diff.outputs.diff
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install gettext libxapian-dev libgraphviz-dev
|
|
||||||
|
|
||||||
- name: Install poetry
|
|
||||||
if: steps.git-diff.outputs.diff
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
python -m pip install poetry
|
|
||||||
|
|
||||||
- name: Checking pyproject.toml syntax
|
|
||||||
if: steps.git-diff.outputs.diff
|
|
||||||
run: poetry check
|
|
||||||
|
|
||||||
- name: Install project
|
|
||||||
if: steps.git-diff.outputs.diff
|
|
||||||
run: poetry install -E testing
|
|
||||||
|
|
||||||
- name: Setup xapian index
|
|
||||||
if: steps.git-diff.outputs.diff
|
|
||||||
run: |
|
|
||||||
mkdir -p /dev/shm/search_indexes
|
|
||||||
ln -s /dev/shm/search_indexes sith/search_indexes
|
|
||||||
|
|
||||||
- name: Setup project
|
|
||||||
if: steps.git-diff.outputs.diff
|
|
||||||
run: poetry run ./manage.py compilemessages
|
|
||||||
|
|
||||||
- name: Launch tests and generate coverage report
|
|
||||||
if: steps.git-diff.outputs.diff
|
|
||||||
run: |
|
|
||||||
poetry run coverage run ./manage.py test
|
|
||||||
poetry run coverage report
|
|
||||||
|
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Set up python
|
|
||||||
uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: '3.8'
|
|
||||||
|
|
||||||
- name: Install black
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
python -m pip install black==22.6.0
|
|
||||||
|
|
||||||
- name: Check linting
|
|
||||||
run: black --check .
|
|
2
.gitignore
vendored
@ -7,9 +7,11 @@ db.sqlite3
|
|||||||
pyrightconfig.json
|
pyrightconfig.json
|
||||||
dist/
|
dist/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
.idea/
|
||||||
env/
|
env/
|
||||||
doc/html
|
doc/html
|
||||||
data/
|
data/
|
||||||
|
galaxy/test_galaxy_state.json
|
||||||
/static/
|
/static/
|
||||||
sith/settings_custom.py
|
sith/settings_custom.py
|
||||||
sith/search_indexes/
|
sith/search_indexes/
|
||||||
|
3
.mailmap
@ -15,4 +15,5 @@ Vial <robin.trioux@utbm.fr>
|
|||||||
Zar <antoine.charmeau@utbm.fr> <antoine.charmeau@laposte.net>
|
Zar <antoine.charmeau@utbm.fr> <antoine.charmeau@laposte.net>
|
||||||
root <root@localhost.localdomain>
|
root <root@localhost.localdomain>
|
||||||
tleb <tleb@openmailbox.org> <theo.lebrun@live.fr>
|
tleb <tleb@openmailbox.org> <theo.lebrun@live.fr>
|
||||||
tleb <tleb@openmailbox.org> <theo.lebrun@utbm.fr>
|
tleb <tleb@openmailbox.org> <theo.lebrun@utbm.fr>
|
||||||
|
Maréchal <thgirod@hotmail.com>
|
@ -18,7 +18,7 @@ formats: all
|
|||||||
|
|
||||||
# Optionally set the version of Python and requirements required to build your docs
|
# Optionally set the version of Python and requirements required to build your docs
|
||||||
python:
|
python:
|
||||||
version: 3.8
|
version: "3.8"
|
||||||
install:
|
install:
|
||||||
- method: pip
|
- method: pip
|
||||||
path: .
|
path: .
|
||||||
|
31
CONTRIBUTORS.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Contributors
|
||||||
|
|
||||||
|
Thanks to everyone who has contributed to this project! We appreciate your time and effort.
|
||||||
|
|
||||||
|
## Copyright
|
||||||
|
|
||||||
|
> All contributions to this project are subject to the copyright owned by the Association des Étudiants de l'Université de Technologie de Belfort-Montbéliard (AE UTBM), for both past and future years. By making a contribution to this project, you acknowledge and agree that AE UTBM has the exclusive right to use, distribute, and modify your contribution, as well as to license others to do the same, in any way they see fit.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project was previously released under the MIT license, but it has since been changed to the GPL v3 license. Any contributions made to this project before the switch to GPL v3 are still subject to the MIT license, while contributions made after the switch are subject to the GPL v3 license.
|
||||||
|
|
||||||
|
## List of Contributors
|
||||||
|
|
||||||
|
- [@Hyask](https://github.com/Hyask) — Florent "Skia" Jacquet <skia@hya.sk>
|
||||||
|
- [@klmp200](https://github.com/klmp200) — Antoine "Sli" Bartuccio <antoine@bartuccio.fr>
|
||||||
|
- [@nab-os](https://github.com/nab-os) (AKA Gnikwo) — Sasha "Nabos" Ballet <nabos@glargh.fr>
|
||||||
|
- [@Krophil](https://github.com/Krophil) — Pierre "Krophil'" Brunet <pierre.brunet@krophil.fr>
|
||||||
|
- [@guillaume-renaud](https://github.com/guillaume-renaud) — Guillaume "Lo-J" RENAUD <renaudg779@gmail.com>
|
||||||
|
- [@imperosol](https://github.com/imperosol) — Thomas "Maréchal" Girod <thgirod@hotmail.com>
|
||||||
|
- [@TheoDurr](https://github.com/TheoDurr) — Théo "Ailé" Durr <git@theodurr.fr>
|
||||||
|
- [@RTrioux](https://github.com/RTrioux) — Robin "Vial" Trioux
|
||||||
|
- [@TheRolfFR](https://github.com/TheRolfFR) — Yann "Réseau" Le Vaguerès
|
||||||
|
- [@Magador](https://github.com/Magador) — Lucie "Magador" Lenglet
|
||||||
|
- [@lsacienne](https://github.com/lsacienne) — Alexandre "L'Sacienne" Viala
|
||||||
|
- [@Juknum](https://github.com/Juknum) — Julien "Tinople" Constant
|
||||||
|
- [@Tartofraise](https://github.com/Tartofraise) — Ryan "Soldat" Hadj-Mebarek
|
||||||
|
- [@FrancescoWitz](https://github.com/FrancescoWitz) — Francesco "Och" WITZ
|
||||||
|
- [@maxence-leblanc](https://github.com/maxence-leblanc) — Maxence "Juste" LEBLANC
|
||||||
|
|
||||||
|
_If you've contributed to this project and your name isn't on the list, please let us know so we can add you. And if you've contributed anonymously, thank you! We appreciate your contributions just as much as those from named contributors._
|
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
@ -9,7 +9,7 @@
|
|||||||
<img src="https://img.shields.io/readthedocs/sith-ae?logo=readthedocs&style=for-the-badge">
|
<img src="https://img.shields.io/readthedocs/sith-ae?logo=readthedocs&style=for-the-badge">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/XK9WfPsUFm">
|
<a href="https://discord.gg/XK9WfPsUFm">
|
||||||
<img src="https://img.shields.io/discord/889796155523874847?label=Discord&logo=discord&style=for-the-badge">
|
<img src="https://img.shields.io/discord/971448179075731476?label=Discord&logo=discord&style=for-the-badge">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -37,5 +37,4 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
> This project is licenced under GNU GPL, see the LICENSE file at the top of the repository for more details.
|
> This project is licensed under GNU GPL, see the LICENSE file at the top of the repository for more details.
|
||||||
|
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
@ -1,32 +1,27 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from accounting.models import *
|
from accounting.models import *
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(BankAccount)
|
admin.site.register(BankAccount)
|
||||||
admin.site.register(ClubAccount)
|
admin.site.register(ClubAccount)
|
||||||
admin.site.register(GeneralJournal)
|
admin.site.register(GeneralJournal)
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.core.validators
|
import django.core.validators
|
||||||
import accounting.models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import accounting.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = []
|
dependencies = []
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("club", "0001_initial"),
|
("club", "0001_initial"),
|
||||||
("accounting", "0001_initial"),
|
("accounting", "0001_initial"),
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import phonenumber_field.modelfields
|
import phonenumber_field.modelfields
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounting", "0002_auto_20160824_2152")]
|
dependencies = [("accounting", "0002_auto_20160824_2152")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounting", "0003_auto_20160824_2203")]
|
dependencies = [("accounting", "0003_auto_20160824_2203")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -5,7 +5,6 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("accounting", "0004_auto_20161005_1505")]
|
dependencies = [("accounting", "0004_auto_20161005_1505")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,40 +1,36 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
#
|
|
||||||
|
|
||||||
from django.urls import reverse
|
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
from django.core import validators
|
|
||||||
from django.db import models
|
|
||||||
from django.conf import settings
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
from django.template import defaultfilters
|
|
||||||
|
|
||||||
from phonenumber_field.modelfields import PhoneNumberField
|
|
||||||
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from core.models import User, SithFile
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core import validators
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.db import models
|
||||||
|
from django.template import defaultfilters
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from phonenumber_field.modelfields import PhoneNumberField
|
||||||
|
|
||||||
from club.models import Club
|
from club.models import Club
|
||||||
|
from core.models import SithFile, User
|
||||||
|
|
||||||
|
|
||||||
class CurrencyField(models.DecimalField):
|
class CurrencyField(models.DecimalField):
|
||||||
@ -74,7 +70,7 @@ class Company(models.Model):
|
|||||||
"""
|
"""
|
||||||
Method to see if that object can be edited by the given user
|
Method to see if that object can be edited by the given user
|
||||||
"""
|
"""
|
||||||
if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -125,7 +121,9 @@ class BankAccount(models.Model):
|
|||||||
"""
|
"""
|
||||||
Method to see if that object can be edited by the given user
|
Method to see if that object can be edited by the given user
|
||||||
"""
|
"""
|
||||||
if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
||||||
return True
|
return True
|
||||||
m = self.club.get_membership_for(user)
|
m = self.club.get_membership_for(user)
|
||||||
if m is not None and m.role >= settings.SITH_CLUB_ROLES_ID["Treasurer"]:
|
if m is not None and m.role >= settings.SITH_CLUB_ROLES_ID["Treasurer"]:
|
||||||
@ -162,7 +160,9 @@ class ClubAccount(models.Model):
|
|||||||
"""
|
"""
|
||||||
Method to see if that object can be edited by the given user
|
Method to see if that object can be edited by the given user
|
||||||
"""
|
"""
|
||||||
if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -233,7 +233,9 @@ class GeneralJournal(models.Model):
|
|||||||
"""
|
"""
|
||||||
Method to see if that object can be edited by the given user
|
Method to see if that object can be edited by the given user
|
||||||
"""
|
"""
|
||||||
if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
||||||
return True
|
return True
|
||||||
if self.club_account.can_be_edited_by(user):
|
if self.club_account.can_be_edited_by(user):
|
||||||
return True
|
return True
|
||||||
@ -243,7 +245,7 @@ class GeneralJournal(models.Model):
|
|||||||
"""
|
"""
|
||||||
Method to see if that object can be edited by the given user
|
Method to see if that object can be edited by the given user
|
||||||
"""
|
"""
|
||||||
if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
||||||
return True
|
return True
|
||||||
if self.club_account.can_be_edited_by(user):
|
if self.club_account.can_be_edited_by(user):
|
||||||
return True
|
return True
|
||||||
@ -422,7 +424,9 @@ class Operation(models.Model):
|
|||||||
"""
|
"""
|
||||||
Method to see if that object can be edited by the given user
|
Method to see if that object can be edited by the given user
|
||||||
"""
|
"""
|
||||||
if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
||||||
return True
|
return True
|
||||||
if self.journal.closed:
|
if self.journal.closed:
|
||||||
return False
|
return False
|
||||||
@ -435,7 +439,7 @@ class Operation(models.Model):
|
|||||||
"""
|
"""
|
||||||
Method to see if that object can be edited by the given user
|
Method to see if that object can be edited by the given user
|
||||||
"""
|
"""
|
||||||
if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
||||||
return True
|
return True
|
||||||
if self.journal.closed:
|
if self.journal.closed:
|
||||||
return False
|
return False
|
||||||
@ -491,7 +495,9 @@ class AccountingType(models.Model):
|
|||||||
"""
|
"""
|
||||||
Method to see if that object can be edited by the given user
|
Method to see if that object can be edited by the given user
|
||||||
"""
|
"""
|
||||||
if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -562,6 +568,8 @@ class Label(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
return self.club_account.is_owned_by(user)
|
return self.club_account.is_owned_by(user)
|
||||||
|
|
||||||
def can_be_edited_by(self, user):
|
def can_be_edited_by(self, user):
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<hr>
|
<hr>
|
||||||
<h2>{% trans %}Bank account: {% endtrans %}{{ object.name }}</h2>
|
<h2>{% trans %}Bank account: {% endtrans %}{{ object.name }}</h2>
|
||||||
{% if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) and not object.club_accounts.exists() %}
|
{% if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) and not object.club_accounts.exists() %}
|
||||||
<a href="{{ url('accounting:bank_delete', b_account_id=object.id) }}">{% trans %}Delete{% endtrans %}</a>
|
<a href="{{ url('accounting:bank_delete', b_account_id=object.id) }}">{% trans %}Delete{% endtrans %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h4>{% trans %}Infos{% endtrans %}</h4>
|
<h4>{% trans %}Infos{% endtrans %}</h4>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<h4>
|
<h4>
|
||||||
{% trans %}Accounting{% endtrans %}
|
{% trans %}Accounting{% endtrans %}
|
||||||
</h4>
|
</h4>
|
||||||
{% if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
|
{% if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
|
||||||
<p><a href="{{ url('accounting:simple_type_list') }}">{% trans %}Manage simplified types{% endtrans %}</a></p>
|
<p><a href="{{ url('accounting:simple_type_list') }}">{% trans %}Manage simplified types{% endtrans %}</a></p>
|
||||||
<p><a href="{{ url('accounting:type_list') }}">{% trans %}Manage accounting types{% endtrans %}</a></p>
|
<p><a href="{{ url('accounting:type_list') }}">{% trans %}Manage accounting types{% endtrans %}</a></p>
|
||||||
<p><a href="{{ url('accounting:bank_new') }}">{% trans %}New bank account{% endtrans %}</a></p>
|
<p><a href="{{ url('accounting:bank_new') }}">{% trans %}New bank account{% endtrans %}</a></p>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
{% if user.is_root and not object.journals.exists() %}
|
{% if user.is_root and not object.journals.exists() %}
|
||||||
<a href="{{ url('accounting:club_delete', c_account_id=object.id) }}">{% trans %}Delete{% endtrans %}</a>
|
<a href="{{ url('accounting:club_delete', c_account_id=object.id) }}">{% trans %}Delete{% endtrans %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
|
{% if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
|
||||||
<p><a href="{{ url('accounting:label_new') }}?parent={{ object.id }}">{% trans %}New label{% endtrans %}</a></p>
|
<p><a href="{{ url('accounting:label_new') }}?parent={{ object.id }}">{% trans %}New label{% endtrans %}</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p><a href="{{ url('accounting:label_list', clubaccount_id=object.id) }}">{% trans %}Label list{% endtrans %}</a></p>
|
<p><a href="{{ url('accounting:label_list', clubaccount_id=object.id) }}">{% trans %}Label list{% endtrans %}</a></p>
|
||||||
@ -56,7 +56,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<td> <a href="{{ url('accounting:journal_details', j_id=j.id) }}">{% trans %}View{% endtrans %}</a>
|
<td> <a href="{{ url('accounting:journal_details', j_id=j.id) }}">{% trans %}View{% endtrans %}</a>
|
||||||
<a href="{{ url('accounting:journal_edit', j_id=j.id) }}">{% trans %}Edit{% endtrans %}</a>
|
<a href="{{ url('accounting:journal_edit', j_id=j.id) }}">{% trans %}Edit{% endtrans %}</a>
|
||||||
{% if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) and j.operations.count() == 0 %}
|
{% if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) and j.operations.count() == 0 %}
|
||||||
<a href="{{ url('accounting:journal_delete', j_id=j.id) }}">{% trans %}Delete{% endtrans %}</a>
|
<a href="{{ url('accounting:journal_delete', j_id=j.id) }}">{% trans %}Delete{% endtrans %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
@ -6,11 +6,12 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="accounting">
|
<div id="accounting">
|
||||||
{% if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) or user.is_root %}
|
{% if user.is_root
|
||||||
|
or user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID)
|
||||||
|
%}
|
||||||
<p><a href="{{ url('accounting:co_new') }}">{% trans %}Create new company{% endtrans %}</a></p>
|
<p><a href="{{ url('accounting:co_new') }}">{% trans %}Create new company{% endtrans %}</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<br/>
|
||||||
</br>
|
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -84,10 +84,13 @@
|
|||||||
<td>-</td>
|
<td>-</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<td>
|
<td>
|
||||||
{% if o.journal.club_account.bank_account.name != "AE TI" and o.journal.club_account.bank_account.name != "TI" or user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
|
{%
|
||||||
{% if not o.journal.closed %}
|
if o.journal.club_account.bank_account.name not in ["AE TI", "TI"]
|
||||||
<a href="{{ url('accounting:op_edit', op_id=o.id) }}">{% trans %}Edit{% endtrans %}</a>
|
or user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID)
|
||||||
{% endif %}
|
%}
|
||||||
|
{% if not o.journal.closed %}
|
||||||
|
<a href="{{ url('accounting:op_edit', op_id=o.id) }}">{% trans %}Edit{% endtrans %}</a>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td><a href="{{ url('accounting:op_pdf', op_id=o.id) }}">{% trans %}Generate{% endtrans %}</a></td>
|
<td><a href="{{ url('accounting:op_pdf', op_id=o.id) }}">{% trans %}Generate{% endtrans %}</a></td>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<hr>
|
<hr>
|
||||||
<p><a href="{{ url('accounting:club_details', c_account_id=object.id) }}">{% trans %}Back to club account{% endtrans %}</a></p>
|
<p><a href="{{ url('accounting:club_details', c_account_id=object.id) }}">{% trans %}Back to club account{% endtrans %}</a></p>
|
||||||
{% if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
|
{% if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
|
||||||
<p><a href="{{ url('accounting:label_new') }}?parent={{ object.id }}">{% trans %}New label{% endtrans %}</a></p>
|
<p><a href="{{ url('accounting:label_new') }}?parent={{ object.id }}">{% trans %}New label{% endtrans %}</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if object.labels.all() %}
|
{% if object.labels.all() %}
|
||||||
@ -21,7 +21,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
{% for l in object.labels.all() %}
|
{% for l in object.labels.all() %}
|
||||||
<li><a href="{{ url('accounting:label_edit', label_id=l.id) }}">{{ l }}</a>
|
<li><a href="{{ url('accounting:label_edit', label_id=l.id) }}">{{ l }}</a>
|
||||||
{% if user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
|
{% if user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID) %}
|
||||||
-
|
-
|
||||||
<a href="{{ url('accounting:label_delete', label_id=l.id) }}">{% trans %}Delete{% endtrans %}</a>
|
<a href="{{ url('accounting:label_delete', label_id=l.id) }}">{% trans %}Delete{% endtrans %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -1,115 +1,103 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from datetime import date, timedelta
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.core.management import call_command
|
|
||||||
from datetime import date, timedelta
|
|
||||||
|
|
||||||
from core.models import User
|
|
||||||
from accounting.models import (
|
from accounting.models import (
|
||||||
GeneralJournal,
|
|
||||||
Operation,
|
|
||||||
Label,
|
|
||||||
AccountingType,
|
AccountingType,
|
||||||
|
GeneralJournal,
|
||||||
|
Label,
|
||||||
|
Operation,
|
||||||
SimplifiedAccountingType,
|
SimplifiedAccountingType,
|
||||||
)
|
)
|
||||||
|
from core.models import User
|
||||||
|
|
||||||
|
|
||||||
class RefoundAccountTest(TestCase):
|
class RefoundAccountTest(TestCase):
|
||||||
def setUp(self):
|
@classmethod
|
||||||
call_command("populate")
|
def setUpTestData(cls):
|
||||||
self.skia = User.objects.filter(username="skia").first()
|
cls.skia = User.objects.get(username="skia")
|
||||||
# reffil skia's account
|
# reffil skia's account
|
||||||
self.skia.customer.amount = 800
|
cls.skia.customer.amount = 800
|
||||||
self.skia.customer.save()
|
cls.skia.customer.save()
|
||||||
|
cls.refound_account_url = reverse("accounting:refound_account")
|
||||||
|
|
||||||
def test_permission_denied(self):
|
def test_permission_denied(self):
|
||||||
self.client.login(username="guy", password="plop")
|
self.client.force_login(User.objects.get(username="guy"))
|
||||||
response_post = self.client.post(
|
response_post = self.client.post(
|
||||||
reverse("accounting:refound_account"), {"user": self.skia.id}
|
self.refound_account_url, {"user": self.skia.id}
|
||||||
)
|
)
|
||||||
response_get = self.client.get(reverse("accounting:refound_account"))
|
response_get = self.client.get(self.refound_account_url)
|
||||||
self.assertTrue(response_get.status_code == 403)
|
assert response_get.status_code == 403
|
||||||
self.assertTrue(response_post.status_code == 403)
|
assert response_post.status_code == 403
|
||||||
|
|
||||||
def test_root_granteed(self):
|
def test_root_granteed(self):
|
||||||
self.client.login(username="root", password="plop")
|
self.client.force_login(User.objects.get(username="root"))
|
||||||
response_post = self.client.post(
|
response = self.client.post(self.refound_account_url, {"user": self.skia.id})
|
||||||
reverse("accounting:refound_account"), {"user": self.skia.id}
|
self.assertRedirects(response, self.refound_account_url)
|
||||||
)
|
self.skia.refresh_from_db()
|
||||||
self.skia = User.objects.filter(username="skia").first()
|
response = self.client.get(self.refound_account_url)
|
||||||
response_get = self.client.get(reverse("accounting:refound_account"))
|
assert response.status_code == 200
|
||||||
self.assertFalse(response_get.status_code == 403)
|
assert '<form action="" method="post">' in str(response.content)
|
||||||
self.assertTrue('<form action="" method="post">' in str(response_get.content))
|
assert self.skia.customer.amount == 0
|
||||||
self.assertFalse(response_post.status_code == 403)
|
|
||||||
self.assertTrue(self.skia.customer.amount == 0)
|
|
||||||
|
|
||||||
def test_comptable_granteed(self):
|
def test_comptable_granteed(self):
|
||||||
self.client.login(username="comptable", password="plop")
|
self.client.force_login(User.objects.get(username="comptable"))
|
||||||
response_post = self.client.post(
|
response = self.client.post(self.refound_account_url, {"user": self.skia.id})
|
||||||
reverse("accounting:refound_account"), {"user": self.skia.id}
|
self.assertRedirects(response, self.refound_account_url)
|
||||||
)
|
self.skia.refresh_from_db()
|
||||||
self.skia = User.objects.filter(username="skia").first()
|
response = self.client.get(self.refound_account_url)
|
||||||
response_get = self.client.get(reverse("accounting:refound_account"))
|
assert response.status_code == 200
|
||||||
self.assertFalse(response_get.status_code == 403)
|
assert '<form action="" method="post">' in str(response.content)
|
||||||
self.assertTrue('<form action="" method="post">' in str(response_get.content))
|
assert self.skia.customer.amount == 0
|
||||||
self.assertFalse(response_post.status_code == 403)
|
|
||||||
self.assertTrue(self.skia.customer.amount == 0)
|
|
||||||
|
|
||||||
|
|
||||||
class JournalTest(TestCase):
|
class JournalTest(TestCase):
|
||||||
def setUp(self):
|
@classmethod
|
||||||
call_command("populate")
|
def setUpTestData(cls):
|
||||||
self.journal = GeneralJournal.objects.filter(id=1).first()
|
cls.journal = GeneralJournal.objects.get(id=1)
|
||||||
|
|
||||||
def test_permission_granted(self):
|
def test_permission_granted(self):
|
||||||
self.client.login(username="comptable", password="plop")
|
self.client.force_login(User.objects.get(username="comptable"))
|
||||||
response_get = self.client.get(
|
response_get = self.client.get(
|
||||||
reverse("accounting:journal_details", args=[self.journal.id])
|
reverse("accounting:journal_details", args=[self.journal.id])
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertTrue(response_get.status_code == 200)
|
assert response_get.status_code == 200
|
||||||
self.assertTrue(
|
assert "<td>M\\xc3\\xa9thode de paiement</td>" in str(response_get.content)
|
||||||
"<td>M\\xc3\\xa9thode de paiement</td>" in str(response_get.content)
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_permission_not_granted(self):
|
def test_permission_not_granted(self):
|
||||||
self.client.login(username="skia", password="plop")
|
self.client.force_login(User.objects.get(username="skia"))
|
||||||
response_get = self.client.get(
|
response_get = self.client.get(
|
||||||
reverse("accounting:journal_details", args=[self.journal.id])
|
reverse("accounting:journal_details", args=[self.journal.id])
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertTrue(response_get.status_code == 403)
|
assert response_get.status_code == 403
|
||||||
self.assertFalse(
|
assert "<td>M\xc3\xa9thode de paiement</td>" not in str(response_get.content)
|
||||||
"<td>M\xc3\xa9thode de paiement</td>" in str(response_get.content)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class OperationTest(TestCase):
|
class OperationTest(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
call_command("populate")
|
|
||||||
self.tomorrow_formatted = (date.today() + timedelta(days=1)).strftime(
|
self.tomorrow_formatted = (date.today() + timedelta(days=1)).strftime(
|
||||||
"%d/%m/%Y"
|
"%d/%m/%Y"
|
||||||
)
|
)
|
||||||
@ -119,9 +107,8 @@ class OperationTest(TestCase):
|
|||||||
code="443", label="Ce code n'existe pas", movement_type="CREDIT"
|
code="443", label="Ce code n'existe pas", movement_type="CREDIT"
|
||||||
)
|
)
|
||||||
at.save()
|
at.save()
|
||||||
l = Label(club_account=self.journal.club_account, name="bob")
|
l = Label.objects.create(club_account=self.journal.club_account, name="bob")
|
||||||
l.save()
|
self.client.force_login(User.objects.get(username="comptable"))
|
||||||
self.client.login(username="comptable", password="plop")
|
|
||||||
self.op1 = Operation(
|
self.op1 = Operation(
|
||||||
journal=self.journal,
|
journal=self.journal,
|
||||||
date=date.today(),
|
date=date.today(),
|
||||||
@ -150,8 +137,7 @@ class OperationTest(TestCase):
|
|||||||
self.op2.save()
|
self.op2.save()
|
||||||
|
|
||||||
def test_new_operation(self):
|
def test_new_operation(self):
|
||||||
self.client.login(username="comptable", password="plop")
|
at = AccountingType.objects.get(code="604")
|
||||||
at = AccountingType.objects.filter(code="604").first()
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("accounting:op_new", args=[self.journal.id]),
|
reverse("accounting:op_new", args=[self.journal.id]),
|
||||||
{
|
{
|
||||||
@ -183,8 +169,7 @@ class OperationTest(TestCase):
|
|||||||
self.assertTrue("<td>Le fantome de la nuit</td>" in str(response_get.content))
|
self.assertTrue("<td>Le fantome de la nuit</td>" in str(response_get.content))
|
||||||
|
|
||||||
def test_bad_new_operation(self):
|
def test_bad_new_operation(self):
|
||||||
self.client.login(username="comptable", password="plop")
|
AccountingType.objects.get(code="604")
|
||||||
AccountingType.objects.filter(code="604").first()
|
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("accounting:op_new", args=[self.journal.id]),
|
reverse("accounting:op_new", args=[self.journal.id]),
|
||||||
{
|
{
|
||||||
@ -210,7 +195,7 @@ class OperationTest(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_new_operation_not_authorized(self):
|
def test_new_operation_not_authorized(self):
|
||||||
self.client.login(username="skia", password="plop")
|
self.client.force_login(self.skia)
|
||||||
at = AccountingType.objects.filter(code="604").first()
|
at = AccountingType.objects.filter(code="604").first()
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("accounting:op_new", args=[self.journal.id]),
|
reverse("accounting:op_new", args=[self.journal.id]),
|
||||||
@ -237,7 +222,6 @@ class OperationTest(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test__operation_simple_accounting(self):
|
def test__operation_simple_accounting(self):
|
||||||
self.client.login(username="comptable", password="plop")
|
|
||||||
sat = SimplifiedAccountingType.objects.all().first()
|
sat = SimplifiedAccountingType.objects.all().first()
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
reverse("accounting:op_new", args=[self.journal.id]),
|
reverse("accounting:op_new", args=[self.journal.id]),
|
||||||
@ -274,14 +258,12 @@ class OperationTest(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_nature_statement(self):
|
def test_nature_statement(self):
|
||||||
self.client.login(username="comptable", password="plop")
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("accounting:journal_nature_statement", args=[self.journal.id])
|
reverse("accounting:journal_nature_statement", args=[self.journal.id])
|
||||||
)
|
)
|
||||||
self.assertContains(response, "bob (Troll Penché) : 3.00", status_code=200)
|
self.assertContains(response, "bob (Troll Penché) : 3.00", status_code=200)
|
||||||
|
|
||||||
def test_person_statement(self):
|
def test_person_statement(self):
|
||||||
self.client.login(username="comptable", password="plop")
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("accounting:journal_person_statement", args=[self.journal.id])
|
reverse("accounting:journal_person_statement", args=[self.journal.id])
|
||||||
)
|
)
|
||||||
@ -303,7 +285,6 @@ class OperationTest(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_accounting_statement(self):
|
def test_accounting_statement(self):
|
||||||
self.client.login(username="comptable", password="plop")
|
|
||||||
response = self.client.get(
|
response = self.client.get(
|
||||||
reverse("accounting:journal_accounting_statement", args=[self.journal.id])
|
reverse("accounting:journal_accounting_statement", args=[self.journal.id])
|
||||||
)
|
)
|
||||||
|
@ -1,154 +1,144 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.urls import re_path
|
from django.urls import path
|
||||||
|
|
||||||
from accounting.views import *
|
from accounting.views import *
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# Accounting types
|
# Accounting types
|
||||||
re_path(
|
path(
|
||||||
r"^simple_type$",
|
"simple_type/",
|
||||||
SimplifiedAccountingTypeListView.as_view(),
|
SimplifiedAccountingTypeListView.as_view(),
|
||||||
name="simple_type_list",
|
name="simple_type_list",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^simple_type/create$",
|
"simple_type/create/",
|
||||||
SimplifiedAccountingTypeCreateView.as_view(),
|
SimplifiedAccountingTypeCreateView.as_view(),
|
||||||
name="simple_type_new",
|
name="simple_type_new",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^simple_type/(?P<type_id>[0-9]+)/edit$",
|
"simple_type/<int:type_id>/edit/",
|
||||||
SimplifiedAccountingTypeEditView.as_view(),
|
SimplifiedAccountingTypeEditView.as_view(),
|
||||||
name="simple_type_edit",
|
name="simple_type_edit",
|
||||||
),
|
),
|
||||||
# Accounting types
|
# Accounting types
|
||||||
re_path(r"^type$", AccountingTypeListView.as_view(), name="type_list"),
|
path("type/", AccountingTypeListView.as_view(), name="type_list"),
|
||||||
re_path(r"^type/create$", AccountingTypeCreateView.as_view(), name="type_new"),
|
path("type/create/", AccountingTypeCreateView.as_view(), name="type_new"),
|
||||||
re_path(
|
path(
|
||||||
r"^type/(?P<type_id>[0-9]+)/edit$",
|
"type/<int:type_id>/edit/",
|
||||||
AccountingTypeEditView.as_view(),
|
AccountingTypeEditView.as_view(),
|
||||||
name="type_edit",
|
name="type_edit",
|
||||||
),
|
),
|
||||||
# Bank accounts
|
# Bank accounts
|
||||||
re_path(r"^$", BankAccountListView.as_view(), name="bank_list"),
|
path("", BankAccountListView.as_view(), name="bank_list"),
|
||||||
re_path(r"^bank/create$", BankAccountCreateView.as_view(), name="bank_new"),
|
path("bank/create", BankAccountCreateView.as_view(), name="bank_new"),
|
||||||
re_path(
|
path(
|
||||||
r"^bank/(?P<b_account_id>[0-9]+)$",
|
"bank/<int:b_account_id>/",
|
||||||
BankAccountDetailView.as_view(),
|
BankAccountDetailView.as_view(),
|
||||||
name="bank_details",
|
name="bank_details",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^bank/(?P<b_account_id>[0-9]+)/edit$",
|
"bank/<int:b_account_id>/edit/",
|
||||||
BankAccountEditView.as_view(),
|
BankAccountEditView.as_view(),
|
||||||
name="bank_edit",
|
name="bank_edit",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^bank/(?P<b_account_id>[0-9]+)/delete$",
|
"bank/<int:b_account_id>/delete/",
|
||||||
BankAccountDeleteView.as_view(),
|
BankAccountDeleteView.as_view(),
|
||||||
name="bank_delete",
|
name="bank_delete",
|
||||||
),
|
),
|
||||||
# Club accounts
|
# Club accounts
|
||||||
re_path(r"^club/create$", ClubAccountCreateView.as_view(), name="club_new"),
|
path("club/create/", ClubAccountCreateView.as_view(), name="club_new"),
|
||||||
re_path(
|
path(
|
||||||
r"^club/(?P<c_account_id>[0-9]+)$",
|
"club/<int:c_account_id>/",
|
||||||
ClubAccountDetailView.as_view(),
|
ClubAccountDetailView.as_view(),
|
||||||
name="club_details",
|
name="club_details",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^club/(?P<c_account_id>[0-9]+)/edit$",
|
"club/<int:c_account_id>/edit/",
|
||||||
ClubAccountEditView.as_view(),
|
ClubAccountEditView.as_view(),
|
||||||
name="club_edit",
|
name="club_edit",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^club/(?P<c_account_id>[0-9]+)/delete$",
|
"club/<int:c_account_id>/delete/",
|
||||||
ClubAccountDeleteView.as_view(),
|
ClubAccountDeleteView.as_view(),
|
||||||
name="club_delete",
|
name="club_delete",
|
||||||
),
|
),
|
||||||
# Journals
|
# Journals
|
||||||
re_path(r"^journal/create$", JournalCreateView.as_view(), name="journal_new"),
|
path("journal/create/", JournalCreateView.as_view(), name="journal_new"),
|
||||||
re_path(
|
path(
|
||||||
r"^journal/(?P<j_id>[0-9]+)$",
|
"journal/<int:j_id>/",
|
||||||
JournalDetailView.as_view(),
|
JournalDetailView.as_view(),
|
||||||
name="journal_details",
|
name="journal_details",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^journal/(?P<j_id>[0-9]+)/edit$",
|
"journal/<int:j_id>/edit/",
|
||||||
JournalEditView.as_view(),
|
JournalEditView.as_view(),
|
||||||
name="journal_edit",
|
name="journal_edit",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^journal/(?P<j_id>[0-9]+)/delete$",
|
"journal/<int:j_id>/delete/",
|
||||||
JournalDeleteView.as_view(),
|
JournalDeleteView.as_view(),
|
||||||
name="journal_delete",
|
name="journal_delete",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^journal/(?P<j_id>[0-9]+)/statement/nature$",
|
"journal/<int:j_id>/statement/nature/",
|
||||||
JournalNatureStatementView.as_view(),
|
JournalNatureStatementView.as_view(),
|
||||||
name="journal_nature_statement",
|
name="journal_nature_statement",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^journal/(?P<j_id>[0-9]+)/statement/person$",
|
"journal/<int:j_id>/statement/person/",
|
||||||
JournalPersonStatementView.as_view(),
|
JournalPersonStatementView.as_view(),
|
||||||
name="journal_person_statement",
|
name="journal_person_statement",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^journal/(?P<j_id>[0-9]+)/statement/accounting$",
|
"journal/<int:j_id>/statement/accounting/",
|
||||||
JournalAccountingStatementView.as_view(),
|
JournalAccountingStatementView.as_view(),
|
||||||
name="journal_accounting_statement",
|
name="journal_accounting_statement",
|
||||||
),
|
),
|
||||||
# Operations
|
# Operations
|
||||||
re_path(
|
path(
|
||||||
r"^operation/create/(?P<j_id>[0-9]+)$",
|
"operation/create/<int:j_id>/",
|
||||||
OperationCreateView.as_view(),
|
OperationCreateView.as_view(),
|
||||||
name="op_new",
|
name="op_new",
|
||||||
),
|
),
|
||||||
re_path(
|
path("operation/<int:op_id>/", OperationEditView.as_view(), name="op_edit"),
|
||||||
r"^operation/(?P<op_id>[0-9]+)$", OperationEditView.as_view(), name="op_edit"
|
path("operation/<int:op_id>/pdf/", OperationPDFView.as_view(), name="op_pdf"),
|
||||||
),
|
|
||||||
re_path(
|
|
||||||
r"^operation/(?P<op_id>[0-9]+)/pdf$", OperationPDFView.as_view(), name="op_pdf"
|
|
||||||
),
|
|
||||||
# Companies
|
# Companies
|
||||||
re_path(r"^company/list$", CompanyListView.as_view(), name="co_list"),
|
path("company/list/", CompanyListView.as_view(), name="co_list"),
|
||||||
re_path(r"^company/create$", CompanyCreateView.as_view(), name="co_new"),
|
path("company/create/", CompanyCreateView.as_view(), name="co_new"),
|
||||||
re_path(r"^company/(?P<co_id>[0-9]+)$", CompanyEditView.as_view(), name="co_edit"),
|
path("company/<int:co_id>/", CompanyEditView.as_view(), name="co_edit"),
|
||||||
# Labels
|
# Labels
|
||||||
re_path(r"^label/new$", LabelCreateView.as_view(), name="label_new"),
|
path("label/new/", LabelCreateView.as_view(), name="label_new"),
|
||||||
re_path(
|
path(
|
||||||
r"^label/(?P<clubaccount_id>[0-9]+)$",
|
"label/<int:clubaccount_id>/",
|
||||||
LabelListView.as_view(),
|
LabelListView.as_view(),
|
||||||
name="label_list",
|
name="label_list",
|
||||||
),
|
),
|
||||||
re_path(
|
path("label/<int:label_id>/edit/", LabelEditView.as_view(), name="label_edit"),
|
||||||
r"^label/(?P<label_id>[0-9]+)/edit$", LabelEditView.as_view(), name="label_edit"
|
path(
|
||||||
),
|
"label/<int:label_id>/delete/",
|
||||||
re_path(
|
|
||||||
r"^label/(?P<label_id>[0-9]+)/delete$",
|
|
||||||
LabelDeleteView.as_view(),
|
LabelDeleteView.as_view(),
|
||||||
name="label_delete",
|
name="label_delete",
|
||||||
),
|
),
|
||||||
# User account
|
# User account
|
||||||
re_path(r"^refound/account$", RefoundAccountView.as_view(), name="refound_account"),
|
path("refound/account/", RefoundAccountView.as_view(), name="refound_account"),
|
||||||
]
|
]
|
||||||
|
@ -1,62 +1,58 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.views.generic import ListView, DetailView
|
|
||||||
from django.views.generic.edit import UpdateView, CreateView, DeleteView, FormView
|
|
||||||
from django.urls import reverse_lazy, reverse
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
from django.forms.models import modelform_factory
|
|
||||||
from django.core.exceptions import PermissionDenied, ValidationError
|
|
||||||
from django.forms import HiddenInput
|
|
||||||
from django.db import transaction
|
|
||||||
from django.db.models import Sum
|
|
||||||
from django.conf import settings
|
|
||||||
from django import forms
|
|
||||||
from django.http import HttpResponse
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
from ajax_select.fields import AutoCompleteSelectField
|
from ajax_select.fields import AutoCompleteSelectField
|
||||||
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.exceptions import PermissionDenied, ValidationError
|
||||||
|
from django.db import transaction
|
||||||
|
from django.db.models import Sum
|
||||||
|
from django.forms import HiddenInput
|
||||||
|
from django.forms.models import modelform_factory
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.urls import reverse, reverse_lazy
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.views.generic import DetailView, ListView
|
||||||
|
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
|
||||||
|
|
||||||
from core.views import (
|
|
||||||
CanViewMixin,
|
|
||||||
CanEditMixin,
|
|
||||||
CanEditPropMixin,
|
|
||||||
CanCreateMixin,
|
|
||||||
TabedViewMixin,
|
|
||||||
)
|
|
||||||
from core.views.forms import SelectFile, SelectDate
|
|
||||||
from accounting.models import (
|
from accounting.models import (
|
||||||
|
AccountingType,
|
||||||
BankAccount,
|
BankAccount,
|
||||||
ClubAccount,
|
ClubAccount,
|
||||||
GeneralJournal,
|
|
||||||
Operation,
|
|
||||||
AccountingType,
|
|
||||||
Company,
|
Company,
|
||||||
SimplifiedAccountingType,
|
GeneralJournal,
|
||||||
Label,
|
Label,
|
||||||
|
Operation,
|
||||||
|
SimplifiedAccountingType,
|
||||||
)
|
)
|
||||||
from counter.models import Counter, Selling, Product
|
from core.views import (
|
||||||
|
CanCreateMixin,
|
||||||
|
CanEditMixin,
|
||||||
|
CanEditPropMixin,
|
||||||
|
CanViewMixin,
|
||||||
|
TabedViewMixin,
|
||||||
|
)
|
||||||
|
from core.views.forms import SelectDate, SelectFile
|
||||||
|
from counter.models import Counter, Product, Selling
|
||||||
|
|
||||||
# Main accounting view
|
# Main accounting view
|
||||||
|
|
||||||
@ -529,14 +525,14 @@ class OperationPDFView(CanViewMixin, DetailView):
|
|||||||
pk_url_kwarg = "op_id"
|
pk_url_kwarg = "op_id"
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
from reportlab.pdfgen import canvas
|
|
||||||
from reportlab.lib.units import cm
|
|
||||||
from reportlab.platypus import Table, TableStyle
|
|
||||||
from reportlab.lib import colors
|
from reportlab.lib import colors
|
||||||
from reportlab.lib.pagesizes import letter
|
from reportlab.lib.pagesizes import letter
|
||||||
|
from reportlab.lib.units import cm
|
||||||
from reportlab.lib.utils import ImageReader
|
from reportlab.lib.utils import ImageReader
|
||||||
from reportlab.pdfbase.ttfonts import TTFont
|
|
||||||
from reportlab.pdfbase import pdfmetrics
|
from reportlab.pdfbase import pdfmetrics
|
||||||
|
from reportlab.pdfbase.ttfonts import TTFont
|
||||||
|
from reportlab.pdfgen import canvas
|
||||||
|
from reportlab.platypus import Table, TableStyle
|
||||||
|
|
||||||
pdfmetrics.registerFont(TTFont("DejaVu", "DejaVuSerif.ttf"))
|
pdfmetrics.registerFont(TTFont("DejaVu", "DejaVuSerif.ttf"))
|
||||||
|
|
||||||
@ -607,7 +603,7 @@ class OperationPDFView(CanViewMixin, DetailView):
|
|||||||
payment_mode = ""
|
payment_mode = ""
|
||||||
for m in settings.SITH_ACCOUNTING_PAYMENT_METHOD:
|
for m in settings.SITH_ACCOUNTING_PAYMENT_METHOD:
|
||||||
if m[0] == mode:
|
if m[0] == mode:
|
||||||
payment_mode += "[\u00D7]"
|
payment_mode += "[\u00d7]"
|
||||||
else:
|
else:
|
||||||
payment_mode += "[ ]"
|
payment_mode += "[ ]"
|
||||||
payment_mode += " %s\n" % (m[1])
|
payment_mode += " %s\n" % (m[1])
|
||||||
@ -899,7 +895,7 @@ class RefoundAccountView(FormView):
|
|||||||
form_class = CloseCustomerAccountForm
|
form_class = CloseCustomerAccountForm
|
||||||
|
|
||||||
def permission(self, user):
|
def permission(self, user):
|
||||||
if user.is_root or user.is_in_group(settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
if user.is_root or user.is_in_group(pk=settings.SITH_GROUP_ACCOUNTING_ADMIN_ID):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
32
api/admin.py
@ -1,27 +1,21 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
#
|
|
||||||
|
|
||||||
from django.contrib import admin
|
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
|
@ -1,27 +1,21 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
#
|
|
||||||
|
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
32
api/tests.py
@ -1,27 +1,21 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
#
|
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
# Create your tests here.
|
||||||
|
34
api/urls.py
@ -1,31 +1,27 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.urls import re_path, path, include
|
from django.urls import include, path, re_path
|
||||||
|
from rest_framework import routers
|
||||||
|
|
||||||
from api.views import *
|
from api.views import *
|
||||||
from rest_framework import routers
|
|
||||||
|
|
||||||
# Router config
|
# Router config
|
||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
|
@ -1,34 +1,30 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework import viewsets
|
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from rest_framework.decorators import action
|
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
|
from rest_framework import viewsets
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from core.views import can_view, can_edit
|
from core.views import can_edit, can_view
|
||||||
|
|
||||||
|
|
||||||
def check_if(obj, user, test):
|
def check_if(obj, user, test):
|
||||||
@ -72,10 +68,10 @@ class RightModelViewSet(ManageModelMixin, viewsets.ModelViewSet):
|
|||||||
|
|
||||||
|
|
||||||
from .api import *
|
from .api import *
|
||||||
from .counter import *
|
|
||||||
from .user import *
|
|
||||||
from .club import *
|
from .club import *
|
||||||
|
from .counter import *
|
||||||
from .group import *
|
from .group import *
|
||||||
from .launderette import *
|
from .launderette import *
|
||||||
from .uv import *
|
|
||||||
from .sas import *
|
from .sas import *
|
||||||
|
from .user import *
|
||||||
|
from .uv import *
|
||||||
|
@ -1,30 +1,26 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework.decorators import api_view, renderer_classes
|
from rest_framework.decorators import api_view, renderer_classes
|
||||||
from rest_framework.renderers import StaticHTMLRenderer
|
from rest_framework.renderers import StaticHTMLRenderer
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from core.templatetags.renderer import markdown
|
from core.templatetags.renderer import markdown
|
||||||
|
|
||||||
|
@ -1,38 +1,32 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
#
|
|
||||||
|
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework import serializers
|
|
||||||
from rest_framework.decorators import api_view, renderer_classes
|
|
||||||
from rest_framework.renderers import StaticHTMLRenderer
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
|
from rest_framework import serializers
|
||||||
from club.models import Club, Mailing
|
from rest_framework.decorators import api_view, renderer_classes
|
||||||
|
from rest_framework.renderers import StaticHTMLRenderer
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from api.views import RightModelViewSet
|
from api.views import RightModelViewSet
|
||||||
|
from club.models import Club, Mailing
|
||||||
|
|
||||||
|
|
||||||
class ClubSerializer(serializers.ModelSerializer):
|
class ClubSerializer(serializers.ModelSerializer):
|
||||||
|
@ -1,38 +1,32 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.response import Response
|
||||||
from counter.models import Counter
|
|
||||||
|
|
||||||
from api.views import RightModelViewSet
|
from api.views import RightModelViewSet
|
||||||
|
from counter.models import Counter
|
||||||
|
|
||||||
|
|
||||||
class CounterSerializer(serializers.ModelSerializer):
|
class CounterSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
is_open = serializers.BooleanField(read_only=True)
|
is_open = serializers.BooleanField(read_only=True)
|
||||||
barman_list = serializers.ListField(
|
barman_list = serializers.ListField(
|
||||||
child=serializers.IntegerField(), read_only=True
|
child=serializers.IntegerField(), read_only=True
|
||||||
|
@ -1,32 +1,27 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from core.models import RealGroup
|
|
||||||
|
|
||||||
from api.views import RightModelViewSet
|
from api.views import RightModelViewSet
|
||||||
|
from core.models import RealGroup
|
||||||
|
|
||||||
|
|
||||||
class GroupSerializer(serializers.ModelSerializer):
|
class GroupSerializer(serializers.ModelSerializer):
|
||||||
|
@ -1,38 +1,32 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.response import Response
|
||||||
from launderette.models import Launderette, Machine, Token
|
|
||||||
|
|
||||||
from api.views import RightModelViewSet
|
from api.views import RightModelViewSet
|
||||||
|
from launderette.models import Launderette, Machine, Token
|
||||||
|
|
||||||
|
|
||||||
class LaunderettePlaceSerializer(serializers.ModelSerializer):
|
class LaunderettePlaceSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
machine_list = serializers.ListField(
|
machine_list = serializers.ListField(
|
||||||
child=serializers.IntegerField(), read_only=True
|
child=serializers.IntegerField(), read_only=True
|
||||||
)
|
)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from rest_framework.decorators import api_view, renderer_classes
|
from rest_framework.decorators import api_view, renderer_classes
|
||||||
from rest_framework.exceptions import PermissionDenied
|
from rest_framework.exceptions import PermissionDenied
|
||||||
from rest_framework.generics import get_object_or_404
|
from rest_framework.generics import get_object_or_404
|
||||||
@ -6,8 +7,8 @@ from rest_framework.renderers import JSONRenderer
|
|||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from core.views import can_edit
|
|
||||||
from core.models import User
|
from core.models import User
|
||||||
|
from core.views import can_edit
|
||||||
from sas.models import Picture
|
from sas.models import Picture
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,36 +1,31 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.response import Response
|
||||||
from core.models import User
|
|
||||||
|
|
||||||
from api.views import RightModelViewSet
|
from api.views import RightModelViewSet
|
||||||
|
from core.models import User
|
||||||
|
|
||||||
|
|
||||||
class UserSerializer(serializers.ModelSerializer):
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
from rest_framework.response import Response
|
import json
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
|
from rest_framework import serializers
|
||||||
from rest_framework.decorators import api_view, renderer_classes
|
from rest_framework.decorators import api_view, renderer_classes
|
||||||
from rest_framework.renderers import JSONRenderer
|
from rest_framework.renderers import JSONRenderer
|
||||||
from django.core.exceptions import PermissionDenied
|
from rest_framework.response import Response
|
||||||
from django.conf import settings
|
|
||||||
from rest_framework import serializers
|
|
||||||
import urllib.request
|
|
||||||
import json
|
|
||||||
|
|
||||||
from pedagogy.views import CanCreateUVFunctionMixin
|
from pedagogy.views import CanCreateUVFunctionMixin
|
||||||
|
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
@ -1,31 +1,40 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
#
|
from ajax_select import make_ajax_form
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from club.models import Club, Membership
|
from club.models import Club, Membership
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Club)
|
@admin.register(Club)
|
||||||
admin.site.register(Membership)
|
class ClubAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("name", "unix_name", "parent", "is_active")
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Membership)
|
||||||
|
class MembershipAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("user", "club", "role", "start_date", "end_date")
|
||||||
|
search_fields = (
|
||||||
|
"user__username",
|
||||||
|
"user__first_name",
|
||||||
|
"user__last_name",
|
||||||
|
"club__name",
|
||||||
|
)
|
||||||
|
form = make_ajax_form(Membership, {"user": "users"})
|
||||||
|
@ -1,40 +1,32 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
# - Sli <antoine@bartuccio.fr>
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.conf import settings
|
from ajax_select.fields import AutoCompleteSelectMultipleField
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
|
from club.models import Club, Mailing, MailingSubscription, Membership
|
||||||
|
|
||||||
from club.models import Mailing, MailingSubscription, Club, Membership
|
|
||||||
|
|
||||||
from core.models import User
|
from core.models import User
|
||||||
from core.views.forms import SelectDate, SelectDateTime
|
from core.views.forms import SelectDate, TzAwareDateTimeField
|
||||||
from counter.models import Counter
|
from counter.models import Counter
|
||||||
from core.views.forms import TzAwareDateTimeField
|
|
||||||
|
|
||||||
|
|
||||||
class ClubEditForm(forms.ModelForm):
|
class ClubEditForm(forms.ModelForm):
|
||||||
@ -167,7 +159,6 @@ class SellingsForm(forms.Form):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, club, *args, **kwargs):
|
def __init__(self, club, *args, **kwargs):
|
||||||
|
|
||||||
super(SellingsForm, self).__init__(*args, **kwargs)
|
super(SellingsForm, self).__init__(*args, **kwargs)
|
||||||
self.fields["products"] = forms.ModelMultipleChoiceField(
|
self.fields["products"] = forms.ModelMultipleChoiceField(
|
||||||
club.products.order_by("name").filter(archived=False).all(),
|
club.products.order_by("name").filter(archived=False).all(),
|
||||||
@ -230,9 +221,7 @@ class ClubMemberForm(forms.Form):
|
|||||||
id__in=[
|
id__in=[
|
||||||
ms.user.id
|
ms.user.id
|
||||||
for ms in self.club_members
|
for ms in self.club_members
|
||||||
if ms.can_be_edited_by(
|
if ms.can_be_edited_by(self.request_user)
|
||||||
self.request_user, self.request_user_membership
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
).all(),
|
).all(),
|
||||||
label=_("Mark as old"),
|
label=_("Mark as old"),
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.core.validators
|
import django.core.validators
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = []
|
dependencies = []
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
from django.conf import settings
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
("club", "0001_initial"),
|
("club", "0001_initial"),
|
||||||
|
@ -5,7 +5,6 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("club", "0002_auto_20160824_2152")]
|
dependencies = [("club", "0002_auto_20160824_2152")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
from django.conf import settings
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("club", "0003_auto_20160902_2042")]
|
dependencies = [("club", "0003_auto_20160902_2042")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("club", "0004_auto_20160915_1057")]
|
dependencies = [("club", "0004_auto_20160915_1057")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.utils.timezone
|
import django.utils.timezone
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("club", "0005_auto_20161120_1149")]
|
dependencies = [("club", "0005_auto_20161120_1149")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("club", "0006_auto_20161229_0040")]
|
dependencies = [("club", "0006_auto_20161229_0040")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -5,7 +5,6 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("club", "0007_auto_20170324_0917")]
|
dependencies = [("club", "0007_auto_20170324_0917")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
from django.conf import settings
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import django.core.validators
|
import django.core.validators
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
("club", "0008_auto_20170515_2214"),
|
("club", "0008_auto_20170515_2214"),
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
from club.models import Club
|
from club.models import Club
|
||||||
from core.operations import PsqlRunOnly
|
from core.operations import PsqlRunOnly
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
def generate_club_pages(apps, schema_editor):
|
def generate_club_pages(apps, schema_editor):
|
||||||
@ -19,7 +19,6 @@ def generate_club_pages(apps, schema_editor):
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("core", "0024_auto_20170906_1317"), ("club", "0010_club_logo")]
|
dependencies = [("core", "0024_auto_20170906_1317"), ("club", "0010_club_logo")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -5,7 +5,6 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("club", "0009_auto_20170822_2232")]
|
dependencies = [("club", "0009_auto_20170822_2232")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import club.models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import club.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("club", "0010_auto_20170912_2028")]
|
dependencies = [("club", "0010_auto_20170912_2028")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
259
club/models.py
@ -1,40 +1,37 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
# - Sli <antoine@bartuccio.fr>
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from django.db import models
|
|
||||||
from django.core import validators
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.core import validators
|
||||||
from django.core.exceptions import ValidationError, ObjectDoesNotExist
|
from django.core.cache import cache
|
||||||
from django.db import transaction
|
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||||
|
from django.core.validators import RegexValidator, validate_email
|
||||||
|
from django.db import models, transaction
|
||||||
|
from django.db.models import Q
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.core.validators import RegexValidator, validate_email
|
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from core.models import User, MetaGroup, Group, SithFile, RealGroup, Notification, Page
|
from core.models import Group, MetaGroup, Notification, Page, RealGroup, SithFile, User
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
@ -72,6 +69,7 @@ class Club(models.Model):
|
|||||||
_("short description"), max_length=1000, default="", blank=True, null=True
|
_("short description"), max_length=1000, default="", blank=True, null=True
|
||||||
)
|
)
|
||||||
address = models.CharField(_("address"), max_length=254)
|
address = models.CharField(_("address"), max_length=254)
|
||||||
|
|
||||||
# This function prevents generating migration upon settings change
|
# This function prevents generating migration upon settings change
|
||||||
def get_default_owner_group():
|
def get_default_owner_group():
|
||||||
return settings.SITH_GROUP_ROOT_ID
|
return settings.SITH_GROUP_ROOT_ID
|
||||||
@ -122,12 +120,22 @@ class Club(models.Model):
|
|||||||
def clean(self):
|
def clean(self):
|
||||||
self.check_loop()
|
self.check_loop()
|
||||||
|
|
||||||
def _change_unixname(self, new_name):
|
def _change_unixname(self, old_name, new_name):
|
||||||
c = Club.objects.filter(unix_name=new_name).first()
|
c = Club.objects.filter(unix_name=new_name).first()
|
||||||
if c is None:
|
if c is None:
|
||||||
|
# Update all the groups names
|
||||||
|
Group.objects.filter(name=old_name).update(name=new_name)
|
||||||
|
Group.objects.filter(name=old_name + settings.SITH_BOARD_SUFFIX).update(
|
||||||
|
name=new_name + settings.SITH_BOARD_SUFFIX
|
||||||
|
)
|
||||||
|
Group.objects.filter(name=old_name + settings.SITH_MEMBER_SUFFIX).update(
|
||||||
|
name=new_name + settings.SITH_MEMBER_SUFFIX
|
||||||
|
)
|
||||||
|
|
||||||
if self.home:
|
if self.home:
|
||||||
self.home.name = new_name
|
self.home.name = new_name
|
||||||
self.home.save()
|
self.home.save()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValidationError(_("A club with that unix_name already exists"))
|
raise ValidationError(_("A club with that unix_name already exists"))
|
||||||
|
|
||||||
@ -171,29 +179,34 @@ class Club(models.Model):
|
|||||||
self.page.parent = self.parent.page
|
self.page.parent = self.parent.page
|
||||||
self.page.save(force_lock=True)
|
self.page.save(force_lock=True)
|
||||||
|
|
||||||
|
@transaction.atomic()
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
with transaction.atomic():
|
old = Club.objects.filter(id=self.id).first()
|
||||||
creation = False
|
creation = old is None
|
||||||
old = Club.objects.filter(id=self.id).first()
|
if not creation and old.unix_name != self.unix_name:
|
||||||
if not old:
|
self._change_unixname(self.unix_name)
|
||||||
creation = True
|
super(Club, self).save(*args, **kwargs)
|
||||||
else:
|
if creation:
|
||||||
if old.unix_name != self.unix_name:
|
board = MetaGroup(name=self.unix_name + settings.SITH_BOARD_SUFFIX)
|
||||||
self._change_unixname(self.unix_name)
|
board.save()
|
||||||
super(Club, self).save(*args, **kwargs)
|
member = MetaGroup(name=self.unix_name + settings.SITH_MEMBER_SUFFIX)
|
||||||
if creation:
|
member.save()
|
||||||
board = MetaGroup(name=self.unix_name + settings.SITH_BOARD_SUFFIX)
|
subscribers = Group.objects.filter(
|
||||||
board.save()
|
name=settings.SITH_MAIN_MEMBERS_GROUP
|
||||||
member = MetaGroup(name=self.unix_name + settings.SITH_MEMBER_SUFFIX)
|
).first()
|
||||||
member.save()
|
self.make_home()
|
||||||
subscribers = Group.objects.filter(
|
self.home.edit_groups.set([board])
|
||||||
name=settings.SITH_MAIN_MEMBERS_GROUP
|
self.home.view_groups.set([member, subscribers])
|
||||||
).first()
|
self.home.save()
|
||||||
self.make_home()
|
self.make_page()
|
||||||
self.home.edit_groups.set([board])
|
cache.set(f"sith_club_{self.unix_name}", self)
|
||||||
self.home.view_groups.set([member, subscribers])
|
|
||||||
self.home.save()
|
def delete(self, *args, **kwargs):
|
||||||
self.make_page()
|
super().delete(*args, **kwargs)
|
||||||
|
# Invalidate the cache of this club and of its memberships
|
||||||
|
for membership in self.members.ongoing().select_related("user"):
|
||||||
|
cache.delete(f"membership_{self.id}_{membership.user.id}")
|
||||||
|
cache.delete(f"sith_club_{self.unix_name}")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -208,7 +221,9 @@ class Club(models.Model):
|
|||||||
"""
|
"""
|
||||||
Method to see if that object can be super edited by the given user
|
Method to see if that object can be super edited by the given user
|
||||||
"""
|
"""
|
||||||
return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP)
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user.is_board_member
|
||||||
|
|
||||||
def get_full_logo_url(self):
|
def get_full_logo_url(self):
|
||||||
return "https://%s%s" % (settings.SITH_URL, self.logo.url)
|
return "https://%s%s" % (settings.SITH_URL, self.logo.url)
|
||||||
@ -228,28 +243,89 @@ class Club(models.Model):
|
|||||||
return False
|
return False
|
||||||
return sub.was_subscribed
|
return sub.was_subscribed
|
||||||
|
|
||||||
_memberships = {}
|
def get_membership_for(self, user: User) -> Optional["Membership"]:
|
||||||
|
|
||||||
def get_membership_for(self, user):
|
|
||||||
"""
|
"""
|
||||||
Returns the current membership the given user
|
Return the current membership the given user.
|
||||||
|
The result is cached.
|
||||||
"""
|
"""
|
||||||
try:
|
if user.is_anonymous:
|
||||||
return Club._memberships[self.id][user.id]
|
return None
|
||||||
except:
|
membership = cache.get(f"membership_{self.id}_{user.id}")
|
||||||
m = self.members.filter(user=user.id).filter(end_date=None).first()
|
if membership == "not_member":
|
||||||
try:
|
return None
|
||||||
Club._memberships[self.id][user.id] = m
|
if membership is None:
|
||||||
except:
|
membership = self.members.filter(user=user, end_date=None).first()
|
||||||
Club._memberships[self.id] = {}
|
if membership is None:
|
||||||
Club._memberships[self.id][user.id] = m
|
cache.set(f"membership_{self.id}_{user.id}", "not_member")
|
||||||
return m
|
else:
|
||||||
|
cache.set(f"membership_{self.id}_{user.id}", membership)
|
||||||
|
return membership
|
||||||
|
|
||||||
def has_rights_in_club(self, user):
|
def has_rights_in_club(self, user):
|
||||||
m = self.get_membership_for(user)
|
m = self.get_membership_for(user)
|
||||||
return m is not None and m.role > settings.SITH_MAXIMUM_FREE_ROLE
|
return m is not None and m.role > settings.SITH_MAXIMUM_FREE_ROLE
|
||||||
|
|
||||||
|
|
||||||
|
class MembershipQuerySet(models.QuerySet):
|
||||||
|
def ongoing(self) -> "MembershipQuerySet":
|
||||||
|
"""
|
||||||
|
Filter all memberships which are not finished yet
|
||||||
|
"""
|
||||||
|
# noinspection PyTypeChecker
|
||||||
|
return self.filter(Q(end_date=None) | Q(end_date__gte=timezone.now()))
|
||||||
|
|
||||||
|
def board(self) -> "MembershipQuerySet":
|
||||||
|
"""
|
||||||
|
Filter all memberships where the user is/was in the board.
|
||||||
|
|
||||||
|
Be aware that users who were in the board in the past
|
||||||
|
are included, even if there are no more members.
|
||||||
|
|
||||||
|
If you want to get the users who are currently in the board,
|
||||||
|
mind combining this with the :meth:`ongoing` queryset method
|
||||||
|
"""
|
||||||
|
# noinspection PyTypeChecker
|
||||||
|
return self.filter(role__gt=settings.SITH_MAXIMUM_FREE_ROLE)
|
||||||
|
|
||||||
|
def update(self, **kwargs):
|
||||||
|
"""
|
||||||
|
Work just like the default Django's update() method,
|
||||||
|
but add a cache refresh for the elements of the queryset.
|
||||||
|
|
||||||
|
Be aware that this adds a db query to retrieve the updated objects
|
||||||
|
"""
|
||||||
|
nb_rows = super().update(**kwargs)
|
||||||
|
if nb_rows > 0:
|
||||||
|
# if at least a row was affected, refresh the cache
|
||||||
|
for membership in self.all():
|
||||||
|
if membership.end_date is not None:
|
||||||
|
cache.set(
|
||||||
|
f"membership_{membership.club_id}_{membership.user_id}",
|
||||||
|
"not_member",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
cache.set(
|
||||||
|
f"membership_{membership.club_id}_{membership.user_id}",
|
||||||
|
membership,
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
"""
|
||||||
|
Work just like the default Django's delete() method,
|
||||||
|
but add a cache invalidation for the elements of the queryset
|
||||||
|
before the deletion.
|
||||||
|
|
||||||
|
Be aware that this adds a db query to retrieve the deleted element.
|
||||||
|
As this first query take place before the deletion operation,
|
||||||
|
it will be performed even if the deletion fails.
|
||||||
|
"""
|
||||||
|
ids = list(self.values_list("club_id", "user_id"))
|
||||||
|
nb_rows, _ = super().delete()
|
||||||
|
if nb_rows > 0:
|
||||||
|
for club_id, user_id in ids:
|
||||||
|
cache.set(f"membership_{club_id}_{user_id}", "not_member")
|
||||||
|
|
||||||
|
|
||||||
class Membership(models.Model):
|
class Membership(models.Model):
|
||||||
"""
|
"""
|
||||||
The Membership class makes the connection between User and Clubs
|
The Membership class makes the connection between User and Clubs
|
||||||
@ -289,6 +365,8 @@ class Membership(models.Model):
|
|||||||
_("description"), max_length=128, null=False, blank=True
|
_("description"), max_length=128, null=False, blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
objects = MembershipQuerySet.as_manager()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return (
|
return (
|
||||||
self.club.name
|
self.club.name
|
||||||
@ -303,24 +381,34 @@ class Membership(models.Model):
|
|||||||
"""
|
"""
|
||||||
Method to see if that object can be super edited by the given user
|
Method to see if that object can be super edited by the given user
|
||||||
"""
|
"""
|
||||||
return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP)
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user.is_board_member
|
||||||
|
|
||||||
def can_be_edited_by(self, user, membership=None):
|
def can_be_edited_by(self, user: User) -> bool:
|
||||||
"""
|
"""
|
||||||
Method to see if that object can be edited by the given user
|
Check if that object can be edited by the given user
|
||||||
"""
|
"""
|
||||||
if user.memberships:
|
if user.is_root or user.is_board_member:
|
||||||
if membership: # This is for optimisation purpose
|
return True
|
||||||
ms = membership
|
membership = self.club.get_membership_for(user)
|
||||||
else:
|
if membership is not None and membership.role >= self.role:
|
||||||
ms = user.memberships.filter(club=self.club, end_date=None).first()
|
return True
|
||||||
return (ms and ms.role >= self.role) or user.is_in_group(
|
return False
|
||||||
settings.SITH_MAIN_BOARD_GROUP
|
|
||||||
)
|
|
||||||
return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP)
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse("club:club_members", kwargs={"club_id": self.club.id})
|
return reverse("club:club_members", kwargs={"club_id": self.club_id})
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
if self.end_date is None:
|
||||||
|
cache.set(f"membership_{self.club_id}_{self.user_id}", self)
|
||||||
|
else:
|
||||||
|
cache.set(f"membership_{self.club_id}_{self.user_id}", "not_member")
|
||||||
|
|
||||||
|
def delete(self, *args, **kwargs):
|
||||||
|
super().delete(*args, **kwargs)
|
||||||
|
cache.delete(f"membership_{self.club_id}_{self.user_id}")
|
||||||
|
|
||||||
|
|
||||||
class Mailing(models.Model):
|
class Mailing(models.Model):
|
||||||
@ -373,14 +461,12 @@ class Mailing(models.Model):
|
|||||||
return self.email + "@" + settings.SITH_MAILING_DOMAIN
|
return self.email + "@" + settings.SITH_MAILING_DOMAIN
|
||||||
|
|
||||||
def can_moderate(self, user):
|
def can_moderate(self, user):
|
||||||
return user.is_root or user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
return user.is_root or user.is_com_admin
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
return (
|
if user.is_anonymous:
|
||||||
user.is_in_group(self)
|
return False
|
||||||
or user.is_root
|
return user.is_root or user.is_com_admin
|
||||||
or user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
|
||||||
)
|
|
||||||
|
|
||||||
def can_view(self, user):
|
def can_view(self, user):
|
||||||
return self.club.has_rights_in_club(user)
|
return self.club.has_rights_in_club(user)
|
||||||
@ -388,9 +474,8 @@ class Mailing(models.Model):
|
|||||||
def can_be_edited_by(self, user):
|
def can_be_edited_by(self, user):
|
||||||
return self.club.has_rights_in_club(user)
|
return self.club.has_rights_in_club(user)
|
||||||
|
|
||||||
def delete(self):
|
def delete(self, *args, **kwargs):
|
||||||
for sub in self.subscriptions.all():
|
self.subscriptions.all().delete()
|
||||||
sub.delete()
|
|
||||||
super(Mailing, self).delete()
|
super(Mailing, self).delete()
|
||||||
|
|
||||||
def fetch_format(self):
|
def fetch_format(self):
|
||||||
@ -463,10 +548,12 @@ class MailingSubscription(models.Model):
|
|||||||
super(MailingSubscription, self).clean()
|
super(MailingSubscription, self).clean()
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
return (
|
return (
|
||||||
self.mailing.club.has_rights_in_club(user)
|
self.mailing.club.has_rights_in_club(user)
|
||||||
or user.is_root
|
or user.is_root
|
||||||
or self.user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
or self.user.is_com_admin
|
||||||
)
|
)
|
||||||
|
|
||||||
def can_be_edited_by(self, user):
|
def can_be_edited_by(self, user):
|
||||||
|
@ -13,13 +13,15 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<td>{% trans %}User{% endtrans %}</td>
|
<tr>
|
||||||
<td>{% trans %}Role{% endtrans %}</td>
|
<td>{% trans %}User{% endtrans %}</td>
|
||||||
<td>{% trans %}Description{% endtrans %}</td>
|
<td>{% trans %}Role{% endtrans %}</td>
|
||||||
<td>{% trans %}Since{% endtrans %}</td>
|
<td>{% trans %}Description{% endtrans %}</td>
|
||||||
{% if users_old %}
|
<td>{% trans %}Since{% endtrans %}</td>
|
||||||
<td>{% trans %}Mark as old{% endtrans %}</td>
|
{% if users_old %}
|
||||||
{% endif %}
|
<td>{% trans %}Mark as old{% endtrans %}</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for m in members %}
|
{% for m in members %}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{% from 'core/macros.jinja' import user_profile_link, paginate %}
|
{% from 'core/macros.jinja' import user_profile_link, paginate %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h3>{% trans %}Sellings{% endtrans %}</h3>
|
<h3>{% trans %}Sales{% endtrans %}</h3>
|
||||||
<form id="form" action="?page=1" method="post">
|
<form id="form" action="?page=1" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form }}
|
{{ form }}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
{% if object.club_account.exists() %}
|
{% if object.club_account.exists() %}
|
||||||
<h4>{% trans %}Accouting: {% endtrans %}</h4>
|
<h4>{% trans %}Accounting: {% endtrans %}</h4>
|
||||||
<ul>
|
<ul>
|
||||||
{% for ca in object.club_account.all() %}
|
{% for ca in object.club_account.all() %}
|
||||||
<li><a href="{{ url('accounting:club_details', c_account_id=ca.id) }}">{{ ca.get_display_name() }}</a></li>
|
<li><a href="{{ url('accounting:club_details', c_account_id=ca.id) }}">{{ ca.get_display_name() }}</a></li>
|
||||||
|
1080
club/tests.py
117
club/urls.py
@ -1,116 +1,101 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
# - Sli <antoine@bartuccio.fr>
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.urls import re_path
|
from django.urls import path
|
||||||
|
|
||||||
from club.views import *
|
from club.views import *
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
re_path(r"^$", ClubListView.as_view(), name="club_list"),
|
path("", ClubListView.as_view(), name="club_list"),
|
||||||
re_path(r"^new$", ClubCreateView.as_view(), name="club_new"),
|
path("new/", ClubCreateView.as_view(), name="club_new"),
|
||||||
re_path(r"^stats$", ClubStatView.as_view(), name="club_stats"),
|
path("stats/", ClubStatView.as_view(), name="club_stats"),
|
||||||
re_path(r"^(?P<club_id>[0-9]+)/$", ClubView.as_view(), name="club_view"),
|
path("<int:club_id>/", ClubView.as_view(), name="club_view"),
|
||||||
re_path(
|
path(
|
||||||
r"^(?P<club_id>[0-9]+)/rev/(?P<rev_id>[0-9]+)/$",
|
"<int:club_id>/rev/<int:rev_id>/",
|
||||||
ClubRevView.as_view(),
|
ClubRevView.as_view(),
|
||||||
name="club_view_rev",
|
name="club_view_rev",
|
||||||
),
|
),
|
||||||
re_path(
|
path("<int:club_id>/hist/", ClubPageHistView.as_view(), name="club_hist"),
|
||||||
r"^(?P<club_id>[0-9]+)/hist$", ClubPageHistView.as_view(), name="club_hist"
|
path("<int:club_id>/edit/", ClubEditView.as_view(), name="club_edit"),
|
||||||
),
|
path(
|
||||||
re_path(r"^(?P<club_id>[0-9]+)/edit$", ClubEditView.as_view(), name="club_edit"),
|
"<int:club_id>/edit/page/",
|
||||||
re_path(
|
|
||||||
r"^(?P<club_id>[0-9]+)/edit/page$",
|
|
||||||
ClubPageEditView.as_view(),
|
ClubPageEditView.as_view(),
|
||||||
name="club_edit_page",
|
name="club_edit_page",
|
||||||
),
|
),
|
||||||
re_path(
|
path("<int:club_id>/members/", ClubMembersView.as_view(), name="club_members"),
|
||||||
r"^(?P<club_id>[0-9]+)/members$", ClubMembersView.as_view(), name="club_members"
|
path(
|
||||||
),
|
"<int:club_id>/elderlies/",
|
||||||
re_path(
|
|
||||||
r"^(?P<club_id>[0-9]+)/elderlies$",
|
|
||||||
ClubOldMembersView.as_view(),
|
ClubOldMembersView.as_view(),
|
||||||
name="club_old_members",
|
name="club_old_members",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^(?P<club_id>[0-9]+)/sellings$",
|
"<int:club_id>/sellings/",
|
||||||
ClubSellingView.as_view(),
|
ClubSellingView.as_view(),
|
||||||
name="club_sellings",
|
name="club_sellings",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^(?P<club_id>[0-9]+)/sellings/csv$",
|
"<int:club_id>/sellings/csv/",
|
||||||
ClubSellingCSVView.as_view(),
|
ClubSellingCSVView.as_view(),
|
||||||
name="sellings_csv",
|
name="sellings_csv",
|
||||||
),
|
),
|
||||||
re_path(
|
path("<int:club_id>/prop/", ClubEditPropView.as_view(), name="club_prop"),
|
||||||
r"^(?P<club_id>[0-9]+)/prop$", ClubEditPropView.as_view(), name="club_prop"
|
path("<int:club_id>/tools/", ClubToolsView.as_view(), name="tools"),
|
||||||
),
|
path("<int:club_id>/mailing/", ClubMailingView.as_view(), name="mailing"),
|
||||||
re_path(r"^(?P<club_id>[0-9]+)/tools$", ClubToolsView.as_view(), name="tools"),
|
path(
|
||||||
re_path(
|
"<int:mailing_id>/mailing/generate/",
|
||||||
r"^(?P<club_id>[0-9]+)/mailing$", ClubMailingView.as_view(), name="mailing"
|
|
||||||
),
|
|
||||||
re_path(
|
|
||||||
r"^(?P<mailing_id>[0-9]+)/mailing/generate$",
|
|
||||||
MailingAutoGenerationView.as_view(),
|
MailingAutoGenerationView.as_view(),
|
||||||
name="mailing_generate",
|
name="mailing_generate",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^(?P<mailing_id>[0-9]+)/mailing/delete$",
|
"<int:mailing_id>/mailing/delete/",
|
||||||
MailingDeleteView.as_view(),
|
MailingDeleteView.as_view(),
|
||||||
name="mailing_delete",
|
name="mailing_delete",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^(?P<mailing_subscription_id>[0-9]+)/mailing/delete/subscription$",
|
"<int:mailing_subscription_id>/mailing/delete/subscription/",
|
||||||
MailingSubscriptionDeleteView.as_view(),
|
MailingSubscriptionDeleteView.as_view(),
|
||||||
name="mailing_subscription_delete",
|
name="mailing_subscription_delete",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^membership/(?P<membership_id>[0-9]+)/set_old$",
|
"membership/<int:membership_id>/set_old/",
|
||||||
MembershipSetOldView.as_view(),
|
MembershipSetOldView.as_view(),
|
||||||
name="membership_set_old",
|
name="membership_set_old",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^membership/(?P<membership_id>[0-9]+)/delete$",
|
"membership/<int:membership_id>/delete/",
|
||||||
MembershipDeleteView.as_view(),
|
MembershipDeleteView.as_view(),
|
||||||
name="membership_delete",
|
name="membership_delete",
|
||||||
),
|
),
|
||||||
re_path(
|
path("<int:club_id>/poster/", PosterListView.as_view(), name="poster_list"),
|
||||||
r"^(?P<club_id>[0-9]+)/poster$", PosterListView.as_view(), name="poster_list"
|
path(
|
||||||
),
|
"<int:club_id>/poster/create/",
|
||||||
re_path(
|
|
||||||
r"^(?P<club_id>[0-9]+)/poster/create$",
|
|
||||||
PosterCreateView.as_view(),
|
PosterCreateView.as_view(),
|
||||||
name="poster_create",
|
name="poster_create",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^(?P<club_id>[0-9]+)/poster/(?P<poster_id>[0-9]+)/edit$",
|
"<int:club_id>/poster/<int:poster_id>/edit/",
|
||||||
PosterEditView.as_view(),
|
PosterEditView.as_view(),
|
||||||
name="poster_edit",
|
name="poster_edit",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^(?P<club_id>[0-9]+)/poster/(?P<poster_id>[0-9]+)/delete$",
|
"<int:club_id>/poster/<int:poster_id>/delete/",
|
||||||
PosterDeleteView.as_view(),
|
PosterDeleteView.as_view(),
|
||||||
name="poster_delete",
|
name="poster_delete",
|
||||||
),
|
),
|
||||||
|
100
club/views.py
@ -1,75 +1,62 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
# - Sli <antoine@bartuccio.fr>
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django import forms
|
from django.core.exceptions import NON_FIELD_ERRORS, PermissionDenied, ValidationError
|
||||||
from django.views.generic import ListView, DetailView, TemplateView, View
|
from django.core.paginator import InvalidPage, Paginator
|
||||||
from django.views.generic.edit import DeleteView
|
from django.db.models import Sum
|
||||||
from django.views.generic.detail import SingleObjectMixin
|
|
||||||
from django.views.generic.edit import UpdateView, CreateView
|
|
||||||
from django.http import (
|
from django.http import (
|
||||||
HttpResponseRedirect,
|
|
||||||
HttpResponse,
|
|
||||||
Http404,
|
Http404,
|
||||||
|
HttpResponseRedirect,
|
||||||
StreamingHttpResponse,
|
StreamingHttpResponse,
|
||||||
)
|
)
|
||||||
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
from django.utils.translation import gettext as _t
|
from django.utils.translation import gettext as _t
|
||||||
from django.core.exceptions import PermissionDenied, ValidationError, NON_FIELD_ERRORS
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.core.paginator import Paginator, InvalidPage
|
from django.views.generic import DetailView, ListView, TemplateView, View
|
||||||
from django.shortcuts import get_object_or_404, redirect
|
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
||||||
from django.db.models import Sum
|
|
||||||
|
|
||||||
|
from club.forms import ClubEditForm, ClubMemberForm, MailingForm, SellingsForm
|
||||||
from core.views import (
|
from club.models import Club, Mailing, MailingSubscription, Membership
|
||||||
CanCreateMixin,
|
from com.views import (
|
||||||
CanViewMixin,
|
PosterCreateBaseView,
|
||||||
CanEditMixin,
|
PosterDeleteBaseView,
|
||||||
CanEditPropMixin,
|
PosterEditBaseView,
|
||||||
UserIsRootMixin,
|
PosterListBaseView,
|
||||||
TabedViewMixin,
|
|
||||||
PageEditViewBase,
|
|
||||||
DetailFormView,
|
|
||||||
)
|
)
|
||||||
from core.models import PageRev
|
from core.models import PageRev
|
||||||
|
from core.views import (
|
||||||
from counter.models import Selling
|
CanCreateMixin,
|
||||||
|
CanEditMixin,
|
||||||
from com.views import (
|
CanEditPropMixin,
|
||||||
PosterListBaseView,
|
CanViewMixin,
|
||||||
PosterCreateBaseView,
|
DetailFormView,
|
||||||
PosterEditBaseView,
|
PageEditViewBase,
|
||||||
PosterDeleteBaseView,
|
TabedViewMixin,
|
||||||
|
UserIsRootMixin,
|
||||||
)
|
)
|
||||||
|
from counter.models import Selling
|
||||||
from club.models import Club, Membership, Mailing, MailingSubscription
|
|
||||||
from club.forms import MailingForm, ClubEditForm, ClubMemberForm, SellingsForm
|
|
||||||
|
|
||||||
|
|
||||||
class ClubTabsMixin(TabedViewMixin):
|
class ClubTabsMixin(TabedViewMixin):
|
||||||
@ -306,9 +293,7 @@ class ClubMembersView(ClubTabsMixin, CanViewMixin, DetailFormView):
|
|||||||
return resp
|
return resp
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
self.members = (
|
self.members = self.get_object().members.ongoing().order_by("-role")
|
||||||
self.get_object().members.filter(end_date=None).order_by("-role").all()
|
|
||||||
)
|
|
||||||
return super(ClubMembersView, self).dispatch(request, *args, **kwargs)
|
return super(ClubMembersView, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_success_url(self, **kwargs):
|
def get_success_url(self, **kwargs):
|
||||||
@ -443,7 +428,6 @@ class ClubSellingCSVView(ClubSellingView):
|
|||||||
return row
|
return row
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
kwargs = self.get_context_data(**kwargs)
|
kwargs = self.get_context_data(**kwargs)
|
||||||
|
|
||||||
@ -614,7 +598,7 @@ class ClubMailingView(ClubTabsMixin, CanEditMixin, DetailFormView):
|
|||||||
}
|
}
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def add_new_mailing(self, cleaned_data) -> ValidationError:
|
def add_new_mailing(self, cleaned_data) -> ValidationError | None:
|
||||||
"""
|
"""
|
||||||
Create a new mailing list from the form
|
Create a new mailing list from the form
|
||||||
"""
|
"""
|
||||||
@ -631,7 +615,7 @@ class ClubMailingView(ClubTabsMixin, CanEditMixin, DetailFormView):
|
|||||||
mailing.save()
|
mailing.save()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def add_new_subscription(self, cleaned_data) -> ValidationError:
|
def add_new_subscription(self, cleaned_data) -> ValidationError | None:
|
||||||
"""
|
"""
|
||||||
Add mailing subscriptions for each user given and/or for the specified email in form
|
Add mailing subscriptions for each user given and/or for the specified email in form
|
||||||
"""
|
"""
|
||||||
@ -706,7 +690,6 @@ class ClubMailingView(ClubTabsMixin, CanEditMixin, DetailFormView):
|
|||||||
|
|
||||||
|
|
||||||
class MailingDeleteView(CanEditMixin, DeleteView):
|
class MailingDeleteView(CanEditMixin, DeleteView):
|
||||||
|
|
||||||
model = Mailing
|
model = Mailing
|
||||||
template_name = "core/delete_confirm.jinja"
|
template_name = "core/delete_confirm.jinja"
|
||||||
pk_url_kwarg = "mailing_id"
|
pk_url_kwarg = "mailing_id"
|
||||||
@ -724,7 +707,6 @@ class MailingDeleteView(CanEditMixin, DeleteView):
|
|||||||
|
|
||||||
|
|
||||||
class MailingSubscriptionDeleteView(CanEditMixin, DeleteView):
|
class MailingSubscriptionDeleteView(CanEditMixin, DeleteView):
|
||||||
|
|
||||||
model = MailingSubscription
|
model = MailingSubscription
|
||||||
template_name = "core/delete_confirm.jinja"
|
template_name = "core/delete_confirm.jinja"
|
||||||
pk_url_kwarg = "mailing_subscription_id"
|
pk_url_kwarg = "mailing_subscription_id"
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
56
com/admin.py
@ -1,43 +1,53 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
#
|
from ajax_select import make_ajax_form
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from haystack.admin import SearchModelAdmin
|
from haystack.admin import SearchModelAdmin
|
||||||
|
|
||||||
from com.models import *
|
from com.models import *
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(News)
|
||||||
class NewsAdmin(SearchModelAdmin):
|
class NewsAdmin(SearchModelAdmin):
|
||||||
search_fields = ["title", "summary", "content"]
|
list_display = ("title", "type", "club", "author")
|
||||||
|
search_fields = ("title", "summary", "content")
|
||||||
|
form = make_ajax_form(
|
||||||
|
News,
|
||||||
|
{
|
||||||
|
"author": "users",
|
||||||
|
"moderator": "users",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Poster)
|
||||||
|
class PosterAdmin(SearchModelAdmin):
|
||||||
|
list_display = ("name", "club", "date_begin", "date_end", "moderator")
|
||||||
|
form = make_ajax_form(Poster, {"moderator": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Weekmail)
|
||||||
class WeekmailAdmin(SearchModelAdmin):
|
class WeekmailAdmin(SearchModelAdmin):
|
||||||
search_fields = ["title"]
|
list_display = ("title", "sent")
|
||||||
|
search_fields = ("title",)
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Sith)
|
admin.site.register(Sith)
|
||||||
admin.site.register(News, NewsAdmin)
|
|
||||||
admin.site.register(Weekmail, WeekmailAdmin)
|
|
||||||
admin.site.register(Screen)
|
admin.site.register(Screen)
|
||||||
admin.site.register(Poster)
|
|
||||||
|
@ -5,7 +5,6 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = []
|
dependencies = []
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
from django.conf import settings
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("club", "0005_auto_20161120_1149"),
|
("club", "0005_auto_20161120_1149"),
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
from django.conf import settings
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("club", "0006_auto_20161229_0040"),
|
("club", "0006_auto_20161229_0040"),
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
import django.db.models.deletion
|
||||||
import django.utils.timezone
|
import django.utils.timezone
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import django.db.models.deletion
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("club", "0010_auto_20170912_2028"),
|
("club", "0010_auto_20170912_2028"),
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
@ -5,7 +5,6 @@ from django.db import migrations, models
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("com", "0004_auto_20171221_1614")]
|
dependencies = [("com", "0004_auto_20171221_1614")]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -6,7 +6,6 @@ from django.db import migrations
|
|||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [("com", "0005_auto_20180318_2227")]
|
dependencies = [("com", "0005_auto_20180318_2227")]
|
||||||
|
|
||||||
operations = [migrations.RemoveField(model_name="sith", name="index_page")]
|
operations = [migrations.RemoveField(model_name="sith", name="index_page")]
|
||||||
|
105
com/models.py
@ -1,43 +1,37 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
# - Sli <antoine@bartuccio.fr>
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.shortcuts import render
|
from django.conf import settings
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.core.mail import EmailMultiAlternatives
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.shortcuts import render
|
||||||
from django.utils import timezone
|
|
||||||
from django.urls import reverse
|
|
||||||
from django.conf import settings
|
|
||||||
from django.templatetags.static import static
|
from django.templatetags.static import static
|
||||||
from django.core.mail import EmailMultiAlternatives
|
from django.urls import reverse
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from core.models import User, Preferences, RealGroup, Notification, SithFile
|
|
||||||
from club.models import Club
|
from club.models import Club
|
||||||
|
from core import utils
|
||||||
|
from core.models import Notification, Preferences, RealGroup, User
|
||||||
|
|
||||||
|
|
||||||
class Sith(models.Model):
|
class Sith(models.Model):
|
||||||
@ -46,9 +40,12 @@ class Sith(models.Model):
|
|||||||
alert_msg = models.TextField(_("alert message"), default="", blank=True)
|
alert_msg = models.TextField(_("alert message"), default="", blank=True)
|
||||||
info_msg = models.TextField(_("info message"), default="", blank=True)
|
info_msg = models.TextField(_("info message"), default="", blank=True)
|
||||||
weekmail_destinations = models.TextField(_("weekmail destinations"), default="")
|
weekmail_destinations = models.TextField(_("weekmail destinations"), default="")
|
||||||
|
version = utils.get_git_revision_short_hash()
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
return user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user.is_com_admin
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "⛩ Sith ⛩"
|
return "⛩ Sith ⛩"
|
||||||
@ -61,11 +58,6 @@ NEWS_TYPES = [
|
|||||||
("CALL", _("Call")),
|
("CALL", _("Call")),
|
||||||
]
|
]
|
||||||
|
|
||||||
WEEKMAIL_TYPE = [
|
|
||||||
("WEEKMAIL", _("Weekmail")),
|
|
||||||
("INVITATION", _("Invitation")),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class News(models.Model):
|
class News(models.Model):
|
||||||
"""The news class"""
|
"""The news class"""
|
||||||
@ -95,13 +87,15 @@ class News(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
return user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) or user == self.author
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user.is_com_admin or user == self.author
|
||||||
|
|
||||||
def can_be_edited_by(self, user):
|
def can_be_edited_by(self, user):
|
||||||
return user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
return user.is_com_admin
|
||||||
|
|
||||||
def can_be_viewed_by(self, user):
|
def can_be_viewed_by(self, user):
|
||||||
return self.is_moderated or user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
return self.is_moderated or user.is_com_admin
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse("com:news_detail", kwargs={"news_id": self.id})
|
return reverse("com:news_detail", kwargs={"news_id": self.id})
|
||||||
@ -183,9 +177,6 @@ class Weekmail(models.Model):
|
|||||||
protip = models.TextField(_("protip"), blank=True)
|
protip = models.TextField(_("protip"), blank=True)
|
||||||
conclusion = models.TextField(_("conclusion"), blank=True)
|
conclusion = models.TextField(_("conclusion"), blank=True)
|
||||||
sent = models.BooleanField(_("sent"), default=False)
|
sent = models.BooleanField(_("sent"), default=False)
|
||||||
type = models.CharField(
|
|
||||||
_("type"), max_length=16, choices=WEEKMAIL_TYPE, default="WEEKMAIL"
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ["-id"]
|
ordering = ["-id"]
|
||||||
@ -223,17 +214,6 @@ class Weekmail(models.Model):
|
|||||||
None, "com/weekmail_renderer_text.jinja", context={"weekmail": self}
|
None, "com/weekmail_renderer_text.jinja", context={"weekmail": self}
|
||||||
).content.decode("utf-8")
|
).content.decode("utf-8")
|
||||||
|
|
||||||
def switch_type(self):
|
|
||||||
"""
|
|
||||||
Switch the type of weekmail we are sending :
|
|
||||||
- a simple weekmail
|
|
||||||
- or an invitation
|
|
||||||
"""
|
|
||||||
if self.type == "INVITATION":
|
|
||||||
self.type = "WEEKMAIL"
|
|
||||||
else:
|
|
||||||
self.type = "INVITATION"
|
|
||||||
|
|
||||||
def render_html(self):
|
def render_html(self):
|
||||||
"""
|
"""
|
||||||
Renders an HTML version of the mail with images and fancy CSS.
|
Renders an HTML version of the mail with images and fancy CSS.
|
||||||
@ -246,15 +226,10 @@ class Weekmail(models.Model):
|
|||||||
"""
|
"""
|
||||||
Return an absolute link to the banner.
|
Return an absolute link to the banner.
|
||||||
"""
|
"""
|
||||||
if self.type == "INVITATION":
|
|
||||||
return (
|
|
||||||
"http://" + settings.SITH_URL + static("com/img/invitation_bannerP22.png")
|
|
||||||
)
|
|
||||||
return (
|
return (
|
||||||
"http://" + settings.SITH_URL + static("com/img/weekmail_bannerV2P22.png")
|
"http://" + settings.SITH_URL + static("com/img/weekmail_bannerV2P22.png")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_footer(self):
|
def get_footer(self):
|
||||||
"""
|
"""
|
||||||
Return an absolute link to the footer.
|
Return an absolute link to the footer.
|
||||||
@ -265,7 +240,9 @@ class Weekmail(models.Model):
|
|||||||
return "Weekmail %s (sent: %s) - %s" % (self.id, self.sent, self.title)
|
return "Weekmail %s (sent: %s) - %s" % (self.id, self.sent, self.title)
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
return user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user.is_com_admin
|
||||||
|
|
||||||
|
|
||||||
class WeekmailArticle(models.Model):
|
class WeekmailArticle(models.Model):
|
||||||
@ -293,7 +270,9 @@ class WeekmailArticle(models.Model):
|
|||||||
rank = models.IntegerField(_("rank"), default=-1)
|
rank = models.IntegerField(_("rank"), default=-1)
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
return user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user.is_com_admin
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s - %s (%s)" % (self.title, self.author, self.club)
|
return "%s - %s (%s)" % (self.title, self.author, self.club)
|
||||||
@ -309,7 +288,9 @@ class Screen(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
return user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
if user.is_anonymous:
|
||||||
|
return False
|
||||||
|
return user.is_com_admin
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s" % (self.name)
|
return "%s" % (self.name)
|
||||||
@ -362,12 +343,12 @@ class Poster(models.Model):
|
|||||||
raise ValidationError(_("Begin date should be before end date"))
|
raise ValidationError(_("Begin date should be before end date"))
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
return user.is_in_group(
|
if user.is_anonymous:
|
||||||
settings.SITH_GROUP_COM_ADMIN_ID
|
return False
|
||||||
) or Club.objects.filter(id__in=user.clubs_with_rights)
|
return user.is_com_admin or len(user.clubs_with_rights) > 0
|
||||||
|
|
||||||
def can_be_moderated_by(self, user):
|
def can_be_moderated_by(self, user):
|
||||||
return user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
return user.is_com_admin
|
||||||
|
|
||||||
def get_display_name(self):
|
def get_display_name(self):
|
||||||
return self.club.get_display_name()
|
return self.club.get_display_name()
|
||||||
|
@ -35,11 +35,11 @@
|
|||||||
<p>{% trans %}Author: {% endtrans %}{{ user_profile_link(news.author) }}</p>
|
<p>{% trans %}Author: {% endtrans %}{{ user_profile_link(news.author) }}</p>
|
||||||
{% if news.moderator %}
|
{% if news.moderator %}
|
||||||
<p>{% trans %}Moderator: {% endtrans %}{{ user_profile_link(news.moderator) }}</p>
|
<p>{% trans %}Moderator: {% endtrans %}{{ user_profile_link(news.moderator) }}</p>
|
||||||
{% elif user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) %}
|
{% elif user.is_com_admin %}
|
||||||
<p> <a href="{{ url('com:news_moderate', news_id=news.id) }}">{% trans %}Moderate{% endtrans %}</a></p>
|
<p> <a href="{{ url('com:news_moderate', news_id=news.id) }}">{% trans %}Moderate{% endtrans %}</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.can_edit(news) %}
|
{% if user.can_edit(news) %}
|
||||||
<p> <a href="{{ url('com:news_edit', news_id=news.id) }}">{% trans %}Edit (will be remoderated){% endtrans %}</a></p>
|
<p> <a href="{{ url('com:news_edit', news_id=news.id) }}">{% trans %}Edit (will be moderated again){% endtrans %}</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
<p>{{ form.club.errors }}<label for="{{ form.club.name }}">{{ form.club.label }}</label> {{ form.club }}</p>
|
<p>{{ form.club.errors }}<label for="{{ form.club.name }}">{{ form.club.label }}</label> {{ form.club }}</p>
|
||||||
<p>{{ form.summary.errors }}<label for="{{ form.summary.name }}">{{ form.summary.label }}</label> {{ form.summary }}</p>
|
<p>{{ form.summary.errors }}<label for="{{ form.summary.name }}">{{ form.summary.label }}</label> {{ form.summary }}</p>
|
||||||
<p>{{ form.content.errors }}<label for="{{ form.content.name }}">{{ form.content.label }}</label> {{ form.content }}</p>
|
<p>{{ form.content.errors }}<label for="{{ form.content.name }}">{{ form.content.label }}</label> {{ form.content }}</p>
|
||||||
{% if user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) %}
|
{% if user.is_com_admin %}
|
||||||
<p>{{ form.automoderation.errors }}<label for="{{ form.automoderation.name }}">{{ form.automoderation.label }}</label>
|
<p>{{ form.automoderation.errors }}<label for="{{ form.automoderation.name }}">{{ form.automoderation.label }}</label>
|
||||||
{{ form.automoderation }}</p>
|
{{ form.automoderation }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -6,15 +6,15 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) %}
|
{% if user.is_com_admin %}
|
||||||
<div id="news_admin">
|
<div id="news_admin">
|
||||||
<a href="{{ url('com:news_admin_list') }}">{% trans %}Administrate news{% endtrans %}</a>
|
<a class="button" href="{{ url('com:news_admin_list') }}">{% trans %}Administrate news{% endtrans %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
<br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div id="news">
|
<div id="news">
|
||||||
<div id="left_column" class="news_column">
|
<div id="left_column" class="news_column">
|
||||||
|
|
||||||
{% for news in object_list.filter(type="NOTICE") %}
|
{% for news in object_list.filter(type="NOTICE") %}
|
||||||
<section class="news_notice">
|
<section class="news_notice">
|
||||||
<h4><a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4>
|
<h4><a href="{{ url('com:news_detail', news_id=news.id) }}">{{ news.title }}</a></h4>
|
||||||
@ -97,6 +97,15 @@
|
|||||||
</section>
|
</section>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<h3>{% trans %}All coming events{% endtrans %}</h3>
|
||||||
|
<iframe
|
||||||
|
src="https://embed.styledcalendar.com/#2mF2is8CEXhr4ADcX6qN"
|
||||||
|
title="Styled Calendar"
|
||||||
|
class="styled-calendar-container"
|
||||||
|
style="width: 100%; border: none; height: 1060px"
|
||||||
|
data-cy="calendar-embed-iframe">
|
||||||
|
</iframe>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="right_column" class="news_column">
|
<div id="right_column" class="news_column">
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<div id="progress_bar"></div>
|
<div id="progress_bar"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<script src="{{ static('core/js/jquery-3.1.0.min.js') }}"></script>
|
<script src="{{ static('core/js/jquery-3.6.2.min.js') }}"></script>
|
||||||
<script src="{{ static('com/js/slideshow.js') }}"></script>
|
<script src="{{ static('com/js/slideshow.js') }}"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
<p><a href="{{ url('com:weekmail_preview') }}">{% trans %}Preview{% endtrans %}</a></p>
|
<p><a href="{{ url('com:weekmail_preview') }}">{% trans %}Preview{% endtrans %}</a></p>
|
||||||
<p><a href="{{ url('com:weekmail_preview') }}?send=true">{% trans %}Send{% endtrans %}</a></p>
|
<p><a href="{{ url('com:weekmail_preview') }}?send=true">{% trans %}Send{% endtrans %}</a></p>
|
||||||
<p><a href="{{ url('com:weekmail_article') }}">{% trans %}New article{% endtrans %}</a></p>
|
<p><a href="{{ url('com:weekmail_article') }}">{% trans %}New article{% endtrans %}</a></p>
|
||||||
<p><a href="{{ url('com:weekmail') }}" onclick="{{weekmail.switch_type()}}">{% trans %}Switch invitation/weekmail{% endtrans %}</a></p>
|
|
||||||
<h4>{% trans %}Articles in no weekmail yet{% endtrans %}</h4>
|
<h4>{% trans %}Articles in no weekmail yet{% endtrans %}</h4>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
228
com/tests.py
@ -1,73 +1,69 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
#
|
import pytest
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.core.management import call_command
|
|
||||||
from django.utils import html
|
from django.utils import html
|
||||||
|
from django.utils.timezone import localtime, now
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
|
from club.models import Club, Membership
|
||||||
from core.models import User, RealGroup
|
from com.models import News, Poster, Sith, Weekmail, WeekmailArticle
|
||||||
|
from core.models import AnonymousUser, RealGroup, User
|
||||||
|
|
||||||
|
|
||||||
class ComAlertTest(TestCase):
|
@pytest.fixture()
|
||||||
def setUp(self):
|
def user_community():
|
||||||
call_command("populate")
|
return User.objects.get(username="comunity")
|
||||||
|
|
||||||
def test_page_is_working(self):
|
|
||||||
self.client.login(username="comunity", password="plop")
|
|
||||||
response = self.client.get(reverse("com:alert_edit"))
|
|
||||||
self.assertNotEqual(response.status_code, 500)
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
|
|
||||||
|
|
||||||
class ComInfoTest(TestCase):
|
@pytest.mark.django_db
|
||||||
def setUp(self):
|
@pytest.mark.parametrize(
|
||||||
call_command("populate")
|
"url",
|
||||||
|
[
|
||||||
def test_page_is_working(self):
|
reverse("com:alert_edit"),
|
||||||
self.client.login(username="comunity", password="plop")
|
reverse("com:info_edit"),
|
||||||
response = self.client.get(reverse("com:info_edit"))
|
],
|
||||||
self.assertNotEqual(response.status_code, 500)
|
)
|
||||||
self.assertEqual(response.status_code, 200)
|
def test_com_page_is_working(client, url, user_community):
|
||||||
|
client.force_login(user_community)
|
||||||
|
response = client.get(url)
|
||||||
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
class ComTest(TestCase):
|
class ComTest(TestCase):
|
||||||
def setUp(self):
|
@classmethod
|
||||||
call_command("populate")
|
def setUpTestData(cls):
|
||||||
self.skia = User.objects.filter(username="skia").first()
|
cls.skia = User.objects.get(username="skia")
|
||||||
self.com_group = RealGroup.objects.filter(
|
cls.com_group = RealGroup.objects.filter(
|
||||||
id=settings.SITH_GROUP_COM_ADMIN_ID
|
id=settings.SITH_GROUP_COM_ADMIN_ID
|
||||||
).first()
|
).first()
|
||||||
self.skia.groups.set([self.com_group])
|
cls.skia.groups.set([cls.com_group])
|
||||||
self.skia.save()
|
|
||||||
self.client.login(username=self.skia.username, password="plop")
|
def setUp(self):
|
||||||
|
self.client.force_login(self.skia)
|
||||||
|
|
||||||
def test_alert_msg(self):
|
def test_alert_msg(self):
|
||||||
response = self.client.post(
|
self.client.post(
|
||||||
reverse("com:alert_edit"),
|
reverse("com:alert_edit"),
|
||||||
{
|
{
|
||||||
"alert_msg": """
|
"alert_msg": """
|
||||||
@ -78,16 +74,15 @@ class ComTest(TestCase):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
r = self.client.get(reverse("core:index"))
|
r = self.client.get(reverse("core:index"))
|
||||||
self.assertTrue(r.status_code == 200)
|
|
||||||
self.assertContains(
|
self.assertContains(
|
||||||
r,
|
r,
|
||||||
"""<div id="alert_box">
|
"""<div id="alert_box">
|
||||||
<div class="markdown"><h3>ALERTE!</h3>
|
<div class="markdown"><h3>ALERTE!</h3>
|
||||||
<p><strong>Caaaataaaapuuuulte!!!!</strong></p>""",
|
<p><strong>Caaaataaaapuuuulte!!!!</strong></p>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_info_msg(self):
|
def test_info_msg(self):
|
||||||
response = self.client.post(
|
self.client.post(
|
||||||
reverse("com:info_edit"),
|
reverse("com:info_edit"),
|
||||||
{
|
{
|
||||||
"info_msg": """
|
"info_msg": """
|
||||||
@ -96,15 +91,14 @@ class ComTest(TestCase):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
r = self.client.get(reverse("core:index"))
|
r = self.client.get(reverse("core:index"))
|
||||||
self.assertTrue(r.status_code == 200)
|
|
||||||
self.assertContains(
|
self.assertContains(
|
||||||
r,
|
r,
|
||||||
"""<div id="info_box">
|
"""<div id="info_box">
|
||||||
<div class="markdown"><h3>INFO: <strong>Caaaataaaapuuuulte!!!!</strong></h3>""",
|
<div class="markdown"><h3>INFO: <strong>Caaaataaaapuuuulte!!!!</strong></h3>""",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_birthday_non_subscribed_user(self):
|
def test_birthday_non_subscribed_user(self):
|
||||||
self.client.login(username="guy", password="plop")
|
self.client.force_login(User.objects.get(username="guy"))
|
||||||
response = self.client.get(reverse("core:index"))
|
response = self.client.get(reverse("core:index"))
|
||||||
self.assertContains(
|
self.assertContains(
|
||||||
response,
|
response,
|
||||||
@ -122,3 +116,129 @@ class ComTest(TestCase):
|
|||||||
_("You need an up to date subscription to access this content")
|
_("You need an up to date subscription to access this content")
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SithTest(TestCase):
|
||||||
|
def test_sith_owner(self):
|
||||||
|
"""
|
||||||
|
Test that the sith instance is owned by com admins
|
||||||
|
and nobody else
|
||||||
|
"""
|
||||||
|
sith: Sith = Sith.objects.first()
|
||||||
|
|
||||||
|
com_admin = User.objects.get(username="comunity")
|
||||||
|
assert sith.is_owned_by(com_admin)
|
||||||
|
|
||||||
|
anonymous = AnonymousUser()
|
||||||
|
assert not sith.is_owned_by(anonymous)
|
||||||
|
|
||||||
|
sli = User.objects.get(username="sli")
|
||||||
|
assert not sith.is_owned_by(sli)
|
||||||
|
|
||||||
|
|
||||||
|
class NewsTest(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpTestData(cls):
|
||||||
|
cls.com_admin = User.objects.get(username="comunity")
|
||||||
|
new = News.objects.create(
|
||||||
|
title="dummy new",
|
||||||
|
summary="This is a dummy new",
|
||||||
|
content="Look at that beautiful dummy new",
|
||||||
|
author=User.objects.get(username="subscriber"),
|
||||||
|
club=Club.objects.first(),
|
||||||
|
)
|
||||||
|
cls.new = new
|
||||||
|
cls.author = new.author
|
||||||
|
cls.sli = User.objects.get(username="sli")
|
||||||
|
cls.anonymous = AnonymousUser()
|
||||||
|
|
||||||
|
def test_news_owner(self):
|
||||||
|
"""
|
||||||
|
Test that news are owned by com admins
|
||||||
|
or by their author but nobody else
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert self.new.is_owned_by(self.com_admin)
|
||||||
|
assert self.new.is_owned_by(self.author)
|
||||||
|
assert not self.new.is_owned_by(self.anonymous)
|
||||||
|
assert not self.new.is_owned_by(self.sli)
|
||||||
|
|
||||||
|
def test_news_viewer(self):
|
||||||
|
"""
|
||||||
|
Test that moderated news can be viewed by anyone
|
||||||
|
and not moderated news only by com admins
|
||||||
|
"""
|
||||||
|
# by default a news isn't moderated
|
||||||
|
assert self.new.can_be_viewed_by(self.com_admin)
|
||||||
|
assert not self.new.can_be_viewed_by(self.sli)
|
||||||
|
assert not self.new.can_be_viewed_by(self.anonymous)
|
||||||
|
assert not self.new.can_be_viewed_by(self.author)
|
||||||
|
|
||||||
|
self.new.is_moderated = True
|
||||||
|
self.new.save()
|
||||||
|
assert self.new.can_be_viewed_by(self.com_admin)
|
||||||
|
assert self.new.can_be_viewed_by(self.sli)
|
||||||
|
assert self.new.can_be_viewed_by(self.anonymous)
|
||||||
|
assert self.new.can_be_viewed_by(self.author)
|
||||||
|
|
||||||
|
def test_news_editor(self):
|
||||||
|
"""
|
||||||
|
Test that only com admins can edit news
|
||||||
|
"""
|
||||||
|
assert self.new.can_be_edited_by(self.com_admin)
|
||||||
|
assert not self.new.can_be_edited_by(self.sli)
|
||||||
|
assert not self.new.can_be_edited_by(self.anonymous)
|
||||||
|
assert not self.new.can_be_edited_by(self.author)
|
||||||
|
|
||||||
|
|
||||||
|
class WeekmailArticleTest(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpTestData(cls):
|
||||||
|
cls.com_admin = User.objects.get(username="comunity")
|
||||||
|
author = User.objects.get(username="subscriber")
|
||||||
|
cls.article = WeekmailArticle.objects.create(
|
||||||
|
weekmail=Weekmail.objects.create(),
|
||||||
|
author=author,
|
||||||
|
title="title",
|
||||||
|
content="Some content",
|
||||||
|
club=Club.objects.first(),
|
||||||
|
)
|
||||||
|
cls.author = author
|
||||||
|
cls.sli = User.objects.get(username="sli")
|
||||||
|
cls.anonymous = AnonymousUser()
|
||||||
|
|
||||||
|
def test_weekmail_owner(self):
|
||||||
|
"""
|
||||||
|
Test that weekmails are owned only by com admins
|
||||||
|
"""
|
||||||
|
assert self.article.is_owned_by(self.com_admin)
|
||||||
|
assert not self.article.is_owned_by(self.author)
|
||||||
|
assert not self.article.is_owned_by(self.anonymous)
|
||||||
|
assert not self.article.is_owned_by(self.sli)
|
||||||
|
|
||||||
|
|
||||||
|
class PosterTest(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpTestData(cls):
|
||||||
|
cls.com_admin = User.objects.get(username="comunity")
|
||||||
|
cls.poster = Poster.objects.create(
|
||||||
|
name="dummy",
|
||||||
|
file=SimpleUploadedFile("dummy.jpg", b"azertyuiop"),
|
||||||
|
club=Club.objects.first(),
|
||||||
|
date_begin=localtime(now()),
|
||||||
|
)
|
||||||
|
cls.sli = User.objects.get(username="sli")
|
||||||
|
cls.sli.memberships.all().delete()
|
||||||
|
Membership(user=cls.sli, club=Club.objects.first(), role=5).save()
|
||||||
|
cls.susbcriber = User.objects.get(username="subscriber")
|
||||||
|
cls.anonymous = AnonymousUser()
|
||||||
|
|
||||||
|
def test_poster_owner(self):
|
||||||
|
"""
|
||||||
|
Test that poster are owned by com admins and board members in clubs
|
||||||
|
"""
|
||||||
|
assert self.poster.is_owned_by(self.com_admin)
|
||||||
|
assert not self.poster.is_owned_by(self.anonymous)
|
||||||
|
|
||||||
|
assert not self.poster.is_owned_by(self.susbcriber)
|
||||||
|
assert self.poster.is_owned_by(self.sli)
|
||||||
|
128
com/urls.py
@ -1,125 +1,115 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.urls import re_path
|
from django.urls import path
|
||||||
|
|
||||||
from com.views import *
|
|
||||||
from club.views import MailingDeleteView
|
from club.views import MailingDeleteView
|
||||||
|
from com.views import *
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
re_path(r"^sith/edit/alert$", AlertMsgEditView.as_view(), name="alert_edit"),
|
path("sith/edit/alert/", AlertMsgEditView.as_view(), name="alert_edit"),
|
||||||
re_path(r"^sith/edit/info$", InfoMsgEditView.as_view(), name="info_edit"),
|
path("sith/edit/info/", InfoMsgEditView.as_view(), name="info_edit"),
|
||||||
re_path(
|
path(
|
||||||
r"^sith/edit/weekmail_destinations$",
|
"sith/edit/weekmail_destinations/",
|
||||||
WeekmailDestinationEditView.as_view(),
|
WeekmailDestinationEditView.as_view(),
|
||||||
name="weekmail_destinations",
|
name="weekmail_destinations",
|
||||||
),
|
),
|
||||||
re_path(r"^weekmail$", WeekmailEditView.as_view(), name="weekmail"),
|
path("weekmail/", WeekmailEditView.as_view(), name="weekmail"),
|
||||||
re_path(
|
path("weekmail/preview/", WeekmailPreviewView.as_view(), name="weekmail_preview"),
|
||||||
r"^weekmail/preview$", WeekmailPreviewView.as_view(), name="weekmail_preview"
|
path(
|
||||||
),
|
"weekmail/new_article/",
|
||||||
re_path(
|
|
||||||
r"^weekmail/new_article$",
|
|
||||||
WeekmailArticleCreateView.as_view(),
|
WeekmailArticleCreateView.as_view(),
|
||||||
name="weekmail_article",
|
name="weekmail_article",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^weekmail/article/(?P<article_id>[0-9]+)/delete$",
|
"weekmail/article/<int:article_id>/delete/",
|
||||||
WeekmailArticleDeleteView.as_view(),
|
WeekmailArticleDeleteView.as_view(),
|
||||||
name="weekmail_article_delete",
|
name="weekmail_article_delete",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^weekmail/article/(?P<article_id>[0-9]+)/edit$",
|
"weekmail/article/<int:article_id>/edit/",
|
||||||
WeekmailArticleEditView.as_view(),
|
WeekmailArticleEditView.as_view(),
|
||||||
name="weekmail_article_edit",
|
name="weekmail_article_edit",
|
||||||
),
|
),
|
||||||
re_path(r"^news$", NewsListView.as_view(), name="news_list"),
|
path("news/", NewsListView.as_view(), name="news_list"),
|
||||||
re_path(r"^news/admin$", NewsAdminListView.as_view(), name="news_admin_list"),
|
path("news/admin/", NewsAdminListView.as_view(), name="news_admin_list"),
|
||||||
re_path(r"^news/create$", NewsCreateView.as_view(), name="news_new"),
|
path("news/create/", NewsCreateView.as_view(), name="news_new"),
|
||||||
re_path(
|
path(
|
||||||
r"^news/(?P<news_id>[0-9]+)/delete$",
|
"news/<int:news_id>/delete/",
|
||||||
NewsDeleteView.as_view(),
|
NewsDeleteView.as_view(),
|
||||||
name="news_delete",
|
name="news_delete",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^news/(?P<news_id>[0-9]+)/moderate$",
|
"news/<int:news_id>/moderate/",
|
||||||
NewsModerateView.as_view(),
|
NewsModerateView.as_view(),
|
||||||
name="news_moderate",
|
name="news_moderate",
|
||||||
),
|
),
|
||||||
re_path(
|
path("news/<int:news_id>/edit/", NewsEditView.as_view(), name="news_edit"),
|
||||||
r"^news/(?P<news_id>[0-9]+)/edit$", NewsEditView.as_view(), name="news_edit"
|
path("news/<int:news_id>/", NewsDetailView.as_view(), name="news_detail"),
|
||||||
),
|
path("mailings/", MailingListAdminView.as_view(), name="mailing_admin"),
|
||||||
re_path(
|
path(
|
||||||
r"^news/(?P<news_id>[0-9]+)$", NewsDetailView.as_view(), name="news_detail"
|
"mailings/<int:mailing_id>/moderate/",
|
||||||
),
|
|
||||||
re_path(r"^mailings$", MailingListAdminView.as_view(), name="mailing_admin"),
|
|
||||||
re_path(
|
|
||||||
r"^mailings/(?P<mailing_id>[0-9]+)/moderate$",
|
|
||||||
MailingModerateView.as_view(),
|
MailingModerateView.as_view(),
|
||||||
name="mailing_moderate",
|
name="mailing_moderate",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^mailings/(?P<mailing_id>[0-9]+)/delete$",
|
"mailings/<int:mailing_id>/delete/",
|
||||||
MailingDeleteView.as_view(redirect_page="com:mailing_admin"),
|
MailingDeleteView.as_view(redirect_page="com:mailing_admin"),
|
||||||
name="mailing_delete",
|
name="mailing_delete",
|
||||||
),
|
),
|
||||||
re_path(r"^poster$", PosterListView.as_view(), name="poster_list"),
|
path("poster/", PosterListView.as_view(), name="poster_list"),
|
||||||
re_path(r"^poster/create$", PosterCreateView.as_view(), name="poster_create"),
|
path("poster/create/", PosterCreateView.as_view(), name="poster_create"),
|
||||||
re_path(
|
path(
|
||||||
r"^poster/(?P<poster_id>[0-9]+)/edit$",
|
"poster/<int:poster_id>/edit/",
|
||||||
PosterEditView.as_view(),
|
PosterEditView.as_view(),
|
||||||
name="poster_edit",
|
name="poster_edit",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^poster/(?P<poster_id>[0-9]+)/delete$",
|
"poster/<int:poster_id>/delete/",
|
||||||
PosterDeleteView.as_view(),
|
PosterDeleteView.as_view(),
|
||||||
name="poster_delete",
|
name="poster_delete",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^poster/moderate$",
|
"poster/moderate/",
|
||||||
PosterModerateListView.as_view(),
|
PosterModerateListView.as_view(),
|
||||||
name="poster_moderate_list",
|
name="poster_moderate_list",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^poster/(?P<object_id>[0-9]+)/moderate$",
|
"poster/<int:object_id>/moderate/",
|
||||||
PosterModerateView.as_view(),
|
PosterModerateView.as_view(),
|
||||||
name="poster_moderate",
|
name="poster_moderate",
|
||||||
),
|
),
|
||||||
re_path(r"^screen$", ScreenListView.as_view(), name="screen_list"),
|
path("screen/", ScreenListView.as_view(), name="screen_list"),
|
||||||
re_path(r"^screen/create$", ScreenCreateView.as_view(), name="screen_create"),
|
path("screen/create/", ScreenCreateView.as_view(), name="screen_create"),
|
||||||
re_path(
|
path(
|
||||||
r"^screen/(?P<screen_id>[0-9]+)/slideshow$",
|
"screen/<int:screen_id>/slideshow/",
|
||||||
ScreenSlideshowView.as_view(),
|
ScreenSlideshowView.as_view(),
|
||||||
name="screen_slideshow",
|
name="screen_slideshow",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^screen/(?P<screen_id>[0-9]+)/edit$",
|
"screen/<int:screen_id>/edit/",
|
||||||
ScreenEditView.as_view(),
|
ScreenEditView.as_view(),
|
||||||
name="screen_edit",
|
name="screen_edit",
|
||||||
),
|
),
|
||||||
re_path(
|
path(
|
||||||
r"^screen/(?P<screen_id>[0-9]+)/delete$",
|
"screen/<int:screen_id>/delete/",
|
||||||
ScreenDeleteView.as_view(),
|
ScreenDeleteView.as_view(),
|
||||||
name="screen_delete",
|
name="screen_delete",
|
||||||
),
|
),
|
||||||
|
91
com/views.py
@ -1,60 +1,52 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
# - Sli <antoine@bartuccio.fr>
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
#
|
|
||||||
|
|
||||||
from django.shortcuts import redirect, get_object_or_404
|
|
||||||
from django.http import HttpResponseRedirect
|
|
||||||
from django.views.generic import ListView, DetailView, View
|
|
||||||
from django.views.generic.edit import UpdateView, CreateView, DeleteView
|
|
||||||
from django.views.generic.detail import SingleObjectMixin
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
from django.urls import reverse, reverse_lazy
|
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
from django.utils import timezone
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db.models import Max
|
|
||||||
from django.forms.models import modelform_factory
|
|
||||||
from django.core.exceptions import PermissionDenied
|
|
||||||
from django import forms
|
|
||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from smtplib import SMTPRecipientsRefused
|
from smtplib import SMTPRecipientsRefused
|
||||||
|
|
||||||
from com.models import Sith, News, NewsDate, Weekmail, WeekmailArticle, Screen, Poster
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.exceptions import PermissionDenied, ValidationError
|
||||||
|
from django.db.models import Max
|
||||||
|
from django.forms.models import modelform_factory
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
|
from django.urls import reverse, reverse_lazy
|
||||||
|
from django.utils import timezone
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.views.generic import DetailView, ListView, View
|
||||||
|
from django.views.generic.detail import SingleObjectMixin
|
||||||
|
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
||||||
|
|
||||||
|
from club.models import Club, Mailing
|
||||||
|
from com.models import News, NewsDate, Poster, Screen, Sith, Weekmail, WeekmailArticle
|
||||||
|
from core.models import Notification, RealGroup, User
|
||||||
from core.views import (
|
from core.views import (
|
||||||
CanViewMixin,
|
CanCreateMixin,
|
||||||
CanEditMixin,
|
CanEditMixin,
|
||||||
CanEditPropMixin,
|
CanEditPropMixin,
|
||||||
TabedViewMixin,
|
CanViewMixin,
|
||||||
CanCreateMixin,
|
|
||||||
QuickNotifMixin,
|
QuickNotifMixin,
|
||||||
|
TabedViewMixin,
|
||||||
)
|
)
|
||||||
from core.views.forms import SelectDateTime, MarkdownInput
|
from core.views.forms import MarkdownInput, TzAwareDateTimeField
|
||||||
from core.models import Notification, RealGroup, User
|
|
||||||
from club.models import Club, Mailing
|
|
||||||
from core.views.forms import TzAwareDateTimeField
|
|
||||||
|
|
||||||
|
|
||||||
# Sith object
|
# Sith object
|
||||||
|
|
||||||
@ -146,7 +138,7 @@ class ComTabsMixin(TabedViewMixin):
|
|||||||
|
|
||||||
class IsComAdminMixin(View):
|
class IsComAdminMixin(View):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if not (request.user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)):
|
if not request.user.is_com_admin:
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
return super(IsComAdminMixin, self).dispatch(request, *args, **kwargs)
|
return super(IsComAdminMixin, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
@ -283,9 +275,7 @@ class NewsEditView(CanEditMixin, UpdateView):
|
|||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
if form.cleaned_data["automoderation"] and self.request.user.is_in_group(
|
if form.cleaned_data["automoderation"] and self.request.user.is_com_admin:
|
||||||
settings.SITH_GROUP_COM_ADMIN_ID
|
|
||||||
):
|
|
||||||
self.object.moderator = self.request.user
|
self.object.moderator = self.request.user
|
||||||
self.object.is_moderated = True
|
self.object.is_moderated = True
|
||||||
self.object.save()
|
self.object.save()
|
||||||
@ -333,9 +323,7 @@ class NewsCreateView(CanCreateMixin, CreateView):
|
|||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
if form.cleaned_data["automoderation"] and self.request.user.is_in_group(
|
if form.cleaned_data["automoderation"] and self.request.user.is_com_admin:
|
||||||
settings.SITH_GROUP_COM_ADMIN_ID
|
|
||||||
):
|
|
||||||
self.object.moderator = self.request.user
|
self.object.moderator = self.request.user
|
||||||
self.object.is_moderated = True
|
self.object.is_moderated = True
|
||||||
self.object.save()
|
self.object.save()
|
||||||
@ -617,10 +605,7 @@ class MailingListAdminView(ComTabsMixin, ListView):
|
|||||||
current_tab = "mailings"
|
current_tab = "mailings"
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if not (
|
if not (request.user.is_com_admin or request.user.is_root):
|
||||||
request.user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID)
|
|
||||||
or request.user.is_root
|
|
||||||
):
|
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
return super(MailingListAdminView, self).dispatch(request, *args, **kwargs)
|
return super(MailingListAdminView, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
14
conftest.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import pytest
|
||||||
|
from django.core.management import call_command
|
||||||
|
from django.utils.translation import activate
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def django_db_setup(django_db_setup, django_db_blocker):
|
||||||
|
with django_db_blocker.unblock():
|
||||||
|
call_command("setup")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session", autouse=True)
|
||||||
|
def set_default_language():
|
||||||
|
activate("fr")
|
@ -1,23 +1,19 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
@ -1,40 +1,38 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.contrib import admin
|
|
||||||
from ajax_select import make_ajax_form
|
from ajax_select import make_ajax_form
|
||||||
from core.models import User, Page, RealGroup, SithFile
|
from django.contrib import admin
|
||||||
from django.contrib.auth.models import Group as AuthGroup
|
from django.contrib.auth.models import Group as AuthGroup
|
||||||
from haystack.admin import SearchModelAdmin
|
from haystack.admin import SearchModelAdmin
|
||||||
|
|
||||||
|
from core.models import MetaGroup, Page, RealGroup, SithFile, User
|
||||||
|
|
||||||
admin.site.unregister(AuthGroup)
|
admin.site.unregister(AuthGroup)
|
||||||
|
admin.site.register(MetaGroup)
|
||||||
admin.site.register(RealGroup)
|
admin.site.register(RealGroup)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(User)
|
||||||
class UserAdmin(SearchModelAdmin):
|
class UserAdmin(SearchModelAdmin):
|
||||||
list_display = ["first_name", "last_name", "username", "email", "nick_name"]
|
list_display = ("first_name", "last_name", "username", "email", "nick_name")
|
||||||
form = make_ajax_form(
|
form = make_ajax_form(
|
||||||
User,
|
User,
|
||||||
{
|
{
|
||||||
@ -48,11 +46,9 @@ class UserAdmin(SearchModelAdmin):
|
|||||||
search_fields = ["first_name", "last_name", "username"]
|
search_fields = ["first_name", "last_name", "username"]
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(User, UserAdmin)
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Page)
|
@admin.register(Page)
|
||||||
class PageAdmin(admin.ModelAdmin):
|
class PageAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("name", "_full_name", "owner_group")
|
||||||
form = make_ajax_form(
|
form = make_ajax_form(
|
||||||
Page,
|
Page,
|
||||||
{
|
{
|
||||||
@ -66,4 +62,12 @@ class PageAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
@admin.register(SithFile)
|
@admin.register(SithFile)
|
||||||
class SithFileAdmin(admin.ModelAdmin):
|
class SithFileAdmin(admin.ModelAdmin):
|
||||||
form = make_ajax_form(SithFile, {"parent": "files"}) # ManyToManyField
|
list_display = ("name", "owner", "size", "date", "is_in_sas")
|
||||||
|
form = make_ajax_form(
|
||||||
|
SithFile,
|
||||||
|
{
|
||||||
|
"parent": "files",
|
||||||
|
"owner": "users",
|
||||||
|
"moderator": "users",
|
||||||
|
},
|
||||||
|
) # ManyToManyField
|
||||||
|
44
core/apps.py
@ -1,30 +1,27 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
from django.core.cache import cache
|
||||||
from django.core.signals import request_started
|
from django.core.signals import request_started
|
||||||
|
|
||||||
|
|
||||||
@ -33,26 +30,17 @@ class SithConfig(AppConfig):
|
|||||||
verbose_name = "Core app of the Sith"
|
verbose_name = "Core app of the Sith"
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from core.models import User
|
import core.signals # noqa F401
|
||||||
from club.models import Club
|
|
||||||
from forum.models import Forum
|
from forum.models import Forum
|
||||||
|
|
||||||
def clear_cached_groups(**kwargs):
|
cache.clear()
|
||||||
User._group_ids = {}
|
|
||||||
User._group_name = {}
|
|
||||||
|
|
||||||
def clear_cached_memberships(**kwargs):
|
def clear_cached_memberships(**kwargs):
|
||||||
User._club_memberships = {}
|
|
||||||
Club._memberships = {}
|
|
||||||
Forum._club_memberships = {}
|
Forum._club_memberships = {}
|
||||||
|
|
||||||
print("Connecting signals!", file=sys.stderr)
|
print("Connecting signals!", file=sys.stderr)
|
||||||
request_started.connect(
|
|
||||||
clear_cached_groups, weak=False, dispatch_uid="clear_cached_groups"
|
|
||||||
)
|
|
||||||
request_started.connect(
|
request_started.connect(
|
||||||
clear_cached_memberships,
|
clear_cached_memberships,
|
||||||
weak=False,
|
weak=False,
|
||||||
dispatch_uid="clear_cached_memberships",
|
dispatch_uid="clear_cached_memberships",
|
||||||
)
|
)
|
||||||
# TODO: there may be a need to add more cache clearing
|
|
||||||
|
55
core/converters.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# -*- coding:utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright 2023 © AE UTBM
|
||||||
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
|
#
|
||||||
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
|
# https://ae.utbm.fr.
|
||||||
|
#
|
||||||
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
|
#
|
||||||
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
|
#
|
||||||
|
|
||||||
|
from core.models import Page
|
||||||
|
|
||||||
|
|
||||||
|
class FourDigitYearConverter:
|
||||||
|
regex = "[0-9]{4}"
|
||||||
|
|
||||||
|
def to_python(self, value):
|
||||||
|
return int(value)
|
||||||
|
|
||||||
|
def to_url(self, value):
|
||||||
|
return str(value).zfill(4)
|
||||||
|
|
||||||
|
|
||||||
|
class TwoDigitMonthConverter:
|
||||||
|
regex = "[0-9]{2}"
|
||||||
|
|
||||||
|
def to_python(self, value):
|
||||||
|
return int(value)
|
||||||
|
|
||||||
|
def to_url(self, value):
|
||||||
|
return str(value).zfill(2)
|
||||||
|
|
||||||
|
|
||||||
|
class BooleanStringConverter:
|
||||||
|
"""
|
||||||
|
Converter whose regex match either True or False
|
||||||
|
"""
|
||||||
|
|
||||||
|
regex = r"(True)|(False)"
|
||||||
|
|
||||||
|
def to_python(self, value):
|
||||||
|
return str(value) == "True"
|
||||||
|
|
||||||
|
def to_url(self, value):
|
||||||
|
return str(value)
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
BIN
core/fixtures/images/sas/Family/skia_sli.jpg
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
core/fixtures/images/sas/Family/skia_sli_krophil.jpg
Normal file
After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 30 KiB |
@ -1,35 +1,31 @@
|
|||||||
# -*- coding:utf-8 -*
|
# -*- coding:utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2016,2017
|
# Copyright 2023 © AE UTBM
|
||||||
# - Skia <skia@libskia.so>
|
# ae@utbm.fr / ae.info@utbm.fr
|
||||||
|
# All contributors are listed in the CONTRIBUTORS file.
|
||||||
#
|
#
|
||||||
# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM,
|
# This file is part of the website of the UTBM Student Association (AE UTBM),
|
||||||
# http://ae.utbm.fr.
|
# https://ae.utbm.fr.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
# You can find the whole source code at https://github.com/ae-utbm/sith3
|
||||||
# the terms of the GNU General Public License a published by the Free Software
|
|
||||||
# Foundation; either version 3 of the License, or (at your option) any later
|
|
||||||
# version.
|
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License along with
|
|
||||||
# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple
|
|
||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
#
|
#
|
||||||
|
# PREVIOUSLY LICENSED UNDER THE MIT LICENSE,
|
||||||
|
# SEE : https://raw.githubusercontent.com/ae-utbm/sith3/master/LICENSE.old
|
||||||
|
# OR WITHIN THE LOCAL FILE "LICENSE.old"
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from ajax_select import LookupChannel, register
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from ajax_select import register, LookupChannel
|
|
||||||
|
|
||||||
from core.views.site import search_user
|
|
||||||
from core.models import User, Group, SithFile
|
|
||||||
from club.models import Club
|
|
||||||
from counter.models import Product, Counter
|
|
||||||
from accounting.models import ClubAccount, Company
|
from accounting.models import ClubAccount, Company
|
||||||
|
from club.models import Club
|
||||||
|
from core.models import Group, SithFile, User
|
||||||
|
from core.views.site import search_user
|
||||||
|
from counter.models import Counter, Customer, Product
|
||||||
|
|
||||||
|
|
||||||
def check_token(request):
|
def check_token(request):
|
||||||
@ -60,6 +56,21 @@ class UsersLookup(RightManagedLookupChannel):
|
|||||||
return item.get_display_name()
|
return item.get_display_name()
|
||||||
|
|
||||||
|
|
||||||
|
@register("customers")
|
||||||
|
class CustomerLookup(RightManagedLookupChannel):
|
||||||
|
model = Customer
|
||||||
|
|
||||||
|
def get_query(self, q, request):
|
||||||
|
users = search_user(q)
|
||||||
|
return [user.customer for user in users]
|
||||||
|
|
||||||
|
def format_match(self, obj):
|
||||||
|
return obj.user.get_mini_item()
|
||||||
|
|
||||||
|
def format_item_display(self, obj):
|
||||||
|
return f"{obj.user.get_display_name()} ({obj.account_id})"
|
||||||
|
|
||||||
|
|
||||||
@register("groups")
|
@register("groups")
|
||||||
class GroupsLookup(RightManagedLookupChannel):
|
class GroupsLookup(RightManagedLookupChannel):
|
||||||
model = Group
|
model = Group
|
||||||
|