Commit 62c1729f authored by Théo GUILLON's avatar Théo GUILLON
Browse files

Ajout : mise en place du typage des annexes

parent 9e3c9597
......@@ -181,5 +181,45 @@ INSERT INTO normes (norme, numero, libelle, description, name_fichier, fichier,
('MR', '006', 'Études nécessitant l’accès aux données du PMSI par les industriels de santé', 'La MR 006 encadre l’accès par des industriels de santé aux données du Programme de médicalisation des systèmes d''information (PMSI) de l’Agence technique de l’information sur l’hospitalisation (ATIH) mises à disposition via une solution sécurisée. Les responsables de traitement ont l’obligation de documenter les projets menés dans le registre des activités de traitement. Les études menées doivent présenter un caractère d’intérêt public et aucun appariement avec d’autres données à caractère personnel n’est possible. Les responsables de traitement doivent enregistrer leurs traitements auprès d’un répertoire public tenu par l’INDS. Les industriels devront recourir à un bureau d’études/laboratoires de recherches ayant réalisé un engagement de conformité au référentiel fixé par l’arrêté du 17 juillet 2017 auprès de la CNIL. Ils devront également faire réaliser un audit indépendant tous les 3 ans sur l’utilisation des données et le respect de l’interdiction des finalités interdites.', 'MR-006.pdf', '1584952271.pdf', NOW(), NOW()),
('RS', '001', 'Gestion des vigilances sanitaires', 'Le référentiel « RS-001 » encadre les traitements de données à caractère personnel mis en œuvre à des fins de gestion des vigilances sanitaires. Ce référentiel s’applique à l’ensemble des vigilances sanitaires visées par l''arrêté du 27 février 2017 fixant la liste des catégories d''événements sanitaires indésirables pour lesquels la déclaration ou le signalement peut s''effectuer au moyen du portail de signalement des événements sanitaires indésirables (pharmacovigilance, cosmétovigilance, addictovigilance, hémovigilance, etc.) . Seuls les fabricants, entreprises, exploitants, organismes responsables de la mise sur le marché d''un médicament, d''un dispositif ou d''un produit peuvent effectuer un engagement de conformité au référentiel « RS-001 ». Ce référentiel ne couvre pas les traitements mis en œuvre par les professionnels de santé et les systèmes ou services de soins de santé (p. ex. : établissements de santé, maisons de santé, centres de santé, agences sanitaires, etc.).', 'RS-001.pdf', '1584952286.pdf', NOW(), NOW());
INSERT INTO liste_droits (libelle, value, created, modified) VALUES
('Gestion du typage des annexes', 32, NOW(), NOW());
CREATE TABLE typages (
id SERIAL NOT NULL PRIMARY KEY,
libelle VARCHAR(255) NOT NULL,
createdbyorganisation INT DEFAULT NULL,
created timestamp without time zone NOT NULL,
modified timestamp without time zone NOT NULL
);
CREATE UNIQUE INDEX typages_libelle_idx ON typages (libelle);
INSERT INTO typages (libelle, created, modified) VALUES
('Sous-traitance', NOW(), NOW()),
('Co-responsabilité', NOW(), NOW()),
('AIPD', NOW(), NOW()),
('Autre', NOW(), NOW());
CREATE TABLE typages_organisations (
id SERIAL PRIMARY KEY NOT NULL,
typage_id INTEGER NOT NULL REFERENCES typages(id) ON DELETE CASCADE ON UPDATE CASCADE,
organisation_id INTEGER NOT NULL REFERENCES organisations(id) ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE UNIQUE INDEX typages_organisations_typage_id_organisation_id_idx ON typages_organisations (typage_id, organisation_id);
INSERT INTO role_droits (role_id, liste_droit_id)
SELECT roles.id, liste_droits.id
FROM roles
LEFT OUTER JOIN liste_droits ON (1 = 1)
WHERE
roles.libelle = 'DPO'
AND liste_droits.libelle <> 'Créer une organisation'
ORDER BY roles.id, liste_droits.id;
INSERT INTO typages_organisations (typage_id, organisation_id)
SELECT typages.id, organisations.id
FROM typages
LEFT OUTER JOIN organisations ON (1 = 1);
COMMIT;
<?php
/**
* TypagesController
*
* 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 App.Controller
*/
App::uses('ListeDroit', 'Model');
class TypagesController extends AppController {
public $uses = [
'Typage',
'TypageOrganisation',
'Organisation'
];
/**
* @throws ForbiddenException
*
* @author Théo GUILLON <theo.guillon@libriciel.coop>
* @access public
* @created 12/04/2018
* @version v1.0.0
*/
public function index() {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$this->set('title', __d('responsable', 'responsable.titreGestionResponsableApplication'));
$condition = [];
$query = [
'contain' => [
'Organisation' => [
'raisonsociale',
'order' => ['raisonsociale']
]
],
'order' => [
'Responsable.raisonsocialestructure ASC'
]
];
if ($this->request->is('post')) {
// Affectation
if (!empty($this->request->data['ResponsableOrganisation']['organisation_id'])) {
if (isset($this->request->data['ResponsableOrganisation']) === true) {
$success = true;
$this->Organisation->begin();
$organisations_ids = Hash::extract($this->request->data, 'ResponsableOrganisation.organisation_id');
$responsables_ids = Hash::extract($this->request->data, 'ResponsableOrganisation.responsable_id');
foreach ($organisations_ids as $organisation_id) {
$responsableEntite = [];
$responsableEntite = $this->ResponsableOrganisation->find('list', [
'conditions' => [
'organisation_id' => $organisation_id
],
'fields' => [
'responsable_id'
]
]);
$diff = array_diff($responsableEntite, $responsables_ids);
$resultResponsable = [];
if (!empty($diff)) {
$resultResponsable = array_merge($responsables_ids, $responsableEntite);
} else {
$resultResponsable = $responsables_ids;
}
$data = [
'Organisation' => [
'id' => $organisation_id,
],
'Responsable' => [
'Responsable' => $resultResponsable
]
];
$this->Organisation->create($data);
$success = $success && false !== $this->Organisation->save(null, ['atomic' => false]);
}
if ($success == true) {
$this->Organisation->commit();
$this->Session->setFlash(__d('responsable', 'responsable.flashsuccessSousTraitantAffecterEnregistrer'), 'flashsuccess');
$this->redirect(['action' => 'index']);
} else {
$this->Organisation->rollback();
$this->Session->setFlash(__d('responsable', 'responsable.flasherrorErreurEnregistrementSousTraitantAffecter'), 'flasherror');
}
}
}
// Filtre
if (isset($this->request->data['Filtre']) === true) {
$condition = $this->_findFiltre($condition);
$query['conditions'] = $condition;
// Filtre sur l'utilisateur à l'origine du traitement
if (!empty($this->request->data['Filtre']['organisation'])) {
$subQuery = [
'alias' => 'responsables_organisations',
'fields' => [
'responsables_organisations.responsable_id'
],
'conditions' => [
'responsables_organisations.organisation_id' => $this->request->data['Filtre']['organisation']
]
];
$sql = $this->Responsable->ResponsableOrganisation->sql($subQuery);
$query['conditions'][] = "Responsable.id IN ( {$sql} )";
}
}
}
$this->paginate = $query;
$responsables = $this->paginate($this->Responsable);
$this->set(compact('responsables'));
$mesOrganisations = $this->WebcilUsers->organisations(
'list',
[
'droits' => 'add' === $this->request->params['action']
? ListeDroit::CREER_UTILISATEUR
: ListeDroit::MODIFIER_UTILISATEUR
]
);
$this->set(compact('mesOrganisations'));
$options = $this->_optionsFiltre();
$this->set(compact('options'));
}
private function _optionsFiltre($organisation_id = null) {
$query = [];
$condition = [];
if ($organisation_id !== null) {
$query = [
'conditions' => $condition,
'order' => [
'Responsable.raisonsocialestructure ASC'
]
];;
$subQuery = [
'alias' => 'responsables_organisations',
'fields' => [
'responsables_organisations.responsable_id'
],
'conditions' => [
'responsables_organisations.organisation_id' => $organisation_id
]
];
$sql = $this->ResponsableOrganisation->sql($subQuery);
$query['conditions'][] = "Responsable.id IN ( {$sql} )";
}
$query['fields'] = 'raisonsocialestructure';
$raisonsociale = $this->Responsable->find('list', $query);
$query['fields'] = 'siretstructure';
$siret = $this->Responsable->find('list', $query);
$query['fields'] = 'apestructure';
$ape = $this->Responsable->find('list', $query);
$options = [
'raisonsocialestructure' => array_combine($raisonsociale, $raisonsociale),
'siretstructure' => array_combine($siret, $siret),
'apestructure' => array_combine($ape, $ape)
];
return ($options);
}
private function _findFiltre($condition) {
// Filtre sur le numéro de siret
if (!empty($this->request->data['Filtre']['siretstructure'])) {
$condition['Responsable.siretstructure'] = $this->request->data['Filtre']['siretstructure'];
}
// Filtre sur le code ape
if (!empty($this->request->data['Filtre']['apestructure'])) {
$condition['Responsable.apestructure'] = $this->request->data['Filtre']['apestructure'];
}
// Filtre sur la raison sociale
if (!empty($this->request->data['Filtre']['raisonsocialestructure'])) {
$condition['Responsable.raisonsocialestructure'] = $this->request->data['Filtre']['raisonsocialestructure'];
}
return ($condition);
}
/**
*
* @throws ForbiddenException
*
* @author Théo GUILLON <theo.guillon@libriciel.coop>
* @access public
* @created 12/04/2018
* @version v1.0.0
*/
public function entite() {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$this->set('title', __d('responsable', 'responsable.titreGestionResponsableEntitee'));
$organisation_id = $this->Session->read('Organisation.id');
$condition = [];
if ($this->request->is('post')) {
// Filtre
if (isset($this->request->data['Filtre']) === true) {
$condition = $this->_findFiltre($condition);
}
}
$query = [
'conditions' => $condition,
'order' => [
'Responsable.raisonsocialestructure ASC'
]
];
$subQuery = [
'alias' => 'responsables_organisations',
'fields' => [
'responsables_organisations.responsable_id'
],
'conditions' => [
'responsables_organisations.organisation_id' => $organisation_id
]
];
$sql = $this->ResponsableOrganisation->sql($subQuery);
$query['conditions'][] = "Responsable.id IN ( {$sql} )";
$this->paginate = $query;
$responsables = $this->paginate($this->Responsable);
$this->set(compact('responsables'));
$options = $this->_optionsFiltre($organisation_id);
$this->set(compact('options'));
}
/**
* Fonction qui permet l'ajout d'une nouvelle norme
*
* @throws ForbiddenException
*
* @author Théo GUILLON <theo.guillon@libriciel.coop>
* @access public
* @created 20/12/2017
* @version V1.0.0
*/
public function add()
{
return $this->edit();
}
/**
* Fonction qui permet la modification d'une norme
*
* @param int $id
* @throws ForbiddenException
*
* @author Théo GUILLON <theo.guillon@libriciel.coop>
* @access public
* @created 21/04/2020
* @version V1.2.0
*/
public function edit($id = null)
{
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$this->set('title', __d('responsable', 'responsable.titreModifierResponsable'));
if ($this->request->is('post') || $this->request->is('put')) {
if ('Cancel' === Hash::get($this->request->data, 'submit')) {
$this->redirect($this->Referers->get());
}
$success = true;
$this->Responsable->begin();
$this->request->data['Responsable']['id'] = $id;
$this->Responsable->create($this->request->data['Responsable']);
$success = $success && false !== $this->Responsable->save();
if ($success == true) {
$responsableId = $this->Responsable->id;
$success = $this->ResponsableOrganisation->deleteAll([
'ResponsableOrganisation.responsable_id' => $responsableId
]) && $success;
if ($success == true && !empty($this->request->data['ResponsableOrganisation']['organisation_id'])) {
foreach ($this->request->data['ResponsableOrganisation']['organisation_id'] as $organisationId) {
if ($success == true) {
$this->ResponsableOrganisation->create([
'responsable_id' => $responsableId,
'organisation_id' => $organisationId
]);
$success = $success && false !== $this->ResponsableOrganisation->save();
}
}
}
}
if ($success == true) {
$this->Responsable->commit();
$this->Session->setFlash(__d('role', 'role.flashsuccessProfilEnregistrer'), 'flashsuccess');
$this->redirect($this->Referers->get());
} else {
$this->Responsable->rollback();
$this->Session->setFlash(__d('role', 'role.flasherrorErreurEnregistrementProfil'), 'flasherror');
}
}
$responsable = $this->Responsable->find('first', [
'conditions' => [
'id' => $id
]
]);
$this->request->data = $responsable;
$responsableOrganisation = $this->ResponsableOrganisation->find('all', [
'conditions' => [
'responsable_id' => $id
]
]);
$organisationResponsableSelect = Hash::extract($responsableOrganisation, '{n}.ResponsableOrganisation.organisation_id');
$optionsAffecter = [
'ResponsableOrganisation' => [
'organisation_id' => $organisationResponsableSelect
]
];
$this->request->data += $optionsAffecter;
$mesOrganisations = $this->WebcilUsers->organisations(
'list',
[
'droits' => 'add' === $this->request->params['action']
? ListeDroit::CREER_UTILISATEUR
: ListeDroit::MODIFIER_UTILISATEUR
]
);
$this->set(compact('mesOrganisations'));
$this->view = 'edit';
}
/**
* Permet de supprimer un responsable
*
* @param type $id | Id du responsable
*
* @author Théo GUILLON <theo.guillon@libriciel.coop>
* @access public
* @created 12/04/2018
* @version v1.0.0
*/
public function delete($id) {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$associationResponsable = $this->ResponsableOrganisation->find('all', [
'conditions' => [
'responsable_id' => $id
]
]);
if (empty($associationResponsable)) {
$success = true;
$this->Responsable->begin();
$success = $success && false !== $this->Responsable->deleteAll([
'id' => $id
]);
if ($success == true) {
$this->Responsable->commit();
$this->Session->setFlash(__d('responsable', 'responsable.flashsuccessSuppressionResponsableEntite'), 'flashsuccess');
} else {
$this->Responsable->rollback();
$this->Session->setFlash(__d('responsable', 'responsable.flasherrorErreurSuppressionResponsableEntite'), 'flasherror');
}
} else {
$this->Session->setFlash(__d('responsable', 'responsable.flasherrorErreurAssociationExistanteResponsableEntite'), 'flasherror');
}
$this->redirect($this->Referers->get());
}
/**
* Fonction qui permet de supprimer un responsable liée à l'entité
*
* @param int $responsableId
* @throws ForbiddenException
*
* @author Théo GUILLON <theo.guillon@libriciel.coop>
* @access public
* @created 12/04/2018
* @version v1.0.0
*/
public function dissocierResponsable($responsableId) {
if (true !== $this->Droits->authorized(ListeDroit::GESTION_CORESPONSABLE)) {
throw new ForbiddenException(__d('default', 'default.flasherrorPasDroitPage'));
}
$success = true;
$this->ResponsableOrganisation->begin();
$success = $success && false !== $this->ResponsableOrganisation->deleteAll([
'ResponsableOrganisation.organisation_id' => $this->Session->read('Organisation.id'),
'ResponsableOrganisation.responsable_id' => $responsableId
]);
if ($success == true) {
$this->ResponsableOrganisation->commit();
$this->Session->setFlash(__d('responsable', 'responsable.flashsuccessDissocierResponsableEntite'), 'flashsuccess');
} else {
$this->ResponsableOrganisation->rollback();
$this->Session->setFlash(__d('responsable', 'responsable.flasherrorErreurDissocierResponsableEntite'), 'flasherror');
}
$this->redirect($this->Referers->get());
}
}
......@@ -58,6 +58,7 @@ class ListeDroit extends AppModel {
const MODIFIER_ARTICLE_FAQ = 29; // Modifier un article dans la FAQ
const CONSULTER_ARTICLE_FAQ = 30; // Consulter un article dans la FAQ
const SUPPRIMER_ARTICLE_FAQ = 31; // Supprimer un article dans la FAQ
const GESTION_TYPAGE = 32; //Gestion des types d'annexes
const LISTE_DROITS_ADMINISTRATEUR = [
ListeDroit::REDIGER_TRAITEMENT,
......@@ -86,7 +87,8 @@ class ListeDroit extends AppModel {
ListeDroit::CREER_ARTICLE_FAQ,
ListeDroit::MODIFIER_ARTICLE_FAQ,
ListeDroit::CONSULTER_ARTICLE_FAQ,
ListeDroit::SUPPRIMER_ARTICLE_FAQ
ListeDroit::SUPPRIMER_ARTICLE_FAQ,
ListeDroit::GESTION_TYPAGE,
];
const LISTE_DROITS_REDACTEUR = [
......@@ -141,7 +143,8 @@ class ListeDroit extends AppModel {
ListeDroit::CREER_ARTICLE_FAQ,
ListeDroit::MODIFIER_ARTICLE_FAQ,
ListeDroit::CONSULTER_ARTICLE_FAQ,
ListeDroit::SUPPRIMER_ARTICLE_FAQ
ListeDroit::SUPPRIMER_ARTICLE_FAQ,
ListeDroit::GESTION_TYPAGE,
];
const LISTE_DROITS_DPO_MINIMUM = [
......@@ -160,7 +163,8 @@ class ListeDroit extends AppModel {
ListeDroit::CREER_ARTICLE_FAQ,
ListeDroit::MODIFIER_ARTICLE_FAQ,
ListeDroit::CONSULTER_ARTICLE_FAQ,
ListeDroit::SUPPRIMER_ARTICLE_FAQ
ListeDroit::SUPPRIMER_ARTICLE_FAQ,
ListeDroit::GESTION_TYPAGE,
];
/**
......
<?php
/**
* Model Responsable
*
* 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 Typage extends AppModel {
public $name = 'Typage';
public $validationDomain = 'validation';
/**
* validate associations
*
* @var array
*
* @access public
* @created 12/04/2018
* @version v1.0.0
*/
public $validate = [
'libelle' => [
'notBlank' => [
'rule' => ['notBlank']
]
],
];
/**
* hasMany associations
*
* @var array
*
* @access public
* @created 11/04/2018
* @version v1.0.0
*/
public $hasAndBelongsToMany = [
'Organisation' => [