Version pré-prod

This commit is contained in:
Ambulance Clerc
2022-03-04 19:19:23 +01:00
parent 5573370e8c
commit c298602685
4 changed files with 320 additions and 16 deletions

View File

@@ -1,4 +1,4 @@
py -m pip install -r requirements.txt
py main.py
pause
#pause

BIN
convert.xlsm Normal file

Binary file not shown.

334
main.py
View File

@@ -1,17 +1,22 @@
import csv
import json
import os
import logging
import shutil
import time
import tkinter
from datetime import datetime
import tkinter.filedialog
from tkinter import *
from tkinter import messagebox
from tkinter.ttk import Progressbar
from tkinter.scrolledtext import ScrolledText
from threading import *
from class_invoices import *
VERSION = 1.1
VERSION = "20220304-1546"
@@ -19,6 +24,173 @@ src_dir = os.getenv('APPDATA') + "\Attrib2Biz\src"
dest_dir = os.getenv('APPDATA') + "\Attrib2Biz\output"
file_path ="" #os.path.dirname(__file__)
code_debiteur = [
{
"ID": 100,
"NAME": "Hôpital Riviera-Chablais Vaud-Valais - Fournisseurs "
},
{
"ID": 101,
"NAME": "Hôpital du Valais - Direction des Finances/Service des fournisseurs "
},
{
"ID": 102,
"NAME": "Clinique Bernoise Montana - Secrétariat médical "
},
{
"ID": 103,
"NAME": "Clinique Genevoise de Montana - Comptabilité "
},
{
"ID": 104,
"NAME": "Clinique SUVA - Comptabilité "
},
{
"ID": 105,
"NAME": "Fondation de Nant - Comptabilité "
},
{
"ID": 106,
"NAME": "Service de l'action sociale - Office de l'asile - Administration RAValais"
},
{
"ID": 107,
"NAME": "OCVS - Comptabilité"
},
{
"ID": 108,
"NAME": "Suva Aarau - Service Center"
},
{
"ID": 109,
"NAME": "Suva Basel - Service Center"
},
{
"ID": 110,
"NAME": "Suva Bellinzona - Assicurazione militare - Service Center"
},
{
"ID": 111,
"NAME": "Suva Bellinzona - Service Center"
},
{
"ID": 112,
"NAME": "Suva Bern - Militärversicherung - Service Center"
},
{
"ID": 113,
"NAME": "Suva Chur - Service Center"
},
{
"ID": 114,
"NAME": "Suva Delémont - Service Center"
},
{
"ID": 115,
"NAME": "Suva Fribourg - Service Center"
},
{
"ID": 116,
"NAME": "Suva Genčve - Assurance militaire - Service Center"
},
{
"ID": 117,
"NAME": "Suva Genčve - Service Center"
},
{
"ID": 118,
"NAME": "Suva La Chaux-de-Fonds - Service Center"
},
{
"ID": 119,
"NAME": "Suva Lausanne - Service Center"
},
{
"ID": 120,
"NAME": "Suva Luzern - Service Center"
},
{
"ID": 121,
"NAME": "Suva Sion - Service Center"
},
{
"ID": 122,
"NAME": "Suva Solothurn - Service Center"
},
{
"ID": 123,
"NAME": "Suva St-Gallen - Militärversicherung - Service Center"
},
{
"ID": 124,
"NAME": "Suva Zurich - Service Center"
},
{
"ID": 125,
"NAME": "Antaé - Allianz Worldwide Care"
},
{
"ID": 126,
"NAME": "Terre des Hommes - Soins aux Enfants "
},
{
"ID": 127,
"NAME": "Schweizerische Rettungsflugwacht (Rega) - Medizinischoperationnelle Dienstleistungszentrale"
},
{
"ID": 128,
"NAME": "Clinique Valmont - Comptabilité "
},
{
"ID": 129,
"NAME": "Clinique Lucernoise Montana - Comptabilité "
},
{
"ID": 130,
"NAME": "AAA Alpine Air Ambulance AG"
},
{
"ID": 131,
"NAME": "CHUV - coordination transferts de patients - ŕ l'att. de Monsieur Meylan - BH8, porte 104"
},
{
"ID": 132,
"NAME": "Clinique CIC Collombey SA - c/o Clinique CIC Suisse SA "
},
{
"ID": 133,
"NAME": "Clinique CIC Montreux SA "
},
{
"ID": 134,
"NAME": "Clinique CIC Saxon SA - c/o Clinique CIC Saxon SA "
},
{
"ID": 135,
"NAME": "Clinique CIC Suisse SA "
},
{
"ID": 136,
"NAME": "MedSTAR - Swiss Mobile Healthcare Alliance Sŕrl"
},
{
"ID": 137,
"NAME": "RFSM - Réseau fribourgeois de santé mentale "
}
]
def get_debitor_code(str):
for obj in code_debiteur:
try:
if obj["NAME"] in str:
#print(f"pass code débiteur {str}")
return obj["ID"]
except:
print("error code_debiteur")
return 5
Elements = []
export_csv = "";
con_csv = "";
@@ -31,17 +203,45 @@ if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
class TextHandler(logging.Handler):
"""This class allows you to log to a Tkinter Text or ScrolledText widget"""
def __init__(self, text):
# run the regular Handler __init__
logging.Handler.__init__(self)
# Store a reference to the Text it will log to
self.text = text
def emit(self, record):
msg = self.format(record)
print("pass 1 " + msg)
def append():
self.text.configure(state='normal')
self.text.insert(tkinter.END, msg + '\n')
self.text.configure(state='disabled')
# Autoscroll to the bottom
self.text.yview(tkinter.END)
# This is necessary because we can't modify the Text from other threads
self.text.after(0, append)
class ClercAttrib2Biz():
def __init__(self):
self.count_facture = 0
self.a_index = {"invoice": [], "intervention": [], "patient": [], "debtor": [], "articles": [], "global": []}
self.index_counter = 0
self.a_listings = {}
self.fenetre = Tk()
self.delete_after_parse = BooleanVar(self.fenetre)
self.export_format_biz = BooleanVar(self.fenetre)
self.export_one_file = BooleanVar(self.fenetre)
self.run_excel_after_export = BooleanVar(self.fenetre)
self.export_one_file.set(True)
self.run_excel_after_export.set(True)
self.draw_mainWindows()
@@ -65,11 +265,12 @@ class ClercAttrib2Biz():
self.fenetre.iconbitmap("./logo_clerc_03X_icon.ico")
self.fenetre.title("Clerc Attrib2Biz v" + str(VERSION))
self.fenetre.resizable(True, False)
self.fenetre.geometry("700x250")
self.fenetre.resizable(True, True)
self.fenetre.geometry("700x475")
self.fenetre.columnconfigure(0, weight=3)
self.fenetre.columnconfigure(1, weight=1)
self.fenetre.rowconfigure(3,weight=1)
@@ -114,7 +315,23 @@ class ClercAttrib2Biz():
self.txt_progress.columnconfigure(0,weight=1)
self.progress_bar = Progressbar(self.txt_progress, orient=HORIZONTAL, mode='determinate')
self.progress_bar.grid( sticky='WE')
self.progress_bar.grid(sticky='WE')
self.frame_logs = LabelFrame(self.fenetre, text="Log")
self.frame_logs.grid(row=3, column=0, sticky='WENS', columnspan=2, padx=5, pady=5)
self.frame_logs.columnconfigure(0, weight=1)
self.frame_logs.rowconfigure(0, weight=1)
st = ScrolledText( self.frame_logs, state='disabled', height=10)
st.grid(row=0, column=0, sticky="WENS", pady=5)
text_handler = TextHandler(st)
self.logger = logging.getLogger()
self.logger.addHandler(text_handler)
lbf_3 = LabelFrame(self.fenetre, text="Options")
@@ -122,7 +339,11 @@ class ClercAttrib2Biz():
Checkbutton(lbf_3, text="Supprimer fichiers après conversion", variable= self.delete_after_parse, onvalue=True, offvalue=False).grid(row=0, sticky='W')
Checkbutton(lbf_3, text="Export au format .biz", variable= self.export_format_biz, onvalue=True, offvalue=False).grid(row=1, sticky='W')
Checkbutton(lbf_3, text="Export en 1 seul fichier", variable= self.export_one_file, onvalue=True, offvalue=False, state="disabled").grid(row=2, sticky='W')
Checkbutton(lbf_3, text="Export en 1 seul fichier", variable= self.export_one_file, onvalue=True, offvalue=False, command=self.refresh_ui).grid(row=2, sticky='W')
self.cb_run = Checkbutton(lbf_3, text="Lancer la conversion excel", variable=self.run_excel_after_export, onvalue=True, offvalue=False)
self.cb_run.grid(row=3, sticky='W')
self.var_file_count = StringVar(self.fenetre)
@@ -130,6 +351,13 @@ class ClercAttrib2Biz():
self.thread = Thread(target=self.start_parsing)
def refresh_ui(self):
print("pass refresh UI")
if self.export_one_file.get():
self.cb_run['state'] = "active"
else:
self.cb_run['state'] = "disabled"
self.run_excel_after_export.set(False)
@@ -138,6 +366,11 @@ class ClercAttrib2Biz():
dir = src_dir
self.count_facture = 0
x = 0
if self.export_one_file.get() and os.path.exists(os.path.join(dest_dir, f"src.csv")):
os.remove(os.path.join(dest_dir, f"src.csv"))
for filename in os.listdir(dir):
x += 1
if ".json" in filename:
@@ -155,6 +388,9 @@ class ClercAttrib2Biz():
self.fenetre.update_idletasks()
self.nb_facture_var.set(self.count_facture)
if self.run_excel_after_export.get():
self.open_export_file()
def parseFile(self, data, filename):
@@ -267,6 +503,7 @@ class ClercAttrib2Biz():
def convertFile(self, data, filename):
self.count_facture += len(data["invoices"])
self.a_listings["to_check"] = []
@@ -276,14 +513,58 @@ class ClercAttrib2Biz():
data = cls_Invoice()
data.parse_item(ele)
b_update_debitor = True
print()
if data.Debtor["code"] != "1":
if data.Patient["fip_number"] not in self.a_listings["to_check"] :
self.a_listings["to_check"].append(data.Patient["fip_number"])
self.logger.warning(f"Vérifier facture N°: {data.data['id']} / {data.Patient['fip_number']} {data.Debtor['code']} {data.Debtor['lastname']} {data.Debtor['firstname']}")
for elem in data.Debtor:
if "name" in data.Debtor.keys():
# print(f"{data.Patient['fip_number']} => {data.Debtor['name']}")
data.data["comments"] = data.Debtor["code"] if data.Debtor["code"] != "2" else data.data["comments"]
data.Debtor["code"] = get_debitor_code(data.Debtor["name"])
break
''' TODO activer ce code quand les débiteur auront un bon numéro
try:
if int(data.Debtor["code"]) > 100:
print("code débiteur > 100 => no update data")
b_update_debitor = False
except:
messagebox.showerror(title="Erreur de code débiteur", message=f"il y a une erreur dans le code débiteur, il faut le vérifier. \n(n'est pas un chiffre) {data.Patient['fip_number']}")
exit()
'''
'''
if data.Debtor["type"] == "Établissement":
self.a_listings["to_check"].append(data.Patient["fip_number"])
print(data.Patient["complement"])
self.logger.warn(f"Débiteur établissement facture N°: {data.data['id']} / {data.Patient['fip_number']} {data.Debtor['name']}")
'''
if data.Debtor["code"] == 1 and data.Patient["lastname"] + data.Patient["firstname"] != data.Debtor["lastname"] + data.Debtor["firstname"]:
self.a_listings["to_check"].append(data.Patient["fip_number"])
print(data.Patient["complement"])
self.logger.warning(f"Débiteur différents: facture N°: {data.data['id']} / {data.Patient['fip_number']}")
if data.Patient["complement"] != None :
self.a_listings["to_check"].append(data.Patient["fip_number"])
print(data.Patient["complement"])
self.logger.warning(f"Complément patient: facture N°: {data.data['id']} / {data.Patient['fip_number']}")
b_HRF = False
sHRF = ""
for article in data.Articles:
if "code" in article.keys():
if article["code"] == "CLN.9431":
if article["code"] == "HRF":
b_HRF = True
sHRF = article["line_1"].replace("h",":")
print("pass HRF")
print(f"pass HRF => {data.Patient['fip_number']}")
break
@@ -304,20 +585,22 @@ class ClercAttrib2Biz():
for elem in data.Intervention:
if elem == "without_transportation":
whitout_transport = True
print(f"without_transportation {data.Patient['fip_number']}")
break
self.addToIndexs(obj=csv_col, data=data.Intervention[elem], cat="intervention", key=elem)
if whitout_transport:
for x in range(8):
csv_col.data.append("")
pass
#csv_col.data.append("")
self.addToIndexs(obj=csv_col, data="", cat="intervention", key=x)
self.addToIndexs(obj=csv_col, data=whitout_transport, cat="intervention", key="whitout_transport")
if b_HRF:
print("pass Change end_time on b_HRF")
print(f"pass Change end_time on b_HRF")
dt = datetime.fromisoformat(csv_col.data[self.a_index["global"].index("end_time")])
month = "0" + str(dt.month) if dt.month < 10 else dt.month
csv_col.data[self.a_index["global"].index("end_time")] = f"{dt.year}-{month}-{dt.day}T"+sHRF+":00+01:00"
@@ -329,6 +612,10 @@ class ClercAttrib2Biz():
self.addToIndexs(obj=csv_col, data=data.Patient[elem], cat="patient", key=elem)
for elem in data.Debtor:
if "name" in data.Debtor.keys():
#print(f"{data.Patient['fip_number']} => {data.Debtor['name']}")
data.Debtor["code"] = get_debitor_code(data.Debtor["name"])
if elem != "name":
csv_col.data.append(data.Debtor[elem])
if "name" in data.Debtor.keys():
@@ -341,10 +628,9 @@ class ClercAttrib2Biz():
## Données prestations
if "code" in article.keys():
if article["code"] == "CLN.9431":
pass
# csv_col = None
# break
if article["code"] == "HRF":
csv_col = None
break
else:
csv_col.data.append(article["code"])
@@ -378,12 +664,30 @@ class ClercAttrib2Biz():
else:
csv_col.data.append("")
lines.append(csv_col.data)
csv_col = None
with open(os.path.join(dest_dir, f"bizexdoc_" + filename.replace(".json", "") + ".csv"), "w+", errors='replace',newline='') as csv_file:
if not self.export_one_file.get():
with open(os.path.join(dest_dir, f"bizexdoc_" + filename.replace(".json", "") + ".csv"), "w+", errors='replace', newline='') as csv_file:
wr = csv.writer(csv_file, delimiter=';')
for cdr in lines:
wr.writerow(cdr)
else:
self.save_file(lines)
def save_file(self,lines):
with open(os.path.join(dest_dir, f"src.csv"), "a+", errors='replace',newline='') as csv_file:
wr = csv.writer(csv_file, delimiter=';')
for cdr in lines:
for cdr in lines:
wr.writerow(cdr)
def open_export_file(self):
print("RUN EXCEL with open")
os.startfile(os.path.join(dest_dir, f"src.csv"))
shutil.copy(file_path + "convert.xlsm", os.path.join(dest_dir, f"convert.xlsm"))
os.startfile(os.path.join(dest_dir, f"convert.xlsm"))
def open_src(self):
os.startfile(file_path + src_dir)

Binary file not shown.