Untitled

 avatar
unknown
php
a month ago
6.9 kB
4
Indexable
<?php
/**
 * Plugin Name: Bulk Cards - FedEx One Rate (Bulk) pricing
 * Description: Overrides Flat Rate shipping for Bulk Cards based on pack size and adds optional (default ON) 9% operating support fee.
 */

/**
 * Safety helpers
 */
function sc_wc_ready(): bool {
    return function_exists('WC') && WC();
}

function sc_is_checkout_page(): bool {
    return function_exists('is_checkout') && is_checkout();
}

function sc_is_order_received_page(): bool {
    return function_exists('is_order_received_page') && is_order_received_page();
}

/**
 * Helper: detect if cart has Bulk Cards (parent or variation)
 */
function sc_cart_has_bulk_cards($bulk_parent_product_id = 27): bool {
    if (!sc_wc_ready() || !WC()->cart) {
        return false;
    }

    foreach (WC()->cart->get_cart() as $item) {
        $product_id   = (int) ($item['product_id'] ?? 0);
        $variation_id = (int) ($item['variation_id'] ?? 0);

        if ($product_id === $bulk_parent_product_id) {
            return true;
        }

        if ($variation_id && (int) wp_get_post_parent_id($variation_id) === $bulk_parent_product_id) {
            return true;
        }
    }

    return false;
}

/**
 * 1) FedEx One Rate (Bulk) - Shipping override by units
 */
add_filter('woocommerce_package_rates', function ($rates, $package) {
    if (!sc_wc_ready() || !WC()->cart) {
        return $rates;
    }

    $bulk_parent_product_id = 27; // ID do produto Bulk Cards (pai)
    $target_label_contains  = 'FedEx One Rate (Bulk)';

    $units = 0;

    foreach (WC()->cart->get_cart() as $item) {
        $product_id   = (int) ($item['product_id'] ?? 0);
        $variation_id = (int) ($item['variation_id'] ?? 0);
        $qty_in_cart  = (int) ($item['quantity'] ?? 0);

        // Detecta se é o produto Bulk (pai) ou uma variação dele
        $is_bulk = ($product_id === $bulk_parent_product_id);

        if (!$is_bulk && $variation_id) {
            $parent_id = (int) wp_get_post_parent_id($variation_id);

            if ($parent_id === $bulk_parent_product_id) {
                $is_bulk = true;
            }
        }

        if (!$is_bulk) {
            continue;
        }

        // Tenta extrair o pack size do nome (ex: "Bulk Cards - 25")
        $name = isset($item['data']) && is_object($item['data']) ? (string) $item['data']->get_name() : '';
        $pack = 0;

        if (preg_match('/\b(25|50|75|100|125|150|175|200|225|250|275|300|325|350|375|400|425|450|475|500|525|550|575|600|625|650|675|700|725|750|775|800|825|850|875|900|925|950|975|1000)\b/', $name, $m)) {
            $pack = (int) $m[1];
        }

        // Fallback: se não encontrou no nome, assume que qty é a unidade
        if ($pack > 0) {
            $units += ($pack * $qty_in_cart);
        } else {
            $units += $qty_in_cart;
        }
    }

    if ($units <= 0) {
        return $rates;
    }

    // Tabela final
    $cost = null;

    if ($units === 25) {
        $cost = 11.90;
    } elseif ($units >= 50 && $units <= 200) {
        $cost = 12.50;
    } elseif ($units >= 225 && $units <= 500) {
        $cost = 22.75;
    } elseif ($units >= 525 && $units <= 975) {
        $cost = 29.95;
    } elseif ($units >= 1000) {
        $cost = 39.95;
    }

    if ($cost === null) {
        return $rates;
    }

    foreach ($rates as $rate_key => $rate) {
        if (!isset($rate->method_id, $rate->label)) {
            continue;
        }

        if ($rate->method_id !== 'flat_rate') {
            continue;
        }

        if (stripos($rate->label, $target_label_contains) === false) {
            continue;
        }

        $rates[$rate_key]->cost = (float) $cost;
        break;
    }

    return $rates;
}, 20, 2);

/**
 * 2) Seed default opt-in (9%) for Bulk checkout (default ON)
 * Ensures the fee applies on first load without needing a click.
 */
add_action('wp_loaded', function () {
    if (!sc_wc_ready()) {
        return;
    }

    if (!sc_is_checkout_page() || sc_is_order_received_page()) {
        return;
    }

    if (!WC()->session || !WC()->cart) {
        return;
    }

    if (!sc_cart_has_bulk_cards(27)) {
        return;
    }

    if (WC()->session->get('sc_operating_optin') === null) {
        WC()->session->set('sc_operating_optin', 'yes');
    }
});

/**
 * 3) Render checkbox (below totals area in checkout)
 */
add_action('woocommerce_review_order_before_payment', function () {
    if (!sc_wc_ready()) {
        return;
    }

    if (!sc_is_checkout_page()) {
        return;
    }

    if (!sc_cart_has_bulk_cards(27)) {
        return;
    }

    $optin_session = WC()->session ? WC()->session->get('sc_operating_optin') : null;
    $checked = ($optin_session === null || $optin_session === 'yes');

    echo '<div style="
        margin:15px 0;
        padding:14px 16px;
        border:1px solid #F2C94C;
        background:#fff7d6;
        border-radius:10px;
        box-shadow: 0 1px 2px rgba(0,0,0,.06);
    ">';

    woocommerce_form_field('sc_operating_optin', [
        'type'  => 'checkbox',
        'class' => ['form-row-wide'],
        'label' => 'Add 9% to help cover Street Charity’s operating costs and expand impact.',
    ], $checked ? 1 : 0);

    echo '</div>';
});

/**
 * 4) Save checkbox state to session
 */
add_action('woocommerce_checkout_update_order_review', function ($post_data) {
    if (!sc_wc_ready() || !WC()->session) {
        return;
    }

    parse_str($post_data, $data);

    $optin = !empty($data['sc_operating_optin']) ? 'yes' : 'no';

    WC()->session->set('sc_operating_optin', $optin);
});

/**
 * 5) Apply 9% fee (only when opted-in, only for Bulk, subtotal-only)
 */
add_action('woocommerce_cart_calculate_fees', function () {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }

    if (!sc_wc_ready()) {
        return;
    }

    if (!WC()->cart || !WC()->session) {
        return;
    }

    if (!sc_cart_has_bulk_cards(27)) {
        return;
    }

    if (WC()->session->get('sc_operating_optin') !== 'yes') {
        return;
    }

    // Subtotal of items after discounts, excluding shipping/tax/fees
    $base = (float) WC()->cart->get_cart_contents_total();

    if ($base <= 0) {
        return;
    }

    $fee = round($base * 0.09, 2);

    // Third param = taxable? false (non-taxable fee)
    WC()->cart->add_fee('Operating Support (9%)', $fee, false);
});

/**
 * 6) Force instant checkout recalculation when toggling the checkbox
 */
add_action('wp_footer', function () {
    if (!sc_wc_ready()) {
        return;
    }

    if (!sc_is_checkout_page() || sc_is_order_received_page()) {
        return;
    }

    if (!sc_cart_has_bulk_cards(27)) {
        return;
    }
    ?>
    <script>
      (function($){
        $(document.body).on('change', 'input[name="sc_operating_optin"]', function(){
          $(document.body).trigger('update_checkout');
        });
      })(jQuery);
    </script>
    <?php
}, 50);
Editor is loading...
Leave a Comment