def sumd(dic, sumkeys): """ Sums values from a dictionary according to sumkeys parameter dic: {key1: val1, key2:val2, ...} sumkeys: [key1, key3, ...] """ val = dec(0) for key in sumkeys: val += dic.get(key, dec(0)) return val
def isozygio(self, apo=None, eos=None, chart=None): """ Ισοζύγιο λογαριασμών """ iso = {} txr = tpi = typ = 0 for tra in self.filter_by_dates(apo, eos): for lin in tra["lines"]: debit = lin["value"] if lin["typ"] == 1 else 0 credit = lin["value"] if lin["typ"] == 2 else 0 gcode = lin["account"] iso[gcode] = iso.get(gcode, { "debit": dec(0), "credit": dec(0) }) iso[gcode]["debit"] += debit iso[gcode]["credit"] += credit txr += debit tpi += credit typ += debit - credit fiso = {} apot = 0 for code, val in iso.items(): for lcode in levels_reverse(code): fiso[lcode] = fiso.get(lcode, { "debit": dec(0), "credit": dec(0) }) fiso[lcode]["debit"] += val["debit"] fiso[lcode]["credit"] += val["credit"] if code[0] in "267": apot += val["debit"] - val["credit"] tapo = f" Από: {date_iso2gr(apo)}" teos = f" Έως: {date_iso2gr(eos)}" tapoeos = f"{tapo}{teos}" tmp = f"\n{'ΙΣΟΖΥΓΙΟ ΛΟΓΙΣΤΙΚΗΣ':^104}\n" tmp += f"{tapoeos:^104}\n" tmp += "-" * 104 + "\n" for acc in sorted(fiso): delta = dec2gr(fiso[acc]["debit"] - fiso[acc]["credit"]) if acc in self.accounts: accp = self.accounts[acc] else: accp = closest_name(acc, chart) tmp += (f"{acc:<15}{accp:<50} {dec2gr(fiso[acc]['debit']):>12} " f"{dec2gr(fiso[acc]['credit']):>12} {delta:>12}\n") tmp += "-" * 104 + "\n" tmp += (f"{'':<15}{'Σύνολα':^50} {dec2gr(txr):>12} " f"{dec2gr(tpi):>12} {dec2gr(typ):>12}\n" f"{'':<15}{'Αποτέλεσμα (2, 6, 7)':^50} {dec2gr(0):>12} " f"{dec2gr(0):>12} {dec2gr(apot):>12}\n") return tmp
def parse_acc_fpa(cfg): fpas = dict(cfg["fpa"]) fpas = {el: fpas[el].split() for el in fpas} acc_fpa = {} for cod_fpa, vals in fpas.items(): cod, fpa = cod_fpa.split("_") cod = int(cod) fpa = int(fpa) for val in vals: """Επειδή οι εγγραφές ενδοκοινοτικών δεν έχουν ΦΠΑ και ο υπολογισμός γίνεται μόνο για το έντυπο, κατά τον έλεγχο βάζουμε την τιμή να είναι 0 """ if cod_fpa in ("364_24", ): acc_fpa[val] = dec(0) else: acc_fpa[val] = dec(fpa) return acc_fpa
def fpa(cfg, args): # apo, eos, outfile=None, ini_file='logistiki.ini'): """ Για τον υπολογισμό του φπα χρησιμοποιούμε παραμέτρους από το αρχείο logistiki.ini """ # Εδώ δημιουργούμε το {'20.00.24': {363: 24}, ...} fpas = dict(cfg["fpa"]) fpas = {el: fpas[el].split() for el in fpas} acc_code_fpa = reverse_fpa_dict(fpas) codata = dict(cfg["company"]) codata["apo"] = date_iso2gr(args.apo) codata["eos"] = date_iso2gr(args.eos) # Εδώ φορτώνουμε τα δεδομένα στο βιβλίο book = prs.parse_all(cfg) isozygio = book.totals_for_fpa(args.apo, args.eos) fdata = {} fpad = {} for account, value in isozygio.items(): if account in acc_code_fpa: for code, fpa in acc_code_fpa[account].items(): fdata[code] = fdata.get(code, dec(0)) fdata[code] += value fpad[code] = fpad.get(code, dec(0)) fpad[code] += dec(value * dec(fpa) / dec(100)) fdata[5400] = isozygio[5400] for cods in [361, 362, 363, 364, 365, 366]: fpa_value = fpad.get(cods, dec(0)) if fpa_value != 0: # Για να αποφύγω τις μηδενικές τιμές fdata[cods + 20] = fpa_value # DATA = {361: dec(95156.97), 303: dec(101119.21), 381: dec(100.34), # 306: dec(28529.25), 364: dec(1825.68), 349: dec(39527.90)} f2_render(codata, fdata, args.out)
def fpa_errors(tran, acc_fpa, threshold): poso = dec(0) cfpa = dec(0) tfpa = dec(0) for lin in tran["lines"]: acc = lin["account"] if acc[0] in "1267": if acc in acc_fpa: cfpa += dec(lin["value"] * acc_fpa[acc] / dec(100)) poso += lin["value"] elif acc.startswith("54.00"): tfpa += lin["value"] delta = abs(cfpa - tfpa) if delta > threshold: return { "tran": tran, "poso": poso, "delta": delta, "cfpa": cfpa, "tfpa": tfpa } return False
def totals_for_fpa(self, apo, eos): """ Ισοζύγιο ειδικά για τον υπολογισμό του ΦΠΑ """ iso = {} fpa_delta = 0 for tra in self.filter_by_dates(apo, eos): for lin in tra["lines"]: account = lin["account"] if account.startswith("54.00"): if not account.startswith("54.00.99"): fpa_delta += lin["value"] if lin[ "typ"] == 1 else -lin["value"] if account[0] not in "1267": continue iso[account] = iso.get(account, dec(0)) if account[0] in "126": iso[account] += lin["value"] if lin[ "typ"] == 1 else -lin["value"] elif account[0] == "7": iso[account] += lin["value"] if lin[ "typ"] == 2 else -lin["value"] iso[5400] = fpa_delta return iso
def calculate_f2(dat): """ Calculate values """ adi = {} # Εκροές με ΦΠΑ for elm in range(301, 307): adi[elm] = dat.get(elm, dec(0)) adi[307] = sumd(adi, range(301, 307)) adi[331] = dec(adi[301] * dec(0.13)) adi[332] = dec(adi[302] * dec(0.06)) adi[333] = dec(adi[303] * dec(0.24)) adi[334] = dec(adi[304] * dec(0.09)) adi[335] = dec(adi[305] * dec(0.04)) adi[336] = dec(adi[306] * dec(0.17)) adi[337] = sumd(adi, range(331, 337)) # Λοιπές εκροές adi[342] = dat.get(342, dec(0)) adi[345] = dat.get(345, dec(0)) adi[348] = dat.get(348, dec(0)) adi[349] = dat.get(349, dec(0)) adi[310] = dat.get(310, dec(0)) adi[311] = sumd(adi, [307, 342, 345, 348, 349, 310]) adi[312] = adi[311] - dat.get(364, dec(0)) - dat.get(365, dec(0)) # Εισροές με ΦΠΑ for elm in range(361, 367): adi[elm] = dat.get(elm, dec(0)) adi[367] = sumd(adi, range(361, 367)) for elm in range(381, 387): adi[elm] = dat.get(elm, dec(0)) adi[387] = sumd(adi, range(381, 387)) # Ο λογαριασμός ελέγχου του φπα περιόδου fpa_apo_logistiki = dat.get(5400, dec(0)) delta_fpa = adi[337] - adi[387] + fpa_apo_logistiki if delta_fpa > 0: dat[402] = delta_fpa elif delta_fpa < 0: dat[422] = -delta_fpa # Προστιθέμενα ποσά for elm in [400, 402, 407]: adi[elm] = dat.get(elm, dec(0)) adi[410] = sumd(adi, [400, 402, 407]) # Αφαιρούμενα ποσά for elm in [411, 422, 423]: adi[elm] = dat.get(elm, dec(0)) adi[428] = sumd(adi, [411, 422, 423]) adi[430] = adi[387] + adi[410] - adi[428] # Πίνακας Εκκαθάρισης Φόρου adi[401] = dat.get(401, dec(0)) adi[483] = dat.get(483, dec(0)) adi[403] = dat.get(403, dec(0)) adi[505] = dat.get(505, dec(0)) if adi[430] < adi[337]: adi[470] = dec(0) adi[480] = adi[337] - adi[430] else: adi[470] = adi[430] - adi[337] adi[480] = dec(0) if (adi[480] + adi[483]) > (adi[470] + adi[401]): adi[511] = (adi[480] + adi[483]) - (adi[470] + adi[401]) else: adi[502] = (adi[470] + adi[401]) - (adi[480] + adi[483]) return adi
# Fill fields from f2data for key, val in f2data.items(): if key in html_data.keys(): html_data[key] = val # Finally save the form if html_file: with open(html_file, "w") as fout: fout.write(F2_HTML.format(**html_data)) logger.info(f"fpa report saved to file: {html_file}") else: print(html_data) if __name__ == "__main__": # print(render_f2({'epon': 'ΛΑΖΑΡΟΣ'}, 'skata.html')) HEAD = { "epon": "ΔΟΚΙΜΗ ΕΠΕ", "afm": "123123123", "apo": "1/2019", "eos": "3/2019" } # data = {301: 100, 303: 1500, 361: 1500, 381: 360, 401: 100, 364: 100, } DATA = { 361: dec(95156.97), 303: dec(101119.21), 306: dec(28529.25), 364: dec(1825.68), 349: dec(39527.90), } f2_render(HEAD, DATA)
def kartella(self, account, apo=None, eos=None): """ Μας δίνει την καρτέλλα του λογαριασμού id ημερομηνία παραστατικό περιγραφή χρεωση πίστωση υπόλοιπο ------------------------------------------------------------- από μεταφορά 100.34 30.88 20.33 12 10/1/2020 ΤΔΑ322 αγορες 10.35 """ dapo = apo if apo else "1900-01-01" deos = eos if eos else "3000-12-31" if dapo > deos: deos = dapo tdelta = dec(0) prin = { "id": "", "dat": "", "acc": "", "par": "Aπό μεταφορά", "per": "", "debit": dec(0), "credit": dec(0), "delta": dec(0), } per = [] meta = { "id": "", "dat": "", "acc": "", "par": "Επόμενες εγγραφές", "per": "", "debit": dec(0), "credit": dec(0), "delta": dec(0), } per_debit = per_credit = 0 for trn in self.transactions: for lin in trn["lines"]: debit = lin["value"] if lin["typ"] == 1 else 0 credit = lin["value"] if lin["typ"] == 2 else 0 if lin["account"].startswith(account): if trn["date"] < dapo: prin["debit"] += debit prin["credit"] += credit tdelta += debit - credit prin["delta"] = tdelta elif dapo <= trn["date"] <= deos: per_debit += debit per_credit += credit tdelta += debit - credit adi = { "id": trn["id"], "dat": trn["date"], "acc": lin["account"], "par": trn["parno"][:20], "per": trn["perigrafi"][:45], "debit": dec2gr(debit), "credit": dec2gr(credit), "delta": dec2gr(tdelta), } per.append(adi) else: meta["debit"] += debit meta["credit"] += credit tdelta += debit - credit meta["delta"] = tdelta if prin["delta"] == 0: dprin = [] else: prin["debit"] = dec2gr(prin["debit"]) prin["credit"] = dec2gr(prin["credit"]) prin["delta"] = dec2gr(prin["delta"]) dprin = [prin] data = dprin + per tit = { "id": "AA", "dat": "Ημ/νία", "acc": "Λογαριασμός", "par": "Παραστατικό", "per": "Περιγραφή", "debit": "Χρέωση", "credit": "Πίστωση", "delta": "Υπόλοιπο", } fst = ("{id:<4} {dat:10} {acc:<15} {par:<20} {per:<45} " "{debit:>12} {credit:>12} {delta:>12}\n") st1 = f"\nΚαρτέλλα λογαριασμού {account}\n" if apo: st1 += f"Aπό: {date_iso2gr(dapo)}\n" if eos: st1 += f"Έως: {date_iso2gr(deos)}\n" st1 += fst.format(**tit) st1 += "-" * 137 + "\n" for line in data: st1 += fst.format(**line) synola_periodoy = { "id": "", "dat": "", "acc": "", "par": "Σύνολα περιόδου", "per": "", "debit": dec2gr(per_debit), "credit": dec2gr(per_credit), "delta": dec2gr(0), } st1 += fst.format(**synola_periodoy) if meta["delta"] != 0: meta["debit"] = dec2gr(meta["debit"]) meta["credit"] = dec2gr(meta["credit"]) meta["delta"] = dec2gr(meta["delta"]) st1 += fst.format(**meta) return st1
def myf_xml(self, exclude=None, only=None, koybas=(), rfpa=(), action="replace"): """ Συγκεντρωτικές τιμολογίων πελατών/προμηθευτών σε xml """ data = { "action": action, "co": { "afm": self.afm, "month": "12", "year": self.year, "branch": self.branch, }, "gcash": [], "oexpenses": {}, } dat = "2020-12-31" di1 = {} di2 = {} di6 = {} di7 = {} cre = "credit" nor = "normal" tam = {"tamNo": "", "amount": 0, "tax": 0, "date": dat} reversed_afm = set() for trn in self.ee_book(): # first we filter records if only: if not startswith_any(trn["accounts"], only): continue if exclude: if startswith_any(tuple(trn["accounts"]), exclude): continue afm = trn["afm"] if trn["typos"] == "1": pass elif trn["typos"] in "26": # Εάν έχουμε λογαριασμούς χωρίς έκπτωση φπα, επειδή οι # εγγραφές είναι συνολικές θα πρέπει πρωτού προχωρήσουμε # να αποφορολογήσουμε if any(i in rfpa for i in trn["accounts"]): if trn["fpa"] == 0: val = dec(trn["value"] / dec(1.24)) trn["fpa"] = trn["value"] - val trn["value"] = val reversed_afm.add(afm) # Προμηθευτές σε κουβά (πχ ΔΕΗ) if afm in koybas: data["oexpenses"]["amount"] = data["oexpenses"].get( "amount", 0) data["oexpenses"]["amount"] += trn["value"] data["oexpenses"]["tax"] = data["oexpenses"].get("tax", 0) data["oexpenses"]["tax"] += trn["fpa"] data["oexpenses"]["date"] = data["oexpenses"].get( "date", dat) continue if len(afm) < 9: raise ValueError(f"There is an error in {trn}") # Διαφορετικά κανονικά ανά ΑΦΜ/normal-credit di6[afm] = di6.get(afm, {}) if trn["value"] >= 0: di6[afm][nor] = di6[afm].get( nor, { "afm": afm, "amount": 0, "tax": 0, "note": nor, "invoices": 0, "date": dat, "nonObl": 0, }, ) di6[afm][nor]["amount"] += trn["value"] di6[afm][nor]["tax"] += trn["fpa"] di6[afm][nor]["invoices"] += 1 else: di6[afm][cre] = di6[afm].get( cre, { "afm": afm, "amount": 0, "tax": 0, "note": cre, "invoices": 0, "date": dat, "nonObl": 0, }, ) di6[afm][cre]["amount"] -= trn["value"] di6[afm][cre]["tax"] -= trn["fpa"] di6[afm][cre]["invoices"] += 1 elif trn["typos"] == "7": if afm == "": tam["amount"] += trn["value"] tam["tax"] += trn["fpa"] else: di7[afm] = di7.get(afm, {}) if trn["value"] >= 0: di7[afm][nor] = di7[afm].get( nor, { "afm": afm, "amount": 0, "tax": 0, "note": nor, "invoices": 0, "date": dat, }, ) di7[afm][nor]["amount"] += trn["value"] di7[afm][nor]["tax"] += trn["fpa"] di7[afm][nor]["invoices"] += 1 else: di7[afm][cre] = di7[afm].get( cre, { "afm": afm, "amount": 0, "tax": 0, "note": cre, "invoices": 0, "date": dat, }, ) di7[afm][cre]["amount"] -= trn["value"] di7[afm][cre]["tax"] -= trn["fpa"] di7[afm][cre]["invoices"] += 1 else: raise ValueError("Αδύνατη περίπτωση !!!") logger.info(f"Λογαριασμοί που εξαιρούνται σπό τη ΜΥΦ: {exclude}") logger.info(f"ΜΥΦ μόνο για λογαριασμούς: {only}") logger.info(f"ΑΦΜ για κουβά εξόδων: {koybas}") logger.info(f"Λογαριασμοί για αντιστροφή ΦΠΑ: {rfpa}") logger.info(f"ΑΦΜ που έγινε αντιστροφή ΦΠΑ: {reversed_afm}") # Έχουμε πλέον τα σύνολα ανα ομάδα gexpenses = [] for afm, decre in sorted(di2.items()): for _, val in decre.items(): val["amount"] = dec2grp(val["amount"]) val["tax"] = dec2grp(val["tax"]) gexpenses.append(val) # ΕΛΛΗΝΙΚΟ format ΑΡΙΘΜΩΝ # Εγγραφές χωρίς έκπτωση του ΦΠΑ επαναφορά for afm, decre in sorted(di6.items()): for _, val in decre.items(): val["amount"] = dec2grp(val["amount"]) val["tax"] = dec2grp(val["tax"]) gexpenses.append(val) data["gexpenses"] = gexpenses grevenues = [] for afm, decre in sorted(di7.items()): for _, val in decre.items(): val["amount"] = dec2grp(val["amount"]) val["tax"] = dec2grp(val["tax"]) grevenues.append(val) data["grevenues"] = grevenues # Mόνο όταν υπάρχουν τιμές στο gcash if tam["amount"] != 0: tam["amount"] = dec2grp(tam["amount"]) tam["tax"] = dec2grp(tam["tax"]) data["gcash"].append(tam) # Μόνο όταν υπάρχουν τιμές στο oexpenses if data["oexpenses"]: data["oexpenses"]["amount"] = dec2grp(data["oexpenses"]["amount"]) data["oexpenses"]["tax"] = dec2grp(data["oexpenses"]["tax"]) return data