<?php

require_once dirname(__FILE__) . '/../../../../base/lib/ICTIDB.class.php';
require_once dirname(__FILE__) . '/../../../../base/php/lib/cti/Environnement/Environnement.class.php';
require_once dirname(__FILE__) . '/../../../../base/php/Amfphp/src/com/ctisante/vo/PmsiMat2aImport.php';

// Classe PHP qui décrit un objet import mat2a
class CtiPmsiImportService {
	
	// Emplacement de stockage des fichiers mat2a
	private static $MAT2A_FILES_DIRECTORY;
	// Emplacement temporaire pour stockage temporaire justement
	private static $TMP_DIR;
	
	// tableau stockant les prestations (code, quantite, br, amo)
	private $_prestations;
	
	// tableau stockant le case-mix GHS. Une ligne par couple GHS-GHM
	private $_casemix_ghs;
	
	// tableau stockant les LPP (code, quantite, dépenses, dépenses autorisées, dépenses accordées)
	private $_lpp;

	// tableau stockant les UCD (code, quantite, dépenses, dépenses autorisées, dépenses accordées)
	private $_ucd;

	// tableau stockant le casemix des séjours supprimés Hors problème de tarif
	private $_rsfsupp;
    
	private $_debug = false;

	public function __construct(){
		self::$MAT2A_FILES_DIRECTORY = dirname(__FILE__) . '/../../../mat2a_files/';
		self::$TMP_DIR = dirname(__FILE__) . '/../../../../../temp/';
	}
		
	/**
	 * Vérifie si l'extension pdo_pgsql utilisée dans la classe ICTIDB.class est bien chargée par PHP.
	 */
	public function checkPhpConfig() {
		$result = 'KO';
		if (extension_loaded('pdo_pgsql')) {	// Nom interne de l'extension
			$result = 'OK';
		}
		return $result;
	}
	
	
	public function getMat2aImports() {
        
        // Vérifie l'existance du répertoire de stockage des fichiers OVALIDE
        if (!is_dir(self::$MAT2A_FILES_DIRECTORY)) {
            mkdir(self::$MAT2A_FILES_DIRECTORY);
        }
    
		$ret = array();
		try {
			$con = ICTIDB::getInstance();
			$con->beginTransaction();
            $finess = Environnement::getInstance()->getFiness();
			$sql = "
				SELECT
					p_mat2a_import.sha1,
					p_mat2a_import.oid,
					p_mat2a_import.fichier,
					to_char(p_mat2a_import.date, 'YYYY/MM/DD') AS date,
					to_char(p_mat2a_import.mat2a_date, 'YYYY/MM/DD') AS mat2a_date,
					p_mat2a_import.mat2a_annee,
					p_mat2a_import.mat2a_mois,
					COALESCE(p_mat2a_import.mat2a_rsa_transmis, 0) as mat2a_rsa_transmis, 
					COALESCE(p_mat2a_import.mat2a_rsa_traites, 0) as mat2a_rsa_traites, 
					COALESCE(p_mat2a_import.mat2a_rsa_seances, 0) as mat2a_rsa_seances, 
					COALESCE(p_mat2a_import.mat2a_rsa_0_nuits, 0) as mat2a_rsa_0_nuits, 
					COALESCE(p_mat2a_import.mat2a_rsa_prestations_nb_total, 0) as mat2a_rsa_prestations_nb_total, 
					round(COALESCE(p_mat2a_import.mat2a_rsa_prestations_base_remb, 0)) as mat2a_rsa_prestations_base_remb,
					COALESCE(p_mat2a_import.mat2a_nb_sejours_valorises, 0) as mat2a_nb_sejours_valorises,
					round(COALESCE(p_mat2a_import.mat2a_br_sejours_valorises, 0)) as mat2a_br_sejours_valorises,
					CASE WHEN length(p_mat2a_file.data) > 0 THEN '$finess'::text || '.'::text || p_mat2a_import.mat2a_annee::text || '.'::text || p_mat2a_import.mat2a_mois::text || '.'::text || to_char(p_mat2a_import.mat2a_date, 'DDMMYYYY') || '.OVALIDE.'::text || p_mat2a_import.oid::text ELSE ''::text END as filename,
					p_mat2a_file.data as mat2a_data,
					COALESCE(length(p_mat2a_file.data), 0) as mat2a_data_length
				FROM pmsi.p_mat2a_import
					LEFT JOIN pmsi.p_mat2a_file ON p_mat2a_file.mat2a_import_id = p_mat2a_import.oid
				ORDER BY 2 DESC
				;	
			";
			foreach ($con->query($sql, PDO::FETCH_ASSOC) as $row) {
				$import = new PmsiMat2aImport();
				
				$import->sha1 = $row['sha1'];
				$import->fichier = $row['fichier'];
				$import->oid = $row['oid'];
				$import->date_text = $row['date'];
				$import->mat2a_annee = $row['mat2a_annee'];
				$import->mat2a_mois = $row['mat2a_mois'];
				$import->mat2a_date_text = $row['mat2a_date'];
				$import->mat2a_rsa_transmis = $row['mat2a_rsa_transmis'];
				$import->mat2a_rsa_traites = $row['mat2a_rsa_traites'];
				$import->mat2a_rsa_seances = $row['mat2a_rsa_seances'];
				$import->mat2a_rsa_0_nuits = $row['mat2a_rsa_0_nuits'];
				$import->mat2a_rsa_prestations_nb_total = $row['mat2a_rsa_prestations_nb_total'];
				$import->mat2a_rsa_prestations_base_remb = $row['mat2a_rsa_prestations_base_remb'];
				$import->mat2a_nb_sejours_valorises = $row['mat2a_nb_sejours_valorises'];
				$import->mat2a_br_sejours_valorises = $row['mat2a_br_sejours_valorises'];
				
				// Ecriture des fichiers dans le répertoire de dépot des ficheirs Mat2a
				$mat2a_file_path = self::$MAT2A_FILES_DIRECTORY . $import->sha1;
				if (is_writable(self::$MAT2A_FILES_DIRECTORY)) {
					file_put_contents($mat2a_file_path, $row['mat2a_data']);
				}
				$import->mat2a_filename = (is_readable($mat2a_file_path)) ? $row['filename'] : ''; // nom du fichier
                $env = array_pop(split('/', Environnement::getInstance()->getRootPath()));
				$import->mat2a_filepath = (is_readable($mat2a_file_path)) ? 'http://' . $_SERVER['HTTP_HOST'] . '/' . $env . '/modules/pmsi/mat2a_files/' . $import->sha1  : ''; // URL d'accès au fichier
				
				$ret[] = $import;
				
			}
			$con->commit();
		} catch (Exception $e) {
			
		}
		$this->cleanUpFiles();
		return $ret;
	}
	
	
	/**
	 * Fonction qui va supprimer tous les fichiers présents dans le répertoire de stockage des fichiers Mat2a/OVALIDE ($MAT2A_FILES_DIRECTORY)
	 * qui ne font référence à aucun import Mat2A/OVALIDE.
	 * 
	 * On récupère d'abord tous les sha1 des imports mat2a/OVALIDE présents en base.
	 * Ensuite, pour chaque fichier présent dans le répertoire de stockage, on regarde si son nom apparait dans la liste des sha1 précédemment récupérée.
	 * Si le nom du fichier n'apparait pas dans la liste des sha1, on efface le fichier.
	 *
	 * @param $force Force la suppression de tous les fichiers du répertoire $MAT2A_FILES_DIRECTORY
	 */
	private function cleanUpFiles($force=false) {
		$ret = 'OK';
		try {
			$con = ICTIDB::getInstance();
			$con->beginTransaction();
			$sql = " SELECT sha1 FROM pmsi.p_mat2a_import";
			$sha1 = array();
			
			// Liste tous les sha1 des fichiers Mat2a/OVALIDE déjà importés
			foreach ($con->query($sql, PDO::FETCH_ASSOC) as $row) {
				$sha1[] = $row['sha1'];
			}
			$con->commit();
			
			// Liste tous les fichiers présents dans le répertoire de stockage temporaire des fichiers MAT2A/OVALIDE
			if (is_readable(self::$MAT2A_FILES_DIRECTORY)) {
				$rep = opendir(self::$MAT2A_FILES_DIRECTORY);
				if ($rep > 0) {
					while ($file = readdir($rep)) {
						if($file != '..' && $file != '.' && $file != '' && substr($file, 0, 1) != '.') {
							if(!in_array($file, $sha1) || $force == true) {
								$dstFilePath = self::$MAT2A_FILES_DIRECTORY . $file;
								unlink($dstFilePath);
							}
						}
					}
				}
				closedir($rep);
			}
		} catch (Exception $e) {
			$ret = 'Impossible de nettoyer le répertoire de stockage des fichiers Mat2a/OVALIDE';
		}
		return $ret;
	}
	
	
	/**
	 * Supprime l'import dont l'oid est passé en paramètre :
	 * _ Efface l'entrée dans la table pmsi.p_mat2a_import
	 * _ Efface le fichier stocké dans le répertoire mat2a_files du module pmsi (le fichier en question est nommé
	 *   avec le sha1 du zip utilisé pour l'import
	 * _ Efface le casemix GHM de cet import si la table w_mat2a_dgf_casemix existe
	 *
	 * @param	$import_id	Oid de l'import à effacer
	 * @return	'OK' si tout s'est bien passé, un message d'erreur si non
	 */
	public function deleteImport($import_id) {
		$ret = 'OK';
		try {
			$con = ICTIDB::getInstance();
			$con->beginTransaction();
			$sql = " SELECT sha1 FROM pmsi.p_mat2a_import WHERE oid = $import_id; ";
			
			foreach ($con->query($sql, PDO::FETCH_ASSOC) as $row) {
				$sha1 = $row['sha1'];
				$sql = " DELETE FROM pmsi.p_mat2a_import WHERE oid = $import_id; ";
				$con->exec($sql);
				
				$sql = " DELETE FROM pmsi.p_mat2a_data WHERE mat2a_import_id NOT IN (SELECT oid FROM pmsi.p_mat2a_import); ";
				$con->exec($sql);
				$sql = " ANALYSE pmsi.p_mat2a_data";
				$con->exec($sql);
				
				$sql = " SELECT * FROM information_schema.tables WHERE table_name= 'w_mat2a_dgf_casemix' AND table_schema = 'pmsi'; ";
				$res = $con->query($sql);
				if ($res->rowCount() > 0) {
					$sql = " DELETE FROM pmsi.w_mat2a_dgf_casemix WHERE mat2a_id = $import_id; ";
					$con->exec($sql);
				}
				
				$dstFilePath = self::$MAT2A_FILES_DIRECTORY . $sha1;
				if (file_exists($dstFilePath)) {
					unlink($dstFilePath);
				}
			}
			$con->commit();
		} catch (Exception $e) {
			$ret = 'Erreur dans les requêtes SQL ' . $e->getMessage();
		}
		return $ret;
	}
	
	/**
	 * Traite le fichier ZIP mat2a/ovalide pour en extraire les infos qui vont bien
	 *
	 * @param $fileData Nom du fichier zip
	 * @param $fileData Données du fichier zip
	 * @param $typeEts	Type d'établissement. 1 : privé, autre : public
	 */
	public function uploadFile($fileName, $fileData, $typeEts) {
		
		// Tableau à retourner
		$ret = array();
		
		$tmpFilePath = self::$TMP_DIR . preg_replace("/[^0-9]+/", "_", microtime()) . '_' . $fileName;
		
		$uncompressedData = false;
		if (isset($fileData->data)){
			$uncompressedData = gzuncompress($fileData->data);
		}
		// Enregistrer le fichier dans le dossier temporaire
		if($uncompressedData){
			file_put_contents($tmpFilePath, $uncompressedData);
		} else {
			move_uploaded_file($fileData["tmp_name"], $tmpFilePath);
		}
		$tmpFilePath = realpath($tmpFilePath);
		
		
		$submitCmd = realpath(dirname(__FILE__) . "/../../../../pmsi/import_rss_rsf/iCTI_import_mat2a.exe") . " -fs \"$tmpFilePath\" -fd \"$fileName\"";
		$return = exec($submitCmd);
		
		@unlink($tmpFilePath);
		
		
		return $ret;
	}
	
	public function downloadImport($import_id) {
		
		$con = ICTIDB::getInstance();
		$ok_import = FALSE;
		$temp = tmpfile();
		$metaDatas = stream_get_meta_data($temp);
		$tmpFilename = $metaDatas['uri'];
		$this->debug($tmpFilename);
		$sql = "SELECT file_path FROM pmsi.p_mat2a_file WHERE mat2a_import_id = $import_id";
		$this->debug($sql);
		foreach ($con->query($sql, PDO::FETCH_ASSOC) as $row) {
			$file_path = $row['file_path'];
			$ok_import = TRUE;
			$this->debug($file_path);
		}
		
		if ($ok_import == TRUE) {
			$sql = "SELECT data as truc FROM pmsi.p_mat2a_file WHERE mat2a_import_id = $import_id ORDER by data_num  ";
			$this->debug($sql);
			
			foreach ($con->query($sql, PDO::FETCH_ASSOC) as $row) {
				$yep = $row['truc'];
				$this->debug($yep);
				file_put_contents($tmpFilename, $yep, FILE_APPEND);
			}
		}
		copy($tmpFilename, "C:/temp/" . $file_path);
		
		// return $temp;
		return 'pipo';
	}
	
	private function debug($msg) {
        if ($_debug == true) {
            file_put_contents('yep.txt', PHP_EOL . date('Y-m-d H:i:s') . "\t\t" . $msg, FILE_APPEND);
        }
	}
	/**
	 * Traite le fichier ZIP mat2a/ovalide pour en extraire les infos qui vont bien
	 *
	 * @param $fileData Nom du fichier zip
	 * @param $fileData Données du fichier zip
	 * @param $typeEts	Type d'établissement. 1 : privé, autre : public
	 */
	public function uploadFileX($fileName, $fileData, $typeEts) {
		
		// Tableau à retourner
		$ret = array();
		// Fichiers dans le ZIP
		$mat2a_files = array();
		
		// Connexion à la base SQL
		$con = ICTIDB::getInstance();
		
		$tmpFilePath = self::$TMP_DIR . preg_replace("/[^0-9]+/", "_", microtime()) . '_' . $fileName;
		
		file_put_contents($tmpFilePath, gzuncompress($fileData->data));
		
		$sha1 = sha1_file($tmpFilePath);
		if (!is_dir(self::$MAT2A_FILES_DIRECTORY)) {
			mkdir(self::$MAT2A_FILES_DIRECTORY);
		}
		$dstFilePath = self::$MAT2A_FILES_DIRECTORY . $sha1;
		
		if (file_exists($dstFilePath)) {
			unlink($tmpFilePath);
			$ret[] = "false";
			$ret[] = "Fichier \"$fileName\" déjà importé.";
		} 
		else {
			// Stocker le fichier dans son emplacement définitif.
			rename($tmpFilePath, $dstFilePath);
			
			// Initialisation des différents champs
			$mat2a_rsa_transmis = 0;
			$mat2a_rsa_traites = 0;
			$mat2a_rsa_seances = 0;
			$mat2a_rsa_0_nuits = 0;
			$mat2a_nb_sejours_valorises = 0;
			$mat2a_br_sejours_valorises = 0;
			$mat2a_rsa_prestations_nb_total = 0;
			$mat2a_rsa_prestations_base_remb = 0;
			
			// Analyser le fichier
			$check_code = 0;
			$mahosYearOk = false;
			
			// L'utilisation de la classe ZipArchive permet d'avoir simplement le nombre d'entrées dans le zip.
			// Une évolution du programme pourrait être de n'utiliser QUE cette classe pour parcourir tous les tableaux du ZIP
			// plutôt que de réouvrir le zip une deuxième fois
			$zap = new ZipArchive();
			$zap->open(realpath($dstFilePath));
			$nbTableaux = $zap->numFiles;
			$zap->close();
			
			$zip = zip_open(realpath($dstFilePath));
			if ($zip) {
				// Il existe deux versions des ZIP Mat2a/OVALIDE. Une avec un seul fichier html regroupant tous les tableaux
				// et une autre avec (en gros) un tableau par fichier HTML. On ne traite que la deuxième version
				if ($nbTableaux > 1) {
					while ($zip_entry = zip_read($zip)) {
						if (zip_entry_open($zip, $zip_entry)) {
							$filename = trim(zip_entry_name($zip_entry));
							
							$eFileName = explode('.', $filename);
							$tab_code = strtolower($eFileName[count($eFileName) - 2]);
							
							//  Stocker données sur disque pour import ultérieur
							$mat2aFilePath = realpath(self::$MAT2A_FILES_DIRECTORY) . "/$filename";
							$mat2aData = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
							file_put_contents($mat2aFilePath,$mat2aData);
							$mat2a_files[] = $mat2aFilePath;
							
							//	Etablissements privés
							//
							//	Version Mat2a (jusqu'à février 2013)
							//		Tableau 01A			--> RSA transmis, RSA traités, RSA séances, RSA 0 nuits
							//		Tableau 32			--> Nb RSA prestations, BR RSA prestations
							//
							// Version OVALIDE (à partir de mars 2013)
							//		Tableau t1d2rtp		--> RSA transmis, RSA séances, RSA 0 nuits
							//		Tableau t1v4synts	--> RSA traités
							//		Tableau t1v1cp		--> Nb RSA prestations, BR RSA prestations
							//							--> Tableau des prestations
							//		Tableau t1v1cmg		--> CaseMix GHS
							//		Tableau t1v3vdmi	--> Valorisation des LPP
							//		Tableau t1v2vmed	--> Valorisation des UCD
							//
							if ($typeEts == '1') {
								switch ($tab_code) {
									
									// ***********************  MAT2A ***********************
									
									case 't01' :
										
										$check_code += 1;
										
										$mat2a_annee = $eFileName[count($eFileName) - 4];
										$mat2a_mois = $eFileName[count($eFileName) - 3];
										
										// On traite les tableaux Mat2a à partir de 2012.
										if ((intval($mat2a_annee) >= 2012) || (intval($mat2a_annee) == 2013 && intval($mat2a_mois) < 3)) {
											
											$mahosYearOk = true;
											
											$tmpMat2aData = $this->traiterTableau($mat2aData);
											
											$mat2a_date = $tmpMat2aData[0]['mat2a_date'];
											
											$mat2a_rsa_transmis = $this->fix($tmpMat2aData[1][0][1][0][1]);
											$mat2a_rsa_traites = $this->fix($tmpMat2aData[1][0][1][1][1]);
											$mat2a_rsa_seances = $this->fix($tmpMat2aData[1][0][1][2][1]);
											$mat2a_rsa_0_nuits = $this->fix($tmpMat2aData[1][0][1][4][1]);
										}
										break;
										
									case 't32' : 
									
										// Prestations
										
										$check_code += 2;
										// Compatibilité avec ovalide privé où il y a un tableau en plus
										if ($check_code & 3 == 3) { $check_code += 4;}
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										$mat2a_rsa_prestations_nb_total = $this->fix($tmpMat2aData[1][1][0][0][14]);
										$mat2a_rsa_prestations_base_remb = $this->fix($tmpMat2aData[1][1][0][0][15]);
										// Change les virgules en points et non pas l'eau en vin (dommage...)
										$mat2a_rsa_prestations_base_remb = str_replace(',', '.', $mat2a_rsa_prestations_base_remb);	
										
										$_prestations = $this->traiterPrestations($tmpMat2aData, $mat2a_rsa_prestations_nb_total, $mat2a_rsa_prestations_base_remb);
										break;
									
									case 't33' : 
										
										// CaseMix GHS
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
											
											$_casemix_ghs = $this->traiterCaseMixGHS($tmpMat2aData);
										}
										break;
									
									case 't35' : 
										
										// LPP
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
											
											$_lpp = $this->traiterLPP($tmpMat2aData, $typeEts);
										}
										break;
									
									case 't36' : 
										
										// UCD
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
											
											$_ucd = $this->traiterUCD($tmpMat2aData);
										}
										break;
									
									// ***********************  OVALIDE ***********************
									
									case 't1d2rtp' :
										
										$check_code += 1;
										
										$mat2a_annee = $eFileName[count($eFileName) - 4];
										$mat2a_mois = $eFileName[count($eFileName) - 3];
										
										if (intval($mat2a_annee) >= 2013) {
										
											$mahosYearOk = true;
											
											$tmpMat2aData = $this->traiterTableau($mat2aData);
											
											$mat2a_date = $tmpMat2aData[0]['mat2a_date'];
											
											$mat2a_rsa_transmis = $this->fix($tmpMat2aData[1][0][1][0][1]);
											$mat2a_rsa_seances = $this->fix($tmpMat2aData[1][0][1][6][1]);
											$mat2a_rsa_0_nuits = $this->fix($tmpMat2aData[1][0][1][8][1]);
										}
										break;
										
									case 't1v4synts' :
									
										$check_code += 2;
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										$mat2a_rsa_traites = $this->fix($tmpMat2aData[1][0][1][8][1]);
										break;
										
									case 't1v1cp' :
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
											
											$check_code += 4;
											
											$mat2a_rsa_prestations_nb_total = $this->fix($tmpMat2aData[1][1][0][0][14]);
											$mat2a_rsa_prestations_base_remb = $this->fix($tmpMat2aData[1][1][0][0][15]);
											$mat2a_rsa_prestations_base_remb = str_replace(',', '.', $mat2a_rsa_prestations_base_remb);
											
											// Récupération des données du tableau des prestations
											$_prestations = $this->traiterPrestations($tmpMat2aData, $mat2a_rsa_prestations_nb_total, $mat2a_rsa_prestations_base_remb);
											
										}
										break;
										
									case 't1v1cmg' :
										
										// CaseMix GHS
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
											
											$_casemix_ghs = $this->traiterCaseMixGHS($tmpMat2aData);
										}
										break;
										
									case 't1v3vdmi' :
										
										// LPP
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
										
											$_lpp = $this->traiterLPP($tmpMat2aData, $typeEts);
										}
										break;
										
									case 't1v2vmed' :
										
										// UCD
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
											
											$_ucd = $this->traiterUCD($tmpMat2aData);
										}
										break;
										
									case 't1v1fsuphc' :
										
										// UCD
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
											
											$_rsfsupp = $this->traiterRSBSupp($tmpMat2aData);
										}
										break;
								}
							}
							//	Etablissements publics
							//
							//	Version Mat2a (jusqu'à février 2013)
							//		Tableau 01A			--> RSA transmis, RSA traités, RSA séances, RSA 0 nuits
							//		Tableau 34A			--> Nb Séjours valorisés, BR Séjours valorisés
							//
							// Version OVALIDE (à partir de mars 2013)
							//		Tableau t1d2rtp		--> RSA transmis, RSA séances, RSA 0 nuits
							//		Tableau t1v1sv		--> Effectifs et BR des séjours valorisés
							//
							else {
								switch ($tab_code) {
									
									// ***********************  MAT2A ***********************
								
									case 't01_stc' :
										
										$check_code += 1;
										
										$mat2a_annee = $eFileName[count($eFileName) - 4];
										$mat2a_mois = $eFileName[count($eFileName) - 3];
										
										// On traite les tableaux Mat2a à partir de 2012 et jusqu'à février 2013
										if ((intval($mat2a_annee) >= 2012) || (intval($mat2a_annee) == 2013 && intval($mat2a_mois) < 3)) {
											$mahosYearOk = true;
											$tmpMat2aData = $this->traiterTableau($mat2aData);
											
											$mat2a_date = $tmpMat2aData[0]['mat2a_date'];
											
											$mat2a_rsa_transmis = $this->fix($tmpMat2aData[1][0][1][0][1]);
											$mat2a_rsa_traites = $this->fix($tmpMat2aData[1][0][1][4][1]);
											$mat2a_rsa_seances = $this->fix($tmpMat2aData[1][0][1][5][1]);
											$mat2a_rsa_0_nuits = $this->fix($tmpMat2aData[1][0][1][7][1]);
										}
										break;
										
									case 't34_stc' :
										
										$check_code += 2;
										// Compatibilité avec ovalide privé où il y a un tableau en plus
										if ($check_code & 3 == 3) { $check_code += 4;}
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										$mat2a_nb_sejours_valorises = $this->fix($tmpMat2aData[1][0][1][10][1]);
										$mat2a_br_sejours_valorises = $this->fix($tmpMat2aData[1][0][1][10][2]);
										$mat2a_br_sejours_valorises = str_replace(',', '.', $mat2a_br_sejours_valorises);
										break;
										
									// Les tableaux t29_stc, t30_stc et t31_stc servent à générer le casemix-GHS
									
									case 't29_stc' :
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
											
											$check_code += 8;
											
											$casemix = array();
											$casemix = $tmpMat2aData[1][0][1];
											
											foreach ($casemix as $key => $row) {
											
												$ghs_code = $row[0];
												$ghm_code = substr(trim($row[1]), 0, 6);
												$a = $_casemix_ghs[$ghs_code . '|' . $ghm_code];
												if ($a == null) {
													$a = array();
												}
												if (intval($mat2a_annee) >= 2013) { 
													$a["eff"]         = $row[2];
													$a["nb_j"]        = $row[4];
													$a["nb_exb"]      = $row[5];
													$a["nb_rehosp"]   = $row[7];
													$a["nb_exh"]      = $row[8];
													$a["nbj_exh"]     = $row[10];
													$a["nb_dia"]      = $row[12];
													$a["nb_rdth"]     = $row[13];
													$a["nb_rdth_ped"] = $row[14];
													$a["nb_ant"]      = $row[15];
													$a["nb_9615"]     = $row[17];
													$a["nb_rea"]      = $row[18];
													$a["nb_rep"]      = $row[19];
													$a["nb_si"]       = $row[20];
													$a["nb_sc"]       = $row[21];
													$a["nb_nn1"]      = $row[22];
													$a["nb_nn2"]      = $row[23];
													$a["nb_nn3"]      = $row[24];
													$a["nb_po"]       = $row[25];
													$a["nb_hyp"]      = $row[26];
												}
												else {
													$a["eff"]         = $row[2];
													$a["nb_j"]        = $row[4];
													$a["nb_exb"]      = $row[5];
													$a["nb_rehosp"]   = $row[7];
													$a["nb_exh"]      = $row[8];
													$a["nbj_exh"]     = $row[10];
													$a["nb_dia"]      = $row[12];
													$a["nb_rdth"]     = $row[13];
													$a["nb_rdth_ped"] = $row[14];
													$a["nb_ant"]      = 0;
													$a["nb_9615"]     = $row[15];
													$a["nb_rea"]      = $row[16];
													$a["nb_rep"]      = $row[17];
													$a["nb_si"]       = $row[18];
													$a["nb_sc"]       = $row[19];
													$a["nb_nn1"]      = $row[20];
													$a["nb_nn2"]      = $row[21];
													$a["nb_nn3"]      = $row[22];
													$a["nb_po"]       = $row[23];
													$a["nb_hyp"]      = $row[24];
												}
												$_casemix_ghs[$ghs_code . '|' . $ghm_code] = $a;
											}
										}
										break;
										
									case 't30_stc' :
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
										
											$check_code += 16;
										
											$casemix = array();
											$casemix = $tmpMat2aData[1][0][1];
											
											foreach ($casemix as $key => $row) {
												$ghs_code = $row[0];
												$ghm_code = substr(trim($row[1]), 0, 6);
												// Normalement, le cmv est traité après le cmv et donc $_casemix_ghs[$ghs_code . '|' . $ghm_code] ne devrait jamais être null
												// mais on ne sait jamais...
												$a = $_casemix_ghs[$ghs_code . '|' . $ghm_code];
												if ($a == null) {
													$a = array();
												}
												if (intval($mat2a_annee) >= 2013) { 
													$a["mnt_ghs"]      = $row[5];
													$a["mnt_exb"]      = $row[6];
													$a["mnt_rehosp"]   = $row[8];
													$a["mnt_exh"]      = $row[9];
													$a["mnt_rdth"]     = $row[11];
													$a["mnt_rdth_ped"] = $row[12];
													$a["mnt_ant"]      = $row[13];
													$a["mnt_rea"]      = $row[14];
													$a["mnt_rep"]      = $row[15];
													$a["mnt_si"]       = $row[16];
													$a["mnt_sc"]       = $row[17];
													$a["mnt_dia"]      = $row[18];
													$a["mnt_nn1"]      = $row[19];
													$a["mnt_nn2"]      = $row[20];
													$a["mnt_nn3"]      = $row[21];
													$a["mnt_po"]       = $row[22];
													$a["mnt_hyp"]      = $row[23];
													$a["mnt_9615"]     = $row[24];
												}
												else { 
													$a["mnt_ghs"]      = $row[5];
													$a["mnt_exb"]      = $row[6];
													$a["mnt_rehosp"]   = $row[8];
													$a["mnt_exh"]      = $row[9];
													$a["mnt_rdth"]     = $row[11];
													$a["mnt_rdth_ped"] = $row[12];
													$a["mnt_ant"]      = 0;
													$a["mnt_rea"]      = $row[13];
													$a["mnt_rep"]      = $row[14];
													$a["mnt_si"]       = $row[15];
													$a["mnt_sc"]       = $row[16];
													$a["mnt_dia"]      = $row[17];
													$a["mnt_nn1"]      = $row[18];
													$a["mnt_nn2"]      = $row[19];
													$a["mnt_nn3"]      = $row[20];
													$a["mnt_po"]       = $row[21];
													$a["mnt_hyp"]      = $row[22];
													$a["mnt_9615"]     = $row[23];
												}
												$_casemix_ghs[$ghs_code . '|' . $ghm_code] = $a;
											}
										}
										break;
										
									// CMD 14 et 15 jusqu'à décembre 2012. A partir de 2013, les CMD 14 et 15 sont réincorporées aux tableaux 29 et 30
									case 't31_stc' :
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
										
											$casemix = array();
											
											// Effectifs avant mars
											$casemix = $tmpMat2aData[1][0][1];
											
											foreach ($casemix as $key => $row) {
											
												$ghs_code = $row[0];
												$ghm_code = substr(trim($row[1]), 0, 6);
												$a = $_casemix_ghs[$ghs_code . '|' . $ghm_code];
												if ($a == null) {
													$a = array();
												}
												$a["eff"]         = $row[2];
												$a["nb_j"]        = $row[3];
												$a["nb_exb"]      = $row[4];
												$a["nb_rehosp"]   = $row[5];
												$a["nb_exh"]      = $row[6];
												$a["nbj_exh"]     = $row[7];
												$a["nb_dia"]      = $row[8];
												$a["nb_rdth"]     = $row[9];
												$a["nb_rdth_ped"] = $row[10];
												$a["nb_9615"]     = $row[11];
												$a["nb_rea"]      = $row[12];
												$a["nb_rep"]      = $row[13];
												$a["nb_si"]       = $row[14];
												$a["nb_sc"]       = $row[15];
												$a["nb_nn1"]      = $row[16];
												$a["nb_nn2"]      = $row[17];
												$a["nb_nn3"]      = $row[18];
												$a["nb_ant"]      = $row[20];
												$a["nb_po"]       = $row[21];
												$a["nb_hyp"]      = $row[22];
												$_casemix_ghs[$ghs_code . '|' . $ghm_code] = $a;
											}
											
											// Effectifs apres mars
											$casemix = $tmpMat2aData[1][1][1];
											
											foreach ($casemix as $key => $row) {
											
													$ghs_code = $row[0];
													$ghm_code = substr(trim($row[1]), 0, 6);
													$a = $_casemix_ghs[$ghs_code . '|' . $ghm_code];
													if ($a == null) {
														$a = array();
														$a["eff"]         = $row[2];
														$a["nb_j"]        = $row[3];
														$a["nb_exb"]      = $row[4];
														$a["nb_rehosp"]   = $row[5];
														$a["nb_exh"]      = $row[6];
														$a["nbj_exh"]     = $row[7];
														$a["nb_dia"]      = $row[8];
														$a["nb_rdth"]     = $row[9];
														$a["nb_rdth_ped"] = $row[10];
														$a["nb_9615"]     = $row[11];
														$a["nb_rea"]      = $row[12];
														$a["nb_rep"]      = $row[13];
														$a["nb_si"]       = $row[14];
														$a["nb_sc"]       = $row[15];
														$a["nb_nn1"]      = $row[16];
														$a["nb_nn2"]      = $row[17];
														$a["nb_nn3"]      = $row[18];
														$a["nb_ant"]      = $row[20];
														$a["nb_po"]       = $row[21];
														$a["nb_hyp"]      = $row[22];
													}
													else {
														$a["eff"]         += $row[2];
														$a["nb_j"]        += $row[3];
														$a["nb_exb"]      += $row[4];
														$a["nb_rehosp"]   += $row[5];
														$a["nb_exh"]      += $row[6];
														$a["nbj_exh"]     += $row[7];
														$a["nb_dia"]      += $row[8];
														$a["nb_rdth"]     += $row[9];
														$a["nb_rdth_ped"] += $row[10];
														$a["nb_9615"]     += $row[11];
														$a["nb_rea"]      += $row[12];
														$a["nb_rep"]      += $row[13];
														$a["nb_si"]       += $row[14];
														$a["nb_sc"]       += $row[15];
														$a["nb_nn1"]      += $row[16];
														$a["nb_nn2"]      += $row[17];
														$a["nb_nn3"]      += $row[18];
														$a["nb_ant"]      += $row[20];
														$a["nb_po"]       += $row[21];
														$a["nb_hyp"]      += $row[22];
													}
													$_casemix_ghs[$ghs_code . '|' . $ghm_code] = $a;
											}
											
											// Valorisation avant mars
											$casemix = $tmpMat2aData[1][2][1];
											
											foreach ($casemix as $key => $row) {
											
												$ghs_code = $row[0];
												$ghm_code = substr(trim($row[1]), 0, 6);
												$a = $_casemix_ghs[$ghs_code . '|' . $ghm_code];
												if ($a == null) {
													$a = array();
												}
												$a["mnt_ghs"]      = $row[4];
												$a["mnt_exb"]      = $row[5];
												$a["mnt_rehosp"]   = $row[6];
												$a["mnt_exh"]      = $row[7];
												$a["mnt_rdth"]     = $row[8];
												$a["mnt_rdth_ped"] = $row[9];
												$a["mnt_rea"]      = $row[10];
												$a["mnt_rep"]      = $row[11];
												$a["mnt_si"]       = $row[12];
												$a["mnt_sc"]       = $row[13];
												$a["mnt_dia"]      = $row[14];
												$a["mnt_nn1"]      = $row[15];
												$a["mnt_nn2"]      = $row[16];
												$a["mnt_nn3"]      = $row[17];
												$a["mnt_ant"]      = $row[18];
												$a["mnt_po"]       = $row[19];
												$a["mnt_hyp"]      = $row[20];
												$a["mnt_9615"]     = $row[21];
												$_casemix_ghs[$ghs_code . '|' . $ghm_code] = $a;
											}
											
											// Valorisation après mars
											$casemix = $tmpMat2aData[1][3][1];
											
											foreach ($casemix as $key => $row) {
												$ghs_code = $row[0];
												$ghm_code = substr(trim($row[1]), 0, 6);
												$a = $_casemix_ghs[$ghs_code . '|' . $ghm_code];
												if ($a == null) {
													$a = array();
												}
												if ($a["mnt_ghs"] == null) {
													$a["mnt_ghs"]      = $row[4];
													$a["mnt_exb"]      = $row[5];
													$a["mnt_rehosp"]   = $row[6];
													$a["mnt_exh"]      = $row[7];
													$a["mnt_rdth"]     = $row[8];
													$a["mnt_rdth_ped"] = $row[9];
													$a["mnt_rea"]      = $row[10];
													$a["mnt_rep"]      = $row[11];
													$a["mnt_si"]       = $row[12];
													$a["mnt_sc"]       = $row[13];
													$a["mnt_dia"]      = $row[14];
													$a["mnt_nn1"]      = $row[15];
													$a["mnt_nn2"]      = $row[16];
													$a["mnt_nn3"]      = $row[17];
													$a["mnt_ant"]      = $row[18];
													$a["mnt_po"]       = $row[19];
													$a["mnt_hyp"]      = $row[20];
													$a["mnt_9615"]     = $row[21];
												}
												else {
													$a["mnt_ghs"]      += $row[4];
													$a["mnt_exb"]      += $row[5];
													$a["mnt_rehosp"]   += $row[6];
													$a["mnt_exh"]      += $row[7];
													$a["mnt_rdth"]     += $row[8];
													$a["mnt_rdth_ped"] += $row[9];
													$a["mnt_rea"]      += $row[10];
													$a["mnt_rep"]      += $row[11];
													$a["mnt_si"]       += $row[12];
													$a["mnt_sc"]       += $row[13];
													$a["mnt_dia"]      += $row[14];
													$a["mnt_nn1"]      += $row[15];
													$a["mnt_nn2"]      += $row[16];
													$a["mnt_nn3"]      += $row[17];
													$a["mnt_ant"]      += $row[18];
													$a["mnt_po"]       += $row[19];
													$a["mnt_hyp"]      += $row[20];
													$a["mnt_9615"]     += $row[21];
												}
												$_casemix_ghs[$ghs_code . '|' . $ghm_code] = $a;
											}
										}
										break;
										
									// ***********************  OVALIDE ***********************
										
									case 't1d2rtp' :
										
										$check_code += 1;
										
										$mat2a_annee = $eFileName[count($eFileName) - 4];
										$mat2a_mois = $eFileName[count($eFileName) - 3];
										
										if (intval($mat2a_annee) >= 2013) {
										
											$mahosYearOk = true;
											
											$tmpMat2aData = $this->traiterTableau($mat2aData);
											
											$mat2a_date = $tmpMat2aData[0]['mat2a_date'];
											
											$mat2a_rsa_transmis = $this->fix($tmpMat2aData[1][0][1][0][1]);
											$mat2a_rsa_seances = $this->fix($tmpMat2aData[1][0][1][5][1]);
											$mat2a_rsa_0_nuits = $this->fix($tmpMat2aData[1][0][1][7][1]);
											
											// On déduit le nombre de RSA traités en soustrayant le décomptes des erreurs aux nombre de rsa transmis
											$mat2a_rsa_cmd90 = $this->fix($tmpMat2aData[1][0][1][1][1]);
											$mat2a_rsa_hors_periode = $this->fix($tmpMat2aData[1][0][1][2][1]);
											$mat2a_rsa_presta_inter_etab = $this->fix($tmpMat2aData[1][0][1][3][1]);
											$mat2a_rsa_ghs_9999 = $this->fix($tmpMat2aData[1][0][1][4][1]);
											$mat2a_rsa_traites = $mat2a_rsa_transmis 
																	- $mat2a_rsa_cmd90 
																	- $mat2a_rsa_hors_periode 
																	- $mat2a_rsa_presta_inter_etab
																	- $mat2a_rsa_ghs_9999;
										}
										break;
										
									case 't1v1sv' :
										
										$check_code += 2;
										// Compatibilité avec ovalide privé où il y a un tableau en plus
										if ($check_code & 3 == 3) { $check_code += 4;}
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
											$mat2a_nb_sejours_valorises = $this->fix($tmpMat2aData[1][0][1][10][1]);
											$mat2a_br_sejours_valorises = $this->fix($tmpMat2aData[1][0][1][10][2]);
											$mat2a_br_sejours_valorises = str_replace(',', '.', $mat2a_br_sejours_valorises);
										}
										break;
										
									// Les tableaux t.1.v.1.cme et t.1.v.1.cmv servent à générer le casemix-GHS
									case 't1v1cme' :
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
										
											$check_code += 8;
										
											$casemix = array();
											$casemix = $tmpMat2aData[1][0][1];
											
											foreach ($casemix as $key => $row) {
												$ghs_code = $row[0];
												$ghm_code = substr(trim($row[1]), 0, 6);
												// Normalement, le tableau cme est traité avant le cmv et donc $_casemix_ghs[$ghs_code . '|' . $ghm_code] devrait toujours être null
												// mais on ne sait jamais...
												$a = $_casemix_ghs[$ghs_code . '|' . $ghm_code];
												if ($a == null) {
													$a = array();
												}
												$a["eff"] = $row[2];
												$a["nb_j"] = $row[4];
												$a["nb_exb"] = $row[5];
												$a["nb_rehosp"] = $row[7];
												$a["nb_exh"] = $row[8];
												$a["nbj_exh"] = $row[10];
												$a["nb_dia"] = $row[12];
												$a["nb_rdth"] = $row[13];
												$a["nb_rdth_ped"] = $row[14];
												$a["nb_ant"] = $row[15];
												$a["nb_9615"] = $row[17];
												$a["nb_rea"] = $row[18];
												$a["nb_rep"] = $row[19];
												$a["nb_si"] = $row[20];
												$a["nb_sc"] = $row[21];
												$a["nb_nn1"] = $row[22];
												$a["nb_nn2"] = $row[23];
												$a["nb_nn3"] = $row[24];
												$a["nb_po"] = $row[25];
												$a["nb_hyp"] = $row[26];
												$_casemix_ghs[$ghs_code . '|' . $ghm_code] = $a;
											}
										}
										break;
										
									case 't1v1cmv' :
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
										
											$check_code += 16;
										
											$casemix = array();
											$casemix = $tmpMat2aData[1][0][1];
											
											foreach ($casemix as $key => $row) {
												$ghs_code = $row[0];
												$ghm_code = substr(trim($row[1]), 0, 6);
												// Normalement, le cmv est traité après le cmv et donc $_casemix_ghs[$ghs_code] ne devrait jamais être null
												// mais on ne sait jamais...
												$a = $_casemix_ghs[$ghs_code . '|' . $ghm_code];
												if ($a == null) {
													$a = array();
												}
												$a["mnt_ghs"] = $row[5];
												$a["mnt_exb"] = $row[6];
												$a["mnt_rehosp"] = $row[8];
												$a["mnt_exh"] = $row[9];
												$a["mnt_rdth"] = $row[11];
												$a["mnt_rdth_ped"] = $row[12];
												$a["mnt_ant"] = $row[13];
												$a["mnt_rea"] = $row[14];
												$a["mnt_rep"] = $row[15];
												$a["mnt_si"] = $row[16];
												$a["mnt_sc"] = $row[17];
												$a["mnt_dia"] = $row[18];
												$a["mnt_nn1"] = $row[19];
												$a["mnt_nn2"] = $row[20];
												$a["mnt_nn3"] = $row[21];
												$a["mnt_po"] = $row[22];
												$a["mnt_hyp"] = $row[23];
												$a["mnt_9615"] = $row[24];
												$_casemix_ghs[$ghs_code . '|' . $ghm_code] = $a;
											}
										}
										break;
										
									case 't1v3vdmi' :
										
										// LPP
										
										$tmpMat2aData = $this->traiterTableau($mat2aData);
										
										if ($tmpMat2aData != -1) {
											
											$_lpp = $this->traiterLPP($tmpMat2aData, $typeEts);
										}
										break;
										

								}
							}
							zip_entry_close($zip_entry);
						}
					}
				}
				else {
					$ret[] = "false";
					$ret[] = "Le fichier \"$fileName\" ne compte qu'un fichier comportant tous les tabeleaux concaténés. Merci d'importer un fichier zip avec tous les tableaux séparés";
				}
				zip_close($zip);
			}
			
			// On ne fait les insertions en base que si les tableaux pricipaux ont été trouvés :
			// . t01 et t32 pour MAT2A privé
			// . t1d2rtp, t1v4synts et t1v1cp pour OVALIDE privé
			// . t1d2rtp, t1v1sv pour OVALIDE public
			// . t01 et t34 pour MAT2A public
			if (($check_code & 7 == 7) && $mahosYearOk) {
				try {
					// $con = ICTIDB::getInstance();
					$con->beginTransaction();
					$sql = "
						INSERT INTO pmsi.p_mat2a_import(
							sha1,
							fichier,
							date,
							mat2a_annee,
							mat2a_mois,
							mat2a_date,
							mat2a_rsa_transmis,
							mat2a_rsa_traites,
							mat2a_rsa_seances,
							mat2a_rsa_0_nuits,
							mat2a_rsa_prestations_nb_total,
							mat2a_rsa_prestations_base_remb,
							mat2a_nb_sejours_valorises,
							mat2a_br_sejours_valorises
							)
						VALUES (
							'$sha1',
							'$fileName',
							now()::date,
							$mat2a_annee,
							$mat2a_mois,
							'$mat2a_date',
							$mat2a_rsa_transmis,
							$mat2a_rsa_traites,
							$mat2a_rsa_seances,
							$mat2a_rsa_0_nuits,
							$mat2a_rsa_prestations_nb_total,
							round($mat2a_rsa_prestations_base_remb),
							$mat2a_nb_sejours_valorises,
							round($mat2a_br_sejours_valorises)
							)
						;
					";
					$con->exec($sql);
					
					// Valider automatiquement l'import MAT2A si tous les champs sont identiques entre CTI et MAT2A
					$sql = "
						UPDATE pmsi.p_imports
						SET mat2a_ok = subq_validation.mat2a_ok
						FROM
							(
							SELECT 
								import_id,
								(CASE WHEN sum(import_manquant + (CASE WHEN mat2a_ok = 0 THEN (e0 + e1 + e2 + e3 + e4 + e5 + e6 + e7) ELSE 0 END)) > 0 THEN 0 ELSE 1 END) AS mat2a_ok
							FROM
								(
								SELECT
									CASE WHEN last_mat2a_imports.annee IS NULL THEN 1 ELSE 0 END AS import_manquant,
									coalesce(abs(mat2a_rsa_transmis - nb_rsa_transmis), 0) AS e0,
									coalesce(abs(mat2a_rsa_traites - nb_rsa_traites), 0) AS e1,
									coalesce(abs(mat2a_rsa_seances - nb_rsa_seances), 0) AS e2,
									coalesce(abs(mat2a_rsa_0_nuits - nb_rsa_0_nuits), 0) AS e3,
									coalesce(abs(mat2a_rsa_prestations_nb_total - nb_total_rsa_prestations), 0) AS e4,
									coalesce(abs(round(mat2a_rsa_prestations_base_remb) - round(br_total_rsa_prestations)), 0) AS e5,
									coalesce(abs(mat2a_nb_sejours_valorises - nb_sejours_valorises), 0) AS e6,
									coalesce(abs(round(mat2a_br_sejours_valorises) - round(br_sejours_valorises)), 0) AS e7,
									mat2a_ok,
									last_rss_imports.oid AS import_id
								FROM
									(
									SELECT *
									FROM pmsi.p_imports
										JOIN pmsi.p_imports_stats on p_imports_stats.import_id = p_imports.oid
										JOIN
											(
											SELECT 
												annee,
												max(mois) AS mois,
												(max(ARRAY [annee||lpad(mois, 2, '0'), lpad(oid::text, 4, '0')]))[2]::numeric AS import_id
											FROM
												(
												SELECT 
													to_char(date_debut, 'YYYY') AS annee,
													to_char(date_fin - '3 days'::interval, 'MM') AS mois,
													oid
												FROM pmsi.p_imports
												WHERE 1=1
													AND date_fin - date_debut < 400 
													AND date_debut < now() 
												) AS subq1
											GROUP BY 1
											) AS subq2 ON subq2.import_id = p_imports.oid
									) AS last_rss_imports
									LEFT JOIN
										(
										SELECT *
										FROM pmsi.p_mat2a_import
										JOIN 
											(
											SELECT
												mat2a_annee || lpad(mat2a_mois, 2, '0') AS annee,
												(max(ARRAY [mat2a_date::text, oid::text]))[2] AS oid
											FROM pmsi.p_mat2a_import
											WHERE 1=1
												AND sha1 = '$sha1'
											GROUP BY 1
											) AS subq1 ON subq1.oid = p_mat2a_import.oid
										) AS last_mat2a_imports ON 1=1
											AND last_rss_imports.annee||lpad(last_rss_imports.mois, 2, '0') = last_mat2a_imports.annee
									WHERE 1=1
									AND last_rss_imports.annee >= 2012
								) AS subq_total
							GROUP BY 1
							) AS subq_validation
						WHERE 1=1
							AND p_imports.oid = subq_validation.import_id
						;
					";
					
					$con->exec($sql);
					
					// Récupère l'oid de l'import MAT2A en cours de traitement
					$oid = 0;
					$sql = " SELECT oid FROM pmsi.p_mat2a_import WHERE sha1 = '$sha1'; ";
					foreach ($con->query($sql, PDO::FETCH_ASSOC) as $row) {
						$oid = $row['oid'];
					}
					
					// Pointer le n° d'import MAT2A dans import RSS
					$sql = "UPDATE pmsi.p_imports
					SET mat2a_import_id = p_mat2a_import.oid
					FROM (
					SELECT p_mat2a_import.mat2a_annee, p_mat2a_import.mat2a_mois, MAX(p_mat2a_import.oid) AS oid
					FROM pmsi.p_mat2a_import
					GROUP BY 1,2
					) p_mat2a_import
					WHERE
						date_part('year',p_imports.date_fin) = p_mat2a_import.mat2a_annee AND
						date_part('month',p_imports.date_fin) = p_mat2a_import.mat2a_mois AND
						etat = 'G' AND
						p_imports.oid IN (SELECT import_id FROM pmsi.p_rss WHERE etat = '') AND
						mat2a_import_id IS DISTINCT FROM p_mat2a_import.oid;
					"; 
					$con->exec($sql);
					
					// Import des données brutes
					foreach ($mat2a_files as $mat2a_file) {
						$sql = "SELECT pmsi.cti_import_mat2a_file($oid, '$mat2a_file');"; 
						$con->exec($sql);
					}
					
					// Contrôles complémentaires. Pour chaque contrôle : 
					//	- on s'appuiera sur une table de travail prefixée en 'w_' dans le schéma PMSI
					//	- on vérifiera au préalable l'existance de cette table de travail. Selon le cas, soit on la crééra,
					//		soit on en effacera le contenu faisant référence à un import mat2a/ovalide inexistant
					if (count($_casemix_ghs) > 0) {
						
						if ($typeEts != '1') {
							
							// Création ou nettoyage de la table du casemix GHS DGF
							$sql = " SELECT * FROM information_schema.tables WHERE table_name= 'w_mat2a_dgf_casemix' AND table_schema = 'pmsi'; ";
							$res = $con->query($sql);
							if ($res->rowCount() == 0) {
								$sql = " CREATE TABLE pmsi.w_mat2a_dgf_casemix( mat2a_id bigint, ghs_code text, ghm_code text, eff bigint, nb_j bigint, nb_exb bigint,
										nb_exh bigint, nb_rehosp bigint, nbj_exh bigint, nb_dia bigint, nb_rdth bigint, nb_rdth_ped bigint, nb_9615 bigint, nb_rea bigint,
										nb_rep bigint, nb_si bigint, nb_sc bigint, nb_nn1 bigint, nb_nn2 bigint, nb_nn3 bigint, nb_ant bigint, nb_po bigint, nb_hyp bigint,
										mnt_ghs numeric, mnt_exb numeric, mnt_exh numeric, mnt_rehosp numeric, mnt_rdth numeric, mnt_rdth_ped numeric, mnt_rea numeric, 
										mnt_rep numeric, mnt_si numeric, mnt_sc numeric, mnt_dia numeric, mnt_nn1 numeric, mnt_nn2 numeric, mnt_nn3 numeric, mnt_ant numeric, 
										mnt_po numeric, mnt_hyp numeric, mnt_9615 numeric); "; 
								$con->exec($sql);
							}
							else {
								$sql = " DELETE FROM pmsi.w_mat2a_dgf_casemix WHERE mat2a_id NOT IN (SELECT oid FROM pmsi.p_mat2a_import) "; 
								$con->exec($sql);
							}
							
							// Insertion des données à l'aide d'un seul INSERT
							$sql = " INSERT INTO pmsi.w_mat2a_dgf_casemix (
										mat2a_id, ghs_code, ghm_code, eff, nb_j, nb_exb, nb_exh, nb_rehosp, nbj_exh,
										nb_dia, nb_rdth, nb_rdth_ped, nb_9615, nb_rea, nb_rep, nb_si, nb_sc, nb_nn1, 
										nb_nn2, nb_nn3, nb_ant, nb_po, nb_hyp, mnt_ghs, mnt_exb, mnt_exh, mnt_rehosp,
										mnt_rdth, mnt_rdth_ped, mnt_rea, mnt_rep, mnt_si, mnt_sc, mnt_dia, 
										mnt_nn1, mnt_nn2, mnt_nn3, mnt_ant, mnt_po, mnt_hyp, mnt_9615) VALUES ";
							
							foreach ($_casemix_ghs as $key => $row) {
								$codes = explode('|', $key);
								$sql .= " ($oid, '" . $codes[0] . "', '" . $codes[1] . "', " . 
									$row["eff"] . ", " . $row["nb_j"] . ", " . $row["nb_exb"] . ", " . $row["nb_exh"] . ", " . $row["nb_rehosp"] . ", " .
									$row["nbj_exh"] . ", " . $row["nb_dia"] . ", " . $row["nb_rdth"] . ", " . $row["nb_rdth_ped"] . ", " . 
									$row["nb_9615"] . ", " . $row["nb_rea"] . ", " . $row["nb_rep"] . ", " . $row["nb_si"] . ", " . 
									$row["nb_sc"] . ", " . $row["nb_nn1"] . ", " . $row["nb_nn2"] . ", " . $row["nb_nn3"] . ", " . 
									$row["nb_ant"] . ", " . $row["nb_po"] . ", " . $row["nb_hyp"] . ", " . $row["mnt_ghs"] . ", " . 
									$row["mnt_exb"] . ", " . $row["mnt_exh"] . ", " . $row["mnt_rehosp"] . ", " . $row["mnt_rdth"] . ", " . $row["mnt_rdth_ped"] . ", " . 
									$row["mnt_rea"] . ", " . $row["mnt_rep"] . ", " . $row["mnt_si"] . ", " . $row["mnt_sc"] . ", " . 
									$row["mnt_dia"] . ", " . $row["mnt_nn1"] . ", " . $row["mnt_nn2"] . ", " . $row["mnt_nn3"] . ", " . 
									$row["mnt_ant"] . ", " . $row["mnt_po"] . ", " . $row["mnt_hyp"] . ", " . $row["mnt_9615"] . "),";
							}
							// Vire la dernière virgule
							$sql = substr($sql, 0, -1);
							$con->exec($sql);
						}
						else {
							
							// Création ou nettoyage de la table du casemix GHS OQN
							$sql = " SELECT * FROM information_schema.tables WHERE table_name= 'w_mat2a_oqn_casemix' AND table_schema = 'pmsi'; ";
							$res = $con->query($sql);
							if ($res->rowCount() == 0) {
								$sql = " CREATE TABLE pmsi.w_mat2a_oqn_casemix (mat2a_id bigint, ghs_code text, ghm_code text, nb_sej bigint, montant_br numeric); "; 
								$con->exec($sql);
							}
							else {
								$sql = " DELETE FROM pmsi.w_mat2a_oqn_casemix WHERE mat2a_id NOT IN (SELECT oid FROM pmsi.p_mat2a_import) "; 
								$con->exec($sql);
							}
							
							// Insertion des données à l'aide d'un seul INSERT
							$sql = " INSERT INTO pmsi.w_mat2a_oqn_casemix (mat2a_id, ghs_code, ghm_code, nb_sej, montant_br) VALUES ";
							
							foreach ($_casemix_ghs as $key => $row) {
								$codes = explode('|', $key);
								$sql .= " ($oid, '" . $codes[0] . "', '" . $codes[1] . "', " . $row["nb_sej"] . ", " . $row["montant_br"] . "),";
							}
							// Vire la dernière virgule
							$sql = substr($sql, 0, -1);
							$con->exec($sql);
						}
					}
					if (count($_rsfsupp) > 0 && $typeEts == '1') {
						
						// Création ou nettoyage de la table du casemix GHS DGF
						$sql = " SELECT * FROM information_schema.tables WHERE table_name= 'w_mat2a_oqn_rsfsupp' AND table_schema = 'pmsi'; ";
						$res = $con->query($sql);
						if ($res->rowCount() == 0) {
							$sql = " CREATE TABLE pmsi.w_mat2a_oqn_rsfsupp( mat2a_id bigint, ghs_code text, ghm_code text, eff bigint, montant_br numeric); "; 
							$con->exec($sql);
						}
						else {
							$sql = " DELETE FROM pmsi.w_mat2a_oqn_rsfsupp WHERE mat2a_id NOT IN (SELECT oid FROM pmsi.p_mat2a_import) "; 
							$con->exec($sql);
						}
						
						// Insertion des données à l'aide d'un seul INSERT
						$sql = " INSERT INTO pmsi.w_mat2a_oqn_rsfsupp (mat2a_id, ghs_code, ghm_code, eff, montant_br) VALUES ";
						
						foreach ($_rsfsupp as $key => $row) {
							$codes = explode('|', $key);
							$sql .= " ($oid, '" . $codes[0] . "', '" . $codes[1] . "', " . $row["eff"] . ", " . $row["montant_br"] . "),";
						}
						// Vire la dernière virgule
						$sql = substr($sql, 0, -1);
						$con->exec($sql);
					}
					if (count($_prestations) > 0 && $typeEts == '1') {
						
						// Création ou nettoyage de la table du tableau des prestations
						$sql = " SELECT * FROM information_schema.tables WHERE table_name= 'w_mat2a_oqn_prestations' AND table_schema = 'pmsi'; ";
						$res = $con->query($sql);
						if ($res->rowCount() == 0) {
							$sql = " CREATE TABLE pmsi.w_mat2a_oqn_prestations (mat2a_id bigint, prestation_code text, quantite numeric, montant_br numeric, montant_amo numeric); "; 
							$con->exec($sql);
						}
						else {
							$sql = " DELETE FROM pmsi.w_mat2a_oqn_prestations WHERE mat2a_id NOT IN (SELECT oid FROM pmsi.p_mat2a_import) "; 
							$con->exec($sql);
						}
						
						// Insertion des données à l'aide d'un seul INSERT
						$sql = " INSERT INTO pmsi.w_mat2a_oqn_prestations (mat2a_id, prestation_code, quantite, montant_br, montant_amo) VALUES ";
						
						foreach ($_prestations as $key => $row) {
							$sql .= " ($oid, '" . $key . "', " . $row["quantite"] . ", " . $row["montant_br"] . ", " . $row["montant_amo"] . "),";
						}
						// Vire la dernière virgule
						$sql = substr($sql, 0, -1);
						$con->exec($sql);
					}
					if (count($_lpp) > 0) {
						
						if ($typeEts == '1') {
							// Création ou nettoyage de la table du tableau des LPP
							$sql = " SELECT * FROM information_schema.tables WHERE table_name= 'w_mat2a_oqn_lpp' AND table_schema = 'pmsi'; ";
							$res = $con->query($sql);
							if ($res->rowCount() == 0) {
								$sql = " CREATE TABLE pmsi.w_mat2a_oqn_lpp (mat2a_id bigint, lpp_code text, quantite numeric, depenses numeric, depenses_autorisees numeric, depenses_accordees numeric); "; 
								$con->exec($sql);
							}
							else {
								$sql = " DELETE FROM pmsi.w_mat2a_oqn_lpp WHERE mat2a_id NOT IN (SELECT oid FROM pmsi.p_mat2a_import) "; 
								$con->exec($sql);
							}
							
							// Insertion des données à l'aide d'un seul INSERT
							$sql = " INSERT INTO pmsi.w_mat2a_oqn_lpp (mat2a_id, lpp_code, quantite, depenses, depenses_autorisees, depenses_accordees) VALUES ";
							
							foreach ($_lpp as $key => $row) {
								$sql .= " ($oid, '" . $key . "', " . $row["quantite"] . ", " . $row["depenses"] . ", " . $row["depenses_autorisees"] . ", " . $row["depenses_accordees"] . "),";
							}
						}
						else {
							// Création ou nettoyage de la table du tableau des LPP
							$sql = " SELECT * FROM information_schema.tables WHERE table_name= 'w_mat2a_dgf_lpp' AND table_schema = 'pmsi'; ";
							$res = $con->query($sql);
							if ($res->rowCount() == 0) {
								$sql = " CREATE TABLE pmsi.w_mat2a_dgf_lpp (mat2a_id bigint, lpp_code text, transmis_fichcomp numeric, non_valorises_a numeric, non_valorises_b numeric, fichcomp_0 numeric, valorises numeric, depenses numeric, depenses_autorisees numeric, depenses_accordees numeric, ecart numeric); "; 
								$con->exec($sql);
							}
							else {
								$sql = " DELETE FROM pmsi.w_mat2a_dgf_lpp WHERE mat2a_id NOT IN (SELECT oid FROM pmsi.p_mat2a_import) "; 
								$con->exec($sql);
							}
							
							// Insertion des données à l'aide d'un seul INSERT
							$sql = " INSERT INTO pmsi.w_mat2a_dgf_lpp (mat2a_id, lpp_code, transmis_fichcomp, non_valorises_a, non_valorises_b, fichcomp_0, valorises, depenses, depenses_autorisees, depenses_accordees, ecart) VALUES ";
							
							foreach ($_lpp as $key => $row) {
								$sql .= " ($oid, '" . $key . "', " . $row["transmis_fichcomp"] . ", " . $row["non_valorises_a"] . ", " . $row["non_valorises_b"] . ", " . $row["fichcomp_0"] . ", " . $row["valorises"] . ", " . $row["depenses"] . ", " . $row["depenses_autorisees"] . ", " . $row["depenses_accordees"] . ", " . $row["ecart"] . "),";
							}
						}
						// Vire la dernière virgule
						$sql = substr($sql, 0, -1);
						$con->exec($sql);
					}
					if (count($_ucd) > 0 && $typeEts == '1') {
						
						// Création ou nettoyage de la table du tableau des UCD
						$sql = " SELECT * FROM information_schema.tables WHERE table_name= 'w_mat2a_oqn_ucd' AND table_schema = 'pmsi'; ";
						$res = $con->query($sql);
						if ($res->rowCount() == 0) {
							$sql = " CREATE TABLE pmsi.w_mat2a_oqn_ucd (mat2a_id bigint, ucd_code text, quantite numeric, depenses numeric, depenses_autorisees numeric, depenses_accordees numeric, ecart numeric); "; 
							$con->exec($sql);
						}
						else {
							$sql = " DELETE FROM pmsi.w_mat2a_oqn_ucd WHERE mat2a_id NOT IN (SELECT oid FROM pmsi.p_mat2a_import) "; 
							$con->exec($sql);
						}
						
						// Insertion des données à l'aide d'un seul INSERT
						$sql = " INSERT INTO pmsi.w_mat2a_oqn_ucd (mat2a_id, ucd_code, quantite, depenses, depenses_autorisees, depenses_accordees, ecart) VALUES ";
						
						foreach ($_ucd as $key => $row) {
							$sql .= " ($oid, '" . $key . "', " . $row["quantite"] . ", " . $row["depenses"] . ", " . $row["depenses_autorisees"] . ", " . $row["depenses_accordees"] . ", " . $row["ecart"] . "),";
						}
						// Vire la dernière virgule
						$sql = substr($sql, 0, -1);
						$con->exec($sql);
					}
					
					$con->commit();
					
				} catch (Exception $e) {
					// Attendre 2 sec pour être sûr que zip_close() ait bien libéré le fichier.
					sleep(2);
					unlink($dstFilePath);
					
					$ret[] = "false";
					$ret[] = "Erreur lors de l'insertion en BD. " . $e->getMessage();
				}
				
				$ret[] = "true";
				$ret[] = "Fichier \"$fileName\" importé avec succès.";
			}
			else {
				// Attendre 2 sec pour être sûr que zip_close() ait bien libéré le fichier.
				sleep(2);
				unlink($dstFilePath);
				
				if ($check_code == 0) {
					$ret[] = "false";
					$ret[] = "Aucun tableau MAT2A/OVALIDE n'a été trouvé dans  \"$fileName\".";
				}
				else if ($check_code & 7 != 7 ) {	// 1 + 2
					$ret[] = "false";
					// $tab = $typeEts == '1' ? '32' : '34';
					$ret[] = "Les tableaux principaux n'ont pas été trouvés dans  \"$fileName\".";
				}
				else if ($check_code > 7 && $check_code & 24 != 24 ) {	// 8 + 16
					$ret[] = "false";
					$ret[] = "Le CaseMix GHS n'a pas pu etre généré";
				}
				else if (!$mahosYearOk) {
					$ret[] = "false";
					$ret[] = "Les tableaux MAT2A/OVALIDE ne sont traités qu'à partir de l'année 2012.";
				}
				else {
					$ret[] = "false";
					$ret[] = "Erreur non répertoriée. Ce cas n'aurais jamais dû arriver !";
				}
			}
		}
		
		return $ret;
	}
	
	
	/**
	 * Analyse le tableau des UCD et retourne un tableau donnant les infos par code UCD
	 */
	private function traiterRSBSupp($rsfbsupp_array) {
		
		$rsfb = array();
		$casemix = array();
		
		if (count($rsfbsupp_array[1]) > 2) {
		
			$casemix = $rsfbsupp_array[1][2][1];
			
			foreach ($casemix as $row) {
				$ghs_code = $row[1];
				$ghm_code = substr(trim($row[0]), 0, 6);
				$a = $rsfb[$ghs_code . '|' . $ghm_code];
				if ($a == null) {
					$a = array();
				}
				$a["eff"] = $row[2];
				$a["montant_br"] = $row[3];
				$rsfb[$ghs_code. '|' . $ghm_code] = $a;
			}
		}
		return $rsfb;
	}
	
	
	/**
	 * Analyse le tableau des UCD et retourne un tableau donnant les infos par code UCD
	 */
	private function traiterUCD($ucd_array) {
		
		$ucd = array();
		$casemix = array();
		$casemix = $ucd_array[1][0][1];
		
		foreach ($casemix as $row) {
			$ucd_code = $row[0];
			$a = $ucd[$ucd_code];
			if ($a == null) {
				$a = array();
			}
			$a["quantite"] = $row[2];
			$a["depenses"] = $row[3];
			$a["depenses_autorisees"] = $row[4];
			$a["depenses_accordees"] = $row[5];
			$a["ecart"] = $row[6];
			$ucd[$ucd_code] = $a;
		}
		return $ucd;
	}
	
	
	/**
	 * Analyse le tableau des LPP et retourne un tableau donnant les infos par code LPP
	 */	
	private function traiterLPP($lpp_array, $typeEts) {
	
		$casemix = array();
		$lpp = array();
		
		if ($typeEts == '1') {
			$casemix = $lpp_array[1][0][1];
			
			foreach ($casemix as $row) {
				$lpp_code = $row[0];
				$a = $lpp[$lpp_code];
				if ($a == null) {
					$a = array();
				}
				$a["quantite"] = $row[2];
				$a["depenses"] = $row[3];
				$a["depenses_autorisees"] = $row[4];
				$a["depenses_accordees"] = $row[5];
				$lpp[$lpp_code] = $a;
			}
		}
		else {
			$casemix = $lpp_array[1][0][1];
			
			foreach ($casemix as $row) {
				$lpp_code = $row[0];
				$a = $lpp[$lpp_code];
				if ($a == null) {
					$a = array();
				}
				$a["transmis_fichcomp"] = $row[2];
				$a["non_valorises_a"] = $row[3];
				$a["non_valorises_b"] = $row[4];
				$a["fichcomp_0"] = $row[5];
				$a["valorises"] = $row[6];
				// Initialise les valeurs du deuxième tableau à 0 car si un LPP n'est pas valorisé, il n'apparait pas dans le deuxième tableau,
				// Cela évite de se retrouver avec des valeurs vides
				$a["depenses"] = 0;
				$a["depenses_autorisees"] = 0;
				$a["depenses_accordees"] = 0;
				$a["ecart"] = 0;
				$lpp[$lpp_code] = $a;
			}
			
			$casemix = $lpp_array[1][1][1];
			
			foreach ($casemix as $row) {
				$lpp_code = $row[0];
				$a = $lpp[$lpp_code];
				$a["depenses"] = $row[3];
				$a["depenses_autorisees"] = $row[4];
				$a["depenses_accordees"] = $row[5];
				$a["ecart"] = $row[6];
				$lpp[$lpp_code] = $a;
			}
		}
		return $lpp;
	}
	
	/**
	 * Traite le méta-tableau des CaseMix GHM
	 * Selon le cas, on aura ou non des dialyses et/ou de la mater
	 */
	private function traiterCaseMixGHS($ghs_array) {
	
		// [0] tableau A1 : Case-Mix GHS et IVG (hors facture avec GHS NN)
		// [1] tableau A2 : Case-Mix GHS et IVG par racine (hors facture avec GHS NN)
		// [2] tableau A3 : Case-Mix GHS et IVG par niveau (hors facture avec GHS NN)
		// [3] tableau B : Case-Mix GHS des Factures avec GHS NN _ Lignes de RSFB autres que celles ayant un GHS NN
		// [4] tableau C : Case-Mix GHS des Factures avec GHS NN _ Lignes de RSFB avec un GHS NN
		// [5] tableau D : Case-Mix facturation hors GHS - Dialyse
		
		$casemix_ghs = array();
		
		// Construit un tableau d'association GHS <--> GHM
		$ghs_ghm = array();
		$con = ICTIDB::getInstance();
		$con->beginTransaction();
		$sql = " SELECT t_ghs.code as ghs, t_ghm.code as ghm FROM pmsi.t_ghs JOIN pmsi.t_ghm ON t_ghs.ghm_id = t_ghm.oid WHERE t_ghs.code >= 0 ORDER BY 1;";
		foreach ($con->query($sql, PDO::FETCH_ASSOC) as $row) {
			$oid = $row['oid'];
			$ghs_ghm[trim($row['ghs'])] = trim($row['ghm']);
		}
		$con->commit();
		
		$casemix = array();
		
		// S'il y a plus de 4 tableaux, il y a forcément de la mater
		if (count($ghs_array[1]) > 4) {
			
			// Traitement à part du tableau de la CMD 15 (tableau C)
			$casemix = $ghs_array[1][4][1];
			
			foreach ($casemix as $row) {
				$ghs_code = trim($row[0]);
				reset($ghs_ghm);
				if (array_key_exists($ghs_code, $ghs_ghm)) {
					$ghm_code = $ghs_ghm[$ghs_code];
				}
				else {
					$ghm_code = $ghs_ghm[0];
				}

				$a = $casemix_ghs[$ghs_code . '|' . $ghm_code];
				if ($a == null) {
					$a = array();
				}
				$a["nb_sej"] = $row[3];
				$a["montant_br"] = $row[5];
				$casemix_ghs[$ghs_code . '|' . $ghm_code] = $a;
			}
			// S'il y a de la dialyse et de la mater, on concatène les tableaux A1, B et D qui ont la même construction
			if (count($ghs_array[1]) > 5) {
				$casemix = array_merge($ghs_array[1][0][1], $ghs_array[1][3][1], $ghs_array[1][5][1]);
			}
			// Pas de dialyse, on concatène les tableaux A1 et B
			else {
				$casemix = array_merge($ghs_array[1][0][1], $ghs_array[1][3][1]);
			}
		}
		// S'il n'y a pas de mater mais qu'il y a des dialyses, on concatène les tableaux A1 et D
		else if (count($ghs_array[1]) > 3) {
			$casemix = array_merge($ghs_array[1][0][1], $ghs_array[1][5][1]);
		}
		// Pas de mate, pas de dialyse, on ne traite que le tableau A1
		else {
			$casemix = $ghs_array[1][0][1];
		}
		
		foreach ($casemix as $row) {
			$ghs_code = $row[1];
			$ghm_code = substr(trim($row[0]), 0, 6);
			$a = $casemix_ghs[$ghs_code . '|' . $ghm_code];
			if ($a == null) {
				$a = array();
			}
			$a["nb_sej"] = $row[2];
			$a["montant_br"] = $row[4];
			$casemix_ghs[$ghs_code. '|' . $ghm_code] = $a;
		}
		
		return $casemix_ghs;
	}
	
	
	private function traiterPrestations($presta_array, &$nb_total=0, &$br_total=0) {
	
		$casemix = array();
		$prestations = array();
		
		// S'il y a de l'activité externe, on fusionne les tableaux d'hospitalisation complète
		// et d'activité externe pour ne faire qu'un foreach. SI non, on ne prend que le premier tableau
		if (count($presta_array[1] > 1)) {
			$casemix = array_merge($presta_array[1][0][1], $presta_array[1][1][1]);
		}
		else {
			$casemix = $presta_array[1][0][1];
		}
		
		foreach ($casemix as $row) {
			$code = $row[0];
			$a = $prestations[$code];
			if ($a == null) {
				$a = array();
			}
			$a["quantite"] = $row[2];
			$a["montant_br"] = $row[3];
			$a["montant_amo"] = $row[4];
			$prestations[$code] = $a;
		}
		
		// Traite le tableau B des codes n'appartenant pas à la norme B2 s'il est présent
		if (count($presta_array[1]) > 2) {
		
			$casemix = $presta_array[1][2][1];
			
			$quantite_hors_b2 = 0;
			$br_hors_b2 = 0;
			
			foreach ($casemix as $row) {
				$code = $row[0];
				$a = $prestations[$code];
				if ($a == null) {
					$a = array();
				}
				$a["quantite"] = $row[1];
				$quantite_hors_b2 += $this->fix($row[1]);
				$a["montant_br"] = $row[2];
				$br_hors_b2 += $this->fix($row[2]);
				$a["montant_amo"] = $row[3];
				$prestations[$code] = $a;
			}
			
			// Mise à jour des totaux en prenant en compte les prestations hors norme B2
			$nb_total += $quantite_hors_b2;
			$br_total += $br_hors_b2;
		}
		return $prestations;
	}
	
	
	/**
	 * Vire les espaces d'une chaine de caractères
	 *
	 * @param	$value	chaîne à traiter
	 * @return	La chaîne délestée de ses espaces
	 */
	private function fix($value) {
		return preg_replace('/ +/', '', $value);
	}
	
	
	private function traiterTableau($str) {
		
		// nom des balises de tables à rechercher
		$TABLE_TAG = 'table';
		// classe des tables à traiter
		$TABLE_CLASS = 'table';
		// classe des tables d'informations sur les tableaux
		$TAB_CLASS = 'systitleandfootercontainer';
		// classe de la ligne où on va récupérer la date de traitement
		$DATE_CLASS = 'c systemtitle';

		// Init des tableaux de travail
		$headerArray = array();
		$outputArray = array();
		$ret = array();

		// Les données à récupérer sont dans des balises <$TABLE_TAG> de classe '$TABLE_CLASS'
		// Les détails sont dans les lignes <td>
		// Les totaux et sous-totaux sont dans les lignes <th>
		
		// Vire ces putains de tags <a> qui font bugguer loadHTML() avec certains tableaux
		$str = preg_replace("/<a[^>]+\>/i", "", $str); 
		$str = preg_replace("/<\/a>/i", "", $str); 

		$doc = new DOMDocument();
		$doc->loadHTML($str);
		
		// Toutes les tables du fichier
		$tables = $doc->getElementsByTagName($TABLE_TAG);
		
		foreach ($tables as $key0 => $table) {
			$tab = array();
			if ($table->attributes > 0) {
				$classe = strtolower($table->getAttribute('class'));
				if ($classe == $TABLE_CLASS) {
					
					// Données présentes dans les headers et les footes (lignes fond bleu) des tableaux
					$tab_header = array();
					$tab_header[] = $this->parse_node($table->getElementsByTagName('th'));
					
					// Données présentes dans les tableaux (lignes fond blanc)
					$tbody = $table->getElementsByTagName('tbody');
					$tr = $tbody->item(0)->getElementsByTagName('tr');
					$rows = array();
					foreach ($tr as $row) {
						// Seuls les lignes <tr> avec des colonnes <td> nous intéressent.
						// Les lignes <tr> avec des tags <th> sont donc ignorées car déjà traitées par $tab_header
						$k = $row->getElementsByTagName('td');
						if ($k->length > 0) {
							$rows[] = $this->parse_node($k);
						}
					}
					$tab[0] = $tab_header;
					$tab[1] = $rows;
					$outputArray[] = $tab;
				}
				// Extraction de la date de traitement
				// On ne la récupère que si elle n'a pas encore été récupée pour s'éviter des traitements inutiles
				elseif ($classe == $TAB_CLASS && !isset($headerArray['mat2a_date'])) {
					$td = $table->getElementsByTagName('td');
					foreach($td as $row) {
						if (strtolower($row->getAttribute('class')) == $DATE_CLASS) {
							$value = trim($row->nodeValue);
							$headerArray['mat2a_date'] = preg_replace("@^.*([0-9]{2})\/([0-9]{2})\/([0-9]{4})$@", '\\3-\\2-\\1', $value);
						}
					}
				}
			}
		}
		// Retourne -1 s'il y a eu un problème pendant le traitement
		if (count($outputArray) > 0 ) {
			$ret[0] = $headerArray;
			$ret[1] = $outputArray;
		}
		else {
			$ret = -1;
		}
		return $ret;
	}
	
	
	/**
	 * Fonction utilitaire qui pousse la valeur de chaque noeud d'une liste de noeuds DOM dans un tableau
	 * et retourne ce tableau
	 */
	private function parse_node($nodeList) {
		$columns = array();
		foreach ($nodeList as $value) {
			$tmpText = utf8_decode(trim($value->nodeValue));
			if ($tmpText == '.') {
				// Traitement d'un cas particulier où une valeur numérique
				// est égale au caractère point.
				$tmpText = 0.0;
			}
			$tmpNum = str_replace(array(',', ' '), array('.', ''), $tmpText);
			if (is_numeric($tmpNum)) {
				$tmpText = (float) $tmpNum;
			}
			$columns[] = $tmpText;
		}
		return $columns;
	}
	
	
	/**
	 * Deprecated. Ancien nom = traiterTableau($str)
	 * 
	 * @param String $str la source de l'HTML du tableau T01.
	 * @return Array le tableau au format array PHP.
	 */
	private function traiterTableauOld($str) {
		
		$ret = array();
		// Nettoyage des balises superflues
		$str = str_replace('<br>', ' ', $str);
		$str = str_replace('<colgroup>', '', $str);
		$str = str_replace('<col>', '', $str);
		$str = str_replace('</colgroup>', '', $str);
		
		// Interprétation du HTML.
		$html = str_get_html($str);
		if ($html != false) {
			// Extraction de la date de traitement MAT2A
			$headerArray = array();
			$tmpMat2aDate = trim($html->find('td[class=\'c SystemTitle\']', 0)->plaintext);
			$headerArray['mat2a_date'] = preg_replace("@^.*([0-9]{2})\/([0-9]{2})\/([0-9]{4})$@", '\\3-\\2-\\1', $tmpMat2aDate);
			
			// Extraction du tableau de données
			$outputArray = array();
			
			foreach ($html->find('table.Table') as $table) {
				$tmpHeader = array();
				$tableArray = array();
				foreach ($table->find('th') as $th) {
					$tmpHeader[] = trim($th->plaintext);
				}
				$tableArray[] = $tmpHeader;
				foreach ($table->find('tr') as $tr) {
					$tmpData = array();
					foreach ($tr->find('td') as $td) {
						$tmpText = trim($td->plaintext);
						if ($tmpText == '.') {
							// Traitement d'un cas particulier où une valeur numérique
							// est égale au caractère point.
							$tmpText = 0.0;
						}
						$tmpNum = str_replace(array(',', ' '), array('.', ''), $tmpText);
						if (is_numeric($tmpNum)) {
							$tmpText = (float) $tmpNum;
						}
						$tmpData[] = $tmpText;
					}
					if (count($tmpData) > 0) {
						$tableArray[] = $tmpData;
					}
				}
				$outputArray[] = $tableArray;
			}
			
			$html->clear();
			unset($html);
			
			$ret[0] = $headerArray;
			$ret[1] = $outputArray;
		}
		else {
			$ret = -1;
		}
		return $ret;
		
	}
}

?>
