Commit c4715cca authored by Grizzly's avatar Grizzly Committed by root

Paiement par note kfet pour les users lambda

parent bf2dd129
......@@ -38,6 +38,7 @@ INSTALLED_APPS = (
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'bootstrap3',
'users',
'panier',
......
......@@ -8,6 +8,7 @@
<h1 class="text-success text-center"><strong> Bienvenue sur {{ site_name }} !</strong></h1>
<div class="row">
<div class="col-sm-6 col-md-4">
......@@ -16,7 +17,7 @@
<div class="thumbnail">
<div class="caption">
<h3>Inscription</h3>
<p clas="vcenter">Pour s'inscrire au site, c'est par ici! Une fois inscrit, rendez-vous dans "Mon profil" puis "Nouvelle commande" pour commander la prochaine livraison.</p>
<p class="vcenter">Pour s'inscrire au site, c'est par ici! Une fois inscrit, rendez-vous dans "Mon profil" puis "Nouvelle commande" pour commander la prochaine livraison.</p>
<a href="{% url 'users:new-user' %}" class="btn btn-primary" role="button">Inscription</a></p>
</div>
</div>
......@@ -50,8 +51,8 @@
<div class="col-sm-6 col-md-4">
<div class="col-12">
<div class="thumbnail">
<div class="alert alert-warning" role="alert">
<div class="thumbnail alert alert-warning">
<div role="alert">
<p><strong>Normale Soup' recrute !</strong> Si vous pensez avoir les nerfs assez solides pour répartir des paniers, les distribuer à des étudiants en manque de légumineuses et que vous pouvez venir nous aider quelques jeudis après-midi, inscrivez- vous à la mailing-list <a href="https://lists.crans.org/listinfo/amap-distributeurs" target="_blank">amap-distributeurs@lists.crans.org </a></p>
</div>
</div>
......
from users.models import User
from datetime import datetime
import pytz
def recap():
trigger=datetime(2017,7,15,0,0,0,0,pytz.UTC)
print("Recherche avant la date: {}".format(trigger))
vieux_riches=[]
vieux_pauvres=[]
for plop in User.objects.all():
last=plop.commande_set.last()
if(last!=None and last.date.date<trigger):
if(plop.solde()<0):
vieux_riches.append((plop.name,last.date.date,plop.solde(),plop.email))
elif(plop.solde()>0):
vieux_riches.append((plop.name,last.date.date,plop.solde(),plop.email))
dette=0
gain=0
for i in vieux_riches:
print("|{:<20}|{:<15}|{:<10}|{:^40}|".format(i[0],str(i[1].year)+"-"+str(i[1].month)+"-"+str(i[1].day),i[2],i[3]))
dette+=i[2]
print("Somme totale due: {}".format(dette))
print("\n\n\n")
for i in vieux_riches:
print("|{:<20}|{:<15}|{:<10}|{:^40}|".format(i[0],str(i[1].year)+"-"+str(i[1].month)+"-"+str(i[1].day),i[2],i[3]))
gain+=i[2]
print("Somme totale gagnée: {}".format(gain))
print("FIN")
def negatifs():
"""
Récupere les utilisateurs en négatif et prépare un mail
"""
negatifs=[plop for plop in User.objects.all() if plop.solde()<0]
for user in negatifs:
solde=user.solde()
nom=user.name
maddr=user.email
print("Écriture du mail pour {}".format(nom))
lignes=[]
lignes.append("Bonjour {},".format(nom))
lignes.append('\n')
lignes.append('Tu reçois ce mail car tu est adhérent de NormalSoup\' et que ton solde est actuellemet de {}€. Nous te prions de régulariser cette situation au plus vite.'.format(solde))
lignes.append('\n')
lignes.append('Pour cela tu peux envoyer un mail à amap-bureau@lists.crans.org en laissant apparaitre [REGULARISATION] dans l\'objet. Tu peux également venir le jeudi aupavillon des jardins entre 17h30 et 19h pour regler en espèce ou par chèque.')
lignes.append('\n')
lignes.append('Légumineusement.')
lignes.append('\n')
lignes.append('L\'équipe de NormalSoup\'.')
mail=open('scripts/mails_negatif/'+maddr+'.txt','w')
for ligne in lignes:
mail.write(ligne)
mail.close()
print("Fin de l'écriture de mails")
......@@ -98,3 +98,17 @@ class CreditFullForm(CreditForm):
class Meta(CreditForm.Meta):
fields = '__all__'
class CreditNoteForm(forms.Form):
"""A special form to get credential and amount to connect and make a credit using the API of NoteKfet2015 server
"""
login = forms.CharField(
label="Pseudo note"
)
password = forms.CharField(
label="Password",
widget=forms.PasswordInput
)
montant = forms.FloatField(
label="Montant"
)
......@@ -21,7 +21,7 @@ class Commande(models.Model):
coefficient_panier = models.DecimalField(max_digits=3, decimal_places=2, null=True)
quantite = models.PositiveIntegerField(validators=[MinValueValidator(1)])
prix_unitaire = models.DecimalField(max_digits=5, decimal_places=2)
livre = models.BooleanField(default=False)
livre = models.BooleanField(default=False)
date = models.ForeignKey('Livraison', on_delete=models.PROTECT)
def prix(self):
......
#!/usr/bin/python3
# -*- coding:utf-8 -*-
""" Module pour dialoguer avec la NoteKfet2015 """
import socket
import json
import ssl
import traceback
def get_response(socket):
length_str = b''
char = socket.recv(1)
while char != b'\n':
length_str += char
char = socket.recv(1)
total = int(length_str)
return json.loads(socket.recv(total).decode('utf-8'))
def connect(server, port):
sock = socket.socket()
try:
# On établit la connexion sur port 4242
sock.connect((server, port))
# On passe en SSL
sock = ssl.wrap_socket(sock)
# On fait un hello
sock.send(b'["hello", "manual"]')
retcode = get_response(sock)
except:
# Si on a foiré quelque part, c'est que le serveur est down
return (False, sock, "Serveur indisponible")
return (True, sock, "")
def login(server, port, username, password, masque = [[], [], True]):
result, sock, err = connect(server, port)
if not result:
return (False, None, err)
try:
commande = ["login", [username, password, "bdd", masque]]
sock.send(json.dumps(commande).encode("utf-8"))
response = get_response(sock)
retcode = response['retcode']
if retcode == 0:
return (True, sock, "")
elif retcode == 5:
return (False, sock, "Login incorrect")
else:
return (False, sock, "Erreur inconnue " + str(retcode))
except:
# Si on a foiré quelque part, c'est que le serveur est down
return (False, sock, "Erreur de communication avec le serveur")
def don(sock, montant, id_note):
"""
Faire faire un don à l'id_note
"""
try:
sock.send(json.dumps(["dons", [[id_note], round(montant*100), "Rechargement NormalSoup\'"]]).encode("utf-8"))
response = get_response(sock)
retcode = response['retcode']
transaction_retcode = response["msg"][0][0]
if 0 < retcode < 100 or 200 <= retcode or 0 < transaction_retcode < 100 or 200 <= transaction_retcode:
return (False, "Transaction échouée. (Solde trop négatif ?)")
elif retcode == 0:
return (True, "")
else:
return (False, "Erreur inconnue " + str(retcode))
except:
return (False, "Erreur de communication avec le serveur")
......@@ -17,7 +17,7 @@
{% else %}
<h2>Résumé</h2>
<div class="table-responsive">
<table class="table table-inverse">
<tr>
<th>Commandes pour la livraison</th>
......@@ -34,11 +34,13 @@
{%endfor%}
</tr>
</table>
</div>
<h2>Utilisateurs non livrés</h2>
{{ controlform.management_form }}
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
......@@ -74,7 +76,7 @@
<td>{{ form.instance.nom }}</td>
<td>{{ form.instance.prix_unitaire }}</td>
<td>{{ form.instance.quantite }}</td>
<td>{{ form.instance.date}}</td>
<td>{{ form.instance.date }}</td>
<td>{{ form.livre }}</td>
<td>{{ form.instance.user.sac_consignes }}</td>
<td><a class="btn btn-primary btn-sm" role="button" href="{% url 'panier:add-sac' form.instance.user.id %}"><i class="glyphicon glyphicon-plus"></i> Ajouter</a></td>
......@@ -86,9 +88,11 @@
{% endif %}
{% endfor %}
</table>
</div>
<h2>Utilisateurs déjà livrés</h2>
{{ controlform.management_form }}
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
......@@ -125,6 +129,7 @@
{% endif %}
{% endfor %}
</table>
</div>
{% endif %}
{% bootstrap_button "Valider" button_type="submit" icon="star" %}
......
......@@ -15,6 +15,7 @@ urlpatterns = [
url(r'^del_livraison/$', views.del_livraison, name='del-livraison'),
url(r'^index_livraison/$', views.index_livraison, name='index-livraison'),
url(r'^add_credit/(?P<userid>[0-9]+)$', views.add_credit, name='add-credit'),
url(r'^add_credit_note/(?P<userid>[0-9]+)$', views.add_credit_note, name='add-credit-note'),
url(r'^edit_credit/(?P<creditid>[0-9]+)$', views.edit_credit, name='edit-credit'),
url(r'^del_credit/(?P<creditid>[0-9]+)$', views.del_credit, name='del-credit'),
url(r'^add_article/$', views.add_article, name='add-article'),
......
......@@ -16,18 +16,21 @@ from django.http import HttpResponseRedirect
from django.db import transaction
from reversion import revisions as reversion
from .models import Panier, Paiement, Commande, Credit, Livraison
from .forms import PaiementForm, CreditForm, CreditFullForm, DelPaiementForm, LivraisonForm, SelectOneLivraisonForm, SelectLivraisonForm
from .forms import PaiementForm, CreditForm, CreditFullForm, CreditNoteForm, DelPaiementForm, LivraisonForm, SelectOneLivraisonForm, SelectLivraisonForm
from .forms import PanierForm, DelPanierForm, SelectArticleForm, FullEditCommandeForm, BaseEditCommandeForm, NewCommandeForm
from django.forms import modelformset_factory, formset_factory
from reversion.models import Version
from fractions import Fraction
from amap.settings import note_server, note_port, note_id
from users.views import User
from django.utils import timezone
from amap.settings import MINIMUM_LEVEL, PAGINATION_LARGE_NUMBER, PAGINATION_NUMBER
from .note import connect, login, don
def form(ctx, template, request):
c = ctx
c.update(csrf(request))
......@@ -69,7 +72,7 @@ def new_commande(request, userid):
reversion.set_comment("Création")
messages.success(request, "La commande est enregistree")
return redirect("/users/profil/" + userid)
return form({'article_form': article_form, 'commande_form': commande_form}, 'panier/new_commande.html', request)
return form({'article_form': article_form, 'commande_form': commande_form}, 'panier/new_commande.html', request)
@login_required
def edit_commande(request, commandeid):
......@@ -234,7 +237,7 @@ def add_credit(request, userid):
credit = CreditForm(request.POST or None)
if credit.is_valid():
credit = credit.save(commit=False)
credit.user = user
credit.user = user
with transaction.atomic(), reversion.create_revision():
credit.save()
reversion.set_user(request.user)
......@@ -277,6 +280,41 @@ def del_credit(request, creditid):
return redirect("/panier/")
return form({'objet': credit, 'objet_name': 'credit'}, 'panier/delete.html', request)
@login_required
def add_credit_note(request, userid):
"""
Build a request to start the negociation with NoteKfet
"""
try:
user = User.objects.get(pk=userid)
except User.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect("/panier/")
noteform = CreditNoteForm(request.POST or None)
if noteform.is_valid():
pseudo = noteform.cleaned_data['login']
password = noteform.cleaned_data['password']
montant = noteform.cleaned_data['montant']
result, sock, err = login(note_server, note_port, pseudo, password)
if not result:
messages.error(request, err)
return redirect("/users/profil/" + userid)
else:
result, err = don(sock, montant, note_id)
if not result:
messages.error(request, err)
return redirect("/users/profil/" + userid)
moyen = Paiement.objects.filter(moyen='Note Kfet (self)').get()
moyen.save()
credit = Credit(user=user,montant=montant,moyen=moyen,validite=True)
with transaction.atomic(), reversion.create_revision():
credit.save()
reversion.set_user(request.user)
reversion.set_comment("Creation")
messages.success(request, "Le paiement par note a bien été effectué")
return redirect("/users/profil/" + userid)
return form({'panierform': noteform}, 'panier/panier.html', request)
@login_required
@permission_required('bureau')
def add_article(request):
......@@ -343,11 +381,10 @@ def control(request, livraisonid=False):
return redirect("/panier/control/")
livraison_commandes = len(Commande.objects.filter(date=Livraison.objects.filter(date=livraison_select.date)))
livraison_paniers = sum(pan.coefficient_panier*pan.quantite for pan in Commande.objects.filter(date=Livraison.objects.filter(date=livraison_select.date)))
livraison_quantite={}
for coeff in list(Commande.objects.all().values_list('coefficient_panier', flat=True).distinct()):
livraison_quantite[Fraction(coeff)]=Commande.objects.filter(date=Livraison.objects.filter(date=livraison_select.date)).filter(coefficient_panier=coeff).count()
livraison_quantite[Fraction(coeff)]=Commande.objects.filter(date=Livraison.objects.filter(date=livraison_select.date)).filter(livre=False).filter(coefficient_panier=coeff).count()
return render(request, 'panier/control.html', {'controlform': controlform, 'livraison_commandes': livraison_commandes, 'livraison_paniers': livraison_paniers,'livraison_quantite':livraison_quantite})
@login_required
......@@ -361,10 +398,10 @@ def add_sac(request, userid):
article_instance = Panier.objects.get(nom="Sac")
except Panier.DoesNotExist:
messages.error(request, u"Merci de créer une entrée Sac" )
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
with transaction.atomic(), reversion.create_revision():
user_instance.sac_consignes += 1
user_instance.save()
user_instance.save()
reversion.set_user(request.user)
reversion.set_comment("Ajout sac")
messages.success(request, u"Sac ajouté à %s (dispose actuellement de %s sacs)" % (user_instance.get_full_name(), user_instance.sac_consignes) )
......@@ -477,7 +514,7 @@ def index(request):
credit_list = paginator_credit.page(paginator_credit.num_pages)
management_view = request.user.has_perms(('bureau',))
solde_total = sum(us.solde() for us in User.objects.all())
solde_total = sum(us.solde() for us in User.objects.all())
user_total = len(User.objects.filter(state=0))
user_ens = len(User.objects.filter(state=0).filter(is_ens=True))
solde_moyen = round(solde_total/user_total, 2)
......
......@@ -24,6 +24,8 @@ footer {
.navbar {
margin-bottom: 0;
border-radius: 0;
color: #38BA1C;
background-color: #009900;
}
/* Set height of the grid so .sidenav can be 100% (adjust as needed) */
......
......@@ -110,7 +110,7 @@
<p>Vous n'êtes pas authentifié</p>
{% endif %}
</div>
<center><p style="color:#C6C1C1;font-size: 70%;">En cas d'extrêmement rarissime soucis technique de notre côté rappelez vous que l'erreur est humaine et à NormalSoup', nous valorisons l'humain avant tout !</p></center>
<center><p style="color:#C6C1C1;font-size: 70%;">En cas d'extrêmement rarissime soucis technique de notre côté rappelez vous que l'erreur est humaine et à NormalSoup', nous valorisons l'humain avant tout ! Et souquez les artimuses !</p></center>
</div>
</div>
</div>
......
......@@ -16,17 +16,19 @@
<table class="table table-striped">
<thead>
<tr>
<th>Profil</th>
<th>Prénom</th>
<th>Nom</th>
<th>Pseudo</th>
<th>Statut</th>
<th>Telephone</th>
<th>Mail</th>
<th>Profil</th>
</tr>
</thead>
{% for user in users_list %}
<tr>
<td><a href="{% url "users:profil" user.id%}" class="btn btn-primary btn-sm" role="button"><i class="glyphicon glyphicon-user"></i></a>
</td>
<td>{{ user.name }}</td>
<td>{{ user.surname }}</td>
<td>{{ user.pseudo }}</td>
......@@ -39,8 +41,7 @@
{% endif %}
<td>{{ user.telephone }}</td>
<td>{{ user.email }}</td>
<td><a href="{% url "users:profil" user.id%}" class="btn btn-primary btn-sm" role="button"><i class="glyphicon glyphicon-user"></i></a>
</td>
</tr>
{% endfor %}
</table>
......
......@@ -68,6 +68,7 @@
<h2>Commandes et crédits</h2>
{% if is_bureau %}<a class="btn btn-primary btn-sm" role="button" href="{% url 'panier:add-credit' user.id %}"><i class="glyphicon glyphicon-piggy-bank"></i> Enregistrer un crédit</a>{% endif %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'panier:new-commande' user.id %}"><i class="glyphicon glyphicon-shopping-cart"></i> Nouvelle commande</a>
{#<a class="btn btn-primary btn-sm" role="button" href="{% url 'panier:add-credit-note' user.id %}"><i class="glyphicon glyphicon-piggy-bank"></i> Crédit par note Kfet</a>#}
{% if is_bureau %}<a class="btn btn-primary btn-sm" role="button" href="{% url 'panier:add-sac' user.id %}"><i class="glyphicon glyphicon-plus"></i> Ajouter un sac consigné</a>
<a class="btn btn-primary btn-sm" role="button" href="{% url 'panier:del-sac' user.id %}"><i class="glyphicon glyphicon-minus"></i> Retirer un sac consigné</a>{% endif %}
<br/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment