3
0
Fork 0
mirror of https://github.com/nanoy42/coope synced 2024-11-25 22:22:27 +00:00

Fix de bugs, menus

This commit is contained in:
Yoann Pétri 2018-11-27 09:07:12 +01:00
parent a78828375c
commit 6aad16445e
21 changed files with 748 additions and 76 deletions

View file

@ -44,6 +44,7 @@ INSTALLED_APPS = [
'coopeV3', 'coopeV3',
'dal', 'dal',
'dal_select2', 'dal_select2',
'simple_history',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -54,6 +55,7 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'simple_history.middleware.HistoryRequestMiddleware',
] ]
ROOT_URLCONF = 'coopeV3.urls' ROOT_URLCONF = 'coopeV3.urls'

View file

@ -1,11 +1,14 @@
from django.contrib import admin from django.contrib import admin
from simple_history.admin import SimpleHistoryAdmin
from .models import Reload, Refund, Product, Keg, ConsumptionHistory, KegHistory, Consumption from .models import Reload, Refund, Product, Keg, ConsumptionHistory, KegHistory, Consumption, Menu, MenuHistory
admin.site.register(Reload) admin.site.register(Reload, SimpleHistoryAdmin)
admin.site.register(Refund) admin.site.register(Refund, SimpleHistoryAdmin)
admin.site.register(Product) admin.site.register(Product, SimpleHistoryAdmin)
admin.site.register(Keg) admin.site.register(Keg, SimpleHistoryAdmin)
admin.site.register(ConsumptionHistory) admin.site.register(ConsumptionHistory, SimpleHistoryAdmin)
admin.site.register(KegHistory) admin.site.register(KegHistory, SimpleHistoryAdmin)
admin.site.register(Consumption) admin.site.register(Consumption, SimpleHistoryAdmin)
admin.site.register(Menu, SimpleHistoryAdmin)
admin.site.register(MenuHistory, SimpleHistoryAdmin)

View file

@ -18,14 +18,6 @@ class ReloadForm(forms.ModelForm):
fields = ("customer", "amount", "PaymentMethod") fields = ("customer", "amount", "PaymentMethod")
widgets = {'customer': autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2})} widgets = {'customer': autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2})}
def clean_amount(self):
if self.cleaned_data['amount'] <= 0:
raise ValidationError(
"Le montant doit être strictement positif"
)
else:
return self.cleaned_data['amount']
class RefundForm(forms.ModelForm): class RefundForm(forms.ModelForm):
class Meta: class Meta:
@ -33,14 +25,6 @@ class RefundForm(forms.ModelForm):
fields = ("customer", "amount") fields = ("customer", "amount")
widgets = {'customer': autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2})} widgets = {'customer': autocomplete.ModelSelect2(url='users:active-users-autocomplete', attrs={'data-minimum-input-length':2})}
def clean_amount(self):
if self.cleaned_data['amount'] <= 0:
raise ValidationError(
"Le montant doit être strictement positif"
)
else:
return self.cleaned_data['amount']
class ProductForm(forms.ModelForm): class ProductForm(forms.ModelForm):
class Meta: class Meta:

View file

@ -0,0 +1,266 @@
# Generated by Django 2.1 on 2018-11-26 07:57
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 = [
('preferences', '0003_historicalcotisation_historicalgeneralpreferences_historicalpaymentmethod'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('gestion', '0004_consumption'),
]
operations = [
migrations.CreateModel(
name='HistoricalConsumption',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('quantity', models.PositiveIntegerField(default=0)),
('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)),
('customer', 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)),
('product', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gestion.Product')),
],
options={
'verbose_name': 'historical consumption',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalConsumptionHistory',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('quantity', models.PositiveIntegerField(default=0)),
('date', models.DateTimeField(blank=True, editable=False)),
('amount', models.DecimalField(decimal_places=2, default=0, max_digits=7)),
('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)),
('coopeman', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
('customer', 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)),
('menu', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gestion.MenuHistory')),
('paymentMethod', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='preferences.PaymentMethod')),
('product', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gestion.Product')),
],
options={
'verbose_name': 'historical consumption history',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalKeg',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('name', models.CharField(db_index=True, max_length=20, verbose_name='Nom')),
('stockHold', models.IntegerField(default=0, verbose_name='Stock en soute')),
('barcode', models.CharField(db_index=True, max_length=20, verbose_name='Code barre')),
('amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Prix du fût')),
('capacity', models.IntegerField(default=30, verbose_name='Capacité (L)')),
('is_active', models.BooleanField(default=False, verbose_name='Actif')),
('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)),
('demi', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gestion.Product')),
('galopin', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gestion.Product')),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('pinte', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gestion.Product')),
],
options={
'verbose_name': 'historical keg',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalKegHistory',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('openingDate', models.DateTimeField(blank=True, editable=False)),
('quantitySold', models.DecimalField(decimal_places=2, default=0, max_digits=5)),
('amountSold', models.DecimalField(decimal_places=2, default=0, max_digits=5)),
('closingDate', models.DateTimeField(blank=True, null=True)),
('isCurrentKegHistory', models.BooleanField(default=True)),
('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)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('keg', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gestion.Keg')),
],
options={
'verbose_name': 'historical keg history',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalMenu',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='Nom')),
('amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Montant')),
('barcode', models.CharField(db_index=True, max_length=20, verbose_name='Code barre')),
('is_active', models.BooleanField(default=False, verbose_name='Actif')),
('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)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical menu',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalMenuHistory',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('quantity', models.PositiveIntegerField(default=0)),
('date', models.DateTimeField(blank=True, editable=False)),
('amount', models.DecimalField(decimal_places=2, default=0, max_digits=5)),
('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)),
('PaymentMethod', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='preferences.PaymentMethod')),
('coopeman', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
('customer', 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)),
('menu', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gestion.Menu')),
],
options={
'verbose_name': 'historical menu history',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalProduct',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('name', models.CharField(db_index=True, max_length=40, verbose_name='Nom')),
('amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Prix de vente')),
('stockHold', models.IntegerField(default=0, verbose_name='Stock en soute')),
('stockBar', models.IntegerField(default=0, verbose_name='Stock en bar')),
('barcode', models.CharField(db_index=True, max_length=20, verbose_name='Code barre')),
('category', models.CharField(choices=[('PP', 'Pinte Pression'), ('DP', 'Demi Pression'), ('GP', 'Galopin pression'), ('BT', 'Bouteille'), ('SO', 'Soft'), ('FO', 'Bouffe autre que panini'), ('PA', 'Bouffe pour panini')], default='FO', max_length=2, verbose_name='Catégorie')),
('needQuantityButton', models.BooleanField(default=False, verbose_name='Bouton quantité')),
('is_active', models.BooleanField(default=True, verbose_name='Actif')),
('volume', models.IntegerField(default=0)),
('deg', models.DecimalField(decimal_places=2, default=0, max_digits=5, verbose_name='Degré')),
('adherentRequired', models.BooleanField(default=True)),
('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)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical product',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalRaming',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('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)),
('coopeman', 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)),
('keg', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='gestion.Keg')),
],
options={
'verbose_name': 'historical raming',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalRefund',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('date', models.DateTimeField(blank=True, editable=False)),
('amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Montant')),
('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)),
('coopeman', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
('customer', 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)),
],
options={
'verbose_name': 'historical refund',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalReload',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Montant')),
('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)),
('PaymentMethod', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='preferences.PaymentMethod')),
('coopeman', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
('customer', 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)),
],
options={
'verbose_name': 'historical reload',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalStocking',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('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)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical stocking',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
]

View file

@ -0,0 +1,84 @@
# Generated by Django 2.1 on 2018-11-26 13:08
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gestion', '0005_historicalconsumption_historicalconsumptionhistory_historicalkeg_historicalkeghistory_historicalmenu'),
]
operations = [
migrations.AlterField(
model_name='historicalkeg',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Prix du fût'),
),
migrations.AlterField(
model_name='historicalmenu',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Montant'),
),
migrations.AlterField(
model_name='historicalproduct',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Prix de vente'),
),
migrations.AlterField(
model_name='historicalproduct',
name='deg',
field=models.DecimalField(decimal_places=2, default=0, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Degré'),
),
migrations.AlterField(
model_name='historicalproduct',
name='volume',
field=models.PositiveIntegerField(default=0),
),
migrations.AlterField(
model_name='historicalrefund',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Montant'),
),
migrations.AlterField(
model_name='historicalreload',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Montant'),
),
migrations.AlterField(
model_name='keg',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Prix du fût'),
),
migrations.AlterField(
model_name='menu',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Montant'),
),
migrations.AlterField(
model_name='product',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Prix de vente'),
),
migrations.AlterField(
model_name='product',
name='deg',
field=models.DecimalField(decimal_places=2, default=0, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Degré'),
),
migrations.AlterField(
model_name='product',
name='volume',
field=models.PositiveIntegerField(default=0),
),
migrations.AlterField(
model_name='refund',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Montant'),
),
migrations.AlterField(
model_name='reload',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Montant'),
),
]

View file

@ -0,0 +1,23 @@
# Generated by Django 2.1 on 2018-11-27 08:02
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('gestion', '0006_auto_20181126_1408'),
]
operations = [
migrations.RenameField(
model_name='historicalmenuhistory',
old_name='PaymentMethod',
new_name='paymentMethod',
),
migrations.RenameField(
model_name='menuhistory',
old_name='PaymentMethod',
new_name='paymentMethod',
),
]

View file

@ -2,6 +2,9 @@ from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from preferences.models import PaymentMethod from preferences.models import PaymentMethod
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from simple_history.models import HistoricalRecords
from django.core.validators import MinValueValidator
class Product(models.Model): class Product(models.Model):
P_PRESSION = 'PP' P_PRESSION = 'PP'
@ -21,16 +24,17 @@ class Product(models.Model):
(PANINI, "Bouffe pour panini"), (PANINI, "Bouffe pour panini"),
) )
name = models.CharField(max_length=40, verbose_name="Nom", unique=True) name = models.CharField(max_length=40, verbose_name="Nom", unique=True)
amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Prix de vente") amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Prix de vente", validators=[MinValueValidator(0)])
stockHold = models.IntegerField(default=0, verbose_name="Stock en soute") stockHold = models.IntegerField(default=0, verbose_name="Stock en soute")
stockBar = models.IntegerField(default=0, verbose_name="Stock en bar") stockBar = models.IntegerField(default=0, verbose_name="Stock en bar")
barcode= models.CharField(max_length=20, unique=True, verbose_name="Code barre") barcode = models.CharField(max_length=20, unique=True, verbose_name="Code barre")
category = models.CharField(max_length=2, choices=TYPEINPUT_CHOICES_CATEGORIE, default=FOOD, verbose_name="Catégorie") category = models.CharField(max_length=2, choices=TYPEINPUT_CHOICES_CATEGORIE, default=FOOD, verbose_name="Catégorie")
needQuantityButton = models.BooleanField(default=False, verbose_name="Bouton quantité") needQuantityButton = models.BooleanField(default=False, verbose_name="Bouton quantité")
is_active = models.BooleanField(default=True, verbose_name="Actif") is_active = models.BooleanField(default=True, verbose_name="Actif")
volume = models.IntegerField(default=0) volume = models.PositiveIntegerField(default=0)
deg = models.DecimalField(default=0,max_digits=5, decimal_places=2, verbose_name="Degré") deg = models.DecimalField(default=0,max_digits=5, decimal_places=2, verbose_name="Degré", validators=[MinValueValidator(0)])
adherentRequired = models.BooleanField(default=True) adherentRequired = models.BooleanField(default=True)
history = HistoricalRecords()
def __str__(self): def __str__(self):
return self.name return self.name
@ -71,12 +75,13 @@ class Keg(models.Model):
name = models.CharField(max_length=20, unique=True, verbose_name="Nom") name = models.CharField(max_length=20, unique=True, verbose_name="Nom")
stockHold = models.IntegerField(default=0, verbose_name="Stock en soute") stockHold = models.IntegerField(default=0, verbose_name="Stock en soute")
barcode = models.CharField(max_length=20, unique=True, verbose_name="Code barre") barcode = models.CharField(max_length=20, unique=True, verbose_name="Code barre")
amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Prix du fût") amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Prix du fût", validators=[MinValueValidator(0)])
capacity = models.IntegerField(default=30, verbose_name="Capacité (L)") capacity = models.IntegerField(default=30, verbose_name="Capacité (L)")
pinte = models.ForeignKey(Product, on_delete=models.PROTECT, related_name="futp", validators=[isPinte]) pinte = models.ForeignKey(Product, on_delete=models.PROTECT, related_name="futp", validators=[isPinte])
demi = models.ForeignKey(Product, on_delete=models.PROTECT, related_name="futd", validators=[isDemi]) demi = models.ForeignKey(Product, on_delete=models.PROTECT, related_name="futd", validators=[isDemi])
galopin = models.ForeignKey(Product, on_delete=models.PROTECT, related_name="futg", validators=[isGalopin],null=True, blank=True) galopin = models.ForeignKey(Product, on_delete=models.PROTECT, related_name="futg", validators=[isGalopin],null=True, blank=True)
is_active = models.BooleanField(default=False, verbose_name="Actif") is_active = models.BooleanField(default=False, verbose_name="Actif")
history = HistoricalRecords()
def __str__(self): def __str__(self):
return self.name return self.name
@ -88,6 +93,7 @@ class KegHistory(models.Model):
amountSold = models.DecimalField(decimal_places=2, max_digits=5, default=0) amountSold = models.DecimalField(decimal_places=2, max_digits=5, default=0)
closingDate = models.DateTimeField(null=True, blank=True) closingDate = models.DateTimeField(null=True, blank=True)
isCurrentKegHistory = models.BooleanField(default=True) isCurrentKegHistory = models.BooleanField(default=True)
history = HistoricalRecords()
def __str__(self): def __str__(self):
res = "Fût de " + str(self.keg) + " (" + str(self.openingDate) + " - " res = "Fût de " + str(self.keg) + " (" + str(self.openingDate) + " - "
@ -99,10 +105,11 @@ class KegHistory(models.Model):
class Reload(models.Model): class Reload(models.Model):
customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="reload_taken", verbose_name="Client") customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="reload_taken", verbose_name="Client")
amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant") amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant", validators=[MinValueValidator(0)])
PaymentMethod = models.ForeignKey(PaymentMethod, on_delete=models.PROTECT, verbose_name="Moyen de paiement") PaymentMethod = models.ForeignKey(PaymentMethod, on_delete=models.PROTECT, verbose_name="Moyen de paiement")
coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="reload_realized") coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="reload_realized")
date = models.DateTimeField(auto_now_add=True) date = models.DateTimeField(auto_now_add=True)
history = HistoricalRecords()
def __str__(self): def __str__(self):
return "Rechargement effectue par {0} le {1} ({2} euros, coopeman : {3})".format(self.customer, self.date, self.amount, self.coopeman) return "Rechargement effectue par {0} le {1} ({2} euros, coopeman : {3})".format(self.customer, self.date, self.amount, self.coopeman)
@ -112,12 +119,14 @@ class Raming(models.Model):
keg = models.ForeignKey(Keg, on_delete=models.PROTECT) keg = models.ForeignKey(Keg, on_delete=models.PROTECT)
coopeman = models.ForeignKey(User, on_delete=models.PROTECT) coopeman = models.ForeignKey(User, on_delete=models.PROTECT)
date = models.DateTimeField(auto_now_add=True) date = models.DateTimeField(auto_now_add=True)
history = HistoricalRecords()
def __str__(self): def __str__(self):
return "Percussion d'un {0} effectué par {1} le {2}".format(self.keg, self.coopeman, self.date) return "Percussion d'un {0} effectué par {1} le {2}".format(self.keg, self.coopeman, self.date)
class Stocking(models.Model): class Stocking(models.Model):
date = models.DateTimeField(auto_now_add=True) date = models.DateTimeField(auto_now_add=True)
history = HistoricalRecords()
def __str__(self): def __str__(self):
return "Inventaire fait le {0}".format(self.date) return "Inventaire fait le {0}".format(self.date)
@ -126,8 +135,9 @@ class Stocking(models.Model):
class Refund(models.Model): class Refund(models.Model):
date = models.DateTimeField(auto_now_add=True) date = models.DateTimeField(auto_now_add=True)
customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="refund_taken", verbose_name="Client") customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="refund_taken", verbose_name="Client")
amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant") amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant", validators=[MinValueValidator(0)])
coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="refund_realized") coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="refund_realized")
history = HistoricalRecords()
def __str__(self): def __str__(self):
return "{0} remboursé de {1} le {2} (effectué par {3})".format(self.customer, self.amount, self.date, self.coopeman) return "{0} remboursé de {1} le {2} (effectué par {3})".format(self.customer, self.amount, self.date, self.coopeman)
@ -135,22 +145,31 @@ class Refund(models.Model):
class Menu(models.Model): class Menu(models.Model):
name = models.CharField(max_length=255, verbose_name="Nom") name = models.CharField(max_length=255, verbose_name="Nom")
amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant") amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant", validators=[MinValueValidator(0)])
barcode = models.CharField(max_length=20, unique=True, verbose_name="Code barre") barcode = models.CharField(max_length=20, unique=True, verbose_name="Code barre")
articles = models.ManyToManyField(Product, verbose_name="Produits") articles = models.ManyToManyField(Product, verbose_name="Produits")
is_active = models.BooleanField(default=False, verbose_name="Actif") is_active = models.BooleanField(default=False, verbose_name="Actif")
history = HistoricalRecords()
def __str__(self): def __str__(self):
return self.name return self.name
@property
def adherent_required(self):
res = False
for article in self.articles.all():
res = res or article.adherentRequired
return res
class MenuHistory(models.Model): class MenuHistory(models.Model):
customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="menu_taken") customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="menu_taken")
quantity = models.PositiveIntegerField(default=0) quantity = models.PositiveIntegerField(default=0)
PaymentMethod = models.ForeignKey(PaymentMethod, on_delete=models.PROTECT) paymentMethod = models.ForeignKey(PaymentMethod, on_delete=models.PROTECT)
date = models.DateTimeField(auto_now_add=True) date = models.DateTimeField(auto_now_add=True)
menu = models.ForeignKey(Menu, on_delete=models.PROTECT) menu = models.ForeignKey(Menu, on_delete=models.PROTECT)
amount = models.DecimalField(max_digits=5, decimal_places=2, default=0) amount = models.DecimalField(max_digits=5, decimal_places=2, default=0)
coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="menu_selled") coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="menu_selled")
history = HistoricalRecords()
def __str__(self): def __str__(self):
return "{2} a consommé {0} {1}".format(self.quantity, self.menu, self.customer) return "{2} a consommé {0} {1}".format(self.quantity, self.menu, self.customer)
@ -164,6 +183,7 @@ class ConsumptionHistory(models.Model):
menu = models.ForeignKey(MenuHistory, on_delete=models.CASCADE, null=True, blank=True) menu = models.ForeignKey(MenuHistory, on_delete=models.CASCADE, null=True, blank=True)
amount = models.DecimalField(max_digits=7, decimal_places=2, default=0) amount = models.DecimalField(max_digits=7, decimal_places=2, default=0)
coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="consumption_selled") coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="consumption_selled")
history = HistoricalRecords()
def __str__(self): def __str__(self):
return "{0} {1} consommé par {2} le {3} (encaissé par {4})".format(self.quantity, self.product, self.customer, self.date, self.coopeman) return "{0} {1} consommé par {2} le {3} (encaissé par {4})".format(self.quantity, self.product, self.customer, self.date, self.coopeman)
@ -172,6 +192,7 @@ class Consumption(models.Model):
customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="consumption_global_taken") customer = models.ForeignKey(User, on_delete=models.PROTECT, related_name="consumption_global_taken")
product = models.ForeignKey(Product, on_delete=models.PROTECT) product = models.ForeignKey(Product, on_delete=models.PROTECT)
quantity = models.PositiveIntegerField(default=0) quantity = models.PositiveIntegerField(default=0)
history = HistoricalRecords()
def __str__(self): def __str__(self):
return "Consommation de " + str(self.customer) + " concernant le produit " + str(self.product) return "Consommation de " + str(self.customer) + " concernant le produit " + str(self.product)

View file

@ -97,7 +97,7 @@
{% if forloop.counter0|divisibleby:4 %} {% if forloop.counter0|divisibleby:4 %}
<tr style="text-align:center"> <tr style="text-align:center">
{% endif %} {% endif %}
<td><button class="product" target="{{product.barcode}}">{{product.name}}</button></td> <td><button class="product {% if product.adherentRequired %}special{% endif%}" target="{{product.barcode}}">{{product.name}}</button></td>
{% if forloop.counter|divisibleby:4 %} {% if forloop.counter|divisibleby:4 %}
</tr> </tr>
{% endif %} {% endif %}
@ -110,7 +110,7 @@
{% if forloop.counter0|divisibleby:4 %} {% if forloop.counter0|divisibleby:4 %}
<tr style="text-align:center"> <tr style="text-align:center">
{% endif %} {% endif %}
<td><button class="product" target="{{product.barcode}}">{{product.name}}</button></td> <td><button class="product {% if product.adherentRequired %}special{% endif%}" target="{{product.barcode}}">{{product.name}}</button></td>
{% if forloop.counter|divisibleby:4 %} {% if forloop.counter|divisibleby:4 %}
</tr> </tr>
{% endif %} {% endif %}
@ -123,7 +123,7 @@
{% if forloop.counter0|divisibleby:4 %} {% if forloop.counter0|divisibleby:4 %}
<tr style="text-align:center"> <tr style="text-align:center">
{% endif %} {% endif %}
<td><button class="product" target="{{product.barcode}}">{{product.name}}</button></td> <td><button class="product {% if product.adherentRequired %}special{% endif%}" target="{{product.barcode}}">{{product.name}}</button></td>
{% if forloop.counter|divisibleby:4 %} {% if forloop.counter|divisibleby:4 %}
</tr> </tr>
{% endif %} {% endif %}
@ -136,7 +136,7 @@
{% if forloop.counter0|divisibleby:4 %} {% if forloop.counter0|divisibleby:4 %}
<tr style="text-align:center"> <tr style="text-align:center">
{% endif %} {% endif %}
<td><button class="product" target="{{product.barcode}}">{{product.name}}</button></td> <td><button class="product {% if product.adherentRequired %}special{% endif%}" target="{{product.barcode}}">{{product.name}}</button></td>
{% if forloop.counter|divisibleby:4 %} {% if forloop.counter|divisibleby:4 %}
</tr> </tr>
{% endif %} {% endif %}
@ -150,7 +150,7 @@
{% if forloop.counter0|divisibleby:4 %} {% if forloop.counter0|divisibleby:4 %}
<tr style="text-align:center"> <tr style="text-align:center">
{% endif %} {% endif %}
<td><button class="product" target="{{product.barcode}}">{{product.name}}</button></td> <td><button class="product {% if product.adherentRequired %}special{% endif%}" target="{{product.barcode}}">{{product.name}}</button></td>
{% if forloop.counter|divisibleby:4 %} {% if forloop.counter|divisibleby:4 %}
</tr> </tr>
{% endif %} {% endif %}
@ -164,7 +164,7 @@
{% if forloop.counter0|divisibleby:4 %} {% if forloop.counter0|divisibleby:4 %}
<tr style="text-align:center"> <tr style="text-align:center">
{% endif %} {% endif %}
<td><button class="product" target="{{product.barcode}}">{{product.name}}</button></td> <td><button class="menu {% if product.adherent_required %}special{% endif%}" target="{{product.barcode}}">{{product.name}}</button></td>
{% if forloop.counter|divisibleby:4 %} {% if forloop.counter|divisibleby:4 %}
</tr> </tr>
{% endif %} {% endif %}

View file

@ -24,6 +24,7 @@ urlpatterns = [
path('searchMenu', views.searchMenu, name="searchMenu"), path('searchMenu', views.searchMenu, name="searchMenu"),
path('editMenu/<int:pk>', views.edit_menu, name="editMenu"), path('editMenu/<int:pk>', views.edit_menu, name="editMenu"),
path('menusList', views.menus_list, name="menusList"), path('menusList', views.menus_list, name="menusList"),
path('getMenu/<str:barcode>', views.get_menu, name="getMenu"),
path('swicthActivateMenu/<int:pk>', views.switch_activate_menu, name="switchActivateMenu"), path('swicthActivateMenu/<int:pk>', views.switch_activate_menu, name="switchActivateMenu"),
path('getProduct/<str:barcode>', views.getProduct, name="getProduct"), path('getProduct/<str:barcode>', views.getProduct, name="getProduct"),
path('order', views.order, name="order"), path('order', views.order, name="order"),

View file

@ -14,7 +14,7 @@ from dal import autocomplete
from decimal import * from decimal import *
from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm
from .models import Product, Menu, Keg, ConsumptionHistory, KegHistory, Consumption from .models import Product, Menu, Keg, ConsumptionHistory, KegHistory, Consumption, MenuHistory
from preferences.models import PaymentMethod from preferences.models import PaymentMethod
@active_required @active_required
@ -52,12 +52,16 @@ def order(request):
paymentMethod = get_object_or_404(PaymentMethod, pk=request.POST['paymentMethod']) paymentMethod = get_object_or_404(PaymentMethod, pk=request.POST['paymentMethod'])
amount = Decimal(request.POST['amount']) amount = Decimal(request.POST['amount'])
order = json.loads(request.POST["order"]) order = json.loads(request.POST["order"])
if(len(order) == 0 or amount == 0): menus = json.loads(request.POST["menus"])
if (not order) and (not menus):
return HttpResponse("Pas de commande") return HttpResponse("Pas de commande")
adherentRequired = False adherentRequired = False
for o in order: for o in order:
product = get_object_or_404(Product, pk=o["pk"]) product = get_object_or_404(Product, pk=o["pk"])
adherentRequired = adherentRequired or product.adherentRequired adherentRequired = adherentRequired or product.adherentRequired
for m in menus:
menu = get_object_or_404(Menu, pk=m["pk"])
adherentRequired = adherentRequired or menu.adherent_required
if(adherentRequired and not user.profile.is_adherent): if(adherentRequired and not user.profile.is_adherent):
return HttpResponse("N'est pas adhérent et devrait l'être") return HttpResponse("N'est pas adhérent et devrait l'être")
if(paymentMethod.affect_balance): if(paymentMethod.affect_balance):
@ -72,7 +76,7 @@ def order(request):
if(product.category == Product.P_PRESSION): if(product.category == Product.P_PRESSION):
keg = get_object_or_404(Keg, pinte=product) keg = get_object_or_404(Keg, pinte=product)
if(not keg.is_active): if(not keg.is_active):
return HttpResponse("Une erreur inconnue s'est produite") return HttpResponse("Une erreur inconnue s'est produite. Veuillez contacter le trésorier ou le président")
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True) kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
kegHistory.quantitySold += Decimal(quantity * 0.5) kegHistory.quantitySold += Decimal(quantity * 0.5)
kegHistory.amountSold += Decimal(quantity * product.amount) kegHistory.amountSold += Decimal(quantity * product.amount)
@ -80,7 +84,7 @@ def order(request):
elif(product.category == Product.D_PRESSION): elif(product.category == Product.D_PRESSION):
keg = get_object_or_404(Keg, demi=product) keg = get_object_or_404(Keg, demi=product)
if(not keg.is_active): if(not keg.is_active):
return HttpResponse("Une erreur inconnue s'est produite") return HttpResponse("Une erreur inconnue s'est produite. Veuillez contacter le trésorier ou le président")
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True) kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
kegHistory.quantitySold += Decimal(quantity * 0.25) kegHistory.quantitySold += Decimal(quantity * 0.25)
kegHistory.amountSold += Decimal(quantity * product.amount) kegHistory.amountSold += Decimal(quantity * product.amount)
@ -88,7 +92,7 @@ def order(request):
elif(product.category == Product.G_PRESSION): elif(product.category == Product.G_PRESSION):
keg = get_object_or_404(Keg, galopin=product) keg = get_object_or_404(Keg, galopin=product)
if(not keg.is_active): if(not keg.is_active):
return HttpResponse("Une erreur inconnue s'est produite") return HttpResponse("Une erreur inconnue s'est produite. Veuillez contacter le trésorier ou le président")
kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True) kegHistory = get_object_or_404(KegHistory, keg=keg, isCurrentKegHistory=True)
kegHistory.quantitySold += Decimal(quantity * 0.125) kegHistory.quantitySold += Decimal(quantity * 0.125)
kegHistory.amountSold += Decimal(quantity * product.amount) kegHistory.amountSold += Decimal(quantity * product.amount)
@ -100,7 +104,18 @@ def order(request):
consumption, _ = Consumption.objects.get_or_create(customer=user, product=product) consumption, _ = Consumption.objects.get_or_create(customer=user, product=product)
consumption.quantity += quantity consumption.quantity += quantity
consumption.save() consumption.save()
ch = ConsumptionHistory(customer = user, quantity = quantity, paymentMethod=paymentMethod, product=product, amount=int(o["quantity"])*product.amount, coopeman=request.user) ch = ConsumptionHistory(customer = user, quantity = quantity, paymentMethod=paymentMethod, product=product, amount=int(quantity*product.amount), coopeman=request.user)
ch.save()
for m in menus:
menu = get_object_or_404(Menu, pk=m["pk"])
quantity = int(m["quantity"])
mh = MenuHistory(customer=user, quantity=quantity, paymentMethod=paymentMethod, menu=menu, amount=int(quantity*menu.amount), coopeman=request.user)
mh.save()
for article in menu.articles.all():
consumption, _ = Consumption.objects.get_or_create(customer=user, product=article)
consumption.quantity += quantity
consumption.save()
ch = ConsumptionHistory(customer=user, quantity=quantity, paymentMethod=paymentMethod, product=article, amount=int(quantity*article.amount), coopeman=request.user, menu=mh)
ch.save() ch.save()
return HttpResponse("La commande a bien été effectuée") return HttpResponse("La commande a bien été effectuée")
@ -410,6 +425,12 @@ def switch_activate_menu(request, pk):
messages.success(request, "La disponibilité du menu a bien été changée") messages.success(request, "La disponibilité du menu a bien été changée")
return redirect(reverse('gestion:menusList')) return redirect(reverse('gestion:menusList'))
@login_required
def get_menu(request, barcode):
menu = get_object_or_404(Menu, barcode=barcode)
data = json.dumps({"pk": menu.pk, "barcode" : menu.barcode, "name": menu.name, "amount" : menu.amount})
return HttpResponse(data, content_type='application/json')
class MenusAutocomplete(autocomplete.Select2QuerySetView): class MenusAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self): def get_queryset(self):
qs = Menu.objects.all() qs = Menu.objects.all()

View file

@ -1,8 +1,7 @@
from django.contrib import admin from django.contrib import admin
from simple_history.admin import SimpleHistoryAdmin
from .models import PaymentMethod, GeneralPreferences, Cotisation from .models import PaymentMethod, GeneralPreferences, Cotisation
admin.site.register(PaymentMethod) admin.site.register(PaymentMethod, SimpleHistoryAdmin)
admin.site.register(GeneralPreferences) admin.site.register(GeneralPreferences, SimpleHistoryAdmin)
admin.site.register(Cotisation) admin.site.register(Cotisation, SimpleHistoryAdmin)
# Register your models here.

View file

@ -8,14 +8,6 @@ class CotisationForm(forms.ModelForm):
model = Cotisation model = Cotisation
fields = "__all__" fields = "__all__"
def clean_amount(self):
if self.cleaned_data['amount'] <= 0:
raise ValidationError(
"Le montant doit être strictement positif"
)
else:
return self.cleaned_data['amount']
class PaymentMethodForm(forms.ModelForm): class PaymentMethodForm(forms.ModelForm):
class Meta: class Meta:
model = PaymentMethod model = PaymentMethod

View file

@ -0,0 +1,84 @@
# Generated by Django 2.1 on 2018-11-26 07:57
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),
('preferences', '0002_auto_20181009_1119'),
]
operations = [
migrations.CreateModel(
name='HistoricalCotisation',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('amount', models.DecimalField(decimal_places=2, max_digits=5, null=True, verbose_name='Montant')),
('duration', models.PositiveIntegerField(verbose_name='Durée de la cotisation (jours)')),
('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)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical cotisation',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalGeneralPreferences',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('is_active', models.BooleanField(default=True)),
('active_message', models.TextField(blank=True)),
('global_message', models.TextField(blank=True)),
('president', models.CharField(blank=True, max_length=255)),
('vice_president', models.CharField(blank=True, max_length=255)),
('treasurer', models.CharField(blank=True, max_length=255)),
('secretary', models.CharField(blank=True, max_length=255)),
('brewer', models.CharField(blank=True, max_length=255)),
('grocer', models.CharField(blank=True, max_length=255)),
('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)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical general preferences',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalPaymentMethod',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='Nom')),
('is_active', models.BooleanField(default=True, verbose_name='Actif')),
('is_usable_in_cotisation', models.BooleanField(default=True, verbose_name='Cotisations ?')),
('is_usable_in_reload', models.BooleanField(default=True, verbose_name='Rechargements ?')),
('affect_balance', models.BooleanField(default=False, verbose_name='Affecte le solde')),
('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)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical payment method',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
]

View file

@ -0,0 +1,24 @@
# Generated by Django 2.1 on 2018-11-26 13:08
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('preferences', '0003_historicalcotisation_historicalgeneralpreferences_historicalpaymentmethod'),
]
operations = [
migrations.AlterField(
model_name='cotisation',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Montant'),
),
migrations.AlterField(
model_name='historicalcotisation',
name='amount',
field=models.DecimalField(decimal_places=2, max_digits=5, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Montant'),
),
]

View file

@ -1,4 +1,7 @@
from django.db import models from django.db import models
from simple_history.models import HistoricalRecords
from django.core.validators import MinValueValidator
class PaymentMethod(models.Model): class PaymentMethod(models.Model):
name = models.CharField(max_length=255, verbose_name="Nom") name = models.CharField(max_length=255, verbose_name="Nom")
@ -6,6 +9,7 @@ class PaymentMethod(models.Model):
is_usable_in_cotisation = models.BooleanField(default=True, verbose_name="Cotisations ?") is_usable_in_cotisation = models.BooleanField(default=True, verbose_name="Cotisations ?")
is_usable_in_reload = models.BooleanField(default=True, verbose_name="Rechargements ?") is_usable_in_reload = models.BooleanField(default=True, verbose_name="Rechargements ?")
affect_balance = models.BooleanField(default=False, verbose_name="Affecte le solde") affect_balance = models.BooleanField(default=False, verbose_name="Affecte le solde")
history = HistoricalRecords()
def __str__(self): def __str__(self):
return self.name return self.name
@ -20,10 +24,12 @@ class GeneralPreferences(models.Model):
secretary = models.CharField(max_length=255, blank=True) secretary = models.CharField(max_length=255, blank=True)
brewer = models.CharField(max_length=255, blank=True) brewer = models.CharField(max_length=255, blank=True)
grocer = models.CharField(max_length=255, blank=True) grocer = models.CharField(max_length=255, blank=True)
history = HistoricalRecords()
class Cotisation(models.Model): class Cotisation(models.Model):
amount = models.DecimalField(max_digits=5, decimal_places=2, null=True, verbose_name="Montant") amount = models.DecimalField(max_digits=5, decimal_places=2, null=True, verbose_name="Montant", validators=[MinValueValidator(0)])
duration = models.PositiveIntegerField(verbose_name="Durée de la cotisation (jours)") duration = models.PositiveIntegerField(verbose_name="Durée de la cotisation (jours)")
history = HistoricalRecords()
def __str__(self): def __str__(self):
return "Cotisation de " + str(self.duration) + " jours pour le prix de " + str(self.amount) + "" return "Cotisation de " + str(self.duration) + " jours pour le prix de " + str(self.amount) + ""

View file

@ -3,3 +3,4 @@ django-autocomplete-light==3.3.2
pytz==2018.5 pytz==2018.5
simplejson==3.16.0 simplejson==3.16.0
docutils==0.14 docutils==0.14
django-simple-history==2.5.1

View file

@ -1,5 +1,6 @@
total = 0 total = 0
products = [] products = []
menus = []
paymentMethod = null paymentMethod = null
balance = 0 balance = 0
username = "" username = ""
@ -11,6 +12,12 @@ function get_product(barcode){
}); });
} }
function get_menu(barcode){
res = $.get("getMenu/" + barcode, function(data){
add_menu(data.pk, data.barcode, data.name, data.amount);
});
}
function add_product(pk, barcode, name, amount){ function add_product(pk, barcode, name, amount){
exist = false exist = false
index = -1 index = -1
@ -28,30 +35,71 @@ function add_product(pk, barcode, name, amount){
generate_html() generate_html()
} }
function add_menu(pk, barcode, name, amount){
exist = false;
index = -1;
for(k=0; k < menus.length; k++){
if(menus[k].pk == pk){
exist = true;
index = k;
}
}
if(exist){
menus[index].quantity += 1;
}else{
menus.push({"pk": pk, "barcode": barcode, "name": name, "amount": amount, "quantity":1});
}
generate_html();
}
function generate_html(){ function generate_html(){
html ="" html =""
for(k=0;k<products.length;k++){ for(k=0;k<products.length;k++){
product = products[k] product = products[k]
html += "<tr><td>" + product.barcode + "</td><td>" + product.name + "</td><td>" + String(product.amount) + "</td><td>" + String(product.quantity) + "</td><td>" + String(product.quantity * product.amount) + "</td></tr>" html += '<tr><td>' + product.barcode + '</td><td>' + product.name + '</td><td>' + String(product.amount) + '</td><td><input type="number" data-target="' + String(k) + '" onChange="updateInput(this)" value="' + String(product.quantity) + '"/></td><td>' + String(product.quantity * product.amount) + '</td></tr>';
}
for(k=0; k<menus.length;k++){
menu = menus[k]
html += '<tr><td>' + menu.barcode + '</td><td>' + menu.name + '</td><td>' + String(menu.amount) + '</td><td><input type="number" data-target="' + String(k) + '" onChange="updateMenuInput(this)" value="' + String(menu.quantity) + '"/></td><td>' + String(menu.quantity * menu.amount) + '</td></tr>';
} }
$("#items").html(html) $("#items").html(html)
updateTotal() updateTotal();
} }
function updateTotal(){ function updateTotal(){
total = 0 total = 0
for(k=0;k<products.length;k++){ for(k=0;k<products.length;k++){
total += products[k].quantity * products[k].amount total += products[k].quantity * products[k].amount;
}
for(k=0; k<menus.length;k++){
total += menus[k].quantity * menus[k].amount;
} }
$("#totalAmount").text(String(total) + "€") $("#totalAmount").text(String(total) + "€")
totalAfter = balance - total totalAfter = balance - total
$("#totalAfter").text(totalAfter + "€") $("#totalAfter").text(totalAfter + "€")
} }
function updateInput(a){
quantity = parseInt(a.value)
k = parseInt(a.getAttribute("data-target"))
products[k].quantity = quantity
generate_html()
}
function updateMenuInput(a){
quantity = parseInt(a.value);
k = parseInt(a.getAttribute("data-target"));
menus[k].quantity = quantity;
generate_html();
}
$(document).ready(function(){ $(document).ready(function(){
$(".product").click(function(){ $(".product").click(function(){
product = get_product($(this).attr('target')); product = get_product($(this).attr('target'));
}); });
$(".menu").click(function(){
menu = get_menu($(this).attr('target'));
})
$("#id_client").on('change', function(){ $("#id_client").on('change', function(){
id = $("#id_client").val(); id = $("#id_client").val();
$.get("/users/getUser/" + id, function(data){ $.get("/users/getUser/" + id, function(data){
@ -65,13 +113,11 @@ $(document).ready(function(){
}); });
}); });
$(".pay_button").click(function(){ $(".pay_button").click(function(){
alert('Tentative de paiment avec le moyen ' + $(this).attr('data-payment')); $.post("order", {"user":id, "paymentMethod": $(this).attr('data-payment'), "order_length": products.length + menus.length, "order": JSON.stringify(products), "amount": total, "menus": JSON.stringify(menus)}, function(data){
console.log(products)
$.post("order", {"user":id, "paymentMethod": $(this).attr('data-payment'), "order_length": products.length, "order": JSON.stringify(products), "amount": total}, function(data){
alert(data); alert(data);
location.reload(); location.reload();
}).fail(function(data){ }).fail(function(data){
alert("Impossible d'effectuer la transaction"); alert("Impossible d'effectuer la transaction. Veuillez contacter le trésorier ou le président");
location.reload(); location.reload();
}); });
}); });

View file

@ -1,9 +1,10 @@
from django.contrib import admin from django.contrib import admin
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from simple_history.admin import SimpleHistoryAdmin
from .models import School, Profile, CotisationHistory from .models import School, Profile, CotisationHistory
admin.site.register(Permission) admin.site.register(Permission, SimpleHistoryAdmin)
admin.site.register(School) admin.site.register(School, SimpleHistoryAdmin)
admin.site.register(Profile) admin.site.register(Profile, SimpleHistoryAdmin)
admin.site.register(CotisationHistory) admin.site.register(CotisationHistory, SimpleHistoryAdmin)

View file

@ -0,0 +1,106 @@
# Generated by Django 2.1 on 2018-11-26 07:57
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 = [
('preferences', '0003_historicalcotisation_historicalgeneralpreferences_historicalpaymentmethod'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('users', '0003_auto_20181123_0229'),
]
operations = [
migrations.CreateModel(
name='HistoricalCotisationHistory',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('amount', models.DecimalField(decimal_places=2, max_digits=5, verbose_name='Montant')),
('duration', models.PositiveIntegerField(verbose_name='Durée')),
('paymentDate', models.DateTimeField(blank=True, editable=False, verbose_name='Date du paiement')),
('endDate', models.DateTimeField(verbose_name='Fin de la cotisation')),
('valid', models.IntegerField(choices=[(0, 'En attente de validation'), (1, 'Validée'), (2, 'Invalidée')], default=0)),
('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)),
('coopeman', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
('cotisation', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='preferences.Cotisation')),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('paymentMethod', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='preferences.PaymentMethod')),
('user', 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 cotisation history',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalProfile',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('credit', models.DecimalField(decimal_places=2, default=0, max_digits=5)),
('debit', models.DecimalField(decimal_places=2, default=0, max_digits=5)),
('cotisationEnd', models.DateTimeField(blank=True, null=True)),
('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)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('school', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='users.School')),
('user', 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 profile',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalSchool',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='Nom')),
('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)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical school',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalWhiteListHistory',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('paymentDate', models.DateTimeField(blank=True, editable=False)),
('endDate', models.DateTimeField()),
('duration', models.PositiveIntegerField(help_text="Durée de l'accès gracieux en jour", verbose_name='Durée')),
('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)),
('coopeman', 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)),
('user', 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 white list history',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
]

View file

@ -3,12 +3,13 @@ from django.contrib.auth.models import User
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from django.utils import timezone from django.utils import timezone
from simple_history.models import HistoricalRecords
from preferences.models import PaymentMethod, Cotisation from preferences.models import PaymentMethod, Cotisation
from gestion.models import ConsumptionHistory from gestion.models import ConsumptionHistory
class School(models.Model): class School(models.Model):
name = models.CharField(max_length=255, verbose_name="Nom") name = models.CharField(max_length=255, verbose_name="Nom")
history = HistoricalRecords()
def __str__(self): def __str__(self):
return self.name return self.name
@ -36,6 +37,7 @@ class CotisationHistory(models.Model):
cotisation = models.ForeignKey(Cotisation, on_delete=models.PROTECT, verbose_name="Type de cotisation") cotisation = models.ForeignKey(Cotisation, on_delete=models.PROTECT, verbose_name="Type de cotisation")
coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="cotisation_made") coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="cotisation_made")
valid = models.IntegerField(choices=VALIDATION_CHOICES, default=WAITING) valid = models.IntegerField(choices=VALIDATION_CHOICES, default=WAITING)
history = HistoricalRecords()
class WhiteListHistory(models.Model): class WhiteListHistory(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT) user = models.ForeignKey(User, on_delete=models.PROTECT)
@ -43,6 +45,7 @@ class WhiteListHistory(models.Model):
endDate = models.DateTimeField() endDate = models.DateTimeField()
duration = models.PositiveIntegerField(verbose_name="Durée", help_text="Durée de l'accès gracieux en jour") duration = models.PositiveIntegerField(verbose_name="Durée", help_text="Durée de l'accès gracieux en jour")
coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="whitelist_made") coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="whitelist_made")
history = HistoricalRecords()
class Profile(models.Model): class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE) user = models.OneToOneField(User, on_delete=models.CASCADE)
@ -50,6 +53,7 @@ class Profile(models.Model):
debit = models.DecimalField(max_digits=5, decimal_places=2, default=0) debit = models.DecimalField(max_digits=5, decimal_places=2, default=0)
school = models.ForeignKey(School, on_delete=models.PROTECT, blank=True, null=True) school = models.ForeignKey(School, on_delete=models.PROTECT, blank=True, null=True)
cotisationEnd = models.DateTimeField(blank=True, null=True) cotisationEnd = models.DateTimeField(blank=True, null=True)
history = HistoricalRecords()
@property @property
def is_adherent(self): def is_adherent(self):
@ -91,6 +95,10 @@ def save_user_profile(sender, instance, **kwargs):
instance.profile.save() instance.profile.save()
def str_user(self): def str_user(self):
return self.username + " (" + self.first_name + " " + self.last_name + ", " + str(self.profile.balance) + "€)" if(self.profile.is_adherent):
fin = "Adhérent"
else:
fin = "Non adhérent"
return self.username + " (" + self.first_name + " " + self.last_name + ", " + str(self.profile.balance) + "€, " + fin + ")"
User.add_to_class("__str__", str_user) User.add_to_class("__str__", str_user)

View file

@ -651,8 +651,8 @@ def addCotisationHistory(request, pk):
if(user.profile.balance >= cotisation.cotisation.amount): if(user.profile.balance >= cotisation.cotisation.amount):
user.profile.debit += cotisation.cotisation.amount user.profile.debit += cotisation.cotisation.amount
else: else:
cotisation.delete()
messages.error(request, "Solde insuffisant") messages.error(request, "Solde insuffisant")
return redirect(reverse('users:profile',kwargs={'pk':user.pk}))
cotisation.user = user cotisation.user = user
cotisation.coopeman = request.user cotisation.coopeman = request.user
cotisation.amount = cotisation.cotisation.amount cotisation.amount = cotisation.cotisation.amount
@ -708,7 +708,7 @@ def addWhiteListHistory(request, pk):
if(user.profile.cotisationEnd): if(user.profile.cotisationEnd):
whiteList.endDate = user.profile.cotisationEnd + timedelta(days=whiteList.duration) whiteList.endDate = user.profile.cotisationEnd + timedelta(days=whiteList.duration)
else: else:
whiteList = datetime.now() + timedelta(days=whiteList.duration) whiteList.endDate = datetime.now() + timedelta(days=whiteList.duration)
user.profile.cotisationEnd = whiteList.endDate user.profile.cotisationEnd = whiteList.endDate
user.save() user.save()
whiteList.save() whiteList.save()