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.
1071 righe
38 KiB
1071 righe
38 KiB
<?php |
|
|
|
/** |
|
* Enum che definisce i tipi di suggerimento |
|
*/ |
|
class NPASuggestionType { |
|
/** |
|
* Il suggeerimento viene applicato e l'utente non può modificarlo |
|
*/ |
|
const FORCED = "FORCE"; |
|
/** |
|
* Il suggerimento viene applicato se il campo è vuoto e l'utente può modificarlo |
|
*/ |
|
const AUTOFILL = "AUTO"; |
|
/** |
|
* Il suggerimento viene suggerito ma è a scelta dell'utente applicarlo |
|
*/ |
|
const OPTIONAL = "OPT"; |
|
} |
|
trait NPASuggestionsTrait |
|
{ |
|
|
|
/** |
|
* La cache dei suggerimenti già processati |
|
* |
|
* @var array |
|
*/ |
|
public $suggestionsCache = []; |
|
|
|
/** |
|
* I suggerimenti non processati così come ottenuti dalle integrazioni |
|
* |
|
* @var array |
|
*/ |
|
public $integration = []; |
|
|
|
/** |
|
* Traccia interna dei lotti per la consistenza delle ripetizioni |
|
* |
|
* @var array |
|
*/ |
|
private $indiciLotto = []; |
|
/** |
|
* Traccia interna dei partecipanti per la consistenza delle ripetizioni |
|
* |
|
* @var array |
|
*/ |
|
private $indiciPartecipanti = []; |
|
/** |
|
* Traccia interna degli aggiudicatari per la consistenza delle ripetizioni |
|
* |
|
* @var array |
|
*/ |
|
private $indiciAggiudicatari = []; |
|
|
|
/** |
|
* Return a cleaned versione of the suggestion to be compliant with the JSON |
|
* |
|
* @param String $string The raw suggestion to be cleaned |
|
* @return String |
|
*/ |
|
public static function cleanSuggestion(String $string): String |
|
{ |
|
return strip_tags(str_replace('"', '\"', $string)); |
|
} |
|
|
|
/** |
|
* Ottiene la modalità con cui suggerire l'URL dell'appalto impostato nei settings di piattaforma (Forzato o Modificabile) |
|
* |
|
* @return String |
|
*/ |
|
public static function urlSuggetionMode() : String { |
|
$option = settingsManager::getValue("consentiModificaURLANAC"); |
|
return ($option == "S") ? NPASuggestionType::AUTOFILL : NPASuggestionType::FORCED; |
|
} |
|
|
|
/** |
|
* Ottiene i suggerimenti relativi alla procedura in corso |
|
* |
|
* @return array |
|
*/ |
|
public function getSuggestions(): array |
|
{ |
|
//if (empty($this->scheda["codice"])) return []; |
|
|
|
|
|
if (!empty($this->suggestionsCache)) { |
|
return $this->suggestionsCache; |
|
} |
|
|
|
$integrationPath = NuovaPiattaformaAppalti::INTEGRATION_PATHS[$this->fascicolo["modulo_riferimento"]]; |
|
|
|
|
|
if (empty($this->fascicolo["id_riferimento"])) { |
|
return []; |
|
} |
|
|
|
global $root; |
|
|
|
|
|
$this->info["modulo"] = $this->fascicolo["modulo_riferimento"]; |
|
$this->info["codice_elemento"] = $this->fascicolo["id_riferimento"]; |
|
|
|
$integration = []; |
|
if (!file_exists("{$root}/backend/{$integrationPath}")) { |
|
return []; |
|
} |
|
|
|
$callIntegration = function ($path) use (&$integration, $root) { |
|
|
|
$contents = require "{$root}/backend/{$path}"; |
|
if (is_array($contents)) { |
|
|
|
$integration = array_merge($integration, $contents); |
|
} |
|
}; |
|
|
|
$callIntegration($integrationPath); |
|
|
|
$this->integration = $integration; |
|
|
|
$stazioneAppaltante = $this->integration["STAZIONEAPPALTANTE"] ?? []; |
|
|
|
$this->suggestionsCache = []; |
|
#region Suggerimenti Generali |
|
$this->addSuggestion( |
|
"appalto.linkDocumenti", |
|
$this->integration["PUBLIC_URL"] ?? null, |
|
self::urlSuggetionMode() |
|
); |
|
$_oggetto = isset($this->integration["GENERAL"]["oggetto"]) ? self::cleanSuggestion($this->integration["GENERAL"]["oggetto"], "appalto.datiBase.oggetto") : ""; |
|
if (!empty($_oggetto)) { |
|
$this->addSuggestion("appalto.datiBase.oggetto", $_oggetto); |
|
} |
|
|
|
if ($this->fascicolo["modulo_riferimento"] == "gare") { |
|
$this->addSuggestionsGara(); |
|
} |
|
|
|
|
|
|
|
// Prezzo di riferimento |
|
$prezzoRiferimento = $this->integration["GENERAL"]["prezzoRiferimento"] ?? null; |
|
if ($prezzoRiferimento !== null) { |
|
$this->addSuggestion("appalto.datiBase.importo", currency_format($prezzoRiferimento)); |
|
} |
|
|
|
// Codice Appalto e stazione appaltante principale |
|
if (!empty($stazioneAppaltante)) { |
|
$letter = "P"; |
|
if (DEVELOP_ENV) { |
|
global $config; |
|
if (isset($config["npaLetter"])) { |
|
$letter = $config["npaLetter"]; |
|
} |
|
} |
|
|
|
// Generiamo il codice appalto |
|
$versione_interna = $this->fascicolo["versione_interna"] ?? 0; |
|
if($versione_interna >= 4) { |
|
$codiceAppalto = $this->integration["GENERAL"]["codiceAppalto"]; |
|
if (!empty($this->fascicolo["revisione_fascicolo"])) { |
|
$codiceAppalto .= "_v{$this->fascicolo['revisione_fascicolo']}"; |
|
} |
|
} else { |
|
$codiceAppalto = strtoupper("{$letter}{$_SESSION["ente"]->codice}-E{$stazioneAppaltante["codice"]}-{$this->integration["MODULO"]}-ID-{$this->oggetto->info["id"]}"); |
|
if (!empty($this->fascicolo["revisione_fascicolo"])) { |
|
$codiceAppalto .= "_rev{$this->fascicolo['revisione_fascicolo']}"; |
|
} |
|
} |
|
|
|
|
|
// Se siamo una modifica od una rettifica, allora prendiamo il codice appalto della scheda che stiamo andando a rettificare |
|
if(!empty($this->scheda["codice_modifica"]) || !empty($this->scheda["codice_rettifica"])) { |
|
$codiceSchedaOriginale = empty($this->scheda["codice_modifica"]) ? $this->scheda["codice_rettifica"] : $this->scheda["codice_modifica"]; |
|
$schedaOriginale = NuovaPiattaformaAppalti::fetchSchede(["dati"], ["codice" => $codiceSchedaOriginale], false, false); |
|
if(!empty($schedaOriginale) && valid_json($schedaOriginale["dati"], $schedaOriginale, true)) { |
|
$codiceAppaltoOriginale = DotPath::Get($schedaOriginale, "anacForm.appalto.codiceAppalto"); |
|
if(!empty($codiceAppaltoOriginale)) { |
|
$codiceAppalto = $codiceAppaltoOriginale; |
|
} |
|
} |
|
} |
|
|
|
if($this->fascicolo["codice_appalto"] !== $codiceAppalto) { |
|
$this->updateFascicolo(["codice_appalto" => $codiceAppalto]); |
|
} |
|
|
|
$this->addSuggestion("appalto.codiceAppalto", $codiceAppalto); |
|
$this->addSuggestion("stazioniAppaltanti.0.codiceFiscale", $stazioneAppaltante["cf"]); |
|
$this->addSuggestion("stazioniAppaltanti.0.codiceAusa", $stazioneAppaltante["codice_ausa"]); |
|
$this->addSuggestion("datiContratto.codiceAusa.0", $stazioneAppaltante["codice_ausa"]); |
|
} |
|
|
|
$idPianificazione = $this->fascicolo["id_pianificazione"] ?? ""; |
|
|
|
$this->addSuggestion( |
|
"appalto.idPianificazione", |
|
$idPianificazione, |
|
empty($idPianificazione) ? NPASuggestionType::AUTOFILL : NPASuggestionType::FORCED |
|
); |
|
#endregion |
|
|
|
|
|
|
|
// Per una scheda di lotto usiamo solo il lotto corrente, altrimenti tutti |
|
|
|
$codice_lotto_npa = $this->scheda["codice_lotto"] ?? 0; |
|
|
|
if (!empty($codice_lotto_npa)) { |
|
$this->addSuggestionsLotto($codice_lotto_npa); |
|
} else { |
|
foreach ($this->getLots() as $lot) { |
|
$this->setLotto($lot["codice_lotto_npa"]); |
|
$ignoreDeserta = false; |
|
if(isset($this->scheda["id_scheda"])) { |
|
$idScheda = $this->scheda["id_scheda"]; |
|
$metadata = $this->metadataSchede[$idScheda]; |
|
$ignoreDeserta = $metadata['categoria'] === 'affidamento'; |
|
} |
|
$agg = $this->getPartecipanti(true); |
|
if($ignoreDeserta && ($lot["stato"] == 95 || empty($agg))) { |
|
continue; |
|
} |
|
$this->unsetLotto(); |
|
$this->addSuggestionsLotto($lot["codice_lotto_npa"]); |
|
} |
|
} |
|
|
|
return $this->suggestionsCache; |
|
} |
|
|
|
/** |
|
* Aggiunge i suggerimenti relativi alle scadenze della procedura |
|
* |
|
* @return void |
|
*/ |
|
private function addSuggestionsScadenze(int $indiceLotto) |
|
{ |
|
if (empty($this->integration["ROUNDS"])) return; |
|
|
|
$isLotto = false; |
|
|
|
if(!empty($this->scheda["codice"])) { |
|
$idScheda = $this->scheda["id_scheda"]; |
|
$metadata = $this->metadataSchede[$idScheda]; |
|
$isLotto = $metadata["lotto"]; |
|
} |
|
|
|
$scadenzaOfferte = null; |
|
$scadenzaInviti = null; |
|
|
|
$rounds = $isLotto ? [end($this->integration["ROUNDS"])] : $this->integration["ROUNDS"]; |
|
|
|
foreach ($rounds as $round) { |
|
if (empty($round["scadenza"])) continue; |
|
if ($round["infoFase"]["graduatoria"]) { |
|
$scadenzaOfferte = mysql2datetime($round["scadenza"]); |
|
} else { |
|
$scadenzaInviti = mysql2datetime($round["scadenza"]); |
|
} |
|
} |
|
|
|
if($scadenzaOfferte !== null) { |
|
$this->addSuggestion( |
|
"lotti.$indiceLotto.datiBaseTerminiInvio.oraScadenzaPresentazioneOfferte", |
|
$scadenzaOfferte, |
|
NPASuggestionType::FORCED |
|
); |
|
$this->addSuggestion( |
|
"elencoSoggetti.$indiceLotto.dataScadenzaPresentazioneOfferta", |
|
$scadenzaOfferte, |
|
NPASuggestionType::FORCED |
|
); |
|
} elseif($scadenzaInviti !== null) { |
|
$this->addSuggestion( |
|
"lotti.$indiceLotto.datiBaseTerminiInvio.scadenzaPresentazioneInvito", |
|
$scadenzaInviti, |
|
NPASuggestionType::FORCED |
|
); |
|
} |
|
|
|
|
|
} |
|
|
|
/** |
|
* Aggiunge un suggerimento alla cache dei suggerimenti |
|
* |
|
* @param string $tag Dotpath della chiave del suggerimento (senza anacForm.) |
|
* @param mixed $value Valore del suggerimento |
|
* @param string $forced |
|
* @return void |
|
*/ |
|
private function addSuggestion(string $tag, $value, string $forced = NPASuggestionType::FORCED) |
|
{ |
|
DotPath::set($this->suggestionsCache, "anacForm.$tag", [ |
|
"forced" => $forced, |
|
"value" => $value |
|
]); |
|
} |
|
|
|
/** |
|
* Aggiunge i suggerimenti puramente relativi alle gare |
|
* |
|
* @return void |
|
*/ |
|
private function addSuggestionsGara() |
|
{ |
|
/** |
|
* @var gara |
|
*/ |
|
$gara = $this->oggetto; |
|
|
|
// Strumenti svolgimento |
|
$procedura = $gara->getProcedura(); |
|
$accordoQuadro = false; |
|
switch ($procedura["key"]) { |
|
case "aq": |
|
case "aqe": |
|
$strumentiSvolgimento = 6; |
|
$accordoQuadro = true; |
|
break; |
|
case "mercato": |
|
case "meex": |
|
$strumentiSvolgimento = 3; |
|
break; |
|
case "sda": |
|
$strumentiSvolgimento = 7; |
|
break; |
|
default: |
|
$elaborazione = $gara->getRisposteElaborazione(); |
|
if (($elaborazione["asta"] ?? "N") == "S") { |
|
$strumentiSvolgimento = 2; |
|
} else { |
|
$strumentiSvolgimento = 5; |
|
} |
|
} |
|
$this->addSuggestion( |
|
"appalto.strumentiSvolgimentoProcedure.codice", |
|
$strumentiSvolgimento, |
|
NPASuggestionType::AUTOFILL |
|
); |
|
|
|
// Asta elettronica |
|
$this->addSuggestion( |
|
"appalto.datiBaseStrumentiProcedura.astaElettronica", |
|
$strumentiSvolgimento == 2 ? "true" : "false", // True se strumenti svolgimento è asta elettronica, |
|
NPASuggestionType::AUTOFILL |
|
); |
|
|
|
// Tipo procedura |
|
$tipoProcedura = $procedura["bdncp"][0] ?? null; |
|
if ($tipoProcedura !== null) { |
|
// Tipo procedura |
|
$this->addSuggestion( |
|
"appalto.datiBaseProcedura.tipoProcedura.codice", |
|
$tipoProcedura, |
|
NPASuggestionType::AUTOFILL |
|
); |
|
} |
|
|
|
|
|
/*$this->addSuggestion( |
|
"appalto.datiBaseStrumentiProcedura.accordoQuadro.codice", |
|
"none", |
|
);*/ |
|
|
|
if(!empty($this->oggetto->info["derivazione"]) && $procedura["key"] == "aq") { |
|
|
|
$accordo = accordiQuadro::init($this->oggetto->info["derivazione"]); |
|
if(!empty($accordo->info["cig"])) { |
|
$this->addSuggestion( |
|
"appalto.cigAccordoQuadro", |
|
$accordo->info["cig"] |
|
); |
|
} |
|
} |
|
|
|
|
|
} |
|
/** |
|
* Shorthand per aggiungere un suggerimento ai partecipanti |
|
* |
|
* @param integer $indiceLotto Indice del lotto |
|
* @param integer $indicePartecipante Indice del partecipante |
|
* @param string $key Chiave del suggerimento |
|
* @param mixed $value Valore del suggerimento |
|
* @param string $forced Forzato? |
|
* @return void |
|
*/ |
|
private function addSuggestionPartecipante(int $indiceLotto, int $indicePartecipante, string $key, $value, string $forced = NPASuggestionType::FORCED) { |
|
$this->addSuggestion("elencoSoggetti.$indiceLotto.partecipanti.$indicePartecipante.$key", $value, $forced); |
|
$this->addSuggestion("elencoSoggettiRichiedenti.$indiceLotto.soggettiInteressati.$indicePartecipante.$key", $value, $forced); |
|
} |
|
/** |
|
* Aggiunge i suggerimenti relativi ai partecipanti |
|
* |
|
* @param integer $indiceLotto Indice del lotto |
|
* @param array $partecipanti Array contenente i partecipanti |
|
* @param array $invitati Array contenente gli invitati alla procedura |
|
* @return void |
|
*/ |
|
private function addSuggestionsPartecipanti(int $indiceLotto, array $partecipanti, array $invitati = []) |
|
{ |
|
|
|
if (!empty($invitati)) { |
|
$invitatiNonPartecipanti = array_filter($invitati, function ($invitato, $key) use ($partecipanti) { |
|
foreach ($partecipanti as $partecipante) { |
|
if (trim(strtoupper($partecipante["codice_fiscale"])) == trim(strtoupper($invitato["codice_fiscale"]))) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
}, ARRAY_FILTER_USE_BOTH); |
|
$indiceInvitato = 0; |
|
if(!empty($invitatiNonPartecipanti)) { |
|
$this->locked_repetitions["invitatiCheNonHannoPresentatoOfferta"] = true; |
|
} |
|
foreach ($invitatiNonPartecipanti as $invitato) { |
|
$this->addSuggestion("elencoSoggetti.$indiceLotto.invitatiCheNonHannoPresentatoOfferta.$indiceInvitato.codiceFiscale", $invitato["codice_fiscale"]); |
|
$this->addSuggestion("elencoSoggetti.$indiceLotto.invitatiCheNonHannoPresentatoOfferta.$indiceInvitato.denominazione", $invitato["ragione_sociale"]); |
|
$indiceInvitato++; |
|
} |
|
} |
|
$this->locked_repetitions["partecipanti"] = true; |
|
$this->locked_repetitions["soggettiInteressati"] = true; |
|
foreach ($partecipanti as $partecipante) { |
|
$codice_partecipante = $partecipante["codice"]; // Preveniamo edge case in cui due entry di tabelle diverse |
|
// hanno lo stesso codice |
|
if(isset($partecipante["codice_padre"])) { |
|
$codice_partecipante += 1000000000; |
|
} |
|
$indicePartecipante = $this->indiciPartecipanti[$indiceLotto][$codice_partecipante] ?? count($this->indiciPartecipanti[$indiceLotto] ?? []); |
|
$this->indiciPartecipanti[$indiceLotto][$codice_partecipante] = $indicePartecipante; |
|
$idPartecipante = $partecipante["identificativo_partecipante"]; |
|
$codiceFiscale = $partecipante["codice_fiscale"]; |
|
$ragioneSociale = $partecipante["ragione_sociale"]; |
|
$paese = $partecipante["stato"] ?? null; |
|
$this->addSuggestionPartecipante($indiceLotto, $indicePartecipante, "idPartecipante", $idPartecipante); |
|
$this->addSuggestionPartecipante($indiceLotto, $indicePartecipante, "codiceFiscale", $codiceFiscale); |
|
$this->addSuggestionPartecipante($indiceLotto, $indicePartecipante, "denominazione", $ragioneSociale); |
|
|
|
if (!empty($paese)) { |
|
$this->addSuggestionPartecipante($indiceLotto, $indicePartecipante, "paeseOperatoreEconomico", $paese, NPASuggestionType::AUTOFILL); |
|
} |
|
if (!empty($partecipante["ruoloOE"])) { |
|
$this->addSuggestionPartecipante($indiceLotto, $indicePartecipante, "ruoloOE.codice", $partecipante["ruoloOE"], NPASuggestionType::AUTOFILL); |
|
} |
|
if(!empty($partecipante["avvalimento"])) { |
|
$this->addSuggestionPartecipante($indiceLotto, $indicePartecipante, "avvalimento", "true", NPASuggestionType::AUTOFILL); |
|
$this->addSuggestionPartecipante($indiceLotto, $indicePartecipante, "tipologiaAvvalimento.codice", $partecipante["avvalimento"], NPASuggestionType::AUTOFILL); |
|
} else { |
|
$this->addSuggestionPartecipante($indiceLotto, $indicePartecipante, "avvalimento", "false", NPASuggestionType::AUTOFILL); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Shortand per aggiungere un suggerimento per gli aggiudicatari |
|
* |
|
* @param integer $indiceLotto Indice del lotto |
|
* @param integer $indiceAggiudicatario Indice dell'aggiudicatario |
|
* @param string $key Chiave del suggerimento |
|
* @param mixed $value Valore del suggerimento |
|
* @param boolean $forced Forzato? |
|
* @return void |
|
*/ |
|
private function addSuggestionAggiudicatario(int $indiceLotto, int $indiceAggiudicatario, string $key, $value, string $forced = NPASuggestionType::FORCED) { |
|
$this->addSuggestion("aggiudicazioni.$indiceLotto.partecipanti.$indiceAggiudicatario.$key", $value, $forced); |
|
$this->addSuggestion("aggiudicazioni.$indiceLotto.offertePresentate.$indiceAggiudicatario.$key", $value, $forced); |
|
$this->addSuggestion("partecipante.$key", $value, $forced); |
|
} |
|
/** |
|
* Aggiunge i suggerimenti relativi agli aggiudicatari |
|
* |
|
* @param integer $indiceLotto Indice del lotto |
|
* @param array $partecipanti Array contenente gli aggiudicatari |
|
* @return void |
|
*/ |
|
private function addSuggestionsAggiudicatari(int $indiceLotto, array $partecipanti) |
|
{ |
|
$affidamento = false; |
|
|
|
if(!empty($this->scheda["codice"])) { |
|
$metadata = $this->metadataSchede[$this->scheda["id_scheda"]]; |
|
$affidamento = str_contains(strtolower("affidamento diretto"), $metadata["evento"]); |
|
} |
|
|
|
foreach ($partecipanti as $partecipante) { |
|
// Per i non affidamenti prendiamo senza raggruppamenti o avvalimenti perchè sono già stati definiti |
|
if(!$affidamento && $partecipante["isChild"]) { |
|
continue; |
|
} |
|
|
|
$isAggiudicatario = ($partecipante["aggiudicatario"] ?? "N") == "S"; |
|
|
|
// negli affidamenti prendiamo solo gli aggiudicatari |
|
if($affidamento && !$isAggiudicatario) { |
|
continue; |
|
} |
|
|
|
// TODO Inserire anche i non aggiudicatari se necessario |
|
if(!$isAggiudicatario) continue; |
|
|
|
$this->locked_repetitions["aggiudicazioni"] = true; |
|
$codice_partecipante = $partecipante["codice"]; |
|
|
|
// Preveniamo edge case in cui due entry di tabelle diverse |
|
// hanno lo stesso codice |
|
if(isset($partecipante["codice_padre"])) { |
|
$codice_partecipante += 1000000000; |
|
} |
|
$idPartecipante = $partecipante["identificativo_partecipante"]; |
|
$codiceFiscale = $partecipante["codice_fiscale"]; |
|
$ragioneSociale = $partecipante["ragione_sociale"]; |
|
$paeseOE = $partecipante["stato"] ?? null; |
|
$indiceAggiudicatario = $this->indiciAggiudicatari[$indiceLotto][$codice_partecipante] ?? count($this->indiciAggiudicatari[$indiceLotto] ?? []); |
|
$this->indiciAggiudicatari[$indiceLotto][$codice_partecipante] = $indiceAggiudicatario; |
|
|
|
|
|
|
|
|
|
|
|
|
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "idPartecipante", $idPartecipante); |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "codiceFiscale", $codiceFiscale); |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "denominazione", $ragioneSociale); |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "aggiudicatario", $isAggiudicatario ? "true" : "false"); |
|
|
|
$importoAggiudicazione = 0; |
|
if($isAggiudicatario) { |
|
$importoAggiudicazione = $this->lot["importoAggiudicazione"]; |
|
} |
|
if($importoAggiudicazione > 0) { |
|
$this->addSuggestion("comunicazione.importo", currency_format($importoAggiudicazione), NPASuggestionType::FORCED); |
|
} else { |
|
$this->addSuggestion("comunicazione.importo", "", NPASuggestionType::AUTOFILL); |
|
|
|
} |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "importo", currency_format($importoAggiudicazione), NPASuggestionType::AUTOFILL); |
|
|
|
|
|
|
|
if (!empty($paeseOE)) { |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "paeseOperatoreEconomico", $paeseOE, NPASuggestionType::OPTIONAL); |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "paeseOperatoreEconomico", $paeseOE, NPASuggestionType::OPTIONAL); |
|
} |
|
if (!empty($partecipante["ruoloOE"])) { |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "ruoloOE.codice", $partecipante["ruoloOE"], NPASuggestionType::AUTOFILL); |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "ruoloOE.codice", $partecipante["ruoloOE"], NPASuggestionType::AUTOFILL); |
|
} |
|
if(!empty($partecipante["avvalimento"])) { |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "avvalimento", "true", NPASuggestionType::AUTOFILL); |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "tipologiaAvvalimento.codice", $partecipante["avvalimento"], NPASuggestionType::AUTOFILL); |
|
} else { |
|
$this->addSuggestionAggiudicatario($indiceLotto, $indiceAggiudicatario, "avvalimento", "false", NPASuggestionType::AUTOFILL); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Ottiene il lotto delle integrazioni a partire dal codice lotto NPA |
|
* |
|
* @param integer $codiceLottoNpa |
|
* @return bool |
|
*/ |
|
private function getIntegrationLot(int $codiceLottoNpa): bool |
|
{ |
|
// Otteniamo il lotto NPA |
|
$this->setLotto($codiceLottoNpa); |
|
$npaLot = $this->lot; |
|
|
|
// Cerchiamo la corrispondenza con i lotti passati dalle integrazioni |
|
foreach ($this->integration["LOT"] as $integrationLot) { |
|
if ($integrationLot["codice"] == $npaLot["codice"]) { |
|
$this->lot = array_merge($this->lot, $integrationLot); |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
/** |
|
* Cache di getPartecipanti per questioni di performance |
|
* |
|
* @var array |
|
*/ |
|
private $cachePartecipanti = []; |
|
|
|
|
|
/** |
|
* Ritorna gli invitati alla procedura corrente |
|
* |
|
* @return array |
|
*/ |
|
public function getInvitati(): array |
|
{ |
|
if(empty($this->lot)) { |
|
return []; |
|
} |
|
|
|
$retval = []; |
|
if (!method_exists($this->oggetto, "getInvitati")) { |
|
return $retval; |
|
} |
|
// Otteniamo gli invitati |
|
$invitati = $this->oggetto->getInvitati(); |
|
if (!empty($invitati)) { |
|
$invitati = array_column($invitati, "codice_operatore"); |
|
$ooee = oeManager::getOE($invitati); |
|
if (!empty($ooee)) { |
|
foreach ($ooee as $oe) { |
|
$retval[] = [ |
|
"codice" => $oe["codice"], |
|
"codice_fiscale" => $oe["codice_fiscale_impresa"], |
|
"ragione_sociale" => $oe["ragione_sociale"], |
|
]; |
|
} |
|
} |
|
} |
|
if (!method_exists($this->oggetto, "getInvitatiManuali")) { |
|
return $retval; |
|
} |
|
|
|
// Otteniamo gli invitati manuali |
|
$invitatiManuali = $this->oggetto->getInvitatiManuali(); |
|
if (!empty($invitatiManuali)) { |
|
foreach ($invitatiManuali as $oe) { |
|
$retval[] = [ |
|
"codice" => $oe["codice"], |
|
"codice_fiscale" => $oe["codice_fiscale_operatore"], |
|
"ragione_sociale" => $oe["denominazione"], |
|
]; |
|
} |
|
} |
|
return $retval; |
|
} |
|
/** |
|
* Ottiene i partecipanti relativi a questo fascicolo |
|
* |
|
* @param boolean $only_aggiudicatari Se true vengono ritornati solo i partecipanti aggiudicatari |
|
* @param boolean $include_raggruppamenti Se true vengono inclusi anche i partecipanti dei raggruppamenti, condividendo lo stesso idPartecipante |
|
* @param boolean $noCache Se true non viene usata la cache |
|
* @return array|null |
|
*/ |
|
public function getPartecipanti(bool $only_aggiudicatari, bool $include_raggruppamenti = true, bool $noCache = false, bool $subappalto = false): ?array |
|
{ |
|
if(empty($this->lot)) { |
|
return []; |
|
} |
|
|
|
$codice_lotto_npa = $this->lot["codice_lotto_npa"]; |
|
|
|
$id_scheda = ($this->scheda["id_scheda"] ?? null); |
|
// Cache per velocizzare chiamate successive |
|
if (!$noCache && isset($this->cachePartecipanti[$codice_lotto_npa][$only_aggiudicatari ? 1 : 0][$include_raggruppamenti ? 1 : 0][$subappalto ? 1 : 0])) { |
|
return $this->cachePartecipanti[$codice_lotto_npa][$only_aggiudicatari ? 1 : 0][$include_raggruppamenti ? 1 : 0][$subappalto ? 1 : 0]; |
|
} |
|
|
|
if (! empty($this->oggetto) && method_exists($this->oggetto, "getPartecipanti")) { |
|
|
|
$shouldUseInvitati = $id_scheda === "S1" && ($this->oggetto->round["infoFase"]["graduatoria"] ?? false); |
|
$isExpired = $this->oggetto->info["stato"] >= 21 || !empty($this->oggetto->quickPanel); |
|
if (! $isExpired && is_a($this->oggetto, "gara")) { |
|
if (! ($shouldUseInvitati || ($id_scheda === "S1" && count($this->oggetto->getRounds()) > 1))) { |
|
return []; |
|
} |
|
} |
|
if ($shouldUseInvitati) { |
|
$participantsData = $this->getInvitati(); |
|
} else { |
|
$participantsData = $this->oggetto->getPartecipanti(); |
|
} |
|
$finalParticipantsData = []; |
|
if (!empty($participantsData)) { |
|
|
|
$participantsData = array_column($participantsData, null, "codice"); |
|
$versione_interna = $this->fascicolo["versione_interna"] ?? 0; |
|
|
|
foreach ($participantsData as &$participant) { |
|
if ($only_aggiudicatari && $participant["aggiudicatario"] !== "S") { |
|
continue; |
|
} |
|
// Generiamo comunque la versione v1 dell'idPartecipante perchè viene usata come fallback |
|
$idPartecipanteV1 = uuidgen_v4("{$participant["codice"]}-{$participant["codice_fiscale"]}-{$participant["ragione_sociale"]}" . "tuttogare_npa" . $this->fascicolo["codice"]); |
|
switch ($versione_interna) { |
|
case 3: |
|
case 4: |
|
// La v3 cerca di usare quello preso dalla tabella e fa fallback alla v1 |
|
$participant["identificativo_partecipante"] = !empty($participant["uuid"]) ? $participant["uuid"] : $idPartecipanteV1; |
|
break; |
|
case 2: |
|
case 1: |
|
$participant["identificativo_partecipante"] = $idPartecipanteV1; |
|
break; |
|
default: |
|
$md5 = md5("{$participant["codice"]}-{$participant["codice_fiscale"]}-{$participant["ragione_sociale"]}"); |
|
$participant["identificativo_partecipante"] = substr($md5, 0, 8) . '-' . substr($md5, 8, 4) . '-' . substr($md5, 12, 4) . '-' . substr($md5, 16, 4) . '-' . substr($md5, 20); |
|
break; |
|
} |
|
$participant["codice_lotto_npa"] = $codice_lotto_npa; |
|
$participant["ruoloOE"] = 3; // Ente unico |
|
$participant["isChild"] = false; // Ente unico |
|
|
|
// Dalla v2 andiamo pure a pescarci i raggruppamenti |
|
if ($include_raggruppamenti && $versione_interna >= 2 && isset($participant["uuid"])) { |
|
$raggruppamento = $this->oggetto->getRaggruppamento($participant["codice"]); |
|
if (!empty($raggruppamento)) { |
|
$participant["ruoloOE"] = 1; // Mandatario |
|
} |
|
if(method_exists($this->oggetto, "getAvvalimento")) { |
|
$avvalimento = $this->oggetto->getAvvalimento($participant["codice"]); |
|
$participant["has_avvalimento"] = !empty($avvalimento); |
|
} |
|
} |
|
|
|
if($shouldUseInvitati) { |
|
$participant["fromInvitati"] = true; |
|
unset($participant["ruoloOE"]); |
|
} |
|
|
|
$finalParticipantsData[] = $participant; |
|
|
|
// Dati di avvalimento e raggruppamento |
|
$subData = []; |
|
|
|
if (!empty($avvalimento)) { |
|
foreach ($avvalimento as $partecipanteAvvalimento) { |
|
$cf = trim(strtoupper($partecipanteAvvalimento["codice_fiscale_impresa"])); |
|
// Usiamo il codice fiscale come differenziante |
|
$target = &$subData[$cf]; |
|
$target = $partecipanteAvvalimento; |
|
$target["identificativo_partecipante"] = $participant["identificativo_partecipante"]; |
|
$target["codice_lotto_npa"] = $codice_lotto_npa; |
|
$target["codice_fiscale"] = $partecipanteAvvalimento["codice_fiscale_impresa"]; |
|
$target["ruoloOE"] = 4; // Ausiliaria |
|
$target["isChild"] = true; // Ausiliaria |
|
$target["avvalimento"] = $partecipanteAvvalimento["ruolo"]; |
|
$target["aggiudicatario"] = $participant["aggiudicatario"] ?? "N"; |
|
$target["uuid"] = uuidgen_v4("{$target["codice"]}-{$target["codice_fiscale"]}-{$partecipanteAvvalimento["ragione_sociale"]}" . "tuttogare_npa" . $this->fascicolo["codice"]); |
|
} |
|
} |
|
if (!empty($raggruppamento)) { |
|
foreach ($raggruppamento as $partecipanteGruppo) { |
|
$cf = trim(strtoupper($partecipanteGruppo["codice_fiscale_impresa"])); |
|
|
|
// Usiamo il codice fiscale come differenziante |
|
$target = &$subData[$cf]; |
|
// Se esiste già sovrascriviamo solo alcuni dati |
|
if(empty($target)) |
|
$target = $partecipanteGruppo; |
|
|
|
$target["identificativo_partecipante"] = $participant["identificativo_partecipante"]; |
|
$target["codice_lotto_npa"] = $codice_lotto_npa; |
|
$target["codice_fiscale"] = $partecipanteGruppo["codice_fiscale_impresa"]; |
|
$target["aggiudicatario"] = $participant["aggiudicatario"] ?? "N"; |
|
$target["isChild"] = true; |
|
// ruoloOE del raggruppamento prende priorità |
|
$target["ruoloOE"] = 2; // Mandante |
|
$target["uuid"] = uuidgen_v4("{$target["codice"]}-{$target["codice_fiscale"]}-{$partecipanteGruppo["ragione_sociale"]}" . "tuttogare_npa" . $this->fascicolo["codice"]); |
|
} |
|
} |
|
foreach($subData as $subPartecipante) { |
|
$finalParticipantsData[] = $subPartecipante; |
|
} |
|
} |
|
} |
|
if($subappalto) { |
|
$subappaltatori = $this->getPartecipantiFromSubappalto(); |
|
$subappaltatori = array_column($subappaltatori, null, "codice_fiscale"); |
|
foreach (array_column($subappaltatori, null, "codice_fiscale") as $codice_fiscale_subappaltatore => $subappaltatore) { |
|
if(array_search($codice_fiscale_subappaltatore, array_column($finalParticipantsData, "codice_fiscale")) === false) { |
|
$finalParticipantsData[] = $subappaltatore; |
|
} |
|
} |
|
} |
|
if (!$noCache) { |
|
$this->cachePartecipanti[$codice_lotto_npa][$only_aggiudicatari ? 1 : 0][$include_raggruppamenti ? 1 : 0][$subappalto ? 1 : 0] = $finalParticipantsData; |
|
} |
|
return $finalParticipantsData; |
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
/** |
|
* Recupera i partecipenti trasmessi nelle schede di subappalto ANAC (RSU1) |
|
* |
|
* @return Array |
|
*/ |
|
public function getPartecipantiFromSubappalto() : Array { |
|
|
|
$retval = []; |
|
$select = ["codice", "dati"]; |
|
$filters = [ |
|
"codice_npa" => $this->fascicolo["codice"], |
|
"codice_lotto" => $this->lot["codice_lotto_npa"], |
|
"stato" => [">=", 50], |
|
"errore" => "NO", |
|
"id_scheda" => "RSU1" |
|
]; |
|
|
|
$schede = self::fetchSchede($select, $filters, false, true); |
|
if(! empty($schede)) { |
|
|
|
foreach($schede as $scheda) { |
|
|
|
$info = json_decode($scheda["dati"], TRUE); |
|
$retval[] = [ |
|
'codice' => null, |
|
'codice_operatore' => null, |
|
'codice_round' => null, |
|
'codice_lotto' => $this->lot['codice'], |
|
'stato' => 'IT', |
|
'codice_fiscale' => $info['anacForm']['subappalto']['codiceFiscaleDittaACascata'], |
|
'ragione_sociale' => $info['anacForm']['subappalto']['denominazioneDittaACascata'] ?? 'OPERATORE ECONOMICO', |
|
'ragione_sociale' => 'OE ' . $info['anacForm']['subappalto']['codiceFiscaleDittaACascata'], |
|
'aggiudicatario' => 'N', |
|
'posizione' => '0', |
|
'utente_modifica' => '4', |
|
'timestamp' => '', |
|
'uuid' => generateUUIDFromString(md5('OE-SUBAPPALTO-SCHEDA-RSU1-'.$scheda['codice'].'-'.$info['anacForm']['subappalto']['codiceFiscaleDittaACascata'])), |
|
'identificativo_partecipante' => generateUUIDFromString(md5('OE-SUBAPPALTO-SCHEDA-RSU1-'.$scheda['codice'].'-'.$info['anacForm']['subappalto']['codiceFiscaleDittaACascata'])), |
|
'codice_lotto_npa' => $this->lot["codice_lotto_npa"], |
|
'ruoloOE' => 3, |
|
"isSubAppaltatore" => true, |
|
'isChild' => false, |
|
'has_avvalimento' => false, |
|
]; |
|
|
|
// if(isset($info["anacForm"]["subappalto"]["codiciFiscaliOE"]) && is_array($info["anacForm"]["subappalto"]["codiciFiscaliOE"])) { |
|
|
|
// foreach ($info["anacForm"]["subappalto"]["codiciFiscaliOE"] as $codice_fiscale) { |
|
|
|
// if(! empty($codice_fiscale)) { |
|
|
|
// $retval[] = [ |
|
// 'codice' => null, |
|
// 'codice_operatore' => null, |
|
// 'codice_round' => null, |
|
// 'codice_lotto' => $this->lot['codice'], |
|
// 'stato' => 'IT', |
|
// 'codice_fiscale' => $codice_fiscale, |
|
// 'ragione_sociale' => 'OPERATORE ECONOMICO ' . $codice_fiscale, |
|
// 'aggiudicatario' => 'N', |
|
// 'posizione' => '0', |
|
// 'utente_modifica' => '4', |
|
// 'timestamp' => '', |
|
// 'uuid' => generateUUIDFromString(md5('OE-SUBAPPALTO-SCHEDA-RSU1-'.$scheda['codice'].'-'.$codice_fiscale)), |
|
// 'identificativo_partecipante' => generateUUIDFromString(md5('OE-SUBAPPALTO-SCHEDA-RSU1-'.$scheda['codice'].'-'.$codice_fiscale)), |
|
// 'codice_lotto_npa' => $this->lot["codice_lotto_npa"], |
|
// 'ruoloOE' => 3, |
|
// "isSubAppaltatore" => true, |
|
// 'isChild' => false, |
|
// 'has_avvalimento' => false, |
|
// ]; |
|
|
|
// } |
|
|
|
|
|
// } |
|
|
|
// } |
|
|
|
} |
|
|
|
return $retval; |
|
|
|
} |
|
|
|
return []; |
|
} |
|
|
|
/** |
|
* Shorthand per aggiungere un suggerimento al quadroEconomicoStandard |
|
* |
|
* @param integer $indiceLotto Indice del lotto |
|
* @param string $key Chiave del suggerimento |
|
* @param mixed $value Valore del suggerimento |
|
* @param string $forced Forzato? |
|
* @return void |
|
*/ |
|
private function addSuggestionLotto(int $indiceLotto, string $key, $value, string $forced = NPASuggestionType::FORCED) { |
|
$this->addSuggestion("lotti.$indiceLotto.$key", $value, $forced); |
|
$this->addSuggestion("aggiudicazioni.$indiceLotto.$key", $value, $forced); |
|
} |
|
|
|
/** |
|
* Aggiunge i suggerimenti relativi ad un lotto |
|
* |
|
* @param integer $codiceLottoNpa Codice lotto NPA |
|
* @return void |
|
*/ |
|
private function addSuggestionsLotto(int $codiceLottoNpa) |
|
{ |
|
$oldLot = $this->lot; |
|
try { |
|
|
|
if(!$this->getIntegrationLot($codiceLottoNpa)) { |
|
return; |
|
} |
|
$lot = $this->lot; |
|
|
|
|
|
$this->locked_repetitions["lotti"] = true; |
|
$this->locked_repetitions["elencoSoggetti"] = true; |
|
$this->locked_repetitions["elencoSoggettiRichiedenti"] = true; |
|
$this->locked_repetitions["elencoIncarichi"] = true; |
|
|
|
|
|
$indiceLotto = $this->indiciLotto[$codiceLottoNpa] ?? count($this->indiciLotto); |
|
$this->indiciLotto[$codiceLottoNpa] = $indiceLotto; |
|
|
|
|
|
// Popoliamo la select dei partecipanti |
|
$aggiudicatariNoRaggruppamenti = $this->getPartecipanti(true, false); |
|
$aggiudicatari_options = []; |
|
foreach ($aggiudicatariNoRaggruppamenti as $partecipante) { |
|
$aggiudicatari_options[$partecipante["identificativo_partecipante"]] = "{$partecipante["ragione_sociale"]} ({$partecipante["codice_fiscale"]})"; |
|
} |
|
if (!empty($aggiudicatari_options)) { |
|
$this->addSuggestion( |
|
"datiContratto.idPartecipante", |
|
["options" => $aggiudicatari_options], |
|
NPASuggestionType::OPTIONAL |
|
); |
|
} |
|
$partecipanti = $this->getPartecipanti(false, true); |
|
$invitati = []; |
|
if ($this->scheda["id_scheda"] !== "S1") { |
|
$invitati = $this->getInvitati($codiceLottoNpa); |
|
} |
|
// Partecipanti |
|
if ($this->has_partecipanti || $this->scheda["id_scheda"] === "S1") { |
|
|
|
$this->addSuggestionsPartecipanti($indiceLotto, $partecipanti, $invitati); |
|
} |
|
// Aggiudicatari |
|
if ($this->has_aggiudicatari || in_array($this->scheda["id_scheda"], ["CM1", "CM2", "S4"], true)) { |
|
$this->addSuggestionsAggiudicatari($indiceLotto, $partecipanti); |
|
} |
|
|
|
/* TODO trovare una corrispondenza tra codici NUTS e codici ISTAT se possibile |
|
|
|
$this->addSuggestion( |
|
"lotti.$lotIndex.codIstat.codice", |
|
$codiceIstat, |
|
false |
|
); |
|
*/ |
|
|
|
// Dati base lotto |
|
$this->locked_repetitions["lotti"] = true; |
|
|
|
$this->addSuggestion("elencoIncarichi.$indiceLotto.cig", $lot["cig"]); |
|
$this->addSuggestion("elencoSoggettiRichiedenti.$indiceLotto.cig", $lot["cig"]); |
|
$this->addSuggestion("elencoSoggetti.$indiceLotto.cig", $lot["cig"]); |
|
$this->addSuggestion("aggiudicazioni.$indiceLotto.cig", $lot["cig"]); |
|
$this->addSuggestion("datiContratto.cig.$indiceLotto", $lot["cig"]); |
|
$this->addSuggestion("cig", $lot["cig"]); |
|
$this->addSuggestion("lotti.$indiceLotto.cig", $lot["cig"]); |
|
|
|
$tipologia = $this->integration["MODULO"] == "concorsi" ? "services" : $this->integration["GENERAL"]["tipologia"] ?? null; |
|
$this->addSuggestionLotto($indiceLotto, "datiBaseDocumenti.url", $this->integration["PUBLIC_URL"], self::urlSuggetionMode()); |
|
|
|
$this->addSuggestionLotto($indiceLotto, "lotIdentifier", "LOT-" . str_pad($lot["numero"], 4, "0", STR_PAD_LEFT)); |
|
|
|
$this->addSuggestionLotto($indiceLotto, "datiBase.oggettoContratto.codice", $tipologia); |
|
$this->addSuggestionLotto($indiceLotto, "datiBase.oggetto", self::cleanSuggestion($lot["oggetto"], "aggiudicazioni.$indiceLotto.datiBase.oggetto")); |
|
|
|
|
|
// scadenzaPresentazioneInvito e oraScadenzaPresentazioneOfferte, iterare tutti i round ed in base a |
|
// alla tipologia, impostare (non forzatamente) la scadenza |
|
|
|
|
|
// La CPV |
|
$this->addSuggestionLotto($indiceLotto, "datiBaseCPV.tipoClassificazione.codice", "cpv"); |
|
$this->addSuggestionLotto($indiceLotto, "datiBaseCPV.cpvPrevalente.codice", $lot["cpv"]); |
|
|
|
|
|
// lotti.0.datiBaseDocumenti.lingue.codice => it |
|
$nuts = DotPath::get($this->integration, "GENERAL.extraInfo.gara.nuts"); |
|
if ($nuts) { |
|
$this->addSuggestionLotto($indiceLotto, "datiBaseContratto.codNUTS.codice", $nuts, NPASuggestionType::OPTIONAL); |
|
} |
|
|
|
$this->addSuggestionLotto($indiceLotto, "cupLotto.0", $lot["cup"]); |
|
$this->addSuggestionLotto($indiceLotto, "cup", $lot["cup"]); |
|
$this->addSuggestion("comunicazione.cup", $lot["cup"], NPASuggestionType::FORCED); |
|
|
|
$importoTotale = $lot["importoTotale"] ?? null; |
|
if ($importoTotale !== null) { |
|
$this->addSuggestionLotto( |
|
$indiceLotto, |
|
"finanziamenti.0.importo", |
|
currency_format($importoTotale), |
|
NPASuggestionType::AUTOFILL |
|
); |
|
$this->addSuggestion("lotti.$indiceLotto.datiBase.importo", currency_format($importoTotale), NPASuggestionType::AUTOFILL); |
|
} |
|
|
|
// |
|
|
|
if (isset($lot["criterio"])) { |
|
$this->addSuggestion("lotti.$indiceLotto.datiBaseAggiudicazione.criteriAggiudicazione.codice", $lot["criterio"] == "vantaggiosa" ? "quality" : "price"); |
|
} |
|
// $this->addSuggestion("lotti.$lotIndex.datiBaseTerminiInvio.oraScadenzaPresentazioneOfferte"]; |
|
|
|
$this->addSuggestionLotto($indiceLotto, "quadroEconomicoStandard.impForniture", "0.00", NPASuggestionType::AUTOFILL); |
|
$this->addSuggestionLotto($indiceLotto, "quadroEconomicoStandard.impServizi", "0.00", NPASuggestionType::AUTOFILL); |
|
$this->addSuggestionLotto($indiceLotto, "quadroEconomicoStandard.impLavori", "0.00", NPASuggestionType::AUTOFILL); |
|
$this->addSuggestionLotto($indiceLotto, "quadroEconomicoStandard.impTotaleSicurezza", currency_format($lot["oneriNoRibasso"] ?? 0), NPASuggestionType::AUTOFILL); |
|
|
|
// Importo del lotto |
|
$importoRibassabile = currency_format($lot["importoRibassabile"] ?? ($lot["importoBase"] ?? 0)); |
|
$chiaveImportoLotto = [ |
|
"services" => "impServizi", |
|
"supplies" => "impForniture", |
|
"works" => "impLavori", |
|
][$tipologia] ?? null; |
|
if ($chiaveImportoLotto !== null) { |
|
$this->addSuggestionLotto( |
|
$indiceLotto, |
|
"quadroEconomicoStandard." . $chiaveImportoLotto, |
|
$importoRibassabile, |
|
NPASuggestionType::AUTOFILL |
|
); |
|
} |
|
|
|
$sommeOpzioniRinnovi = $lot["importoOpzioni"] ?? 0; |
|
$this->addSuggestionQuadroEconomicoStandard($indiceLotto, "quadroEconomicoStandard.sommeOpzioniRinnovi", currency_format($sommeOpzioniRinnovi)); |
|
$this->addSuggestion("lotti.$indiceLotto.opzioniRinnovi", ($sommeOpzioniRinnovi > 0) ? "true" : "false", NPASuggestionType::AUTOFILL); |
|
|
|
if ($tipologia === "works") { |
|
if(!empty($lot["CAT_SOA"])) { |
|
foreach ($lot["CAT_SOA"] as $cs) { |
|
|
|
$indiceRipetibile = 0; |
|
$categoria = $this->pdo->go("SELECT id FROM b_categorie_soa WHERE codice = :codice AND id <> 'ALTRO'", [":codice" => $cs["codice_categoria"]])->fetch(PDO::FETCH_COLUMN, 0); |
|
if (!empty($categoria)) { |
|
if ($cs["prevalente"] == "S") { |
|
|
|
$this->addSuggestionLotto($indiceLotto, "categoria.codice", $categoria); |
|
} else { |
|
|
|
$this->addSuggestionLotto($indiceLotto, "categoriaScorporabile.$indiceRipetibile.codice", $categoria); |
|
$indiceRipetibile++; |
|
} |
|
} |
|
} |
|
} |
|
|
|
} else { |
|
$categoriaLotto = ["services" => "FS", "supplies" => "FB"][$tipologia] ?? "999"; |
|
$this->addSuggestionLotto($indiceLotto, "categoria.codice", $categoriaLotto, NPASuggestionType::AUTOFILL); |
|
} |
|
|
|
$this->addSuggestionsScadenze($indiceLotto); |
|
} finally { |
|
// Resettiamo tutto com'era |
|
if(empty($oldLot)) { |
|
$this->lot = null; |
|
if(isset($this->oggetto)) $this->oggetto->lotto = null; |
|
} else { |
|
$this->setLot($oldLot["codice_lotto_npa"]); |
|
} |
|
} |
|
|
|
} |
|
}
|
|
|