listing d'instruments
This commit is contained in:
parent
5d1d3f8eff
commit
406f92098f
27 changed files with 673 additions and 1 deletions
|
@ -52,6 +52,7 @@ INSTALLED_APPS = [
|
|||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'avatar',
|
||||
'instruments',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
|
|
@ -39,6 +39,7 @@ urlpatterns += i18n_patterns(
|
|||
),
|
||||
path('agenda/', include('calendrier.urls',namespace='calendrier')),
|
||||
path('partitions/', include('partitions.urls')),
|
||||
path('instruments/', include('instruments.urls')),
|
||||
path('pads/', include('pads.urls')),
|
||||
path('admin/', admin.site.urls,),
|
||||
path('trombonoscope/',include('trombonoscope.urls')),
|
||||
|
|
18
gestion/migrations/0004_auto_20210331_2031.py
Normal file
18
gestion/migrations/0004_auto_20210331_2031.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.2.17 on 2021-03-31 20:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestion', '0003_photo'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='photo',
|
||||
name='cat',
|
||||
field=models.CharField(choices=[('home_join', 'Rejoignez nous'), ('home_contact', 'Nous Contacter'), ('home_rep', "Répertoire de l'acceuil"), ('login', 'Connexion'), ('change_membre', 'Modification du profil'), ('inscription_membre', 'Inscription'), ('home', 'Calendrier connecté'), ('liste', 'Agenda public'), ('part', 'Répertoire'), ('instru', 'Instruments'), ('n', "N'apparait pas")], default='n', max_length=127),
|
||||
),
|
||||
]
|
|
@ -17,6 +17,7 @@ class Photo(models.Model):
|
|||
('home', _('Calendrier connecté')),
|
||||
('liste', _('Agenda public')),
|
||||
('part', _('Répertoire')),
|
||||
('instru', _('Instruments')),
|
||||
('n',_("N'apparait pas"))
|
||||
)
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
<li><a href="{% url 'partitions:liste' %}">{% trans "Répertoire" %}</a></li>
|
||||
{% if user.is_authenticated %}
|
||||
<li><a href="{% url 'trombonoscope:view' %}">{% trans "Trombonoscope" %}</a></li>
|
||||
<li><a href="{% url 'instruments:liste' %}">{% trans "Instruments" %}</a></li>
|
||||
<li><a href="https://photos.cof.ens.fr/index.php/Clubs-du-COF/L'Ernestophone" target="_blank">{% trans "Galerie Photo" %}</a></li>
|
||||
<li><a href="{% url 'pads:list' %}">{% trans "Pads" %}</a></li>
|
||||
{% if user.is_superuser or user.profile.is_chef %}
|
||||
|
|
0
instruments/__init__.py
Normal file
0
instruments/__init__.py
Normal file
8
instruments/admin.py
Normal file
8
instruments/admin.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
from django.contrib import admin
|
||||
|
||||
|
||||
from .models import Instrument,Reparation
|
||||
|
||||
|
||||
admin.site.register(Instrument)
|
||||
admin.site.register(Reparation)
|
5
instruments/apps.py
Normal file
5
instruments/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class InstrumentsConfig(AppConfig):
|
||||
name = 'instruments'
|
11
instruments/decorators.py
Normal file
11
instruments/decorators.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
from django.contrib.auth.decorators import user_passes_test
|
||||
|
||||
|
||||
def is_chef(user):
|
||||
try:
|
||||
profile = user.profile
|
||||
return profile.is_chef
|
||||
except:
|
||||
return False
|
||||
|
||||
chef_required = user_passes_test(lambda u: is_chef(u))
|
0
instruments/forms.py
Normal file
0
instruments/forms.py
Normal file
56
instruments/migrations/0001_initial.py
Normal file
56
instruments/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Generated by Django 2.2.17 on 2021-04-01 19:25
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.db.models.functions.text
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Instrument',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('model', models.CharField(blank=True, max_length=100, null=True, verbose_name='Modèle')),
|
||||
('prix', models.CharField(blank=True, default='', max_length=100, verbose_name='Prix')),
|
||||
('etat', models.CharField(choices=[('Bon état', 'Bon état'), ('Etat moyen', 'Etat moyen'), ('Mauvais état', 'Mauvais état')], default='Bon état', max_length=100)),
|
||||
('marque', models.CharField(blank=True, max_length=100, null=True, verbose_name='Marque')),
|
||||
('serial', models.CharField(blank=True, default=' ', max_length=100, null=True, verbose_name='Numéro de série')),
|
||||
('annee', models.CharField(blank=True, max_length=100, null=True, verbose_name="Année d'achat")),
|
||||
('owner', models.CharField(default='Fanfare', max_length=100, verbose_name='Propriétaire')),
|
||||
('user', models.CharField(blank=True, max_length=100, verbose_name='Utilisateur')),
|
||||
('type', models.CharField(max_length=40, verbose_name='Instrument')),
|
||||
('statut', models.CharField(choices=[('Disponible', 'Disponible'), ('Prêté', 'Prêté')], default='Disponible', max_length=100)),
|
||||
('infos', models.TextField(blank=True, default='', verbose_name='Infos utiles')),
|
||||
('infos_en', models.TextField(blank=True, default='', verbose_name='Infos utiles en anglais')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Instrument',
|
||||
'verbose_name_plural': 'Instruments',
|
||||
'ordering': (django.db.models.functions.text.Lower('type'),),
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Reparation',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date', models.DateField(max_length=100, verbose_name='Date')),
|
||||
('description', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Description')),
|
||||
('description_en', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Description en anglais')),
|
||||
('prix', models.CharField(blank=True, default='', max_length=100, verbose_name='Prix')),
|
||||
('lieux', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Lieux')),
|
||||
('instru', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='instruments.Instrument', verbose_name='Instrument')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Réparation',
|
||||
'verbose_name_plural': 'Réparations',
|
||||
'ordering': ('date',),
|
||||
},
|
||||
),
|
||||
]
|
0
instruments/migrations/__init__.py
Normal file
0
instruments/migrations/__init__.py
Normal file
44
instruments/models.py
Normal file
44
instruments/models.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
import os
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.db.models.functions import Lower
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class Instrument(models.Model):
|
||||
|
||||
model = models.CharField(_("Modèle"),max_length=100,null=True,blank=True)
|
||||
prix = models.CharField(_("Prix"),max_length=100,default='',blank=True)
|
||||
etat = models.CharField(max_length=100,default='Bon état',choices = [('Bon état',_('Bon état')),('Etat moyen',_('Etat moyen')),('Mauvais état',_('Mauvais état'))])
|
||||
marque = models.CharField(_("Marque"),max_length=100,null=True,blank=True)
|
||||
serial = models.CharField(_("Numéro de série"),max_length=100,default=' ',null=True,blank=True)
|
||||
annee = models.CharField(_("Année d'achat"),max_length=100,null=True,blank=True)
|
||||
owner = models.CharField(_("Propriétaire"),max_length=100,default='Fanfare')
|
||||
user = models.CharField(_('Utilisateur'),max_length=100,blank=True)
|
||||
type = models.CharField(_("Instrument"), max_length=40, blank=False)
|
||||
statut = models.CharField(max_length=100,default='Disponible',choices = [('Disponible',_('Disponible')),('Prêté',_('Prêté'))])
|
||||
infos = models.TextField(_("Infos utiles"), null=False, blank=True,default="")
|
||||
infos_en = models.TextField("Infos utiles en anglais", null=False, blank=True,default="")
|
||||
def __str__(self):
|
||||
return self.type
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Instrument')
|
||||
verbose_name_plural = _('Instruments')
|
||||
ordering = (Lower('type'),)
|
||||
|
||||
class Reparation(models.Model):
|
||||
date = models.DateField(_("Date"),max_length=100)
|
||||
instru = models.ForeignKey("Instrument", on_delete=models.CASCADE,verbose_name=_("Instrument"))
|
||||
description = models.CharField(_("Description"),max_length=100,default=' ',blank=True)
|
||||
description_en = models.CharField(_("Description en anglais"),max_length=100,default=' ',blank=True)
|
||||
prix = models.CharField(_("Prix"),max_length=100,default='',blank=True)
|
||||
lieux = models.CharField(_('Lieux'),max_length=100,default=' ',blank=True)
|
||||
def __str__(self):
|
||||
return self.description
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Réparation')
|
||||
verbose_name_plural = _('Réparations')
|
||||
ordering = ('date',)
|
BIN
instruments/static/images/instruments.jpg
Executable file
BIN
instruments/static/images/instruments.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 341 KiB |
19
instruments/templates/instruments/create_instru.html
Normal file
19
instruments/templates/instruments/create_instru.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
{% extends "gestion/base.html" %}
|
||||
{% load i18n %}
|
||||
{%block titre %}{% trans "Ajout d'une instrument" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="main">
|
||||
<section class="wrapper style1">
|
||||
<div class="inner">
|
||||
<p><a href="{% url "instruments:liste" %}" class="button alt">{% trans "Retour à la liste" %}</a></p>
|
||||
{% if envoi %}<p>{% trans "Cet instrument a été enregistré" %}.{% endif %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="{% trans "Enregistrer" %}" />
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% endblock %}
|
19
instruments/templates/instruments/create_rep.html
Normal file
19
instruments/templates/instruments/create_rep.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
{% extends "gestion/base.html" %}
|
||||
{% load i18n %}
|
||||
{%block titre %}{% trans "Ajout d'une réparation" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="main">
|
||||
<section class="wrapper style1">
|
||||
<div class="inner">
|
||||
<p><a href="{% url "instruments:fiche_instru" pk %}" class="button alt">{% trans "Retour à la fiche" %}</a></p>
|
||||
{% if envoi %}<p>{% trans "Cette réparation a été enregistrée" %}.{% endif %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="{% trans "Enregistrer" %}" />
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% endblock %}
|
16
instruments/templates/instruments/delete_instru.html
Normal file
16
instruments/templates/instruments/delete_instru.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
{% extends "gestion/base.html" %}
|
||||
{% load i18n %}
|
||||
{% block titre %}{% trans "Suppression d'un instrument" %}{% endblock %}
|
||||
{% block content %}
|
||||
<div id="main">
|
||||
<section class="wrapper style1">
|
||||
<div class="inner">
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<p><a href="{% url "instruments:liste" %}" class="button alt">{% trans "Retour aux instruments" %}</a></p>
|
||||
<p>{% blocktrans with object=object %} Voulez vous vraiment supprimer le.a {{ object }}?{% endblocktrans %}</p>
|
||||
<input type="submit" value="{% trans "Oui" %}" />
|
||||
</form>
|
||||
</div></section>
|
||||
</div>
|
||||
{% endblock %}
|
16
instruments/templates/instruments/delete_rep.html
Normal file
16
instruments/templates/instruments/delete_rep.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
{% extends "gestion/base.html" %}
|
||||
{% load i18n %}
|
||||
{% block titre %}{% trans "Suppression d'une réparation" %}{% endblock %}
|
||||
{% block content %}
|
||||
<div id="main">
|
||||
<section class="wrapper style1">
|
||||
<div class="inner">
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<p><a href="{% url "instruments:fiche_instru" id %}" class="button alt">{% trans "Retour à la fiche instrument" %}</a></p>
|
||||
<p>{% blocktrans with object=object %} Voulez vous vraiment supprimer la réparation {{object}}?{% endblocktrans %}</p>
|
||||
<input type="submit" value="{% trans "Oui" %}" />
|
||||
</form>
|
||||
</div></section>
|
||||
</div>
|
||||
{% endblock %}
|
103
instruments/templates/instruments/instru_liste.html
Normal file
103
instruments/templates/instruments/instru_liste.html
Normal file
|
@ -0,0 +1,103 @@
|
|||
{% extends "gestion/base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load autotranslate %}
|
||||
{% load halflength %}
|
||||
{% block titre %}{% trans "Instruments" %}{% endblock %}
|
||||
{% block content %}
|
||||
<div id="main">
|
||||
<section class="wrapper style1">
|
||||
<div class="inner">
|
||||
<span class="image fit">
|
||||
{% if photo %}
|
||||
<img src="{{photo.image.url}}" alt="" /> <div style="position:absolute;z-index:1;right:0;bottom:0">
|
||||
{% if photo.url %}
|
||||
<a href="{{photo.url}}" target="_blank" class="icon fa-copyright" style="color: {{photo.color}}"> {% if photo.auteur %}{{photo.auteur}}{%endif%}</a>
|
||||
{% elif photo.auteur %}
|
||||
<div class="icon fa-copyright" style="color: {{photo.color}}" > {{photo.auteur}}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<img src="{% static 'images/instruments.jpg' %}" alt="" /> <div style="position:absolute;z-index:1;right:0;bottom:0">
|
||||
<div class="icon fa-copyright" style="color:#000000"> Lucas Gierzack</div>
|
||||
{% endif %}
|
||||
</div></span>
|
||||
{% if user.profile.is_chef %}
|
||||
<a href="{% url "instruments:ajouter_instru" %}" class="button alt big">{% trans "Ajouter un instrument" %}</a>
|
||||
{% endif %}
|
||||
<p></p>
|
||||
<h4>{% trans "Instruments Disponibles :" %} </h4>
|
||||
<div class="table-wrapper">
|
||||
<table class="default">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Intrument" %}</th>
|
||||
<th>{% trans "Propriétaire" %}</th>
|
||||
<th>{% trans "Etat" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for instrument in instrus_dispo %}
|
||||
<a href="{% url "instruments:fiche_instru" instrument.id %}">
|
||||
<tr>
|
||||
<td> {{ instrument.type }} </td>
|
||||
<td> {{ instrument.owner }} </td>
|
||||
<td> {{ instrument.etat }} </td>
|
||||
<td>
|
||||
<a href="{% url "instruments:fiche_instru" instrument.id %}" class="button small">{% trans "Consulter" %}<a/>
|
||||
{% if user.profile.is_chef %}
|
||||
|
||||
<a href="{% url "instruments:delete_instru" instrument.id %}" class="button small">{% trans "Supprimer" %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="wrapper style2">
|
||||
<div class="inner">
|
||||
<h4>{% trans "Instruments Prêtés :" %} </h4>
|
||||
<div class="table-wrapper">
|
||||
<table class="default">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>{% trans "Intrument" %}</th>
|
||||
<th>{% trans "Propriétaire" %}</th>
|
||||
<th>{% trans "Utilisateur" %}</th>
|
||||
<th>{% trans "Etat" %}</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for instrument in instrus_prete %}
|
||||
<tr>
|
||||
|
||||
<td> {{ instrument.type }} </td>
|
||||
<td> {{ instrument.owner }} </td>
|
||||
<td> {{ instrument.user }} </td>
|
||||
<td> {{ instrument.etat}} </td>
|
||||
<td>
|
||||
<a href="{% url "instruments:fiche_instru" instrument.id %}" class="button small">{% trans "Consulter" %}<a/>
|
||||
{% if user.profile.is_chef %}
|
||||
|
||||
<a href="{% url "instruments:delete_instru" instrument.id %}" class="button small">{% trans "Supprimer" %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
114
instruments/templates/instruments/update_instru.html
Normal file
114
instruments/templates/instruments/update_instru.html
Normal file
|
@ -0,0 +1,114 @@
|
|||
{% extends "gestion/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% get_current_language as current_language %}
|
||||
{% load autotranslate %}
|
||||
{% block titre %}{{ instru.type }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="main">
|
||||
<section class="wrapper style1">
|
||||
<div class="inner">
|
||||
<h1>{% blocktrans with type=instru.type etat=instru.etat%} {{type}} en {{etat}} {% endblocktrans%}</h1>
|
||||
<div class="row">
|
||||
|
||||
<div class="7u 12u$(small)">
|
||||
<p>{% trans "Propriétaire : "%} {{instru.owner}} <br>
|
||||
{% trans "Statut : "%} {{instru.statut}} <br>
|
||||
{% ifequal instru.statut 'Prêté' %}
|
||||
{% trans "Utilisateur : "%} {{instru.user}} <br>
|
||||
{% endifequal %}
|
||||
{% trans "Marque : "%} {{instru.marque}} <br>
|
||||
{% trans "Modele : "%} {{instru.model}} <br>
|
||||
{% trans "Numéro de série : "%} {{instru.serial}} <br>
|
||||
{% trans "Prix : "%} {{instru.prix}} <br>
|
||||
{% blocktrans with annee=instru.annee %} Acheté.e en {{annee}} {% endblocktrans%}
|
||||
</p>
|
||||
{% if infos or infos_en %}
|
||||
|
||||
<h3>{% trans "Infos utiles :" %}</h3>
|
||||
|
||||
<div class="box">{% autotranslate current_language infos infos_en %}</div>
|
||||
|
||||
|
||||
{% endif %}
|
||||
{% if suppression %}
|
||||
<p>{{ suppression }}</p>
|
||||
{% endif %}
|
||||
{% if not user.profile.is_chef %}
|
||||
</div>
|
||||
<div class="5u 12u$(small)">
|
||||
{% endif %}
|
||||
<h4>{% blocktrans count counter=reparations|length %}Réparation :{% plural %}Réparations {% endblocktrans %}</h4>
|
||||
<div class="table-wrapper">
|
||||
<table class="default">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Date" %}</th>
|
||||
<th>{% trans "Description" %}</th>
|
||||
<th>{% trans "Prix" %}</th>
|
||||
<th>{% trans "lieu" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for rep in reparations %}
|
||||
<tr>
|
||||
|
||||
<td> {{ rep.date }} </td>
|
||||
<td> {% ifequal current_language "fr" %}
|
||||
{{ rep.description }}
|
||||
{% else %}
|
||||
{% if instru.description_en %}
|
||||
{{ rep.description_en }}
|
||||
{% else %}
|
||||
{{ rep.description }}
|
||||
{% endif %}
|
||||
{% endifequal %} </td>
|
||||
<td> {{ rep.prix }} </td>
|
||||
<td> {{ rep.lieux }} </td>
|
||||
{% if user.profile.is_chef %}
|
||||
<td>
|
||||
<a href="{% url "instruments:update_rep" rep.id %}" class="button small">{% trans "Modifier" %}</a>
|
||||
<a href="{% url "instruments:delete_rep" rep.id %}" class="button small">{% trans "Supprimer" %}</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>
|
||||
<a class='button ' href="{% url "instruments:liste" %}">Retour aux instruments</a>
|
||||
{% if user.profile.is_chef %}
|
||||
<a class='button ' href="{% url "instruments:ajouter_rep" instru.id %}">Ajouter une réparation</a>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{% if user.profile.is_chef %}
|
||||
|
||||
<div class="5u 12u$(small)">
|
||||
<div class="info_part">
|
||||
<form action="{% url "instruments:fiche_instru" instru.id %}" id="chef-edit-form" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="Enregister" />
|
||||
</form>
|
||||
{% else %}
|
||||
{% if instru.infos %}
|
||||
<div>
|
||||
<h4>Infos utiles</h4>
|
||||
<p>{{ infos }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% endblock %}
|
19
instruments/templates/instruments/update_rep.html
Normal file
19
instruments/templates/instruments/update_rep.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
{% extends "gestion/base.html" %}
|
||||
{% load i18n %}
|
||||
{%block titre %}{% trans "Ajout d'une réparation" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="main">
|
||||
<section class="wrapper style1">
|
||||
<div class="inner">
|
||||
<p><a href="{% url "instruments:fiche_instru" object.instru.id %}" class="button alt">{% trans "Retour à la fiche" %}</a></p>
|
||||
{% if envoi %}<p>{% trans "Cette réparation a été enregistrée" %}.{% endif %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" value="{% trans "Enregistrer" %}" />
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% endblock %}
|
0
instruments/tests/__init__.py
Normal file
0
instruments/tests/__init__.py
Normal file
1
instruments/tests/test_file.txt
Normal file
1
instruments/tests/test_file.txt
Normal file
|
@ -0,0 +1 @@
|
|||
do not delete me
|
101
instruments/tests/test_views.py
Normal file
101
instruments/tests/test_views.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
from django.contrib.auth import get_user_model
|
||||
from django.core.files import File
|
||||
from django.template.defaultfilters import urlencode
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from gestion.models import ErnestoUser
|
||||
from ..models import Category, Partition, PartitionSet
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
def new_user(username, ernesto=False, chef=False):
|
||||
u = User.objects.create_user(username=username)
|
||||
ErnestoUser.objects.create(
|
||||
user=u,
|
||||
slug=username,
|
||||
is_chef=chef,
|
||||
is_ernesto=ernesto
|
||||
)
|
||||
return u
|
||||
|
||||
|
||||
class TestViews(TestCase):
|
||||
# TODO: add tests for upload/deletions
|
||||
# TODO: test forms
|
||||
|
||||
def setUp(self):
|
||||
# User with different access level and their clients
|
||||
chef = new_user("chef", ernesto=True, chef=True)
|
||||
chef_c = Client()
|
||||
chef_c.force_login(chef)
|
||||
ernesto = new_user("ernesto", ernesto=True)
|
||||
ernesto_c = Client()
|
||||
ernesto_c.force_login(ernesto)
|
||||
self.client_matrix = [
|
||||
(chef, chef_c),
|
||||
(ernesto, ernesto_c),
|
||||
(None, Client())
|
||||
]
|
||||
# A Partition set with 1 partition
|
||||
self.pset = PartitionSet.objects.create(
|
||||
category=Category.objects.first(),
|
||||
nom="My PSet",
|
||||
auteur="PSet author"
|
||||
)
|
||||
file = File(open("partitions/tests/test_file.txt"), "test file")
|
||||
Partition.objects.create(nom="part1", part=file, morceau=self.pset)
|
||||
|
||||
def tearDown(self):
|
||||
"""Remove dummy files from media/partitions/"""
|
||||
for partition in self.pset.partition_set.all():
|
||||
partition.delete()
|
||||
|
||||
def _get_restricted_page(self, url):
|
||||
"""
|
||||
Shorthand for testing wether a page in only accessible by ernesto
|
||||
members
|
||||
"""
|
||||
for user, client in self.client_matrix:
|
||||
# If user is not None, it is an ernesto member
|
||||
resp = client.get(url)
|
||||
if user:
|
||||
self.assertEqual(200, resp.status_code)
|
||||
else:
|
||||
encoded_url = urlencode(urlencode(url))
|
||||
redirection_url = "/login?next={}".format(encoded_url)
|
||||
self.assertRedirects(resp, redirection_url)
|
||||
|
||||
def test_get_partition_sets(self):
|
||||
"""The list of all partition sets can be fetched by everyone"""
|
||||
for _, client in self.client_matrix:
|
||||
resp = client.get("/partitions/")
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
def test_get_partitions(self):
|
||||
"""
|
||||
Only ernesto members can see the partitions inside of a partition set
|
||||
"""
|
||||
url = "/partitions/{}/{}".format(self.pset.nom, self.pset.auteur)
|
||||
self._get_restricted_page(url)
|
||||
|
||||
def test_see(self):
|
||||
"""Only ernesto members can see partitions"""
|
||||
part = self.pset.partition_set.first()
|
||||
url = "/partitions/{}/{}/see/{}".format(
|
||||
self.pset.nom, self.pset.auteur, part.id
|
||||
)
|
||||
self._get_restricted_page(url)
|
||||
|
||||
def test_download(self):
|
||||
"""Only ernesto members can download partitions"""
|
||||
part = self.pset.partition_set.first()
|
||||
url = "/partitions/{}/{}/{}".format(
|
||||
self.pset.nom, self.pset.auteur, part.id
|
||||
)
|
||||
self._get_restricted_page(url)
|
||||
|
||||
def test_new(self):
|
||||
"""Only ernesto members can create partiton sets"""
|
||||
url = "/partitions/new"
|
||||
self._get_restricted_page(url)
|
14
instruments/urls.py
Normal file
14
instruments/urls.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = 'instruments'
|
||||
urlpatterns = [
|
||||
path('', views.liste, name='liste'),
|
||||
path("delete/<int:pk>", views.InstruDelete.as_view(), name="delete_instru"),
|
||||
path("delete_reparation/<int:pk>", views.delete_rep, name="delete_rep"),
|
||||
path("new", views.InstruCreate.as_view(), name="ajouter_instru"),
|
||||
path("new_rep/<int:pk>", views.create_rep, name="ajouter_rep"),
|
||||
path("update_rep/<int:pk>", views.RepUpdate.as_view(), name="update_rep"),
|
||||
path("fiche/<int:pk>",views.fiche_instru,name="fiche_instru"),
|
||||
]
|
104
instruments/views.py
Normal file
104
instruments/views.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
from django.shortcuts import render, HttpResponse, get_object_or_404, redirect, reverse
|
||||
from instruments.models import Instrument,Reparation
|
||||
from gestion.models import Photo
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.forms.models import modelform_factory
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.text import slugify
|
||||
from django.core.files import File
|
||||
from django.utils.encoding import smart_str
|
||||
from django.http import Http404
|
||||
from instruments.decorators import chef_required
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
import os
|
||||
import zipfile
|
||||
import io
|
||||
from gestion.mixins import ChefRequiredMixin
|
||||
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.http import HttpResponseRedirect
|
||||
@login_required
|
||||
def liste(request):
|
||||
photo = Photo.objects.filter(cat='instru').order_by('?').first()
|
||||
instrus_dispo = Instrument.objects.all().order_by('type').filter(statut='Disponible')
|
||||
instrus_prete = Instrument.objects.all().order_by('type').filter(statut='Prêté')
|
||||
return render(request, 'instruments/instru_liste.html', {"instrus_dispo":instrus_dispo,"instrus_prete":instrus_prete,"photo":photo})
|
||||
|
||||
|
||||
|
||||
class InstruCreate(ChefRequiredMixin, CreateView):
|
||||
model = Instrument
|
||||
fields = ["owner",'etat','type','marque','model','serial','annee','prix']
|
||||
template_name = "instruments/create_instru.html"
|
||||
success_url = reverse_lazy("instruments:liste")
|
||||
|
||||
|
||||
@chef_required
|
||||
def create_rep(request, pk):
|
||||
ChefEditForm = modelform_factory(Reparation,
|
||||
fields=("date","description","description_en","prix",'lieux'))
|
||||
if request.method == "POST":
|
||||
form = ChefEditForm(request.POST)
|
||||
|
||||
if form.is_valid():
|
||||
rep = Reparation()
|
||||
rep.date = form.cleaned_data['date']
|
||||
rep.description = form.cleaned_data['description']
|
||||
rep.description_en = form.cleaned_data['description_en']
|
||||
rep.prix = form.cleaned_data['prix']
|
||||
rep.lieux = form.cleaned_data['lieux']
|
||||
rep.id_instru = get_object_or_404(Instrument, id=pk)
|
||||
rep.save()
|
||||
return redirect( 'instruments:fiche_instru', pk=pk)
|
||||
|
||||
else:
|
||||
form = ChefEditForm(request.POST)
|
||||
return render(request, 'instruments/create_rep.html', locals())
|
||||
|
||||
|
||||
|
||||
@chef_required
|
||||
def delete_rep(request,pk):
|
||||
rep = get_object_or_404(Reparation, id=pk)
|
||||
|
||||
id_instru = rep.instru.id
|
||||
|
||||
rep.delete()
|
||||
suppression = _("Réparation supprimée")
|
||||
|
||||
|
||||
return redirect('instruments:fiche_instru',pk=id_instru)
|
||||
|
||||
@login_required
|
||||
def fiche_instru(request, pk):
|
||||
instru = get_object_or_404(Instrument, id=pk)
|
||||
reparations= Reparation.objects.filter(instru = pk).order_by('-date')
|
||||
ChefEditForm = modelform_factory(Instrument,
|
||||
fields=("statut","user","infos","type","owner","marque","model","serial","annee","prix","infos_en"))
|
||||
if request.method == "POST" and request.user.profile.is_chef:
|
||||
form = ChefEditForm(request.POST, instance=instru)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
form = ChefEditForm(instance=instru)
|
||||
infos = mark_safe(instru.infos)
|
||||
infos_en = mark_safe(instru.infos_en)
|
||||
return render(request, 'instruments/update_instru.html', locals())
|
||||
|
||||
|
||||
class RepUpdate(ChefRequiredMixin, UpdateView):
|
||||
model = Reparation
|
||||
fields = ["date","description","description_en","prix",'lieux']
|
||||
template_name = "instruments/update_rep.html"
|
||||
|
||||
def get_success_url(self):
|
||||
# if you are passing 'pk' from 'urls' to 'DeleteView' for company
|
||||
# capture that 'pk' as companyid and pass it to 'reverse_lazy()' function
|
||||
id_instru=get_object_or_404(Reparation, id=self.kwargs['pk']).instru.id
|
||||
return reverse_lazy('instruments:fiche_instru', kwargs={'pk': id_instru})
|
||||
|
||||
class InstruDelete(ChefRequiredMixin, DeleteView):
|
||||
model = Instrument
|
||||
template_name = "instruments/delete_instru.html"
|
||||
success_url = reverse_lazy("instruments:liste")
|
|
@ -73,7 +73,7 @@ def listepart(request, nom, auteur):
|
|||
infos_en = mark_safe(p.infos_en)
|
||||
return render(request, 'partitions/part.html', locals())
|
||||
|
||||
@login_required
|
||||
@chef_required
|
||||
def upload(request, nom, auteur):
|
||||
if request.method == "POST":
|
||||
form = UploadFileForm(request.POST, request.FILES)
|
||||
|
|
Loading…
Reference in a new issue