You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

276 lines
8.5 KiB

<?php
class RegleExpert {
//********************************************************************************************
//
// VARIABLES
//
//********************************************************************************************/
// Oid de la règle
private $oid;
// Oid du contrôle auquel appartient la règle
private $controle_id;
// Conditions de sélection de la règle (Clause WHERE de la requête)
private $sqlcmd_where;
// Liste de champs à retourner en guise de justificatif (séparée par une virgule, un espace, une barre verticale,...)
private $sqlcmd_justificatif;
// Numéro d'ordre de la règle dans le contrôle
private $numero;
// Oid de la table sur laquelle va être exécutée la règle
private $table_id;
// Table sur laquelle va être exécutée la règle
private $table;
// Connexion à la base de données iCTI
private $database;
// Message d'erreur alimenté en cas d'erreur, justement
private $error;
// Tableau de résultats de la rèle (voir ControleExpert->aggregate_retults() pour détails)
private $results;
// Date de sortie des séjours à partir de laquelle on peut lancer les contrôles expert
private $expert_date_debut;
// Etat des dossiers ciblés 0:Tous, 1:Présents, 2:Non facturés, ...
private $etat_cible;
//********************************************************************************************
//
// PUBLIC FUNCTIONS
//
//********************************************************************************************/
function __construct() {
// Initialisation des paramètres
$this->oid = -1;
$this->controle_id = -1;
$this->sqlcmd_where = '';
$this->sqlcmd_justificatif = '';
$this->numero = 0;
$this->table_id = -1;
$this->table = array();
$this->database = null;
$this->error = '';
$this->results = array();
$this->expert_date_debut = '';
$this->etat_cible = array();
}
public function __set($property, $value) {
if (property_exists($this, $property)) {
$this->$property = $value;
}
return $this;
}
public function __get($property) {
if (property_exists($this, $property)) {
return $this->$property;
}
}
/**
* Exécute la règle expert
*
* Deux tableaux seront générés pour chaque ligne (séjour) retournée : un pour les informations fixes et un pour les
* justiicatigs de la règle. Ces tableaux sont ajoutés au tableau $results[sejour_id]
*/
public function run() {
$succes = false;
// Vérifie l'existance des justificatifs dans la table à interroger et ajoute les champs à sélectionner d'office
$what = $this->what_to_select();
// Met en forme le where de la requete de sélection
$where_conditions = $this->which_conditions($this->table['fictive']);
if (strlen($what) > 0 || $this->table['fictive'] == true) {
// Construit et exécute prprement dit la requête de la règle
if ($this->table['fictive'] == true) {
$request = $this->sqlcmd_where . $where_conditions . ";";
}
else {
$request = "SELECT " . $what . " FROM " . $this->table['from'] . $where_conditions . ";";
}
// file_put_contents('yep.txt', $request . PHP_EOL , FILE_APPEND);
$result = $this->database->exec($request);
if ($result === false) {
// N'écrase pas une erreur déjà explicitée par les sous-fonctions
if (strlen($this->error) == 0) {
$this->error = "Erreur pendant l'exécution de la règle n°" . $this->numero . " : requête erronée." . PHP_EOL;
}
}
else {
while ($row = pg_fetch_array($result)) {
$i = pg_num_fields($result);
// Tableau des justificatifs demandés
$justificatifs = array();
// Tableau des infos fixes
$infos = array();
for ($j = 0; $j < $i; $j++) {
// Si le champ retourné fait partie des justificatifs, on le stocke daans le tableau $justificatifs
// Si non dans le tablau des infos
$field_name = pg_field_name($result, $j);
if (stripos($this->sqlcmd_justificatif, $field_name) === false) {
$infos[$field_name] = $row[$j];
}
else {
$justificatifs[$field_name] = $row[$j];
}
}
// Stocke les infos et les justificatifs dans les réultats du séjour
$this->results[$row['sejour_id']]['infos'] = $infos;
$this->results[$row['sejour_id']]['justificatifs'] = $justificatifs;
}
$succes = true;
}
}
else {
$this->error .= "Règle" . $this->numero . " ignorée, justificatif non traité." . PHP_EOL;
}
return $succes;
}
//********************************************************************************************
//
// PRIVATE FUNCTIONS
//
//********************************************************************************************/
/**
* $this->sqlcmd_justificatif représente une suite de champs à retourner comme justificatif du contrôle.
* Ces champs peuvent être délimités par un espace (\s) ou les caractètres ,;:|
*
* On cherche l'existance de chacun de ces champs dans la table $table sur laquelle est exécutée la règle et
* on les concatène dans une chaîne de caractère séparée par des virgules.
* Cette fonction permet donc de valider l'existance des champs à retourner et les met en forme
*/
private function what_to_select() {
$rets = array();
// Par défaut, on va toujours récupérer les chaps définis dans la variable $this->table['defaults']
foreach($this->table['defaults'] as $default) {
$rets[] = $default;
}
// Les champs de la variable $this->sqlcmd_justificati peuvent être séparés par un espace, une virgule, un point-virgule, deux-points ou une barre verticale
$fields = preg_split("/[\s,;:\|]+/", $this->sqlcmd_justificatif);
foreach($fields as $field) {
// Si le champ à retourner existe ben en base (= dans la propritété 'fields' de $this->table), on l'ajoute à la liste des champs à retourner
if (in_array($field, $this->table['fields'])) {
$rets[] = $this->table['name'] . '.' . $field;
}
}
return implode(', ', $rets);
}
/**
* Construit le filtre de la requête de sélection du contrôle expert
* Notez que les règles ne s'éxécutent pas sur les séjours prévus
*/
private function which_conditions($sql_brut=false) {
$partie_fixe = " AND date_sortie >= '" . $this->expert_date_debut . "'::date " .
$this->etat_cible['where'] .
" AND code_prevu <> '1' " .
" AND type_sejour <> '9' ";
if (strlen($this->sqlcmd_where) == 0) {
return '';
}
else if ($sql_brut == true) {
return $partie_fixe;
}
else {
return " WHERE 1=1 AND (" . $this->explicit_where($this->sqlcmd_where) . ") " . $partie_fixe;
}
}
/**
* Analyse le WHERE de la requête de sélection de la règle et tente de remplacer les éventuels TAGS
*
* [LI:xxxx] : remplace ce tag par la liste des oids pointés par la liste xxxx
*
* @param $where Chaîne de caractère à analyser
*/
private function explicit_where($where) {
// Recherche toutes les occurences du pattern suivant [LI:xxxx] où xxxx est le code de la liste concernée
// Les résultats sont stockés dans le tableau $listes.
// $listes
// [0] =>
// [0] => [LI:zzzz]
// [1] => zzzz
// [1] =>
// [0] => [LI:yyyy]
// [1] => yyyy
// quelques tags intéressants pour les regexp : http://fr2.php.net/manual/fr/function.preg-match.php#105924
$listes = array();
if (preg_match_all('/\[LI:([^\]]*)\]/', $where, $listes, PREG_SET_ORDER) > 0) {
foreach($listes as $liste) {
$oids = ' (' . $this->get_liste_oids(trim($liste[1])) . ') ';
$where = str_replace($liste[0], $oids, $where);
}
}
return $where;
}
/**
* Cherche le contenu de la liste $liste et renvoie la liste des oids pointés par la liste de code $liste
*
* @param $liste Code de la liste dont il faut récupérer les oids
* @return Chaîne de caractère des oids séparés par des virgules, exemple : 'oid1, oid2, oid3'
*/
private function get_liste_oids($liste) {
$oids = array();
$request = "SELECT to_id
FROM activite.t_listes JOIN activite.t_listes_contenu ON t_listes_contenu.liste_id = t_listes.oid
WHERE t_listes.code = '" . $liste. "' ;";
$result = $this->database->exec($request);
if ($result === false) {
$this->error .= "Erreur pendant l'exécution de la règle n°" . $this->numero . " : Impossible de récupérer les données de la liste " . $liste . "." . PHP_EOL;
}
else {
if (pg_num_rows($result) < 1) {
$this->error .= "Erreur pendant l'exécution de la règle n°" . $this->numero . " : Liste '" . $liste . "' vide ou inexisante." . PHP_EOL;
}
while ($row = $this->database->nextRecord($result)) {
$oids[] = $row[0];
}
}
return implode(', ', $oids);
}
}
?>