2 LeenO - modulo di importazione prezzari
7 from com.sun.star.beans
import PropertyValue
9 from io
import StringIO
10 import xml.etree.ElementTree
as ET
14 import LeenoDialogs
as DLG
20 import LeenoImport_XmlSix
21 import LeenoImport_XmlToscana
22 import LeenoImport_XmlSardegna
23 import LeenoImport_XmlLiguria
24 import LeenoImport_XmlVeneto
25 import LeenoImport_XmlBasilicata
30 corregge il paragrafo della descrizione negli elenchi prezzi
31 in modo che LibreOffice calcoli correttamente l'altezza della cella
34 splitted = txt.split(
'\n')
38 if len(spl0) + len(spl1) < minLen:
39 dl = minLen - len(spl0) - len(spl1)
40 spl0 = spl0 + dl *
" "
41 txt = spl0 +
'\n' + spl1
42 for t
in splitted[2:]:
49 prende una stringa contenente un file XML
50 elimina i namespaces dai dati
51 e ritorna il root dell' XML
53 it = ET.iterparse(StringIO(data))
56 _, _, el.tag = el.tag.rpartition(
'}')
62 fa un pre-esame del contenuto xml della stringa fornita
63 per determinare se si tratta di un tipo noto
64 (nel qual caso fornisce un parser adatto) oppure no
65 (nel qual caso avvisa di inviare il file allo staff)
69 'xmlns="six.xsd"': LeenoImport_XmlSix.parseXML,
70 'autore="Regione Toscana"': LeenoImport_XmlToscana.parseXML,
71 'autore="Regione Sardegna"': LeenoImport_XmlSardegna.parseXML,
72 'autore="Regione Liguria"': LeenoImport_XmlLiguria.parseXML,
73 'rks=': LeenoImport_XmlVeneto.parseXML,
74 '<pdf>Prezzario_Regione_Basilicata': LeenoImport_XmlBasilicata.parseXML,
78 for pattern, xmlParser
in parsers.items():
79 if pattern
in xmlText:
88 Scrive la pagina dell' Elenco Prezzi di un documento LeenO
89 Il documento deve essere vuoto (appena creato)
90 I dati DEVONO essere nel formato seguente :
100 artList = { codice : articolo, ... }
102 superCatList = { codice : descrizione, ... }
103 catList = { codice : descrizione, ... }
107 'superCategorie': superCatList,
108 'categorie': catList,
112 progress è una progressbar già visualizzata
118 artList = dati[
'articoli']
119 superCatList = dati[
'superCategorie']
120 catList = dati[
'categorie']
121 for codice, desc
in superCatList.items():
130 for codice, desc
in catList.items():
141 sortedArtList = sorted(artList.items())
148 for item
in sortedArtList:
150 prezzo = itemData[
'prezzo']
151 mdo = itemData[
'mdo']
165 itemData[
'sicurezza'],
171 numItems = len(artArray)
172 numColumns = len(artArray[0])
174 oSheet = oDoc.getSheets().getByName(
'S2')
175 oSheet.getCellByPosition(2, 2).String = dati[
'titolo']
176 oSheet = oDoc.getSheets().getByName(
'Elenco Prezzi')
177 oSheet.getCellByPosition(1, 0).String = dati[
'titolo']
178 oSheet.getRows().insertByIndex(4, numItems)
185 progress.setLimits(0, numItems)
190 while item < numItems:
191 progress.setValue(item)
192 sliced = artArray[item:item + step]
194 oRange = oSheet.getCellRangeByPosition(
198 startCol + numColumns - 1,
199 startRow + item + num - 1)
200 oRange.setDataArray(sliced)
211 Routine di importazione di un prezzario XML in tabella Elenco Prezzi
219 defaultTitle = os.path.split(filename)[1]
222 with open(filename,
'r', errors=
'ignore', encoding=
"utf8")
as file:
229 if xmlParser
is None:
231 Title =
"File sconosciuto",
232 Text =
"Il file fornito sembra di tipo sconosciuto.\n\n"
233 "Puoi riprovare cambiandone l'estensione in .XPWE quindi\n"
234 "utilizzando la relativa voce di menù per l'importazione.\n\n"
235 "In caso di nuovo errore, puoi inviare una copia del file\n"
236 "allo staff di LeenO affinchè il suo formato possa essere\n"
237 "importato dalla prossima versione del programma.\n\n"
242 dati = xmlParser(data, defaultTitle)
256 oDoc = PL.creaComputo(0)
261 Title=
"Importazione prezzario",
262 Text=
"Compilazione prezzario in corso")
269 oSheet = oDoc.getSheets().getByName(
'Elenco Prezzi')
270 oDoc.CurrentController.setActiveSheet(oSheet)
273 Dialogs.Ok(Text=f
'Importate {len(dati["articoli"])} voci\ndi elenco prezzi')
280 oSheet.getCellByPosition(11, 3).String =
''
281 oSheet.getCellByPosition(12, 3).String =
''
282 oSheet.getCellByPosition(13, 3).String =
''
283 oSheet.getCellByPosition(0, 3).String =
'000'
284 oSheet.getCellByPosition(1, 3).String =
'''ATTENZIONE!
285 1. Lo staff di LeenO non si assume alcuna responsabilità riguardo al contenuto del prezzario.
286 2. L’utente finale è tenuto a verificare il contenuto dei prezzari sulla base di documenti ufficiali.
287 3. L’utente finale è il solo responsabile degli elaborati ottenuti con l'uso di questo prezzario.
288 N.B.: Si rimanda ad una attenta lettura delle note informative disponibili sul sito istituzionale ufficiale di riferimento prima di accedere al prezzario.'''
291 Text=
'''Vuoi ripulire le descrizioni dagli spazi e dai salti riga in eccesso?
293 L'OPERAZIONE POTREBBE RICHIEDERE DEL TEMPO E
294 LibreOffice POTREBBE SEMBRARE BLOCCATO!
296 Vuoi procedere comunque?''') == 0:
299 oRange = oDoc.NamedRanges.elenco_prezzi.ReferredCells.RangeAddress
300 SR = oRange.StartRow + 1
302 oDoc.CurrentController.select(oSheet.getCellRangeByPosition(1, SR, 1, ER -1))
306 PL.struttura_Elenco()
307 oSheet.getCellRangeByName(
'E2').Formula =
'=COUNT(E:E) & " prezzi"'
308 dest = filename[0:-4]+
'.ods'
315 Title =
"Importazione eseguita con successo!",
318 1. Lo staff di LeenO non si assume alcuna responsabilità riguardo al contenuto del prezzario.
319 2. L’utente finale è tenuto a verificare il contenuto dei prezzari sulla base di documenti ufficiali.
320 3. L’utente finale è il solo responsabile degli elaborati ottenuti con l'uso di questo prezzario.
322 N.B.: Si rimanda ad una attenta lettura delle note informative disponibili
323 sul sito istituzionale ufficiale prima di accedere al Prezzario.'''
340 threading.Thread.__init__(self)
349 Esegue la conversione di un listino (formato LeenO) in template Computo
352 oSheet = oDoc.CurrentController.ActiveSheet
356 lista_articoli = list()
357 nome = oSheet.getCellByPosition(2, 0).String
363 assembla = DLG.DlgSiNo(
364 '''Il riconoscimento di descrizioni e sottodescrizioni
365 dipende dalla colorazione di sfondo delle righe.
367 Nel caso in cui questa fosse alterata, il risultato finale
368 della conversione potrebbe essere inatteso.
370 Considera anche la possibilità di recuperare il formato XML(SIX)
371 di questo prezzario dal sito ufficiale dell'ente che lo rilascia.
373 Vuoi assemblare descrizioni e sottodescrizioni?''',
'Richiesta')
374 oDialogo_attesa = DLG.dlg_attesa()
378 PL.colora_vecchio_elenco()
380 dest0 = orig[0:-4] +
'_new.ods'
382 orig = uno.fileUrlToSystemPath(PL.LeenO_path() +
'/template/leeno/Computo_LeenO.ots')
383 dest = uno.fileUrlToSystemPath(dest0)
385 PL.shutil.copyfile(orig, dest)
388 tariffa = oSheet.getCellByPosition(2, el).String
389 descrizione = oSheet.getCellByPosition(4, el).String
390 um = oSheet.getCellByPosition(6, el).String
391 sic = oSheet.getCellByPosition(11, el).String
392 prezzo = oSheet.getCellByPosition(7, el).String
393 mdo_p = oSheet.getCellByPosition(8, el).String
394 mdo = oSheet.getCellByPosition(9, el).String
395 if oSheet.getCellByPosition(2,
396 el).CellBackColor
in (16777072, 16777120,
408 elif oSheet.getCellByPosition(2,
409 el).CellBackColor
in (16777168, 15794160,
424 descrizione = oSheet.getCellByPosition(4, el).String
426 descrizione = madre +
' \n- ' + oSheet.getCellByPosition(
437 lista_articoli.append(articolo)
438 oDialogo_attesa.endExecute()
442 oDialogo_attesa = DLG.dlg_attesa()
445 oSheet = oDoc.getSheets().getByName(
'S2')
446 oSheet.getCellByPosition(2, 2).String = nome
447 oSheet = oDoc.getSheets().getByName(
'Elenco Prezzi')
448 oSheet.getCellByPosition(1, 1).String = nome
450 oSheet.getRows().insertByIndex(4, len(lista_articoli))
451 lista_come_array = tuple(lista_articoli)
453 colonne_lista = len(lista_come_array[1]
457 oRange = oSheet.getCellRangeByPosition(
462 oRange.setDataArray(lista_come_array)
463 oSheet.getRows().removeByIndex(3, 1)
464 oDoc.CurrentController.setActiveSheet(oSheet)
465 oDialogo_attesa.endExecute()
467 PL.struttura_Elenco()
468 DLG.MsgBox(
'Conversione eseguita con successo!',
'')
475 Adatta la struttura del prezzario rilasciato dalla regione Emilia Romagna
477 *** IMPRATICABILE: IL FILE DI ORIGINE È PARECCHIO DISORDINATO ***
479 Il risultato ottenuto va inserito in Elenco Prezzi.
483 oSheet = oDoc.CurrentController.ActiveSheet
485 for i
in range(0, fine):
486 if len(oSheet.getCellByPosition(0, i).String.split(
'.')) == 3
and \
487 oSheet.getCellByPosition(3, i).Type.value !=
'EMPTY':
488 madre = oSheet.getCellByPosition(1, i).String
489 elif len(oSheet.getCellByPosition(0, i).String.split(
'.')) == 4:
490 if oSheet.getCellByPosition(1, i).String !=
'':
491 oSheet.getCellByPosition(1, i).String = (
494 oSheet.getCellByPosition(1, i).String)
496 oSheet.getCellByPosition(1, i).String = madre
497 oSheet.getCellByPosition(4, i).Value = oSheet.getCellByPosition(4, i).Value / 100
504 Adatta la struttura del prezzario rilasciato dalla regione Umbria
506 Il risultato ottenuto va inserito in Elenco Prezzi.
510 oSheet = oDoc.CurrentController.ActiveSheet
511 oSheet.Columns.insertByIndex(4, 1)
512 oSheet.getCellByPosition(4, 0).String =
'Incidenza MdO\n%'
514 for i
in range(1, fine):
515 oSheet.getCellByPosition(0, i).String = oSheet.getCellByPosition(0, i).String
516 if len(oSheet.getCellByPosition(0, i).String.split(
'.')) == 1
and \
517 len(oSheet.getCellByPosition(0, i).String.split(
'.')) == 2:
519 if len(oSheet.getCellByPosition(0, i).String.split(
'.')) == 3
and \
520 oSheet.getCellByPosition(3, i).Type.value !=
'EMPTY':
521 mdo = oSheet.getCellByPosition(5, i).Value
522 prz = oSheet.getCellByPosition(3, i).Value
523 oSheet.getCellByPosition(4, i).Value = mdo / prz
524 if len(oSheet.getCellByPosition(0, i).String.split(
'.')) == 4
and \
525 oSheet.getCellByPosition(3, i).Type.value ==
'EMPTY':
526 madre = oSheet.getCellByPosition(1, i).String
527 if len(oSheet.getCellByPosition(0, i).String.split(
'.')) == 4
and \
528 oSheet.getCellByPosition(3, i).Type.value !=
'EMPTY':
529 oSheet.getCellByPosition(1, i).String = madre +
"\n- " + oSheet.getCellByPosition(1, i).String
530 mdo = oSheet.getCellByPosition(5, i).Value
531 prz = oSheet.getCellByPosition(3, i).Value
532 oSheet.getCellByPosition(4, i).Value = mdo / prz
540 *** da applicare dopo aver unito i file in un unico ODS con Sub _accoda_files_in_unico ***
541 Adatta la struttura del prezzario rilasciato dalla regione Piemonte
542 partendo dalle colonne: Sez. Codice Descrizione U.M. Euro Manod. lorda % Manod. Note
543 Il risultato ottenuto va inserito in Elenco Prezzi.
547 oSheet = oDoc.CurrentController.ActiveSheet
550 for i
in range(0, fine):
551 if len(oSheet.getCellByPosition(1, i).String.split(
'.')) <= 2:
552 cod = oSheet.getCellByPosition(1, i).String
553 des = oSheet.getCellByPosition(2, i).String.replace(
'\n\n',
'\n')
558 if oSheet.getCellByPosition(7, i).String !=
'':
559 des = des +
'\n(' + oSheet.getCellByPosition(7, i).String +
')'
560 elenco.append((cod, des, um,
'', eur, mdo, mdol))
562 if len(oSheet.getCellByPosition(1, i).String.split(
'.')) == 3:
563 cod = oSheet.getCellByPosition(1, i).String
564 des = oSheet.getCellByPosition(2, i).String.replace(
' \n\n',
'')
570 if oSheet.getCellByPosition(7, i).String !=
'':
571 des = des +
'\n(' + oSheet.getCellByPosition(7, i).String +
')'
573 if len(oSheet.getCellByPosition(1, i).String.split(
'.')) == 4:
574 cod = oSheet.getCellByPosition(1, i).String
576 if oSheet.getCellByPosition(2, i).String !=
'...':
577 des = madre +
'\n- ' + oSheet.getCellByPosition(2, i).String.replace(
'\n\n',
'')
578 um = oSheet.getCellByPosition(3, i).String
580 if oSheet.getCellByPosition(4, i).Value != 0:
581 eur = oSheet.getCellByPosition(4, i).Value
583 if oSheet.getCellByPosition(5, i).Value != 0:
584 mdol = oSheet.getCellByPosition(5, i).Value
586 if oSheet.getCellByPosition(6, i).Value != 0:
587 mdo = oSheet.getCellByPosition(6, i).Value
589 elenco.append((cod, des, um,
'', eur, mdo, mdol))
592 oDoc.getSheets().insertNewByName(
'nuova_tabella', 2)
596 PL.GotoSheet(
'nuova_tabella')
597 oSheet = oDoc.getSheets().getByName(
'nuova_tabella')
598 elenco = tuple(elenco)
599 oRange = oSheet.getCellRangeByPosition(0,
604 oRange.setDataArray(elenco)
611 Traduce un particolare formato DAT usato in falegnameria - non c'entra un tubo con LeenO.
612 E' solo una cortesia per un amico.
617 f = open(filename,
'r')
621 riga = (
'Codice',
'Descrizione articolo',
'Quantità',
'Data consegna',
622 'Conto lavoro',
'Prezzo(€)')
627 if art[0:4]
not in (
'HEAD',
'FEET'):
633 dataC =
'=DATE(' + dataC[:4] +
';' + dataC[4:6] +
';' + dataC[
637 riga = (art, des, num, dataC, clav, float(prz.strip()))
641 oSheet = oDoc.CurrentController.ActiveSheet
642 lista_come_array = tuple(ordini)
643 colonne_lista = len(lista_come_array[0]
648 oRange = oSheet.getCellRangeByPosition(
653 oRange.setFormulaArray(lista_come_array)
655 oSheet.getCellRangeByPosition(
659 oDoc.CurrentController.freezeAtPosition(0, 1)
661 oDoc.CurrentController.ShowGrid =
True
662 oSheet.getCellRangeByName(
'A1:F1').CellStyle =
'Accent 3'
668 oFrame = desktop.getCurrentFrame()
669 dispatchHelper = ctx.ServiceManager.createInstanceWithContext(
'com.sun.star.frame.DispatchHelper', ctx)
671 oProp0 = PropertyValue()
672 oProp0.Name =
'Flags'
674 oProp1 = PropertyValue()
675 oProp1.Name =
'FormulaCommand'
677 oProp2 = PropertyValue()
678 oProp2.Name =
'SkipEmptyCells'
680 oProp3 = PropertyValue()
681 oProp3.Name =
'Transpose'
683 oProp4 = PropertyValue()
684 oProp4.Name =
'AsLink'
686 oProp5 = PropertyValue()
687 oProp5.Name =
'MoveMode'
695 properties = tuple(oProp)
697 dispatchHelper.executeDispatch(oFrame,
'.uno:InsertContents',
'', 0, properties)
701 oDoc.CurrentController.select(
702 oDoc.createInstance(
"com.sun.star.sheet.SheetCellRanges"))