diff --git a/traf2000Converter/traf2000_convert.py b/converter.py old mode 100644 new mode 100755 similarity index 76% rename from traf2000Converter/traf2000_convert.py rename to converter.py index b12c5dd..7a8d1c1 --- a/traf2000Converter/traf2000_convert.py +++ b/converter.py @@ -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): """Output to a file the TRAF2000 records""" @@ -174,4 +263,4 @@ def convert(fatture, out_file_path): linea = ''.join(linea) + '\n' - traf2000_file.write(linea) + traf2000_file.write(linea) \ No newline at end of file diff --git a/downloader.py b/downloader.py new file mode 100644 index 0000000..e69de29 diff --git a/fatture_ccsr.py b/fatture_ccsr.py new file mode 100644 index 0000000..062fb81 --- /dev/null +++ b/fatture_ccsr.py @@ -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() diff --git a/traf2000Converter/manual/imppn.v2019.1.6.pdf b/manual/IMPPN.v2020.1.2.pdf similarity index 57% rename from traf2000Converter/manual/imppn.v2019.1.6.pdf rename to manual/IMPPN.v2020.1.2.pdf index 41d0a26..28a7736 100644 Binary files a/traf2000Converter/manual/imppn.v2019.1.6.pdf and b/manual/IMPPN.v2020.1.2.pdf differ diff --git a/traf2000Converter/fatture_import.py b/traf2000Converter/fatture_import.py deleted file mode 100644 index 11f8772..0000000 --- a/traf2000Converter/fatture_import.py +++ /dev/null @@ -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 diff --git a/traf2000Converter/traf2000.py b/utilities.py old mode 100755 new mode 100644 similarity index 50% rename from traf2000Converter/traf2000.py rename to utilities.py index daaf4c9..6813416 --- a/traf2000Converter/traf2000.py +++ b/utilities.py @@ -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 fatture_import -import traf2000_convert - def get_input_file(wildcard): """Return the input file path""" _ = wx.App(None) @@ -29,25 +22,4 @@ def get_output_file(default_output_filename): else: path = None dialog.Destroy() - 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) + return path \ No newline at end of file