Passed
Push — master ( 65eac8...1d79f0 )
by Jan
06:20 queued 01:00
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
nc 1
nop 2
dl 0
loc 8
rs 10
c 0
b 0
f 0
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\Services\EmailConfirmation\ConfirmationEmailSender;
27
use App\Services\PaymentOrderMailLinkGenerator;
28
use Doctrine\ORM\EntityManagerInterface;
29
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
30
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
31
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
32
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
33
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
34
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
35
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
36
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
37
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
38
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
39
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
40
use EasyCorp\Bundle\EasyAdminBundle\Field\FormField;
41
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
42
use EasyCorp\Bundle\EasyAdminBundle\Field\MoneyField;
43
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
44
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
45
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
46
use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter;
47
use EasyCorp\Bundle\EasyAdminBundle\Filter\DateTimeFilter;
48
use EasyCorp\Bundle\EasyAdminBundle\Filter\EntityFilter;
49
use EasyCorp\Bundle\EasyAdminBundle\Filter\TextFilter;
50
use EasyCorp\Bundle\EasyAdminBundle\Registry\DashboardControllerRegistry;
51
use RuntimeException;
52
use Symfony\Component\HttpFoundation\RequestStack;
53
use Symfony\Component\HttpFoundation\Response;
54
55
class PaymentOrderCrudController extends AbstractCrudController
56
{
57
    private $mailToGenerator;
58
    private $dashboardControllerRegistry;
59
    private $confirmationEmailSender;
60
    private $request;
0 ignored issues
show
introduced by
The private property $request is not used, and could be removed.
Loading history...
61
    private $entityManager;
62
63
    public function __construct(PaymentOrderMailLinkGenerator $mailToGenerator,
64
        DashboardControllerRegistry $dashboardControllerRegistry, EntityManagerInterface $entityManager,
65
        ConfirmationEmailSender $confirmationEmailSender)
66
    {
67
        $this->mailToGenerator = $mailToGenerator;
68
        $this->dashboardControllerRegistry = $dashboardControllerRegistry;
69
        $this->confirmationEmailSender = $confirmationEmailSender;
70
71
        $this->entityManager = $entityManager;
72
    }
73
74
    public static function getEntityFqcn(): string
75
    {
76
        return PaymentOrder::class;
77
    }
78
79
    public function sepaXMLexport(array $ids, AdminContext $context): Response
80
    {
81
        //We must add an eaContext Parameter or we will run into an error...
82
        $context_id = $this->dashboardControllerRegistry->getContextIdByControllerFqcn($context->getDashboardControllerFqcn());
83
84
        return $this->redirectToRoute('payment_order_export', [
85
            'eaContext' => $context_id,
86
            'ids' => implode(',', $ids),
87
        ]);
88
    }
89
90
    public function configureCrud(Crud $crud): Crud
91
    {
92
        return $crud
93
            ->setEntityLabelInSingular('payment_order.label')
94
            ->setEntityLabelInPlural('payment_order.labelp')
95
            ->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']);
96
    }
97
98
    public function configureFilters(Filters $filters): Filters
99
    {
100
        return $filters
101
            ->add(EntityFilter::new('department', 'payment_order.department.label'))
102
            ->add(DepartmentTypeFilter::new('department_type', 'payment_order.department_type.label'))
103
            ->add(MoneyAmountFilter::new('amount', 'payment_order.amount.label'))
104
            ->add(BooleanFilter::new('factually_correct', 'payment_order.factually_correct.label'))
105
            ->add(BooleanFilter::new('exported', 'payment_order.exported.label'))
106
            ->add(BooleanFilter::new('mathematically_correct', 'payment_order.mathematically_correct.label'))
107
            ->add(ConfirmedFilter::new('confirmed', 'payment_order.confirmed.label'))
108
            ->add(TextFilter::new('funding_id', 'payment_order.funding_id.label'))
109
            ->add(DateTimeFilter::new('creation_date', 'creation_date'))
110
            ->add(DateTimeFilter::new('last_modified', 'last_modified'));
111
    }
112
113
    /**
114
     * Handler for action if user click "resend" button in admin page.
115
     */
116
    public function resendConfirmationEmail(AdminContext $context): Response
117
    {
118
        $this->denyAccessUnlessGranted('ROLE_EDIT_PAYMENT_ORDERS');
119
        $payment_order = $context->getEntity()
120
            ->getInstance();
121
122
        $this->confirmationEmailSender->resendConfirmations($payment_order);
123
124
        $this->addFlash('success', 'payment_order.action.resend_confirmation.success');
125
126
        return $this->redirect($context->getReferrer() ?? '/admin');
127
    }
128
129
    /**
130
     * Handler for action if user click "check mathematically" button in admin page.
131
     */
132
    public function checkMathematicallyCorrect(AdminContext $context): Response
133
    {
134
        $this->denyAccessUnlessGranted('ROLE_PO_MATHEMATICALLY');
135
136
        /** @var PaymentOrder $payment_order */
137
        $payment_order = $context->getEntity()
138
            ->getInstance();
139
        $payment_order->setMathematicallyCorrect(true);
140
        $this->entityManager->flush();
141
        $this->addFlash('success', 'payment_order.action.mathematically_correct.success');
142
143
        return $this->redirect($context->getReferrer() ?? '/admin');
144
    }
145
146
    /**
147
     * Handler for action if user click "check factually" button in admin page.
148
     */
149
    public function checkFactuallyCorrect(AdminContext $context): Response
150
    {
151
        $this->denyAccessUnlessGranted('ROLE_PO_FACTUALLY');
152
153
        /** @var PaymentOrder $payment_order */
154
        $payment_order = $context->getEntity()
155
            ->getInstance();
156
        $payment_order->setFactuallyCorrect(true);
157
        $this->entityManager->flush();
158
        $this->addFlash('success', 'payment_order.action.factually_correct.success');
159
160
        return $this->redirect($context->getReferrer() ?? '/admin');
161
    }
162
163
    public function configureActions(Actions $actions): Actions
164
    {
165
166
        if($this->isGranted('ROLE_EXPORT_PAYMENT_ORDERS')) {
167
            // Button with text and icon
168
            $actions->add(Crud::PAGE_INDEX, Action::new('sepaXMLExport', 'payment_order.action.export_xml')
169
                ->createAsBatchAction()
170
                ->linkToCrudAction('export')
171
                ->addCssClass('btn btn-primary')
172
                ->setIcon('fas fa-file-export')
173
            );
174
        }
175
176
        $actions->setPermissions([
177
            Action::INDEX => 'ROLE_SHOW_PAYMENT_ORDERS',
178
            Action::DETAIL => 'ROLE_SHOW_PAYMENT_ORDERS',
179
            Action::EDIT => 'ROLE_EDIT_PAYMENT_ORDERS',
180
            Action::DELETE => 'ROLE_EDIT_PAYMENT_ORDERS',
181
            Action::NEW => 'ROLE_EDIT_PAYMENT_ORDERS',
182
        ]);
183
184
        $emailAction = Action::new('sendEmail', 'payment_order.action.email', 'fas fa-envelope')
185
            ->linkToUrl(function (PaymentOrder $paymentOrder) {
186
                return $this->mailToGenerator->generateContactMailLink($paymentOrder);
187
            })
188
            ->setCssClass('text-dark');
189
190
        //Hide action if no contact emails are associated with department
191
        $emailAction->displayIf(function (PaymentOrder $paymentOrder) {
192
            return null !== $this->mailToGenerator->generateContactMailLink($paymentOrder);
193
        });
194
195
        $hhv_action = Action::new('contactHHV', 'payment_order.action.contact_hhv', 'fas fa-comment-dots')
196
            ->linkToUrl(function (PaymentOrder $paymentOrder) {
197
                return $this->mailToGenerator->getHHVMailLink($paymentOrder);
198
            })
199
            ->setCssClass('mr-2 text-dark');
200
201
        $resend_confirmation_action = Action::new('resendConfirmation', 'payment_order.action.resend_confirmation', 'fas fa-redo')
202
            ->linkToCrudAction('resendConfirmationEmail')
203
            ->displayIf(function (PaymentOrder $paymentOrder) {
204
                return $this->isGranted('ROLE_EDIT_PAYMENT_ORDERS') && (null === $paymentOrder->getConfirm2Timestamp() || null === $paymentOrder->getConfirm1Timestamp());
205
            })
206
            ->setCssClass('mr-2 text-dark');
207
208
        $mathematically_correct_action = Action::new('mathematicallyCorrect', 'payment_order.action.mathematically_correct', 'fas fa-check')
209
            ->linkToCrudAction('checkMathematicallyCorrect')
210
            ->displayIf(function (PaymentOrder $paymentOrder) {
211
                return $this->isGranted('ROLE_PO_MATHEMATICALLY')
212
                    && $paymentOrder->isConfirmed()
213
                    && !$paymentOrder->isMathematicallyCorrect();
214
            })
215
            ->setCssClass('mr-2 btn btn-success');
216
217
        $factually_correct_action = Action::new('factuallyCorrect', 'payment_order.action.factually_correct', 'fas fa-check')
218
            ->linkToCrudAction('checkFactuallyCorrect')
219
            ->displayIf(function (PaymentOrder $paymentOrder) {
220
                return $this->isGranted('ROLE_PO_FACTUALLY')
221
                    && $paymentOrder->isConfirmed()
222
                    && !$paymentOrder->isFactuallyCorrect()
223
                    && $paymentOrder->isMathematicallyCorrect();
224
            })
225
            ->setCssClass('mr-2 btn btn-success');
226
227
        $actions->add(Crud::PAGE_EDIT, $emailAction);
228
        $actions->add(Crud::PAGE_DETAIL, $emailAction);
229
230
        $actions->add(Crud::PAGE_EDIT, $hhv_action);
231
        $actions->add(Crud::PAGE_DETAIL, $hhv_action);
232
233
        $actions->disable(Crud::PAGE_NEW);
234
235
        $actions->add(Crud::PAGE_DETAIL, $resend_confirmation_action);
236
        $actions->add(Crud::PAGE_EDIT, $resend_confirmation_action);
237
238
        $actions->add(Crud::PAGE_DETAIL, $mathematically_correct_action);
239
        $actions->add(Crud::PAGE_DETAIL, $factually_correct_action);
240
241
        return $actions->add(Crud::PAGE_INDEX, Action::DETAIL);
242
    }
243
244
    public function configureFields(string $pageName): iterable
245
    {
246
        //Documents
247
        $documentsPanel = FormField::addPanel('payment_order.group.documents');
248
        $printed_form = VichyFileField::new('printed_form_file', 'payment_order.printed_form.label');
249
        $references = VichyFileField::new('references_file', 'payment_order.references.label');
250
251
        //Basic informations
252
        $infoPanel = FormField::addPanel('payment_order.group.info');
253
        $id = IntegerField::new('id', 'payment_order.id.label');
254
        $firstName = TextField::new('first_name', 'payment_order.first_name.label');
255
        $lastName = TextField::new('last_name', 'payment_order.last_name.label');
256
        $contact_email = EmailField::new('contact_email', 'payment_order.contact_email.label')
257
            ->setFormTypeOption('empty_data', '')
258
            ->setRequired(false);
259
        $department = AssociationField::new('department', 'payment_order.department.label')
260
            ->setFormTypeOption('attr', [
261
                'data-widget' => 'select2',
262
            ]);
263
        $departmentName = TextareaField::new('department.name', 'payment_order.department.label_short');
264
        $amount = MoneyField::new('amount', 'payment_order.amount.label')
265
            ->setCurrency('EUR')
266
            ->setStoredAsCents(true);
267
        $projectName = TextField::new('project_name', 'payment_order.project_name.label');
268
        $funding_id = TextField::new('funding_id', 'payment_order.funding_id.label')
269
            ->setRequired(false)
270
            ->setFormTypeOption('empty_data', '');
271
        //Use short name for index
272
        $funding_id_index = TextField::new('funding_id', 'payment_order.funding_id.label_short')
273
            ->setHelp('payment_order.funding_id.label');
274
        $fsr_kom = BooleanField::new('fsr_kom_resolution', 'payment_order.fsr_kom.label')
275
            ->setRequired(false);
276
        $resolution_date = DateField::new('resolution_date', 'payment_order.resolution_date.label')
277
            ->setRequired(false);
278
        $comment = TextEditorField::new('comment', 'payment_order.comment.label')
279
            ->setRequired(false)
280
            ->setFormTypeOption('empty_data', '');
281
        $lastModified = DateTimeField::new('last_modified', 'last_modified');
282
        $creationDate = DateTimeField::new('creation_date', 'creation_date');
283
284
        //Status informations
285
        $statusPanel = FormField::addPanel('payment_order.group.status');
286
        $mathematicallyCorrect = BooleanField::new('mathematically_correct', 'payment_order.mathematically_correct.label')
287
            ->setHelp('payment_order.mathematically_correct.help')
288
            //Disable fields (and show coloumns as read only tags) if user does not have proper permissions to change
289
            //factually and mathematically correct status
290
            ->setFormTypeOption('disabled', !$this->isGranted('ROLE_PO_MATHEMATICALLY'))
291
            ->renderAsSwitch($this->isGranted('ROLE_PO_MATHEMATICALLY'));
292
        $exported = BooleanField::new('exported', 'payment_order.exported.label')
293
            ->setHelp('payment_order.exported.help');
294
        $factuallyCorrect = BooleanField::new('factually_correct', 'payment_order.factually_correct.label')
295
            ->setHelp('payment_order.factually_correct.help')
296
            ->setFormTypeOption('disabled', !$this->isGranted('ROLE_PO_FACTUALLY'))
297
            ->renderAsSwitch($this->isGranted('ROLE_PO_FACTUALLY'));
298
        $confirmed_1 = DateTimeField::new('confirm1_timestamp', 'payment_order.confirmed_1.label');
299
        $confirmed_2 = DateTimeField::new('confirm2_timestamp', 'payment_order.confirmed_2.label');
300
301
        //Payee informations
302
        $payeePanel = FormField::addPanel('payment_order.group.receiver');
303
        $bankInfoAccountOwner = TextField::new('bank_info.account_owner', 'bank_info.account_owner.label');
304
        $bankInfoStreet = TextField::new('bank_info.street', 'bank_info.street.label');
305
        $bankInfoZipCode = TextField::new('bank_info.zip_code', 'bank_info.zip_code.label');
306
        $bankInfoCity = TextField::new('bank_info.city', 'bank_info.city.label');
307
308
        //Payee bank account infos
309
        $bankInfoPanel = FormField::addPanel('payment_order.group.bank_info');
310
        $bankInfoIban = TextField::new('bank_info.iban', 'bank_info.iban.label');
311
        $bankInfoBic = TextField::new('bank_info.bic', 'bank_info.bic.label')
312
            ->setRequired(false)
313
            ->setFormTypeOption('empty_data', '');
314
        $bankInfoBankName = TextField::new('bank_info.bank_name', 'bank_info.bank_name.label');
315
        $bankInfoReference = TextField::new('bank_info.reference', 'bank_info.reference.label')
316
            ->setRequired(false)
317
            ->setFormTypeOption('empty_data', '');
318
319
        if (Crud::PAGE_INDEX === $pageName) {
320
            return [$id, $projectName, $departmentName, $amount, $mathematicallyCorrect, $factuallyCorrect, $funding_id_index, $creationDate];
321
        }
322
323
        if (Crud::PAGE_DETAIL === $pageName) {
324
            return [
325
                //Documents section
326
                $documentsPanel,
327
                $printed_form,
328
                $references,
329
                //Basic informations
330
                $infoPanel,
331
                $id,
332
                $firstName,
333
                $lastName,
334
                $contact_email,
335
                $projectName,
336
                $department,
337
                $amount,
338
                $funding_id,
339
                $resolution_date,
340
                $fsr_kom,
341
                $comment,
342
                $lastModified,
343
                $creationDate,
344
                //Status infos
345
                $statusPanel,
346
                $mathematicallyCorrect,
347
                $exported,
348
                $factuallyCorrect,
349
                $confirmed_1,
350
                $confirmed_2,
351
                //Payee informations
352
                $payeePanel,
353
                $bankInfoAccountOwner,
354
                $bankInfoStreet,
355
                $bankInfoZipCode,
356
                $bankInfoCity,
357
                //Banking informations
358
                $bankInfoPanel,
359
                $bankInfoIban,
360
                $bankInfoBic,
361
                $bankInfoBankName,
362
                $bankInfoReference,
363
            ];
364
        }
365
366
        if (Crud::PAGE_EDIT === $pageName) {
367
            return [
368
                //Documents section
369
                $documentsPanel,
370
                $printed_form,
371
                $references,
372
                //Basic informations
373
                $infoPanel,
374
                $firstName,
375
                $lastName,
376
                $contact_email,
377
                $projectName,
378
                $department,
379
                $amount,
380
                $funding_id,
381
                $resolution_date,
382
                $fsr_kom,
383
                $comment,
384
                //Status infos
385
                $statusPanel,
386
                $mathematicallyCorrect,
387
                $exported,
388
                $factuallyCorrect,
389
                //Payee informations
390
                $payeePanel,
391
                $bankInfoAccountOwner,
392
                $bankInfoStreet,
393
                $bankInfoZipCode,
394
                $bankInfoCity,
395
                //Banking informations
396
                $bankInfoPanel,
397
                $bankInfoIban,
398
                $bankInfoBic,
399
                $bankInfoBankName,
400
                $bankInfoReference,
401
            ];
402
        }
403
404
        throw new RuntimeException('It should not be possible to reach this point...');
405
    }
406
407
    public function deleteEntity(EntityManagerInterface $entityManager, $entityInstance): void
408
    {
409
        /** @var PaymentOrder $entityInstance */
410
        //Forbit delete process if PaymentOrder was already exported or checked
411
        if ($entityInstance->isExported()
412
            || $entityInstance->isMathematicallyCorrect()
413
            || $entityInstance->isFactuallyCorrect()) {
414
            $this->addFlash('warning', 'payment_order.flash.can_not_delete_checked_payment_order');
415
            //Return early
416
            return;
417
        }
418
419
        parent::deleteEntity($entityManager, $entityInstance);
420
    }
421
}
422