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