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 -m pip install -r requirements.txt
py main.py 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 csv
import json import json
import os import os
import logging
import shutil
import time
import tkinter
from datetime import datetime from datetime import datetime
import tkinter.filedialog import tkinter.filedialog
from tkinter import * from tkinter import *
from tkinter import messagebox from tkinter import messagebox
from tkinter.ttk import Progressbar from tkinter.ttk import Progressbar
from tkinter.scrolledtext import ScrolledText
from threading import * from threading import *
from class_invoices 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" dest_dir = os.getenv('APPDATA') + "\Attrib2Biz\output"
file_path ="" #os.path.dirname(__file__) 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 = [] Elements = []
export_csv = ""; export_csv = "";
con_csv = ""; con_csv = "";
@@ -31,17 +203,45 @@ if not os.path.exists(dest_dir):
os.makedirs(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(): class ClercAttrib2Biz():
def __init__(self): def __init__(self):
self.count_facture = 0 self.count_facture = 0
self.a_index = {"invoice": [], "intervention": [], "patient": [], "debtor": [], "articles": [], "global": []} self.a_index = {"invoice": [], "intervention": [], "patient": [], "debtor": [], "articles": [], "global": []}
self.index_counter = 0 self.index_counter = 0
self.a_listings = {}
self.fenetre = Tk() self.fenetre = Tk()
self.delete_after_parse = BooleanVar(self.fenetre) self.delete_after_parse = BooleanVar(self.fenetre)
self.export_format_biz = BooleanVar(self.fenetre) self.export_format_biz = BooleanVar(self.fenetre)
self.export_one_file = 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() self.draw_mainWindows()
@@ -65,11 +265,12 @@ class ClercAttrib2Biz():
self.fenetre.iconbitmap("./logo_clerc_03X_icon.ico") self.fenetre.iconbitmap("./logo_clerc_03X_icon.ico")
self.fenetre.title("Clerc Attrib2Biz v" + str(VERSION)) self.fenetre.title("Clerc Attrib2Biz v" + str(VERSION))
self.fenetre.resizable(True, False) self.fenetre.resizable(True, True)
self.fenetre.geometry("700x250") self.fenetre.geometry("700x475")
self.fenetre.columnconfigure(0, weight=3) self.fenetre.columnconfigure(0, weight=3)
self.fenetre.columnconfigure(1, weight=1) 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.txt_progress.columnconfigure(0,weight=1)
self.progress_bar = Progressbar(self.txt_progress, orient=HORIZONTAL, mode='determinate') 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") 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="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 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) self.var_file_count = StringVar(self.fenetre)
@@ -130,6 +351,13 @@ class ClercAttrib2Biz():
self.thread = Thread(target=self.start_parsing) 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 dir = src_dir
self.count_facture = 0 self.count_facture = 0
x = 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): for filename in os.listdir(dir):
x += 1 x += 1
if ".json" in filename: if ".json" in filename:
@@ -155,6 +388,9 @@ class ClercAttrib2Biz():
self.fenetre.update_idletasks() self.fenetre.update_idletasks()
self.nb_facture_var.set(self.count_facture) self.nb_facture_var.set(self.count_facture)
if self.run_excel_after_export.get():
self.open_export_file()
def parseFile(self, data, filename): def parseFile(self, data, filename):
@@ -267,6 +503,7 @@ class ClercAttrib2Biz():
def convertFile(self, data, filename): def convertFile(self, data, filename):
self.count_facture += len(data["invoices"]) self.count_facture += len(data["invoices"])
self.a_listings["to_check"] = []
@@ -276,14 +513,58 @@ class ClercAttrib2Biz():
data = cls_Invoice() data = cls_Invoice()
data.parse_item(ele) 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 b_HRF = False
sHRF = "" sHRF = ""
for article in data.Articles: for article in data.Articles:
if "code" in article.keys(): if "code" in article.keys():
if article["code"] == "CLN.9431": if article["code"] == "HRF":
b_HRF = True b_HRF = True
sHRF = article["line_1"].replace("h",":") sHRF = article["line_1"].replace("h",":")
print("pass HRF") print(f"pass HRF => {data.Patient['fip_number']}")
break break
@@ -304,20 +585,22 @@ class ClercAttrib2Biz():
for elem in data.Intervention: for elem in data.Intervention:
if elem == "without_transportation": if elem == "without_transportation":
whitout_transport = True whitout_transport = True
print(f"without_transportation {data.Patient['fip_number']}")
break break
self.addToIndexs(obj=csv_col, data=data.Intervention[elem], cat="intervention", key=elem) self.addToIndexs(obj=csv_col, data=data.Intervention[elem], cat="intervention", key=elem)
if whitout_transport: if whitout_transport:
for x in range(8): 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="", cat="intervention", key=x)
self.addToIndexs(obj=csv_col, data=whitout_transport, cat="intervention", key="whitout_transport") self.addToIndexs(obj=csv_col, data=whitout_transport, cat="intervention", key="whitout_transport")
if b_HRF: 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")]) 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 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" 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) self.addToIndexs(obj=csv_col, data=data.Patient[elem], cat="patient", key=elem)
for elem in data.Debtor: 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": if elem != "name":
csv_col.data.append(data.Debtor[elem]) csv_col.data.append(data.Debtor[elem])
if "name" in data.Debtor.keys(): if "name" in data.Debtor.keys():
@@ -341,10 +628,9 @@ class ClercAttrib2Biz():
## Données prestations ## Données prestations
if "code" in article.keys(): if "code" in article.keys():
if article["code"] == "CLN.9431": if article["code"] == "HRF":
pass csv_col = None
# csv_col = None break
# break
else: else:
csv_col.data.append(article["code"]) csv_col.data.append(article["code"])
@@ -378,12 +664,30 @@ class ClercAttrib2Biz():
else: else:
csv_col.data.append("") csv_col.data.append("")
lines.append(csv_col.data) lines.append(csv_col.data)
csv_col = None 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=';') wr = csv.writer(csv_file, delimiter=';')
for cdr in lines: for cdr in lines:
wr.writerow(cdr) 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): def open_src(self):
os.startfile(file_path + src_dir) os.startfile(file_path + src_dir)

Binary file not shown.