gestione gare pubbliche
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 

881 righe
32 KiB

<?php
use GPBMetadata\Google\Type\Datetime;
use Symfony\Component\Routing\Exception\InvalidParameterException;
require_once dirname(__DIR__, 2) . "/inc/traits/api.trait.php";
require_once dirname(__DIR__, 2) . "/inc/traits/deleghe.trait.php";
require_once dirname(__DIR__, 2) . "/inc/traits/npalogger.trait.php";
require_once dirname(__DIR__, 2) . "/inc/traits/render.trait.php";
class FVOEDocument {
use API, Deleghe, NpaLogger, NuovaPiattaformaAppaltiRenderTrait;
public $codice;
public $codice_fvoe;
public $id_documento;
public $tipo_documento;
public $oggetto;
public $stato;
public $data_creazione;
public $stato_comprova;
public $stato_utilizzo;
public $stato_richiesta;
public $data_inserimento;
public $data_emissione;
public $data_fine_validita;
public $numero_protocollo;
public $utente_modifica;
public $timestamp_creazione;
public $timestamp;
private FVOE $fvoe;
private array $fascicolo;
private static PDOStatement $stm;
private static PDOStatement $stmDocumento;
private static PDOStatement $stmRequestData;
private static PDOStatement $stmPendingDocument;
private static stdClass $utilizzo;
private static stdClass $stati_richiesta;
private static stdClass $comprova;
private static stdClass $stati;
private static array $tipologia_documenti;
private static string $path_modelli_dati_aggiuntivi;
/**
* Query initialization
*
* @var bool
*/
private static bool $queryInitialized = false;
/**
* Contiene la configurazione corrente delle API
*
* @var array
*/
private $api_config = [];
public const STATI = [
0 => [
"id" => 0,
"color" => "var(--danger)",
"icon" => "fas fa-times-circle",
"title" => "Documento non disponibile"
],
1 => [
"id" => 1,
"color" => "var(--primary)",
"icon" => "fas fa-check-circle",
"title" => "Documento disponibile"
],
2 => [
"id" => 2,
"color" => "var(--warning)",
"icon" => "fas fa-check-circle",
"title" => "Documento scaduto"
]
];
/**
* Getter
*
* @param mixed $name
* @return void
*/
public function __get($name)
{
if ($name === 'info') {
return get_object_vars($this);
}
if ($name === 'scheda' || $name == 'form') {
return null;
}
// Se la proprietà richiesta non è 'info', gestisci come errore o restituisci null
trigger_error("Proprietà non definita: {$name}", E_USER_NOTICE);
return null;
}
private function __construct()
{
self::setup();
$this->api_config = require dirname(__DIR__, 2) . "/inc/configurazione.php";
$this->stato = self::$stati->{0};
$this->stato_utilizzo = self::$utilizzo->{$this->stato_utilizzo ?? "001"};
$this->stato_comprova = self::$comprova->{$this->stato_comprova ?? "001"};
$this->stato_richiesta = ! empty($this->stato_richiesta) ? self::$stati_richiesta->{$this->stato_richiesta} : (object) ["descrizione" => (object) ["it" => "/"]];
if(! empty($this->codice)) {
if(! empty($this->data_inserimento)) {
$this->stato = self::$stati->{1};
}
if(! empty($this->data_fine_validita) && strtotime($this->data_fine_validita) < strtotime('now')) {
$this->stato = self::$stati->{2};
}
}
}
/**
* Inizializza le varibili statiche
*
* @return void
*/
private static function setup() : void
{
// Inizializzo gli stati
self::$stati = (object) json_decode(json_encode(self::STATI));
// Inizlializzo le query
global $pdo;
if (!self::$queryInitialized) {
self::$stm = $pdo->prepare("SELECT * FROM b_fvoe_documenti WHERE `tipo_documento` = :tipo_documento AND `codice_fvoe` = :codice_fvoe AND (`data_inserimento` IS NOT NULL OR `data_inserimento` <> '') ORDER BY `data_fine_validita` DESC LIMIT 0,1");
self::$stmDocumento = $pdo->prepare("SELECT * FROM b_fvoe_documenti WHERE `tipo_documento` = :tipo_documento AND `codice_fvoe` = :codice_fvoe AND (`data_inserimento` IS NULL OR `data_inserimento` = '') ORDER BY `timestamp_creazione` DESC LIMIT 0,1");
self::$stmRequestData = $pdo->prepare("SELECT `richiesta` FROM `b_fvoe_operazioni` WHERE (`richiesta` IS NOT NULL OR `richiesta` <> '') AND `tipo_documento` = :tipo_documento AND `codice_fvoe` = :codice_fvoe ORDER BY `timestamp` DESC LIMIT 0,1");
self::$stmPendingDocument = $pdo->prepare("SELECT * FROM b_fvoe_documenti WHERE `tipo_documento` = :tipo_documento AND `codice_fvoe` = :codice_fvoe AND (`id_documento` IS NULL OR `id_documento` = '') ORDER BY `codice` DESC LIMIT 0,1");
self::$queryInitialized = true;
}
// Iniziallizzo la stato delle richieste di documento
if(empty(self::$stati_richiesta)) {
$stato_richiesta = jsonToArray(__DIR__ . DIRECTORY_SEPARATOR . "json" . DIRECTORY_SEPARATOR . "stato_richiesta_documento.json");
$stato_richiesta = array_column($stato_richiesta, null, "codice");
self::$stati_richiesta = json_decode(json_encode($stato_richiesta));
}
// Iniziallizzo la tipologia di utilizzo del documento
if(empty(self::$utilizzo)) {
$utilizzo = jsonToArray(__DIR__ . DIRECTORY_SEPARATOR . "json" . DIRECTORY_SEPARATOR . "stato_utilizzo.json");
$utilizzo = array_column($utilizzo, null, "codice");
self::$utilizzo = json_decode(json_encode($utilizzo));
}
// Iniziallizzo la comprova del documento
if(empty(self::$comprova)) {
$comprova = jsonToArray(__DIR__ . DIRECTORY_SEPARATOR . "json" . DIRECTORY_SEPARATOR . "comprova_documento.json");
$comprova = array_column($comprova, null, "codice");
self::$comprova = json_decode(json_encode($comprova));
}
// Inizializzo le tipoligie di documento
if(empty(self::$tipologia_documenti)) {
self::$tipologia_documenti = jsonToArray(__DIR__ . "/json/tipologia_documenti.json");
self::$tipologia_documenti = array_column(self::$tipologia_documenti, null, "codice");
}
// Inizializzo il path dei modelli di dati da richiedere
if(empty(self::$path_modelli_dati_aggiuntivi)) {
self::$path_modelli_dati_aggiuntivi = dirname(__DIR__, 2) . '/versions/' . NuovaPiattaformaAppalti::LATEST_SDK_VERSION . '/fvoe';
}
}
/**
* Inizializza la classe
*
* @param mixed $tipo_documento
* @return self
*/
public static function init(string $tipo_documento, int $codice_fvoe) : self
{
self::setup();
if(empty(self::$tipologia_documenti[$tipo_documento])) {
throw new InvalidArgumentException("Tipologia di documento non valida", 1);
}
$document = new self();
$document->tipo_documento = $tipo_documento;
$document->codice_fvoe = $codice_fvoe;
$document->oggetto = self::$tipologia_documenti[$tipo_documento]["descrizione"]["it"];
$document->stato_richiesta = "001";
return $document;
}
/**
* Get pending document record
*
* @return FVOEDocument
*/
public function getPendingDocument() : FVOEDocument {
if($this->documentsCollection()->areThereDocumentsPendingRelease() && $this->documentsCollection()->haveRequestsBeenMade()) {
self::$stmPendingDocument->execute([":tipo_documento" => $this->tipo_documento, ":codice_fvoe" => $this->codice_fvoe]);
if(self::$stmPendingDocument->rowCount() > 0) {
self::$stmPendingDocument->setFetchMode(PDO::FETCH_CLASS, 'FVOEDocument');
return self::$stmPendingDocument->fetch();
}
}
}
/**
* Verifica se una specifica classe documentale richiede dati aggiuntivi
*
* @param mixed $tipo_documento
* @return bool
*/
public static function hasFormRequest(?string $tipo_documento) : bool
{
self::setup();
return ! empty(self::$tipologia_documenti[$tipo_documento]["modelloDati"]) &&
file_exists(self::$path_modelli_dati_aggiuntivi . '/' . self::$tipologia_documenti[$tipo_documento]["modelloDati"] . '.json');
}
/**
* Ottieni il form per la richiesta della classe documentale
*
* @param mixed $tipo_documento
* @return array
*/
public static function getFormRequest(string $tipo_documento) : ?array {
self::setup();
if(self::hasFormRequest($tipo_documento)) {
return jsonToArray(self::$path_modelli_dati_aggiuntivi . '/' . self::$tipologia_documenti[$tipo_documento]["modelloDati"] . '.json');
}
return null;
}
/**
* Make repeatable object for ajax request.
*
* @param Array $settings
* @return String
*/
public function makeRepeatableObject(array $settings): String
{
$settings["codice"] = $this->codice;
$settings["tipo_documento"] = $this->tipo_documento;
$settings["codice_fvoe"] = $this->codice_fvoe;
return base64_encode(gzdeflate(json_encode($settings)));
}
private function fixCustomFields(array &$data) {
foreach ($data as $key => &$element) {
if(is_array($element)) {
if (array_keys(array_merge($element)) === range(0, count($element) - 1)) {
$element = array_values($element);
}
if(!empty($element['Giorno']) && !empty($element['Mese']) && !empty($element['Anno'])) {
$element["DataDiNascitaCustomField"] = "{$element['Giorno']}/{$element['Mese']}/{$element['Anno']}";
}
self::fixCustomFields($element);
}
}
}
/**
* Get data already transmitted for the current document type
*
* @return array
*/
public function getCardData(): array {
self::$stmRequestData->execute([":tipo_documento" => $this->tipo_documento, ":codice_fvoe" => $this->codice_fvoe]);
if(self::$stmRequestData->rowCount() == 1) {
$data = self::$stmRequestData->fetch(PDO::FETCH_COLUMN, 0);
$data = unserialize($data);
self::fixCustomFields($data);
return $data;
}
return [];
}
/**
* Stampa il form per una specifica classe documentale
*
* @param mixed $tipo_documento
* @return void
*/
public function printDocumentRequestForm(?string $tipo_documento = null) : void {
if(empty($tipo_documento)) { $tipo_documento = $this->tipo_documento; }
$form = FVOEDocument::getFormRequest($tipo_documento);
if(! empty($form["content"])) {
$this->printSection($form["content"]);
?>
<style>
@media (min-width: 1200px) {
.col-xl-6 {
flex: 1 0 50%;
max-width: 100%;
}
}
/* Workaround for excessive padding */
.form-group.col-sm-12 {
padding: 0 !important;
}
/* Workaround for tab-pane row */
.tab-pane .row .active {
display: flex !important;
}
.tab-content > .active.row {
display: flex !important;
}
.btn-xs {
padding: 0 0.4rem;
font-size: 0.8rem;
}
#master-fieldset > .col-12 {
padding-left: 0 !important;
padding-right: 0 !important;
}
</style>
<script type="text/javascript">
if (typeof window.npa === "undefined") {
const npa = class {
ready() {
f_ready();
}
bindEvents() {
const self = this;
self.groupRepeatables();
}
add2Form(target, data) {
const self = this;
let repeatable_target = target;
let container = document.getElementById(repeatable_target);
let iterations = Number(container.childElementCount);
if (container.dataset.hasTabs) {
iterations = Number(container.dataset.iterations);
}
$.ajax({
type: "POST",
url: "ajax/add2Form.php",
data: {
data: data,
index: iterations + 1,
},
dataType: "html",
beforeSend: function() {
$("#wait_div").show();
}
})
.fail(function(response) {
swal(js_dict["error-retry"]);
})
.done(function(response) {
let newChild = document.createElement("template");
newChild.innerHTML = response.trim();
newChild = container.appendChild(newChild.content.firstChild);
self.ready();
self.groupRepeatables();
})
.always(function() {
$("#wait_div").slideUp('fast');
});
}
groupRepeatables() {
const self = this;
document.querySelectorAll(".repeatable_container").forEach(function(el) {
let i = 0;
let tabs = null;
let tabHeaders = null;
let hasTabs = el.dataset.hasTabs;
let selectedBind = "";
let toSelect = null;
// Aggiunta o rimozione
if (hasTabs) {
// Otteniamo la tab correntemente selezionata
selectedBind = el.querySelector(".nav-link.active").dataset.bindtarget;
// Otteniamo, puliamo e rimuoviamo i vecchi header
tabHeaders = el.removeChild(document.getElementById(el.dataset.tabHeadersId));
tabHeaders.innerHTML = "";
// Otteniamo e rimuoviamo le vechie tab
tabs = el.removeChild(document.getElementById(el.dataset.tabsId));
// I vecchi elementi in tab vengono trasposti dentro il repeatable nell'ordine corretto
let tempContainer = [];
let index = 0;
tabs.childNodes.forEach(function(oldChild) {
if (oldChild.nodeType !== Node.ELEMENT_NODE)
return;
tempContainer.push(oldChild);
});
// Iteriamo i figli nuovi e verifichiamo che ce ne
// sia solo uno nuovo.
el.childNodes.forEach(function(newChild) {
if (newChild.id) {
if (toSelect === null) {
if (newChild.id) {
toSelect = newChild;
}
} else {
// Ne abbiamo più di uno, non selezioneremo nulla
toSelect = false;
}
}
});
tempContainer.forEach(function(oldChild) {
el.insertBefore(oldChild, el.children[index++]);
});
// In questo modo abbiamo vecchi figli e poi i nuovi figli e possiamo far ricreare header e tutto
} else {
// Creiamo l'header
tabHeaders = document.createElement("ul");
tabHeaders.classList.add("nav");
tabHeaders.classList.add("nav-tabs");
tabHeaders.classList.add("npa-tabs");
tabHeaders.classList.add("px-4");
tabHeaders.setAttribute("role", "tablist");
tabHeaders.id = self.generateRandomID();
// Creiamo il contenitore di tabs
tabs = document.createElement("div");
tabs.classList.add("tab-content");
tabs.id = self.generateRandomID();
// Assegnamo id casuali per poterli riferire dopo
el.dataset.hasTabs = true;
el.dataset.tabHeadersId = tabHeaders.id;
el.dataset.tabsId = tabs.id;
i = 0;
}
let straightToTabs = [];
let iteration = 0;
el.childNodes.forEach(function(child) {
if (child.nodeType !== Node.ELEMENT_NODE) {
return;
}
// Header della tab
let tabLi = document.createElement("li");
tabLi.classList.add("nav-item");
tabLi.setAttribute("role", "presentation");
let tabButton = document.createElement("a");
tabButton.classList.add("nav-link");
tabButton.classList.add("h-100");
tabButton.classList.add("ignore-lock");
tabButton.dataset.toggle = "tab";
tabButton.dataset.target = `#${child.id}`;
tabButton.style.minWidth = "90px";
tabButton.style.textAlign = "left";
tabLi.appendChild(tabButton);
tabHeaders.appendChild(tabLi);
if (Number(child.dataset.index) > Number(iteration)) {
iteration = Number(child.dataset.index);
}
// Creo un ID univoco per associare facilmente tab button e tab
if (child.dataset.bind) { // Riportiamo quello esistente se già c'è
// Nessuna azione necessaria
} else {
child.dataset.bind = self.generateRandomID();
}
tabButton.dataset.bindtarget = child.dataset.bind;
let tabText = document.createElement("span");
tabText.classList.add("nav-link-text");
tabButton.appendChild(tabText);
tabText.innerText = i + 1;
let found = [];
for (let key of ["denominazione", "lotIdentifier", "cig"]) {
const el = child.querySelector(`input[data-reference$='${key}']`);
if (el && el.value) {
found.push(el);
}
}
if (found.length > 0) {
if (found.length === 1) {
found = found[0];
} else {
found = self.findClosest(child, found);
}
tabText.innerText = found.value;
}
// Tab in se
child.classList.remove("col-12");
child.classList.add("tab-pane");
child.classList.add("fade");
child.classList.add("row");
straightToTabs.push(child);
// Cerchiamo di recuperare il tasto di eliminazione
if (i > 0) {
let deleteButton = child.querySelector(".npa-delete-button");
if (deleteButton) {
deleteButton.style.display = "inline";
deleteButton.parentNode.style.display = "none";
tabButton.appendChild(deleteButton.cloneNode(true));
deleteButton.style.display = "none";
}
}
i++;
});
tabHeaders.style.display = "flex";
tabHeaders.classList.add("mb-3");
straightToTabs.forEach(function(child) {
tabs.appendChild(child);
});
el.dataset.iterations = iteration;
el.appendChild(tabHeaders);
el.appendChild(tabs);
// Se abbiamo un solo elemento non mostriamo le tab
if (i == 1) {
tabHeaders.style.display = "none";
}
// Una volta creati andiamo a caccia dell'attivo
let toBeActive = el.querySelector(`.nav-link[data-bindtarget]`)
// Cerchiamo di ripristinare quello che era già selezionato ove possibile
if (selectedBind.length > 0) {
let selectedActive = el.querySelector(`.nav-link[data-bindtarget="${selectedBind}"]`);
if (selectedActive) {
toBeActive = selectedActive;
}
}
// Settiamo attive sia tab button che child
if (toBeActive) {
// Però se abbiamo invece da selezionare uno nuovo
// perchè è quello appena selezionato
if (toSelect) {
// toBeActive viene deselezionato
toBeActive.classList.remove("active");
// Cerchiamo la sua tab
const child = document.querySelector(`[data-bind="${toBeActive.dataset.bindtarget}"]`);
if (child) {
child.classList.remove("show")
child.classList.remove("active");
}
// e quindi toSelect diventa l'effettivo toBeActive
toBeActive = document.querySelector(`[data-bindtarget="${toSelect.dataset.bind}"]`);
}
toBeActive.classList.add("active");
// Cerchiamo la sua tab
const child = document.querySelector(`[data-bind="${toBeActive.dataset.bindtarget}"]`);
if (child) {
child.classList.add("show")
child.classList.add("active");
}
}
});
}
generateRandomID() {
var S4 = function() { return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); };
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}
}
window.npa = document.npa = new npa();
}
npa.bindEvents();
</script>
<?
}
}
/**
* Set form request data before send
*
* @param array &$data
* @param array $types
* @return void
*/
private static function setDocumentRequestFormData(array &$data, array $types) {
foreach ($types as $key => $settings) {
if (isset($data[$key])) {
if(is_array($data[$key])) {
// Gestisco le ripetizioni
if(isset($data[$key][0])) {
foreach ($data[$key] as $index => &$subvalues) {
self::setDocumentRequestFormData($subvalues, $settings);
}
} else {
self::setDocumentRequestFormData($data[$key], $settings);
}
} else {
if($key == "CF") {
if(isset($data["DatiNascita"]["CodiceCatastoStato"]) && $data["DatiNascita"]["CodiceCatastoStato"] == "Z000") {
$data["DatiNascita"]["CodiceCatastoComuneItaliano"] = codice_catasto_from_cf($data[$key]);
}
}
if($key == "CF_Soggetto") {
$data["LuogoNascita_Soggetto"] = codice_catasto_from_cf($data[$key]);
}
if($key == "DataDiNascitaCustomField") {
$date = date2mysql($data[$key]);
$date = \DateTime::createFromFormat('Y-m-d', $date);
$data["Giorno"] = $date->format('d');
$data["Mese"] = $date->format('m');
$data["Anno"] = $date->format('Y');
unset($data["DataDiNascitaCustomField"]);
}
if($key == "DataNascita_Soggetto") {
$date = date2mysql($data[$key]);
$date = \DateTime::createFromFormat('Y-m-d', $date);
$data[$key] = $date->format('Y-m-d\T00:00:00+02:00');
}
switch ($settings['format']) {
case 'datetime':
case 'date-time':
$date = datetime2mysql($data[$key]);
$date = \DateTime::createFromFormat('Y-m-d H:i', $date);
if (! is_bool($date)) {
$data[$key] = $date->format(\DateTime::ATOM);
}
break;
default:
break;
}
}
}
}
}
/**
* Richiedi un documento a un ente certificato
*
* @param string $tipologia
* @param ?array $data
* @return bool
*/
public function request(?array $data = [], ?string &$message = "") : bool
{
global $config;
// Prevalorizziamo $message
$message = __("Errore interno sconosciuto");
// Verifichiamo che sia settata una tipologia di documento
if(empty($this->tipo_documento) || empty($this->codice_fvoe)) {
$message = __("Impossibile completare la richiesta: è necessario selezionare una tipologia di documento e un fascicolo OE.");
return false;
}
// Verifichiamo che i servizi siano disponibili
if (! $this->getServiceStatusBool(true)) {
$message = __("Impossibile completare la richiesta: i server ANAC non sono raggiungibili. Riprova tra qualche minuto.");
return false;
}
// Verifica se la richiesta può essere inviata
self::$stm->execute([":tipo_documento" => $this->tipo_documento, ":codice_fvoe" => $this->codice_fvoe]);
if(self::$stm->rowCount() > 0) {
self::$stm->setFetchMode(PDO::FETCH_CLASS, 'FVOEDocument');
$document = self::$stm->fetch();
if(strtotime($document->data_fine_validita) > strtotime("+ 1 month")) {
$message = __("Impossibile completare la richiesta: il documento non è in scadenza o scaduto.");
return false;
}
}
$this->fvoe = FVOE::init($this->codice_fvoe, FVOEInizializationType::CODICE_FVOE);
$this->fascicolo = $this->fvoe->fascicolo;
$documento = new Salva();
$documento->debug = false;
$documento->nome_tabella = "b_fvoe_documenti";
$documento->operazione = "INSERT";
$documento->expect = ["codice_fvoe", "tipo_documento", "oggetto", "stato_richiesta"];
$documento->oggetto = [
"codice_fvoe" => $this->codice_fvoe,
"tipo_documento" => $this->tipo_documento,
"oggetto" => $this->oggetto,
"stato_richiesta" => $this->stato_richiesta
];
self::$stmDocumento->execute([":tipo_documento" => $this->tipo_documento, ":codice_fvoe" => $this->codice_fvoe]);
if(self::$stmDocumento->rowCount() > 0) {
self::$stmDocumento->setFetchMode(PDO::FETCH_CLASS, 'FVOEDocument');
$doc = self::$stmDocumento->fetch();
$documento->operazione = "UPDATE";
$documento->expect[] = "codice";
$documento->oggetto["codice"] = $doc->codice;
}
$this->codice = $documento->oggetto["codice"] = $documento->save();
$operazione = new Salva();
$operazione->debug = false;
$operazione->nome_tabella = "b_fvoe_operazioni";
$operazione->operazione = "INSERT";
$operazione->expect = ["codice_documento", "codice_partecipante", "codice_lotto", "operazione", "codice_fvoe", "tipo_documento"];
$operazione->oggetto = [
"codice_fvoe" => $this->codice_fvoe,
"codice_documento" => $this->codice,
"codice_partecipante" => $this->fvoe->info["uuid_partecipante"],
"tipo_documento" => $this->tipo_documento,
"codice_lotto" => $this->fvoe->info["codice_lotto_npa"],
"operazione" => "RICHIESTA-DOCUMENTO"
];
date_default_timezone_set('Europe/Rome');
$claims = $this->getAnacJwsCustomClaims($this->api_config["fvoe"]["endpoint"]);
// Andiamo a verificare che ci sia un'operazione di richiesta documento in attesa
$richiesta_documento = FVOE::fetchLastOperation($this->codice, null, null, "RICHIESTA-DOCUMENTO", null, false);
// Se c'è
if (! empty($richiesta_documento)) {
// Popoliamo il messaggio di errore
$message = __("Errore durante la richiesta del documento");
$operazione->operazione = "UPDATE";
$operazione->expect = ["codice", "esito", "risultato"];
$operazione->oggetto = $richiesta_documento;
// Andiamo a chiedere al server lo stato della richiesta di accesso
$request = [
"idRichiesta" => $richiesta_documento["id_richiesta"]
];
$apiMessage = "";
$result_str = $this->apiCall("fvoe", "check-document-request", $request, $claims, [], $apiMessage);
if (is_json($result_str)) {
$message = __("Impossibile verificare l'esito dell'operazione. Contatta l'Help Desk tecnico.");
$result = json_decode($result_str);
$operazione->oggetto["risultato"] = serialize($result);
$operazione->oggetto["esito"] = "KO";
if ($result->status == 200 && ! empty($result->result)) {
global $config;
$message = null;
foreach ($result->result as $document_request) {
if($document_request->idRichiesta == $richiesta_documento["id_richiesta"]) {
$documento->operazione = "UPDATE";
$documento->expect = ["codice", "stato_richiesta", "id_documento"];
$documento->oggetto = [
"codice" => $this->codice,
"stato_richiesta" => $document_request->stato->codice,
"id_documento" => $document_request->idDocumento ?? null,
];
$documento->save();
}
}
$operazione->oggetto["esito"] = "OK";
$operazione->save();
return true;
}
$operazione->save();
return false;
}
return false;
}
// Verifico se è necessario trasmettere dati aggiuntivi
if(! empty(self::$tipologia_documenti[$this->tipo_documento]["modelloDati"]) && empty($data)) {
$message = __("Impossibile completare la richiesta: il documento richiede dati aggiuntivi non presenti nel form.");
return false;
}
// Creiamo la richiesta di accesso al documento
$request = [
"chiaveAccesso" => simple_decrypt($this->fvoe->info["chiave_accesso"], $config["simple_encrypt"]["chiave_fvoe"]),
// "codiceFiscaleSoggetti" => "",
"tipoDocumento" => json_encode([
// "idTipologica" => "tipoDocumento",
"codice" => $this->tipo_documento
]),
// "datiRichiesta" => ""
];
if(! empty(self::$tipologia_documenti[$this->tipo_documento]["modelloDati"])) {
$form = self::getFormRequest($this->tipo_documento);
$types = $this->getFormInputsTypes($form["content"]);
self::setDocumentRequestFormData($data, $types);
$request["datiRichiesta"] = json_encode($data);
// $request["datiRichiesta"]["type"] = str_replace('_', '', self::$tipologia_documenti[$this->tipo_documento]["modelloDati"]);
}
$operazione->expect[] = "richiesta";
$operazione->oggetto["richiesta"] = serialize($request["datiRichiesta"] ?? null);
// Effettuiamo la richiesta
$apiMessage = "";
$claims = $this->getAnacJwsCustomClaims($this->api_config["fvoe"]["endpoint"]);
// $result_str = $this->apiCall("fvoe", "documents-request", $request, $claims, [], $apiMessage);
$result_str = $this->apiCall("fvoe", "request-document", $request, $claims, [], $apiMessage);
$result = self::manageANACResponse($result_str, $message);
if($result === null) {
$message = empty($apiMessage) ? $message : $apiMessage;
return false;
}
$message = __("Errore in fase di invio della richiesta.");
// Verifichiamo la risposta
// Se non ci viene fornita una risposta con successo
if ($result->status !== 200) {
// Aggiorniamo lo status
$operazione->expect[] = "esito";
$operazione->oggetto["esito"] = "KO";
$operazione->expect[] = "risultato";
$operazione->oggetto["risultato"] = serialize($result);
$operazione->save();
$message = __("Errore in fase di richiesta del documento.");
if(! empty($result->errori)) {
$dictionary = NuovaPiattaformaAppalti::getErrorsDictionary();
foreach ($result->errori as $errore) {
$errorInfo = $dictionary[$errore->codice ?? null] ?? [];
if(! empty($errorInfo["descrizione"]["it"]) && $errorInfo["codice"]) {
$message = "{$errorInfo["codice"]} {$errorInfo["descrizione"]["it"]}";
}
}
} elseif(! empty($result->title)) {
$message = "{$message} {$result->title}";
}
return false;
}
// Conferma andata con successo
$operazione->expect[] = "id_richiesta";
$operazione->oggetto["id_richiesta"] = $result->idRichiesta;
if ($operazione->save()) {
$message = "";
return true;
}
return false;
}
/**
* get the related FVOEDocumentsCollection
*
* @return FVOEDocumentsCollection
*/
public function documentsCollection() : FVOEDocumentsCollection {
return new FVOEDocumentsCollection($this->codice_fvoe, $this->tipo_documento);
}
}