Denne shortcode bruges til at der i kurvn og Popup kurv kan vises prorata og næste måned betaling for WooCommerce produkter.
Visningen er således:
Første betaling, indeværende måned: 00,00 kr.
Herefter pris, pr. md.: 00,00 kr.
Teksten kan manuelt ændres i koden.
Styling skal laves under Tilpasset CSS
Shortcoden fungere KUN på sider med udelukkende abonnementsprodukter.
Ønsker du at nogle elementer i kurven/popup kurven skal skjules hvis der ingen produkter er i kurven kan du i funktionen auxo_prorata_toggle_selectors() tilføje classes eller ID’er så vil de elementer blive skjult. For at tilføje flere skal du blot gøre således:
‘.elementor-element-ca12467’,
‘.elementor-element-ca123’,
‘3elementor-element-ca9123’,
Brug shortcode: [auxo_cart_prorata]
/**
* Konfiguration: elementer der skal toggles
* Skriv dine selectors her (ID'er, classes, eller andre CSS selectors)
*/
function auxo_prorata_toggle_selectors() {
return [
'.elementor-element-ca96345',
];
}
/**
* Beregn og cache state pr. request (så vi ikke løber cart flere gange)
*/
function auxo_prorata_state() {
static $cache = null;
if ($cache !== null) return $cache;
$zero_html = function_exists('wc_price') ? wc_price(0) : '0';
$state = [
'empty' => true,
'totals' => [
'found' => false,
'now_raw' => 0,
'next_raw' => 0,
'now_html' => $zero_html,
'next_html' => $zero_html,
],
];
if (!function_exists('WC') || !WC()->cart || !class_exists('WC_Subscriptions_Product')) {
return $cache = $state;
}
$totals = auxo_calculate_cart_prorata_and_next();
if (!empty($totals['found']) && (float) ($totals['next_raw'] ?? 0) > 0) {
$state['empty'] = false;
$state['totals'] = $totals;
}
return $cache = $state;
}
/**
* Shortcode: [auxo_cart_prorata]
* Returnerer "0" som element (kan toggles), og opdaterer indhold via fragments.
*/
add_shortcode('auxo_cart_prorata', 'auxo_cart_prorata_shortcode');
function auxo_cart_prorata_shortcode() {
$state = auxo_prorata_state();
// 0 som et element (kan toggles)
$out = '<span class="auxo-prorata-zero"' . ($state['empty'] ? '' : ' style="display:none;"') . '>0</span>';
// Content container (altid til stede, så fragments kan erstatte den)
if ($state['empty']) {
$out .= '<div id="auxo-cart-prorata" class="auxo-cart-prorata" style="display:none;"></div>';
} else {
$out .= auxo_render_cart_prorata_markup($state['totals']);
}
// Hook + JS
$out .= auxo_prorata_hook_span($state['empty']);
$out .= auxo_prorata_toggle_js_once();
return $out;
}
/**
* Fragments: opdater kun hook-span + selve content div (2 fragments)
*/
add_filter('woocommerce_add_to_cart_fragments', 'auxo_prorata_fragments');
function auxo_prorata_fragments($fragments) {
$state = auxo_prorata_state();
// Hook-span (til toggling)
$fragments['span.auxo-prorata-hook'] = auxo_prorata_hook_span($state['empty']);
// Content (prorata + næste måned)
if ($state['empty']) {
$fragments['div#auxo-cart-prorata'] = '<div id="auxo-cart-prorata" class="auxo-cart-prorata" style="display:none;"></div>';
} else {
$fragments['div#auxo-cart-prorata'] = auxo_render_cart_prorata_markup($state['totals']);
}
return $fragments;
}
/**
* Hook-span med selectors + empty flag (opdateres via fragments)
*/
function auxo_prorata_hook_span($is_empty) {
$selectors = auxo_prorata_toggle_selectors();
$selectors = is_array($selectors) ? array_values(array_filter($selectors)) : [];
$selectors_csv = implode(',', $selectors);
return '<span class="auxo-prorata-hook" data-auxo-empty="' . ($is_empty ? '1' : '0') . '" data-auxo-toggle="' . esc_attr($selectors_csv) . '" style="display:none;"></span>';
}
/**
* JS toggler (indsættes kun én gang per side) + debounce for færre reflows
*/
function auxo_prorata_toggle_js_once() {
static $printed = false;
if ($printed) return '';
$printed = true;
ob_start(); ?>
<script>
jQuery(document).ready(function ($) {
var auxoTimer = null;
function auxoApplyToggleNow() {
var $hook = $('span.auxo-prorata-hook').last();
if (!$hook.length) return;
var empty = String($hook.data('auxo-empty')) === '1';
// Toggle "0"
if (empty) {
$('span.auxo-prorata-zero').show();
} else {
$('span.auxo-prorata-zero').hide();
}
var selectors = ($hook.data('auxo-toggle') || '').toString().trim();
if (!selectors.length) return;
selectors.split(',').forEach(function (sel) {
sel = sel.trim();
if (!sel) return;
if (empty) {
$(sel).hide();
} else {
$(sel).show();
}
});
}
function auxoApplyToggle() {
clearTimeout(auxoTimer);
auxoTimer = setTimeout(auxoApplyToggleNow, 80);
}
// ved load
auxoApplyToggleNow();
// reager primært på end-state events
$(document.body).on('wc_fragments_refreshed updated_wc_div', auxoApplyToggle);
// fallback events
$(document.body).on('added_to_cart removed_from_cart updated_cart_totals wc_fragments_loaded', auxoApplyToggle);
});
</script>
<?php
return ob_get_clean();
}
/**
* Render markup (kun når der er indhold)
*/
function auxo_render_cart_prorata_markup($totals) {
$now = $totals['now_html'] ?? (function_exists('wc_price') ? wc_price(0) : '0');
$next = $totals['next_html'] ?? (function_exists('wc_price') ? wc_price(0) : '0');
ob_start(); ?>
<div id="auxo-cart-prorata" class="auxo-cart-prorata">
<div class="auxo-row auxo-now">
<strong>Første betaling, indeværende måned:</strong>
<span class="auxo-value auxo-now-value"><?php echo wp_kses_post($now); ?></span>
</div>
<div class="auxo-row auxo-next">
<strong>Herefter pris, pr. md.:</strong>
<span class="auxo-value auxo-next-value"><?php echo wp_kses_post($next); ?></span>
</div>
</div>
<?php
return ob_get_clean();
}
/** Beregning (din eksisterende) */
function auxo_calculate_cart_prorata_and_next() {
$now_total = 0.0;
$next_total = 0.0;
$found = false;
if (!function_exists('WC') || !WC()->cart || !class_exists('WC_Subscriptions_Product')) {
return [
'found' => false,
'now_raw' => 0,
'next_raw' => 0,
'now_html' => function_exists('wc_price') ? wc_price(0) : '0',
'next_html'=> function_exists('wc_price') ? wc_price(0) : '0',
];
}
$tz = wp_timezone();
$today = new DateTime('now', $tz);
$days_in_month = (int) $today->format('t');
$today_day = (int) $today->format('j');
$days_remaining = max(0, $days_in_month - $today_day + 1);
foreach (WC()->cart->get_cart() as $cart_item) {
$product = $cart_item['data'] ?? null;
if (!$product || !is_a($product, 'WC_Product')) continue;
if (!WC_Subscriptions_Product::is_subscription($product)) continue;
$found = true;
$qty = isset($cart_item['quantity']) ? (int) $cart_item['quantity'] : 1;
$base = (float) WC_Subscriptions_Product::get_price($product);
$base_display = (float) wc_get_price_to_display($product, ['price' => $base]);
$period = WC_Subscriptions_Product::get_period($product);
$interval = (int) WC_Subscriptions_Product::get_interval($product);
if ($period === 'month' && $interval === 1) {
$next_total += ($base_display * $qty);
$daily = $base_display / max(1, $days_in_month);
$prorata = $daily * $days_remaining;
$now_total += ($prorata * $qty);
} else {
$next_total += ($base_display * $qty);
}
}
$decimals = (int) wc_get_price_decimals();
$now_total = round($now_total, $decimals);
$next_total = round($next_total, $decimals);
if (!$found) {
return [
'found' => false,
'now_raw' => 0,
'next_raw' => 0,
'now_html' => wc_price(0),
'next_html'=> wc_price(0),
];
}
return [
'found' => true,
'now_raw' => $now_total,
'next_raw' => $next_total,
'now_html' => wc_price($now_total),
'next_html'=> wc_price($next_total),
];
}