Intial commit
This commit is contained in:
commit
ad9623f215
|
|
@ -0,0 +1,10 @@
|
||||||
|
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/27.0.9 Chrome/134.0.6998.205 Electron/35.4.0 Safari/537.36" version="27.0.9">
|
||||||
|
<diagram name="Page-1" id="ye6wzyZs03NBqkSZrfCj">
|
||||||
|
<mxGraphModel dx="1426" dy="861" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="157" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0" />
|
||||||
|
<mxCell id="1" parent="0" />
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
.venv/
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
Etabli;0;1000
|
||||||
|
Animation;0;1500
|
||||||
|
Atelier;0;1000
|
||||||
|
Cotisations;0;4000
|
||||||
|
Dons;0;1000
|
||||||
|
Quincaillerie;0;300
|
||||||
|
Evenement;0;1000
|
||||||
|
Location;0;1500
|
||||||
|
Subvention;0;5000
|
||||||
|
Services;1250;0
|
||||||
|
Outillages;1500;0
|
||||||
|
Fourniture animations;300;0
|
||||||
|
Entretien local;2000;0
|
||||||
|
Loyer;10500;0
|
||||||
|
Assurances;250;0
|
||||||
|
Fourniture évenement;500;0
|
||||||
|
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 44 KiB |
|
|
@ -0,0 +1,4 @@
|
||||||
|
[path]
|
||||||
|
wp-config=wp-config.php
|
||||||
|
budget=budget.csv
|
||||||
|
save_directory=.
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/27.0.9 Chrome/134.0.6998.205 Electron/35.4.0 Safari/537.36" version="27.0.9">
|
||||||
|
<diagram name="Page-1" id="ye6wzyZs03NBqkSZrfCj">
|
||||||
|
<mxGraphModel dx="1426" dy="861" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="157" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0" />
|
||||||
|
<mxCell id="1" parent="0" />
|
||||||
|
<mxCell id="Tv65sSvnq-8v8yjLEzWo-4" value="main" style="shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;recursiveResize=0;container=1;collapsible=0;width=160;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="270" y="104" width="340" height="760" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="Tv65sSvnq-8v8yjLEzWo-1" value="" style="ellipse;fillColor=strokeColor;html=1;" vertex="1" parent="Tv65sSvnq-8v8yjLEzWo-4">
|
||||||
|
<mxGeometry x="149" y="90" width="30" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="Tv65sSvnq-8v8yjLEzWo-5" value="importer budget en csv" style="html=1;align=center;verticalAlign=top;rounded=1;absoluteArcSize=1;arcSize=10;dashed=0;whiteSpace=wrap;" vertex="1" parent="Tv65sSvnq-8v8yjLEzWo-4">
|
||||||
|
<mxGeometry x="100" y="146" width="140" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="Tv65sSvnq-8v8yjLEzWo-6" value="Creer sankey diagram du budget" style="html=1;align=center;verticalAlign=top;rounded=1;absoluteArcSize=1;arcSize=10;dashed=0;whiteSpace=wrap;" vertex="1" parent="Tv65sSvnq-8v8yjLEzWo-4">
|
||||||
|
<mxGeometry x="100" y="246" width="140" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="Tv65sSvnq-8v8yjLEzWo-3" value="" style="ellipse;html=1;shape=endState;fillColor=strokeColor;" vertex="1" parent="Tv65sSvnq-8v8yjLEzWo-4">
|
||||||
|
<mxGeometry x="149" y="480" width="30" height="30" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="Tv65sSvnq-8v8yjLEzWo-7" value="Creer sankey diagram des opérations" style="html=1;align=center;verticalAlign=top;rounded=1;absoluteArcSize=1;arcSize=10;dashed=0;whiteSpace=wrap;" vertex="1" parent="Tv65sSvnq-8v8yjLEzWo-4">
|
||||||
|
<mxGeometry x="94" y="406" width="140" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="Tv65sSvnq-8v8yjLEzWo-8" value="importer ventes et achat depuisbdd dolibarr" style="html=1;align=center;verticalAlign=top;rounded=1;absoluteArcSize=1;arcSize=10;dashed=0;whiteSpace=wrap;" vertex="1" parent="Tv65sSvnq-8v8yjLEzWo-4">
|
||||||
|
<mxGeometry x="94" y="316" width="140" height="40" as="geometry" />
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,2 @@
|
||||||
|
from typing import TypedDict
|
||||||
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
def connect_db():
|
||||||
|
|
||||||
|
return test
|
||||||
|
|
||||||
|
|
||||||
|
def request_db():
|
||||||
|
|
||||||
|
return array
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
from sankeyflow import Sankey
|
||||||
|
import matplotlib as mpt
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,238 @@
|
||||||
|
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
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import re
|
||||||
|
import datetime
|
||||||
|
import mariadb
|
||||||
|
import sys
|
||||||
|
node_central = 'total'
|
||||||
|
|
||||||
|
class BudgetLine():
|
||||||
|
|
||||||
|
def __init__(self, desc:str, charge:int, revenue:int):
|
||||||
|
self.desc = desc
|
||||||
|
self.charge = charge
|
||||||
|
self.revenue = revenue
|
||||||
|
|
||||||
|
class DBInfos():
|
||||||
|
name:str
|
||||||
|
user:str
|
||||||
|
password:str
|
||||||
|
host:str
|
||||||
|
port:int
|
||||||
|
|
||||||
|
|
||||||
|
class Account():
|
||||||
|
def __init__(self, label:str, number:int, tmp:int):
|
||||||
|
self.label = label
|
||||||
|
self.number = number
|
||||||
|
self.type = tmp
|
||||||
|
|
||||||
|
def main(path_b:str,
|
||||||
|
path_wp:str,
|
||||||
|
save_dir:str):
|
||||||
|
budget=import_csv(path_b)
|
||||||
|
create_budget_sankey(budget,save_dir)
|
||||||
|
db_infos = get_db_infos(path_wp)
|
||||||
|
cursor = connect_mariadb(db_infos)
|
||||||
|
|
||||||
|
|
||||||
|
#connection à la db
|
||||||
|
# Lister les comptes qui m'intéressent
|
||||||
|
|
||||||
|
# Pour chaque compte 7 puis 6 :
|
||||||
|
# - calculer somme entre le 1 er janvier et ajd
|
||||||
|
# - ajouter valeur dans flow et nodes
|
||||||
|
|
||||||
|
|
||||||
|
def create_accounting_sankey(cursor, save_dir):
|
||||||
|
nodes = 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'}))
|
||||||
|
|
||||||
|
# lister les comptes de charges et produit
|
||||||
|
accounts = get_income_and_expense_accounts(cursor)
|
||||||
|
for a in accounts:
|
||||||
|
tot_deb, tot_cred = get_sum_of_operations(
|
||||||
|
cursor,
|
||||||
|
first_day,
|
||||||
|
a
|
||||||
|
)
|
||||||
|
|
||||||
|
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'"
|
||||||
|
)
|
||||||
|
accounts = []
|
||||||
|
for account_number, label in cursor:
|
||||||
|
tmp = str(account_number)[0]
|
||||||
|
if tmp == '6' or tmp == '7':
|
||||||
|
accounts.append(Account(label, account_number, int(tmp)))
|
||||||
|
|
||||||
|
[print(f'account {a.number} / {a.label}') for a in accounts]
|
||||||
|
return accounts
|
||||||
|
|
||||||
|
|
||||||
|
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 = ?",
|
||||||
|
(5121, 5311, date, 'AN',)
|
||||||
|
)
|
||||||
|
for debit, label_compte in cursor:
|
||||||
|
print(f'ajout de : {debit} provenant du compte {label_compte} au total')
|
||||||
|
total += debit
|
||||||
|
print(f'total = {total}')
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
)
|
||||||
|
except mariadb.Error as e:
|
||||||
|
print(f"Error connecting to MariaDB Platform: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Get Cursor
|
||||||
|
return conn.cursor()
|
||||||
|
|
||||||
|
|
||||||
|
def import_csv(csv:str):
|
||||||
|
with open(csv, "r") as file:
|
||||||
|
content = file.read()
|
||||||
|
values = []
|
||||||
|
for line in content.split('\n'):
|
||||||
|
tmp = line.split(';')
|
||||||
|
values.append(
|
||||||
|
BudgetLine(
|
||||||
|
desc=tmp[0],
|
||||||
|
charge=int(tmp[1]),
|
||||||
|
revenue=int(tmp[2])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
def extract_value(content:str, param:str):
|
||||||
|
tmp = re.search(rf'define...{param}.+', content)
|
||||||
|
print('test')
|
||||||
|
if tmp is not None:
|
||||||
|
return tmp.group().split(',')[1].split('\'')[1]
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def get_sum_of_operations(cursor, date:str, account:Account):
|
||||||
|
tot_cred = tot_deb = 0
|
||||||
|
cursor.execute(
|
||||||
|
"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 :
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
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.user = extract_value(content, 'DB_USER')
|
||||||
|
db_infos.password = extract_value(content, 'DB_PASSWORD')
|
||||||
|
db_infos.host = extract_value(content, 'DB_HOST')
|
||||||
|
db_infos.port = 3306
|
||||||
|
return db_infos
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_budget_elements(budget:list[BudgetLine]):
|
||||||
|
nodes = []
|
||||||
|
flows=[]
|
||||||
|
total = 0
|
||||||
|
CL = []
|
||||||
|
RL = []
|
||||||
|
for line in budget:
|
||||||
|
charge = line.charge
|
||||||
|
desc = line.desc
|
||||||
|
revenue = line.revenue
|
||||||
|
if charge != 0 and revenue == 0:
|
||||||
|
total += charge
|
||||||
|
CL.append((desc, charge, {'label_pos':'right'}))
|
||||||
|
flows.append(('Total', desc, charge))
|
||||||
|
|
||||||
|
elif charge == 0 and revenue != 0:
|
||||||
|
RL.append((desc, revenue, {'label_pos':'left'}))
|
||||||
|
flows.append((desc, 'Total', revenue))
|
||||||
|
|
||||||
|
nodes = [
|
||||||
|
RL,
|
||||||
|
[('Total', total)],
|
||||||
|
CL
|
||||||
|
]
|
||||||
|
|
||||||
|
return nodes, flows
|
||||||
|
|
||||||
|
|
||||||
|
def create_budget_sankey(
|
||||||
|
budget:list[BudgetLine],
|
||||||
|
save:str):
|
||||||
|
|
||||||
|
nodes, flows = get_budget_elements(budget)
|
||||||
|
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, 'budget.svg')
|
||||||
|
plt.savefig(path)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
conf = cp.ConfigParser()
|
||||||
|
conf.read('config')
|
||||||
|
|
||||||
|
path_b = conf['path']['budget']
|
||||||
|
path_wp_config = conf['path']['wp-config']
|
||||||
|
path_save = conf['path']['save_directory']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if os.path.exists(path_b) and os.path.exists(path_wp_config):
|
||||||
|
print("les 2 fichiers budget et wp-config ont été trouvé")
|
||||||
|
main(path_b, path_wp_config, path_save)
|
||||||
|
else :
|
||||||
|
if not os.path.exists(path_b) :
|
||||||
|
msg = "le chemin indiqué pour le paramètre budget dans le fichier config est incorrect. Le document a été supprimé ou déplacer. Merci de préciser un autre chemin"
|
||||||
|
print(msg)
|
||||||
|
print(f'budget = {path_b}')
|
||||||
|
if not os.path.exists(path_wp_config) :
|
||||||
|
msg = "le chemin indiqué pour le paramètre wp-config dans le fichier config est incorrect. Le document a été supprimé ou déplacer. Merci de préciser un autre chemin"
|
||||||
|
print(msg)
|
||||||
|
print(f'wp-config = {path_wp_config}')
|
||||||
|
|
||||||
|
respo = input('Appuyer sur entrée pour terminer')
|
||||||
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The base configuration for WordPress
|
||||||
|
*
|
||||||
|
* The wp-config.php creation script uses this file during the installation.
|
||||||
|
* You don't have to use the web site, you can copy this file to "wp-config.php"
|
||||||
|
* and fill in the values.
|
||||||
|
*
|
||||||
|
* This file contains the following configurations:
|
||||||
|
*
|
||||||
|
* * Database settings
|
||||||
|
* * Secret keys
|
||||||
|
* * Database table prefix
|
||||||
|
* * ABSPATH
|
||||||
|
*
|
||||||
|
* @link https://wordpress.org/documentation/article/editing-wp-config-php/
|
||||||
|
*
|
||||||
|
* @package WordPress
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ** Database settings - You can get this info from your web host ** //
|
||||||
|
/** The name of the database for WordPress */
|
||||||
|
define( 'DB_NAME', 'wp_bsc_prod' );
|
||||||
|
|
||||||
|
/** Database username */
|
||||||
|
define( 'DB_USER', 'bsc' );
|
||||||
|
|
||||||
|
/** Database password */
|
||||||
|
define( 'DB_PASSWORD', 'lebsccestcool' );
|
||||||
|
|
||||||
|
/** Database hostname */
|
||||||
|
define( 'DB_HOST', 'localhost' );
|
||||||
|
|
||||||
|
/** Database charset to use in creating database tables. */
|
||||||
|
define( 'DB_CHARSET', 'utf8mb4' );
|
||||||
|
|
||||||
|
/** The database collate type. Don't change this if in doubt. */
|
||||||
|
define( 'DB_COLLATE', '' );
|
||||||
|
define( 'WP_HOME', 'https://bricolesocialclub.org' );
|
||||||
|
define( 'WP_SITEURL', 'https://bricolesocialclub.org' );
|
||||||
|
|
||||||
|
/**#@+
|
||||||
|
* Authentication unique keys and salts.
|
||||||
|
*
|
||||||
|
* Change these to different unique phrases! You can generate these using
|
||||||
|
* the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
|
||||||
|
*
|
||||||
|
* You can change these at any point in time to invalidate all existing cookies.
|
||||||
|
* This will force all users to have to log in again.
|
||||||
|
*
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
define( 'AUTH_KEY', 'ps(y yMrDd~p3|+{1oY0[)~NdCs)UL:~*:Uu|0G~Jm_OsR0e.=o~5+t5*F4SfY;s' );
|
||||||
|
define( 'SECURE_AUTH_KEY', 'm !9i eFCTK^k>fiPe,dnFuMb =Edb@F1#(nhKR*tOG8C5Jf!-:`l<2wPA&zjq4Q' );
|
||||||
|
define( 'LOGGED_IN_KEY', 'rK`: X~U e%;Us(v6m3?U0[R_^7bWW%uH f%e] hm-m`,}J{pl&x8ZHAn_eEWv<:' );
|
||||||
|
define( 'NONCE_KEY', 'x&zI;Mv1uQnLsyfof2KD$Ju:IU$z.whW&2:Of{X%}nKvbFT~iKNw;kT.NLy5OIb$' );
|
||||||
|
define( 'AUTH_SALT', '$%lxK?!bXFCEi5bz{@(aUD ^Tu/x1%:6mTjk/:R8im%_WIN{rG3sFaoeSQ{naWZ(' );
|
||||||
|
define( 'SECURE_AUTH_SALT', 's+j_oKuz^A-)f/c(R _)hg^C$<Lh5kHd[2aDSXCXHZE_]?ugbtfR==8vqKhy-}UA' );
|
||||||
|
define( 'LOGGED_IN_SALT', 'cgZ$jBskAt:=W:(p>$!f2;?oo@Z)5AngdCD.e#$gGO4*)BIG#/N}^{4.2 ]j0o_N' );
|
||||||
|
define( 'NONCE_SALT', '3w!TulB~HmA26D{/Kb>Ai]>5K~z%,Sa&O*Usx-z$SKGP@(Lmu+i]8DrK, n;X?t;' );
|
||||||
|
|
||||||
|
/**#@-*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WordPress database table prefix.
|
||||||
|
*
|
||||||
|
* You can have multiple installations in one database if you give each
|
||||||
|
* a unique prefix. Only numbers, letters, and underscores please!
|
||||||
|
*/
|
||||||
|
$table_prefix = 'bsc';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For developers: WordPress debugging mode.
|
||||||
|
*
|
||||||
|
* Change this to true to enable the display of notices during development.
|
||||||
|
* It is strongly recommended that plugin and theme developers use WP_DEBUG
|
||||||
|
* in their development environments.
|
||||||
|
*
|
||||||
|
* For information on other constants that can be used for debugging,
|
||||||
|
* visit the documentation.
|
||||||
|
*
|
||||||
|
* @link https://wordpress.org/documentation/article/debugging-in-wordpress/
|
||||||
|
*/
|
||||||
|
define( 'WP_DEBUG', false );
|
||||||
|
|
||||||
|
/* Add any custom values between this line and the "stop editing" line. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* That's all, stop editing! Happy publishing. */
|
||||||
|
|
||||||
|
/** Absolute path to the WordPress directory. */
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
define( 'ABSPATH', __DIR__ . '/' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets up WordPress vars and included files. */
|
||||||
|
require_once ABSPATH . 'wp-settings.php';
|
||||||
Loading…
Reference in New Issue