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