From 565700b9b4f2fd6038b1bb5701cac309c04dde3f Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Sun, 22 Jul 2018 20:55:27 +0200 Subject: [PATCH] Child management from parents Consider parent can edit. Parent can see their children list of contributions Parents can show/edit childs Parent can see children contribution in their list Contribution and invopices access for parents --- .../Crud/ContributionsController.php | 56 +++++++++++++++---- .../Controllers/Crud/MembersController.php | 32 +++++------ galette/lib/Galette/Entity/Adherent.php | 33 +++++++++-- galette/lib/Galette/Entity/Contribution.php | 27 ++++++++- galette/lib/Galette/Features/Replacements.php | 13 +++-- .../lib/Galette/Filters/ContributionsList.php | 3 + .../lib/Galette/Repository/Contributions.php | 55 ++++++++++++++++-- .../default/gestion_contributions.tpl | 4 +- galette/templates/default/voir_adherent.tpl | 4 +- 9 files changed, 177 insertions(+), 50 deletions(-) diff --git a/galette/lib/Galette/Controllers/Crud/ContributionsController.php b/galette/lib/Galette/Controllers/Crud/ContributionsController.php index b9ca44f43..171e1e79b 100644 --- a/galette/lib/Galette/Controllers/Crud/ContributionsController.php +++ b/galette/lib/Galette/Controllers/Crud/ContributionsController.php @@ -37,6 +37,7 @@ namespace Galette\Controllers\Crud; use Throwable; +use Analog\Analog; use Galette\Controllers\CrudController; use Slim\Http\Request; use Slim\Http\Response; @@ -426,22 +427,39 @@ class ContributionsController extends CrudController $filters->orderby = $value; break; case 'member': - if ( - ($this->login->isAdmin() - || $this->login->isStaff()) - ) { - if ($value == 'all') { - $filters->filtre_cotis_adh = null; - } else { - $filters->filtre_cotis_adh = $value; - } - } + $filters->filtre_cotis_adh = ($value === 'all' ? null : $value); break; } } - if (!$this->login->isAdmin() && !$this->login->isStaff()) { - $filters->filtre_cotis_adh = $this->login->id; + if (!$this->login->isAdmin() && !$this->login->isStaff() && $value != $this->login->id) { + if ($value == 'all') { + $value = null; + $filters->filtre_cotis_children = $this->login->id; + } else { + $member = new Adherent( + $this->zdb, + (int)$value, + [ + 'picture' => false, + 'groups' => false, + 'dues' => false, + 'parent' => true + ] + ); + if ( + !$member->hasParent() || + $member->hasParent() && $member->parent->id != $this->login->id + ) { + $value = $this->login->id; + Analog::log( + 'Trying to display contributions for member #' . $value . + ' without appropriate ACLs', + Analog::WARNING + ); + } + } + $filters->filtre_cotis_children = $value; } $class = '\\Galette\\Repository\\' . ucwords($raw_type); @@ -472,6 +490,20 @@ class ContributionsController extends CrudController $tpl_vars['member'] = $member; } + if ($filters->filtre_cotis_children != false) { + $member = new Adherent( + $this->zdb, + $filters->filtre_cotis_children, + [ + 'picture' => false, + 'groups' => false, + 'dues' => false, + 'parent' => true + ] + ); + $tpl_vars['pmember'] = $member; + } + // display page $this->view->render( $response, diff --git a/galette/lib/Galette/Controllers/Crud/MembersController.php b/galette/lib/Galette/Controllers/Crud/MembersController.php index 70e7d6e76..998c7b659 100644 --- a/galette/lib/Galette/Controllers/Crud/MembersController.php +++ b/galette/lib/Galette/Controllers/Crud/MembersController.php @@ -244,7 +244,7 @@ class MembersController extends CrudController ); $member = new Adherent($this->zdb, $id, $deps); - if (!$member->canEdit($this->login)) { + if (!$member->canShow($this->login)) { $this->flash->addMessage( 'error_detected', _T("You do not have permission for requested URL.") @@ -440,7 +440,7 @@ class MembersController extends CrudController $member = new Adherent($this->zdb, $id, $deps); $denied = null; - if (!$member->canEdit($this->login)) { + if (!$member->canShow($this->login)) { $fields = $member->getDynamicFields()->getFields(); if (!isset($fields[$fid])) { //field does not exists or access is forbidden @@ -1560,22 +1560,22 @@ class MembersController extends CrudController } // new or edit - if ($this->login->isAdmin() || $this->login->isStaff() || $this->login->isGroupManager()) { - if (isset($post['id_adh'])) { - $member->load((int)$post['id_adh']); - if (!$member->canEdit($this->login)) { - //redirection should have been done before. Just throw an Exception. - throw new \RuntimeException( - str_replace( - '%id', - $member->id, - 'No right to store member #%id' - ) - ); - } + if (isset($post['id_adh'])) { + $member->load((int)$post['id_adh']); + if (!$member->canEdit($this->login)) { + //redirection should have been done before. Just throw an Exception. + throw new \RuntimeException( + str_replace( + '%id', + $member->id, + 'No right to store member #%id' + ) + ); } } else { - $member->load($this->login->id); + if ($member->id != '') { + $member->load($this->login->id); + } } // flagging required fields diff --git a/galette/lib/Galette/Entity/Adherent.php b/galette/lib/Galette/Entity/Adherent.php index 55f0fd30c..387932983 100644 --- a/galette/lib/Galette/Entity/Adherent.php +++ b/galette/lib/Galette/Entity/Adherent.php @@ -46,6 +46,7 @@ use Galette\Core\Password; use Galette\Core\Preferences; use Galette\Core\History; use Galette\Repository\Groups; +use Galette\Core\Login; use Galette\Repository\Members; /** @@ -1429,9 +1430,13 @@ class Adherent */ public function store() { - global $hist, $emitter; + global $hist, $emitter, $login; $event = null; + if (!$login->isAdmin() && !$login->isStaff() && !$login->isGroupManager() && $this->id == '') { + $this->_parent = $login->id; + } + try { $values = array(); $fields = self::getDbFields($this->zdb); @@ -1567,7 +1572,6 @@ class Adherent ); } $success = true; - $event = 'member.edit'; } @@ -1757,6 +1761,9 @@ class Adherent } } break; + case 'parent_id': + return ($this->_parent instanceof Adherent) ? (int)$this->_parent->id : (int)$this->_parent; + break; default: if (!property_exists($this, $rname)) { Analog::log( @@ -2038,13 +2045,19 @@ class Adherent * * @return boolean */ - public function canEdit($login) + public function canEdit(Login $login) { + //admin and staff users can edit, as well as member itself if ($this->id && $login->id == $this->id || $login->isAdmin() || $login->isStaff()) { return true; } - //check if requested member is part of managed groups + //parent can edit their child cards + if ($this->hasParent() && $this->parent_id === $login->id) { + return true; + } + + //group managers can edit members of groups they manage if ($login->isGroupManager()) { foreach ($this->getGroups() as $g) { if ($login->isGroupManager($g->getId())) { @@ -2056,6 +2069,18 @@ class Adherent return false; } + /** + * Can current logged in user display member + * + * @param Login $login Login instance + * + * @return boolean + */ + public function canShow(Login $login) + { + return $this->canEdit($login); + } + /** * Are we currently duplicated a member? * diff --git a/galette/lib/Galette/Entity/Contribution.php b/galette/lib/Galette/Entity/Contribution.php index e0da8a896..bfa80bc42 100644 --- a/galette/lib/Galette/Entity/Contribution.php +++ b/galette/lib/Galette/Entity/Contribution.php @@ -272,11 +272,32 @@ class Contribution public function load($id) { try { - $select = $this->zdb->select(self::TABLE); - $select->where(self::PK . ' = ' . $id); + $select = $this->zdb->select(self::TABLE, 'c'); + $select->join( + array('a' => PREFIX_DB . Adherent::TABLE), + 'c.' . Adherent::PK . '=a.' . Adherent::PK, + array() + ); //restrict query on current member id if he's not admin nor staff member if (!$this->login->isAdmin() && !$this->login->isStaff()) { - $select->where(Adherent::PK . ' = ' . $this->login->id); + if (!$this->login->isGroupManager()) { + $select->where + ->nest() + ->equalTo('a.' . Adherent::PK, $this->login->id) + ->or + ->equalTo('a.parent_id', $this->login->id) + ->unnest() + ->and + ->equalTo('c.' . self::PK, $id) + ; + } else { + $select->where([ + Adherent::PK => $this->login->id, + self::PK => $id + ]); + } + } else { + $select->where->equalTo(self::PK, $id); } $results = $this->zdb->execute($select); diff --git a/galette/lib/Galette/Features/Replacements.php b/galette/lib/Galette/Features/Replacements.php index 2c487295c..b97563688 100644 --- a/galette/lib/Galette/Features/Replacements.php +++ b/galette/lib/Galette/Features/Replacements.php @@ -594,9 +594,9 @@ trait Replacements { global $login; - $address = $member->address; - if ($member->address_continuation !== '') { - $address .= '
' . $member->address_continuation; + $address = $member->getAddress(); + if ($member->getAddressContinuation() !== '') { + $address .= '
' . $member->getAddressContinuation(); } if ($member->isMan()) { @@ -633,11 +633,12 @@ trait Replacements 'adh_profession' => $member->job, 'adh_company' => $member->company_name, 'adh_address' => $address, - 'adh_zip' => $member->zipcode, - 'adh_town' => $member->town, - 'adh_country' => $member->country, + 'adh_zip' => $member->getZipcode(), + 'adh_town' => $member->getTown(), + 'adh_country' => $member->getCountry(), 'adh_phone' => $member->phone, 'adh_mobile' => $member->gsm, + //always take current member email, to be sure. 'adh_email' => $member->email, 'adh_login' => $member->login, 'adh_main_group' => $main_group, diff --git a/galette/lib/Galette/Filters/ContributionsList.php b/galette/lib/Galette/Filters/ContributionsList.php index 4441ba139..8ee474f57 100644 --- a/galette/lib/Galette/Filters/ContributionsList.php +++ b/galette/lib/Galette/Filters/ContributionsList.php @@ -75,6 +75,7 @@ class ContributionsList extends Pagination private $end_date_filter = null; private $payment_type_filter = null; private $filtre_cotis_adh = null; + private $filtre_cotis_children = false; private $filtre_transactions = null; private $from_transaction = false; @@ -84,6 +85,7 @@ class ContributionsList extends Pagination 'start_date_filter', 'end_date_filter', 'filtre_cotis_adh', + 'filtre_cotis_children', 'date_field', 'payment_type_filter', 'filtre_transactions', @@ -128,6 +130,7 @@ class ContributionsList extends Pagination $this->payment_type_filter = null; $this->filtre_transactions = null; $this->filtre_cotis_adh = null; + $this->filtre_cotis_children = false; $this->from_transaction = false; $this->max_amount = null; } diff --git a/galette/lib/Galette/Repository/Contributions.php b/galette/lib/Galette/Repository/Contributions.php index 87b0716e5..8a23c9bd1 100644 --- a/galette/lib/Galette/Repository/Contributions.php +++ b/galette/lib/Galette/Repository/Contributions.php @@ -364,18 +364,60 @@ class Contributions ); } - if (!$this->login->isAdmin() && !$this->login->isStaff()) { + $member_clause = null; + if ($this->filters->filtre_cotis_children !== false) { + $member_clause = [$this->login->id]; + $member = new Adherent( + $this->zdb, + (int)$this->filters->filtre_cotis_children, + [ + 'picture' => false, + 'groups' => false, + 'dues' => false, + 'children' => true + ] + ); + foreach ($member->children as $child) { + $member_clause[] = $child->id; + } + } elseif ($this->filters->filtre_cotis_adh != null) { + $member_clause = [$this->filters->filtre_cotis_adh]; + if (!$this->login->isAdmin() && !$this->login->isStaff() && $this->filters->filtre_cotis_adh != $this->login->id) { + $member = new Adherent( + $this->zdb, + (int)$this->filters->filtre_cotis_adh, + [ + 'picture' => false, + 'groups' => false, + 'dues' => false, + 'parent' => true + ] + ); + if ( + !$member->hasParent() || + $member->hasParent() && $member->parent->id != $this->login->id + ) { + Analog::log( + 'Trying to display contributions for member #' . $member->id . + ' without appropriate ACLs', + Analog::WARNING + ); + $member_clause = [$this->login->id]; + } + } + } elseif (!$this->login->isAdmin() && !$this->login->isStaff()) { //non staff members can only view their own contributions + $member_clause = $this->login->id; + } + + if ($member_clause !== null) { $select->where( array( - 'a.' . Adherent::PK => $this->login->id + 'a.' . Adherent::PK => $member_clause ) ); - } elseif ($this->filters->filtre_cotis_adh != null) { - $select->where( - 'a.' . Adherent::PK . ' = ' . $this->filters->filtre_cotis_adh - ); } + if ($this->filters->filtre_transactions === true) { $select->where('a.trans_id IS NULL'); } @@ -384,6 +426,7 @@ class Contributions __METHOD__ . ' | ' . $e->getMessage(), Analog::WARNING ); + throw $e; } } diff --git a/galette/templates/default/gestion_contributions.tpl b/galette/templates/default/gestion_contributions.tpl index ea1b6d159..9e183ebbe 100644 --- a/galette/templates/default/gestion_contributions.tpl +++ b/galette/templates/default/gestion_contributions.tpl @@ -111,7 +111,7 @@ {/if} -{if ($login->isAdmin() or $login->isStaff()) and !isset($member)} +{if (($login->isAdmin() or $login->isStaff()) and !isset($member)) or isset($pmember)} "contributions", "option" => "order", "value" => "Galette\Filters\ContributionsList::ORDERBY_MEMBER"|constant]}">{_T string="Member"} {if $filters->orderby eq constant('Galette\Filters\ContributionsList::ORDERBY_MEMBER')} @@ -230,7 +230,7 @@ {$contribution->date} {$contribution->begin_date} {$contribution->end_date} - {if ($login->isAdmin() or $login->isStaff()) && !isset($member)} + {if (($login->isAdmin() or $login->isStaff()) && !isset($member)) or isset($pmember)} {if isset($member)} {assign var="mname" value=$member->sname} diff --git a/galette/templates/default/voir_adherent.tpl b/galette/templates/default/voir_adherent.tpl index 415a90f99..fdc8463ee 100644 --- a/galette/templates/default/voir_adherent.tpl +++ b/galette/templates/default/voir_adherent.tpl @@ -61,7 +61,7 @@ {_T string="Modification"} -{if $login->isAdmin() or $login->isStaff()} +{if $login->isAdmin() or $login->isStaff() || $login->id eq $member->id || ($member->hasParent() and $member->parent->id eq $login->id)}
  • "contributions", "option" => "member", "value" => $member->id]}" @@ -72,6 +72,8 @@ {_T string="View contributions"}
  • +{/if} +{if $login->isAdmin() or $login->isStaff()}
  • constant('Galette\Entity\Contribution::TYPE_FEE')]}?id_adh={$member->id}" -- 2.39.2