LeenO computo metrico con LibreOffice  3.22.0
Il software libero per la gestione di computi metrici e contabilità lavori.
LeenoImport_XmlToscana.py
Vai alla documentazione di questo file.
1 import Dialogs
2 import pyleeno as PL
3 
4 from io import StringIO
5 import xml.etree.ElementTree as ET
6 
7 import codecs
8 import shutil
9 import LeenoImport
10 import LeenoUtils
11 import LeenoDialogs as DLG
12 import SheetUtils
13 
14 from com.sun.star.sheet.CellFlags import \
15  VALUE, DATETIME, STRING, ANNOTATION, FORMULA, HARDATTR, OBJECTS, EDITATTR, FORMATTED
16 
17 def parseXML(data, defaultTitle=None):
18  '''
19  estrae dal file XML i dati dell'elenco prezzi
20  I dati estratti avranno il formato seguente:
21 
22  articolo = {
23  'codice': codice,
24  'desc': desc,
25  'um': um,
26  'prezzo': prezzo,
27  'mdo': mdo,
28  'sicurezza': oneriSic
29  }
30  artList = { codice : articolo, ... }
31 
32  superCatList = { codice : descrizione, ... }
33  catList = { codice : descrizione, ... }
34 
35  dati = {
36  'titolo': titolo,
37  'superCategorie': superCatList,
38  'categorie': catList,
39  'articoli' : artList
40  }
41  '''
42  # alcuni files sono degli XML-SIX con un bug
43  # consistente nella mancata dichiarazione del namespace
44  # quindi lo aggiungiamo a manina nei dati
45  if data.find("xmlns:PRT=") < 0:
46  pattern = "<PRT:Prezzario>"
47  pos = data.find(pattern) + len(pattern) - 1
48  data = data[:pos] + ' xmlns:PRT="mynamespace"' + data[pos:]
49  print(data[:1000])
50 
51  # elimina i namespaces dai dati ed ottiene
52  # elemento radice dell' albero XML
54 
55  intestazione = root.find('intestazione')
56  autore = intestazione.attrib['autore']
57  # versione = intestazione.attrib['versione']
58 
59  dettaglio = intestazione.find('dettaglio')
60  anno = dettaglio.attrib['anno']
61  area = dettaglio.attrib['area']
62 
63  copyright = intestazione.find('copyright')
64  ccType = copyright.attrib['tipo']
65  ccDesc = copyright.attrib['descrizione']
66 
67  # crea il titolo dell' EP
68  # ~titolo = "Elenco prezzi - " + autore + " - " + area + " - anno " + anno
69  titolo = "Elenco prezzi - " + area + " - anno " + anno + "\n"\
70  + "Copyright: " + ccType + " - " + ccDesc
71 
72  contenuto = root.find('Contenuto')
73  articoli = contenuto.findall('Articolo')
74 
75  artList = {}
76  superCatList = {}
77  catList = {}
78 
79  for articolo in articoli:
80  # rimuovo il 'TOS20_' dal codice
81  # ~codice = articolo.attrib['codice'].split('_')[1]
82  codice = articolo.attrib['codice']
83 
84  # divide il codice per ottenere i codici di supercategoria e categoria
85  codiceSplit = codice.split('.')
86  codiceSuperCat = codiceSplit[0]
87  codiceCat = codiceSuperCat + '.' + codiceSplit[1]
88 
89  # estrae supercategoria e categoria
90  superCat = articolo.find('tipo').text
91  cat = articolo.find('capitolo').text
92 
93  # li inserisce se necessario nelle liste
94  if not codiceSuperCat in superCatList:
95  superCatList[codiceSuperCat] = superCat
96  if not codiceCat in catList:
97  catList[codiceCat] = cat
98 
99  voce = articolo.find('voce').text
100  if voce is None:
101  voce = ''
102  art = articolo.find('articolo').text
103  if art is None:
104  art = ''
105  desc = voce + '\n' + art
106 
107  # giochino per garantire che la prima stringa abbia una lunghezza minima
108  # in modo che LO formatti correttamente la cella
109  # ~desc = LeenoImport.fixParagraphSize(desc)
110 
111  # un po' di pulizia nel testo
112  desc = desc.replace(
113  '\t', ' ').replace('\n', ' ').replace('\n\n', '\n').replace('è', 'è').replace(
114  '°', '°').replace('Ã', 'à').replace(' $', '')
115  while ' ' in desc:
116  desc = desc.replace(' ', ' ')
117  while '\n\n' in desc:
118  desc = desc.replace('\n\n', '\n')
119 
120  um = articolo.find('um').text
121  prezzo = articolo.find('prezzo').text
122 
123  # in 'sto benedetto prezzario ci sono numeri (grandi) con un punto
124  # per separare le migliaia OLTRE al punto per separare i decimali
125  # quindi... se trovo più di un punto decimale, devo eliminare i primi
126  if prezzo is not None:
127  if '.' not in prezzo:
128  prezzo = prezzo + '.0'
129  prSplit = prezzo.split('.')
130  prezzo = ''
131  for p in prSplit[0:-1]:
132  prezzo += p
133  prezzo += '.' + prSplit[-1]
134  prezzo = float(prezzo)
135 
136  analisi = articolo.find('Analisi')
137  if analisi is not None:
138  # se c'è l'analisi, estrae incidenza MDO e costi sicurezza da quella
139  try:
140  oneriSic = float(analisi.find('onerisicurezza').attrib['valore'])
141  except Exception:
142  oneriSic = ''
143 
144  try:
145  mdo = float(analisi.find('incidenzamanodopera').attrib['percentuale']) / 100
146  except Exception:
147  mdo = ''
148  else:
149  # niente analisi, la voce non dispone di incidenza MDO e costi sicurezza
150  oneriSic = ''
151  mdo = ''
152 
153  # compone l'articolo e lo mette in lista
154  artList[codice] = {
155  'codice': codice,
156  'desc': desc,
157  'um': um,
158  'prezzo': prezzo,
159  'mdo': mdo,
160  'sicurezza': oneriSic
161  }
162 
163  # ritorna un dizionario contenente tutto il necessario
164  # per costruire l'elenco prezzi
165  return {
166  'titolo': titolo,
167  'superCategorie': superCatList,
168  'categorie': catList,
169  'articoli' : artList
170  }
LeenoImport_XmlToscana.parseXML
def parseXML(data, defaultTitle=None)
Definition: LeenoImport_XmlToscana.py:17
LeenoImport.stripXMLNamespaces
def stripXMLNamespaces(data)
Definition: LeenoImport.py:47