Commit 050975a3 authored by tguillon's avatar tguillon
Browse files

Mise en place de l'export CSV au registre.

Rajout au registre la possibilité de filtré sur un ou plusieurs formulaire utiliser par les traitements.
L'export propose un fichier .zip à télécharger. Un fichier est créé par formulaire. Toutes les informations du traitement sont enregistrées dans le fichier CSV qui correspond à son formulaire.
parent 22c29a00
......@@ -28,10 +28,12 @@
/build
/dist
/tags
/app/files
/app/files/modeles
/app/files/piece_joint_traitement
/app/files/registre
/app/files/connecteurs
/app/files/export
# OS generated files #
######################
......
......@@ -45,6 +45,10 @@ define('CHEMIN_CONNECTEURS', APP . FICHIER . CONNECTEURS . DS);
define('AUTHENTIFICATION', DS . "authentifications");
define('CHEMIN_CONNECTEURS_AUTHENTIFICATION', APP . FICHIER . CONNECTEURS . AUTHENTIFICATION . DS);
//Dossier qui va contenir tous les exports csv execute
define('EXPORTS', DS . "exports");
define('CHEMIN_EXPORTS', APP . FICHIER . EXPORTS . DS);
//Format des dates et heures
define('FORMAT_DATE', '%e-%m-%Y');
define('FORMAT_DATE_HEURE', '%e-%m-%Y à %H:%M');
......
......@@ -37,6 +37,7 @@ class FichesController extends AppController {
'ExtraitRegistre',
'Fiche',
'Fichier',
'Formulaire',
'FormGeneric',
'FormGenerator.Champ',
'Historique',
......@@ -218,6 +219,7 @@ class FichesController extends AppController {
'ligne ASC'
]
]);
// @fixme factoriser dans une méthode à utiliser également dans l'édit
foreach ($champs as $champ) {
$details = json_decode(Hash::get($champ, 'Champ.details'));
......@@ -1180,4 +1182,159 @@ class FichesController extends AppController {
$this->redirect($this->Referers->get());
}
public function export($tabId) {
$ids = json_decode($tabId);
// On vérifie que $tadId n'est pas vide
if (empty($ids)) {
$this->Session->setFlash(__d('registre', 'registre.flasherrorAucunTraitementSelectionner'), 'flasherror');
$this->redirect($this->Referers->get());
}
//Pour la possition des traitements à l'exportation
$case = [];
foreach ($ids as $key => $value) {
$case[] = sprintf('WHEN "Fiche"."id" = %d THEN %d', $value, $key);
}
$case = sprintf('(CASE %s END) ASC', implode(' ', $case));
$traitements = $this->Fiche->find('all', [
'fields' => [
'Fiche.id',
'Fiche.form_id',
'Fiche.norme_id',
'Fiche.numero'
],
'conditions' => [
'Fiche.id' => $ids
],
'contain' => [
'Formulaire' => [
'fields' => [
'Formulaire.libelle'
],
'Champ' => [
'fields' => [
'Champ.details'
]
]
],
'Valeur' => [
'fields' => [
'Valeur.valeur',
'Valeur.champ_name'
]
],
'Norme' => [
'fields' => [
'Norme.norme',
'Norme.numero'
]
]
],
'order' => [
$case
]
]);
$csv = [];
foreach ($traitements as $traitement) {
$champs = Hash::extract($traitement['Formulaire'], 'Champ.details');
$names = Hash::extract($traitement['Valeur'], '{n}.champ_name');
$valeurs = Hash::extract($traitement['Valeur'], '{n}.valeur');
foreach ($names as $key => $name) {
foreach ($champs as $champ) {
$champ = json_decode($champ, true);
if ($name == $champ['name']) {//@fixme collisions possibles
$names[$key] = $champ['label'];
} else {
$names[$key] = __d('fiche', 'fiche.champ'.Inflector::camelize("{$name}"));
}
}
}
foreach ($valeurs as $key => $valeur) {
$valeurs[$key] = $valeur;
}
if (!isset($csv[$traitement['Formulaire']['id']])) {
$csv[$traitement['Formulaire']['id']] = [
array_merge(
[
'Numero d\'enregistrement au registre',
'Norme'
],
$names
)
];
$nameFileCsv[$traitement['Formulaire']['id']] = str_replace(' ', '_', $traitement['Formulaire']['libelle']);
}
$csv[$traitement['Formulaire']['id']][] = array_merge(
[
$traitement['Fiche']['numero'],
$traitement['Norme']['norme'] . '-' . $traitement['Norme']['numero'],
],
$valeurs
);
}
// On verifie si le dossier file existe. Si c'est pas le cas on le cree
if (!file_exists(APP . FICHIER)) {
mkdir(APP . FICHIER, 0777, true);
mkdir(APP . FICHIER . EXPORTS, 0777, true);
} else {
if (!file_exists(APP . FICHIER . EXPORTS)) {
mkdir(APP . FICHIER . EXPORTS, 0777, true);
}
}
$date = date("Y-m-d_H:i:s");
if (!file_exists(CHEMIN_EXPORTS . $date)) {
mkdir(CHEMIN_EXPORTS . $date, 0777, true);
}
$csvFiles = [];
foreach ($csv as $key => $valueCsv) {
//@fixme générer des noms de fichiers ou un dossier temporaire
$chemin = CHEMIN_EXPORTS . $date . DS . $nameFileCsv[$key].'_'.$date.'.csv';
$fp = fopen($chemin, 'w');
foreach ($valueCsv as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
$csvFiles[] = $chemin;
}
$path = tempnam(TMP, $this->Session->id().'_');
$zip = new ZipArchive();
if($zip->open($path, ZipArchive::CREATE) === true) {
foreach ($csvFiles as $csvFile) {
$zip->addFile($csvFile, basename($csvFile));
}
$zip->close();
} else {
$this->Session->setFlash(__d('fiche', 'flasherrorErreurCreationZip'), 'flasherror');
}
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=Extrait-CSV-'.$date.'.zip');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($path));
readfile($path);
unlink($path);
exit();
}
}
......@@ -31,6 +31,7 @@ class RegistresController extends AppController {
'EtatFiche',
'Fiche',
'Fichier',
'Formulaire',
'Modification',
'Norme',
'Organisation',
......@@ -141,6 +142,11 @@ class RegistresController extends AppController {
if (!empty($this->request->data['Registre']['norme'])) {
$condition['Fiche.norme_id'] = $this->request->data['Registre']['norme'];
}
// Filtre sur les formulaires
if (!empty($this->request->data['Registre']['formulaire'])) {
$condition['Fiche.form_id'] = $this->request->data['Registre']['formulaire'];
}
}
if (false === empty($conditionValeur)) {
......@@ -181,12 +187,8 @@ class RegistresController extends AppController {
]
]
],
'Fichier' => [
],
'Norme' => [
]
'Fichier' => [],
'Norme' => []
]
],
'order' => 'Fiche.created DESC',
......@@ -237,9 +239,27 @@ class RegistresController extends AppController {
$options = [
'users' => $this->WebcilUsers->users('list', ['restrict' => true]),
'services' => $this->WebcilUsers->services('list', ['restrict' => true])
'services' => $this->WebcilUsers->services('list', ['restrict' => true]),
'formulaires' => $this->Formulaire->find('list', [ 'id' => 'libelle'])
];
$this->set(compact('options'));
$optionsAction = [];
if ($this->Droits->authorized(ListeDroit::TELECHARGER_TRAITEMENT_REGISTRE) == true) {
$optionsAction[0] = __d('registre', 'registre.btnImprimerExtraitRegistrePDF');
}
$formulaires = [];
if ($this->Droits->authorized($this->Droits->isCil()) == true) {
if ($organisationActuelle['Organisation']['verrouiller'] == true) {
$optionsAction[1] = __d('registre', 'registre.btnImprimerTraitementRegistrePDF');
} else {
$optionsAction[2] = __d('registre', 'registre.btnGenererTraitementRegistrePDF');
}
$optionsAction[3] = __d('registre', 'registre.btnExportCsv');
}
$this->set(compact('optionsAction'));
}
/**
......
......@@ -49,6 +49,9 @@ msgstr "Une erreur est survenue lors de l'enregistrement. Merci de contacter vot
msgid "fiche.flasherrorErreurPDF"
msgstr "Une erreur est survenue lors de la récupération du PDF. Merci de contacter votre administrateur"
msgid "fiche.flasherrorErreurCreationZip"
msgstr "Une erreur est survenue lors de la création de l'archive. Merci de contacter votre administrateur"
###############################################################
###############################################################################
......@@ -78,16 +81,16 @@ msgid "fiche.textInfoContact"
msgstr "Information sur le rédacteur :"
msgid "fiche.champDeclarantpersonnenom"
msgstr "Prénom et nom "
msgstr "Prénom et nom du rédacteur"
msgid "fiche.champDeclarantservice"
msgstr "Service de déclaration du traitement"
msgid "fiche.champDeclarantpersonneportable"
msgstr "Téléphone portable"
msgstr "Téléphone portable du rédacteur"
msgid "fiche.champDeclarantpersonnefix"
msgstr "Téléphone fixe"
msgstr "Téléphone fixe du rédacteur"
msgid "fiche.champDeclarantpersonneemail"
msgstr "E-mail du rédacteur"
......
......@@ -54,7 +54,7 @@ msgid "registre.textTableauNumeroEnregistrement"
msgstr "Numéro : "
msgid "registre.btnImprimerExtraitRegistrePDF"
msgstr " Générer les extraits de registre"
msgstr "Générer les extraits de registre"
msgid "registre.btnGenerer"
msgstr "Générer"
......@@ -63,10 +63,10 @@ msgid "registre.btnTélécharger"
msgstr "Télécharger"
msgid "registre.btnImprimerTraitementRegistrePDF"
msgstr " Télécharger les déclarations"
msgstr "Télécharger les déclarations"
msgid "registre.btnGenererTraitementRegistrePDF"
msgstr " Générer les déclarations"
msgstr "Générer les déclarations"
msgid "registre.commentaireTelechargeRegistrePDF"
msgstr "Télécharger le traitement"
......@@ -159,7 +159,7 @@ msgid "registre.textAnnulerTraitementAfficher"
msgstr "Il n'y a aucun traitement à afficher"
msgid "registre.popupPositionnement"
msgstr "Choisissez la position des traitements pour la génération"
msgstr "Choisissez la position des traitements"
msgid "registre.textTableauPositionTraitement"
msgstr "Position"
......@@ -167,4 +167,16 @@ msgstr "Position"
msgid "registre.textAucuneNormeDefini"
msgstr " Aucune norme n'a été définie"
msgid "registre.btnExportCsv"
msgstr "Exporter au format .csv"
msgid "registre.btnExport"
msgstr "Exporter"
msgid "registre.placeholderSelectionnerFormulaire"
msgstr "Sélectionner un formulaire"
msgid "registre.filtreFormulaire"
msgstr "Filtrer par formulaire"
###############################################################################
\ No newline at end of file
<?php
/**
* Champ Formulaire
*
* web-DPO : Outil de gestion de vos traitements dans le cadre de la
* réglementation relative à la protection des données personnelles (RGPD)
*
* Copyright (c) Libriciel SCOP (https://www.libriciel.fr/)
*
* Licensed under The CeCiLL V2 License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Libriciel SCOP (https://www.libriciel.fr/)
* @link https://www.libriciel.fr/web-cil/
* @since web-DPO v1.0.0
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.html CeCiLL V2 License
* @version v1.0.0
* @package AppModel
*/
App::uses('AppModel', 'Model');
class Champ extends AppModel {
public $tablePrefix = 'fg_';
/**
* hasOne associations
*
* @var array
*
* @author Théo GUILLON <theo.guillon@adullact-projet.coop>
* @access public
* @created 19/04/2018
* @version V1.0.0
*/
public $hasOne = [
'Formulaire' => [
'className' => 'Formulaire',
'foreignKey' => 'formulaires_id'
]
];
}
......@@ -88,6 +88,14 @@ class Fiche extends AppModel {
'className' => 'Norme',
'foreignKey' => 'norme_id',
'dependent' => true
],
'Formulaire' => [
'className' => 'Formulaire',
'foreignKey' => 'form_id'
],
'Champ' => [
'className' => 'Champ',
'foreignKey' => 'formulaires_id'
]
];
......
......@@ -42,6 +42,10 @@ class Formulaire extends AppModel {
'className' => 'Modele',
'foreignKey' => 'formulaires_id',
'dependent' => true
],
'Fiche' => [
'className' => 'Fiche',
'foreignKey' => 'form_id'
]
];
......@@ -61,5 +65,12 @@ class Formulaire extends AppModel {
'foreignKey' => 'service_id'
]
];
public $hasMany = [
'Champ' => [
'className' => 'Champ',
'foreignKey' => 'formulaires_id'
]
];
}
......@@ -294,6 +294,7 @@
<div class="col-md-6">
<?php
$incrementation_id = 0;
foreach ($champs as $value) {
if ($value['Champ']['colonne'] > $col) {
?>
......
......@@ -685,7 +685,7 @@ class BanettesHelper extends AppHelper {
$options = ['class' => 'commentaireRefus', 'id' => "commentaireRefus{$fiche_id}"];
$content = $this->WebcilForm->create('EtatFiche', [
'action' => 'refuse',
'url' => ['action' => 'refuse'],
'autocomplete' => 'off',
'inputDefaults' => ['div' => false],
'class' => 'form-horizontal',
......
......@@ -428,7 +428,7 @@
<ul class="dropdown-menu" role="menu">
<li>
<?php
echo '<li>' . $this->Html->link('<i class="fa fa-plug fa-fw"></i>' . __d('default', 'default.sousTitreLesSousTraitants'), [
echo '<li>' . $this->Html->link('<i class="fa fa-address-card fa-fw"></i>' . __d('default', 'default.sousTitreLesSousTraitants'), [
'controller' => 'soustraitants',
'action' => 'index'
], ['escape' => false]) . '</li>';
......@@ -436,7 +436,7 @@
</li>
<li>
<?php
echo '<li>' . $this->Html->link('<i class="fa fa-clock-o fa-fw"></i>' . __d('default', 'default.sousTitreMesSousTraitants'), [
echo '<li>' . $this->Html->link('<i class="fa fa-link fa-fw"></i>' . __d('default', 'default.sousTitreMesSousTraitants'), [
'controller' => 'soustraitants',
'action' => 'entite',
], ['escape' => false]) . '</li>';
......
......@@ -220,7 +220,7 @@
'div',
$this->Html->tag(
'div',
$this->WebcilForm->create('Registre', ['url' => 'add'])
$this->WebcilForm->create('Registre', ['url' => ['action' => 'add']])
.$this->WebcilForm->input('Registre.numero', [
'id' => 'numero',
'label' => [
......
......@@ -146,6 +146,29 @@
]);
?>
</div>
<!-- Filtre sur les formulaires -->
<div class="input-group login">
<span class="input-group-addon">
<?php
echo $this->Form->label('formulaire', '', [
'class' => 'fa fa-file-text-o fa-lg',
'title' => __d('registre', 'registre.filtreFormulaire')
]);
?>
</span>
<?php
echo $this->Form->input('formulaire', [
'options' => $options['formulaires'],
'class' => 'usersDeroulant transformSelect form-control',
'empty' => true,
'data-placeholder' => __d('registre', 'registre.placeholderSelectionnerFormulaire'),
'label' => false,
'multiple' => true
]);
?>
</div>
<?php
if ($organisationActuelle['Organisation']['verrouiller'] == true) {
......@@ -215,20 +238,6 @@
<fieldset>
<div class="pull-left" style="min-width:30em">
<?php
$optionsAction = [];
if ($this->Autorisation->authorized('7', $this->Session->read('Droit.liste'))) {
$optionsAction[0] = __d('registre', 'registre.btnImprimerExtraitRegistrePDF');
}
if ($organisationActuelle['Organisation']['cil'] == $this->Session->read('Auth.User.id')) {
if ($organisationActuelle['Organisation']['verrouiller'] == true) {
$optionsAction[1] = __d('registre', 'registre.btnImprimerTraitementRegistrePDF');
} else {
$optionsAction[2] = __d('registre', 'registre.btnGenererTraitementRegistrePDF');
}
}
echo $this->Form->input('action',[
'id' => 'action',
'options' => $optionsAction,
......@@ -244,6 +253,26 @@
?>
</div>
<!-- <span class="fa fa-arrow-right pull-left" style="margin-left:30px; margin-top: 7px"></span>
<div class="pull-left" style="min-width:30em; margin-top: -2em">
<?php
echo $this->Form->input('formulaire',[
'id' => 'formulaire',
'options' => $formulaires,
'class' => 'form-control usersDeroulant pull-left menuDeroulantFormulaire',
'label' => [
'text' => false,
'class' => false
],
'data-placeholder' => __d( 'registre', 'registre.placeholderSelectionnerFormulaire' ),
'disabled' => true,
'empty' => true,
'multiple' => true,
]);
?>
</div>-->
<span class="fa fa-arrow-right pull-left" style="margin-left:30px; margin-top: 7px"></span>
<div class="pull-left btnExecuter" style="margin-left:25px">
......@@ -271,29 +300,44 @@
?>
<?php
if ($organisationActuelle['Organisation']['cil'] == $this->Session->read('Auth.User.id') && $organisationActuelle['Organisation']['verrouiller'] == true) {
if ($organisationActuelle['Organisation']['cil'] == $this->Session->read('Auth.User.id')) {
if ($organisationActuelle['Organisation']['verrouiller'] == true) {
?>
<!--Bouton qui permet de choisir l'ordre de generation pour généré l'extrait de registre -->
<div class="pull-left btnTraitementRegistre" style="margin-left:25px">
<button type="button" class="btn btn-default-primary btn_telecharger" data-toggle="modal" data-target="#modalChangerPosition">
<span class="fa fa-download fa-lg"></span>
<?php
echo __d('registre', 'registre.btnTélécharger');
?>
</button>
</div>
<?php
} else {
?>
<!--Bouton qui permet de choisir l'ordre de generation pour généré l'extrait de registre -->
<div class="pull-left btnTraitementRegistreNonVerrouiller" style="margin-left:25px">
<button type="button" class="btn btn-default-primary btn_telechargerNonVerrouiller" data-toggle="modal" data-target="#modalChangerPosition">
<span class="fa fa-cogs fa-lg"></span>
<?php
echo __d('registre', 'registre.btnGenerer');
?>
</button>
</div>
<?php
}
?>
<!--Bouton qui permet de choisir l'ordre de generation pour généré l'extrait de registre -->
<div class="pull-left btnTraitementRegistre" style="margin-left:25px">
<button type="button" class="btn btn-default-primary btn_telecharger" data-toggle="modal" data-target="#modalChangerPosition">
<!--Bouton pour l'export csv -->
<div class="pull-left btnExportCsv" style="margin-left:25px">
<button type="button" class="btn btn-default-primary btn_exportCsv" data-toggle="modal" data-target="#modalChangerPosition">
<span class="fa fa-download fa-lg"></span>
<?php
echo __d('registre', 'registre.btnTélécharger');
?>
</button>
</div>
<?php
} else {
?>
<!--Bouton qui permet de choisir l'ordre de generation pour généré l'extrait de registre -->
<div class="pull-left btnTraitementRegistreNonVerrouiller" style="margin-left:25px">
<button type="button" class="btn btn-default-primary btn_telechargerNonVerrouiller" data-toggle="modal" data-target="#modalChangerPosition">
<span class="fa fa-cogs fa-lg"></span>
<?php
echo __d('registre', 'registre.btnGenerer');
echo __d('registre', 'registre.btnExport');
?>
</button>
</div>
<?php
}