[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:
parent
d017ddb44e
commit
0b9635a91d
1 changed files with 198 additions and 4 deletions
|
@ -17,6 +17,7 @@ import os
|
|||
import sys
|
||||
import ssl
|
||||
import time
|
||||
import copy
|
||||
import ldap
|
||||
import signal
|
||||
import inspect
|
||||
|
@ -31,6 +32,7 @@ from gestion.cert_utils import createCertRequest
|
|||
from gestion.affich_tools import get_screen_size, coul
|
||||
from gestion.chgpass import checkpass
|
||||
import gestion.config as config
|
||||
import gestion.config.factures
|
||||
|
||||
import lc_ldap.shortcuts
|
||||
import lc_ldap.objets as objets
|
||||
|
@ -142,6 +144,12 @@ class TailCall(object) :
|
|||
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()))
|
||||
|
||||
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):
|
||||
self.kwargs.update(kwargs)
|
||||
self.args = self.args + args
|
||||
|
@ -251,6 +259,17 @@ class GestCrans(object):
|
|||
self.dialog_last_access = time.time()
|
||||
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
|
||||
def handle_dialog(self, cancel_cont, box, *args):
|
||||
ctrlC=False
|
||||
|
@ -2469,9 +2488,184 @@ les valeurs valident sont :
|
|||
self.dialog.msgbox("todo", width=0, height=0)
|
||||
return cont
|
||||
|
||||
def proprio_vente(self, proprio, cont):
|
||||
self.dialog.msgbox("todo", width=0, height=0)
|
||||
return cont
|
||||
@tailcaller
|
||||
def proprio_vente_set(self, article, 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 mycont(adherent=None, **kwargs):
|
||||
|
@ -2561,7 +2755,7 @@ les valeurs valident sont :
|
|||
'aMC': {'text':"Ajouter une machine à un club", 'callback': self.create_machine_club},
|
||||
#'dC' : {'text':"Détruire un club", 'callback': self.delete_club},
|
||||
'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 ''
|
||||
#menu_order = ["aA", "mA", "aMA", "dA", "", "mM", "dM", " ", "aC", "mC", "aMC", "dC", " ", "aKM"]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue