Loading front/gulpfile.js +18 −1 Original line number Diff line number Diff line Loading @@ -86,9 +86,20 @@ exports.contratTypePCRUWatch = function(cb){ watch(pathModuleSrc + "ActivityTypeTree.vue", contratTypePCRU); } //// 2.5 Recherche d'activité et processus PCRU function createProcessusPCRU(cb) { compile("CreateProcessusPCRU"); cb(); } exports.createProcessusPCRU = createProcessusPCRU; exports.createProcessusPCRUWatch = function(cb){ watch(pathModuleSrc + "CreateProcessusPCRU.vue", createProcessusPCRU); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //// 3. COMPOSANTS ///////////////////////// COMPOSANTS COMPILES // --- Password function componentPassword(cb) { compileComponent('PasswordField'); cb(); Loading @@ -96,6 +107,7 @@ function componentPassword(cb) { exports.componentPassword = componentPassword; exports.componentPasswordWatch = function(cb){ watch('./src/components/PasswordField.vue', componentPassword); } // --- Textarea function componentTextarea(cb) { compileComponent('TextareaField'); cb(); Loading @@ -103,6 +115,8 @@ function componentTextarea(cb) { exports.componentTextarea = componentTextarea; exports.componentTextareaWatch = function(cb){ watch('./src/components/TextareaField.vue', componentTextarea); } // --- RNSRField function componentRNSRField(cb) { compileComponent('RNSRField'); cb(); Loading @@ -110,7 +124,10 @@ function componentRNSRField(cb) { exports.componentRNSRField = componentRNSRField; exports.componentRNSRFieldWatch = function(cb){ watch('./src/components/RNSRField.vue', componentRNSRField); } let commands = ['activityDocument', 'administrationPcru', 'administrationPcruPC', 'componentRNSRField']; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// let commands = ['activityDocument', 'administrationPcru', 'administrationPcruPC', 'componentRNSRField', 'createProcessusPCRU']; function defaultTask(cb) { console.log("Usage : "); Loading front/src/CreateProcessusPCRU.vue 0 → 100644 +155 −0 Original line number Diff line number Diff line <template> <div id="contrattypepcru"> <ajax-oscar :oscar-remote-data="remoteState"/> <div class="overlay" v-if="searchActivity"> <div class="overlay-content"> <h3>Rechercher une activité</h3> <input type="search" v-model="search" class="form-control lg" /> <section class="results"> <article class="card xs" v-for="a in activities"> <h3 class="card-title"> <code>{{ a.numOscar }}</code> <strong><i class="icon-cubes"></i> {{ a.projectacronym }}</strong> <em><i class="icon-cube"></i> {{ a.label }}</em> {{ a.label }}({{ a.PFI }})</h3> <div v-if="a.pcruenable"> <code>{{ a.pcru.status }}</code> <div class="alert alert-danger" v-if="a.pcru.errors.length > 0"> {{ a.pcru.errors }} </div> <div v-else> {{ a.pcru.datas }} </div> </div> <div v-else> <button class="btn xs" @click="handlerSelectActivity(a)">Activation PCRU</button> </div> </article> </section> </div> </div> <button class="btn btn-primary" @click="handlerSearchActivity"> <i class="icon-search-outline"></i> Rechercher une activité </button> <pre> {{ search }} </pre> </div> </template> <script> /******************************************************************************************************************/ /* ! DEVELOPPEUR Depuis la racine OSCAR : cd front Pour compiler en temps réél : node node_modules/.bin/gulp contratTypePCRUWatch Pour compiler : node node_modules/.bin/gulp contratTypePCRU */ import AjaxOscar from "./remote/AjaxOscar"; import OscarRemoteData from "./remote/OscarRemoteData"; // test let oscarRemoteData = new OscarRemoteData(); let searchTempo = null; export default { components: { "ajax-oscar": AjaxOscar }, props: { urlSearchActivities: { required: true }, urlActivityPCRUCreate: { required: true }, urlPreviewPCRU: { required: true }, }, data() { return { remoterState: oscarRemoteData.state, remoteState: oscarRemoteData.state, activities: [], searchActivity: false, selectedActivity: null, search: "" } }, watch: { search(val){ if( searchTempo ){ clearTimeout(searchTempo); } searchTempo = setTimeout(this.performSearch, 700); } }, methods: { handlerSearchActivity(){ this.searchActivity = true; }, handlerSelectActivity(activity){ this.selectedActivity = activity; let searchQuery = this.urlPreviewPCRU+'&activity_id=' + activity.id; oscarRemoteData .setDebug(true) .setPendingMessage("Calcule des données PCRU pour " + activity.id +"...") .setErrorMessage("Impossible de charger les données PCRU") .performGet(searchQuery, this.handlerPreviewSuccess); }, handlerPreviewSuccess(response){ this.selectedActivity.pcruenable = true; this.selectedActivity.pcru = { 'datas': response.data.preview.datas, 'errors': response.data.preview.errors, 'status': response.data.preview.status }; }, performSearch(){ let searchQuery = this.urlSearchActivities+'&search=' + this.search; oscarRemoteData .setDebug(true) .setPendingMessage("Recherche...") .setErrorMessage("Erreur de recherche") .performGet(searchQuery, this.handlerSearchSuccess); }, handlerClose(){ }, handlerSearchSuccess(response){ this.activities = response.data.activities; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TRAITEMENT des DONNEES }, mounted() { console.log("CreateProcessusPCRU mounted") } } </script> No newline at end of file module/Oscar/src/Oscar/Controller/ProjectGrantController.php +30 −22 Original line number Diff line number Diff line Loading @@ -2805,6 +2805,35 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif public function pcruListAction() { $pcruInfos = $this->getProjectGrantService()->getPCRUService()->getPcruInfos(); $methods = $this->getHttpXMethod(); if( $methods == 'GET' ){ $action = $this->params()->fromQuery('a'); // Recherche des activités if( $action == 'search' ){ $search = $this->params()->fromQuery('search'); $idsActivities = $this->getProjectGrantService()->search($search); $activities = []; /** @var Activity $activity */ foreach ($this->getProjectGrantService()->getActivitiesByIds($idsActivities) as $activity) { $a = $activity->toArray(); $a['pcru'] = []; $a['pcruenable'] = false; $activities[] = $a; } return $this->jsonOutput(["activities" => $activities]); } // Aperçu PCRU if( $action == 'preview' ){ $activity_id = $this->params()->fromQuery('activity_id'); $activity = $this->getProjectGrantService()->getActivityById($activity_id); $preview = $this->getProjectGrantService()->getPCRUService()->getPreview($activity); return $this->jsonOutput(["preview" => $preview]); } } return [ 'pcruInfos' => $pcruInfos ]; Loading @@ -2812,34 +2841,13 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif public function pcruInfosAction() { if( !$this->getOscarConfigurationService()->getPcruEnabled() ){ throw new OscarException("Le module PCR n'est pas activé"); } /** @var Activity $activity */ $activity = $this->getActivityFromRoute(); // Droit d'accès $this->getOscarUserContextService()->check(Privileges::ACTIVITY_PCRU, $activity); $factory = new ActivityPcruInfoFromActivityFactory($this->getOscarConfigurationService(), $this->getEntityManager()); $pcruInfos = $factory->createNew($activity); $headers = $factory->getHeaders(); $datas = $pcruInfos->toArray(); $validation = $pcruInfos->validation(); $documentPath = $this->getOscarConfigurationService()->getDocumentDropLocation().'/'.$pcruInfos->getDocumentPath(); // $valid = $pcruInfos->isValidToSend(); return [ //'form' => $form, 'validations' => $validation, 'headers' => $headers, 'datas' => $datas, 'activity' => $activity, 'documentPath' => $documentPath ]; return $this->getPCRUService()->getPreview($activity); } public function mergeAction() Loading module/Oscar/src/Oscar/Entity/ActivityPcruInfos.php +68 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ class ActivityPcruInfos const VALIDATION_ERROR = 'error'; const VALIDATION_EMPTY = 'empty'; /** * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") Loading Loading @@ -190,6 +192,27 @@ class ActivityPcruInfos */ private $poleCompetivite = ""; const STATUS_PREVIEW = "preview"; // Aperçu const STATUS_ERROR_DATA = "error_data"; // Erreur dans les données const STATUS_SEND_READY = "send_ready"; // Prêt pour envoi const STATUS_SEND_PENDING = "send_pending"; // Envoyé (attente du retour) const STATUS_ERROR_REMOTE = "error_remote"; // Erreur (retour PCRU) const STATUS_DONE = "done"; // Envoyé (OK) /** * @ORM\Column(type="string", length=20, nullable=true) */ private $status = ""; /** * @ORM\Column(type="array", nullable=true) */ private $error = []; /** * @var string Commentaire du gestionnaire de contrat * @ORM\Column(type="text", nullable=true) Loading Loading @@ -238,6 +261,15 @@ class ActivityPcruInfos */ private $documentId = null; /** * ActivityPcruInfos constructor. * @param string $status */ public function __construct() { $this->status = self::STATUS_PREVIEW; } public function toArray() :array { $out = []; Loading Loading @@ -998,4 +1030,40 @@ class ActivityPcruInfos { return $this->documentPath; } /** * @return string */ public function getStatus(): string { return $this->status; } /** * @param string $status */ public function setStatus(string $status): self { $this->status = $status; return $this; } /** * @return array */ public function getError(): ?array { return $this->error; } /** * @param array $error */ public function setError(?array $error): self { $this->error = $error; return $this; } } No newline at end of file module/Oscar/src/Oscar/Factory/ActivityPcruInfoFromActivityFactory.php +14 −4 Original line number Diff line number Diff line Loading @@ -37,8 +37,12 @@ class ActivityPcruInfoFromActivityFactory public function createNew(Activity $activity): ActivityPcruInfos { // Données PCRU $activityPcruInfos = new ActivityPcruInfos(); // Erreurs métiers $errors = []; // --- Recherche automatique de l'Unité (Laboratoire) // Intitulé du rôle "Laboratoire" pour PCRU Loading @@ -51,7 +55,7 @@ class ActivityPcruInfoFromActivityFactory // Récupération des laboratoires $structures = $activity->getOrganizationsWithRole($roleStructureToFind); if( count($structures) == 0 ){ throw new OscarException("Aucune structure $roleStructureToFind pour cette activité."); $errors[] = "Aucune structure $roleStructureToFind pour cette activité."; } Loading @@ -66,7 +70,7 @@ class ActivityPcruInfoFromActivityFactory } if( $codeUniteLabintel == "" ){ throw new OscarException("Le $roleStructureToFind (".implode(', ', $organizationsParsed).") n'a pas de code LABINTEL"); $errors[] = "Le $roleStructureToFind (".implode(', ', $organizationsParsed).") n'a pas de code LABINTEL"; } // Recherche automatique du responsable scientifique Loading @@ -88,11 +92,12 @@ class ActivityPcruInfoFromActivityFactory if( $document->getTypeDocument()->getLabel() == $typeDocumentSigne ){ // Test sur les versions if( $documentSigned != null ){ throw new OscarException("Il y'a plusieurs $typeDocumentSigne sur cette activité"); } $errors[] = "Il y'a plusieurs $typeDocumentSigne sur cette activité"; } else { $documentSigned = $document->getPath(); } } } /** @var PcruTypeContractRepository $pcruContractTypeRepository */ $pcruContractTypeRepository = $this->entityManager->getRepository(PcruTypeContract::class); Loading @@ -118,6 +123,11 @@ class ActivityPcruInfoFromActivityFactory ->setDateDerniereSignature($activity->getDateSigned()) ->setReference($activity->getOscarNum()); if( count($errors) ){ $activityPcruInfos->setError($errors) ->setStatus(ActivityPcruInfos::STATUS_ERROR_DATA); } return $activityPcruInfos; } Loading Loading
front/gulpfile.js +18 −1 Original line number Diff line number Diff line Loading @@ -86,9 +86,20 @@ exports.contratTypePCRUWatch = function(cb){ watch(pathModuleSrc + "ActivityTypeTree.vue", contratTypePCRU); } //// 2.5 Recherche d'activité et processus PCRU function createProcessusPCRU(cb) { compile("CreateProcessusPCRU"); cb(); } exports.createProcessusPCRU = createProcessusPCRU; exports.createProcessusPCRUWatch = function(cb){ watch(pathModuleSrc + "CreateProcessusPCRU.vue", createProcessusPCRU); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //// 3. COMPOSANTS ///////////////////////// COMPOSANTS COMPILES // --- Password function componentPassword(cb) { compileComponent('PasswordField'); cb(); Loading @@ -96,6 +107,7 @@ function componentPassword(cb) { exports.componentPassword = componentPassword; exports.componentPasswordWatch = function(cb){ watch('./src/components/PasswordField.vue', componentPassword); } // --- Textarea function componentTextarea(cb) { compileComponent('TextareaField'); cb(); Loading @@ -103,6 +115,8 @@ function componentTextarea(cb) { exports.componentTextarea = componentTextarea; exports.componentTextareaWatch = function(cb){ watch('./src/components/TextareaField.vue', componentTextarea); } // --- RNSRField function componentRNSRField(cb) { compileComponent('RNSRField'); cb(); Loading @@ -110,7 +124,10 @@ function componentRNSRField(cb) { exports.componentRNSRField = componentRNSRField; exports.componentRNSRFieldWatch = function(cb){ watch('./src/components/RNSRField.vue', componentRNSRField); } let commands = ['activityDocument', 'administrationPcru', 'administrationPcruPC', 'componentRNSRField']; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// let commands = ['activityDocument', 'administrationPcru', 'administrationPcruPC', 'componentRNSRField', 'createProcessusPCRU']; function defaultTask(cb) { console.log("Usage : "); Loading
front/src/CreateProcessusPCRU.vue 0 → 100644 +155 −0 Original line number Diff line number Diff line <template> <div id="contrattypepcru"> <ajax-oscar :oscar-remote-data="remoteState"/> <div class="overlay" v-if="searchActivity"> <div class="overlay-content"> <h3>Rechercher une activité</h3> <input type="search" v-model="search" class="form-control lg" /> <section class="results"> <article class="card xs" v-for="a in activities"> <h3 class="card-title"> <code>{{ a.numOscar }}</code> <strong><i class="icon-cubes"></i> {{ a.projectacronym }}</strong> <em><i class="icon-cube"></i> {{ a.label }}</em> {{ a.label }}({{ a.PFI }})</h3> <div v-if="a.pcruenable"> <code>{{ a.pcru.status }}</code> <div class="alert alert-danger" v-if="a.pcru.errors.length > 0"> {{ a.pcru.errors }} </div> <div v-else> {{ a.pcru.datas }} </div> </div> <div v-else> <button class="btn xs" @click="handlerSelectActivity(a)">Activation PCRU</button> </div> </article> </section> </div> </div> <button class="btn btn-primary" @click="handlerSearchActivity"> <i class="icon-search-outline"></i> Rechercher une activité </button> <pre> {{ search }} </pre> </div> </template> <script> /******************************************************************************************************************/ /* ! DEVELOPPEUR Depuis la racine OSCAR : cd front Pour compiler en temps réél : node node_modules/.bin/gulp contratTypePCRUWatch Pour compiler : node node_modules/.bin/gulp contratTypePCRU */ import AjaxOscar from "./remote/AjaxOscar"; import OscarRemoteData from "./remote/OscarRemoteData"; // test let oscarRemoteData = new OscarRemoteData(); let searchTempo = null; export default { components: { "ajax-oscar": AjaxOscar }, props: { urlSearchActivities: { required: true }, urlActivityPCRUCreate: { required: true }, urlPreviewPCRU: { required: true }, }, data() { return { remoterState: oscarRemoteData.state, remoteState: oscarRemoteData.state, activities: [], searchActivity: false, selectedActivity: null, search: "" } }, watch: { search(val){ if( searchTempo ){ clearTimeout(searchTempo); } searchTempo = setTimeout(this.performSearch, 700); } }, methods: { handlerSearchActivity(){ this.searchActivity = true; }, handlerSelectActivity(activity){ this.selectedActivity = activity; let searchQuery = this.urlPreviewPCRU+'&activity_id=' + activity.id; oscarRemoteData .setDebug(true) .setPendingMessage("Calcule des données PCRU pour " + activity.id +"...") .setErrorMessage("Impossible de charger les données PCRU") .performGet(searchQuery, this.handlerPreviewSuccess); }, handlerPreviewSuccess(response){ this.selectedActivity.pcruenable = true; this.selectedActivity.pcru = { 'datas': response.data.preview.datas, 'errors': response.data.preview.errors, 'status': response.data.preview.status }; }, performSearch(){ let searchQuery = this.urlSearchActivities+'&search=' + this.search; oscarRemoteData .setDebug(true) .setPendingMessage("Recherche...") .setErrorMessage("Erreur de recherche") .performGet(searchQuery, this.handlerSearchSuccess); }, handlerClose(){ }, handlerSearchSuccess(response){ this.activities = response.data.activities; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TRAITEMENT des DONNEES }, mounted() { console.log("CreateProcessusPCRU mounted") } } </script> No newline at end of file
module/Oscar/src/Oscar/Controller/ProjectGrantController.php +30 −22 Original line number Diff line number Diff line Loading @@ -2805,6 +2805,35 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif public function pcruListAction() { $pcruInfos = $this->getProjectGrantService()->getPCRUService()->getPcruInfos(); $methods = $this->getHttpXMethod(); if( $methods == 'GET' ){ $action = $this->params()->fromQuery('a'); // Recherche des activités if( $action == 'search' ){ $search = $this->params()->fromQuery('search'); $idsActivities = $this->getProjectGrantService()->search($search); $activities = []; /** @var Activity $activity */ foreach ($this->getProjectGrantService()->getActivitiesByIds($idsActivities) as $activity) { $a = $activity->toArray(); $a['pcru'] = []; $a['pcruenable'] = false; $activities[] = $a; } return $this->jsonOutput(["activities" => $activities]); } // Aperçu PCRU if( $action == 'preview' ){ $activity_id = $this->params()->fromQuery('activity_id'); $activity = $this->getProjectGrantService()->getActivityById($activity_id); $preview = $this->getProjectGrantService()->getPCRUService()->getPreview($activity); return $this->jsonOutput(["preview" => $preview]); } } return [ 'pcruInfos' => $pcruInfos ]; Loading @@ -2812,34 +2841,13 @@ class ProjectGrantController extends AbstractOscarController implements UseNotif public function pcruInfosAction() { if( !$this->getOscarConfigurationService()->getPcruEnabled() ){ throw new OscarException("Le module PCR n'est pas activé"); } /** @var Activity $activity */ $activity = $this->getActivityFromRoute(); // Droit d'accès $this->getOscarUserContextService()->check(Privileges::ACTIVITY_PCRU, $activity); $factory = new ActivityPcruInfoFromActivityFactory($this->getOscarConfigurationService(), $this->getEntityManager()); $pcruInfos = $factory->createNew($activity); $headers = $factory->getHeaders(); $datas = $pcruInfos->toArray(); $validation = $pcruInfos->validation(); $documentPath = $this->getOscarConfigurationService()->getDocumentDropLocation().'/'.$pcruInfos->getDocumentPath(); // $valid = $pcruInfos->isValidToSend(); return [ //'form' => $form, 'validations' => $validation, 'headers' => $headers, 'datas' => $datas, 'activity' => $activity, 'documentPath' => $documentPath ]; return $this->getPCRUService()->getPreview($activity); } public function mergeAction() Loading
module/Oscar/src/Oscar/Entity/ActivityPcruInfos.php +68 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ class ActivityPcruInfos const VALIDATION_ERROR = 'error'; const VALIDATION_EMPTY = 'empty'; /** * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") Loading Loading @@ -190,6 +192,27 @@ class ActivityPcruInfos */ private $poleCompetivite = ""; const STATUS_PREVIEW = "preview"; // Aperçu const STATUS_ERROR_DATA = "error_data"; // Erreur dans les données const STATUS_SEND_READY = "send_ready"; // Prêt pour envoi const STATUS_SEND_PENDING = "send_pending"; // Envoyé (attente du retour) const STATUS_ERROR_REMOTE = "error_remote"; // Erreur (retour PCRU) const STATUS_DONE = "done"; // Envoyé (OK) /** * @ORM\Column(type="string", length=20, nullable=true) */ private $status = ""; /** * @ORM\Column(type="array", nullable=true) */ private $error = []; /** * @var string Commentaire du gestionnaire de contrat * @ORM\Column(type="text", nullable=true) Loading Loading @@ -238,6 +261,15 @@ class ActivityPcruInfos */ private $documentId = null; /** * ActivityPcruInfos constructor. * @param string $status */ public function __construct() { $this->status = self::STATUS_PREVIEW; } public function toArray() :array { $out = []; Loading Loading @@ -998,4 +1030,40 @@ class ActivityPcruInfos { return $this->documentPath; } /** * @return string */ public function getStatus(): string { return $this->status; } /** * @param string $status */ public function setStatus(string $status): self { $this->status = $status; return $this; } /** * @return array */ public function getError(): ?array { return $this->error; } /** * @param array $error */ public function setError(?array $error): self { $this->error = $error; return $this; } } No newline at end of file
module/Oscar/src/Oscar/Factory/ActivityPcruInfoFromActivityFactory.php +14 −4 Original line number Diff line number Diff line Loading @@ -37,8 +37,12 @@ class ActivityPcruInfoFromActivityFactory public function createNew(Activity $activity): ActivityPcruInfos { // Données PCRU $activityPcruInfos = new ActivityPcruInfos(); // Erreurs métiers $errors = []; // --- Recherche automatique de l'Unité (Laboratoire) // Intitulé du rôle "Laboratoire" pour PCRU Loading @@ -51,7 +55,7 @@ class ActivityPcruInfoFromActivityFactory // Récupération des laboratoires $structures = $activity->getOrganizationsWithRole($roleStructureToFind); if( count($structures) == 0 ){ throw new OscarException("Aucune structure $roleStructureToFind pour cette activité."); $errors[] = "Aucune structure $roleStructureToFind pour cette activité."; } Loading @@ -66,7 +70,7 @@ class ActivityPcruInfoFromActivityFactory } if( $codeUniteLabintel == "" ){ throw new OscarException("Le $roleStructureToFind (".implode(', ', $organizationsParsed).") n'a pas de code LABINTEL"); $errors[] = "Le $roleStructureToFind (".implode(', ', $organizationsParsed).") n'a pas de code LABINTEL"; } // Recherche automatique du responsable scientifique Loading @@ -88,11 +92,12 @@ class ActivityPcruInfoFromActivityFactory if( $document->getTypeDocument()->getLabel() == $typeDocumentSigne ){ // Test sur les versions if( $documentSigned != null ){ throw new OscarException("Il y'a plusieurs $typeDocumentSigne sur cette activité"); } $errors[] = "Il y'a plusieurs $typeDocumentSigne sur cette activité"; } else { $documentSigned = $document->getPath(); } } } /** @var PcruTypeContractRepository $pcruContractTypeRepository */ $pcruContractTypeRepository = $this->entityManager->getRepository(PcruTypeContract::class); Loading @@ -118,6 +123,11 @@ class ActivityPcruInfoFromActivityFactory ->setDateDerniereSignature($activity->getDateSigned()) ->setReference($activity->getOscarNum()); if( count($errors) ){ $activityPcruInfos->setError($errors) ->setStatus(ActivityPcruInfos::STATUS_ERROR_DATA); } return $activityPcruInfos; } Loading