Gestion des factures dans gest_crans.
* Attention, c'est à utiliser avec précaution.
This commit is contained in:
parent
04a129f879
commit
ad5e4e9d09
3 changed files with 226 additions and 17 deletions
|
@ -1653,6 +1653,62 @@ def del_club(club):
|
|||
arg += u'--msgbox "Club détruit\n\n\n" 0 0'
|
||||
dialog(arg)
|
||||
|
||||
##################################################################
|
||||
## Fonctions de modif des factures
|
||||
|
||||
def set_facture_mode(facture):
|
||||
"""Change le mode de paiement
|
||||
|
||||
"""
|
||||
|
||||
arg = u'--title "Mode de paiement pour la facture fid=%s (%s)" ' % (facture.id(), facture.proprietaire().Nom(),)
|
||||
arg += u'--menu "Quel moyen de paiement enregistrer ?" 0 0 0 '
|
||||
arg += u'"Liquide" "En espèces : penser à mettre l\'argent dans une enveloppe." '
|
||||
arg += u'"Cheque" "Par chèque : ne pas oublier de vérifier signature, date, ordre et montant." '
|
||||
if facture.proprietaire().solde() - facture.total() > 0:
|
||||
arg += u'"Solde" "Par solde : il a assez d\'argent pour ça." '
|
||||
annul, res = dialog(arg)
|
||||
if annul:
|
||||
return 1
|
||||
facture.modePaiement(res[0].lower())
|
||||
|
||||
def set_facture_recu(facture):
|
||||
"""Change le reçu d'une facture
|
||||
|
||||
"""
|
||||
arg = u'--title "Reçu pour la facture fid=%s (%s)" ' % (facture.id(), facture.proprietaire().Nom())
|
||||
arg += u'--separate-output '
|
||||
arg += u'--checklist "État du paiement\n" 0 0 0 '
|
||||
arg += u'"Pmt" "Paiement fourni." "%s"' % (on_off(facture.recuPaiement() is not None),)
|
||||
|
||||
annul, res = dialog(arg)
|
||||
if annul:
|
||||
return 1
|
||||
if "Pmt\n" in res:
|
||||
facture.recuPaiement(strftime("%Y-%m-%d %H:%M:%S"))
|
||||
else:
|
||||
facture.recuPaiement(False)
|
||||
|
||||
def set_facture_controle(facture):
|
||||
"""Change le contrôle de la facture
|
||||
|
||||
"""
|
||||
arg = u'--title "Contrôle pour la facture fid=%s (%s)" ' % (facture.id(), facture.proprietaire().Nom())
|
||||
arg += u'--separate-output '
|
||||
arg += u'--checklist "État du contrôle\n" 0 0 0 '
|
||||
arg += u'"Ctl" "Contrôle OK." "%s" ' % (on_off(facture.controle() == "TRUE"),)
|
||||
arg += u'"NCtl" "Contrôle pas OK." "%s" ' % (on_off(facture.controle() == "FALSE"),)
|
||||
|
||||
annul, res = dialog(arg)
|
||||
if annul:
|
||||
return 1
|
||||
if "Ctl\n" in res:
|
||||
facture.controle(True)
|
||||
elif "NCtl\n" in res:
|
||||
facture.controle(False)
|
||||
else:
|
||||
facture.controle("")
|
||||
|
||||
##################################################################
|
||||
## Fonctions de remplissage ou modification des paramètres machine
|
||||
|
||||
|
@ -1906,6 +1962,31 @@ def del_machine(machine):
|
|||
arg += u'--msgbox "Machine détruite\n\n\n" 0 0'
|
||||
dialog(arg)
|
||||
|
||||
def del_facture(facture):
|
||||
u"""
|
||||
Destruction facture
|
||||
"""
|
||||
while 1:
|
||||
arg = u'--title "Destruction facture fid=%s" --colors ' % facture.id()
|
||||
arg += u'--inputbox "\Zr\Z1ATTENTION\Zn : la destruction est définitive, et aucun remboursement automatique n\'aura lieu.\nCommentaire à insérer ?" 0 0'
|
||||
annul, res = dialog(arg)
|
||||
if annul: return 1
|
||||
if res[0]: break
|
||||
arg = u'--title "Destruction facture" '
|
||||
arg += u'--msgbox "Le commentaire est obligatoire\n\n\n" 0 0'
|
||||
dialog(arg)
|
||||
|
||||
try:
|
||||
facture.delete(res[0])
|
||||
except EnvironmentError, c:
|
||||
arg = u'--title "Destruction facture" '
|
||||
arg += u'--msgbox "ERREUR n°%s\n\n\n" 0 0' % to_unicode(c.args[0])
|
||||
dialog(arg)
|
||||
return 1
|
||||
|
||||
arg = u'--title "Destruction facture" '
|
||||
arg += u'--msgbox "Facture détruite\n\n\n" 0 0'
|
||||
dialog(arg)
|
||||
|
||||
####################################
|
||||
## Fonctions principales d'interface
|
||||
|
@ -2174,6 +2255,36 @@ def modif_machine(machine):
|
|||
if machine.modifs:
|
||||
return confirm(machine)
|
||||
|
||||
def modif_facture(facture):
|
||||
"""Modifie la facture sélectionnée
|
||||
|
||||
"""
|
||||
|
||||
if facture.controle() and not iscontroleur and not isadm:
|
||||
return 1
|
||||
|
||||
arg = u'--title "Modification de la facture %s (%s)" ' % (facture.id(), facture.proprietaire().Nom(),)
|
||||
arg += u'--menu "Que souhaitez vous modifier ?" 0 0 0 '
|
||||
if not (facture.controle() == "TRUE" or facture.controle() == "FALSE") and not facture.recuPaiement():
|
||||
arg += u'"Mode" "Mode de paiement" '
|
||||
if not (facture.controle() == "TRUE" or facture.controle() == "FALSE") and facture.modePaiement():
|
||||
arg += u'"Recu" "Valider le reçu du paiement ou non" '
|
||||
if facture.recuPaiement() and (iscontroleur or isadm):
|
||||
arg += u'"Controle" "Valider ou non le contrôle de la facture." '
|
||||
|
||||
annul, res = dialog(arg)
|
||||
|
||||
if annul: return 1
|
||||
|
||||
if res[0] == 'Mode':
|
||||
set_facture_mode(facture)
|
||||
elif res[0] == 'Recu':
|
||||
set_facture_recu(facture)
|
||||
elif res[0] == 'Controle':
|
||||
set_facture_controle(facture)
|
||||
|
||||
if facture.modifs:
|
||||
return confirm(facture)
|
||||
|
||||
########################################################################
|
||||
## Fonction de sélection (adhérent ou machine)
|
||||
|
@ -2268,7 +2379,7 @@ def select(clas, quoi, mde=''):
|
|||
# Affichage
|
||||
if quoi[-1] == 'a':
|
||||
valid = res['adherent']
|
||||
if not valid and res['machine']:
|
||||
if not valid and (res['machine'] or res['facture']):
|
||||
# On va récupérer les adhérents correspondants aux machines trouvés
|
||||
deja= []
|
||||
for m in res['machine']:
|
||||
|
@ -2276,6 +2387,11 @@ def select(clas, quoi, mde=''):
|
|||
if a.id() in deja: continue
|
||||
deja.append(a.id())
|
||||
valid.append(a)
|
||||
for f in res['facture']:
|
||||
a = f.proprietaire()
|
||||
if a.id() in deja: continue
|
||||
deja.append(a.id())
|
||||
valid.append(a)
|
||||
elif quoi[-1] == 'm':
|
||||
valid = res['machine']
|
||||
if not valid and res['adherent']:
|
||||
|
@ -2283,6 +2399,13 @@ def select(clas, quoi, mde=''):
|
|||
for a in res['adherent']:
|
||||
for m in a.machines():
|
||||
valid.append(m)
|
||||
elif quoi[-1] == 'f':
|
||||
valid = res['facture']
|
||||
if not valid and res['adherent']:
|
||||
# On va récupérer les machines des adhérents trouvés
|
||||
for a in res['adherent']:
|
||||
for f in a.factures():
|
||||
valid.append(f)
|
||||
else:
|
||||
raise TypeError('Argument fonction invalide')
|
||||
|
||||
|
@ -2382,6 +2505,9 @@ def menu_principal():
|
|||
arg += u'"mM" "Modifier une machine existante" "Changer le nom ou la MAC d\'une machine." '
|
||||
arg += u'"dM" "Détruire une machine" "" '
|
||||
arg += u'"" "---------------------------------------" "" '
|
||||
arg += u'"mF" "Modifier une facture existante" "Modifier les données relatives à la facture…" '
|
||||
arg += u'"dF" "Détruire une facture" "" '
|
||||
arg += u'"" "---------------------------------------" "" '
|
||||
arg += u'"aC" "Inscrire un nouveau club" "" '
|
||||
arg += u'"mC" "Modifier un club" "" '
|
||||
arg += u'"aMC" "Ajouter une machine à un club" "" '
|
||||
|
@ -2438,6 +2564,12 @@ def menu_principal():
|
|||
if not becane: continue
|
||||
choix= 'mMc'
|
||||
|
||||
elif choix == "mF":
|
||||
# Modif d'une facture. Choisir facture.
|
||||
facture = select(db, u'Facture à modifier f')
|
||||
if not facture: continue
|
||||
choix = "mFc"
|
||||
|
||||
elif choix == 'aC':
|
||||
# Ajout d'un club
|
||||
proprio = Club()
|
||||
|
@ -2474,6 +2606,17 @@ def menu_principal():
|
|||
del(proprio) ; proprio= None
|
||||
del(becane) ; becane= None
|
||||
|
||||
elif choix == 'dF':
|
||||
# Destruction machine
|
||||
facture = select(db, u'facture à détruire f')
|
||||
if not facture: continue
|
||||
proprio = facture.proprietaire()
|
||||
if del_facture(facture): continue
|
||||
del(facture)
|
||||
facture = None
|
||||
proprio.update_adhesion()
|
||||
proprio.update_connexion()
|
||||
|
||||
elif choix == 'aKM':
|
||||
# Ajout machine au crans
|
||||
becane = MachineCrans(AssociationCrans(db.conn))
|
||||
|
@ -2583,6 +2726,12 @@ def menu_principal():
|
|||
# Annulation des modifs
|
||||
becane.restore()
|
||||
|
||||
elif choix == 'mFc':
|
||||
# Modif machine courante
|
||||
if modif_facture(facture):
|
||||
# Annulation des modifs
|
||||
facture.restore()
|
||||
|
||||
elif choix == 'mCc':
|
||||
# Modif club courant
|
||||
if modif_club(proprio):
|
||||
|
|
|
@ -1503,7 +1503,7 @@ class BaseProprietaire(BaseClasseCrans):
|
|||
|
||||
# On récupère sur les factures l'ensemble de celles comportant une adhésion.
|
||||
adh_factures = self.factures_adh()
|
||||
finAdh = max([0.0] + [fromGeneralizedTimeFormat(facture._data.get('finAdhesion', ["19700101000000Z"])[0]) for facture in adh_factures if facture.controle() != "FALSE"])
|
||||
finAdh = max([0.0] + [fromGeneralizedTimeFormat(facture._data.get('finAdhesion', ["19700101000000Z"])[0]) for facture in adh_factures if facture.controle() != "FALSE" and facture.recuPaiement() is not None])
|
||||
|
||||
if update == False:
|
||||
return finAdh
|
||||
|
@ -1530,6 +1530,19 @@ class BaseProprietaire(BaseClasseCrans):
|
|||
self._set("debutAdhesion", self._data.get("debutAdhesion", []) + [generalizedTimeFormat(thetime)])
|
||||
return f
|
||||
|
||||
def update_adhesion(self):
|
||||
"""Récupère les dates de début et fin d'adhésion dans les factures
|
||||
de l'adhérent, et met à jour ses données."""
|
||||
|
||||
debutAdh = []
|
||||
finAdh = []
|
||||
for facture in self.factures_adh():
|
||||
debutAdh.append(generalizedTimeFormat(facture._data['debutAdhesion'][0]))
|
||||
finAdh.append(generalizedTimeFormat(facture._data['finAdhesion'][0]))
|
||||
self._set('debutAdhesion', debutAdh)
|
||||
self._set('finAdhesion', finAdh)
|
||||
self._save()
|
||||
|
||||
def droits(self, droits=None, light=False):
|
||||
""" Renvoie les droits courants. Non modifiable (sauf si surchargée dans classe enfant)"""
|
||||
if droits <> None:
|
||||
|
@ -2378,7 +2391,7 @@ class Adherent(BaseProprietaire):
|
|||
|
||||
# On récupère sur les factures l'ensemble de celles comportant une connexion.
|
||||
conn_factures = self.factures_conn()
|
||||
finConn = max([0.0] + [fromGeneralizedTimeFormat(facture._data.get('finConnexion', ["19700101000000Z"])[0]) for facture in conn_factures if facture.controle() != "FALSE"])
|
||||
finConn = max([0.0] + [fromGeneralizedTimeFormat(facture._data.get('finConnexion', ["19700101000000Z"])[0]) for facture in conn_factures if facture.controle() != "FALSE" and facture.recuPaiement() is not None])
|
||||
|
||||
if mois is None:
|
||||
return finConn
|
||||
|
@ -2408,6 +2421,19 @@ class Adherent(BaseProprietaire):
|
|||
self._set("debutConnexion", self._data.get("debutConnexion", []) + [generalizedTimeFormat(thetime)])
|
||||
return f
|
||||
|
||||
def update_connexion(self):
|
||||
"""Récupère les dates de début et fin de connexion dans les factures
|
||||
de l'adhérent, et met à jour ses données."""
|
||||
|
||||
debutConn = []
|
||||
finConn = []
|
||||
for facture in self.factures_adh():
|
||||
debutConn.append(generalizedTimeFormat(facture._data['debutConnexion'][0]))
|
||||
finConn.append(generalizedTimeFormat(facture._data['finConnexion'][0]))
|
||||
self._set('debutConnexion', debutConn)
|
||||
self._set('finConnexion', finConn)
|
||||
self._save()
|
||||
|
||||
def adherentPayant(self, valeur = None):
|
||||
"""
|
||||
L'adhérent paie sa cotisation (a droit au WiFi, à un compte Crans, ... True par défaut
|
||||
|
@ -3946,7 +3972,7 @@ class Facture(BaseClasseCrans):
|
|||
raise ValueError, u'Facture déja payée'
|
||||
|
||||
# modification de la valeur
|
||||
if new != None:
|
||||
if new is not None and new != False:
|
||||
# on vérifie que la facture est modifiable
|
||||
if not self._modifiable and new:
|
||||
raise NotImplementedError, "La facture n'est pas modifiable"
|
||||
|
@ -3960,6 +3986,17 @@ class Facture(BaseClasseCrans):
|
|||
|
||||
# modifie la base ldap
|
||||
self._set("recuPaiement", [new])
|
||||
elif new == False:
|
||||
# on vérifie que la facture est modifiable
|
||||
if not self._modifiable and new:
|
||||
raise NotImplementedError, "La facture n'est pas modifiable"
|
||||
|
||||
# on crédite les articles, si c'est pas possible, la metode
|
||||
# levera une exeption
|
||||
self._vider()
|
||||
|
||||
# modifie la base ldap
|
||||
self._set("recuPaiement", [])
|
||||
|
||||
# renvoie la valeur trouvée dans la base
|
||||
return self._data.get("recuPaiement", [None])[0]
|
||||
|
@ -3997,14 +4034,37 @@ class Facture(BaseClasseCrans):
|
|||
# on crédite les articles
|
||||
for art in self._articles():
|
||||
# solde impression (on débite d'abord si jamais quelqu'un s'amuse à recharger son solde avec son solde)
|
||||
if self.modePaiement() == 'solde':
|
||||
proprio = self.proprietaire()
|
||||
proprio.solde(operation=0.0 - self.total(), comment="Facture n°%s" % self.numero())
|
||||
proprio.save()
|
||||
if art["code"] == "SOLDE":
|
||||
proprio = self.proprietaire()
|
||||
proprio.solde(operation=art['nombre']*art["pu"], comment="Facture n°%s : %s" % (self.numero(), art['designation']))
|
||||
proprio.save()
|
||||
if self.modePaiement() == 'solde':
|
||||
proprio = self.proprietaire()
|
||||
proprio.solde(operation=0.0 - self.total(), comment="Facture n°%s" % self.numero())
|
||||
proprio.save()
|
||||
|
||||
def _vider(self):
|
||||
"""
|
||||
Retire les articles à son propriétaire
|
||||
"""
|
||||
|
||||
# on vérifie que le propriétaire est modifiable
|
||||
if not self.proprietaire()._modifiable:
|
||||
raise SystemError, u"Impossible de créditer les articles, le proprietaire n'est pas modifiable"
|
||||
|
||||
# on crédite les articles
|
||||
for art in self._articles():
|
||||
# solde impression (on débite d'abord si jamais quelqu'un s'amuse à recharger son solde avec son solde)
|
||||
if art["code"] == "SOLDE":
|
||||
proprio = self.proprietaire()
|
||||
proprio.solde(operation=-art['nombre']*art["pu"], comment="Revert facture n°%s : %s" % (self.numero(), art['designation']))
|
||||
proprio.save()
|
||||
if art["code"] == "FRAIS":
|
||||
self.supprime(art)
|
||||
if self.modePaiement() == 'solde':
|
||||
proprio = self.proprietaire()
|
||||
proprio.solde(operation=0.0 + self.total(), comment="Revert facture n°%s" % self.numero())
|
||||
proprio.save()
|
||||
|
||||
def _frais(self):
|
||||
"""
|
||||
|
|
|
@ -295,11 +295,11 @@ def factures_brief(factures) :
|
|||
# Contrôle
|
||||
controle = facture.controle()
|
||||
if controle == "TRUE":
|
||||
controle = coul("Validée", "vert")
|
||||
controle = coul(u"Validée", "vert")
|
||||
elif controle == "FALSE":
|
||||
controle = coul("Invalide", "rouge")
|
||||
controle = coul(u"Invalide", "rouge")
|
||||
else:
|
||||
controle = "N/A"
|
||||
controle = u"N/A"
|
||||
|
||||
# Données
|
||||
data.append([
|
||||
|
@ -423,11 +423,11 @@ def list_factures(factures) :
|
|||
for f in factures :
|
||||
controle = f.controle()
|
||||
if controle == "TRUE":
|
||||
controle = coul("Validée", "vert")
|
||||
controle = coul(u"Validée", "vert")
|
||||
elif controle == "FALSE":
|
||||
controle = coul("Invalide", "rouge")
|
||||
controle = coul(u"Invalide", "rouge")
|
||||
else:
|
||||
controle = "N/A"
|
||||
controle = u"N/A"
|
||||
data.append([
|
||||
f.id(),
|
||||
f.modePaiement(),
|
||||
|
@ -702,11 +702,11 @@ def facture_details(facture) :
|
|||
|
||||
controle = facture.controle()
|
||||
if controle == "TRUE":
|
||||
controle = coul("Validée", "vert")
|
||||
controle = coul(u"Validée", "vert")
|
||||
elif controle == "FALSE":
|
||||
controle = coul("Invalide", "rouge")
|
||||
controle = coul(u"Invalide", "rouge")
|
||||
else:
|
||||
controle = "N/A"
|
||||
controle = u"N/A"
|
||||
|
||||
f=u''
|
||||
# Fid
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue