[gest_crans_lc] Menu vente. Il manque l'éditon de solde via lc_ldap

En effet, il faut faire un truc propre pour éditer le solde, avec un lock
pour éviter les éditions concurrente entrainant des valeurs du solde incohérente.
du coup, pour le moment, quand on essaye (via le menu vente) ça lève une erreur.
Mais il ne manque que ça, ça doit pouvoir se faire.
This commit is contained in:
Valentin Samir 2014-03-23 20:33:04 +01:00
parent d017ddb44e
commit 0b9635a91d

View file

@ -17,6 +17,7 @@ import os
import sys import sys
import ssl import ssl
import time import time
import copy
import ldap import ldap
import signal import signal
import inspect import inspect
@ -31,6 +32,7 @@ from gestion.cert_utils import createCertRequest
from gestion.affich_tools import get_screen_size, coul from gestion.affich_tools import get_screen_size, coul
from gestion.chgpass import checkpass from gestion.chgpass import checkpass
import gestion.config as config import gestion.config as config
import gestion.config.factures
import lc_ldap.shortcuts import lc_ldap.shortcuts
import lc_ldap.objets as objets import lc_ldap.objets as objets
@ -142,6 +144,12 @@ class TailCall(object) :
def __str__(self): def __str__(self):
return "TailCall<%s(%s%s%s)>" % (self.call.func_name, ', '.join(repr(a) for a in self.args), ', ' if self.args and self.kwargs else '', ', '.join("%s=%s" % (repr(k),repr(v)) for (k,v) in self.kwargs.items())) return "TailCall<%s(%s%s%s)>" % (self.call.func_name, ', '.join(repr(a) for a in self.args), ', ' if self.args and self.kwargs else '', ', '.join("%s=%s" % (repr(k),repr(v)) for (k,v) in self.kwargs.items()))
def copy(self):
''' Patch the deepcopy dispatcher to pass modules back unchanged '''
result = TailCall(self.call, *list(self.args), **dict(self.kwargs))
result.stacklvl = self.stacklvl
return result
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
self.kwargs.update(kwargs) self.kwargs.update(kwargs)
self.args = self.args + args self.args = self.args + args
@ -251,6 +259,17 @@ class GestCrans(object):
self.dialog_last_access = time.time() self.dialog_last_access = time.time()
return self._dialog return self._dialog
def nyan(self, cont, *args, **kwargs):
(lines, cols) = get_screen_size()
print "\033[48;5;17m"
print " "*(lines * cols)
cols = int(min(cols/2, 65))
lines = int(lines) -1
cmd = "/usr/bin/nyancat -W %s -H %s" % (cols, lines)
os.system(cmd)
raise Continue(cont)
@tailcaller @tailcaller
def handle_dialog(self, cancel_cont, box, *args): def handle_dialog(self, cancel_cont, box, *args):
ctrlC=False ctrlC=False
@ -2469,9 +2488,184 @@ les valeurs valident sont :
self.dialog.msgbox("todo", width=0, height=0) self.dialog.msgbox("todo", width=0, height=0)
return cont return cont
def proprio_vente(self, proprio, cont): @tailcaller
self.dialog.msgbox("todo", width=0, height=0) def proprio_vente_set(self, article, cont):
return cont def box():
if article['pu'] == '*':
return self.dialog.inputbox(title="Montant pour %s ?" % article['designation'],
text="", init=str(article.get('nombre','')), timeout=self.timeout, width=70)
else:
return self.dialog.inputbox(title="Nombre de %s ?" % article['designation'],
text="", timeout=self.timeout, init=str(article.get('nombre','1')), width=70)
def todo(article, output, cont):
article['nombre']=output
# Il faut entrer quelque chose
if not output:
raise ValueError("Merci d'entrer une valeur")
# Vérification des centimes
if article['pu'] == '*' and '.' in output:
if len(output.split('.', 1)[1])>2:
raise ValueError("Les centimes, c'est seulement deux chiffres après la virgule")
typ = float if article['pu'] == '*' else int
# Vérification du type de l'entré
try:
output=typ(output)
except ValueError:
raise ValueError("Merci d'entrez seulement des nombres")
# On définis le nombre d'entrée. Pour pu=* il y aura du trairement à faire
# avant de générer la facture : mettre pu à nombre et nombre à 1
# on le met comme ça pour pouvoir naviger aisément entre les écrans dialog
article['nombre'] = output
return article
(code, output) = self.handle_dialog(cont, box)
self_cont = TailCall(self.proprio_vente_set, article=article, cont=cont)
return self.handle_dialog_result(
code=code,
output=output,
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [article, output, cont])]
)
@tailcaller
def proprio_vente(self, proprio, cont, tags=[], tag_paiment=None, to_set=[], have_set=[]):
box_paiement = {
"liquide" : "Espèces",
"cheque" : "Chèque",
"solde" : "Solde Crans (actuel : %s€)",
}
def box_choose_item(tags):
choices = []
for code, article in gestion.config.factures.items.items():
choices.append((code, u"%s%s" % (article['designation'], (u' (%s€)' % article['pu']) if article['pu'] != '*' else ""), 1 if code in tags else 0))
return self.dialog.checklist(
text="",
title="Vente de truc à %s %s" % (proprio.get("prenom", [''])[0], proprio["nom"][0]),
choices=choices,
timeout=self.timeout)
def box_choose_paiment(tag, articles):
box_paiement_order = ["liquide", "cheque"]
if "cransAccount" in proprio['objectClass']:
if not "SOLDE" in [art['code'] for art in articles]:
box_paiement_order.append("solde")
box_paiement["solde"] = box_paiement["solde"] % proprio["solde"][0]
choices = []
for key in box_paiement_order:
choices.append((key, box_paiement[key], 1 if key == tag else 0))
return self.dialog.radiolist(
text="",
title="Choix d'un mode de paiement pour %s %s" % (proprio.get("prenom", [''])[0], proprio["nom"][0]),
choices=choices,
timeout=self.timeout)
def choose_item(proprio, tags, articles, self_cont):
to_set=[]
for tag in tags:
articles[tag]['code']=tag
to_set.append(articles[tag])
raise Continue(self_cont(to_set=to_set, have_set=[]))
def number_of_items(to_set, have_set, self_cont):
# Où faut-il aller si l'utilisateur appuis sur annuler
if not have_set:
lcont = self_cont(to_set=[])
else:
lcont = self_cont(to_set=[have_set[-1]] + to_set, have_set=have_set[:-1])
art = self.proprio_vente_set(to_set[0], cont=lcont)
if not to_set[1:]:
total = 0
line=1
text=u"Résumé :\n"
for article in have_set + [art]:
if article['pu'] == '*':
total += article['nombre']
text+=u" * %s pour %s\n" % (article['designation'], article['nombre'])
else:
total += article['nombre']*article['pu']
text+=u" * %dx %s à %s\n" % (article['nombre'], article['designation'], article['pu'])
line+=1
text+=u"Total à payer : %s" % total
self.dialog.msgbox(text=text,
title="Résumé de la facture à payer",
width=70, height=5+line, timeout=self.timeout)
return self_cont(to_set=to_set[1:], have_set=have_set + [art])
def choose_paiment(have_set, tag, proprio, lcont, self_cont, cont):
if not tag:
raise ValueError("Il faut choisir un moyen de paiement")
code, comment = self.dialog.inputbox(text="Détail pour les espèce, nom de la note ou banque du chèque", title="Commentaire", width=70, timeout=self.timeout)
if code != self.dialog.DIALOG_OK:
raise Continue(self_cont)
if not comment:
raise ValueError("Commentaire nécessaire")
articles = copy.deepcopy(have_set)
for article in articles:
if article['pu'] == '*':
article['pu'] = article['nombre']
article['nombre'] = 1
with self.conn.newFacture(proprio.dn, {}) as facture:
facture['modePaiement']=unicode(tag, 'utf-8')
facture['article']=articles
facture['info']=unicode(comment, 'utf-8')
if self.confirm_item(item=facture,
text=u"Le paiement de %s€ a-t-il bien été reçu (mode : %s) ?\n" % (facture.total(), tag),
title=u"Validation du paiement",
timeout=self.timeout):
# Appeler créditer va créditer ou débiter le solde, sauver le proprio et créer la facture
facture.crediter()
arts = ["%s %s" % (art['nombre'], art['designation']) for art in facture['article'] if art['code'] != 'SOLDE']
if arts:
self.dialog.msgbox(
text=u"Vous pouvez remettre à l'adherent les articles (si se sont des articles) suivant :\n * %s" % '\n * '.join(arts),
title=u"Vente terminée",
width=0, height=0, timeout=self.timeout)
if tag == "solde":
self.dialog.msgbox(text=u"Le solde de l'adhérent à bien été débité", title="Solde débité", width=0, height=0, timeout=self.timeout)
if [a for a in facture['article'] if art['code'] == 'SOLDE']:
self.dialog.msgbox(text=u"Le solde de l'adhérent à bien été crédité", title="Solde crédité", width=0, height=0, timeout=self.timeout)
else:
self.dialog.msgbox(text=u"Le paiement n'ayant pas été reçue\nla vente est annulée", title="Annulation de la vente", width=0, height=0, timeout=self.timeout)
raise Continue(cont)
self_cont=TailCall(self.proprio_vente, proprio=proprio, cont=cont, tags=tags, tag_paiment=tag_paiment, to_set=to_set, have_set=have_set)
# S'il y a des article dont il faut définir la quantité
if to_set:
return self.handle_dialog_result(
code=self.dialog.DIALOG_OK,
output=None,
cancel_cont=None,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], number_of_items, [to_set, have_set, self_cont])]
)
# Sinon, si tous les quantités de tous les articles sont définis
elif have_set:
lcont = self_cont.copy()
lcont(to_set=[have_set[-1]] + to_set, have_set=have_set[:-1])
(code, tag) = self.handle_dialog(lcont, box_choose_paiment, tag_paiment, have_set)
self_cont=self_cont(tag_paiment=tag)
lcont(tag_paiment=tag)
return self.handle_dialog_result(
code=code,
output=tag,
cancel_cont=lcont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], choose_paiment, [have_set, tag, proprio, lcont, self_cont, cont])]
)
# Sinon, on propose des articles à chosir
else:
(code, tags) = self.handle_dialog(cont, box_choose_item, tags)
self_cont=self_cont(tags=tags, have_set=[], to_set=[], tag_paiment=None)
return self.handle_dialog_result(
code=code,
output=tags,
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], choose_item, [proprio, tags, copy.deepcopy(gestion.config.factures.items), self_cont])]
)
def create_adherent(self, cont): def create_adherent(self, cont):
def mycont(adherent=None, **kwargs): def mycont(adherent=None, **kwargs):
@ -2561,7 +2755,7 @@ les valeurs valident sont :
'aMC': {'text':"Ajouter une machine à un club", 'callback': self.create_machine_club}, 'aMC': {'text':"Ajouter une machine à un club", 'callback': self.create_machine_club},
#'dC' : {'text':"Détruire un club", 'callback': self.delete_club}, #'dC' : {'text':"Détruire un club", 'callback': self.delete_club},
'aKM': {'text':"Ajouter une machine à l'association", 'callback': self.create_machine_crans}, 'aKM': {'text':"Ajouter une machine à l'association", 'callback': self.create_machine_crans},
'' : {'text':"---------------------------------------",'callback': None}, '' : {'text':"---------------------------------------",'callback': self.nyan},
} }
### Les clef qui n'existe pas sont toute renvoyé sur la clef '' ### Les clef qui n'existe pas sont toute renvoyé sur la clef ''
#menu_order = ["aA", "mA", "aMA", "dA", "", "mM", "dM", " ", "aC", "mC", "aMC", "dC", " ", "aKM"] #menu_order = ["aA", "mA", "aMA", "dA", "", "mM", "dM", " ", "aC", "mC", "aMC", "dC", " ", "aKM"]