/**
* Make ‘Customs Fees for WooCommerce’ compatible with ‘WooCommerce Composite Products’.
*
* This function addresses the issue where the main composite product container has a price of zero,
* causing the customs plugin to miscalculate fees.
*
* It works by:
* 1. Calculating the total value of all selected components within each composite product.
* 2. Creating a new, temporary copy of the cart’s contents.
* 3. In this new copy, it assigns the calculated total to the main composite “container” product
* and sets the value of the individual components to zero.
* 4. Finally, it replaces the live cart’s contents with the corrected version.
*
* This function runs with priority 9, ensuring it executes just before the Customs Fees plugin’s
* calculation hook (which runs at the default priority of 10), providing it with the correct data.
*
* @param WC_Cart $cart The WooCommerce cart object.
*/
function cfwc_composite_product_compatibility_fix( $cart ) {
// Ensure both the Customs Fees plugin and Composite Products plugin are active before running.
if ( ! class_exists( ‘Customs_Fees_WooCommerce’ ) || ! class_exists( ‘WC_Composite_Products’ ) ) {
return;
}
$composite_totals = [];
// First, loop through the cart to find composite components and sum their line totals.
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
if ( ! empty( $cart_item[‘composite_parent’] ) ) {
$parent_key = $cart_item[‘composite_parent’];
if ( ! isset( $composite_totals[ $parent_key ] ) ) {
$composite_totals[ $parent_key ] = 0;
}
$composite_totals[ $parent_key ] += $cart_item[‘line_total’];
}
}
// If any composite products were found, proceed with adjusting the cart.
if ( ! empty( $composite_totals ) ) {
// Make a copy of the cart contents to modify.
$new_cart_contents = $cart->get_cart();
// Loop through the copied cart contents to apply adjustments.
foreach ( $new_cart_contents as $cart_item_key => &$cart_item ) {
// If this item is a composite container with a calculated total…
if ( isset( $composite_totals[ $cart_item_key ] ) ) {
// …assign the summed component value to its total.
$new_total = $composite_totals[ $cart_item_key ];
$cart_item[‘line_total’] = $new_total;
$cart_item[‘line_subtotal’] = $new_total;
}
// If this item is a component of a composite product…
elseif ( ! empty( $cart_item[‘composite_parent’] ) ) {
// …set its value to 0 to ensure it’s not counted separately.
$cart_item[‘line_total’] = 0;
$cart_item[‘line_subtotal’] = 0;
}
}
// Replace the live cart contents with our modified version.
$cart->set_cart_contents( $new_cart_contents );
}
}
// Add the function with priority 9 to run BEFORE the customs plugin’s calculation.
add_action( ‘woocommerce_cart_calculate_fees’, ‘cfwc_composite_product_compatibility_fix’, 9 );
From our friend Gemini:
/**
* Make ‘Customs Fees for WooCommerce’ compatible with ‘WooCommerce Composite Products’.
*
* This function addresses the issue where the main composite product container has a price of zero,
* causing the customs plugin to miscalculate fees.
*
* It works by:
* 1. Calculating the total value of all selected components within each composite product.
* 2. Creating a new, temporary copy of the cart’s contents.
* 3. In this new copy, it assigns the calculated total to the main composite “container” product
* and sets the value of the individual components to zero.
* 4. Finally, it replaces the live cart’s contents with the corrected version.
*
* This function runs with priority 9, ensuring it executes just before the Customs Fees plugin’s
* calculation hook (which runs at the default priority of 10), providing it with the correct data.
*
* @param WC_Cart $cart The WooCommerce cart object.
*/
function cfwc_composite_product_compatibility_fix( $cart ) {
// Ensure both the Customs Fees plugin and Composite Products plugin are active before running.
if ( ! class_exists( ‘Customs_Fees_WooCommerce’ ) || ! class_exists( ‘WC_Composite_Products’ ) ) {
return;
}
$composite_totals = [];
// First, loop through the cart to find composite components and sum their line totals.
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
if ( ! empty( $cart_item[‘composite_parent’] ) ) {
$parent_key = $cart_item[‘composite_parent’];
if ( ! isset( $composite_totals[ $parent_key ] ) ) {
$composite_totals[ $parent_key ] = 0;
}
$composite_totals[ $parent_key ] += $cart_item[‘line_total’];
}
}
// If any composite products were found, proceed with adjusting the cart.
if ( ! empty( $composite_totals ) ) {
// Make a copy of the cart contents to modify.
$new_cart_contents = $cart->get_cart();
// Loop through the copied cart contents to apply adjustments.
foreach ( $new_cart_contents as $cart_item_key => &$cart_item ) {
// If this item is a composite container with a calculated total…
if ( isset( $composite_totals[ $cart_item_key ] ) ) {
// …assign the summed component value to its total.
$new_total = $composite_totals[ $cart_item_key ];
$cart_item[‘line_total’] = $new_total;
$cart_item[‘line_subtotal’] = $new_total;
}
// If this item is a component of a composite product…
elseif ( ! empty( $cart_item[‘composite_parent’] ) ) {
// …set its value to 0 to ensure it’s not counted separately.
$cart_item[‘line_total’] = 0;
$cart_item[‘line_subtotal’] = 0;
}
}
// Replace the live cart contents with our modified version.
$cart->set_cart_contents( $new_cart_contents );
}
}
// Add the function with priority 9 to run BEFORE the customs plugin’s calculation.
add_action( ‘woocommerce_cart_calculate_fees’, ‘cfwc_composite_product_compatibility_fix’, 9 );