diff --git a/VERSIONS b/VERSIONS index 39a076216084416f5d690e4cc9f04147db44bfc1..7b322094e4f0304942bbe7fc8b88b404dc1359f3 100644 --- a/VERSIONS +++ b/VERSIONS @@ -1,3 +1,17 @@ +26/03/2020 - v8.0.47 + + - ticket #108377 : Ressources numériques : Correction du calcul du quota de prêt pour les invités + + - ticket #108358 : Gestion des groupes : Les affectations manuelles à des groupes dynamiques ne sont plus supportées + + + +24/03/2020 - v8.0.46 + + - ticket #108306 : Correction de la prise en compte de la case "abonnement valide" dans les groupes d'utilisateurs + + + 23/03/2020 - v8.0.45 - ticket #108047 : Ressources numériques : L'accès à une ressource s'appuie exclusivement sur l'appartenance aux groupes diff --git a/library/Class/Loan/Pnb.php b/library/Class/Loan/Pnb.php index a1fe01601e9173d528651725099d099fcb55642a..34d77db6f075b384fb137e9a78def33ea6ed2091 100644 --- a/library/Class/Loan/Pnb.php +++ b/library/Class/Loan/Pnb.php @@ -1,6 +1,6 @@ findAllOngoingBy(['subscriber_id' => $user->getIdabon()]), - $this->findAllOngoingBy(['user_id' => $user->getId()]))); + $loans = $this->_ongoingOf($user); (new Class_WebService_BibNumerique_Dilicom_Hub())->updateLoansReturnDate($loans); @@ -37,6 +33,16 @@ class Class_Loan_PnbLoader extends Storm_Model_Loader { } + protected function _ongoingOf($user) { + $by_user_id = $this->findAllOngoingBy(['user_id' => $user->getId()]); + if (!$user->isAbonne()) + return $by_user_id; + + return array_unique(array_merge($this->findAllOngoingBy(['subscriber_id' => $user->getIdabon()]), + $by_user_id)); + } + + public function findAllOngoingOfItem($item) { $loans = $this->findAllOngoingBy(['order_line_id' => $item->getOrderLineId()]); (new Class_WebService_BibNumerique_Dilicom_Hub())->updateLoansReturnDate($loans); diff --git a/library/Class/User/SearchCriteria.php b/library/Class/User/SearchCriteria.php index bdacc6a13acf5ee81264bbc6e0a1f61c8b457df0..f5ee313d23e0981750672ce23e5240a6089fc974 100644 --- a/library/Class/User/SearchCriteria.php +++ b/library/Class/User/SearchCriteria.php @@ -96,7 +96,7 @@ class Class_User_SearchCriteriaValidSubscription extends Class_SearchCriteria_Ab if (!$this->_should_filter) return true; - return $model->isValid(); + return $model->isAbonnementValid(); } diff --git a/library/Class/UserGroup.php b/library/Class/UserGroup.php index 43172fc8bc595ec8088c48b6cd9459b27b99d580..79bdacd6f772802c0f004f69f9855b90fe16c8e5 100644 --- a/library/Class/UserGroup.php +++ b/library/Class/UserGroup.php @@ -305,8 +305,9 @@ class Class_UserGroup extends Storm_Model_Abstract { * @return array */ public function getUsers() { - return $this->isManual() ? - parent::_get('users') : $this->getDynamicUsers(); + return $this->isManual() + ? parent::_get('users') + : $this->getDynamicUsers(); } diff --git a/library/Class/Users.php b/library/Class/Users.php index 33461c1662a1ce1bd6d6ee213e5ddcecb86adac5..c9d260e59a1cfb2311282c31c8cf090a5d80fb2f 100644 --- a/library/Class/Users.php +++ b/library/Class/Users.php @@ -811,8 +811,7 @@ class Class_Users extends Storm_Model_Abstract { */ public function getUserGroupsIds() { $groups = $this->getUserGroups(); - return array_map( - function($group) { return $group->getId();}, + return array_map(function($group) { return $group->getId();}, $groups); } @@ -828,7 +827,11 @@ class Class_Users extends Storm_Model_Abstract { * @return array */ public function getUserGroups() { - return array_merge(parent::_get('user_groups'), + return array_merge(array_filter(parent::_get('user_groups'), + function($group) + { + return !$group->isDynamic(); + }), $this->getDynamicUserGroups()); } diff --git a/library/ZendAfi/Controller/Plugin/Manager/User.php b/library/ZendAfi/Controller/Plugin/Manager/User.php index 71b149ac298f284a472c15768c734ccb10a9026b..c584377b6590fd04e6149e43ed13863cc18f7d4e 100644 --- a/library/ZendAfi/Controller/Plugin/Manager/User.php +++ b/library/ZendAfi/Controller/Plugin/Manager/User.php @@ -78,10 +78,14 @@ class ZendAfi_Controller_Plugin_Manager_User extends ZendAfi_Controller_Plugin_M protected function _getPost($key = null, $default = null) { $post = $this->_request->getPost(); - $post['user_groups'] = array_filter( - array_map(function($id) { return Class_UserGroup::find((int)$id);}, - explode('-', $this->_getParam('user_group_ids',''))) - ); + $mapper = function($id) { + return ($group = Class_UserGroup::find((int)$id)) && !$group->isDynamic() + ? $group + : null; + }; + + $post['user_groups'] = array_filter(array_map($mapper, + explode('-', $this->_getParam('user_group_ids','')))); $post['date_fin'] = isset($post['date_fin']) && trim($post['date_fin']) ? Class_Date::frToIso(trim($post['date_fin'])) diff --git a/library/ZendAfi/View/Helper/Admin/FrontNavEntries.php b/library/ZendAfi/View/Helper/Admin/FrontNavEntries.php index 9751726ee4c328e3b2677260a5139cb0c4503436..40bacff5c41b0dd80700a0224ac03659e3ad57ed 100644 --- a/library/ZendAfi/View/Helper/Admin/FrontNavEntries.php +++ b/library/ZendAfi/View/Helper/Admin/FrontNavEntries.php @@ -309,7 +309,7 @@ class ZendAfi_View_Helper_Admin_FrontNavEntries extends ZendAfi_View_Helper_Base $anchors = []; foreach(ZendAfi_Auth_Others::getInstance()->getIdentities() as $user) { - $user_name = Class_Users::getNomAff($user->getId()); + $user_name = $user->getNomAff(); $remove_from_list = $user->isSuperAdmin() ? '' : $this->view->tagAnchor($this->view->url(['module' => 'opac', @@ -350,8 +350,8 @@ class ZendAfi_View_Helper_Admin_FrontNavEntries extends ZendAfi_View_Helper_Base protected function _multipleAccounts() { $admin = ZendAfi_Auth_Others::getInstance()->getSuperAdminInIdentities(); $user = Class_Users::getIdentity(); - $name = Class_Users::getNomAff($admin->getId()); - $user_name = Class_Users::getNomAff($user->getId()); + $name = $admin->getNomAff(); + $user_name = $user->getNomAff(); $user_anchors = [$this->_tag('li', $this->view->tagAnchor($this->view->url(['module' => 'opac', 'controller' => 'auth', diff --git a/library/startup.php b/library/startup.php index 3a13335dc558df880732414f061ed30239e3caf0..c4da1e03dd87b30ecafaa4c306eb5f13b867bd8e 100644 --- a/library/startup.php +++ b/library/startup.php @@ -81,7 +81,7 @@ class Bokeh_Engine { function setupConstants() { defineConstant('BOKEH_MAJOR_VERSION','8.0'); - defineConstant('BOKEH_RELEASE_NUMBER', BOKEH_MAJOR_VERSION . '.45'); + defineConstant('BOKEH_RELEASE_NUMBER', BOKEH_MAJOR_VERSION . '.47'); defineConstant('BOKEH_REMOTE_FILES', 'https://git.afi-sa.net/afi/opacce/'); diff --git a/tests/application/modules/admin/controllers/UsersControllerTest.php b/tests/application/modules/admin/controllers/UsersControllerTest.php index 60bd4807401a7511edad6877384f96b3eb9ee554..33e8da686558fc05fc41f38590b2e6f2fb501e63 100644 --- a/tests/application/modules/admin/controllers/UsersControllerTest.php +++ b/tests/application/modules/admin/controllers/UsersControllerTest.php @@ -2198,4 +2198,59 @@ class UsersControllerMassDeleteRunStepMatchingSuperAdminUserTest $this->assertEquals(2, $json->done); $this->assertEquals(2, $json->total); } -} \ No newline at end of file +} + + + + +/** @see http://forge.afi-sa.fr/issues/108358#note-9 */ +class UsersControllerPostEditWithDynamicGroupTest extends Admin_UsersControllerEditAdminTestCase { + public function setUp() { + parent::setUp(); + + $this->fixture('Class_UserGroup', + ['id' => 33, + 'group_type' => Class_UserGroup::TYPE_DYNAMIC]); + + $this->fixture('Class_UserGroup', + ['id' => 34, + 'group_type' => Class_UserGroup::TYPE_MANUAL]); + + Class_Crypt::setPhpCommand(null); + $this->postDispatch('/admin/users/edit/id/10', ['login' => 'Tom', + 'password' => 'tutu', + 'nom' => 'Davis', + 'prenom' => 'Miles', + 'pseudo' => 'Dave', + 'mail' => 'mdavis@free.fr', + 'role_level' => ZendAfi_Acl_AdminControllerRoles::MODO_PORTAIL, + 'id_site' => '7', + 'idabon' => '2341', + 'ordreabon' => '2', + 'telephone' => '', + 'adresse' => '12 rue miles', + 'code_postal' => '75000', + 'ville' => 'Paris', + 'civilite' => 1, + 'mobile' => '', + 'naissance' => '1976-02-17', + 'date_debut' => '', + 'date_fin' => '14/10/2015', + 'user_group_ids' => '33-34', + 'redmine_library' => '15']); + } + + + /** @test */ + public function membershipShouldNotBeCreatedForDynamicGroup() { + $this->assertNull(Class_UserGroupMembership::findFirstBy(['user_id' => 10, + 'user_group_id' => 33])); + } + + + /** @test */ + public function membershipShouldBeCreatedForManualGroup() { + $this->assertNotNull(Class_UserGroupMembership::findFirstBy(['user_id' => 10, + 'user_group_id' => 34])); + } +} diff --git a/tests/library/Class/DynamicUserGroupTest.php b/tests/library/Class/DynamicUserGroupTest.php index 5a103f5d3e76f37846cb901c524ea97046901cff..304fe13a32e8ee13404e71d14423c26bc9de3648 100644 --- a/tests/library/Class/DynamicUserGroupTest.php +++ b/tests/library/Class/DynamicUserGroupTest.php @@ -170,8 +170,24 @@ class DynamicUserGroupModoBibTest extends DynamicUserGroupTestCase { ['id' => 13, 'libelle' => 'Abonnés', 'group_type' => Class_UserGroup::TYPE_DYNAMIC, - 'filters' => json_encode(['search_valid_subscription' => 1 - ])]); + 'filters' => json_encode(['search_role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB, + 'search_valid_subscription' => 1])]); + + // @see http://forge.afi-sa.fr/issues/108358#note-9, manually linked to dynamic + $this->_max = $this->fixture('Class_Users', + ['id' => 32, + 'login' => 'max', + 'password' => 'zemenace', + 'id_site' => 1, + 'idabon' => '88308ID', + 'role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB, + 'date_fin' => '2019-01-01', + 'user_group_memberships' => [$this->fixture('Class_UserGroupMembership', + ['id' => 1000, + 'user_id' => 32, + 'user_group_id' => 13])], + ]); + ; $this->_late_subscribers = $this ->fixture('Class_UserGroup', @@ -293,6 +309,7 @@ class DynamicUserGroupModoBibTest extends DynamicUserGroupTestCase { ['_gontran', '_adults'], ['_shella', '_abonnes'], ['_gontran', '_abonnes'], + ['_max', '_abonnes'], ]; } @@ -322,6 +339,7 @@ class DynamicUserGroupModoBibTest extends DynamicUserGroupTestCase { ['_gontran', '_subscription_ended'], ['_shella', '_adults'], ['_gontran', '_minors'], + ['_max', '_subscribers'], ]; } diff --git a/tests/scenarios/PnbDilicom/PnbDilicomTest.php b/tests/scenarios/PnbDilicom/PnbDilicomTest.php index ff40337e78508c082deea4e9a61938aa01c60ad0..8d0d075e4c632f3b2049cd44cdf284d95a48bfb4 100644 --- a/tests/scenarios/PnbDilicom/PnbDilicomTest.php +++ b/tests/scenarios/PnbDilicom/PnbDilicomTest.php @@ -2645,7 +2645,8 @@ class PnbDilicomBibNumeriqueControllerConsultBookWithErrorsActionTest extends Pn -class PnbDilicomBibNumeriqueControllerLoanBookActionTest extends PnbDilicomBibNumeriqueControllerLoanBookActionTestCase { +class PnbDilicomBibNumeriqueControllerLoanBookActionTest + extends PnbDilicomBibNumeriqueControllerLoanBookActionTestCase { public function setUp() { parent::setUp(); @@ -2781,6 +2782,115 @@ class PnbDilicomBibNumeriqueControllerLoanBookActionTwiceWithSameUserTest extend + + +/** @see http://forge.afi-sa.fr/issues/108377 */ +abstract class PnbDilicomBibNumeriqueControllerLoanBookActionGuestTestCase + extends PnbDilicomBibNumeriqueControllerTestCase { + + public function setUp() { + parent::setUp(); + + Class_AdminVar::set('DILICOM_PNB_MAX_LOAN_PER_USER', 3); + + $user = $this->fixture('Class_Users', + ['id' => 88, + 'login' => 'guest', + 'password' => 'roxor', + 'id_site' => 1, + 'user_groups' => [Class_UserGroup::find(20)], + 'role' => ZendAfi_Acl_AdminControllerRoles::INVITE, + ]); + + ZendAfi_Auth::getInstance()->logUser($user); + } +} + + + + +class PnbDilicomBibNumeriqueControllerLoanBookActionGuestWithOtherGuestsLoansTest + extends PnbDilicomBibNumeriqueControllerLoanBookActionGuestTestCase { + + public function setUp() { + parent::setUp(); + + foreach(range(1, 6) as $i) + $this->fixture('Class_Loan_Pnb', + ['id' => 10000+$i, + 'user_id' => 10000+$i, + 'subscriber_id' => '', + 'record_origin_id' => '', + 'expected_return_date' => '2022-06-01']); + + $this->_http + ->whenCalled('open_url') + ->with('https://pnb-test.centprod.com/v3/pnb-numerique/json/getEndedLoans?login=afi-bib&password=secretPassword&glnContractor=123456789&loanId%5B0%5D=10001&loanId%5B1%5D=10002&loanId%5B2%5D=10003&loanId%5B3%5D=10004&loanId%5B4%5D=10005&loanId%5B5%5D=10006', + ['auth' => [ 'user' => 'afi-bib', + 'password' => 'secretPassword']]) + ->answers(DilicomFixtures::getEndedLoansResponse()) + + ->whenCalled('open_url') + ->with('https://pnb-test.centprod.com/v3/pnb-numerique/json/getLoanStatus?login=afi-bib&password=secretPassword&glnContractor=123456789&orderLineId%5B0%5D=x321&returnEndedLoan=0', + ['auth' => [ 'user' => 'afi-bib', + 'password' => 'secretPassword']]) + ->answers(DilicomFixtures::getLoanStatusResponse()) + + ->whenCalled('open_url') + ->with('https://pnb-test.centprod.com/v3/pnb-numerique/json/loanBook?login=afi-bib&password=secretPassword&glnContractor=123456789&glnLoaner=2345889&UserInfo.year=1930&UserInfo.gender=H&DRMinfo.readerPass=MTA%3D&DRMinfo.readerHint=Votre+login+est+%22drm%22+et+votre+mot+de+passe+est+%220000%22&DRMinfo.readerId=drm&orderLineId=x321&loanId=10007&ean13=435465&accessMedium=DOWNLOAD&localization=EX_SITU&loanEndDate=2014-08-10T14%3A14%3A14%2B0200', + ['auth' => [ 'user' => 'afi-bib', + 'password' => 'secretPassword']]) + ->answers(DilicomFixtures::loanBookResponse()) + ; + + $this->dispatch('/bib-numerique/loan-book/id/3'); + } + + + /** @test */ + public function shouldBeAbleToLoan() { + $this->assertNotNull(Class_Loan_Pnb::find(10007)); + } +} + + + + +class PnbDilicomBibNumeriqueControllerLoanBookActionGuestWithExceededLoansTest + extends PnbDilicomBibNumeriqueControllerLoanBookActionGuestTestCase { + + public function setUp() { + parent::setUp(); + + foreach(range(1, 6) as $i) + $this->fixture('Class_Loan_Pnb', + ['id' => 10000+$i, + 'user_id' => Class_Users::getIdentity()->getId(), + 'subscriber_id' => '', + 'record_origin_id' => '', + 'expected_return_date' => '2022-06-01']); + + $this->_http + ->whenCalled('open_url') + ->with('https://pnb-test.centprod.com/v3/pnb-numerique/json/getEndedLoans?login=afi-bib&password=secretPassword&glnContractor=123456789&loanId%5B0%5D=10001&loanId%5B1%5D=10002&loanId%5B2%5D=10003&loanId%5B3%5D=10004&loanId%5B4%5D=10005&loanId%5B5%5D=10006', + ['auth' => [ 'user' => 'afi-bib', + 'password' => 'secretPassword']]) + ->answers(DilicomFixtures::getEndedLoansResponse()) + ; + + $this->dispatch('/bib-numerique/loan-book/id/3'); + } + + + /** @test */ + public function shouldNotBeAbleToLoan() { + $this->assertNull(Class_Loan_Pnb::find(10007)); + } +} + + + + abstract class PnbDilicomBibNumeriqueControllerSecondUserTestCase extends PnbDilicomBibNumeriqueControllerTestCase { public function setUp() {