Passed
Pull Request — master (#57)
by Anton
07:51
created

OrderPriceDistributor::distributeOrderPrice()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 22
rs 9.8666
1
<?php
2
3
/**
4
 * MIT License
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerEco\Zed\Payone\Business\Distributor;
9
10
use Generated\Shared\Transfer\OrderTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\OrderTransfer 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\PaymentTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\PaymentTransfer 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 SprykerEco\Zed\Payone\PayoneConfig;
13
14
class OrderPriceDistributor implements OrderPriceDistributorInterface
15
{
16
    /**
17
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
18
     *
19
     * @return \Generated\Shared\Transfer\OrderTransfer
20
     */
21
    public function distributeOrderPrice(OrderTransfer $orderTransfer): OrderTransfer
22
    {
23
        if ($orderTransfer->getPayments()->count() <= 1) {
24
            return $orderTransfer;
25
        }
26
27
        $payonePayment = $this->findPayonePayment($orderTransfer);
28
        if (!$payonePayment) {
29
            return $orderTransfer;
30
        }
31
32
        $totals = $orderTransfer->getTotals();
33
34
        $roundingError = 0;
35
        $priceRatio = $this->calculatePriceRatio($payonePayment->getAmount(), $totals->getGrandTotal());
36
37
        $this->distributeOrderItemsPrices($orderTransfer, $priceRatio, $roundingError);
38
        $this->distributeOrderExpensesPrices($orderTransfer, $priceRatio, $roundingError);
39
40
        $orderTransfer->setTotals($totals->setGrandTotal($payonePayment->getAmount()));
41
42
        return $orderTransfer;
43
    }
44
45
    /**
46
     * @param int $paymentAmount
47
     * @param int $grandTotalAmount
48
     *
49
     * @return float
50
     */
51
    protected function calculatePriceRatio(int $paymentAmount, int $grandTotalAmount): float
52
    {
53
        return $paymentAmount / $grandTotalAmount;
54
    }
55
56
    /**
57
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
58
     *
59
     * @return \Generated\Shared\Transfer\PaymentTransfer|null
60
     */
61
    protected function findPayonePayment(OrderTransfer $orderTransfer): ?PaymentTransfer
62
    {
63
        $paymentTransfers = $orderTransfer->getPayments();
64
65
        foreach ($paymentTransfers as $paymentTransfer) {
66
            if ($paymentTransfer->getPaymentProvider() === PayoneConfig::PROVIDER_NAME) {
67
                return $paymentTransfer;
68
            }
69
        }
70
71
        return null;
72
    }
73
74
    /**
75
     * @param int $unitPrice
76
     * @param float $priceRatio
77
     * @param float $roundingError
78
     *
79
     * @return int
80
     */
81
    protected function calculateRoundedPrice(int $unitPrice, float $priceRatio, float &$roundingError): int
82
    {
83
        $priceBeforeRound = ($unitPrice * $priceRatio) + $roundingError;
84
        $priceRounded = (int)round($priceBeforeRound);
85
        $roundingError = $priceBeforeRound - $priceRounded;
86
87
        return $priceRounded;
88
    }
89
90
    /**
91
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
92
     * @param float $priceRatio
93
     * @param float $roundingError
94
     *
95
     * @return void
96
     */
97
    protected function distributeOrderItemsPrices(
98
        OrderTransfer $orderTransfer,
99
        float $priceRatio,
100
        float &$roundingError
101
    ): void {
102
        foreach ($orderTransfer->getItems() as $itemTransfer) {
103
            $priceRounded = $this->calculateRoundedPrice(
104
                $itemTransfer->getSumPriceToPayAggregation(),
105
                $priceRatio,
106
                $roundingError,
107
            );
108
109
            $itemTransfer->setSumPriceToPayAggregation($priceRounded);
110
111
            $unitPrice = $priceRounded / $itemTransfer->getQuantity();
112
            $itemTransfer->setUnitPriceToPayAggregation($unitPrice);
113
            $itemTransfer->setUnitGrossPrice($unitPrice);
114
        }
115
    }
116
117
    /**
118
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
119
     * @param float $priceRatio
120
     * @param float $roundingError
121
     *
122
     * @return void
123
     */
124
    protected function distributeOrderExpensesPrices(
125
        OrderTransfer $orderTransfer,
126
        float $priceRatio,
127
        float &$roundingError
128
    ): void {
129
        foreach ($orderTransfer->getExpenses() as $expenseTransfer) {
130
            $expenseTransfer->setSumGrossPrice(
131
                $this->calculateRoundedPrice(
132
                    $expenseTransfer->getSumGrossPrice(),
133
                    $priceRatio,
134
                    $roundingError,
135
                ),
136
            );
137
        }
138
    }
139
}
140