1<?php
2/**
3 * Copyright since 2007 PrestaShop SA and Contributors
4 * PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5 *
6 * NOTICE OF LICENSE
7 *
8 * This source file is subject to the Open Software License (OSL 3.0)
9 * that is bundled with this package in the file LICENSE.md.
10 * It is also available through the world-wide-web at this URL:
11 * https://opensource.org/licenses/OSL-3.0
12 * If you did not receive a copy of the license and are unable to
13 * obtain it through the world-wide-web, please send an email
14 * to license@prestashop.com so we can send you a copy immediately.
15 *
16 * DISCLAIMER
17 *
18 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
19 * versions in the future. If you wish to customize PrestaShop for your
20 * needs please refer to https://devdocs.prestashop.com/ for more information.
21 *
22 * @author    PrestaShop SA and Contributors <contact@prestashop.com>
23 * @copyright Since 2007 PrestaShop SA and Contributors
24 * @license   https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
25 */
26
27namespace PrestaShop\PrestaShop\Core\Cart;
28
29use Cart;
30use Currency;
31use Tools;
32
33class Fees
34{
35    /**
36     * @var Cart
37     */
38    protected $cart;
39
40    /**
41     * @var AmountImmutable
42     */
43    protected $shippingFees;
44
45    /**
46     * @var AmountImmutable|null
47     */
48    protected $finalShippingFees;
49
50    /**
51     * @var AmountImmutable
52     */
53    protected $wrappingFees;
54
55    /**
56     * @var AmountImmutable
57     */
58    protected $finalWrappingFees;
59
60    /**
61     * indicates if cart was already processed.
62     *
63     * @var bool
64     */
65    protected $isProcessed = false;
66
67    /**
68     * @var int|null
69     */
70    protected $orderId;
71
72    /**
73     * @param int|null $orderId
74     */
75    public function __construct(?int $orderId = null)
76    {
77        $this->shippingFees = new AmountImmutable();
78        $this->orderId = $orderId;
79    }
80
81    /**
82     * @param Cart $cart
83     * @param CartRowCollection $cartRowCollection
84     * @param int $computePrecision
85     * @param int|null $id_carrier
86     */
87    public function processCalculation(
88        Cart $cart,
89        CartRowCollection $cartRowCollection,
90        $computePrecision,
91        $id_carrier = null
92    ) {
93        if ($id_carrier === null) {
94            $this->shippingFees = new AmountImmutable(
95                $cart->getTotalShippingCost(null, true),
96                $cart->getTotalShippingCost(null, false)
97            );
98        } else {
99            $products = $cartRowCollection->getProducts();
100            $this->shippingFees = new AmountImmutable(
101                $cart->getPackageShippingCost(
102                    (int) $id_carrier,
103                    true,
104                    null,
105                    $products,
106                    null,
107                    null !== $this->orderId
108                ),
109                $cart->getPackageShippingCost(
110                    (int) $id_carrier,
111                    false,
112                    null,
113                    $products,
114                    null,
115                    null !== $this->orderId
116                )
117            );
118        }
119        $this->finalShippingFees = clone $this->shippingFees;
120
121        // wrapping fees
122        if ($cart->gift) {
123            $this->wrappingFees = new AmountImmutable(
124                Tools::convertPrice(
125                    Tools::ps_round(
126                        $cart->getGiftWrappingPrice(true),
127                        $computePrecision
128                    ),
129                    Currency::getCurrencyInstance((int) $cart->id_currency)
130                ),
131                Tools::convertPrice(
132                    Tools::ps_round(
133                        $cart->getGiftWrappingPrice(false),
134                        $computePrecision
135                    ),
136                    Currency::getCurrencyInstance((int) $cart->id_currency)
137                )
138            );
139        } else {
140            $this->wrappingFees = new AmountImmutable();
141        }
142        $this->finalWrappingFees = clone $this->wrappingFees;
143        $this->isProcessed = true;
144    }
145
146    /**
147     * @param Cart $cart
148     *
149     * @return Fees
150     */
151    public function setCart($cart)
152    {
153        $this->cart = $cart;
154
155        return $this;
156    }
157
158    /**
159     * @return AmountImmutable
160     */
161    public function getInitialShippingFees()
162    {
163        return $this->shippingFees;
164    }
165
166    /**
167     * @return AmountImmutable|null
168     */
169    public function getFinalShippingFees()
170    {
171        return $this->finalShippingFees;
172    }
173
174    /**
175     * @return AmountImmutable
176     */
177    public function getFinalWrappingFees()
178    {
179        return $this->finalWrappingFees;
180    }
181
182    /**
183     * @return AmountImmutable
184     */
185    public function getInitialWrappingFees()
186    {
187        return $this->wrappingFees;
188    }
189
190    public function subDiscountValueShipping(AmountImmutable $amount)
191    {
192        $taxIncluded = $this->finalShippingFees->getTaxIncluded() - $amount->getTaxIncluded();
193        $taxExcluded = $this->finalShippingFees->getTaxExcluded() - $amount->getTaxExcluded();
194        if ($taxIncluded < 0) {
195            $taxIncluded = 0;
196        }
197        if ($taxExcluded < 0) {
198            $taxExcluded = 0;
199        }
200        $this->finalShippingFees = new AmountImmutable(
201            $taxIncluded,
202            $taxExcluded
203        );
204    }
205}
206