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.
 
 
 
 
 

5456 righe
204 KiB

<?
class gara
{
public $info;
public $round;
public $lotto;
public $activeRound;
public $quickAvailable;
public $quickPanel;
public $db;
public $commissario;
public $normaRiferimento;
protected $managerAvvisi;
protected $managerCommissione;
protected $managerIncarichi;
protected $managerDGUE;
protected $managerRichieste;
protected $managerPubblicita;
public $privata;
public $printSelectLottiConditions;
public $npa;
public $extender;
public $error_rda;
static function getTipologie($filters = null)
{
$moduli = self::getModuli($filters);
$tmp = [];
foreach ($moduli as $modulo) {
$tmp[] = $modulo["tipo"];
}
$tmp = array_unique($tmp);
if (!empty($tmp)) {
$tipologie = [];
global $config;
$conf = jsonToArray($config["jsonFolder"] . "/gare-tipologie.json");
foreach ($tmp as $tipo) {
$tipologie[$tipo] = $conf[$tipo];
}
return $tipologie;
} else {
return false;
}
}
private static function extensionExists() {
if (isset($_SESSION["ente"])) {
$pathExtender = $_SESSION["ente"]->getExtensionPath() . DIRECTORY_SEPARATOR . "gara.extender.class.php";
$extenderName = "GaraExtender{$_SESSION["ente"]->codice}";
if (file_exists($pathExtender)) {
include_once $pathExtender;
return $extenderName;
}
}
}
private function __construct()
{
global $pdo;
$this->commissario = false;
$this->db = $pdo;
}
public static function riferimentiNormativi() {
return [
"2016-50" => [
"label" => "D.lgs 50/2016",
"inizio" => null,
"fine" => '2023-06-30 23:59:59'
],
"2023-36" => [
"label" => "D.lgs 36/2023",
"inizio" => '2023-07-01 00:00:00',
"fine" => null
],
];
}
public static function interpretazioniArt41() : Array {
return [
"complessivo" => "Offerta complessiva: L'operatore economico esprimerà un'offerta complessiva inclusiva di eventuali costi della manodopera differenti",
"scorporato" => "Valutazione separata: L'operatore economico esprimerà un'offerta sulla componente base a cui si sommeranno i costi della manodopera da lui indicati per il calcolo del ribasso complessivo"
];
}
public static function statiTermineProcedura() {
return [
"35", // "Aggiudicazione definitiva"
"50", // "Inviato esito"
"90", // "Annullato"
"95", // "Deserto"
"99", // "Non aggiudicato"
"100" // "Completo"
];
}
public function updateStato($stato)
{
if ($this->info["fase_attiva"] == $this->round["numero"] && $this->info["stato"] < $stato) {
$this->db->go("UPDATE b_gare SET stato = :stato WHERE codice = :codice", [":stato" => $stato, ":codice" => $this->info["codice"]]);
$this->info["stato"] = $stato;
if (in_array($stato,static::statiTermineProcedura()) !== false) {
$b = settingsManager::getValue("pubblicazioneSuConclusione");
if ($b >= 0 && !$this->privata) {
$this->db->go("UPDATE b_gare_round SET pubblica = :pubblica WHERE codice = :codice", [":pubblica" => $b, ":codice" => $this->round["codice"]]);
$this->round["pubblica"] = $b;
if (empty($this->round["pubblicazione"])) {
$this->db->go("UPDATE b_gare_round SET pubblicazione = NOW() WHERE codice = :codice", [":codice" => $this->round["codice"]]);
$this->round["pubblicazione"] = date("Y-m-d H:i:s");
}
}
}
$this->calcolaContributo();
$this->updateBadges();
}
$this->triggerUpdates();
// se la gara è collegata a un'rda, aggiorna lo stato dell'rda
$this->updateStateRda();
}
public function triggerUpdates() {
if (isset($_SESSION["ente"])) {
$_SESSION["ente"]->manageUpdates("gare", $this->info["codice"], $this);
$_SESSION["ente"]->checkConservazione("gare", $this->info["codice"], $this->info["stato"], $this->info["codice_ente"]);
try {
ProcurePlus\Out::sendGara($this);
} catch(\Throwable $t) { /* Niente */ }
}
}
public function updateStatoLotto(int $stato,bool $force = false)
{
if (!empty($this->lotto) && ($this->info["fase_attiva"] == $this->round["numero"] && ($this->lotto["stato"] < $stato || $force))) {
$this->db->go("UPDATE b_gare_lotti SET stato = :stato WHERE codice = :codice", [":stato" => $stato, ":codice" => $this->lotto["codice"]]);
$this->valutaStatoGenerale($force);
}
}
public function calcolaContributo() {
if ($this->info["codice"] != $_SESSION["ente"]->codice) {
$infoContributo = Ente::getContributiSUA($_SESSION["ente"]->codice,$this->info["prezzoRiferimento"]);
if (!empty($infoContributo["quote"]) && ($infoContributo["all"] || !empty($this->getModalita()["online"]))) {
if (($infoContributo["tipo"] == "2" && $this->info["stato"] == 20) || ($infoContributo["tipo"] == "1" && $this->info["stato"] == 35)) {
$riferimento = $this->info["prezzoRiferimento"];
if ($infoContributo["tipo"] != "2") {
$lotti = $this->getLotti();
$riferimento = 0;
foreach($lotti AS $lotto) {
$riferimento += $lotto["importoAggiudicazione"];
}
}
if (!empty($riferimento)) {
$contributo = 0;
foreach($infoContributo["quote"] AS $quota) {
if($quota["tipo"] == "fisso") {
$contributo += $quota["valore"];
} else if ($quota["tipo"] == "percentuale") {
$contributo += $riferimento * ($quota["valore"]/100);
}
}
if (!empty($contributo)) {
$this->db->go("UPDATE b_gare SET contributoSUA = :contributo WHERE codice = :codice", [":contributo" => $contributo, ":codice" => $this->info["codice"]]);
$this->info["contributo"] = $contributo;
}
}
}
}
}
}
public function getManagerRegistro()
{
return new registriManager("gare", $this->info["codice"]);
}
public function configurazioneBusteConfermata()
{
if ($this->info["stato"] <= 10) {
$extraInfo = $this->getExtraInfo()["round"] ?? [];
if (isset($extraInfo["conferma_buste"]) && $extraInfo["conferma_buste"] === true) {
return true;
}
return false;
}
return true;
}
public function sedutaAperta()
{
$extraInfo = $this->getExtraInfo()["round"] ?? [];
if (isset($extraInfo["seduta_aperta"]) && $extraInfo["seduta_aperta"] === true) {
return true;
}
return false;
}
public function showPunteggiTecnici()
{
$extraInfo = $this->getExtraInfo()["round"] ?? [];
if (isset($extraInfo["esponi_tecnici"]) && $extraInfo["esponi_tecnici"] === true) {
return true;
}
return false;
}
public function showPunteggiEconomici()
{
$extraInfo = $this->getExtraInfo()["round"] ?? [];
if (isset($extraInfo["esponi_economici"]) && $extraInfo["esponi_economici"] === true) {
return true;
}
return false;
}
public function addToLog($operazione, $oggetto)
{
return $this->getManagerRegistro()->addToLog($operazione, $oggetto);
}
public function getLog($start = 0, $length = -1)
{
return $this->getManagerRegistro()->getLog($start, $length);
}
public function saveExtraInfo($chiave, $valore, $ambito = "gara")
{
$extraInfo = $this->getExtraInfo();
$extraInfo[$ambito][$chiave] = $valore;
if ($ambito == "gara") {
$codice = $this->info["codice"];
$tabella = "b_gare";
$this->info["extraInfo"] = json_encode($extraInfo["gara"]);
} else if ($ambito == "round") {
$codice = $this->round["codice"];
$tabella = "b_gare_round";
$this->round["extraInfo"] = json_encode($extraInfo["round"]);
} else if ($ambito == "lotto") {
$codice = $this->lotto["codice"];
$tabella = "b_gare_lotti";
$this->lotto["extraInfo"] = json_encode($extraInfo["lotto"]);
}
if (!empty($codice) && !empty($tabella)) {
$extraInfo = json_encode($extraInfo[$ambito]);
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = $tabella;
$salva->operazione = "UPDATE";
$salva->oggetto = ["codice" => $codice, "extraInfo" => $extraInfo];
if (!empty($salva->save())) {
return true;
}
}
return false;
}
public static function save($data)
{
global $pdo;
$return = false;
$operazione_generale = $operazione = empty($data["codice"]) ? "INSERT" : "UPDATE";
$expect = ["codice", "id", "oggetto", "modalita", "tipologia", "accordo_quadro", "procedura", "prezzoRiferimento", "codice_pec", "email_chiave", "codice_ente", "utente_creazione", "timestamp_creazione"];
$solare = false;
$affix = "";
if ($_SESSION["ente"]->getInfo()["numerazione"] == "solare") {
$solare = true;
$expect[] = "anno";
$affix = $data["anno"] . "/";
}
$canClone = false;
if ($operazione == "INSERT") {
$canClone = true;
$data["id"] = 1;
$where = "";
$bind = [];
if ($solare) {
$where = " WHERE anno = :anno ";
$bind[":anno"] = $data["anno"];
}
$sql = "SELECT id FROM b_gare {$where} ORDER BY codice DESC LIMIT 0,1 ";
$ris = $pdo->go($sql,$bind);
if ($ris->rowCount() === 1) {
$rec = $ris->fetch(PDO::FETCH_ASSOC);
if ($solare) {
$tmp = explode("/",$rec["id"]);
if (!empty($tmp[1])) {
$rec["id"] = $tmp[1];
}
}
$data["id"] = (int)$rec["id"] + 1;
}
$data["id"] = $affix . $data["id"];
$data["utente_creazione"] = $_SESSION["utente"]->codice;
$data["timestamp_creazione"] = date('Y-m-d H:i:s');
} else {
$checkRound = $pdo->go("SELECT codice FROM b_gare_round WHERE codice_gara = :codice",[":codice"=>$data["codice"]]);
if ($checkRound->rowCount() > 0) {
$expect = ["codice", "id", "oggetto", "modalita", "accordo_quadro", "prezzoRiferimento", "codice_pec", "email_chiave", "codice_ente", "utente_creazione", "timestamp_creazione"];
}
}
if(!empty($data["importata"])) {
$expect[] = "importata";
}
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "b_gare";
$salva->operazione = $operazione;
$salva->oggetto = $data;
$salva->expect = $expect;
$codice = $salva->save();
if ($codice !== false) {
if ($operazione_generale == "INSERT") {
if ($_SESSION["utente"]->gerarchia > 15) {
$utenti = [$_SESSION["utente"]->codice];
}
if (!empty($utenti)) {
foreach ($utenti as $utente) {
$permesso = [];
$permesso["sezione"] = "gare";
$permesso["codice_elemento"] = $codice;
$permesso["funzione"] = "0";
$permesso["codice_gestore"] = $_SESSION["ente"]->codice;
$permesso["codice_utente"] = $utente;
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "r_permessi";
$salva->operazione = "INSERT";
$salva->oggetto = $permesso;
$salva->save();
}
}
}
$bind = array(":codice" => $codice);
$strsql = "DELETE FROM r_cpv_gare WHERE codice_gara = :codice";
$pdo->go($strsql, $bind);
scriviLog("r_cpv_gare", "DELETE", $pdo->getSQL());
if (!empty($data["cpv"])) {
$data["cpv"] = array_unique($data["cpv"]);
foreach ($data["cpv"] as $codice_categoria) {
if ($codice_categoria != "") {
$bind = array(":codice" => $codice, ":codice_categoria" => $codice_categoria, ":codice_utente" => $_SESSION["utente"]->codice);
$strsql = "INSERT INTO r_cpv_gare (codice_gara,codice,utente_modifica) VALUES (:codice,:codice_categoria,:codice_utente)";
$pdo->go($strsql, $bind);
scriviLog("r_cpv_gare", "INSERT", $pdo->getSQL());
}
}
}
$bind = array();
$bind[":codice"] = $codice;
$strsql = "SELECT * FROM b_gare WHERE codice = :codice";
$risultato = $pdo->go($strsql, $bind);
if ($risultato->rowCount() > 0) {
$record = $risultato->fetch(PDO::FETCH_ASSOC);
if (empty($record["public_key"]) && getModalita()[$record["modalita"]]["online"]) {
$email = $data["email_chiave"] ?? "";
$public = P7Manager::generateKeys("gare-{$record["id"]}", $record["oggetto"], $email);
if (!empty($public)) {
if (!$pdo->go("UPDATE b_gare SET public_key = :public_key WHERE codice = :codice", [":public_key" => $public, ":codice" => $record["codice"]])) {
$error_key = true;
}
} else {
$error_key = true;
}
}
if (!isset($error_key)) {
$return = gara::init($record["codice"]);
if (!empty($return)) {
foreach ($data["extraInfo"] as $chiave => $valore) {
$return->saveExtraInfo($chiave, $valore, "gara");
}
$return->addToLog($operazione_generale, "Dati preliminari");
if ($canClone) {
$return->clone();
}
}
} else {
$return = -1;
if ($operazione == "INSERT") {
$pdo->go("DELETE FROM b_gare WHERE codice = :codice", [":codice" => $codice]);
}
}
}
// salva relazione con rda se esiste
if(!empty($return->info['codice']) && !empty($data['codici_rda'])){
foreach ($data['codici_rda'] as $codice_rda) {
$bind = array(":codice_gara" => $codice, ":codice_rda" => $codice_rda, ":codice_utente" => $_SESSION["utente"]->codice);
$strsql = "INSERT INTO r_gara_rda (codice_gara,codice_rda,utente_modifica) VALUES (:codice_gara,:codice_rda,:codice_utente)";
$ris = $pdo->go($strsql, $bind);
scriviLog("r_gara_rda", "INSERT", $pdo->getSQL());
if($ris->rowCount() === 1){
// controlla se esiste lo stato 20
$codice_stato = StatoRda::getStati(null, 20);
if(!empty($codice_stato)){
$codice_stato = reset($codice_stato);
$bind = array(":codice" => $codice_rda, ":codice_stato" => $codice_stato['codice'], ":utente_modifica" => $_SESSION["utente"]->codice);
$strsql = "UPDATE b_rda SET codice_stato = :codice_stato, utente_modifica = :utente_modifica WHERE codice = :codice";
$ris = $pdo->go($strsql, $bind);
scriviLog("b_rda", "UPDATE", $pdo->getSQL());
}else{
$rda = rda::init($codice_rda);
$return->error_rda[] = __("Errore creazione Gara da RDA #{$rda->info['codice']} - {$rda->info['oggetto']} ");
}
}
}
}
}
return $return;
}
public function setLotto($codice) {
if (!empty($codice)) {
$dbLotto = $this->getLotti($codice)[0] ?? false;
if (!empty($dbLotto)) {
$dbLotto = static::getImportiBaseAsta($dbLotto,$this->normaRiferimento);
$this->lotto = $dbLotto;
return true;
}
}
return false;
}
public function pubblicaPartecipanti($codiceLotto = NULL) {
if (!empty($this->round)) {
if (!empty($codiceLotto)) {
$lotto = $this->getLotti($codiceLotto)[0] ?? false;
} else if (!empty($this->lotto)) {
$lotto = $this->lotto;
}
if ($lotto["stato"] >= 30) {
$extraInfo = json_decode($lotto["extraInfo"],true);
return $extraInfo["showPartecipanti-{$this->round["codice"]}"] ?? false;
}
}
return false;
}
public function pubblicaAtti($codiceLotto = NULL) {
if (!empty($this->round)) {
if (!empty($codiceLotto)) {
$lotto = $this->getLotti($codiceLotto)[0] ?? false;
} else if (!empty($this->lotto)) {
$lotto = $this->lotto;
}
if (isset($lotto)) {
if ($lotto["stato"] >= 50) {
$extraInfo = json_decode($lotto["extraInfo"],true);
return $extraInfo["showAtti-{$this->round["codice"]}"] ?? false;
}
}
}
return false;
}
public function forceAccessoAttiAmministrativa() : Bool {
$rispostaForce = $this->getRisposteElaborazione()["accessoArt36ForceAmministrativa"] ?? "N";
return ($rispostaForce == "S");
}
/**
* amministrativaSecretabile
*
* @param string $dataPubblicazione
* @param string $force
* @return Bool
*/
public static function amministrativaSecretabile(?String $dataPubblicazione = "1970-01-01", Bool $force = false) : Bool {
return ($force || strtotime($dataPubblicazione) > strtotime(date("2024-04-04")));
}
public function getRichiestePubblicabili() {
$richieste = $this->getRichieste();
$return = [];
if (!empty($richieste)) {
foreach($richieste AS $richiesta) {
if ($richiesta["busta"] != "amministrativa" || self::amministrativaSecretabile($this->round["pubblicazione"],$this->forceAccessoAttiAmministrativa())) {
$return[] = $richiesta;
}
}
}
return $return;
}
public function getBustaAccesso(int $richiesta,int $partecipante,bool $content = false) {
$busta = $this->getBusta($partecipante,$richiesta,false,$content);
if (!empty($busta)) {
$pubblica = $busta["pubblica"];
$origine = "busta";
$oscurata = false;
$emendamento = $this->getEmendamento($partecipante,$richiesta,$content);
if (!empty($emendamento) && $emendamento["accettata"] == "S") {
$busta = $emendamento;
$origine = "emendamento";
if ($emendamento["segreta"] == "S") {
$tmp = $this->getBustaSecretata($partecipante,$richiesta,"emendamento",$content);
if (!empty($tmp) && $tmp["accettata"] == "S") {
$oscurata = true;
$busta = $tmp;
}
} else {
if (empty($pubblica)) {
$this->modificaPubblicazioneBusta("S",$partecipante,$richiesta);
$pubblica = "S";
}
}
} else {
if ($busta["segreta"] == "S") {
$tmp = $this->getBustaSecretata($partecipante,$richiesta,"busta",$content);
if (!empty($tmp) && $tmp["accettata"] == "S") {
$oscurata = true;
$busta = $tmp;
}
} else {
if (empty($pubblica)) {
$this->modificaPubblicazioneBusta("S",$partecipante,$richiesta);
$pubblica = "S";
}
}
}
$busta["origine"] = $origine;
$busta["oscurata"] = $oscurata;
$busta["pubblica"] = $pubblica;
}
return $busta;
}
public function modificaPubblicazioneBusta(string $esito,int $partecipante,int $richiesta) {
$busta = $this->getBusta($partecipante,$richiesta);
if (!empty($busta)) {
$richiesta = $this->getRichiesta($richiesta);
if ($richiesta["busta"] != "amministrativa" || self::amministrativaSecretabile($this->round["pubblicazione"],$this->forceAccessoAttiAmministrativa())) {
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "b_gare_buste";
$salva->operazione = "UPDATE";
$salva->oggetto = ["codice"=>$busta["codice"],"pubblica"=>$esito];
$salva->save();
return true;
}
}
}
public function getBusteSoggetteAccesso() {
$richieste = $this->getRichiestePubblicabili();
$partecipanti = $this->getPartecipanti();
$return = [];
if (!empty($richieste) && !empty($partecipanti)) {
foreach($partecipanti AS $partecipante) {
if ($partecipante["escluso"] == "N") {
$return[$partecipante["codice"]] = [];
foreach($richieste AS $richiesta) {
$return[$partecipante["codice"]][$richiesta["codice"]] = $this->getBustaAccesso($richiesta["codice"],$partecipante["codice"]);
}
}
}
}
return $return;
}
public function saveLotto($data) {
$operazione = (empty($data["codice"])) ? "INSERT" : "UPDATE";
if ($operazione == "INSERT") {
$lotti = $this->getLotti();
if (!empty($lotti)) {
$data["numero"] = count($lotti) + 1;
} else {
$data["numero"] = 1;
}
}
$data["codice_gara"] = $this->info["codice"];
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "b_gare_lotti";
$salva->operazione = $operazione;
$salva->oggetto = $data;
$salva->ignore = ["extraInfo","stato"];
$codice = $salva->save();
if (!empty($codice)) {
if ($this->setLotto($codice)) {
if (!empty($data["extraInfo"])) {
foreach($data["extraInfo"] AS $key => $value) {
$this->saveExtraInfo($key,$value,"lotto");
}
}
return $codice;
}
}
return false;
}
public function soloEconomica() {
return (empty($this->getLottiOEPV())) ? true : false;
}
public function getLottiMP() {
$lotti = $this->getLotti();
$return = [];
if (!empty($lotti)) {
foreach($lotti AS $lotto) {
if ($lotto["criterio"] == "prezzo") {
$return[] = $lotto;
}
}
}
return $return;
}
public function getLottiOEPV() {
$lotti = $this->getLotti();
$return = [];
if (!empty($lotti)) {
foreach($lotti AS $lotto) {
if ($lotto["criterio"] != "prezzo") {
$return[] = $lotto;
}
}
}
return $return;
}
public function getIdAppalto() {
return $this->info["codice"]; // TODO: Restituire l'id appalto rilasciato da ANAC
}
public function getExtraInfo()
{
$return = [];
if (!empty($this->info["extraInfo"])) {
$return["gara"] = json_decode($this->info["extraInfo"], true);
}
if (!empty($this->round["extraInfo"])) {
$return["round"] = json_decode($this->round["extraInfo"], true);
}
if (!empty($this->lotto["extraInfo"])) {
$return["lotto"] = json_decode($this->lotto["extraInfo"], true);
}
return $return;
}
public static function getStati()
{
return jsonToArray(__DIR__ . "/stati.json");
}
/**
* Restituisce la configurazione delle buste
*
* @param String|null $dataPubblicazione - Indicare la data di pubblicazione
* @return Array
*/
public static function tipologieBusta(String $dataPubblicazione = "1970-01-01") : Array
{
$return = [];
$return["amministrativa"] = ["titolo" => "Busta Amministrativa","emendabile"=>false,"secretabile"=>self::amministrativaSecretabile($dataPubblicazione)];
$return["tecnica"] = ["titolo" => "Busta Tecnica","emendabile"=>true,"secretabile"=>true];
$return["economica"] = ["titolo" => "Busta Economica","emendabile"=>true,"secretabile"=>true];
return $return;
}
public function busteDisponibili() {
$return = self::tipologieBusta();
if (empty($this->getLottiOEPV()) || (isset($this->lotto) && $this->lotto["criterio"] == "prezzo")) {
unset($return["tecnica"]);
}
return $return;
}
public function getRichieste($busta = NULL)
{
$bind = [":codice_round" => $this->round["codice"]];
$sql = "SELECT b_gare_richieste.* FROM b_gare_richieste ";
if (!empty($this->lotto)) {
$sql .= " JOIN r_gare_richieste_lotti ON b_gare_richieste.codice = r_gare_richieste_lotti.codice_richiesta ";
}
$sql .= " WHERE codice_round = :codice_round ";
if (!empty($this->lotto)) {
$sql .= " AND (r_gare_richieste_lotti.codice_lotto = 0 OR r_gare_richieste_lotti.codice_lotto = :lotto ) ";
if ($this->lotto["criterio"] == "prezzo") {
$sql .= " AND b_gare_richieste.busta <> 'tecnica' ";
}
$bind[":lotto"] = $this->lotto["codice"];
}
if (!empty($busta)) {
$bind[":busta"] = $busta;
$sql .= " AND b_gare_richieste.busta = :busta ";
}
$sql .= " ORDER BY b_gare_richieste.ordinamento, b_gare_richieste.codice ";
return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
}
public function getRichiesta($codice) {
$richieste = $this->getRichieste();
if (!empty($richieste)) {
foreach($richieste AS $richiesta) {
if ($richiesta["codice"] == $codice) {
return $richiesta;
}
}
}
return false;
}
public function getRounds($codice = null)
{
$bind = [":codice_gara" => $this->info["codice"]];
$sql = "SELECT * FROM b_gare_round WHERE codice_gara = :codice_gara ";
if ($codice !== null) {
$bind[":codice"] = $codice;
$sql .= " AND codice = :codice ";
}
return $this->db->go($sql . " ORDER BY numero", $bind)->fetchAll(PDO::FETCH_ASSOC);
}
public function fasiSuccessive() {
$return = [];
$procedura = $this->getProcedura();
if (!empty($procedura["fasi"])) {
$found = false;
foreach($procedura["fasi"] AS $key => $info) {
if ($key == $this->round["id"]) {
$found = true;
if ($info["ripetibile"]) {
$return[$key] = $info;
}
} else {
if ($found) {
$return[$key] = $info;
break;
}
}
}
}
return $return;
}
/**
* getInmportiBaseAsta
*
* Aggiunge al lotto passato alla funzione le chiavi importoRibassabile e importoNonRibassabile in base alla configurazione del lotto
*
* @param Array $lotto
* @param ?String $norma
* @return Array
*/
public static function getImportiBaseAsta(Array $lotto, String $norma = null ) : Array {
$lotto["importoRibassabile"] = (!empty($lotto["importoBase"])) ? $lotto["importoBase"] : 0;
if ($norma != "2016-50") {
$lotto["importoRibassabile"] += (!empty($lotto["importoManodopera"])) ? $lotto["importoManodopera"] : 0;
}
$lotto["importoNonRibassabile"] = (!empty($lotto["oneriNoRibasso"])) ? $lotto["oneriNoRibasso"] : 0;
return $lotto;
}
public static function formatLotto($lotto,$niceNumbers = false) {
$decimale = ".";
$migliaia = "";
if ($niceNumbers) {
$decimale = ",";
$migliaia = ".";
}
if (!isset($lotto["importoRibassabile"])) {
$lotto = static::getImportiBaseAsta($lotto);
}
if (!empty($lotto["importoRibassabile"])) { $lotto["importoRibassabile"] = number_format($lotto["importoRibassabile"],2,$decimale,$migliaia); }
if (!empty($lotto["importoNonRibassabile"])) { $lotto["importoNonRibassabile"] = number_format($lotto["importoNonRibassabile"],2,$decimale,$migliaia); }
if (!empty($lotto["importoBase"])) { $lotto["importoBase"] = number_format($lotto["importoBase"],2,$decimale,$migliaia); }
if (!empty($lotto["importoManodopera"])) { $lotto["importoManodopera"] = number_format($lotto["importoManodopera"],2,$decimale,$migliaia); }
if (!empty($lotto["oneriNoRibasso"])) { $lotto["oneriNoRibasso"] = number_format($lotto["oneriNoRibasso"],2,$decimale,$migliaia); }
if (!empty($lotto["importoOpzioni"])) { $lotto["importoOpzioni"] = number_format($lotto["importoOpzioni"],2,$decimale,$migliaia); }
$lotto["extraInfo"] = json_decode($lotto["extraInfo"],true);
return $lotto;
}
public function getLotti($codice = null)
{
$bind = [":codice_gara" => $this->info["codice"]];
$sql = "SELECT * FROM b_gare_lotti WHERE codice_gara = :codice_gara ";
if ($codice !== null) {
$bind[":codice"] = $codice;
$sql .= " AND codice = :codice ";
}
return $this->db->go($sql . " ORDER BY numero", $bind)->fetchAll(PDO::FETCH_ASSOC);
}
public function getAsta($object = false) {
if (!empty($this->lotto)) {
$bind = [":codice_lotto"=>$this->lotto["codice"],":codice_round"=>$this->round["codice"]];
$sql = "SELECT * FROM b_gare_aste WHERE codice_lotto = :codice_lotto AND codice_round = :codice_round";
$asta = $this->db->go($sql, $bind)->fetch(PDO::FETCH_ASSOC);
if (!empty($asta)) {
if ($object) {
$asta = new asta($this,$asta);
}
return $asta;
}
}
}
public function getCategorieMerceologiche()
{
$codici_categoria = [];
$sql_categoria = "SELECT codice FROM r_cpv_gare WHERE codice_gara = :codice ";
$ris_custom = $this->db->go($sql_categoria, array(":codice" => $this->info["codice"]));
if ($ris_custom->rowCount() > 0) {
while ($categoria = $ris_custom->fetch(PDO::FETCH_ASSOC)) {
if (!empty($categoria)) {
$codici_categoria[] = $categoria["codice"];
}
}
}
$codici_categoria = array_unique($codici_categoria);
return $codici_categoria;
}
public static function getFormule()
{
return tuttogareMath::getFormule();
}
public static function initStatic()
{
$gara = new self();
$gara->info = get_campi("b_gare");
return $gara;
}
public static function init($codice, $codice_round = NULL, $valutazione = NULL)
{
if (! empty($codice) && (defined("__CMDS_JOB_EXEC") || (! empty($_SESSION["utente"]) && ! empty($_SESSION["ente"])))) {
global $pdo;
$bind = [":codice" => $codice];
$sql = "SELECT * FROM b_gare WHERE codice = :codice ";
if (! defined("__CMDS_JOB_EXEC") && ! $_SESSION["utente"]->fromHere() && !isset($valutazione)) {
$sql .= " AND codice_ente = :codice_ente";
$bind[":codice_ente"] = $_SESSION["utente"]->codice_ente;
}
$gara = $pdo->go($sql, $bind)->fetch(PDO::FETCH_ASSOC);
if (! empty($gara)) {
$continua = false;
$commissario = false;
if ($valutazione !== NULL) {
$check = $pdo->go(
"SELECT r_commissione.codice, b_commissioni.scadenza FROM r_commissione JOIN b_commissioni ON r_commissione.codice_commissione = b_commissioni.codice
WHERE r_commissione.codice_utente = :codice_utente AND b_commissioni.codice_elemento = :codice_round
AND b_commissioni.modulo = \"gare\" AND b_commissioni.tipologia = :tipologia ",
[":codice_utente" => $_SESSION["utente"]->codice, ":codice_round" => $codice_round, ":tipologia" => "commissione"]
);
if ($check->rowCount() == 1) {
$check = $check->fetch(PDO::FETCH_ASSOC);
if (($valutazione == "commissione" && ($gara["stato"] == "21" || $gara["stato"] == "25") && strtotime($check["scadenza"]) > time())) {
$continua = true;
$commissario = true;
}
}
} else {
if (!defined("__CMDS_JOB_EXEC")) {
$continua = $_SESSION["utente"]->permission("gare",$gara["codice"],"0",true);
if ($continua) {
if ($_SESSION["utente"]->gerarchia > 9 && $_SESSION["utente"]->codice_ente != $gara["codice_ente"] && $_SESSION["utente"]->codice_ente != $_SESSION["ente"]->codice) {
$continua = false;
}
}
} else {
$continua = true;
}
}
if ($continua) {
$continua = false;
$extensionClass= self::extensionExists();
if (!empty($extensionClass)) {
$instance = new $extensionClass();
} else {
$instance = new gara();
}
$instance->info = $gara;
$instance->commissario = $commissario;
$instance->activeRound = false;
$instance->quickAvailable = false;
$instance->quickPanel = false;
$instance->privata = false;
$enteBeneficiario = Ente::getInfoFromID($gara["codice_ente"])[0] ?? null;
if (isset($enteBeneficiario["soggettoPrivato"]) && $enteBeneficiario["soggettoPrivato"] == "S") {
$instance->privata = true;
}
if ($instance->info["modalita"] == "extra" && $instance->getProcedura()["quick-extra"]) {
$instance->quickAvailable = true;
$instance->quickPanel = false;
$quickPanel = $instance->getExtraInfo()["gara"]["quickPanel"] ?? null;
if (isset($quickPanel) && $quickPanel == "S") {
$instance->quickPanel = true;
}
}
$rounds = $instance->getRounds();
$first = true;
$timeRiferimentoNormativo = time();
if (!empty($rounds)) {
foreach($rounds AS $round) {
if ($first) {
if (!empty($round["pubblicazione"])) {
$timeRiferimentoNormativo = strtotime($round["pubblicazione"]);
}
$first = false;
}
if ($round["codice"] === $codice_round) {
$instance->round = $round;
}
}
if (empty($instance->round)) {
$instance->round = $round;
}
$instance->round["infoFase"] = $instance->getProcedura()["fasi"][$instance->round["id"]] ?? [];
} else {
$instance->round = get_campi("b_gare_round");
$instance->round["numero"] = 1;
}
if ($instance->round["numero"] == $gara["fase_attiva"]) {
$instance->activeRound = true;
}
if ($instance->round["numero"] < $gara["fase_attiva"]) {
$instance->info["stato"] = 100;
}
if (isset($round) && $gara["stato"] == 20 && strtotime($round["scadenza"]) < time() && $instance->activeRound) {
$instance->updateStato(21);
}
$extraInfo = $instance->getExtraInfo()["gara"] ?? null;
if (!empty($extraInfo["normaRiferimento"]) && !empty(self::riferimentiNormativi()[$extraInfo["normaRiferimento"]])) {
$instance->normaRiferimento = $extraInfo["normaRiferimento"];
}
if (empty($instance->normaRiferimento)) {
$instance->normaRiferimento = self::findRiferimentoNormativo($timeRiferimentoNormativo);
}
return $instance;
}
}
}
return false;
}
public static function findRiferimentoNormativo($time = null) {
if (empty($time)) {
return "2023-36";
} else {
$versions = self::riferimentiNormativi();
if (!empty($versions)) {
foreach($versions AS $key => $version) {
$start = null;
$end = null;
if (!empty($version["inizio"])) {
$start = strtotime($version["inizio"]);
}
if (!empty($version["fine"])) {
$end = strtotime($version["fine"]);
}
if ((empty($start) || $start < $time) && (empty($end) || $end > $time)) {
return $key;
}
}
}
}
}
public function getPublicExternalURL() {
return "https://{$_SESSION["ente"]->getInfo()["dominio"]}/gare/dettaglio.php?codice={$this->info["codice"]}";
}
public function getHubData() {
if ($this->info["fase_attiva"] > 1 || $this->round['pubblica'] > 0) {
$lotti = $this->getLotti();
$extraInfo = $this->getExtraInfo();
$return = [
'b_hub_centrale' => [
'codice_gestore'=> $_SESSION["ente"]->codice,
'codice_ente'=> $this->info["codice_ente"],
'codice_interno'=> $this->info["codice"],
'stato'=> $this->info["stato"],
'pubblica'=> $this->round["pubblica"],
'invito'=> (!$this->round["infoFase"]["aperta"]) ? "S" : "N",
'ambito'=> "gare",
'lotti'=> count($lotti),
'oggetto'=> $this->info["oggetto"],
'url'=> $this->getPublicExternalURL(),
'procedura'=> $this->info["procedura"],
'tipologia'=> $this->info["tipologia"],
'pubblicazione'=> mysql2datetime($this->round["pubblicazione"]),
'scadenza'=> mysql2datetime($this->round["scadenza"]),
'chiarimenti'=> mysql2datetime($this->round["chiarimenti"]),
'apertura'=> mysql2datetime($this->round["apertura"]),
'importo'=> $this->info["prezzoRiferimento"],
'nuts'=> $extraInfo["gara"]["nuts"],
]
];
if (!empty($lotti)) {
$return['b_hub_cig'] = [];
$return['b_hub_cup'] = [];
foreach($lotti AS $lotto) {
if (!empty($lotto["cig"])) {
$return['b_hub_cig'][] = [
'cig'=> $lotto["cig"],
'oggetto'=> $lotto["oggetto"],
'importo'=> $lotto["importoBase"] + $lotto["importoOpzioni"] + $lotto["importoManodopera"] + $lotto["oneriNoRibasso"],
'criterio'=> $lotto["criterio"]
];
}
if (!empty($lotto["cup"])) {
$return['b_hub_cup'][] = [
'cup'=> $lotto["cup"],
];
}
}
}
$cpv = $this->getCategorieMerceologiche();
if (!empty($cpv)) {
$return['r_hub_cpv'] = [];
foreach($cpv AS $categoria) {
$return['r_hub_cpv'][] = [
'codice' => $categoria,
];
}
}
$soa = $this->getSOA();
if (!empty($soa)) {
$return['r_hub_soa'] = [];
foreach($soa AS $categoria) {
$return['r_hub_soa'][] = [
'codice_categoria' => $categoria["codice_categoria"],
];
}
}
return $return;
}
}
public function getProcedura()
{
$return = getProcedure(true, null, $this->info["timestamp_creazione"])[$this->info["procedura"]];
if ($this->info["accordo_quadro"] == "S") {
$return["aggiudicazioneMultipla"] = true;
}
$return["key"] = $this->info["procedura"];
return $return;
}
public function getModalita() {
return getModalita()[$this->info["modalita"]];
}
public function getTotaleImporti() {
$totale = self::getTotaleImportiFromTipologie($this->getExtraInfo()["gara"]["importi"]);
return $totale;
}
public static function getTotaleImportiFromTipologie($tipologie)
{
$totale = 0;
foreach ($tipologie as $importo) {
$totale += $importo;
}
return $totale;
}
public function getInterpretazioneArt41() : String {
$return = "";
if ($this->normaRiferimento == "2023-36") {
$return = settingsManager::getValue("interpretazioneArt41");
if ($return == "chiedi") {
$return = $this->getExtraInfo()["gara"]["interpretazioneArt41"] ?? "complessivo";
}
}
return $return;
}
public function updateBadges()
{
$badge = 0;
$sql_bad = "SELECT b_gare_chiarimenti.codice
FROM b_gare_chiarimenti JOIN b_gare_round ON b_gare_chiarimenti.codice_round = b_gare_round.codice
JOIN b_gare ON b_gare_round.codice_gara = b_gare.codice
WHERE b_gare_round.scadenza >= now()
AND b_gare_chiarimenti.attivo = 'N'
AND b_gare.codice = :codice ";
$ris_badge = $this->db->go($sql_bad, [":codice" => $this->info["codice"]]);
$badge += $ris_badge->rowCount();
$sql_bad = "SELECT b_gare_sopralluogo.codice
FROM b_gare_sopralluogo JOIN b_gare_round ON b_gare_sopralluogo.codice_round = b_gare_round.codice
JOIN b_gare ON b_gare_round.codice_gara = b_gare.codice
WHERE b_gare_round.scadenza >= now()
AND b_gare_sopralluogo.attivo = 'P'
AND b_gare.codice = :codice ";
$ris_badge = $this->db->go($sql_bad, [":codice" => $this->info["codice"]]);
$badge += $ris_badge->rowCount();
$this->db->go("UPDATE b_gare SET badge = :badge WHERE codice = :codice", [":badge" => $badge, ":codice" => $this->info["codice"]]);
}
public function printOfferEconomica($edit = true, $bozza = true, $data = false)
{
if (!empty($this->lotto)) {
$model = new editorManager("economica-gare", "gare-preview-" . $this->round["codice"]);
if (!empty($model)) {
$criteriEconomici = $this->getCriteriEconomici();
if (!empty($criteriEconomici)) {
$inputs = [];
$first = true;
global $beRoot;
$receveidData = $data;
if (!empty($data) && is_numeric($data)) {
$dettagli = $this->db->prepare("SELECT offerta,codice_partecipante FROM b_dettaglio_offerte_gare WHERE codice_offerta = :codice_offerta AND codice_dettaglio = :codice_dettaglio AND offerta IS NOT NULL");
$dettagli->bindValue(":codice_offerta", $data);
}
foreach($criteriEconomici AS $criterio) {
if (!empty($criterio["auto"])) {
ob_start();
if ($criterio["tipologia"] != "E") {
$this->printOfferCriterio($criterio["codice"],$edit,$bozza,$data);
} else {
$elencoPrezzi = $this->getElencoPrezzi($criterio["codice"]);
if (!empty($elencoPrezzi)) {
ob_start();
include($beRoot . "/common/criteri/inputs/ep-input.php");
$inputs[] = ob_get_clean();
} else {
alertManager::printAlertBox($criterio["denominazione"],__("Errore configurazione"));
}
}
$inputs[] = ob_get_clean();
if ($first) {
$parentCriteria = $criterio;
$first = false;
}
}
}
if (!empty($parentCriteria)) {
$model->vocabolario["gare"] = $this->info;
$model->vocabolario["fase"] = $this->round;
$formattedLotto = self::formatLotto($this->lotto,true);
$model->vocabolario["lotto"] = $formattedLotto;
if ($this->normaRiferimento == "2016-50") {
$importi = __("Prezzo a base") . ": &euro; " . $formattedLotto["importoBase"];
if ($this->lotto["importoManodopera"] > 0) {
$importi .= " " . strtolower(__("di cui")) . " &euro; " . $formattedLotto["importoManodopera"] . " " . strtolower(__("per costi della manodopera"));
}
$importi .= "<br>" . __("oneri per la sicurezza") . ": &euro; " . $formattedLotto["oneriNoRibasso"];
} else if ($this->normaRiferimento == "2023-36") {
if ($this->getInterpretazioneArt41() === "complessivo") {
$importi = "Importo posto a base di gara: &euro; " . $formattedLotto["importoRibassabile"]. ": <ul>";
$importi .= "<li>" . __(getTipologieAffidamento(false, $this->info["timestamp_creazione"])[$this->info["tipologia"]]["titolo"]) . ": &euro; " . $formattedLotto["importoBase"] . "</li>";
if ($this->lotto["importoManodopera"] > 0) {
$importi .= "<li>" . __("Costi della manodopera") . " &euro; " . $formattedLotto["importoManodopera"] . "</li>";
}
$importi .= "</ul>";
$importi .= __("oneri per la sicurezza") . ": &euro; " . $formattedLotto["oneriNoRibasso"];
} else {
$importi = "<ul>";
$importi .= "<li>" . __(getTipologieAffidamento(false, $this->info["timestamp_creazione"])[$this->info["tipologia"]]["titolo"]) . ": &euro; " . $formattedLotto["importoBase"] . "</li>";
if ($this->lotto["importoManodopera"] > 0) {
$importi .= "<li>" . __("Costi della manodopera") . " &euro; " . $formattedLotto["importoManodopera"] . "</li>";
}
$importi .= "<li>" . __("oneri per la sicurezza") . ": &euro; " . $formattedLotto["oneriNoRibasso"] . "</li>";
$importi .= "</ul>";
}
}
$model->vocabolario["lotto"]["importi"] = $importi;
if (!empty($receveidData) && is_numeric($receveidData)) {
$dettagli->bindValue(":codice_dettaglio", $parentCriteria["codice"] . ".01");
$dettagli->execute();
if ($dettagli->rowCount() > 0) {
$det = $dettagli->fetch(PDO::FETCH_ASSOC);
$partecipante = $this->getPartecipante($det["codice_partecipante"]);
$list_partecipanti = $this->listPartecipanti($partecipante["codice"]);
$valore_sicurezza = $det["offerta"];
}
$dettagli->bindValue(":codice_dettaglio", $parentCriteria["codice"] . ".02");
$dettagli->execute();
if ($dettagli->rowCount() > 0) {
$valore_manodopera = $dettagli->fetch(PDO::FETCH_ASSOC)["offerta"];
}
$data = [];
$tmpCriterio["codice"] = $parentCriteria["codice"] . ".01";
$data[$tmpCriterio["codice"]] = $valore_sicurezza ?? "";
$tmpCriterio["codice"] = $parentCriteria["codice"] . ".02";
$data[$tmpCriterio["codice"]] = $valore_manodopera ?? "";
$data["partecipanti"] = $list_partecipanti;
}
$criterio = [];
$criterio["denominazione"] = "ONERI SICUREZZA AZIENDALE";
$criterio["descrizione"] = "(esprimere il valore in cifre al netto di IVA)";
$criterio["codice"] = $parentCriteria["codice"] . ".01";
$criterio["decimali"] = $parentCriteria["decimali"];
$criterio["auto"] = "";
$criterio["vincoli"] = "";
ob_start();
include($beRoot . "/common/criteri/inputs/offer-input.php");
$inputs[] = ob_get_clean();
$criterio = [];
$criterio["denominazione"] = "COSTO DELLA MANODOPERA";
$criterio["descrizione"] = "(esprimere il valore in cifre al netto di IVA)";
$criterio["codice"] = $parentCriteria["codice"] . ".02";
$criterio["decimali"] = $parentCriteria["decimali"];
$criterio["auto"] = "";
$criterio["vincoli"] = "";
ob_start();
include($beRoot . "/common/criteri/inputs/offer-input.php");
$inputs[] = ob_get_clean();
if (isset($data["partecipanti"])) {
$model->vocabolario["partecipanti"] = $data["partecipanti"];
}
}
if (!empty($inputs)) {
$inputs = implode("",$inputs);
}
}
$criteriTecnici = $this->getCriteriTecnici();
if (!empty($criteriTecnici)) {
if (!empty($receveidData)) {
$data = $receveidData;
}
$inputsTecnici = [];
foreach($criteriTecnici AS $criterio) {
if (!empty($criterio["auto"]) && $criterio["busta"] == "economica") {
ob_start();
$this->printOfferCriterio($criterio["codice"],$edit,$bozza,$data);
$inputsTecnici[] = ob_get_clean();
}
}
if (!empty($inputsTecnici)) {
$inputsTecnici = "<br><br><h2>" . __("ELEMENTI NON ECONOMICI DELL'OFFERTA") . "</h2><br><br>" . implode("",$inputsTecnici);
if (empty($inputs)) {
$inputs = $inputsTecnici;
} else {
$inputs .= $inputsTecnici;
}
}
}
if (!empty($inputs)) {
$model->vocabolario["inputs"] = $inputs;
$model = $model->getModello();
echo $model;
}
}
}
}
public function printOfferCriterio($codice_criterio, $edit = true, $bozza = true, $data = false,$annotazioni = null)
{
$criterio = $this->getCriteri($codice_criterio)[0];
$criterio["vincoli"] = "";
if (!empty($criterio["auto"])) {
if (!empty($data) && is_numeric($data)) {
$dettagli = $this->db->prepare("SELECT offerta FROM b_dettaglio_offerte_gare WHERE codice_offerta = :codice_offerta AND codice_dettaglio = :codice_dettaglio AND offerta IS NOT NULL");
$dettagli->bindValue(":codice_offerta", $data);
}
global $beRoot;
include($beRoot . "/common/criteri/inputs/offer-input.php");
}
}
public function printFormCriterio($codice_criterio, $edit = true, $bozza = true, $data = 0)
{
$criterio = $this->getCriteri($codice_criterio)[0];
$form = $this->getFormCriterio($codice_criterio);
if (!empty($form)) {
$attachID = "gare-form";
$dataSql = "SELECT codice, content FROM b_gare_form_data WHERE codice_input = :input AND codice_offerta = :offerta ";
$viewFormAttachPath = "/backend/gare/open/viewFormAttachment.php";
global $beRoot;
include($beRoot . "/common/criteri/inputs/form-input.php");
}
}
public function getLottiFromCriterio($codice_criterio) {
if (!empty($this->getCriteri($codice_criterio))) {
return $this->db->go("SELECT codice_lotto FROM r_gare_criteri_lotti WHERE codice_criterio = :criterio",[":criterio"=>$codice_criterio])->fetchAll(PDO::FETCH_COLUMN);
}
}
public function getLottiFromRichiesta($codice_richiesta) {
if (!empty($this->getRichiesta($codice_richiesta))) {
return $this->db->go("SELECT codice_lotto FROM r_gare_richieste_lotti WHERE codice_richiesta = :richiesta",[":richiesta"=>$codice_richiesta])->fetchAll(PDO::FETCH_COLUMN);
}
}
public function getCriteriEconomici()
{
return $this->returnCriteri($this->round["codice"], ["economico" => "S"]);
}
public function getCriteriTecnici()
{
return $this->returnCriteri($this->round["codice"], ["economico" => "N"]);
}
public function getCriteriValutabili($codice_criterio = NULL)
{
$tmpCriteri = $this->getCriteri($codice_criterio);
$criteri = [];
if (count($tmpCriteri) > 0) {
foreach ($tmpCriteri as $criterio) {
if (empty($this->getSubCriteri($criterio["codice"]))) {
$criteri[] = $criterio;
}
}
}
return $criteri;
}
public function getCriteriTecniciValutabili()
{
$tmp = $this->getCriteriValutabili();
$criteri = [];
foreach ($tmp as $criterio) {
if ($criterio["economico"] == "N") {
$criteri[] = $criterio;
}
}
return $criteri;
}
public function getCriteriEconomiciValutabili()
{
$tmp = $this->getCriteriValutabili();
$criteri = [];
foreach ($tmp as $criterio) {
if ($criterio["economico"] == "S") {
$criteri[] = $criterio;
}
}
return $criteri;
}
public function returnCriteri($codice_round, $filters = [])
{
if (!empty($this->getRounds($codice_round))) {
$bind = [":codice_round" => $codice_round];
$keysFilters = array_keys(get_campi("b_gare_criteri_valutazione"));
$sql = "SELECT b_gare_criteri_valutazione.* FROM b_gare_criteri_valutazione ";
if (!empty($this->lotto) && empty($filters["ignore-lotto"])) {
$sql .= " JOIN r_gare_criteri_lotti ON b_gare_criteri_valutazione.codice = r_gare_criteri_lotti.codice_criterio ";
}
$sql .= " WHERE b_gare_criteri_valutazione.codice_round = :codice_round ";
if (!empty($this->lotto) && empty($filters["ignore-lotto"])) {
$sql .= " AND (r_gare_criteri_lotti.codice_lotto = 0 OR r_gare_criteri_lotti.codice_lotto = :lotto ) ";
if ($this->lotto["criterio"] == "prezzo") {
$sql .= " AND b_gare_criteri_valutazione.economico = 'S' ";
}
$bind[":lotto"] = $this->lotto["codice"];
}
foreach ($filters as $key => $value) {
if (in_array($key, $keysFilters, true) !== false) {
$bind[":{$key}"] = $value;
$sql .= " AND b_gare_criteri_valutazione.{$key} = :{$key} ";
} else {
if ($key != "ignore-lotto") {
return null;
}
}
}
$sql .= " GROUP BY b_gare_criteri_valutazione.codice ORDER BY b_gare_criteri_valutazione.ordinamento, b_gare_criteri_valutazione.codice ";
return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
}
}
public function getElencoPrezzi($codice_criterio) {
return $this->db->go("SELECT * FROM b_gare_ep WHERE codice_criterio = :criterio ORDER BY ordinamento,codice",[":criterio"=>$codice_criterio])->fetchAll(PDO::FETCH_ASSOC);
}
public function printCriteriaTable()
{
$criteri = $this->getMacroCriteri();
if (!empty($criteri)) {
global $beRoot;
include($beRoot . "/common/criteri/model-table.php");
}
}
public function getDestinatariInterni(bool $onlyCode = false) {
return $this->getManagerRegistro()->getUtentiCoinvoltiConRuolo("USR",$onlyCode);
}
public function chooseLotto($input,$target,$stati = []) {
$lotti = $this->getLotti();
if (!empty($lotti)) {
if (count($lotti) > 1) {
if (!empty($input)) {
$setLotto = $input;
}
} else {
$setLotto = $lotti[0]["codice"];
}
if (!empty($setLotto)) {
if ($this->setLotto($setLotto)) {
return true;
}
} else {
$this->printSelectLotto($target,false,$stati);
return false;
}
}
return false;
}
public function printSelectLotto($target,$allOption = false,$stati = []) {
include(__DIR__."/lotti/selectView.php");
}
public function valutaStatoGenerale(?bool $force = false) {
$lotti = $this->getLotti();
$stati = [];
$lottiCompleti = 0;
foreach($lotti AS $lotto) {
//if ($lotto["stato"] > 0) {
if (in_array($lotto["stato"],self::statiTermineProcedura())) {
$lottiCompleti++;
}
$stati[] = $lotto["stato"];
//}
}
if (!empty($stati) && count($stati) == count($lotti)) {
$stati = array_unique($stati);
if (count($stati) === 1) {
$this->updateStato($stati[0],$force);
} else {
$stato = 25;
if (count($lotti) == $lottiCompleti) {
$stato = 100;
}
$this->updateStato($stato,$force);
}
}
}
public static function ruoloAvvalimento(int $index) {
return ["Requisito", "Miglioramento d'offerta"][$index-1] ?? "SCONOSCIUTO";
}
public function savePartecipante($partecipante) {
if (!empty($partecipante["codice"]) || !$this->getModalita()["online"]) {
$continua = false;
if (!empty($partecipante["codice"])) {
if (!empty($this->getPartecipante($partecipante["codice"],true))) {
$continua = true;
unset($partecipante["codice_operatore"]);
}
} else {
if (!isset($partecipante["codice_operatore"])) {
$partecipante["codice_operatore"] = 0;
}
$partecipante["conferma"] = "S";
$continua = true;
}
if ($continua) {
$partecipante["ruolo"] = (!empty($partecipante["raggruppamento"])) ? "04-CAPOGRUPPO" : "";
$partecipante["codice_lotto"] = $this->lotto["codice"];
$partecipante["codice_round"] = $this->round["codice"];
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "r_partecipanti_gare";
$salva->operazione = empty($partecipante["codice"]) ? "INSERT" : "UPDATE";
$salva->oggetto = $partecipante;
if($salva->operazione === "INSERT") {
$salva->oggetto["uuid"] = uuidgen_v4();
}
$codice = $salva->save();
if ($codice > 0) {
$this->db->go("DELETE FROM r_raggruppamenti_gare WHERE codice_padre = :codice",[":codice"=>$codice]);
if (!empty($partecipante["raggruppamento"])) {
foreach($partecipante["raggruppamento"] as $sub) {
$sub["codice_padre"] = $codice;
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "r_raggruppamenti_gare";
$salva->operazione = "INSERT";
$salva->oggetto = $sub;
$salva->save();
}
}
$this->db->go("DELETE FROM r_avvalimenti_gare WHERE codice_padre = :codice",[":codice"=>$codice]);
if (!empty($partecipante["avvalimento"])) {
foreach($partecipante["avvalimento"] as $sub) {
if(empty($sub["identifier_raggruppamento"]) || $sub["identifier_raggruppamento"] === "PARENT") {
$sub["identifier_raggruppamento"] = null;
}
$sub["codice_padre"] = $codice;
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "r_avvalimenti_gare";
$salva->operazione = "INSERT";
$salva->oggetto = $sub;
$salva->save();
}
}
$this->addToLog(empty($partecipante["codice"]) ? "INSERT" : "UPDATE",__("Partecipante") . " #" . $codice);
return $codice;
}
}
return false;
}
}
public function saveCriterio($criterio) {
if (!empty($this->round)) {
$continua = true;
if (!empty($criterio["codice_padre"])) {
$check = $this->getCriteri($criterio["codice_padre"]);
if (!empty($check)) {
$check = $check[0];
if (!empty($check["auto"])) {
$continua = false;
} else {
$form = $this->getFormCriterio($check["codice"]);
if (!empty($form)) {
$continua = false;
}
}
}
}
if ($continua) {
$criterio["codice_round"] = $this->round["codice"];
if ($criterio["tipologia"] == "Q") {
$criterio["auto"] = "";
$criterio["options"] = "";
} else {
if (isset($criterio["auto"]) && !empty(($criterio["options"][$criterio["auto"]]))) {
$criterio["options"] = json_encode($criterio["options"][$criterio["auto"]]);
} else {
$criterio["options"] = "";
}
}
if ($criterio["economico"] == "S") {
$criterio["busta"] = "economica";
}
$operazione = (is_numeric($criterio["codice"])) ? "UPDATE" : "INSERT";
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "b_gare_criteri_valutazione";
$salva->operazione = $operazione;
$salva->ignore = ["timestamp_modifica"];
$salva->oggetto = $criterio;
$codice = $salva->save();
if ($codice !== false) {
if ($operazione == "INSERT") {
$this->bindCriterio($codice);
}
if ($criterio["tipologia"] != "Q") {
$this->db->go("DELETE FROM b_gare_form WHERE codice_criterio = :codice",[":codice"=>$codice]);
scriviLog("b_gare_form","DELETE",$this->db->getSQL(),$codice);
}
$subCriteri = $this->getSubCriteri($codice);
if (!empty($subCriteri)) {
foreach($subCriteri AS $sub) {
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "b_gare_criteri_valutazione";
$salva->operazione = "UPDATE";
$salva->oggetto = [
"codice" => $sub["codice"],
"decimali" => $criterio["decimali"],
"economico" => $criterio["economico"],
"tipologia" => $criterio["tipologia"],
];
$salva->save();
}
}
$this->checkRichiesteOnEditCriteri();
return $codice;
}
}
}
return false;
}
public function deleteCriterio(Int $codice) {
$lock = $this->checkLock("criteri");
if (!$lock) {
if (!empty($this->getCriteri($codice))) {
$bind = array(":codice"=>$codice);
$sql = "DELETE FROM b_gare_criteri_valutazione WHERE codice_padre = :codice ";
$ris = $this->db->go($sql,$bind);
$sql = "DELETE FROM b_gare_criteri_valutazione WHERE codice = :codice ";
$ris = $this->db->go($sql,$bind);
if ($ris->rowCount() === 1) {
scriviLog("b_gare_criteri_valutazione","DELETE",$this->db->getSQL(),$codice);
$error = false;
$this->addToLog("DELETE",__("Criterio") . "#" . $codice);
$this->checkRichiesteOnEditCriteri();
return true;
}
}
}
return false;
}
public function bindCriterio($criterio,$lotti = 0) {
$this->db->go("DELETE FROM r_gare_criteri_lotti WHERE codice_criterio = :codice",[":codice"=>$criterio]);
$insert = $this->db->prepare("INSERT INTO r_gare_criteri_lotti (codice_criterio,codice_lotto) VALUES (:criterio,:lotto)");
$insert->bindValue(":criterio",$criterio);
$return = true;
if (is_array($lotti)) {
$ok = 0;
foreach($lotti AS $lotto) {
$insert->bindValue(":lotto",$lotto);
$insert->execute();
if ($insert->rowCount() === 1) {
$ok++;
}
}
if (count($lotti) != $ok) {
$return = false;
}
} else {
$insert->bindValue(":lotto",0);
$insert->execute();
if ($insert->rowCount() !== 1) {
$return = false;
}
}
if ($return) {
$sub = $this->getSubCriteri($criterio);
if (!empty($sub)) {
foreach($sub AS $c) {
$this->bindCriterio($c["codice"],$lotti);
}
}
}
$this->checkRichiesteOnEditCriteri();
return $return;
}
public function saveVociEP($criterio,$voci) {
$codici = [];
$error_input = "";
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "b_gare_ep";
$ordinamento = 0;
if (!empty($voci)) {
foreach($voci AS $codice_input => $input) {
if (is_numeric($codice_input)) { $input["codice"] = $codice_input; }
if (empty($input["ordinamento"]) && !is_numeric($codice_input)) {
$input["ordinamento"] = $ordinamento;
}
$input["codice_criterio"] = $criterio;
$salva->operazione = (is_numeric($codice_input)) ? "UPDATE" : "INSERT";
$salva->oggetto = $input;
$cod_input = $salva->save();
$codici[] = $cod_input;
if (empty($cod_input)) {
$error_input .= "<br>Error: " . $input["titolo"];
}
$ordinamento++;
}
}
if (empty($error_input)) {
$codici = implode(",",$codici);
$this->db->go("DELETE FROM b_gare_ep WHERE codice_criterio = :criterio AND codice NOT IN (".$codici.")",[":criterio"=>$criterio]);
$this->addToLog("UPDATE",__("Elenco prezzi") . " - " . __("Criterio") . " #" . $criterio);
}
$this->checkRichiesteOnEditCriteri();
return $error_input;
}
public function saveRichiesta($richiesta) {
if (!empty($this->busteDisponibili($richiesta["busta"]))) {
if (empty($richiesta["codice"])) {
$richiesta["ordinamento"] = count($this->getRichieste($richiesta["busta"]));
}
$richiesta["codice_round"] = $this->round["codice"];
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "b_gare_richieste";
$salva->operazione = (!empty($richiesta["codice"])) ? "UPDATE" : "INSERT";
$salva->oggetto = $richiesta;
$codice = $salva->save();
if (!empty($codice)) {
if (empty($richiesta["codice"])) {
$this->bindRichiesta($codice);
}
if (isset($richiesta["allegato-public"])) {
foreach($richiesta["allegato-public"] as $allegato) {
filesManager::saveFile($allegato["filename"],$codice,"gare-richiesta",$allegato["nome"] ?? "","A",$allegato["classificazione"] ?? "");
}
}
$this->addToLog($salva->operazione,__("Richiesta").": " . $richiesta["titolo"]);
return $codice;
}
}
return false;
}
public function deleteRichiesta($richiesta) {
$richiesta = $this->getRichiesta($richiesta);
if (!empty($richiesta) && $richiesta["locked"] == "N") {
$sql = "DELETE FROM b_gare_richieste WHERE codice = :codice ";
$ris = $this->db->go($sql,[":codice"=>$richiesta["codice"]]);
if ($ris->rowCount() === 1) {
scriviLog("b_gare_richieste","DELETE",$this->db->getSQL(),$richiesta["codice"]);
$this->addToLog("DELETE",__("Richiesta").": " . $richiesta["titolo"]);
return true;
}
}
return false;
}
public function bindRichiesta($richiesta,$lotti = 0) {
$this->db->go("DELETE FROM r_gare_richieste_lotti WHERE codice_richiesta = :codice",[":codice"=>$richiesta]);
$check = $this->db->prepare("SELECT codice FROM r_gare_richieste_lotti WHERE codice_richiesta = :richiesta AND (codice_lotto = :lotto OR codice_lotto = 0)");
$insert = $this->db->prepare("INSERT INTO r_gare_richieste_lotti (codice_richiesta,codice_lotto) VALUES (:richiesta,:lotto)");
$insert->bindValue(":richiesta",$richiesta);
$check->bindValue(":richiesta",$richiesta);
if (is_array($lotti)) {
$ok = 0;
foreach($lotti AS $lotto) {
$insert->bindValue(":lotto",$lotto);
$check->bindValue(":lotto",$lotto);
$check->execute();
if ($check->rowCount() === 0) {
$insert->execute();
if ($insert->rowCount() === 1) {
$ok++;
}
} else {
$ok++;
}
}
if (count($lotti) == $ok) {
return true;
}
} else {
$insert->bindValue(":lotto",0);
$check->bindValue(":lotto",0);
$check->execute();
if ($check->rowCount() === 0) {
$insert->execute();
if ($insert->rowCount() === 1) {
return true;
}
} else {
return true;
}
}
return false;
}
public function checkRichiesteOnEditCriteri()
{
if ($this->getModalita()["online"]) {
$lottoSelezionato = $this->lotto;
$this->lotto = null;
$criteri = $this->getAllCriteri();
$binds = [];
$tipologie = self::tipologieBusta();
$tipologie = array_keys($tipologie);
$allLotti = $this->getLotti();
if (!empty($criteri)) {
foreach ($criteri as $criterio) {
$sub = $this->getSubCriteri($criterio["codice"]);
if (empty($sub)) {
$type = null;
$lotti = $this->getLottiFromCriterio($criterio["codice"]);
if (!empty($lotti)) {
if (!empty($criterio["auto"])) {
if ($criterio["economico"] == "S" || $criterio["busta"] == "economica") {
$type = "economica";
} else if ($criterio["economico"] == "N") {
$type = "tecnica";
}
} else if ($criterio["tipologia"] == "Q" && !empty($this->getFormCriterio($criterio["codice"]))) {
$type = "tecnica";
}
if (!empty($type)) {
if (!isset($binds[$type])) {
$binds[$type] = [];
}
$binds[$type] = array_merge($binds[$type],$lotti);
}
}
}
}
}
foreach ($tipologie as $busta) {
$bind = [];
$bind[":codice_round"] = $this->round["codice"];
$bind[":busta"] = $busta;
if (isset($binds[$busta])) {
$check = $this->db->go("SELECT codice FROM b_gare_richieste WHERE codice_round = :codice_round AND busta = :busta AND locked = 'S'", $bind);
if ($check->rowCount() == 0) {
$richiesta = [];
$richiesta["codice_round"] = $this->round["codice"];
$richiesta["busta"] = $busta;
$richiesta["titolo"] = __("Offerta {$busta}");
$richiesta["descrizione"] = __("Caricare il file generato dal sistema in merito alla compilazione dell'offerta {$busta}");
$richiesta["controllo"] = "F";
$richiesta["ordinamento"] = 0;
$richiesta["locked"] = "S";
$codiceRichiesta = $this->saveRichiesta($richiesta);
} else {
$codiceRichiesta = $check->fetch(PDO::FETCH_COLUMN);
}
if (count($binds[$busta]) == count($allLotti)) {
$lotti = 0;
} else {
$lotti = $binds[$busta];
}
$this->bindRichiesta($codiceRichiesta,$lotti);
} else {
$this->db->go("DELETE FROM b_gare_richieste WHERE busta = :busta AND locked = 'S' AND codice_round = :codice_round",[":busta"=>$busta,":codice_round"=>$this->round["codice"]]);
scriviLog("b_gare_richieste", "DELETE", $this->db->getSQL());
}
}
$this->lotto = $lottoSelezionato;
}
}
public function getCPVLotto(int $codice_lotto) : ?string
{
$res = $this->db->go(
"SELECT cpv FROM b_gare_lotti WHERE codice_gara = :codice AND codice = :codice_lotto LIMIT 1",
[":codice" => $this->info["codice"], ":codice_lotto" => $codice_lotto]
);
if ($res->rowCount() < 1) return null;
$categoria = $res->fetch(PDO::FETCH_ASSOC)["cpv"] ?? "";
if(empty($categoria)) return null;
return str_pad($categoria, 8, "0", STR_PAD_RIGHT);
}
public function getSOASerialize($codice_lotto = null)
{
$soaLotto = $this->getSOA($codice_lotto);
$categorie = getCategorieSOA();
foreach($soaLotto as $key => $soa ) {
$soaLotto[$key]["categoria"] = $categorie[$soa["codice_categoria"]]["id"];
unset($soaLotto[$key]["codice_categoria"]);
$soaLotto[$key]["prevalente"] = $soa["prevalente"] == "S";
}
return $soaLotto;
}
public function getSOA($codice_lotto = null) {
if (!isset($codice_lotto) && !empty($this->lotto)) {
$codice_lotto = $this->lotto["codice"];
}
if (!empty($codice_lotto)) {
return $this->db->go("SELECT * FROM b_gare_soa WHERE codice_lotto = :lotto",[":lotto"=>$codice_lotto])->fetchAll(PDO::FETCH_ASSOC);
}
}
public function getDettaglioSOA($forceAll = false) {
$prevalenti = [];
$scorporabili = [];
$totale_sios = 0;
$sios = [];
$qo = [];
$no_qo = [];
$sios_30 = [];
$sios_no_30 = [];
$tutelate = [];
$scorporabili = [];
$og11 = [];
$vincoli_soa = [];
$flag_sios = false;
$categorie = getCategorieSOA();
$classifica = $this->db->prepare("SELECT * FROM b_classifiche_soa WHERE attivo = 'S' AND minimo <= :importo AND (massimo >= :importo OR massimo = 0)");
if (empty($this->lotto) || $forceAll) {
$lottiCheck = $this->getLotti();
} else {
$lottiCheck = [$this->lotto];
}
foreach($lottiCheck AS $lotto) {
$soa = $this->getSOA($lotto["codice"]);
if (!empty($soa)) {
$vincoli_soa[] = 11;
foreach($soa AS $categoria) {
if ($categoria["prevalente"] == "S") {
$variabile = &$prevalenti;
} else {
$variabile = &$scorporabili;
}
if (!isset($variabile[$categoria["codice_categoria"]])) {
$variabile[$categoria["codice_categoria"]] = 0;
}
$variabile[$categoria["codice_categoria"]] += $categoria["importo"];
}
}
}
if (!empty($scorporabili)) {
foreach($scorporabili AS $id => $importo) {
$categoria = $categorie[$id] ?? null;
if (!empty($categoria)) {
if ($categoria["sios"] == "S") {
if ((($importo * 100) / $this->info["prezzoRiferimento"]) > 15) {
$flag_sios = true;
$vincoli_soa[] = 1;
$sios[] = $categoria["id"];
$totale_sios += $importo;
$classifica->bindValue(":importo",$importo);
$classifica->execute();
if ($classifica->rowCount() > 0) {
$cl = $classifica->fetch(PDO::FETCH_ASSOC);
$classifica->bindValue(":importo",$importo * 0.7);
$classifica->execute();
if ($classifica->rowCount() > 0) {
$cl_ridotta = $classifica->fetch(PDO::FETCH_ASSOC);
if ($cl_ridotta["id"] != $cl["id"]) {
$sios_30[] = $categoria["id"];
$vincoli_soa[] = 2;
} else {
$sios_no_30[] = $categoria["id"];
$vincoli_soa[] = 3;
}
}
}
}
}
if ($categoria["obbligo_qualificazione"] == "S" && !$flag_sios) {
if (((($importo*100)/$this->info["prezzoRiferimento"]) > 10) || $importo > 150000) {
$vincoli_soa[] = 6;
$qo[] = $categoria["id"];
}
}
if ($categoria["obbligo_qualificazione"] == "N") {
$vincoli_soa[] = 7;
$no_qo[] = $categoria["id"];
}
if ($categoria["tutelate"] == "N") {
$vincoli_soa[] = 8;
$tutelate[] = $categoria["id"];
}
if ($categoria["id"] == "OG 11") {
$vincoli_soa[] = 9;
}
if (($categoria["id"] == "OS 3") || ($categoria["id"] == "OS 28") || ($categoria["id"] == "OS 30")) {
if (!isset($og11[$categoria["id"]])) {
$og11[$categoria["id"]] = 0;
}
$og11[$categoria["id"]] += $categoria["importo_base"];
}
}
}
} else {
$vincoli_soa[] = 10;
}
if (empty($tutelate)) {
$vincoli_soa[]=13;
}
if (count($og11)==3) {
$flag = 0;
foreach($og11 AS $key=>$importo) {
switch($key) {
case "OS 3":
if ((($importo*100)/$this->info["prezzoRiferimento"]) >= 10) { $flag++; }
break;
case "OS 28":
if ((($importo*100)/$this->info["prezzoRiferimento"]) >= 25) { $flag++; }
break;
case "OS 30":
if ((($importo*100)/$this->info["prezzoRiferimento"]) >= 25) { $flag++; }
break;
}
}
if ($flag == 3) {
$vincoli_soa[]=9;
}
}
if ($totale_sios>0) {
if (($this->info["prezzoRiferimento"] - ($totale_sios*0.7))>20658000) {
$vincoli_soa[] = 4;
} else {
$vincoli_soa[] = 5;
}
} else {
$vincoli_soa[] = 12;
}
$vincoli_soa = array_unique($vincoli_soa);
$sios = implode(",",$sios);
$qo = implode(",",$qo);
$no_qo = implode(",",$no_qo);
$sios_30 = implode(",",$sios_30);
$sios_no_30 = implode(",",$sios_no_30);
$tutelate = implode(",",$tutelate);
return ["vincoli_soa" => $vincoli_soa,
"sios" => $sios,
"qo" => $qo,
"no_qo" => $no_qo,
"sios_30" => $sios_30,
"sios_no_30" => $sios_no_30,
"tutelate" => $tutelate,
"prevalenti" => $prevalenti,
"scorporabili" => $scorporabili];
}
public function getProgettazione($codice_lotto = null) {
if (!isset($codice_lotto) && !empty($this->lotto)) {
$codice_lotto = $this->lotto["codice"];
}
if (!empty($codice_lotto)) {
$where = " codice_lotto = :lotto ";
$bind = [":lotto"=>$codice_lotto];
} else {
$bind = [":gara"=>$this->info["codice"]];
$where = " codice_lotto IN (SELECT codice FROM b_gare_lotti WHERE codice_gara = :gara) ";
}
if (!empty($where)) {
return $this->db->go("SELECT * FROM b_gare_progettazione WHERE {$where}",$bind)->fetchAll(PDO::FETCH_ASSOC);
}
}
public function getCriteri($codice = NULL)
{
$filters = [];
if (!empty($codice)) {
$filters = ["codice" => $codice];
}
return $this->returnCriteri($this->round["codice"], $filters);
}
public function getAllCriteri($codice = NULL)
{
$filters = ["ignore-lotto"=>true];
if (!empty($codice)) {
$filters = ["codice" => $codice];
}
return $this->returnCriteri($this->round["codice"], $filters);
}
public function getMacroCriteri()
{
return $this->returnCriteri($this->round["codice"], ["codice_padre" => 0]);
}
public function getSubCriteri($codice_padre)
{
return $this->returnCriteri($this->round["codice"], ["codice_padre" => $codice_padre]);
}
public function getFormCriterio($codice_criterio)
{
$risultato = $this->db->go("SELECT * FROM b_gare_form WHERE codice_criterio = :codice_criterio ORDER BY ordinamento, codice", array(":codice_criterio" => $codice_criterio));
if ($risultato->rowCount() > 0) {
return $risultato->fetchAll(PDO::FETCH_ASSOC);
}
return false;
}
private static function defaultAutenticationLevel() {
return $_SESSION["ente"]->defaultAutenticationLevel();
}
public function checkLock($id_cmd,$checkStato = null)
{
$return = true;
$stato = $this->info["stato"];
if (!empty($this->lotto) && $this->lotto["stato"] > 0) {
$stato = $this->lotto["stato"];
}
if (!empty($checkStato)) {
$stato = $checkStato;
}
if ($_SESSION["utente"]->readOnly) {
return true;
} else {
if ($_SESSION["utente"]->hasSuperPowers()) {
$return = false;
} else {
if (($stato >= 0) && !empty($id_cmd) && $_SESSION["utente"]->unlockSupporto()) {
$cmd = self::getInfoModulo($id_cmd);
if ($cmd !== false) {
$loa = $cmd["authenticationLevel"] ?? self::defaultAutenticationLevel();
if ($_SESSION["utente"]->authenticationLevel < $loa) {
return true;
}
if (isset($this->round)) {
if ($this->round["numero"] >= $this->info["fase_attiva"]) {
if (!$this->quickPanel) {
if (($stato >= $cmd["stato_minimo"] || $cmd["stato_minimo"] == null) && ($stato <= $cmd["stato_massimo"] || $cmd["stato_massimo"] === null)) {
$return = false;
}
if (!$return) {
if ($cmd["apertura"] && time() < strtotime($this->round["apertura"])) {
$return = true;
}
if ($cmd["scaduta"] && time() < strtotime($this->round["scadenza"])) {
$return = true;
}
}
} else {
$return = false;
}
}
} else {
$return = false;
}
}
}
}
}
if ($return) {
if($id_cmd == "partecipanti") {
$npa = $this->getNpaInstance();
if(!empty($npa)) {
$return = $npa->hasLockOnPartecipanti(false);
}
}
if($id_cmd == "definitiva") {
$npa = $this->getNpaInstance();
if(!empty($npa)) {
$return = $npa->hasLockOnPartecipanti(true);
} else if (!$this->usaGraduatoria()) {
$return = false;
}
}
}
if ($id_cmd == "lotti" || $id_cmd == "criteri" || $id_cmd == "buste") {
if ((($this->checkPartecipantiPresenti() && !$_SESSION["utente"]->hasSuperPowers()) || $this->info["stato"] > 20) && !$this->quickPanel) {
$return = true;
}
if ($id_cmd == "lotti") {
$npa = $this->getNpaInstance();
if (!empty($npa)) {
$return = (!empty($npa->fascicolo["id_appalto"]) || !empty($npa->fascicolo["id_pianificazione"]));
// Se sarebbe bloccato, verifichiamo che non ci siano modifiche/rettifiche in corso
if($return) {
$return = !$npa->hasPendingRettificheOrModifiche(null, ["CM1", "CM2"]);
}
}
}
}
/*if ($id_cmd == "partecipanti") {
$npa = $this->getNpaInstance();
if (!empty($npa)) {
$return = $npa->hasConfirmedParticipantsCards();
}
}*/
if ($id_cmd == "inviti" && $this->round["numero"] > 1 && !$_SESSION["utente"]->hasSuperPowers() && (!$this->round["infoFase"]["estrazione"] ?? true)) {
$return = true;
}
if ($id_cmd == "preliminari" && !empty($this->getRounds())) {
$return = true;
}
if(in_array($id_cmd, ["provvisoria", "definitiva"], true) && $return) {
$npa = $this->getNpaInstance();
if(!empty($npa)) {
$return = !$npa->hasPendingRettificheOrModifiche(null, ["S4"]);
}
}
return $return;
}
public function alertModifichePericolose($id_cmd) {
if ($id_cmd == "lotti" || $id_cmd == "criteri" || $id_cmd == "buste") {
if ($this->checkPartecipantiPresenti() && $_SESSION["utente"]->hasSuperPowers()) {
include __DIR__ . "/misc/alertModifichePericolose.php";
}
}
}
public function checkOpeningPermission($partecipante, $richiesta, $aggiuntive = false)
{
$return = false;
if (!empty($this->lotto)) {
if (!empty($partecipante) && !empty($richiesta)) {
if ((!empty($this->getRisposteElaborazione()["inversioneProcedimentale"])) && $this->getRisposteElaborazione()["inversioneProcedimentale"] == "S") {
$return = true; // Se non c'è l'apertura sequenziale permetto l'apertura
} else {
$busta = $this->getBusta($partecipante, $richiesta, $aggiuntive); // controllo che la busta esista
if (!empty($busta)) {
if ($busta["open"] == "S") { // se è già aperta posso procedere all'apertura
$return = true;
} else {
if (!$this->activeRound || !$this->checkLock("open")) { // Blocco se è l'ultimo round di lavorazione o se il comando è locked
$infoPartecipante = $this->getPartecipante($partecipante);
if ($infoPartecipante["escluso"] == "N" || $infoPartecipante["escluso"] == "P") {
$tipologie = array_keys(self::tipologieBusta());
$tipologia = $this->db->go("SELECT busta FROM b_gare_richieste WHERE codice = :codice", [":codice" => $richiesta])->fetch(PDO::FETCH_ASSOC);
if (!empty($tipologia)) {
$tipologia = $tipologia["busta"];
$checkSeduta = $this->db->go("SELECT data FROM b_gare_sedute WHERE codice_round = :round AND busta = :busta ORDER BY codice DESC LIMIT 0,1", [":round" => $this->round["codice"], ":busta" => $tipologia]);
$continua = true;
if ($checkSeduta->rowCount() === 1) {
$dataSeduta = $checkSeduta->fetch(PDO::FETCH_ASSOC)["data"];
$continua = false;
if (strtotime($dataSeduta) < time()) {
$continua = true;
}
}
if ($continua) {
$block = false; // la variabile sarà utilizzata per determinare l'esito dopo il ciclo foreach
$buste = [];
foreach ($tipologie as $tipo) {
$buste[] = $tipo;
if ($tipo == $tipologia) {
break;
}
}
if (count($buste) > 1) {
$inBuste = implode("','", $buste);
} else {
$inBuste = $buste[0];
}
$check = $this->db->go(
"SELECT MIN(r_partecipanti_gare.codice) AS firstPartecipante, b_gare_richieste.busta
FROM r_partecipanti_gare JOIN b_gare_buste ON r_partecipanti_gare.codice = b_gare_buste.codice_partecipante
JOIN b_gare_richieste ON b_gare_buste.codice_richiesta = b_gare_richieste.codice
WHERE r_partecipanti_gare.codice_round = :codice_round AND r_partecipanti_gare.conferma =\"S\" AND (r_partecipanti_gare.escluso = \"N\" OR r_partecipanti_gare.escluso = \"P\")
AND b_gare_buste.open = 'N'
AND r_partecipanti_gare.codice_lotto = :codice_lotto
AND b_gare_richieste.busta IN ('{$inBuste}')
GROUP BY b_gare_richieste.busta ",
[":codice_round" => $this->round["codice"],":codice_lotto"=>$this->lotto["codice"]]
);
// si controlla che non ci siano buste chiuse di partecipanti ammessi precedenti a quella del concorrente attuale
if ($check->rowCount() == 1) {
$check = $check->fetch(PDO::FETCH_ASSOC);
if ($check["firstPartecipante"] != $partecipante || $check["busta"] != $tipologia) {
$block = true;
}
} else {
$block = true;
}
if (!$block) {
$return = true;
}
}
}
}
}
}
}
}
}
if ($return && $this->commissario) {
$tipologia = $this->db->go("SELECT busta FROM b_gare_richieste WHERE codice = :codice", [":codice" => $richiesta])->fetch(PDO::FETCH_ASSOC);
$return = false;
if (!empty($tipologia)) {
$tipologia = $tipologia["busta"];
if ($tipologia != "amministrativa") {
$criteri = $this->getCriteri();
foreach ($criteri as $criterio) {
if ($criterio["tipologia"] == "Q" && (($criterio["economico"] == "S" && $tipologia == "economica") || ($criterio["economico"] == "N" && $tipologia == "tecnica"))) {
$return = true;
break;
}
}
}
}
}
}
return $return;
}
public function checkSoglie()
{
$partecipanti = $this->getPartecipanti("ALL");
if (!empty($partecipanti)) {
$codici_partecipanti = [];
foreach($partecipanti AS $partecipante) {
$codici_partecipanti[] = (int) $partecipante["codice"];
}
$codici_partecipanti = implode(",",$codici_partecipanti);
$punteggio = $this->db->prepare("SELECT b_gare_punteggi_partecipanti.codice, b_gare_punteggi_partecipanti.codice_partecipante, b_gare_punteggi_partecipanti.valore
FROM b_gare_punteggi_partecipanti WHERE codice_criterio = :criterio AND codice_partecipante IN (".$codici_partecipanti.")");
$macro = $this->getMacroCriteri();
$esclusi = [];
$checkSoglia = $this->getRisposteElaborazione()["sogliaMinima"] ?? false;
if (!empty($checkSoglia) && $checkSoglia != "N") {
foreach ($macro as $padre) {
$sub = $this->getSubCriteri($padre["codice"]);
if (!empty($sub)) {
$somma = [];
foreach ($sub as $s) {
$punteggio->bindValue(":criterio", $s["codice"]);
$punteggio->execute();
if ($punteggio->rowCount() > 0) {
while ($punt = $punteggio->fetch(PDO::FETCH_ASSOC)) {
if (!isset($somma[$punt["codice_partecipante"]])) {
$somma[$punt["codice_partecipante"]] = 0;
}
$somma[$punt["codice_partecipante"]] += $punt["valore"];
if ($s["soglia"] > 0 && $punt["valore"] < $s["soglia"]) {
$esclusi[] = ["partecipante" => $punt["codice_partecipante"], "codice_relazione" => $s["codice"], "criterio" => $s["denominazione"], "soglia" => $s["soglia"], "valore" => $punt["valore"]];
}
}
}
}
} else {
$somma = [];
$punteggio->bindValue(":criterio", $padre["codice"]);
$punteggio->execute();
if ($punteggio->rowCount() > 0) {
while ($punt = $punteggio->fetch(PDO::FETCH_ASSOC)) {
if (!isset($somma[$punt["codice_partecipante"]])) {
$somma[$punt["codice_partecipante"]] = 0;
}
$somma[$punt["codice_partecipante"]] += $punt["valore"];
}
}
}
if (!empty($somma)) {
foreach ($somma as $codice_partecipante => $valore) {
if ($padre["soglia"] > 0 && $valore < $padre["soglia"]) {
$esclusi[] = ["partecipante" => $codice_partecipante, "codice_relazione" => $padre["codice"], "criterio" => $padre["denominazione"], "soglia" => $padre["soglia"], "valore" => $valore];
}
}
}
}
if (!empty($esclusi)) {
if ($checkSoglia == "E") {
$partecipanti = [];
foreach ($esclusi as $info) {
if (!isset($partecipanti[$info["partecipante"]])) {
$partecipanti[$info["partecipante"]] = __("Soglia minima non superata");
}
$partecipanti[$info["partecipante"]] .= "<br>" . $info["criterio"] . " - " . __("Soglia") . ": " . $info["soglia"] . " - Punteggio: " . $info["valore"];
}
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "r_partecipanti_gare";
foreach ($partecipanti as $codice => $motivazione) {
$salva->operazione = "UPDATE";
$salva->oggetto = ["codice" => $codice, "escluso" => "S", "motivazione" => $motivazione];
$salva->save();
}
} else if ($checkSoglia == "A") {
$updatePunteggio = $this->db->prepare("UPDATE b_gare_punteggi_partecipanti SET valore = 0 WHERE codice = :codice");
foreach ($esclusi as $info) {
$updatePunteggio->bindValue(":codice",$info["codice_relazione"]);
$updatePunteggio->execute();
}
}
}
}
return $esclusi;
}
}
public function updateTotalePunteggi()
{
$this->checkSoglie();
$return = false;
$partecipanti = $this->getPartecipanti("ALL");
$totali = [];
$tecnici = [];
$economici = [];
$sommaMacroTecnici = [];
$sommaMacroEconomici = [];
if (!empty($partecipanti)) {
$sql_punteggi = "SELECT r_partecipanti_gare.codice, b_gare_punteggi_partecipanti.valore, b_gare_criteri_valutazione.economico, b_gare_criteri_valutazione.codice AS codice_criterio, b_gare_criteri_valutazione.codice_padre
FROM b_gare_punteggi_partecipanti JOIN r_partecipanti_gare ON b_gare_punteggi_partecipanti.codice_partecipante = r_partecipanti_gare.codice
JOIN b_gare_criteri_valutazione ON b_gare_punteggi_partecipanti.codice_criterio = b_gare_criteri_valutazione.codice
WHERE r_partecipanti_gare.codice_round = :codice AND r_partecipanti_gare.codice_lotto = :lotto";
$ris_punteggi = $this->db->go($sql_punteggi, array(":codice" => $this->round["codice"],":lotto"=>$this->lotto["codice"]));
if ($ris_punteggi->rowCount() > 0) {
$riparametra = $this->getRisposteElaborazione()["riparametrazioneMacroCriteri"] ?? null;
$riparametra = ($riparametra === "S");
while ($punteggio = $ris_punteggi->fetch(PDO::FETCH_ASSOC)) {
if ($riparametra) {
$riferimento = (!empty($punteggio["codice_padre"])) ? $punteggio["codice_padre"] : $punteggio["codice_criterio"];
if ($punteggio["economico"] == "S") {
if (!isset($sommaMacroEconomici[$riferimento])) {
$sommaMacroEconomici[$riferimento] = [];
}
if (!isset($sommaMacroEconomici[$riferimento][$punteggio["codice"]])) {
$sommaMacroEconomici[$riferimento][$punteggio["codice"]] = 0;
}
$sommaMacroEconomici[$riferimento][$punteggio["codice"]] += $punteggio["valore"];
} else {
if (!isset($sommaMacroTecnici[$riferimento])) {
$sommaMacroTecnici[$riferimento] = [];
}
if (!isset($sommaMacroTecnici[$riferimento][$punteggio["codice"]])) {
$sommaMacroTecnici[$riferimento][$punteggio["codice"]] = 0;
}
$sommaMacroTecnici[$riferimento][$punteggio["codice"]] += $punteggio["valore"];
}
} else {
if ($punteggio["economico"] == "S") {
if (!isset($economici[$punteggio["codice"]])) {
$economici[$punteggio["codice"]] = 0;
}
$economici[$punteggio["codice"]] += $punteggio["valore"];
} else {
if (!isset($tecnici[$punteggio["codice"]])) {
$tecnici[$punteggio["codice"]] = 0;
}
$tecnici[$punteggio["codice"]] += $punteggio["valore"];
}
if (!isset($totali[$punteggio["codice"]])) {
$totali[$punteggio["codice"]] = 0;
}
$totali[$punteggio["codice"]] += $punteggio["valore"];
}
}
if ($riparametra) {
if (!empty($sommaMacroTecnici)) {
foreach($sommaMacroTecnici AS $criterio => $punteggi) {
$criterio = $this->getCriteri($criterio)[0];
$normalizzati = tuttogareMath::proporzionale($punteggi,$criterio["peso"],$criterio["decimali"]);
foreach($normalizzati AS $partecipante => $punteggio) {
if (!isset($tecnici[$partecipante])) {
$tecnici[$partecipante] = 0;
}
$tecnici[$partecipante] += $punteggio;
if (!isset($totali[$partecipante])) {
$totali[$partecipante] = 0;
}
$totali[$partecipante] += $punteggio;
}
}
}
if (!empty($sommaMacroEconomici)) {
foreach($sommaMacroEconomici AS $criterio => $punteggi) {
$criterio = $this->getCriteri($criterio)[0];
$normalizzati = tuttogareMath::proporzionale($punteggi,$criterio["peso"],$criterio["decimali"]);
foreach($normalizzati AS $partecipante => $punteggio) {
if (!isset($economici[$partecipante])) {
$economici[$partecipante] = 0;
}
$economici[$partecipante] += $punteggio;
if (!isset($totali[$partecipante])) {
$totali[$partecipante] = 0;
}
$totali[$partecipante] += $punteggio;
}
}
}
}
}
$return = true;
$salva = new salva();
$salva->debug = false;
foreach ($partecipanti as $partecipante) {
$totale = $totali[$partecipante["codice"]] ?? null;
$totaleTecnico = $tecnici[$partecipante["codice"]] ?? null;
$totaleEconomico = $economici[$partecipante["codice"]] ?? null;
$partecipante["totale"] = number_format($totale, 5);
$partecipante["totaleTecnico"] = number_format($totaleTecnico, 5);
$partecipante["totaleEconomico"] = number_format($totaleEconomico, 5);
$salva->nome_tabella = "r_partecipanti_gare";
$salva->operazione = "UPDATE";
$salva->oggetto = $partecipante;
$salva->save();
}
}
return $return;
}
public function importScore($economici, $ammessi = TRUE)
{
$return = false;
$asta = ($economici === "asta");
if ($asta) {
$criteri = $this->getCriteriValutabili();
} else {
$criteri = ($economici) ? $this->getCriteriEconomiciValutabili() : $this->getCriteriTecniciValutabili();
}
if (!empty($criteri)) {
$partecipanti = $this->getPartecipanti($ammessi);
if (!empty($partecipanti)) {
$salva = new salva();
$salva->debug = false;
$ris_check = $this->db->prepare("SELECT * FROM b_gare_punteggi_partecipanti WHERE codice_partecipante = :codice_partecipante AND codice_criterio = :codice_criterio ");
$errori_importazione = [];
foreach ($criteri as $criterio) {
$punteggi = [];
$auto = false;
if (!empty($criterio["auto"])) {
$auto = true;
$offerte = $this->getOfferte($criterio["codice"], TRUE, $ammessi, $asta);
if (!empty($offerte)) {
$options = json_decode($criterio["options"], true);
if ($economici && count($criteri) === 1 && $this->getInterpretazioneArt41() === "scorporato") {
$offerte = $this->getRibassoComplessivoArt41($offerte);
}
if ($this->lotto["formato"] === "assoluto" && tuttogareMath::getFormule()[$criterio["auto"]]["diretta"]) {
$offerte = tuttogareMath::convertInversaForScore($offerte,$this->lotto["importoRibassabile"]);
}
if ($criterio["peso"] == 100 && $criterio["auto"] == "P" && $criterio["economico"] == "S" && $this->lotto["formato"] !== "r-assoluto") {
$punteggi = $offerte;
} else {
switch ($criterio["auto"]) {
case "I":
$punteggi = tuttogareMath::inversamenteProporzionale($offerte, $criterio["peso"], $criterio["decimali"]);
break;
case "L":
$punteggi = tuttogareMath::lineareSemplice($offerte, $criterio["peso"], $criterio["decimali"], $options);
break;
case "H":
$punteggi = tuttogareMath::incrementoLineare($offerte, $criterio["peso"], $criterio["decimali"]);
break;
case "P":
$punteggi = tuttogareMath::proporzionale($offerte, $criterio["peso"], $criterio["decimali"]);
break;
case "O":
$punteggi = tuttogareMath::onOff($offerte, $criterio["peso"]);
break;
case "S":
$punteggi = tuttogareMath::tabellare($offerte, $options,$criterio["peso"], $criterio["decimali"]);
break;
case "B":
$punteggi = tuttogareMath::bilineare($offerte, $criterio["peso"], $criterio["decimali"], $options);
break;
case "Q":
$punteggi = tuttogareMath::quadratica($offerte, $criterio["peso"], $criterio["decimali"], $options);
break;
default:
return false;
}
}
}
} else if ($criterio["tipologia"] == "Q") {
$auto = true;
$punteggi = $this->getSommaMediaPunteggiCoefficienti($criterio["codice"], NULL, "punteggi");
}
if (!empty($punteggi)) {
foreach ($punteggi as $partecipante => $valore) {
if (is_numeric($valore)) {
$punteggio = array();
$punteggio["codice_partecipante"] = $partecipante;
$punteggio["codice_criterio"] = $criterio["codice"];
$punteggio["valore"] = number_format($valore, $criterio["decimali"]);
$ris_check->bindValue(":codice_partecipante", $punteggio["codice_partecipante"], PDO::PARAM_INT);
$ris_check->bindValue(":codice_criterio", $punteggio["codice_criterio"], PDO::PARAM_INT);
$ris_check->execute();
$operazione = "INSERT";
$continua = true;
if ($ris_check->rowCount() == 1) {
$old = $ris_check->fetch(PDO::FETCH_ASSOC);
$operazione = "UPDATE";
$punteggio["codice"] = $old["codice"];
if ($old["valore"] == $valore) {
$continua = false;
}
}
if ($continua) {
$salva->nome_tabella = "b_gare_punteggi_partecipanti";
$salva->operazione = $operazione;
$salva->oggetto = $punteggio;
$salva->save();
}
}
}
} else if ($auto) {
$errori_importazione[] = $criterio["denominazione"];
}
}
$return = $this->updateTotalePunteggi();
if ($return && !empty($errori_importazione)) {
$return = $errori_importazione;
}
}
}
return $return;
}
public static function algoritmiAnomalie() {
global $config;
return jsonToArray($config["jsonFolder"]."/gare-algoritimiAnomalia.json");
}
public static function domandeStandardAnomalia() {
$domande = [];
$domande["decimali"] = ["label"=>"Decimali","options"=>[0,1,2,3,4,5,6,7,8,9]];
$domande["arrotondamento"] = ["label"=>"Arrotondamento","options"=>["S"=>"Si","N"=>"No"]];
$domande["soloSoglia"] = ["label"=>"Applicazione decimali e arrotondamenti","options"=>["S"=>"Solo soglia","N"=>"Tutti i passaggi"]];
return $domande;
}
public function getAnomaliaSorteggiata() {
$extraInfo = $this->getExtraInfo();
if (isset($this->lotto) && !empty($extraInfo["lotto"]["anomaliaSorteggiata"])) {
return $extraInfo["lotto"]["anomaliaSorteggiata"];
}
}
public function getRispostaElaborazioneAlgoritmoAnomalia() : ?String {
$risposta = $this->getRisposteElaborazione()["esclusioneAutomaticaDlgs36"] ?? null;
if (empty($risposta)) {
$risposta = $this->getRisposteElaborazione()["anomaliaSoprasogliaDlgs36"] ?? null;
}
return $risposta;
}
public function getAlgoritmoAnomalia($excludeSorteggio = false) {
$algoritmi = self::algoritmiAnomalie();
$return = [];
if (!empty($this->lotto) && !empty($algoritmi) && !$this->privata) {
$partecipanti = count($this->getPartecipantiForAnomalia());
$firstRound = $this->getRounds()[0] ?? false;
if (!empty($partecipanti) && !empty($firstRound)) {
$anomaliaSorteggiata = $this->getAnomaliaSorteggiata();
if (!empty($anomaliaSorteggiata)) {
if (!empty($algoritmi[$anomaliaSorteggiata])) {
$algoritmi = [$anomaliaSorteggiata => $algoritmi[$anomaliaSorteggiata]];
} else {
$algoritmi = [];
}
}
if (!empty($algoritmi)) {
foreach($algoritmi AS $idAlgo => $algoritmo) {
if (
(in_array($this->normaRiferimento,$algoritmo["idNormeApplicazione"]) !== false) &&
(in_array($this->lotto["criterio"],$algoritmo["criteri"]) !== false) &&
(in_array($this->info["procedura"],$algoritmo["procedureEscluse"]) === false) &&
(empty($algoritmo["inizio"]) || (strtotime($algoritmo["inizio"]) <= strtotime($firstRound["pubblicazione"]))) &&
(empty($algoritmo["fine"]) || (strtotime($algoritmo["fine"]) >= strtotime($firstRound["pubblicazione"]))) &&
(empty($algoritmo["partecipantiMinimi"]) || ($algoritmo["partecipantiMinimi"] <= $partecipanti)) &&
(empty($algoritmo["partecipantiMassimi"]) || ($algoritmo["partecipantiMassimi"] >= $partecipanti)) &&
(empty($algoritmo["tipologia"]) || in_array($this->info["tipologia"],$algoritmo["tipologia"]) !== false) &&
(!$excludeSorteggio || !$algoritmo["algoritmoSorteggio"])
)
{
$include = true;
$path = __DIR__."/provvisoria/calcoloAnomalie/{$idAlgo}/check.php";
if (file_exists($path)) {
$include = false;
include($path);
}
if($include) {
$return[$idAlgo] = $algoritmo;
}
}
}
}
}
}
return $return;
}
public function calcolaAnomalia($algo,$settings) {
$errors = __("Errore generale nel calcolo");
foreach($this->getAlgoritmoAnomalia() AS $idAlgo => $algoritmo) {
if ($idAlgo == $algo) {
$path = __DIR__."/provvisoria/calcoloAnomalie/{$idAlgo}/calcolo.php";
if (file_exists($path)) {
$soloSoglia = ($settings["soloSoglia"] == "S");
$arrotondamento = ($settings["arrotondamento"] == "S");
$decimali = (int) $settings["decimali"];
$this->db->go("UPDATE r_partecipanti_gare SET anomalia = 'N', motivazione_anomalia = '' WHERE codice_round = :round AND codice_lotto = :lotto AND a_verificata = 'N' AND a_facoltativa = 'N'",[":round"=>$this->round["codice"],":lotto"=>$this->lotto["codice"]]);
$this->db->go("UPDATE r_partecipanti_gare SET escluso = 'N', motivazione = '', esclusione_automatica = 'N' WHERE codice_round = :round AND codice_lotto = :lotto AND esclusione_automatica = 'S'",[":round"=>$this->round["codice"],":lotto"=>$this->lotto["codice"]]);
include($path);
if (isset($extraInfo)) {
foreach($extraInfo AS $key => $value) {
$this->saveExtraInfo($key,$value,"lotto");
}
}
if (isset($soglia_anomalia)) {
$this->db->go("UPDATE b_gare_lotti SET sogliaAnomalia = :soglia WHERE codice = :codice",[":soglia"=>$soglia_anomalia,":codice"=>$this->lotto["codice"]]);
}
} else {
$errors = __("Impossibile eseguire calcolo dell'anomalia");
}
break;
}
}
return $errors;
}
public function aggiudica($aggiudicatari = 1) {
if (!empty($this->lotto)) {
$requestedAggiudicatari = $aggiudicatari;
$salva = new salva();
$salva->debug = false;
$sql = "UPDATE r_partecipanti_gare SET aggiudicatario = 'N', posizione = 0 WHERE codice_round = :codice AND codice_lotto = :lotto ";
$this->db->go($sql,array(":codice"=>$this->round["codice"],":lotto"=>$this->lotto["codice"]));
$sql = "SELECT * FROM r_partecipanti_gare WHERE codice_round = :codice AND codice_lotto = :lotto AND conferma = 'S' AND escluso = 'N' ORDER BY totale DESC";
$ris_partecipanti = $this->db->go($sql,array(":codice"=>$this->round["codice"],":lotto"=>$this->lotto["codice"]));
$partecipanti = $ris_partecipanti->fetchAll(PDO::FETCH_ASSOC);
$current = null;
$riparametrazioneAssoluta = $this->getRisposteElaborazione()["riparametrazioneAssoluta"] ?? "N";
if ($riparametrazioneAssoluta === "S") {
$criteriTecnici = $this->getMacroCriteri();
$punteggioMassimo = 0;
$decimali = 3;
foreach($criteriTecnici AS $criterio) {
if ($criterio["economico"] == "N") {
$punteggioMassimo += $criterio["peso"];
if ($decimali < $criterio["decimali"]) {
$decimali = $criterio["decimali"];
}
}
}
$punteggi = [];
foreach($partecipanti AS $partecipante) {
$punteggi[$partecipante["codice"]] = $partecipante["totaleTecnico"];
}
$punteggi = tuttogareMath::proporzionale($punteggi,$punteggioMassimo,$decimali);
reset($partecipanti);
foreach($partecipanti AS $ind => $partecipante) {
$partecipante["totaleTecnico"] = $punteggi[$partecipante["codice"]];
$partecipante["totale"] = $partecipante["totaleTecnico"] + $partecipante["totaleEconomico"];
$partecipanti[$ind] = $partecipante;
}
usort($partecipanti, function($a, $b) {
return $b["totale"] > $a["totale"];
});
reset($partecipanti);
}
$count = 0;
$posizione = 0;
foreach($partecipanti AS $partecipante) {
$count++;
if ($current != $partecipante["totale"]) {
$posizione = $count;
}
if ($aggiudicatari > 0 || $current == $partecipante["totale"]) {
$partecipante["aggiudicatario"] = "S";
$partecipante["posizione"] = $posizione;
if ($current != $partecipante["totale"]) {
$aggiudicatari--;
}
$current = $partecipante["totale"];
} else {
$partecipante["posizione"] = $posizione;
$partecipante["aggiudicatario"] = "N";
}
$salva->nome_tabella = "r_partecipanti_gare";
$salva->operazione = "UPDATE";
$salva->oggetto = $partecipante;
$salva->save();
}
$this->saveExtraInfo("aggiudicatari-{$this->round["codice"]}",$requestedAggiudicatari,"lotto");
}
}
public function getCostiManodoperaPartecipanti() : ?Array {
$criteri = $this->getCriteriEconomiciValutabili();
$partecipanti = $this->getPartecipanti("ALL");
if (!empty($criteri) && !empty($partecipanti)) {
$first = reset($criteri);
$tmp = $this->getDettaglioOfferta("N",["{$first["codice"]}.02"],$partecipanti);
if (!empty($tmp)) {
$return = [];
foreach ($tmp as $partecipante => $costo) {
$return[$partecipante] = reset($costo);
}
return $return;
}
}
return null;
}
public function getRibassoComplessivoArt41(Array $offerte, Bool $importoAssoluto = false) : ? Array {
$costi = $this->getCostiManodoperaPartecipanti();
$formato = $this->lotto["formato"];
if (!empty($costi)) {
$tmp = [];
foreach($offerte AS $partecipante => $offerta) {
if ($formato == "assoluto" || $formato == "r-assoluto") {
$offerta = $offerta + ($costi[$partecipante] ?? 0);
} else {
if ($formato == "ribasso" || $formato == "nulla") {
$offerta = $this->lotto["importoBase"] * $offerta / 100;
$offerta = $this->lotto["importoBase"] - $offerta;
$offerta += $costi[$partecipante] ?? 0;
} else if ($formato == "rialzo") {
$offerta = $this->lotto["importoBase"] * $offerta / 100;
$offerta = $this->lotto["importoBase"] + $offerta;
$offerta += $costi[$partecipante] ?? 0;
}
if (!$importoAssoluto) {
$offerta = 100 - ($offerta * 100 / $this->lotto["importoRibassabile"]);
}
}
$tmp[$partecipante] = $offerta;
}
$offerte = $tmp;
}
return (empty($offerte)) ? null : $offerte;
}
private function getDettaglioOfferta(String $tipologia, Array $codici_dettaglio, Array $partecipanti, ?String $busta = null) : ?Array {
$return = [];
$filtroTipologia = "";
if (!empty($busta)) {
$filtroTipologia = " AND tipo = :tipoOfferta AND verificata = 'S'";
} else {
$asta = $this->getAsta(true);
$filtroTipologia = " AND verificata <> 'P'";
if (!empty($asta->info) && $asta->getScadenza(true)) {
$filtroTipologia = " AND verificata = 'S'";
}
}
$sql = "SELECT offerta FROM b_dettaglio_offerte_gare
WHERE codice_dettaglio = :dettaglio AND codice_partecipante = :partecipante AND offerta IS NOT NULL AND tipo = :tipologia AND codice_offerta IN
(SELECT MAX(codice) AS last_offer FROM b_offerte_gare WHERE codice_partecipante = :partecipante {$filtroTipologia})";
$getOffer = $this->db->prepare($sql);
$getOffer->bindValue(":tipologia", $tipologia);
if (!empty($busta)) {
$getOffer->bindValue(":tipoOfferta", $busta);
}
foreach ($partecipanti as $partecipante) {
if (!empty($codici_dettaglio)) {
$found = false;
foreach ($codici_dettaglio as $dettaglio) {
$quantita = 1;
if (is_array($dettaglio)) {
$quantita = $dettaglio["quantita"];
$dettaglio = $dettaglio["codice"];
}
$getOffer->bindValue(":dettaglio", $dettaglio);
$getOffer->bindValue(":partecipante", $partecipante["codice"]);
$getOffer->execute();
if ($getOffer->rowCount() == 1) {
$found = true;
$tmpOfferta = $getOffer->fetch(PDO::FETCH_COLUMN);
if ($tmpOfferta !== false) {
$dettagli[$dettaglio] = ($tmpOfferta * $quantita);
}
}
}
if ($found) {
$return[$partecipante["codice"]] = $dettagli;
}
}
}
return (empty($return)) ? null : $return;
}
public function getOfferte($codice_criterio, $totale = true, $ammessi = TRUE, $asta = false)
{
$criterio = $this->getCriteri($codice_criterio);
if (!empty($criterio)) {
$criterio = $criterio[0];
$partecipanti = $this->getPartecipanti($ammessi);
$offerte = [];
$codici_dettaglio = [$codice_criterio];
if ($criterio["tipologia"] == "E") {
$codici_dettaglio = [];
$voci = $this->getElencoPrezzi($criterio["codice"]);
if (!empty($voci)) {
foreach($voci AS $voce) {
$codice_d = $criterio["codice"] . "." . $voce["codice"];
$codici_dettaglio[] = ["codice"=>$codice_d,"quantita"=>$voce["quantita"]];
}
}
}
$dettagli = $this->getDettaglioOfferta($criterio["tipologia"],$codici_dettaglio,$partecipanti, (empty($asta)) ? $criterio["busta"] : null);
if (!empty($dettagli)) {
if (!$totale) {
$offerte = $dettagli;
} else {
foreach($dettagli AS $partecipante => $ds) {
foreach($ds AS $d) {
if (!isset($offerte[$partecipante])) $offerte[$partecipante] = 0;
$offerte[$partecipante] += $d;
}
}
}
}
return $offerte;
}
return false;
}
public function getCoefficientiValutazione($codice_criterio = NULL, $codice_utente = NULL)
{
$tmp = $this->getManagerCommissione("commissione")->getCoefficientiValutazione($codice_criterio, $codice_utente);
$coefficienti = [];
$partecipanti = $this->getPartecipanti();
if (!empty($partecipanti)) {
$codiciPartecipanti = [];
foreach($partecipanti AS $par) {
$codiciPartecipanti[] = $par["codice"];
}
if (!empty($tmp) && !empty($partecipanti)) {
if ((!empty($codice_criterio)) && (!empty($codice_utente))) {
foreach($tmp AS $codicePart => $coef) {
if (in_array($codicePart,$codiciPartecipanti) !== false) {
$coefficienti[$codicePart] = $coef;
}
}
} else if (!empty($codice_utente)) {
foreach($tmp AS $codiceCriterio => $coefP) {
foreach($coefP AS $codicePart => $coef) {
if (in_array($codicePart,$codiciPartecipanti) !== false) {
$coefficienti[$codiceCriterio][$codicePart] = $coef;
}
}
}
} else if (!empty($codice_criterio)) {
foreach($tmp AS $codiceUtente => $coefP) {
foreach($coefP AS $codicePart => $coef) {
if (in_array($codicePart,$codiciPartecipanti) !== false) {
$coefficienti[$codiceUtente][$codicePart] = $coef;
}
}
}
} else {
foreach($tmp AS $codiceCriterio => $coefU) {
foreach($coefU AS $codiceUtente => $coefP) {
foreach($coefP AS $codicePart => $coef) {
if (in_array($codicePart,$codiciPartecipanti) !== false) {
$coefficienti[$codiceCriterio][$codiceUtente][$codicePart] = $coef;
}
}
}
}
}
}
}
return $coefficienti;
}
public function getSommaMediaPunteggiCoefficienti($codice_criterio, $codice_utente = NULL, $output = NULL)
{
$valutazioni = $this->getCoefficientiValutazione($codice_criterio);
$criterio = $this->getCriteri($codice_criterio)[0];
$commissari = $this->getCommissari("commissione", $codice_utente);
$settings = $this->getManagerCommissione("commissione")->getInfo();
$partecipanti = $this->getPartecipanti(TRUE);
$somme = [];
$medie = [];
$normalizzazione = [];
$count = 0;
if (!empty($commissari)) {
foreach ($commissari as $commissario) {
foreach ($partecipanti as $partecipante) {
if (isset($valutazioni[$commissario["codice_utente"]][$partecipante["codice"]])) {
$count++;
if (!isset($somme[$partecipante["codice"]])) {
$somme[$partecipante["codice"]] = 0;
}
$somme[$partecipante["codice"]] += $valutazioni[$commissario["codice_utente"]][$partecipante["codice"]];
}
}
}
if ($count == count($commissari) * count($partecipanti)) {
foreach ($partecipanti as $partecipante) {
$medie[$partecipante["codice"]] = $somme[$partecipante["codice"]] / count($commissari);
if ($settings["riparametra"] == "S") {
$normalizzazione = tuttogareMath::proporzionale($medie, 1, null);
} else {
$normalizzazione = $medie;
}
}
if (!empty($normalizzazione)) {
foreach ($normalizzazione as $partecipante => $coef) {
if ($settings["arrotonda"] == "S") {
$punteggi[$partecipante] = number_format($coef * $criterio["peso"], $criterio["decimali"]);
} else {
$punteggi[$partecipante] = truncate($coef * $criterio["peso"], $criterio["decimali"]);
}
}
switch ($output) {
case "somme":
$return = $somme;
break;
case "medie":
$return = $medie;
break;
case "normalizzazione":
$return = $normalizzazione;
break;
case "punteggi":
$return = $punteggi;
break;
default:
$return = ["somme" => $somme, "medie" => $medie, "normalizzazione" => $normalizzazione, "punteggi" => $punteggi];
}
}
}
}
return $return ?? false;
}
public function getManagerAvvisi()
{
if (empty($this->managerAvvisi)) {
$avvisiProcedura = new avvisiProcedura($_SESSION["ente"]->codice, "gare", $this->info["codice"], $this->round["codice"]);
if (!empty($avvisiProcedura)) {
$this->managerAvvisi = $avvisiProcedura;
}
}
return $this->managerAvvisi;
}
public function getManagerCommissione($tipologia)
{
$manager = new Commissione("gare", $this->round["codice"], $tipologia);
if (!empty($manager)) {
$this->managerCommissione = $manager;
}
return $this->managerCommissione;
}
public function getManagerIncarichi()
{
$manager = new Incarichi("gare", $this->info["codice"]);
if (!empty($manager)) {
$this->managerIncarichi = $manager;
}
return $this->managerIncarichi;
}
public function getManagerDGUE()
{
$manager = new DGUE("gare", $this->round["codice"]);
if (!empty($manager)) {
$this->managerDGUE = $manager;
}
return $this->managerDGUE;
}
public function getDestinatari($ignoreStato = false) {
$return = [];
if (!empty($this->lotto)) {
$lotti = [$this->lotto];
} else {
$lotti = $this->getLotti();
}
foreach($lotti AS $lotto) {
if ($this->setLotto($lotto["codice"])) {
$destinatari = $this->getPartecipanti() ?? [];
if ($this->info["stato"] < 21 || $ignoreStato) {
$destinatari = array_merge($destinatari, ($this->getInvitati() ?? []));
}
$tmp = array_column($destinatari,"codice_operatore");
if (!empty($tmp)) {
$return = array_merge($return,$tmp);
}
if ($this->info["stato"] < 21 || $ignoreStato) {
$manuali = $this->getInvitatiManuali();
if (!empty($manuali)) {
$return = array_merge($return,array_column($manuali,"pec"));
}
}
}
}
if (count($lotti) > 1) {
$this->lotto = null;
}
$return = array_unique($return);
return $return;
}
public function addDGUERequest()
{
if (!$this->checkLock("buste") &&
$this->db->go("SELECT codice FROM b_gare_richieste WHERE titolo = 'DGUE' AND codice_round = :codice_round AND busta = 'amministrativa'", [":codice_round" => $this->round["codice"]])
->rowCount() == 0
) {
$richiesta = [];
$richiesta["codice_round"] = $this->round["codice"];
$richiesta["ordinamento"] = 0;
$richiesta["titolo"] = "DGUE";
$richiesta["descrizione"] = __("Documento di Gara Unico Europeo");
$richiesta["controllo"] = "F";
$richiesta["busta"] = "amministrativa";
$this->saveRichiesta($richiesta);
}
}
public function deleteDGUERequest()
{
if (!$this->checkLock("buste")) {
$this->db->go("DELETE FROM b_gare_richieste WHERE titolo = 'DGUE' AND codice_round = :codice_round AND busta = 'amministrativa'", [":codice_round" => $this->round["codice"]]);
}
}
public function lottiMisti() {
return (!empty($this->getLottiMP()) && !empty($this->getLottiOEPV()));
}
public function getDomandeElaborazione() {
global $config;
$tmp = jsonToArray($config["jsonFolder"]."/gare-elaborazione.json");
$return = [];
$economici = (!empty($this->getLottiMP()));
$tecnici = (!empty($this->getLottiOEPV()));
$multiLotto = (count($this->getLotti()) > 1);
$soglia = $this->getSogliaGara();
if (!empty($tmp)) {
foreach($tmp AS $key => $domanda) {
if ((empty($domanda["inizio"]) || strtotime($domanda["inizio"]) <= strtotime($this->info["timestamp_creazione"])) && (empty($domanda["fine"]) || strtotime($domanda["fine"]) >= strtotime($this->info["timestamp_creazione"]))) {
$insert = true;
if (!empty($domanda["procedureEscluse"]) && in_array($this->info["procedura"],$domanda["procedureEscluse"]) !== false) {
$insert = false;
}
if (!empty($domanda["idNormeApplicazione"]) && in_array($this->normaRiferimento,$domanda["idNormeApplicazione"]) === false) {
$insert = false;
}
if ($soglia == "sottosoglia" && !$domanda["sottosoglia"]) {
$insert = false;
}
if ($soglia == "soprasoglia" && !$domanda["soprasoglia"]) {
$insert = false;
}
if (($this->getModalita()["online"] && !$domanda["online"]) || (!$this->getModalita()["online"] && !$domanda["offline"])) {
$insert = false;
}
if (($multiLotto && !$domanda["multi_lotto"]) || (!$multiLotto && !$domanda["mono_lotto"])) {
$insert = false;
}
if (!empty($this->round["infoFase"]) && (($this->round["infoFase"]["graduatoria"] && !$domanda["graduatoria"]) || (!$this->round["infoFase"]["graduatoria"] && !$domanda["istanza_semplice"]))) {
$insert = false;
}
if (!empty($domanda["tipologieEscluse"]) && in_array($this->info["tipologia"],$domanda["tipologieEscluse"]) !== false) {
$insert = false;
}
if (!empty($domanda["criteri"]) && $insert) {
$insert = false;
if ($economici && in_array("prezzo",$domanda["criteri"]) !== false) {
$insert = true;
}
if ($tecnici && in_array("vantaggiosa",$domanda["criteri"]) !== false) {
$insert = true;
}
}
if ($this->privata && !$domanda["privata"]) {
$insert = false;
}
if($this->quickPanel && ! $domanda["quickPanel"]) {
$insert = false;
}
if (!empty($domanda["impostazioneModuloNecessaria"])) {
foreach($domanda["impostazioneModuloNecessaria"] AS $set => $value) {
$v = settingsManager::getValue($set) ?? null;
if (empty($v) || $v !== $value) {
$insert = false;
break;
}
}
}
if ($insert) {
$return[$key] = $domanda;
}
}
}
}
return $return;
}
public function getDatiMinimi() {
$datiMinimi = $this->db->go("SELECT * FROM b_impostazioni_dati_minimi WHERE attivo = 'S' AND soft_delete = 'N'")->fetchAll(PDO::FETCH_ASSOC);
$return = [];
if (!empty($datiMinimi)) {
foreach($datiMinimi AS $domanda) {
$tipologie = json_decode($domanda["tipologie"],true);
if (in_array($this->info["tipologia"],$tipologie) !== false) {
$return[$domanda["codice"]] = $domanda;
}
}
}
return $return;
}
public function getRisposteElaborazione() {
return json_decode($this->getExtraInfo()["round"]["elaborazione"] ?? "",true);
}
public function modalitaLotti() {
return $this->getRisposteElaborazione()["modalita_lotti"] ?? "libera";
}
public function getRisposteDatiMinimi() {
return json_decode($this->getExtraInfo()["round"]["datiMinimi"] ?? "",true);
}
public function accessoAttiAutomatico() {
$risposta = $this->getRisposteElaborazione()["accessoArt36"] ?? "N";
return ($risposta == "S");
}
public function abilitaBusteSecretate() {
return $this->accessoAttiAutomatico();
}
public function usaGraduatoria() {
$return = true;
$risposte = $this->getRisposteElaborazione();
if (!empty($risposte["usaGraduatoria"]) && $risposte["usaGraduatoria"] == "N") {
$return = false;
}
return $return;
}
public function validaElaborazione() {
$domandeElaborazione = $this->getDomandeElaborazione();
$return = [];
if (!empty($domandeElaborazione)) {
$risposteElaborazione = $this->getRisposteElaborazione();
foreach($domandeElaborazione AS $idDomanda => $infoDomanda) {
if ($infoDomanda["obbligatorio"] && (!isset($risposteElaborazione[$idDomanda]) || $risposteElaborazione[$idDomanda] === "")) {
$return[$idDomanda] = $infoDomanda["quesito"];
} else {
if (!empty($infoDomanda["incompatibilita"])) {
foreach($infoDomanda["incompatibilita"] AS $idIncompatibile => $valoriIncompatibili) {
if (isset($risposteElaborazione[$idIncompatibile])) {
if (!is_array($valoriIncompatibili)) {
$valoriIncompatibili = [$valoriIncompatibili];
}
if (in_array($risposteElaborazione[$idIncompatibile],$valoriIncompatibili)) {
$return[$idDomanda] = $domandeElaborazione[$idIncompatibile]["quesito"] . ":" . __("Risposta incompatibile");
}
}
}
}
}
}
}
if (!$_SESSION["utente"]->fromHere() && $_SESSION["ente"]->getInfo()["permit_cross"] == "N") {
$domandeMinimi = $this->getDatiMinimi();
if (!empty($domandeMinimi)) {
$risposteElaborazione = $this->getRisposteDatiMinimi();
foreach($domandeMinimi AS $idDomanda => $infoDomanda) {
if ($infoDomanda["obbligatorio"] == "S" && (!isset($risposteElaborazione[$idDomanda]) || $risposteElaborazione[$idDomanda] === "" || (is_array($risposteElaborazione[$idDomanda]) && empty($risposteElaborazione[$idDomanda])))) {
$return[$idDomanda] = $infoDomanda["titolo"];
}
}
}
}
if (empty($return)) {
$return = true;
}
return $return;
}
public function inizializzaFase($key,$fase) {
$continua = true;
$infoRda = $this->getExtraInfo()["gara"]["rda"] ?? null;
$rounds = $this->getRounds();
if (!$fase["ripetibile"] && !empty($rounds)) {
foreach($rounds AS $round) {
if ($round["id"] == $key) {
$continua = false;
}
}
}
if ($continua) {
$lotti = $this->getLotti();
if (!empty($lotti) || $this->quickAvailable) {
$numero = 1;
if (!empty($rounds)) {
foreach($rounds AS $round) {
$numero = $round["numero"] + 1;
}
}
$newRound = [];
$newRound["id"] = $key;
$newRound["codice_gara"] = $this->info["codice"];
$newRound["numero"] = $numero;
$newRound["pubblica"] = 0;
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "b_gare_round";
$salva->operazione = "INSERT";
$salva->oggetto = $newRound;
$codice_round = $salva->save();
if ($codice_round) {
if ($numero > 1) {
$this->db->go("UPDATE b_gare SET stato = 10 WHERE codice = :codice",[":codice"=>$this->info["codice"]]);
$statiConclusivi = implode(",",self::statiTermineProcedura());
$this->db->go("UPDATE b_gare_lotti SET stato = 0 WHERE codice_gara = :codice AND stato NOT IN ({$statiConclusivi})",[":codice"=>$this->info["codice"]]);
if (!isset($lotti)) {
$lotti = $this->getLotti();
}
$invitati = [];
foreach($lotti AS $lotto) {
if (!in_array($lotto["stato"],gara::statiTermineProcedura())) {
$this->setLotto($lotto["codice"]);
$partecipanti = $this->getPartecipanti(TRUE);
if (!empty($partecipanti)) {
$invitati[$lotto["codice"]] = array_column($partecipanti,"codice_operatore");
$invitati[$lotto["codice"]] = array_filter($invitati[$lotto["codice"]]);
}
}
}
$this->lotto = null;
}
$this->round = $this->getRounds($codice_round)[0] ?? null;
$this->db->go("UPDATE b_gare SET fase_attiva = :numero WHERE codice = :codice",[":numero"=>$numero,":codice"=>$this->info["codice"]]);
if (!empty($invitati)) {
foreach($invitati AS $codice_lotto => $operatori) {
foreach($operatori AS $oe) {
$this->saveInvito($codice_lotto,$oe,"N",false);
}
}
}
if ($fase["graduatoria"]) {
$formati = [];
$soloPrezzo = true;
if (!isset($lotti)) {
$lotti = $this->getLotti();
}
if (!empty($lotti)) {
foreach($lotti AS $lotto) {
$formati[] = $lotto["formato"];
if ($lotto["criterio"] != "prezzo") {
$soloPrezzo = false;
}
}
$formati = array_unique($formati);
if (count($formati) === 1 && $soloPrezzo) {
$formato = reset($formati);
if (!empty($formato) && $formato != "nulla") {
$criterio = [];
$criterio["codice"] = "";
$criterio["denominazione"] = __(self::formatiOffertaDisponibili()[$formato] ?? "Ribasso");
$criterio["descrizione"] = __("{$criterio["denominazione"]} sull'importo a base di gara");
$criterio["economico"] = "S";
$criterio["auto"] = (in_array($formato,["ribasso","rialzo"])) ? "P" : "I";
$criterio["peso"] = "100";
$criterio["decimali"] = "3";
$criterio["tipologia"] = "N";
$this->saveCriterio($criterio);
}
}
}
}
if (!empty($infoRda) && $infoRda["remote"]) {
if (isset($_SESSION["ente"]->erpConnector) && method_exists($_SESSION["ente"]->erpConnector,"aggiungiInfoRDAaGara")) {
$_SESSION["ente"]->erpConnector->aggiungiInfoRDAaGara($this);
}
}elseif($codici_rda = $this->getRda()){
$this->aggiungiInfoRDAaGara($codici_rda);
}
$this->addToLog("INSERT","Creata fase: " . $key);
return $codice_round;
}
}
}
return false;
}
public function aggiungiInfoRDAaGara(Array $codici_rda = [])
{
if(!empty($codici_rda)){
$tmpCriteri = $tmpArticoli = [];
$count = 0;
$criteriDisponibili = $this->getCriteriEconomici();
foreach ($codici_rda as $codice_rda) {
$rda = rda::init($codice_rda, ['articoli', 'criteri']);
if($rda->info['codice']){
if($rda->relazioni['articoli']){
foreach ($rda->relazioni['articoli'] as $articolo) {
$count++;
$tmpArticoli["i_{$count}"] = [
"titolo" => $articolo["denominazione"],
"descrizione" => $articolo["denominazione"],
"unita" => "UdM",
"tipo" => "misura",
"quantita" => $articolo["quantita"]
];
}
}
if($rda->relazioni['criteri']){
foreach ($rda->relazioni['criteri'] as $criterio) {
if ($criterio["economico"] == "N") {
$tmpCriteri[] = [
'codice' => '',
'denominazione' => $criterio['denominazione'],
'descrizione' => '',
'economico' => $criterio['economico'],
'auto' => '',
'peso' => $criterio['peso'],
'decimali' => '3',
'tipologia' => $criterio["economico"] == 'S' ? 'N' : 'Q'
];
}
}
}
$rda->relazioni['allegato'] = filesManager::listFiles($rda->info["codice"],"rda","A",0,false);
if (!empty($rda->relazioni["allegato"])) {
foreach($rda->relazioni["allegato"] as $allegato) {
$allegato = filesManager::fileInfo($allegato['codice'], $allegato['name'], $allegato['sourceID'], $allegato['sourceType']);
filesManager::saveFileFromBuffer(NULL, base64_decode($allegato["content"]),$this->round["codice"],"gare-reserved",$allegato["titolo"]);
}
}
}
}
if(!empty($tmpArticoli)){
foreach ($criteriDisponibili as $criterio) {
if (!empty($criterio["auto"])) {
$criterio["tipologia"] = "E";
$this->saveCriterio($criterio);
$this->saveVociEP($criterio["codice"],$tmpArticoli);
break;
}
}
}
if(!empty($tmpCriteri)){
foreach ($tmpCriteri as $tmpCriterio) {
$this->saveCriterio($tmpCriterio);
}
}
}
}
public function selfFill() {
if ($this->info["stato"] >= 10 && $this->activeRound) {
if (!$this->usaGraduatoria()) {
$criteri = $this->getCriteri();
if (!empty($criteri)) {
foreach($criteri AS $criterio) {
$this->deleteCriterio($criterio["codice"]);
}
}
}
$risposte = $this->getRisposteElaborazione();
if (!empty($risposte["slotGiustificativi"])) {
$titolo =__("Giustificativi manodopera");
$richieste = $this->getRichieste();
$element = null;
if (!empty($richieste)) {
foreach($richieste AS $tmp) {
if ($tmp["titolo"] == $titolo) {
$element = $tmp["codice"];
break;
}
}
}
if ($risposte["slotGiustificativi"] === "S" && empty($element)) {
$richiesta = [];
$richiesta["codice_round"] = $this->round["codice"];
$richiesta["busta"] = "economica";
$richiesta["titolo"] = $titolo;
$richiesta["descrizione"] = __("Se applicabile, utilizza questo spazio per caricare i tuoi giustificativi per il ribasso della manodopera");
$richiesta["controllo"] = "N";
$richiesta["ordinamento"] = 90;
$richiesta["locked"] = "N";
$this->saveRichiesta($richiesta);
} else if ($risposte["slotGiustificativi"] === "N" && !empty($element)) {
$this->deleteRichiesta($element);
}
}
}
}
public function getManagerRichieste()
{
$manager = new richiesteOE("gare", $this->info["codice"], $this->lotto["codice"]);
if (!empty($manager)) {
$this->managerRichieste = $manager;
}
return $this->managerRichieste;
}
public function getManagerPubblicita()
{
$manager = new pubblicitaLegale("gare", $this->info["codice"], $this->round["codice"]);
if (!empty($manager)) {
$this->managerPubblicita = $manager;
}
return $this->managerPubblicita;
}
public function getChiarimenti(int $codice = NULL)
{
$bind = [":codice_round" => $this->round["codice"]];
$sql_chiarimenti = "SELECT b_gare_chiarimenti.*
FROM b_gare_chiarimenti
WHERE b_gare_chiarimenti.codice_round = :codice_round ";
if (!empty($codice)) {
$sql_chiarimenti .= " AND b_gare_chiarimenti.codice = :codice ";
$bind[":codice"] = $codice;
}
$sql_chiarimenti .= " ORDER BY b_gare_chiarimenti.timestamp ";
$tmp = $this->db->go($sql_chiarimenti, $bind)->fetchAll(PDO::FETCH_ASSOC);
$return = [];
if (!empty($tmp)) {
$i = 0;
foreach ($tmp as $t) {
$i++;
$t["count"] = $i;
$oeInfo = oeManager::getOE($t["codice_richiedente"]);
if(! empty($oeInfo["ragione_sociale"])) { $t["ragione_sociale"] = $oeInfo["ragione_sociale"]; }
$return[] = $t;
}
}
if (!empty($codice) && !empty($return)) {
$return = $return[0];
}
return $return;
}
public function getSopralluoghi(int $codice = NULL)
{
$bind = [":codice_round" => $this->round["codice"]];
$sql_sopralluoghi = "SELECT b_gare_sopralluogo.*
FROM b_gare_sopralluogo
WHERE b_gare_sopralluogo.codice_round = :codice_round ";
if (!empty($codice)) {
$sql_sopralluoghi .= " AND b_gare_sopralluogo.codice = :codice ";
$bind[":codice"] = $codice;
}
$sql_sopralluoghi .= " ORDER BY b_gare_sopralluogo.timestamp ";
$tmp = $this->db->go($sql_sopralluoghi, $bind)->fetchAll(PDO::FETCH_ASSOC);
$return = [];
if (!empty($tmp)) {
foreach ($tmp as $t) {
$oeInfo = oeManager::getOE($t["codice_richiedente"]);
$t["ragione_sociale"] = $oeInfo["ragione_sociale"] ?? "Ragione sociale non presente";
$return[] = $t;
}
}
if (!empty($codice) && !empty($return)) {
$return = $return[0];
}
return $return;
}
public function getAvvalimento($partecipante)
{
if (!empty($this->lotto)) {
$bind = [":codice_round" => $this->round["codice"], ":codice_partecipante" => $partecipante,":codice_lotto" => $this->lotto["codice"]];
$sql = "SELECT r_avvalimenti_gare.*, r_raggruppamenti_gare.ragione_sociale AS nome_padre FROM r_avvalimenti_gare JOIN r_partecipanti_gare
ON r_avvalimenti_gare.codice_padre = r_partecipanti_gare.codice
LEFT JOIN r_raggruppamenti_gare ON r_avvalimenti_gare.identifier_raggruppamento = r_raggruppamenti_gare.identifier
WHERE r_partecipanti_gare.codice_round = :codice_round AND r_partecipanti_gare.codice = :codice_partecipante AND codice_lotto = :codice_lotto";
return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
}
}
public function getRaggruppamento($partecipante)
{
if (!empty($this->lotto)) {
$bind = [":codice_round" => $this->round["codice"], ":codice_partecipante" => $partecipante,":codice_lotto" => $this->lotto["codice"]];
$sql = "SELECT r_raggruppamenti_gare.* FROM r_raggruppamenti_gare JOIN r_partecipanti_gare
ON r_raggruppamenti_gare.codice_padre = r_partecipanti_gare.codice
WHERE r_partecipanti_gare.codice_round = :codice_round AND r_partecipanti_gare.codice = :codice_partecipante AND codice_lotto = :codice_lotto";
return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
}
}
public function getSorgenteInvitati() : String {
$return = __DIR__ . "/inviti/sorgenti/";
$source = "default.php";
$derivazione = $this->getProcedura()["derivazione"] ?? null;
if (!empty($derivazione)) {
switch($derivazione) {
case "accordo":
$source = "accordo.php";
break;
default:
throw new Exception("Derivazione sconosciuta", 404);
break;
}
} else {
if (($this->round["infoFase"]["graduatoria"] ?? false) && $this->round["numero"] > 1) {
$source = "indagine.php";
}
}
$return .= $source;
return $return;
}
public function sorteggiaInvitati(String $tokenOE, String $lotto, Int $partecipanti, String $descrizione = "", Array $esclusioni = []) : Bool {
$estrazione = oeManager::getEstrazione("gare", $this->info["codice"], $lotto);
if (empty($estrazione)) {
if (!empty($lotto)) {
$lotti = [$lotto];
} else {
$lotti = array_column($this->getLotti(), "codice");
}
$continua = true;
foreach ($lotti as $checkLotto) {
if ($this->setLotto($checkLotto)) {
if (!empty($this->countInvitati()) && $tokenOE != "indagine") {
$continua = false;
break;
}
} else {
$continua = false;
break;
}
}
if ($continua) {
unset($this->lotto);
$continua = false;
$oeManager = new oeManager;
if ($tokenOE == "accordo") {
$accordo = accordiQuadro::init($this->info["derivazione"]);
if (!empty($accordo)) {
$aggiudicatari = $accordo->getAggiudicatari();
if (!empty($aggiudicatari)) {
$ooee = array_column($aggiudicatari, "codice_operatore");
$ooee = array_filter($ooee);
if (!empty($ooee)) {
$continua = true;
$oeManager->operatoriSorteggio = $ooee;
}
}
}
} else if ($tokenOE == "indagine") {
$invitati = $this->getInvitati($lotto);
if (!empty($invitati)) {
$ooee = array_column($invitati, "codice_operatore");
$ooee = array_filter($ooee);
if (!empty($ooee)) {
$continua = true;
$deleteInvitati = true;
$oeManager->operatoriSorteggio = $ooee;
}
}
} else {
$continua = true;
$oeManager->setFilters($_SESSION["exportoperatoriSettings"][$tokenOE]);
}
if ($continua) {
$esito = $oeManager->eseguiEstrazione($_SESSION["ente"]->codice, $partecipanti, $esclusioni, $descrizione, "gare", true, $this->info["codice"], $lotto);
if (is_numeric($esito)) {
if (!empty($_SESSION["exportoperatoriSettings"][$tokenOE]["elenco"])) {
$filtroElenco = explode("|", $_SESSION["exportoperatoriSettings"][$tokenOE]["elenco"]);
if (count($filtroElenco) == 2) {
$sources = oeManager::tipiElenco();
$tabellePartecipanti = oeManager::tabelleElenco();
if (in_array($filtroElenco[0], array_keys($sources)) !== false && !empty($tabellePartecipanti[$filtroElenco[0]])) {
$tipo_elenco = $filtroElenco[0];
$codice_elenco = $filtroElenco[1];
$this->saveExtraInfo("tipo_elenco_invito", $tipo_elenco, "round");
$this->saveExtraInfo("codice_elenco_invito", $codice_elenco, "round");
}
}
}
$estrazione = oeManager::getEstrazione("gare", $this->info["codice"], $lotto);
$relazioni = $oeManager->getRelazioniEstrazione($estrazione["codice"]);
if (!empty($deleteInvitati)) {
$this->db->go("DELETE FROM r_inviti_gare WHERE codice_round = :codice_round AND codice_lotto = :lotto ",[":codice_round"=>$this->round["codice"],":lotto"=>$lotto]);
}
foreach ($relazioni as $relazione) {
if ($relazione["selezionato"] == "S" || $relazione["selezionato"] == "A") {
$this->saveInvito($lotto, $relazione["codice_operatore"], true, true);
}
}
ob_start();
oeManager::printReportEstrazione($estrazione, $relazioni, true);
$report = ob_get_clean();
$report = "<html><style>body{font-size:10px;}td,th{padding:5px;border:1pxsolid#AAA}th{background-color:#DDD}tr.odd{background-color:#DDD;}table{width:100%}</style><body>{$report}</body></html>";
$pdf = documentConverter::getPDFWithWKHTML($report,"A4","landscape");
$sezione = ($this->accessoAttiAutomatico()) ? "gare-accessoatti" : "gare-reserved";
filesManager::saveFileFromBuffer(null,$pdf,$this->round["codice"],$sezione,__("Verbale estrazione") . " - " . date("Y-m-d H:i:s"));
return true;
} else {
throw new Exception("Errore nel sorteggio");
}
} else {
throw new Exception("Errore identificazione Operatori");
}
} else {
throw new Exception("Invitati già selezionati");
}
} else {
throw new Exception("Estrazione già presente");
}
return false;
}
public function saveInvito($lotto,$operatore,$sorteggio,$updateContatori = true) {
$insert = $this->db->prepare("INSERT INTO r_inviti_gare (codice_operatore,codice_round,codice_lotto,sorteggio,utente_modifica) VALUES (:oe,:fase,:lotto,:sorteggio,:utente) ");
$oe = oeManager::getOE($operatore);
$insert->bindValue(":fase",$this->round["codice"]);
$insert->bindValue(":lotto",$lotto);
$insert->bindValue(":sorteggio",($sorteggio ? "S" : "N"));
$insert->bindValue(":utente",$_SESSION["utente"]->codice ?? -1);
if (!empty($oe)) {
$insert->bindValue(":oe",$oe["codice"]);
$insert->execute();
$this->addToLog("INSERT",__("Invito operatore") . ":" . $oe["ragione_sociale"]);
if ($updateContatori) {
$invito = [];
$invito["codice_ente"] = $_SESSION["ente"]->codice;
$invito["contesto"] = "gare";
$invito["codice_elemento"] = $this->round["codice"];
$invito["data_invito"] = date("d-m-Y");
$invito["sub_elemento"] = $lotto;
$extraInfo = $this->getExtraInfo();
if (!empty($extraInfo["round"]["tipo_elenco_invito"])) {
$invito["tipo_elenco"] = $extraInfo["round"]["tipo_elenco_invito"];
$invito["codice_elenco"] = $extraInfo["round"]["codice_elenco_invito"];
}
$invito["codice_fiscale_operatore"] = $oe["codice_fiscale_impresa"];
$soa = [];
$tmpSoa = $this->getSOA();
if (!empty($tmpSoa)) {
foreach($tmpSoa AS $categoria) {
$classifica = getClassificaSOAFromImporto($categoria["importo"]);
$soa[] = ["categoria"=>$categoria["codice_categoria"],"classifica"=>$classifica];
}
}
$progettazione = [];
$tmpProg = $this->getProgettazione();
if (!empty($tmpProg)) {
$progettazione = array_column($tmpProg,"codice_categoria");
}
oeManager::saveInvito($invito,$this->getCategorieMerceologiche(),$soa,$progettazione);
}
return true;
}
return false;
}
public function saveTempInvito($lotto,$codice_fiscale,$denominazione,$pec,$updateContatori = true) {
$invito = [];
$invito["contesto"] = "gare";
$invito["codice_elemento"] = $this->round["codice"];
$invito["sub_elemento"] = $lotto;
$invito["codice_fiscale_operatore"] = $codice_fiscale;
$invito["denominazione"] = $denominazione;
$invito["pec"] = $pec;
$invito["attivo"] = "S";
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = "temp_inviti";
$salva->operazione = "INSERT";
$salva->oggetto = $invito;
$codice_invito = $salva->save();
if (!empty($codice_invito)) {
$this->addToLog("INSERT",__("Invito operatore manuale") . ":" . $denominazione);
if ($updateContatori) {
$invito = [];
$invito["codice_ente"] = $_SESSION["ente"]->codice;
$invito["contesto"] = "gare";
$invito["codice_elemento"] = $this->round["codice"];
$invito["data_invito"] = date("d-m-Y");
$invito["sub_elemento"] = $lotto;
$invito["codice_fiscale_operatore"] = $codice_fiscale;
oeManager::saveInvito($invito,$this->getCategorieMerceologiche());
}
return $codice_invito;
}
return false;
}
public function inviaInvito($destinatari) {
$this->round = $this->getRounds($this->round["codice"])[0];
$this->round["infoFase"] = $this->getProcedura()["fasi"][$this->round["id"]] ?? [];
if (strtotime($this->round["pubblicazione"]) < time()) {
$editor = new editorManager("msg-invito-gara",0);
$editor->vocabolario["ragione-sociale"] = $_SESSION["ente"]->getInfo()["denominazione"];
$editor->vocabolario["fase"] = $this->round;
$editor->vocabolario["gara"] = $this->info;
$editor->vocabolario["link"] = $_SESSION["config"]["link_sito"]."/gare/dettaglio.php?codice=".$this->info["codice"];
$editor->vocabolario["nome-sito"] = $_SESSION["config"]["nome_sito"];
$editor->vocabolario["description"] = $this->info["oggetto"];
$corpo = $editor->getModello();
$mailer = new Communicator();
$mailer->oggetto = __('Invito') . " - " . $this->info["oggetto"];
$mailer->corpo = $corpo;
$mailer->codice_pec = $this->info["codice_pec"];
$mailer->comunicazione = true;
$mailer->sezione = "gare";
$mailer->codice_gara = $this->info["codice"];
$mailer->coda = true;
$mailer->destinatari = $destinatari;
return $mailer->send();
} else{
$this->db->go("UPDATE b_gare SET invito_programmato = 'S' WHERE codice = :codice",[":codice"=>$this->info["codice"]]);
return true;
}
}
public function getInvitati($codice_lotto = null)
{
$filtro_lotto = null;
if (isset($codice_lotto)) {
$filtro_lotto = $codice_lotto;
} else if (!empty($this->lotto)) {
$filtro_lotto = $this->lotto["codice"];
}
$bind = [":codice_round" => $this->round["codice"]];
$sql = "SELECT * FROM r_inviti_gare WHERE codice_round = :codice_round ";
if (isset($filtro_lotto)) {
$bind[":codice_lotto"]=$filtro_lotto;
$sql .= " AND (codice_lotto = :codice_lotto OR codice_lotto = 0) ";
}
return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
}
public function getInvitatiManuali($codice_lotto = null)
{
$filtro_lotto = null;
if (isset($codice_lotto)) {
$filtro_lotto = $codice_lotto;
} else if (!empty($this->lotto)) {
$filtro_lotto = $this->lotto["codice"];
}
$bind = [":codice_round" => $this->round["codice"]];
$sql = "SELECT * FROM temp_inviti WHERE contesto = 'gare' AND attivo = 'S' AND codice_elemento = :codice_round ";
if (isset($filtro_lotto)) {
$bind[":codice_lotto"]=$filtro_lotto;
$sql .= " AND (sub_elemento = :codice_lotto OR sub_elemento = 0) ";
}
return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
}
public function countInvitati($codice_lotto = null) {
return count($this->getInvitati($codice_lotto)) + count($this->getInvitatiManuali($codice_lotto));
}
public function checkPartecipantiPresenti() {
return !empty($this->db->go("SELECT codice FROM r_partecipanti_gare WHERE codice_round = :codice_round",[":codice_round"=>$this->round["codice"]])->rowCount());
}
public function returnPartecipanti($filters = [],$all = false) {
if (!empty($this->lotto)) {
$bind = [":codice_round" => $this->round["codice"],":codice_lotto" => $this->lotto["codice"]];
$sql = "SELECT * FROM r_partecipanti_gare WHERE codice_round = :codice_round AND codice_lotto = :codice_lotto ";
if (empty($all)) {
$filters["conferma"] = "S";
}
$where = [];
$keys = array_keys(get_campi("r_partecipanti_gare"));
foreach($keys AS $key) {
if (isset($filters[$key])) {
$where[] = "$key = :{$key}";
$bind[":{$key}"] = $filters[$key];
}
}
if (!empty($where)) {
$sql .= " AND " . implode(" AND ",$where);
}
return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
}
}
public function getPartecipante($codice,$all = false) {
return $this->returnPartecipanti(["codice"=>$codice],$all)[0] ?? null;
}
public function getPartecipantiForAnomalia() {
$tmps = $this->returnPartecipanti();
$partecipanti = [];
foreach($tmps AS $tmp) {
if ($tmp["escluso"] == "N" || $tmp["esclusione_automatica"] == "S") {
$partecipanti[] = $tmp;
}
}
return $partecipanti;
}
public function getPartecipanti($ammessi = NULL,$valutazione = null)
{
if (!empty($this->lotto)) {
$filters = [];
$all = false;
if ($ammessi === TRUE) {
$filters = ["escluso"=>"N"];
} else if ($ammessi === "ALL") {
$all = true;
}
$return = $this->returnPartecipanti($filters,$all);
if ($valutazione && !empty($return) && $this->getModalita()["online"]) {
$tmp = $return;
$return = [];
$richieste = $this->getRichieste("tecnica");
if (!empty($richieste)) {
$checkPunteggio = $this->db->prepare("SELECT b_gare_punteggi_partecipanti.codice FROM b_gare_punteggi_partecipanti
JOIN b_gare_criteri_valutazione ON b_gare_punteggi_partecipanti.codice_criterio = b_gare_criteri_valutazione.codice
WHERE codice_partecipante = :partecipante AND b_gare_criteri_valutazione.economico = 'N'");
foreach($tmp AS $partecipante) {
$checkPunteggio->execute([":partecipante"=>$partecipante["codice"]]);
if ($checkPunteggio->rowCount() > 0) {
$return[$partecipante["codice"]] = $partecipante;
} else {
foreach($richieste AS $richiesta) {
$busta = $this->getBusta($partecipante["codice"],$richiesta["codice"]);
if (!empty($busta) && $busta["open"] == "S") {
$return[$partecipante["codice"]] = $partecipante;
break;
}
}
}
}
$return = array_values($return);
}
}
return $return;
}
}
public function getGraduatoria($ammessi = NULL)
{
$partecipanti = [];
$tmp = $this->getPartecipanti($ammessi);
if (!empty($tmp)) {
$ammessi = [];
$esclusi = [];
foreach($tmp AS $partecipante) {
if ($partecipante["escluso"] == "N") {
$ammessi[] = $partecipante;
} else {
$esclusi[] = $partecipante;
}
}
if (!empty($ammessi)) {
usort($ammessi, "sortPartecipantiTotale");
}
if (!empty($esclusi)) {
usort($esclusi, "sortPartecipantiTotale");
}
$partecipanti = array_merge($ammessi,$esclusi);
}
return $partecipanti;
}
public function checkImported($busta) {
$imported = explode(".", $busta);
if (is_array($imported)) {
$imported = end($imported);
if ($imported == "imported-offer") {
return true;
}
}
return false;
}
public function downloadBusta(array $busta) {
global $config;
$richiesta = $this->getRichiesta($busta["codice_richiesta"]);
$partecipante = $this->getPartecipante($busta["codice_partecipante"]);
$imported = $this->checkImported($busta["nomeFile"]);
$file_content = $busta["content"];
if (P7Manager::bustaEstensioneSoloP7M($busta["nomeFile"])) {
$ext = getTypeAndExtension($file_content, true);
$busta["nomeFile"] = str_replace(".p7m", "{$ext["ext"]}", $busta["nomeFile"]);
}
if ($imported === true) {
$ext = getTypeAndExtension($file_content, true);
$busta["nomeFile"] = str_replace(".imported-offer", "{$ext["ext"]}", $busta["nomeFile"]);
}
if (strpos($busta["nomeFile"], ".x-empty") !== false) {
$ext = getTypeAndExtension($file_content, true);
$busta["nomeFile"] = substr($busta["nomeFile"], 0, strpos($busta["nomeFile"], ".x-empty")) . "." . $ext["ext"];
}
if ($_POST["openP7M"] == "S") {
$path = $config["chunk_folder"] . "/" . $_SESSION["utente"]->codice;
if (!is_dir($path)) {
mkdir($path);
}
$path .= "/" . $busta["nomeFile"];
file_put_contents($path, $file_content);
$file_content = "";
if (file_exists($path)) {
$p7m = new P7Manager($path);
if ($p7m !== false) {
$file_content = $p7m->extract(true);
$file_info = new finfo(FILEINFO_MIME_TYPE);
$mime_type = $file_info->buffer($file_content);
$ext = P7manager::extFromMime($mime_type);
$busta["mime"] = $mime_type;
$busta["nomeFile"] = str_replace(".p7m", ".{$ext}", $busta["nomeFile"]);
}
unlink($path);
}
}
if (!empty($file_content)) {
$busta["nomeFile"] = $partecipante["codice_fiscale"] . "-" . $richiesta["busta"] . "-" . $busta["nomeFile"];
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename=' . str_replace("-", ".", $busta["nomeFile"]));
header('Content-Type: ' . $busta["mime"]);
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
echo $file_content;
return true;
}
}
public function decryptBusta(array $busta,string $private,string $type) {
switch ($type) {
case "busta":
$table = "b_gare_buste";
$decDescrizione = false;
break;
case "emendamento":
$table = "b_gare_emendamenti";
$decDescrizione = true;
break;
case "segreto":
$table = "b_gare_buste_secretate";
$decDescrizione = true;
break;
}
$return = __("Errore nella richiesta");
if (!empty($table)) {
$imported = $this->checkImported($busta["nomeFile"]);
$key = openssl_pkey_get_private($private);
if (@openssl_private_decrypt($busta["salt"],$salt,$key)) {
global $config;
$addSalt = $config["simple_encrypt"]["offer"];
$busta["content"] = openssl_decrypt($busta["content"],"AES128",$salt,OPENSSL_RAW_DATA,$addSalt);
if ($decDescrizione) {
$busta["descrizione"] = simple_decrypt($busta["descrizione"],$salt);
}
if ($busta["content"] !== false && !empty($busta["password"])) {
if ($imported === true) {
$fileInfo = getTypeAndExtension($busta["content"],true);
$busta["mime"] = $fileInfo["type"];
$busta["nomeFile"] = str_replace(".imported-offer","",$busta["nomeFile"]) . $fileInfo["ext"];
}
$content = simple_encrypt($busta["content"],$busta["password"]);
if (!empty($content) && file_put_contents($busta["path"],$content)) {
unset($busta["content"]);
$busta["open"] = "S";
$busta["utente_decrypt"] = $_SESSION["utente"]->codice;
$busta["timestamp_decrypt"] = date('Y-m-d H:i:s');
$salva = new salva();
$salva->debug = false;
$salva->nome_tabella = $table;
$salva->operazione = "UPDATE";
$salva->oggetto = $busta;
$salva->expect = array("codice","nomeFile","mime","content","open","utente_decrypt","timestamp_decrypt");
if ($decDescrizione) {
$salva->expect[] = "descrizione";
}
$esito = $salva->save();
if ($esito > 0) {
$return = true;
}
} else {
$return = __("Errore nel salvataggio del contenuto decriptato") . " - #001";
}
} else {
$return = __("Errore nella decriptazione del contenuto") . " - #001";
}
} else {
$return = __("Chiave errata") . " - #002";
}
}
return $return;
}
public function getBusta($partecipante, $richiesta, $aggiuntive = false, bool $contenuto = false)
{
$return = false;
$select = "*";
if (!$aggiuntive) {
$sql = "SELECT {$select} FROM b_gare_buste WHERE codice_partecipante = :partecipante AND codice_richiesta = :richiesta ORDER BY codice DESC";
} else {
$sql = "SELECT {$select} FROM b_gare_buste_aggiuntive WHERE codice_partecipante = :partecipante AND codice_richiesta = :richiesta ORDER BY codice DESC";
}
$bind = [":partecipante" => $partecipante, ":richiesta" => $richiesta];
$return = $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
if (!empty($return)) {
$return = $return[0];
$return["path"] = $this->getSpecificBustaPath($return);
if ($contenuto) {
adaptMemoryLimitToFile($return["path"]);
$content = file_get_contents($return["path"]);
if (!empty($content)) {
if ($return["open"] == "S") {
$content = simple_decrypt($content,base64_decode($return["content"]));
} else {
$return["password"] = base64_decode($return["content"]);
}
$return["content"] = $content;
}
}
}
return $return;
}
public function getSpecificBustaPath($busta) {
return $this->getBustePath($busta["codice_partecipante"])."/{$busta["codice_richiesta"]}-{$busta["sha1"]}";
}
public function getBustePath(int $partecipante = null) {
if (!empty($this->lotto) && !empty($this->round)) {
global $config;
$path = "{$config["mediaFolder"]}/{$_SESSION["ente"]->codice}/gare-buste/{$this->info["codice"]}/{$this->round["codice"]}/{$this->lotto["codice"]}";
if (!file_exists($path)) {
mkdir($path,0777,true);
}
if (is_dir($path)) {
$return = true;
if (!empty($partecipante)) {
$return = false;
$path .= "/{$partecipante}";
if (!file_exists($path)) {
mkdir($path,0777,true);
}
if (is_dir($path)) {
$return = true;
}
}
if ($return) {
return $path;
}
}
}
}
public function getBustaSecretata($partecipante, $richiesta, $derivazione, bool $contenuto = false)
{
$return = false;
$select = "*";
$sql = "SELECT {$select} FROM b_gare_buste_secretate WHERE derivazione = :derivazione AND codice_partecipante = :partecipante AND codice_richiesta = :richiesta ORDER BY codice DESC";
$bind = [":partecipante" => $partecipante, ":richiesta" => $richiesta, ":derivazione" => $derivazione];
$return = $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
if (!empty($return)) {
$return = $return[0];
$return["path"] = $this->getSpecificSecretatePath($return);
if ($contenuto) {
adaptMemoryLimitToFile($return["path"]);
$content = file_get_contents($return["path"]);
if (!empty($content)) {
if ($return["open"] == "S") {
$content = simple_decrypt($content,base64_decode($return["content"]));
} else {
$return["password"] = base64_decode($return["content"]);
}
$return["content"] = $content;
}
}
}
return $return;
}
public function getSpecificSecretatePath($busta) {
return $this->getBustePath($busta["codice_partecipante"])."/{$busta["codice_richiesta"]}-{$busta["derivazione"]}-{$busta["sha1"]}";
}
public function getSecretatePath(int $partecipante = null) {
if (!empty($this->lotto) && !empty($this->round)) {
global $config;
$path = "{$config["mediaFolder"]}/{$_SESSION["ente"]->codice}/gare-secretate/{$this->info["codice"]}/{$this->round["codice"]}/{$this->lotto["codice"]}";
if (!file_exists($path)) {
mkdir($path,0777,true);
}
if (is_dir($path)) {
$return = true;
if (!empty($partecipante)) {
$return = false;
$path .= "/{$partecipante}";
if (!file_exists($path)) {
mkdir($path,0777,true);
}
if (is_dir($path)) {
$return = true;
}
}
if ($return) {
return $path;
}
}
}
}
public function getEmendamento($partecipante, $richiesta, bool $contenuto = false)
{
$return = false;
$select = "*";
$sql = "SELECT {$select} FROM b_gare_emendamenti WHERE codice_partecipante = :partecipante AND codice_richiesta = :richiesta ";
$bind = [":partecipante" => $partecipante, ":richiesta" => $richiesta];
$return = $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
if (!empty($return)) {
$return = $return[0];
$return["path"] = $this->getSpecificEmendamentoPath($return);
if ($contenuto) {
adaptMemoryLimitToFile($return["path"]);
$content = file_get_contents($return["path"]);
if (!empty($content)) {
if ($return["open"] == "S") {
$content = simple_decrypt($content,base64_decode($return["content"]));
} else {
$return["password"] = base64_decode($return["content"]);
}
$return["content"] = $content;
}
}
}
return $return;
}
public function getSpecificEmendamentoPath($busta) {
return $this->getEmendamentoPath($busta["codice_partecipante"])."/{$busta["codice_richiesta"]}-{$busta["sha1"]}";
}
public function getEmendamentoPath(int $partecipante = null) {
if (!empty($this->lotto) && !empty($this->round)) {
global $config;
$path = "{$config["mediaFolder"]}/{$_SESSION["ente"]->codice}/gare-emendamenti/{$this->info["codice"]}/{$this->round["codice"]}/{$this->lotto["codice"]}";
if (!file_exists($path)) {
mkdir($path,0777,true);
}
if (is_dir($path)) {
$return = true;
if (!empty($partecipante)) {
$return = false;
$path .= "/{$partecipante}";
if (!file_exists($path)) {
mkdir($path,0777,true);
}
if (is_dir($path)) {
$return = true;
}
}
if ($return) {
return $path;
}
}
}
}
public function arrangePartecipantiForANAC($tmp) {
$partecipanti = [];
foreach ($tmp as $partecipante) {
$raggruppamento = $this->getRaggruppamento($partecipante["codice"]);
if (!empty($raggruppamento)) {
$partecipante["raggruppamento"] = $raggruppamento;
}
unset($partecipante["codice"]);
$partecipanti[] = $partecipante;
}
return $partecipanti;
}
public function updatePartecipantiANAC()
{
if (!empty($this->lotto["cig"])) {
$tmp = $this->getPartecipanti();
if (!empty($tmp)) {
$partecipanti = $this->arrangePartecipantiForANAC($tmp);
anac::updatePartecipanti190($this->lotto["cig"], $partecipanti);
}
}
}
public function creaIstanzaANAC(string $smart_cig = "N") {
$return = false;
$record = $this->info;
$lotti = $this->getLotti();
$beneficiario = Ente::getInfoFromID($record["codice_ente"])[0];
$relazioni = anac::relazioniModulo("gare", $this->info["codice"]);
if (empty($relazioni)) {
$gara = [];
$gara["codice"] = 0;
$gara["smart_cig"] = $smart_cig;
$gara["oggetto"] = $record["oggetto"];
$gara["anno_riferimento"] = date("Y");
$gara["codice_ente"] = $record["codice_ente"];
$gara["codice_gestore"] = $_SESSION["ente"]->codice;
$gara["dati"]["cf_sua"] = $beneficiario["cf"];
$gara["dati"]["denominazione_sua"] = $beneficiario["denominazione"];
$gara["dati"]["categorie_merc"] = [999];
if ($smart_cig == "N") {
$gara["dati"]["importo"] = $record["prezzoRiferimento"];
$gara["dati"]["numero_lotti"] = count($lotti);
$gara["dati"]["tipo_scheda"] = "";
$gara["dati"]["modo_indizione"] = "";
$gara["dati"]["allegato_ix"] = "";
$gara["dati"]["modo_realizzazione"] = "";
$gara["dati"]["motivo_rich_cig"] = "";
$gara["dati"]["cig_acc_quadro"] = "";
$gara["dati"]["durata_accquadro_convenzione_gara"] = "";
$gara["dati"]["escluso_avcpass"] = "";
$gara["dati"]["urgenza_dl133"] = "";
$gara["dati"]["estrema_urgenza"] = "";
$gara["dati"]["strumento_svolgimento"] = "";
$gara["dati"]["id_f_delegate"] = "";
$gara["dati"]["cf_amm_agente_gara"] = "";
} else {
$lottoDB = $lotti[0];
$gara["lotto"]["cig"] = $lottoDB["cig"];
$gara["lotto"]["importo"] = $record["prezzoRiferimento"];
$gara["dati"]["codiceProceduraSceltaContraente"] = anac::getSceltaContraenteFromGara($record["procedura"],"S",$record["timestamp_creazione"]);
$gara["dati"]["codiceClassificazioneGara"] = "";
$gara["dati"]["codiceFattispecieContrattuale"] = "";
$gara["dati"]["cigAccordoQuadro"] = "";
$gara["cup"] = $lottoDB["cup"];
$gara["dati"]["motivo_rich_cig_catmerc"] = "";
}
$anac = new anac();
$anac->modulo = "gare";
$esito_gara = $anac->saveGara($gara);
if ($esito_gara["esito"] === true) {
$return["codice_gara_simog"] = $esito_gara["codice"];
$creazione = true;
$anac = anac::init($esito_gara["codice"]);
if ($smart_cig == "S") {
$relazione = $anac->saveRelazione("gare", $record["codice"], $lottoDB["codice"], $anac->getLotti()[0]["codice"]);
if (empty($relazione)) {
$this->db->go("DELETE FROM b_simog WHERE codice = :codice", [":codice" => $esito_gara["codice"]]);
$return["errore_lotto"] = true;
}
}
} else {
$return["msg"] = "";
if (!empty($esito_gara["errori"])) {
$return["msg"] = implode("<br>", $esito_gara["errori"]);
}
}
} else {
$relazioni = reset($relazioni);
$return["codice_gara_simog"] = $relazioni["gara_simog"];
$anac = anac::init($return["codice_gara_simog"]);
}
if (!empty($anac->info) && $anac->info["smart_cig"] == "N") {
foreach ($lotti as $lottoDB) {
$relazioni = anac::relazioniModulo("gare", $record["codice"], $lottoDB["codice"]);
if (empty($relazioni)) {
$lotto = [];
$lotto["codice"] = 0;
$lotto["codice_simog"] = $anac->info["codice"];
$lotto["oggetto"] = $lottoDB["oggetto"];
$lotto["cig"] = $lottoDB["cig"];
$lotto["cup"] = $lottoDB["cup"];
$lotto["importo"] = $lottoDB["importoBase"];
$lotto["dati"]["importo_attuazione_sicurezza"] = $lottoDB["oneriNoRibasso"];
$lotto["cpv"] = [$lottoDB["cpv"]];
$lotto["id_scelta_contraente"] = anac::getSceltaContraenteFromGara($record["procedura"],"N",$record["timestamp_creazione"]);
$lotto["dati"]["condizioni"] = "";
$lotto["dati"]["id_aff_riservati"] = "";
$lotto["dati"]["tipo_contratto"] = "";
$lotto["dati"]["id_categoria_prevalente"] = "";
$lotto["dati"]["categoria_merc"] = "";
$lotto["dati"]["flag_escluso"] = "";
$lotto["dati"]["id_esclusione"] = "";
$lotto["dati"]["flag_regime"] = "";
$lotto["dati"]["art_regime"] = "";
$lotto["dati"]["luogo_nuts"] = "";
$lotto["dati"]["flag_dl50"] = "";
$lotto["dati"]["prima_annualita"] = "";
$lotto["dati"]["annuale_cui_mininf"] = "";
$lotto["dati"]["tipoappalto"] = "";
$lotto["dati"]["id_motivo_coll_cig"] = "";
$lotto["dati"]["cig_origine_rip"] = "";
$lotto["dati"]["flag_no_adesione_iniziativa"] = "";
$lotto["dati"]["flag_sa_non_classificata"] = "";
$esito_lotto = $anac->saveLotto($lotto,true,true);
if ($esito_lotto["esito"] === true) {
$relazione = $anac->saveRelazione("gare", $record["codice"], $lottoDB["codice"], $esito_lotto["codice"]);
if (empty($relazione) && !empty($creazione)) {
$this->db->go("DELETE FROM b_simog WHERE codice = :codice", [":codice" => $esito_gara["codice"]]);
$return["errore_lotto"] = true;
}
anac::importazioneSuggerimenti190Lotto($lotto);
} else {
$return["msg"] = "";
$return["errore_lotto"] = true;
if (!empty($esito_lotto["errori"])) {
$return["msg"] = implode("<br>", $esito_lotto["errori"]);
}
}
}
}
}
return $return;
}
public function selezioneManualeAggiudicatari() {
return ($this->quickPanel || !$this->usaGraduatoria() || (settingsManager::getValue("proponiAggiudicazioneMultiplaManuale") === "S" && ($this->getRisposteElaborazione()["aggiudicazioneManuale"] ?? "N") == "S"));
}
public function getAggiudicatari($codice_lotto = NULL)
{
if (!empty($codice_lotto)) {
$lottoSearch = $this->getLotti($codice_lotto)[0] ?? false;
} else if (!empty($this->lotto)) {
$lottoSearch = $this->lotto;
}
if (!empty($lottoSearch)) {
$bind = [":codice_round" => $this->round["codice"],":codice_lotto" => $lottoSearch["codice"]];
$sql = "SELECT * FROM r_partecipanti_gare WHERE codice_round = :codice_round AND aggiudicatario = 'S' AND codice_lotto = :codice_lotto";
return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
}
}
public function getAggiudicatario($codice) {
return $this->returnPartecipanti(["codice"=>$codice,"aggiudicatario"=>"S"])[0] ?? "";
}
public function getImportoAggiudicazione()
{
$aggiudicatari = $this->getImportoAggiudicazionePartecipanti();
if (!empty($aggiudicatari)) {
$totale = 0;
foreach ($aggiudicatari as $aggiudicatario) {
if (!empty($aggiudicatario["offerta"])) {
$totale += $aggiudicatario["offerta"];
}
}
return $totale;
}
}
public static function formatiOffertaDisponibili () {
return [
"ribasso" => "Ribasso percentuale",
"rialzo" => "Rialzo percentuale",
"assoluto" => "Ribasso con prezzo assoluto",
"r-assoluto" => "Rialzo con prezzo assoluto",
"nulla" => "Non prevista"
];
}
public function getImportoAggiudicazionePartecipanti($totale = true, $onlyAggiudicatario = true)
{
$partecipanti = $this->getGraduatoria();
$criteri = $this->getCriteriEconomici();
$formato = $this->lotto["formato"];
$aggiudicatari = [];
foreach ($partecipanti as $partecipante) {
if (!$onlyAggiudicatario || $partecipante["aggiudicatario"] == "S") {
$aggiudicatari[$partecipante["codice"]] = $partecipante;
}
}
if (!empty($criteri)) {
$extraInfoLotto = $this->getExtraInfo()["lotto"] ?? null;
if (count($criteri) === 1 && !empty($extraInfoLotto["ribassoAggiudicazione-{$this->round["codice"]}"])) {
$criterio = reset($criteri);
$ribasso = number_format($extraInfoLotto["ribassoAggiudicazione-{$this->round["codice"]}"],$criterio["decimali"],".","");
foreach ($aggiudicatari as $i => $aggiudicatario) {
if ($totale) {
if (!isset($aggiudicatario["offerta"])) {
$aggiudicatario["offerta"] = 0;
}
if ($this->normaRiferimento == "2023-36") {
$offerta = ($this->lotto["importoBase"] + $this->lotto["importoManodopera"]) * $ribasso / 100;
$offerta = ($this->lotto["importoBase"] + $this->lotto["importoManodopera"]) - $offerta;
} else {
$offerta = $this->lotto["importoBase"] * $ribasso / 100;
$offerta = $this->lotto["importoBase"] - $offerta;
}
$offerta += $this->lotto["oneriNoRibasso"];
$aggiudicatario["offerta"] += $offerta;
$aggiudicatari[$i] = $aggiudicatario;
} else {
$aggiudicatari[$i]["offerta"][$criteri[0]["codice"]] = $ribasso;
}
}
} else {
foreach ($criteri as $criterio) {
$offerte = $this->getOfferte($criterio["codice"], $totale);
if (!empty($offerte)) {
if (count($criteri) === 1 && $this->getInterpretazioneArt41() === "scorporato") {
$offerte = $this->getRibassoComplessivoArt41($offerte,true);
foreach ($aggiudicatari as $i => $aggiudicatario) {
if (!isset($aggiudicatario["offerta"])) {
$aggiudicatario["offerta"] = 0;
}
$offerta = number_format($offerte[$aggiudicatario["codice"]],$criterio["decimali"],".","");
$offerta += $this->lotto["oneriNoRibasso"];
$aggiudicatario["offerta"] += $offerta;
$aggiudicatari[$i] = $aggiudicatario;
}
} else {
foreach ($aggiudicatari as $i => $aggiudicatario) {
if ($totale) {
if (!isset($aggiudicatario["offerta"])) {
$aggiudicatario["offerta"] = 0;
}
if (!empty($offerte[$aggiudicatario["codice"]])) {
$offerta = number_format($offerte[$aggiudicatario["codice"]],$criterio["decimali"],".","");
if ($formato == "ribasso" || $formato == "rialzo" || (($criterio["auto"] == "P" || $criterio["auto"] == "B" || $criterio["auto"] == "Q") && ($offerta < 100))) {
if ($this->normaRiferimento == "2023-36") {
$offerta = ($this->lotto["importoBase"] + $this->lotto["importoManodopera"]) * $offerta / 100;
if ($formato != "rialzo") {
$offerta = ($this->lotto["importoBase"] + $this->lotto["importoManodopera"]) - $offerta;
} else {
$offerta = ($this->lotto["importoBase"] + $this->lotto["importoManodopera"]) + $offerta;
}
} else {
$offerta = $this->lotto["importoBase"] * $offerta / 100;
if ($formato != "rialzo") {
$offerta = $this->lotto["importoBase"] - $offerta;
} else {
$offerta = $this->lotto["importoBase"] + $offerta;
}
}
}
$offerta += $this->lotto["oneriNoRibasso"];
$aggiudicatario["offerta"] += $offerta;
$aggiudicatari[$i] = $aggiudicatario;
}
} else {
$aggiudicatari[$i]["offerta"][$criterio["codice"]] = $offerte[$aggiudicatario["codice"]] ?? NULL;
}
}
}
}
}
}
}
return $aggiudicatari;
}
public function getSedute($codice = null)
{
$bind = [":round" => $this->round["codice"]];
$sql = "SELECT * FROM b_gare_sedute WHERE codice_round = :round ";
if (!empty($codice)) {
$bind[":codice"] = $codice;
$sql .= " AND codice = :codice ";
}
$sql .= " ORDER BY codice DESC ";
return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC);
}
public function listPartecipanti($partecipante = null)
{
if (!empty($partecipante)) {
$partecipante = $this->getPartecipante($partecipante,true);
$raggruppamento = $this->getRaggruppamento($partecipante["codice"]);
$list_partecipanti = "";
if (!empty($raggruppamento)) {
$list_partecipanti = "<strong>RAGGRUPPAMENTO</strong><br>" . $partecipante["ragione_sociale"] . " - " . $partecipante["codice_fiscale"] . " - 04-CAPOGRUPPO";
foreach ($raggruppamento as $membro) {
$list_partecipanti .= "<br>" . $membro["ragione_sociale"] . " - " . $membro["codice_fiscale_impresa"] . " - " . $membro["ruolo"];
}
}
$avvalimento = $this->getAvvalimento($partecipante["codice"]);
if (!empty($avvalimento)) {
$list_partecipanti .= "<br><strong>AVVALIMENTO</strong>";
foreach ($avvalimento as $membro) {
$list_partecipanti .= "<br>" . $membro["ragione_sociale"] . " - " . $membro["codice_fiscale_impresa"] . " - " . $membro["ruolo"];
}
}
if (empty($list_partecipanti)) {
$list_partecipanti = $partecipante["ragione_sociale"] . " - " . $partecipante["codice_fiscale"];
}
return $list_partecipanti;
} else {
return false;
}
}
public function getCommissari($tipologia, $codice_utente = NULL)
{
return $this->getManagerCommissione($tipologia)->getCommissari($codice_utente);
}
public function getConferences($codice = NULL)
{
$conference = [];
foreach ($this->getRounds() as $round) {
$tmp = conferenceManager::getMeetingsFromDB("gare", $this->info["codice"], "seduta", $round["codice"]);
if (!empty($tmp)) {
$conference = array_merge($conference, $tmp);
}
$seggio = new Commissione("gare", $round["codice"], "seggio");
if (!empty($seggio->getInfo())) {
$tmp = conferenceManager::getMeetingsFromDB("commissioni", $seggio->getInfo()["codice"], $seggio->tipologia, 0);
if (!empty($tmp)) {
$conference = array_merge($conference, $tmp);
}
}
$commissione = new Commissione("gare", $round["codice"], "commissione");
if (!empty($commissione->getInfo())) {
$tmp = conferenceManager::getMeetingsFromDB("commissioni", $commissione->getInfo()["codice"], $commissione->tipologia, 0);
if (!empty($tmp)) {
$conference = array_merge($conference, $tmp);
}
}
}
if (!empty($conference)) {
if (!empty($codice)) {
$tmp = $conference;
$conference = [];
foreach ($tmp as $meet) {
if ($meet["codice"] == $codice) {
$conference = $meet;
break;
}
}
} else {
$timestamp = array_column($conference, 'timestamp');
array_multisort($timestamp, SORT_DESC, $conference);
}
}
return $conference;
}
static function getModuli($filters = null, $stato = null, $fase = null, $quick = false)
{
global $config;
$moduli = jsonToArray($config["jsonFolder"] . "/gare-panel.json");
$tmp = [];
foreach ($moduli as $id_modulo => $modulo) {
$insert = true;
if (is_array($filters) && !empty($filters)) {
foreach ($filters as $key => $value) {
if ($modulo[$key] !== $value) {
$insert = false;
}
}
}
if ($quick) {
if (!$modulo["quick-panel"]) {
$insert = false;
}
} else {
if ($insert && $stato !== null) {
if ($modulo["stato_minimo"] > $stato) {
$insert = false;
}
if ($insert && $fase !== null) {
if ($modulo["fase_minima"] !== null && $fase < $modulo["fase_minima"]) {
$insert = false;
}
if ($modulo["fase_massima"] !== null && $fase > $modulo["fase_massima"]) {
$insert = false;
}
}
}
}
if (is_array($modulo["stati_esclusi"]) && in_array($stato, $modulo["stati_esclusi"]) !== false) {
$insert = false;
}
if ($insert) {
$tmp[$id_modulo] = $modulo;
}
$moduli = $tmp;
}
return $moduli;
}
static function getInfoModulo($radice)
{
$return = false;
if (!empty($radice)) {
$moduli = self::getModuli(false);
if (!empty($moduli[$radice])) {
$return = $moduli[$radice];
$return["id"] = $radice;
$return["titolo"] = __($return["titolo"]);
$return["descrizione"] = __($return["descrizione"]);
}
}
return $return;
}
public function getAvvisi()
{
return $this->getManagerAvvisi()->getAvvisi("N");
}
public function printAvvisi()
{
return $this->getManagerAvvisi()->printPublic();
}
public function getContratti()
{
return stipula::getContrattiFromModulo("gare", $this->lotto["codice"]);
}
public function getPubblicazioniGUUE()
{
global $beRoot;
include_once($beRoot."/guue/class/TedEsender.class.php");
return TedEsender::getPubblicazioniFromModulo("gare", $this->info["codice"]);
}
public function getStatoPannello() {
$statoMax = $this->info["stato"];
$statoMin = null;
foreach($this->getLotti() AS $lotto) {
if ($lotto["stato"] > 0) {
if ($lotto["stato"] > $statoMax) {
$statoMax = $lotto["stato"];
}
if ($lotto["stato"] < $statoMin || $statoMin === null) {
$statoMin = $lotto["stato"];
}
}
}
if ($statoMin === null) {
$statoMin = $this->info["stato"];
}
if (!$this->usaGraduatoria() && $statoMin == 21) {
$statoMin = 21;
$statoMax = 30;
}
return ["min"=>$statoMin,"max"=>$statoMax];
}
public function serialize(bool $checkPubblica = true) : ?array {
if($checkPubblica) {
// TODO Verificare che si trovi in uno stato finale E abbia i CIG, in quel caso possiamo procedere all'invio
// Verifica che sia pubblica per tutti
if($this->round["pubblica"] != 2) { return null; }
// Verifica della data di pubblicazione
$dataPubblicazione = $this->round["pubblicazione"];
if(strtotime($dataPubblicazione) > time()){ return null; }
}
global $pdo;
global $config;
$data = [];
$whitelist = [
"anno", "stato", "procedura", "modalita", "tipologia",
"accordo_quadro", "oggetto", "fase_attiva", "prezzoRiferimento",
"extraInfo", "timestamp_creazione"
];
$whitelist_lotto = [
"cig", "cup", "cpv", "criterio", "formato",
"oggetto", "descrizione", "importoBase", "importoManodopera",
"oneriNoRibasso", "importoOpzioni", "importoAggiudicazione",
"sogliaAnomalia", "extraInfo", "stato"
];
$whitelist_partecipante = [
"codice_operatore", "stato", "codice_fiscale", "ragione_sociale",
"escluso", "aggiudicatario", "tipo"
];
$whitelist_round = [
"id", "pubblica", "pubblicazione", "chiarimenti", "sopralluogo", "scadenza", "extraInfo", "attivo", "metadata_fase"
];
$whitelist_allegati = [
"url", "mime", "name", "titolo"
];
// Dati base
foreach($this->info as $key => $entry) {
if(!in_array($key, $whitelist, true)) continue;
if(is_string($entry) && valid_json($entry, $entry_data, true)) {
$entry = $entry_data;
}
$data[$key] = $entry;
}
$data["url"] = $this->getPublicExternalURL();
// Stazione Appaltante
$data["ente"] = $this->getEnteBeneficiario(["denominazione"]);
// Lotti
foreach($this->getLotti() as $lotto) {
$codiceLotto = $lotto['codice'];
$target = &$data['lotti'][$codiceLotto];
$this->setLotto($lotto['codice']);
foreach($lotto as $key => $entry) {
if(!in_array($key, $whitelist_lotto, true)) continue;
if(is_string($entry) && valid_json($entry, $entry_data, true)) {
$entry = $entry_data;
}
$target[$key] = $entry;
}
$target['soa'] = $this->getSOASerialize();
$target['cpv'] = $this->getCPVLotto($lotto['codice']);
$target["id_lotto"] = "{$this->getPublicIdentifier()}-L-{$codiceLotto}";
// Partecipanti
if($this->pubblicaPartecipanti($lotto['codice'])) {
foreach($this->getPartecipanti("ALL") ?? [] as $partecipante) {
if(empty($partecipante['uuid'])) { continue; }
$targetP = &$target['partecipanti'][$partecipante['uuid']];
if($partecipante["codice_operatore"] > 0) {
$oe = oeManager::getOE($partecipante["codice_operatore"]);
if($oe) {
$partecipante["tipo"] = $oe["tipo"];
}
}
foreach($partecipante as $key => $entry) {
if(!in_array($key, $whitelist_partecipante, true)) { continue; }
if(is_string($entry) && valid_json($entry, $entry_data, true)) {
$entry = $entry_data;
}
$targetP[$key] = $entry;
}
$targetP["raggruppamento"] = array_column($this->getRaggruppamento($partecipante['codice']), null, "identifier");
$targetP["avvalimento"] = array_column($this->getAvvalimento($partecipante['codice']), null, "identifier");
}
}
}
// Allegati
// Round
$rounds = $this->getRounds();
if(!empty($rounds)) {
$i = 0;
foreach($rounds as $round) {
if($checkPubblica) {
if($round["pubblica"] != 2) { continue; }
$dataPubblicazione = $round["pubblicazione"];
if(strtotime($dataPubblicazione) > time()){ continue; }
}
$round['attivo'] = $round["numero"] == $this->round["numero"];
$round['metadata_fase'] = $this->getProcedura()["fasi"][$round["id"]] ?? [];
$target = &$data['round'][$i++];
foreach($round as $key => $entry) {
if(!in_array($key, $whitelist_round, true)) { continue; }
if(is_string($entry) && valid_json_recursive($entry, $entry_data)) {
$entry = $entry_data;
}
$target[$key] = $entry;
}
$allegati = filesManager::listFilesWithLink(NULL, $round["codice"],"gare-public","A") ?? [];
$link = $config["protocollo"] . getCurrentDomain();
if(!empty($allegati)) {
foreach($allegati as $index => $allegato) {
$allegato['url'] = $link . filesManager::getAttachURL($allegato, $round["codice"], "gare-public", false);
foreach($allegato as $key => $entry) {
if(!in_array($key, $whitelist_allegati, true)) { continue; }
$target['allegati'][$index][$key] = $entry;
}
}
}
}
}
array_walk_recursive($data, function(&$val, &$key) use($pdo){
if($key === "nuts" && !empty($val)) {
$res = $pdo->go(
"SELECT descrizione FROM b_nuts WHERE nuts = :nuts LIMIT 1", [":nuts" => $val]
);
$val = ["id" => $val, "descrizione" => ""];
if ($res->rowCount() > 0) {
$val["descrizione"] = $res->fetch(PDO::FETCH_ASSOC)["descrizione"];
}
}
if ($val === "S" || $val === "SI") { $val = true; }
elseif($val === "N" || $val === "NO") { $val = false; }
});
recursive_unset($data, ["utente_modifica", "utente_creazione", "codice", "codice_lotto", "timestamp"]);
$npa = $this->getNpaInstance();
$data["codice_gara"] = $this->getPublicIdentifier();
if($npa) {
if(!empty($npa->fascicolo["id_appalto"]))
$data["id_appalto"] = $npa->fascicolo["id_appalto"];
if(!empty($npa->fascicolo["codice_appalto"]))
$data["codice_appalto"] = $npa->fascicolo["codice_appalto"];
}
return $data;
}
public function getModelli($codice = null) {
$statoMax = $this->getStatoPannello()["max"];
$lotti = $this->getLotti();
if (!empty($lotti)) {
$criteri = array_column($lotti,"criterio");
}
$bind = [
":norma" => "%\"{$this->normaRiferimento}\"%",
":procedura" => "%\"{$this->info["procedura"]}\"%",
":tipologia" => "%\"{$this->info["tipologia"]}\"%",
":fase"=>$statoMax,
":reservedEnte"=>"__reserved-{$_SESSION["ente"]->codice}-%",
":dataPubblicazione"=>($this->getRounds()[0]["pubblicazione"] ?? date('Y-m-d'))
];
if (!empty($criteri)) {
$criteri = array_unique($criteri);
if (count($criteri) === 1) {
$criterio = reset($criteri);
$bind[":criterio"] = "%\"{$criterio}\"%";
}
}
$sql = "SELECT *
FROM b_impostazioni_modelli_gara
WHERE attivo = 'S'
AND soft_delete = 'N'
AND norma LIKE :norma
AND (criterio LIKE :criterio OR criterio IS NULL OR criterio = '')
AND (tipologia LIKE :tipologia OR tipologia IS NULL OR tipologia = '')
AND (procedura LIKE :procedura OR procedura IS NULL OR procedura = '')
AND fase_minima <= :fase AND (tipo NOT LIKE '__reserved-%' OR tipo LIKE :reservedEnte)
AND (dataInizio IS NULL OR dataInizio <= :dataPubblicazione)
AND (dataFine IS NULL OR dataFine >= :dataPubblicazione) ";
if (!empty($codice)) {
$bind[":codice"] = $codice;
$sql .= " AND codice = :codice";
}
$sql .= " ORDER BY ordinamento ASC, codice ASC";
$return = $this->db->go($sql,$bind)->fetchAll(PDO::FETCH_ASSOC);
if (!empty($codice)) {
$return = $return[0];
}
return $return;
}
public function checkLockModello($codice) {
$modello = $this->getModelli($codice);
$statoMax = $this->getStatoPannello()["max"];
if ($statoMax <= $modello["fase_massima"]) {
return false;
}
return true;
}
public function getDestinatariModello($codice) {
$modello = $this->getModelli($codice);
if (!empty($modello["destinatari"])) {
switch($modello["destinatari"]) {
case "T":
$destinatari = $this->getDestinatari(true);
break;
case "P": // __("Partecipanti")
$destinatari = array_column($this->getPartecipanti(),"codice_operatore");
break;
case "O": // __("Ammessi")
$partecipanti = $this->getPartecipanti();
foreach($partecipanti AS $partecipante) {
if ($partecipante["escluso"] == "N") {
$destinatari[] = $partecipante["codice_operatore"];
}
}
break;
case "N": // __("Esclusi")
$partecipanti = $this->getPartecipanti();
foreach($partecipanti AS $partecipante) {
if ($partecipante["escluso"] == "S") {
$destinatari[] = $partecipante["codice_operatore"];
}
}
break;
case "A": // __("Aggiudicatari")
$destinatari = array_column($this->getAggiudicatari(),"codice_operatore");
break;
case "E": // __("Non aggiudicatari")
$partecipanti = $this->getPartecipanti();
foreach($partecipanti AS $partecipante) {
if ($partecipante["aggiudicatario"] == "N") {
$destinatari[] = $partecipante["codice_operatore"];
}
}
break;
}
if (!empty($destinatari)) {
$destinatari = array_unique($destinatari);
$destinatari = array_filter($destinatari);
return $destinatari;
}
}
return false;
}
/**
* checkCPVServiziArt74
*
* @param Int $cpv
* @return bool
*/
function checkCPVServiziArt74(Int $cpv) : bool {
$cpv = (int) str_pad($cpv, 8, '0', STR_PAD_RIGHT);
if(in_array($cpv, [75200000, 75231200, 75231240, 79611000, 79622000, 79624000, 79625000, 98133100, 98133000, 98200000, 98500000, 85321000, 85322000, 75000000, 75121000, 75122000, 75124000, 79950000, 79951000, 79952000, 79952100, 79953000, 79954000, 79955000, 79956000, 75300000, 75310000, 75311000, 75312000, 75313000, 75313100, 75314000, 75320000, 75330000, 75340000, 98000000, 98120000, 98132000, 98133110, 98130000, 98131000, 55521000, 55521100, 55521200, 55520000, 55522000, 55523000, 55524000, 55510000, 55511000, 55512000, 55523100, 75231100, 75123000, 79430000, 98113100, 79722000, 79723000, 98900000, 98910000, 64000000, 64100000, 64110000, 64111000, 64112000, 64113000, 64114000, 64115000, 64116000, 64122000, 50116510, 71550000])) {
return true;
}
if($cpv >= 85000000 && $cpv <= 85323000) {
return true;
}
if($cpv >= 98513000 && $cpv <= 98514000) {
return true;
}
if($cpv >= 79995000 && $cpv <= 79995200) {
return true;
}
if($cpv >= 80000000 && $cpv <= 80660000) {
return true;
}
if($cpv >= 92000000 && $cpv <= 92700000) {
return true;
}
if($cpv >= 55100000 && $cpv <= 55410000) {
return true;
}
if($cpv >= 55521000 && $cpv <= 55521200) {
return true;
}
if($cpv >= 79100000 && $cpv <= 79140000) {
return true;
}
if($cpv >= 75100000 && $cpv <= 75120000) {
return true;
}
if($cpv >= 75125000 && $cpv <= 75131000) {
return true;
}
if($cpv >= 75200000 && $cpv <= 75231000) {
return true;
}
if($cpv >= 75231210 && $cpv <= 75231230) {
return true;
}
if($cpv >= 75240000 && $cpv <= 75252000) {
return true;
}
if($cpv >= 79700000 && $cpv <= 79721000) {
return true;
}
return false;
}
/**
* Get the current bidding threshold.
*
* @return ?string
*/
function getSogliaGara() : ?string {
$soglia = "sottosoglia";
$tipologia_ente = $this->db->go("SELECT tipologia_ente FROM b_enti WHERE codice = :codice_ente", [":codice_ente" => $this->info["codice_ente"]])->fetch(PDO::FETCH_COLUMN, 0);
if(empty($tipologia_ente)) $tipologia_ente = 15;
$tipologia_ente = array_column(ente::tipologieEnte(), null, "codice")[$tipologia_ente];
$tipologia = $this->info["tipologia"][0];
$prezzo = $this->info["prezzoRiferimento"];
$elaborazione = $this->getRisposteElaborazione();
$concessione = $elaborazione["concessione"] ?? "N";
$concessione = ($concessione == "S");
$cpvs = $this->getCategorieMerceologiche();
$servizi_art74 = false;
if (! empty($cpvs)) {
foreach($cpvs AS $cpv) {
if($this->checkCPVServiziArt74($cpv)) {
$servizi_art74 = true;
break;
}
}
}
if ($concessione) {
if($prezzo >= 5538000.00) {
$soglia = "soprasoglia";
}
} else {
switch($tipologia) {
case "L":
if($prezzo >= 5538000.00) {
$soglia = "soprasoglia";
}
break;
case "S":
case "F":
if(!empty($elaborazione) && $elaborazione["settoreRiferimento"] == "speciale") {
if($prezzo >= 443000.00 && (!$servizi_art74 || $prezzo >= 1000000)) {
$soglia = "soprasoglia";
}
} else {
if ($servizi_art74) {
if ($prezzo >= 750000) {
$soglia = "soprasoglia";
}
} else {
if($tipologia_ente["centrale"] == "S") {
if($prezzo >= 143000.00) {
$soglia = "soprasoglia";
}
} else {
if($prezzo >= 221000.00) {
$soglia = "soprasoglia";
}
}
}
}
break;
}
}
return $soglia;
}
public function getPublicIdentifier() : string {
return generatePublicIdentifier("G", $this->info["codice_ente"], $this->info["codice"]);
}
/**
* Get a new NuovaPiattaformaAppalti instance for the given tender.
*
* @return NuovaPiattaformaAppalti
*/
function getNpaInstance() : ?NuovaPiattaformaAppalti {
if($this->npa) return $this->npa;
$sql = "SELECT * FROM b_npa WHERE modulo_riferimento = :modulo_riferimento AND id_riferimento = :codice_riferimento ORDER BY revisione_fascicolo DESC LIMIT 0,1";
$bind = [":codice_riferimento" => $this->info["codice"], ":modulo_riferimento" => "gare"];
$fascicolo = $this->db->go($sql, $bind)->fetch(PDO::FETCH_ASSOC);
if(! empty($fascicolo["codice"])) {
$this->npa = NuovaPiattaformaAppalti::init($fascicolo["codice"], null, null, "gare", $this->info["codice"]);
return $this->npa;
}
return null;
}
public function getRup() : ?Array {
$incaricati = $this->getManagerIncarichi()->getIncaricati();
if (!empty($incaricati)) {
$incaricati = array_column($incaricati, null, "ruolo");
if(! empty($incaricati[14])) {
return $incaricati[14];
}
}
return null;
}
/**
* Retrieves descendant cards for the given dossier.
*
* @return ?Array
*/
function getDescendantCards(bool $arrangeByCategory = true) : ?Array {
$npa = $this->getNpaInstance();
if(! empty($npa)) {
$elaborazione = $this->getRisposteElaborazione();
$soglia = $this->getSogliaGara();
$schede = $npa->getCardsAndItsDescendantsList($elaborazione["settoreRiferimento"], $soglia, ($elaborazione["concessione"] ?? "N") == "S", false);
$procedura = $this->getProcedura();
if(count($procedura["fasi"]) < 2) {
$schede = array_filter($schede, function($key) {
return $key != "S1";
}, ARRAY_FILTER_USE_KEY);
}
return $arrangeByCategory ? $npa->arrangeCardsByCategory($schede) : $schede;
}
return null;
}
/**
* Get the list of available cards for the NPA
*
* @return ?Array
*/
public function getInitialCards() : ?Array {
$rounds = $this->getRounds();
$elaborazione = $this->getRisposteElaborazione();
$soglia = $this->getSogliaGara();
return NuovaPiattaformaAppalti::getInitialCards("gare", $this->info["procedura"], $rounds[0]["id"], $elaborazione["settoreRiferimento"], $soglia, ($elaborazione["concessione"] ?? "N") == "S") ;
}
/**
* Updates the CIG (Contract Identification Code) within the application
*
* @param Int $codice
* @param String $cig
* @return Bool
*/
public function updateCig(Int $codice, String $cig) : void {
$this->db->go("UPDATE b_gare_lotti SET cig = :cig WHERE codice = :codice", [":codice" => $codice, ":cig" => $cig]);
$this->triggerUpdates();
}
function getEnteBeneficiario(array $extraFields = []): ?array
{
if (empty($this->info) || empty($this->info["codice_ente"])) return null;
$tmp = Ente::getInfoFromID($this->info["codice_ente"]);
if (empty($tmp)) return null;
$return = null;
$tmp = reset($tmp);
if (!empty($tmp["cf"])) {
$return = ["codice_fiscale" => $tmp["cf"], "codice_ausa" => $tmp["codice_ausa"]];
} else {
if (!empty($tmp["sua"]) && $tmp["ufficio"] == "S") {
$tmp = Ente::getInfoFromID($tmp["sua"]);
if (!empty($tmp)) {
$tmp = reset($tmp);
}
}
if (!empty($tmp["cf"])) {
$return = ["codice_fiscale" => $tmp["cf"], "codice_ausa" => $tmp["codice_ausa"]];
}
}
if(!empty($return)) {
foreach($extraFields as $extraField) {
$return[$extraField] = $tmp[$extraField] ?? null;
}
}
return $return;
}
public function deleteRound() : bool {
if ($this->activeRound && $this->round["numero"] > 1 && !$this->checkPartecipantiPresenti()) {
$check = $this->db->go("DELETE FROM b_gare_round WHERE codice_gara = :gara AND codice = :codice",[":gara"=>$this->info["codice"],":codice"=>$this->round["codice"]]);
if ($check->rowCount() > 0) {
$check = $this->db->go("UPDATE b_gare SET fase_attiva = fase_attiva - 1, stato = 21 WHERE codice = :gara",[":gara"=>$this->info["codice"]]);
if ($check->rowCount() > 0) {
return true;
}
}
}
return false;
}
public function clone() : Bool {
$return = false;
$copyInfo = $this->getExtraInfo()["gara"]["copyInfo"] ?? null;
if (!empty($copyInfo["codice"])) {
$source = self::init($copyInfo["codice"]);
if (!empty($source)) {
$cloner = new CloneGara($source,$this);
return $cloner->clone();
}
}
return $return;
}
function getAggiudicazioneProdotti() :?Array
{
if(!empty($this->info)){
global $pdo;
$sql = "SELECT r_gara_prodotto.codice_prodotto as codice,
b_prodotti.denominazione,
b_prodotti.codice_oe,
b_prodotti.brand,
b_prodotti.prezzo,
b_prodotti.percIva
FROM r_gara_prodotto
LEFT JOIN b_prodotti ON r_gara_prodotto.codice_prodotto = b_prodotti.codice
WHERE r_gara_prodotto.codice_gara = :codice_gara";
$ris = $pdo->go($sql, [':codice_gara' => $this->info['codice']]);
if($ris->rowCount() > 0){
return $ris->fetchAll(PDO::FETCH_ASSOC);
}
}
return [];
}
public function canAddOrRemovePartecipanti() {
if($this->checkLock("partecipanti")) return false;
$npa = $this->getNpaInstance();
if($npa !== null)
return !$npa->hasLockOnPartecipanti(false, false);
return true;
}
public function canAddOrRemoveLotti() {
$partecipanti = $this->db->go("SELECT codice FROM r_partecipanti_gare WHERE codice_round IN (SELECT codice FROM b_gare_round WHERE codice_gara = :gara)",[":gara"=>$this->info["codice"]]);
if(!$this->activeRound || $this->checkLock("lotti") || $partecipanti->rowCount() > 0) return false;
$npa = $this->getNpaInstance();
if($npa !== null)
return empty($npa->fascicolo["id_appalto"]) && empty($npa->fascicolo["id_pianificazione"]);
return true;
}
public function inviteOE(array $selected, ?int $codice_lotto, ?array $invito_manuale = null, bool $delete = false) {
global $pdo;
$invitati = [];
if (!empty($codice_lotto)) {
$this->setLotto($codice_lotto);
}
$invitatiDB = array_column($this->getInvitati(),"codice_operatore");
if (!empty($selected)) {
foreach($selected AS $oe) {
if (in_array($oe,$invitatiDB) === false) {
if ($this->saveInvito($codice_lotto,$oe,false,true)) {
$invitati[] = $oe;
if ($this->info["stato"] >= 20) {
$this->inviaInvito([$oe]);
}
}
} else {
$invitati[] = $oe;
}
}
}
if($delete) {
$invitatiDB = array_column($this->getInvitati(),"codice_operatore");
$deleteInvito = $pdo->prepare("DELETE FROM r_inviti_gare WHERE codice_round = :codice_round AND codice_lotto = :lotto AND codice_operatore = :operatore ");
$deleteInvito->bindValue(":codice_round",$this->round["codice"]);
$deleteInvito->bindValue(":lotto",$codice_lotto);
$deleteStoricoInvito = $pdo->prepare("DELETE FROM b_inviti WHERE contesto = 'gare' AND codice_elemento = :codice_round AND sub_elemento = :lotto AND codice_fiscale_operatore = :operatore ");
$deleteStoricoInvito->bindValue(":codice_round",$this->round["codice"]);
$deleteStoricoInvito->bindValue(":lotto",$codice_lotto);
foreach($invitatiDB AS $oe) {
if (in_array($oe,$invitati) === false) {
$deleteInvito->bindValue(":operatore",$oe);
$deleteInvito->execute();
$oe = oeManager::getOE($oe);
$this->addToLog("DELETE",__("Invito operatore") . ":" . $oe["ragione_sociale"]);
ob_start();
$deleteInvito->debugDumpParams();
$dumpParams = ob_get_clean();
scriviLog("r_inviti_gare","DELETE",$dumpParams);
if (!empty($oe["codice_fiscale_impresa"])) {
$deleteStoricoInvito->bindValue(":operatore",$oe["codice_fiscale_impresa"]);
$deleteStoricoInvito->execute();
ob_start();
$deleteStoricoInvito->debugDumpParams();
$dumpParams = ob_get_clean();
scriviLog("b_inviti","DELETE",$dumpParams);
}
}
}
if (!empty($invito_manuale)) {
$deleteInvito = $pdo->prepare("DELETE FROM temp_inviti WHERE codice = :codice AND contesto = 'gare' AND attivo = 'S' AND codice_elemento = :codice_round AND sub_elemento = :lotto");
$deleteInvito->bindValue(":codice_round",$this->round["codice"]);
$deleteInvito->bindValue(":lotto",$codice_lotto);
foreach($invito_manuale AS $codice => $codice_fiscale) {
$deleteInvito->bindValue(":codice",$codice);
$deleteInvito->execute();
ob_start();
$deleteInvito->debugDumpParams();
$dumpParams = ob_get_clean();
scriviLog("temp_inviti","DELETE",$dumpParams);
if (!empty($codice_fiscale)) {
$deleteStoricoInvito->bindValue(":operatore",$codice_fiscale);
$deleteStoricoInvito->execute();
ob_start();
$deleteStoricoInvito->debugDumpParams();
$dumpParams = ob_get_clean();
scriviLog("b_inviti","DELETE",$dumpParams);
}
}
}
}
}
/**
* getRda
*
* @return array
*/
public function getRda()
{
if(!empty($this->info)){
global $pdo;
$sql = "SELECT b_rda.codice
FROM r_gara_rda
LEFT JOIN b_rda ON r_gara_rda.codice_rda = b_rda.codice
WHERE r_gara_rda.codice_gara = :codice_gara";
return $pdo->go($sql, [':codice_gara' => $this->info['codice']])->fetchAll(PDO::FETCH_COLUMN) ?? [];
}
}
/**
* updateStateRda
*
* @return void
*/
public function updateStateRda()
{
if(!empty($this->getRda())){
$statoRda = '0';
if(in_array($this->info['stato'], ['95', '99'] )){
$statoRda = '10';
}
if(in_array($this->info['stato'], ['35', '50'])){
$statoRda = '30';
}
if(in_array($this->info['stato'], ['90'])){
$statoRda = '90';
}
if($statoRda > 0){
$statoRda = StatoRda::getStati(null, $statoRda);
if(!empty($statoRda)){
$statoRda = reset($statoRda);
foreach ($this->getRda() as $rda) {
$rda = Rda::init($rda);
$rda->moveStatus($statoRda['codice']);
}
}
}
}
}
}