scripts/gestion/dialog/proprio.py
2015-11-19 03:19:28 +01:00

589 lines
30 KiB
Python

#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
u"""
Copyright (C) Valentin Samir
Licence : GPLv3
"""
import os
import sys
import copy
import ldap
if '/usr/scripts' not in sys.path:
sys.path.append('/usr/scripts')
from gestion.chgpass import check_password
import gestion.config as config
import gestion.config.factures
import lc_ldap.objets as objets
import lc_ldap.attributs as attributs
import lc_ldap.crans_utils as lc_utils
import machine
import blacklist
from CPS import TailCall, tailcaller, Continue
class Dialog(machine.Dialog, blacklist.Dialog):
def modif_proprio_attributs(self, proprio, attr, cont):
"""Juste un raccourci vers edit_attributs spécifique aux proprios"""
return self.edit_attributs(obj=proprio, update_obj='proprio', attr=attr, title="Modification de %s %s" % (proprio.get('prenom', [''])[0], proprio['nom'][0]), cont=cont)
@tailcaller
def proprio_compte_create(self, proprio, cont, warning=True, guess_login=True, guess_pass=0, return_obj=False, update_obj='proprio'):
"""Permet de créer un compte crans à un proprio (club ou adhérent)"""
def box_warning(warning, proprio, cont):
# Affiche-t-on le warning sur la consutation de l'adresse crans
if warning:
if self.dialog.yesno(
text="\Zr\Z1AVERTISSEMENT :\Zn \nL'adhérent devra impérativement consulter l'adresse mail associée\n\n\n\ZnContinuer ?",
title="Création du compte de %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]),
defaultno=True,
width=70,
colors=True, timeout=self.timeout) != self.dialog.DIALOG_OK:
raise Continue(cont)
def get_login(guess_login, guess_pass, proprio, self_cont, cont):
# Essaye-t-on de deviner le login à utiliser
if not guess_login:
(code, login) = self.dialog.inputbox(
text="Le login doit faire au maximum %s caractères\nIl ne doit pas être un pseudo ou prénom mais doit être relié au nom de famille\nSeuls les caractères alphabétiques et le trait d'union sont autorisés" % config.maxlen_login,
title="Choix du login pour %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]),
init=str(proprio['nom'][0]).lower(),
width=60,
height=10, timeout=self.timeout)
if code != self.dialog.DIALOG_OK:
raise Continue(cont)
else:
# Si oui, de quelle manière
if guess_pass == 0:
login = str(proprio['nom'][0])
elif guess_pass == 1 and proprio.get('prenom', [''])[0]:
login = "%s%s" % (str(proprio['prenom'][0])[0], proprio['nom'][0])
# Si toutes les manières ont échoués, la prochaine fois, ça on n'essaye pas de deviner
else:
raise Continue(self_cont(warning=False, guess_login=False, guess_pass=2))
return login
def create_compte(proprio, login, guess_login, self_cont, cont):
try:
proprio.compte(login=unicode(login, 'utf-8'))
except ValueError:
# Il y a eu une erreur, si on essaye de deviner, on essaye la manière suivante
if guess_login:
raise Continue(self_cont(warning=False, guess_login=True, guess_pass=guess_pass+1))
# Sinon on propage l'erreur pour l'afficher à l'utilisateur
else:
raise
self.dialog.msgbox(
text="Le compte ne sera créé que lors de l'enregistrement des données\n\nL'adresse mail de l'adhérent est : %s\nL'adhérent possède également l'alias :\n%s\n" % (proprio['mail'][0], proprio['canonicalAlias'][0]),
title="Création du compte de %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]),
width=75,
height=12, timeout=self.timeout,
)
return proprio
@tailcaller
def set_password(proprio, update_obj, cont):
if self.dialog.yesno("Attribuer un mot de passe maintenant ?",
title="Création du compte de %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]),
timeout=self.timeout
) == self.dialog.DIALOG_OK:
#return self.proprio_compte_password(proprio=proprio, return_obj=return_obj, cont=cont(**{update_obj:proprio}))
proprio = self.proprio_compte_password(proprio=proprio, return_obj=True, cont=TailCall(set_password, proprio, update_obj, cont))
if return_obj:
return proprio
else:
raise Continue(cont(**{update_obj:proprio}))
elif return_obj:
return proprio
else:
raise Continue(cont(**{update_obj:proprio}))
def todo(proprio, warning, guess_login, guess_pass, return_obj, self_cont, cont):
box_warning(warning, proprio, cont)
login = get_login(guess_login, guess_pass, proprio, self_cont, cont)
if return_obj:
proprio = create_compte(proprio, login, guess_login, self_cont, cont)
return set_password(proprio, update_obj, cont)
else:
with self.conn.search(dn=proprio.dn, scope=0, mode='rw')[0] as proprio:
proprio = create_compte(proprio, login, guess_login, self_cont, cont)
if not self.confirm_item(item=proprio, title="Création du compte crans pour l'adhérent ?"):
raise Continue(cont)
else:
proprio.validate_changes()
proprio.history_gen()
proprio.save()
self.dialog.msgbox(
text="Compte créé avec succès.",
title="Création du compte de %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]),
timeout=self.timeout
)
return set_password(proprio, update_obj, cont)
self_cont = TailCall(self.proprio_compte_create, proprio=proprio, cont=cont, warning=warning, guess_login=guess_login, guess_pass=guess_pass)
return self.handle_dialog_result(
code=self.dialog.DIALOG_OK,
output="",
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [proprio, warning, guess_login, guess_pass, return_obj, self_cont, cont])]
)
@tailcaller
def proprio_compte_password(self, proprio, cont, return_obj=False):
"""Permet de changer le mot de passe d'un compte crans"""
def test_password(password, self_cont):
(good, msg) = check_password(password, dialog=True)
if not good:
self.dialog.msgbox(
msg,
title="Erreur dans le mot de passe de %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]),
colors=True,
width=70, timeout=self.timeout)
raise Continue(self_cont)
else:
return True
def todo(passwords, proprio, return_obj, self_cont, cont):
password = self.get_password(cont=cont,
title="Choix du mot de passe pour %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]),
backtitle="Le mot de passe doit être assez difficile")
if test_password(password, self_cont):
if return_obj:
proprio['userPassword']=unicode(lc_utils.hash_password(password))
return proprio
else:
with self.conn.search(dn=proprio.dn, scope=0, mode='rw')[0] as proprio:
proprio['userPassword']=unicode(lc_utils.hash_password(password))
proprio.validate_changes()
proprio.history_gen()
proprio.save()
self.dialog.msgbox(
"Mot de passe changé avec succès",
title="Choix du mot de passe pour %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]),
width=70, timeout=self.timeout
)
raise Continue(cont(proprio=proprio))
#(code, passwords) = self.handle_dialog(cont, box)
(code, passwords) = (self.dialog.DIALOG_OK, "")
self_cont = TailCall(self.proprio_compte_password, proprio=proprio, cont=cont)
return self.handle_dialog_result(
code=code,
output=passwords,
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [passwords, proprio, return_obj, self_cont, cont])]
)
@tailcaller
def proprio_compte_delete(self, proprio, cont, force=False):
"""Permet la suppression du compte crans d'un proprio"""
def todo(proprio, self_cont, cont):
if force or self.confirm_item(item=proprio, title="Voulez vous vraiement supprimer le compte de %s %s ?" % (proprio.get('prenom', [''])[0], proprio["nom"][0]), defaultno=True):
(code, mail) = self.dialog.inputbox(
text="Il faut choisir une nouvelle adresse de contact.\n(On regarde s'il y a une adresse optionnel)",
title="Choix d'une adresse de contact pour %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]),
init=str(proprio.get("mailExt", [""])[0]),
width=50, timeout=self.timeout)
if not code == self.dialog.DIALOG_OK:
raise Continue(cont)
elif not mail:
raise ValueError("Il faut entrer une adresse mail")
with self.conn.search(dn=proprio.dn, scope=0, mode='rw')[0] as proprio:
proprio.delete_compte(unicode(mail, 'utf-8'))
proprio.validate_changes()
proprio.history_gen()
proprio.save()
self.dialog.msgbox("Le compte a bien été supprimée", timeout=self.timeout, title="Suppression du compte de %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]))
raise Continue(cont(proprio=proprio))
else:
raise Continue(cont)
self_cont = TailCall(self.proprio_compte_delete, proprio=proprio, cont=cont, force=force)
return self.handle_dialog_result(
code=self.dialog.DIALOG_OK,
output="",
cancel_cont=cont(proprio=proprio),
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [proprio, self_cont, cont])]
)
def proprio_compte_etat(self, proprio, disable, cont):
"""Permet de d'éastiver ou activer un compte crans avec l'attribut shadowExpire"""
with self.conn.search(dn=proprio.dn, scope=0, mode='rw')[0] as proprio:
if disable:
proprio["shadowExpire"]=0
else:
proprio["shadowExpire"]=[]
proprio.validate_changes()
proprio.history_gen()
proprio.save()
raise Continue(cont(proprio=proprio))
def proprio_compte_shell(self, proprio, cont, choices_values=None):
"""Permet de modifier le shell d'un compte crans"""
a = attributs
# Seul les nounous peuvent changer les shells restrictifs
shells_droits = {
'default' : [a.soi, a.nounou, a.cableur],
'rbash' : [a.nounou],
'rssh' : [a.nounou],
'badPassSh' : [a.nounou],
'disconnect_shell':[a.nounou],
}
shell = os.path.basename(str(proprio['loginShell'][0])).lower()
shells = config.shells_gest_crans
shells_order = config.shells_gest_crans_order
def box():
# liste des shell éditables par l'utilisateur
editable_sheels = [s for s in shells_order if self.has_right(shells_droits.get(s, shells_droits['default']), proprio)]
# Si l'utilisateur de gest_crans peut éditer le shell courant
# il peut le changer pour un autre shell qu'il peut éditer
if shell in editable_sheels:
choices=[(s, shells[s]['desc'], 1 if s == shell else 0) for s in editable_sheels]
return self.dialog.radiolist(
text="",
height=0, width=0, list_height=0,
choices=choices_values if choices_values else choices,
title="Shell de %s %s" % (proprio.get('prenom', [""])[0], proprio['nom'][0]),
timeout=self.timeout
)
# Sinon, on affiche un message d'erreur et on annule
else:
self.dialog.msgbox("Vous ne pouvez pas changer le shell de cet utilisateur",
title="Édition du shell impossible", timeout=self.timeout, width=0, height=0)
return (self.dialog.DIALOG_CANCEL, None)
def todo(output, shell, shells, proprio, self_cont, cont):
loginShell = shells[output]['path']
if shell and shell != output:
with self.conn.search(dn=proprio.dn, scope=0, mode='rw')[0] as proprio:
proprio['loginShell']=unicode(loginShell)
proprio.validate_changes()
proprio.history_gen()
proprio.save()
self.dialog.msgbox("Shell modifié avec succès.\nLa modification peut prendre une quainzaine de minute avant d'être effective.",
title="Shell de %s %s" % (proprio.get('prenom', [""])[0], proprio['nom'][0]),
width=50, timeout=self.timeout,
)
raise Continue(cont(proprio=proprio))
(code, output) = self.handle_dialog(cont, box)
self_cont = TailCall(self.proprio_compte_shell, proprio=proprio, cont=cont, choices_values=[(s, shells[s]['desc'], 1 if s == output else 0) for s in shells_order])
return self.handle_dialog_result(
code=code,
output=output,
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [output, shell, shells, proprio, self_cont, cont])]
)
def proprio_compte(self, proprio, cont, default_item=None, update_obj='proprio'):
"""Menu de gestion du compte crans d'un proprio"""
has_compte = 'cransAccount' in proprio['objectClass']
disabled_compte = has_compte and 0 in proprio['shadowExpire']
a = attributs
menu_droits = {
"Password": [a.cableur, a.nounou],
'MailAlias': [a.cableur, a.nounou],
"Activer" : [a.nounou],
"Désactiver" : [a.nounou],
"Créer" : [a.cableur, a.nounou],
"Supprimer" : [a.cableur, a.nounou],
"Shell" : [a.nounou, a.soi, a.cableur],
}
menu = {
"Password" : {"text":"Changer le mot de passe du compte", "help":"", "callback":self.proprio_compte_password},
'MailAlias' : {'text': 'Créer ou supprimer des alias mail', "help":"", 'attribut':attributs.mailAlias},
"Shell" : {"text" : "Changer le shell de cet utilisateur", "help":'', "callback":self.proprio_compte_shell},
"Activer" : {"text" : "Activer le compte pour la connexion mail/serveur", "help":"Permet d'autoriser les connexions smtp, imap, ssh, etc… avec le compte", "callback":TailCall(self.proprio_compte_etat, disable=False)},
"Désactiver" : {"text" : "Désactiver le compte pour la connexion mail/serveur", "help":"Permet d'interdire les connexions smtp, imap, ssh, etc… avec le compte", "callback":TailCall(self.proprio_compte_etat, disable=True)},
"Créer" : {"text": "Créer un compte", "help":'', "callback":self.proprio_compte_create},
"Supprimer" : {"text": "Supprimer le compte", "help":"Le home sera archivé dans le cimetière", "callback":self.proprio_compte_delete},
}
menu_order = []
tag_translate = {
"Créer":"Password",
"Password":"Password",
"Supprimer":"Créer",
"Activer":"Désactiver",
"Désactiver":"Activer",
"Shell":"Shell",
'MailAlias':'MailAlias',
'':'',
}
if has_compte:
if disabled_compte:
menu_order.append("Activer")
else:
menu_order.append("Désactiver")
menu_order.extend(['MailAlias', "Shell", "Password", "Supprimer"])
else:
menu_order.append("Créer")
def box(default_item=None):
return self.dialog.menu(
"Quel action effectuer sur le compte ?",
width=0,
height=0,
menu_height=0,
timeout=self.timeout,
item_help=1,
default_item=str(default_item),
title="Gestion du compte de %s %s" % (proprio.get('prenom', [''])[0], proprio["nom"][0]),
scrollbar=True,
cancel_label="Retour",
backtitle=self._connected_as(),
choices=[(k, menu[k]['text'], menu[k]['help']) for k in menu_order if self.has_right(menu_droits[k], proprio)])
def todo(tag, menu, proprio, self_cont):
if not tag in menu_order:
raise Continue(self_cont)
elif 'callback' in menu[tag]:
raise Continue(TailCall(menu[tag]['callback'], cont=self_cont, proprio=proprio))
elif 'attribut' in menu[tag]:
raise Continue(TailCall(self.modif_proprio_attributs, proprio=proprio, cont=self_cont, attr=menu[tag]['attribut'].ldap_name))
else:
raise EnvironmentError("Il n'y a ni champ 'attribut' ni 'callback' pour le tag %s" % tag)
cont(**{update_obj:proprio})
(code, tag) = self.handle_dialog(cont, box, default_item)
self_cont = TailCall(self.proprio_compte, proprio=proprio, cont=cont, default_item=tag_translate.get(tag, tag), update_obj=update_obj)
return self.handle_dialog_result(
code=code,
output=tag,
cancel_cont=cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [tag, menu, proprio, self_cont])]
)
@tailcaller
def proprio_vente_set(self, article, cont):
"""Permet de définir la quantité de l'article à vendre"""
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_choose_paiement(self, proprio, cont, cancel_cont, articles=[], tag_paiment=None, comment=True, text=""):
"""Pour choisir un mode de paiement.
Si `articles` est donné, empêche le paiement par solde si soldes est dans articles
La continuation `cont` doit accepter en paramètre `tag_paiment` pour le mode de paiement
et `comment_paiement` pour un commentaire.
"""
box_paiement = {
"liquide" : "Espèces",
"cheque" : "Chèque",
"carte" : "Par carte bancaire",
"solde" : "Solde Crans (actuel : %s€)",
"arbitraire" : "Création ou destruction magique d'argent.",
}
def box_choose_paiment(tag, articles):
box_paiement_order = ["liquide", "cheque", "carte"]
if "cransAccount" in proprio['objectClass']:
if not "SOLDE" in [art['code'] for art in articles] and proprio["solde"]:
box_paiement_order.append("solde")
box_paiement["solde"] = box_paiement["solde"] % proprio["solde"][0]
if len(articles) == 1 and "SOLDE" in [art['code'] for art in articles]:
box_paiement_order.append("arbitraire")
choices = []
for key in box_paiement_order:
choices.append((key, box_paiement[key], 1 if key == tag else 0))
return self.dialog.radiolist(
text=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_paiment(tag_paiement, proprio, self_cont, cont):
if not tag_paiement:
raise ValueError("Il faut choisir un moyen de paiement")
if comment:
code, comment_paiement = 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_paiement:
raise ValueError("Commentaire nécessaire")
raise Continue(cont(tag_paiment=tag_paiement, comment_paiement=comment_paiement))
self_cont=TailCall(self.proprio_choose_paiement, proprio=proprio, cont=cont, cancel_cont=cancel_cont, tag_paiment=tag_paiment, comment=comment)
(code, tag) = self.handle_dialog(cancel_cont, box_choose_paiment, tag_paiment, articles)
self_cont=self_cont(tag_paiment=tag)
return self.handle_dialog_result(
code=code,
output=tag,
cancel_cont=cancel_cont,
error_cont=self_cont,
codes_todo=[([self.dialog.DIALOG_OK], choose_paiment, [tag, proprio, self_cont, cont])]
)
@tailcaller
def proprio_vente(self, proprio, cont, tags=[], tag_paiment=None, to_set=[], have_set=[], comment_paiement=None):
"""Menu de vente du crans. Permet également de recharger le solde crans"""
def box_choose_item(tags):
choices = []
gestion.config.factures.ITEMS.update(gestion.config.factures.ITEM_SOLDE)
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 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 paiement(have_set, tag, proprio, comment, cancel_cont, cont):
articles = copy.deepcopy(have_set)
# On formate les articles
for article in articles:
if article['pu'] == '*':
article['pu'] = article['nombre']
article['nombre'] = 1
# En arbitraire, on accepte que le solde
if tag == u"arbitraire":
if len(articles) > 1 or "SOLDE" not in [art['code'] for art in articles]:
raise ValueError("Il n'est possible que de faire une opération de solde en mode arbitraire")
else:
with self.conn.search(dn=proprio.dn, scope=0, mode='rw')[0] as adh:
adh.solde(articles[0]['pu'], comment=unicode(comment))
adh.history_gen()
adh.save()
self.dialog.msgbox(text=u"Le solde de l'adhérent a bien été crédité", title="Solde crédité", width=0, height=0, timeout=self.timeout)
raise Continue(cont)
# Les articles classiques on facture
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 ce 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 a 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 a bien été crédité", title="Solde crédité", width=0, height=0, timeout=self.timeout)
else:
if not self.confirm(text=u"Le paiement n'a pas été reçue.\n Annuler la vente ?", title="Annulation de la vente", defaultno=True):
raise Continue(cancel_cont)
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, comment_paiement=comment_paiement)
# 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 and (not comment_paiement or not tag_paiment):
lcont = self_cont.copy()
lcont(to_set=[have_set[-1]] + to_set, have_set=have_set[:-1])
return self.proprio_choose_paiement(proprio=proprio, cont=self_cont, cancel_cont=lcont, articles=have_set, tag_paiment=tag_paiment)
# Et si on a choisit le mode de paiement
elif have_set and comment_paiement:
cancel_cont = self_cont(comment_paiement=None)
return self.handle_dialog_result(
code=self.dialog.DIALOG_OK,
output=[],
cancel_cont=cancel_cont,
error_cont=cancel_cont,
codes_todo=[([self.dialog.DIALOG_OK], paiement, [have_set, tag_paiment, proprio, comment_paiement, cancel_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)
gestion.config.factures.ITEMS.update(gestion.config.factures.ITEM_SOLDE)
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])]
)