Passed
Push — master ( 1d79f0...af841a )
by Jan
03:19
created

PaymentOrderCrudController::sepaXMLExport()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 8
rs 10
1
<?php
2
/*
3
 * Copyright (C) 2020  Jan Böhmer
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU Affero General Public License as published
7
 * by the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU Affero General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Affero General Public License
16
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
 */
18
19
namespace App\Controller\Admin;
20
21
use App\Admin\Field\VichyFileField;
22
use App\Admin\Filter\ConfirmedFilter;
23
use App\Admin\Filter\DepartmentTypeFilter;
24
use App\Admin\Filter\MoneyAmountFilter;
25
use App\Entity\PaymentOrder;
26
use App\Helpers\ZIPBinaryFileResponseFacade;
27
use App\Services\EmailConfirmation\ConfirmationEmailSender;
28
use App\Services\PaymentOrderMailLinkGenerator;
29
use Doctrine\ORM\EntityManagerInterface;
30
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
31
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
32
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
33
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
34
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
35
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
36
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
37
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
38
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
39
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
40
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
41
use EasyCorp\Bundle\EasyAdminBundle\Field\FormField;
42
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
43
use EasyCorp\Bundle\EasyAdminBundle\Field\MoneyField;
44
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
45
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
46
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
47
use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter;
48
use EasyCorp\Bundle\EasyAdminBundle\Filter\DateTimeFilter;
49
use EasyCorp\Bundle\EasyAdminBundle\Filter\EntityFilter;
50
use EasyCorp\Bundle\EasyAdminBundle\Filter\TextFilter;
51
use EasyCorp\Bundle\EasyAdminBundle\Registry\DashboardControllerRegistry;
52
use RuntimeException;
53
use Symfony\Component\HttpFoundation\RequestStack;
54
use Symfony\Component\HttpFoundation\Response;
55
56
class PaymentOrderCrudController extends AbstractCrudController
57
{
58
    private $mailToGenerator;
59
    private $dashboardControllerRegistry;
60
    private $confirmationEmailSender;
61
    private $request;
0 ignored issues
show
introduced by
The private property $request is not used, and could be removed.
Loading history...
62
    private $entityManager;
63
64
    public function __construct(PaymentOrderMailLinkGenerator $mailToGenerator,
65
        DashboardControllerRegistry $dashboardControllerRegistry, EntityManagerInterface $entityManager,
66
        ConfirmationEmailSender $confirmationEmailSender)
67
    {
68
        $this->mailToGenerator = $mailToGenerator;
69
        $this->dashboardControllerRegistry = $dashboardControllerRegistry;
70
        $this->confirmationEmailSender = $confirmationEmailSender;
71
72
        $this->entityManager = $entityManager;
73
    }
74
75
    public static function getEntityFqcn(): string
76
    {
77
        return PaymentOrder::class;
78
    }
79
80
    public function sepaXMLExport(array $ids, AdminContext $context): Response
81
    {
82
        //We must add an eaContext Parameter or we will run into an error...
83
        $context_id = $this->dashboardControllerRegistry->getContextIdByControllerFqcn($context->getDashboardControllerFqcn());
84
85
        return $this->redirectToRoute('payment_order_export', [
86
            'eaContext' => $context_id,
87
            'ids' => implode(',', $ids),
88
        ]);
89
    }
90
91
    public function referencesExport(array $ids, AdminContext $context): Response
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

91
    public function referencesExport(array $ids, /** @scrutinizer ignore-unused */ AdminContext $context): Response

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
92
    {
93
        $data = [];
94
        foreach ($ids as $id) {
95
            /** @var PaymentOrder $payment_order */
96
            $payment_order = $this->entityManager->find(PaymentOrder::class, $id);
97
            $path = $payment_order->getReferencesFile()->getPathname();
98
            $extension = $payment_order->getReferencesFile()->getExtension();
99
            $data[$payment_order->getIDString() . '.' . $extension] = $path;
100
        }
101
102
        return ZIPBinaryFileResponseFacade::createZIPResponseFromFiles(
103
            $data,
104
            'Belege_'  .date('Y-m-d_H-i-s').'.zip');
105
    }
106
107
    public function configureCrud(Crud $crud): Crud
108
    {
109
        return $crud
110
            ->setEntityLabelInSingular('payment_order.label')
111
            ->setEntityLabelInPlural('payment_order.labelp')
112
            ->setSearchFields(['id', 'first_name', 'last_name', 'project_name', 'funding_id', 'contact_email', 'amount', 'comment', 'bank_info.account_owner', 'bank_info.street', 'bank_info.zip_code', 'bank_info.city', 'bank_info.iban', 'bank_info.bic', 'bank_info.bank_name', 'bank_info.reference']);
113
    }
114
115
    public function configureFilters(Filters $filters): Filters
116
    {
117
        return $filters
118
            ->add(EntityFilter::new('department', 'payment_order.department.label'))
119
            ->add(DepartmentTypeFilter::new('department_type', 'payment_order.department_type.label'))
120
            ->add(MoneyAmountFilter::new('amount', 'payment_order.amount.label'))
121
            ->add(BooleanFilter::new('factually_correct', 'payment_order.factually_correct.label'))
122
            ->add(BooleanFilter::new('exported', 'payment_order.exported.label'))
123
            ->add(BooleanFilter::new('mathematically_correct', 'payment_order.mathematically_correct.label'))
124
            ->add(ConfirmedFilter::new('confirmed', 'payment_order.confirmed.label'))
125
            ->add(TextFilter::new('funding_id', 'payment_order.funding_id.label'))
126
            ->add(DateTimeFilter::new('creation_date', 'creation_date'))
127
            ->add(DateTimeFilter::new('last_modified', 'last_modified'));
128
    }
129
130
    /**
131
     * Handler for action if user click "resend" button in admin page.
132
     */
133
    public function resendConfirmationEmail(AdminContext $context): Response
134
    {
135
        $this->denyAccessUnlessGranted('ROLE_EDIT_PAYMENT_ORDERS');
136
        $payment_order = $context->getEntity()
137
            ->getInstance();
138
139
        $this->confirmationEmailSender->resendConfirmations($payment_order);
140
141
        $this->addFlash('success', 'payment_order.action.resend_confirmation.success');
142
143
        return $this->redirect($context->getReferrer() ?? '/admin');
144
    }
145
146
    /**
147
     * Handler for action if user click "check mathematically" button in admin page.
148
     */
149
    public function checkMathematicallyCorrect(AdminContext $context): Response
150
    {
151
        $this->denyAccessUnlessGranted('ROLE_PO_MATHEMATICALLY');
152
153
        /** @var PaymentOrder $payment_order */
154
        $payment_order = $context->getEntity()
155
            ->getInstance();
156
        $payment_order->setMathematicallyCorrect(true);
157
        $this->entityManager->flush();
158
        $this->addFlash('success', 'payment_order.action.mathematically_correct.success');
159
160
        return $this->redirect($context->getReferrer() ?? '/admin');
161
    }
162
163
    /**
164
     * Handler for action if user click "check factually" button in admin page.
165
     */
166
    public function checkFactuallyCorrect(AdminContext $context): Response
167
    {
168
        $this->denyAccessUnlessGranted('ROLE_PO_FACTUALLY');
169
170
        /** @var PaymentOrder $payment_order */
171
        $payment_order = $context->getEntity()
172
            ->getInstance();
173
        $payment_order->setFactuallyCorrect(true);
174
        $this->entityManager->flush();
175
        $this->addFlash('success', 'payment_order.action.factually_correct.success');
176
177
        return $this->redirect($context->getReferrer() ?? '/admin');
178
    }
179
180
    public function configureActions(Actions $actions): Actions
181
    {
182
        if ($this->isGranted('ROLE_EXPORT_PAYMENT_ORDERS')) {
183
            // Button with text and icon
184
            $actions->add(Crud::PAGE_INDEX, Action::new('sepaXMLExport', 'payment_order.action.export_xml')
185
                ->createAsBatchAction()
186
                ->linkToCrudAction('sepaXMLExport')
187
                ->addCssClass('btn btn-primary')
188
                ->setIcon('fas fa-file-export')
189
            );
190
        }
191
192
        if ($this->isGranted('ROLE_EXPORT_PAYMENT_ORDERS_REFERENCES')) {
193
            $actions->add(Crud::PAGE_INDEX,
194
                Action::new('referencesExport', 'payment.order.action.export.export_references')
195
                    ->createAsBatchAction()
196
                    ->linkToCrudAction('referencesExport')
197
                    ->addCssClass('btn btn-primary')
198
                    ->setIcon('fas fa-file-invoice')
199
            );
200
        }
201
202
203
        $actions->setPermissions([
204
            Action::INDEX => 'ROLE_SHOW_PAYMENT_ORDERS',
205
            Action::DETAIL => 'ROLE_SHOW_PAYMENT_ORDERS',
206
            Action::EDIT => 'ROLE_EDIT_PAYMENT_ORDERS',
207
            Action::DELETE => 'ROLE_EDIT_PAYMENT_ORDERS',
208
            Action::NEW => 'ROLE_EDIT_PAYMENT_ORDERS',
209
        ]);
210
211
        $emailAction = Action::new('sendEmail', 'payment_order.action.email', 'fas fa-envelope')
212
            ->linkToUrl(function (PaymentOrder $paymentOrder) {
213
                return $this->mailToGenerator->generateContactMailLink($paymentOrder);
214
            })
215
            ->setCssClass('text-dark');
216
217
        //Hide action if no contact emails are associated with department
218
        $emailAction->displayIf(function (PaymentOrder $paymentOrder) {
219
            return null !== $this->mailToGenerator->generateContactMailLink($paymentOrder);
220
        });
221
222
        $hhv_action = Action::new('contactHHV', 'payment_order.action.contact_hhv', 'fas fa-comment-dots')
223
            ->linkToUrl(function (PaymentOrder $paymentOrder) {
224
                return $this->mailToGenerator->getHHVMailLink($paymentOrder);
225
            })
226
            ->setCssClass('mr-2 text-dark');
227
228
        $resend_confirmation_action = Action::new('resendConfirmation', 'payment_order.action.resend_confirmation', 'fas fa-redo')
229
            ->linkToCrudAction('resendConfirmationEmail')
230
            ->displayIf(function (PaymentOrder $paymentOrder) {
231
                return $this->isGranted('ROLE_EDIT_PAYMENT_ORDERS') && (null === $paymentOrder->getConfirm2Timestamp() || null === $paymentOrder->getConfirm1Timestamp());
232
            })
233
            ->setCssClass('mr-2 text-dark');
234
235
        $mathematically_correct_action = Action::new('mathematicallyCorrect', 'payment_order.action.mathematically_correct', 'fas fa-check')
236
            ->linkToCrudAction('checkMathematicallyCorrect')
237
            ->displayIf(function (PaymentOrder $paymentOrder) {
238
                return $this->isGranted('ROLE_PO_MATHEMATICALLY')
239
                    && $paymentOrder->isConfirmed()
240
                    && !$paymentOrder->isMathematicallyCorrect();
241
            })
242
            ->setCssClass('mr-2 btn btn-success');
243
244
        $factually_correct_action = Action::new('factuallyCorrect', 'payment_order.action.factually_correct', 'fas fa-check')
245
            ->linkToCrudAction('checkFactuallyCorrect')
246
            ->displayIf(function (PaymentOrder $paymentOrder) {
247
                return $this->isGranted('ROLE_PO_FACTUALLY')
248
                    && $paymentOrder->isConfirmed()
249
                    && !$paymentOrder->isFactuallyCorrect()
250
                    && $paymentOrder->isMathematicallyCorrect();
251
            })
252
            ->setCssClass('mr-2 btn btn-success');
253
254
        $actions->add(Crud::PAGE_EDIT, $emailAction);
255
        $actions->add(Crud::PAGE_DETAIL, $emailAction);
256
257
        $actions->add(Crud::PAGE_EDIT, $hhv_action);
258
        $actions->add(Crud::PAGE_DETAIL, $hhv_action);
259
260
        $actions->disable(Crud::PAGE_NEW);
261
262
        $actions->add(Crud::PAGE_DETAIL, $resend_confirmation_action);
263
        $actions->add(Crud::PAGE_EDIT, $resend_confirmation_action);
264
265
        $actions->add(Crud::PAGE_DETAIL, $mathematically_correct_action);
266
        $actions->add(Crud::PAGE_DETAIL, $factually_correct_action);
267
268
        return $actions->add(Crud::PAGE_INDEX, Action::DETAIL);
269
    }
270
271
    public function configureFields(string $pageName): iterable
272
    {
273
        //Documents
274
        $documentsPanel = FormField::addPanel('payment_order.group.documents');
275
        $printed_form = VichyFileField::new('printed_form_file', 'payment_order.printed_form.label');
276
        $references = VichyFileField::new('references_file', 'payment_order.references.label');
277
278
        //Basic informations
279
        $infoPanel = FormField::addPanel('payment_order.group.info');
280
        $id = IntegerField::new('id', 'payment_order.id.label');
281
        $firstName = TextField::new('first_name', 'payment_order.first_name.label');
282
        $lastName = TextField::new('last_name', 'payment_order.last_name.label');
283
        $contact_email = EmailField::new('contact_email', 'payment_order.contact_email.label')
284
            ->setFormTypeOption('empty_data', '')
285
            ->setRequired(false);
286
        $department = AssociationField::new('department', 'payment_order.department.label')
287
            ->setFormTypeOption('attr', [
288
                'data-widget' => 'select2',
289
            ]);
290
        $departmentName = TextareaField::new('department.name', 'payment_order.department.label_short');
291
        $amount = MoneyField::new('amount', 'payment_order.amount.label')
292
            ->setCurrency('EUR')
293
            ->setStoredAsCents(true);
294
        $projectName = TextField::new('project_name', 'payment_order.project_name.label');
295
        $funding_id = TextField::new('funding_id', 'payment_order.funding_id.label')
296
            ->setRequired(false)
297
            ->setFormTypeOption('empty_data', '');
298
        //Use short name for index
299
        $funding_id_index = TextField::new('funding_id', 'payment_order.funding_id.label_short')
300
            ->setHelp('payment_order.funding_id.label');
301
        $fsr_kom = BooleanField::new('fsr_kom_resolution', 'payment_order.fsr_kom.label')
302
            ->setRequired(false);
303
        $resolution_date = DateField::new('resolution_date', 'payment_order.resolution_date.label')
304
            ->setRequired(false);
305
        $comment = TextEditorField::new('comment', 'payment_order.comment.label')
306
            ->setRequired(false)
307
            ->setFormTypeOption('empty_data', '');
308
        $lastModified = DateTimeField::new('last_modified', 'last_modified');
309
        $creationDate = DateTimeField::new('creation_date', 'creation_date');
310
311
        //Status informations
312
        $statusPanel = FormField::addPanel('payment_order.group.status');
313
        $mathematicallyCorrect = BooleanField::new('mathematically_correct', 'payment_order.mathematically_correct.label')
314
            ->setHelp('payment_order.mathematically_correct.help')
315
            //Disable fields (and show coloumns as read only tags) if user does not have proper permissions to change
316
            //factually and mathematically correct status
317
            ->setFormTypeOption('disabled', !$this->isGranted('ROLE_PO_MATHEMATICALLY'))
318
            ->renderAsSwitch($this->isGranted('ROLE_PO_MATHEMATICALLY'));
319
        $exported = BooleanField::new('exported', 'payment_order.exported.label')
320
            ->setHelp('payment_order.exported.help');
321
        $factuallyCorrect = BooleanField::new('factually_correct', 'payment_order.factually_correct.label')
322
            ->setHelp('payment_order.factually_correct.help')
323
            ->setFormTypeOption('disabled', !$this->isGranted('ROLE_PO_FACTUALLY'))
324
            ->renderAsSwitch($this->isGranted('ROLE_PO_FACTUALLY'));
325
        $confirmed_1 = DateTimeField::new('confirm1_timestamp', 'payment_order.confirmed_1.label');
326
        $confirmed_2 = DateTimeField::new('confirm2_timestamp', 'payment_order.confirmed_2.label');
327
328
        //Payee informations
329
        $payeePanel = FormField::addPanel('payment_order.group.receiver');
330
        $bankInfoAccountOwner = TextField::new('bank_info.account_owner', 'bank_info.account_owner.label');
331
        $bankInfoStreet = TextField::new('bank_info.street', 'bank_info.street.label');
332
        $bankInfoZipCode = TextField::new('bank_info.zip_code', 'bank_info.zip_code.label');
333
        $bankInfoCity = TextField::new('bank_info.city', 'bank_info.city.label');
334
335
        //Payee bank account infos
336
        $bankInfoPanel = FormField::addPanel('payment_order.group.bank_info');
337
        $bankInfoIban = TextField::new('bank_info.iban', 'bank_info.iban.label');
338
        $bankInfoBic = TextField::new('bank_info.bic', 'bank_info.bic.label')
339
            ->setRequired(false)
340
            ->setFormTypeOption('empty_data', '');
341
        $bankInfoBankName = TextField::new('bank_info.bank_name', 'bank_info.bank_name.label');
342
        $bankInfoReference = TextField::new('bank_info.reference', 'bank_info.reference.label')
343
            ->setRequired(false)
344
            ->setFormTypeOption('empty_data', '');
345
346
        if (Crud::PAGE_INDEX === $pageName) {
347
            return [$id, $projectName, $departmentName, $amount, $mathematicallyCorrect, $factuallyCorrect, $funding_id_index, $creationDate];
348
        }
349
350
        if (Crud::PAGE_DETAIL === $pageName) {
351
            return [
352
                //Documents section
353
                $documentsPanel,
354
                $printed_form,
355
                $references,
356
                //Basic informations
357
                $infoPanel,
358
                $id,
359
                $firstName,
360
                $lastName,
361
                $contact_email,
362
                $projectName,
363
                $department,
364
                $amount,
365
                $funding_id,
366
                $resolution_date,
367
                $fsr_kom,
368
                $comment,
369
                $lastModified,
370
                $creationDate,
371
                //Status infos
372
                $statusPanel,
373
                $mathematicallyCorrect,
374
                $exported,
375
                $factuallyCorrect,
376
                $confirmed_1,
377
                $confirmed_2,
378
                //Payee informations
379
                $payeePanel,
380
                $bankInfoAccountOwner,
381
                $bankInfoStreet,
382
                $bankInfoZipCode,
383
                $bankInfoCity,
384
                //Banking informations
385
                $bankInfoPanel,
386
                $bankInfoIban,
387
                $bankInfoBic,
388
                $bankInfoBankName,
389
                $bankInfoReference,
390
            ];
391
        }
392
393
        if (Crud::PAGE_EDIT === $pageName) {
394
            return [
395
                //Documents section
396
                $documentsPanel,
397
                $printed_form,
398
                $references,
399
                //Basic informations
400
                $infoPanel,
401
                $firstName,
402
                $lastName,
403
                $contact_email,
404
                $projectName,
405
                $department,
406
                $amount,
407
                $funding_id,
408
                $resolution_date,
409
                $fsr_kom,
410
                $comment,
411
                //Status infos
412
                $statusPanel,
413
                $mathematicallyCorrect,
414
                $exported,
415
                $factuallyCorrect,
416
                //Payee informations
417
                $payeePanel,
418
                $bankInfoAccountOwner,
419
                $bankInfoStreet,
420
                $bankInfoZipCode,
421
                $bankInfoCity,
422
                //Banking informations
423
                $bankInfoPanel,
424
                $bankInfoIban,
425
                $bankInfoBic,
426
                $bankInfoBankName,
427
                $bankInfoReference,
428
            ];
429
        }
430
431
        throw new RuntimeException('It should not be possible to reach this point...');
432
    }
433
434
    public function deleteEntity(EntityManagerInterface $entityManager, $entityInstance): void
435
    {
436
        /** @var PaymentOrder $entityInstance */
437
        //Forbit delete process if PaymentOrder was already exported or checked
438
        if ($entityInstance->isExported()
439
            || $entityInstance->isMathematicallyCorrect()
440
            || $entityInstance->isFactuallyCorrect()) {
441
            $this->addFlash('warning', 'payment_order.flash.can_not_delete_checked_payment_order');
442
            //Return early
443
            return;
444
        }
445
446
        parent::deleteEntity($entityManager, $entityInstance);
447
    }
448
}
449