PluginProbe
Packeta / 2.0.9
Packeta v2.0.9
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / src / Packetery / Module / Checkout / RateCalculator.php

RateCalculator.php in Packeta 2.0.9, at src/Packetery/Module/Checkout/RateCalculator.php

207 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class RateCalculator.
4 *
5 * @package Packetery
6 */
7
8 declare( strict_types=1 );
9
10 namespace Packetery\Module\Checkout;
11
12 use Packetery\Module\Carrier;
13 use Packetery\Module\Framework\WcAdapter;
14 use Packetery\Module\Framework\WpAdapter;
15 use WC_Cart;
16 use WC_Order;
17
18 /**
19 * Class RateCalculator. Calculates cost for WooCommerce shipping rate.
20 *
21 * @package Packetery
22 */
23 class RateCalculator {
24
25 /**
26 * @var CurrencySwitcherService
27 */
28 private $currencySwitcherService;
29
30 /**
31 * @var WpAdapter
32 */
33 private $wpAdapter;
34
35 /**
36 * @var WcAdapter
37 */
38 private $wcAdapter;
39
40 public function __construct(
41 WpAdapter $wpAdapter,
42 WcAdapter $wcAdapter,
43 CurrencySwitcherService $currencySwitcherService
44 ) {
45 $this->wpAdapter = $wpAdapter;
46 $this->wcAdapter = $wcAdapter;
47 $this->currencySwitcherService = $currencySwitcherService;
48 }
49
50 /**
51 * Computes custom rate cost for carrier using cart contents.
52 *
53 * @param Carrier\Options $options Carrier options.
54 * @param float $cartPrice Price.
55 * @param float $totalCartProductValue Total cart product value.
56 * @param float|int $cartWeight Weight.
57 *
58 * @return ?float
59 */
60 public function getRateCost( Carrier\Options $options, float $cartPrice, float $totalCartProductValue, $cartWeight ): ?float {
61 return $this->getShippingRateCost(
62 $options,
63 $cartPrice,
64 $totalCartProductValue,
65 $cartWeight,
66 $this->isFreeShippingCouponApplied( $this->wcAdapter->cart() )
67 );
68 }
69
70 /**
71 * Computes custom rate cost for carrier using cart contents.
72 *
73 * @param Carrier\Options $options Carrier options.
74 * @param float $cartPrice Price.
75 * @param float $totalCartProductValue Total cart product value.
76 * @param float|int $cartWeight Weight.
77 * @param bool $isFreeShippingCouponApplied Is free shipping coupon applied?
78 *
79 * @return ?float
80 */
81 public function getShippingRateCost(
82 Carrier\Options $options,
83 float $cartPrice,
84 float $totalCartProductValue,
85 $cartWeight,
86 bool $isFreeShippingCouponApplied
87 ): ?float {
88 $cost = null;
89 $carrierOptions = $options->toArray();
90
91 if ( isset( $carrierOptions[ Carrier\OptionsPage::FORM_FIELD_WEIGHT_LIMITS ] ) && $options->getPricingType() === Carrier\Options::PRICING_TYPE_BY_WEIGHT ) {
92 foreach ( $carrierOptions[ Carrier\OptionsPage::FORM_FIELD_WEIGHT_LIMITS ] as $weightLimit ) {
93 if ( $cartWeight <= $weightLimit['weight'] ) {
94 $cost = $weightLimit['price'];
95
96 break;
97 }
98 }
99 }
100
101 if ( isset( $carrierOptions[ Carrier\OptionsPage::FORM_FIELD_PRODUCT_VALUE_LIMITS ] ) && $options->getPricingType() === Carrier\Options::PRICING_TYPE_BY_PRODUCT_VALUE ) {
102 foreach ( $carrierOptions[ Carrier\OptionsPage::FORM_FIELD_PRODUCT_VALUE_LIMITS ] as $productValueLimit ) {
103 if ( $totalCartProductValue <= $productValueLimit['value'] ) {
104 $cost = $productValueLimit['price'];
105
106 break;
107 }
108 }
109 }
110
111 if ( $cost === null ) {
112 return null;
113 }
114
115 $freeShippingLimit = null;
116 if ( $carrierOptions['free_shipping_limit'] ) {
117 $freeShippingLimit = $this->currencySwitcherService->getConvertedPrice( $carrierOptions['free_shipping_limit'] );
118 if ( $cartPrice >= $freeShippingLimit ) {
119 $cost = 0;
120 }
121 }
122
123 if ( $cost !== 0 && $isFreeShippingCouponApplied && $options->hasCouponFreeShippingActive() ) {
124 $cost = 0;
125 }
126
127 $filterParameters = [
128 'carrier_id' => $carrierOptions['id'],
129 'free_shipping_limit' => $freeShippingLimit,
130 Carrier\OptionsPage::FORM_FIELD_PRICING_TYPE => $options->getPricingType(),
131 Carrier\OptionsPage::FORM_FIELD_WEIGHT_LIMITS => $carrierOptions[ Carrier\OptionsPage::FORM_FIELD_WEIGHT_LIMITS ],
132 Carrier\OptionsPage::FORM_FIELD_PRODUCT_VALUE_LIMITS => $carrierOptions[ Carrier\OptionsPage::FORM_FIELD_PRODUCT_VALUE_LIMITS ] ?? [],
133 ];
134
135 /**
136 * Filter shipping rate cost in checkout
137 *
138 * @since 1.4.1
139 */
140 return (float) $this->wpAdapter->applyFilters( 'packeta_shipping_price', (float) $cost, $filterParameters );
141 }
142
143 /**
144 * Gets applicable COD surcharge.
145 *
146 * @param array $carrierOptions Carrier options.
147 * @param float $cartPrice Cart price.
148 *
149 * @return float
150 */
151 public function getCODSurcharge( array $carrierOptions, float $cartPrice ): float {
152 if ( isset( $carrierOptions['surcharge_limits'] ) ) {
153 foreach ( $carrierOptions['surcharge_limits'] as $weightLimit ) {
154 if ( $cartPrice <= $weightLimit['order_price'] ) {
155 return (float) $weightLimit['surcharge'];
156 }
157 }
158 }
159
160 if ( isset( $carrierOptions['default_COD_surcharge'] ) && is_numeric( $carrierOptions['default_COD_surcharge'] ) ) {
161 return (float) $carrierOptions['default_COD_surcharge'];
162 }
163
164 return 0.0;
165 }
166
167 /**
168 * @param string $name
169 * @param string $optionId
170 * @param float $taxExclusiveCost
171 * @param float[]|null $taxes Taxes. It is going to be calculated if null.
172 *
173 * @return array<string, string|float|array>
174 */
175 public function createShippingRate( string $name, string $optionId, float $taxExclusiveCost, ?array $taxes ): array {
176 return [
177 'label' => $name,
178 'id' => $optionId,
179 'cost' => $taxExclusiveCost,
180 'taxes' => $taxes ?? '',
181 'calc_tax' => 'per_order',
182 ];
183 }
184
185 /**
186 * Tells if free shipping coupon is applied.
187 *
188 * @param WC_Cart|WC_Order|null $cartOrOrder Cart or order.
189 *
190 * @return bool
191 */
192 public function isFreeShippingCouponApplied( $cartOrOrder ): bool {
193 if ( $cartOrOrder === null ) {
194 return false;
195 }
196
197 $coupons = $cartOrOrder->get_coupons();
198 foreach ( $coupons as $coupon ) {
199 if ( method_exists( $coupon, 'get_free_shipping' ) && $coupon->get_free_shipping() ) {
200 return true;
201 }
202 }
203
204 return false;
205 }
206 }
207