Loading module/Oscar/config/routes.yml +1 −1 Original line number Diff line number Diff line Loading @@ -515,7 +515,7 @@ project: options: route: '/show/:id' defaults: action: show action: show2 may_terminate: true ### Fiche du projet :id Loading module/Oscar/src/Oscar/Controller/ProjectController.php +12 −1 Original line number Diff line number Diff line Loading @@ -253,7 +253,6 @@ class ProjectController extends AbstractOscarController } } return array( 'spentActivitiesIds' => $spentActivitiesIds, 'spentMissingAcces' => $nbrSpentAllow < $nbrSpent, Loading Loading @@ -948,14 +947,26 @@ class ProjectController extends AbstractOscarController ->getQuery() ->getResult(); $oldProjects = []; /** @var Activity $activity */ foreach ($activities as $activity) { if ($activity->getProject() != $project) { if( $activity->getProject() ){ $oldProjects[] = $activity->getProject(); } $activity->touch(); $activity->setProject($project); } } foreach ($oldProjects as $oldProject){ $this->getProjectGrantService()->getGearmanJobLauncherService()->triggerUpdateSearchIndexProject( $oldProject, false ); } $project->touch(); $this->getEntityManager()->flush(); foreach ($activities as $activity) { Loading module/Oscar/src/Oscar/Entity/ActivityDate.php +45 −21 Original line number Diff line number Diff line Loading @@ -242,21 +242,45 @@ class ActivityDate implements ITrackable public function getStateCssClass(): string { $css = ['milestone']; if ($this->isFinishable()) { $css[] = 'milestone-finishable'; $finishedValueLabel = $this->getFinished() != null ? $this->getFinished() : self::VALUE_TODO; if ($this->isLate()) { return 'progress-item-late'; $css[] = 'milestone-finishable-late'; } else { return 'progress-item-' . self::progressInfoCode($finishedValueLabel); $css[] = 'milestone-finishable-' . self::progressInfoCode($finishedValueLabel); } } else { } if ($this->isToday()) { return 'progress-item-today'; $css[] = 'milestone-today'; } elseif ($this->isFutur()) { return 'progress-item-futur'; $css[] = 'milestone-futur'; } else { return 'progress-item-past'; $css[] = 'milestone-past'; } return implode(' ', $css); } public function getStatus(): string { if ($this->isFinishable()) { if ($this->isLate()) { return "En retard"; } $finishedValue = $this->getFinished() !== null ? $this->getFinished() : self::VALUE_TODO; return self::progressInfoLabel((int)$finishedValue); } if ($this->isToday()) { return "Aujourd'hui"; } elseif ($this->isFutur()) { return "A venir"; } else { return "Passé"; } } Loading module/Oscar/src/Oscar/Service/ProjectGrantApiService.php +6 −0 Original line number Diff line number Diff line Loading @@ -593,6 +593,7 @@ class ProjectGrantApiService implements 'status' => $projectActivity->getStatus(), 'status_label' => $projectActivity->getStatusLabel(), 'numOscar' => $projectActivity->getOscarNum(), 'amount' => $projectActivity->getAmount(), 'codeEOTP' => $projectActivity->getCodeEOTP(), 'dateStart' => $this->formatDateTime($projectActivity->getDateStart()), 'dateEnd' => $this->formatDateTime($projectActivity->getDateEnd()), Loading Loading @@ -949,6 +950,11 @@ class ProjectGrantApiService implements 'comment' => $data->getComment(), 'type' => $typesArr[$data->getType()->getId()], 'type_id' => $data->getType()->getId(), 'status_tag' => $data->getStateCssClass(), 'status_text' => $data->getStatus(), 'activity_num' => $data->getActivity()->getOscarNum(), 'activity_id' => $data->getActivity()->getId(), 'is_finished' => $data->isFinished(), 'finished' => $data->getFinished(), 'finishedBy' => $data->getFinishedBy(), 'validable' => $data->getType()->isFinishable(), Loading module/Oscar/src/Oscar/Service/ProjectService.php +111 −17 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ class ProjectService implements UseServiceContainer public const PERIMETER_LOGS = 'logs'; ///////////////////////////////////////////////////////////////////////////////////////////////////// ACCES SERVICES const PERIMETER_MILESTONES = ProjectGrantApiService::PERIMETER_MILESTONES; use UseServiceContainerTrait; Loading Loading @@ -126,7 +127,10 @@ class ProjectService implements UseServiceContainer self::PERIMETER_ACTIVITIES, self::PERIMETER_BUDGET, self::PERIMETER_CORE, ProjectGrantApiService::PERIMETER_DOCUMENTS, self::PERIMETER_MILESTONES, self::PERIMETER_ORGANIZATIONS, ProjectGrantApiService::PERIMETER_PAYMENTS, self::PERIMETER_PERSONS, self::PERIMETER_LOGS, ]; Loading Loading @@ -173,29 +177,46 @@ class ProjectService implements UseServiceContainer 'traces' => [], ]; $urls = []; $read = $oscarUserContext->hasPrivileges(Privileges::PROJECT_SHOW, $project); $edit = $oscarUserContext->hasPrivileges(Privileges::PROJECT_EDIT, $project); if( $edit ){ $urls['edit'] = $urlPlugin->fromRoute('project/edit', ['id' => $project->getId()]); $urls['add_activities'] = $urlPlugin->fromRoute('project/add-activities', ['id' => $project->getId()]); } if (!$oscarUserContext) { $credentials = [ 'forced' => true, 'read' => true, 'edit' => false, ]; } else { $read = $oscarUserContext->hasPrivileges(Privileges::PROJECT_SHOW, $project); $credentialsBudget = [ $credentials = [ 'read' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_SHOW, $project), 'edit' => $edit, 'delete' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_EDIT, $project), self::PERIMETER_ACTIVITIES => [ 'read' => $read ], self::PERIMETER_BUDGET => [ '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 = [ ], ProjectGrantApiService::PERIMETER_MILESTONES => [ 'read' => false, 'edit' => false, ], ProjectGrantApiService::PERIMETER_DOCUMENTS => [ 'read' => false, 'edit' => false, ], self::PERIMETER_CORE => [ 'read' => $read, self::PERIMETER_ACTIVITIES => ['read' => $read], self::PERIMETER_BUDGET => $credentialsBudget, self::PERIMETER_CORE => ['read' => $read], 'edit' => $edit, ], self::PERIMETER_PERSONS => [ 'read' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_PERSON_SHOW, $project), 'edit' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_PERSON_MANAGE, $project), Loading @@ -208,13 +229,40 @@ class ProjectService implements UseServiceContainer 'read' => $oscarUserContext->hasPrivileges(Privileges::MAINTENANCE_MENU_ADMIN), ], ]; foreach ($project->getActivities() as $activity) { if( $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['read'] === false ){ $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['read'] = $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['read'] || $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_MILESTONE_SHOW, $activity); } if( $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['edit'] === false ){ $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['edit'] = $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['edit'] || $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_MILESTONE_SHOW, $activity); } if( $credentials[ProjectGrantApiService::PERIMETER_DOCUMENTS]['show'] === false ){ $credentials[ProjectGrantApiService::PERIMETER_DOCUMENTS]['show'] = $credentials[ProjectGrantApiService::PERIMETER_DOCUMENTS]['show'] || $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_DOCUMENT_SHOW, $activity); } $credentials[self::PERIMETER_BUDGET]['read'] = $credentials[self::PERIMETER_BUDGET]['read'] && $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_PAYMENT_SHOW, $activity); $credentials[self::PERIMETER_BUDGET]['edit'] = $credentials[self::PERIMETER_BUDGET]['edit'] && $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_PAYMENT_MANAGE, $activity); } } if ($credentials['read'] !== true) { $out['error'] = 'access denied'; return $out; } $credentials['urls'] = $urls; $out['credentials'] = $credentials; $forced = (($credentials['forced'] ?? false) === true); foreach ($perimeters as $perimeter) { Loading @@ -234,6 +282,14 @@ class ProjectService implements UseServiceContainer ); break; case self::PERIMETER_MILESTONES: $out['datas'][self::PERIMETER_MILESTONES] = $this->getProjectDataMilestones( $project, $urlPlugin, $oscarUserContext ); break; case self::PERIMETER_BUDGET: $out['datas'][self::PERIMETER_BUDGET] = $this->getProjectDataBudget($project, $urlPlugin); break; Loading @@ -242,6 +298,10 @@ class ProjectService implements UseServiceContainer $out['datas'][self::PERIMETER_CORE] = $this->getProjectDataCore($project, $urlPlugin); break; case ProjectGrantApiService::PERIMETER_MILESTONES: $out['datas'][self::PERIMETER_MILESTONES] = $this->getProjectDataCore($project, $urlPlugin); break; case self::PERIMETER_PERSONS: $persons = []; $out['datas'][self::PERIMETER_PERSONS] = $this->getPersonsProjectsAPI($project, $persons, $urlPlugin); Loading Loading @@ -895,6 +955,21 @@ class ProjectService implements UseServiceContainer 'dateEnd' => $project->getDateEnd()?->format('Y-m-d H:i:s'), ]; $keywords = []; $disciplines = []; $pfi = []; foreach ($project->getActivities() as $activity) { $keywords = array_merge_recursive($keywords, $activity->getMotsclesArray()); $disciplines = array_merge_recursive($disciplines, $activity->getDisciplinesArray()); if($activity->getCodeEOTP()) { $pfi[] = $activity->getCodeEOTP(); } } $out['keywords'] = array_unique($keywords); $out['disciplines'] = array_unique($disciplines); $out['pfi'] = array_unique($pfi); if ($urlHelper) { $out['urls'] = [ 'show' => $urlHelper->fromRoute('project/show', ['id' => $project->getId()]), Loading @@ -915,12 +990,31 @@ class ProjectService implements UseServiceContainer $activity->getId(), $urlHelper, $oscarUserContext, 'core,budget' 'core,budget,milestones,payments' ); } return $output; } private function getProjectDataMilestones(Project $project, Url $urlHelper, OscarUserContext $oscarUserContext): array { $output = []; /** @var ProjectGrantApiService $projectGrantApiService */ $projectGrantApiService = $this->getServiceContainer()->get(ProjectGrantApiService::class); foreach ($project->getActivities() as $activity) { if( $oscarUserContext && $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_MILESTONE_SHOW) ){ $milestonesActivity = $projectGrantApiService->getActivityJson( $activity->getId(), $urlHelper, $oscarUserContext, 'milestones' ); $output = array_merge($output, $milestonesActivity['datas']['milestones']['entities']); } } return $output; } private function getProjectDataBudget(object $project, Url $urlPlugin) { // $activities = []; Loading Loading
module/Oscar/config/routes.yml +1 −1 Original line number Diff line number Diff line Loading @@ -515,7 +515,7 @@ project: options: route: '/show/:id' defaults: action: show action: show2 may_terminate: true ### Fiche du projet :id Loading
module/Oscar/src/Oscar/Controller/ProjectController.php +12 −1 Original line number Diff line number Diff line Loading @@ -253,7 +253,6 @@ class ProjectController extends AbstractOscarController } } return array( 'spentActivitiesIds' => $spentActivitiesIds, 'spentMissingAcces' => $nbrSpentAllow < $nbrSpent, Loading Loading @@ -948,14 +947,26 @@ class ProjectController extends AbstractOscarController ->getQuery() ->getResult(); $oldProjects = []; /** @var Activity $activity */ foreach ($activities as $activity) { if ($activity->getProject() != $project) { if( $activity->getProject() ){ $oldProjects[] = $activity->getProject(); } $activity->touch(); $activity->setProject($project); } } foreach ($oldProjects as $oldProject){ $this->getProjectGrantService()->getGearmanJobLauncherService()->triggerUpdateSearchIndexProject( $oldProject, false ); } $project->touch(); $this->getEntityManager()->flush(); foreach ($activities as $activity) { Loading
module/Oscar/src/Oscar/Entity/ActivityDate.php +45 −21 Original line number Diff line number Diff line Loading @@ -242,21 +242,45 @@ class ActivityDate implements ITrackable public function getStateCssClass(): string { $css = ['milestone']; if ($this->isFinishable()) { $css[] = 'milestone-finishable'; $finishedValueLabel = $this->getFinished() != null ? $this->getFinished() : self::VALUE_TODO; if ($this->isLate()) { return 'progress-item-late'; $css[] = 'milestone-finishable-late'; } else { return 'progress-item-' . self::progressInfoCode($finishedValueLabel); $css[] = 'milestone-finishable-' . self::progressInfoCode($finishedValueLabel); } } else { } if ($this->isToday()) { return 'progress-item-today'; $css[] = 'milestone-today'; } elseif ($this->isFutur()) { return 'progress-item-futur'; $css[] = 'milestone-futur'; } else { return 'progress-item-past'; $css[] = 'milestone-past'; } return implode(' ', $css); } public function getStatus(): string { if ($this->isFinishable()) { if ($this->isLate()) { return "En retard"; } $finishedValue = $this->getFinished() !== null ? $this->getFinished() : self::VALUE_TODO; return self::progressInfoLabel((int)$finishedValue); } if ($this->isToday()) { return "Aujourd'hui"; } elseif ($this->isFutur()) { return "A venir"; } else { return "Passé"; } } Loading
module/Oscar/src/Oscar/Service/ProjectGrantApiService.php +6 −0 Original line number Diff line number Diff line Loading @@ -593,6 +593,7 @@ class ProjectGrantApiService implements 'status' => $projectActivity->getStatus(), 'status_label' => $projectActivity->getStatusLabel(), 'numOscar' => $projectActivity->getOscarNum(), 'amount' => $projectActivity->getAmount(), 'codeEOTP' => $projectActivity->getCodeEOTP(), 'dateStart' => $this->formatDateTime($projectActivity->getDateStart()), 'dateEnd' => $this->formatDateTime($projectActivity->getDateEnd()), Loading Loading @@ -949,6 +950,11 @@ class ProjectGrantApiService implements 'comment' => $data->getComment(), 'type' => $typesArr[$data->getType()->getId()], 'type_id' => $data->getType()->getId(), 'status_tag' => $data->getStateCssClass(), 'status_text' => $data->getStatus(), 'activity_num' => $data->getActivity()->getOscarNum(), 'activity_id' => $data->getActivity()->getId(), 'is_finished' => $data->isFinished(), 'finished' => $data->getFinished(), 'finishedBy' => $data->getFinishedBy(), 'validable' => $data->getType()->isFinishable(), Loading
module/Oscar/src/Oscar/Service/ProjectService.php +111 −17 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ class ProjectService implements UseServiceContainer public const PERIMETER_LOGS = 'logs'; ///////////////////////////////////////////////////////////////////////////////////////////////////// ACCES SERVICES const PERIMETER_MILESTONES = ProjectGrantApiService::PERIMETER_MILESTONES; use UseServiceContainerTrait; Loading Loading @@ -126,7 +127,10 @@ class ProjectService implements UseServiceContainer self::PERIMETER_ACTIVITIES, self::PERIMETER_BUDGET, self::PERIMETER_CORE, ProjectGrantApiService::PERIMETER_DOCUMENTS, self::PERIMETER_MILESTONES, self::PERIMETER_ORGANIZATIONS, ProjectGrantApiService::PERIMETER_PAYMENTS, self::PERIMETER_PERSONS, self::PERIMETER_LOGS, ]; Loading Loading @@ -173,29 +177,46 @@ class ProjectService implements UseServiceContainer 'traces' => [], ]; $urls = []; $read = $oscarUserContext->hasPrivileges(Privileges::PROJECT_SHOW, $project); $edit = $oscarUserContext->hasPrivileges(Privileges::PROJECT_EDIT, $project); if( $edit ){ $urls['edit'] = $urlPlugin->fromRoute('project/edit', ['id' => $project->getId()]); $urls['add_activities'] = $urlPlugin->fromRoute('project/add-activities', ['id' => $project->getId()]); } if (!$oscarUserContext) { $credentials = [ 'forced' => true, 'read' => true, 'edit' => false, ]; } else { $read = $oscarUserContext->hasPrivileges(Privileges::PROJECT_SHOW, $project); $credentialsBudget = [ $credentials = [ 'read' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_SHOW, $project), 'edit' => $edit, 'delete' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_EDIT, $project), self::PERIMETER_ACTIVITIES => [ 'read' => $read ], self::PERIMETER_BUDGET => [ '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 = [ ], ProjectGrantApiService::PERIMETER_MILESTONES => [ 'read' => false, 'edit' => false, ], ProjectGrantApiService::PERIMETER_DOCUMENTS => [ 'read' => false, 'edit' => false, ], self::PERIMETER_CORE => [ 'read' => $read, self::PERIMETER_ACTIVITIES => ['read' => $read], self::PERIMETER_BUDGET => $credentialsBudget, self::PERIMETER_CORE => ['read' => $read], 'edit' => $edit, ], self::PERIMETER_PERSONS => [ 'read' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_PERSON_SHOW, $project), 'edit' => $oscarUserContext->hasPrivileges(Privileges::PROJECT_PERSON_MANAGE, $project), Loading @@ -208,13 +229,40 @@ class ProjectService implements UseServiceContainer 'read' => $oscarUserContext->hasPrivileges(Privileges::MAINTENANCE_MENU_ADMIN), ], ]; foreach ($project->getActivities() as $activity) { if( $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['read'] === false ){ $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['read'] = $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['read'] || $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_MILESTONE_SHOW, $activity); } if( $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['edit'] === false ){ $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['edit'] = $credentials[ProjectGrantApiService::PERIMETER_MILESTONES]['edit'] || $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_MILESTONE_SHOW, $activity); } if( $credentials[ProjectGrantApiService::PERIMETER_DOCUMENTS]['show'] === false ){ $credentials[ProjectGrantApiService::PERIMETER_DOCUMENTS]['show'] = $credentials[ProjectGrantApiService::PERIMETER_DOCUMENTS]['show'] || $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_DOCUMENT_SHOW, $activity); } $credentials[self::PERIMETER_BUDGET]['read'] = $credentials[self::PERIMETER_BUDGET]['read'] && $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_PAYMENT_SHOW, $activity); $credentials[self::PERIMETER_BUDGET]['edit'] = $credentials[self::PERIMETER_BUDGET]['edit'] && $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_PAYMENT_MANAGE, $activity); } } if ($credentials['read'] !== true) { $out['error'] = 'access denied'; return $out; } $credentials['urls'] = $urls; $out['credentials'] = $credentials; $forced = (($credentials['forced'] ?? false) === true); foreach ($perimeters as $perimeter) { Loading @@ -234,6 +282,14 @@ class ProjectService implements UseServiceContainer ); break; case self::PERIMETER_MILESTONES: $out['datas'][self::PERIMETER_MILESTONES] = $this->getProjectDataMilestones( $project, $urlPlugin, $oscarUserContext ); break; case self::PERIMETER_BUDGET: $out['datas'][self::PERIMETER_BUDGET] = $this->getProjectDataBudget($project, $urlPlugin); break; Loading @@ -242,6 +298,10 @@ class ProjectService implements UseServiceContainer $out['datas'][self::PERIMETER_CORE] = $this->getProjectDataCore($project, $urlPlugin); break; case ProjectGrantApiService::PERIMETER_MILESTONES: $out['datas'][self::PERIMETER_MILESTONES] = $this->getProjectDataCore($project, $urlPlugin); break; case self::PERIMETER_PERSONS: $persons = []; $out['datas'][self::PERIMETER_PERSONS] = $this->getPersonsProjectsAPI($project, $persons, $urlPlugin); Loading Loading @@ -895,6 +955,21 @@ class ProjectService implements UseServiceContainer 'dateEnd' => $project->getDateEnd()?->format('Y-m-d H:i:s'), ]; $keywords = []; $disciplines = []; $pfi = []; foreach ($project->getActivities() as $activity) { $keywords = array_merge_recursive($keywords, $activity->getMotsclesArray()); $disciplines = array_merge_recursive($disciplines, $activity->getDisciplinesArray()); if($activity->getCodeEOTP()) { $pfi[] = $activity->getCodeEOTP(); } } $out['keywords'] = array_unique($keywords); $out['disciplines'] = array_unique($disciplines); $out['pfi'] = array_unique($pfi); if ($urlHelper) { $out['urls'] = [ 'show' => $urlHelper->fromRoute('project/show', ['id' => $project->getId()]), Loading @@ -915,12 +990,31 @@ class ProjectService implements UseServiceContainer $activity->getId(), $urlHelper, $oscarUserContext, 'core,budget' 'core,budget,milestones,payments' ); } return $output; } private function getProjectDataMilestones(Project $project, Url $urlHelper, OscarUserContext $oscarUserContext): array { $output = []; /** @var ProjectGrantApiService $projectGrantApiService */ $projectGrantApiService = $this->getServiceContainer()->get(ProjectGrantApiService::class); foreach ($project->getActivities() as $activity) { if( $oscarUserContext && $oscarUserContext->hasPrivileges(Privileges::ACTIVITY_MILESTONE_SHOW) ){ $milestonesActivity = $projectGrantApiService->getActivityJson( $activity->getId(), $urlHelper, $oscarUserContext, 'milestones' ); $output = array_merge($output, $milestonesActivity['datas']['milestones']['entities']); } } return $output; } private function getProjectDataBudget(object $project, Url $urlPlugin) { // $activities = []; Loading