ajout sankey compta fonctionnel

This commit is contained in:
pb 2025-06-21 20:39:14 +02:00
parent e9a6c465a1
commit ac65921498
8 changed files with 1986 additions and 57 deletions

View File

@ -6,7 +6,7 @@
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:date>2025-06-15T14:55:20.889417</dc:date>
<dc:date>2025-06-21T20:31:55.648539</dc:date>
<dc:format>image/svg+xml</dc:format>
<dc:creator>
<cc:Agent>
@ -35,7 +35,7 @@ L 307.150694 140.046626
L 307.150694 111.6
L 288.409091 111.6
z
" clip-path="url(#pd093175b84)" style="fill: #1f77b4"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #1f77b4"/>
</g>
<g id="patch_3">
<path d="M 288.409091 187.756564
@ -43,7 +43,7 @@ L 307.150694 187.756564
L 307.150694 145.086626
L 288.409091 145.086626
z
" clip-path="url(#pd093175b84)" style="fill: #ff7f0e"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #ff7f0e"/>
</g>
<g id="patch_4">
<path d="M 288.409091 221.24319
@ -51,7 +51,7 @@ L 307.150694 221.24319
L 307.150694 192.796564
L 288.409091 192.796564
z
" clip-path="url(#pd093175b84)" style="fill: #2ca02c"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #2ca02c"/>
</g>
<g id="patch_5">
<path d="M 288.409091 340.069693
@ -59,7 +59,7 @@ L 307.150694 340.069693
L 307.150694 226.28319
L 288.409091 226.28319
z
" clip-path="url(#pd093175b84)" style="fill: #d62728"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #d62728"/>
</g>
<g id="patch_6">
<path d="M 288.409091 373.556319
@ -67,7 +67,7 @@ L 307.150694 373.556319
L 307.150694 345.109693
L 288.409091 345.109693
z
" clip-path="url(#pd093175b84)" style="fill: #9467bd"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #9467bd"/>
</g>
<g id="patch_7">
<path d="M 288.409091 387.130307
@ -75,7 +75,7 @@ L 307.150694 387.130307
L 307.150694 378.596319
L 288.409091 378.596319
z
" clip-path="url(#pd093175b84)" style="fill: #8c564b"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #8c564b"/>
</g>
<g id="patch_8">
<path d="M 288.409091 420.616933
@ -83,7 +83,7 @@ L 307.150694 420.616933
L 307.150694 392.170307
L 288.409091 392.170307
z
" clip-path="url(#pd093175b84)" style="fill: #e377c2"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #e377c2"/>
</g>
<g id="patch_9">
<path d="M 288.409091 468.326871
@ -91,7 +91,7 @@ L 307.150694 468.326871
L 307.150694 425.656933
L 288.409091 425.656933
z
" clip-path="url(#pd093175b84)" style="fill: #7f7f7f"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #7f7f7f"/>
</g>
<g id="patch_10">
<path d="M 288.409091 615.6
@ -99,7 +99,7 @@ L 307.150694 615.6
L 307.150694 473.366871
L 288.409091 473.366871
z
" clip-path="url(#pd093175b84)" style="fill: #bcbd22"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #bcbd22"/>
</g>
<g id="patch_11">
<path d="M 913.129198 575.28
@ -107,7 +107,7 @@ L 931.870802 575.28
L 931.870802 111.6
L 913.129198 111.6
z
" clip-path="url(#pd093175b84)" style="fill: #17becf"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #17becf"/>
</g>
<g id="patch_12">
<path d="M 1537.849306 147.158282
@ -115,7 +115,7 @@ L 1556.590909 147.158282
L 1556.590909 111.6
L 1537.849306 111.6
z
" clip-path="url(#pd093175b84)" style="fill: #1f77b4"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #1f77b4"/>
</g>
<g id="patch_13">
<path d="M 1537.849306 196.548221
@ -123,7 +123,7 @@ L 1556.590909 196.548221
L 1556.590909 153.878282
L 1537.849306 153.878282
z
" clip-path="url(#pd093175b84)" style="fill: #ff7f0e"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #ff7f0e"/>
</g>
<g id="patch_14">
<path d="M 1537.849306 211.802209
@ -131,7 +131,7 @@ L 1556.590909 211.802209
L 1556.590909 203.268221
L 1537.849306 203.268221
z
" clip-path="url(#pd093175b84)" style="fill: #2ca02c"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #2ca02c"/>
</g>
<g id="patch_15">
<path d="M 1537.849306 275.41546
@ -139,7 +139,7 @@ L 1556.590909 275.41546
L 1556.590909 218.522209
L 1537.849306 218.522209
z
" clip-path="url(#pd093175b84)" style="fill: #d62728"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #d62728"/>
</g>
<g id="patch_16">
<path d="M 1537.849306 580.825031
@ -147,7 +147,7 @@ L 1556.590909 580.825031
L 1556.590909 282.13546
L 1537.849306 282.13546
z
" clip-path="url(#pd093175b84)" style="fill: #9467bd"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #9467bd"/>
</g>
<g id="patch_17">
<path d="M 1537.849306 594.656687
@ -155,7 +155,7 @@ L 1556.590909 594.656687
L 1556.590909 587.545031
L 1537.849306 587.545031
z
" clip-path="url(#pd093175b84)" style="fill: #8c564b"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #8c564b"/>
</g>
<g id="patch_18">
<path d="M 1537.849306 615.6
@ -163,7 +163,7 @@ L 1556.590909 615.6
L 1556.590909 601.376687
L 1537.849306 601.376687
z
" clip-path="url(#pd093175b84)" style="fill: #e377c2"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #e377c2"/>
</g>
<g id="patch_19">
<path d="M 307.150694 111.6
@ -171,7 +171,7 @@ C 488.944245 111.6 731.335647 111.6 913.129198 111.6
L 913.129198 140.046626
C 731.335647 140.046626 488.944245 140.046626 307.150694 140.046626
z
" clip-path="url(#pd093175b84)" style="fill: #17becf; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #17becf; fill-opacity: 0.6"/>
</g>
<g id="patch_20">
<path d="M 307.150694 145.086626
@ -179,7 +179,7 @@ C 488.944245 145.086626 731.335647 140.046626 913.129198 140.046626
L 913.129198 182.716564
C 731.335647 182.716564 488.944245 187.756564 307.150694 187.756564
z
" clip-path="url(#pd093175b84)" style="fill: #17becf; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #17becf; fill-opacity: 0.6"/>
</g>
<g id="patch_21">
<path d="M 307.150694 192.796564
@ -187,7 +187,7 @@ C 488.944245 192.796564 731.335647 182.716564 913.129198 182.716564
L 913.129198 211.16319
C 731.335647 211.16319 488.944245 221.24319 307.150694 221.24319
z
" clip-path="url(#pd093175b84)" style="fill: #17becf; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #17becf; fill-opacity: 0.6"/>
</g>
<g id="patch_22">
<path d="M 307.150694 226.28319
@ -195,7 +195,7 @@ C 488.944245 226.28319 731.335647 211.16319 913.129198 211.16319
L 913.129198 324.949693
C 731.335647 324.949693 488.944245 340.069693 307.150694 340.069693
z
" clip-path="url(#pd093175b84)" style="fill: #17becf; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #17becf; fill-opacity: 0.6"/>
</g>
<g id="patch_23">
<path d="M 307.150694 345.109693
@ -203,7 +203,7 @@ C 488.944245 345.109693 731.335647 324.949693 913.129198 324.949693
L 913.129198 353.396319
C 731.335647 353.396319 488.944245 373.556319 307.150694 373.556319
z
" clip-path="url(#pd093175b84)" style="fill: #17becf; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #17becf; fill-opacity: 0.6"/>
</g>
<g id="patch_24">
<path d="M 307.150694 378.596319
@ -211,7 +211,7 @@ C 488.944245 378.596319 731.335647 353.396319 913.129198 353.396319
L 913.129198 361.930307
C 731.335647 361.930307 488.944245 387.130307 307.150694 387.130307
z
" clip-path="url(#pd093175b84)" style="fill: #17becf; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #17becf; fill-opacity: 0.6"/>
</g>
<g id="patch_25">
<path d="M 307.150694 392.170307
@ -219,7 +219,7 @@ C 488.944245 392.170307 731.335647 361.930307 913.129198 361.930307
L 913.129198 390.376933
C 731.335647 390.376933 488.944245 420.616933 307.150694 420.616933
z
" clip-path="url(#pd093175b84)" style="fill: #17becf; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #17becf; fill-opacity: 0.6"/>
</g>
<g id="patch_26">
<path d="M 307.150694 425.656933
@ -227,7 +227,7 @@ C 488.944245 425.656933 731.335647 390.376933 913.129198 390.376933
L 913.129198 433.046871
C 731.335647 433.046871 488.944245 468.326871 307.150694 468.326871
z
" clip-path="url(#pd093175b84)" style="fill: #17becf; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #17becf; fill-opacity: 0.6"/>
</g>
<g id="patch_27">
<path d="M 307.150694 473.366871
@ -235,7 +235,7 @@ C 488.944245 473.366871 731.335647 433.046871 913.129198 433.046871
L 913.129198 575.28
C 731.335647 575.28 488.944245 615.6 307.150694 615.6
z
" clip-path="url(#pd093175b84)" style="fill: #17becf; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #17becf; fill-opacity: 0.6"/>
</g>
<g id="patch_28">
<path d="M 931.870802 111.6
@ -243,7 +243,7 @@ C 1113.664353 111.6 1356.055755 111.6 1537.849306 111.6
L 1537.849306 147.158282
C 1356.055755 147.158282 1113.664353 147.158282 931.870802 147.158282
z
" clip-path="url(#pd093175b84)" style="fill: #1f77b4; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #1f77b4; fill-opacity: 0.6"/>
</g>
<g id="patch_29">
<path d="M 931.870802 147.158282
@ -251,7 +251,7 @@ C 1113.664353 147.158282 1356.055755 153.878282 1537.849306 153.878282
L 1537.849306 196.548221
C 1356.055755 196.548221 1113.664353 189.828221 931.870802 189.828221
z
" clip-path="url(#pd093175b84)" style="fill: #ff7f0e; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #ff7f0e; fill-opacity: 0.6"/>
</g>
<g id="patch_30">
<path d="M 931.870802 189.828221
@ -259,7 +259,7 @@ C 1113.664353 189.828221 1356.055755 203.268221 1537.849306 203.268221
L 1537.849306 211.802209
C 1356.055755 211.802209 1113.664353 198.362209 931.870802 198.362209
z
" clip-path="url(#pd093175b84)" style="fill: #2ca02c; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #2ca02c; fill-opacity: 0.6"/>
</g>
<g id="patch_31">
<path d="M 931.870802 198.362209
@ -267,7 +267,7 @@ C 1113.664353 198.362209 1356.055755 218.522209 1537.849306 218.522209
L 1537.849306 275.41546
C 1356.055755 275.41546 1113.664353 255.25546 931.870802 255.25546
z
" clip-path="url(#pd093175b84)" style="fill: #d62728; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #d62728; fill-opacity: 0.6"/>
</g>
<g id="patch_32">
<path d="M 931.870802 255.25546
@ -275,7 +275,7 @@ C 1113.664353 255.25546 1356.055755 282.13546 1537.849306 282.13546
L 1537.849306 580.825031
C 1356.055755 580.825031 1113.664353 553.945031 931.870802 553.945031
z
" clip-path="url(#pd093175b84)" style="fill: #9467bd; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #9467bd; fill-opacity: 0.6"/>
</g>
<g id="patch_33">
<path d="M 931.870802 553.945031
@ -283,7 +283,7 @@ C 1113.664353 553.945031 1356.055755 587.545031 1537.849306 587.545031
L 1537.849306 594.656687
C 1356.055755 594.656687 1113.664353 561.056687 931.870802 561.056687
z
" clip-path="url(#pd093175b84)" style="fill: #8c564b; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #8c564b; fill-opacity: 0.6"/>
</g>
<g id="patch_34">
<path d="M 931.870802 561.056687
@ -291,7 +291,7 @@ C 1113.664353 561.056687 1356.055755 601.376687 1537.849306 601.376687
L 1537.849306 615.6
C 1356.055755 615.6 1113.664353 575.28 931.870802 575.28
z
" clip-path="url(#pd093175b84)" style="fill: #e377c2; fill-opacity: 0.6"/>
" clip-path="url(#p3a0fb5d9d6)" style="fill: #e377c2; fill-opacity: 0.6"/>
</g>
<g id="text_1">
<!-- Etabli:1000 -->
@ -1404,7 +1404,7 @@ z
</g>
</g>
<defs>
<clipPath id="pd093175b84">
<clipPath id="p3a0fb5d9d6">
<rect x="225" y="86.4" width="1395" height="554.4"/>
</clipPath>
</defs>

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

1891
compta.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -1,4 +1,2 @@
from sankeyflow import Sankey
import matplotlib as mpt

79
main.py
View File

@ -1,6 +1,6 @@
from libs import lib_mariadb as mdb
from libs import lib_csv as csv
from libs import lib_matplotlib as mtp
# from libs import lib_mariadb as mdb
# from libs import lib_csv as csv
# from libs import lib_matplotlib as mtp
import configparser as cp
import os
from sankeyflow import Sankey
@ -9,7 +9,8 @@ import re
import datetime
import mariadb
import sys
node_central = 'total'
#node_central = 'total'
class BudgetLine():
@ -18,6 +19,7 @@ class BudgetLine():
self.charge = charge
self.revenue = revenue
class DBInfos():
name:str
user:str
@ -32,6 +34,7 @@ class Account():
self.number = number
self.type = tmp
def main(path_b:str,
path_wp:str,
save_dir:str):
@ -39,6 +42,7 @@ def main(path_b:str,
create_budget_sankey(budget,save_dir)
db_infos = get_db_infos(path_wp)
cursor = connect_mariadb(db_infos)
create_accounting_sankey(cursor, save_dir)
#connection à la db
@ -50,33 +54,66 @@ def main(path_b:str,
def create_accounting_sankey(cursor, save_dir):
nodes = NR = NC =[]
NR = []
NC = []
flows = []
# extraire le compte et la caisse au 1 er janvier de l'année
year = datetime.datetime.now().year
first_day = rf'{year}-01-01'
reserves = get_bank_reserves(cursor, first_day)
NR.append(('reserves', reserves, {'label_pos':'left'}))
reserves = int(get_bank_reserves(cursor, first_day))
NR.append(('reserves au début de l\'année', reserves, {'label_pos':'left'}))
# lister les comptes de charges et produit
accounts = get_income_and_expense_accounts(cursor)
tmp_res = reserves
tot = reserves
for a in accounts:
tot_deb, tot_cred = get_sum_of_operations(
cursor,
first_day,
a
)
tmp_res = tmp_res + tot_cred - tot_deb
if a.type == 6 :
tmp_tot = tot_deb-tot_cred
if tmp_tot > 0 :
NC.append((a.label, tmp_tot, {'label_pos':'right'}))
flows.append(('Total', a.label, tmp_tot))
else :
tmp_tot = tot_cred-tot_deb
if tmp_tot > 0 :
tot += tmp_tot
NR.append((a.label, tmp_tot, {'label_pos':'left'}))
flows.append((a.label, 'Total', tmp_tot))
NC.insert(0, ('reserves aujourd\'hui', tmp_res, {'label_pos':'right'}))
nodes = [
NR,
[('Total', tot, {'label_pos':'top'})],
NC
]
plt.figure(figsize=(25, 10), dpi=144)
s = Sankey(
flows=flows,
nodes=nodes,
node_opts=dict(label_format='{label}:{value}')
)
s.draw()
path = os.path.join(save_dir, 'compta.svg')
plt.savefig(path)
plt.close()
def get_income_and_expense_accounts(cursor):
print("get_income_and_expense_accounts")
cursor.execute(
"SELECT account_number, label FROM llx_accounting_account WHERE reconcilable = 'PCG-BSC'"
"SELECT account_number, label FROM llx_accounting_account WHERE fk_pcg_version = 'PCG-BSC' AND active = 1;"
)
accounts = []
for account_number, label in cursor:
tmp = str(account_number)[0]
if tmp == '6' or tmp == '7':
tmp = account_number[0]
if (tmp == '6' or tmp == '7') and int(account_number) > 10:
accounts.append(Account(label, account_number, int(tmp)))
[print(f'account {a.number} / {a.label}') for a in accounts]
@ -87,10 +124,11 @@ def get_bank_reserves(cursor, date:str):
print('get_bank_reserves')
total = 0
cursor.execute(
"SELECT piece_num, numero_compte, label_compte, doc_date, code_journal, debit, credit FROM llx_accounting_bookkeeping WHERE (numero_compte = ? OR numero_compte = ?) AND doc_date = ? AND code_journal = ?",
"SELECT piece_num, numero_compte, label_compte, doc_date, code_journal, debit, credit FROM llx_accounting_bookkeeping WHERE (numero_compte = ? OR numero_compte = ?) AND doc_date = ? AND code_journal = ?;",
(5121, 5311, date, 'AN',)
)
for debit, label_compte in cursor:
for piece_num, numero_compte, label_compte, doc_date, code_journal, debit, credit in cursor:
#print(piece_num, numero_compte, label_compte, doc_date, code_journal, debit, credit, sep=" | ")
print(f'ajout de : {debit} provenant du compte {label_compte} au total')
total += debit
print(f'total = {total}')
@ -100,11 +138,11 @@ def get_bank_reserves(cursor, date:str):
def connect_mariadb(db_infos:DBInfos):
try:
conn = mariadb.connect(
user="db_user",
password="db_user_passwd",
host="192.0.2.1",
port=3306,
database="employees"
user=db_infos.user,
password=db_infos.password,
host=db_infos.host,
port=db_infos.port,
database=db_infos.name
)
except mariadb.Error as e:
@ -146,19 +184,19 @@ def get_sum_of_operations(cursor, date:str, account:Account):
"SELECT piece_num, numero_compte, label_compte, doc_date, code_journal, debit, credit FROM llx_accounting_bookkeeping WHERE numero_compte = ? AND doc_date >= ?",
(account.number, date)
)
for debit, credit in cursor :
for piece_num, numero_compte, label_compte, doc_date, code_journal, debit, credit in cursor :
tot_cred += credit
tot_deb += debit
print(f'pour le compte {account.number} : credit = {tot_cred} / debit = {tot_deb} à partir du {date}')
return tot_deb, tot_cred
return int(tot_deb), int(tot_cred)
def get_db_infos(path_wp:str):
with open(path_wp, "r") as file:
content = file.read()
db_infos = DBInfos()
db_infos.name = extract_value(content, 'DB_NAME')
db_infos.name = "doli_bsc"
db_infos.user = extract_value(content, 'DB_USER')
db_infos.password = extract_value(content, 'DB_PASSWORD')
db_infos.host = extract_value(content, 'DB_HOST')
@ -209,6 +247,7 @@ def create_budget_sankey(
s.draw()
path = os.path.join(save, 'budget.svg')
plt.savefig(path)
plt.close()
if __name__ == "__main__":

View File

@ -3,6 +3,7 @@ contourpy==1.3.2
cycler==0.12.1
fonttools==4.58.2
kiwisolver==1.4.8
mariadb==1.1.12
matplotlib==3.10.3
mysql-connector-python==9.3.0
numpy==2.3.0