Compare commits

...

37 Commits

Author SHA1 Message Date
Ambulance Clerc
6a28aeaa16 Changement version 2022-06-15 15:44:23 +02:00
Ambulance Clerc
42f32873ea Ajout input popup 2022-06-15 15:43:46 +02:00
Ambulance Clerc
e4137d4780 Débug HRF 2022-06-15 15:31:32 +02:00
Ambulance Clerc
b10b14c420 Utilisation de adresses.txt au lieu de .csv 2022-06-15 09:10:47 +02:00
Ambulance Clerc
0a1cbd31b8 Changement visuels mineurs 2022-06-15 09:08:23 +02:00
Ambulance Clerc
dc7ace0446 Trim des nom, prénom, adresse pour les patients et débiteurs 2022-06-15 09:04:18 +02:00
Ambulance Clerc
6a46da5a89 Débug blocage sur erreur de saisi 2022-06-14 16:53:51 +02:00
Ambulance Clerc
e8d1bf7696 Finalisation système check debitor 2022-06-09 01:19:18 +02:00
Ambulance Clerc
d918e5b7aa Changement de version 2022-06-09 00:07:40 +02:00
Ambulance Clerc
d2c132bc24 Débug date de naissance 2022-06-09 00:04:08 +02:00
Ambulance Clerc
934ed40937 Changement popup check adresse 2022-06-08 23:57:16 +02:00
Ambulance Clerc
ff789f409c Changement popup check adresse 2022-06-08 23:44:11 +02:00
Ambulance Clerc
c8e1d42af0 Ajout check des codes débiteurs 2022-06-08 23:42:27 +02:00
Ambulance Clerc
b6ba37b3c9 Débug check_adresses 2022-06-06 18:32:38 +02:00
Ambulance Clerc
714f6101ff Débug check_adresses 2022-06-06 18:22:14 +02:00
Ambulance Clerc
075ab7cee7 débug affichage check_adresse (doublon AVS) 2022-06-06 17:48:22 +02:00
Ambulance Clerc
16cb31d859 new release 2022-06-06 17:42:39 +02:00
Ambulance Clerc
b3c4ab9e0b Merge remote-tracking branch 'origin/master'
# Conflicts:
#	dl_version
2022-06-06 17:39:48 +02:00
Ambulance Clerc
bb57b3edff new release 2022-06-06 17:38:37 +02:00
Ambulance Clerc
ab248478c0 débug auto-update 2022-06-06 17:38:18 +02:00
Ambulance Clerc
2a1fcd7437 débug auto-update 2022-06-06 17:35:53 +02:00
49297d23ef Mise à jour de 'dl_version' 2022-06-06 17:34:58 +02:00
Ambulance Clerc
8995d412f9 débug auto-update 2022-06-06 17:30:31 +02:00
Ambulance Clerc
b8bca94f65 débug auto-update 2022-06-06 17:29:10 +02:00
Ambulance Clerc
e3c4ee9d3e New version 2022-06-06 17:28:34 +02:00
Ambulance Clerc
80fa01633e New version 2022-06-06 17:17:02 +02:00
Ambulance Clerc
d8fea135a9 Merge check_adress 2022-06-06 17:14:55 +02:00
Ambulance Clerc
ccb2b73d51 Merge remote-tracking branch 'origin/addresses'
# Conflicts:
#	main.py
2022-06-06 17:08:07 +02:00
Ambulance Clerc
fd776244b9 Version 0.9 pre-release 2022-06-06 17:01:37 +02:00
Ambulance Clerc
393e9c844d Amélioration système auto-update 2022-06-06 13:46:06 +02:00
Ambulance Clerc
44197d446b nettoyage code source 2022-05-22 19:05:32 +02:00
Ambulance Clerc
2c1b77b65f nettoyage code source 2022-05-22 19:05:04 +02:00
Ambulance Clerc
cd3f8d3f50 Merge remote-tracking branch 'origin/master' into addresses 2022-05-22 19:03:45 +02:00
Ambulance Clerc
37486aede9 débug git 2022-05-22 18:58:56 +02:00
Ambulance Clerc
6af89ff67a débug git 2022-05-22 18:52:03 +02:00
Ambulance Clerc
852acc1749 début système check doublon addresses 2022-05-22 18:45:12 +02:00
Ambulance Clerc
fb0eebff07 Revert "débug objet des factures"
This reverts commit 04bae4f3d3.
2022-05-22 18:43:57 +02:00
7 changed files with 548 additions and 155 deletions

View File

@@ -3,8 +3,11 @@ import urllib.request
import ssl import ssl
import io import io
class auto_updater:
dl_version = 0
temp_dir = ""
def clean(str): def clean(self, str):
str = str.replace('/','') str = str.replace('/','')
str = str.replace(':', '') str = str.replace(':', '')
str = str.replace('{', '') str = str.replace('{', '')
@@ -12,19 +15,23 @@ def clean(str):
str = str.replace("\\", '') str = str.replace("\\", '')
return str return str
def new_update_available(): def new_update_available(self):
ret = False ret = False
ctx = ssl.create_default_context() ctx = ssl.create_default_context()
ctx.check_hostname = False ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE ctx.verify_mode = ssl.CERT_NONE
data = urllib.request.urlopen("https://gitea.prod.resk-u.ch/CLERC/AttribWinbiz/raw/branch/master/dl_version", context=ctx) data = urllib.request.urlopen("https://gitea.prod.resk-u.ch/CLERC/AttribWinbiz/raw/branch/master/dl_version", context=ctx)
dl_version = str(data.read()).replace('b', '').replace("'", "") self.dl_version = str(data.read()).replace('b', '').replace("'", "")
ssl._create_default_https_context = ssl._create_unverified_context ssl._create_default_https_context = ssl._create_unverified_context
if dl_version != VERSION: if self.dl_version != VERSION:
print(f"Version différente trouvée {dl_version} téléchargement en cours") print(f"Version différente trouvée {self.dl_version} téléchargement en cours => {self.temp_dir}update.exe")
urllib.request.urlretrieve(url=f"https://gitea.prod.resk-u.ch/CLERC/AttribWinbiz/releases/download/{clean(dl_version)}/Clercattrib2Biz_setup.exe", filename="update.exe") try:
urllib.request.urlretrieve(url=f"https://gitea.prod.resk-u.ch/CLERC/AttribWinbiz/releases/download/{self.clean(self.dl_version)}/Clercattrib2Biz_setup.exe", filename=f"{self.temp_dir}update.exe")
except:
print("ERREUR de téléchargement mise à jours")
return "ERROR"
ret = True ret = True
return ret return ret

146
class_debitors.py Normal file
View File

@@ -0,0 +1,146 @@
import pickle
import os
import shutil
class cls_debitors:
items = []
file_path = ""
def __init__(self, filepath=".temp"):
self.items = []
self.file_path = filepath
if not os.path.exists(self.file_path):
os.makedirs(os.path.abspath(self.file_path))
if not os.path.isfile(os.path.join(self.file_path, f"debitors.bin")):
shutil.copy("debitors_src.bin", os.path.join(self.file_path, f"debitors.bin"))
self.load_debitors()
def get_names_by_code(self, code):
for deb in self.items:
if deb.code == int(code):
return deb.names
return None
def is_in_debitor_name(self, code, search_name):
names = self.get_names_by_code(code)
if search_name in names:
return True
return False
def add_items(self, code, name):
for deb in self.items:
if deb.code == int(code):
deb.add_name(name)
return
deb = cls_debitor()
deb.code = int(code)
deb.add_name(name)
self.items.append(deb)
def save_debitors(self):
if len(self.items) > 0:
with open(os.path.join(self.file_path, f"debitors.bin"), "wb") as file:
pickle.dump(self.items, file)
def load_debitors(self):
try:
with open(os.path.join(self.file_path, f"debitors.bin"), "rb") as file:
self.items = pickle.load(file)
except:
print("Erreur lecture fichier débiteur")
class cls_debitor:
code = ""
names = []
def __init__(self):
self.code = ""
self.names = []
def add_name(self, name):
self.names.append(name)
o_debs = cls_debitors(filepath=os.getenv('APPDATA') + '\Attrib2Biz\.temp')
'''
o_deb = cls_debitor()
o_deb.code = 100
o_deb.add_name("HRC Rennaz")
o_deb.add_name("Hôpital riviera chablais Rennaz")
o_debs.items.append(o_deb)
o_deb = cls_debitor()
o_deb.code = 101
o_deb.add_name("HVS")
o_debs.items.append(o_deb)
o_debs.add_items(102,"Clinique Bernoise Montana - Secrétariat médical")
o_debs.add_items(102,"Clinique Bernoise Montana")
o_debs.add_items(100,'Hôpital Riviera-Chablais Vaud-Valais - Fournisseurs ')
o_debs.add_items(101,'Hôpital du Valais - Direction des Finances/Service des fournisseurs ')
o_debs.add_items(102,'Clinique Bernoise Montana - Secrétariat médical ')
o_debs.add_items(103,'Clinique Genevoise de Montana - Comptabilité ')
o_debs.add_items(104,'Clinique SUVA - Comptabilité ')
o_debs.add_items(105,'Fondation de Nant - Comptabilité ')
o_debs.add_items(106,"Service de l'action sociale - Office de l'asile - Administration RAValais")
o_debs.add_items(107,'OCVS - Comptabilité')
o_debs.add_items(108,'Suva Aarau - Service Center')
o_debs.add_items(109,'Suva Basel - Service Center')
o_debs.add_items(110,'Suva Bellinzona - Assicurazione militare - Service Center')
o_debs.add_items(111,'Suva Bellinzona - Service Center')
o_debs.add_items(112,'Suva Bern - Militärversicherung - Service Center')
o_debs.add_items(113,'Suva Chur - Service Center')
o_debs.add_items(114,'Suva Delémont - Service Center')
o_debs.add_items(115,'Suva Fribourg - Service Center')
o_debs.add_items(116,'Suva Genève - Assurance militaire - Service Center')
o_debs.add_items(117,'Suva Genève - Service Center')
o_debs.add_items(118,'Suva La Chaux-de-Fonds - Service Center')
o_debs.add_items(119,'Suva Lausanne - Service Center')
o_debs.add_items(120,'Suva Luzern - Service Center')
o_debs.add_items(121,'Suva Sion - Service Center')
o_debs.add_items(122,'Suva Solothurn - Service Center')
o_debs.add_items(123,'Suva St-Gallen - Militärversicherung - Service Center')
o_debs.add_items(124,'Suva Zurich - Service Center')
o_debs.add_items(125,'Antaé - Allianz Worldwide Care')
o_debs.add_items(126,'Terre des Hommes - Soins aux Enfants ')
o_debs.add_items(127,'REGA')
o_debs.add_items(128,'CNAS Assistance')
o_debs.add_items(129,'Clinique Lucernoise Montana - Comptabilité ')
o_debs.add_items(130,'AAA Alpine Air Ambulance AG')
o_debs.add_items(131,'CHUV')
o_debs.add_items(132,'Clinique CIC Collombey SA - c/o Clinique CIC Suisse SA ')
o_debs.add_items(133,'Clinique CIC Montreux SA ')
o_debs.add_items(134,'Clinique CIC Saxon SA - c/o Clinique CIC Saxon SA ')
o_debs.add_items(135,'Clinique CIC Suisse SA ')
o_debs.add_items(136,'MedSTAR - Swiss Mobile Healthcare Alliance Sàrl')
o_debs.add_items(137,'RFSM - Réseau fribourgeois de santé mentale ')
o_debs.add_items(138,'Swiss Medical Network - GSMN Suisse SA - Clinique de Genolier')
o_debs.add_items(139,'Swiss Medical Network - GSMN Suisse SA - Clinique de Montchoisi')
o_debs.add_items(140,'Swiss Medical Network - GSMN Suisse SA - Clinique Valmont')
o_debs.add_items(141,'Swiss Medical Network - Swiss Medical Network Hospitals SA - Hôpital de la Providence')
o_debs.add_items(142,'Swiss Medical Network - Swiss Medical Network Hospitals SA - Clinique Montbrillant')
o_debs.add_items(143,'Swiss Medical Network - Swiss Medical Network Hospitals SA - Clinique Générale Ste-Anne')
o_debs.add_items(144,'Swiss Medical Network - Swiss Medical Network Hospitals SA - Clinique de Valère')
o_debs.add_items(146,'Leukerbad Clinic - Comptabilité')
o_debs.add_items(147,'Hôpital psychiatrique de Belle-Idée')
o_debs.add_items(148,'Direction générale de la Santé VD')
o_debs.add_items(149,'Swiss Risk & Care')
o_debs.save_debitors()
'''

250
custom_popup.py Normal file
View File

@@ -0,0 +1,250 @@
from tkinter import *
from tkinter import font
from datetime import datetime
from tkinter import messagebox
class Check_addresses_popup(Toplevel):
x_row = 0
no_selection_possible = False
def __init__(self, parent, item_1=None, item_2=None, debitor=None, factureID=""):
super().__init__(parent)
self.geometry(f"700x300+{parent.winfo_x() + 25 }+{parent.winfo_y() +25 }")
self.resizable(True,True)
self.iconbitmap("./logo_clerc_03X_icon.ico")
self.title(f"Choix de l'adresse à conserver {item_1['fip_number']} / {factureID}. Code débiteur: {debitor['code']}")
self.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=1)
lbf_new = LabelFrame(self, text="Données Attrib")
lbf_new.grid(row=0, column=0, sticky='WE', padx=5, pady=5)
lbf_old = LabelFrame(self, text="Données Winbiz")
lbf_old.grid(row=0, column=1, sticky='NSEW', padx=5, pady=5)
str_address_1 = ""
fonts = []
self.x_row = 0
self.add_compares_element(new_frame=lbf_new,old_frame=lbf_old,label="N° AVS de l'adresse:",str1=item_1['insurance_policy_number'].replace('.',''), str2=item_2.AVS)
self.add_compares_element(new_frame=lbf_new, old_frame=lbf_old, label="Nom:", str1=item_1['lastname'], str2=item_2.lastName)
self.add_compares_element(new_frame=lbf_new, old_frame=lbf_old, label="Prénom:", str1=item_1['firstname'], str2=item_2.firstName)
self.add_compares_element(new_frame=lbf_new, old_frame=lbf_old, label="Date de naissance:", str1=datetime.strptime(item_1['birthdate'], "%Y-%m-%d").strftime("%d.%m.%Y"), str2=item_2.birth)
self.add_compares_element(new_frame=lbf_new, old_frame=lbf_old, label="Adresse:", str1=f"{item_1['street']} {item_1['street_number']}", str2=item_2.street)
self.add_compares_element(new_frame=lbf_new, old_frame=lbf_old, label="NPA/Localité:", str1=f"{item_1['postal_code']} {item_1['city']}", str2=f"{item_2.npa} {item_2.city}")
str_address_1 += item_1['insurance_policy_number'].replace('.', '')
str_address_1 += item_1['lastname'].strip()
str_address_1 += item_1['firstname'].strip()
str_address_1 += datetime.strptime(item_1['birthdate'], "%Y-%m-%d").strftime("%d.%m.%Y")
str_address_1 += f"{item_1['street']} {item_1['street_number']}"
str_address_1 += f"{item_1['postal_code']} {item_1['city']}"
str_address_2 = ""
str_address_2 += item_2.AVS
str_address_2 += item_2.lastName
str_address_2 += item_2.firstName
str_address_2 += item_2.birth
str_address_2 += f"{item_2.street.strip()}"
str_address_2 += f"{item_2.npa} {item_2.city}"
self.listbox = Listbox(self, height=3, width=35)
self.listbox.grid(row=1,column=0, columnspan= 2, pady=15,padx=15, sticky='NSEW')
self.btn = Button(self, text="Valider", command=self.select)
self.btn.grid(row=2,columnspan=2 , pady=10,padx=10, sticky='NSEW')
for (idd, info) in ((0, "Winbiz"), (1, "Attrib")) :
self.listbox.insert(END, info)
if int(debitor["code"]) >= 100:
self.listbox.delete(0,END)
self.listbox.delete(0, END)
self.listbox.insert(END, f"Aucun changement possible, code débiteur {debitor['code']}")
self.listbox.configure(state='disabled')
self.no_selection_possible = True
if int(debitor["code"]) == 1:
if str_address_1 == str_address_2:
self.listbox.selection_set(0)
print("adresse identique")
else:
self.listbox.selection_set(1)
print(f"adresse différente [{str_address_1}] ({str_address_2})")
def add_compares_element(self,new_frame, old_frame,str1, str2, label):
label_font = font.Font(weight='bold', size=9)
value_color = "black"
con = ""
if str1 != str2:
value_color = "red"
con = "*"
Label(new_frame, text=label, font=label_font).grid(row=self.x_row, column=0, sticky="W")
Label(new_frame, text=con + str1 + con, fg=value_color).grid(row=self.x_row, column=1, sticky="W")
Label(old_frame, text=label, font=label_font).grid(row=self.x_row, column=0, sticky="W")
Label(old_frame, text=con + str2 + con, fg=value_color).grid(row=self.x_row, column=1, sticky="W")
self.x_row += 1
self.selection = None
def destroy(self):
if self.selection is None:
self.selection = True
super().destroy()
def select(self):
selection = self.listbox.curselection()
if selection:
self.selection = self.listbox.get(selection[0])
self.selection = True if self.selection == "Attrib" else False
self.destroy()
if self.no_selection_possible:
self.destroy()
def show(self):
self.deiconify()
self.wm_protocol("WM_DELETE_WINDOW", self.destroy)
self.wait_window(self)
return self.selection
class Check_debitor_popup(Toplevel):
x_row = 0
no_selection_possible = False
def __init__(self, parent, debitor=None, lists_available_names=None, factureID=None,fip=None,object=None):
super().__init__(parent)
self.object = object
self.debitor = debitor
self.inp_code = StringVar()
self.inp_code.set(debitor['code'])
self.geometry(f"850x300+{parent.winfo_x() + 25 }+{parent.winfo_y() +25 }")
self.resizable(True,True)
self.iconbitmap("./logo_clerc_03X_icon.ico")
self.title(f"Incohérence sur les débiteurs {fip} / {factureID}. Code débiteur: {debitor['code']}")
self.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=1)
lbf_new = LabelFrame(self, text="Données Attrib")
lbf_new.grid(row=0, column=0, sticky='WE', padx=5, pady=5)
label_font = font.Font(weight='bold', size=9)
Label(lbf_new, text="Code saisi", font=label_font).grid(row=0, column=0, sticky="W")
Entry(lbf_new, textvariable=self.inp_code, width= 10).grid(row=0, column=1, sticky="W", pady= 10)
Label(lbf_new, text="Débiteur sélectionné", font=label_font).grid(row=1, column=0, sticky="W")
text_name = Text(lbf_new, fg="red", height=3,width= 30)
text_name.grid(row=1, column=1, sticky="W")
text_name.insert(END,debitor['name'])
text_name.configure(state='disabled')
lbf_old = LabelFrame(self, text="Nom possible")
lbf_old.grid(row=0, column=1, sticky='NSEW', padx=5, pady=5)
self.listbox = Text(lbf_old, height=5, width=50)
self.listbox.grid(row=1,column=0, columnspan= 2, pady=15,padx=15, sticky='NSEW')
for info in lists_available_names :
self.listbox.insert(END, f"{info}\n")
self.listbox.configure(state='disabled')
self.no_selection_possible = True
self.btn = Button(lbf_old, text="Ajouter", command=self.add)
self.btn.grid(row=2, column=0, columnspan= 2, pady=10, padx=10, sticky='NSEW')
self.btn = Button(self, text="Valider", command=self.destroy)
self.btn.grid(row=2,column=0, columnspan= 2, pady=10,padx=10, sticky='NSEW')
def add(self):
self.destroy()
if self.object is not None:
self.object.add_items(code=self.inp_code.get(), name=self.debitor["name"])
self.object.save_debitors()
def destroy(self):
super().destroy()
def show(self):
self.deiconify()
self.wm_protocol("WM_DELETE_WINDOW", self.destroy)
self.wait_window(self)
print("nouveau code = "+ self.inp_code.get())
return self.inp_code.get()
class Input_popup(Toplevel):
x_row = 0
no_selection_possible = False
def __init__(self, parent, text="Veuillez saisir la nouvelle valeur.", default="" ,factureID=None, fip=None, object=None):
super().__init__(parent)
self.object = object
self.inp_value = StringVar()
if default is not None:
self.inp_value.set(default)
self.geometry(f"650x120+{parent.winfo_x() + 25}+{parent.winfo_y() + 25}")
self.resizable(True, True)
self.iconbitmap("./logo_clerc_03X_icon.ico")
self.title(f"Saisir une valeur {fip} / {factureID}.")
self.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=1)
lbf_new = LabelFrame(self, text=text)
lbf_new.grid(row=0, column=0, sticky='WE', padx=5, pady=5)
label_font = font.Font(weight='bold', size=9)
Label(lbf_new, text="", font=label_font).grid(row=0, column=0, sticky="W")
Entry(lbf_new, textvariable=self.inp_value, width=100).grid(row=0, column=1, sticky="W", pady=10)
self.btn = Button(self, text="Valider", command=self.destroy)
self.btn.grid(row=2, column=0, pady=10, padx=10, sticky='NSEW')
def add(self):
self.destroy()
if self.object is not None:
self.object.add_items(code=self.inp_code.get(), name=self.debitor["name"])
self.object.save_debitors()
def destroy(self):
if self.inp_value.get() is None or self.inp_value.get() == "":
messagebox.showerror(title="ERREUR", message="Veuillez saisir une valeur !")
self.focus()
else:
super().destroy()
def show(self):
self.deiconify()
self.wm_protocol("WM_DELETE_WINDOW", self.destroy)
self.wait_window(self)
print("nouvelle valeur = " + self.inp_value.get())
return self.inp_value.get()

BIN
debitors_src.bin Normal file

Binary file not shown.

View File

@@ -1 +1 @@
20220606-1330 20220615-1544

246
main.py
View File

@@ -12,6 +12,7 @@ from datetime import datetime
import tkinter.filedialog import tkinter.filedialog
from tkinter import * from tkinter import *
from tkinter import font
from tkinter import messagebox from tkinter import messagebox
from tkinter.ttk import Progressbar from tkinter.ttk import Progressbar
from tkinter.scrolledtext import ScrolledText from tkinter.scrolledtext import ScrolledText
@@ -20,12 +21,15 @@ from threading import *
from class_invoices import * from class_invoices import *
from class_addresses import * from class_addresses import *
from auto_update import * from auto_update import *
from class_debitors import *
from version import * from version import *
#test master 2 from custom_popup import *
src_dir = os.getenv('APPDATA') + "\Attrib2Biz\src" src_dir = os.getenv('APPDATA') + "\Attrib2Biz\src"
dest_dir = os.getenv('APPDATA') + "\Attrib2Biz\output" dest_dir = os.getenv('APPDATA') + "\Attrib2Biz\output"
temp_dir = os.getenv('APPDATA') + '\Attrib2Biz\.temp'
file_path ="" #os.path.dirname(__file__) file_path ="" #os.path.dirname(__file__)
Elements = [] Elements = []
@@ -39,57 +43,9 @@ if not os.path.exists(src_dir):
if not os.path.exists(dest_dir): if not os.path.exists(dest_dir):
os.makedirs(dest_dir) os.makedirs(dest_dir)
if not os.path.exists(temp_dir):
os.makedirs(temp_dir)
class SuggestionPopup(Toplevel):
def __init__(self, parent, item_1=None, item_2=None):
super().__init__(parent)
self.geometry("400x475")
self.resizable(True,True)
self.iconbitmap("./logo_clerc_03X_icon.ico")
self.title("Choix de l'adresse à conserver 1")
self.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=1)
lbf_new = LabelFrame(self, text="Nouveau patient")
lbf_new.grid(row=0, column=0, sticky='WE', padx=5, pady=5)
Label(lbf_new, text=f"N° AVS de l'adresse \t {item_1['insurance_policy_number'].replace('.','')}").grid(row=0, column=0)
lbf_old = LabelFrame(self, text="Ancien patient")
lbf_old.grid(row=0, column=1, sticky='NSEW', padx=5, pady=5)
Label(lbf_old, text=f"N° AVS de l'adresse \t {item_2.AVS}").grid(row=0, column=0)
self.listbox = Listbox(self, height=10, width=20)
self.listbox.grid(row=1,column=0, columnspan= 2, pady=15)
self.btn = Button(self, text="Confirm selection", command=self.select)
self.btn.grid(row=2, pady=10)
for (idd, info) in ((0, "Ancienne"), (1, "Nouvelle")) :
self.listbox.insert(END, info)
self.selection = None
def destroy(self):
if self.selection is None:
self.selection = 0
super().destroy()
def select(self):
selection = self.listbox.curselection()
if selection:
self.selection = self.listbox.get(selection[0])
self.destroy()
def show(self):
self.deiconify()
self.wm_protocol("WM_DELETE_WINDOW", self.destroy)
self.wait_window(self)
return self.selection
class TextHandler(logging.Handler): class TextHandler(logging.Handler):
@@ -130,18 +86,23 @@ class ClercAttrib2Biz():
self.prompt = None self.prompt = None
self.b_prompt_open = False self.b_prompt_open = False
self.check_addresses = BooleanVar(self.fenetre)
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.run_excel_after_export = BooleanVar(self.fenetre)
self.check_addresses.set(True)
self.export_one_file.set(True) self.export_one_file.set(True)
self.run_excel_after_export.set(False) self.run_excel_after_export.set(False)
self.export_format_biz.set(True) self.export_format_biz.set(True)
self.draw_mainWindows() self.draw_mainWindows()
self.refresh_ui() self.refresh_ui()
#self.read_addresses() self.read_addresses()
self.o_debs = cls_debitors(filepath=temp_dir)
self.timer = self.fenetre.after(1000, self.main_timer_fn) self.timer = self.fenetre.after(1000, self.main_timer_fn)
@@ -152,6 +113,9 @@ class ClercAttrib2Biz():
def main_timer_fn(self): def main_timer_fn(self):
print("Pass tick timer main app") print("Pass tick timer main app")
self.timer = self.fenetre.after(5000, self.main_timer_fn) self.timer = self.fenetre.after(5000, self.main_timer_fn)
@@ -238,11 +202,12 @@ class ClercAttrib2Biz():
lbf_3 = LabelFrame(self.fenetre, text="Options") lbf_3 = LabelFrame(self.fenetre, text="Options")
lbf_3.grid(row=0, column=1, rowspan=2, sticky='NSEW', padx=5, pady=5) lbf_3.grid(row=0, column=1, rowspan=2, sticky='NSEW', padx=5, pady=5)
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="Vérifier les Adresses", variable=self.check_addresses, 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, command=self.refresh_ui).grid(row=1, sticky='W') Checkbutton(lbf_3, text="Supprimer fichiers après conversion", variable= self.delete_after_parse, 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, command=self.refresh_ui).grid(row=2, sticky='W') Checkbutton(lbf_3, text="Export au format .biz", variable= self.export_format_biz, onvalue=True, offvalue=False, command=self.refresh_ui).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=3, 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 = 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.cb_run.grid(row=4, sticky='W')
@@ -252,63 +217,21 @@ class ClercAttrib2Biz():
self.thread = Thread(target=self.start_parsing) self.thread = Thread(target=self.start_parsing)
if new_update_available(): auto_update = auto_updater()
auto_update.temp_dir = temp_dir + '\\'
update_available = auto_update.new_update_available()
if update_available == True:
self.logger.warning(f"Nouvelle version du script disponible. {auto_update.dl_version}")
if messagebox.askyesno(title="Nouvelle version trouvée", message=f"Une nouvelle version a été trouvée, vous pouvez l'installer dès maintenant !", ): if messagebox.askyesno(title="Nouvelle version trouvée", message=f"Une nouvelle version a été trouvée, vous pouvez l'installer dès maintenant !", ):
subprocess.call("update.exe") subprocess.call(temp_dir + "\\update.exe")
self.fenetre.destroy() self.fenetre.destroy()
elif update_available == "ERROR":
messagebox.showerror(title="ERREUR téléchargement", message="Erreur lors du téléchargement de la nouvelle mise à jour")
def draw_addressesWindows(self):
# Init de la fenêtre addresses prompt
self.fenetre.iconbitmap("./logo_clerc_03X_icon.ico")
self.fenetre.title("Clerc Attrib2Biz v" + str(VERSION))
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)
def disable_prompt(self): def disable_prompt(self):
self.prompt.destroy() self.prompt.destroy()
self.b_prompt_open = False self.b_prompt_open = False
def draw_test(self, item_1=None, item_2=None):
return None
self.b_prompt_open = True
self.prompt = Toplevel()
self.prompt.geometry("400x275")
self.prompt.iconbitmap("./logo_clerc_03X_icon.ico")
self.prompt.title("Choix de l'adresse à conserver ")
self.prompt.protocol("WM_DELETE_WINDOW", self.disable_prompt)
self.prompt.columnconfigure(0, weight=1)
self.prompt.columnconfigure(1, weight=1)
lbf_new = LabelFrame(self.prompt, text="Nouveau patient")
lbf_new.grid(row=0,column=0,sticky='WE', padx=5, pady=5)
Label(lbf_new, text=f"N° AVS de l'adresse").grid(row=0,column=0)
lbf_old = LabelFrame(self.prompt, text="Ancien patient")
lbf_old.grid(row=0, column=1, sticky='NSEW', padx=5, pady=5)
Label(lbf_old, text=f"N° AVS de l'adresse").grid(row=0, column=0)
'''a = StringVar()
Label(root, text='enter something').pack()
Entry(root, textvariable=a).pack()
Button(root, text='Ok', command=lambda: self.DoSomethingWithInput(a.get, root)).pack()'''
def DoSomethingWithInput(self,var,root):
print("var")
root.destroy()
def refresh_ui(self): def refresh_ui(self):
print("pass refresh UI") print("pass refresh UI")
if self.export_one_file.get() and not self.export_format_biz.get(): if self.export_one_file.get() and not self.export_format_biz.get():
@@ -322,7 +245,7 @@ class ClercAttrib2Biz():
def read_addresses(self): def read_addresses(self):
file_addresses_path = os.path.join(dest_dir, f"adresses.csv") file_addresses_path = os.path.join(dest_dir, f"adresses.txt")
if os.path.exists(file_addresses_path): if os.path.exists(file_addresses_path):
file = open(file_addresses_path) file = open(file_addresses_path)
csvreader = csv.reader(file, delimiter=';') csvreader = csv.reader(file, delimiter=';')
@@ -334,17 +257,17 @@ class ClercAttrib2Biz():
o_addresse.lastName = row[9] o_addresse.lastName = row[9]
o_addresse.firstName = row[10] o_addresse.firstName = row[10]
o_addresse.birth = row[38] o_addresse.birth = row[38]
o_addresse.street = row[11] o_addresse.street = row[12]
o_addresse.npa = row[13] o_addresse.npa = row[13]
o_addresse.city = row[15] o_addresse.city = row[15]
self.addresses.add_addresse(o_addresse) self.addresses.add_addresse(o_addresse)
print(self.addresses.items)
file.close() file.close()
else: else:
messagebox.showwarning(title="Impossible d'ouvrir le fichier d'adresse existantes", message=f"Le fichier {file_addresses_path} est introuvable. Aucune vérification des adresses possible") messagebox.showwarning(title="Impossible d'ouvrir le fichier d'adresse existantes", message=f"Le fichier {file_addresses_path} est introuvable. Aucune vérification des adresses possible")
#messagebox.showerror(title="Erreur fichier déjà ouvert", message=f"Le fichier {self.export_filename} est déjà ouvert. Veuillez le fermer et recommencer")
def start_parsing(self): def start_parsing(self):
@@ -399,6 +322,37 @@ class ClercAttrib2Biz():
return ret return ret
return value.strip() return value.strip()
def trim_all_data(self, data):
if data.Patient["lastname"] is not None:
data.Patient["lastname"] = data.Patient["lastname"].strip()
if data.Patient["firstname"] is not None:
data.Patient["firstname"] = data.Patient["firstname"].strip()
if data.Patient["street"] is not None:
data.Patient["street"] = data.Patient["street"].strip()
if data.Debtor["lastname"] is not None:
data.Debtor["lastname"] = data.Debtor["lastname"].strip()
if data.Debtor["firstname"] is not None:
data.Debtor["firstname"] = data.Debtor["firstname"].strip()
if data.Debtor["street"] is not None:
data.Debtor["street"] = data.Debtor["street"].strip()
def check_code_validity(self, code,data):
ret = True
check_patients = ["firstname", "lastname", "street"]
check_Debtor = ["firstname", "lastname", "street"]
if code == 1:
for check in check_patients:
if data.Patient[check] is None:
ret = False
for check in check_Debtor:
if data.Debtor[check] is None:
ret = False
if not ret:
messagebox.showerror(title="Erreur Critique", message=f"Les informations de la factures [{data.data['id']}] comportes trop d'erreur arrêt du processus ")
return False
return ret
def parseFile(self, data, filename): def parseFile(self, data, filename):
self.index_counter += 1 self.index_counter += 1
@@ -416,20 +370,25 @@ class ClercAttrib2Biz():
x = 70 x = 70
for ele in data["invoices"]: for ele in data["invoices"]:
b_address_update = True
data = cls_Invoice() data = cls_Invoice()
data.parse_item(ele) data.parse_item(ele)
self.trim_all_data(data)
print(f"Code débiteur => {data.data['id']}: {data.Debtor['code']}") print(f"Code débiteur => {data.data['id']}: {data.Debtor['code']}")
if data.Debtor["code"] is None or '.' in str(data.Debtor["code"]): if data.Debtor["code"] is None or '.' in str(data.Debtor["code"]):
print("ERROR code débiteur") print("ERROR code débiteur #1")
messagebox.showerror(title="Erreur code débiteur erroné", message=f"Le code débiteur de la facture {data.data['id']} est faux: [{data.Debtor['code']}], merci de le corriger ") messagebox.showerror(title="Erreur code débiteur", message=f"Le code débiteur de la facture {data.data['id']} est faux: [{data.Debtor['code']}], merci de le corriger ")
if data.Debtor["code"] is None: inp_popup = Input_popup(self.fenetre, default=data.Debtor["code"], factureID=data.data['id'], fip=data.Patient['fip_number'])
data.Debtor["code"] = 1 data.Debtor["code"] = int(inp_popup.show())
else:
data.Debtor["code"] = str(data.Debtor["code"]).replace('.', '')
if data.Debtor["code"] != "1" and data.Debtor["code"] != None and int(data.Debtor["code"]) < 100: if data.Debtor["code"] == 1:
if not self.check_code_validity(data.Debtor["code"],data):
return False
if int(data.Debtor["code"]) != "1" and data.Debtor["code"] != None and int(data.Debtor["code"]) < 100:
if data.Patient["fip_number"] not in self.a_listings["to_check"]: if data.Patient["fip_number"] not in self.a_listings["to_check"]:
self.a_listings["to_check"].append(data.Patient["fip_number"]) 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']}") self.logger.warning(f"Vérifier facture N°: {data.data['id']} / {data.Patient['fip_number']} {data.Debtor['code']} {data.Debtor['lastname']} {data.Debtor['firstname']}")
@@ -453,11 +412,19 @@ class ClercAttrib2Biz():
self.logger.warn(f"Débiteur établissement facture N°: {data.data['id']} / {data.Patient['fip_number']} {data.Debtor['name']}") 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"]: if int(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"]) self.a_listings["to_check"].append(data.Patient["fip_number"])
print(data.Patient["complement"]) print(data.Patient["complement"])
self.logger.warning(f"Débiteur différents: facture N°: {data.data['id']} / {data.Patient['fip_number']}") self.logger.warning(f"Débiteur différents: facture N°: {data.data['id']} / {data.Patient['fip_number']}")
if int(data.Debtor["code"]) >= 100:
if not self.o_debs.is_in_debitor_name(code=data.Debtor["code"],search_name=data.Debtor["name"]):
#messagebox.showerror(title="Erreur code débiteur erroné", message=f"Information débiteur incohérente: facture N°: {data.data['id']} / {data.Patient['fip_number']}.\nCode débiteur: {data.Debtor['code']}\nNom du débiteur: {data.Debtor['name']}. \nAurait dû être: {self.o_debs.get_names_by_code(data.Debtor['code'])}")
debitor_popup = Check_debitor_popup(self.fenetre,data.Debtor,self.o_debs.get_names_by_code(data.Debtor['code']),data.data['id'],data.Patient['fip_number'], object=self.o_debs)
data.Debtor["code"] = int(debitor_popup.show())
if data.Patient["complement"] != None: if data.Patient["complement"] != None:
self.a_listings["to_check"].append(data.Patient["fip_number"]) self.a_listings["to_check"].append(data.Patient["fip_number"])
print(data.Patient["complement"]) print(data.Patient["complement"])
@@ -467,12 +434,15 @@ class ClercAttrib2Biz():
if data.Patient['insurance_policy_number'] == None: if data.Patient['insurance_policy_number'] == None:
data.Patient['insurance_policy_number'] = f"{uuid.uuid4()}"[:15] data.Patient['insurance_policy_number'] = f"{uuid.uuid4()}"[:15]
if self.check_addresses.get():
addresses_exist = self.addresses.get_item_by_AVS(data.Patient['insurance_policy_number'].replace(".", "")) addresses_exist = self.addresses.get_item_by_AVS(data.Patient['insurance_policy_number'].replace(".", ""))
if addresses_exist is not None: if addresses_exist is not None:
pass popup = Check_addresses_popup(self.fenetre, item_1=data.Patient, item_2=addresses_exist, debitor=data.Debtor, factureID=data.data['id'])
#popup = SuggestionPopup(self.fenetre, item_1=data.Patient, item_2=addresses_exist) b_address_update = popup.show()
#result = popup.show() print(f"Result Popup: {b_address_update}")
#print(f"Result Popup: {result}") else:
b_address_update = True
#self.draw_test(item_1=data.Patient, item_2=addresses_exist) #self.draw_test(item_1=data.Patient, item_2=addresses_exist)
#messagebox.showerror(title="AVS Trouvé", message=f"Le code AVS de l'adresse {data.Patient['insurance_policy_number']} est déjà existant: [{data.Debtor['code']}], merci de le corriger ") #messagebox.showerror(title="AVS Trouvé", message=f"Le code AVS de l'adresse {data.Patient['insurance_policy_number']} est déjà existant: [{data.Debtor['code']}], merci de le corriger ")
@@ -494,6 +464,11 @@ class ClercAttrib2Biz():
self.bs_counter += 1 self.bs_counter += 1
csv_col = cls_Col(True) csv_col = cls_Col(True)
print(article)
if "code" in article.keys() and article["code"] == "HRF":
break
##Donnée globales ##Donnée globales
csv_col.data[0] = data.data["id"] # N° document csv_col.data[0] = data.data["id"] # N° document
csv_col.data[1] = 20 # Type of document 20 = facture débiteur csv_col.data[1] = 20 # Type of document 20 = facture débiteur
@@ -530,7 +505,7 @@ class ClercAttrib2Biz():
con = ", " con = ", "
concat_str += con + self.ifNotNull(data.Intervention["site_postal_code"]) + " " + self.ifNotNull(data.Intervention["site_city"]) concat_str += con + self.ifNotNull(data.Intervention["site_postal_code"]) + " " + self.ifNotNull(data.Intervention["site_city"])
csv_col.data[18] = concat_str # Adresse PEC csv_col.data[18] = concat_str # Adresse PEC
print(f'debug id:{data.data["id"]} code: {data.Debtor["code"]}') print(f'debug FIP:{data.Patient["fip_number"]} id:{data.data["id"]} code: {data.Debtor["code"]}')
if int(data.Debtor["code"]) < 100: if int(data.Debtor["code"]) < 100:
csv_col.data[19] = data.Patient['insurance_policy_number'].replace(".","") csv_col.data[19] = data.Patient['insurance_policy_number'].replace(".","")
csv_col.data[22] = data.Patient["lastname"] csv_col.data[22] = data.Patient["lastname"]
@@ -545,14 +520,24 @@ class ClercAttrib2Biz():
csv_col.data[41] = "Monsieur" if data.Patient["gender"] == "Masculin" else "Madame" csv_col.data[41] = "Monsieur" if data.Patient["gender"] == "Masculin" else "Madame"
csv_col.data[44] = csv_col.data[41] csv_col.data[44] = csv_col.data[41]
csv_col.data[46] = 0 # Maj adresse #csv_col.data[46] = 0 # Maj adresse
if b_address_update:
csv_col.data[46] = 0 # Maj adresse ajoute ou met à jour l'adresse
print("mise à jour de l'adresse")
else:
csv_col.data[46] = 1 # Maj adresse, ajoute, mais ne met pas à jour l'adresse si elle existe
print("NON mise à jour de l'adresse")
if int(data.Debtor["code"]) > 1: if int(data.Debtor["code"]) > 1:
con = "" con = ""
concat_str = "" concat_str = ""
if "name" in data.Debtor.keys(): if "name" in data.Debtor.keys():
if data.Debtor["name"] is not None:
concat_str += con + data.Debtor["name"] concat_str += con + data.Debtor["name"]
con = "#chr(13)##chr(10)#" con = "#chr(13)##chr(10)#"
else:
messagebox.showerror(title="Erreur nom débiteur", message=f"Le nom débiteur de la facture {data.data['id']} est faux: [{data.Debtor['name']}], merci de le corriger ")
if data.Debtor["gender"] is not None: if data.Debtor["gender"] is not None:
concat_str += con + "Monsieur" if data.Debtor["gender"] == "Masculin" else con + "Madame" concat_str += con + "Monsieur" if data.Debtor["gender"] == "Masculin" else con + "Madame"
@@ -584,14 +569,18 @@ class ClercAttrib2Biz():
if data.Debtor["country_name"] != "Suisse": if data.Debtor["country_name"] != "Suisse":
csv_col.data[29] = data.Debtor["country_name"] csv_col.data[29] = data.Debtor["country_name"]
csv_col.data[46] =1 # Maj adresse csv_col.data[46] =1 # Maj adresse, ajoute, mais ne met pas à jour l'adresse si elle existe
if "name" in data.Debtor.keys(): if "name" in data.Debtor.keys():
csv_col.data[21] = self.ifNotNull(data.Debtor["name"]) csv_col.data[21] = self.ifNotNull(data.Debtor["name"])
else: else:
csv_col.data[21] = '' csv_col.data[21] = ''
csv_col.data[40] = data.Patient["birthdate"] if data.Patient["birthdate"] is not None:
csv_col.data[40] = datetime.strptime(data.Patient["birthdate"], "%Y-%m-%d").strftime("%d.%m.%Y")
else:
csv_col.data[40] = ""
messagebox.showerror(title="Erreur date de naissance", message=f"La date de naissance de la facture {data.data['id']} est faux: [{data.Patient['birthdate']}], merci de le corriger ")
csv_col.data[48] = 0 csv_col.data[48] = 0
@@ -708,8 +697,9 @@ class ClercAttrib2Biz():
print(f"Code débiteur => {data.data['id']}: {data.Debtor['code']}" ) print(f"Code débiteur => {data.data['id']}: {data.Debtor['code']}" )
if data.Debtor["code"] == "None" or '.' in str(data.Debtor["code"]): if data.Debtor["code"] == "None" or '.' in str(data.Debtor["code"]):
print("ERROR code débiteur") print("ERROR code débiteur")
messagebox.showerror(title="Erreur code débiteur erroné", message=f"Le code débiteur de la facture {data.data['id']} est faux: [{data.Debtor['code']}], merci de le corriger ") messagebox.showerror(title="Erreur code débiteur", message=f"Le code débiteur de la facture {data.data['id']} est faux: [{data.Debtor['code']}], merci de le corriger ")
data.Debtor["code"] = str(data.Debtor["code"]).replace('.', '') inp_popup = Input_popup(self.fenetre,default=data.Debtor["code"],factureID=data.data['id'], fip=data.Patient['fip_number'])
data.Debtor["code"] = str(inp_popup.show())
if data.Debtor["code"] != "1" and data.Debtor["code"] != None and int(data.Debtor["code"]) < 100: if data.Debtor["code"] != "1" and data.Debtor["code"] != None and int(data.Debtor["code"]) < 100:

View File

@@ -1 +1 @@
VERSION = "20220606-1330" VERSION = "20220615-1544"