Плагин администратора для создания счетов на основе неоплаченных кварталов из пользовательской таблицы.

Вопрос или проблема

У меня есть плагин, который в основном работает. Мне нужно, чтобы он вычислял все задолженности за текущий квартал года и все предыдущие. Допустим, они заплатили в 2024 году за все кварталы, кроме 4-го. Плагин должен показать, что они должны за ОКТ НОЯБРЬ ДЕК 2024 и ЯНВ ФЕВРАЛЬ МАРТ 2025. В настоящее время он показывает все месяцы 2025 года. Мне нужно, чтобы он показывал только текущий квартал. Ничего в будущем.

<?php
/**
 * Plugin Name: Club Dues Tracker and Invoice Generator
 * Description:  
 * Version: 1.0
 * Author: David
 */

function club_dues_enqueue_admin_scripts($hook_suffix) {

    wp_enqueue_script('jquery');

    wp_enqueue_script('club-dues-script', plugin_dir_url(__FILE__) . 'club-dues-script.js', ['jquery'], null, true);

    wp_enqueue_style('club-dues-style', plugin_dir_url(__FILE__) . 'club-dues-style.css');

    wp_localize_script('club-dues-script', 'clubDuesAjax', [
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('generate_invoice_nonce')
    ]);
}
add_action('admin_enqueue_scripts', 'club_dues_enqueue_admin_scripts');

function club_dues_add_admin_menu() {
    add_menu_page(
        'club Dues Tracker',
        'club Dues Tracker',
        'manage_options',
        'club-dues-tracker',
        'club_dues_tracker_admin_page',
        'dashicons-groups',
        26
    );
}
add_action('admin_menu', 'club_dues_add_admin_menu');

function club_dues_tracker_admin_page() {
    if (!current_user_can('manage_options')) {
        return;
    }

    global $wpdb;

    $current_month = (int) date('m');
    $current_year = date('Y');
    $current_quarter = ceil($current_month / 3);
    $table_name="wp_Dues_Tracker";

    $results = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT roadname, chapter, january, february, march, april, may, june, july, august, september, october, november, december
            FROM $table_name
            WHERE Status="Active" AND (
                (january = 'FALSE') OR
                (february = 'FALSE') OR
                (march="FALSE") OR
                (april="FALSE") OR
                (may = 'FALSE') OR
                (june="FALSE") OR
                (july = 'FALSE') OR
                (august="FALSE") OR
                (september="FALSE") OR
                (october="FALSE") OR
                (november="FALSE") OR
                (december="FALSE")
            )"
        )
    );

    $clubs = [];
    foreach ($results as $row) {
        $months_due = [];
        $total_due = 0;

        foreach (['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'] as $index => $month) {
            if ($row->$month === 'FALSE') {

                $month_number = $index + 1;
                $year_due = $current_year;

                if ($month_number < $current_month) {
                    if ($current_month <= 3) {
                        $year_due = $current_year - 1;  
                    }
                }

                $months_due[] = date('F Y', strtotime("$year_due-$month_number-01"));
                $total_due += 10;  
            }
        }

        if (!empty($months_due)) {
            $row->months_due = implode(', ', $months_due);
            $row->total_due = $total_due;
            $clubs[$row->chapter][] = $row;
        }
    }

    ?>
    <div class="wrap">
        <h1>club Dues Tracker</h1>
        <table class="club-dues-table">
            <thead>
                <tr>
                    <th>club Name</th>
                    <th>Members</th>
                    <th>Total Due</th>
                    <th>Months Due</th>
                    <th>Invoice</th>
                </tr>
            </thead>
            <tbody>
                <?php foreach ($clubs as $club_name => $members) : ?>
                    <tr>
                        <td rowspan="<?php echo count($members) + 1; ?>"><?php echo esc_html($club_name); ?></td>
                        <?php $total_club_due = 0; ?>
                        <?php foreach ($members as $member) : ?>
                            <tr>
                                <td><?php echo esc_html($member->roadname); ?></td>
                                <td>$<?php echo esc_html($member->total_due); ?></td>
                                <td><?php echo esc_html($member->months_due); ?></td>
                                <?php $total_club_due += $member->total_due; ?>
                            </tr>
                        <?php endforeach; ?>
                    <tr style="border: 1px solid black;">
                        <td style="border: 1px solid black;" colspan="2">Total</td>
                        <td style="border: 1px solid black;">$<?php echo esc_html($total_club_due); ?></td>
                        <td style="border: 1px solid black;"></td>
                        <td style="border: 1px solid black;"><button class="generate-invoice" data-club="<?php echo esc_attr($club_name); ?>" data-total="<?php echo esc_attr($total_club_due); ?>">Generate Invoice</button></td>
                    </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    </div>
    <?php
}

function generate_invoice_ajax_handler() {
    check_ajax_referer('generate_invoice_nonce', 'nonce');

    $club_name = sanitize_text_field($_POST['club_name']);
    $total_due = floatval($_POST['total_due']);

    if (!class_exists('WC_Order')) {
        wp_send_json_error(['message' => 'WooCommerce is not active.']);
        return;
    }

    $product = wc_get_product(2008); 
    if (!$product) {
        wp_send_json_error(['message' => 'Invalid product ID.']);
        return;
    }

    global $wpdb;
    $table_name="wp_Dues_Tracker";

    $roadnames = $wpdb->get_col(
        $wpdb->prepare(
            "SELECT roadname FROM $table_name WHERE chapter = %s AND (january = 'FALSE' OR february = 'FALSE' OR march="FALSE" OR april="FALSE" OR may = 'FALSE' OR june="FALSE" OR july = 'FALSE' OR august="FALSE" OR september="FALSE" OR october="FALSE" OR november="FALSE" OR december="FALSE")",
            $club_name
        )
    );

    if (empty($roadnames)) {
        wp_send_json_error(['message' => 'No road names found for this club.']);
        return;
    }

    $roadnames_list = implode(', ', $roadnames);

    try {

        $order = wc_create_order();
        $order->set_billing_company($club_name);

        $order_item = $order->add_product($product, 1, [
            'subtotal' => $total_due,
            'total' => $total_due,
        ]);

        $note="club Brothers: " . $roadnames_list;
        $order->add_order_note($note, false, true); 

        $order->calculate_totals();
        $order->save();

        wp_send_json_success(['message' => 'Invoice generated successfully.', 'order_id' => $order->get_id()]);
    } catch (Exception $e) {
        wp_send_json_error(['message' => 'Error generating invoice: ' . $e->getMessage()]);
    }
}

add_action('wp_ajax_generate_invoice', 'generate_invoice_ajax_handler');

Где я ошибаюсь в этом скрипте?

Ответ или решение

Для решения вашей задачи по корректировке плагина, который генерирует счета на основе неоплаченных кварталов из пользовательской таблицы, необходимо внести изменения, чтобы отображались только задолженности за текущий квартал и все предыдущие кварталы, исключив будущие месяцы, за которые оплата пока не требуется. Давайте детально разберемся, какие изменения следует внести.

1. Анализ текущей проблемы

На данный момент скрипт отображает все месяцы 2025 года, даже если задолженность есть только за часть кварталов. Это происходит из-за того, что проверка условия не учитывает квартальную логику, и вы просто проверяете все месяцы на неоплату без учета текущих временных рамок.

2. Вычисление текущего квартала

Разделите года на четыре квартала:

  • 1 квартал: Январь, Февраль, Март
  • 2 квартал: Апрель, Май, Июнь
  • 3 квартал: Июль, Август, Сентябрь
  • 4 квартал: Октябрь, Ноябрь, Декабрь

Вы уже частично решаете задачу, определяя текущий квартал с помощью:

$current_month = (int) date('m');
$current_quarter = ceil($current_month / 3);

3. Корректная фильтрация месяцев

Вам нужно фильтровать месяцы, исходя из контекста кварталов. Для этого предлагаем следующие изменения в коде:

Изменения в логике определения задолженностей:

  1. Калькуляция задолженностей на основе текущего квартала:
foreach (['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'] as $index => $month) {
    if ($row->$month === 'FALSE') {
        $month_number = $index + 1;
        $month_quarter = ceil($month_number / 3);

        // Фильтруем только те месяцы, которые входят в текущий или предыдущий квартал
        if ($month_quarter <= $current_quarter || ($month_number < $current_month && $current_quarter == 1)) {
            $year_due = $month_number < $current_month ? $current_year - 1 : $current_year;

            $months_due[] = date('F Y', strtotime("$year_due-$month_number-01"));
            $total_due += 10; // Используйте реальную стоимость вместо фиксированной суммы
        }
    }
}

4. Рекомендации и использование

  1. Проверка статуса данных: Убедитесь, что данные в таблице корректно отражают статус оплаты. К примеру, поле Status должно четко различать между "Активный" и другими статусами.

  2. Оптимизация запросов: Убедитесь, что SQL-запросы к базе данных правильно оптимизированы, чтобы избежать лишних загрузок данных.

  3. Тестирование: Проведите тщательное тестирование после внесения изменений, чтобы убедиться, что корректировки действуют именно так, как планировалось.

Следуя данным рекомендациям, вы сможете отобразить только актуальные задолженности за кварталы без учета будущих месяцев. Отслеживайте регулярно актуальность данных и убедитесь, что пользователи получают корректные счета на оплату.

Оцените материал
Добавить комментарий

Капча загружается...