commissario = false; $this->v2placeholder = "__v2Decrypt__"; $this->db = $pdo; } public static function statiTermineProcedura($lastRound = null) { $return = []; if (!$lastRound) { $return = [30]; } $return = array_merge($return,[ "50", // "Inviato esito" "90", // "Annullato" "95", // "Deserto" "99", // "Non aggiudicato" "100" // "Completo" ]); return $return; } public function updateStato($stato) { if ($this->info["fase_attiva"] == $this->round["numero"] && $this->info["stato"] < $stato) { $this->db->go("UPDATE b_concorsi 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->db->go("UPDATE b_concorsi_round SET pubblica = :pubblica WHERE codice = :codice", [":pubblica" => $b, ":codice" => $this->round["codice"]]); $this->round["pubblica"] = $b; } } $this->updateBadges(); } if (isset($_SESSION["ente"])) { $_SESSION["ente"]->manageUpdates("concorsi",$this->info["codice"],$this); } } public function updateStatoLotto($stato) { if (!empty($this->lotto) && ($this->info["fase_attiva"] == $this->round["numero"] && $this->lotto["stato"] < $stato)) { $this->db->go("UPDATE b_concorsi_lotti SET stato = :stato WHERE codice = :codice", [":stato" => $stato, ":codice" => $this->lotto["codice"]]); } $this->valutaStatoGenerale(); } public function getRisposteElaborazione() { return json_decode($this->getExtraInfo()["round"]["elaborazione"] ?? "",true); } 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"]; } } } if (empty($return)) { $return = true; } return $return; } public function getManagerRegistro() { return new registriManager("concorsi", $this->info["codice"]); } 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 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 = "concorso") { $extraInfo = $this->getExtraInfo(); $extraInfo[$ambito][$chiave] = $valore; if ($ambito == "concorso") { $codice = $this->info["codice"]; $tabella = "b_concorsi"; $this->info["extraInfo"] = json_encode($extraInfo["concorso"]); } else if ($ambito == "round") { $codice = $this->round["codice"]; $tabella = "b_concorsi_round"; $this->round["extraInfo"] = json_encode($extraInfo["round"]); } else if ($ambito == "lotto") { $codice = $this->lotto["codice"]; $tabella = "b_concorsi_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", "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"] . "/"; } if ($operazione == "INSERT") { $data["id"] = 1; $where = ""; $bind = []; if ($solare) { $where = " WHERE anno = :anno "; $bind[":anno"] = $data["anno"]; } $sql = "SELECT id FROM b_concorsi {$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'); } $salva = new salva(); $salva->debug = false; $salva->nome_tabella = "b_concorsi"; $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"] = "concorsi"; $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); if (empty($pdo->go("SELECT codice FROM b_concorsi_lotti WHERE codice_concorso = :codice",$bind)->rowCount())) { $strsql = "DELETE FROM r_cpv_concorsi WHERE codice_concorso = :codice"; $pdo->go($strsql, $bind); scriviLog("r_cpv_concorsi", "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_concorsi (codice_concorso,codice,utente_modifica) VALUES (:codice,:codice_categoria,:codice_utente)"; $pdo->go($strsql, $bind); scriviLog("r_cpv_concorsi", "INSERT", $pdo->getSQL()); } } } } $bind = array(); $bind[":codice"] = $codice; $strsql = "SELECT * FROM b_concorsi WHERE codice = :codice"; $risultato = $pdo->go($strsql, $bind); if ($risultato->rowCount() > 0) { $record = $risultato->fetch(PDO::FETCH_ASSOC); if (empty($record["public_key"])) { $email = $data["email_chiave"] ?? ""; $public = P7Manager::generateKeys("concorsi-{$record["id"]}", $record["oggetto"], $email); if (!empty($public)) { if (!$pdo->go("UPDATE b_concorsi 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)) { $i = 0; foreach ($data["fase"] as $fase) { $i++; $operazione = "INSERT"; if (is_numeric($fase["codice"])) { $operazione = "UPDATE"; } $fase["codice_concorso"] = $record["codice"]; $fase["numero"] = $i; $salva = new salva(); $salva->debug = false; $salva->nome_tabella = "b_concorsi_round"; $salva->operazione = $operazione; $salva->expect = ["codice", "codice_concorso", "numero", "oggetto", "descrizione"]; $salva->oggetto = $fase; $codice_round = $salva->save(); } $return = concorso::init($record["codice"]); if (!empty($return)) { foreach ($data["extraInfo"] as $chiave => $valore) { $return->saveExtraInfo($chiave, $valore, "concorso"); } $return->addToLog($operazione_generale, "Dati preliminari"); } } else { $return = -1; if ($operazione == "INSERT") { $pdo->go("DELETE FROM b_concorsi WHERE codice = :codice", [":codice" => $codice]); } } } } return $return; } public function getCategorieMerceologiche() { $codici_categoria = []; $sql_categoria = "SELECT codice FROM r_cpv_concorsi WHERE codice_concorso = :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 function setLotto($codice) { if (!empty($codice)) { $dbLotto = $this->getLotti($codice)[0] ?? false; if (!empty($dbLotto)) { $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 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; } } $salva = new salva(); $salva->debug = false; $salva->nome_tabella = "b_concorsi_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 getIdAppalto() { return $this->info["codice"]; // TODO: Restituire l'id appalto rilasciato da ANAC } public function getExtraInfo() { $return = []; if (!empty($this->info["extraInfo"])) { $return["concorso"] = 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"); } public function canDecryptInfo() { return (isset($this->lotto) && $this->lotto["stato"] >= 30 && $this->info["fase_attiva"] == count($this->getRounds())); } public static function tipologieBusta() { $return = []; $return["tecnica"] = ["titolo" => "Busta Tecnica", "firma" => false, "estensioniAccettate" => [".xml",".docx",".doc",".xlsx",".xls",".pptx",".ppt",".pdf",".rtf",".csv",".odt",".ods",".jpeg",".jpg",".png",".gif",".mp4",".mov",".wmv",".avi",".webm",".avchd",".flv",".f4v",".swf",".mkv",".mpeg-2"] ]; $return["amministrativa"] = ["titolo" => "Busta Amministrativa", "firma" => true]; return $return; } public function busteDisponibili($open = false) { $tmp = self::tipologieBusta(); if ($open) { $return = []; foreach($tmp AS $key => $info) { if ($this->canDecryptInfo() || !$info["firma"]) { $return[$key] = $info; } } } else { $return = $tmp; } return $return; } public function getRichieste($busta = NULL) { $bind = [":codice_round" => $this->round["codice"]]; $sql = "SELECT b_concorsi_richieste.* FROM b_concorsi_richieste "; if (!empty($this->lotto)) { $sql .= " JOIN r_concorsi_richieste_lotti ON b_concorsi_richieste.codice = r_concorsi_richieste_lotti.codice_richiesta "; } $sql .= " WHERE codice_round = :codice_round "; if (!empty($this->lotto)) { $sql .= " AND (r_concorsi_richieste_lotti.codice_lotto = 0 OR r_concorsi_richieste_lotti.codice_lotto = :lotto ) "; $bind[":lotto"] = $this->lotto["codice"]; } if (!empty($busta)) { $bind[":busta"] = $busta; $sql .= " AND b_concorsi_richieste.busta = :busta "; } $sql .= " ORDER BY b_concorsi_richieste.ordinamento, b_concorsi_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_concorso" => $this->info["codice"]]; $sql = "SELECT * FROM b_concorsi_round WHERE codice_concorso = :codice_concorso "; 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 getLotti($codice = null) { $bind = [":codice_concorso" => $this->info["codice"]]; $sql = "SELECT * FROM b_concorsi_lotti WHERE codice_concorso = :codice_concorso "; if ($codice !== null) { $bind[":codice"] = $codice; $sql .= " AND codice = :codice "; } return $this->db->go($sql . " ORDER BY numero", $bind)->fetchAll(PDO::FETCH_ASSOC); } public static function getFormule() { return tuttogareMath::getFormule(); } public static function init($codice, $codice_round = NULL, $valutazione = NULL) { if (!empty($codice) && !empty($_SESSION["utente"]) && !empty($_SESSION["ente"])) { global $pdo; $bind = [":codice" => $codice]; $sql = "SELECT * FROM b_concorsi 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; } $concorso = $pdo->go($sql, $bind)->fetch(PDO::FETCH_ASSOC); if (!empty($concorso)) { $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 = \"concorsi\" 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" && ($concorso["stato"] == "21" || $concorso["stato"] == "25") && strtotime($check["scadenza"]) > time()) { $continua = true; $commissario = true; } } } else { if (!defined("__CMDS_JOB_EXEC")) { $continua = $_SESSION["utente"]->permission("concorsi",$concorso["codice"],"0",true); if ($continua) { if ($_SESSION["utente"]->gerarchia > 9 && $_SESSION["utente"]->codice_ente != $concorso["codice_ente"] && $_SESSION["utente"]->codice_ente != $_SESSION["ente"]->codice) { $continua = false; } } } else { $continua = true; } } if ($continua) { $continua = false; $instance = new concorso(); $instance->info = $concorso; $instance->commissario = $commissario; $instance->activeRound = false; $instance->lastRound = false; $rounds = $instance->getRounds(); if (!empty($rounds)) { foreach($rounds AS $round) { if ($round["codice"] === $codice_round || (!isset($codice_round) && $round["numero"] == $instance->info["fase_attiva"])) { $instance->round = $round; break; } } } if (empty($instance->round)) { if (!empty($rounds)) { $instance->round = reset($rounds); } else { $instance->round = get_campi("b_concorsi_round"); $instance->round["numero"] = 1; } } if ($instance->round["numero"] == $concorso["fase_attiva"]) { $instance->activeRound = true; } if ($instance->round["numero"] == count($rounds)) { $instance->lastRound = true; } if ($instance->round["numero"] < $concorso["fase_attiva"]) { $instance->info["stato"] = 100; } if ($instance->round["numero"] > $concorso["fase_attiva"]) { $instance->info["stato"] = 10; } if (isset($instance->round) && $concorso["stato"] == 20 && strtotime($instance->round["scadenza"]) < time() && $instance->activeRound) { $instance->updateStato(21); } return $instance; } } } return false; } 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->info["fase_attiva"] > 1) ? "S" : "N", 'ambito'=> "concorsi", 'lotti'=> count($lotti), 'oggetto'=> $this->info["oggetto"], 'url'=> "https://{$_SESSION["ente"]->getInfo()["dominio"]}/concorsi/dettaglio.php?codice={$this->info["codice"]}", 'procedura'=> "concorso", 'tipologia'=> "S", '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'=> "", ] ]; 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"], '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, ]; } } return $return; } } public function updateBadges() { $badge = 0; $sql_bad = "SELECT b_concorsi_chiarimenti.codice FROM b_concorsi_chiarimenti JOIN b_concorsi_round ON b_concorsi_chiarimenti.codice_round = b_concorsi_round.codice JOIN b_concorsi ON b_concorsi_round.codice_concorso = b_concorsi.codice WHERE b_concorsi_round.scadenza >= now() AND b_concorsi_chiarimenti.attivo = 'N' AND b_concorsi.codice = :codice "; $ris_badge = $this->db->go($sql_bad, [":codice" => $this->info["codice"]]); $badge += $ris_badge->rowCount(); $sql_bad = "SELECT b_concorsi_sopralluogo.codice FROM b_concorsi_sopralluogo JOIN b_concorsi_round ON b_concorsi_sopralluogo.codice_round = b_concorsi_round.codice JOIN b_concorsi ON b_concorsi_round.codice_concorso = b_concorsi.codice WHERE b_concorsi_round.scadenza >= now() AND b_concorsi_sopralluogo.attivo = 'P' AND b_concorsi.codice = :codice "; $ris_badge = $this->db->go($sql_bad, [":codice" => $this->info["codice"]]); $badge += $ris_badge->rowCount(); $this->db->go("UPDATE b_concorsi SET badge = :badge WHERE codice = :codice", [":badge" => $badge, ":codice" => $this->info["codice"]]); } 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_concorsi 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 = "concorsi-form"; $dataSql = "SELECT codice, content FROM b_concorsi_form_data WHERE codice_input = :input AND codice_offerta = :offerta "; $viewFormAttachPath = "/backend/concorsi/open/viewFormAttachment.php"; global $beRoot; $parentAllowedTypes = [".xml",".docx",".doc",".xlsx",".xls",".pptx",".ppt",".pdf",".rtf",".csv",".odt",".ods",".jpeg",".jpg",".png",".gif"]; 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_concorsi_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_concorsi_richieste_lotti WHERE codice_richiesta = :richiesta",[":richiesta"=>$codice_richiesta])->fetchAll(PDO::FETCH_COLUMN); } } 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 returnCriteri($codice_round, $filters = []) { if (!empty($this->getRounds($codice_round))) { $bind = [":codice_round" => $codice_round]; $keysFilters = array_keys(get_campi("b_concorsi_criteri_valutazione")); $sql = "SELECT b_concorsi_criteri_valutazione.* FROM b_concorsi_criteri_valutazione "; if (!empty($this->lotto) && empty($filters["ignore-lotto"])) { $sql .= " JOIN r_concorsi_criteri_lotti ON b_concorsi_criteri_valutazione.codice = r_concorsi_criteri_lotti.codice_criterio "; } $sql .= " WHERE b_concorsi_criteri_valutazione.codice_round = :codice_round "; if (!empty($this->lotto) && empty($filters["ignore-lotto"])) { $sql .= " AND (r_concorsi_criteri_lotti.codice_lotto = 0 OR r_concorsi_criteri_lotti.codice_lotto = :lotto ) "; $bind[":lotto"] = $this->lotto["codice"]; } foreach ($filters as $key => $value) { if (in_array($key, $keysFilters, true) !== false) { $bind[":{$key}"] = $value; $sql .= " AND b_concorsi_criteri_valutazione.{$key} = :{$key} "; } else { if ($key != "ignore-lotto") { return null; } } } $sql .= " GROUP BY b_concorsi_criteri_valutazione.codice ORDER BY b_concorsi_criteri_valutazione.ordinamento, b_concorsi_criteri_valutazione.codice "; return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC); } } public function printCriteriaTable() { $criteri = $this->getMacroCriteri(); if (!empty($criteri)) { global $beRoot; include($beRoot . "/common/criteri/model-table.php"); } } 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() { $lotti = $this->getLotti(); $stati = []; $lottiCompleti = 0; foreach($lotti AS $lotto) { if ($lotto["stato"] > 0) { if (in_array($lotto["stato"],self::statiTermineProcedura($this->lastRound))) { $lottiCompleti++; } $stati[] = $lotto["stato"]; } } if (!empty($stati) && count($stati) == count($lotti)) { $stati = array_unique($stati); if (count($stati) === 1) { $this->updateStato($stati[0]); } else { $stato = 25; if (count($lotti) == $lottiCompleti) { if ($this->lastRound) { $stato = 100; } else { $stato = 30; } } $this->updateStato($stato); } } } public function decriptaPartecipanti() { if (!empty($this->lotto) && $this->canDecryptInfo()) { $partecipanti = $this->getPartecipanti(true); if (!empty($partecipanti)) { $salva = new salva(); $salva->debug = false; global $config; foreach($partecipanti AS $partecipante) { if ($partecipante["flagEncrypted"] == "S") { if (strpos($partecipante["encryptedData"],$this->v2placeholder) === 0) { return false; } else { $decrypted = json_decode(simple_decrypt(base64_decode($partecipante["encryptedData"]),$config["simple_encrypt"]["offer"]),true); } $partecipante = array_merge($partecipante,$decrypted); $partecipante["flagEncrypted"] = "N"; unset($partecipante["timestamp_invio"]); $salva->nome_tabella = "r_partecipanti_concorsi"; $salva->operazione = "UPDATE"; $salva->oggetto = $partecipante; $salva->save(); $raggruppamento = $this->getRaggruppamento($partecipante["codice"]); if (!empty($raggruppamento)) { foreach($raggruppamento AS $membro) { $decrypted = json_decode(simple_decrypt(base64_decode($membro["encryptedData"]),$config["simple_encrypt"]["offer"]),true); $membro = array_merge($membro,$decrypted); $membro["flagEncrypted"] = "N"; $salva->nome_tabella = "r_raggruppamenti_concorsi"; $salva->operazione = "UPDATE"; $salva->oggetto = $membro; $salva->save(); } } } } return true; } } return false; } public function savePartecipante($partecipante) { if (!empty($partecipante["codice"])) { $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"]; unset($partecipante["timestamp_invio"]); $salva = new salva(); $salva->debug = false; $salva->nome_tabella = "r_partecipanti_concorsi"; $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_concorsi 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_concorsi"; $salva->operazione = "INSERT"; $salva->oggetto = $sub; $salva->save(); } } $this->addToLog(empty($partecipante["codice"]) ? "INSERT" : "UPDATE",__("Partecipante") . " #" . $codice); return true; } } 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"] = ""; } } $operazione = (is_numeric($criterio["codice"])) ? "UPDATE" : "INSERT"; $salva = new salva(); $salva->debug = false; $salva->nome_tabella = "b_concorsi_criteri_valutazione"; $salva->operazione = $operazione; $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_concorsi_form WHERE codice_criterio = :codice",[":codice"=>$codice]); scriviLog("b_concorsi_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_concorsi_criteri_valutazione"; $salva->operazione = "UPDATE"; $salva->oggetto = [ "codice" => $sub["codice"], "decimali" => $criterio["decimali"], "tipologia" => $criterio["tipologia"], ]; $salva->save(); } } $this->checkRichiesteOnEditCriteri(); $this->updateStato(10); return $codice; } } } return false; } public function bindCriterio($criterio,$lotti = 0) { $this->db->go("DELETE FROM r_concorsi_criteri_lotti WHERE codice_criterio = :codice",[":codice"=>$criterio]); $insert = $this->db->prepare("INSERT INTO r_concorsi_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 saveRichiesta($richiesta) { if (!empty($this->busteDisponibili($richiesta["busta"]))) { if (empty($richiesta["codice"])) { $richiesta["ordinamento"] = count($this->getRichieste($richiesta["busta"])); } $salva = new salva(); $salva->debug = false; $salva->nome_tabella = "b_concorsi_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,"concorsi-richiesta",$allegato["nome"] ?? "","A",$allegato["classificazione"] ?? ""); } } $this->addToLog($salva->operazione,__("Richiesta").": " . $richiesta["titolo"]); return $codice; } } return false; } public function bindRichiesta($richiesta,$lotti = 0) { $this->db->go("DELETE FROM r_concorsi_richieste_lotti WHERE codice_richiesta = :codice",[":codice"=>$richiesta]); $check = $this->db->prepare("SELECT codice FROM r_concorsi_richieste_lotti WHERE codice_richiesta = :richiesta AND (codice_lotto = :lotto OR codice_lotto = 0)"); $insert = $this->db->prepare("INSERT INTO r_concorsi_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() { $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) { $type = null; $lotti = $this->getLottiFromCriterio($criterio["codice"]); if (!empty($lotti)) { if (!empty($criterio["auto"]) || ($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_concorsi_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"] = "S"; $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; } $this->bindRichiesta($codiceRichiesta,$lotti); } else { $this->db->go("DELETE FROM b_concorsi_richieste WHERE busta = :busta AND locked = 'S' AND codice_round = :codice_round",[":busta"=>$busta,":codice_round"=>$this->round["codice"]]); scriviLog("b_concorsi_richieste", "DELETE", $this->db->getSQL()); } } } $this->lotto = $lottoSelezionato; } 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_concorsi_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 (($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; } } } } } 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); } } if ($id_cmd == "criteri" || $id_cmd == "buste" || $id_cmd == "lotti") { global $pdo; $check = $pdo->go("SELECT r_partecipanti_concorsi.codice FROM r_partecipanti_concorsi JOIN b_concorsi_buste ON r_partecipanti_concorsi.codice = b_concorsi_buste.codice_partecipante WHERE codice_round = :codice_round",[":codice_round"=>$this->round["codice"]]); $checkOfferte = $pdo->go("SELECT r_partecipanti_concorsi.codice FROM r_partecipanti_concorsi JOIN b_offerte_concorsi ON r_partecipanti_concorsi.codice = b_offerte_concorsi.codice_partecipante WHERE codice_round = :codice_round",[":codice_round"=>$this->round["codice"]]); if ($check->rowCount() > 0 || $checkOfferte->rowCount() > 0) { $return = true; } if ($id_cmd == "lotti" && !$return) { $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 == "preliminari" || $id_cmd == "lotti") && $this->info["stato"] > 0) { $return = true; } return $return; } public function checkOpeningPermission($partecipante, $richiesta, $aggiuntive = false) { $return = false; if (!empty($this->lotto)) { if (!empty($partecipante) && !empty($richiesta)) { $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($this->busteDisponibili(true)); $tipologia = $this->db->go("SELECT busta FROM b_concorsi_richieste WHERE codice = :codice", [":codice" => $richiesta])->fetch(PDO::FETCH_ASSOC); if (!empty($tipologia)) { $tipologia = $tipologia["busta"]; $checkSeduta = $this->db->go("SELECT data FROM b_concorsi_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_concorsi.codice) AS firstPartecipante, b_concorsi_richieste.busta FROM r_partecipanti_concorsi JOIN b_concorsi_buste ON r_partecipanti_concorsi.codice = b_concorsi_buste.codice_partecipante JOIN b_concorsi_richieste ON b_concorsi_buste.codice_richiesta = b_concorsi_richieste.codice WHERE r_partecipanti_concorsi.codice_round = :codice_round AND r_partecipanti_concorsi.conferma =\"S\" AND (r_partecipanti_concorsi.escluso = \"N\" OR r_partecipanti_concorsi.escluso = \"P\") AND b_concorsi_buste.open = 'N' AND r_partecipanti_concorsi.codice_lotto = :codice_lotto AND b_concorsi_richieste.busta IN ('{$inBuste}') GROUP BY b_concorsi_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_concorsi_richieste WHERE codice = :codice", [":codice" => $richiesta])->fetch(PDO::FETCH_ASSOC); $return = false; if (!empty($tipologia)) { $tipologia = $tipologia["busta"]; if ($busta != "amministrativa") { $criteri = $this->getCriteri(); foreach ($criteri as $criterio) { if ($criterio["tipologia"] == "Q") { $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_concorsi_punteggi_partecipanti.codice, b_concorsi_punteggi_partecipanti.codice_partecipante, b_concorsi_punteggi_partecipanti.valore FROM b_concorsi_punteggi_partecipanti WHERE codice_criterio = :criterio AND codice_partecipante IN (".$codici_partecipanti.")"); $macro = $this->getMacroCriteri(); $esclusi = []; 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"]] .= "
" . $info["criterio"] . " - " . __("Soglia") . ": " . $info["soglia"] . " - Punteggio: " . $info["valore"]; } $salva = new salva(); $salva->debug = false; $salva->nome_tabella = "r_partecipanti_concorsi"; 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_concorsi_punteggi_partecipanti SET valore = 0 WHERE codice = :codice"); foreach ($esclusi as $info) { $updatePunteggio->bindValue(":codice",$info["codice_relazione"]); $updatePunteggio->execute(); } } } } return $esclusi; } } public function avviaFaseSuccessiva() { $rounds = $this->getRounds(); $nuova_fase = $this->info["fase_attiva"] + 1; if ($nuova_fase <= count($rounds)) { foreach($rounds AS $round) { if ($round["numero"] == $nuova_fase) { $newRound = $round; break; } } } if (!empty($newRound)) { $lotti = $this->getLotti(); $continua = true; if (!empty($lotti)) { $aggiudicatari = []; foreach($lotti AS $lotto) { $aggiudicatari[$lotto["codice"]] = $this->getAggiudicatari($lotto["codice"]); if (empty($aggiudicatari[$lotto["codice"]])) { if ($lotto["stato"] != 95) { $continua = false; } else { unset($aggiudicatari[$lotto["codice"]]); } } } if ($continua) { $this->db->go("UPDATE b_concorsi SET stato = 10 WHERE codice = :codice",[":codice"=>$this->info["codice"]]); $salva = new salva(); $salva->debug = false; foreach($aggiudicatari AS $lotto => $aggiudicatari) { $this->db->go("UPDATE b_concorsi_lotti SET stato = 0 WHERE codice = :codice",[":codice"=>$lotto]); foreach($aggiudicatari AS $aggiudicatario) { $raggruppamento = $this->getRaggruppamento($aggiudicatario["codice"]); unset($aggiudicatario["codice"]); $aggiudicatario["flagEncrypted"] = "S"; $aggiudicatario["codice_round"] = $newRound["codice"]; $aggiudicatario["codice_lotto"] = $lotto; unset($aggiudicatario["stato"]); unset($aggiudicatario["codice_fiscale"]); unset($aggiudicatario["ragione_sociale"]); $aggiudicatario["escluso"] = "N"; $aggiudicatario["conferma"] = "N"; unset($aggiudicatario["motivazione"]); unset($aggiudicatario["totale"]); unset($aggiudicatario["totaleTmp"]); unset($aggiudicatario["aggiudicatario"]); unset($aggiudicatario["posizione"]); unset($aggiudicatario["utente_modifica"]); unset($aggiudicatario["timestamp_invio"]); unset($aggiudicatario["timestamp"]); $aggiudicatario["uuid"] = uuidgen_v4(); $salva->nome_tabella = "r_partecipanti_concorsi"; $salva->operazione = "INSERT"; $salva->oggetto = $aggiudicatario; $codice = $salva->save(); if (!empty($codice) && !empty($raggruppamento)) { foreach($raggruppamento AS $membro) { unset($membro["codice"]); $membro["codice_padre"] = $codice; $membro["flagEncrypted"] = "S"; unset($membro["stato"]); unset($membro["codice_fiscale_impresa"]); unset($membro["ragione_sociale"]); unset($membro["ruolo"]); unset($membro["utente_modifica"]); unset($membro["timestamp"]); $salva->nome_tabella = "r_raggruppamenti_concorsi"; $salva->operazione = "INSERT"; $salva->oggetto = $aggiudicatario; $salva->save(); } } } } $this->round = $newRound; $this->db->go("UPDATE b_concorsi SET fase_attiva = :numero WHERE codice = :codice",[":numero"=>$nuova_fase,":codice"=>$this->info["codice"]]); return $newRound["codice"]; } } } return false; } public function updateTotalePunteggi() { $this->checkSoglie(); $return = false; $partecipanti = $this->getPartecipanti("ALL"); $totali = []; $sql_punteggi = "SELECT r_partecipanti_concorsi.codice, b_concorsi_punteggi_partecipanti.valore FROM b_concorsi_punteggi_partecipanti JOIN r_partecipanti_concorsi ON b_concorsi_punteggi_partecipanti.codice_partecipante = r_partecipanti_concorsi.codice JOIN b_concorsi_criteri_valutazione ON b_concorsi_punteggi_partecipanti.codice_criterio = b_concorsi_criteri_valutazione.codice WHERE r_partecipanti_concorsi.codice_round = :codice AND r_partecipanti_concorsi.codice_lotto = :lotto"; $ris_punteggi = $this->db->go($sql_punteggi, array(":codice" => $this->round["codice"],":lotto"=>$this->lotto["codice"])); if ($ris_punteggi->rowCount() > 0) { while ($punteggio = $ris_punteggi->fetch(PDO::FETCH_ASSOC)) { if (!isset($totali[$punteggio["codice"]])) { $totali[$punteggio["codice"]] = 0; } $totali[$punteggio["codice"]] += $punteggio["valore"]; } } if (!empty($partecipanti)) { $return = true; $salva = new salva(); $salva->debug = false; foreach ($partecipanti as $partecipante) { unset($partecipante["timestamp_invio"]); $totale = $totali[$partecipante["codice"]] ?? null; $partecipante["totale"] = number_format($totale, 5); $salva->nome_tabella = "r_partecipanti_concorsi"; $salva->operazione = "UPDATE"; $salva->oggetto = $partecipante; $salva->save(); } } return $return; } public function importScore($ammessi = TRUE) { $return = false; $criteri = $this->getCriteriValutabili(); if (!empty($criteri)) { $partecipanti = $this->getPartecipanti($ammessi); if (!empty($partecipanti)) { $salva = new salva(); $salva->debug = false; $ris_check = $this->db->prepare("SELECT * FROM b_concorsi_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); if (!empty($offerte)) { $options = json_decode($criterio["options"], true); 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_concorsi_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 function aggiudica($aggiudicatari = 1) { if (!empty($this->lotto)) { $requestedAggiudicatari = $aggiudicatari; $salva = new salva(); $salva->debug = false; $sql = "UPDATE r_partecipanti_concorsi SET aggiudicatario = 'N' 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_concorsi 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"])); $current = null; while($partecipante = $ris_partecipanti->fetch(PDO::FETCH_ASSOC)) { if ($aggiudicatari > 0 || $current == $partecipante["totale"]) { $partecipante["aggiudicatario"] = "S"; if ($current != $partecipante["totale"]) { $aggiudicatari--; } $current = $partecipante["totale"]; } else { $partecipante["aggiudicatario"] = "N"; } unset($partecipante["timestamp_invio"]); $salva->nome_tabella = "r_partecipanti_concorsi"; $salva->operazione = "UPDATE"; $salva->oggetto = $partecipante; $salva->save(); } $this->saveExtraInfo("aggiudicatari-{$this->round["codice"]}",$requestedAggiudicatari,"lotto"); } } public function getOfferte($codice_criterio, $totale = true, $ammessi = TRUE) { $criterio = $this->getCriteri($codice_criterio); if (!empty($criterio)) { $criterio = $criterio[0]; $partecipanti = $this->getPartecipanti($ammessi); $offerte = []; $codici_dettaglio = [$codice_criterio]; $sql = "SELECT offerta FROM b_dettaglio_offerte_concorsi 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_concorsi WHERE codice_partecipante = :partecipante)"; $getOffer = $this->db->prepare($sql); $getOffer->bindValue(":tipologia", $criterio["tipologia"]); $getOffer->bindValue(":tipoOfferta", "tecnica"); foreach ($partecipanti as $partecipante) { if (!empty($codici_dettaglio)) { if ($totale) { $offer = 0; } else { $offer = []; } $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_ASSOC); if (!empty($tmpOfferta)) { $tmpOfferta = $tmpOfferta["offerta"]; if ($totale) { $offer += ($tmpOfferta * $quantita); } else { $offer[$dettaglio] = ($tmpOfferta * $quantita); } } } } if ($found) { $offerte[$partecipante["codice"]] = $offer; } } } 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, "concorsi", $this->info["codice"], $this->round["codice"]); if (!empty($avvisiProcedura)) { $this->managerAvvisi = $avvisiProcedura; } } return $this->managerAvvisi; } public function getManagerCommissione($tipologia) { $manager = new Commissione("concorsi", $this->round["codice"], $tipologia); if (!empty($manager)) { $this->managerCommissione = $manager; } return $this->managerCommissione; } public function getManagerIncarichi() { $manager = new Incarichi("concorsi", $this->info["codice"]); if (!empty($manager)) { $this->managerIncarichi = $manager; } return $this->managerIncarichi; } public function getManagerDGUE() { $manager = new DGUE("concorsi", $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() ?? []; $return = array_column($destinatari,"codice_operatore"); } } if (count($lotti) > 1) { $this->lotto = null; } $return = array_unique($return); return $return; } public function getDestinatariInterni(bool $onlyCode = false) { return $this->getManagerRegistro()->getUtentiCoinvoltiConRuolo("USR",$onlyCode); } public function addDGUERequest() { if (!$this->checkLock("buste") && $this->db->go("SELECT codice FROM b_concorsi_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 concorso Unico Europeo"); $richiesta["controllo"] = "F"; $richiesta["busta"] = "amministrativa"; $this->saveRichiesta($richiesta); } } public function deleteDGUERequest() { if (!$this->checkLock("buste")) { $this->db->go("DELETE FROM b_concorsi_richieste WHERE titolo = 'DGUE' AND codice_round = :codice_round AND busta = 'amministrativa'", [":codice_round" => $this->round["codice"]]); } } public function getDomandeElaborazione() { global $config; $tmp = jsonToArray($config["jsonFolder"]."/concorsi-elaborazione.json"); $return = []; $multiLotto = (count($this->getLotti()) > 1); 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 (($multiLotto && !$domanda["multi_lotto"]) || (!$multiLotto && !$domanda["mono_lotto"])) { $insert = false; } if ($insert) { $return[$key] = $domanda; } } } } return $return; } public function getManagerRichieste() { $manager = new richiesteOE("concorsi", $this->info["codice"], $this->lotto["codice"]); if (!empty($manager)) { $this->managerRichieste = $manager; } return $this->managerRichieste; } public function getManagerPubblicita() { $manager = new pubblicitaLegale("concorsi", $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_concorsi_chiarimenti.* FROM b_concorsi_chiarimenti WHERE b_concorsi_chiarimenti.codice_round = :codice_round "; if (!empty($codice)) { $sql_chiarimenti .= " AND b_concorsi_chiarimenti.codice = :codice "; $bind[":codice"] = $codice; } $sql_chiarimenti .= " ORDER BY b_concorsi_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"]); $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_concorsi_sopralluogo.* FROM b_concorsi_sopralluogo WHERE b_concorsi_sopralluogo.codice_round = :codice_round "; if (!empty($codice)) { $sql_sopralluoghi .= " AND b_concorsi_sopralluogo.codice = :codice "; $bind[":codice"] = $codice; } $sql_sopralluoghi .= " ORDER BY b_concorsi_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"]; $return[] = $t; } } if (!empty($codice) && !empty($return)) { $return = $return[0]; } return $return; } 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_concorsi.* FROM r_raggruppamenti_concorsi JOIN r_partecipanti_concorsi ON r_raggruppamenti_concorsi.codice_padre = r_partecipanti_concorsi.codice WHERE r_partecipanti_concorsi.codice_round = :codice_round AND r_partecipanti_concorsi.codice = :codice_partecipante AND codice_lotto = :codice_lotto"; return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC); } } 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_concorsi.* FROM r_avvalimenti_concorsi JOIN r_partecipanti_concorsi ON r_avvalimenti_concorsi.codice_padre = r_partecipanti_concorsi.codice WHERE r_avvalimenti_concorsi.codice_round = :codice_round AND r_partecipanti_concorsi.codice = :codice_partecipante AND codice_lotto = :codice_lotto"; return $this->db->go($sql, $bind)->fetchAll(PDO::FETCH_ASSOC); } } 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_concorsi WHERE codice_round = :codice_round AND codice_lotto = :codice_lotto "; if (empty($all)) { $filters["conferma"] = "S"; } $where = []; $keys = array_keys(get_campi("r_partecipanti_concorsi")); 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 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)) { $tmp = $return; $return = []; $richieste = $this->getRichieste("tecnica"); if (!empty($richieste)) { foreach($tmp AS $partecipante) { foreach($richieste AS $richiesta) { $busta = $this->getBusta($partecipante["codice"],$richiesta["codice"]); if (!empty($busta) && $busta["open"] == "S") { $return[] = $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 getBusta($partecipante, $richiesta, $aggiuntive = false, bool $contenuto = false) { $return = false; $select = "*"; if (!$aggiuntive) { $sql = "SELECT {$select} FROM b_concorsi_buste WHERE codice_partecipante = :partecipante AND codice_richiesta = :richiesta "; } else { $sql = "SELECT {$select} FROM b_concorsi_buste_aggiuntive 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->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}/concorsi-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 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("concorsi", $this->info["codice"]); if (empty($relazioni)) { $concorso = []; $concorso["codice"] = 0; $concorso["smart_cig"] = $smart_cig; $concorso["oggetto"] = $record["oggetto"]; $concorso["anno_riferimento"] = date("Y"); $concorso["codice_ente"] = $record["codice_ente"]; $concorso["codice_gestore"] = $_SESSION["ente"]->codice; $concorso["dati"]["cf_sua"] = $beneficiario["cf"]; $concorso["dati"]["denominazione_sua"] = $beneficiario["denominazione"]; $concorso["dati"]["categorie_merc"] = [999]; if ($smart_cig == "N") { $concorso["dati"]["importo"] = $record["prezzoRiferimento"]; $concorso["dati"]["numero_lotti"] = count($lotti); $concorso["dati"]["tipo_scheda"] = ""; $concorso["dati"]["modo_indizione"] = ""; $concorso["dati"]["allegato_ix"] = ""; $concorso["dati"]["modo_realizzazione"] = ""; $concorso["dati"]["motivo_rich_cig"] = ""; $concorso["dati"]["cig_acc_quadro"] = ""; $concorso["dati"]["durata_accquadro_convenzione_concorso"] = ""; $concorso["dati"]["escluso_avcpass"] = ""; $concorso["dati"]["urgenza_dl133"] = ""; $concorso["dati"]["estrema_urgenza"] = ""; $concorso["dati"]["strumento_svolgimento"] = ""; $concorso["dati"]["id_f_delegate"] = ""; $concorso["dati"]["cf_amm_agente_concorso"] = ""; } else { $lottoDB = $lotti[0]; $concorso["lotto"]["id_scelta_contraente"] = 1; $concorso["lotto"]["cig"] = $lottoDB["cig"]; $concorso["lotto"]["importo"] = $record["prezzoRiferimento"]; $concorso["dati"]["codiceClassificazioneconcorso"] = ""; $concorso["dati"]["codiceFattispecieContrattuale"] = ""; $concorso["dati"]["cigAccordoQuadro"] = ""; $concorso["cup"] = $lottoDB["cup"]; $concorso["dati"]["motivo_rich_cig_catmerc"] = ""; } $anac = new anac(); $anac->modulo = "concorsi"; $esito_concorso = $anac->saveGara($concorso); if ($esito_concorso["esito"] === true) { $return["codice_concorso_simog"] = $esito_concorso["codice"]; $creazione = true; $anac = anac::init($esito_concorso["codice"]); if ($smart_cig == "S") { $relazione = $anac->saveRelazione("concorsi", $record["codice"], $lottoDB["codice"], $anac->getLotti()[0]["codice"]); if (empty($relazione)) { $this->db->go("DELETE FROM b_simog WHERE codice = :codice", [":codice" => $esito_concorso["codice"]]); $return["errore_lotto"] = true; } } } else { $return["msg"] = ""; if (!empty($esito_concorso["errori"])) { $return["msg"] = implode("
", $esito_concorso["errori"]); } } } else { $relazioni = reset($relazioni); $return["codice_concorso_simog"] = $relazioni["gara_simog"]; $anac = anac::init($return["codice_concorso_simog"]); } if (!empty($anac->info) && $anac->info["smart_cig"] == "N") { foreach ($lotti as $lottoDB) { $relazioni = anac::relazioniModulo("concorsi", $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["cpv"] = [$lottoDB["cpv"]]; $lotto["id_scelta_contraente"] = 1; $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("concorsi", $record["codice"], $lottoDB["codice"], $esito_lotto["codice"]); if (empty($relazione) && !empty($creazione)) { $this->db->go("DELETE FROM b_simog WHERE codice = :codice", [":codice" => $esito_concorso["codice"]]); $return["errore_lotto"] = true; } } else { $return["msg"] = ""; $return["errore_lotto"] = true; if (!empty($esito_lotto["errori"])) { $return["msg"] = implode("
", $esito_lotto["errori"]); } } } } } return $return; } 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_concorsi 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 getSedute($codice = null) { $bind = [":round" => $this->round["codice"]]; $sql = "SELECT * FROM b_concorsi_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); if ($partecipante["flagEncrypted"] == "N") { $list_partecipanti = $partecipante["ragione_sociale"] . " - " . $partecipante["codice_fiscale"]; $raggruppamento = $this->getRaggruppamento($partecipante["codice"]); if (!empty($raggruppamento)) { $list_partecipanti = "RAGGRUPPAMENTO
" . $list_partecipanti . " - 04-CAPOGRUPPO"; foreach ($raggruppamento as $membro) { $list_partecipanti .= "
" . $membro["ragione_sociale"] . " - " . $membro["codice_fiscale_impresa"] . " - " . $membro["ruolo"]; } } $avvalimento = $this->getAvvalimento($partecipante["codice"]); if (!empty($raggruppamento)) { $list_partecipanti = "AVVALIMENTO
" . $list_partecipanti . " - 04-CAPOGRUPPO"; foreach ($raggruppamento as $membro) { $list_partecipanti .= "
" . $membro["ragione_sociale"] . " - " . $membro["codice_fiscale_impresa"] . " - " . $membro["ruolo"]; } } return $list_partecipanti; } } 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("concorsi", $this->info["codice"], "seduta", $round["codice"]); if (!empty($tmp)) { $conference = array_merge($conference, $tmp); } $seggio = new Commissione("concorsi", $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("concorsi", $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) { global $config; $moduli = jsonToArray($config["jsonFolder"] . "/concorsi-panel.json"); $tmp = []; foreach ($moduli as $id_modulo => $modulo) { $insert = true; if (is_array($filters) && !empty($filters)) { foreach ($filters as $key => $value) { if (isset($modulo[$key])) { if ($key == "lastRound") { if (!$value && $modulo[$key]) { $insert = false; } } else { if ($modulo[$key] !== $value) { $insert = false; } } } } } if ($insert && $modulo["faseAttiva"] && !empty($filters)) { $insert = $filters["fase_attiva"] >= $filters["fase_selezionata"]; } 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("concorsi", $this->lotto["codice"]); } public function getPublicExternalURL() { return "https://{$_SESSION["ente"]->getInfo()["dominio"]}/concorsi/dettaglio.php?codice={$this->info["codice"]}"; } public function getPubblicazioniGUUE() { global $beRoot; include_once($beRoot."/guue/class/TedEsender.class.php"); return TedEsender::getPubblicazioniFromModulo("concorsi", $this->info["codice"]); } public function getStatoPannello() { $statoMax = $this->info["stato"]; $statoMin = null; if ($this->activeRound) { $lotti = $this->getLotti(); foreach($lotti AS $lotto) { if (count($lotti) === 1 || ($lotto["stato"] != 95 && $lotto["stato"] != 99)) 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"]; } } return ["min"=>$statoMin,"max"=>$statoMax]; } public function getModelli($codice = null) { $statoMax = $this->getStatoPannello()["max"]; $bind = [":fase"=>$statoMax]; $sql = "SELECT * FROM b_impostazioni_modelli_concorso WHERE attivo = 'S' AND soft_delete = 'N' AND fase_minima <= :fase"; if (!empty($codice)) { $bind[":codice"] = $codice; $sql .= " AND codice = :codice"; } $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 "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; } /** * Get the current bidding threshold. * * @return ?string */ function getSogliaConcorso() : ?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]; $prezzo = $this->info["prezzoRiferimento"]; if($tipologia_ente["centrale"] == "S") { if($prezzo >= 143000.00) { $soglia = "soprasoglia"; } } else { if($prezzo >= 221000.00) { $soglia = "soprasoglia"; } } return $soglia; } /** * 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" => "concorsi"]; $fascicolo = $this->db->go($sql, $bind)->fetch(PDO::FETCH_ASSOC); if(! empty($fascicolo["codice"])) { $this->npa = NuovaPiattaformaAppalti::init($fascicolo["codice"], null, null, "concorsi", $this->info["codice"]); return $this->npa; } return null; } public function getRup() : ?Array { $incaricati = $this->getManagerIncarichi()->getIncaricati(); $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)) { $soglia = $this->getSogliaConcorso(); $schede = $npa->getCardsAndItsDescendantsList("ordinario", $soglia, null, true); 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(); $soglia = $this->getSogliaConcorso(); return NuovaPiattaformaAppalti::getInitialCards("concorsi", null, null, "ordinario", $soglia); } public function getPublicIdentifier() : string { return generatePublicIdentifier("C", $this->info["codice_ente"], $this->info["codice"]); } /** * 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_concorsi_lotti SET cig = :cig WHERE codice = :codice", [":codice" => $codice, ":cig" => $cig]); } 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() { if($this->checkLock("lotti")) return false; $npa = $this->getNpaInstance(); if($npa !== null) return empty($npa->fascicolo["id_appalto"]) && empty($npa->fascicolo["id_pianificazione"]); return true; } function getEnteBeneficiario() : ?Array { if(! empty($this->info) && ! empty($this->info["codice_ente"])) { $tmp = Ente::getInfoFromID($this->info["codice_ente"]); if(! empty($tmp)) { $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"]]; } } } return null; } }