mirror of
https://github.com/Noettore/fattureCCSR.git
synced 2025-10-14 19:26:39 +02:00
fattureCCSR: python rewrite of downloader and integration with minimal gui. Initial commit
Signed-off-by: Ettore Dreucci <ettore.dreucci@gmail.com>
This commit is contained in:
93
traf2000Converter/traf2000_convert.py → converter.py
Normal file → Executable file
93
traf2000Converter/traf2000_convert.py → converter.py
Normal file → Executable file
@@ -1,4 +1,93 @@
|
|||||||
"""This script provides a function to convert a dict of invoices to a TRAF2000 file"""
|
"""This script ask for an input file and an output file and generates the TRAF2000 records from a .csv or .xml"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import csv
|
||||||
|
import xml.etree.ElementTree
|
||||||
|
import unidecode
|
||||||
|
|
||||||
|
def import_csv(csv_file_path):
|
||||||
|
"""Return a dict containing the invoices info"""
|
||||||
|
fatture = dict()
|
||||||
|
with open(csv_file_path, newline="") as csv_file:
|
||||||
|
lettore = csv.reader(csv_file, delimiter=",")
|
||||||
|
|
||||||
|
for _ in range(4):
|
||||||
|
next(lettore)
|
||||||
|
|
||||||
|
for linea in lettore:
|
||||||
|
if len(linea) == 0:
|
||||||
|
break
|
||||||
|
num_fattura = linea[1]
|
||||||
|
tipo_fattura = linea[8]
|
||||||
|
importo = linea[15]
|
||||||
|
segno = 1
|
||||||
|
if tipo_fattura == "Nota di credito" and '(' not in importo:
|
||||||
|
segno = -1
|
||||||
|
importo = int(linea[15].replace("€", "").replace(",", "").replace(".", "").replace("(", "").replace(")", "")) * segno
|
||||||
|
if num_fattura not in fatture:
|
||||||
|
fattura = {
|
||||||
|
"numFattura": num_fattura,
|
||||||
|
"tipoFattura": tipo_fattura,
|
||||||
|
"rifFattura": linea[4],
|
||||||
|
"dataFattura": linea[2].replace("/", ""),
|
||||||
|
"ragioneSociale": unidecode.unidecode(linea[6] + " " + " ".join(linea[5].split(" ")[0:2])),
|
||||||
|
"posDivide": str(len(linea[6]) + 1),
|
||||||
|
"cf": linea[7],
|
||||||
|
"importoTotale": 0,
|
||||||
|
"ritenutaAcconto": 0,
|
||||||
|
"righe": dict()
|
||||||
|
}
|
||||||
|
fatture[num_fattura] = fattura
|
||||||
|
|
||||||
|
if linea[14] == "Ritenuta d'acconto":
|
||||||
|
fatture[num_fattura]["ritenutaAcconto"] = importo
|
||||||
|
|
||||||
|
else:
|
||||||
|
fatture[num_fattura]["importoTotale"] += importo
|
||||||
|
fatture[num_fattura]["righe"][linea[14]] = importo
|
||||||
|
return fatture
|
||||||
|
|
||||||
|
def import_xml(xml_file_path):
|
||||||
|
"""Return a dict containing the invoices info"""
|
||||||
|
fatture = dict()
|
||||||
|
|
||||||
|
tree = xml.etree.ElementTree.parse(xml_file_path)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
for fattura in root.iter('{STAT_FATTURATO_CTERZI}Dettagli'):
|
||||||
|
righe = dict()
|
||||||
|
num_fattura = fattura.get('protocollo_fatturatestata')
|
||||||
|
tipo_fattura = fattura.get('fat_ndc')
|
||||||
|
importo_totale = 0
|
||||||
|
ritenuta_acconto = 0
|
||||||
|
|
||||||
|
for riga in fattura.iter('{STAT_FATTURATO_CTERZI}Dettagli2'):
|
||||||
|
desc = riga.get('descrizione_fatturariga1')
|
||||||
|
segno = 1
|
||||||
|
if tipo_fattura == 'Nota di credito' and '-' not in riga.get('prezzounitario_fatturariga1'):
|
||||||
|
segno = -1
|
||||||
|
importo = int(format(round(float(riga.get('prezzounitario_fatturariga1')), 2), '.2f').replace('.', '').replace('-', '')) * segno
|
||||||
|
if desc == "Ritenuta d'acconto":
|
||||||
|
ritenuta_acconto = importo
|
||||||
|
else:
|
||||||
|
righe[desc] = importo
|
||||||
|
importo_totale += importo
|
||||||
|
|
||||||
|
fattura_elem = {
|
||||||
|
"numFattura": num_fattura,
|
||||||
|
"tipoFattura": tipo_fattura,
|
||||||
|
"rifFattura": fattura.get('protocollo_fatturatestata1'),
|
||||||
|
"dataFattura": datetime.datetime.fromisoformat(fattura.get('data_fatturatestata')).strftime("%d%m%Y"),
|
||||||
|
"ragioneSociale": unidecode.unidecode(fattura.get('cognome_cliente') + ' ' + ' '.join(fattura.get('nome_cliente').split(' ')[0:2])),
|
||||||
|
"posDivide": str(len(fattura.get('cognome_cliente')) + 1),
|
||||||
|
"cf": fattura.get('cf_piva_cliente'),
|
||||||
|
"importoTotale": importo_totale,
|
||||||
|
"ritenutaAcconto": ritenuta_acconto,
|
||||||
|
"righe": righe,
|
||||||
|
}
|
||||||
|
fatture[num_fattura] = fattura_elem
|
||||||
|
return fatture
|
||||||
|
|
||||||
|
|
||||||
def convert(fatture, out_file_path):
|
def convert(fatture, out_file_path):
|
||||||
"""Output to a file the TRAF2000 records"""
|
"""Output to a file the TRAF2000 records"""
|
||||||
@@ -174,4 +263,4 @@ def convert(fatture, out_file_path):
|
|||||||
|
|
||||||
linea = ''.join(linea) + '\n'
|
linea = ''.join(linea) + '\n'
|
||||||
|
|
||||||
traf2000_file.write(linea)
|
traf2000_file.write(linea)
|
0
downloader.py
Normal file
0
downloader.py
Normal file
66
fatture_ccsr.py
Normal file
66
fatture_ccsr.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
"""This script prompts for downloading or converting to TRAF2000 from a .csv or .xml report file"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
import converter
|
||||||
|
import utilities
|
||||||
|
|
||||||
|
class FattureCCSRFrame(wx.Frame):
|
||||||
|
def __init__(self, parent, title):
|
||||||
|
super(FattureCCSRFrame, self).__init__(parent, title=title, size=(500, 150))
|
||||||
|
panel = wx.Panel(self)
|
||||||
|
vbox = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
|
||||||
|
self.input_file_picker = wx.FilePickerCtrl(panel, 101, "", "Seleziona il .csv o .xml", "*.csv;*.xml")
|
||||||
|
hbox1.Add(self.input_file_picker, 1, wx.EXPAND, 0)
|
||||||
|
|
||||||
|
self.download_btn = wx.Button(panel, 201, "Scarica Fatture")
|
||||||
|
hbox2.Add(self.download_btn, 0, wx.ALIGN_CENTER)
|
||||||
|
self.download_btn.Bind(wx.EVT_BUTTON, self.btn_onclick)
|
||||||
|
|
||||||
|
self.traf2000_btn = wx.Button(panel, 202, "Genera TRAF2000")
|
||||||
|
hbox2.Add(self.traf2000_btn, 0, wx.ALIGN_CENTER)
|
||||||
|
self.traf2000_btn.Bind(wx.EVT_BUTTON, self.btn_onclick)
|
||||||
|
|
||||||
|
vbox.Add(hbox1, 0, wx.EXPAND)
|
||||||
|
vbox.Add(hbox2, 0, wx.ALIGN_CENTER_HORIZONTAL)
|
||||||
|
|
||||||
|
panel.SetSizer(vbox)
|
||||||
|
|
||||||
|
self.Centre()
|
||||||
|
self.Show()
|
||||||
|
|
||||||
|
def btn_onclick(self, event):
|
||||||
|
btn_id = event.GetEventObject().GetId()
|
||||||
|
if btn_id == 202:
|
||||||
|
input_file_path = utilities.get_input_file("*.csv;*.xml")
|
||||||
|
if input_file_path is None:
|
||||||
|
sys.exit("ERROR: No input file selected!")
|
||||||
|
|
||||||
|
fatture_file_extension = os.path.splitext(input_file_path)[1]
|
||||||
|
|
||||||
|
output_file_path = utilities.get_output_file("TRAF2000")
|
||||||
|
if output_file_path is None:
|
||||||
|
sys.exit("ERROR: No output file selected!")
|
||||||
|
|
||||||
|
if fatture_file_extension == ".csv":
|
||||||
|
fatture = converter.import_csv(input_file_path)
|
||||||
|
|
||||||
|
elif fatture_file_extension == ".xml":
|
||||||
|
fatture = converter.import_xml(input_file_path)
|
||||||
|
|
||||||
|
else:
|
||||||
|
sys.exit("ERROR: file extension not supported")
|
||||||
|
|
||||||
|
converter.convert(fatture, output_file_path)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = wx.App()
|
||||||
|
FattureCCSRFrame(None, "Utility FattureCCSR")
|
||||||
|
app.MainLoop()
|
Binary file not shown.
@@ -1,89 +0,0 @@
|
|||||||
"""This script provides two functions to import invoices from .csv or .xml into a dict"""
|
|
||||||
|
|
||||||
import csv
|
|
||||||
import xml.etree.ElementTree
|
|
||||||
import datetime
|
|
||||||
import unidecode
|
|
||||||
|
|
||||||
def import_csv(csv_file_path):
|
|
||||||
"""Return a dict containing the invoices info"""
|
|
||||||
fatture = dict()
|
|
||||||
with open(csv_file_path, newline="") as csv_file:
|
|
||||||
lettore = csv.reader(csv_file, delimiter=",")
|
|
||||||
|
|
||||||
for _ in range(4):
|
|
||||||
next(lettore)
|
|
||||||
|
|
||||||
for linea in lettore:
|
|
||||||
if len(linea) == 0:
|
|
||||||
break
|
|
||||||
num_fattura = linea[1]
|
|
||||||
tipo_fattura = linea[8]
|
|
||||||
importo = linea[15]
|
|
||||||
segno = 1
|
|
||||||
if tipo_fattura == "Nota di credito" and '(' not in importo:
|
|
||||||
segno = -1
|
|
||||||
importo = int(linea[15].replace("€", "").replace(",", "").replace(".", "").replace("(", "").replace(")", "")) * segno
|
|
||||||
if num_fattura not in fatture:
|
|
||||||
fattura = {
|
|
||||||
"numFattura": num_fattura,
|
|
||||||
"tipoFattura": tipo_fattura,
|
|
||||||
"rifFattura": linea[4],
|
|
||||||
"dataFattura": linea[2].replace("/", ""),
|
|
||||||
"ragioneSociale": unidecode.unidecode(linea[6] + " " + " ".join(linea[5].split(" ")[0:2])),
|
|
||||||
"posDivide": str(len(linea[6]) + 1),
|
|
||||||
"cf": linea[7],
|
|
||||||
"importoTotale": 0,
|
|
||||||
"ritenutaAcconto": 0,
|
|
||||||
"righe": dict()
|
|
||||||
}
|
|
||||||
fatture[num_fattura] = fattura
|
|
||||||
|
|
||||||
if linea[14] == "Ritenuta d'acconto":
|
|
||||||
fatture[num_fattura]["ritenutaAcconto"] = importo
|
|
||||||
|
|
||||||
else:
|
|
||||||
fatture[num_fattura]["importoTotale"] += importo
|
|
||||||
fatture[num_fattura]["righe"][linea[14]] = importo
|
|
||||||
return fatture
|
|
||||||
|
|
||||||
def import_xml(xml_file_path):
|
|
||||||
"""Return a dict containing the invoices info"""
|
|
||||||
fatture = dict()
|
|
||||||
|
|
||||||
tree = xml.etree.ElementTree.parse(xml_file_path)
|
|
||||||
root = tree.getroot()
|
|
||||||
|
|
||||||
for fattura in root.iter('{STAT_FATTURATO_CTERZI}Dettagli'):
|
|
||||||
righe = dict()
|
|
||||||
num_fattura = fattura.get('protocollo_fatturatestata')
|
|
||||||
tipo_fattura = fattura.get('fat_ndc')
|
|
||||||
importo_totale = 0
|
|
||||||
ritenuta_acconto = 0
|
|
||||||
|
|
||||||
for riga in fattura.iter('{STAT_FATTURATO_CTERZI}Dettagli2'):
|
|
||||||
desc = riga.get('descrizione_fatturariga1')
|
|
||||||
segno = 1
|
|
||||||
if tipo_fattura == 'Nota di credito' and '-' not in riga.get('prezzounitario_fatturariga1'):
|
|
||||||
segno = -1
|
|
||||||
importo = int(format(round(float(riga.get('prezzounitario_fatturariga1')), 2), '.2f').replace('.', '').replace('-', '')) * segno
|
|
||||||
if desc == "Ritenuta d'acconto":
|
|
||||||
ritenuta_acconto = importo
|
|
||||||
else:
|
|
||||||
righe[desc] = importo
|
|
||||||
importo_totale += importo
|
|
||||||
|
|
||||||
fattura_elem = {
|
|
||||||
"numFattura": num_fattura,
|
|
||||||
"tipoFattura": tipo_fattura,
|
|
||||||
"rifFattura": fattura.get('protocollo_fatturatestata1'),
|
|
||||||
"dataFattura": datetime.datetime.fromisoformat(fattura.get('data_fatturatestata')).strftime("%d%m%Y"),
|
|
||||||
"ragioneSociale": unidecode.unidecode(fattura.get('cognome_cliente') + ' ' + ' '.join(fattura.get('nome_cliente').split(' ')[0:2])),
|
|
||||||
"posDivide": str(len(fattura.get('cognome_cliente')) + 1),
|
|
||||||
"cf": fattura.get('cf_piva_cliente'),
|
|
||||||
"importoTotale": importo_totale,
|
|
||||||
"ritenutaAcconto": ritenuta_acconto,
|
|
||||||
"righe": righe,
|
|
||||||
}
|
|
||||||
fatture[num_fattura] = fattura_elem
|
|
||||||
return fatture
|
|
30
traf2000Converter/traf2000.py → utilities.py
Executable file → Normal file
30
traf2000Converter/traf2000.py → utilities.py
Executable file → Normal file
@@ -1,12 +1,5 @@
|
|||||||
"""This script ask for an input file and an output file and generates the TRAF2000 records from a .csv or .xml"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import wx
|
import wx
|
||||||
|
|
||||||
import fatture_import
|
|
||||||
import traf2000_convert
|
|
||||||
|
|
||||||
def get_input_file(wildcard):
|
def get_input_file(wildcard):
|
||||||
"""Return the input file path"""
|
"""Return the input file path"""
|
||||||
_ = wx.App(None)
|
_ = wx.App(None)
|
||||||
@@ -29,25 +22,4 @@ def get_output_file(default_output_filename):
|
|||||||
else:
|
else:
|
||||||
path = None
|
path = None
|
||||||
dialog.Destroy()
|
dialog.Destroy()
|
||||||
return path
|
return path
|
||||||
|
|
||||||
input_file_path = get_input_file("*.csv;*.xml")
|
|
||||||
if input_file_path is None:
|
|
||||||
sys.exit("ERROR: No input file selected!")
|
|
||||||
|
|
||||||
fattureFileExtension = os.path.splitext(input_file_path)[1]
|
|
||||||
|
|
||||||
output_file_path = get_output_file("TRAF2000")
|
|
||||||
if output_file_path is None:
|
|
||||||
sys.exit("ERROR: No output file selected!")
|
|
||||||
|
|
||||||
if fattureFileExtension == ".csv":
|
|
||||||
fatture = fatture_import.import_csv(input_file_path)
|
|
||||||
|
|
||||||
elif fattureFileExtension == ".xml":
|
|
||||||
fatture = fatture_import.import_xml(input_file_path)
|
|
||||||
|
|
||||||
else:
|
|
||||||
sys.exit("ERROR: file extension not supported")
|
|
||||||
|
|
||||||
traf2000_convert.convert(fatture, output_file_path)
|
|
Reference in New Issue
Block a user