link-it / govpay

Porta di accesso al sistema pagoPA
GNU General Public License v3.0
44 stars 22 forks source link

Flussi di rendicontazione mancanti #691

Closed pperliti closed 8 months ago

pperliti commented 8 months ago

Descrizione del Bug Qualora GovPay rifiuti una RT (es. pagamento proveniente da app IO con utilizzo incoerente delle API), il pagamento non viene registrato. Si potrebbe pensare di "recuperarlo" in autonomia una volta che siano disponibili i flussi di rendicontazione (es. rilevazione pagamento rendicontato ma non recepito -> richiesta RT a pagoPA tramite relativa API), tuttavia il flusso contenente il suddetto pagamento potrebbe non essere restituito dalla API /v1/flussiRendicontazione di BO qualora le credenziali di autenticazione utilizzate siano legate ad un ruolo (es. APPLICAZIONE) con visibilità limitata ad un dominio specifico. Il problema non si verifica invece qualora si utilizzi un ruolo con visibilità su tutti gli enti.

Il problema sembra legato a come viene costruita la query per ottenere l'elenco dei flussi di rendicontazione. La query SQL generata nel metodo it.govpay.bd.viste.RendicontazioniBD.count(RendicontazioneFilter filter) invocato da it.govpay.core.dao.pagamenti.RendicontazioniDAO.listaRendicontazioni(...) è infatti diversa a seconda della visibilità sui domini del ruolo utilizzato per l'autenticazione:

  1. Caso ruolo con visibilità su TUTTI i domini:
    SELECT
    TOP 100 PERCENT count(DISTINCT id) as id
    FROM
    (
    SELECT
        TOP 10000 fr.id,
        fr.data_acquisizione
    FROM
        fr
    WHERE
        ( (fr.cod_dominio = 'xxxxxxxxxxx' ) )
        AND ( (fr.data_acquisizione >= '2024-02-08T08:10:00' ) )
        AND ( (fr.data_acquisizione <= '2024-02-09T08:10:00' ) )
        AND ( (fr.obsoleto = 0 ) )
    ORDER BY
        fr.data_acquisizione DESC ) as tabellaNAD;
  2. Caso ruolo con visibilità su un dominio specifico 'xxxxxxxxxxx':
    SELECT
    TOP 100 PERCENT count(DISTINCT id) as id
    FROM
    (
    SELECT
        TOP 10000 fr.id,
        fr.data_acquisizione
    FROM
        fr,
        rendicontazioni,
        singoli_versamenti,
        versamenti
    WHERE
        ( (fr.cod_dominio = 'xxxxxxxxxxx' ) )
        AND ( (fr.data_acquisizione >= '2024-02-08T08:10:00' ) )
        AND ( (fr.data_acquisizione <= '2024-02-09T08:10:00' ) )
        AND ( fr.id = rendicontazioni.id_fr )
        AND ( rendicontazioni.id_singolo_versamento = singoli_versamenti.id )  -- QUESTO JOIN NON RESTITUISCE NULLA!
        AND ( singoli_versamenti.id_versamento = versamenti.id )
        AND ( (versamenti.id_dominio = 'xxxxxxxxxxx' ) )
        AND ( (fr.obsoleto = 0 ) )
    ORDER BY
        fr.data_acquisizione DESC ) as tabellapvR

    Quest'ultima query esegue un join su rendicontazioni.id_singolo_versamento = singoli_versamenti.id tuttavia, nel caso in cui la RT sia stata rifiutata da GovPay, rendicontazioni.id_singolo_versamento è NULL e quindi il join non ha effetto, restituendo un elenco di flussi vuoto.

Come riprodurlo: Basta avere un flusso che faccia riferimento a un pagamento non recepito (RT rifiutata). La relativa riga di rendicontazione avrà stato=ANOMALA e anomalie='007101#Il pagamento riferito dalla rendicontazione non risulta presente in base dati.' Chiedendo l'elenco flussi porterà a risultati diversi a seconda che il ruolo abbia visibilità su tutti i domini o solo su quello cui il flusso si riferisce.

Risultato atteso: L'elenco dei flussi dovrebbe essere lo stesso in entrambi i casi. La query al punto 2) esegue un join che produce l'anomalia qualora rendicontazioni.id_singolo_versamento = NULL, quando (potenzialmente) il join non sarebbe nemmeno necessario ai fini dell'elenco dei flussi.

Ambiente:

pintorig commented 8 months ago

Attualemente per un'utenza con visibilita' limitata su alcuni enti creditori viene applicato un filtro sulla tabella dei versamenti attraverso la join incriminata che si interrompe in caso di anomalie nell'acquisizione delle ricevute. Questo filtro e' stato introdotto per la doppia autorizzazione su EC e UO, ma e' inutile poiche' le autorizzazioni sulla ragioneria si devono fare sull'intero EC. La soluzione consiste nel spostare il filtro sugli EC associati direttamente sulla colonna cod_dominio della tabella fr.