From 13200e9a74f2345f09b1d49c6be404e600558831 Mon Sep 17 00:00:00 2001 From: Valentin Samir Date: Sun, 23 Mar 2014 20:38:06 +0100 Subject: [PATCH] =?UTF-8?q?[objets/facture]=20Factures=20=C3=A9ditables=20?= =?UTF-8?q?via=20lc=5Fldap=20modulo=20l'=C3=A9dition=20du=20solde=20de=20s?= =?UTF-8?q?ont=20propri=C3=A9taire?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L'idée étant d'essayer d'avoir un fonction 'crediter' qui va éditier le solde de sont parent puis sauvegarder/creer la facture de la fonçon la plus atomique possible. Il faudarait voir s'il y a quelque chose de plus propre pour rendre tout ça un peu plus atomique --- objets.py | 106 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 89 insertions(+), 17 deletions(-) diff --git a/objets.py b/objets.py index 0fdb87c..cfe40ef 100644 --- a/objets.py +++ b/objets.py @@ -1234,7 +1234,7 @@ class facture(CransLdapObject): variables.deleted: [attributs.nounou, attributs.bureau, attributs.cableur], } attribs = [attributs.fid, attributs.modePaiement, attributs.recuPaiement, - attributs.historique, attributs.article] + attributs.historique, attributs.article, attributs.info] ldap_name = "facture" _proprio = None @@ -1245,30 +1245,102 @@ class facture(CransLdapObject): #### GROS HACK pour rester comptatible avec ldap_crans où l'article representant les frais n'est ajouté qu'une fois le paiement reçu def __init__(self, *args, **kwargs): super(facture, self).__init__(*args, **kwargs) - self._frais = [] - if not self['recuPaiement']: - if 'paypal' in self['modePaiement']: - # 25 centimes pour le paiement paypal - s = 0.25 - # et on ajoute 3.5% du montant - for art in self['article']: - s += 0.035 * int(art['nombre']) * float(art['pu']) - # arrondissage-tronquage - s = float(int(s*100)/100.0) - # ajoute à la liste d'articles de frais - self._frais.append(attributs.attrify('FRAIS~~Frais de tansaction PayPal~~1~~%s' % round(s, 2), 'article', self.conn, Parent=self)) + self._has_frais = True if [art for art in self.attrs.get('article', []) if art['code'] != 'FRAIS'] else False + self._recuPaiement = True if self['recuPaiement'] else False def __getitem__(self,attr, default=None): ret = super(facture, self).__getitem__(attr, default) - if attr == 'article' and self.mode == 'ro': - return ret + self._frais + if attr == 'article' and self.mode == 'ro' and not self._has_frais: + return ret + ([self._article_frais] if self._article_frais else []) else: return ret #### FIN DU GROS HACK - def proprio(self): + def __setitem__(self, attr, value): + if self._recuPaiement and attr in ['article', 'modePaiement', 'recuPaiement']: + raise EnvironmentError("Paiement déjà effectué pour cette facture, impossible de modifier son contenu") + return super(facture, self).__setitem__(attr, value) + + _article_frais = None + def _frais(self, mode=None): + if mode is None: + mode = self['modePaiement'][0] + if self._recuPaiement: + return + frais = {'code':'FRAIS', 'designation':'Frais de tansaction', 'nombre':1, 'pu':0.0} + if mode == 'paypal': + # 25 centimes pour le paiement paypal + s = 0.25 + # et on ajoute 3.5% du montant + for art in self['article']: + s += 0.035 * int(art['nombre']) * float(art['pu']) + # arrondissage-tronquage + s = float(int(s*100)/100.0) + # ajoute à la liste d'articles de frais + frais['pu']=round(s, 2) + self._article_frais = dict(frais) + + def _add_frais(self): + self._frais() + if not self._recuPaiement: + articles = [art for art in self['article'] if art['code'] != 'FRAIS'] + if self._article_frais: + articles.append(self._article_frais) + self['article'] = articles + self._has_frais = True + + def total(self): + total=0 + for article in self["article"]: + total+=int(article['nombre'])*float(article['pu']) + return total + + def crediter(self): + """ + Crédite les articles à son propriétaire + """ + + def credite_arts(proprio, cancel=False): + sign = -1 if cancel else +1 + proprio_save = False + # on crédite les articles + for art in self['article']: + # solde impression (on débite d'abord si jamais quelqu'un s'amuse à recharger son solde avec son solde) + if self['modePaiement'][0] == 'solde': + proprio.solde(operation=sign * (0.0 - self.total()), comment=u"Facture n°%s" % self['fid'][0]) + proprio_save = True + if art["code"] == "SOLDE": + proprio.solde(operation=sign * (int(art['nombre'])*float(art["pu"])), comment=u"Facture n°%s : %s" % (self['fid'][0], art['designation'])) + proprio_save = True + return proprio_save + + if not self._recuPaiement: + self._add_frais() + with self.proprio() as proprio: + proprio_save = credite_arts(proprio) + # On vient de créditer, le paiement a été reçu + self['recuPaiement']=unicode(int(time.time())) + self._recuPaiement = True + + # Il faudrait faire quelquechose pour que si l'enregistrement suivant de la facture crash, + # on défait ce qu'on fait sur le proprio plus proprement + if proprio_save: + proprio.save() + + # On force l'enregistrement de la facture après avoir crédité + try: + if self.exists(): + self.save() + else: + self.create() + except: + if proprio_save: + credite_arts(proprio, cancel=True) + proprio.save() + + def proprio(self, refresh=False): u"""Renvoie le propriétaire de la facture""" - if not self._proprio: + if refresh or not self._proprio: self._proprio = new_cransldapobject(self.conn, self.parent_dn, self.mode) return self._proprio