]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Controllers/Crud/ContributionsController.php
Fix selection of contributions on transaction form
[galette.git] / galette / lib / Galette / Controllers / Crud / ContributionsController.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Galette contributions controller
7 *
8 * PHP version 5
9 *
10 * Copyright © 2020-2022 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
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.
18 *
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.
23 *
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/>.
26 *
27 * @category Controllers
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2020-2022 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.9.4dev - 2020-05-08
35 */
36
37 namespace Galette\Controllers\Crud;
38
39 use Galette\Filters\ContributionsList;
40 use Throwable;
41 use Analog\Analog;
42 use Galette\Controllers\CrudController;
43 use Slim\Http\Request;
44 use Slim\Http\Response;
45 use Galette\Entity\Adherent;
46 use Galette\Entity\Contribution;
47 use Galette\Entity\Transaction;
48 use Galette\Repository\Members;
49 use Galette\Entity\ContributionsTypes;
50 use Galette\Repository\PaymentTypes;
51
52 /**
53 * Galette contributions controller
54 *
55 * @category Controllers
56 * @name ContributionsController
57 * @package Galette
58 * @author Johan Cwiklinski <johan@x-tnd.be>
59 * @copyright 2020-2022 The Galette Team
60 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
61 * @link http://galette.tuxfamily.org
62 * @since Available since 0.9.4dev - 2020-05-02
63 */
64
65 class ContributionsController extends CrudController
66 {
67 // CRUD - Create
68
69 /**
70 * Add/Edit page
71 *
72 * Only a few things changes in add and edit pages,
73 * boths methods will use this common one.
74 *
75 * @param Request $request PSR Request
76 * @param Response $response PSR Response
77 * @param string $type Contribution type
78 * @param Contribution $contrib Contribution instance
79 *
80 * @return Response
81 */
82 public function addEditPage(
83 Request $request,
84 Response $response,
85 string $type,
86 Contribution $contrib
87 ): Response {
88 $post = $request->getParsedBody();
89
90 // check for ajax mode
91 $ajax = false;
92 if (
93 $request->isXhr()
94 || isset($post['ajax'])
95 && $post['ajax'] == 'true'
96 ) {
97 $ajax = true;
98 }
99
100 // contribution types
101 $ct = new ContributionsTypes($this->zdb);
102 $contributions_types = $ct->getList($type === Contribution::TYPE_FEE);
103
104 // template variable declaration
105 $title = null;
106 if ($type === Contribution::TYPE_FEE) {
107 $title = _T("Membership fee");
108 } else {
109 $title = _T("Donation");
110 }
111
112 if ($contrib->id != '') {
113 $title .= ' (' . _T("modification") . ')';
114 } else {
115 $title .= ' (' . _T("creation") . ')';
116 }
117
118 $params = [
119 'page_title' => $title,
120 'required' => $contrib->getRequired(),
121 'contribution' => $contrib,
122 'adh_selected' => $contrib->member,
123 'type' => $type
124 ];
125
126 // contribution types
127 $params['type_cotis_options'] = $contributions_types;
128
129 // members
130 $m = new Members();
131 $members = $m->getDropdownMembers(
132 $this->zdb,
133 $this->login,
134 $contrib->member > 0 ? $contrib->member : null
135 );
136
137 $params['members'] = [
138 'filters' => $m->getFilters(),
139 'count' => $m->getCount()
140 ];
141
142 if (count($members)) {
143 $params['members']['list'] = $members;
144 }
145
146 $ext_membership = '';
147 if ($contrib->isFee() || !isset($contrib) && $type === Contribution::TYPE_FEE) {
148 $ext_membership = $this->preferences->pref_membership_ext;
149 }
150 $params['pref_membership_ext'] = $ext_membership;
151 $params['autocomplete'] = true;
152 $params['mode'] = ($ajax ? 'ajax' : '');
153
154 // display page
155 $this->view->render(
156 $response,
157 'pages/contribution_form.html.twig',
158 $params
159 );
160 return $response;
161 }
162
163 /**
164 * Add page
165 *
166 * @param Request $request PSR Request
167 * @param Response $response PSR Response
168 * @param string|null $type Contribution type
169 *
170 * @return Response
171 */
172 public function add(Request $request, Response $response, string $type = null): Response
173 {
174 if ($this->session->contribution !== null) {
175 $contrib = $this->session->contribution;
176 $this->session->contribution = null;
177 } else {
178 $get = $request->getQueryParams();
179
180 $ct = new ContributionsTypes($this->zdb);
181 $contributions_types = $ct->getList($type === Contribution::TYPE_FEE);
182
183 $cparams = ['type' => array_keys($contributions_types)[0]];
184
185 //member id
186 if (isset($get[Adherent::PK]) && $get[Adherent::PK] > 0) {
187 $cparams['adh'] = (int)$get[Adherent::PK];
188 }
189
190 //transaction id
191 if (isset($get[Transaction::PK]) && $get[Transaction::PK] > 0) {
192 $cparams['trans'] = $get[Transaction::PK];
193 }
194
195 $contrib = new Contribution(
196 $this->zdb,
197 $this->login,
198 (count($cparams) > 0 ? $cparams : null)
199 );
200
201 if (isset($cparams['adh'])) {
202 $contrib->member = $cparams['adh'];
203 }
204
205 if (isset($get['montant_cotis']) && $get['montant_cotis'] > 0) {
206 $contrib->amount = $get['montant_cotis'];
207 }
208 }
209
210 return $this->addEditPage($request, $response, $type, $contrib);
211 }
212
213 /**
214 * Add action
215 *
216 * @param Request $request PSR Request
217 * @param Response $response PSR Response
218 * @param string|null $type Contribution type
219 *
220 * @return Response
221 */
222 public function doAdd(Request $request, Response $response, string $type = null): Response
223 {
224 return $this->store($request, $response, 'add', $type);
225 }
226
227 /**
228 * Choose contribution type to mass add contribution
229 *
230 * @param Request $request PSR Request
231 * @param Response $response PSR Response
232 *
233 * @return Response
234 */
235 public function massAddChooseType(Request $request, Response $response): Response
236 {
237 $filters = $this->session->filter_members;
238 $data = [
239 'id' => $filters->selected,
240 'redirect_uri' => $this->router->pathFor('members')
241 ];
242
243 // display page
244 $this->view->render(
245 $response,
246 'modals/mass_choose_contributions_type.html.twig',
247 array(
248 'mode' => $request->isXhr() ? 'ajax' : '',
249 'page_title' => str_replace(
250 '%count',
251 count($data['id']),
252 _T('Mass add contribution on %count members')
253 ),
254 'data' => $data,
255 'form_url' => $this->router->pathFor('massAddContributions'),
256 'cancel_uri' => $this->router->pathFor('members')
257 )
258 );
259 return $response;
260 }
261
262 /**
263 * Massive change page
264 *
265 * @param Request $request PSR Request
266 * @param Response $response PSR Response
267 *
268 * @return Response
269 */
270 public function massAddContributions(Request $request, Response $response): Response
271 {
272 $post = $request->getParsedBody();
273 $filters = $this->session->filter_members;
274 $contribution = new Contribution($this->zdb, $this->login);
275
276 $type = $post['type'];
277 $data = [
278 'id' => $filters->selected,
279 'redirect_uri' => $this->router->pathFor('members'),
280 'type' => $type
281 ];
282
283 // contribution types
284 $ct = new ContributionsTypes($this->zdb);
285 $contributions_types = $ct->getList($type === Contribution::TYPE_FEE);
286
287 // display page
288 $this->view->render(
289 $response,
290 'modals/mass_add_contributions.html.twig',
291 array(
292 'mode' => $request->isXhr() ? 'ajax' : '',
293 'page_title' => str_replace(
294 '%count',
295 count($data['id']),
296 _T('Mass add contribution on %count members')
297 ),
298 'form_url' => $this->router->pathFor('doMassAddContributions'),
299 'cancel_uri' => $this->router->pathFor('members'),
300 'data' => $data,
301 'contribution' => $contribution,
302 'type' => $type,
303 'require_mass' => true,
304 'required' => $contribution->getRequired(),
305 'type_cotis_options' => $contributions_types
306 )
307 );
308 return $response;
309 }
310
311 /**
312 * Do massive contribution add
313 *
314 * @param Request $request PSR Request
315 * @param Response $response PSR Response
316 *
317 * @return Response
318 */
319 public function doMassAddContributions(Request $request, Response $response): Response
320 {
321 $post = $request->getParsedBody();
322 $members_ids = $post['id'];
323 unset($post['id']);
324
325 $error_detected = [];
326
327 // flagging required fields for first step only
328 $disabled = [];
329 $success = 0;
330 $errors = 0;
331
332 foreach ($members_ids as $member_id) {
333 $post[Adherent::PK] = (int)$member_id;
334 $contrib = new Contribution($this->zdb, $this->login);
335
336 // regular fields
337 $valid = $contrib->check($post, $contrib->getRequired(), $disabled);
338 if ($valid !== true) {
339 $error_detected = array_merge($error_detected, $valid);
340 }
341
342 //all goes well, we can proceed
343 if (count($error_detected) == 0) {
344 $store = $contrib->store();
345 if ($store === true) {
346 ++$success;
347 $files_res = $contrib->handleFiles($_FILES);
348 if (is_array($files_res)) {
349 $error_detected = array_merge($error_detected, $files_res);
350 }
351 } else {
352 ++$errors;
353 }
354 }
355 }
356
357 if (count($error_detected) == 0) {
358 $redirect_url = $this->router->pathFor('members');
359 } else {
360 //something went wrong.
361 //store entity in session
362 $redirect_url = $this->router->pathFor('massAddContributions');
363 //report errors
364 foreach ($error_detected as $error) {
365 $this->flash->addMessage(
366 'error_detected',
367 $error
368 );
369 }
370 }
371
372 //redirect to calling action
373 return $response
374 ->withStatus(301)
375 ->withHeader('Location', $redirect_url);
376 }
377
378 // /CRUD - Create
379 // CRUD - Read
380
381 /**
382 * List page
383 *
384 * @param Request $request PSR Request
385 * @param Response $response PSR Response
386 * @param string $option One of 'page' or 'order'
387 * @param string|integer $value Value of the option
388 * @param string $type One of 'transactions' or 'contributions'
389 *
390 * @return Response
391 */
392 public function list(Request $request, Response $response, $option = null, $value = null, $type = null): Response
393 {
394 $ajax = false;
395 $get = $request->getQueryParams();
396
397 if (
398 $request->isXhr()
399 || isset($get['ajax'])
400 && $get['ajax'] == 'true'
401 ) {
402 $ajax = true;
403 }
404
405 switch ($type) {
406 case 'transactions':
407 $raw_type = 'transactions';
408 break;
409 case 'contributions':
410 $raw_type = 'contributions';
411 break;
412 default:
413 Analog::log(
414 'Trying to load unknown contribution type ' . $type,
415 Analog::WARNING
416 );
417 return $response
418 ->withStatus(301)
419 ->withHeader(
420 'Location',
421 $this->router->pathFor('me')
422 );
423 }
424
425 $filter_name = 'filter_' . $raw_type;
426
427 if (isset($this->session->$filter_name) && $ajax === false) {
428 $filters = $this->session->$filter_name;
429 } else {
430 $filter_class = '\\Galette\\Filters\\' . ucwords($raw_type . 'List');
431 $filters = new $filter_class();
432 }
433
434 //member id
435 if (isset($get[Adherent::PK]) && $get[Adherent::PK] > 0) {
436 $filters->filtre_cotis_adh = (int)$get[Adherent::PK];
437 }
438
439 $filters->filtre_transactions = false;
440 if (isset($request->getQueryParams()['max_amount'])) {
441 $filters->filtre_transactions = true;
442 $filters->max_amount = (int)$request->getQueryParams()['max_amount'];
443 }
444
445 if ($option !== null) {
446 switch ($option) {
447 case 'page':
448 $filters->current_page = (int)$value;
449 break;
450 case 'order':
451 $filters->orderby = $value;
452 break;
453 case 'member':
454 $filters->filtre_cotis_adh = ($value === 'all' ? null : $value);
455 break;
456 }
457 }
458
459 if (!$this->login->isAdmin() && !$this->login->isStaff() && $value != $this->login->id) {
460 if ($value === 'all' || empty($value)) {
461 $value = $this->login->id;
462 } else {
463 $member = new Adherent(
464 $this->zdb,
465 (int)$value,
466 [
467 'picture' => false,
468 'groups' => false,
469 'dues' => false,
470 'parent' => true
471 ]
472 );
473 if (
474 !$member->hasParent() ||
475 $member->hasParent() && $member->parent->id != $this->login->id
476 ) {
477 $value = $this->login->id;
478 Analog::log(
479 'Trying to display contributions for member #' . $value .
480 ' without appropriate ACLs',
481 Analog::WARNING
482 );
483 }
484 }
485 $filters->filtre_cotis_children = $value;
486 }
487
488 $class = '\\Galette\\Entity\\' . ucwords(trim($raw_type, 's'));
489 $contrib = new $class($this->zdb, $this->login);
490
491 if (!$contrib->canShow($this->login)) {
492 Analog::log(
493 'Trying to display contributions without appropriate ACLs',
494 Analog::WARNING
495 );
496 return $response
497 ->withStatus(301)
498 ->withHeader(
499 'Location',
500 $this->router->pathFor('me')
501 );
502 }
503
504 $class = '\\Galette\\Repository\\' . ucwords($raw_type);
505 $contrib = new $class($this->zdb, $this->login, $filters);
506 $contribs_list = $contrib->getList(true);
507
508 //store filters into session
509 if ($ajax === false) {
510 $this->session->$filter_name = $filters;
511 }
512
513 //assign pagination variables to the template and add pagination links
514 $filters->setSmartyPagination($this->router, $this->view);
515
516 $tpl_vars = [
517 'page_title' => $raw_type === 'contributions' ?
518 _T("Contributions management") : _T("Transactions management"),
519 'contribs' => $contrib,
520 'list' => $contribs_list,
521 'nb' => $contrib->getCount(),
522 'filters' => $filters,
523 'mode' => ($ajax === true ? 'ajax' : 'std')
524 ];
525
526 if ($filters->filtre_cotis_adh != null) {
527 $member = new Adherent($this->zdb);
528 $member->load($filters->filtre_cotis_adh);
529 $tpl_vars['member'] = $member;
530 }
531
532 if ($filters->filtre_cotis_children != false) {
533 $member = new Adherent(
534 $this->zdb,
535 $filters->filtre_cotis_children,
536 [
537 'picture' => false,
538 'groups' => false,
539 'dues' => false,
540 'parent' => true
541 ]
542 );
543 $tpl_vars['pmember'] = $member;
544 }
545
546 // hide column action in ajax mode
547 if ($ajax === true) {
548 $tpl_vars['no_action'] = true;
549 }
550
551 // display page
552 $this->view->render(
553 $response,
554 'pages/' . $raw_type . '_list.html.twig',
555 $tpl_vars
556 );
557 return $response;
558 }
559
560 /**
561 * List page for logged-in member
562 *
563 * @param Request $request PSR Request
564 * @param Response $response PSR Response
565 * @param string $type One of 'transactions' or 'contributions'
566 *
567 * @return Response
568 */
569 public function myList(Request $request, Response $response, string $type = null): Response
570 {
571 return $this->list(
572 $request->withQueryParams(
573 $request->getQueryParams() + [
574 Adherent::PK => $this->login->id
575 ]
576 ),
577 $response,
578 null,
579 null,
580 $type
581 );
582 }
583
584 /**
585 * Filtering
586 *
587 * @param Request $request PSR Request
588 * @param Response $response PSR Response
589 * @param string|null $type One of 'transactions' or 'contributions'
590 *
591 * @return Response
592 */
593 public function filter(Request $request, Response $response, string $type = null): Response
594 {
595 $filter_name = 'filter_' . $type;
596 $post = $request->getParsedBody();
597 $error_detected = [];
598
599 if ($this->session->$filter_name !== null) {
600 $filters = $this->session->$filter_name;
601 } else {
602 $filter_class = '\\Galette\\Filters\\' . ucwords($type) . 'List';
603 $filters = new $filter_class();
604 }
605
606 if (isset($post['clear_filter'])) {
607 $filters->reinit();
608 } else {
609 if (isset($post['max_amount'])) {
610 $filters->max_amount = null;
611 }
612
613 if (
614 (isset($post['nbshow']) && is_numeric($post['nbshow']))
615 ) {
616 $filters->show = $post['nbshow'];
617 }
618
619 if (isset($post['date_field'])) {
620 $filters->date_field = $post['date_field'];
621 }
622
623 if (isset($post['end_date_filter']) || isset($post['start_date_filter'])) {
624 try {
625 if (isset($post['start_date_filter'])) {
626 $filters->start_date_filter = $post['start_date_filter'];
627 }
628 if (isset($post['end_date_filter'])) {
629 $filters->end_date_filter = $post['end_date_filter'];
630 }
631 } catch (Throwable $e) {
632 $error_detected[] = $e->getMessage();
633 }
634 }
635
636 if (isset($post['payment_type_filter'])) {
637 $ptf = (int)$post['payment_type_filter'];
638 $ptypes = new PaymentTypes(
639 $this->zdb,
640 $this->preferences,
641 $this->login
642 );
643 $ptlist = $ptypes->getList();
644 if (isset($ptlist[$ptf])) {
645 $filters->payment_type_filter = $ptf;
646 } elseif ($ptf == -1) {
647 $filters->payment_type_filter = null;
648 } else {
649 $error_detected[] = _T("- Unknown payment type!");
650 }
651 }
652 }
653
654 $this->session->$filter_name = $filters;
655
656 if (count($error_detected) > 0) {
657 //report errors
658 foreach ($error_detected as $error) {
659 $this->flash->addMessage(
660 'error_detected',
661 $error
662 );
663 }
664 }
665
666 return $response
667 ->withStatus(301)
668 ->withHeader('Location', $this->router->pathFor('contributions', ['type' => $type]));
669 }
670
671 /**
672 * Batch actions handler
673 *
674 * @param Request $request PSR Request
675 * @param Response $response PSR Response
676 * @param string $type One of 'transactions' or 'contributions'
677 *
678 * @return Response
679 */
680 public function handleBatch(Request $request, Response $response, string $type): Response
681 {
682 $filter_name = 'filter_' . $type;
683 $post = $request->getParsedBody();
684
685 if (isset($post['entries_sel'])) {
686 $filters = $this->session->$filter_name ?? new ContributionsList();
687 $filters->selected = $post['entries_sel'];
688 $this->session->$filter_name = $filters;
689
690 if (isset($post['csv'])) {
691 return $response
692 ->withStatus(301)
693 ->withHeader('Location', $this->router->pathFor('csv-contributionslist', ['type' => $type]));
694 }
695
696 if (isset($post['delete'])) {
697 return $response
698 ->withStatus(301)
699 ->withHeader('Location', $this->router->pathFor('removeContributions'));
700 }
701
702 throw new \RuntimeException('Does not know what to batch :(');
703 } else {
704 $this->flash->addMessage(
705 'error_detected',
706 _T("No contribution was selected, please check at least one.")
707 );
708
709 return $response
710 ->withStatus(301)
711 ->withHeader('Location', $this->router->pathFor('contributions', ['type' => $type]));
712 }
713 }
714
715 // /CRUD - Read
716 // CRUD - Update
717
718 /**
719 * Edit page
720 *
721 * @param Request $request PSR Request
722 * @param Response $response PSR Response
723 * @param int $id Contribution id
724 * @param string|null $type Contribution type
725 *
726 * @return Response
727 */
728 public function edit(Request $request, Response $response, int $id, string $type = null): Response
729 {
730 if ($this->session->contribution !== null) {
731 $contrib = $this->session->contribution;
732 $this->session->contribution = null;
733 } else {
734 $contrib = new Contribution($this->zdb, $this->login, $id);
735 if ($contrib->id == '') {
736 //not possible to load contribution, exit
737 $this->flash->addMessage(
738 'error_detected',
739 str_replace(
740 '%id',
741 $id,
742 _T("Unable to load contribution #%id!")
743 )
744 );
745 return $response
746 ->withStatus(301)
747 ->withHeader('Location', $this->router->pathFor(
748 'contributions',
749 ['type' => 'contributions']
750 ));
751 }
752 }
753
754 return $this->addEditPage($request, $response, $type, $contrib);
755 }
756
757 /**
758 * Edit action
759 *
760 * @param Request $request PSR Request
761 * @param Response $response PSR Response
762 * @param integer $id Contribution id
763 * @param string|null $type Contribution type
764 *
765 * @return Response
766 */
767 public function doEdit(Request $request, Response $response, int $id, string $type = null): Response
768 {
769 return $this->store($request, $response, 'edit', $type, $id);
770 }
771
772 /**
773 * Store contribution (new or existing)
774 *
775 * @param Request $request PSR Request
776 * @param Response $response PSR Response
777 * @param string $action Action ('edit' or 'add')
778 * @param string $type Contribution type
779 * @param integer $id Contribution id
780 *
781 * @return Response
782 */
783 public function store(Request $request, Response $response, $action, string $type, $id = null): Response
784 {
785 $post = $request->getParsedBody();
786 $args = [
787 'action' => $action,
788 'type' => $type
789 ];
790 if ($id !== null) {
791 $args['id'] = $id;
792 }
793
794 if ($action == 'edit' && isset($post['btnreload'])) {
795 $redirect_url = $this->router->pathFor($action . 'Contribution', $args);
796 $redirect_url .= '?' . Adherent::PK . '=' . $post[Adherent::PK] . '&' .
797 ContributionsTypes::PK . '=' . $post[ContributionsTypes::PK] . '&' .
798 'montant_cotis=' . $post['montant_cotis'];
799 return $response
800 ->withStatus(301)
801 ->withHeader('Location', $redirect_url);
802 }
803
804 $error_detected = [];
805
806 if ($this->session->contribution !== null) {
807 $contrib = $this->session->contribution;
808 $this->session->contribution = null;
809 } else {
810 if ($id === null) {
811 $contrib = new Contribution($this->zdb, $this->login);
812 } else {
813 $contrib = new Contribution($this->zdb, $this->login, $id);
814 }
815 }
816
817 $disabled = [];
818
819 // regular fields
820 $valid = $contrib->check($post, $contrib->getRequired(), $disabled);
821 if ($valid !== true) {
822 $error_detected = array_merge($error_detected, $valid);
823 }
824
825 // send email to member
826 if (isset($post['mail_confirm']) && $post['mail_confirm'] == '1') {
827 $contrib->setSendmail(); //flag to send creation email
828 }
829
830 //all goes well, we can proceed
831 if (count($error_detected) == 0) {
832 $store = $contrib->store();
833 if ($store === true) {
834 $this->flash->addMessage(
835 'success_detected',
836 _T('Contribution has been successfully stored')
837 );
838 } else {
839 //something went wrong :'(
840 $error_detected[] = _T("An error occurred while storing the contribution.");
841 }
842 }
843
844 if (count($error_detected) === 0) {
845 $files_res = $contrib->handleFiles($_FILES);
846 if (is_array($files_res)) {
847 $error_detected = array_merge($error_detected, $files_res);
848 }
849 }
850
851 if (count($error_detected) == 0) {
852 $this->session->contribution = null;
853 if ($contrib->isTransactionPart() && $contrib->transaction->getMissingAmount() > 0) {
854 //new contribution
855 $redirect_url = $this->router->pathFor(
856 'addContribution',
857 [
858 'type' => $post['contrib_type']
859 ]
860 ) . '?' . Transaction::PK . '=' . $contrib->transaction->id .
861 '&' . Adherent::PK . '=' . $contrib->member;
862 } else {
863 //contributions list for member
864 $redirect_url = $this->router->pathFor(
865 'contributions',
866 [
867 'type' => 'contributions'
868 ]
869 ) . '?' . Adherent::PK . '=' . $contrib->member;
870 }
871 } else {
872 //something went wrong.
873 //store entity in session
874 $this->session->contribution = $contrib;
875 $redirect_url = $this->router->pathFor($action . 'Contribution', $args);
876
877 //report errors
878 foreach ($error_detected as $error) {
879 $this->flash->addMessage(
880 'error_detected',
881 $error
882 );
883 }
884 }
885
886 //redirect to calling action
887 return $response
888 ->withStatus(301)
889 ->withHeader('Location', $redirect_url);
890 }
891
892 // /CRUD - Update
893 // CRUD - Delete
894
895 /**
896 * Get redirection URI
897 *
898 * @param array $args Route arguments
899 *
900 * @return string
901 */
902 public function redirectUri(array $args)
903 {
904 return $this->router->pathFor('contributions', ['type' => $args['type']]);
905 }
906
907 /**
908 * Get form URI
909 *
910 * @param array $args Route arguments
911 *
912 * @return string
913 */
914 public function formUri(array $args)
915 {
916 return $this->router->pathFor(
917 'doRemoveContribution',
918 $args
919 );
920 }
921
922 /**
923 * Get confirmation removal page title
924 *
925 * @param array $args Route arguments
926 *
927 * @return string
928 */
929 public function confirmRemoveTitle(array $args)
930 {
931 $raw_type = null;
932
933 switch ($args['type']) {
934 case 'transactions':
935 $raw_type = 'transactions';
936 break;
937 case 'contributions':
938 $raw_type = 'contributions';
939 break;
940 }
941
942 if (isset($args['ids'])) {
943 return sprintf(
944 _T('Remove %1$s %2$s'),
945 count($args['ids']),
946 ($raw_type === 'contributions') ? _T('contributions') : _T('transactions')
947 );
948 } else {
949 return sprintf(
950 _T('Remove %1$s #%2$s'),
951 ($raw_type === 'contributions') ? _T('contribution') : _T('transaction'),
952 $args['id']
953 );
954 }
955 }
956
957 /**
958 * Remove object
959 *
960 * @param array $args Route arguments
961 * @param array $post POST values
962 *
963 * @return boolean
964 */
965 protected function doDelete(array $args, array $post)
966 {
967 $raw_type = null;
968 switch ($args['type']) {
969 case 'transactions':
970 $raw_type = 'transactions';
971 break;
972 case 'contributions':
973 $raw_type = 'contributions';
974 break;
975 }
976
977 $class = '\\Galette\Repository\\' . ucwords($raw_type);
978 $contribs = new $class($this->zdb, $this->login);
979 $rm = $contribs->remove($args['ids'] ?? $args['id'], $this->history);
980 return $rm;
981 }
982
983 // /CRUD - Delete
984 // /CRUD
985 }