From 1f91448525dd6e7a9a7f6417ec34f4cdfcdb3f47 Mon Sep 17 00:00:00 2001 From: Drew Rowan Date: Tue, 23 Apr 2024 11:37:00 +0200 Subject: [PATCH] Release 3.0.2 --- changelog.txt | 15 +++++ ...-wc-postfinancecheckout-admin-document.php | 51 ++++++----------- ...financecheckout-admin-order-completion.php | 3 + ...-postfinancecheckout-admin-transaction.php | 56 ++++++++----------- .../class-wc-postfinancecheckout-helper.php | 4 +- ...nancecheckout-packages-coupon-discount.php | 20 +++++-- ...-postfinancecheckout-service-line-item.php | 14 ++++- readme.txt | 13 +++-- woocommerce-postfinancecheckout.php | 17 +++--- 9 files changed, 106 insertions(+), 87 deletions(-) diff --git a/changelog.txt b/changelog.txt index 60fc22b..bdb346f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -727,3 +727,18 @@ Tested against: - [Tested Against] Woocommerce 8.5.2 - [Tested Against] PHP SDK 4.0.2 += 3.0.1 - April 3 2024 = +- [Feature] Added support to High Performance Order Storage (HPOS). +- [Tested Against] PHP 8.2 +- [Tested Against] Wordpress 6.5 +- [Tested Against] Woocommerce 8.7.0 +- [Tested Against] PHP SDK 4.0.2 + += 3.0.2 - April 22 2024 = +- [Hotfix] Fixed completion in the backend with coupon. +- [Hotfix] Fixed tax amount not sent correctly to the portal. +- [Tested Against] PHP 8.2 +- [Tested Against] Wordpress 6.5 +- [Tested Against] Woocommerce 8.7.0 +- [Tested Against] PHP SDK 4.0.2 + diff --git a/includes/admin/class-wc-postfinancecheckout-admin-document.php b/includes/admin/class-wc-postfinancecheckout-admin-document.php index 0c5cb61..4baf6c5 100644 --- a/includes/admin/class-wc-postfinancecheckout-admin-document.php +++ b/includes/admin/class-wc-postfinancecheckout-admin-document.php @@ -113,50 +113,35 @@ public static function add_buttons_to_overview( WC_Order $order ) { /** * Add WC Meta boxes. + * @see: https://woo.com/document/high-performance-order-storage/#section-8 */ public static function add_meta_box() { - global $post; - if ( 'shop_order' !== $post->post_type ) { - return; - } - $order = WC_Order_Factory::get_order( $post->ID ); - $method = wc_get_payment_gateway_by_order( $order ); - if ( ! ( $method instanceof WC_PostFinanceCheckout_Gateway ) ) { - return; - } - $transaction_info = WC_PostFinanceCheckout_Entity_Transaction_Info::load_by_order_id( $order->get_id() ); - if ( $transaction_info->get_id() !== null && in_array( - $transaction_info->get_state(), + $screen = class_exists( '\Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController' ) + && wc_get_container()->get( \Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled() + ? wc_get_page_screen_id( 'shop-order' ) + : 'shop_order'; + add_meta_box( + 'woocommerce-order-postfinancecheckout-documents', + __( 'PostFinance Checkout Documents', 'woo-postfinancecheckout' ), array( - \PostFinanceCheckout\Sdk\Model\TransactionState::COMPLETED, - \PostFinanceCheckout\Sdk\Model\TransactionState::FULFILL, - \PostFinanceCheckout\Sdk\Model\TransactionState::DECLINE, + __CLASS__, + 'output', ), - true - ) ) { - add_meta_box( - 'woocommerce-order-postfinancecheckout-documents', - __( 'PostFinance Checkout Documents', 'woo-postfinancecheckout' ), - array( - __CLASS__, - 'output', - ), - 'shop_order', - 'side', - 'default' - ); - } + $screen, + 'side', + 'default' + ); } /** * Output the metabox. * - * @param WP_Post $post Post. + * @param WP_Post|WP_Order $post_or_order_object + * This object is provided by woocommerce when using its screen. */ - public static function output( $post ) { - global $post; + public static function output( $post_or_order_object ) { + $order = ( $post_or_order_object instanceof WP_Post ) ? wc_get_order( $post_or_order_object->ID ) : $post_or_order_object; - $order = WC_Order_Factory::get_order( $post->ID ); $method = wc_get_payment_gateway_by_order( $order ); if ( ! ( $method instanceof WC_PostFinanceCheckout_Gateway ) ) { return; diff --git a/includes/admin/class-wc-postfinancecheckout-admin-order-completion.php b/includes/admin/class-wc-postfinancecheckout-admin-order-completion.php index 6357866..e708d35 100644 --- a/includes/admin/class-wc-postfinancecheckout-admin-order-completion.php +++ b/includes/admin/class-wc-postfinancecheckout-admin-order-completion.php @@ -213,6 +213,9 @@ public static function execute_completion() { } try { + //the order id is saved for later use + //e.g. use the order id to check if the order has a discount applied to it + WC()->session->set( 'postfinancecheckout_order_id', $order_id ); self::update_line_items( $current_completion_id ); self::send_completion( $current_completion_id ); diff --git a/includes/admin/class-wc-postfinancecheckout-admin-transaction.php b/includes/admin/class-wc-postfinancecheckout-admin-transaction.php index f65c6fe..a9b3366 100644 --- a/includes/admin/class-wc-postfinancecheckout-admin-transaction.php +++ b/includes/admin/class-wc-postfinancecheckout-admin-transaction.php @@ -41,45 +41,35 @@ public static function init() { /** * Add WC Meta boxes. + * @see: https://woo.com/document/high-performance-order-storage/#section-8 */ public static function add_meta_box() { - global $post; - if ( 'shop_order' != $post->post_type ) { - return; - } - $order = WC_Order_Factory::get_order( $post->ID ); - $method = wc_get_payment_gateway_by_order( $order ); - if ( ! ( $method instanceof WC_PostFinanceCheckout_Gateway ) ) { - return; - } - $transaction_info = WC_PostFinanceCheckout_Entity_Transaction_Info::load_by_order_id( $order->get_id() ); - if ( $transaction_info->get_id() == null ) { - $transaction_info = WC_PostFinanceCheckout_Entity_Transaction_Info::load_newest_by_mapped_order_id( $order->get_id() ); - } - if ( $transaction_info->get_id() != null ) { - add_meta_box( - 'woocommerce-order-postfinancecheckout-transaction', - __( 'PostFinance Checkout Transaction', 'woocommerc-postfinancecheckout' ), - array( - __CLASS__, - 'output', - ), - 'shop_order', - 'normal', - 'default' - ); - } + $screen = class_exists( '\Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController' ) + && wc_get_container()->get( \Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled() + ? wc_get_page_screen_id( 'shop-order' ) + : 'shop_order'; + add_meta_box( + 'woocommerce-order-postfinancecheckout-transaction', + __( 'PostFinance Checkout Transaction', 'woocommerce-postfinancecheckout' ), + array( + __CLASS__, + 'output', + ), + $screen, + 'normal', + 'default' + ); } /** * Output the metabox. * - * @param WP_Post $post post data. + * @param WP_Post|WP_Order $post_or_order_object + * This object is provided by woocommerce when using its screen. */ - public static function output( $post ) { - global $post; + public static function output( $post_or_order_object ) { + $order = ( $post_or_order_object instanceof WP_Post ) ? wc_get_order( $post_or_order_object->ID ) : $post_or_order_object; - $order = WC_Order_Factory::get_order( $post->ID ); $method = wc_get_payment_gateway_by_order( $order ); if ( ! ( $method instanceof WC_PostFinanceCheckout_Gateway ) ) { return; @@ -129,7 +119,7 @@ public static function output( $post ) { get_order_id() ); ?> - + get_failure_reason() != null ) : ?> @@ -155,7 +145,7 @@ public static function output( $post ) { - + @@ -177,7 +167,7 @@ public static function output( $post ) { - + diff --git a/includes/class-wc-postfinancecheckout-helper.php b/includes/class-wc-postfinancecheckout-helper.php index 0106691..4f8eb2f 100644 --- a/includes/class-wc-postfinancecheckout-helper.php +++ b/includes/class-wc-postfinancecheckout-helper.php @@ -218,7 +218,7 @@ public function get_total_amount_including_tax( array $line_items, bool $exclude //convert negative values to positive in order to be able to subtract it $sum -= abs( $line_item->getAmountIncludingTax() ); } else { - $sum += $line_item->getAmountIncludingTax(); + $sum += abs( $line_item->getAmountIncludingTax() ); } } return $sum; @@ -235,7 +235,7 @@ public function get_total_amount_including_tax( array $line_items, bool $exclude */ public function cleanup_line_items( array $line_items, $expected_sum, $currency ) { //ensure that the effective sum coincides with the total discounted by the coupons - $has_coupons = apply_filters( 'wc_postfinancecheckout_packages_coupon_cart_has_coupon_discounts_applied', $currency ); + $has_coupons = apply_filters( 'wc_postfinancecheckout_packages_coupon_has_coupon_discounts_applied', $currency ); $effective_sum = $this->round_amount( $this->get_total_amount_including_tax( $line_items, $has_coupons ), $currency ); $rounded_expected_sum = $this->round_amount( $expected_sum, $currency ); diff --git a/includes/packages/coupon/class-wc-postfinancecheckout-packages-coupon-discount.php b/includes/packages/coupon/class-wc-postfinancecheckout-packages-coupon-discount.php index 8d34059..e39bf98 100644 --- a/includes/packages/coupon/class-wc-postfinancecheckout-packages-coupon-discount.php +++ b/includes/packages/coupon/class-wc-postfinancecheckout-packages-coupon-discount.php @@ -48,10 +48,10 @@ public static function init() { 1 ); add_filter( - 'wc_postfinancecheckout_packages_coupon_cart_has_coupon_discounts_applied', + 'wc_postfinancecheckout_packages_coupon_has_coupon_discounts_applied', array( __CLASS__, - 'has_cart_coupon_discounts_applied', + 'has_coupon_discounts_applied', ), 10, 1 @@ -111,8 +111,17 @@ public static function copy_total_coupon_discount_meta_data_to_order_item( WC_Or public static function get_coupons_discount_totals_including_tax( $currency ) { $coupons_discount_total = 0; + //guard clause if the order doesn't exists, nothing to do here. + $order_id = WC()->session->get( 'postfinancecheckout_order_id' ); + if ( WC()->cart->get_cart_contents_count() == 0 && !is_null( $order_id ) ) { + + if ( $order = wc_get_order( $order_id ) ) { + $coupons_discount_total += $order->get_total_discount(); + } + } + //guard clause if the cart is empty, nothing to do here. This applies to subscription renewals - if ( empty( WC()->cart ) ) { + if ( empty( WC()->cart->get_cart_contents_count() ) ) { return $coupons_discount_total; } @@ -129,7 +138,7 @@ public static function get_coupons_discount_totals_including_tax( $currency ) { * @param $currency * @return bool */ - public static function has_cart_coupon_discounts_applied( $currency ) { + public static function has_coupon_discounts_applied( $currency ) { $discount = apply_filters( 'wc_postfinancecheckout_packages_coupon_discount_totals_including_tax', $currency ); return $discount > 0; } @@ -184,6 +193,7 @@ public static function get_coupon_percentage_discount_by_item( string $item_key * @return array */ public static function process_line_items_with_coupons( array $line_items, float $expected_sum, string $currency ) { + $line_item_coupons = []; $exclude_discounts = true; $amount = WC_PostFinanceCheckout_Helper::instance()->get_total_amount_including_tax( $line_items, $exclude_discounts); $effective_sum = WC_PostFinanceCheckout_Helper::instance()->round_amount( $amount , $currency ); @@ -195,6 +205,7 @@ public static function process_line_items_with_coupons( array $line_items, float foreach ( $line_items as $line_item ) { if ( $line_item->getType() == \PostFinanceCheckout\Sdk\Model\LineItemType::DISCOUNT ) { //if there is a difference, a penny, then the coupon is readjust + $line_item_coupons[] = clone $line_item; $item_amount = $line_item->getAmountIncludingTax() + $result_amount; $line_item->setAmountIncludingTax( WC_PostFinanceCheckout_Helper::instance()->round_amount( $item_amount, $currency ) ); } @@ -223,6 +234,7 @@ public static function process_line_items_with_coupons( array $line_items, float //format number with two decimal places 'effective_sum' => sprintf("%.2f", $amount_rounded ), 'line_items_cleaned' => $line_items, + 'line_item_coupons' => $line_item_coupons, ]; } diff --git a/includes/service/class-wc-postfinancecheckout-service-line-item.php b/includes/service/class-wc-postfinancecheckout-service-line-item.php index 647052d..995e307 100644 --- a/includes/service/class-wc-postfinancecheckout-service-line-item.php +++ b/includes/service/class-wc-postfinancecheckout-service-line-item.php @@ -561,12 +561,22 @@ protected function create_product_line_items_from_backend( array $backend_items, $line_item = new \PostFinanceCheckout\Sdk\Model\LineItemCreate(); - $tax = 0; + $tax = $discounts = 0; if ( isset( $backend_items[ $item_id ]['completion_tax'] ) ) { $tax = array_sum( $backend_items[ $item_id ]['completion_tax'] ); } - $amount_including_tax = $backend_items[ $item_id ]['completion_total'] + $tax; + //At this point, if there is a discount applied by coupon, the price already has the discount applied, + //and to be able to send the discount to the portal, it is necessary to restore the discounted amount, + //the original price must be restored before being applied, otherwise it would be discounting twice in the portal. + $item_data_coupon = $item->get_meta( '_postfinancecheckout_coupon_discount_line_item_discounts' ); + if ( !empty ( $item_data_coupon ) ) { + $discount_tax = $item->get_subtotal_tax() - $item->get_total_tax(); + $discount_amount = $item->get_subtotal() - $item->get_total(); + $discounts = $discount_tax + $discount_amount; + } + + $amount_including_tax = $backend_items[ $item_id ]['completion_total'] + $tax + $discounts; $line_item->setAmountIncludingTax( $this->round_amount( $amount_including_tax, $currency ) ); $quantity = empty( $backend_items[ $item_id ]['qty'] ) ? 1 : $backend_items[ $item_id ]['qty']; diff --git a/readme.txt b/readme.txt index 62673f1..e335ba2 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: postfinancecheckout AG Tags: woocommerce PostFinance Checkout, woocommerce, PostFinance Checkout, payment, e-commerce, webshop, psp, invoice, packing slips, pdf, customer invoice, processing Requires at least: 4.7 Tested up to: 6.2 -Stable tag: 3.0.0 +Stable tag: 3.0.2 License: Apache 2 License URI: http://www.apache.org/licenses/LICENSE-2.0 @@ -56,9 +56,10 @@ Support queries can be issued on the [PostFinance Checkout support site](https:/ == Changelog == -= 3.0.0 - February 20 2024 = -- [Feature] Full version release -- [Tested Against] PHP 8.0 -- [Tested Against] Wordpress 6.4.3 -- [Tested Against] Woocommerce 8.5.2 += 3.0.2 - April 22 2024 = +- [Hotfix] Fixed completion in the backend with coupon. +- [Hotfix] Fixed tax amount not sent correctly to the portal. +- [Tested Against] PHP 8.2 +- [Tested Against] Wordpress 6.5 +- [Tested Against] Woocommerce 8.7.0 - [Tested Against] PHP SDK 4.0.2 diff --git a/woocommerce-postfinancecheckout.php b/woocommerce-postfinancecheckout.php index 71e6a76..397a23a 100644 --- a/woocommerce-postfinancecheckout.php +++ b/woocommerce-postfinancecheckout.php @@ -3,15 +3,10 @@ * Plugin Name: PostFinance Checkout * Plugin URI: https://wordpress.org/plugins/woo-postfinancecheckout * Description: Process WooCommerce payments with PostFinance Checkout. - * Version: 3.0.0 * License: Apache2 * License URI: http://www.apache.org/licenses/LICENSE-2.0 * Author: postfinancecheckout AG * Author URI: https://postfinance.ch/en/business/products/e-commerce/postfinance-checkout-all-in-one.html - * Requires at least: 4.7 - * Tested up to: 6.3 - * WC requires at least: 3.0.0 - * WC tested up to: 7.8.2 * * Text Domain: postfinancecheckout * Domain Path: /languages/ @@ -39,14 +34,14 @@ final class WooCommerce_PostFinanceCheckout { const CK_INTEGRATION = 'wc_postfinancecheckout_integration'; const CK_ORDER_REFERENCE = 'wc_postfinancecheckout_order_reference'; const CK_ENFORCE_CONSISTENCY = 'wc_postfinancecheckout_enforce_consistency'; - const WC_MAXIMUM_VERSION = '8.5.2'; + const WC_MAXIMUM_VERSION = '8.7.0'; /** * WooCommerce PostFinanceCheckout version. * * @var string */ - private $version = '3.0.0'; + private $version = '3.0.2'; /** * The single instance of the class. @@ -447,6 +442,14 @@ public function loaded() { 10, 2 ); + + + add_action( 'before_woocommerce_init', function() { + if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { + \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); + } + } ); + } /**