3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
10 * Copyright © 2010-2021 The Galette Team
12 * This file is part of Galette (http://galette.tuxfamily.org).
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
27 * @category Repository
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2010-2021 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since Available since 0.7dev - 2010-03-11
37 namespace Galette\Repository
;
41 use Laminas\Db\Sql\Expression
;
43 use Galette\Core\Login
;
44 use Galette\Core\History
;
45 use Galette\Entity\Contribution
;
46 use Galette\Entity\Adherent
;
47 use Galette\Entity\Transaction
;
48 use Galette\Entity\ContributionsTypes
;
49 use Galette\Filters\ContributionsList
;
50 use Laminas\Db\Sql\Select
;
53 * Contributions class for galette
56 * @category Repository
59 * @author Johan Cwiklinski <johan@x-tnd.be>
60 * @copyright 2009-2021 The Galette Team
61 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
62 * @link http://galette.tuxfamily.org
66 public const TABLE
= Contribution
::TABLE
;
67 public const PK
= Contribution
::PK
;
69 private $count = null;
76 * @param Db $zdb Database
77 * @param Login $login Login
78 * @param ContributionsList $filters Filtering
80 public function __construct(Db
$zdb, Login
$login, $filters = null)
83 $this->login
= $login;
85 if ($filters === null) {
86 $this->filters
= new ContributionsList();
88 $this->filters
= $filters;
93 * Get contributions list for a specific transaction
95 * @param int $trans_id Transaction identifier
97 * @return Contribution[]
99 public function getListFromTransaction($trans_id)
101 $this->filters
->from_transaction
= $trans_id;
102 return $this->getList(true);
106 * Get contributions list
108 * @param bool $as_contrib return the results as an array of
109 * Contribution object.
110 * @param array $fields field(s) name(s) to get. Should be a string or
111 * an array. If null, all fields will be
113 * @param boolean $count true if we want to count members
115 * @return Contribution[]|ResultSet
117 public function getList($as_contrib = false, $fields = null, $count = true)
120 $select = $this->buildSelect($fields, $count);
122 $this->filters
->setLimits($select);
124 $contributions = array();
125 $results = $this->zdb
->execute($select);
127 foreach ($results as $row) {
128 $contributions[] = new Contribution($this->zdb
, $this->login
, $row);
131 $contributions = $results;
133 return $contributions;
134 } catch (Throwable
$e) {
136 'Cannot list contributions | ' . $e->getMessage(),
144 * Builds the SELECT statement
146 * @param array $fields fields list to retrieve
147 * @param bool $count true if we want to count members
148 * (not applicable from static calls), defaults to false
150 * @return string SELECT statement
152 private function buildSelect($fields, $count = false)
155 $fieldsList = ($fields != null)
156 ?
((!is_array($fields) ||
count($fields) < 1) ?
(array)'*'
157 : implode(', ', $fields)) : (array)'*';
159 $select = $this->zdb
->select(self
::TABLE
, 'a');
160 $select->columns($fieldsList);
163 array('p' => PREFIX_DB
. Adherent
::TABLE
),
164 'a.' . Adherent
::PK
. '= p.' . Adherent
::PK
167 $this->buildWhereClause($select);
168 $select->order(self
::buildOrderClause());
170 $this->calculateSum($select);
173 $this->proceedCount($select);
177 } catch (Throwable
$e) {
179 'Cannot build SELECT clause for contributions | ' . $e->getMessage(),
187 * Count contributions from the query
189 * @param Select $select Original select
193 private function proceedCount(Select
$select)
196 $countSelect = clone $select;
197 $countSelect->reset($countSelect::COLUMNS
);
198 $countSelect->reset($countSelect::JOINS
);
199 $countSelect->reset($countSelect::ORDER
);
200 $countSelect->columns(
202 self
::PK
=> new Expression('COUNT(' . self
::PK
. ')')
206 $results = $this->zdb
->execute($countSelect);
207 $result = $results->current();
210 $this->count
= $result->$k;
212 if ($this->count
> 0) {
213 $this->filters
->setCounter($this->count
);
215 } catch (Throwable
$e) {
217 'Cannot count contributions | ' . $e->getMessage(),
225 * Calculate sum of all selected contributions
227 * @param Select $select Original select
231 private function calculateSum(Select
$select)
234 $sumSelect = clone $select;
235 $sumSelect->reset($sumSelect::COLUMNS
);
236 $sumSelect->reset($sumSelect::JOINS
);
237 $sumSelect->reset($sumSelect::ORDER
);
240 'contribsum' => new Expression('SUM(montant_cotis)')
244 $results = $this->zdb
->execute($sumSelect);
245 $result = $results->current();
247 $this->sum
= round($result->contribsum
, 2);
248 } catch (Throwable
$e) {
250 'Cannot calculate contributions sum | ' . $e->getMessage(),
258 * Builds the order clause
260 * @return string SQL ORDER clause
262 private function buildOrderClause()
266 switch ($this->filters
->orderby
) {
267 case ContributionsList
::ORDERBY_ID
:
268 $order[] = Contribution
::PK
. ' ' . $this->filters
->ordered
;
270 case ContributionsList
::ORDERBY_DATE
:
271 $order[] = 'date_enreg ' . $this->filters
->ordered
;
273 case ContributionsList
::ORDERBY_BEGIN_DATE
:
274 $order[] = 'date_debut_cotis ' . $this->filters
->ordered
;
276 case ContributionsList
::ORDERBY_END_DATE
:
277 $order[] = 'date_fin_cotis ' . $this->filters
->ordered
;
279 case ContributionsList
::ORDERBY_MEMBER
:
280 $order[] = 'nom_adh ' . $this->filters
->ordered
;
281 $order[] = 'prenom_adh ' . $this->filters
->ordered
;
283 case ContributionsList
::ORDERBY_TYPE
:
284 $order[] = ContributionsTypes
::PK
;
286 case ContributionsList
::ORDERBY_AMOUNT
:
287 $order[] = 'montant_cotis ' . $this->filters
->ordered
;
290 Hum... I really do not know how to sort a query with a value that
291 is calculated code side :/
292 case ContributionsList::ORDERBY_DURATION:
294 case ContributionsList
::ORDERBY_PAYMENT_TYPE
:
295 $order[] = 'type_paiement_cotis ' . $this->filters
->ordered
;
298 $order[] = $this->filters
->orderby
. ' ' . $this->filters
->ordered
;
306 * Builds where clause, for filtering on simple list mode
308 * @param Select $select Original select
310 * @return string SQL WHERE clause
312 private function buildWhereClause(Select
$select)
314 $field = 'date_debut_cotis';
316 switch ($this->filters
->date_field
) {
317 case ContributionsList
::DATE_RECORD
:
318 $field = 'date_enreg';
320 case ContributionsList
::DATE_END
:
321 $field = 'date_fin_cotis';
323 case ContributionsList
::DATE_BEGIN
:
325 $field = 'date_debut_cotis';
330 if ($this->filters
->start_date_filter
!= null) {
331 $d = new \
DateTime($this->filters
->rstart_date_filter
);
332 $select->where
->greaterThanOrEqualTo(
338 if ($this->filters
->end_date_filter
!= null) {
339 $d = new \
DateTime($this->filters
->rend_date_filter
);
340 $select->where
->lessThanOrEqualTo(
346 if ($this->filters
->payment_type_filter
!== null) {
347 $select->where
->equalTo(
348 'type_paiement_cotis',
349 $this->filters
->payment_type_filter
353 if ($this->filters
->from_transaction
!== false) {
354 $select->where
->equalTo(
356 $this->filters
->from_transaction
360 if ($this->filters
->max_amount
!== null && is_int($this->filters
->max_amount
)) {
362 '(montant_cotis <= ' . $this->filters
->max_amount
.
363 ' OR montant_cotis IS NULL)'
367 $member_clause = null;
368 if ($this->filters
->filtre_cotis_adh
!= null) {
369 $member_clause = [$this->filters
->filtre_cotis_adh
];
370 if (!$this->login
->isAdmin() && !$this->login
->isStaff() && $this->filters
->filtre_cotis_adh
!= $this->login
->id
) {
371 $member = new Adherent(
373 (int)$this->filters
->filtre_cotis_adh
,
382 !$member->hasParent() ||
383 $member->hasParent() && $member->parent
->id
!= $this->login
->id
386 'Trying to display contributions for member #' . $member->id
.
387 ' without appropriate ACLs',
390 $this->filters
->filtre_cotis_adh
= $this->login
->id
;
391 $member_clause = [$this->login
->id
];
394 } elseif ($this->filters
->filtre_cotis_children
!== false) {
395 $member_clause = [$this->login
->id
];
396 $member = new Adherent(
398 (int)$this->filters
->filtre_cotis_children
,
406 foreach ($member->children
as $child) {
407 $member_clause[] = $child->id
;
409 } elseif (!$this->login
->isAdmin() && !$this->login
->isStaff()) {
410 //non staff members can only view their own contributions
411 $member_clause = $this->login
->id
;
414 if ($member_clause !== null) {
417 'a.' . Adherent
::PK
=> $member_clause
422 if ($this->filters
->filtre_transactions
=== true) {
423 $select->where('a.trans_id IS NULL');
425 } catch (Throwable
$e) {
427 __METHOD__
. ' | ' . $e->getMessage(),
435 * Get count for current query
439 public function getCount()
449 public function getSum()
455 * Remove specified contributions
457 * @param integer|array $ids Contributions identifiers to delete
458 * @param History $hist History
459 * @param boolean $transaction True to begin a database transaction
463 public function remove($ids, History
$hist, $transaction = true)
466 if (is_numeric($ids)) {
467 //we've got only one identifier
473 if (is_array($list)) {
477 $this->zdb
->connection
->beginTransaction();
479 $select = $this->zdb
->select(self
::TABLE
);
480 $select->where
->in(self
::PK
, $list);
481 $contributions = $this->zdb
->execute($select);
482 foreach ($contributions as $contribution) {
483 $c = new Contribution($this->zdb
, $this->login
, $contribution);
484 $res = $c->remove(false);
485 if ($res === false) {
486 throw new \
Exception();
490 $this->zdb
->connection
->commit();
495 print_r($list, true),
496 _T("Contributions deleted (%list)")
500 } catch (Throwable
$e) {
502 $this->zdb
->connection
->rollBack();
505 'An error occurred trying to remove contributions | ' .
512 //not numeric and not an array: incorrect.
514 'Asking to remove contribution, but without providing an array or a single numeric value.',