diff --git a/.gitignore b/.gitignore index 0878e26..0964b9a 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,5 @@ tags # End of https://www.gitignore.io/api/vim,git,django .vscode -venv \ No newline at end of file +venv +static/ diff --git a/CHANGELOG.md b/CHANGELOG.md index fcfd6d7..24b9fde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +## v3.1.0 +* Tronque la quantité d'alcool ingéré sur le profil (fix #8) +* La modification des produits retourne sur la pge de profil du produit (fix #9) +* Les rechargements affichés sur le profil s'arrête bien à 5 (fix #14) +* Seuls les bons moyens de paiement sont proposés dans les cotisations (fix #15) +* Seuls les bons produits sont proposés dans le formulaire de création de fût (fix #16) +* Ajout d'un formulaire pour exporter les utilisateurs au format csv (new feature #2) +* Ajout d'un système de suivi de pintes (new feature #25) +* Désactiver les utilisateurs depuis l'interface (new feature #10) +* Ajout d'une barre de recherche dans l'admin des profils (new feature #3) +* Corrections de mots dans les templates (fix #12) +* Fix de certaines permissions dans les templates de gestion de produits et d'utilisateurs (fix #21) +* Ajout d'un champ d'autocomplétion pour les produits dans les transactions (new feature #20) +* Annulation de rechargement (new feature #23) + +## v3.0.2 +* Fix des annulations de consommations + ## v3.0.1 * Fix page inactive * Fix prix dans les historiques de consommations \ No newline at end of file diff --git a/gestion/forms.py b/gestion/forms.py index da007cf..01079a4 100644 --- a/gestion/forms.py +++ b/gestion/forms.py @@ -11,7 +11,7 @@ from coopeV3.widgets import SearchField class ReloadForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(ReloadForm, self).__init__(*args, **kwargs) - self.fields['PaymentMethod'].queryset = PaymentMethod.objects.filter(is_usable_in_reload=True) + self.fields['PaymentMethod'].queryset = PaymentMethod.objects.filter(is_usable_in_reload=True).filter(is_active=True) class Meta: model = Reload @@ -32,6 +32,12 @@ class ProductForm(forms.ModelForm): fields = "__all__" class KegForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + super(KegForm, self).__init__(*args, **kwargs) + self.fields['pinte'].queryset = Product.objects.filter(category=Product.P_PRESSION) + self.fields['demi'].queryset = Product.objects.filter(category=Product.D_PRESSION) + self.fields['galopin'].queryset = Product.objects.filter(category=Product.G_PRESSION) + class Meta: model = Keg exclude = ("is_active", ) @@ -49,9 +55,15 @@ class SearchMenuForm(forms.Form): class GestionForm(forms.Form): client = forms.ModelChoiceField(queryset=User.objects.filter(is_active=True), required=True, label="Client", widget=autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2})) + product = forms.ModelChoiceField(queryset=Product.objects.filter(is_active=True), required=True, label="Produit", widget=autocomplete.ModelSelect2(url='gestion:active-products-autocomplete', attrs={'data-minimum-input-length':2})) class SelectPositiveKegForm(forms.Form): keg = forms.ModelChoiceField(queryset=Keg.objects.filter(stockHold__gt = 0), required=True, label="Fût", widget=autocomplete.ModelSelect2(url='gestion:kegs-positive-autocomplete')) class SelectActiveKegForm(forms.Form): - keg = forms.ModelChoiceField(queryset=Keg.objects.filter(is_active = True), required=True, label="Fût", widget=autocomplete.ModelSelect2(url='gestion:kegs-active-autocomplete')) \ No newline at end of file + keg = forms.ModelChoiceField(queryset=Keg.objects.filter(is_active = True), required=True, label="Fût", widget=autocomplete.ModelSelect2(url='gestion:kegs-active-autocomplete')) + +class PinteForm(forms.Form): + ids = forms.CharField(widget=forms.Textarea, label="Numéros", help_text="Numéros séparés par un espace. Laissez vide pour utiliser le range.", required=False) + begin = forms.IntegerField(label="Début", help_text="Début du range", required=False) + end = forms.IntegerField(label="Fin", help_text="Fin du range", required=False) \ No newline at end of file diff --git a/gestion/migrations/0002_pinte.py b/gestion/migrations/0002_pinte.py new file mode 100644 index 0000000..93f21fb --- /dev/null +++ b/gestion/migrations/0002_pinte.py @@ -0,0 +1,25 @@ +# Generated by Django 2.1 on 2018-12-21 20:34 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('gestion', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Pinte', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('last_update_date', models.DateTimeField(auto_now=True)), + ('current_owner', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='pinte_owned_currently', to=settings.AUTH_USER_MODEL)), + ('previous_owner', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='pinte_owned_previously', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/gestion/migrations/0003_historicalpinte.py b/gestion/migrations/0003_historicalpinte.py new file mode 100644 index 0000000..243fc58 --- /dev/null +++ b/gestion/migrations/0003_historicalpinte.py @@ -0,0 +1,37 @@ +# Generated by Django 2.1 on 2018-12-21 20:51 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import simple_history.models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('gestion', '0002_pinte'), + ] + + operations = [ + migrations.CreateModel( + name='HistoricalPinte', + fields=[ + ('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), + ('last_update_date', models.DateTimeField(blank=True, editable=False)), + ('history_id', models.AutoField(primary_key=True, serialize=False)), + ('history_change_reason', models.CharField(max_length=100, null=True)), + ('history_date', models.DateTimeField()), + ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)), + ('current_owner', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)), + ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ('previous_owner', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'historical pinte', + 'ordering': ('-history_date', '-history_id'), + 'get_latest_by': 'history_date', + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + ] diff --git a/gestion/migrations/0004_auto_20181223_1830.py b/gestion/migrations/0004_auto_20181223_1830.py new file mode 100644 index 0000000..de74c17 --- /dev/null +++ b/gestion/migrations/0004_auto_20181223_1830.py @@ -0,0 +1,25 @@ +# Generated by Django 2.1 on 2018-12-23 17:30 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('gestion', '0003_historicalpinte'), + ] + + operations = [ + migrations.AlterField( + model_name='pinte', + name='current_owner', + field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='pintes_owned_currently', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='pinte', + name='previous_owner', + field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='pintes_owned_previously', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/gestion/models.py b/gestion/models.py index 33828d6..ee03f91 100644 --- a/gestion/models.py +++ b/gestion/models.py @@ -225,3 +225,12 @@ class Consumption(models.Model): def __str__(self): return "Consommation de " + str(self.customer) + " concernant le produit " + str(self.product) + +class Pinte(models.Model): + """ + Stores a physical pinte + """ + current_owner = models.ForeignKey(User, on_delete=models.PROTECT, null=True, default=None, related_name="pintes_owned_currently") + previous_owner = models.ForeignKey(User, on_delete=models.PROTECT, null=True, default=None, related_name="pintes_owned_previously") + last_update_date = models.DateTimeField(auto_now=True) + history = HistoricalRecords() diff --git a/gestion/templates/gestion/kegh.html b/gestion/templates/gestion/kegh.html index 2842487..339a5e6 100644 --- a/gestion/templates/gestion/kegh.html +++ b/gestion/templates/gestion/kegh.html @@ -1,5 +1,5 @@ {% extends 'base.html' %} -{% block entete %}

Gestion des produits

{% endblock %} +{% block entete %}Gestion des produits{% endblock %} {% block navbar%}