PluginProbe
PostNL for WooCommerce / 4.0.0
PostNL for WooCommerce v4.0.0
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.0.0, at includes/frontend/class-wcpn-cart-fees.php

237 lines 7.0 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 (is_admin() && ! defined('DOING_AJAX')) {
45 return;
46 }
47
48 if (isset($_POST['post_data'])) {
49 // non-default post data for AJAX calls
50 parse_str($_POST['post_data'], $post_data);
51 } else {
52 // checkout finalization
53 $post_data = $_POST;
54 }
55
56 /* check for delivery options & add fees*/
57 if (empty($post_data[WCPOST_Admin::META_DELIVERY_OPTIONS])) {
58 return;
59 }
60
61 $delivery_options_data = $post_data[WCPOST_Admin::META_DELIVERY_OPTIONS];
62 $delivery_options_data = json_decode(stripslashes($delivery_options_data), true);
63 $this->deliveryOptions = DeliveryOptionsAdapterFactory::create($delivery_options_data);
64
65 $this->addDeliveryFee();
66 $this->addShipmentOptionFees();
67
68 $this->addFees($cart);
69 }
70
71 /**
72 * @param string $name
73 *
74 * @return array
75 */
76 private function getFee(string $name): array
77 {
78 $fees = $this->getFeeMap();
79 $titles = $this->getFeeTitles();
80
81 return [$titles[$name] ?? null, $fees[$name] ?? 0];
82 }
83
84 /**
85 * Get shipping tax class
86 * adapted from WC_Tax::get_shipping_tax_rates
87 * assumes per order shipping (per item shipping not supported for postnl yet)
88 *
89 * @return string tax class
90 */
91 public function get_shipping_tax_class()
92 {
93 $shipping_tax_class = get_option('woocommerce_shipping_tax_class');
94
95 // WC3.0+ sets 'inherit' for taxes based on items, empty for 'standard'
96 if (version_compare(WOOCOMMERCE_VERSION, '3.0', '>=') && 'inherit' !== $shipping_tax_class) {
97 $shipping_tax_class = '' === $shipping_tax_class ? 'standard' : $shipping_tax_class;
98
99 return $shipping_tax_class;
100 } elseif (! empty($shipping_tax_class) && 'inherit' !== $shipping_tax_class) {
101 return $shipping_tax_class;
102 }
103
104 if ($shipping_tax_class == 'inherit') {
105 $shipping_tax_class = '';
106 }
107
108 // See if we have an explicitly set shipping tax class
109 if ($shipping_tax_class) {
110 $tax_class = 'standard' === $shipping_tax_class ? '' : $shipping_tax_class;
111 }
112
113 $location = WC_Tax::get_tax_location('');
114
115 if (sizeof($location) === 4) {
116 list($country, $state, $postcode, $city) = $location;
117
118 // This will be per order shipping - loop through the order and find the highest tax class rate
119 $cart_tax_classes = WC()->cart->get_cart_item_tax_classes();
120 // If multiple classes are found, use the first one. Don't bother with standard rate, we can get that later.
121 if (sizeof($cart_tax_classes) > 1 && ! in_array('', $cart_tax_classes)) {
122 $tax_classes = WC_Tax::get_tax_classes();
123
124 foreach ($tax_classes as $tax_class) {
125 $tax_class = sanitize_title($tax_class);
126 if (in_array($tax_class, $cart_tax_classes)) {
127 // correct $tax_class is now set
128 break;
129 }
130 }
131 // If a single tax class is found, use it
132 } elseif (sizeof($cart_tax_classes) == 1) {
133 $tax_class = array_pop($cart_tax_classes);
134 }
135
136 // no rate = standard rate
137 if (empty($tax_class)) {
138 $tax_class = 'standard';
139 }
140 }
141
142 return $tax_class;
143 }
144
145 /**
146 * Add the fees for the selected shipment options.
147 */
148 private function addShipmentOptionFees(): void
149 {
150 $shipmentOptions = ($this->deliveryOptions->getShipmentOptions())->toArray();
151
152 foreach ($shipmentOptions as $shipmentOption => $enabled) {
153 //Don't add the fee if it wasn't selected.
154 if ($enabled) {
155 $this->addFee($shipmentOption);
156 }
157
158 }
159
160 return;
161 }
162
163 /**
164 * @param WC_Cart $cart
165 */
166 private function addFees(WC_Cart $cart)
167 {
168 $tax = $this->get_shipping_tax_class();
169
170 foreach ($this->fees as $name) {
171 [$string, $fee] = $this->getFee($name);
172
173 if ($string) {
174 $cart->add_fee($string, $fee, ! ! $tax, $tax ?? "");
175 }
176 }
177 }
178
179 /**
180 * Add a fee to the fees array.
181 *
182 * @param string $fee
183 */
184 private function addFee(string $fee): void
185 {
186 $this->fees[] = $fee;
187 }
188
189 /**
190 * Map items to prices for display in the checkout.
191 *
192 * @return array
193 */
194 private function getFeeMap(): array
195 {
196 $carrier = $this->deliveryOptions->getCarrier();
197
198 $getCarrierFee = function(string $setting) use ($carrier): float {
199 return WCPOST()->setting_collection->getFloatByName("{$carrier}_{$setting}");
200 };
201
202 return [
203 "delivery_evening" => $getCarrierFee(WCPOST_Settings::SETTING_CARRIER_DELIVERY_EVENING_FEE),
204 "delivery_morning" => $getCarrierFee(WCPOST_Settings::SETTING_CARRIER_DELIVERY_MORNING_FEE),
205 "delivery_pickup" => $getCarrierFee(WCPOST_Settings::SETTING_CARRIER_PICKUP_FEE),
206 "only_recipient" => $getCarrierFee(WCPOST_Settings::SETTING_CARRIER_ONLY_RECIPIENT_FEE),
207 "signature" => $getCarrierFee(WCPOST_Settings::SETTING_CARRIER_SIGNATURE_FEE),
208 ];
209 }
210
211 /**
212 * Map items to strings for display in the checkout.
213 *
214 * @return array
215 */
216 private function getFeeTitles(): array
217 {
218 $carrierName = WCPN_Data::getCarriersHuman()[$this->deliveryOptions->getCarrier()];
219
220 return [
221 "delivery_evening" => __("Evening delivery", "woocommerce-postnl"),
222 "delivery_morning" => __("Morning delivery", "woocommerce-postnl"),
223 "delivery_pickup" => __("Pick up at", "woocommerce-postnl") . " $carrierName",
224 "only_recipient" => __("Only recipient", "woocommerce-postnl"),
225 "signature" => __("Signature on delivery", "woocommerce-postnl"),
226 ];
227 }
228
229 /**
230 * Add a delivery fee
231 */
232 private function addDeliveryFee(): void
233 {
234 $this->addFee("delivery_{$this->deliveryOptions->getDeliveryType()}");
235 }
236 }
237