【问题标题】:Change WooCommerce Subscription end date更改 WooCommerce 订阅结束日期
【发布时间】:2021-06-02 20:11:17
【问题描述】:

我对 WooCommerce 订阅的结束日期有疑问。我在这里找到了这个话题Woocommerce Subscription change expiration date 然而,我们这里的案例有点不同,但这个主题很有帮助。

我们使用按比例分配(每月 10 日)设置来同时创建续订订单(每月)。这工作正常。 我们还使用 WooCommerce 会员资格,以便客户可以访问特定的会员内容。 WooCommerce 订阅会根据最后付款日期自动设置结束日期。我们有不同期限的订阅变体产品。 (3、6 和 12 个月)

这样,我们有以下问题: 当客户今天订购 04/03/2021 (d/m/y) 订阅时,系统将创建一个订阅,第一笔付款为 2021 年 3 月 10 日。在这种情况下,结束日期将是 2021 年 10 月 6 日。 (10/03/2021 + 3 个月) 但我们希望结束日期是 2021 年 4 月 6 日(开始日期 +3 个月),而不是 2021 年 6 月 10 日。

为此,我们尝试根据开始日期(订单日期)和特定订阅版本(3. 6 或 12 个月)计算订阅结束日期。

示例:

  • 04/03/2021(订单日期和创建的初始父订单)
  • 10/03/2021(发货 1)
  • 10/04/2021(发货 2)
  • 10/05/2021(发货 3)

=> 结束日期应为 04/06/2021 而不是 10/06/2021

其他示例:

  • 20/03/2021(订单日期和创建的初始父订单)
  • 2021 年 10 月 4 日(发货 1)
  • 10/05/2021(发货 2)
  • 10/06/2021(发货 3)

=> 结束日期应为 20/06/2021 而不是 10/07/2021

目前的做法 我们尝试在这里使用这些动作挂钩:https://docs.woocommerce.com/document/subscriptions/develop/action-reference/

在此当前状态下,结束日期不会更改。我现在不确定问题是什么。我认为我以正确的方式访问结束日期,但在创建订阅后它没有更改。

add_action( 'woocommerce_checkout_subscription_created', 'recalc_subscription_end_date' );

function recalc_subscription_end_date ($order, $subscription) {
    if ( function_exists( 'wcs_order_contains_subscription' ) ) {
        if ( wcs_order_contains_subscription( $order->ID ) ) {
            
            // Set subscription end date based on subscription variation
            $end_date = date('Y-m-d H:i:s',strtotime("+12 months", strtotime($start_date)));

            $dates_to_update = array();
            $dates_to_update['end'] = $end_date;

            $subscription->update_dates($dates_to_update);

            $subscription->update_dates( array(
                'end' => $end_date,
            ) );

            $subscription->save();
        }
        $return;
    } 
}

更新: 使用来自@LoicTheAztec 的新信息,我在日志中收到以下错误。 目前 +12 个月的计算是针对每个变体进行硬编码的。那么我如何访问所有 3 个变体的数组?

我们的变体 ID:3 个月的 11903、6 个月的 11904、12 个月的 11905,

[04-Mar-2021 16:43:10 UTC] PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function recalc_subscription_end_date(), 1 passed in /home/testsystem/www/test887854.ch/cbctest/wp-includes/class-wp-hook.php on line 289 and exactly 2 expected in /home/testsystem/www/test887854.ch/cbctest/wp-content/plugins/code-snippets/php/snippet-ops.php(446) : eval()'d code:2
Stack trace:
#0 /home/testsystem/www/test887854.ch/cbctest/wp-includes/class-wp-hook.php(289): recalc_subscription_end_date(Object(WC_Subscription))
#1 /home/testsystem/www/test887854.ch/cbctest/wp-includes/class-wp-hook.php(311): WP_Hook->apply_filters(NULL, Array)
#2 /home/testsystem/www/test887854.ch/cbctest/wp-includes/plugin.php(478): WP_Hook->do_action(Array)
#3 /home/testsystem/www/test887854.ch/cbctest/wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscriptions-checkout.php(103): do_action('woocommerce_che...', Object(WC_Subscription), Object(Automattic\WooCommerce\Admin\Overrides\Order), Object(WC_Cart))

【问题讨论】:

  • 您只写了大约两个屏幕页面的文本,而没有告诉我们您尝试的代码实际发生了什么
  • 哦,对不起..我忘了!我的错!我更新了问题。感谢反馈的小伙伴! :)
  • 根据文档,woocommerce_checkout_subscription_created 的回调函数采用三个参数,其中第一个是 WC_Subscription 实例。你的只拿了一个,似乎认为它是一个订单对象?
  • 似乎我想念那里。我更新了代码并再次尝试。结束日期没有变化。这是我第一次使用 WooCommerce 订阅。所以我没有任何经验如何以正确的方式访问日期。

标签: php wordpress date woocommerce woocommerce-subscriptions


【解决方案1】:

更新 - 变量$start_date 未在您的代码中定义,还有其他错误。

尝试以下(未经测试):

add_action( 'woocommerce_checkout_subscription_created', 'recalc_subscription_end_date' );
function recalc_subscription_end_date ($order, $subscription) {
    if ( function_exists( 'wcs_order_contains_subscription' ) && wcs_order_contains_subscription( $order ) ) {
        // The array of subscriptions dates
        $date_types = array('start', 'trial_end', 'next_payment', 'last_payment', 'end');
        $dates      = array(); // Initializing
        
        foreach( $suscription_date_types as $date_type ) {
            $dates[$date_type] = $subscription->get_date($date_type);
        }
        
        // Set subscription end date based on subscription variation
        $dates['end'] = date( 'Y-m-d H:i:s',strtotime( "+12 months", strtotime( $dates['start'] ) ) );

        $subscription->update_dates($dates);
        $subscription->save();
    } 
}

代码位于活动子主题(或活动主题)的functions.php 文件中。它可以工作。

【讨论】:

  • 谢谢。但是我无法使用该代码签出订阅产品。我收到一条红色通知消息,其中没有消息。并且在调试模式下也没有错误消息。当我删除代码时,我可以毫无问题地结帐。
  • 是的。我刚刚用错误更新了问题。
  • @Nik7 我删除了can_date_be_updated() 方法……并进行了较小的更改。但我不确定它是否会起作用。
  • 谢谢。但是错误仍然存​​在。相同的错误代码和结帐不起作用。即使在仅添加订阅插件的全新安装中。我不理解为什么?我们在订阅创建后调用该操作,为什么无法结帐?
  • @Nik7 抱歉我暂时不知道……
猜你喜欢
  • 2020-11-23
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-07
  • 2017-12-30
  • 2019-06-24
  • 2014-09-27
  • 2012-05-19
相关资源
最近更新 更多