diff --git a/VERSIONS_WIP/33379 b/VERSIONS_WIP/33379 new file mode 100644 index 0000000000000000000000000000000000000000..34bc1e9001d84f06fb203b506ff60b574be8fa33 --- /dev/null +++ b/VERSIONS_WIP/33379 @@ -0,0 +1 @@ + - ticket #33379 : Intégration des demandes d'assistance \ No newline at end of file diff --git a/application/modules/admin/controllers/BibController.php b/application/modules/admin/controllers/BibController.php index b3a56d3ed894b1c743980fc201d4a52b0153ab4d..b34b17c88e2e029b888f495fc626cc9d8feb9427 100644 --- a/application/modules/admin/controllers/BibController.php +++ b/application/modules/admin/controllers/BibController.php @@ -35,8 +35,7 @@ class Admin_BibController extends ZendAfi_Controller_Action { 'actions' => ['edit' => ['title' => $this->_("Modifier une bibliothèque"), 'add' => ['title' => $this->_("Ajouter une bibliothèque")]]], - 'after_edit' => function($formation) { $this->_redirect('/admin/bib');} - ]; + 'form_class_name' => 'ZendAfi_Form_Admin_Library']; } @@ -60,14 +59,6 @@ class Admin_BibController extends ZendAfi_Controller_Action { } - protected function _getForm($model) { - $this - ->_definitions - ->setFormClassName( 'ZendAfi_Form_Admin_Library'); - $form = parent::_getForm($model); - return $form; - } - protected function _doAfterSave($model) { $model->receiveFile('photo'); } diff --git a/application/modules/admin/controllers/RedmineController.php b/application/modules/admin/controllers/RedmineController.php index 6cf1d3c823d690f715db1b8c92a589a10788b471..64e04914912bd60df35609ea0b1a836110cbf82b 100644 --- a/application/modules/admin/controllers/RedmineController.php +++ b/application/modules/admin/controllers/RedmineController.php @@ -23,76 +23,166 @@ class Admin_RedmineController extends ZendAfi_Controller_Action { public function indexAction() { - $this->view->titre = $this->_('Redmine'); - $this->view->user = Class_Users::getIdentity(); - $this->fetchLibrariesDatas($this->view->user->getRedmineLibraries()); + $this->view->titre = $this->_('Assistance'); + $this->view->user = $user = Class_Users::getIdentity(); + + if (!$libraries = $user->getRedmineLibraries()) + return; + + $this->view->libraries = $this->_librariesOptions($libraries); + + if (!$id_bib = (int)$this->_getParam('id_bib', 0)) { + $this->view->library = $this->fetchLibraryDatas($libraries[0]); + return; + } + + if (!$library = $this->_selectLibraryIn($id_bib, $libraries)) + return; + + $this->view->library = $this->fetchLibraryDatas($library); } - protected function fetchLibrariesDatas($libraries) { - $this->view->libraries = []; + protected function _librariesOptions($libraries) { + $options = []; + foreach($libraries as $library) + $options[$library->getId()] = $library->getLabel(); - $renderIssues = function($library_id, $data) { - return $this->view->libraries[$library_id]['issues'] = Class_WebService_redmine::extractIssues($data); - }; + return $options; + } - $renderUser = function($library_id, $data) { - return $this->view->libraries[$library_id]['user'] = Class_WebService_redmine::extractConnectedUser($data, Class_Users::getIdentity()->getRedmineLibrary()); - }; - $renderProject = function($library_id, $data) { - return $this->view->libraries[$library_id ]['project'] = Class_WebService_redmine::extractProject($data); - }; + protected function _selectLibraryIn($id, $possibles) { + foreach($possibles as $possible) + if ($possible->getId() == $id) + return $possible; + } - foreach($libraries as $library) { - $this->withResponseDo($library, - Class_WebService_Redmine::getCurrentUser($library), - $renderUser); - $this->withResponseDo($library, - Class_WebService_Redmine::getIssuesForLib($library), - $renderIssues); + protected function fetchLibraryDatas($library) { + $entity = (new Class_Entity()) + ->setLibrary($library) + ->setIssues([]) + ->setUser(null); - $this->withResponseDo($library, - Class_WebService_Redmine::getProject($library), - $renderProject); + $service = new Class_WebService_Redmine($library); + if (!$service->isValid()) + return $entity; - $this->view->libraries[$library->getId()]['instance'] = $library; - } + $entity->setIssues($service->getIssues()) + ->setClosedIssues($service->getClosedIssues()) + ->setUser($service->getUser()); + + return $entity; } public function testAction() { - $renderSuccess = function($library_id, $data) { - if($connected = Class_WebService_Redmine::extractConnectedUser($data, Class_Bib::find($library_id))) - return $this->view->getHelper('Redmine_AccountStatus')->successfullConnection($connected); - return $this->view->getHelper('Redmine_AccountStatus')->connectionFail(); - }; - $library = Class_Bib::find($this->_getParam('id_bib', 0)); - return $this->withResponseDoInPopup($library, - Class_WebService_Redmine::getCurrentUser($library), - $renderSuccess, - $this->_('Test de l\'API Redmine')); - } + $title = $this->_('Test de la configuration de l\'API d\'assistance'); + $service = new Class_WebService_Redmine($library); + + if (!$service->isValid()) { + return $this->_helper->json(['title' => $title, + 'content' => $service->validate()]); + } + $helper = $this->view->getHelper('Redmine_AccountStatus'); + $message = ($connected = $service->getUser()) + ? $helper->successfullConnection($connected) + : $helper->connectionFail(); - protected function withResponseDoInPopup($library, $data, $call_back, $title) { return $this->_helper->json(['title' => $title, - 'content' => $this->withResponseDo($library, $data, $call_back)]); + 'content' => $message]); + } + + + public function addAction() { + $this->view->titre = $this->_('Nouvelle demande'); + + $library = Class_Bib::find($this->_getParam('id_lib', 0)); + + $service = new Class_WebService_Redmine($library); + if (null !== $message = $service->validate()) { + $this->_helper->notify($message); + $this->_redirectToIndex(); + return; + } + + $issue = (new Class_WebService_Redmine_Issue()) + ->setService($service); + + $this->view->form = $form = ZendAfi_Form_Redmine_Issue::newWithIssue($issue, $service); + if ($this->_request->isPost() + && $form->isValid($this->_request->getPost())) { + $issue->updateAttributes($form->getValues()); + + if ($service->createIssue($issue)) { + $this->_helper->notify($this->_('Demande enregistrée')); + $this->_redirectToIndex(); + return; + } + + $this->_helper->notify($this->_('Erreur lors de l\'enregistrement')); + } + } + + + public function deleteAction() { + $this->_redirectToIndex(); + } + + + public function editIssueAction() { + $ticket_number = $this->_getParam('id', 0); + $this->view->titre = $this->_('Modifier la demande #%s', $ticket_number); + + $library = Class_Bib::find($this->_getParam('id_lib', 0)); + + $service = new Class_WebService_Redmine($library); + if (null !== $message = $service->validate()) { + $this->_helper->notify($message); + $this->_redirectToIndex(); + return; + } + + $issue = $service->getIssue($ticket_number); + if (!$issue->getid()) { + $this->_redirectToIndex(); + return; + } + + $this->view->issue = $issue; + $this->view->form = $form = ZendAfi_Form_Redmine_Issue::newWithIssue($issue, $service); + + if ($this->_request->isPost() + && $form->isValid($this->_request->getPost())) { + $issue->updateAttributes($form->getValues()); + $service->updateIssue($issue); + + $this->_helper->notify($this->_('Demande #%s enregistrée', $issue->getid())); + $this->_redirectToIndex(); + } } - protected function withResponseDo($library, $data, $call_back) { - $message = $this->view->getHelper('Redmine_AccountStatus')->connectionFail(); + protected function withResponseDo($data, $call_back) { + $error_message = $this->view->getHelper('Redmine_AccountStatus')->connectionFail(); if(false === $data) - return $message; + return $error_message; + + if(isset($data['error_message'])) + return $data['error_message'] + ? $data['error_message'] + : $error_message; - if(isset($data['error_message']) && '' != $data['error_message']) - return $data['error_message']; + return call_user_func($call_back, $data); + } - return call_user_func($call_back, $library->getId(), $data); + + protected function withResponseDoInPopup($data, $call_back, $title) { + return $this->_helper->json(['title' => $title, + 'content' => $this->withResponseDo($data, $call_back)]); } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/application/modules/admin/controllers/UsersController.php b/application/modules/admin/controllers/UsersController.php index 8a9d6c73ca7e0aeec37b4f53d516102b7cce2732..276bd86a5d667ab320ff354b21bb9a5e330b1783 100644 --- a/application/modules/admin/controllers/UsersController.php +++ b/application/modules/admin/controllers/UsersController.php @@ -26,14 +26,13 @@ class Admin_UsersController extends ZendAfi_Controller_Action { 'name' => 'user', 'order' => 'id'], - 'messages' => ['successful_save' => $this->_('Utilisateur "%s" sauvegardé'), + 'messages' => ['successful_save' => $this->_('L\'utilisateur "%s" a été sauvegardé'), 'successful_add' => $this->_('L\'utilisateur "%s" a été ajouté'), - 'successful_delete' => $this->_('L\'utilisateur "%s" a été supprimée')], + 'successful_delete' => $this->_('L\'utilisateur "%s" a été supprimé')], - 'actions' => ['add' => ['title' => $this->_("Ajouter un utilisateur")], - 'edit' => ['title' => $this->_("Modifier le utilisateur: %s")], - 'delete' => ['title' => $this->_("Supprimer le utilisateur: %s")] - ], + 'actions' => ['add' => ['title' => $this->_('Ajouter un utilisateur')], + 'edit' => ['title' => $this->_('Modifier l\'utilisateur: %s')], + 'delete' => ['title' => $this->_('Supprimer l\'utilisateur: %s')]], 'form_class_name' => 'ZendAfi_Form_Admin_User']; } @@ -101,23 +100,14 @@ class Admin_UsersController extends ZendAfi_Controller_Action { protected function _setupFormAndSave($model) { - if ($this->_request->isPost()) { - $role_level=intval($this->_getParam('role_level')); - if ($role_level > 4) $this->_setParam('id_site',0); - if ($role_level < 2) { - $this->_setParam('idabon',0); - $this->_setParam('ordreabon',0); - } + if ($this->_request->isPost()) $model->updateSIGBOnSave(); - } + try { return parent::_setupFormAndSave($model); - } catch (Exception $e) { $this->_helper->notify($e->getMessage()); - } - } diff --git a/application/modules/admin/views/scripts/redmine/add.phtml b/application/modules/admin/views/scripts/redmine/add.phtml new file mode 100644 index 0000000000000000000000000000000000000000..ac7363359759fdc81ec27a1c761cdf8d81e268d8 --- /dev/null +++ b/application/modules/admin/views/scripts/redmine/add.phtml @@ -0,0 +1,2 @@ +<?php +echo $this->renderForm($this->form); diff --git a/application/modules/admin/views/scripts/redmine/edit-issue.phtml b/application/modules/admin/views/scripts/redmine/edit-issue.phtml new file mode 100644 index 0000000000000000000000000000000000000000..970664867c8a6c99a93ae75aa30030548fdd6baa --- /dev/null +++ b/application/modules/admin/views/scripts/redmine/edit-issue.phtml @@ -0,0 +1,33 @@ +<div class="form"> + <fieldset> + <table> + <tr> + <td></td> + <td class="gauche" style="font-weight:bold;font-size:130%"><?php echo $this->escape($this->issue->getsubject()); ?></td> + </tr> + </table> + </fieldset> + <fieldset> + <legend><?php echo $this->_('Description');?></legend> + <table> + <tr> + <td></td> + <td class="gauche"><pre style="font-family:inherit;font-size:130%;white-space:normal;"> + <?php echo nl2br($this->issue->getdescription()); ?><pre> + </td> + </tr> + </table> + </fieldset> + <fieldset> + <legend><?php echo $this->_('Historique');?></legend> + <table> + <tr> + <td></td> + <td class="gauche"><?php echo $this->redmine_IssueJournal($this->issue); ?></td> + </tr> + </table> + </fieldset> +</div> +<?php + +echo $this->renderForm($this->form); diff --git a/application/modules/admin/views/scripts/redmine/index.phtml b/application/modules/admin/views/scripts/redmine/index.phtml index a10b599032a596956a6a3b45de01378373a78413..f76fdd0994864e45ca2aa3f7992e910d4d6159d3 100644 --- a/application/modules/admin/views/scripts/redmine/index.phtml +++ b/application/modules/admin/views/scripts/redmine/index.phtml @@ -1,11 +1,9 @@ <?php -$html = ''; -foreach($this->libraries as $library_id => $data) - $html .= $this->tag('li', $this->Redmine_Header($this->user, - isset($data['instance']) ? $data['instance'] : null, - isset($data['user']) ? $data['user'] : false, - isset($data['project']) ? $data['project'] : '') . -$this->Redmine_Issues(isset($data['issues']) ? $data['issues'] : [])); -echo $this->tag('ul', $html); -?> +if (!$this->libraries) { + echo $this->getHelper('Redmine_Header')->shouldSelectLib($this->user); + return; +} + +if ($this->library) + echo $this->redmine_Library($this->library, $this->user, $this->libraries); diff --git a/library/Class/AdminVar.php b/library/Class/AdminVar.php index 03d4db0b71c9e2c7db7d6ef6c2e2c5466c755d0d..c8c4627f5b4a2c4c4d770955cb4a5c963e7e3fdc 100644 --- a/library/Class/AdminVar.php +++ b/library/Class/AdminVar.php @@ -80,8 +80,6 @@ class Class_AdminVarLoader extends Storm_Model_Loader { public function findAllByController($controller) { - - return isset($this->knownVars()[$controller]) ? self::filterByUserRole(array_map( function($clef) { @@ -291,6 +289,7 @@ class Class_AdminVarLoader extends Storm_Model_Loader { 'users' => ['NDAYS_EXPIRY_NOTICE' => Class_AdminVar_Meta::newDefault($this->_('Prévenir l\'utilisateur xx jour(s) avant l\'expiration de son abonnement (par défaut 30 jours).'), ['value' => 30]), 'DISABLE_SUGGESTIONS' => Class_AdminVar_Meta::newOnOff($this->_('Désactivation des suggestions d\'achats'))->bePrivate()], 'redmine' => ['REDMINE_SERVER_URL' => Class_Adminvar_Meta::newDefault($this->_('Url du serveur redmine'))->bePrivate(), + 'REDMINE_PROXY_URL' => Class_Adminvar_Meta::newDefault($this->_('Url du proxy Redmine'))->bePrivate() 'REDMINE_PROJECT_ID' => Class_Adminvar_Meta::newDefault($this->_('Identifiant du project Redmine'))->bePrivate()], 'lesocial' => ['LESOCIAL_URL' => Class_Adminvar_Meta::newDefault($this->_('Url du connecteur Le Social'))->bePrivate(), 'LESOCIAL_ID' => Class_Adminvar_Meta::newDefault($this->_('Id du connecteur Le Social'))->bePrivate()] @@ -445,7 +444,9 @@ class Class_AdminVarLoader extends Storm_Model_Loader { * @return bool */ public function isRedmineEnabled() { - return ('' != Class_AdminVar::get('REDMINE_SERVER_URL')); + return ('' != Class_AdminVar::get('REDMINE_SERVER_URL')) + && ('' != Class_AdminVar::get('REDMINE_PROJECT_ID')) + && ('' != Class_AdminVar::get('REDMINE_PROXY_URL')); } diff --git a/library/Class/Bib.php b/library/Class/Bib.php index 31aa4ee5e595edf7d4d68ac3a951f8ca4905a403..c7054decd83036532b4cde117be713e5f5c03a6e 100644 --- a/library/Class/Bib.php +++ b/library/Class/Bib.php @@ -18,11 +18,8 @@ * along with BOKEH; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Table Name -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -require_once dirname(__FILE__)."/CompositeBuilder.php"; +require_once dirname(__FILE__)."/CompositeBuilder.php"; class BibCSite extends Zend_Db_Table_Abstract { @@ -135,11 +132,10 @@ class BibLoader extends Storm_Model_Loader { } - public function findAllWithRedmine($user) { + public function findAllWithRedmine() { return array_filter(array_unique(array_merge(Class_Bib::findAllBy(['redmine_login not' => '', 'redmine_password not' => '']), - Class_Bib::findAllBy(['redmine_api_key not' => '']), - [$user->getBib()]))); + Class_Bib::findAllBy(['redmine_api_key not' => ''])))); } @@ -233,10 +229,15 @@ class Class_Bib extends Storm_Model_Abstract { 'libelle' => '', 'id_zone' => 0, 'ville' => '', + 'mail' => '', + 'telephone' => '', 'aff_zone' => '', 'interdire_resa' => 0, 'google_map' => '', - 'photo' => '']; + 'photo' => '', + 'redmine_login' => '', + 'redmine_password' => '', + 'redmine_api_key' => '']; protected $_translate; @@ -738,5 +739,9 @@ class Class_Bib extends Storm_Model_Abstract { public function getPermissionsChildren() { return $this->getArticleCategories(); } + + + public function getRedmineLoginOrKey() { + return ($login = $this->getRedmineLogin()) ? $login : $this->getRedmineApiKey(); + } } -?> \ No newline at end of file diff --git a/library/Class/User/Settings.php b/library/Class/User/Settings.php index 4d7b043e9a886ad323135d9e49e4bcdb1a9828ef..b5b6416223cba9c8cf849463109091393bcf5e3b 100644 --- a/library/Class/User/Settings.php +++ b/library/Class/User/Settings.php @@ -68,13 +68,13 @@ class Class_User_Settings { public function getRedmineLibrary() { - if(!isset($this->_user_settings[self::REDMINE_LIBRARY])) - return $this->getLocalLib(); + if(!isset($this->_user_settings[self::REDMINE_LIBRARY]) && !$this->_user_settings[self::REDMINE_LIBRARY]) + return $this->getUserLib(); return Class_Bib::find($this->_user_settings[self::REDMINE_LIBRARY]); } - protected function getLocalLib() { + protected function getUserLib() { return $this->_user->getBib(); } diff --git a/library/Class/Users.php b/library/Class/Users.php index c519c624f45a2835959b2c06a35b8834ec871b54..85121d6200c67dcd310131f678c7ed82bcdddb74 100644 --- a/library/Class/Users.php +++ b/library/Class/Users.php @@ -326,7 +326,7 @@ class Class_Users extends Storm_Model_Abstract { 'idabon' => '', 'date_fin' => '', 'naissance' => '', - 'date_debut' => 0, + 'date_debut' => '', 'telephone' => '', 'mail' => '', 'mobile' => '', @@ -1664,16 +1664,13 @@ class Class_Users extends Storm_Model_Abstract { public function getRedmineLibraries() { if($this->getRoleLevel() >= ZendAfi_Acl_AdminControllerRoles::MODO_PORTAIL) - return Class_Bib::findAllWithRedmine($this); + return Class_Bib::findAll(); return [$this->getRedmineLibrary()]; } public function getLibelle() { - return $this->getPrenom() . ' ' . $this->getNom(); + return $this->getNomComplet(); } - - -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/library/Class/WebService/Redmine.php b/library/Class/WebService/Redmine.php index cde3d28f344e7da698d452a5259b8f19b5a9b36b..fe2d641b2a415d4d686ca37f674a44175e2a0742 100644 --- a/library/Class/WebService/Redmine.php +++ b/library/Class/WebService/Redmine.php @@ -22,120 +22,361 @@ class Class_WebService_Redmine extends Class_WebService_Abstract { use Trait_Translator; - protected static $_redmine_client; + const CUSTOM_PRIORITY_ID = 5; + const CUSTOM_MODULE_ID = 37; + const CUSTOM_CONTACT_PERSON = 43; + const CUSTOM_CUSTOMER = 1; + const CUSTOM_QUALIFICATION = 38; - protected function missingApiRequirement($library) { - if($error_message = $this->missingApiRequirementMessage($library)) - return ['error_message' => $error_message]; - return null; + protected static $_redmine_client, $_admin_client; + + protected + $_library, + $_custom_fields_cache, + $_issue_statuses_cache, + $_issue_priorities_cache; + + + public function __construct($library) { + $this->_library = $library; + } + + + public function getLibrary() { + return $this->_library; } - protected function missingApiRequirementMessage($library) { - if(!$library) + protected function missingApiRequirement() { + return ($error_message = $this->validate()) + ? ['error_message' => $error_message] + : null; + } + + + public function validate() { + if (!$this->_library) return $this->_('Vous devez fournir un identifiant de bibliothèque en paramètre'); - if(!Class_AdminVar::isRedmineEnabled()) - return $this->_('Aucun serveur Redmine est renseigné'); + if (!Class_AdminVar::isRedmineEnabled()) + return $this->_('Redmine n\'est pas correctement configuré'); - if((!$library->getRedmineLogin() || !$library->getRedminePassword()) && !$library->getRedmineApiKey()) + if ((!$this->_library->getRedmineLogin() || !$this->_library->getRedminePassword()) + && !$this->_library->getRedmineApiKey()) return $this->_('Vous devez renseigner les champs login et password ou le champ clé d\'API'); return null; } - protected function getUserApi($library) { - return $this->getClient($library)->api('user'); + public function isValid() { + return null === $this->validate(); + } + + + protected function getUserApi() { + return $this->getClient()->api('user'); + } + + + protected function getIssueApi() { + return $this->getClient()->api('issue'); } - protected function getIssueApi($library) { - return $this->getClient($library)->api('issue'); + protected function getIssueStatusApi() { + return $this->getClient()->api('issue_status'); } - protected function getProjectApi($library) { - return $this->getClient($library)->api('project'); + protected function getIssuePrioritiesApi() { + return $this->getClient()->api('issue_priority'); } - public function getClient($library) { - if(static::$_redmine_client == null || !isset(static::$_redmine_client)) - return new Redmine\Client(Class_AdminVar::get('REDMINE_SERVER_URL'), $library->getRedmineLogin() ? $library->getRedmineLogin() : $library->getRedmineApiKey(), $library->getRedminePassword()); + protected function getProjectApi() { + return $this->getClient()->api('project'); + } + + + public function getClient() { + if (static::$_redmine_client == null || !isset(static::$_redmine_client)) + return new Redmine\Client(Class_AdminVar::get('REDMINE_SERVER_URL'), + $this->_library->getRedmineLoginOrKey(), + $this->_library->getRedminePassword()); return static::$_redmine_client; } + /** @category testing */ public static function setClient($redmine_client) { static::$_redmine_client = $redmine_client; } - public static function getCurrentUser($library) { - $instance = new self(); - if($requirement = $instance->missingApiRequirement($library)) - return $requirement; + /** @category testing */ + public static function setAdminClient($client) { + static::$_admin_client = $client; + } + + + public function getIssues() { + return $this->isValid() ? $this->getIssuesWithParams() : []; + } + - return $instance->getUserApi($library)->getCurrentUser(); + public function getClosedIssues() { + return $this->isValid() + ? $this->getIssuesWithParams(['status_id' => 'closed', + 'offset' => 0, + 'limit' => 5]) + : []; } - public static function getIssuesForLib($library) { - $instance = new self(); + protected function getIssuesWithParams($params=[]) { + $params['project_id'] = Class_AdminVar::get('REDMINE_PROJECT_ID'); - if($requirement = $instance->missingApiRequirement($library)) - return $requirement; + $data = $this->getIssueApi()->all($params); - return $instance->getIssueApi($library)->all(['assigned_to_id' => $library->getRedmineUserId(), - 'project_id' => Class_AdminVar::get('REDMINE_PROJECT_ID')]); + return isset($data['issues']) + ? array_map(['Class_WebService_Redmine_Issue', 'newWith'], $data['issues']) + : []; } - public static function getProject($library) { - $instance = new self(); + public function getUser() { + if (!$this->isValid()) + return false; - if(!$id_project = Class_AdminVar::get('REDMINE_PROJECT_ID')) - return ['error_message' => $instance->_('Aucun identifiant de projet a été renseigné')]; + $data = $this->getUserApi()->getCurrentUser(); - if($requirement = $instance->missingApiRequirement($library)) - return $requirement; + if (!isset($data['user'])) + return false; + + if ($this->_library) + $this->_library->setRedmineUserId($data['user']['id']) + ->save(); - return $instance->getProjectApi($library)->show($id_project); + return $this->_('Compte d\'assistance: %s', $data['user']['login']); } public static function extractIssues($data) { - $models = []; - if(!isset($data['issues'])) - return $models; + return isset($data['issues']) + ? array_map(['Class_WebService_Redmine_Issue', 'newWith'], $data['issues']) + : []; + } - return array_map(['Class_WebService_Redmine_Issue', 'newWith'], $data['issues']); + + public function createIssue($issue) { + $params = $issue->getCreateParams(); + $params['project_id'] = Class_AdminVar::get('REDMINE_PROJECT_ID'); + $params['status_id'] = 1; + $params['assigned_to_id'] = $this->_library->getRedmineUserId(); + + return $this->getIssueApi()->create($params); } - public static function extractConnectedUser($data, $library) { - if(!isset($data['user'])) - return false; - if($library) - $library->setRedmineUserId($data['user']['id']) - ->setRedmineApiKey($data['user']['api_key']) - ->save(); + public function updateIssue($issue) { + return $this->getIssueApi() + ->update($issue->getid(), $issue->getUpdateParams()); + } + + + public function getIssue($ticket) { + if (!$this->isValid() || !$ticket) + return new Class_WebService_Redmine_Issue(); + + $data = $this->getIssueApi()->show($ticket, ['include' => 'journals']); + $issue = Class_WebService_Redmine_Issue::newWith(isset($data['issue']) ? $data['issue'] : []); + $issue->setService($this); + + return $issue; + } + + + public function getIssueStatusOptions() { + $statuses = []; + foreach($this->getIssueStatus() as $status) + $statuses[$status['id']] = $status['name']; + + return $statuses; + } + + + public function getIssueStatus() { + if (!$this->isValid()) + return []; + + if (null != $this->_issue_statuses_cache) + return $this->_issue_statuses_cache; + + $data = $this->getIssueStatusApi() + ->all(['project_id' => Class_AdminVar::get('REDMINE_PROJECT_ID')]); + + if (!isset($data['issue_statuses'])) + return []; + + return $this->_issue_statuses_cache = $data['issue_statuses']; + } + + + public function getIssueStatusFor($id) { + if (!$this->isValid()) + return $id; + + $statuses = $this->getIssueStatusOptions(); + foreach($statuses as $k => $v) + if ($k == $id) + return $v; + + return $id; + } + + + public function getIssuePriorityFor($id) { + if (!$this->isValid()) + return $id; + + $items = $this->getIssuePriorities(); + foreach($items as $item) + if ($item['id'] == $id) + return $item['name']; - return (new self())->_('Vous êtes connecté(e) en tant que %s %s', - $data['user']['firstname'], - $data['user']['lastname']); + return $id; } - public static function extractProject($data) { - if(!isset($data['project'])) - return ''; + public function getIssuePriorities() { + if (!$this->isValid()) + return []; + + if (null != $this->_issue_priorities_cache) + return $this->_issue_priorities_cache; + + $data = $this->getIssuePrioritiesApi() + ->all(['project_id' => Class_AdminVar::get('REDMINE_PROJECT_ID')]); + + if (!isset($data['issue_priorities'])) + return []; + + return $this->_issue_priorities_cache = $data['issue_priorities']; + } + + + + public function isIssueStatusClosed($id) { + foreach($this->getIssueStatus() as $status) + if ($status['id'] == $id) + return $status['is_closed']; + + return false; + } + + + public function getCustomFieldFor($id) { + foreach($this->getCustomFields() as $field) + if ($field['id'] == $id) + return $field['name']; + + return $id; + } + + + public function getIssueCustomPriorities() { + return $this->getCustomOptions(static::CUSTOM_PRIORITY_ID); + } + + + public function getDefaultIssuePriority() { + return $this->getCustomFieldDefaultValue(static::CUSTOM_PRIORITY_ID); + } + + + public function getDefaultIssueModule() { + return $this->getCustomFieldDefaultValue(static::CUSTOM_MODULE_ID); + } + + + public function getDefaultIssueContact() { + return $this->getCustomFieldDefaultValue(static::CUSTOM_CONTACT_PERSON); + } + + + public function getDefaultIssueCustomer() { + return $this->getCustomFieldDefaultValue(static::CUSTOM_CUSTOMER); + } + + + public function getDefaultIssueQualification() { + return $this->getCustomFieldFirstValue(static::CUSTOM_QUALIFICATION); + } + + + protected function getCustomFieldDefaultValue($id) { + foreach($this->getCustomFields() as $field) { + if ($id != $field['id']) + continue; + + return isset($field['default_value']) ? $field['default_value'] : null; + } + } + + + protected function getCustomFieldFirstValue($id) { + foreach($this->getCustomFields() as $field) { + if ($id != $field['id']) + continue; + + foreach ($field['possible_values'] as $possible) + return $possible['value']; + + return ''; + } + } + + + public function getIssueModules() { + return $this->getCustomOptions(static::CUSTOM_MODULE_ID); + } + + + protected function getCustomOptions($id) { + $options = []; + foreach ($this->getCustomFields() as $field) { + if ($id != $field['id']) + continue; + + if (!isset($field['is_required']) || !$field['is_required']) + $options[''] = ''; + + foreach ($field['possible_values'] as $possible) { + $options[$possible['value']] = $possible['value']; + } + } + + return $options; + } + + + protected function getCustomFields() { + if (!$this->isValid()) + return []; + + if (null != $this->_custom_fields_cache) + return $this->_custom_fields_cache; + + $data = json_decode($this->httpGet(Class_AdminVar::get('REDMINE_PROXY_URL')),true); + if (!isset($data['custom_fields'])) + return []; + + $this->_custom_fields_cache = $data['custom_fields']; - return $data['project']['name']; + return $this->_custom_fields_cache; } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/library/Class/WebService/Redmine/Issue.php b/library/Class/WebService/Redmine/Issue.php index 3ba822926e2e92eebbb6b545093dde1112126065..e9b7c191b9e0acfa01d11f4c0cff18174e261712 100644 --- a/library/Class/WebService/Redmine/Issue.php +++ b/library/Class/WebService/Redmine/Issue.php @@ -21,10 +21,10 @@ class Class_WebService_Redmine_Issue extends Class_Entity { - public static function newWith($data) { - $instance = new self(); + $instance = new static(); $instance->updateAttributes($data); + return $instance; } @@ -32,5 +32,92 @@ class Class_WebService_Redmine_Issue extends Class_Entity { public function callGetterByAttributeName($attribute) { return parent::_get($attribute); } -} -?> \ No newline at end of file + + + public function getUpdateParams() { + $custom_fields = $this->getCustomFieldsParams(); + if ($this->isClosed() && !$this->getQualification()) + $custom_fields[] = ['id' => Class_WebService_Redmine::CUSTOM_QUALIFICATION, + 'value' => $this->getDefaultQualification()]; + + return ['status_id' => $this->_attribs['status_id'], + 'custom_fields' => $custom_fields, + 'notes' => $this->_attribs['notes']]; + } + + + public function getCreateParams() { + return ['subject' => $this->_attribs['subject'], + 'description' => $this->_attribs['description'], + 'custom_fields' => $this->getCustomFieldsParams()]; + } + + + protected function getCustomFieldsParams() { + return [['id' => Class_WebService_Redmine::CUSTOM_PRIORITY_ID, + 'value' => $this->_attribs['priority']], + ['id' => Class_WebService_Redmine::CUSTOM_MODULE_ID, + 'value' => $this->_attribs['module']], + ['id' => Class_WebService_Redmine::CUSTOM_CONTACT_PERSON, + 'value' => $this->_attribs['contact']], + ]; + } + + + public function getCustomField($id) { + if (!$fields = $this->getcustom_fields()) + return null; + + foreach($fields as $field) + if ($id == $field['id']) + return $field['value']; + + return null; + } + + + public function getPriority() { + return $this->getCustomField(Class_WebService_Redmine::CUSTOM_PRIORITY_ID); + } + + + public function getModule() { + return $this->getCustomField(Class_WebService_Redmine::CUSTOM_MODULE_ID); + } + + + public function getContact() { + return $this->getCustomField(Class_WebService_Redmine::CUSTOM_CONTACT_PERSON); + } + + + public function getLibrary() { + return $this->getService()->getLibrary(); + } + + + public function getQualification() { + return $this->getCustomField(Class_WebService_Redmine::CUSTOM_QUALIFICATION); + } + + + public function getDefaultQualification() { + return $this->withServiceDo( + function($service) { + return $service->getDefaultIssueQualification(); + }); + } + + + public function isClosed() { + return $this->withServiceDo( + function($service) { + return $service->isIssueStatusClosed($this->_attribs['status_id']); + }); + } + + + protected function withServiceDo($closure) { + return ($service = $this->getService()) ? $closure($service) : null; + } +} \ No newline at end of file diff --git a/library/ZendAfi/Form.php b/library/ZendAfi/Form.php index d09a50fbec25ccea383387bccccce762e794174b..698a0d0b532f8ba510a76cd76720d22270d0e9c7 100644 --- a/library/ZendAfi/Form.php +++ b/library/ZendAfi/Form.php @@ -182,5 +182,4 @@ class ZendAfi_Form extends Zend_Form { return $this->_summary; } } - ?> \ No newline at end of file diff --git a/library/ZendAfi/Form/Admin/Formation.php b/library/ZendAfi/Form/Admin/Formation.php index 2788ac71424fad20060713738327e678f7953986..82de178deee691cc5ac6a535b22ae490c573e119 100644 --- a/library/ZendAfi/Form/Admin/Formation.php +++ b/library/ZendAfi/Form/Admin/Formation.php @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE * along with BOKEH; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -27,7 +27,7 @@ class ZendAfi_Form_Admin_Formation extends ZendAfi_Form { $this ->setAttrib('id', 'formationform') ->addRequiredTextNamed('libelle') - ->setLabel('Libellé *'); + ->setLabel('Libellé'); $this ->addElement('ckeditor', diff --git a/library/ZendAfi/Form/Admin/Library.php b/library/ZendAfi/Form/Admin/Library.php index 46b6513fbbcefbd216853eab2f62cc9e132d2aae..978153d59e2ed6b4645a34b73c22388872d168c3 100644 --- a/library/ZendAfi/Form/Admin/Library.php +++ b/library/ZendAfi/Form/Admin/Library.php @@ -200,38 +200,29 @@ class ZendAfi_Form_Admin_Library extends ZendAfi_Form { ->addElement('text', 'redmine_login', ['label' => $this->_('Pseudo'), - 'size' => 50]) + 'size' => 50, + 'autocomplete' => 'off']) ->addElement('password', 'redmine_password', ['label' => $this->_('Mot de passe'), 'size' => 50, - 'onkeypress' => 'if (event.keyCode == 13) {this.form.submit();return false;}', - 'renderPassword' => true]) + 'renderPassword' => true, + 'autocomplete' => 'off']) ->addElement('password', 'redmine_api_key', ['label' => $this->_('Clé API'), 'size' => 50, - 'onkeypress' => 'if (event.keyCode == 13) {this.form.submit();return false;}', - 'renderPassword' => true]) - - ->addElement('text', - 'redmine_status', - ['label' => $this->_('Tester la configuration')]) + 'renderPassword' => true, + 'autocomplete' => 'off']) ->addDisplayGroup(['redmine_login', 'redmine_password', - 'redmine_api_key', - 'redmine_status'], + 'redmine_api_key'], 'redmine', ['legend' => $this->_('Configuration du compte Redmine')]); - $this->getElement('redmine_status') - ->addDecorator('Redmine', ['view' => $this->getView(), - 'library' => $this->getView()->bib]); - return $this; } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/library/ZendAfi/Form/Admin/SessionFormation.php b/library/ZendAfi/Form/Admin/SessionFormation.php index bf0dbfa6bbbd6aac2de0660d2a9d4834a0c7d721..7aebd5914a380bf3515f71db3307fa00d166c721 100644 --- a/library/ZendAfi/Form/Admin/SessionFormation.php +++ b/library/ZendAfi/Form/Admin/SessionFormation.php @@ -36,7 +36,7 @@ class ZendAfi_Form_Admin_SessionFormation extends ZendAfi_Form { ->setAttrib('id', 'sessionForm') ->setMethod('post') ->addElement('datePicker', 'date_debut', array( - 'label' => 'Date début *', + 'label' => 'Date début', 'size' => 10, 'required' => true, 'allowEmpty' => false )) @@ -44,19 +44,19 @@ class ZendAfi_Form_Admin_SessionFormation extends ZendAfi_Form { 'label' => 'Date fin', 'size' => 10 )) ->addElement('datePicker', 'date_limite_inscription', array( - 'label' => 'Date limite d\'inscription *', + 'label' => 'Date limite d\'inscription', 'size' => 10, 'required' => true, 'allowEmpty' => false)) ->addElement('text', 'effectif_min', array( - 'label' => 'Effectif minimum *', + 'label' => 'Effectif minimum', 'size' => 2, 'required' => true, 'allowEmpty' => false, 'validators' => array('int'))) ->addElement('text', 'effectif_max', array( - 'label' => 'Effectif maximum *', + 'label' => 'Effectif maximum', 'size' => 2, 'required' => true, 'allowEmpty' => false, @@ -67,7 +67,7 @@ class ZendAfi_Form_Admin_SessionFormation extends ZendAfi_Form { 'validators' => array('int'))) ->addElement('text', 'horaires', array( - 'label' => 'Horaires *', + 'label' => 'Horaires', 'size' => 50, 'required' => true, 'allowEmpty' => false)) diff --git a/library/ZendAfi/Form/Admin/User.php b/library/ZendAfi/Form/Admin/User.php index 2c94ff91ae32c4152445862a48d23fc732c107c0..08a4e957a25c1be80fb4dc40c65aa6cd03f8a6be 100644 --- a/library/ZendAfi/Form/Admin/User.php +++ b/library/ZendAfi/Form/Admin/User.php @@ -202,27 +202,38 @@ class ZendAfi_Form_Admin_User extends ZendAfi_Form { return $this; } + protected function addSIGB() { + $user = $this->getView()->user; + $disabled = $user->getRoleLevel() <= ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB + ? ['disabled' => 'disabled'] + : []; + $this ->addElement('text', 'idabon', - ['label' => $this->_('Numéro'), - 'size' => 50]) + array_merge(['label' => $this->_('Numéro'), + 'size' => 50], + $disabled)) ->addElement('text', 'ordreabon', - ['label' => $this->_('Ordre'), - 'size' => 50]) + array_merge(['label' => $this->_('Ordre'), + 'size' => 50], + $disabled)) ->addElement('dateRangePicker', 'subscription_range_date', ['label' => $this->_('Validité'), + 'start' => ['name' => 'date_debut', 'allowEmpty' => true, 'dateOnly' => true, 'disabled' => true, 'toggleAllDay' => 'all_day'], + 'end' => ['name' => 'date_fin', + 'allowEmpty' => true, 'dateOnly' => true, 'disabled' => true, 'toggleAllDay' => 'all_day']]) @@ -241,13 +252,13 @@ class ZendAfi_Form_Admin_User extends ZendAfi_Form { return $this; $user = $this->getView()->user; - $user_library = $user->getRedmineLibrary(); - $value = $user_library ? $user_library->getId() : null; - $options = ['0' => $this->_('Aucune')]; - foreach(Class_Bib::findAllWithRedmine($user) as $library) - $options[$library->getId()] = $library->getLibelle(); + if($user->getRoleLevel() <= ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB) + return $this; + $user_library = $user->getRedmineLibrary(); + $value = $user_library ? $user_library->getId() : 0; + $options = $this->_getLibraries(); $this ->addElement('select', 'redmine_library', @@ -262,7 +273,7 @@ class ZendAfi_Form_Admin_User extends ZendAfi_Form { ->addDisplayGroup(['redmine_library', 'redmine_status'], 'redmine', - ['legend' => $this->_('Accès à la forge')]); + ['legend' => $this->_('Compte d\'accès à l\'assistance')]); $this->getElement('redmine_status') ->addDecorator('Redmine', ['view' => $this->getView(), @@ -270,5 +281,11 @@ class ZendAfi_Form_Admin_User extends ZendAfi_Form { return $this; } + + + protected function _getLibraries() { + return array_merge(['0' => $this->_('Aucune')], + Class_Bib::findAllLabels()); + } } ?> \ No newline at end of file diff --git a/library/ZendAfi/Form/Admin/UserGroup.php b/library/ZendAfi/Form/Admin/UserGroup.php index c62e231e73b8925fe1852b345892c62116b8bf87..aff54cf68f85d8045b9152b5524eced9e19ad5d8 100644 --- a/library/ZendAfi/Form/Admin/UserGroup.php +++ b/library/ZendAfi/Form/Admin/UserGroup.php @@ -27,7 +27,7 @@ class ZendAfi_Form_Admin_UserGroup extends ZendAfi_Form { $this ->setAttrib('id', 'usergroupform') ->addRequiredTextNamed('libelle') - ->setLabel('Libellé *'); + ->setLabel('Libellé'); $this ->addElement('radio', diff --git a/library/ZendAfi/Form/Album.php b/library/ZendAfi/Form/Album.php index 6c2a2432b3f7fd807e417267503817cb69ffce5e..6e83ade7dc51a1c1fdc47acbf9f1e5dbd67f0631 100644 --- a/library/ZendAfi/Form/Album.php +++ b/library/ZendAfi/Form/Album.php @@ -133,7 +133,7 @@ class ZendAfi_Form_Album extends ZendAfi_Form { $this ->setAttrib('id', 'album') ->setAttrib('enctype', self::ENCTYPE_MULTIPART) - ->addElement('text', 'titre', ['label' => $this->_('Titre *'), + ->addElement('text', 'titre', ['label' => $this->_('Titre'), 'style' => 'width:440px;', 'size' => 75, 'required' => true, diff --git a/library/ZendAfi/Form/Decorator/Redmine.php b/library/ZendAfi/Form/Decorator/Redmine.php index 91e48e7a535f27c702b1972ab3c8c4a6d47cbe01..8db3e0f31a93342bba1f8d2db0651cae7444589c 100644 --- a/library/ZendAfi/Form/Decorator/Redmine.php +++ b/library/ZendAfi/Form/Decorator/Redmine.php @@ -22,7 +22,11 @@ class ZendAfi_Form_Decorator_Redmine extends Zend_Form_Decorator_Abstract { public function render($content) { $view = $this->getOption('view'); - return $content . $view->Redmine_AccountStatus($this->getOption('library')); + $library = $this->getOption('library'); + $content = $content . + $view->Redmine_AccountStatus($library) . + $view->getHelper('Redmine_Header')->anchorEditLibrary($library); + return $content; } } ?> \ No newline at end of file diff --git a/library/ZendAfi/Form/FRBR/Link.php b/library/ZendAfi/Form/FRBR/Link.php index 69f1b294e9fb4c92fae9b3e3980586b9d3482938..6115dfaace873ac06e32c6cfcee7c900328fd024 100644 --- a/library/ZendAfi/Form/FRBR/Link.php +++ b/library/ZendAfi/Form/FRBR/Link.php @@ -26,9 +26,9 @@ class ZendAfi_Form_FRBR_Link extends ZendAfi_Form { ->setAttrib('id', 'frbr_link') ->setAttrib('class', 'zend_form') - ->addElement('frbrType', 'type_id', ['label' => $this->_('Type').' *']) - ->addElement('text', 'source', ['label' => $this->_('URL Objet A') . ' *', 'size' => 80]) - ->addElement('text', 'target', ['label' => $this->_('URL Objet B') . ' *', 'size' => 80]) + ->addElement('frbrType', 'type_id', ['label' => $this->_('Type'), 'required' => true]) + ->addElement('text', 'source', ['label' => $this->_('URL Objet A') ,'required' => true, 'size' => 80]) + ->addElement('text', 'target', ['label' => $this->_('URL Objet B') ,'required' => true, 'size' => 80]) ->addDisplayGroup(['type_id', 'source', 'target'], 'link', ['legend' => '']); } diff --git a/library/ZendAfi/Form/FRBR/LinkType.php b/library/ZendAfi/Form/FRBR/LinkType.php index fa6462416851f8ee2034eba7ca787e3593274eb7..5ac3cb83f930be94ec499eae3cbc66b0391a02f2 100644 --- a/library/ZendAfi/Form/FRBR/LinkType.php +++ b/library/ZendAfi/Form/FRBR/LinkType.php @@ -26,11 +26,11 @@ class ZendAfi_Form_FRBR_LinkType extends ZendAfi_Form { ->setAttrib('id', 'frbr_linktype') ->setAttrib('class', 'zend_form') - ->addElement('text', 'libelle', ['label' => $this->_('Nom').' *', 'size' => 80]) - ->addElement('text', 'from_source', ['label' => $this->_('Libellé de l\'objet A vers l\'objet B') . ' *', - 'size' => 80]) - ->addElement('text', 'from_target', ['label' => $this->_('Libellé de l\'objet B vers l\'objet A') . ' *', - 'size' => 80]) + ->addElement('text', 'libelle', ['label' => $this->_('Nom'), 'size' => 80, 'required' => true]) + ->addElement('text', 'from_source', ['label' => $this->_('Libellé de l\'objet A vers l\'objet B') , + 'size' => 80, 'required' => true]) + ->addElement('text', 'from_target', ['label' => $this->_('Libellé de l\'objet B vers l\'objet A') , + 'size' => 80, 'required' => true]) ->addDisplayGroup(['libelle', 'from_source', 'from_target'], 'linktype', ['legend' => '']); } diff --git a/library/ZendAfi/Form/Login.php b/library/ZendAfi/Form/Login.php index 00eacdf86efc6803906a4a0bf42ffe4df7d1cc99..00a80e7bb2d5f006fb3efc9e90b87f05af3e5873 100644 --- a/library/ZendAfi/Form/Login.php +++ b/library/ZendAfi/Form/Login.php @@ -54,8 +54,7 @@ class ZendAfi_Form_Login extends ZendAfi_Form { 'placeholder' => $this->_data['mot_de_passe_exemple'], 'required' => true, 'allowEmpty' => false, - 'size' => 15, - 'onkeypress' => 'if (event.keyCode == 13) {this.form.submit();return false;}']) + 'size' => 15]) ->addElement('submit', 'login', diff --git a/library/ZendAfi/Form/Redmine/Issue.php b/library/ZendAfi/Form/Redmine/Issue.php new file mode 100644 index 0000000000000000000000000000000000000000..d431b4140c5c5f93f37cb2142bd7e65898dbd8db --- /dev/null +++ b/library/ZendAfi/Form/Redmine/Issue.php @@ -0,0 +1,225 @@ +<?php +/** + * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class ZendAfi_Form_Redmine_Issue extends ZendAfi_Form { + protected + $_issue, + $_status = [], $_priorities = [], $_modules = [], + $_default_priority, $_default_module, $_default_contact, $_default_customer; + + + public static function newWithIssue($issue, $service) { + return (new static()) + ->initIssue($issue) + ->initMultiOptions($service) + ->initInputs(); + } + + + protected function initIssue($issue) { + $this->_issue = $issue; + return $this; + } + + + protected function initMultiOptions($service) { + $this->_status = $service->getIssueStatusOptions(); + + $this->_priorities = $service->getIssueCustomPriorities(); + $this->_modules = $service->getIssueModules(); + $this->_default_priority = $service->getDefaultIssuePriority(); + $this->_default_module = $service->getDefaultIssueModule(); + $this->_default_contact = $service->getDefaultIssueContact(); + $this->_default_customer = $service->getDefaultIssueCustomer(); + + return $this; + } + + + protected function initInputs() { + if (!$this->_issue->getid()) { + $this + ->addElement('text', + 'subject', + ['label' => $this->_('Sujet'), + 'size' => 70, + 'required' => true, + 'allowEmpty' => false]) + + ->addElement('textarea', + 'description', + ['label' => $this->_('Description'), + 'rows' => 10, + 'cols' => 70, + 'required' => true, + 'allowEmpty' => false, + 'value' => $this->getDefaultDescription()]) + + ->addDisplayGroup(['subject', 'description'], + 'common', + ['legend' => '']) + ; + } + + + if ($this->_issue->getid()) { + $this + ->addElement('textarea', 'notes', ['rows' => 5, 'cols' => 100]) + ->addDisplayGroup(['notes'], 'default', ['legend' => $this->_('Nouvelle note')]); + } + + + $this->addStatus() + + ->addElement('text', + 'customer', + ['label' => $this->_('Client'), + 'size' => 70, + 'value' => $this->_issue->getCustomer() ? $this->_issue->getCustomer() : $this->getDefaultCustomer()]) + + ->addElement('select', + 'priority', + ['label' => $this->_('Priorité client'), + 'required' => true, + 'allowEmpty' => false, + 'multioptions' => $this->_priorities, + 'value' => $this->_issue->getPriority() ? $this->_issue->getPriority() : $this->_default_priority]) + + ->addElement('select', + 'module', + ['label' => $this->_('Module Portail'), + 'multioptions' => $this->_modules, + 'value' => $this->_issue->getModule() ? $this->_issue->getModule() : $this->_default_module]) + + ->addElement('textarea', + 'contact', + ['label' => $this->_('Personne à contacter'), + 'rows' => 2, 'cols' => 70, + 'value' => $this->_issue->getContact() ? $this->_issue->getContact() : $this->getDefaultContact()]) + + + ->addDisplayGroup(['customer', 'status_id', 'priority', 'module', 'contact'], + 'properties', + ['legend' => $this->_('Propriétés')]); + + return $this; + } + + + protected function getDefaultContact() { + if ($this->_issue->getid()) + return ''; + + if ($by_user = $this->getDefaultUserContact()) + return $by_user; + + return ($by_lib = $this->getDefaultLibraryContact()) + ? $by_lib : $this->_default_contact; + } + + + protected function getDefaultUserContact() { + if (!$user = Class_Users::getIdentity()) + return; + + $datas = [$user->getNom(), + $user->getPrenom(), + $user->getMail(), + $user->hasTelephone() ? $user->getTelephone() : $user->getMobile()]; + + foreach($datas as $data) + if ($data) + return implode(' / ', array_filter($datas)); + } + + + protected function getDefaultLibraryContact() { + if (!$library = $this->_issue->getLibrary()) + return; + + if ($library->hasMail() || $library->hasTelephone()) + return implode(' / ', array_filter([$library->getLibelle(), + $library->getMail(), + $library->getTelephone()])); + } + + + protected function getDefaultCustomer() { + if ($this->_issue->getid()) + return ''; + + return ($library = $this->_issue->getLibrary()) && ($label = $library->getLibelle()) + ? $label : $this->_default_customer; + } + + + protected function addStatus() { + if (!$current = $this->_issue->getstatus()['id']) + return $this; + + $possibles = []; + + /** !! from id status to id status (AFI, specifics) */ + $workflow = [1 => [5], + 14 => [1], + 15 => [], + 4 => [2, 5], + 19 => [], + 2 => [1, 5], + 13 => [], + 22 => [], + 7 => [5], + 18 => [], + 16 => [], + 3 => [5], + 17 => [], + 11 => [4, 5], + 8 => [5], + 12 => [], + 5 => [1], + 6 => [1, 5]]; + + foreach($this->_status as $k => $v) { + if ($k == $current + || (array_key_exists($current, $workflow) && in_array($k, $workflow[$current]))) + $possibles[$k] = $v; + } + + $this->addElement('select', + 'status_id', + ['label' => $this->_('Status'), + 'multioptions' => $possibles, + 'value' => $current]); + + return $this; + } + + + protected function getDefaultDescription() { + $datas = [$this->_('Url : ') . Class_Url::rootUrl() . Class_Url::baseUrl(), + $this->_('Version : ') . BOKEH_RELEASE_NUMBER . ' (' . BOKEH_VERSION . ')', + $this->_('Navigateur : ') . Zend_Controller_Front::getInstance()->getRequest()->getHeader('User-Agent'), + $this->_('Base de données : ') . Zend_Db_Table::getDefaultAdapter()->getConfig()['dbname']]; + + return implode("\n", $datas); + } +} \ No newline at end of file diff --git a/library/ZendAfi/View/Helper/Admin/HelpLink.php b/library/ZendAfi/View/Helper/Admin/HelpLink.php index 5ba47b992d815333373b055020d70c331287018f..02fb23204d7a4f6e706441f1aba6dc1064adc7b9 100644 --- a/library/ZendAfi/View/Helper/Admin/HelpLink.php +++ b/library/ZendAfi/View/Helper/Admin/HelpLink.php @@ -75,7 +75,9 @@ class ZendAfi_View_Helper_Admin_HelpLinkBokehWiki { 'accueil' => 'Configurer_une_page', 'menusindex' => 'Configurer_un_menu', 'proprietes' => 'Réglage_de_l\'affichage_des_exemplaires'], - 'redmine' => ['index' => 'Visualisation_des_tickets_Redmine'], + 'redmine' => ['index' => 'Intégration_des_demandes_d\'assistance', + 'add' => 'Intégration_des_demandes_d\'assistance#Ajout_d.27une_demande', + 'edit-issue' => 'Intégration_des_demandes_d\'assistance#Modification_d.27une_demande'], 'opds' => ['index' => 'Importer_des_livres_numériques'], 'bib' => ['index' => 'Modifier_une_bibliothèque'], 'index' => ['index' => 'Bokeh'] diff --git a/library/ZendAfi/View/Helper/Admin/MenuHorizontalAdmin.php b/library/ZendAfi/View/Helper/Admin/MenuHorizontalAdmin.php index 1a5a4aa898d1b903285d341b92a5261381d4f466..38e03c7bff1076d7683ddd9dea707470af85a023 100644 --- a/library/ZendAfi/View/Helper/Admin/MenuHorizontalAdmin.php +++ b/library/ZendAfi/View/Helper/Admin/MenuHorizontalAdmin.php @@ -26,7 +26,7 @@ class ZendAfi_View_Helper_Admin_MenuHorizontalAdmin extends ZendAfi_View_Helper_ public function menuHorizontalAdmin() { $redmine = Class_AdminVar::isRedmineEnabled() ? ['icon' => 'redmine_16.png', - 'label' => $this->_('Redmine'), + 'label' => $this->_('Assistance'), 'url' => $this->view->url(['module' => 'admin', 'controller' => 'redmine', 'action' => 'index'], null, true)] diff --git a/library/ZendAfi/View/Helper/Redmine/AccountStatus.php b/library/ZendAfi/View/Helper/Redmine/AccountStatus.php index e6a1b1099b395785dfd06106bb291d2bc6bf8e6c..fac1f8d77b1521c0839459a470fbf1bff622bce0 100644 --- a/library/ZendAfi/View/Helper/Redmine/AccountStatus.php +++ b/library/ZendAfi/View/Helper/Redmine/AccountStatus.php @@ -29,7 +29,7 @@ class ZendAfi_View_Helper_Redmine_AccountStatus extends ZendAfi_View_Helper_Base Class_ScriptLoader::getInstance() ->addOpacScript('redmine') ->addJQueryReady('$("a.redmine_status").autoRefresh();') - ->addJQueryReady('var html = $("a.redmine_status"); var input = $("#redmine_status"); input.parent().append(html); input.remove()'); + ->addJQueryReady('var html = $("a.redmine_status, a.library_redmine_account"); var input = $("#redmine_status"); input.parent().append(html); input.remove()'); $lib_id = $library ? $library->getId() : 0; diff --git a/library/ZendAfi/View/Helper/Redmine/Header.php b/library/ZendAfi/View/Helper/Redmine/Header.php index a12ba3facee0b0d3a6712d700fddc286373fbce7..0800522d6ebaef207b94b756d09224fda677dbbd 100644 --- a/library/ZendAfi/View/Helper/Redmine/Header.php +++ b/library/ZendAfi/View/Helper/Redmine/Header.php @@ -21,58 +21,98 @@ class ZendAfi_View_Helper_Redmine_Header extends ZendAfi_View_Helper_BaseHelper { + protected $_user, $_library, $_user_info, $_others; + + public function Redmine_Header($user, $library, $user_info, $others=[]) { + $this->_user = $user; + $this->_library = $library; + $this->_user_info = $user_info; + $this->_others = $others; - public function Redmine_Header($user, $library, $user_info = false, $project_info) { if (!Class_AdminVar::isRedmineEnabled() || !$user) return ''; - if(!$user_info) - $this->view->getHelper('Redmine_AccountStatus')->connectionFail(); + if ((!$user->getRedmineLibrary()) && (!$library)) + return $this->shouldSelectLib(); + + $add_button = $user_info + ? $this->view->bouton('id=add_issue', + 'picto=add.gif', + 'texte='.$this->_('Nouvelle demande'), + 'url=' . $this->view->url(['action' => 'add', + 'id' => null, + 'id_lib' => $library->getId()]), + 'largeur=250px;') + : ''; + + return $this->view->tag('p', $this->connectedThrough()) + . $add_button; + } + + + public function shouldSelectLib($user=null) { + return $this->view + ->tag('p', + $this->anchorEditUser($this->_('Vous devez sélectionner une bibliothèque'), $user)); + } - if((!$user->getRedmineLibrary()) && (!$library)) - return $this->shouldSelectLib($user); - return $this->view->tag('p', $this->projectInfo($project_info) . - BR . - $this->connectedThrough($user, $library, $user_info)); + protected function connectedThrough() { + return $this + ->_tag('div', $this->renderLibraryLabel() . $this->anchorEditLibrary($this->_library, $this->_user_info), + ['class' => 'form']); } - protected function shouldSelectLib($user) { - return $this->view->tag('p', $this->anchorEditUser($user, $this->_('Vous devez sélectionner une bibliothèque'))); + protected function renderLibraryLabel() { + return ($this->_others && 1 < count($this->_others)) + ? $this->renderLibrariesSelector() + : $this->anchorEditUser($this->_library->getLabel()); } - protected function connectedThrough($user, $library, $user_info) { - return - $this->anchorEditLibrary($library, $user_info) . - $this->_(' au travers de la bibliothèque ') . - $this->anchorEditUser($user, $library->getLibelle()); + protected function renderLibrariesSelector() { + $location = $this->view->url(['module' => 'admin', + 'controller' => 'redmine'], null, true); + + return $this->_tag('strong', $this->_('Bibliothèque : ')) + . $this->view->formSelect('library', + $this->_library ? $this->_library->getId() : null, + ['onchange' => "location='" . $location . "/index/id_bib/' + this.value "], + $this->_others); } - protected function anchorEdituser($user, $library_label) { + protected function anchorEdituser($label, $user=null) { + $user = $user ? $user : $this->_user; + return $this->view->tagAnchor($this->view->url(['module' => 'admin', 'controller' => 'users', 'action' => 'edit', 'id' => $user->getId()], null ,true) . '#redmine', - $library_label, + $label, ['title' => $this->_('sélectionner une autre bibliothèque')]); } - protected function anchorEditLibrary($library, $user_info) { + public function anchorEditLibrary($library, $user_info = '') { + if(!$library) + return ''; + + $title = $this->_('Modifier le compte d\'assistance'); + return $this->view->tagAnchor($this->view->url(['module' => 'admin', 'controller' => 'bib', 'action' => 'edit', 'id' => $library->getId()], null ,true) . '#redmine', - $user_info ? $user_info : $this->_('Aucun compte'), - ['title' => $this->_('modifier le compte redmine')]); + $user_info ? $user_info : $title, + ['class' => 'library_redmine_account', + 'title' => $title]); } - protected function projectInfo($name) { - return $this->_('Projet sélectionné : ') . $this->anchorEditProject($name); + public function projectInfo($name) { + return $this->_('Demandes filtrées par le projet : ') . $this->anchorEditProject($name); } @@ -85,5 +125,4 @@ class ZendAfi_View_Helper_Redmine_Header extends ZendAfi_View_Helper_BaseHelper ['title' => $this->_('sélectionner un autre projet'), 'data-popup' => 'true']); } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/library/ZendAfi/View/Helper/Redmine/IssueJournal.php b/library/ZendAfi/View/Helper/Redmine/IssueJournal.php new file mode 100644 index 0000000000000000000000000000000000000000..2b1a65b6fcf9c67033a3f1ca646f8b3a8dc50c44 --- /dev/null +++ b/library/ZendAfi/View/Helper/Redmine/IssueJournal.php @@ -0,0 +1,184 @@ +<?php +/** + * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class ZendAfi_View_Helper_Redmine_IssueJournal extends ZendAfi_View_Helper_BaseHelper { + protected $_issue; + + public function Redmine_IssueJournal($issue) { + if (!$issue || (!$events = $issue->getjournals())) + return $this->_('Aucun historique'); + + Class_ScriptLoader::getInstance() + ->addInlineStyle(' +.models td { padding:5px; vertical-align:top;} +.models td pre, .models td ul { font-family:inherit; margin:0; } +'); + + $this->_issue = $issue; + + return $this->_tag('table', + $this->renderHeader() . $this->renderBody($events), + ['class' => 'models']); + } + + + protected function renderHeader() { + return $this->_tag('thead', + $this->_tag('tr', + $this->_tag('th', $this->_('Créé le')) + . $this->_tag('th', $this->_('Acteur')) + . $this->_tag('th', $this->_('Note')) + . $this->_tag('th', $this->_('Détails')))); + } + + + protected function renderBody($events) { + $html = ''; + foreach($events as $event) + $html .= $this->render($event); + + return $this->_tag('tbody', $html); + } + + + protected function render($event) { + return $this->_tag('tr', + $this->renderDate($event) + . $this->renderAuthor($event) + . $this->renderNote($event['notes']) + . $this->renderDetails($event['details']) + ); + } + + + protected function renderDate($event) { + return $this->_tag('td', strftime($this->_('%x à %X'), strtotime($event['created_on']))); + } + + + protected function renderAuthor($event) { + return $this->_tag('td', $event['user']['name']); + } + + + protected function renderDetails($details) { + $html = ''; + foreach($details as $detail) + $html .= $this->renderDetail($detail); + + return $this->_tag('td', $this->_tag('ul', $html)); + } + + + protected function renderNote($note) { + return $this->_tag('td', $note ? nl2br($note) : ''); + } + + + protected function renderDetail($detail) { + if ('relation' == $detail['property']) + return $this->_tag('li', $this->labelFromCode($detail['name'], + isset($detail['old_value']) ? $detail['old_value'] : null, + isset($detail['new_value']) ? $detail['new_value'] : null)); + + if ('attr' == $detail['property']) + return $this->_tag('li', $this->labelFromCode($detail['name'], $detail['old_value'], $detail['new_value'])); + + if ('cf' == $detail['property']) + return $this->_tag('li', $this->getChangeLabel($this->customFrom($detail['name']), + $detail['old_value'], $detail['new_value'])); + + return ''; + } + + + protected function labelFromCode($code, $old_value, $new_value) { + $mapping = + ['copied_from' => function() use ($old_value, $new_value) { + return $this->getRelationLabel($this->_('Copié depuis'), $old_value, $new_value); + }, + + 'copied_to' => function() use ($old_value, $new_value) { + return $this->getRelationLabel($this->_('Copié vers'), $old_value, $new_value); + }, + + 'blocks' => function() use ($old_value, $new_value) { + return $this->getRelationLabel($this->_('Bloque'), $old_value, $new_value); + }, + + 'status_id' => function() use ($old_value, $new_value) { + return $this->getChangeLabel($this->_('Statut'), + $this->statusFrom($old_value), $this->statusFrom($new_value)); + }, + + 'priority_id' => function() use ($old_value, $new_value) { + return $this->getChangeLabel($this->_('Priorité'), + $this->priorityFrom($old_value), $this->priorityFrom($new_value)); + }, + + 'done_ratio' => function() use ($old_value, $new_value) { + return $this->getChangeLabel($this->_('% réalisé'), $old_value, $new_value); + }]; + + return array_key_exists($code, $mapping) + ? $mapping[$code]() + : $this->getChangeLabel($code, $old_value, $new_value); + } + + + protected function statusFrom($id) { + if (!$service = $this->_issue->getService()) + return $id; + + return $service->getIssueStatusFor($id); + } + + + protected function priorityFrom($id) { + if (!$service = $this->_issue->getService()) + return $id; + + return $service->getIssuePriorityFor($id); + } + + + protected function customFrom($id) { + if (!$service = $this->_issue->getService()) + return $this->_('Champ personnalisé %s', $id); + + return $service->getCustomFieldFor($id); + } + + + protected function getChangeLabel($field, $old_value, $new_value) { + return (!$old_value) + ? $this->_('%s mis à %s', $field, $new_value) + : $this->_('%s changé de %s à %s', $field, $old_value, $new_value); + } + + + protected function getRelationLabel($type, $old_value, $new_value) { + return $new_value + ? $this->_('%s #%s ajouté', $type, $new_value) + : $this->_('%s #%s supprimé', $type, $old_value); + } +} diff --git a/library/ZendAfi/View/Helper/Redmine/Issues.php b/library/ZendAfi/View/Helper/Redmine/Issues.php index f0648d76f11f59378b36a9c5d5a19f0b0ccb2626..11c9c76b7f9573313c9f8203fd97b86eb4414fe4 100644 --- a/library/ZendAfi/View/Helper/Redmine/Issues.php +++ b/library/ZendAfi/View/Helper/Redmine/Issues.php @@ -21,22 +21,49 @@ class ZendAfi_View_Helper_Redmine_Issues extends ZendAfi_View_Helper_BaseHelper { + public function Redmine_Issues($library) { + if (!Class_AdminVar::isRedmineEnabled() || !$library) + return ''; + + return $this->renderIssues($library, $library->getIssues(), $this->_('Demandes en cours')) + . $this->renderIssues($library, $library->getClosedIssues(), $this->_('Demandes fermées')); + } - public function Redmine_Issues($issues) { - if (!Class_AdminVar::isRedmineEnabled()) + + protected function renderIssues($library, $issues, $label) { + if (!$issues) return ''; - return $this->view->tagModelTable($issues, - [$this->_('Numéro de ticket'), - $this->_('Sujet'), - $this->_('Description'), - $this->_('Date de création')], - ['id', - 'subject', - 'description', - 'created_on'], - null, - null); + $editAction = function($issue) use($library) { + return $this->view->tagAnchor(['module' => 'admin', + 'controller' => 'redmine', + 'action' => 'edit-issue', + 'id_lib' => $library->getLibrary()->getId(), + 'id' => $issue->getid()], + $this->view->boutonIco('type=edit')); + }; + + $status_renderer = function($model) { + return $model->getstatus()['name']; + }; + + $date_renderer = function($model) { + return strftime('%x', strtotime($model->getcreated_on())); + }; + + return $this->_tag('h3', $label) + . $this->view->tagModelTable($issues, + [$this->_('Numéro'), $this->_('Sujet'), + $this->_('Statut'), $this->_('Créée le')], + + ['id', 'subject', 'status', 'created_on'], + + [$editAction], + + 'issues-' . $library->getLibrary()->getId(), + null, + + ['status' => $status_renderer, + 'created_on' => $date_renderer]); } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/library/ZendAfi/View/Helper/Redmine/Library.php b/library/ZendAfi/View/Helper/Redmine/Library.php new file mode 100644 index 0000000000000000000000000000000000000000..7515953d320c601a5999cc4f2b361141fd815138 --- /dev/null +++ b/library/ZendAfi/View/Helper/Redmine/Library.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class ZendAfi_View_Helper_Redmine_Library extends ZendAfi_View_Helper_BaseHelper { + public function redmine_Library($library, $user, $others=[]) { + return $this->view->redmine_Header($user, $library->getLibrary(), $library->getUser(), $others) + . $this->view->redmine_Issues($library); + } +} \ No newline at end of file diff --git a/library/ZendAfi/View/Helper/RenderForm.php b/library/ZendAfi/View/Helper/RenderForm.php index d7847952eec5473f009cc6522732b1503dac1c4f..999e83afa077bb557c741f6c163fe74624c3f638 100644 --- a/library/ZendAfi/View/Helper/RenderForm.php +++ b/library/ZendAfi/View/Helper/RenderForm.php @@ -78,7 +78,11 @@ class ZendAfi_View_Helper_RenderForm extends ZendAfi_View_Helper_BaseHelper { protected function _decoratorsForTableRendering($element) { - $newDecorators = array(); + $newDecorators = []; + + if ('formText' == $element->helper) + $element->onkeypress = 'if (event.keyCode == 13) {this.form.submit();return false;}'; + $decorators = $element->getDecorators(); foreach ($decorators as $name => $decorator) { $name = explode('_', $name); diff --git a/library/storm b/library/storm index 92ffd36e9323bee39bbbdce09ba8e0b11b0ba0b2..72d925ab2bcd2a97f97f4ec2bb8be6b63ebdf462 160000 --- a/library/storm +++ b/library/storm @@ -1 +1 @@ -Subproject commit 92ffd36e9323bee39bbbdce09ba8e0b11b0ba0b2 +Subproject commit 72d925ab2bcd2a97f97f4ec2bb8be6b63ebdf462 diff --git a/public/admin/css/global.css b/public/admin/css/global.css index 27dcc58ca5c1f5904a5b8921055e3cd536a5e65a..0f1b255c31cdfbf9dc02f9e43691ab3d6d1e707b 100644 --- a/public/admin/css/global.css +++ b/public/admin/css/global.css @@ -10,8 +10,6 @@ a, .menuAdmin li { } - - /* Menu Gauche */ .menuGaucheAdmin{background-color:#FFFFFF;border:1px solid #B0BEC7;width:95%;border-radius: 5px; -moz-border-radius: 5px; margin-bottom: 10px} .menuGaucheAdmin table {border:none; width: 100%; border-radius: 5px; border-collapse: collapse} @@ -72,6 +70,12 @@ li.selected {font-weight: bold;} } /* Form */ + +.required:after { + content:" *"; + color: red; +} + .form { background-color:#F0F0F0; border:1px solid #C8C8C8; @@ -1337,6 +1341,10 @@ div#reader { } +.library_redmine_account { + float: right; +} + .digital_connectors td { padding-bottom: 20px; diff --git a/public/admin/images/picto/redmine_16.png b/public/admin/images/picto/redmine_16.png index 9d48fcf980b8af5371081cf0da26974b61924b1d..93aabf1a1e9d01c400fc846195bf2cf2ec8aeb10 100644 Binary files a/public/admin/images/picto/redmine_16.png and b/public/admin/images/picto/redmine_16.png differ diff --git a/tests/application/modules/admin/controllers/BibControllerTest.php b/tests/application/modules/admin/controllers/BibControllerTest.php index fcfc6451ec5714e797f1cbb448190a61759b5be2..ce023d58c2b35881cd786e1be6f0220d4e652106 100644 --- a/tests/application/modules/admin/controllers/BibControllerTest.php +++ b/tests/application/modules/admin/controllers/BibControllerTest.php @@ -1240,11 +1240,15 @@ class BibControllerPermissionsPortalPostActionTest abstract class BibControllerWithRedmineAPITestCase extends BibControllerWithAdminBibTestCase { public function setUp() { parent::setUp(); - $this->fixture('Class_AdminVar', - ['id' => 'REDMINE_API_KEY', 'valeur' => '123456789']); $this->fixture('Class_AdminVar', ['id' => 'REDMINE_SERVER_URL', 'valeur' => 'http://redmine-forge.gnu']); + + $this->fixture('Class_AdminVar', + ['id' => 'REDMINE_PROJECT_ID', 'valeur' => '123456789']); + + $this->fixture('Class_AdminVar', + ['id' => 'REDMINE_PROXY_URL', 'valeur' => 'http://monserveur']); } } @@ -1279,23 +1283,6 @@ class BibControllerWithRemineAPITest extends BibControllerWithRedmineAPITestCase public function anchorRedmineShouldBePresent() { $this->assertXPath('//form//a[@name="redmine"]'); } - - /** @test */ - public function anchorTestApiSettingsShouldBePresent() { - $this->assertXPath('//a[contains(@href, "/admin/redmine/test/id_bib/2")][@data-popup="true"][@data-status="/admin/redmine/test/id_bib/2"]', $this->_response->getBody()); - } - - - /** @test */ - public function redmineJSShouldBeLoaded() { - $this->assertXPath('//script[contains(@src, "/opac/js/redmine.js")]'); - } - - - /** @test */ - public function redmineAutoRefreshShouldLoaded() { - $this->assertXPathContentContains('//script', '$("a.redmine_status").autoRefresh();'); - } } diff --git a/tests/application/modules/admin/controllers/RedmineControllerTest.php b/tests/application/modules/admin/controllers/RedmineControllerTest.php index 092eeb8ef93b0c9cf23b7a9f4376aed72e90cc2c..90dbaece3e04feb39bef9da98196496a92e92845 100644 --- a/tests/application/modules/admin/controllers/RedmineControllerTest.php +++ b/tests/application/modules/admin/controllers/RedmineControllerTest.php @@ -30,13 +30,29 @@ abstract class Admin_RedmineControllerTestCase extends Admin_AbstractControllerT $this->fixture('Class_AdminVar', ['id' => 'REDMINE_SERVER_URL', 'valeur' => 'http://forge.afi-sa.fr']); + + $this->fixture('Class_AdminVar', + ['id' => 'REDMINE_PROJECT_ID', + 'valeur' => '1234']); + + $this->fixture('Class_AdminVar', + ['id' => 'REDMINE_PROXY_URL', + 'valeur' => 'http://monurl']); + } + + + public function tearDown() { + Class_WebService_Redmine::setClient(null); + Class_WebService_Redmine::setAdminClient(null); + Class_WebService_Redmine::setDefaultHttpClient(null); + + parent::tearDown(); } } class Admin_RedmineControllerTestActionWithNoBibTest extends Admin_RedmineControllerTestCase { - public function setUp() { parent::setUp(); $this->dispatch('/admin/redmine/test', true); @@ -123,27 +139,27 @@ class Admin_RedmineControllerTestActionWithEmptyBibTest extends Admin_RedmineCon abstract class Admin_RedmineControllerWithApiTestCase extends Admin_RedmineControllerWithAnnecyLibraryTestCase { - public function setUp() { parent::setUp(); - $redmine_api = Storm_Test_ObjectWrapper::mock(); - $redmine_api - ->whenCalled('all') - ->answers(RedmineFixtures::sandreIssues()) + $redmine_api = $this->mock() + ->whenCalled('all') + ->answers(RedmineFixtures::sandreIssues()) - ->whenCalled('getCurrentUser') - ->answers(RedmineFixtures::currentUser()) + ->whenCalled('getCurrentUser') + ->answers(RedmineFixtures::currentUser()) - ->whenCalled('show') - ->answers(RedmineFixtures::projectHotline()); + ->whenCalled('show') + ->answers(RedmineFixtures::projectHotline()); - $redmine_client = Storm_Test_ObjectWrapper::mock(); - $redmine_client - ->whenCalled('api') - ->answers($redmine_api); + Class_WebService_Redmine::setClient($this->mock() + ->whenCalled('api') + ->answers($redmine_api)); - Class_WebService_Redmine::setClient($redmine_client); + Class_WebService_Redmine::setDefaultHttpClient($this->mock() + ->whenCalled('open_url')->with('http://monurl') + ->answers(RedmineFixtures::customFields()) + ->beStrict()); } @@ -177,6 +193,23 @@ class Admin_RedmineControllerTestActionWithBibAndLoginPasswordSetTest extends Ad +class Admin_RedmineControllerIndexWithNoAccountSetTest extends Admin_RedmineControllerTestCase { + + public function setUp() { + parent::setUp(); + $this->dispatch('admin/redmine', true); + } + + + /** @test */ + public function linkToSetAccountShouldBePresent() { + $this->assertXPathContentContains('//div[@class="modules"]//a[contains(@href,"/users/edit/id")]', + 'Vous devez sélectionner une bibliothèque'); + } +} + + + class Admin_RedmineControllerIndexTest extends Admin_RedmineControllerWithApiTestCase { public function setUp() { parent::setUp(); @@ -190,8 +223,57 @@ class Admin_RedmineControllerIndexTest extends Admin_RedmineControllerWithApiTes /** @test */ - public function sandreIssuesShouldContainsTicket34566() { - $this->assertXPathContentContains('//table//tr//td', '34247', $this->_response->getBody()); + public function numberHeaderShouldBePresent() { + $this->assertXPathContentContains('//th', 'Numéro'); + } + + + /** @test */ + public function subjectHeaderShouldBePresent() { + $this->assertXPathContentContains('//th', 'Sujet'); + } + + + /** @test */ + public function statusHeaderShouldBePresent() { + $this->assertXPathContentContains('//th', 'Statut'); + } + + + /** @test */ + public function dateHeaderShouldBePresent() { + $this->assertXPathContentContains('//th', 'Créée le'); + } + + + /** @test */ + public function sandreIssuesShouldContainsTicket34247() { + $this->assertXPathContentContains('//table//tr//td', '34247'); + } + + + /** @test */ + public function tix34247SubjectShouldBePresent() { + $this->assertXPathContentContains('//td', 'Charte graphique back-office'); + } + + + /** @test */ + public function tix34247StatusShouldBePresent() { + $this->assertXPathContentContains('//td', 'En développement'); + } + + + /** @test */ + public function tix34247DateShouldBePresent() { + $this->assertXPathContentContains('//td', '04/12/2015'); + } + + + /** @test */ + public function editAnchorIssue34247ShouldBePresent() { + $this->assertXPath('//table//tr//td//a[contains(@href, "admin/redmine/edit-issue/id_lib/1/id/34247")]', + $this->_response->getBody()); } @@ -211,12 +293,6 @@ class Admin_RedmineControllerIndexTest extends Admin_RedmineControllerWithApiTes public function anchorToEditCurrentUserShouldBePresent() { $this->assertXPath('//div[@class="modules"]//a[contains(@href, "admin/users/edit/id/")]'); } - - - /** @test */ - public function projectNameShouldBeHotline() { - $this->assertXPathContentContains('//div[@class="modules"]//a[contains(@href, "admin/index/adminvaredit/cle/REDMINE_PROJECT_ID")]', 'Hotline'); - } } @@ -249,7 +325,7 @@ class Admin_RedmineControllerIndexActionWithModoBibTest extends Admin_RedmineCon /** @test */ public function noAccountHaveBeenSetMessageShouldBePresent() { - $this->assertXPathContentContains('//div[@class="modules"]//a[contains(@href, "admin/bib/edit/id/1")]', 'Aucun compte', $this->_response->getBody()); + $this->assertXPathContentContains('//div[@class="modules"]//a[contains(@href, "admin/bib/edit/id/1")]', 'Modifier le compte d\'assistance', $this->_response->getBody()); } } @@ -268,18 +344,269 @@ class Admin_RedmineControllerWithMultipleAccountTest extends Admin_RedmineContro 'redmine_password' => 'late', 'redmine_user_id' => 12]); + Class_Users::getIdentity()->setBib(null); + Class_Users::getIdentity()->setRedmineLibrary(null); + $this->dispatch('admin/redmine', true); } /** @test */ - public function annecyRedmineTableShouldBePresent() { - $this->assertXPathContentContains('//ul//li', 'Mediatheque d\'Annecy', $this->_response->getBody()); + public function annecyShouldBeSelected() { + $this->assertXPathContentContains('//select[@name="library"]//option[@selected="selected"]', + 'Mediatheque d\'Annecy', + $this->_response->getBody()); + } + + + /** @test */ + public function chamberyShouldBeSelectable() { + $this->assertXPathContentContains('//select[@name="library"]//option', 'Mediatheque de Chambéry', + $this->_response->getBody()); + } + + + /** @test */ + public function urserRedmineLibShouldBeNull() { + $this->assertNull(Class_Users::getIdentity()->getRedmineLibrary()); } /** @test */ - public function chamberyRedmineTableShouldBePresent() { - $this->assertXPathContentContains('//ul//li', 'Mediatheque de Chambéry', $this->_response->getBody()); + public function annecyLibraryRedmineUserIdShouldHaveBeenSaved() { + $this->assertEquals('123456', Class_Bib::find(1)->getRedmineUserId()); + } +} + + + +abstract class Admin_RedmineControllerFixtureAbstractTest extends Admin_RedmineControllerWithApiTestCase { + public function setUp() { + parent::setUp(); + + $redmine_api = $this->mock() + ->whenCalled('show')->with('34247', ['include' => 'journals']) + ->answers(RedmineFixtures::fieldIndexation()) + + ->whenCalled('update')->answers('hfg') + ->whenCalled('all')->answers(RedmineFixtures::supportStatus()); + + + $redmine_api_status = $this->mock() + ->whenCalled('all')->answers(RedmineFixtures::supportStatus()); + + $redmine_api_priority = $this->mock() + ->whenCalled('all')->answers(RedmineFixtures::supportPriority()); + + $redmine_client = $this->mock() + ->whenCalled('api')->with('issue')->answers($redmine_api) + ->whenCalled('api')->with('issue_status')->answers($redmine_api_status) + ->beStrict(); + + Class_WebService_Redmine::setClient($redmine_client); + } + + + public function tearDown() { + Class_WebService_Redmine::setDefaultHttpClient(null); + parent::tearDown(); + } +} + + + + +class Admin_RedmineControllerEditIssue34247Test extends Admin_RedmineControllerFixtureAbstractTest { + public function setUp() { + parent::setUp(); + $this->dispatch('admin/redmine/edit-issue/id_lib/1/id/34247', true); + } + + public function datas() { + return [ + ['//ul//li', 'Statut changé de A qualifier à Affecté au dév.'], + ['//ul//li', '% réalisé mis à 20'], + ['//ul//li', 'Copié depuis #35800 ajouté'], + ['//ul//li', 'Copié vers #35831 supprimé'], + ['//td','Pris en charge par le developpement'], + ['//ul//li', 'Priorité client changé de Normale à Urgente'], + ['//td','test-support'], + ['//td', '07/01/2016 à 09:30:26'], + + ]; + } + + public function data_form() { + return [ ['//form'], + ['//textarea[@id="notes"]']]; + } + + + /** + * @test + * @dataProvider datas + */ + public function historyShouldContains($tag, $text) { + $this->assertXPathContentContains($tag, $text, $this->_response->getBody()); + } + + /** + * @test + * @dataProvider data_form + */ + public function formShouldContains($tag) { + $this->assertXPath($tag, $this->_response->getBody()); + } + + /** @test */ + public function tikcetNumberShouldBe34247() { + $this->assertXPathContentContains('//h1', '#34247'); + } + + + /** @test */ + public function subjectShouldBePresent() { + $this->assertXPathContentContains('//div', 'reindexation des champs'); + } + + + /** @test */ + public function statusShouldBePresent() { + $this->assertXPathContentContains('//select[@name="status_id"]//option', 'A qualifier'); + } + + + /** @test */ + public function priorityShouldBePresent() { + $this->assertXPathContentContains('//select[@name="priority"]//option', 'Normale'); + } + + + /** @test */ + public function moduleShouldBePresent() { + $this->assertXPathContentContains('//select[@name="module"]//option', 'Articles'); + } + + + /** @test */ + public function historyShouldBePresent() { + $this->assertXPathContentContains('//legend', 'Historique'); + } +} + + + +class Admin_RedmineControllerPostEditIssue34247Test extends Admin_RedmineControllerWithApiTestCase { + protected $_update_params; + + public function setUp() { + parent::setUp(); + + $redmine_api = $this->mock() + ->whenCalled('show')->with('34247', ['include' => 'journals']) + ->answers(RedmineFixtures::fieldIndexation()) + + ->whenCalled('update')->answers('hfg') + ->whenCalled('all')->answers(RedmineFixtures::supportStatus()); + + $redmine_client = $this->mock() + ->whenCalled('api') + ->answers($redmine_api); + + Class_WebService_Redmine::setClient($redmine_client); + + + $this->postDispatch('admin/redmine/edit-issue/id_lib/1/id/34247', + ['status_id' => '5', + 'priority' => 'Normale', + 'notes' => 'Change priority', + 'module' => '', + 'contact' => '']); + + $this->_update_params = $redmine_api->getAttributesForLastCallOn('update')[1]; + } + + + protected function assertCustomfieldValue($id, $value) { + foreach($this->_update_params['custom_fields'] as $field) { + if ($field['id'] == $id) { + $this->assertEquals($value, $field['value'], + ' in : ' . json_encode($this->_update_params['custom_fields'])); + return; + } + } + + $this->fail('No custom field of id "' . $id . '" in : ' + . json_encode($this->_update_params['custom_fields'])); + } + + + /** @test */ + public function statusShouldBe5() { + $this->assertEquals(5, $this->_update_params['status_id']); + } + + + /** @test */ + public function priorityShouldBeNormale() { + $this->assertCustomfieldValue(Class_WebService_Redmine::CUSTOM_PRIORITY_ID, 'Normale'); + } + + + /** @test */ + public function moduleShouldBeEmpty() { + $this->assertCustomfieldValue(Class_WebService_Redmine::CUSTOM_MODULE_ID, ''); + } + + + /** @test */ + public function contactShouldBeEmpty() { + $this->assertCustomfieldValue(Class_WebService_Redmine::CUSTOM_CONTACT_PERSON, ''); + } + + + /** @test */ + public function qualificationShouldBeBugLogiciel() { + $this->assertCustomfieldValue(Class_WebService_Redmine::CUSTOM_QUALIFICATION, 'Bug logiciel'); + } + + + /** @test */ + public function issue34247ShouldHaveBeenUpdated() { + $this->assertFlashMessengerContentContains('Demande #34247 enregistrée'); + } + + + /** @test */ + public function shouldRedirectToReferer() { + $this->assertRedirect(); + } +} + + + +class Admin_RedmineControllerAddIssueTest extends Admin_RedmineControllerFixtureAbstractTest{ + public function setUp() { + parent::setUp(); + $this->dispatch('admin/redmine/add/id_lib/1', true); + } + + + public function data_form() { + return [ ['//form'], + ['//input[@id="subject"]'], + ['//select[@id="priority"]//option[@value="Normale"][@selected]'], + ['//select[@id="module"]'], + ['//textarea[@id="description"]'], + ['//textarea[@id="contact"]']]; + } + + + /** + * @test + * @dataProvider data_form + */ + public function formShouldContains($tag) { + $this->assertXPath($tag, $this->_response->getBody()); } } \ No newline at end of file diff --git a/tests/application/modules/admin/controllers/UsersControllerTest.php b/tests/application/modules/admin/controllers/UsersControllerTest.php index d8260cc8ec5ab5cdf49d7fd5ae89273975817b26..0e8afd2dae1cf3d116bcb7fc8b429e0381e06f77 100644 --- a/tests/application/modules/admin/controllers/UsersControllerTest.php +++ b/tests/application/modules/admin/controllers/UsersControllerTest.php @@ -122,6 +122,7 @@ class UsersControllerEditMarcusTest extends UsersControllerWithMarcusTestCase { $this->dispatch('/admin/users/edit/id/10', true); } + /** @test **/ public function roleLevelShouldBeSIGBSubscriber() { $this->assertXpathContentContains('//select[@name="role_level"]//option[@value=2][@selected="selected"]','SIGB', $this->_response->getBody()); @@ -130,7 +131,7 @@ class UsersControllerEditMarcusTest extends UsersControllerWithMarcusTestCase { /** @test **/ public function testIdentifiantIsMMiller() { - $this->assertXPath("//input[@name='login'][@value='mmiller']"); + $this->assertXPath("//input[@name='login'][@value='mmiller'][contains(@onkeypress, 'submit()')]"); } @@ -772,8 +773,13 @@ abstract class Admin_UsersControllerEditAdminTestCase extends Admin_AbstractCont parent::setUp(); $this->fixture('Class_AdminVar', - ['id' => 'REDMINE_SERVER_URL', - 'valeur' => 'http://forge.afi-sa.fr']); + ['id' => 'REDMINE_SERVER_URL', 'valeur' => 'http://redmine-forge.gnu']); + + $this->fixture('Class_AdminVar', + ['id' => 'REDMINE_PROJECT_ID', 'valeur' => '123456789']); + + $this->fixture('Class_AdminVar', + ['id' => 'REDMINE_PROXY_URL', 'valeur' => 'http://monurl']); $this->fixture('Class_Zone', ['id' => 1, diff --git a/tests/fixtures/RedmineFixtures.php b/tests/fixtures/RedmineFixtures.php index f3504c4df9a53425e375b820896bb8aeedbb5bb9..2eb4a4168ebde511161d07afca50c342c87df429 100644 --- a/tests/fixtures/RedmineFixtures.php +++ b/tests/fixtures/RedmineFixtures.php @@ -22,17 +22,17 @@ class RedmineFixtures { public static function noLibraryGiven() { - return '{"title":"Test de l\'API Redmine","content":"Vous devez fournir un identifiant de biblioth\u00e8que en param\u00e8tre"}'; + return '{"title":"Test de la configuration de l\'API d\'assistance","content":"Vous devez fournir un identifiant de biblioth\u00e8que en param\u00e8tre"}'; } public static function noServerUrlGiven() { - return '{"title":"Test de l\'API Redmine","content":"Aucun serveur Redmine est renseign\u00e9"}'; + return '{"title":"Test de la configuration de l\'API d\'assistance","content":"Redmine n\'est pas correctement configur\u00e9"}'; } public static function missingParams() { - return '{"title":"Test de l\'API Redmine","content":"Vous devez renseigner les champs login et password ou le champ cl\u00e9 d\'API"}'; + return '{"title":"Test de la configuration de l\'API d\'assistance","content":"Vous devez renseigner les champs login et password ou le champ cl\u00e9 d\'API"}'; } @@ -51,12 +51,12 @@ class RedmineFixtures { public static function sandreBocoeur() { - return '{"title":"Test de l\'API Redmine","content":"<p data-success=\"true\">Vous \u00eates connect\u00e9(e) en tant que Sandre Bocoeur<\/p>"}'; + return '{"title":"Test de la configuration de l\'API d\'assistance","content":"<p data-success=\"true\">Compte d\'assistance: haveBeenSet<\/p>"}'; } public static function sandreIssues() { - return ['issues' => [ ['id' => 34246, + return ['issues' => [['id' => 34246, 'project' => ['id' => 56, 'name' => 'Développement Bokeh AFI-OPAC 2.0'], 'tracker' => ['id' => 2, @@ -85,42 +85,83 @@ class RedmineFixtures { 'updated_on' => '2015-12-04T09:25:42Z', 'story_points' => ''], - ['id' => 34247, - 'project' => ['id' => 56, - 'name' => 'Développement Bokeh AFI-OPAC 2.0'], - 'tracker' => ['id' => 2, - 'name' => 'Développement'], - 'status' => ['id' => 7 , - 'name' => 'En développement'], - 'priority' => ['id' => 4, - 'name' => 'Normal'], - 'author' => ['id' => 207, - 'name' => 'gloas'], - 'assigned_to' => ['id' => 207, - 'name' => 'gloas'], - 'subject' => 'Charte graphique back-office', - 'description' => 'un ticket redmine', - 'done_ratio' => 30, - 'custom_fields' => [ ['id' => 37, - 'name' => 'Module Portail', - 'value' => ''], - ['id' => 5 , - 'name' => 'Priorité client', - 'value' => 'Normale'], - ['id' => 11, - 'name' => 'Phase', - 'value' => '']], - 'created_on' => '2015-12-04T09:19:11Z', - 'updated_on' => '2015-12-04T09:25:42Z', - 'story_points' => '']], + static::issue34247()], 'total_count' => 2, 'offset' => 0 , 'limit' => 25]; } + public static function issue34247() { + return ['id' => 34247, + 'project' => ['id' => 56, + 'name' => 'Développement Bokeh AFI-OPAC 2.0'], + 'tracker' => ['id' => 2, + 'name' => 'Développement'], + 'status' => ['id' => 7 , + 'name' => 'En développement'], + 'priority' => ['id' => 4, + 'name' => 'Normal'], + 'author' => ['id' => 207, + 'name' => 'gloas'], + 'assigned_to' => ['id' => 207, + 'name' => 'gloas'], + 'subject' => 'Charte graphique back-office', + 'description' => 'un ticket redmine', + 'done_ratio' => 30, + 'custom_fields' => [ ['id' => 37, + 'name' => 'Module Portail', + 'value' => ''], + ['id' => 5 , + 'name' => 'Priorité client', + 'value' => 'Normale'], + ['id' => 11, + 'name' => 'Phase', + 'value' => '']], + 'created_on' => '2015-12-04T09:19:11Z', + 'updated_on' => '2015-12-04T09:25:42Z', + 'story_points' => '']; + } + + public static function projectHotline() { return ['project' => ['name' => 'Hotline']]; } + + + public static function fieldIndexation() { + return json_decode('{"issue":{"id":34247,"project":{"id":214,"name":"Support Bokeh AFI-OPAC 2.0"},"tracker":{"id":12,"name":"Demande d\'assistance"},"status":{"id":2,"name":"Affect\u00e9 au d\u00e9v."},"priority":{"id":5,"name":"Haut"},"author":{"id":207,"name":"gloas"},"assigned_to":{"id":207,"name":"gloas"},"subject":"reindexation des champs personnalis\u00e9s ","description":"Url de l\'anomalie : http:\/\/web.afi-sa.net\/miop-test.net\/admin\/custom-fields\/edit\/id\/1\r\n\r\n\u00c9tapes pour parvenir au bug :\r\n* indexer un champs personnalis\u00e9\r\n* les facettes des notices des articles qui ont une valeur de param\u00e9tr\u00e9e pour ce champ personnalis\u00e9 ne sont pas mises \u00e0 jour.\r\n","done_ratio":20,"spent_hours":0,"custom_fields":[{"id":43,"name":"Personne \u00e0 contacter","value":"Nom \/ pr\u00e9nom \/ email \/ t\u00e9l\u00e9phone"},{"id":42,"name":"Pris en charge par","value":""},{"id":37,"name":"Module Portail","value":"Recherche"},{"id":5,"name":"Priorit\u00e9 client","value":"Normale"},{"id":1,"name":"Client","value":""},{"id":46,"name":"Relanc\u00e9 le","value":""}],"created_on":"2015-09-29T10:01:49Z","updated_on":"2015-12-02T13:37:49Z","journals":[{"id":149465,"user":{"id":1198,"name":"test-support"},"notes":"","created_on":"2016-01-07T08:30:26Z","details":[{"property":"relation","name":"copied_from","new_value":"35800"}]},{"id":149517,"user":{"id":92,"name":"other"},"notes":"Pris en charge par le developpement","created_on":"2016-01-07T09:38:13Z","details":[{"property":"attr","name":"status_id","old_value":"1","new_value":"2"},{"property":"attr","name":"done_ratio","old_value":"0","new_value":"20"}]},{"id":149608,"user":{"id":92,"name":"dev"},"notes":"","created_on":"2016-01-07T11:10:00Z","details":[{"property":"relation","name":"copied_to","old_value":"35831"}]},{"id":149610,"user":{"id":92,"name":"dev"},"notes":"","created_on":"2016-01-07T11:10:04Z","details":[{"property":"relation","name":"blocks","new_value":"35831"}]},{"id":149612,"user":{"id":1198,"name":"test-support"},"notes":"","created_on":"2016-01-07T11:12:45Z","details":[{"property":"cf","name":"5","old_value":"Normale","new_value":"Urgente"}]}]}}', true); + } + + + public static function supportStatus() { + return json_decode('{"issue_statuses":[{"id":1,"name":"A qualifier","is_default":true},{"id":14,"name":"A planifier"},{"id":15,"name":"Planifi\u00e9"},{"id":4,"name":"Affect\u00e9 hotline"},{"id":19,"name":"Affect\u00e9 syst\u00e8me"},{"id":2,"name":"Affect\u00e9 au d\u00e9v."},{"id":13,"name":"Affect\u00e9 HL H\u00e9bergement"},{"id":22,"name":"Retour au d\u00e9v"},{"id":7,"name":"En d\u00e9veloppement"},{"id":20,"name":"Impl\u00e9ment\u00e9"},{"id":18,"name":"\u00c0 documenter"},{"id":16,"name":"\u00c0 revoir tech"},{"id":3,"name":"R\u00e9alis\u00e9 (\u00e0 tester)"},{"id":17,"name":"\u00c0 int\u00e9grer"},{"id":11,"name":"Question au client"},{"id":8,"name":"Test\u00e9"},{"id":12,"name":"Transf\u00e9r\u00e9 au plan de d\u00e9v","is_closed":true},{"id":5,"name":"Ferm\u00e9","is_closed":true},{"id":6,"name":"Rejet\u00e9","is_closed":true},{"id":21,"name":"A facturer"}]}', true); + } + + + public static function supportPriority() { + return json_decode('{"issue_priorities":[{"id":3,"name":"Bas"},{"id":4,"name":"Normal","is_default":true},{"id":5,"name":"Haut"},{"id":6,"name":"Urgent"},{"id":7,"name":"Proc\u00e9dure 48h"}]}', true); + } + + + public static function customFields() { + return json_encode(['custom_fields' => [['id' => Class_WebService_Redmine::CUSTOM_PRIORITY_ID, + 'name' => 'Priorité client', + 'is_required' => true, + 'default_value' => 'Normale', + 'possible_values' => [['value' => 'Basse'], + ['value' => 'Normale']]], + + ['id' => Class_WebService_Redmine::CUSTOM_MODULE_ID, + 'name' => 'Module Portail', + 'is_required' => false, + 'possible_values' => [['value' => 'Articles'], + ['value' => 'Interface SIGB']]], + + ['id' => Class_WebService_Redmine::CUSTOM_QUALIFICATION, + 'name' => 'Qualification', + 'is_required' => false, + 'possible_values' => [['value' => 'Bug logiciel'], + ['value' => 'Hors maintenance']]]]]); + } } -?> \ No newline at end of file diff --git a/tests/library/Class/UsersTest.php b/tests/library/Class/UsersTest.php index 6a934e0b05f9091bbe486e8da0332d158a2177bc..0f2da9c95ebf4358510a23687e46632e576bf94a 100644 --- a/tests/library/Class/UsersTest.php +++ b/tests/library/Class/UsersTest.php @@ -220,7 +220,7 @@ class UsersSaveTest extends ModelTestCase { 'idabon' => '1234', 'date_fin' => '', 'naissance' => '', - 'date_debut' => 0, + 'date_debut' => '', 'telephone' => '', 'mail' => '', 'adresse' => '', @@ -273,7 +273,7 @@ class UsersSaveTest extends ModelTestCase { 'date_fin' => '2001-10-23', 'idabon' => '', 'naissance' => '', - 'date_debut' => 0, + 'date_debut' => '', 'telephone' => '', 'adresse' => '', 'code_postal' => '',