]> git.agnieray.net Git - galette.git/commitdiff
Child management from parents
authorJohan Cwiklinski <jcwiklinski@teclib.com>
Sun, 22 Jul 2018 18:55:27 +0000 (20:55 +0200)
committerJohan Cwiklinski <johan@x-tnd.be>
Sun, 17 Oct 2021 04:15:40 +0000 (06:15 +0200)
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

galette/lib/Galette/Controllers/Crud/ContributionsController.php
galette/lib/Galette/Controllers/Crud/MembersController.php
galette/lib/Galette/Entity/Adherent.php
galette/lib/Galette/Entity/Contribution.php
galette/lib/Galette/Features/Replacements.php
galette/lib/Galette/Filters/ContributionsList.php
galette/lib/Galette/Repository/Contributions.php
galette/templates/default/gestion_contributions.tpl
galette/templates/default/voir_adherent.tpl

index b9ca44f433429d3c5a0041d6e0435990a09eab18..171e1e79b2c44046fd350b2e67ee3a1d6fb00d9c 100644 (file)
@@ -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,
index 70e7d6e76ee038925d7d5ed00af68fe49fcf956f..998c7b65915f68537b1ce7a7ae0b7f385aae9968 100644 (file)
@@ -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
index 55f0fd30c23eec39dad060d158f3bc5c02f7a25b..387932983688912dc46c9da8e1d96cd268514093 100644 (file)
@@ -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?
      *
index e0da8a89661a5ec52ab374551d8b25f7f69d8dc6..bfa80bc423b54444f68b7bb017f47c1773941c89 100644 (file)
@@ -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);
index 2c487295c77e7a63370cd5210f939b9001df55f3..b97563688ccdc1d5c94c22c4fd2b2dae0f984c31 100644 (file)
@@ -594,9 +594,9 @@ trait Replacements
     {
         global $login;
 
-        $address = $member->address;
-        if ($member->address_continuation !== '') {
-            $address .= '<br/>' . $member->address_continuation;
+        $address = $member->getAddress();
+        if ($member->getAddressContinuation() !== '') {
+            $address .= '<br/>' . $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,
index 4441ba1397f6cf191ec566195c9a1946a7c145d5..8ee474f5775364c7c63f0936bcaeb152a044c798 100644 (file)
@@ -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;
     }
index 87b0716e5a5f15a11b9ea52cd97fa3049d41c3d2..8a23c9bd193615d437b08fde0649e2e57da6b80b 100644 (file)
@@ -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;
         }
     }
 
index ea1b6d159447b1a49b2c7df255ee0991ca71c509..9e183ebbe1ecc52782d31efa1cc4cd47dd0c816f 100644 (file)
                         {/if}
                         </a>
                     </th>
-{if ($login->isAdmin() or $login->isStaff()) and !isset($member)}
+{if (($login->isAdmin() or $login->isStaff()) and !isset($member)) or isset($pmember)}
                     <th class="left">
                         <a href="{path_for name="contributions" data=["type" => "contributions", "option" => "order", "value" => "Galette\Filters\ContributionsList::ORDERBY_MEMBER"|constant]}">{_T string="Member"}
                         {if $filters->orderby eq constant('Galette\Filters\ContributionsList::ORDERBY_MEMBER')}
                     <td class="{$cclass} nowrap" data-title="{_T string="Date"}">{$contribution->date}</td>
                     <td class="{$cclass} nowrap" data-title="{_T string="Begin"}">{$contribution->begin_date}</td>
                     <td class="{$cclass} nowrap" data-title="{_T string="End"}">{$contribution->end_date}</td>
-    {if ($login->isAdmin() or $login->isStaff()) && !isset($member)}
+    {if (($login->isAdmin() or $login->isStaff()) && !isset($member)) or isset($pmember)}
                     <td class="{$cclass}" data-title="{_T string="Member"}">
         {if isset($member)}
             {assign var="mname" value=$member->sname}
index 415a90f99484ac07255ba841d7f7435fb27c2627..fdc8463ee30d126a8a70742628647e92d9e5bc50 100644 (file)
@@ -61,7 +61,7 @@
                     {_T string="Modification"}
                 </a>
             </li>
-{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)}
             <li>
                 <a
                     href="{path_for name="contributions" data=["type" => "contributions", "option" => "member", "value" => $member->id]}"
@@ -72,6 +72,8 @@
                     {_T string="View contributions"}
                 </a>
             </li>
+{/if}
+{if $login->isAdmin() or $login->isStaff()}
             <li>
                 <a
                     href="{path_for name="addContribution" data=["type" => constant('Galette\Entity\Contribution::TYPE_FEE')]}?id_adh={$member->id}"