def initialize(): """ Inizializzazione delle variabili globali :return None """ global aqua_data, fpro, tipo_lettura, fprol, fproc, fprot, fpros, logger try: # Controllo presenza dei dati dell'azienda if 'Fatpro' not in aqua_data: raise DataMissingError('', "Mancano i dati dell'azienda.") fpro = aqua_data['Fatpro'][0] tipo_lettura = fpro.fp_tipo_let logger.prefix_info("Utente:\t[%d/%s]", fpro.fp_aconto, fpro.fp_azienda) logger.prefix_info("Lettura:\t[%s/%d/%d %s]", tipo_lettura, fpro.fp_numlet_pr, fpro.fp_numlet_aa, fpro.fp_data_let) if fpro.fp_periodo <= 0: raise InvalidDataError('', 'Il periodo non può essere di 0 giorni.') # Controllo della presenza delle letture if 'Fatprol' not in aqua_data: raise DataMissingError('', "Mancano le letture.") fprol = aqua_data['Fatprol'] if 'Fatprol' in aqua_data else None # Controllo della presenza delle tariffe if 'Fatprot' not in aqua_data: raise DataMissingError('', "Mancano le tariffe.") fprot = sorted(aqua_data['Fatprot'], key=lambda t: (t.fpt_vigore, t.fpt_codtar, t.fpt_colonna)) # Controllo della presenza dei costi if 'Fatproc' not in aqua_data: raise DataMissingError("", "Mancano i costi.") # Filtro le righe con quantità 0 fproc = [c for c in aqua_data['Fatproc'] if c.fpc_qta != 0] # Il codice 'CS' deve essere presente if len([c for c in fproc if c.fpc_bcodart == 'CS']) == 0: raise CostCodeMissingError( "", "Mancano le Competenze di Servizio (cod. CS).") # Controllo della presenza degli storni e filtro le righe con quantità 0 if 'Fatpros' not in aqua_data: logger.prefix_warn("Non sono stati specificati storni.") else: fpros = [s for s in aqua_data['Fatpros'] if s.fps_qta != 0] except: logger.error("Errore durante l'inizializzazione!") raise
def costo_acqua_calda(qta): """ Calcola il costo dell'acqua calda :param qta: <int> - Quantità consumata :return <Output()> """ assert isinstance(qta, (int, Decimal)) codart = 'AC' if tipo_lettura == 'R' else 'ACS' try: ac = [x for x in fproc if x.fpc_bcodart == codart][0] importo = ac.fpc_costo return output_line(ac.fpc_bgiorni, 'C', codart, qta, importo) except: raise DataMissingError( '', "Nei costi manca il codice '{0}'".format(codart))
def main(): global results # Isolamento letture casa da letture garage letture_casa = [x for x in fprol if x.fpl_garage == ''] letture_garage = [x for x in fprol if x.fpl_garage == 'G'] # Consumi casa mc_consumo_fredda_casa = consumo_mc( [x for x in letture_casa if x.fpl_fc == 0]) mc_consumo_calda_casa = consumo_mc( [x for x in letture_casa if x.fpl_fc == 1]) # Consumi garage mc_consumo_fredda_garage = consumo_mc( [x for x in letture_garage if x.fpl_fc == 0]) mc_consumo_calda_garage = consumo_mc( [x for x in letture_garage if x.fpl_fc == 1]) # ---------------------------------------------------------------------------------------------- ## Consumi totali - Attenzione: nei consorzi l'acqua calda NON SI SOMMA # ---------------------------------------------------------------------------------------------- mc_consumo_totale_garage = mc_consumo_fredda_garage # + mc_consumo_calda_garage mc_consumo_totale_casa = mc_consumo_fredda_casa # + mc_consumo_calda_casa mc_consumo_totale_calda = mc_consumo_calda_casa + mc_consumo_calda_garage # mc_consumo_totale_fredda = mc_consumo_fredda_casa + mc_consumo_fredda_garage mc_consumo_totale = mc_consumo_totale_casa + mc_consumo_totale_garage # ---------------------------------------------------------------------------------------------- # Periodo di riferimento dei consumi end_date = fpro.fp_data_let start_date = end_date - timedelta(days=fpro.fp_periodo) # Consumi gt = giorni_tariffe(start_date, end_date) if len([gt.items()]) == 0: msg = 'Nessuna tariffa applicabile al periodo specificato [{0} - {1}].'.format( start_date, end_date) raise InvalidDataError('', msg) # Lista ordinata di date di inizio periodo. Serve per dare un ordinamento ai record in output # (nella tupla delle chiavi di 'gt' il primo elemento è la data di inizio del periodo) periodi = sorted(set([x[0] for x in gt.keys()])) for k in gt.keys(): data_vigore = k[0] # Per ogni periodo di tariffazione numfat viene incrementato di 1000 * (ordinale_periodo - 1) # Es: 1^ periodo: numfat + 1000 * 0 = numfat, 2^ periodo = numfat + 1000 * 1 = numfat + 1000, ecc. # In pratica il moltiplicatore è l'indice della data di inizio periodo nella lista ordinata "periodi" def ordina_tariffe(o): o.fpo_numfat += 1000 * periodi.index(data_vigore) return o res = [] ts = [ x for x in fprot if x.fpt_vigore == data_vigore and x.fpt_codtar == k[1] ] consumo = Decimal(round(mc_consumo_totale / fpro.fp_periodo * gt[k])) for tar in ts: qty = 0 if tar.fpt_codtar[0] == 'A': if consumo > 0: sc = scaglione(tar, gt[k]) qty = sc if consumo > sc else consumo consumo -= qty else: qty = consumo if tar.fpt_costo_um == 'MC' else gt[k] if qty != 0: res += [ordina_tariffe(costo(tar, qty))] results += res # Per non aver problemi con l'ordinamento dell'output in caso di più di due periodi di tariffazione # impongo l'ordinamento a numfat + 1000 * numero di scadenze # Es. se ci sono 2 periodi sarà: nufat + 1000 * 2 = numfat + 2000 def ordina(o): o.fpo_numfat += 1000 * len(periodi) return o # Acqua calda, se presente try: if mc_consumo_totale_calda > 0: results += [ordina(costo_acqua_calda(mc_consumo_totale_calda))] except: msg = "Consumo acqua calda > 0 (mc {0}) ma non sono presenti i relativi costi".format( mc_consumo_totale_calda) raise DataMissingError("Fatproc", msg) # Costi results += [ordina(c) for c in altri_costi()] # Storni if fpros: results += [ ordina(s) for s in [calcolo_storno(fps) for fps in compatta_storni(fpros)] ] # Ordino i risultati rispetto fpo_numfat results.sort(key=lambda r: r.fpo_numfat) write_output(results) logger.debug('main(): Results written to %s', basename(globals()['output_filename']))