Compare commits

...

91 Commits

Author SHA1 Message Date
Ambulance Clerc
5998bf48cb débug comparaison de l'adresse de livraison 2023-06-20 15:59:48 +02:00
Ambulance Clerc
5311208184 débug comparaison de l'adresse de livraison 2023-06-20 15:44:29 +02:00
Ambulance Clerc
86a2b99f39 débug comparaison de l'adresse de livraison 2023-06-20 15:44:04 +02:00
Ambulance Clerc
eb0e4b4429 débug comparaison de l'adresse de livraison 2023-06-20 15:02:52 +02:00
Ambulance Clerc
4387a1d00b débug comparaison de l'adresse de livraison 2023-06-20 14:53:20 +02:00
Ambulance Clerc
c722af1091 débug comparaison de l'adresse de livraison 2023-06-20 14:23:34 +02:00
Ambulance Clerc
92b3a76733 débug comparaison de l'adresse de livraison 2023-06-20 11:10:18 +02:00
Ambulance Clerc
5adbc77555 Débug de la feature adresse_livraison 2023-06-16 19:43:34 +02:00
Ambulance Clerc
1146ff01c7 Ajout de la comparaison de l'adresse de livraison 2023-06-16 17:29:35 +02:00
Ambulance Clerc
e4c075f6ef Ajout de la comparaison de l'adresse de livraison 2023-06-16 16:17:10 +02:00
Ambulance Clerc
f05a56bc5a Ajout de la comparaison de l'adresse de livraison 2023-06-16 16:16:49 +02:00
Ambulance Clerc
b19340e149 Changement de version 2023-04-26 11:14:47 +02:00
Ambulance Clerc
d313ddefac Changement du message de log, lors des comparaisons d'adresse 2023-04-26 11:14:08 +02:00
Ambulance Clerc
f3d94d330c Supression des options depreciate avec adaptation du code
Ajout de la persistance des otpions
2023-04-26 11:03:20 +02:00
Ambulance Clerc
c198410cd3 Ajout dans les log après chaque popup d'adresse 2023-04-25 16:37:06 +02:00
Ambulance Clerc
48353c6f98 Débug comparaison date 2023-04-25 14:07:43 +02:00
Ambulance Clerc
a94b2cc0d6 Changement sur la comparaison d'adresse. 2023-04-25 13:55:42 +02:00
Ambulance Clerc
9ba8998c32 Debug load config with outfile 2023-04-21 07:57:00 +02:00
Ambulance Clerc
513556f0a3 Copie automatique et lecture du fichier adresses.dbf 2023-04-21 00:32:05 +02:00
Ambulance Clerc
81a9717716 Changement sur la comparaison d'adresse. 2023-04-20 22:23:26 +02:00
Ambulance Clerc
3ff3416b39 Changement sur la comparaison d'adresse. 2023-04-20 20:44:38 +02:00
Ambulance Clerc
e430117d40 Changement de la longueur de l'HUID de 15 à 10 en raison de bug Winbiz 2023-03-01 18:56:40 +01:00
Ambulance Clerc
5060490ac4 Ajout d'un script pour compter les caractères du projet 2023-03-01 18:55:34 +01:00
Ambulance Clerc
d4e5ff6f1b nettoyage du code débiteur 2023-01-24 16:12:08 +01:00
Ambulance Clerc
894a8bbfbb nettoyage du code débiteur 2023-01-24 15:47:51 +01:00
Ambulance Clerc
4d2e2f2351 supression de "(facturation)" 2023-01-24 15:10:03 +01:00
Ambulance Clerc
6f09de76ab Divers débug sur erreur de saisi lors d'un code débiteur 3 et si code débiteur pas encore connu 2023-01-03 16:18:16 +01:00
Ambulance Clerc
eee31f3a1d Ajout d'une captation de bug si débiteur n'existe pas. 2023-01-03 15:15:11 +01:00
Ambulance Clerc
bf1533ccdb Changement de version 2022-09-07 18:10:27 +02:00
Ambulance Clerc
36ce8a2488 Strip et replace \n en "" sur le numéro opale 2022-09-07 18:05:53 +02:00
Ambulance Clerc
891a29e39b Changement de version 2022-09-07 11:17:48 +02:00
Ambulance Clerc
2f9d8c1da8 Changement de version 2022-09-07 11:12:46 +02:00
Ambulance Clerc
191821d81d Changement de version 2022-09-02 15:13:13 +02:00
Ambulance Clerc
99a89585b5 Changement de version 2022-09-02 15:09:10 +02:00
Ambulance Clerc
e60ed4b5fa Arrêt critique si la saisi du débiteur est à nouveau faux 2022-09-02 15:08:37 +02:00
Ambulance Clerc
4c75a6167b Ajout d'un focus sur l'input dans popup de saisi 2022-09-02 14:57:58 +02:00
Ambulance Clerc
842ae5fb69 Adaptation du fonctionnement de la progessbar 2022-09-02 14:39:11 +02:00
Ambulance Clerc
355d17810f Débug génération nom du fichier d'export 2022-09-02 14:13:14 +02:00
Ambulance Clerc
510587d3eb Ajout du complément d'adresse dans le check adresse 2022-08-22 17:36:03 +02:00
Ambulance Clerc
ff22572e56 Ajout du complément d'adresse dans le check adresse 2022-08-22 17:35:46 +02:00
Ambulance Clerc
54873a2715 Print all debs et ajout barre de menu 2022-08-22 11:43:15 +02:00
Ambulance Clerc
1ce77f4e08 Débug des code débiteur saisi manuellement concidéré comme int à la place de str 2022-08-20 11:35:38 +02:00
Ambulance Clerc
7be1f15c63 Débug des code débiteur saisi manuellement concidéré comme int à la place de str 2022-08-20 11:30:17 +02:00
Ambulance Clerc
cdc7205ab7 Débug version 2022-08-13 07:00:40 +02:00
Ambulance Clerc
5b0f7a1119 Ajout de la date d'intervention dans chaque ligne article => But essayer d'envoyer la date d'intervention comme date Comptable 2022-08-10 18:16:27 +02:00
Ambulance Clerc
5c7f9c1f4e Ajout du commentaire dans référence client 2022-07-29 10:19:10 +02:00
Ambulance Clerc
975595b592 Ajout du commentaire dans référence client 2022-07-29 09:51:21 +02:00
Ambulance Clerc
1907632dca Ajout du pays dans adresse livraison si pas suisse 2022-07-29 09:37:05 +02:00
Ambulance Clerc
6d9b991c04 Changement dans les colonnes code présentation et méthode de payement toujours = 3
Prise en charge des EBILL pour code 101
2022-07-15 10:12:49 +02:00
Ambulance Clerc
e35a24030d Débug des rappels avec inversion de deux champs dans l'objet de facture 2022-07-08 10:16:09 +02:00
Ambulance Clerc
1a7d649651 Débug check adress 2022-07-05 16:07:29 +02:00
Ambulance Clerc
0d499cd0f6 Inversion Street et complément (position) dans adresse livraison 2022-07-05 13:42:12 +02:00
Ambulance Clerc
94c8c64ced ajout de la collone 140 pour les conditions de payement 2022-06-30 10:13:59 +02:00
Ambulance Clerc
79f6c3df6d ajout de la collone 140 pour les conditions de payement 2022-06-30 10:13:37 +02:00
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
11 changed files with 868 additions and 451 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

View File

@@ -7,6 +7,7 @@ class cls_Addresses:
self.items.append(items) self.items.append(items)
def get_item_by_AVS(self, seek): def get_item_by_AVS(self, seek):
for item in self.items: for item in self.items:
if item.AVS == seek: if item.AVS == seek:
return item return item
@@ -18,5 +19,7 @@ class cls_addresse:
firstName = None firstName = None
birth = None birth = None
street = None street = None
street_cpl = None
npa = None npa = None
city = None city = None
addr_2 = None

156
class_debitors.py Normal file
View File

@@ -0,0 +1,156 @@
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 print_all_debs(self):
for elem in self.items:
print(f"Débiteur:{elem.code} {elem.names}")
def get_deb_by_code(self, code):
for deb in self.items:
if deb.code == int(code):
return deb
return None
def get_names_by_code(self, code):
default = []
if int(code) < 100:
return default
for deb in self.items:
if deb.code == int(code):
return deb.names
return default
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()
'''

View File

@@ -16,6 +16,57 @@ class cls_Invoice:
self.data = obj self.data = obj
self.a_index = {"invoice": [], "intervention": [], "patient": [], "debtor": [], "articles": []} self.a_index = {"invoice": [], "intervention": [], "patient": [], "debtor": [], "articles": []}
self.index_counter = 0 self.index_counter = 0
self.format_debitor_addr_2()
def format_debitor_addr_2(self):
debitor = self.Debtor
con = ""
concat_str = ""
if "name" in debitor.keys():
if debitor["name"] is not None:
concat_str += con + debitor["name"]
# con = "#chr(13)##chr(10)#"
con = "\n"
if debitor["gender"] is not None:
concat_str += con + "Monsieur" if debitor["gender"] == "Masculin" else con + "Madame"
# con = "#chr(13)##chr(10)#"
con = "\n"
if debitor["lastname"] is not None:
concat_str += con + self.ifNotNull(debitor["lastname"]) + " " + self.ifNotNull(
debitor["firstname"])
# con = "#chr(13)##chr(10)#"
con = "\n"
if debitor["complement"] is not None:
concat_str += con + debitor["complement"]
# con = "#chr(13)##chr(10)#"
con = "\n"
if debitor["street"] is not None:
concat_str += con + self.ifNotNull(debitor["street"]) + " " + self.ifNotNull(
debitor["street_number"])
# con = "#chr(13)##chr(10)#"
con = "\n"
if debitor["city"] is not None:
concat_str += con + self.ifNotNull(debitor["postal_code"]) + " " + self.ifNotNull(
debitor["city"])
# con = "#chr(13)##chr(10)#"
con = "\n"
if debitor["country_name"] != "Suisse":
concat_str += con + debitor["country_name"]
# con = "#chr(13)##chr(10)#"
con = "\n"
self.Patient["addr_2"] = concat_str
self.Patient["selfish"] = self.is_addr_2_selfish(self.Patient)
def is_addr_2_selfish(self, patient):
print(patient)
temp_addr_2 = str(patient["addr_2"]).replace("Monsieur","").replace("Madame","").replace("\n","").replace(" ","")
str_compare = self.ifNotNull(patient['lastname']).replace('.','') + self.ifNotNull(patient['firstname']).replace('.','') + self.ifNotNull(patient['complement']).strip()+ self.ifNotNull(patient['street']).strip() + self.ifNotNull(patient['street_number']).strip() + self.ifNotNull(patient['postal_code']).strip() +self.ifNotNull(patient['city']).strip()
str_compare = str_compare.replace(" ","")
print(f"is_addr_2_selfish ? {str_compare} <> {temp_addr_2} = {str_compare == temp_addr_2}")
return str_compare == temp_addr_2
def ifNotNull(self, value, ret=""):
if value == None or value == "None":
return ret
return value.strip()
class cls_Col: class cls_Col:
data = [] data = []

16
counter.py Normal file
View File

@@ -0,0 +1,16 @@
import os
def count_chars_in_folder(folder_path):
total_chars = 0
for filename in os.listdir(folder_path):
filepath = os.path.join(folder_path, filename)
if os.path.isfile(filepath):
with open(filepath, 'r') as file:
content = file.read()
total_chars += len(content)
print(f"fichier {filepath} = { len(content)}")
return total_chars
folder_path = '.' # mettre le chemin absolu vers le dossier ici
total_chars = count_chars_in_folder(folder_path)
print(f"Le nombre total de caractères dans les fichiers du dossier {folder_path} est : {total_chars}")

286
custom_popup.py Normal file
View File

@@ -0,0 +1,286 @@
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)
if(item_1["complement"] is None):
item_1["complement"] = ""
self.geometry(f"700x450+{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)
lbf_addr_2_new = LabelFrame(self, text="Livraison Attrib")
lbf_addr_2_new.grid(row=1, column=0, sticky='WE', padx=5, pady=5)
lbf_addr_2_old = LabelFrame(self, text="Livraison Winbiz")
lbf_addr_2_old.grid(row=1, 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=self.ifNotNull(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=self.ifNotNull(item_1['lastname']), str2=item_2.lastName)
self.add_compares_element(new_frame=lbf_new, old_frame=lbf_old, label="Prénom:", str1=self.ifNotNull(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(self.ifNotNull(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"{self.ifNotNull(item_1['street']).strip()} {self.ifNotNull(item_1['street_number']).strip()}", str2=item_2.street.strip())
self.add_compares_element(new_frame=lbf_new, old_frame=lbf_old, label="Complément:", str1=f"{self.ifNotNull(item_1['complement']).strip()}", str2=item_2.street_cpl.strip())
self.add_compares_element(new_frame=lbf_new, old_frame=lbf_old, label="NPA/Localité:", str1=f"{self.ifNotNull(item_1['postal_code'])} {self.ifNotNull(item_1['city'])}", str2=f"{item_2.npa} {item_2.city}")
if int(debitor["code"]) < 100:
if item_1["selfish"]:
force_color = "green"
else:
force_color = None
self.add_compares_element(new_frame=lbf_addr_2_new, old_frame=lbf_addr_2_old, label="Adresse livraison:", str1=item_1["addr_2"],
str2=self.ifNotNull(item_2.addr_2),force_color_1=force_color)
str_address_1 += self.ifNotNull(item_1['insurance_policy_number']).replace('.', '')
str_address_1 += self.ifNotNull(item_1['lastname']).strip()
str_address_1 +=self.ifNotNull( item_1['firstname']).strip()
str_address_1 += datetime.strptime(item_1['birthdate'], "%Y-%m-%d").strftime("%d.%m.%Y")
str_address_1 += f"{self.ifNotNull(item_1['street']).strip()} {self.ifNotNull(item_1['street_number']).strip()}"
str_address_1 += f"{self.ifNotNull(item_1['complement']).strip()}"
str_address_1 += f"{self.ifNotNull(item_1['postal_code'])} {self.ifNotNull(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.street_cpl.strip()}"
str_address_2 += f"{item_2.npa} {item_2.city}"
self.listbox = Listbox(self, height=3, width=35)
self.listbox.grid(row=2,column=0, columnspan= 2, pady=15,padx=15, sticky='NSEW')
self.btn = Button(self, text="Valider", command=self.select)
self.btn.grid(row=3,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 ifNotNull(self, value, ret=""):
if value == None or value == "None":
return ret
return value.strip()
def add_compares_element(self,new_frame, old_frame,str1, str2, label, force_color_1=None):
label_font = font.Font(weight='bold', size=9)
value_color_1 = "black"
value_color_2 = "black"
con = ""
if str1 != str2:
value_color_1 = "red"
value_color_2 = "red"
con = "*"
if force_color_1 is not None:
value_color_1 = force_color_1
Label(new_frame, text=str(label), font=label_font).grid(row=self.x_row, column=0, sticky="W")
Label(new_frame, text=con + str(str1) + con, fg=value_color_1, anchor="w", justify=LEFT).grid(row=self.x_row, column=1, sticky="W")
Label(old_frame, text=str(label), font=label_font).grid(row=self.x_row, column=0, sticky="W")
Label(old_frame, text=con + str(str2) + con, fg=value_color_2, anchor="w", justify=LEFT).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"900x275+{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)
Label(self,text="Une incohérence a été trouvée entre le code débiteur saisi dans Attrib et le code débiteur saisi dans Attrib. \nIls ne correspondent pas.Le code débiteur présent dans le champs Code Saisi sera utiliser pour la facture winbiz \nMerci de vérifier et modifier le code débiteur puis cliquer sur Valider.", wraplength= 950, justify=LEFT).grid(row=0,column=0, columnspan=2, sticky="W")
lbf_new = LabelFrame(self, text="Données Attrib")
lbf_new.grid(row=1, 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é dans Attrib", 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="Noms possibles")
lbf_old.grid(row=1, 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
menu_bar = Menu(self)
menu_param = Menu(menu_bar, tearoff=0)
menu_param.add_command(label="Ajouter à la liste", command=self.add)
menu_bar.add_cascade(label="Paramètre", menu=menu_param)
self.config(menu=menu_bar)
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")
input_entry = Entry(lbf_new, textvariable=self.inp_value, width=100)
input_entry.grid(row=0, column=1, sticky="W", pady=10)
input_entry.focus()
self.after(0,input_entry.focus)
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 20230620-1559

732
main.py
View File

@@ -1,4 +1,5 @@
import csv import csv
import re
import json import json
import os import os
import logging import logging
@@ -9,23 +10,29 @@ import time
import uuid import uuid
import tkinter import tkinter
from datetime import datetime from datetime import datetime
import pickle
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
from threading import * from threading import *
from dbfread import DBF
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 +46,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):
@@ -118,6 +77,7 @@ class ClercAttrib2Biz():
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.addresses = cls_Addresses() self.addresses = cls_Addresses()
self.o_debs = cls_debitors(filepath=temp_dir)
self.index_counter = 0 self.index_counter = 0
self.bs_counter = 70 self.bs_counter = 70
@@ -130,18 +90,27 @@ class ClercAttrib2Biz():
self.prompt = None self.prompt = None
self.b_prompt_open = False self.b_prompt_open = False
self.delete_after_parse = BooleanVar(self.fenetre) self.config = {}
self.export_format_biz = BooleanVar(self.fenetre)
self.export_one_file = BooleanVar(self.fenetre)
self.run_excel_after_export = BooleanVar(self.fenetre)
self.check_addresses = BooleanVar(self.fenetre)
self.delete_after_parse = BooleanVar(self.fenetre)
self.export_one_file = BooleanVar(self.fenetre)
self.winbiz_folder_path = StringVar(self.fenetre)
#Défault value for config
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.delete_after_parse.set(False)
self.export_format_biz.set(True) self.winbiz_folder_path.set(temp_dir)
self.load_config()
self.draw_mainWindows() self.draw_mainWindows()
self.refresh_ui() self.read_addresses()
#self.read_addresses()
self.timer = self.fenetre.after(1000, self.main_timer_fn) self.timer = self.fenetre.after(1000, self.main_timer_fn)
@@ -152,8 +121,40 @@ class ClercAttrib2Biz():
def save_config(self, event=None):
self.config["cfg_check_adresses"] = self.check_addresses.get()
self.config["cfg_delete_after_parse"] = self.delete_after_parse.get()
self.config["cfg_export_one_file"] = self.export_one_file.get()
self.config["winbiz_folder_path"] = self.winbiz_folder_path.get()
with open(os.path.join(temp_dir,"config.dat"),"wb") as pickle_file:
pickle.dump(self.config,pickle_file, pickle.HIGHEST_PROTOCOL)
def load_config(self):
if not os.path.exists(os.path.join(temp_dir, "config.dat")):
self.save_config()
with open(os.path.join(temp_dir, "config.dat"), "rb") as pickle_file:
self.config = pickle.load(pickle_file)
self.check_addresses.set(self.read_config_element("cfg_check_adresses", True))
self.delete_after_parse.set(self.read_config_element("cfg_delete_after_parse", False))
self.export_one_file.set(self.read_config_element("cfg_export_one_file", True))
self.winbiz_folder_path.set(self.read_config_element("winbiz_folder_path", temp_dir))
def add_statistique(self, stat_name, stat_value):
a_stats = None
if "a_stats" in self.config:
a_stats = self.config[""]
def read_config_element(self,name, default):
val = self.config.get(name)
if val is not None:
return val
else:
return default
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)
self.nb_facture_var.set(self.count_facture) self.nb_facture_var.set(self.count_facture)
@@ -238,11 +239,21 @@ 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, command=self.save_config).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, command=self.save_config).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 en 1 seul fichier", variable=self.export_one_file, 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) command=self.save_config).grid(row=3, sticky='W')
self.cb_run.grid(row=3, sticky='W') textEntry = Entry(lbf_3, textvariable=self.winbiz_folder_path, validate="focusout", validatecommand=self.save_config)
textEntry.grid(row=5, sticky="WE", columnspan=3)
textEntry.bind("<KeyRelease>", self.save_config)
menu_bar = Menu(self.fenetre)
menu_param = Menu(menu_bar, tearoff=0)
menu_param.add_command(label="Affichage des débiteurs", command=self.o_debs.print_all_debs)
menu_bar.add_cascade(label="Paramètre", menu=menu_param)
self.fenetre.config(menu=menu_bar)
@@ -252,99 +263,51 @@ 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):
print("pass refresh UI")
if self.export_one_file.get() and not self.export_format_biz.get():
self.cb_run['state'] = "active"
else:
self.cb_run['state'] = "disabled"
self.run_excel_after_export.set(False)
if self.export_format_biz.get():
self.cb_run['state'] = "disabled"
self.run_excel_after_export.set(False)
def read_addresses(self): def read_addresses(self):
file_addresses_path = os.path.join(dest_dir, f"adresses.csv") if os.path.exists(os.path.join(self.winbiz_folder_path.get(),"adresses.dbf")):
if os.path.exists(file_addresses_path): shutil.copyfile(os.path.join(self.winbiz_folder_path.get(),"adresses.dbf"), os.path.join(temp_dir,"adresses.dbf"))
file = open(file_addresses_path) shutil.copyfile(os.path.join(self.winbiz_folder_path.get(), "adresses.FPT"),os.path.join(temp_dir, "adresses.FPT"))
csvreader = csv.reader(file, delimiter=';') else:
rows = [] messagebox.showerror(title="Impossible d'ouvrir le fichier d'adresse existantes", message=f"Le fichier {self.winbiz_folder_path.get()} est introuvable. Aucune vérification des adresses possible")
for row in csvreader:
rows.append(row)
o_addresse = cls_addresse()
o_addresse.AVS = row[5]
o_addresse.lastName = row[9]
o_addresse.firstName = row[10]
o_addresse.birth = row[38]
o_addresse.street = row[11]
o_addresse.npa = row[13]
o_addresse.city = row[15]
self.addresses.add_addresse(o_addresse)
print(self.addresses.items) file_addresses_path = os.path.join(temp_dir, f"adresses.dbf")
file.close() if os.path.exists(file_addresses_path):
for record in DBF(file_addresses_path, load=True):
o_addresse = cls_addresse()
o_addresse.AVS = str(record["AD_CODE"])
o_addresse.lastName =str( record["AD_NOM"])
o_addresse.firstName = str(record["AD_PRENOM"])
if record["AD_NAISSAN"] is not None:
o_addresse.birth = datetime.strptime(str(record["AD_NAISSAN"]), "%Y-%m-%d").strftime("%d.%m.%Y")
else:
o_addresse.birth = ""
o_addresse.street =str( record["AD_RUE_2"])
o_addresse.street_cpl =str( record["AD_RUE_1"])
o_addresse.npa =str( record["AD_NPA"])
o_addresse.city = str(record["AD_VILLE"])
o_addresse.addr_2 = str(record["AD_ADR2"]).replace("\r\n","\n")
self.addresses.add_addresse(o_addresse)
logging.warning(f"Chargement du fichier adresses.dbf terminé ! {len(self.addresses.items)} adresses trouvées ")
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):
@@ -352,9 +315,8 @@ class ClercAttrib2Biz():
self.count_facture = 0 self.count_facture = 0
x = 0 x = 0
self.export_filename = f"bizexdoc_export_Attrib_v{datetime.now().year}{datetime.now().month}{datetime.now().month}{datetime.now().hour}{datetime.now().minute}.csv" self.export_filename = f"bizexdoc_export_Attrib_v{datetime.now().year}{datetime.now().month}{datetime.now().day}{datetime.now().hour}{datetime.now().minute}.csv"
if self.export_format_biz:
if self.export_one_file.get() and os.path.exists(os.path.join(dest_dir, self.export_filename)): if self.export_one_file.get() and os.path.exists(os.path.join(dest_dir, self.export_filename)):
try: try:
os.remove(os.path.join(dest_dir, self.export_filename)) os.remove(os.path.join(dest_dir, self.export_filename))
@@ -363,17 +325,9 @@ class ClercAttrib2Biz():
return return
print(f"remove {self.export_filename} => {os.path.join(dest_dir, self.export_filename)}") print(f"remove {self.export_filename} => {os.path.join(dest_dir, self.export_filename)}")
else:
if self.export_one_file.get() and os.path.exists(os.path.join(dest_dir, f"src.csv")):
try:
os.remove(os.path.join(dest_dir, f"src.csv"))
except:
messagebox.showerror(title="Erreur fichier déjà ouvert", message=f"Le fichier src.csv est déjà ouvert. Veuillez le fermer et recommencer")
return
print(f"remove src.csv => {os.path.join(dest_dir, 'src.csv')}")
self.progress_bar["value"] = 0
for filename in os.listdir(dir): for filename in os.listdir(dir):
x += 1 x += 1
if ".json" in filename: if ".json" in filename:
@@ -381,26 +335,102 @@ class ClercAttrib2Biz():
with open(dir + "/" + filename, encoding="utf-8") as f: with open(dir + "/" + filename, encoding="utf-8") as f:
data = json.load(f) data = json.load(f)
if self.export_format_biz.get(): bRet = self.parseFile(data, filename)
self.parseFile(data, filename) if bRet:
else: messagebox.showinfo(title="Fin de conversion",
self.convertFile(data, filename) message="La conversion s'est terminée avec succès")
if self.delete_after_parse.get():
os.remove(dir + "/" + filename)
self.progress_bar["value"] = x / len(os.listdir(dir)) * 100 self.progress_bar["value"] = x / len(os.listdir(dir)) * 100
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.delete_after_parse.get():
if self.run_excel_after_export.get(): os.remove(dir + "/" + filename)
self.open_export_file()
def ifNotNull(self,value, ret=""): def ifNotNull(self,value, ret=""):
if value == None: if value == None:
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()
if data.data["comments"] is not None:
data.data["comments"] = data.data["comments"].strip().replace("\n",'')
if data.Debtor["code"] is not None:
data.Debtor["code"] = data.Debtor["code"].strip()
data.Debtor["code"] = re.sub(r'[^0-9]', '', data.Debtor["code"])
if "name" in data.Debtor.keys() and data.Debtor["name"] is not None:
data.Debtor["name"] = data.Debtor["name"].replace("(facturation)","")
data.Debtor["name"] = data.Debtor["name"].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 compare_old_and_new_adresses(self, new, old, code):
print(f"compare_old_and_new_adresses ")
if self.ifNotNull(new['insurance_policy_number']).replace('.','') != old.AVS:
print("compare adresse exit avs")
return False
if self.ifNotNull(new['lastname']).replace('.','') != old.lastName:
print("compare adresse exit lastname")
return False
if self.ifNotNull(new['firstname']).replace('.','') != old.firstName:
print("compare adresse exit firstname")
return False
if datetime.strptime(self.ifNotNull(new['birthdate']), "%Y-%m-%d").strftime("%d.%m.%Y") != old.birth:
print("compare adresse exit date")
return False
if f"{self.ifNotNull(new['street']).strip()} {self.ifNotNull(new['street_number']).strip()}" != f"{self.ifNotNull(old.street).strip()}":
print(f"compare adresse exit ({self.ifNotNull(new['street']).strip()} {self.ifNotNull(new['street_number']).strip()}) != [" + self.ifNotNull(old.street).strip()+"]")
return False
if f"{self.ifNotNull(new['postal_code'])} {self.ifNotNull(new['city'])}" != f"{self.ifNotNull(old.npa)} {self.ifNotNull(old.city)}":
print("compare adresse exit city")
return False
if new["addr_2"] != old.addr_2 and int(code) < 100:
if not new["selfish"]:
print(f"Exit selfish")
return False
if old.addr_2 != "None":
print(f"Exit addr_2 = {old.addr_2}/{new['selfish']}")
print(old.addr_2 != "None")
return False
print("return True (same)")
return True
def parseFile(self, data, filename): def parseFile(self, data, filename):
self.progress_bar["value"] = 0
self.index_counter += 1 self.index_counter += 1
lines = [] lines = []
self.count_facture += len(data["invoices"]) self.count_facture += len(data["invoices"])
@@ -412,27 +442,41 @@ class ClercAttrib2Biz():
csv_col.data[5] = f"" csv_col.data[5] = f""
lines.append(csv_col.data) lines.append(csv_col.data)
cur_invoice_index = 0
x = 70
for ele in data["invoices"]: for ele in data["invoices"]:
cur_invoice_index += 1
self.progress_bar["value"] = cur_invoice_index / self.count_facture * 100
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 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"] = str(inp_popup.show())
else: if data.Debtor["code"] is None or '.' in data.Debtor["code"]:
data.Debtor["code"] = str(data.Debtor["code"]).replace('.', '') 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
if int(data.Debtor["code"]) == 1:
if not self.check_code_validity(data.Debtor["code"],data):
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
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:
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']}")
for elem in data.Debtor: for elem in data.Debtor:
pass pass
@@ -453,26 +497,78 @@ 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:
b_check_debitor = False
if data.Debtor["lastname"] == None:
b_check_debitor = True
data.Debtor["lastname"] = ""
messagebox.showerror(title="Erreur",
message=f"Le débiteur n'a pas de nom, vérifier la facture ATTRIB et vérifier le code débiteur: facture N°: {data.data['id']} / {data.Patient['fip_number']}")
if data.Debtor["firstname"] == None:
b_check_debitor = True
data.Debtor["firstname"] = ""
messagebox.showerror(title="Erreur",
message=f"Le débiteur n'a pas de prénom, vérifier la facture ATTRIB et vérifier le code débiteur: facture N°: {data.data['id']} / {data.Patient['fip_number']}")
if b_check_debitor:
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"] = debitor_popup.show()
if 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 data.Patient["complement"] != None: if int(data.Debtor["code"]) >= 100:
if "name" not in data.Debtor.keys():
data.Debtor["name"] = "Invalide"
self.logger.warning(
f"Débiteur > 100 sans nom, vérifier la facture ATTRIB et vérifier le code débiteur: facture N°: {data.data['id']} / {data.Patient['fip_number']}")
messagebox.showerror(title="Erreur",
message=f"Débiteur > 100 sans nom de débiteur ou d'établissement, vérifier la facture ATTRIB et vérifier le code débiteur: facture N°: {data.data['id']} / {data.Patient['fip_number']}")
self.a_listings["to_check"].append(data.Patient["fip_number"])
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"] = debitor_popup.show()
if data.Debtor["code"] is None or '.' in data.Debtor["code"]:
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
'''
Désactivé, plus utile
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"])
self.logger.warning(f"Complément patient: facture N°: {data.data['id']} / {data.Patient['fip_number']}") self.logger.warning(f"Complément patient: facture N°: {data.data['id']} / {data.Patient['fip_number']}")
'''
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 and not self.compare_old_and_new_adresses(new=data.Patient, old=addresses_exist, code=data.Debtor['code']):
pass
#popup = SuggestionPopup(self.fenetre, item_1=data.Patient, item_2=addresses_exist) popup = Check_addresses_popup(self.fenetre, item_1=data.Patient, item_2=addresses_exist, debitor=data.Debtor, factureID=data.data['id'])
#result = popup.show() b_address_update = popup.show()
#print(f"Result Popup: {result}") mode_selected = "Attrib" if b_address_update else "Winbiz"
self.logger.warning(
f"Adresse connue donnée [{mode_selected}] conservé: : {data.data['id']} / {data.Patient['fip_number']} {data.Debtor['code']} {data.Debtor['lastname']} {data.Debtor['firstname']}")
print(f"Result Popup: {b_address_update}")
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,12 +590,19 @@ 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
csv_col.data[2] = datetime.strptime(data.data["date"], "%Y-%m-%d").strftime("%d.%m.%Y") # Date du document csv_col.data[2] = datetime.strptime(data.data["date"], "%Y-%m-%d").strftime("%d.%m.%Y") # Date du document
csv_col.data[4] = data.Patient["fip_number"] # Référence csv_col.data[4] = data.Patient["fip_number"] # Référence
csv_col.data[10] = "<AUTO>" # Compte collectif du tiers = <AUTO> csv_col.data[10] = "<AUTO>" # Compte collectif du tiers = <AUTO>
csv_col.data[139] = "COND-30" # Conditions de payement à 30, COND-30 selon config dans winbiz
if "without_transportation" in data.Intervention.keys() and data.Intervention["without_transportation"] == True: if "without_transportation" in data.Intervention.keys() and data.Intervention["without_transportation"] == True:
@@ -530,7 +633,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,34 +648,16 @@ 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 = "" csv_col.data[42] = data.Patient["addr_2"].replace("\n", "#chr(13)##chr(10)#") #Adresse de livraison
concat_str = ""
if "name" in data.Debtor.keys():
concat_str += con + data.Debtor["name"]
con = "#chr(13)##chr(10)#"
if data.Debtor["gender"] is not None:
concat_str += con + "Monsieur" if data.Debtor["gender"] == "Masculin" else con + "Madame"
con = "#chr(13)##chr(10)#"
if data.Debtor["lastname"] is not None:
concat_str += con + self.ifNotNull(data.Debtor["lastname"]) + " " + self.ifNotNull(data.Debtor["firstname"])
con = "#chr(13)##chr(10)#"
if data.Debtor["street"] is not None:
concat_str += con + self.ifNotNull(data.Debtor["street"]) + " " + self.ifNotNull(data.Debtor["street_number"])
con = "#chr(13)##chr(10)#"
if data.Debtor["complement"] is not None:
concat_str += con + data.Debtor["complement"]
con = "#chr(13)##chr(10)#"
if data.Debtor["city"] is not None:
concat_str += con + self.ifNotNull(data.Debtor["postal_code"]) + " " + self.ifNotNull(data.Debtor["city"])
con = "#chr(13)##chr(10)#"
csv_col.data[42] = concat_str #Adresse de livraison
else: else:
csv_col.data[19] = data.Debtor["code"] # Code adresse à récupérer dans recherche d'adresse automatisée csv_col.data[19] = data.Debtor["code"] # Code adresse à récupérer dans recherche d'adresse automatisée
csv_col.data[22] = data.Debtor["lastname"] csv_col.data[22] = data.Debtor["lastname"]
@@ -584,14 +669,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']} ({data.Patient['lastname']}) est faux: [{data.Patient['birthdate']}], merci de le corriger ")
csv_col.data[48] = 0 csv_col.data[48] = 0
@@ -642,15 +731,18 @@ class ClercAttrib2Biz():
csv_col.data[72] = "BU - 73 - aff" csv_col.data[72] = "BU - 73 - aff"
csv_col.data[73] = 0 csv_col.data[73] = 0
csv_col.data[115] = self.ifNotNull(data.Patient["lastname"]) + " " + self.ifNotNull(data.Patient["firstname"]) #Objet facture
csv_col.data[108] = data.Patient["complement"] csv_col.data[108] = self.ifNotNull(data.Patient["lastname"]) + " " + self.ifNotNull(data.Patient["firstname"])
csv_col.data[115] = data.Patient["complement"]
csv_col.data[109] = datetime.strptime(data.Patient["birthdate"], "%Y-%m-%d").strftime("%d.%m.%Y") if data.Patient["birthdate"] is not None else "" csv_col.data[109] = datetime.strptime(data.Patient["birthdate"], "%Y-%m-%d").strftime("%d.%m.%Y") if data.Patient["birthdate"] is not None else ""
if data.Patient["insurance_policy_number"] is not None and '-' not in data.Patient["insurance_policy_number"]: if data.Patient["insurance_policy_number"] is not None and '-' not in data.Patient["insurance_policy_number"]:
csv_col.data[109] += ", " + data.Patient["insurance_policy_number"] csv_col.data[109] += ", " + data.Patient["insurance_policy_number"]
csv_col.data[110] = data.Patient["insurance_name"] csv_col.data[110] = data.Patient["insurance_name"]
csv_col.data[111] = datetime.strptime(data.Intervention["start_time"], "%Y-%m-%dT%H:%M:%S%z").strftime( date_PEC = datetime.strptime(data.Intervention["start_time"], "%Y-%m-%dT%H:%M:%S%z").strftime(
"%d.%m.%Y") # Date PEC "%d.%m.%Y")
csv_col.data[51] = date_PEC # Date de ligne articles
csv_col.data[111] =date_PEC # Date PEC
csv_col.data[111] += " - " + datetime.strptime(data.Intervention["start_time"], "%Y-%m-%dT%H:%M:%S%z").strftime( csv_col.data[111] += " - " + datetime.strptime(data.Intervention["start_time"], "%Y-%m-%dT%H:%M:%S%z").strftime(
"%H:%M") # Heure START PEC "%H:%M") # Heure START PEC
@@ -670,8 +762,11 @@ class ClercAttrib2Biz():
csv_col.data[116] = self.ifNotNull(data.Patient["category"]) + " - " + self.ifNotNull(data.Intervention["type"]) csv_col.data[116] = self.ifNotNull(data.Patient["category"]) + " - " + self.ifNotNull(data.Intervention["type"])
csv_col.data[118] = data.Intervention["kilometers"] csv_col.data[118] = data.Intervention["kilometers"]
csv_col.data[135] = data.Intervention["base_name"] csv_col.data[135] = data.Intervention["base_name"]
csv_col.data[136] = 2 if data.Intervention["base_name"] == "Uvrier" else 3 if data.Debtor["code"] == "100" or data.Debtor["code"] == "101":
csv_col.data[146] = csv_col.data[136] csv_col.data[136] = "EBILL" #code présentation de facture
else:
csv_col.data[136] = 3 #code présentation de facture
csv_col.data[146] = 3 #Code méthode de payement définit à 3
csv_col.data[168] = 1 if data.Intervention["team_name"] == "Planification" else 2 csv_col.data[168] = 1 if data.Intervention["team_name"] == "Planification" else 2
csv_col.data[169] = data.Patient['insurance_policy_number'] csv_col.data[169] = data.Patient['insurance_policy_number']
@@ -684,6 +779,9 @@ class ClercAttrib2Biz():
wr.writerow(cdr) wr.writerow(cdr)
else: else:
self.save_file(lines,fileName=self.export_filename) self.save_file(lines,fileName=self.export_filename)
return True
def addToIndexs(self,obj,data,cat, key): def addToIndexs(self,obj,data,cat, key):
#self.a_index[cat].append({"key":key,"index":len(obj.data)}) #self.a_index[cat].append({"key":key,"index":len(obj.data)})
if key not in self.a_index[cat]: if key not in self.a_index[cat]:
@@ -691,206 +789,6 @@ class ClercAttrib2Biz():
self.a_index["global"].append(key) self.a_index["global"].append(key)
obj.data.append(data) obj.data.append(data)
def convertFile(self, data, filename):
self.count_facture += len(data["invoices"])
self.a_listings["to_check"] = []
lines = []
for ele in data["invoices"]:
data = cls_Invoice()
data.parse_item(ele)
b_update_debitor = True
print(f"Code débiteur => {data.data['id']}: {data.Debtor['code']}" )
if data.Debtor["code"] == "None" or '.' in str(data.Debtor["code"]):
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 ")
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.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:
pass
''' 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 22 patient: facture N°: {data.data['id']} / {data.Patient['fip_number']}")
if data.Patient['insurance_policy_number'] == None:
data.Patient['insurance_policy_number'] = f"{uuid.uuid4()}"[:15]
b_HRF = False
sHRF = ""
for article in data.Articles:
if "code" in article.keys():
if article["code"] == "HRF":
b_HRF = True
sHRF = article["line_1"].replace("h",":")
print(f"pass HRF => {data.Patient['fip_number']}")
break
for article in data.Articles:
csv_col = cls_Col(False)
pass_article = False
##Donnée globales
self.addToIndexs(obj=csv_col,data=data.data["id"],cat="invoice",key="ID")
self.addToIndexs(obj=csv_col,data=data.data["date"],cat="invoice",key="date") # Date du document
self.addToIndexs(obj=csv_col, data=data.data["total_price"], cat="invoice", key="total_price")
self.addToIndexs(obj=csv_col, data=data.data["comments"], cat="invoice", key="comments")
whitout_transport = False
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):
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(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"
print( csv_col.data[self.a_index["global"].index("end_time")])
for elem in data.Patient:
if elem == "lastname":
if data.Patient[elem] == None:
data.Patient[elem] = "Patient inconnu"
if elem == "street_number":
print(f"ADRESS: data.Patient[elem]")
if data.Patient[elem] != None and "-" in data.Patient[elem] and "\t" not in data.Patient[elem]:
data.Patient[elem] = f"\t{data.Patient[elem]}"
print(f"ERROR DEBUG ADRESS: { data.Patient[elem]}")
self.addToIndexs(obj=csv_col, data=data.Patient[elem], cat="patient", key=elem)
for elem in data.Debtor:
if "name" in data.Debtor.keys():
pass
if elem == "street_number":
if data.Patient[elem] != None and "-" in data.Patient[elem] and "\t" not in data.Patient[elem]:
data.Patient[elem] = f"\t{data.Patient[elem]}"
if elem != "name":
csv_col.data.append(data.Debtor[elem])
if "name" in data.Debtor.keys():
csv_col.data.append(data.Debtor["name"])
else:
csv_col.data.append("")
# csv_col.data[126] = ' '.join(filter(None,temp_data)) # Débiteur nom
## Données prestations
if "code" in article.keys():
if article["code"] == "HRF":
csv_col = None
break
else:
csv_col.data.append(article["code"])
else:
csv_col.data.append("")
csv_col.data.append(article["line_1"])
csv_col.data.append(article["line_2"])
if "quantity" in article.keys():
csv_col.data.append(article["quantity"])
else:
csv_col.data.append("")
if "unit_price" in article.keys():
csv_col.data.append(article["unit_price"])
else:
csv_col.data.append("")
if "unit" in article.keys():
csv_col.data.append(article["unit"])
else:
csv_col.data.append("")
if "price" in article.keys():
csv_col.data.append(article["price"])
else:
csv_col.data.append("")
lines.append(csv_col.data)
csv_col = None
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, fileName = "src.csv"): def save_file(self,lines, fileName = "src.csv"):
with open(os.path.join(dest_dir, fileName), "a+", errors='replace',newline='') as csv_file: with open(os.path.join(dest_dir, fileName), "a+", errors='replace',newline='') as csv_file:
wr = csv.writer(csv_file, delimiter=';') wr = csv.writer(csv_file, delimiter=';')

Binary file not shown.

View File

@@ -1 +1 @@
VERSION = "20220606-1330" VERSION = "20230620-1559"