Customizations via your own code

Last modified:

The Fraktjakt integration exposes a number of filters and hooks so you can tailor its behaviour. The examples below are optional — add them via a child theme or a code-snippets plugin.

Force customer type (business / private individual)

The customer type is treated as a business if the customer has entered information in the Company field in the WooCommerce checkout. In all other cases, the customer type is sent to Fraktjakt as a private individual when the available shipping options are fetched. If you want to control this, there are two different ways to do it.

Modify customer type via filter

By using the filter kroconnect_fraktjakt_address_from_destination, you can control the customer type as follows.

  • Private individual: residential = true.
  • Business: residential = false.
add_filter( 'kroconnect_fraktjakt_address_from_destination', 'krk_kroconnect_fraktjakt_address_from_destination', 10, 2 );

/**
  * Control customer type when qery requests are done towards Fraktjakt.
  *
  * @param object     $address Customer address object that will be sent to Fraktjakt.
  * @param array      $destination Customer Destination used by WooCommerce to calculate shipping.
  * @return object    $address Modified customer address object.
  * */

function krk_kroconnect_fraktjakt_address_from_destination( $address, $destination ) {
  $address->residential = false;
	return $address;
}

Modify customer type via cookie

You can also set the customer type via a cookie. By default this cookie is named krokedil_customer_type. The name of the cookie can, however, be changed through the filter kroconnect_fraktjakt_customer_type_cookie_name.

Set the value of the cookie to business for a business, or person for a private individual.

Exclude or modify products in requests

The products (commodities) that are sent to Fraktjakt can be modified or removed before the request is made. Which filter to use depends on where the request originates: the cart in the frontend, or an existing WooCommerce order.

From the cart (frontend)

Through the filter kroconnect_fraktjakt_commodity_from_cart_item you can modify or remove any of the products that are about to be included in the request to Fraktjakt. Return null to exclude an item.

add_filter('kroconnect_fraktjakt_commodity_from_cart_item', 'krk_commodity_from_cart_item', 10, 3);

/**
  * Modify or exclude a product before it is sent to Fraktjakt.
  *
  * @param object     $commodity The article that will be sent to Fraktjakt.
  * @param array      $cart_item The cart item from WooCommerce cart.
  * @param object     $product WooCommerce product object.
  * @return object
  * */
function krk_commodity_from_cart_item( $commodity, $cart_item, $product ) {
	if( 'art123' === $commodity->article_number ) {
        // Exclude product to be sent to Fraktjakt if sku equals art123.
		$commodity = null;
	}
	return $commodity;
}

From an order (WooCommerce admin)

The cart filter only runs in the frontend. When shipping options are fetched from an existing order — for example from the Fraktjakt meta box in WooCommerce admin, or from an order created via the REST API — the commodities are built from the order’s line items instead, and the filter kroconnect_fraktjakt_commodity_from_order_item is applied to each one.

The same filter is also applied when the shipment is later booked at Fraktjakt, so a change made here follows the order through both steps.

ParameterTypeDescription
$commodityobjectThe commodity that will be sent to Fraktjakt.
$order_itemWC_Order_Item_ProductThe WooCommerce order line item.
$productWC_ProductThe product for the line item (a WC_Product_Variation for variations).
add_filter( 'kroconnect_fraktjakt_commodity_from_order_item', 'krk_commodity_from_order_item', 10, 3 );

/**
  * Modify or exclude a product before it is sent to Fraktjakt from a WooCommerce order.
  *
  * @param object                 $commodity  The article that will be sent to Fraktjakt.
  * @param WC_Order_Item_Product  $order_item The order line item.
  * @param WC_Product             $product    WooCommerce product object.
  * @return object|null
  * */
function krk_commodity_from_order_item( $commodity, $order_item, $product ) {
	// Exclude the product from the request if the SKU is art123.
	if ( 'art123' === $commodity->article_number ) {
		return null;
	}

	// Override the weight for a specific shipping class. The weight is set per line, so
	// multiply by the quantity. Weight is always in kilograms on the commodity.
	if ( 'bulky' === $product->get_shipping_class() ) {
		$commodity->set_weight( 2.5, $order_item->get_quantity(), 'kg' );
	}

	// Ship a specific product in its own parcel.
	if ( 'art456' === $commodity->article_number ) {
		$commodity->set_in_own_parcel( true );
	}

	// Read data from the order the item belongs to.
	$order = $order_item->get_order();
	if ( $order && 'SE' !== $order->get_shipping_country() ) {
		$commodity->set_taric( $product );
	}

	return $commodity;
}

The setters on the commodity object are chainable and can be combined, for example:

$commodity->set_name( 'Custom name' )
	->set_article_number( 'custom-sku' )
	->set_quantity( 1 )
	->set_unit_price( 199.00 )
	->set_dimensions( 30, 20, 10, 'cm' )
	->set_shelf_position( 'A12' );

Available setters: set_name, set_article_number, set_quantity, set_quantity_units, set_unit_price, set_currency, set_weight, set_dimensions (or set_length / set_width / set_height individually), set_description, set_taric, set_country_of_manufacture, set_shipped, set_in_own_parcel and set_shelf_position. Note that set_description, set_taric and set_country_of_manufacture take a WC_Product object rather than a plain value — to set a fixed value, assign the property directly instead, for example $commodity->taric = '61091000';.

A note about excluding items from orders: returning null reliably removes the item when the shipping options are fetched from the order. When the shipment is later created at Fraktjakt, the commodity list is built without that check, so a null may end up in the request. If you need an item left out of the shipment itself, it is safer to keep the commodity and mark it as not shippable with $commodity->set_shipped( false ); — a non-shipped commodity is only used for free shipping calculations — or to also zero out its weight and dimensions.

If you want the cart and the order to behave identically, register the same logic on both filters. Keep in mind that the arguments differ: the cart filter receives a cart item array ($cart_item['quantity']), while the order filter receives a WC_Order_Item_Product object ($order_item->get_quantity()).

Hide shipping rates based on cart contents (customer-controlled shipping)

Since the shipping options shown in WooCommerce are generated dynamically when you choose Customer-controlled shipping (i.e. use the shipping method called Fraktjakt in Woo), there may be occasions when you want to control the availability of a specific shipping option. Here is an example where DHL Servicepoint is not shown in the checkout if the cart contains the shipping class bulky.

add_filter( 'kroconnect_fraktjakt_add_rate', 'custom_kroconnect_fraktjakt_add_rate', 10, 2 );

/**
  * Function to potentially exclude shipping rate from available shipping options in checkout. 
  *
  * @param array $formatted_rate Data about the shipping rate that is about to be added to WooCommerce.
  * @param array $shipping_product Fraktjakt shipping product.
  * @return array|empty string
  * */
function custom_kroconnect_fraktjakt_add_rate( $formatted_rate, $shipping_product ) {
	$shipping_classes = custom_kroconnect_get_cart_shipping_classes();
	
	// If shipping class is bulky and Fraktjakt shipping product is DHL Service Point (ID 99).
	if( in_array( 'bulky', $shipping_classes, true ) && '99' === $shipping_product['id'] ) {
		$formatted_rate = '';
	}
	return $formatted_rate;
}

/**
  * Helper function to return shipping classes used in cart.
  *
  * @return array
  * */
function custom_kroconnect_get_cart_shipping_classes() {
	$shipping_classes = array();
	// Check all cart items.
	foreach ( WC()->cart->get_cart() as $cart_item ) {

		if ( ! empty( $cart_item['data']->get_shipping_class() ) ) {
			$shipping_classes[] = $cart_item['data']->get_shipping_class();
		}
	}
	return $shipping_classes;
}

Add tracking links to customer emails

The example below adds the shipment’s tracking link to the emails sent from WooCommerce. Keep in mind that this information is only available in the WooCommerce order once the shipment has been booked with Fraktjakt.

add_action( 'woocommerce_email_order_meta', 'custom_tracking_link_email_order_meta', 10, 3 );

/**
  * Function for adding Tracking Link to customer mail
  *
  * @param WC_Order $order WC order.
  * @param bool     $sent_to_admin Send to admin.
  * @param bool     $plain_text Plain text.
  * @return void
  * */
function custom_tracking_link_email_order_meta( $order, $sent_to_admin, $plain_text ) {
	$shipment_tracking_url = $order->get_meta( 'kroconnect_shipment_tracking_url', true );

	if ( ! empty( $shipment_tracking_url ) ) {

		$shipment_tracking_text = __( 'Shipment Tracking Link', 'your-text-domain' );

		echo '<a class="custom-email-shipment-tracking-link" href="' . esc_html( $shipment_tracking_url ) . '" target="_blank">' . esc_html( $shipment_tracking_text ) . '</a>';
	}
}

Auto-create shipments for REST API orders

In some cases, orders are created in WooCommerce from external systems via the WooCommerce REST API. Here is an example of how to fetch shipping options from Fraktjakt and save the desired shipping option to the order in WooCommerce. Keep in mind that if the shipping option involves a pickup-point selection, the first pickup point becomes the one selected on the order.


add_action( 'woocommerce_rest_insert_shop_order_object', 'krct_create_shipping_for_cello_orders' );

/**
 * Create Fraktjakt shipment for orders created via WooCommerce REST API.
 *
 * @param object $order WooCommerce order object.
 */
function krct_create_shipping_for_cello_orders( $order ) {
	// Check if this is a REST API order. If not, do nothing.
	if ( 'rest-api' !== $order->get_created_via() ) {
		return;
	}

	// Check if the order already has a Fraktjakt shipment created.
	$shipping_methods              = $order->get_shipping_methods();
	$shipping_method               = reset( $shipping_methods );
	$fraktjakt_shipping_product_id = $shipping_method->get_meta( 'fraktjakt_shipping_product_id' );
	if ( $fraktjakt_shipping_product_id ) {
		return;
	}

	if ( $order->get_meta( 'kroconnect_shipment_processed', true ) ) {
		return;
	}

	// Determine shipping product based on order weight.
	if ( krct_get_order_contents_weight( $order ) > 500 ) {
		// If the order weighs more than 500 g (assuming WooCommerce weight settings are in grams).
		// DHL Servicepoint.
		$shipping_product_id = 99;
	} else {
		// Postnord Varubrev klass 1.
		$shipping_product_id = 162;
	}

	// Do not set a specific pickup point for REST API orders, as we do not have that information available.
	$pickup_point_id = '';

	// Fetch and save shipment for the order.
	// If something goes wrong, it will be logged in the Kroconnect log and create a message as an order note in the WooCommerce order.
	$create_shipment = KROCONNECT()->container()->get( 'fraktjakt_admin_order_shipping' )->fetch_and_save_fraktjakt_shipment( $order, $shipping_product_id, $pickup_point_id );
}

/**
 * Get weight of items in the order.
 *
 * @param object $order The WooCommerce order.
 * @return float
 */
function krct_get_order_contents_weight( $order ) {
	$weight = 0.0;

	foreach ( $order->get_items() as $item ) {
		if ( $item['product_id'] > 0 ) {
			$_product = $item->get_product();
			if ( $_product->has_weight() ) {
				$weight += (float) $_product->get_weight() * $item['qty'];
			}
		}
	}

	return $weight;
}