home *** CD-ROM | disk | FTP | other *** search
Wrap
#Version 2.3 #2.3 : Correction du bug qui dΘcalait les catΘgories #2.2 : correction de bugs #2.1 : possibilitΘ de supprimer ou de renomer un fichier d'ΘchΘance #2.0 : possibilitΘ de dΘcaler une ΘchΘance en avant ou en arriΦre #1.9 : nouveau script de mise α jour des catΘgories import BP, cPickle, time s = BP.BankPerfectExePath() + "Scripts\\Scheduler\\%s.dat" Dat = s %"scheduler" Units = ["jours", "mois", "ans"] modes = ["Carte", "Retrait DAB", "ChΦque Θmis", "PrΘlΦvement", "Virement Θmis", "TIP", "Versement", "DΘp⌠t de chΦque", "Virement reτu"] OtherMode = {0: 8, 1: 6, 2: 7, 3: 8, 4: 8, 5: 8, 6: 1, 7: 2, 8: 3} modesigns = [-1, -1, -1, -1, -1, -1, 1, 1, 1] FrmFiles = """listbox=LstFiles;Left=20;Top=20;Anchors=lrtb;Width=400;Height=130;Text=%s;Enabled=1;ItemIndex=0 button=BRename;Anchors=lb;Left=20;Top=130;Width=90;Height=25;Caption=Renommer button=BDelete;Anchors=lb;Left=120;Top=130;Width=90;Height=25;Caption=Supprimer button=BDouble;Anchors=lb;Left=220;Top=130;Width=90;Height=25;Caption=Dupliquer button=BClose;Anchors=lb;Left=320;Top=130;Width=90;Height=25;Caption=Fermer;cancel=1""" FrmRecs = """grid=ListRecs;Left=20;Top=20;Width=700;Height=349;Anchors=lrtb;Rows=%d;Cols=5;Cells=Compte\\r\\nIntervalle\\r\\nTiers\\r\\nMontant\\r\\nProchaine ΘchΘance\\r\\n%s;Index=%d label=LInfo;Left=20;Top=372;Anchors=lb;Caption=%s button=BAdd;Left=20;Top=400;Width=80;Height=25;Anchors=lb;Caption=Ajouter button=BModify;Left=104;Top=400;Width=80;Height=25;Anchors=lb;Caption=Modifier button=BDelete;Left=188;Top=400;Width=80;Height=25;Anchors=lb;Caption=Supprimer button=BApply;Left=272;Top=400;Width=80;Height=25;Anchors=lb;Caption=Appliquer label=LDelta;Left=420;Top=384;Width=96;Height=13;Anchors=lb;Caption=DΘcaler l'ΘchΘance : button=BRewind;Left=384;Top=400;Width=80;Height=25;Anchors=lb;Caption=½ en arriΦre;hint=Avancer la date d'une pΘriode button=BForward;Left=468;Top=400;Width=80;Height=25;Anchors=lb;Caption=en avant ╗;hint=Reculer la date d'une pΘriode button=BClose;Left=628;Top=400;Width=90;Height=25;Anchors=rb;Caption=Fermer;Cancel=1""" FrmApply = """label=LInsert;Left=20;Top=20;Width=85;Caption=InsΘrer jusqu'au : date=UntilDate;Left=20;Top=36;Width=260;Date=%s label=LWhat;Left=20;Top=80;Width=185;Caption=Quelles lignes souhaitez-vous insΘrer ? combo=CBWhat;Left=20;Top=96;Width=260;Text=La ligne sΘlectionnΘe\\r\\nLes lignes qui ne s'insΦrent pas automatiquement\\r\\nToutes les lignes\\r\\n;ItemIndex=0 checkbox=CheckSimulation;Left=20;Top=136;Width=260;Caption=InsΘrer les lignes pour effectuer une simulation label=LSimulation;Left=36;Top=156;Width=212;Caption=(ne met pas α jour les dates des ΘchΘances);Color=CC0000 button=BOK;Left=55;Top=192;Width=90;Height=25;Caption=OK;Default=1 button=BCancel;Left=155;Top=192;Width=90;Height=25;Caption=Annuler;Cancel=1""" FrmRec = """label=LMsg;Left=30;Top=30;Width=103;Bold=1;Color=%s;Caption=%s label=LNextDate;Left=30;Top=74;Width=103;Caption=Prochaine ΘchΘance : label=LThirdPartyDetails;Left=30;Top=198;Width=69;Caption=Tiers /DΘtails : label=LValue;Left=30;Top=244;Width=47;Caption=Montant : label=LModeCateg;Left=30;Top=156;Width=152;Caption=Mode de paiement / CatΘgorie : label=LDelta;Left=30;Top=288;Width=82;Caption=InsΘrer tous les : label=LAccount;Left=325;Top=288;Width=82;Caption=Compte : date=NextDate;Left=220;Top=70;Width=300;Date=%s checkbox=CheckEndDate;Left=30;Top=112;Width=175;Height=17;Caption=DerniΦre ΘchΘance (incluse) :;Checked=%d date=EndDate;Left=220;Top=110;Width=300;Date=%s combo=CBMode;Left=220;Top=152;Width=145;Text=%s\\r\\n;ItemIndex=%d combo=CBCateg;Left=375;Top=152;Width=145;Text=%s\\r\\n;ItemIndex=%d edit=EThirdParty;Left=220;Top=194;Width=145;Text=%s;Readonly=0 edit=EDetails;Left=375;Top=194;Width=145;Text=%s;Readonly=0 edit=EValue;Left=220;Top=240;Width=301;Text=%s;Readonly=0 edit=EDelta;Left=220;Top=284;Width=30;Text=%s;Readonly=0 combo=CBDeltaUnit;Left=255;Top=284;Width=60;Text=jour(s)\\r\\nmois\\r\\nan(s);ItemIndex=%d combo=CBAccounts;Left=375;Top=284;Width=145;Text=%s;ItemIndex=%d checkbox=CheckTransfer;Left=30;Top=325;Width=334;Height=20;Caption=Cette ΘchΘance est un transfert vers (ou depuis) le compte :;Enabled=1;Checked=%d combo=CBAccounts2;Left=375;Top=324;Width=145;Height=21;Text=%s;Enabled=1;ItemIndex=%d checkbox=CheckAutoInsert;Left=30;Top=350;Width=435;Height=17;Caption=InsΘrer automatiquement cette ΘchΘance α l'ouverture du fichier;Checked=%d label=LPostpone;Left=30;Top=385;Caption=DΘcaler l'Θchance si elle tombe un : checkbox=CheckSat;Left=210;Top=383;Caption=Samedi;Checked=%d checkbox=CheckDim;Left=290;Top=383;Caption=Dimanche;Checked=%d checkbox=CheckFer;Left=370;Top=383;Caption=Jour fΘriΘ;Checked=%d button=BOK;Left=283;Top=415;Width=90;Height=25;Caption=OK;Default=1 button=BCancel;Left=181;Top=415;Width=90;Height=25;Caption=Annuler;Cancel=1""" def CopyDic(dic): new_dic = {} for key in dic.keys(): new_dic[key] = dic[key] return new_dic def DaysOfMonth(y, m): if m == 2 and (y % 4 == 0) and (y % 100 != 0 or y % 400 == 0): return 29 else: return [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][m - 1] def AddYears(date, delta): y, m, d = date return y + delta, m, d def AddDays(dt, delta): y, m, d = dt d += delta if delta > 0: while d > DaysOfMonth(y, m): d -= DaysOfMonth(y, m) m += 1 if m == 13: y += 1; m = 1 else: while d < 1: m -= 1 d += DaysOfMonth(y, m) if m == 0: y -= 1; m = 12 return y, m, d def AddMonths(date, delta): y, m, d = date KeepLast = DaysOfMonth(y, m) == d m += delta if delta > 0: while m > 12: y += 1; m -= 12 elif delta < 0: while m < 1: y -= 1; m += 12; LastDay = DaysOfMonth(y, m) if KeepLast or d > LastDay: return y, m, LastDay else: return y, m, d def Add2Date(dt, d, u): if u == 0: return AddDays(dt, d) elif u == 1: return AddMonths(dt, d) else: return AddYears(dt, d) def DayOfWeek(y, m, d): t = time.mktime((y, m, d, 12, 0, 0, 0, 0, 0)) return time.localtime(t)[6] def Easter(Y): C = Y / 100 H = (19 * (Y % 19) + C - (C / 4) - ((8 * C + 13) / 25) + 15) % 30 I = ((H / 28) * (29 / (H + 1)) * ((21 - (Y % 19)) / 11) - 1) * (H / 28) + H R = 28 + I - (((Y / 4 + Y) + I + 2 + (C / 4) - C) % 7) if R <= 31: return (Y, 3, R) else: return (Y, 4, R - 31) print Easter(2006) def NonWorkingDay(dt, include): #include: DSF, D=dim, S=sam, F=FΘriΘ y, m, d = dt dw = DayOfWeek(y, m, d) if "D" in include and dw == 6: return 1 if "S" in include and dw == 5: return 1 if "F" in include: if (m, d) in [(1, 1), (5, 1), (8, 1), (7, 14), (8, 15), (11, 1), (11, 11), (12, 25)]: return 1 E = Easter(y) #Lundi de pΓques, Jeudi ascension, Lundi de Pentecote if (y, m, d) in [AddDays(E, 1), AddDays(E, 39), AddDays(E, 50)]: return 1 return 0 def NextWorkingDate(dt, include): while NonWorkingDay(dt, include): dt = AddDays(dt, 1) return dt def parse(v): lines = v.replace("\r\n", "\n").replace("\r", "\n").split("\n") d = {} for line in lines: i = line.find("=") if i > -1: d[line[:i]] = line[i + 1:] return d def ExtractFName(path): while path.find("\\") > -1: path = path[path.find("\\") + 1:] return path def Rec2Str(Rec): dl = Rec["delta"] d = Rec["deltaunit"] if dl == 1: s = "Tous les %s" %Units[d] else: s = "Tous les %d %s" %(dl, Units[d]) try: acc_name = AccNames[Rec["account"]] except: acc_name = "COMPTE INACCESSIBLE" if Rec.get("transfer", -1) > -1: trf = " (transfert)" else: trf = "" return "%s\\r\\n%s\\r\\n%s%s\\r\\n%.2f\\r\\n%s" %(acc_name, s, Rec["tiers"], trf, Rec["montant"], Date2Str(Rec["nextdate"])) def Date2Str(date): if date == (0, 0, 0): y, m, d = time.localtime()[:3] else: y, m, d = date return "%.02d/%.02d/%.04d" %(d, m, y) def Str2Date(d): l = d.replace("/", "-").split("-") return int(l[2]), int(l[1]), int(l[0]) def Str2Float(s, Def): s = s.replace("$", "").replace(" ", "").replace("Ç", "").replace("F", "").replace(",", ".") if "." in s: l = s.split(".") s = "%s.%s" %( "".join(l[:-1]), l[-1] ) try: return float(s) except: return Def def IBool(b): if b: return 1 return 0 def EditRec(Rec0): Rec = CopyDic(Rec0) StrAcc = "\\r\\n".join(accounts) AccIdx = BP.AccountCurrent() color = "000000" StrCtg = "\\r\\n".join(["Sans catΘgorie"] + CNames) StrModes = "\\r\\n".join(modes) caption = ("Modifier une ΘchΘance", "Ajouter une ΘchΘance")[Rec == {}] #Affichage de la form show = 1 msg = "Saisissez la valeur de chaque champ de l'ΘchΘance" while show: Postpone = Rec.get("Postpone", "") PostponeSat = IBool("S" in Postpone) PostponeDim = IBool("D" in Postpone) PostponeFer = IBool("F" in Postpone) people = Rec.get("tiers", "") details = Rec.get("details", "") value = abs(Rec.get("montant", 0)) delta = Rec.get("delta", "1") nextdate = Date2Str(Rec.get("nextdate", (0, 0, 0))) enddate = Date2Str(Rec.get("enddate", (0, 0, 0))) categ = CPositions.get(Rec.get("categ", -1), -1) + 1 mode = Rec.get("mode", 3) du = Rec.get("deltaunit", 1) checkdate = Rec.get("enddate", (0, 0, 0)) > (0, 0, 0) AutoInsert = Rec.get("autoinsert", 1) AccIdx = Rec.get("account", 0) Acc2Idx = Rec.get("transfer", -1) check_transfer = Acc2Idx > -1 params = (color, msg, nextdate, checkdate, enddate, StrModes, mode, StrCtg, categ, people, details, value, delta, du, StrAcc, AccIdx, check_transfer, StrAcc, Acc2Idx, AutoInsert, PostponeSat, PostponeDim, PostponeFer) result = parse(BP.CustomForm(caption, FrmRec %params, 562, 480)) if result["SelectedButton"] == "BOK": msg = "" if result["CheckEndDate"] == "1": Rec["enddate"] = Str2Date(result["EndDate"]) else: Rec["enddate"] = (0, 0, 0) Rec["nextdate"] = Str2Date(result["NextDate"]) Rec["mode"] = int(result["CBMode"]) Rec["tiers"] = result["EThirdParty"] Rec["details"] = result["EDetails"] Rec["categ"] = CIndexes.get(int(result["CBCateg"]) - 1, 0) Rec["montant"] = Str2Float(result["EValue"], 0) Rec["autoinsert"] = int(result["CheckAutoInsert"]) Rec["account"] = int(result["CBAccounts"]) Postpone = "" if result["CheckSat"] == "1": Postpone += "S" if result["CheckDim"] == "1": Postpone += "D" if result["CheckFer"] == "1": Postpone += "F" Rec["Postpone"] = Postpone if int(result["CheckTransfer"]): Rec["transfer"] = int(result["CBAccounts2"]) if Rec["transfer"] == Rec["account"]: msg = "Il faut choisir deux comptes diffΘrents pour un transfert" else: Rec["transfer"] = -1 try: Rec["delta"] = int(result["EDelta"]) if Rec["delta"] < 1: Rec["delta"] = 1 except: msg = "Intervalle incorrect" Rec["delta"] = 1 Rec["deltaunit"] = int(result["CBDeltaUnit"]) if msg == "": if Rec["montant"] == 0: msg = "Un montant non nul est obligatoire" elif Rec["tiers"] == "": msg = "Le tiers est obligatoire" if msg == "": #Calcul automatique du signe du montant: Rec["montant"] = modesigns[Rec["mode"]] * abs(Rec["montant"]) return Rec else: color = "dd0000" else: return Rec0 show = 0 def ApplyRec(RecList, SelecIdx): until = time.localtime()[:3] result = parse(BP.CustomForm("InsΘrer des ΘchΘances", FrmApply %(Date2Str(until)), 300, 270)) if result["SelectedButton"] != "BOK": return what = result["CBWhat"] if result["CheckSimulation"] == "1": CurrentRecs = [d.copy() for d in RecList] else: CurrentRecs = RecList if what == "0": CurrentRecs = CurrentRecs[SelecIdx:SelecIdx + 1] elif what == "1": CurrentRecs = [r for r in CurrentRecs if r.get("auto_insert", 1) != 1] inserted = [] for Rec in CurrentRecs: if Rec["account"] > BP.AccountCount() - 1: continue until = Str2Date(result["UntilDate"]) enddate = Rec["enddate"] if enddate != (0, 0, 0) and enddate < until: until = enddate acc1 = Rec.get("account", 0) acc2 = Rec.get("transfer", -1) ctg = Rec["categ"] if not CPositions.has_key(ctg): ctg = -1 while Rec["nextdate"] <= until: DateInsert = Rec["nextdate"] if Rec.get("Postpone", ""): DateInsert = NextWorkingDate(DateInsert, Rec["Postpone"]) date = Date2Str(DateInsert) if acc2 > -1: #Transfert de compte α compte n1 = AccNames[acc1] n2 = AccNames[acc2] mode1 = Rec["mode"] mode2 = OtherMode[mode1] if mode1 in [0, 1, 2, 3, 4, 5]: sens1 = "vers" sens2 = "depuis" else: sens1 = "depuis" sens2 = "vers" BP.LineAdd(acc1, date, modes[mode1], "Transfert %s le compte %s" %(sens1, n2), Rec["details"], ctg, Rec["montant"], 0) BP.LineAdd(acc2, date, modes[mode2], "Transfert %s le compte %s" %(sens2, n1), Rec["details"], ctg, -Rec["montant"], 0) else: #OpΘration standard BP.LineAdd(acc1, date, modes[Rec["mode"]], "[auto] " + Rec["tiers"], Rec["details"], ctg, Rec["montant"], 0) inserted.append("- EchΘance %s le %s" %(Rec["tiers"], date)) Rec["nextdate"] = Add2Date(Rec["nextdate"], Rec["delta"], Rec["deltaunit"]) l = len(inserted) if l == 0: BP.MsgBox("Aucune ΘchΘance n'a ΘtΘ insΘrΘe", 0) else: if l == 1: BP.MsgBox("Une ΘchΘance a ΘtΘ insΘrΘe :\r\n\r\n%s" %inserted[0], 0) else: BP.MsgBox("%d ΘchΘances ont ΘtΘ insΘrΘes :\r\n\r\n%s" %(l, "\r\n".join(inserted)), 0) BP.AccountRefreshScreen() files[FName] = Recs SaveFile() def SaveFile(): f = open(Dat, "wb") cPickle.dump(files, f, 1) f.close() try: f = open(Dat, "rb") files = cPickle.load(f) f.close() except: files = {} FNames = files.keys() FPath = BP.BankPerfectFileName() btn = "Show" if FPath == "": while btn in ["Show", "BDelete", "BRename", "BDouble"]: if files == {}: BP.MsgBox("Il n'y a aucune ΘchΘance α afficher", 0) btn = "BClose" else: LstFiles = "\\r\\n".join(FNames) result = parse(BP.CustomForm("Fichiers contenant des ΘchΘances", FrmFiles %LstFiles, -440, -210)) btn = result["SelectedButton"] SelecIdx = int(result["LstFiles"]) FName = FNames[SelecIdx] if btn == "BRename": send_ok, new_key = BP.InputText("Renommer un fichier", "Saisissez le nouveau nom du fichier .bp", FName) if send_ok and new_key != FName: value = files[FName] files[new_key] = value del(files[FName]) SaveFile() FNames = files.keys() if btn == "BDouble": new_f = BP.OpenDialog("SΘlectionnez le fichier o∙ importer les ΘchΘances", "", ".bp", "Fichier BankPerfect (*.bp)|*.bp") new_f = new_f[new_f.rfind("\\") + 1:] if new_f != "" and new_f != FName: value = files[FName] files[new_f] = value SaveFile() FNames = files.keys() if btn == "BDelete": if BP.MsgBox("Supprimer les ΘchΘances du fichier %s ?" %FName, 4) == 6: del(files[FName]) SaveFile() FNames = files.keys() else: cnames = BP.CategName CTrimNames = [] CPositions = {-1: -1} CIndexes = {-1: -1} CNames = [] for i, c in enumerate(cnames): p = c.find("=") CNames.append(c[p+1:]) CTrimNames.append(c[p+1:].strip()) idx = int(c[:p]) CPositions[idx] = i CIndexes[i] = idx accounts = BP.AccountName AccNames = BP.AccountName; FName = ExtractFName(FPath) if not files.has_key(FName): files[FName] = [] Recs = files[FName] ShowFrm = 1 SelecIdx = 0 Recs = [(r["nextdate"], r) for r in Recs] Recs.sort() Recs = [r[1] for r in Recs] while ShowFrm: StrRec = "\\r\\n".join([Rec2Str(Rec) for Rec in Recs]) NbRec = len(Recs) if NbRec == 0: StrNbRec = "Aucune ΘchΘance" elif NbRec == 1: StrNbRec = "Une ΘchΘance" else: StrNbRec = "%d ΘchΘances" %NbRec result = parse(BP.CustomForm("EchΘances du fichier %s" %FName, FrmRecs %(NbRec + 1, StrRec, SelecIdx + 1, StrNbRec), -740, -445)) btn = result["SelectedButton"] SelecIdx = int(result["ListRecs"]) if btn == "BDelete": if SelecIdx == -1: BP.MsgBox("Veuillez sΘlectionner l'ΘchΘance α supprimer", 0) elif BP.MsgBox("Supprimer l'ΘchΘance %s ?" %Recs[SelecIdx]["tiers"], 4) == 6: del(Recs[SelecIdx]) max_val = len(Recs) - 1 if SelecIdx > max_val: SelecIdx = max_val files[FName] = Recs SaveFile() elif btn == "BAdd": Rec = EditRec({}) if Rec != {}: Recs.append(Rec) SelecIdx = len(Recs) - 1 files[FName] = Recs SaveFile() elif btn == "BModify": if SelecIdx == -1: BP.MsgBox("Vous devez tout d'abord sΘlectionner l'ΘchΘance α modifier.\r\nSi vous souhaitez crΘer une ΘchΘance, cliquez sur le bouton 'Ajouter'", 0) else: Recs[SelecIdx] = EditRec(Recs[SelecIdx]) files[FName] = Recs SaveFile() elif btn == "BApply": if FPath == "": BP.MsgBox("Il n'y a pas de fichier BankPerfect ouvert", 0) else: ApplyRec(Recs, SelecIdx) elif btn == "BForward": if SelecIdx > -1: Rec = Recs[SelecIdx] Rec["nextdate"] = Add2Date(Rec["nextdate"], Rec["delta"], Rec["deltaunit"]) files[FName] = Recs SaveFile() elif btn == "BRewind": if SelecIdx > -1: Rec = Recs[SelecIdx] Rec["nextdate"] = Add2Date(Rec["nextdate"], -Rec["delta"], Rec["deltaunit"]) files[FName] = Recs SaveFile() else: btn = "" ShowFrm = 0