Completed
Pull Request — feature/eco-3135/dev (#40)
by Alexander
12:28 queued 06:18
created

processSuccessRegistration()   A

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;
1 ignored issue
show
Bug introduced by
The type Generated\Shared\Transfe...bitRegistrationTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Generated\Shared\Transfer\HeidelpayResponseErrorTransfer;
1 ignored issue
show
Bug introduced by
The type Generated\Shared\Transfe...ayResponseErrorTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Generated\Shared\Transfer\QuoteTransfer;
1 ignored issue
show
Bug introduced by
The type Generated\Shared\Transfer\QuoteTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

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