processSuccessRegistration()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 26
rs 9.7333
cc 3
nc 3
nop 1
1
<?php
2
3
/**
4
 * MIT License
5
 * For full license information, please view the LICENSE file that was distributed with this source code.
6
 */
7
8
namespace SprykerEco\Yves\Heidelpay\Processor;
9
10
use Generated\Shared\Transfer\HeidelpayDirectDebitRegistrationTransfer;
11
use Generated\Shared\Transfer\HeidelpayResponseErrorTransfer;
12
use Generated\Shared\Transfer\QuoteTransfer;
13
use SprykerEco\Client\Heidelpay\HeidelpayClientInterface;
14
use SprykerEco\Shared\Heidelpay\HeidelpayConfig;
15
use SprykerEco\Shared\Heidelpay\QuoteUniqueIdGenerator;
16
use SprykerEco\Yves\Heidelpay\Dependency\Client\HeidelpayToCalculationClientInterface;
17
use SprykerEco\Yves\Heidelpay\Dependency\Client\HeidelpayToQuoteClientInterface;
18
use Symfony\Component\HttpFoundation\Request;
19
20
class HeidelpayDirectDebitRegistrationProcessor implements HeidelpayDirectDebitRegistrationProcessorInterface
21
{
22
    protected const REQUEST_PARAM_REGISTRATION_ID = 'id_registration';
23
    protected const ERROR_CODE_REGISTRATION_NOT_FOUND = 'registration_not_found';
24
    protected const ERROR_CODE_REGISTRATION_NOT_SAVED = 'registration_not_saved';
25
    protected const ERROR_CODE_QUOTE_EXPIRED = 'quote_expired';
26
    protected const RESPONSE_PARAMETERS_FILTER_PATTERN = '/^paymentForm+|^lang+/';
27
28
    /**
29
     * @var \SprykerEco\Client\Heidelpay\HeidelpayClientInterface
30
     */
31
    protected $heidelpayClient;
32
33
    /**
34
     * @var \SprykerEco\Yves\Heidelpay\Dependency\Client\HeidelpayToCalculationClientInterface
35
     */
36
    protected $calculationClient;
37
38
    /**
39
     * @var \SprykerEco\Yves\Heidelpay\Dependency\Client\HeidelpayToQuoteClientInterface
40
     */
41
    protected $quoteClient;
42
43
    /**
44
     * @param \SprykerEco\Client\Heidelpay\HeidelpayClientInterface $heidelpayClient
45
     * @param \SprykerEco\Yves\Heidelpay\Dependency\Client\HeidelpayToCalculationClientInterface $calculationClient
46
     * @param \SprykerEco\Yves\Heidelpay\Dependency\Client\HeidelpayToQuoteClientInterface $quoteClient
47
     */
48
    public function __construct(
49
        HeidelpayClientInterface $heidelpayClient,
50
        HeidelpayToCalculationClientInterface $calculationClient,
51
        HeidelpayToQuoteClientInterface $quoteClient
52
    ) {
53
        $this->heidelpayClient = $heidelpayClient;
54
        $this->calculationClient = $calculationClient;
55
        $this->quoteClient = $quoteClient;
56
    }
57
58
    /**
59
     * @param \Symfony\Component\HttpFoundation\Request $request
60
     *
61
     * @return \Generated\Shared\Transfer\HeidelpayDirectDebitRegistrationTransfer
62
     */
63
    public function processNewRegistration(Request $request): HeidelpayDirectDebitRegistrationTransfer
64
    {
65
        $directDebitRegistrationTransfer = $this->createNewDirectDebitRegistrationTransferFromRequest($request);
66
        if ($directDebitRegistrationTransfer->getIsError()) {
67
            return $directDebitRegistrationTransfer;
68
        }
69
70
        $directDebitRegistrationTransfer = $this->heidelpayClient
71
            ->saveDirectDebitRegistration($directDebitRegistrationTransfer);
72
73
        if ($directDebitRegistrationTransfer->getIdDirectDebitRegistration() !== null) {
74
            return $directDebitRegistrationTransfer;
75
        }
76
77
        return $this->addError(
78
            static::ERROR_CODE_REGISTRATION_NOT_SAVED,
79
            $directDebitRegistrationTransfer
80
        );
81
    }
82
83
    /**
84
     * @param \Symfony\Component\HttpFoundation\Request $request
85
     *
86
     * @return \Generated\Shared\Transfer\HeidelpayDirectDebitRegistrationTransfer
87
     */
88
    public function processSuccessRegistration(Request $request): HeidelpayDirectDebitRegistrationTransfer
89
    {
90
        $quoteTransfer = $this->quoteClient->getQuote();
91
        $directDebitRegistrationTransfer = $this->retrieveExistingDirectDebitRegistrationByRequestAndQuote($request, $quoteTransfer);
92
        if ($this->isQuoteExpired($quoteTransfer)) {
93
            return $this->addError(
94
                static::ERROR_CODE_QUOTE_EXPIRED,
95
                $directDebitRegistrationTransfer
96
            );
97
        }
98
99
        $directDebitRegistrationTransfer = $this->heidelpayClient
100
            ->retrieveDirectDebitRegistration($directDebitRegistrationTransfer);
101
102
        if ($directDebitRegistrationTransfer->getIdDirectDebitRegistration() === null) {
103
            return $this->addError(
104
                static::ERROR_CODE_REGISTRATION_NOT_FOUND,
105
                $directDebitRegistrationTransfer
106
            );
107
        }
108
109
        $quoteTransfer = $this->addDirectDebitRegistrationToQuote($directDebitRegistrationTransfer, $quoteTransfer);
110
        $quoteTransfer = $this->calculationClient->recalculate($quoteTransfer);
111
        $this->quoteClient->setQuote($quoteTransfer);
112
113
        return $directDebitRegistrationTransfer;
114
    }
115
116
    /**
117
     * @param \Symfony\Component\HttpFoundation\Request $request
118
     *
119
     * @return \Generated\Shared\Transfer\HeidelpayDirectDebitRegistrationTransfer
120
     */
121
    protected function createNewDirectDebitRegistrationTransferFromRequest(Request $request): HeidelpayDirectDebitRegistrationTransfer
122
    {
123
        $apiResponseAsArray = $this->getUrldecodedRequestBody($request);
124
        $apiResponseAsArray = $this->filterResponseParameters($apiResponseAsArray);
125
126
        return $this->heidelpayClient->parseDirectDebitRegistrationResponse($apiResponseAsArray);
127
    }
128
129
    /**
130
     * @param \Symfony\Component\HttpFoundation\Request $request
131
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
132
     *
133
     * @return \Generated\Shared\Transfer\HeidelpayDirectDebitRegistrationTransfer
134
     */
135
    protected function retrieveExistingDirectDebitRegistrationByRequestAndQuote(
136
        Request $request,
137
        QuoteTransfer $quoteTransfer
138
    ): HeidelpayDirectDebitRegistrationTransfer {
139
        $directDebitRegistrationTransfer = (new HeidelpayDirectDebitRegistrationTransfer())
140
            ->setIdDirectDebitRegistration($this->getRegistrationId($request))
141
            ->setIdCustomerAddress($quoteTransfer->getShippingAddress()->getIdCustomerAddress())
142
            ->setTransactionId($this->generateTransactionId($quoteTransfer));
143
144
        return $directDebitRegistrationTransfer;
145
    }
146
147
    /**
148
     * @param string $code
149
     * @param \Generated\Shared\Transfer\HeidelpayDirectDebitRegistrationTransfer $directDebitRegistrationTransfer
150
     *
151
     * @return \Generated\Shared\Transfer\HeidelpayDirectDebitRegistrationTransfer
152
     */
153
    protected function addError(string $code, HeidelpayDirectDebitRegistrationTransfer $directDebitRegistrationTransfer): HeidelpayDirectDebitRegistrationTransfer
154
    {
155
        $directDebitRegistrationTransfer
156
            ->setIsError(true)
157
            ->setError(
158
                (new HeidelpayResponseErrorTransfer())
159
                    ->setCode($code)
160
            );
161
162
        return $directDebitRegistrationTransfer;
163
    }
164
165
    /**
166
     * @param \Symfony\Component\HttpFoundation\Request $request
167
     *
168
     * @return int
169
     */
170
    protected function getRegistrationId(Request $request): int
171
    {
172
        return (int)$request->get(static::REQUEST_PARAM_REGISTRATION_ID);
173
    }
174
175
    /**
176
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
177
     *
178
     * @return bool
179
     */
180
    protected function isQuoteExpired(QuoteTransfer $quoteTransfer): bool
181
    {
182
        return $quoteTransfer->getCustomer() === null
183
            || $quoteTransfer->getCustomer()->getEmail() === null
184
            || $quoteTransfer->getTotals() === null;
185
    }
186
187
    /**
188
     * @param \Generated\Shared\Transfer\HeidelpayDirectDebitRegistrationTransfer $directDebitRegistrationTransfer
189
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
190
     *
191
     * @return \Generated\Shared\Transfer\QuoteTransfer
192
     */
193
    protected function addDirectDebitRegistrationToQuote(
194
        HeidelpayDirectDebitRegistrationTransfer $directDebitRegistrationTransfer,
195
        QuoteTransfer $quoteTransfer
196
    ): QuoteTransfer {
197
        $paymentTransfer = $quoteTransfer->requirePayment()->getPayment();
198
        $paymentTransfer
199
            ->requireHeidelpayDirectDebit()
200
            ->getHeidelpayDirectDebit()
201
            ->setSelectedRegistration($directDebitRegistrationTransfer)
202
            ->setSelectedPaymentOption(HeidelpayConfig::DIRECT_DEBIT_PAYMENT_OPTION_NEW_REGISTRATION);
203
204
        $paymentTransfer
205
            ->setPaymentProvider(HeidelpayConfig::PROVIDER_NAME)
206
            ->setPaymentMethod(HeidelpayConfig::PAYMENT_METHOD_DIRECT_DEBIT)
207
            ->setPaymentSelection(HeidelpayConfig::PAYMENT_METHOD_DIRECT_DEBIT);
208
209
        $quoteTransfer->setPayment($paymentTransfer);
210
211
        return $quoteTransfer;
212
    }
213
214
    /**
215
     * @param \Symfony\Component\HttpFoundation\Request $request
216
     *
217
     * @return string[]
218
     */
219
    protected function getUrlDecodedRequestBody(Request $request): array
220
    {
221
        $allRequestParameters = $request->request->all();
222
223
        foreach ($allRequestParameters as $key => $value) {
224
            if (is_string($value)) {
225
                $allRequestParameters[$key] = urldecode($value);
226
            }
227
        }
228
229
        return $allRequestParameters;
230
    }
231
232
    /**
233
     * @param string[] $responseArray
234
     *
235
     * @return string[]
236
     */
237
    public function filterResponseParameters(array $responseArray): array
238
    {
239
        return array_filter($responseArray, function ($key) {
240
            return !preg_match(static::RESPONSE_PARAMETERS_FILTER_PATTERN, $key);
241
        }, ARRAY_FILTER_USE_KEY);
242
    }
243
244
    /**
245
     * @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
246
     *
247
     * @return string
248
     */
249
    protected function generateTransactionId(QuoteTransfer $quoteTransfer): string
250
    {
251
        return QuoteUniqueIdGenerator::getHashByCustomerEmailAndTotals($quoteTransfer);
252
    }
253
}
254