OrderPriceDistributor   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 50
dl 0
loc 131
rs 10
c 0
b 0
f 0
wmc 16

6 Methods

Rating   Name   Duplication   Size   Complexity  
A distributeOrderExpensesPrices() 0 19 4
A findPayonePayment() 0 11 3
A distributeOrderItemsPrices() 0 23 4
A calculatePriceRatio() 0 3 1
A distributeOrderPrice() 0 20 3
A calculateRoundedPrice() 0 7 1
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
        $totalsTransfer = $orderTransfer->getTotals();
33
        $priceRatio = $this->calculatePriceRatio($payonePayment->getAmount(), $totalsTransfer->getGrandTotal());
34
35
        $this->distributeOrderItemsPrices($orderTransfer, $priceRatio);
36
        $this->distributeOrderExpensesPrices($orderTransfer, $priceRatio);
37
38
        $orderTransfer->setTotals($totalsTransfer->setGrandTotal($payonePayment->getAmount()));
39
40
        return $orderTransfer;
41
    }
42
43
    /**
44
     * @param int $paymentAmount
45
     * @param int $grandTotalAmount
46
     *
47
     * @return float
48
     */
49
    protected function calculatePriceRatio(int $paymentAmount, int $grandTotalAmount): float
50
    {
51
        return $paymentAmount / $grandTotalAmount;
52
    }
53
54
    /**
55
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
56
     *
57
     * @return \Generated\Shared\Transfer\PaymentTransfer|null
58
     */
59
    protected function findPayonePayment(OrderTransfer $orderTransfer): ?PaymentTransfer
60
    {
61
        $paymentTransfers = $orderTransfer->getPayments();
62
63
        foreach ($paymentTransfers as $paymentTransfer) {
64
            if ($paymentTransfer->getPaymentProvider() === PayoneConfig::PROVIDER_NAME) {
65
                return $paymentTransfer;
66
            }
67
        }
68
69
        return null;
70
    }
71
72
    /**
73
     * @param int $unitPrice
74
     * @param float $priceRatio
75
     * @param float $roundingError
76
     *
77
     * @return int
78
     */
79
    protected function calculateRoundedPrice(int $unitPrice, float $priceRatio, float &$roundingError): int
80
    {
81
        $priceBeforeRound = ($unitPrice * $priceRatio) + $roundingError;
82
        $priceRounded = (int)round($priceBeforeRound);
83
        $roundingError = $priceBeforeRound - $priceRounded;
84
85
        return $priceRounded;
86
    }
87
88
    /**
89
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
90
     * @param float $priceRatio
91
     *
92
     * @return void
93
     */
94
    protected function distributeOrderItemsPrices(OrderTransfer $orderTransfer, float $priceRatio): void
95
    {
96
        $lastItemTransfer = null;
97
        $roundingError = 0;
98
99
        foreach ($orderTransfer->getItems() as $itemTransfer) {
100
            $unitPrice = $this->calculateRoundedPrice(
101
                $itemTransfer->getUnitGrossPrice(),
102
                $priceRatio,
103
                $roundingError
104
            );
105
106
            $itemTransfer->setSumPriceToPayAggregation($unitPrice)
107
                ->setUnitPriceToPayAggregation($unitPrice)
108
                ->setUnitGrossPrice($unitPrice);
109
            $lastItemTransfer = $itemTransfer;
110
        }
111
112
        if ($lastItemTransfer && $roundingError) {
113
            $lastItemUnitPrice = (int)round($lastItemTransfer->getUnitGrossPrice() + $roundingError);
114
            $lastItemTransfer->setSumPriceToPayAggregation($lastItemUnitPrice)
115
                ->setUnitPriceToPayAggregation($lastItemUnitPrice)
116
                ->setUnitGrossPrice($lastItemUnitPrice);
117
        }
118
    }
119
120
    /**
121
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
122
     * @param float $priceRatio
123
     *
124
     * @return void
125
     */
126
    protected function distributeOrderExpensesPrices(OrderTransfer $orderTransfer, float $priceRatio): void
127
    {
128
        $lastExpenseTransfer = null;
129
        $roundingError = 0;
130
131
        foreach ($orderTransfer->getExpenses() as $expenseTransfer) {
132
            $roundedPrice = $this->calculateRoundedPrice(
133
                $expenseTransfer->getSumGrossPrice(),
134
                $priceRatio,
135
                $roundingError
136
            );
137
138
            $expenseTransfer->setSumGrossPrice($roundedPrice);
139
            $lastExpenseTransfer = $expenseTransfer;
140
        }
141
142
        if ($lastExpenseTransfer && $roundingError) {
143
            $lastExpenseSumGrossPrice = (int)round($lastExpenseTransfer->getSumGrossPrice() + $roundingError);
144
            $lastExpenseTransfer->setSumGrossPrice($lastExpenseSumGrossPrice);
145
        }
146
    }
147
}
148