BankingInfos   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Test Coverage

Coverage 14.29%

Importance

Changes 0
Metric Value
wmc 10
eloc 71
dl 0
loc 113
ccs 11
cts 77
cp 0.1429
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B qrBill() 0 70 9
A build() 0 34 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Api\Field\Query;
6
7
use Application\Model\User;
8
use Ecodev\Felix\Api\Field\FieldInterface;
9
use Ecodev\Felix\Service\Bvr;
10
use GraphQL\Type\Definition\Type;
11
use Laminas\Http\Client;
12
use Laminas\Http\Client\Exception\RuntimeException;
13
use Laminas\Http\Request;
14
use Laminas\Http\Response;
15
use Money\Money;
16
17
abstract class BankingInfos implements FieldInterface
18
{
19 1
    public static function build(): iterable
20
    {
21 1
        yield 'bankingInfos' => fn () => [
22 1
            'type' => Type::nonNull(_types()->get('BankingInfos')),
23 1
            'description' => 'Info to top-up the current user account by bank transfer',
24 1
            'args' => [
25 1
                'user' => Type::nonNull(_types()->getId(User::class)),
26 1
                'amount' => _types()->get('Money'),
27 1
            ],
28 1
            'resolve' => function ($root, array $args): array {
29
                global $container;
30
                $config = $container->get('config');
31
                $banking = $config['banking'];
32
                $iban = $banking['iban'];
33
                $paymentTo = $banking['paymentTo'];
34
                $paymentFor = $banking['paymentFor'];
35
36
                $user = $args['user']->getEntity();
37
                $amount = $args['amount'] ?? null;
38
39
                $referenceNumber = Bvr::getReferenceNumber('000000', (string) $user->getId());
40
41
                $result = [
42
                    'iban' => $iban,
43
                    'paymentTo' => $paymentTo,
44
                    'paymentFor' => $paymentFor,
45
                    'referenceNumber' => $referenceNumber,
46
                ];
47
48
                $qrCodeField = self::qrBill($user, $amount, $iban, $paymentFor, false);
49
                $qrBillField = self::qrBill($user, $amount, $iban, $paymentFor, true);
50
                $result = array_merge($result, $qrCodeField, $qrBillField);
51
52
                return $result;
53 1
            },
54 1
        ];
55
    }
56
57
    /**
58
     * Lazy resolve qrBill or qrCode fields for banking infos query.
59
     */
60
    protected static function qrBill(User $user, ?Money $amount, string $iban, string $paymentFor, bool $paymentPart): array
61
    {
62
        $resolve = function () use ($user, $amount, $iban, $paymentFor, $paymentPart): ?string {
63
            global $container;
64
65
            if (!Bvr::isQrIban($iban)) {
66
                return null;
67
            }
68
69
            $config = $container->get('config');
70
            $request = new Request();
71
            $request->setUri('https://qrbill.ecodev.ch/qr-code');
72
            $request->getHeaders()->addHeaders([
73
                'Content-Type' => 'application/json',
74
                'Accept' => $paymentPart ? 'application/json application/pdf' : 'application/json image/svg+xml',
75
                'Referer' => 'https://' . $config['hostname'],
76
            ]);
77
            $request->setMethod(Request::METHOD_POST);
78
79
            $creditorLines = explode("\n", (string) $paymentFor);
80
            $creditor = [
81
                'name' => $creditorLines[0],
82
            ];
83
            if (count($creditorLines) > 2) {
84
                $creditor['addressLine1'] = $creditorLines[1];
85
                $creditor['addressLine2'] = $creditorLines[2];
86
            } else {
87
                $creditor['addressLine2'] = $creditorLines[1];
88
            }
89
90
            $attrs = [
91
                'creditor' => $creditor,
92
                'customerIdentification' => null,
93
                'referenceNumber' => (string) $user->getId(),
94
                'iban' => $iban,
95
                'amount' => $amount,
96
            ];
97
98
            if (!empty($user->getPostcode()) && !empty($user->getLocality())) {
99
                $debtor = [
100
                    'name' => $user->getName(),
101
                    'addressLine2' => implode(' ', array_filter([$user->getPostcode(), $user->getLocality()])),
102
                ];
103
                $attrs['ultimateDebtor'] = $debtor;
104
            }
105
106
            $request->setContent(json_encode($attrs));
107
            $client = new Client();
108
109
            try {
110
                /** @var Response $response */
111
                $response = $client->dispatch($request);
112
                if (!$response->isSuccess()) {
113
                    _log()->error('Erreur de génération du QR code: ' . $response->getStatusCode() . ' ' . $response->getReasonPhrase());
114
115
                    return null;
116
                }
117
            } catch (RuntimeException $e) {
118
                _log()->error($e->getMessage(), $attrs);
119
120
                return null;
121
            }
122
123
            $content = json_decode($response->getBody());
124
125
            return $content->qrcode;
126
        };
127
128
        return [
129
            $paymentPart ? 'qrBill' : 'qrCode' => $resolve,
130
        ];
131
    }
132
}
133