PluginProbe
PostNL for WooCommerce / 4.4.1
PostNL for WooCommerce v4.4.1
5.9.12 5.9.11 5.9.10 5.9.9 5.9.8 5.9.7 5.9.6 trunk 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 3.1.4 3.1.5 3.1.6 3.1.7 4.0.0 4.0.1 4.0.2 4.3.2 4.3.3 4.4.0 4.4.1 All 72 releases
woo-postnl / includes / frontend / class-wcpn-cart-fees.php

class-wcpn-cart-fees.php in PostNL for WooCommerce 4.4.1, at includes/frontend/class-wcpn-cart-fees.php

241 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use MyParcelNL\Sdk\src\Adapter\DeliveryOptions\AbstractDeliveryOptionsAdapter as DeliveryOptions;
4 use MyParcelNL\Sdk\src\Factory\DeliveryOptionsAdapterFactory;
5
6 if (! defined('ABSPATH')) {
7 exit;
8 } // Exit if accessed directly
9
10 if (class_exists('WCPN_Cart_Fees')) {
11 return;
12 }
13
14 /**
15 * Frontend views
16 */
17 class WCPN_Cart_Fees
18 {
19 /**
20 * @var array
21 */
22 private $fees;
23
24 /**
25 * @var DeliveryOptions
26 */
27 private $deliveryOptions;
28
29 public function __construct()
30 {
31 // Delivery options fees
32 add_action('woocommerce_cart_calculate_fees', [$this, 'get_delivery_options_fees'], 20);
33 }
34
35 /**
36 * Get delivery fee in your order overview, at the front of the website
37 *
38 * @param WC_Cart $cart
39 *
40 * @throws Exception
41 */
42 public function get_delivery_options_fees(WC_Cart $cart): void
43 {
44 if (! defined('DOING_AJAX') && is_admin()) {
45 return;
46 }
47
48 if (isset($_POST['post_data'])) {
49 // non-default post data for AJAX calls
50 parse_str($_POST['post_data'], $postData);
51 } else {
52 // checkout finalization
53 $postData = $_POST;
54 }
55
56 // Check if delivery options exist at all.
57 if (empty($postData[WCPOST_Admin::META_DELIVERY_OPTIONS])) {
58 return;
59 }
60
61 $deliveryOptionsData = $postData[WCPOST_Admin::META_DELIVERY_OPTIONS];
62 $deliveryOptionsData = json_decode(stripslashes($deliveryOptionsData), true);
63
64 /*
65 * Check if delivery options is null. Happens when when switching to a shipping method that does not allow
66 * showing delivery options, for example.
67 */
68 if (!$deliveryOptionsData) {
69 return;
70 }
71
72 $this->deliveryOptions = DeliveryOptionsAdapterFactory::create($deliveryOptionsData);
73
74 $this->addDeliveryFee();
75 $this->addShipmentOptionFees();
76
77 $this->addFees($cart);
78 }
79
80 /**
81 * @param string $name
82 *
83 * @return array
84 */
85 private function getFee(string $name): array
86 {
87 $fees = $this->getFeeMap();
88 $titles = $this->getFeeTitles();
89
90 return [$titles[$name] ?? null, $fees[$name] ?? 0];
91 }
92
93 /**
94 * Get shipping tax class
95 * adapted from WC_Tax::get_shipping_tax_rates
96 * assumes per order shipping (per item shipping not supported for postnl yet)
97 *
98 * @return string tax class
99 */
100 public function get_shipping_tax_class()
101 {
102 $shipping_tax_class = get_option('woocommerce_shipping_tax_class');
103
104 // WC3.0+ sets 'inherit' for taxes based on items, empty for 'standard'
105 if (version_compare(WOOCOMMERCE_VERSION, '3.0', '>=') && 'inherit' !== $shipping_tax_class) {
106 $shipping_tax_class = '' === $shipping_tax_class ? 'standard' : $shipping_tax_class;
107
108 return $shipping_tax_class;
109 } elseif (! empty($shipping_tax_class) && 'inherit' !== $shipping_tax_class) {
110 return $shipping_tax_class;
111 }
112
113 if ($shipping_tax_class == 'inherit') {
114 $shipping_tax_class = '';
115 }
116
117 // See if we have an explicitly set shipping tax class
118 if ($shipping_tax_class) {
119 $tax_class = 'standard' === $shipping_tax_class ? '' : $shipping_tax_class;
120 }
121
122 $location = WC_Tax::get_tax_location('');
123
124 if (sizeof($location) === 4) {
125 list($country, $state, $postcode, $city) = $location;
126
127 // This will be per order shipping - loop through the order and find the highest tax class rate
128 $cart_tax_classes = WC()->cart->get_cart_item_tax_classes();
129 // If multiple classes are found, use the first one. Don't bother with standard rate, we can get that later.
130 if (sizeof($cart_tax_classes) > 1 && ! in_array('', $cart_tax_classes)) {
131 $tax_classes = WC_Tax::get_tax_classes();
132
133 foreach ($tax_classes as $tax_class) {
134 $tax_class = sanitize_title($tax_class);
135 if (in_array($tax_class, $cart_tax_classes)) {
136 // correct $tax_class is now set
137 break;
138 }
139 }
140 // If a single tax class is found, use it
141 } elseif (sizeof($cart_tax_classes) == 1) {
142 $tax_class = array_pop($cart_tax_classes);
143 }
144
145 // no rate = standard rate
146 if (empty($tax_class)) {
147 $tax_class = 'standard';
148 }
149 }
150
151 return $tax_class;
152 }
153
154 /**
155 * Add the fees for the selected shipment options.
156 */
157 private function addShipmentOptionFees(): void
158 {
159 $shipmentOptions = ($this->deliveryOptions->getShipmentOptions())->toArray();
160
161 foreach ($shipmentOptions as $shipmentOption => $enabled) {
162 //Don't add the fee if it wasn't selected.
163 if ($enabled) {
164 $this->addFee($shipmentOption);
165 }
166 }
167 }
168
169 /**
170 * @param WC_Cart $cart
171 */
172 private function addFees(WC_Cart $cart): void
173 {
174 $tax = $this->get_shipping_tax_class();
175
176 foreach ($this->fees as $name) {
177 [$string, $fee] = $this->getFee($name);
178
179 if ($string) {
180 $cart->add_fee($string, $fee, (bool) $tax, $tax ?? "");
181 }
182 }
183 }
184
185 /**
186 * Add a fee to the fees array.
187 *
188 * @param string $fee
189 */
190 private function addFee(string $fee): void
191 {
192 $this->fees[] = $fee;
193 }
194
195 /**
196 * Map items to prices for display in the checkout.
197 *
198 * @return array
199 */
200 private function getFeeMap(): array
201 {
202 $carrier = $this->deliveryOptions->getCarrier();
203
204 $getCarrierFee = function(string $setting) use ($carrier): float {
205 return WCPOST()->setting_collection->getFloatByName("{$carrier}_{$setting}");
206 };
207
208 return [
209 "delivery_evening" => $getCarrierFee(WCPOST_Settings::SETTING_CARRIER_DELIVERY_EVENING_FEE),
210 "delivery_morning" => $getCarrierFee(WCPOST_Settings::SETTING_CARRIER_DELIVERY_MORNING_FEE),
211 "delivery_pickup" => $getCarrierFee(WCPOST_Settings::SETTING_CARRIER_PICKUP_FEE),
212 "only_recipient" => $getCarrierFee(WCPOST_Settings::SETTING_CARRIER_ONLY_RECIPIENT_FEE),
213 "signature" => $getCarrierFee(WCPOST_Settings::SETTING_CARRIER_SIGNATURE_FEE),
214 ];
215 }
216
217 /**
218 * Map items to strings for display in the checkout.
219 *
220 * @return array
221 */
222 private function getFeeTitles(): array
223 {
224 return [
225 "delivery_evening" => WCPN_Checkout::getDeliveryOptionsTitle(WCPOST_Settings::SETTING_EVENING_DELIVERY_TITLE),
226 "delivery_morning" => WCPN_Checkout::getDeliveryOptionsTitle(WCPOST_Settings::SETTING_MORNING_DELIVERY_TITLE),
227 "delivery_pickup" => WCPN_Checkout::getDeliveryOptionsTitle(WCPOST_Settings::SETTING_PICKUP_TITLE),
228 "only_recipient" => WCPN_Checkout::getDeliveryOptionsTitle(WCPOST_Settings::SETTING_ONLY_RECIPIENT_TITLE),
229 "signature" => WCPN_Checkout::getDeliveryOptionsTitle(WCPOST_Settings::SETTING_SIGNATURE_TITLE),
230 ];
231 }
232
233 /**
234 * Add a delivery fee
235 */
236 private function addDeliveryFee(): void
237 {
238 $this->addFee("delivery_{$this->deliveryOptions->getDeliveryType()}");
239 }
240 }
241