def try_and_close_adozione(piano: Piano): logger.warning('check_and_close_adozione') procedura_adozione: ProceduraAdozione = piano.procedura_adozione if not procedura_adozione.conclusa: piano_controdedotto = piano.getFirstAction( TipologiaAzione.piano_controdedotto) rev_piano_post_cp = piano.getFirstAction( TipologiaAzione.rev_piano_post_cp) _procedura_adozione_vas = ProceduraAdozioneVAS.objects.filter( piano=piano).last() if is_executed(piano_controdedotto) \ and (not procedura_adozione.richiesta_conferenza_paesaggistica or is_executed(rev_piano_post_cp)) \ and (not _procedura_adozione_vas or _procedura_adozione_vas.conclusa): logger.warning('CHIUSURA FASE ADOZIONE') chiudi_pendenti(piano, attesa=True, necessaria=False) procedura_adozione.conclusa = True procedura_adozione.save() procedura_approvazione, created = ProceduraApprovazione.objects.get_or_create( piano=piano) piano.procedura_approvazione = procedura_approvazione piano.save() return True return False
def check_and_promote(piano: Piano, info_to_be_removed=None): logger.warning('Check promozione per piano [{c}]:"{d}" '.format( c=piano.codice, d=piano.descrizione)) eligible, errs = auth_piano.is_eligible_for_promotion(piano) if eligible: logger.warning('Promozione Piano [{c}]:"{d}"'.format( c=piano.codice, d=piano.descrizione)) # if piano.fase == Fase.ANAGRAFICA: # ensure_avvio_objects(piano) piano.fase = _fase = piano.fase.getNext() piano.save() logger.warning("PIANO PROMOSSO {}".format(piano)) # Notify Users piano_phase_changed.send_robust( sender=Piano, piano=piano, message_type=TipoMail.piano_phase_changed) promuovi_piano(_fase, piano) return True, [] else: logger.warning('Piano [{c}]:"{d}" non promosso'.format( c=piano.codice, d=piano.descrizione)) for err in errs: logger.warning(' -> {}'.format(err)) return False, errs
def check_join_pubblicazione_provvedimento(info, piano: Piano): pp_ap = piano.getFirstAction( TipologiaAzione.pubblicazione_provvedimento_verifica_ap) pp_ac = piano.getFirstAction( TipologiaAzione.pubblicazione_provvedimento_verifica_ac) if is_executed(pp_ap) and is_executed(pp_ac): _vas: ProceduraVAS = piano.procedura_vas if not _vas.assoggettamento: _vas.conclusa = True _vas.save() if try_and_close_avvio(piano): check_and_promote(piano, info) else: if _vas.tipologia == TipologiaVAS.PROCEDIMENTO_SEMPLIFICATO: crea_azione( Azione(piano=piano, tipologia=TipologiaAzione.redazione_documenti_vas, qualifica_richiesta=QualificaRichiesta.COMUNE, stato=StatoAzione.NECESSARIA)) else: crea_azione( Azione(piano=piano, tipologia=TipologiaAzione.invio_doc_preliminare, qualifica_richiesta=QualificaRichiesta.COMUNE, stato=StatoAzione.NECESSARIA))
def check_join_redazione_documenti_vas(user, piano: Piano): tp_sca = piano.getFirstAction(TipologiaAzione.trasmissione_pareri_sca) tp_ac = piano.getFirstAction(TipologiaAzione.trasmissione_pareri_ac) if is_executed(tp_sca) and is_executed(tp_ac): crea_azione( Azione(piano=piano, tipologia=TipologiaAzione.redazione_documenti_vas, qualifica_richiesta=QualificaRichiesta.COMUNE, stato=StatoAzione.NECESSARIA)) return True return False
def require_action(piano: Piano, tipo_file, tipo_risorsa: TipoRisorsa, tipo_azione: TipologiaAzione): if tipo_file == tipo_risorsa.value: _az = piano.getFirstAction(tipo_azione) if _az is None: raise GraphQLError('Risorsa inaspettata: azione richiesta "{}"'.format(tipo_azione.value), code=403) if is_scaduta(_az) or is_executed(_az): raise GraphQLError('Risorsa non più accettabile', code=403)
def update_actions_for_phase(cls, fase, piano: Piano, procedura_avvio, user): # Update Azioni Piano # - Update Action state accordingly ensure_fase(fase, Fase.ANAGRAFICA) _integrazioni_richieste = piano.getFirstAction( TipologiaAzione.integrazioni_richieste) if needs_execution(_integrazioni_richieste): chiudi_azione(_integrazioni_richieste) try_and_close_avvio(piano)
def try_and_close_avvio(piano: Piano): procedura_avvio: ProceduraAvvio = piano.procedura_avvio procedura_vas: ProceduraVAS = piano.procedura_vas _conferenza_copianificazione_attiva = \ needs_execution(piano.getFirstAction(TipologiaAzione.richiesta_conferenza_copianificazione)) or \ needs_execution(piano.getFirstAction(TipologiaAzione.esito_conferenza_copianificazione)) _richiesta_integrazioni = piano.getFirstAction( TipologiaAzione.richiesta_integrazioni) _integrazioni_richieste = piano.getFirstAction( TipologiaAzione.integrazioni_richieste) _protocollo_genio_civile = piano.getFirstAction( TipologiaAzione.protocollo_genio_civile) _formazione_del_piano = piano.getFirstAction( TipologiaAzione.formazione_del_piano) if not _conferenza_copianificazione_attiva and \ is_executed(_protocollo_genio_civile) and \ is_executed(_formazione_del_piano) and \ (not procedura_avvio.richiesta_integrazioni or (is_executed(_integrazioni_richieste))) and \ (not procedura_vas or procedura_vas.conclusa or procedura_vas.tipologia == TipologiaVAS.NON_NECESSARIA): if procedura_vas and procedura_vas.conclusa: chiudi_pendenti(piano, attesa=True, necessaria=False) procedura_avvio.conclusa = True procedura_avvio.save() PianoControdedotto.objects.get_or_create(piano=piano) PianoRevPostCP.objects.get_or_create(piano=piano) procedura_adozione, created = ProceduraAdozione.objects.get_or_create( piano=piano) piano.procedura_adozione = procedura_adozione piano.save() return True return False
def mutate_and_get_payload(cls, root, info, **input): try: _piano_data = input.get('piano_operativo') # Ente (M) _data = _piano_data.pop('ente') _ente = Organization.objects.get(usermembership__member=info.context.user, code=_data['code']) _piano_data['ente'] = _ente if rules.test_rule('strt_users.is_RUP_of', info.context.user, _ente): # Codice (M) if 'codice' in _piano_data: _data = _piano_data.pop('codice') _codice = _data else: _year = str(datetime.date.today().year)[2:] _month = datetime.date.today().month _piano_id = Piano.objects.filter(ente=_ente).count() + 1 _codice = '%s%02d%02d%05d' % (_ente.code, int(_year), _month, _piano_id) _piano_data['codice'] = _codice # Fase (O) if 'fase' in _piano_data: _data = _piano_data.pop('fase') _fase = Fase.objects.get(codice=_data['codice']) else: _fase = Fase.objects.get(codice='FP255') _piano_data['fase'] = _fase # Descrizione (O) if 'descrizione' in _piano_data: _data = _piano_data.pop('descrizione') _piano_data['descrizione'] = _data[0] _piano_data['user'] = info.context.user _piano = Piano() nuovo_piano = update_create_instance(_piano, _piano_data) _procedura_vas = ProceduraVAS() _procedura_vas.piano = nuovo_piano _procedura_vas.ente = nuovo_piano.ente _procedura_vas.tipologia = TIPOLOGIA_VAS.semplificata _procedura_vas.save() return cls(nuovo_piano=nuovo_piano) else: return GraphQLError(_("Forbidden"), code=403) except BaseException as e: tb = traceback.format_exc() logger.error(tb) return GraphQLError(e, code=500)
def mutate_and_get_payload(cls, root, info, **input): try: _piano_data = input.get('piano_operativo') # Ente (M) _data = _piano_data.pop('ente') _ente = Organization.objects.get( usermembership__member=info.context.user, code=_data['code']) _piano_data['ente'] = _ente if info.context.user and rules.test_rule('strt_users.is_RUP_of', info.context.user, _ente): # Codice (M) if 'codice' in _piano_data: _data = _piano_data.pop('codice') _codice = _data else: _year = str(datetime.date.today().year)[2:] _month = datetime.date.today().month _piano_id = Piano.objects.filter(ente=_ente).count() + 1 _codice = '%s%02d%02d%05d' % (_ente.code, int(_year), _month, _piano_id) _piano_data['codice'] = _codice # Fase (O) if 'fase' in _piano_data: _data = _piano_data.pop('fase') _fase = Fase.objects.get(codice=_data['codice']) else: _fase = Fase.objects.get(codice='FP255') _piano_data['fase'] = _fase # Descrizione (O) if 'descrizione' in _piano_data: _data = _piano_data.pop('descrizione') _piano_data['descrizione'] = _data[0] _piano_data['user'] = info.context.user _piano = Piano() # Inizializzazione Azioni del Piano _order = 0 _azioni_piano = [] for _a in AZIONI_BASE[_fase.nome]: _azione = Azione(tipologia=_a["tipologia"], attore=_a["attore"], order=_order) _azioni_piano.append(_azione) _order += 1 # Inizializzazione Procedura VAS _procedura_vas = ProceduraVAS() _procedura_vas.tipologia = TIPOLOGIA_VAS.semplificata nuovo_piano = update_create_instance(_piano, _piano_data) _procedura_vas.piano = nuovo_piano _procedura_vas.ente = nuovo_piano.ente _procedura_vas.save() for _ap in _azioni_piano: _ap.save() AzioniPiano.objects.get_or_create(azione=_ap, piano=nuovo_piano) _creato = nuovo_piano.azioni.filter( tipologia=TIPOLOGIA_AZIONE.creato_piano).first() if _creato: _creato.stato = STATO_AZIONE.necessaria _creato.save() return cls(nuovo_piano=nuovo_piano) else: return GraphQLError(_("Forbidden"), code=403) except BaseException as e: tb = traceback.format_exc() logger.error(tb) return GraphQLError(e, code=500)
def is_eligible_for_promotion(piano:Piano): logger.warning("Is eligible for promotion {p} {f}".format(p=piano, f=piano.fase)) msg = [] load_pending_alerts(piano, msg) if piano.fase == Fase.DRAFT: # rules.add_rule('strt_core.api.fase_anagrafica_completa', # ~has_pending_alerts & # is_draft & # has_data_delibera & # has_description & # has_delibera_comunale & # has_soggetto_proponente & # has_procedura_vas & # vas_rules.procedura_vas_is_valid # load_pending_alerts(piano, msg) # if not is_draft(piano): # msg.append("Piano non in stato di bozza") if piano.data_delibera is None: msg.append("Data delibera non impostata") if piano.descrizione is None: msg.append("Descrizione non impostata") if not has_delibera_comunale(piano): msg.append("Delibera comunale mancante") if piano.soggetto_proponente is None: msg.append("Soggetto proponente mancante") if not ProceduraVAS.objects.filter(piano=piano).exists(): msg.append("Procedura VAS mancante") vas_ok, vas_msg = auth_vas.procedura_vas_is_valid(piano) if not vas_ok: msg = msg + vas_msg return len(msg) == 0, msg elif piano.fase == Fase.ANAGRAFICA: # rules.add_rule('strt_core.api.fase_avvio_completa', # ~has_pending_alerts & # is_anagrafica & # protocollo_genio_inviato & # formazione_piano_conclusa & # has_procedura_avvio & # avvio_piano_conclusa & # (~has_procedura_vas | vas_piano_conclusa) # ) # if has_pending_alerts(piano): # msg.append("Ci sono azioni non ancora completate") if not is_executed(piano.getFirstAction(TipologiaAzione.protocollo_genio_civile)): msg.append("Protocollo Genio Civile mancante") if not formazione_piano_conclusa(piano): msg.append("Formazione piano non conclusa") if not ProceduraAvvio.objects.filter(piano=piano).exists(): msg.append("Procedura di avvio mancante") if not avvio_piano_conclusa(piano): msg.append("Procedura di avvio non conclusa") if not vas_piano_conclusa(piano): msg.append("Procedura VAS non conclusa") return len(msg) == 0, msg elif piano.fase == Fase.AVVIO: # rules.add_rule( # 'strt_core.api.fase_adozione_completa', # ~has_pending_alerts & # is_avvio & # has_procedura_adozione & # adozione_piano_conclusa & # (~has_procedura_adozione_vas | adozione_vas_piano_conclusa) # ) # if has_pending_alerts(piano): # msg.append("Ci sono azioni non ancora completate") _procedura_adozione = ProceduraAdozione.objects.filter(piano=piano).first() if not _procedura_adozione: msg.append("Procedura di adozione mancante") if not _procedura_adozione.conclusa: msg.append("Procedura di adozione non conclusa") _procedura_adozione_vas = ProceduraAdozioneVAS.objects.filter(piano=piano).first() if _procedura_adozione_vas and not _procedura_adozione_vas.conclusa: msg.append("Procedura AdozioneVAS non conclusa") return len(msg) == 0, msg elif piano.fase == Fase.ADOZIONE: # rules.add_rule( # 'strt_core.api.fase_approvazione_completa', # ~has_pending_alerts & # is_adozione & # has_procedura_approvazione & # approvazione_piano_conclusa # ) _procedura_approvazione = ProceduraApprovazione.objects.filter(piano=piano).first() if not _procedura_approvazione: msg.append("Procedura di approvazione mancante") if not _procedura_approvazione.conclusa: msg.append("Procedura di approvazione non conclusa") return len(msg) == 0, msg else: raise Exception('Fase non riconosciute [{}]'.format(piano.fase))
def mutate_and_get_payload(cls, root, info, **input): try: _piano_data = input.get('piano_operativo') # Ente (M) _data = _piano_data.pop('ente') _ente = Ente.objects.get(ipa=_data['ipa']) # _role = info.context.session.get('role', None) # _token = info.context.session.get('token', None) _piano_data['ente'] = _ente if not info.context.user: return GraphQLError("Unauthorized", code=401) if not _ente.is_comune(): return GraphQLError("Ente deve essere un comune", code=400) if not auth.can_create_piano(info.context.user, _ente): return GraphQLError("Forbidden: user can't create piano", code=403) # create Piano and assign id _piano = Piano() _piano.ente = _ente # mandatory field _piano.codice = "temp" # mandatory field _piano.save() # Codice (M) if 'codice' in _piano_data: _codice = _piano_data.pop('codice') else: _year = str(datetime.date.today().year)[2:] _month = datetime.date.today().month _codice = '%s%02d%02d%05d' % (_ente.ipa, int(_year), _month, _piano.id) _piano_data['codice'] = _codice # Fase (O) _fase = None if 'fase' in _piano_data: _data = _piano_data.pop('fase') _fase = Fase.fix_enum(_data, none_on_error=True) _fase = _fase if _fase else Fase.DRAFT _piano_data['fase'] = _fase # Descrizione (O) if 'descrizione' in _piano_data: _data = _piano_data.pop('descrizione') _piano_data['descrizione'] = _data[0] if 'tipologia' in _piano_data: _tipologia = _piano_data.pop('tipologia') _tipologia = TipologiaPiano.fix_enum(_tipologia, none_on_error=True) _piano_data['tipologia'] = _tipologia _piano_data['responsabile'] = info.context.user # Crea piano # _piano = Piano() nuovo_piano = update_create_instance(_piano, _piano_data) # Aggiunta soggetti operanti di default for qu in QualificaUfficio.get_soggetti_default(): so = SoggettoOperante(piano=nuovo_piano, qualifica_ufficio=qu) so.save() # Inizializzazione Azioni del Piano _order = 0 for _a in AZIONI_BASE[_fase]: crea_azione( Azione(piano=nuovo_piano, tipologia=_a["tipologia"], qualifica_richiesta=_a["qualifica"], stato=_a.get('stato', None), order=_order)) _order += 1 # Inizializzazione Procedura VAS _procedura_vas, created = ProceduraVAS.objects.get_or_create( piano=nuovo_piano, tipologia=TipologiaVAS.UNKNOWN) # Inizializzazione Procedura Avvio _procedura_avvio, created = ProceduraAvvio.objects.get_or_create( piano=nuovo_piano) nuovo_piano.procedura_vas = _procedura_vas nuovo_piano.procedura_avvio = _procedura_avvio nuovo_piano.save() return cls(nuovo_piano=nuovo_piano) except BaseException as e: tb = traceback.format_exc() logger.error(tb) return GraphQLError(e, code=500)
def init_vas_procedure(piano: Piano, utente: Utente): procedura_vas = piano.procedura_vas _selezione_tipologia_vas = piano.getFirstAction( TipologiaAzione.selezione_tipologia_vas) now = get_now() if needs_execution(_selezione_tipologia_vas): chiudi_azione(_selezione_tipologia_vas, now) else: raise GraphQLError("Stato inconsistente nell'inizializzazione VAS", code=500) if procedura_vas.tipologia == TipologiaVAS.NON_NECESSARIA: pass elif procedura_vas.tipologia == TipologiaVAS.PROCEDURA_ORDINARIA: crea_azione( Azione( piano=piano, tipologia=TipologiaAzione.invio_doc_preliminare, qualifica_richiesta=QualificaRichiesta.COMUNE, stato=StatoAzione.ATTESA, )) elif procedura_vas.tipologia == TipologiaVAS.VERIFICA: crea_azione( Azione( piano=piano, tipologia=TipologiaAzione.trasmissione_dpv_vas, qualifica_richiesta=QualificaRichiesta.AC, stato=StatoAzione.ATTESA, ).imposta_scadenza( get_scadenza(now, TipoExpire.TRASMISSIONE_DPV_VAS))) elif procedura_vas.tipologia == TipologiaVAS.VERIFICA_SEMPLIFICATA: crea_azione( Azione( piano=piano, tipologia=TipologiaAzione.emissione_provvedimento_verifica, qualifica_richiesta=QualificaRichiesta.AC, stato=StatoAzione.ATTESA, ).imposta_scadenza( get_scadenza(now, TipoExpire.EMISSIONE_PV_VERIFICASEMPLIFICATA))) elif procedura_vas.tipologia == TipologiaVAS.PROCEDIMENTO_SEMPLIFICATO: crea_azione( Azione( piano=piano, tipologia=TipologiaAzione.pareri_verifica_sca, qualifica_richiesta=QualificaRichiesta.SCA, stato=StatoAzione.ATTESA, ).imposta_scadenza( get_scadenza( now, TipoExpire.PARERI_VERIFICA_SCA_PROCEDIMENTOSEMPLIFICATO))) # AC deve essere notificato piano_phase_changed.send( message_type=TipoMail.trasmissione_dp_vas, sender=Piano, piano=piano, user=utente, )