<?php
/**
* Descuento automático por monto de carrito (WooCommerce)
* Tramos:
* - $150.000 => 2% OFF
* - $250.000 => 4% OFF
* - $500.000 => 6% OFF
* - $1.000.000 => 7% OFF
*
* Muestra en Carrito y Checkout:
* - Subtotal (antes) (ya lo muestra Woo)
* - Descuento aplicado (con leyenda)
* - Subtotal con descuento (antes de envío/impuestos)
*
* Pegar en functions.php (preferible en un child theme).
*/
/** 1) Configuración de tramos */
function lc_monto_descuento_tramos() {
return array(
1000000 => 0.07,
500000 => 0.06,
250000 => 0.04,
150000 => 0.02,
);
}
/** 2) Calcula el descuento según subtotal */
function lc_monto_descuento_data() {
if ( ! function_exists('WC') || ! WC()->cart ) {
return array( 'rate' => 0, 'amount' => 0, 'subtotal' => 0 );
}
// Subtotal de productos (sin envío). Por defecto: sin impuestos.
$subtotal = (float) WC()->cart->get_subtotal();
$rate = 0.0;
foreach ( lc_monto_descuento_tramos() as $min => $pct ) {
if ( $subtotal >= (float) $min ) {
$rate = (float) $pct;
break;
}
}
$amount = $rate > 0 ? round( $subtotal * $rate, wc_get_price_decimals() ) : 0;
return array(
'rate' => $rate,
'amount' => $amount, // positivo (lo convertimos a negativo al aplicar fee)
'subtotal' => $subtotal,
);
}
/** 3) Aplica el descuento como "fee" negativo (para que afecte totales) */
add_action( 'woocommerce_cart_calculate_fees', function( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if ( ! $cart || $cart->is_empty() ) return;
$data = lc_monto_descuento_data();
if ( $data['amount'] <= 0 ) return;
$label = sprintf(
'Descuento por monto (%s%% OFF)',
rtrim( rtrim( number_format( $data['rate'] * 100, 2, '.', '' ), '0' ), '.' )
);
// Fee negativo = descuento
$cart->add_fee( $label, -1 * $data['amount'], false );
// Guardamos para mostrar “subtotal con descuento” de forma consistente
if ( WC()->session ) {
WC()->session->set( 'lc_monto_desc_rate', $data['rate'] );
WC()->session->set( 'lc_monto_desc_amount', $data['amount'] );
}
}, 20, 1 );
/**
* 4) Oculta la línea del fee en el listado estándar (así no se duplica),
* porque la vamos a mostrar debajo del subtotal con “antes / después”.
*/
add_filter( 'woocommerce_cart_totals_get_fees', function( $fees ) {
if ( empty( $fees ) ) return $fees;
$filtered = array();
foreach ( $fees as $fee ) {
// Oculta SOLO los fees que sean nuestro descuento por monto
if ( isset( $fee->name ) && strpos( $fee->name, 'Descuento por monto' ) === 0 ) {
continue;
}
$filtered[] = $fee;
}
return $filtered;
}, 20, 1 );
/** 5) Render de filas debajo del subtotal (Carrito y Checkout) */
function lc_render_filas_descuento_bajo_subtotal() {
if ( ! function_exists('WC') || ! WC()->cart ) return;
$data = lc_monto_descuento_data();
if ( $data['amount'] <= 0 ) return;
$rate_pct = rtrim( rtrim( number_format( $data['rate'] * 100, 2, '.', '' ), '0' ), '.' );
$discount = $data['amount'];
$after = max( 0, $data['subtotal'] - $discount );
?>
<tr class="lc-monto-desc-row">
<th><?php echo esc_html( 'Descuento por monto (' . $rate_pct . '% OFF)' ); ?></th>
<td data-title="<?php echo esc_attr( 'Descuento por monto' ); ?>">
<?php echo wp_kses_post( '-' . wc_price( $discount ) ); ?>
</td>
</tr>
<tr class="lc-monto-desc-row lc-monto-subtotal-after">
<th><?php echo esc_html( 'Subtotal con descuento' ); ?></th>
<td data-title="<?php echo esc_attr( 'Subtotal con descuento' ); ?>">
<?php echo wp_kses_post( wc_price( $after ) ); ?>
</td>
</tr>
<?php
}
// Carrito (totales)
add_action( 'woocommerce_cart_totals_after_subtotal', 'lc_render_filas_descuento_bajo_subtotal', 20 );
// Checkout (review order)
add_action( 'woocommerce_review_order_after_subtotal', 'lc_render_filas_descuento_bajo_subtotal', 20 );