420 lines
17 KiB
Python
420 lines
17 KiB
Python
import csv
|
|
import json
|
|
import os
|
|
from datetime import datetime
|
|
|
|
import tkinter.filedialog
|
|
from tkinter import *
|
|
from tkinter import messagebox
|
|
from tkinter.ttk import Progressbar
|
|
from threading import *
|
|
|
|
from class_invoices import *
|
|
|
|
VERSION = 1.1
|
|
|
|
|
|
|
|
src_dir = os.getenv('APPDATA') + "\Attrib2Biz\src"
|
|
dest_dir = os.getenv('APPDATA') + "\Attrib2Biz\output"
|
|
file_path ="" #os.path.dirname(__file__)
|
|
|
|
Elements = []
|
|
export_csv = "";
|
|
con_csv = "";
|
|
|
|
|
|
if not os.path.exists(src_dir):
|
|
os.makedirs(src_dir)
|
|
|
|
if not os.path.exists(dest_dir):
|
|
os.makedirs(dest_dir)
|
|
|
|
|
|
class ClercAttrib2Biz():
|
|
def __init__(self):
|
|
self.count_facture = 0
|
|
self.a_index = {"invoice": [], "intervention": [], "patient": [], "debtor": [], "articles": [], "global": []}
|
|
self.index_counter = 0
|
|
|
|
self.fenetre = Tk()
|
|
|
|
self.delete_after_parse = BooleanVar(self.fenetre)
|
|
self.export_format_biz = BooleanVar(self.fenetre)
|
|
self.export_one_file = BooleanVar(self.fenetre)
|
|
|
|
self.draw_mainWindows()
|
|
|
|
self.timer = self.fenetre.after(1000, self.main_timer_fn)
|
|
|
|
self.fenetre.mainloop()
|
|
|
|
|
|
|
|
def main_timer_fn(self):
|
|
print("Pass tick timer main app")
|
|
self.timer = self.fenetre.after(5000, self.main_timer_fn)
|
|
|
|
self.nb_facture_var.set(self.count_facture)
|
|
|
|
self.count_src()
|
|
|
|
def draw_mainWindows(self):
|
|
|
|
#Init de la fenêtre principale
|
|
|
|
self.fenetre.iconbitmap("./logo_clerc_03X_icon.ico")
|
|
self.fenetre.title("Clerc Attrib2Biz v" + str(VERSION))
|
|
self.fenetre.resizable(True, False)
|
|
self.fenetre.geometry("700x250")
|
|
|
|
self.fenetre.columnconfigure(0, weight=3)
|
|
self.fenetre.columnconfigure(1, weight=1)
|
|
|
|
|
|
|
|
lbf_2 = LabelFrame(self.fenetre, text="Nb de facture")
|
|
lbf_2.grid(row=1, column=0, sticky='W',padx=5, pady=5)
|
|
lbf_3 = LabelFrame(self.fenetre, text="Options")
|
|
lbf_3.grid(row=0, column=8, sticky='WE',padx=5, pady=5)
|
|
|
|
#GUI Nb Files
|
|
lbf_1 = LabelFrame(self.fenetre, text="Nb de fichiers")
|
|
lbf_1.grid(row=0, column=0, sticky='WE', padx=5, pady=5)
|
|
self.nb_files_var = IntVar()
|
|
Label(lbf_1, textvariable=self.nb_files_var, anchor="e", font=('Helvetica', 13, 'bold')).grid(row=0, column=0, sticky="W", pady=5)
|
|
Label(lbf_1, text="fichiers .json dans le dossier source", anchor="w" ).grid(row=0,column=1, sticky="W", pady=5)
|
|
|
|
f1 = Frame(lbf_1)
|
|
f1.grid(row=1, column=1)
|
|
bt_open_src = Button(f1, text="Ouvrir le dossier source", command=self.open_src)
|
|
bt_open_src.grid(row=1, column=0, padx=5, pady=5)
|
|
self.bt_clear_src = Button(f1, text="Vider le dossier source", command=self.clear_src, state="disabled")
|
|
self.bt_clear_src.grid(row=1, column=2, padx=5, pady=5)
|
|
|
|
# GUI Nb facture
|
|
lbf_2 = LabelFrame(self.fenetre, text="Nb de Facture", width=250)
|
|
lbf_2.grid(row=1, column=0, sticky='WE', padx=5, pady=5)
|
|
lbf_2.columnconfigure(2, weight=1)
|
|
self.nb_facture_var = IntVar()
|
|
Label(lbf_2, textvariable=self.nb_facture_var, anchor="e", font=('Helvetica', 13, 'bold')).grid(row=0, column=0, sticky="W", pady=5)
|
|
Label(lbf_2, text="factures trouvées sur l'ensemble des fichiers", anchor="w").grid(row=0, column=1, sticky="W", pady=5)
|
|
|
|
f2 = Frame(lbf_2)
|
|
f2.grid(row=1, column=1)
|
|
|
|
self.bt_parse = Button(f2, text="Lancer la conversion", command=self.start_parsing, state="disabled")
|
|
self.bt_parse.grid(row=1, column=0,columnspan=2, padx=5, pady=5, sticky="W")
|
|
bt_open_dest = Button(f2, text="Ouvrir le dossier de sortie", command=self.open_dest)
|
|
bt_open_dest.grid(row=1, column=2, padx=5, pady=5, sticky="W")
|
|
|
|
|
|
self.txt_progress = LabelFrame(self.fenetre, text="Progress")
|
|
self.txt_progress.grid(row=2, column=0, sticky='WE', columnspan=2, padx=5, pady=5)
|
|
self.txt_progress.columnconfigure(0,weight=1)
|
|
|
|
self.progress_bar = Progressbar(self.txt_progress, orient=HORIZONTAL, mode='determinate')
|
|
self.progress_bar.grid( sticky='WE')
|
|
|
|
|
|
lbf_3 = LabelFrame(self.fenetre, text="Options")
|
|
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="Export au format .biz", variable= self.export_format_biz, onvalue=True, offvalue=False).grid(row=1, sticky='W')
|
|
Checkbutton(lbf_3, text="Export en 1 seul fichier", variable= self.export_one_file, onvalue=True, offvalue=False, state="disabled").grid(row=2, sticky='W')
|
|
|
|
|
|
self.var_file_count = StringVar(self.fenetre)
|
|
self.running = False
|
|
|
|
self.thread = Thread(target=self.start_parsing)
|
|
|
|
|
|
|
|
|
|
|
|
def start_parsing(self):
|
|
dir = src_dir
|
|
self.count_facture = 0
|
|
x = 0
|
|
for filename in os.listdir(dir):
|
|
x += 1
|
|
if ".json" in filename:
|
|
print(filename)
|
|
with open(dir + "/" + filename, encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
|
|
if self.export_format_biz.get():
|
|
self.parseFile(data, filename)
|
|
else:
|
|
self.convertFile(data, filename)
|
|
if self.delete_after_parse.get():
|
|
os.remove(dir + "/" + filename)
|
|
self.progress_bar["value"] = x / len(os.listdir(dir)) * 100
|
|
self.fenetre.update_idletasks()
|
|
self.nb_facture_var.set(self.count_facture)
|
|
|
|
|
|
|
|
def parseFile(self, data, filename):
|
|
lines = []
|
|
self.count_facture += len(data["invoices"])
|
|
for ele in data["invoices"]:
|
|
data = cls_Invoice()
|
|
data.parse_item(ele)
|
|
|
|
for article in data.Articles:
|
|
csv_col = cls_Col(True)
|
|
|
|
##Donnée globales
|
|
csv_col.data[0] = data.data["id"] # N° document
|
|
csv_col.data[129] = data.Intervention["type"] # Priorité
|
|
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[4] = data.Patient["fip_number"] # Référence
|
|
csv_col.data[10] = "<AUTO>" # Compte collectif du tiers = <AUTO>
|
|
if data.Patient["gender"] == "Féminin":
|
|
csv_col.data[12] = "F" # Langue du document, utilisé comme sexe
|
|
elif data.Patient["gender"] == "Masculin":
|
|
csv_col.data[12] = "M" # Langue du document, utilisé comme sexe
|
|
csv_col.data[19] = data.Debtor["code"] # Code adresse à récupérer dans recherche d'adresse automatisée
|
|
|
|
## Donnée Patients
|
|
csv_col.data[22] = data.Patient["lastname"] # Nom de famille du patient
|
|
csv_col.data[23] = data.Patient["firstname"] # Prénom du patient
|
|
csv_col.data[24] = data.Patient["street"] # Rue du patient
|
|
csv_col.data[25] = data.Patient["complement"] # Complément rue
|
|
csv_col.data[26] = data.Patient["postal_code"] # NPA du patient
|
|
csv_col.data[27] = data.Patient["city"] # Localité du patient
|
|
csv_col.data[107] = data.Patient["birthdate"] # Date de naissance du patient
|
|
csv_col.data[108] = "" # Profession
|
|
csv_col.data[109] = data.Patient["insurance_name"] # Assurance
|
|
csv_col.data[110] = "Filiation" # Filiation
|
|
csv_col.data[112] = data.Intervention["site_street"] # Rue PEC
|
|
csv_col.data[113] = data.Intervention["site_street_number"] # Rue PEC
|
|
csv_col.data[114] = data.Intervention["site_postal_code"] + " " + data.Intervention["site_city"] # Rue PEC
|
|
if "destination_name" not in data.Intervention.keys():
|
|
csv_col.data[115] = "Sans transport"
|
|
else:
|
|
csv_col.data[115] = data.Intervention["destination_name"]
|
|
csv_col.data[111] = datetime.strptime(data.Intervention["start_time"], "%Y-%m-%dT%H:%M:%S%z").strftime(
|
|
"%d.%m.%Y") # Date PEC
|
|
csv_col.data[118] = datetime.strptime(data.Intervention["start_time"], "%Y-%m-%dT%H:%M:%S%z").strftime(
|
|
"%H:%M") # Heure PEC
|
|
csv_col.data[119] = datetime.strptime(data.Intervention["end_time"], "%Y-%m-%dT%H:%M:%S%z").strftime(
|
|
"%H:%M") # Heure PEC
|
|
|
|
# Donnée débiteur
|
|
|
|
csv_col.data[120] = data.Debtor["lastname"] # Débiteur nom
|
|
csv_col.data[121] = data.Debtor["firstname"] # Débiteur prénom
|
|
if data.Debtor["street"] is not None:
|
|
csv_col.data[122] = data.Debtor["street"] + " " + data.Debtor["street_number"] # Débiteur nom
|
|
csv_col.data[127] = data.Debtor["street"] + " " + data.Debtor["street_number"] # Débiteur nom
|
|
csv_col.data[123] = data.Debtor["postal_code"] + " " + data.Debtor["city"] # Débiteur
|
|
csv_col.data[128] = data.Debtor["postal_code"] + " " + data.Debtor["city"] # Débiteur
|
|
|
|
csv_col.data[124] = "11111111" # Débiteur nom
|
|
if data.Debtor["gender"] == "Féminin":
|
|
csv_col.data[125] = "Madame" # Langue du document, utilisé comme sexe
|
|
elif data.Debtor["gender"] == "Masculin":
|
|
csv_col.data[125] = "Monsieur" # Langue du document, utilisé comme sexe
|
|
else:
|
|
csv_col.data[125] = "" # Langue du document, utilisé comme sexe
|
|
if data.Debtor["type"] == "Personne":
|
|
csv_col.data[126] = data.Debtor["firstname"] + " " + data.Debtor["lastname"] # Débiteur nom
|
|
elif data.Debtor["type"] == "Établissement":
|
|
temp_data = []
|
|
temp_data.append(data.Debtor["name"])
|
|
temp_data.append(data.Debtor["firstname"])
|
|
temp_data.append(data.Debtor["lastname"])
|
|
csv_col.data[126] = ' '.join(filter(None, temp_data)) # Débiteur nom
|
|
|
|
## Données prestations
|
|
if "code" in article.keys():
|
|
csv_col.data[49] = article["code"] # Code de prestations
|
|
csv_col.data[50] = article["line_1"]
|
|
if article["line_2"] != None:
|
|
csv_col.data[50] = article["line_1"] + " / " + article["line_2"] # Descriptions prestations
|
|
csv_col.data[52] = article["quantity"] # Quantité
|
|
csv_col.data[53] = article["unit_price"] # prix unitaire
|
|
csv_col.data[54] = article["unit"] # unité
|
|
csv_col.data[56] = article["price"] # prix total
|
|
csv_col.data[59] = "<AUTO>" # Compte chiffre d'affaire = <AUTO>
|
|
else:
|
|
csv_col.data[49] = "txt"
|
|
csv_col.data[50] = article["line_1"]
|
|
if article["line_2"] != None:
|
|
csv_col.data[50] = article["line_1"] + " / " + article["line_2"] # Descriptions prestations
|
|
csv_col.data[52] = 0
|
|
csv_col.data[53] = 0
|
|
csv_col.data[56] = 0 # prix total
|
|
csv_col.data[59] = "<AUTO>" # Compte chiffre d'affaire = <AUTO>
|
|
|
|
lines.append(csv_col.data)
|
|
csv_col = None
|
|
with open(f"{dest_dir}/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)
|
|
def addToIndexs(self,obj,data,cat, key):
|
|
#self.a_index[cat].append({"key":key,"index":len(obj.data)})
|
|
if key not in self.a_index[cat]:
|
|
self.a_index[cat].append(key)
|
|
self.a_index["global"].append(key)
|
|
obj.data.append(data)
|
|
|
|
def convertFile(self, data, filename):
|
|
self.count_facture += len(data["invoices"])
|
|
|
|
|
|
|
|
|
|
lines = []
|
|
for ele in data["invoices"]:
|
|
data = cls_Invoice()
|
|
data.parse_item(ele)
|
|
|
|
b_HRF = False
|
|
sHRF = ""
|
|
for article in data.Articles:
|
|
if "code" in article.keys():
|
|
if article["code"] == "CLN.9431":
|
|
b_HRF = True
|
|
sHRF = article["line_1"].replace("h",":")
|
|
print("pass HRF")
|
|
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
|
|
break
|
|
|
|
self.addToIndexs(obj=csv_col, data=data.Intervention[elem], cat="intervention", key=elem)
|
|
|
|
if whitout_transport:
|
|
for x in range(8):
|
|
csv_col.data.append("")
|
|
self.addToIndexs(obj=csv_col, data="", cat="intervention", key=x)
|
|
|
|
|
|
self.addToIndexs(obj=csv_col, data=whitout_transport, cat="intervention", key="whitout_transport")
|
|
|
|
if b_HRF:
|
|
print("pass Change end_time on b_HRF")
|
|
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:
|
|
self.addToIndexs(obj=csv_col, data=data.Patient[elem], cat="patient", key=elem)
|
|
|
|
for elem in data.Debtor:
|
|
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"] == "CLN.9431":
|
|
pass
|
|
# 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
|
|
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)
|
|
def open_src(self):
|
|
os.startfile(file_path + src_dir)
|
|
|
|
def open_dest(self):
|
|
os.startfile(file_path + dest_dir)
|
|
|
|
def clear_src(self):
|
|
file_in_src = os.listdir(src_dir)
|
|
for file in file_in_src:
|
|
os.remove(src_dir + "\\" + file)
|
|
print(f"Supression du fichier: {file}")
|
|
|
|
self.count_src()
|
|
|
|
def clear_dest(self):
|
|
file_in = os.listdir(dest_dir)
|
|
for file in file_in:
|
|
os.remove(dest_dir + "\\" + file)
|
|
print(f"Supression du fichier: {file}")
|
|
|
|
def count_src(self):
|
|
file_in_src = os.listdir(src_dir)
|
|
count = len(file_in_src)
|
|
if count > 0:
|
|
self.bt_clear_src["state"] = "normal"
|
|
self.bt_parse["state"] = "normal"
|
|
else:
|
|
self.bt_clear_src["state"] = "disabled"
|
|
self.bt_parse["state"] = "disabled"
|
|
if not self.running:
|
|
self.nb_files_var.set(count)
|
|
|
|
|
|
app = ClercAttrib2Biz() |