Issues (3641)

Business/Calculation/GiftCardCalculator.php (1 issue)

1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace Spryker\Zed\GiftCard\Business\Calculation;
9
10
use ArrayObject;
11
use Generated\Shared\Transfer\CalculableObjectTransfer;
12
use Generated\Shared\Transfer\GiftCardTransfer;
13
use Generated\Shared\Transfer\PaymentTransfer;
14
use Orm\Zed\GiftCard\Persistence\SpyGiftCard;
15
use Spryker\Zed\GiftCard\Business\ActualValueHydrator\GiftCardActualValueHydratorInterface;
16
use Spryker\Zed\GiftCard\Business\GiftCard\GiftCardDecisionRuleCheckerInterface;
17
use Spryker\Zed\GiftCard\Business\GiftCard\GiftCardReaderInterface;
18
use Spryker\Zed\GiftCard\GiftCardConfig;
19
20
class GiftCardCalculator implements GiftCardCalculatorInterface
21
{
22
    /**
23
     * @var \Spryker\Zed\GiftCard\Business\GiftCard\GiftCardReaderInterface
24
     */
25
    protected $giftCardReader;
26
27
    /**
28
     * @var \Spryker\Zed\GiftCard\Business\GiftCard\GiftCardDecisionRuleCheckerInterface
29
     */
30
    protected $giftCardDecisionRuleChecker;
31
32
    /**
33
     * @var \Spryker\Zed\GiftCard\Business\ActualValueHydrator\GiftCardActualValueHydratorInterface
34
     */
35
    protected $giftCardActualValueHydrator;
36
37
    /**
38
     * @var \Spryker\Zed\GiftCard\GiftCardConfig
39
     */
40
    protected $giftCardConfig;
41
42
    /**
43
     * @param \Spryker\Zed\GiftCard\Business\GiftCard\GiftCardReaderInterface $giftCardReader
44
     * @param \Spryker\Zed\GiftCard\Business\GiftCard\GiftCardDecisionRuleCheckerInterface $giftCardDecisionRuleChecker
45
     * @param \Spryker\Zed\GiftCard\Business\ActualValueHydrator\GiftCardActualValueHydratorInterface $giftCardActualValueHydrator
46
     * @param \Spryker\Zed\GiftCard\GiftCardConfig $giftCardConfig
47
     */
48
    public function __construct(
49
        GiftCardReaderInterface $giftCardReader,
50
        GiftCardDecisionRuleCheckerInterface $giftCardDecisionRuleChecker,
51
        GiftCardActualValueHydratorInterface $giftCardActualValueHydrator,
52
        GiftCardConfig $giftCardConfig
53
    ) {
54
        $this->giftCardReader = $giftCardReader;
55
        $this->giftCardDecisionRuleChecker = $giftCardDecisionRuleChecker;
56
        $this->giftCardActualValueHydrator = $giftCardActualValueHydrator;
57
        $this->giftCardConfig = $giftCardConfig;
58
    }
59
60
    /**
61
     * @param \Generated\Shared\Transfer\CalculableObjectTransfer $calculableObjectTransfer
62
     *
63
     * @return void
64
     */
65
    public function recalculate(CalculableObjectTransfer $calculableObjectTransfer)
66
    {
67
        $giftCards = $calculableObjectTransfer->getGiftCards();
68
69
        if ($this->hasGiftCardProducts($calculableObjectTransfer)) {
70
            $calculableObjectTransfer->setGiftCards(new ArrayObject());
71
            $this->addNotApplicableGiftCardsToCalculableObject($calculableObjectTransfer, $giftCards);
72
73
            return;
74
        }
75
76
        [$applicableGiftCards, $nonApplicableGiftCards] = $this->partitionGiftCardsByApplicability($giftCards, $calculableObjectTransfer);
77
78
        $this->addGiftCardPaymentsToQuote($calculableObjectTransfer, $applicableGiftCards);
79
        $calculableObjectTransfer->setGiftCards($applicableGiftCards);
80
        $this->addNotApplicableGiftCardsToCalculableObject($calculableObjectTransfer, $nonApplicableGiftCards);
81
    }
82
83
    /**
84
     * @param \Generated\Shared\Transfer\CalculableObjectTransfer $calculableObjectTransfer
85
     *
86
     * @return bool
87
     */
88
    protected function hasGiftCardProducts(CalculableObjectTransfer $calculableObjectTransfer)
89
    {
90
        foreach ($calculableObjectTransfer->getItems() as $itemTransfer) {
91
            $giftCardMetadata = $itemTransfer->getGiftCardMetadata();
92
93
            if (!$giftCardMetadata) {
94
                continue;
95
            }
96
97
            if ($giftCardMetadata->getIsGiftCard()) {
98
                return true;
99
            }
100
        }
101
102
        return false;
103
    }
104
105
    /**
106
     * @param \Generated\Shared\Transfer\GiftCardTransfer $giftCardTransfer
107
     *
108
     * @return \Generated\Shared\Transfer\GiftCardTransfer|null
109
     */
110
    protected function findGiftCard(GiftCardTransfer $giftCardTransfer)
111
    {
112
        $giftCardTransfer->requireCode();
113
114
        return $this->giftCardReader->findByCode($giftCardTransfer->getCode());
115
    }
116
117
    /**
118
     * @param \ArrayObject<int, \Generated\Shared\Transfer\GiftCardTransfer> $giftCardTransfers
119
     * @param \Generated\Shared\Transfer\CalculableObjectTransfer $calculableObjectTransfer
120
     *
121
     * @return array<int, \ArrayObject<int, \Generated\Shared\Transfer\GiftCardTransfer>>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<int, \ArrayObject<...sfer\GiftCardTransfer>> at position 4 could not be parsed: Expected '>' at position 4, but found '\ArrayObject'.
Loading history...
122
     */
123
    protected function partitionGiftCardsByApplicability(ArrayObject $giftCardTransfers, CalculableObjectTransfer $calculableObjectTransfer)
124
    {
125
        $applicableGiftCards = [];
126
        $nonApplicableGiftCards = [];
127
128
        foreach ($giftCardTransfers as $giftCardTransfer) {
129
            $giftCardTransfer = $this->findGiftCard($giftCardTransfer);
130
131
            if (!$giftCardTransfer) {
132
                continue;
133
            }
134
135
            if ($this->giftCardDecisionRuleChecker->isApplicable($giftCardTransfer, $calculableObjectTransfer->getOriginalQuote())) {
136
                $applicableGiftCards[] = $giftCardTransfer;
137
138
                continue;
139
            }
140
141
            $nonApplicableGiftCards[] = $giftCardTransfer;
142
        }
143
144
        /** @var array<int, \Generated\Shared\Transfer\GiftCardTransfer> $applicableGiftCards */
145
146
        /** @var array<int, \Generated\Shared\Transfer\GiftCardTransfer> $nonApplicableGiftCards */
147
        return [new ArrayObject($applicableGiftCards), new ArrayObject($nonApplicableGiftCards)];
148
    }
149
150
    /**
151
     * @param \Generated\Shared\Transfer\GiftCardTransfer $giftCardTransfer
152
     * @param \Orm\Zed\GiftCard\Persistence\SpyGiftCard $giftCardEntity
153
     *
154
     * @return \Generated\Shared\Transfer\GiftCardTransfer
155
     */
156
    protected function hydrateGiftCardTransfer(GiftCardTransfer $giftCardTransfer, SpyGiftCard $giftCardEntity)
157
    {
158
        $giftCardTransfer->fromArray($giftCardEntity->toArray(), true);
159
160
        return $giftCardTransfer;
161
    }
162
163
    /**
164
     * @param \Generated\Shared\Transfer\CalculableObjectTransfer $calculableObjectTransfer
165
     * @param \ArrayObject<int, \Generated\Shared\Transfer\GiftCardTransfer> $applicableGiftCards
166
     *
167
     * @return void
168
     */
169
    protected function addGiftCardPaymentsToQuote(CalculableObjectTransfer $calculableObjectTransfer, ArrayObject $applicableGiftCards)
170
    {
171
        foreach ($applicableGiftCards as $giftCardTransfer) {
172
            $giftCardPaymentTransfer = $this->findPayment($calculableObjectTransfer, $giftCardTransfer);
173
            $giftCardTransfer = $this->giftCardActualValueHydrator->hydrate($giftCardTransfer);
174
175
            if ($giftCardPaymentTransfer) {
176
                $giftCardPaymentTransfer->setAvailableAmount(
177
                    $giftCardTransfer->getActualValue(),
178
                );
179
180
                continue;
181
            }
182
183
            $giftCardPaymentTransfer = (new PaymentTransfer())
184
                ->setPaymentProvider($this->giftCardConfig->getPaymentProviderName())
185
                ->setPaymentSelection($this->giftCardConfig->getPaymentProviderName())
186
                ->setPaymentMethod($this->giftCardConfig->getPaymentMethodName())
187
                ->setAvailableAmount($giftCardTransfer->getActualValue())
188
                ->setIsLimitedAmount(true)
189
                ->setGiftCard($giftCardTransfer);
190
191
            $calculableObjectTransfer->addPayment($giftCardPaymentTransfer);
192
        }
193
    }
194
195
    /**
196
     * @param \Generated\Shared\Transfer\CalculableObjectTransfer $calculableObjectTransfer
197
     * @param \Generated\Shared\Transfer\GiftCardTransfer $giftCardTransfer
198
     *
199
     * @return \Generated\Shared\Transfer\PaymentTransfer|null
200
     */
201
    protected function findPayment(CalculableObjectTransfer $calculableObjectTransfer, GiftCardTransfer $giftCardTransfer)
202
    {
203
        foreach ($calculableObjectTransfer->getPayments() as $payment) {
204
            if (!$payment->getGiftCard()) {
205
                continue;
206
            }
207
208
            if ($payment->getGiftCard()->getCode() === $giftCardTransfer->getCode()) {
209
                return $payment;
210
            }
211
        }
212
213
        return null;
214
    }
215
216
    /**
217
     * @param \Generated\Shared\Transfer\CalculableObjectTransfer $calculableObjectTransfer
218
     * @param \ArrayObject<int, \Generated\Shared\Transfer\GiftCardTransfer> $nonApplicableGiftCards
219
     *
220
     * @return void
221
     */
222
    protected function addNotApplicableGiftCardsToCalculableObject(CalculableObjectTransfer $calculableObjectTransfer, ArrayObject $nonApplicableGiftCards)
223
    {
224
        foreach ($nonApplicableGiftCards as $giftCardTransfer) {
225
            $giftCardTransfer = $this->giftCardReader->findByCode($giftCardTransfer->getCode());
226
227
            if (!$giftCardTransfer) {
228
                continue;
229
            }
230
231
            $calculableObjectTransfer->addNotApplicableGiftCardCode($giftCardTransfer->getCode());
232
            $this->removeGiftCardPayment($calculableObjectTransfer, $giftCardTransfer);
233
        }
234
    }
235
236
    /**
237
     * @param \Generated\Shared\Transfer\CalculableObjectTransfer $calculableObjectTransfer
238
     * @param \Generated\Shared\Transfer\GiftCardTransfer $giftCardTransfer
239
     *
240
     * @return void
241
     */
242
    protected function removeGiftCardPayment(CalculableObjectTransfer $calculableObjectTransfer, GiftCardTransfer $giftCardTransfer)
243
    {
244
        $payments = [];
245
246
        foreach ($calculableObjectTransfer->getPayments() as $paymentTransfer) {
247
            if (!$paymentTransfer->getGiftCard()) {
248
                $payments[] = $paymentTransfer;
249
            }
250
251
            if ($paymentTransfer->getGiftCard()->getCode() !== $giftCardTransfer->getCode()) {
252
                $payments[] = $paymentTransfer;
253
            }
254
        }
255
256
        $calculableObjectTransfer->setPayments(new ArrayObject($payments));
257
    }
258
}
259