Loading module/Oscar/src/Oscar/Controller/ProjectController.php +49 −12 Original line number Diff line number Diff line Loading @@ -281,8 +281,10 @@ class ProjectController extends AbstractOscarController if ($this->getRequest()->isXmlHttpRequest() || $format === 'json') { $method = $this->getRequest()->getMethod(); if($method === 'GET') { try { $perimeter = $this->params()->fromQuery('p', null); $perimeter = $this->params()->fromQuery('p', 'all'); $datas = $this->getProjectService()->api( $entity->getId(), $this->url(), Loading @@ -294,8 +296,42 @@ class ProjectController extends AbstractOscarController return $this->jsonError($e->getMessage()); } } elseif($method === 'POST') { throw new \Exception('Method POST not allowed'); } elseif($method === 'DELETE') { throw new \Exception('Method DELETE not allowed'); } elseif($method === 'PUT') { throw new \Exception('Method PUT not allowed'); } throw new \Exception("NOP !"); } $rolesPersons = $this->getOscarUserContextService()->getAvailabledRolesPersonActivity(); $rolesPersonsArray = array_map(function($id, $label) { return ['id' => (int)$id, 'label' => $label]; }, array_keys($rolesPersons), array_values($rolesPersons)); $rolesOrganizations = $this->getOscarUserContextService()->getAvailabledRolesOrganizationActivity(); $rolesOrganizationsArray = array_map(function($id, $label) { return ['id' => (int)$id, 'label' => $label]; }, array_keys($rolesOrganizations), array_values($rolesOrganizations)); return [ 'project' => $entity, 'params' => base64_encode(json_encode([ 'urlPerson' => $this->url()->fromRoute('project/persons', ['idproject' => $entity->getId()]), 'urlPersonNew' => $this->url()->fromRoute('personproject/new', ['idenroller' => $entity->getId()]), 'urlOrganization' => $this->url()->fromRoute('project/organizations', ['idproject' => $entity->getId()]), 'urlOrganizationNew' => $this->url()->fromRoute('organizationproject/new', ['idenroller' => $entity->getId()]), 'rolesPersons' => $rolesPersonsArray, 'rolesOrganizations' => $rolesOrganizationsArray, 'managePersons' => $this->getOscarUserContextService()->hasPrivileges(Privileges::PROJECT_PERSON_MANAGE, $entity), 'manageOrganizations' => $this->getOscarUserContextService()->hasPrivileges(Privileges::PROJECT_ORGANIZATION_MANAGE, $entity), 'foo' => 'bar', ])) ]; } catch (\Exception $e) { throw new OscarException($e->getMessage()); Loading Loading @@ -430,7 +466,7 @@ class ProjectController extends AbstractOscarController LogActivity::LEVEL_INCHARGE ); $this->flashMessenger()->addSuccessMessage( $this->flashMessenger()->addSuccessMessagpersonprojecte( sprintf( "Le projet '%s' a bien été créé.", $entity->log() Loading Loading @@ -490,6 +526,7 @@ class ProjectController extends AbstractOscarController public function personsAction(): JsonModel|Response { $this->getLoggerService()->info('personsAction'); try { // Récupération de l'activité $project = $this->getProjectService()->getProject($this->params()->fromRoute('idproject'), true); Loading module/Oscar/src/Oscar/Formatter/EnrollToArrayFormatter.php +1 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ class EnrollToArrayFormatter $output['id'] = $affectation->getId(); $output['shortname'] = $shortname; $output['longname'] = $longName; $output['enrolledShortLabel'] = $shortname; $output['enrolledLabel'] = $affectation->getEnrolled()->__toString(); $output['enrolled'] = $affectation->getEnrolled()->getId(); $output['active'] = $affectation->getEnrolled()->isActive(); Loading module/Oscar/src/Oscar/Service/ProjectService.php +60 −19 Original line number Diff line number Diff line Loading @@ -43,8 +43,9 @@ use Laminas\Mvc\Controller\Plugin\Url; */ class ProjectService implements UseServiceContainer { public const PERIMETER_CORE = 'core'; public const PERIMETER_ACTIVITIES = 'activities'; public const PERIMETER_BUDGET = 'budget'; public const PERIMETER_CORE = 'core'; public const PERIMETER_PERSONS = 'persons'; public const PERIMETER_ORGANIZATIONS = 'organizations'; public const PERIMETER_LOGS = 'logs'; Loading Loading @@ -122,10 +123,11 @@ class ProjectService implements UseServiceContainer public function getPerimetersKeys(): array { return [ self::PERIMETER_CORE, self::PERIMETER_ACTIVITIES, self::PERIMETER_PERSONS, self::PERIMETER_BUDGET, self::PERIMETER_CORE, self::PERIMETER_ORGANIZATIONS, self::PERIMETER_PERSONS, self::PERIMETER_LOGS, ]; } Loading Loading @@ -178,10 +180,22 @@ class ProjectService implements UseServiceContainer ]; } else { $read = $oscarUserContext->hasPrivileges(Privileges::PROJECT_SHOW, $project); $credentialsBudget = [ 'read' => true, 'edit' => true, ]; foreach ($project->getActivities() as $activity) { $credentialsBudget['read'] = $credentialsBudget['read'] && $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_PAYMENT_SHOW, $activity); $credentialsBudget['edit'] = $credentialsBudget['edit'] && $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_PAYMENT_MANAGE, $activity); } $credentials = [ 'read' => $read, self::PERIMETER_CORE => ['read' => $read], self::PERIMETER_ACTIVITIES => ['read' => $read], self::PERIMETER_BUDGET => $credentialsBudget, self::PERIMETER_CORE => ['read' => $read], self::PERIMETER_PERSONS => [ 'read' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_PERSON_SHOW, $project), 'edit' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_PERSON_MANAGE, $project), Loading Loading @@ -211,9 +225,7 @@ class ProjectService implements UseServiceContainer } switch ($perimeter) { case self::PERIMETER_CORE: $out['datas'][self::PERIMETER_CORE] = $this->getProjectDataCore($project, $urlPlugin); break; case self::PERIMETER_ACTIVITIES: $out['datas'][self::PERIMETER_ACTIVITIES] = $this->getProjectDataActivities( $project, Loading @@ -221,14 +233,25 @@ class ProjectService implements UseServiceContainer $oscarUserContext ); break; case self::PERIMETER_BUDGET: $out['datas'][self::PERIMETER_BUDGET] = $this->getProjectDataBudget($project, $urlPlugin); break; case self::PERIMETER_CORE: $out['datas'][self::PERIMETER_CORE] = $this->getProjectDataCore($project, $urlPlugin); break; case self::PERIMETER_PERSONS: $persons = []; $out['datas'][self::PERIMETER_PERSONS] = $this->getPersonsProjectsAPI($project, $persons, $urlPlugin); break; case self::PERIMETER_ORGANIZATIONS: $organizations = []; $out['datas'][self::PERIMETER_ORGANIZATIONS] = $this->getOrganizationsProjectsAPI($project, $organizations, $urlPlugin); break; case self::PERIMETER_LOGS: $logs = $this->getEntityManager()->getRepository(LogActivity::class)->getLogsProject($project->getId()); $out['datas'][self::PERIMETER_LOGS] = $logs; Loading Loading @@ -511,18 +534,6 @@ class ProjectService implements UseServiceContainer // IDS des PROJETS $datas = $this->getProjectGrantService()->search2($params); return $datas; // $idsProject = $this->getProjectGrantService()->searchProject($search); // $idsProjectsEmpty = $this->getProjectRepository()->getEmptyIds($search); // $idsProject = array_values(array_unique(array_merge($idsProject, $idsProjectsEmpty))); // // // Evite un IN() vide qui génère une erreur SQL (500) quand aucun projet ne correspond. // if (count($idsProject) === 0) { // $idsProject = [0]; // } // // return $qb = $this->getBaseQuery() // ->where('p.id IN (:ids)') // ->setParameter('ids', $idsProject); } /** Loading Loading @@ -909,4 +920,34 @@ class ProjectService implements UseServiceContainer } return $output; } private function getProjectDataBudget(object $project, Url $urlPlugin) { // $activities = []; /** @var ProjectGrantApiService $projectGrantApiService */ $projectGrantApiService = $this->getServiceContainer()->get(ProjectGrantApiService::class); $depenses = 0.0; $recettes = 0.0; $activitiesIds = []; foreach ($project->getActivities() as $activity) { $activitiesIds[] = $activity->getId(); $infosActivity = $projectGrantApiService->getBudgetActivity($activity, $urlPlugin); // $activities[] = $infosActivity; if($infosActivity['financialImpact'] === Activity::FINANCIAL_IMPACT_COST){ $depenses += $infosActivity['amount']; } if($infosActivity['financialImpact'] === Activity::FINANCIAL_IMPACT_TAKE){ $recettes += $infosActivity['amount']; } } return [ "info" => "budget", "urlSynthesis" => $urlPlugin->fromRoute('contract/spent-synthesis', ['id' => implode(',', $activitiesIds)]), "depenses" => $depenses, "recettes" => $recettes, // "activities" => $activities, ]; } } module/Oscar/view/oscar/project/show2.phtml +1 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ data-url="<?php echo $this->url('project/show2', ['id' => $project->getId()]) ?>" data-enrole-with-date="<?= $this->oscarConfig("enroleWithDate", true) ? "" : "false" ?>" data-manage="<?php $this->grant()->privilege(\Oscar\Provider\Privileges::PROJECT_EDIT, $project) ? "true" : "false" ?>" data-params="<?php echo $params ?>" ></div> <?= $this->Vite()->addJs('src/Project.js'); ?> </div> No newline at end of file ui/src/ActivityList.js +2 −2 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ import 'vue-select/dist/vue-select.css'; import ActivityTypeItem from "./components/ActivityTypeItem.vue"; import PrimeVue from "primevue/config"; import Aura from '@primeuix/themes/aura'; import {extractJsonFromBase64} from "./utils/Params.js"; let elemID = "#activity-list"; Loading @@ -27,7 +27,7 @@ try{ urlShowOrganization = elemDatas.dataset.urlShowOrganization; urlShowPerson = elemDatas.dataset.urlShowPerson; urlDelete = elemDatas.dataset.urlDelete; filtersOptions = JSON.parse(atob(elemDatas.dataset.filtersOptions)); filtersOptions = extractJsonFromBase64(elemDatas.dataset.filtersOptions); } catch (err){ console.error(err); } Loading Loading
module/Oscar/src/Oscar/Controller/ProjectController.php +49 −12 Original line number Diff line number Diff line Loading @@ -281,8 +281,10 @@ class ProjectController extends AbstractOscarController if ($this->getRequest()->isXmlHttpRequest() || $format === 'json') { $method = $this->getRequest()->getMethod(); if($method === 'GET') { try { $perimeter = $this->params()->fromQuery('p', null); $perimeter = $this->params()->fromQuery('p', 'all'); $datas = $this->getProjectService()->api( $entity->getId(), $this->url(), Loading @@ -294,8 +296,42 @@ class ProjectController extends AbstractOscarController return $this->jsonError($e->getMessage()); } } elseif($method === 'POST') { throw new \Exception('Method POST not allowed'); } elseif($method === 'DELETE') { throw new \Exception('Method DELETE not allowed'); } elseif($method === 'PUT') { throw new \Exception('Method PUT not allowed'); } throw new \Exception("NOP !"); } $rolesPersons = $this->getOscarUserContextService()->getAvailabledRolesPersonActivity(); $rolesPersonsArray = array_map(function($id, $label) { return ['id' => (int)$id, 'label' => $label]; }, array_keys($rolesPersons), array_values($rolesPersons)); $rolesOrganizations = $this->getOscarUserContextService()->getAvailabledRolesOrganizationActivity(); $rolesOrganizationsArray = array_map(function($id, $label) { return ['id' => (int)$id, 'label' => $label]; }, array_keys($rolesOrganizations), array_values($rolesOrganizations)); return [ 'project' => $entity, 'params' => base64_encode(json_encode([ 'urlPerson' => $this->url()->fromRoute('project/persons', ['idproject' => $entity->getId()]), 'urlPersonNew' => $this->url()->fromRoute('personproject/new', ['idenroller' => $entity->getId()]), 'urlOrganization' => $this->url()->fromRoute('project/organizations', ['idproject' => $entity->getId()]), 'urlOrganizationNew' => $this->url()->fromRoute('organizationproject/new', ['idenroller' => $entity->getId()]), 'rolesPersons' => $rolesPersonsArray, 'rolesOrganizations' => $rolesOrganizationsArray, 'managePersons' => $this->getOscarUserContextService()->hasPrivileges(Privileges::PROJECT_PERSON_MANAGE, $entity), 'manageOrganizations' => $this->getOscarUserContextService()->hasPrivileges(Privileges::PROJECT_ORGANIZATION_MANAGE, $entity), 'foo' => 'bar', ])) ]; } catch (\Exception $e) { throw new OscarException($e->getMessage()); Loading Loading @@ -430,7 +466,7 @@ class ProjectController extends AbstractOscarController LogActivity::LEVEL_INCHARGE ); $this->flashMessenger()->addSuccessMessage( $this->flashMessenger()->addSuccessMessagpersonprojecte( sprintf( "Le projet '%s' a bien été créé.", $entity->log() Loading Loading @@ -490,6 +526,7 @@ class ProjectController extends AbstractOscarController public function personsAction(): JsonModel|Response { $this->getLoggerService()->info('personsAction'); try { // Récupération de l'activité $project = $this->getProjectService()->getProject($this->params()->fromRoute('idproject'), true); Loading
module/Oscar/src/Oscar/Formatter/EnrollToArrayFormatter.php +1 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ class EnrollToArrayFormatter $output['id'] = $affectation->getId(); $output['shortname'] = $shortname; $output['longname'] = $longName; $output['enrolledShortLabel'] = $shortname; $output['enrolledLabel'] = $affectation->getEnrolled()->__toString(); $output['enrolled'] = $affectation->getEnrolled()->getId(); $output['active'] = $affectation->getEnrolled()->isActive(); Loading
module/Oscar/src/Oscar/Service/ProjectService.php +60 −19 Original line number Diff line number Diff line Loading @@ -43,8 +43,9 @@ use Laminas\Mvc\Controller\Plugin\Url; */ class ProjectService implements UseServiceContainer { public const PERIMETER_CORE = 'core'; public const PERIMETER_ACTIVITIES = 'activities'; public const PERIMETER_BUDGET = 'budget'; public const PERIMETER_CORE = 'core'; public const PERIMETER_PERSONS = 'persons'; public const PERIMETER_ORGANIZATIONS = 'organizations'; public const PERIMETER_LOGS = 'logs'; Loading Loading @@ -122,10 +123,11 @@ class ProjectService implements UseServiceContainer public function getPerimetersKeys(): array { return [ self::PERIMETER_CORE, self::PERIMETER_ACTIVITIES, self::PERIMETER_PERSONS, self::PERIMETER_BUDGET, self::PERIMETER_CORE, self::PERIMETER_ORGANIZATIONS, self::PERIMETER_PERSONS, self::PERIMETER_LOGS, ]; } Loading Loading @@ -178,10 +180,22 @@ class ProjectService implements UseServiceContainer ]; } else { $read = $oscarUserContext->hasPrivileges(Privileges::PROJECT_SHOW, $project); $credentialsBudget = [ 'read' => true, 'edit' => true, ]; foreach ($project->getActivities() as $activity) { $credentialsBudget['read'] = $credentialsBudget['read'] && $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_PAYMENT_SHOW, $activity); $credentialsBudget['edit'] = $credentialsBudget['edit'] && $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_PAYMENT_MANAGE, $activity); } $credentials = [ 'read' => $read, self::PERIMETER_CORE => ['read' => $read], self::PERIMETER_ACTIVITIES => ['read' => $read], self::PERIMETER_BUDGET => $credentialsBudget, self::PERIMETER_CORE => ['read' => $read], self::PERIMETER_PERSONS => [ 'read' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_PERSON_SHOW, $project), 'edit' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_PERSON_MANAGE, $project), Loading Loading @@ -211,9 +225,7 @@ class ProjectService implements UseServiceContainer } switch ($perimeter) { case self::PERIMETER_CORE: $out['datas'][self::PERIMETER_CORE] = $this->getProjectDataCore($project, $urlPlugin); break; case self::PERIMETER_ACTIVITIES: $out['datas'][self::PERIMETER_ACTIVITIES] = $this->getProjectDataActivities( $project, Loading @@ -221,14 +233,25 @@ class ProjectService implements UseServiceContainer $oscarUserContext ); break; case self::PERIMETER_BUDGET: $out['datas'][self::PERIMETER_BUDGET] = $this->getProjectDataBudget($project, $urlPlugin); break; case self::PERIMETER_CORE: $out['datas'][self::PERIMETER_CORE] = $this->getProjectDataCore($project, $urlPlugin); break; case self::PERIMETER_PERSONS: $persons = []; $out['datas'][self::PERIMETER_PERSONS] = $this->getPersonsProjectsAPI($project, $persons, $urlPlugin); break; case self::PERIMETER_ORGANIZATIONS: $organizations = []; $out['datas'][self::PERIMETER_ORGANIZATIONS] = $this->getOrganizationsProjectsAPI($project, $organizations, $urlPlugin); break; case self::PERIMETER_LOGS: $logs = $this->getEntityManager()->getRepository(LogActivity::class)->getLogsProject($project->getId()); $out['datas'][self::PERIMETER_LOGS] = $logs; Loading Loading @@ -511,18 +534,6 @@ class ProjectService implements UseServiceContainer // IDS des PROJETS $datas = $this->getProjectGrantService()->search2($params); return $datas; // $idsProject = $this->getProjectGrantService()->searchProject($search); // $idsProjectsEmpty = $this->getProjectRepository()->getEmptyIds($search); // $idsProject = array_values(array_unique(array_merge($idsProject, $idsProjectsEmpty))); // // // Evite un IN() vide qui génère une erreur SQL (500) quand aucun projet ne correspond. // if (count($idsProject) === 0) { // $idsProject = [0]; // } // // return $qb = $this->getBaseQuery() // ->where('p.id IN (:ids)') // ->setParameter('ids', $idsProject); } /** Loading Loading @@ -909,4 +920,34 @@ class ProjectService implements UseServiceContainer } return $output; } private function getProjectDataBudget(object $project, Url $urlPlugin) { // $activities = []; /** @var ProjectGrantApiService $projectGrantApiService */ $projectGrantApiService = $this->getServiceContainer()->get(ProjectGrantApiService::class); $depenses = 0.0; $recettes = 0.0; $activitiesIds = []; foreach ($project->getActivities() as $activity) { $activitiesIds[] = $activity->getId(); $infosActivity = $projectGrantApiService->getBudgetActivity($activity, $urlPlugin); // $activities[] = $infosActivity; if($infosActivity['financialImpact'] === Activity::FINANCIAL_IMPACT_COST){ $depenses += $infosActivity['amount']; } if($infosActivity['financialImpact'] === Activity::FINANCIAL_IMPACT_TAKE){ $recettes += $infosActivity['amount']; } } return [ "info" => "budget", "urlSynthesis" => $urlPlugin->fromRoute('contract/spent-synthesis', ['id' => implode(',', $activitiesIds)]), "depenses" => $depenses, "recettes" => $recettes, // "activities" => $activities, ]; } }
module/Oscar/view/oscar/project/show2.phtml +1 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ data-url="<?php echo $this->url('project/show2', ['id' => $project->getId()]) ?>" data-enrole-with-date="<?= $this->oscarConfig("enroleWithDate", true) ? "" : "false" ?>" data-manage="<?php $this->grant()->privilege(\Oscar\Provider\Privileges::PROJECT_EDIT, $project) ? "true" : "false" ?>" data-params="<?php echo $params ?>" ></div> <?= $this->Vite()->addJs('src/Project.js'); ?> </div> No newline at end of file
ui/src/ActivityList.js +2 −2 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ import 'vue-select/dist/vue-select.css'; import ActivityTypeItem from "./components/ActivityTypeItem.vue"; import PrimeVue from "primevue/config"; import Aura from '@primeuix/themes/aura'; import {extractJsonFromBase64} from "./utils/Params.js"; let elemID = "#activity-list"; Loading @@ -27,7 +27,7 @@ try{ urlShowOrganization = elemDatas.dataset.urlShowOrganization; urlShowPerson = elemDatas.dataset.urlShowPerson; urlDelete = elemDatas.dataset.urlDelete; filtersOptions = JSON.parse(atob(elemDatas.dataset.filtersOptions)); filtersOptions = extractJsonFromBase64(elemDatas.dataset.filtersOptions); } catch (err){ console.error(err); } Loading