general_settings['email_tracktrace'])) {
add_action('woocommerce_email_before_order_table', array($this, 'track_trace_email'), 10, 2);
}
// Track & Trace in my account
if (isset(WooCommerce_PostNL()->general_settings['myaccount_tracktrace'])) {
add_filter('woocommerce_my_account_my_orders_actions', array($this, 'track_trace_myaccount'), 10, 2);
}
// pickup address in email
// woocommerce_email_customer_details:
// @10 = templates/email-customer-details.php
// @20 = templates/email-addresses.php
add_action('woocommerce_email_customer_details', array($this, 'email_pickup_html'), 19, 3);
// pickup address on thank you page
add_action('woocommerce_thankyou', array($this, 'thankyou_pickup_html'), 10, 1);
// WooCommerce PDF Invoices & Packing Slips Premium Templates compatibility
add_filter('wpo_wcpdf_templates_replace_postnl_delivery_date', array($this, 'wpo_wcpdf_delivery_date'), 10, 2);
add_filter('wpo_wcpdf_templates_replace_postnl_tracktrace', array($this, 'wpo_wcpdf_tracktrace'), 10, 2);
add_filter('wpo_wcpdf_templates_replace_postnl_tracktrace_link', array($this, 'wpo_wcpdf_tracktrace_link'), 10, 2);
add_filter('wpo_wcpdf_templates_replace_postnl_delivery_options', array($this, 'wpo_wcpdf_delivery_options'), 10, 2);
// Delivery options
if (isset(WooCommerce_PostNL()->checkout_settings['postnl_checkout'])) {
// Change the position of the checkout
if (isset(WooCommerce_PostNL()->checkout_settings['checkout_position'])) {
$checkout_place = WooCommerce_PostNL()->checkout_settings['checkout_position'];
} else {
$checkout_place = 'woocommerce_after_checkout_billing_form';
}
add_action('wp_enqueue_scripts', array($this, 'inject_delivery_options_variables'), 9999);
add_action(apply_filters('wc_postnl_delivery_options_location', $checkout_place), array($this, 'output_delivery_options'), 10);
}
// Save delivery options data
add_action('woocommerce_checkout_update_order_meta', array($this, 'save_delivery_options'), 10, 2);
// Delivery options fees
add_action('woocommerce_cart_calculate_fees', array($this, 'get_delivery_options_fees'));
// Output most expensive shipping class in frontend data
add_action('woocommerce_checkout_after_order_review', array($this, 'output_shipping_data'));
add_action('woocommerce_update_order_review_fragments', array($this, 'order_review_fragments'));
$this->frontend_settings = new WooCommerce_PostNL_Frontend_Settings();
}
public function track_trace_email($order, $sent_to_admin) {
if ($sent_to_admin) return;
if (WCX_Order::get_status($order) != 'completed') return;
$order_id = WCX_Order::get_id($order);
$tracktrace_links = WooCommerce_PostNL()->admin->get_tracktrace_links($order_id);
if ( ! empty($tracktrace_links)) {
$email_text = __(
'You can track your order with the following PostNL Track & Trace code:',
'woocommerce-postnl'
);
$email_text = apply_filters('wcpostnl_email_text', $email_text, $order);
?>
admin->show_order_delivery_options($order);
}
public function thankyou_pickup_html($order_id) {
$order = wc_get_order($order_id);
WooCommerce_PostNL()->admin->show_order_delivery_options($order);
}
public function track_trace_myaccount($actions, $order) {
$order_id = WCX_Order::get_id($order);
if ($consignments = WooCommerce_PostNL()->admin->get_tracktrace_shipments($order_id)) {
foreach ( $consignments as $key => $consignment ) {
$actions['postnl_tracktrace_' . $consignment['tracktrace']] = array(
'url' => $consignment['tracktrace_url'],
'name' => apply_filters(
'wcpostnl_myaccount_tracktrace_button',
__('Track & Trace', 'wooocommerce-postnl')
)
);
}
}
return $actions;
}
public function wpo_wcpdf_delivery_options($replacement, $order) {
ob_start();
WooCommerce_PostNL()->admin->show_order_delivery_options($order);
return ob_get_clean();
}
public function wpo_wcpdf_delivery_date($replacement, $order) {
if ($delivery_date = WooCommerce_PostNL()->export->get_delivery_date($order)) {
$formatted_date = date_i18n(
apply_filters('wcpostnl_delivery_date_format', wc_date_format()),
strtotime($delivery_date)
);
return $formatted_date;
}
return $replacement;
}
public function wpo_wcpdf_tracktrace($replacement, $order) {
if ($shipments = WooCommerce_PostNL()->admin->get_tracktrace_shipments(WCX_Order::get_id($order))) {
$tracktrace = array();
foreach ( $shipments as $shipment ) {
if ( ! empty($shipment['tracktrace'])) {
$tracktrace[] = $shipment['tracktrace'];
}
}
$replacement = implode(', ', $tracktrace);
}
return $replacement;
}
public function wpo_wcpdf_tracktrace_link($replacement, $order) {
$tracktrace_links = WooCommerce_PostNL()->admin->get_tracktrace_links(WCX_Order::get_id($order));
if ( ! empty($tracktrace_links)) {
$replacement = implode(', ', $tracktrace_links);
}
return $replacement;
}
/**
* Output some stuff.
* Return to hide delivery options
*/
public function output_delivery_options() {
do_action('woocommerce_postnl_before_delivery_options');
require_once(WooCommerce_PostNL()->plugin_path() . '/templates/wcmp-delivery-options-template.php');
do_action('woocommerce_postnl_after_delivery_options');
}
/**
* Output inline script with the variables needed
*/
public function inject_delivery_options_variables() {
wp_localize_script(
'wc-postnl',
'wcmp_delivery_options',
array(
'shipping_methods' => $this->get_delivery_options_shipping_methods(),
'always_display' => $this->postnl_delivery_options_always_display()
)
);
wp_localize_script(
'wc-postnl',
'wcmp_config',
$this->get_checkout_config()
);
}
public function output_shipping_data() {
$shipping_data = $this->get_shipping_data();
printf('%s
', $shipping_data);
}
public function get_shipping_data() {
if ($shipping_class = $this->get_cart_shipping_class()) {
$shipping_data = sprintf(
'',
$shipping_class
);
return $shipping_data;
}
return false;
}
/**
* Save delivery options to order when used
*
* @param int $order_id
* @param array $posted
*
* @return void
*/
public function save_delivery_options($order_id, $posted) {
$order = WCX::get_order($order_id);
if ($_POST['postnl_highest_shipping_class'] != null) {
WCX_Order::update_meta_data(
$order,
'_postnl_highest_shipping_class',
$_POST['postnl_highest_shipping_class']
);
} else {
if (isset($_POST['shipping_method'])) {
WCX_Order::update_meta_data(
$order,
'_postnl_highest_shipping_class',
$_POST['shipping_method'][0]
);
}
}
if (isset($_POST['postnl-signature-selector'])) {
WCX_Order::update_meta_data($order, '_postnl_signature', self::RADIO_CHECKED);
}
if (isset($_POST['method-postnl-only-recipient-selector'])) {
WCX_Order::update_meta_data($order, '_postnl_only_recipient', self::RADIO_CHECKED);
}
if ( ! empty($_POST['post-post-nl-data'])) {
$delivery_options = json_decode(stripslashes($_POST['post-post-nl-data']), true);
WCX_Order::update_meta_data($order, '_postnl_delivery_options', $delivery_options);
}
}
/**
* Get delivery fee in your order overview, at the front of the website
*
* @param $cart
*/
public function get_delivery_options_fees() {
if ( ! $_POST || (is_admin() && ! is_ajax())) {
return;
}
if (isset($_POST['post_data'])) {
// non-default post data for AJAX calls
parse_str($_POST['post_data'], $post_data);
} else {
// checkout finalization
$post_data = $_POST;
}
/* check for delivery options & add fees*/
if ( ! empty($post_data['post-post-nl-data'])) {
$delivery_options = json_decode(stripslashes($post_data['post-post-nl-data']), true);
/* Fees for delivery time options*/
if (isset($delivery_options['time'])) {
$time = array_shift($delivery_options['time']); // take first element in time array
if (isset($time['price_comment'])) {
switch($time['price_comment']) {
case 'morning':
if ( ! empty(WooCommerce_PostNL()->checkout_settings['morning_fee'])) {
$fee = WooCommerce_PostNL()->checkout_settings['morning_fee'];
$fee_name = __('Morning delivery', 'woocommerce-postnl');
$this->add_fee_signature($delivery_options, 'Signature on delivery');
}
break;
case 'standard':
$this->add_fee_signature($delivery_options, 'Signature on delivery');
$this->add_fee_only_recipient($delivery_options, 'Home address only');
break;
case 'avond':
if ( ! empty(WooCommerce_PostNL()->checkout_settings['evening_fee'])) {
$fee = WooCommerce_PostNL()->checkout_settings['evening_fee'];
$fee_name = __('Evening delivery', 'woocommerce-postnl');
$this->add_fee_signature($delivery_options, 'Signature on delivery');
}
break;
}
if ( ! empty($fee)) {
$this->add_fee($fee_name, $fee);
}
}
}
/* Fees for pickup & pickup express */
if (isset($delivery_options['price_comment'])) {
switch($delivery_options['price_comment']) {
case 'retail':
if ( ! empty(WooCommerce_PostNL()->checkout_settings['pickup_fee'])) {
$fee = WooCommerce_PostNL()->checkout_settings['pickup_fee'];
$fee_name = __('PostNL pickup', 'woocommerce-postnl');
}
break;
case 'retailexpress':
if ( ! empty(WooCommerce_PostNL()->checkout_settings['pickup_express_fee'])) {
$fee = WooCommerce_PostNL()->checkout_settings['pickup_express_fee'];
$fee_name = __('PostNL Pickup Express', 'woocommerce-postnl');
}
break;
}
if ( ! empty($fee)) {
$this->add_fee($fee_name, $fee);
}
}
}
}
/**
* Get shipping tax class
* adapted from WC_Tax::get_shipping_tax_rates
* assumes per order shipping (per item shipping not supported for postnl yet)
* @return string tax class
*/
public function get_shipping_tax_class() {
$shipping_tax_class = get_option('woocommerce_shipping_tax_class');
// WC3.0+ sets 'inherit' for taxes based on items, empty for 'standard'
if (version_compare(WOOCOMMERCE_VERSION, '3.0', '>=') && 'inherit' !== $shipping_tax_class) {
$shipping_tax_class = '' === $shipping_tax_class ? 'standard' : $shipping_tax_class;
return $shipping_tax_class;
} else if ( ! empty($shipping_tax_class) && 'inherit' !== $shipping_tax_class) {
return $shipping_tax_class;
}
if ($shipping_tax_class == 'inherit') {
$shipping_tax_class = '';
}
// See if we have an explicitly set shipping tax class
if ($shipping_tax_class) {
$tax_class = 'standard' === $shipping_tax_class ? '' : $shipping_tax_class;
}
$location = WC_Tax::get_tax_location('');
if (sizeof($location) === 4) {
list($country, $state, $postcode, $city) = $location;
// This will be per order shipping - loop through the order and find the highest tax class rate
$cart_tax_classes = WC()->cart->get_cart_item_tax_classes();
// If multiple classes are found, use the first one. Don't bother with standard rate, we can get that later.
if (sizeof($cart_tax_classes) > 1 && ! in_array('', $cart_tax_classes)) {
$tax_classes = WC_Tax::get_tax_classes();
foreach ( $tax_classes as $tax_class ) {
$tax_class = sanitize_title($tax_class);
if (in_array($tax_class, $cart_tax_classes)) {
// correct $tax_class is now set
break;
}
}
// If a single tax class is found, use it
} else {
if (sizeof($cart_tax_classes) == 1) {
$tax_class = array_pop($cart_tax_classes);
}
}
// no rate = standard rate
if (empty($tax_class)) {
$tax_class = 'standard';
}
}
return $tax_class;
}
/**
* Get the most expensive shipping class in the cart
* Requires WC2.4+
* Only supports 1 package, takes the first
* @return [type] [description]
*/
public function get_cart_shipping_class() {
if (version_compare(WOOCOMMERCE_VERSION, '2.4', '<')) {
return false;
}
$chosen_method = isset(WC()->session->chosen_shipping_methods[0]) ? WC()->session->chosen_shipping_methods[0] : '';
// get package
$packages = WC()->shipping->get_packages();
$package = current($packages);
$shipping_method = WooCommerce_PostNL()->export->get_shipping_method($chosen_method);
if (empty($shipping_method)) {
return false;
}
// get shipping classes from package
$found_shipping_classes = $shipping_method->find_shipping_classes($package);
// return print_r( $found_shipping_classes, true );
$highest_class = WooCommerce_PostNL()->export->get_shipping_class(
$shipping_method,
$found_shipping_classes
);
return $highest_class;
}
public function order_review_fragments($fragments) {
$postnl_shipping_data = $this->get_shipping_data();
$fragments['.postnl-shipping-data'] = $postnl_shipping_data;
return $fragments;
}
// converts price string to float value, assuming no thousand-separators used
public function normalize_price($price) {
$price = str_replace(',', '.', $price);
$price = floatval($price);
return $price;
}
private function get_checkout_config() {
$PostNLConfig = [
"address" => [
"cc" => '',
"postalCode" => '',
"number" => '',
"city" => ''
],
"txtWeekDays" => [
'Zondag',
'Maandag',
'Dinsdag',
'Woensdag',
'Donderdag',
'Vrijdag',
'Zaterdag'
],
"config" => [
"apiBaseUrl" => WooCommerce_PostNL_Frontend_Settings::BASE_URL,
"carrier" => "1",
"priceMorningDelivery" => $this->frontend_settings->get_price('morning'),
"priceNormalDelivery" => "",
"priceEveningDelivery" => $this->frontend_settings->get_price('evening'),
"priceSignature" => $this->frontend_settings->get_price('signature'),
"priceOnlyRecipient" => $this->frontend_settings->get_price('only_recipient'),
"pricePickup" => $this->frontend_settings->get_price('pickup'),
"pricePickupExpress" => $this->frontend_settings->get_price('pickup_express'),
"allowMondayDelivery" => $this->frontend_settings->is_enabled('saturday_cutoff'),
"allowMorningDelivery" => isset(WooCommerce_PostNL()->export_defaults['age_check']) ? 0 : $this->frontend_settings->is_enabled('morning'),
"allowEveningDelivery" => isset(WooCommerce_PostNL()->export_defaults['age_check']) ? 0 : $this->frontend_settings->is_enabled('evening'),
"allowSignature" => isset(WooCommerce_PostNL()->export_defaults['age_check']) ? 0 : $this->frontend_settings->is_enabled('signature'),
"allowOnlyRecipient" => isset(WooCommerce_PostNL()->export_defaults['age_check']) ? 0 : $this->frontend_settings->is_enabled('only_recipient'),
"allowPickupPoints" => $this->frontend_settings->is_enabled('pickup'),
"allowPickupExpress" => $this->frontend_settings->is_enabled('pickup_express'),
"dropOffDays" => $this->frontend_settings->get_dropoff_days(),
"saturdayCutoffTime" => $this->frontend_settings->get_saturday_cutoff_time(),
"cutoffTime" => $this->frontend_settings->get_cutoff_time(),
"deliverydaysWindow" => $this->frontend_settings->get_deliverydays_window(),
"dropoffDelay" => $this->frontend_settings->get_dropoff_delay(),
],
"textToTranslate" =>[
"deliveryTitle"=> __($this->frontend_settings->get_title('at_home_delivery'), 'woocommerce-postnl'),
"deliveryMorningTitle" => __($this->frontend_settings->get_title('morning'),'woocommerce-postnl'),
"deliveryStandardTitle" => __($this->frontend_settings->get_title('standard'),'woocommerce-postnl'),
"deliveryEveningTitle" => __($this->frontend_settings->get_title('evening'),'woocommerce-postnl'),
"signatureTitle"=> __($this->frontend_settings->get_title('signature'), 'woocommerce-postnl'),
"onlyRecipientTitle"=> __($this->frontend_settings->get_title('only_recipient'), 'woocommerce-postnl'),
"saturdayDeliveryTitle"=> __('saturday_delivery_title', 'woocommerce-postnl'),
"pickupTitle"=> __($this->frontend_settings->get_title('pickup'), 'woocommerce-postnl'),
"headerDeliveryOptions" => __($this->frontend_settings->get_title('header_delivery_options'), 'woocommerce-postnl'),
"BEdeliveryTitle" => __($this->frontend_settings->get_title('belgium_at_home_delivery'), 'woocommerce-postnl'),
"BEdeliveryStandardTitle" => __($this->frontend_settings->get_title('belgium_standard'), 'woocommerce-postnl'),
"addressNotFound" => __('Address details are not entered', 'woocommerce-postnl'),
"pickUpFrom" =>__('Pick up from', 'woocommerce-postnl'),
"openingHours" =>__('Opening hours', 'woocommerce-postnl'),
"closed" =>__('Closed', 'woocommerce-postnl'),
"postcode" =>__('Postcode', 'woocommerce-postnl'),
"houseNumber" =>__('House number', 'woocommerce-postnl'),
"city"=>__('City', 'woocommerce-postnl'),
"retry" =>__('Retry', 'woocommerce-postnl'),
"wrongHouseNumberPostcode" =>__('House number/postcode combination unknown', 'woocommerce-postnl'),
"quickDelivery"=>__('Deliver as quickly as possible', 'woocommerce-postnl'),
'sunday'=> __('Sunday', 'woocommerce-postnl'),
'monday'=> __('Monday', 'woocommerce-postnl'),
'tuesday'=> __('Tuesday', 'woocommerce-postnl'),
'wednesday'=> __('Wednesday', 'woocommerce-postnl'),
'thursday'=> __('Thursday', 'woocommerce-postnl'),
'friday'=> __('Friday', 'woocommerce-postnl'),
'saturday'=> __('Saturday', 'woocommerce-postnl')
]
];
return json_encode($PostNLConfig);
// Use cutoff_time and saturday_cutoff_time on saturdays
}
private function add_fee($fee_name, $fee) {
$fee = $this->normalize_price($fee);
// get shipping tax data
$shipping_tax_class = $this->get_shipping_tax_class();
if ($shipping_tax_class) {
if ($shipping_tax_class == 'standard') {
$shipping_tax_class = '';
}
WC()->cart->add_fee($fee_name, $fee, true, $shipping_tax_class);
} else {
WC()->cart->add_fee($fee_name, $fee);
}
}
/**
* Check witch delivery option is selected
*
* @param $post_data
* @param $post_data_value
* @param $delivery_type
* @param $backend_setting
* @param $delivery_title
*
* @return bool
*/
private function add_fee_from_setting($post_data, $post_data_value, $delivery_type, $backend_setting, $delivery_title) {
// Fee for "delivery" option
if (isset($post_data[$post_data_value]) && $post_data[$post_data_value] == $delivery_type) {
if ( ! empty(WooCommerce_PostNL()->checkout_settings[$backend_setting])) {
$fee = WooCommerce_PostNL()->checkout_settings[$backend_setting];
$fee_name = __($delivery_title, 'woocommerce-postnl');
$this->add_fee($fee_name, $fee);
return true;
}
}
return false;
}
private function add_fee_signature($delivery_options, $delivery_title) {
if ($delivery_options['signature'] !== 1) {
return;
}
$fee = WooCommerce_PostNL()->checkout_settings['signature_fee'];
if ( ! empty($fee)) {
$fee_name = __($delivery_title, 'woocommerce-postnl');
$this->add_fee($fee_name, $fee);
}
}
private function add_fee_only_recipient($delivery_options, $delivery_title) {
if ($delivery_options['only_recipient'] !== 1) {
return;
}
$fee = WooCommerce_PostNL()->checkout_settings['only_recipient_fee'];
if ( ! empty($fee)) {
$fee_name = __($delivery_title, 'woocommerce-postnl');
$this->add_fee($fee_name, $fee);
}
}
/**
* @return string
*/
private function get_delivery_options_shipping_methods() {
if (isset(
WooCommerce_PostNL()->export_defaults['shipping_methods_package_types']
)
&& isset(WooCommerce_PostNL()->export_defaults['shipping_methods_package_types'][WooCommerce_PostNL_Export::PACKAGE])) {
// Shipping methods associated with parcels = enable delivery options
$delivery_options_shipping_methods = WooCommerce_PostNL()->export_defaults['shipping_methods_package_types'][WooCommerce_PostNL_Export::PACKAGE];
} else {
$delivery_options_shipping_methods = array();
}
return json_encode($delivery_options_shipping_methods);
}
private function postnl_delivery_options_always_display() {
if (isset(WooCommerce_PostNL()->checkout_settings['checkout_display'])
&& WooCommerce_PostNL()->checkout_settings['checkout_display'] == 'all_methods') {
return true;
}
return false;
}
}
endif; // class_exists
return new WooCommerce_PostNL_Frontend();