Issues (3641)

Zed/TaxApp/Business/Mapper/TaxAppMapper.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\TaxApp\Business\Mapper;
9
10
use ArrayObject;
11
use DateTime;
12
use Exception;
13
use Generated\Shared\Transfer\AddressTransfer;
14
use Generated\Shared\Transfer\CalculableObjectTransfer;
15
use Generated\Shared\Transfer\ExpenseTransfer;
16
use Generated\Shared\Transfer\ItemTransfer;
17
use Generated\Shared\Transfer\MerchantStockAddressTransfer;
18
use Generated\Shared\Transfer\OrderTransfer;
19
use Generated\Shared\Transfer\QuoteTransfer;
20
use Generated\Shared\Transfer\SaleTaxMetadataTransfer;
21
use Generated\Shared\Transfer\ShippingWarehouseTransfer;
22
use Generated\Shared\Transfer\StoreTransfer;
23
use Generated\Shared\Transfer\TaxAppAddressTransfer;
24
use Generated\Shared\Transfer\TaxAppItemTransfer;
25
use Generated\Shared\Transfer\TaxAppSaleTransfer;
26
use Generated\Shared\Transfer\TaxAppShipmentTransfer;
27
use Ramsey\Uuid\Uuid;
28
use Spryker\Zed\TaxApp\Business\Mapper\Addresses\AddressMapperInterface;
29
use Spryker\Zed\TaxApp\Business\Mapper\Prices\ItemExpensePriceRetrieverInterface;
30
31
class TaxAppMapper implements TaxAppMapperInterface
32
{
33
    /**
34
     * @uses \Spryker\Shared\Shipment\ShipmentConfig::SHIPMENT_EXPENSE_TYPE
35
     *
36
     * @var string
37
     */
38
    public const SHIPMENT_EXPENSE_TYPE = 'SHIPMENT_EXPENSE_TYPE';
39
40
    /**
41
     * @var string
42
     */
43
    protected const ORIGINAL_TRANSFER_MISSING_EXCEPTION = 'Could not get original transfer from CalculableObjectTransfer';
44
45
    /**
46
     * @var \Spryker\Zed\TaxApp\Business\Mapper\Addresses\AddressMapperInterface
47
     */
48
    protected AddressMapperInterface $addressMapper;
49
50
    /**
51
     * @var \Spryker\Zed\TaxApp\Business\Mapper\Prices\ItemExpensePriceRetrieverInterface
52
     */
53
    protected ItemExpensePriceRetrieverInterface $priceFormatter;
54
55
    /**
56
     * @param \Spryker\Zed\TaxApp\Business\Mapper\Addresses\AddressMapperInterface $addressMapper
57
     * @param \Spryker\Zed\TaxApp\Business\Mapper\Prices\ItemExpensePriceRetrieverInterface $priceFormatter
58
     */
59
    public function __construct(AddressMapperInterface $addressMapper, ItemExpensePriceRetrieverInterface $priceFormatter)
60
    {
61
        $this->addressMapper = $addressMapper;
62
        $this->priceFormatter = $priceFormatter;
63
    }
64
65
    /**
66
     * @param \Generated\Shared\Transfer\CalculableObjectTransfer $calculableObjectTransfer
67
     * @param \Generated\Shared\Transfer\TaxAppSaleTransfer $taxAppSaleTransfer
68
     *
69
     * @return \Generated\Shared\Transfer\TaxAppSaleTransfer
70
     */
71
    public function mapCalculableObjectToTaxAppSaleTransfer(
72
        CalculableObjectTransfer $calculableObjectTransfer,
73
        TaxAppSaleTransfer $taxAppSaleTransfer
74
    ): TaxAppSaleTransfer {
75
        $taxAppSaleTransfer = $taxAppSaleTransfer->fromArray($calculableObjectTransfer->toArray(), true);
76
        $saleItemTransfers = new ArrayObject();
77
        $saleShipmentTransfers = new ArrayObject();
78
79
        if (!$calculableObjectTransfer->getTaxMetadata()) {
80
            $taxAppSaleTransfer->setTaxMetadata([]);
81
        }
82
83
        $originalTransfer = $this->getOriginalTransfer($calculableObjectTransfer);
84
        $transferIdentifier = $this->getTransferIdentifier($originalTransfer);
85
86
        $documentDate = (new DateTime())->format('Y-m-d');
87
        if (method_exists($originalTransfer, 'getCreatedAt') && $originalTransfer->getCreatedAt()) {
88
            $createdAt = DateTime::createFromFormat('Y-m-d H:i:s.u', $originalTransfer->getCreatedAt());
89
            $documentDate = $createdAt ? $createdAt->format('Y-m-d') : $documentDate;
0 ignored issues
show
$createdAt is of type DateTime, thus it always evaluated to true.
Loading history...
90
        }
91
92
        $taxAppSaleTransfer
93
            ->setTransactionId($transferIdentifier)
94
            ->setDocumentNumber($transferIdentifier)
95
            ->setDocumentDate($documentDate);
96
97
        foreach ($calculableObjectTransfer->getItems() as $itemIndex => $itemTransfer) {
98
            $taxAppItemTransfer = $this->mapItemTransfersToSaleItemTransfers(
99
                $itemTransfer,
100
                $calculableObjectTransfer->getPriceModeOrFail(),
101
                $originalTransfer->getBillingAddress(),
102
                $itemIndex,
103
            );
104
105
            $saleItemTransfers->append($taxAppItemTransfer);
106
        }
107
108
        foreach ($calculableObjectTransfer->getExpenses() as $hash => $expenseTransfer) {
109
            if ($expenseTransfer->getType() !== static::SHIPMENT_EXPENSE_TYPE) {
110
                continue;
111
            }
112
113
            $taxAppShipmentTransfer = $this->mapExpenseTransferToSaleShipmentTransfer(
114
                $expenseTransfer,
115
                $calculableObjectTransfer->getPriceModeOrFail(),
116
                $originalTransfer->getBillingAddress(),
117
            );
118
119
            $taxAppShipmentTransfer->setId($hash);
120
            $saleShipmentTransfers->append($taxAppShipmentTransfer);
121
        }
122
123
        $taxAppSaleTransfer->setItems($saleItemTransfers);
124
        $taxAppSaleTransfer->setShipments($saleShipmentTransfers);
125
126
        return $taxAppSaleTransfer;
127
    }
128
129
    /**
130
     * @param \Generated\Shared\Transfer\ItemTransfer $itemTransfer
131
     * @param string $priceMode
132
     * @param \Generated\Shared\Transfer\AddressTransfer|null $billingAddressTransfer
133
     * @param int $itemIndex
134
     *
135
     * @return \Generated\Shared\Transfer\TaxAppItemTransfer
136
     */
137
    public function mapItemTransfersToSaleItemTransfers(
138
        ItemTransfer $itemTransfer,
139
        string $priceMode,
140
        ?AddressTransfer $billingAddressTransfer,
141
        int $itemIndex
142
    ): TaxAppItemTransfer {
143
        $taxAppItemTransfer = new TaxAppItemTransfer();
144
145
        $taxAppItemTransfer->setId(sprintf('%s_%s', $itemTransfer->getSku(), $itemIndex));
146
        $taxAppItemTransfer->setSku($itemTransfer->getSku());
147
        $taxAppItemTransfer->setQuantity($itemTransfer->getQuantity());
148
149
        $taxAppItemTransfer->setPriceAmount($this->priceFormatter->getUnitPriceWithoutDiscount($itemTransfer, $priceMode));
150
151
        if ($itemTransfer->getCanceledAmount()) {
152
            $taxAppItemTransfer->setRefundableAmount($this->priceFormatter->getUnitPriceWithoutDiscount($itemTransfer, $priceMode));
153
        }
154
155
        $taxAppItemTransfer->setDiscountAmount($itemTransfer->getUnitDiscountAmountFullAggregation());
156
157
        if ($itemTransfer->getShipment() && $itemTransfer->getShipment()->getShippingAddress()) {
158
            $shippingTaxAppAddressTransfer = $this->addressMapper->mapAddressTransferToTaxAppAddressTransfer($itemTransfer->getShipment()->getShippingAddress(), new TaxAppAddressTransfer());
159
            $taxAppItemTransfer->setShippingAddress($shippingTaxAppAddressTransfer);
160
        }
161
162
        if ($billingAddressTransfer) {
163
            $billingTaxAppAddressTransfer = $this->addressMapper->mapAddressTransferToTaxAppAddressTransfer($billingAddressTransfer, new TaxAppAddressTransfer());
164
            $taxAppItemTransfer->setBillingAddress($billingTaxAppAddressTransfer);
165
        }
166
167
        if ($itemTransfer->getMerchantProfileAddress()) {
168
            $sellerAddress = $this->addressMapper->mapMerchantProfileAddressTransferToTaxAppAddressTransfer($itemTransfer->getMerchantProfileAddress(), new TaxAppAddressTransfer());
169
            $taxAppItemTransfer->setSellerAddress($sellerAddress);
170
        }
171
172
        if (!$itemTransfer->getTaxMetadata()) {
173
            $taxAppItemTransfer->setTaxMetadata([]);
174
        }
175
176
        if ($itemTransfer->getMerchantStockAddresses()->count()) {
177
            foreach ($itemTransfer->getMerchantStockAddresses() as $merchantStockAddress) {
178
                $shippingWarehouseTransfer = $this->mapMerchantStockAddressTransferToShippingWarehouse(
179
                    $taxAppItemTransfer,
180
                    $merchantStockAddress,
181
                    new ShippingWarehouseTransfer(),
182
                );
183
184
                $taxAppItemTransfer->addShippingWarehouse($shippingWarehouseTransfer);
185
            }
186
        }
187
188
        return $taxAppItemTransfer;
189
    }
190
191
    /**
192
     * @param \Generated\Shared\Transfer\TaxAppItemTransfer $taxAppItemTransfer
193
     * @param \Generated\Shared\Transfer\MerchantStockAddressTransfer $merchantStockAddressTransfer
194
     * @param \Generated\Shared\Transfer\ShippingWarehouseTransfer $shippingWarehouseTransfer
195
     *
196
     * @return \Generated\Shared\Transfer\ShippingWarehouseTransfer
197
     */
198
    public function mapMerchantStockAddressTransferToShippingWarehouse(
199
        TaxAppItemTransfer $taxAppItemTransfer,
200
        MerchantStockAddressTransfer $merchantStockAddressTransfer,
201
        ShippingWarehouseTransfer $shippingWarehouseTransfer
202
    ): ShippingWarehouseTransfer {
203
        $quantityToShip = 0;
204
        if ($merchantStockAddressTransfer->getQuantityToShip()) {
205
            $quantityToShip = $merchantStockAddressTransfer->getQuantityToShip()->toInt();
206
        }
207
208
        $shippingWarehouseTransfer->setQuantity($quantityToShip);
209
210
        if ($merchantStockAddressTransfer->getStockAddress()) {
211
            $warehouseAddress = $this->addressMapper->mapStockAddressTransferToTaxAppAddressTransfer($merchantStockAddressTransfer->getStockAddress(), new TaxAppAddressTransfer());
212
            $shippingWarehouseTransfer->setWarehouseAddress($warehouseAddress);
213
        }
214
215
        return $shippingWarehouseTransfer;
216
    }
217
218
    /**
219
     * @param \Generated\Shared\Transfer\ExpenseTransfer $expenseTransfer
220
     * @param string $priceMode
221
     * @param \Generated\Shared\Transfer\AddressTransfer|null $billingAddressTransfer
222
     *
223
     * @return \Generated\Shared\Transfer\TaxAppShipmentTransfer
224
     */
225
    public function mapExpenseTransferToSaleShipmentTransfer(
226
        ExpenseTransfer $expenseTransfer,
227
        string $priceMode,
228
        ?AddressTransfer $billingAddressTransfer
229
    ): TaxAppShipmentTransfer {
230
        $taxAppShipmentTransfer = new TaxAppShipmentTransfer();
231
232
        if ($expenseTransfer->getShipment() && $expenseTransfer->getShipment()->getShippingAddress()) {
233
            $shippingTaxAppAddressTransfer = $this->addressMapper->mapAddressTransferToTaxAppAddressTransfer($expenseTransfer->getShipment()->getShippingAddress(), new TaxAppAddressTransfer());
234
235
            $taxAppShipmentTransfer->setShippingAddress($shippingTaxAppAddressTransfer);
236
        }
237
238
        if ($billingAddressTransfer) {
239
            $billingTaxAppAddressTransfer = $this->addressMapper->mapAddressTransferToTaxAppAddressTransfer($billingAddressTransfer, new TaxAppAddressTransfer());
240
            $taxAppShipmentTransfer->setBillingAddress($billingTaxAppAddressTransfer);
241
        }
242
243
        $taxAppShipmentTransfer->setPriceAmount($this->priceFormatter->getSumPriceWithoutDiscount($expenseTransfer, $priceMode));
244
245
        if ($expenseTransfer->getCanceledAmount()) {
246
            $taxAppShipmentTransfer->setRefundableAmount($this->priceFormatter->getSumPriceWithoutDiscount($expenseTransfer, $priceMode));
247
        }
248
        $taxAppShipmentTransfer->setDiscountAmount($expenseTransfer->getSumDiscountAmountAggregation());
249
250
        return $taxAppShipmentTransfer;
251
    }
252
253
    /**
254
     * @param \Generated\Shared\Transfer\CalculableObjectTransfer $calculableObjectTransfer
255
     *
256
     * @throws \Exception
257
     *
258
     * @return \Generated\Shared\Transfer\OrderTransfer|\Generated\Shared\Transfer\QuoteTransfer
259
     */
260
    protected function getOriginalTransfer(CalculableObjectTransfer $calculableObjectTransfer): OrderTransfer|QuoteTransfer
261
    {
262
        if ($calculableObjectTransfer->getOriginalQuote() !== null) {
263
            return $calculableObjectTransfer->getOriginalQuote();
264
        }
265
266
        if ($calculableObjectTransfer->getOriginalOrder() !== null) {
267
            return $calculableObjectTransfer->getOriginalOrder();
268
        }
269
270
        throw new Exception(static::ORIGINAL_TRANSFER_MISSING_EXCEPTION);
271
    }
272
273
    /**
274
     * @param \Generated\Shared\Transfer\OrderTransfer|\Generated\Shared\Transfer\QuoteTransfer $transfer
275
     *
276
     * @return string
277
     */
278
    protected function getTransferIdentifier(OrderTransfer|QuoteTransfer $transfer): string
279
    {
280
        $transferIdentifier = null;
281
282
        if (method_exists($transfer, 'getUuid')) {
283
            $transferIdentifier = $transfer->getUuid() ?? Uuid::uuid4()->toString();
284
            //@phpstan-ignore-next-line
285
            $transfer->setUuid($transferIdentifier);
286
        }
287
288
        if (method_exists($transfer, 'getOrderReference') && !$transferIdentifier) {
289
            $transferIdentifier = $transfer->getOrderReference();
290
        }
291
292
        if (!$transferIdentifier) {
293
            return Uuid::uuid4()->toString();
294
        }
295
296
        return $transferIdentifier;
297
    }
298
299
    /**
300
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
301
     * @param \Generated\Shared\Transfer\TaxAppSaleTransfer $taxAppSaleTransfer
302
     *
303
     * @return \Generated\Shared\Transfer\TaxAppSaleTransfer
304
     */
305
    public function mapOrderTransferToTaxAppSaleTransfer(OrderTransfer $orderTransfer, TaxAppSaleTransfer $taxAppSaleTransfer): TaxAppSaleTransfer
306
    {
307
        $calculableObjectTransfer = new CalculableObjectTransfer();
308
        $calculableObjectTransfer->fromArray($orderTransfer->toArray(), true);
309
        if (!$orderTransfer->getTaxMetadata()) {
310
            $calculableObjectTransfer->setTaxMetadata(new SaleTaxMetadataTransfer());
311
        }
312
313
        $calculableObjectTransfer->setStore((new StoreTransfer())->setName($orderTransfer->getStore()));
314
        $calculableObjectTransfer->setOriginalOrder($orderTransfer);
315
316
        return $this->mapCalculableObjectToTaxAppSaleTransfer($calculableObjectTransfer, $taxAppSaleTransfer);
317
    }
318
}
319