From ed0bfd3a71b2d6abc758481a57363a483856a125 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Mon, 9 Dec 2024 11:57:55 +0000 Subject: [PATCH 01/69] Fix: jQuery `tipTip` function not available #915 --- includes/Assets.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/includes/Assets.php b/includes/Assets.php index c0eb10227..5ac10cd24 100644 --- a/includes/Assets.php +++ b/includes/Assets.php @@ -20,7 +20,7 @@ public static function instance() { public function __construct() { add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts_styles' ) ); - add_action( 'admin_enqueue_scripts', array( $this, 'backend_scripts_styles' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'backend_scripts_styles' ), 11 ); // after WC } /** @@ -134,9 +134,13 @@ public function backend_scripts_styles ( $hook ) { wp_enqueue_style( 'wp-pointer' ); } + if ( ! wp_script_is( 'jquery-tiptip', 'enqueued' ) ) { + wp_enqueue_script( 'jquery-tiptip' ); + } + wp_enqueue_script( 'wpo-wcpdf-admin', - WPO_WCPDF()->plugin_url() . '/assets/js/admin-script'.$suffix.'.js', + WPO_WCPDF()->plugin_url() . '/assets/js/admin-script' . $suffix . '.js', array( 'jquery', 'wc-enhanced-select', 'jquery-blockui', 'jquery-tiptip', 'wp-pointer' ), WPO_WCPDF_VERSION ); From 4412162bcc9d760f4119b5fd40b361b62db4e4ba Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:42:26 +0330 Subject: [PATCH 02/69] New: adds user info to order notes when generating documents (#913) --- includes/Main.php | 96 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/includes/Main.php b/includes/Main.php index 423c2b055..3d689b7ec 100644 --- a/includes/Main.php +++ b/includes/Main.php @@ -1265,16 +1265,44 @@ public function set_phpmailer_validator( $mailArray ) { * * @param object $document * @param string $trigger + * * @return void */ - public function log_document_creation_to_order_notes( $document, $trigger ) { + public function log_document_creation_to_order_notes( object $document, string $trigger ) { + if ( empty( $document ) || empty( $trigger ) || ! isset( WPO_WCPDF()->settings->debug_settings['log_to_order_notes'] ) ) { + return; + } + $triggers = $this->get_document_triggers(); - if ( ! empty( $document ) && isset( WPO_WCPDF()->settings->debug_settings['log_to_order_notes'] ) && ! empty( $trigger ) && array_key_exists( $trigger, $triggers ) ) { - /* translators: 1. document title, 2. creation trigger */ - $message = __( 'PDF %1$s created via %2$s.', 'woocommerce-pdf-invoices-packing-slips' ); - $note = sprintf( $message, $document->get_title(), $triggers[$trigger] ); - $this->log_to_order_notes( $note, $document ); + + if ( ! array_key_exists( $trigger, $triggers ) ) { + return; } + + $user_note = ''; + $manual_triggers = $this->get_document_triggers( 'manual' ); + + // Add user information if the trigger is manual. + if ( array_key_exists( $trigger, $manual_triggers ) ) { + $user = wp_get_current_user(); + + if ( ! empty( $user->user_login ) ) { + $user_note = sprintf( + ' (%s: %s)', + __( 'User', 'woocommerce-pdf-invoices-packing-slips' ), + esc_html( $user->user_login ) + ); + } + } + + $note = sprintf( + /* translators: 1. document title, 2. creation trigger */ + __( 'PDF %1$s created via %2$s.', 'woocommerce-pdf-invoices-packing-slips' ), + $document->get_title(), + $triggers[ $trigger ] + ); + + $this->log_to_order_notes( $note . $user_note, $document ); } /** @@ -1286,10 +1314,24 @@ public function log_document_creation_to_order_notes( $document, $trigger ) { */ public function log_document_deletion_to_order_notes( object $document ): void { if ( ! empty( WPO_WCPDF()->settings->debug_settings['log_to_order_notes'] ) ) { - /* translators: document title */ - $message = __( 'PDF %s deleted.', 'woocommerce-pdf-invoices-packing-slips' ); - $note = sprintf( $message, $document->get_title() ); - $this->log_to_order_notes( $note, $document ); + $user_note = ''; + $user = wp_get_current_user(); + + if ( ! empty( $user->user_login ) ) { + $user_note = sprintf( + ' (%s: %s)', + __( 'User', 'woocommerce-pdf-invoices-packing-slips' ), + esc_html( $user->user_login ) + ); + } + + $note = sprintf( + /* translators: document title */ + __( 'PDF %s deleted.', 'woocommerce-pdf-invoices-packing-slips' ), + $document->get_title() + ); + + $this->log_to_order_notes( $note . $user_note, $document ); } } @@ -1405,16 +1447,36 @@ public function log_document_creation_trigger_to_order_meta( $document, $trigger /** * Get the document triggers * + * @param string $trigger_type The trigger type: 'manual', 'automatic', or 'all'. Defaults to 'all'. + * * @return array */ - public function get_document_triggers() { - return apply_filters( 'wpo_wcpdf_document_triggers', [ - 'single' => __( 'single order action', 'woocommerce-pdf-invoices-packing-slips' ), - 'bulk' => __( 'bulk order action', 'woocommerce-pdf-invoices-packing-slips' ), - 'my_account' => __( 'my account', 'woocommerce-pdf-invoices-packing-slips' ), + public function get_document_triggers( string $trigger_type = 'all' ): array { + $manual_triggers = apply_filters( 'wpo_wcpdf_manual_document_triggers', array( + 'single' => __( 'single order action', 'woocommerce-pdf-invoices-packing-slips' ), + 'bulk' => __( 'bulk order action', 'woocommerce-pdf-invoices-packing-slips' ), + 'my_account' => __( 'my account', 'woocommerce-pdf-invoices-packing-slips' ), + 'document_data' => __( 'order document data (number and/or date set manually)', 'woocommerce-pdf-invoices-packing-slips' ), + ) ); + + $automatic_triggers = apply_filters( 'wpo_wcpdf_automatic_document_triggers', array( 'email_attachment' => __( 'email attachment', 'woocommerce-pdf-invoices-packing-slips' ), - 'document_data' => __( 'order document data (number and/or date set manually)', 'woocommerce-pdf-invoices-packing-slips' ), - ] ); + ) ); + + switch ( $trigger_type ) { + case 'manual': + $triggers = $manual_triggers; + break; + case 'automatic': + $triggers = $automatic_triggers; + break; + case 'all': + default: + $triggers = array_merge( $manual_triggers, $automatic_triggers ); + break; + } + + return apply_filters( 'wpo_wcpdf_document_triggers', $triggers, $trigger_type ); } /** From 406406fe3d8c305ec059bb4573c19411a0eb1c6a Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Tue, 10 Dec 2024 11:49:58 +0330 Subject: [PATCH 03/69] Fix: UBL issue with empty tax on line items (#904) --- ubl/Handlers/Invoice/InvoiceLineHandler.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ubl/Handlers/Invoice/InvoiceLineHandler.php b/ubl/Handlers/Invoice/InvoiceLineHandler.php index bbbb14d78..52382bcd0 100644 --- a/ubl/Handlers/Invoice/InvoiceLineHandler.php +++ b/ubl/Handlers/Invoice/InvoiceLineHandler.php @@ -23,6 +23,10 @@ public function handle( $data, $options = array() ) { $line_tax_data = $item[ $taxDataContainer ]; foreach ( $line_tax_data[ $taxDataKey ] as $tax_id => $tax ) { + if ( empty( $tax ) ) { + $tax = 0; + } + if ( ! is_numeric( $tax ) ) { continue; } From a94b2ac1292fca7ccf5952f7c0c89c5fb3b89560 Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Tue, 10 Dec 2024 12:38:18 +0330 Subject: [PATCH 04/69] Fix: server requirements admin notice issue (#914) --- includes/Settings/SettingsDebug.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/includes/Settings/SettingsDebug.php b/includes/Settings/SettingsDebug.php index 8fe787ff2..d66d10582 100644 --- a/includes/Settings/SettingsDebug.php +++ b/includes/Settings/SettingsDebug.php @@ -23,7 +23,7 @@ public static function instance() { public function __construct() { // Show a notice if the plugin requirements are not met. - add_action( 'admin_init', array( $this, 'display_server_requirement_notice' ) ); + add_action( 'admin_init', array( $this, 'handle_server_requirement_notice' ) ); add_action( 'admin_init', array( $this, 'init_settings' ) ); add_action( 'wpo_wcpdf_settings_output_debug', array( $this, 'output' ), 10, 1 ); @@ -1066,7 +1066,7 @@ public function get_server_config(): array { * * @return void */ - public function display_server_requirement_notice(): void { + public function handle_server_requirement_notice(): void { // Return if the notice has been dismissed. if ( get_option( 'wpo_wcpdf_dismiss_requirements_notice', false ) ) { return; @@ -1105,6 +1105,15 @@ public function display_server_requirement_notice(): void { } // Display the notice. + add_action( 'admin_notices', array( $this, 'display_server_requirement_notice' ) ); + } + + /** + * Display a notice informing the user that the server requirements are not met. + * + * @return void + */ + public function display_server_requirement_notice(): void { $status_page_url = admin_url( 'admin.php?page=wpo_wcpdf_options_page&tab=debug§ion=status' ); $dismiss_url = wp_nonce_url( add_query_arg( 'wpo_dismiss_requirements_notice', true ), 'dismiss_requirements_notice' ); $notice_message = sprintf( From 78a8e455556065ae51657ba50ad168e9f8e3009e Mon Sep 17 00:00:00 2001 From: Mohamad Nateqi Rostami Date: Tue, 10 Dec 2024 15:56:22 +0330 Subject: [PATCH 05/69] Add shop phone number field for e-Invoice support --- includes/Settings/SettingsGeneral.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/includes/Settings/SettingsGeneral.php b/includes/Settings/SettingsGeneral.php index 4b7ecbce7..f97f4c867 100644 --- a/includes/Settings/SettingsGeneral.php +++ b/includes/Settings/SettingsGeneral.php @@ -197,6 +197,19 @@ public function init_settings() { 'description' => __( 'Required for UBL output format.
You can display this number on the invoice from the document settings.', 'woocommerce-pdf-invoices-packing-slips' ) . ' ' . $requires_pro , ) ), + array( + 'type' => 'setting', + 'id' => 'shop_phone_number', + 'title' => __( 'Shop Phone Number', 'woocommerce-pdf-invoices-packing-slips' ), + 'callback' => 'text_input', + 'section' => 'general_settings', + 'args' => array( + 'option_name' => $option_name, + 'id' => 'shop_phone_number', + 'translatable' => true, + 'description' => __( 'Required for e-Invoice.', 'woocommerce-pdf-invoices-packing-slips' ) . ' ' . $requires_pro , + ) + ), array( 'type' => 'setting', 'id' => 'shop_address', From 2efde2996d7c6f660ecc9018af9cea09f95a7614 Mon Sep 17 00:00:00 2001 From: Mohamad Nateqi Rostami Date: Tue, 10 Dec 2024 18:03:48 +0330 Subject: [PATCH 06/69] Fix issues, WPCS --- includes/Settings/SettingsGeneral.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/includes/Settings/SettingsGeneral.php b/includes/Settings/SettingsGeneral.php index f97f4c867..a2e6c7399 100644 --- a/includes/Settings/SettingsGeneral.php +++ b/includes/Settings/SettingsGeneral.php @@ -181,7 +181,7 @@ public function init_settings() { 'option_name' => $option_name, 'id' => 'vat_number', 'translatable' => true, - 'description' => __( 'Required for UBL output format.
You can display this number on the invoice from the document settings.', 'woocommerce-pdf-invoices-packing-slips' ) . ' ' . $requires_pro , + 'description' => __( 'Required for UBL output format.
You can display this number on the invoice from the document settings.', 'woocommerce-pdf-invoices-packing-slips' ) . ' ' . $requires_pro, ) ), array( @@ -194,20 +194,20 @@ public function init_settings() { 'option_name' => $option_name, 'id' => 'coc_number', 'translatable' => true, - 'description' => __( 'Required for UBL output format.
You can display this number on the invoice from the document settings.', 'woocommerce-pdf-invoices-packing-slips' ) . ' ' . $requires_pro , + 'description' => __( 'Required for UBL output format.
You can display this number on the invoice from the document settings.', 'woocommerce-pdf-invoices-packing-slips' ) . ' ' . $requires_pro, ) ), array( 'type' => 'setting', - 'id' => 'shop_phone_number', + 'id' => 'phone_number', 'title' => __( 'Shop Phone Number', 'woocommerce-pdf-invoices-packing-slips' ), 'callback' => 'text_input', 'section' => 'general_settings', 'args' => array( 'option_name' => $option_name, - 'id' => 'shop_phone_number', + 'id' => 'phone_number', 'translatable' => true, - 'description' => __( 'Required for e-Invoice.', 'woocommerce-pdf-invoices-packing-slips' ) . ' ' . $requires_pro , +// 'description' => __( 'Required for e-Invoice.', 'woocommerce-pdf-invoices-packing-slips' ), ) ), array( From 60a1a00bc1bf865cd69a36cf8aff33b150a5aa36 Mon Sep 17 00:00:00 2001 From: Mohamad Nateqi Rostami Date: Tue, 10 Dec 2024 18:15:22 +0330 Subject: [PATCH 07/69] Update the ID --- includes/Settings/SettingsGeneral.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/Settings/SettingsGeneral.php b/includes/Settings/SettingsGeneral.php index a2e6c7399..5e80c9506 100644 --- a/includes/Settings/SettingsGeneral.php +++ b/includes/Settings/SettingsGeneral.php @@ -199,13 +199,13 @@ public function init_settings() { ), array( 'type' => 'setting', - 'id' => 'phone_number', + 'id' => 'shop_phone_number', 'title' => __( 'Shop Phone Number', 'woocommerce-pdf-invoices-packing-slips' ), 'callback' => 'text_input', 'section' => 'general_settings', 'args' => array( 'option_name' => $option_name, - 'id' => 'phone_number', + 'id' => 'shop_phone_number', 'translatable' => true, // 'description' => __( 'Required for e-Invoice.', 'woocommerce-pdf-invoices-packing-slips' ), ) From 36e704ad1b4a84d42b82efa15307002f277aef87 Mon Sep 17 00:00:00 2001 From: Mohamad Nateqi Rostami Date: Wed, 11 Dec 2024 13:43:17 +0330 Subject: [PATCH 08/69] Improve the description of the "Remove released semaphore locks" tool --- views/advanced-tools.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/advanced-tools.php b/views/advanced-tools.php index 730387990..eac648bfa 100644 --- a/views/advanced-tools.php +++ b/views/advanced-tools.php @@ -60,7 +60,7 @@

-

+

From 63d057f6e678de0e600991f7b87caf1c6e2e8e92 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Wed, 11 Dec 2024 15:07:24 +0000 Subject: [PATCH 09/69] v3.9.1-beta-3 --- woocommerce-pdf-invoices-packingslips.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index 27b94e059..d39f0084f 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,14 +4,14 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.1-beta-2 + * Version: 3.9.1-beta-3 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later * License URI: https://opensource.org/licenses/gpl-license.php * Text Domain: woocommerce-pdf-invoices-packing-slips * WC requires at least: 3.3 - * WC tested up to: 9.4 + * WC tested up to: 9.5 */ if ( ! defined( 'ABSPATH' ) ) { @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.1-beta-2'; + public $version = '3.9.1-beta-3'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; From a04f2b2339acb6e277889360a3c3c0a69f6746fe Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Wed, 11 Dec 2024 15:09:43 +0000 Subject: [PATCH 10/69] Update readme.txt --- readme.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.txt b/readme.txt index c6a8530cd..2bdcbb231 100644 --- a/readme.txt +++ b/readme.txt @@ -4,8 +4,8 @@ Donate link: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing- Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 -Requires PHP: 7.2 -Stable tag: 3.9.1-beta-2 +Requires PHP: 7.4 +Stable tag: 3.9.1-beta-3 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html From 3a41c2e1a1e24f4955ed7e494621488035040e78 Mon Sep 17 00:00:00 2001 From: Mohamad Nateqi Rostami Date: Wed, 11 Dec 2024 18:55:10 +0330 Subject: [PATCH 11/69] Add methods to get/print phone number --- includes/Documents/OrderDocument.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/includes/Documents/OrderDocument.php b/includes/Documents/OrderDocument.php index cabd24df9..d950a0243 100644 --- a/includes/Documents/OrderDocument.php +++ b/includes/Documents/OrderDocument.php @@ -1130,7 +1130,7 @@ public function header_logo(): void { $attachment_src = wp_get_attachment_image_url( $attachment_id, 'full' ); $attachment_path = wp_normalize_path( realpath( get_attached_file( $attachment_id ) ) ); $src = apply_filters( 'wpo_wcpdf_use_path', true ) ? $attachment_path : $attachment_src; - + if ( empty( $src ) ) { wcpdf_log_error( 'Header logo file not found.', 'critical' ); return; @@ -1229,6 +1229,16 @@ public function shop_address() { echo $this->get_shop_address(); } + /** + * Return/Show shop/company phone number if provided. + */ + public function get_shop_phone_number() { + return $this->get_settings_text( 'shop_phone_number' ); + } + public function shop_phone_number() { + echo $this->get_shop_phone_number(); + } + /** * Return/Show shop/company footer imprint, copyright etc. */ From e695f4dc76ea410adb427b9fe0d4232c9cc6dec8 Mon Sep 17 00:00:00 2001 From: Mohamad Nateqi Rostami Date: Wed, 11 Dec 2024 19:54:41 +0330 Subject: [PATCH 12/69] Add shop phone number setting to common setting getter --- includes/Settings.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/includes/Settings.php b/includes/Settings.php index 887c0f7eb..145bb4399 100644 --- a/includes/Settings.php +++ b/includes/Settings.php @@ -506,22 +506,27 @@ public function add_settings_fields( $settings_fields, $page, $option_group, $op } - public function get_common_document_settings() { - $common_settings = array( + /** + * Get document general settings. + * + * @return array + */ + public function get_common_document_settings(): array { + return array( 'paper_size' => isset( $this->general_settings['paper_size'] ) ? $this->general_settings['paper_size'] : '', - 'font_subsetting' => isset( $this->general_settings['font_subsetting'] ) || ( defined("DOMPDF_ENABLE_FONTSUBSETTING") && DOMPDF_ENABLE_FONTSUBSETTING === true ) ? true : false, + 'font_subsetting' => isset( $this->general_settings['font_subsetting'] ) || ( defined( "DOMPDF_ENABLE_FONTSUBSETTING" ) && DOMPDF_ENABLE_FONTSUBSETTING === true ) ? true : false, 'header_logo' => isset( $this->general_settings['header_logo'] ) ? $this->general_settings['header_logo'] : '', 'header_logo_height' => isset( $this->general_settings['header_logo_height'] ) ? $this->general_settings['header_logo_height'] : '', 'vat_number' => isset( $this->general_settings['vat_number'] ) ? $this->general_settings['vat_number'] : '', 'coc_number' => isset( $this->general_settings['coc_number'] ) ? $this->general_settings['coc_number'] : '', 'shop_name' => isset( $this->general_settings['shop_name'] ) ? $this->general_settings['shop_name'] : '', + 'shop_phone_number' => isset( $this->general_settings['shop_phone_number'] ) ? $this->general_settings['shop_phone_number'] : '', 'shop_address' => isset( $this->general_settings['shop_address'] ) ? $this->general_settings['shop_address'] : '', 'footer' => isset( $this->general_settings['footer'] ) ? $this->general_settings['footer'] : '', 'extra_1' => isset( $this->general_settings['extra_1'] ) ? $this->general_settings['extra_1'] : '', 'extra_2' => isset( $this->general_settings['extra_2'] ) ? $this->general_settings['extra_2'] : '', 'extra_3' => isset( $this->general_settings['extra_3'] ) ? $this->general_settings['extra_3'] : '', ); - return $common_settings; } public function get_document_settings( $document_type, $output_format = 'pdf' ) { From 23695ea809bb4193f743da2a5f9c34f94bb8d249 Mon Sep 17 00:00:00 2001 From: Mohamad Nateqi Rostami Date: Wed, 11 Dec 2024 19:57:42 +0330 Subject: [PATCH 13/69] Code improvements --- includes/Settings.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/includes/Settings.php b/includes/Settings.php index 145bb4399..600688855 100644 --- a/includes/Settings.php +++ b/includes/Settings.php @@ -513,19 +513,19 @@ public function add_settings_fields( $settings_fields, $page, $option_group, $op */ public function get_common_document_settings(): array { return array( - 'paper_size' => isset( $this->general_settings['paper_size'] ) ? $this->general_settings['paper_size'] : '', - 'font_subsetting' => isset( $this->general_settings['font_subsetting'] ) || ( defined( "DOMPDF_ENABLE_FONTSUBSETTING" ) && DOMPDF_ENABLE_FONTSUBSETTING === true ) ? true : false, - 'header_logo' => isset( $this->general_settings['header_logo'] ) ? $this->general_settings['header_logo'] : '', - 'header_logo_height' => isset( $this->general_settings['header_logo_height'] ) ? $this->general_settings['header_logo_height'] : '', - 'vat_number' => isset( $this->general_settings['vat_number'] ) ? $this->general_settings['vat_number'] : '', - 'coc_number' => isset( $this->general_settings['coc_number'] ) ? $this->general_settings['coc_number'] : '', - 'shop_name' => isset( $this->general_settings['shop_name'] ) ? $this->general_settings['shop_name'] : '', - 'shop_phone_number' => isset( $this->general_settings['shop_phone_number'] ) ? $this->general_settings['shop_phone_number'] : '', - 'shop_address' => isset( $this->general_settings['shop_address'] ) ? $this->general_settings['shop_address'] : '', - 'footer' => isset( $this->general_settings['footer'] ) ? $this->general_settings['footer'] : '', - 'extra_1' => isset( $this->general_settings['extra_1'] ) ? $this->general_settings['extra_1'] : '', - 'extra_2' => isset( $this->general_settings['extra_2'] ) ? $this->general_settings['extra_2'] : '', - 'extra_3' => isset( $this->general_settings['extra_3'] ) ? $this->general_settings['extra_3'] : '', + 'paper_size' => $this->general_settings['paper_size'] ?? '', + 'font_subsetting' => isset( $this->general_settings['font_subsetting'] ) || ( defined( "DOMPDF_ENABLE_FONTSUBSETTING" ) && DOMPDF_ENABLE_FONTSUBSETTING === true ), + 'header_logo' => $this->general_settings['header_logo'] ?? '', + 'header_logo_height' => $this->general_settings['header_logo_height'] ?? '', + 'vat_number' => $this->general_settings['vat_number'] ?? '', + 'coc_number' => $this->general_settings['coc_number'] ?? '', + 'shop_name' => $this->general_settings['shop_name'] ?? '', + 'shop_phone_number' => $this->general_settings['shop_phone_number'] ?? '', + 'shop_address' => $this->general_settings['shop_address'] ?? '', + 'footer' => $this->general_settings['footer'] ?? '', + 'extra_1' => $this->general_settings['extra_1'] ?? '', + 'extra_2' => $this->general_settings['extra_2'] ?? '', + 'extra_3' => $this->general_settings['extra_3'] ?? '', ); } From d9841cae0018d3193bbc41cd1fc52fe370eee02d Mon Sep 17 00:00:00 2001 From: Mohamad Nateqi Rostami Date: Wed, 11 Dec 2024 20:07:10 +0330 Subject: [PATCH 14/69] Fix get_shop_phone_number --- includes/Documents/OrderDocument.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/Documents/OrderDocument.php b/includes/Documents/OrderDocument.php index d950a0243..0ab5edcb6 100644 --- a/includes/Documents/OrderDocument.php +++ b/includes/Documents/OrderDocument.php @@ -1233,7 +1233,7 @@ public function shop_address() { * Return/Show shop/company phone number if provided. */ public function get_shop_phone_number() { - return $this->get_settings_text( 'shop_phone_number' ); + return $this->get_settings_text( 'shop_phone_number', '', false ); } public function shop_phone_number() { echo $this->get_shop_phone_number(); From 18d85caae2609d4f613d82f474afdb8245eb0461 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 13 Dec 2024 10:34:44 +0000 Subject: [PATCH 15/69] New: adds support for multiple UBL formats (#927) --- assets/js/admin-script.js | 11 +++++++++++ assets/js/admin-script.min.js | 2 +- includes/Documents/Invoice.php | 25 ++++++++++++++++++++----- includes/Documents/OrderDocument.php | 11 +++++++++++ includes/Settings/SettingsGeneral.php | 2 +- ubl/Builders/SabreBuilder.php | 2 +- ubl/Documents/Document.php | 1 + ubl/Documents/UblDocument.php | 8 ++++++-- 8 files changed, 52 insertions(+), 10 deletions(-) diff --git a/assets/js/admin-script.js b/assets/js/admin-script.js index 29ab0b02f..ba4046df8 100644 --- a/assets/js/admin-script.js +++ b/assets/js/admin-script.js @@ -55,6 +55,17 @@ jQuery( function( $ ) { $( this ).closest( 'tr' ).nextAll( 'tr' ).has( 'input#next_invoice_number' ).first().show(); } } ).trigger( 'change' ); + + // disable encrypted pdf option for non UBL 2.1 formats + $( "[name='wpo_wcpdf_documents_settings_invoice_ubl[ubl_format]']" ).on( 'change', function( event ) { + let $encryptedPdfCheckbox = $( this ).closest( 'form' ).find( "[name='wpo_wcpdf_documents_settings_invoice_ubl[include_encrypted_pdf]']" ); + + if ( $( this ).val() !== 'ubl_2_1' ) { + $encryptedPdfCheckbox.prop( 'checked', false ).prop( 'disabled', true ); + } else { + $encryptedPdfCheckbox.prop( 'disabled', false ); + } + } ).trigger( 'change' ); // enable settings document switch $( '.wcpdf_document_settings_sections > h2' ).on( 'click', function() { diff --git a/assets/js/admin-script.min.js b/assets/js/admin-script.min.js index 3b7f2d1de..c43e6e076 100644 --- a/assets/js/admin-script.min.js +++ b/assets/js/admin-script.min.js @@ -1 +1 @@ -jQuery(function(a){function b(){m=w.val(),n=x.val(),o=y.val(),p=z.val(),q=A.serialize()}function c(){w.val("").trigger("change")}function d(){!1==u.attr("data-preview-states-lock")&&(1200>=a(this).width()&&(1200=t||a(this).width()==t)&&("full"==u.attr("data-preview-state")?(u.find(".preview-document").show(),u.find(".sidebar").hide(),u.find(".slide-left").hide(),u.find(".slide-right").show(),u.attr("data-preview-states",3),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","sidebar"),u.addClass("static")):"closed"==u.attr("data-preview-state")&&a(this).width()!==t?(u.find(".preview-document").hide(),u.find(".sidebar").show(),u.find(".slide-left").show(),u.find(".slide-right").hide(),u.attr("data-preview-states",3),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state",""),u.removeClass("static")):(u.find(".preview-document, .sidebar").show(),u.find(".slide-left, .slide-right").show(),u.attr("data-preview-states",3),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state",""),u.removeClass("static")))),t=a(this).width()}function e(a){window.scrollTo(0,0);let b=a;setTimeout(function(){b.addClass("static")},300)}function f(b,c){g();let d=a(b.target);if(!i(d.attr("name"))){if(d.hasClass("remove-requirement")||"disable_for"==d.attr("id"))return;if(-1!==jQuery.inArray(b.type,["keyup","paste"])){if(d.is("input[type=\"checkbox\"], select"))return;c="keyup"==b.type?1e3:0}h(c)}}function g(b){a(".preview-data-wrapper .save-settings p").css("margin-right","0")}function h(a){a="number"==typeof a?a:0,b(),clearTimeout(r),r=setTimeout(function(){j()},a)}function i(b){let c=!1;if(!b)return c;let d=b.includes("[")?b.match(/\[(.*?)\]/)[1]:b;return-1!==a.inArray(d,wpo_wcpdf_admin.preview_excluded_settings)&&(c=!0),c}function j(){let b=wpo_wcpdf_admin.pdfjs_worker,c="preview-canvas",d={action:"wpo_wcpdf_preview",security:p,order_id:m,document_type:n,output_format:o,data:q};v.children(".notice").remove(),v.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),B=a.ajax({type:"POST",url:wpo_wcpdf_admin.ajaxurl,data:d,beforeSend:function(a,b){null!=B&&B.abort()},success:function(d,e,f){if(d.data.error)a("#"+c).remove(),v.append("

"+d.data.error+"

");else if(d.data.preview_data&&d.data.output_format)switch(a("#"+c).remove(),d.data.output_format){default:case"pdf":v.append(""),k(b,c,d.data.preview_data);break;case"ubl":let a=d.data.preview_data,e=a.replace(/&/g,"&").replace(//g,">").replace(/ /g," ").replace(/\n/g,"
");v.html("
"+e+"
")}v.unblock()},error:function(b,d,e){if("abort"!=d){let d=b.status+": "+b.statusText;a("#"+c).remove(),v.append("

"+d+"

"),v.unblock()}}})}function k(a,b,c){c=window.atob(c),pdfjsLib.GlobalWorkerOptions.workerSrc=a;let d=pdfjsLib.getDocument({data:c});d.promise.then(function(a){let c=1;a.getPage(1).then(function(a){let c=2,d=a.getViewport({scale:2}),e=document.getElementById(b),f=e.getContext("2d");e.height=d.height,e.width=d.width;let g={canvasContext:f,viewport:d},h=a.render(g);h.promise.then(function(){})})},function(a){console.error(a)})}function l(b){let c=b.closest(".preview-data").find("#preview-order-search-results"),d=b.val(),e=b.data("nonce"),f="wpo_wcpdf_preview_order_search",g={security:e,action:f,search:d,document_type:n};c.parent().find("img.preview-order-search-clear").hide(),c.children(".error").remove(),c.children("a").remove(),c.hide(),a.ajax({type:"POST",url:wpo_wcpdf_admin.ajaxurl,data:g,success:function(d){d.data&&(d.data.error?(c.append(""+d.data.error+""),c.show()):a.each(d.data,function(a,b){let d="#"+b.order_number+" - "+b.billing_first_name+" "+b.billing_last_name;0"+b.date_created+""+b.total+"";c.append(d+e),c.show()})),b.removeClass("ajax-waiting"),b.closest("div").find("img.preview-order-search-clear").show()}})}a(".wcpdf-extensions .more").hide(),a(".wcpdf-extensions > li").on("click",function(b){a(this).toggleClass("expanded"),a(this).find(".more").slideToggle()}),a(".edit-next-number").on("click",function(b){a(this).hide(),a(this).siblings("input").prop("disabled",!1),a(this).siblings(".save-next-number.button").show()}),a(".save-next-number").on("click",function(b){$input=a(this).siblings("input"),$input.addClass("ajax-waiting");let c=$input.val();if(0 h2").on("click",function(){a(this).parent().find("ul").toggleClass("active")}),a.each(wpo_wcpdf_admin.pointers,function(b,c){a(c.target).pointer({content:c.content,position:{edge:c.position.edge,align:c.position.align},pointerClass:c.pointer_class,pointerWidth:c.pointer_width,close:function(){jQuery.post(wpo_wcpdf_admin.ajaxurl,{pointer:b,action:"dismiss-wp-pointer"})}}),-1===a.inArray(b,wpo_wcpdf_admin.dismissed_pointers.split(","))&&a(c.target).pointer("open")}),a(".woocommerce-help-tip").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}),a("#wpo-wcpdf-preview-wrapper #due_date").on("change",function(){const b=a("#wpo-wcpdf-preview-wrapper #due_date"),c=a("#wpo-wcpdf-preview-wrapper #due_date_days");b.is(":checked")?c.prop("disabled",!1):c.prop("disabled",!0)}).trigger("change");let m,n,o,p,q,r,s,t,u=a("#wpo-wcpdf-preview-wrapper"),v=a("#wpo-wcpdf-preview-wrapper .preview"),w=a("#wpo-wcpdf-preview-wrapper input[name=\"order_id\"]"),x=a("#wpo-wcpdf-preview-wrapper input[name=\"document_type\"]"),y=a("#wpo-wcpdf-preview-wrapper input[name=\"output_format\"]"),z=a("#wpo-wcpdf-preview-wrapper input[name=\"nonce\"]"),A=a("#wpo-wcpdf-settings"),B=null;(function a(){x.val(x.data("default")).trigger("change")})(),c(),b(),t=a(window).width(),d(),a(window).on("resize",d),a(".slide-left").on("click",function(){let a=u.attr("data-preview-states"),b=u.attr("data-preview-state");u.find(".preview-data-wrapper ul").removeClass("active"),3==a?"closed"==b?(u.find(".preview-document").show(),u.find(".slide-right").show(),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state","closed")):(u.find(".slide-left").hide(),u.find(".sidebar").delay(300).hide(0),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","sidebar"),e(u)):(u.find(".preview-document").show(),u.find(".slide-left").hide(),u.find(".slide-right").show(),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","closed"),e(u))}),a(".slide-right").on("click",function(){let a=u.attr("data-preview-states"),b=u.attr("data-preview-state");u.find(".preview-data-wrapper ul").removeClass("active"),3==a?"full"==b?(u.find(".slide-left").delay(400).show(0),u.find(".sidebar").show(),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state","full")):(u.find(".preview-document").hide(300),u.find(".slide-right").hide(),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state","sidebar")):(u.find(".preview-document").hide(300),u.find(".slide-left").show(),u.find(".slide-right").hide(),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state","full")),u.removeClass("static")}),a(".preview-document .preview-data p").on("click",function(){let b=a(this).closest(".preview-data");b.siblings(".preview-data").find("ul").removeClass("active"),b.find("ul").toggleClass("active")}),a(".preview-document .preview-data ul > li").on("click",function(){let b=a(this).closest(".preview-data");b.find("ul").toggleClass("active"),a(this).hasClass("order-search")?(b.find("p.last-order").hide(),b.find("input[name=\"preview-order-search\"]").addClass("active"),b.find("p.order-search").show().find(".order-search-label").text(a(this).text())):(b.find("p.last-order").show(),b.find("p.order-search").hide(),b.find("input[name=\"preview-order-search\"]").removeClass("active").val(""),b.find("#preview-order-search-results").hide(),b.find("img.preview-order-search-clear").hide(),c(),h())}),h(),a(document).on("wpo-wcpdf-settings-changed",function(a,b){g(),h(b)}),a(document).on("wpo-wcpdf-refresh-preview wpo_wcpdf_refresh_preview",function(a,b){h(b)}),a(document).on("click","#preview-order-search-results a",function(b){b.preventDefault(),a(".preview-document .order-search-label").text("#"+a(this).data("order_id")),w.val(a(this).data("order_id")).trigger("change"),a(this).closest("div").hide(),a(this).closest("div").children("a").remove(),h()}),a(document).on("keyup paste","#wpo-wcpdf-settings input, #wpo-wcpdf-settings textarea",f),a(document).on("change","#wpo-wcpdf-settings input[type=\"checkbox\"], #wpo-wcpdf-settings input[type=\"radio\"], #wpo-wcpdf-settings select",function(a){a.isTrigger||f(a)}),a(document).on("select2:select select2:unselect","#wpo-wcpdf-settings select.wc-enhanced-select",f),a(document.body).on("wpo-wcpdf-media-upload-setting-updated",f),a(document).on("click",".wpo_remove_image_button, #wpo-wcpdf-settings .remove-requirement",f),a(document.body).on("click",".preview-data-wrapper .save-settings p input",function(b){a("#wpo-wcpdf-settings input#submit").trigger("click")}),a(document).on("click","img.preview-order-search-clear",function(b){b.preventDefault(),a(this).closest("div").find("input#preview-order-search").val(""),a(this).closest(".preview-data").find("#preview-order-search-results").children("a").remove(),a(this).closest(".preview-data").find("#preview-order-search-results").children(".error").remove(),a(this).closest(".preview-data").find("#preview-order-search-results").hide(),a(this).hide()}),a("#wpo-wcpdf-preview-wrapper ul.preview-data-option-list li").on("click",function(){let b=a(this).closest("ul").data("input-name"),c=a("#wpo-wcpdf-preview-wrapper :input[name="+b+"]");c.val(a(this).data("value")).trigger("change")}),x.on("change",function(){let b=a(this).val();if(b.length){let c=a(this).attr("name"),d=a("#wpo-wcpdf-preview-wrapper ul.preview-data-option-list[data-input-name="+c+"]"),e=d.find("li[data-value="+b+"]");d.parent().find(".current-label").text(e.text()),h()}}).trigger("change"),w.on("change",function(){h()}).trigger("change"),a("#preview-order-search").on("keyup paste",function(c){let d=a(this);d.addClass("ajax-waiting");let e="keyup"==c.type?1e3:0;b(),clearTimeout(s),s=setTimeout(function(){l(d)},e)}),function b(){a(".settings_category").not("#general").find(".form-table").hide(),a("#general > h2").addClass("active"),a(".settings_category h2").each(function(b){const c=localStorage.getItem("wcpdf_accordion_state_"+b);"true"===c&&a(this).addClass("active").next(".form-table").show()}),a(".settings_category h2").on("click",function(){const b=a(".settings_category h2").index(this);a(this).toggleClass("active").next(".form-table").slideToggle("fast",function(){const c=a(this).is(":visible");localStorage.setItem("wcpdf_accordion_state_"+b,c)})})}()}); \ No newline at end of file +jQuery(function(a){function b(){m=w.val(),n=x.val(),o=y.val(),p=z.val(),q=A.serialize()}function c(){w.val("").trigger("change")}function d(){!1==u.attr("data-preview-states-lock")&&(1200>=a(this).width()&&(1200=t||a(this).width()==t)&&("full"==u.attr("data-preview-state")?(u.find(".preview-document").show(),u.find(".sidebar").hide(),u.find(".slide-left").hide(),u.find(".slide-right").show(),u.attr("data-preview-states",3),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","sidebar"),u.addClass("static")):"closed"==u.attr("data-preview-state")&&a(this).width()!==t?(u.find(".preview-document").hide(),u.find(".sidebar").show(),u.find(".slide-left").show(),u.find(".slide-right").hide(),u.attr("data-preview-states",3),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state",""),u.removeClass("static")):(u.find(".preview-document, .sidebar").show(),u.find(".slide-left, .slide-right").show(),u.attr("data-preview-states",3),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state",""),u.removeClass("static")))),t=a(this).width()}function e(a){window.scrollTo(0,0);let b=a;setTimeout(function(){b.addClass("static")},300)}function f(b,c){g();let d=a(b.target);if(!i(d.attr("name"))){if(d.hasClass("remove-requirement")||"disable_for"==d.attr("id"))return;if(-1!==jQuery.inArray(b.type,["keyup","paste"])){if(d.is("input[type=\"checkbox\"], select"))return;c="keyup"==b.type?1e3:0}h(c)}}function g(b){a(".preview-data-wrapper .save-settings p").css("margin-right","0")}function h(a){a="number"==typeof a?a:0,b(),clearTimeout(r),r=setTimeout(function(){j()},a)}function i(b){let c=!1;if(!b)return c;let d=b.includes("[")?b.match(/\[(.*?)\]/)[1]:b;return-1!==a.inArray(d,wpo_wcpdf_admin.preview_excluded_settings)&&(c=!0),c}function j(){let b=wpo_wcpdf_admin.pdfjs_worker,c="preview-canvas",d={action:"wpo_wcpdf_preview",security:p,order_id:m,document_type:n,output_format:o,data:q};v.children(".notice").remove(),v.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),B=a.ajax({type:"POST",url:wpo_wcpdf_admin.ajaxurl,data:d,beforeSend:function(a,b){null!=B&&B.abort()},success:function(d,e,f){if(d.data.error)a("#"+c).remove(),v.append("

"+d.data.error+"

");else if(d.data.preview_data&&d.data.output_format)switch(a("#"+c).remove(),d.data.output_format){default:case"pdf":v.append(""),k(b,c,d.data.preview_data);break;case"ubl":let a=d.data.preview_data,e=a.replace(/&/g,"&").replace(//g,">").replace(/ /g," ").replace(/\n/g,"
");v.html("
"+e+"
")}v.unblock()},error:function(b,d,e){if("abort"!=d){let d=b.status+": "+b.statusText;a("#"+c).remove(),v.append("

"+d+"

"),v.unblock()}}})}function k(a,b,c){c=window.atob(c),pdfjsLib.GlobalWorkerOptions.workerSrc=a;let d=pdfjsLib.getDocument({data:c});d.promise.then(function(a){let c=1;a.getPage(1).then(function(a){let c=2,d=a.getViewport({scale:2}),e=document.getElementById(b),f=e.getContext("2d");e.height=d.height,e.width=d.width;let g={canvasContext:f,viewport:d},h=a.render(g);h.promise.then(function(){})})},function(a){console.error(a)})}function l(b){let c=b.closest(".preview-data").find("#preview-order-search-results"),d=b.val(),e=b.data("nonce"),f="wpo_wcpdf_preview_order_search",g={security:e,action:f,search:d,document_type:n};c.parent().find("img.preview-order-search-clear").hide(),c.children(".error").remove(),c.children("a").remove(),c.hide(),a.ajax({type:"POST",url:wpo_wcpdf_admin.ajaxurl,data:g,success:function(d){d.data&&(d.data.error?(c.append(""+d.data.error+""),c.show()):a.each(d.data,function(a,b){let d="#"+b.order_number+" - "+b.billing_first_name+" "+b.billing_last_name;0"+b.date_created+""+b.total+"";c.append(d+e),c.show()})),b.removeClass("ajax-waiting"),b.closest("div").find("img.preview-order-search-clear").show()}})}a(".wcpdf-extensions .more").hide(),a(".wcpdf-extensions > li").on("click",function(b){a(this).toggleClass("expanded"),a(this).find(".more").slideToggle()}),a(".edit-next-number").on("click",function(b){a(this).hide(),a(this).siblings("input").prop("disabled",!1),a(this).siblings(".save-next-number.button").show()}),a(".save-next-number").on("click",function(b){$input=a(this).siblings("input"),$input.addClass("ajax-waiting");let c=$input.val();if(0 h2").on("click",function(){a(this).parent().find("ul").toggleClass("active")}),a.each(wpo_wcpdf_admin.pointers,function(b,c){a(c.target).pointer({content:c.content,position:{edge:c.position.edge,align:c.position.align},pointerClass:c.pointer_class,pointerWidth:c.pointer_width,close:function(){jQuery.post(wpo_wcpdf_admin.ajaxurl,{pointer:b,action:"dismiss-wp-pointer"})}}),-1===a.inArray(b,wpo_wcpdf_admin.dismissed_pointers.split(","))&&a(c.target).pointer("open")}),a(".woocommerce-help-tip").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}),a("#wpo-wcpdf-preview-wrapper #due_date").on("change",function(){const b=a("#wpo-wcpdf-preview-wrapper #due_date"),c=a("#wpo-wcpdf-preview-wrapper #due_date_days");b.is(":checked")?c.prop("disabled",!1):c.prop("disabled",!0)}).trigger("change");let m,n,o,p,q,r,s,t,u=a("#wpo-wcpdf-preview-wrapper"),v=a("#wpo-wcpdf-preview-wrapper .preview"),w=a("#wpo-wcpdf-preview-wrapper input[name=\"order_id\"]"),x=a("#wpo-wcpdf-preview-wrapper input[name=\"document_type\"]"),y=a("#wpo-wcpdf-preview-wrapper input[name=\"output_format\"]"),z=a("#wpo-wcpdf-preview-wrapper input[name=\"nonce\"]"),A=a("#wpo-wcpdf-settings"),B=null;(function a(){x.val(x.data("default")).trigger("change")})(),c(),b(),t=a(window).width(),d(),a(window).on("resize",d),a(".slide-left").on("click",function(){let a=u.attr("data-preview-states"),b=u.attr("data-preview-state");u.find(".preview-data-wrapper ul").removeClass("active"),3==a?"closed"==b?(u.find(".preview-document").show(),u.find(".slide-right").show(),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state","closed")):(u.find(".slide-left").hide(),u.find(".sidebar").delay(300).hide(0),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","sidebar"),e(u)):(u.find(".preview-document").show(),u.find(".slide-left").hide(),u.find(".slide-right").show(),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","closed"),e(u))}),a(".slide-right").on("click",function(){let a=u.attr("data-preview-states"),b=u.attr("data-preview-state");u.find(".preview-data-wrapper ul").removeClass("active"),3==a?"full"==b?(u.find(".slide-left").delay(400).show(0),u.find(".sidebar").show(),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state","full")):(u.find(".preview-document").hide(300),u.find(".slide-right").hide(),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state","sidebar")):(u.find(".preview-document").hide(300),u.find(".slide-left").show(),u.find(".slide-right").hide(),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state","full")),u.removeClass("static")}),a(".preview-document .preview-data p").on("click",function(){let b=a(this).closest(".preview-data");b.siblings(".preview-data").find("ul").removeClass("active"),b.find("ul").toggleClass("active")}),a(".preview-document .preview-data ul > li").on("click",function(){let b=a(this).closest(".preview-data");b.find("ul").toggleClass("active"),a(this).hasClass("order-search")?(b.find("p.last-order").hide(),b.find("input[name=\"preview-order-search\"]").addClass("active"),b.find("p.order-search").show().find(".order-search-label").text(a(this).text())):(b.find("p.last-order").show(),b.find("p.order-search").hide(),b.find("input[name=\"preview-order-search\"]").removeClass("active").val(""),b.find("#preview-order-search-results").hide(),b.find("img.preview-order-search-clear").hide(),c(),h())}),h(),a(document).on("wpo-wcpdf-settings-changed",function(a,b){g(),h(b)}),a(document).on("wpo-wcpdf-refresh-preview wpo_wcpdf_refresh_preview",function(a,b){h(b)}),a(document).on("click","#preview-order-search-results a",function(b){b.preventDefault(),a(".preview-document .order-search-label").text("#"+a(this).data("order_id")),w.val(a(this).data("order_id")).trigger("change"),a(this).closest("div").hide(),a(this).closest("div").children("a").remove(),h()}),a(document).on("keyup paste","#wpo-wcpdf-settings input, #wpo-wcpdf-settings textarea",f),a(document).on("change","#wpo-wcpdf-settings input[type=\"checkbox\"], #wpo-wcpdf-settings input[type=\"radio\"], #wpo-wcpdf-settings select",function(a){a.isTrigger||f(a)}),a(document).on("select2:select select2:unselect","#wpo-wcpdf-settings select.wc-enhanced-select",f),a(document.body).on("wpo-wcpdf-media-upload-setting-updated",f),a(document).on("click",".wpo_remove_image_button, #wpo-wcpdf-settings .remove-requirement",f),a(document.body).on("click",".preview-data-wrapper .save-settings p input",function(b){a("#wpo-wcpdf-settings input#submit").trigger("click")}),a(document).on("click","img.preview-order-search-clear",function(b){b.preventDefault(),a(this).closest("div").find("input#preview-order-search").val(""),a(this).closest(".preview-data").find("#preview-order-search-results").children("a").remove(),a(this).closest(".preview-data").find("#preview-order-search-results").children(".error").remove(),a(this).closest(".preview-data").find("#preview-order-search-results").hide(),a(this).hide()}),a("#wpo-wcpdf-preview-wrapper ul.preview-data-option-list li").on("click",function(){let b=a(this).closest("ul").data("input-name"),c=a("#wpo-wcpdf-preview-wrapper :input[name="+b+"]");c.val(a(this).data("value")).trigger("change")}),x.on("change",function(){let b=a(this).val();if(b.length){let c=a(this).attr("name"),d=a("#wpo-wcpdf-preview-wrapper ul.preview-data-option-list[data-input-name="+c+"]"),e=d.find("li[data-value="+b+"]");d.parent().find(".current-label").text(e.text()),h()}}).trigger("change"),w.on("change",function(){h()}).trigger("change"),a("#preview-order-search").on("keyup paste",function(c){let d=a(this);d.addClass("ajax-waiting");let e="keyup"==c.type?1e3:0;b(),clearTimeout(s),s=setTimeout(function(){l(d)},e)}),function b(){a(".settings_category").not("#general").find(".form-table").hide(),a("#general > h2").addClass("active"),a(".settings_category h2").each(function(b){const c=localStorage.getItem("wcpdf_accordion_state_"+b);"true"===c&&a(this).addClass("active").next(".form-table").show()}),a(".settings_category h2").on("click",function(){const b=a(".settings_category h2").index(this);a(this).toggleClass("active").next(".form-table").slideToggle("fast",function(){const c=a(this).is(":visible");localStorage.setItem("wcpdf_accordion_state_"+b,c)})})}()}); \ No newline at end of file diff --git a/includes/Documents/Invoice.php b/includes/Documents/Invoice.php index 7c3d6203f..7dd214c58 100644 --- a/includes/Documents/Invoice.php +++ b/includes/Documents/Invoice.php @@ -579,7 +579,7 @@ public function get_ubl_settings_fields( $option_name ) { $settings_fields = array( array( 'type' => 'section', - 'id' => $this->type.'_ubl', + 'id' => $this->type . '_ubl', 'title' => '', 'callback' => 'section', ), @@ -588,18 +588,32 @@ public function get_ubl_settings_fields( $option_name ) { 'id' => 'enabled', 'title' => __( 'Enable', 'woocommerce-pdf-invoices-packing-slips' ), 'callback' => 'checkbox', - 'section' => $this->type.'_ubl', + 'section' => $this->type . '_ubl', 'args' => array( 'option_name' => $option_name, 'id' => 'enabled', ) ), + array( + 'type' => 'setting', + 'id' => 'ubl_format', + 'title' => __( 'Format', 'woocommerce-pdf-invoices-packing-slips' ), + 'callback' => 'select', + 'section' => $this->type . '_ubl', + 'args' => array( + 'option_name' => $option_name, + 'id' => 'ubl_format', + 'options' => apply_filters( 'wpo_wcpdf_document_ubl_settings_formats', array( + 'ubl_2_1' => __( 'UBL 2.1' , 'woocommerce-pdf-invoices-packing-slips' ), + ), $this ), + ) + ), array( 'type' => 'setting', 'id' => 'attach_to_email_ids', 'title' => __( 'Attach to:', 'woocommerce-pdf-invoices-packing-slips' ), 'callback' => 'multiple_checkboxes', - 'section' => $this->type.'_ubl', + 'section' => $this->type . '_ubl', 'args' => array( 'option_name' => $option_name, 'id' => 'attach_to_email_ids', @@ -613,11 +627,11 @@ public function get_ubl_settings_fields( $option_name ) { 'id' => 'include_encrypted_pdf', 'title' => __( 'Include encrypted PDF:', 'woocommerce-pdf-invoices-packing-slips' ), 'callback' => 'checkbox', - 'section' => $this->type.'_ubl', + 'section' => $this->type . '_ubl', 'args' => array( 'option_name' => $option_name, 'id' => 'include_encrypted_pdf', - 'description' => __( 'Include the PDF Invoice file encrypted in the UBL file.', 'woocommerce-pdf-invoices-packing-slips' ), + 'description' => __( 'Embed the encrypted PDF invoice file within the UBL document. Note that this option may not be supported by all UBL formats.', 'woocommerce-pdf-invoices-packing-slips' ), ) ), ); @@ -687,6 +701,7 @@ public function get_settings_categories( string $output_format ): array { 'title' => __( 'General', 'woocommerce-pdf-invoices-packing-slips' ), 'members' => array( 'enabled', + 'ubl_format', 'attach_to_email_ids', 'include_encrypted_pdf', ), diff --git a/includes/Documents/OrderDocument.php b/includes/Documents/OrderDocument.php index 0ab5edcb6..2e2490f3c 100644 --- a/includes/Documents/OrderDocument.php +++ b/includes/Documents/OrderDocument.php @@ -342,6 +342,17 @@ public function is_enabled( $output_format = 'pdf' ) { return apply_filters( 'wpo_wcpdf_document_is_enabled', $is_enabled, $this->type, $output_format ); } + + /** + * Get the UBL format + * + * @return string|false + */ + public function get_ubl_format() { + $ubl_format = $this->get_setting( 'ubl_format', false, 'ubl' ); + + return apply_filters( 'wpo_wcpdf_document_ubl_format', $ubl_format, $this ); + } public function get_hook_prefix() { return 'wpo_wcpdf_' . $this->slug . '_get_'; diff --git a/includes/Settings/SettingsGeneral.php b/includes/Settings/SettingsGeneral.php index 5e80c9506..da9bab033 100644 --- a/includes/Settings/SettingsGeneral.php +++ b/includes/Settings/SettingsGeneral.php @@ -207,7 +207,7 @@ public function init_settings() { 'option_name' => $option_name, 'id' => 'shop_phone_number', 'translatable' => true, -// 'description' => __( 'Required for e-Invoice.', 'woocommerce-pdf-invoices-packing-slips' ), + 'description' => __( 'Mandatory for certain UBL formats.', 'woocommerce-pdf-invoices-packing-slips' ), ) ), array( diff --git a/ubl/Builders/SabreBuilder.php b/ubl/Builders/SabreBuilder.php index 6b8676de7..f9eda847a 100644 --- a/ubl/Builders/SabreBuilder.php +++ b/ubl/Builders/SabreBuilder.php @@ -23,7 +23,7 @@ public function build( Document $document ) { $namespaces = array_flip( $document->get_namespaces() ); $this->service->namespaceMap = $namespaces; - return $this->service->write( 'Invoice', $document->get_data() ); + return $this->service->write( $document->get_root_element(), $document->get_data() ); } } diff --git a/ubl/Documents/Document.php b/ubl/Documents/Document.php index 2ce96d446..c9b38bca9 100644 --- a/ubl/Documents/Document.php +++ b/ubl/Documents/Document.php @@ -31,6 +31,7 @@ public function set_order_document( OrderDocument $order_document ) { $this->order_document = $order_document; } + abstract public function get_root_element(); abstract public function get_format(); abstract public function get_namespaces(); abstract public function get_data(); diff --git a/ubl/Documents/UblDocument.php b/ubl/Documents/UblDocument.php index cfa85f15d..6d48cfbd8 100644 --- a/ubl/Documents/UblDocument.php +++ b/ubl/Documents/UblDocument.php @@ -9,6 +9,10 @@ } class UblDocument extends Document { + + public function get_root_element() { + return apply_filters( 'wpo_wc_ubl_document_root_element', 'Invoice', $this ); + } public function get_format() { $format = apply_filters( 'wpo_wc_ubl_document_format' , array( @@ -82,7 +86,7 @@ public function get_format() { 'enabled' => true, 'handler' => \WPO\IPS\UBL\Handlers\Invoice\InvoiceLineHandler::class, ), - ) ); + ), $this ); foreach ( $format as $key => $element ) { if ( false === $element['enabled'] ) { @@ -98,7 +102,7 @@ public function get_namespaces() { 'cac' => 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2', 'cbc' => 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2', '' => 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2', - ) ); + ), $this ); } public function get_data() { From dc9c8a0d074a570b0d44460e5c256468e484d6d5 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 13 Dec 2024 10:41:08 +0000 Subject: [PATCH 16/69] v3.9.1-beta-4 --- readme.txt | 2 +- woocommerce-pdf-invoices-packingslips.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.txt b/readme.txt index 2bdcbb231..826a37d6d 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 Requires PHP: 7.4 -Stable tag: 3.9.1-beta-3 +Stable tag: 3.9.1-beta-4 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index d39f0084f..c57f423b7 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,7 +4,7 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.1-beta-3 + * Version: 3.9.1-beta-4 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.1-beta-3'; + public $version = '3.9.1-beta-4'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; From a4bf98e4f2605769837a14dd87dfca7b3f701fec Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 13 Dec 2024 12:21:33 +0000 Subject: [PATCH 17/69] Update settings-styles.css --- assets/css/settings-styles.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assets/css/settings-styles.css b/assets/css/settings-styles.css index a883b8c46..a62674491 100644 --- a/assets/css/settings-styles.css +++ b/assets/css/settings-styles.css @@ -393,6 +393,12 @@ body.woocommerce_page_wpo_wcpdf_options_page { padding-top: 0.7em; } +#wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td p.description > span.wpo-warning { + width: 100%; + box-sizing: border-box; + word-wrap: break-word; +} + #wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td > input[type="text"], #wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td > input[type="url"], #wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td > select, From 7a3ab4a08be88825e6a64fccda31e41cbfc969ea Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 13 Dec 2024 12:23:19 +0000 Subject: [PATCH 18/69] Revert "Update settings-styles.css" This reverts commit a4bf98e4f2605769837a14dd87dfca7b3f701fec. --- assets/css/settings-styles.css | 6 ------ 1 file changed, 6 deletions(-) diff --git a/assets/css/settings-styles.css b/assets/css/settings-styles.css index a62674491..a883b8c46 100644 --- a/assets/css/settings-styles.css +++ b/assets/css/settings-styles.css @@ -393,12 +393,6 @@ body.woocommerce_page_wpo_wcpdf_options_page { padding-top: 0.7em; } -#wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td p.description > span.wpo-warning { - width: 100%; - box-sizing: border-box; - word-wrap: break-word; -} - #wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td > input[type="text"], #wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td > input[type="url"], #wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td > select, From b1b50b8a79ab6a5a0a59cf2f68b15372b16d9273 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 13 Dec 2024 12:28:14 +0000 Subject: [PATCH 19/69] Fix: AJAX preview loading when disabled on settings pages (#928) --- assets/js/admin-script.js | 14 +++++++++++--- assets/js/admin-script.min.js | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/assets/js/admin-script.js b/assets/js/admin-script.js index ba4046df8..ad8f7e413 100644 --- a/assets/js/admin-script.js +++ b/assets/js/admin-script.js @@ -55,11 +55,11 @@ jQuery( function( $ ) { $( this ).closest( 'tr' ).nextAll( 'tr' ).has( 'input#next_invoice_number' ).first().show(); } } ).trigger( 'change' ); - + // disable encrypted pdf option for non UBL 2.1 formats $( "[name='wpo_wcpdf_documents_settings_invoice_ubl[ubl_format]']" ).on( 'change', function( event ) { let $encryptedPdfCheckbox = $( this ).closest( 'form' ).find( "[name='wpo_wcpdf_documents_settings_invoice_ubl[include_encrypted_pdf]']" ); - + if ( $( this ).val() !== 'ubl_2_1' ) { $encryptedPdfCheckbox.prop( 'checked', false ).prop( 'disabled', true ); } else { @@ -384,7 +384,14 @@ jQuery( function( $ ) { } ); // Trigger the Preview - function triggerPreview( timeoutDuration ) { + function triggerPreview( timeoutDuration = 0 ) { + $previewStates = $( '#wpo-wcpdf-preview-wrapper' ).data( 'preview-states' ); + + // Check if preview is disabled and return + if ( 'undefined' === $previewStates || 1 === $previewStates ) { + return; + } + timeoutDuration = typeof timeoutDuration == 'number' ? timeoutDuration : 0; loadPreviewData(); @@ -441,6 +448,7 @@ jQuery( function( $ ) { // Load the Preview with AJAX function ajaxLoadPreview() { + console.log( 'Loading preview...' ); let worker = wpo_wcpdf_admin.pdfjs_worker; let canvasId = 'preview-canvas'; let data = { diff --git a/assets/js/admin-script.min.js b/assets/js/admin-script.min.js index c43e6e076..40823d016 100644 --- a/assets/js/admin-script.min.js +++ b/assets/js/admin-script.min.js @@ -1 +1 @@ -jQuery(function(a){function b(){m=w.val(),n=x.val(),o=y.val(),p=z.val(),q=A.serialize()}function c(){w.val("").trigger("change")}function d(){!1==u.attr("data-preview-states-lock")&&(1200>=a(this).width()&&(1200=t||a(this).width()==t)&&("full"==u.attr("data-preview-state")?(u.find(".preview-document").show(),u.find(".sidebar").hide(),u.find(".slide-left").hide(),u.find(".slide-right").show(),u.attr("data-preview-states",3),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","sidebar"),u.addClass("static")):"closed"==u.attr("data-preview-state")&&a(this).width()!==t?(u.find(".preview-document").hide(),u.find(".sidebar").show(),u.find(".slide-left").show(),u.find(".slide-right").hide(),u.attr("data-preview-states",3),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state",""),u.removeClass("static")):(u.find(".preview-document, .sidebar").show(),u.find(".slide-left, .slide-right").show(),u.attr("data-preview-states",3),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state",""),u.removeClass("static")))),t=a(this).width()}function e(a){window.scrollTo(0,0);let b=a;setTimeout(function(){b.addClass("static")},300)}function f(b,c){g();let d=a(b.target);if(!i(d.attr("name"))){if(d.hasClass("remove-requirement")||"disable_for"==d.attr("id"))return;if(-1!==jQuery.inArray(b.type,["keyup","paste"])){if(d.is("input[type=\"checkbox\"], select"))return;c="keyup"==b.type?1e3:0}h(c)}}function g(b){a(".preview-data-wrapper .save-settings p").css("margin-right","0")}function h(a){a="number"==typeof a?a:0,b(),clearTimeout(r),r=setTimeout(function(){j()},a)}function i(b){let c=!1;if(!b)return c;let d=b.includes("[")?b.match(/\[(.*?)\]/)[1]:b;return-1!==a.inArray(d,wpo_wcpdf_admin.preview_excluded_settings)&&(c=!0),c}function j(){let b=wpo_wcpdf_admin.pdfjs_worker,c="preview-canvas",d={action:"wpo_wcpdf_preview",security:p,order_id:m,document_type:n,output_format:o,data:q};v.children(".notice").remove(),v.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),B=a.ajax({type:"POST",url:wpo_wcpdf_admin.ajaxurl,data:d,beforeSend:function(a,b){null!=B&&B.abort()},success:function(d,e,f){if(d.data.error)a("#"+c).remove(),v.append("

"+d.data.error+"

");else if(d.data.preview_data&&d.data.output_format)switch(a("#"+c).remove(),d.data.output_format){default:case"pdf":v.append(""),k(b,c,d.data.preview_data);break;case"ubl":let a=d.data.preview_data,e=a.replace(/&/g,"&").replace(//g,">").replace(/ /g," ").replace(/\n/g,"
");v.html("
"+e+"
")}v.unblock()},error:function(b,d,e){if("abort"!=d){let d=b.status+": "+b.statusText;a("#"+c).remove(),v.append("

"+d+"

"),v.unblock()}}})}function k(a,b,c){c=window.atob(c),pdfjsLib.GlobalWorkerOptions.workerSrc=a;let d=pdfjsLib.getDocument({data:c});d.promise.then(function(a){let c=1;a.getPage(1).then(function(a){let c=2,d=a.getViewport({scale:2}),e=document.getElementById(b),f=e.getContext("2d");e.height=d.height,e.width=d.width;let g={canvasContext:f,viewport:d},h=a.render(g);h.promise.then(function(){})})},function(a){console.error(a)})}function l(b){let c=b.closest(".preview-data").find("#preview-order-search-results"),d=b.val(),e=b.data("nonce"),f="wpo_wcpdf_preview_order_search",g={security:e,action:f,search:d,document_type:n};c.parent().find("img.preview-order-search-clear").hide(),c.children(".error").remove(),c.children("a").remove(),c.hide(),a.ajax({type:"POST",url:wpo_wcpdf_admin.ajaxurl,data:g,success:function(d){d.data&&(d.data.error?(c.append(""+d.data.error+""),c.show()):a.each(d.data,function(a,b){let d="#"+b.order_number+" - "+b.billing_first_name+" "+b.billing_last_name;0"+b.date_created+""+b.total+"";c.append(d+e),c.show()})),b.removeClass("ajax-waiting"),b.closest("div").find("img.preview-order-search-clear").show()}})}a(".wcpdf-extensions .more").hide(),a(".wcpdf-extensions > li").on("click",function(b){a(this).toggleClass("expanded"),a(this).find(".more").slideToggle()}),a(".edit-next-number").on("click",function(b){a(this).hide(),a(this).siblings("input").prop("disabled",!1),a(this).siblings(".save-next-number.button").show()}),a(".save-next-number").on("click",function(b){$input=a(this).siblings("input"),$input.addClass("ajax-waiting");let c=$input.val();if(0 h2").on("click",function(){a(this).parent().find("ul").toggleClass("active")}),a.each(wpo_wcpdf_admin.pointers,function(b,c){a(c.target).pointer({content:c.content,position:{edge:c.position.edge,align:c.position.align},pointerClass:c.pointer_class,pointerWidth:c.pointer_width,close:function(){jQuery.post(wpo_wcpdf_admin.ajaxurl,{pointer:b,action:"dismiss-wp-pointer"})}}),-1===a.inArray(b,wpo_wcpdf_admin.dismissed_pointers.split(","))&&a(c.target).pointer("open")}),a(".woocommerce-help-tip").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}),a("#wpo-wcpdf-preview-wrapper #due_date").on("change",function(){const b=a("#wpo-wcpdf-preview-wrapper #due_date"),c=a("#wpo-wcpdf-preview-wrapper #due_date_days");b.is(":checked")?c.prop("disabled",!1):c.prop("disabled",!0)}).trigger("change");let m,n,o,p,q,r,s,t,u=a("#wpo-wcpdf-preview-wrapper"),v=a("#wpo-wcpdf-preview-wrapper .preview"),w=a("#wpo-wcpdf-preview-wrapper input[name=\"order_id\"]"),x=a("#wpo-wcpdf-preview-wrapper input[name=\"document_type\"]"),y=a("#wpo-wcpdf-preview-wrapper input[name=\"output_format\"]"),z=a("#wpo-wcpdf-preview-wrapper input[name=\"nonce\"]"),A=a("#wpo-wcpdf-settings"),B=null;(function a(){x.val(x.data("default")).trigger("change")})(),c(),b(),t=a(window).width(),d(),a(window).on("resize",d),a(".slide-left").on("click",function(){let a=u.attr("data-preview-states"),b=u.attr("data-preview-state");u.find(".preview-data-wrapper ul").removeClass("active"),3==a?"closed"==b?(u.find(".preview-document").show(),u.find(".slide-right").show(),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state","closed")):(u.find(".slide-left").hide(),u.find(".sidebar").delay(300).hide(0),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","sidebar"),e(u)):(u.find(".preview-document").show(),u.find(".slide-left").hide(),u.find(".slide-right").show(),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","closed"),e(u))}),a(".slide-right").on("click",function(){let a=u.attr("data-preview-states"),b=u.attr("data-preview-state");u.find(".preview-data-wrapper ul").removeClass("active"),3==a?"full"==b?(u.find(".slide-left").delay(400).show(0),u.find(".sidebar").show(),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state","full")):(u.find(".preview-document").hide(300),u.find(".slide-right").hide(),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state","sidebar")):(u.find(".preview-document").hide(300),u.find(".slide-left").show(),u.find(".slide-right").hide(),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state","full")),u.removeClass("static")}),a(".preview-document .preview-data p").on("click",function(){let b=a(this).closest(".preview-data");b.siblings(".preview-data").find("ul").removeClass("active"),b.find("ul").toggleClass("active")}),a(".preview-document .preview-data ul > li").on("click",function(){let b=a(this).closest(".preview-data");b.find("ul").toggleClass("active"),a(this).hasClass("order-search")?(b.find("p.last-order").hide(),b.find("input[name=\"preview-order-search\"]").addClass("active"),b.find("p.order-search").show().find(".order-search-label").text(a(this).text())):(b.find("p.last-order").show(),b.find("p.order-search").hide(),b.find("input[name=\"preview-order-search\"]").removeClass("active").val(""),b.find("#preview-order-search-results").hide(),b.find("img.preview-order-search-clear").hide(),c(),h())}),h(),a(document).on("wpo-wcpdf-settings-changed",function(a,b){g(),h(b)}),a(document).on("wpo-wcpdf-refresh-preview wpo_wcpdf_refresh_preview",function(a,b){h(b)}),a(document).on("click","#preview-order-search-results a",function(b){b.preventDefault(),a(".preview-document .order-search-label").text("#"+a(this).data("order_id")),w.val(a(this).data("order_id")).trigger("change"),a(this).closest("div").hide(),a(this).closest("div").children("a").remove(),h()}),a(document).on("keyup paste","#wpo-wcpdf-settings input, #wpo-wcpdf-settings textarea",f),a(document).on("change","#wpo-wcpdf-settings input[type=\"checkbox\"], #wpo-wcpdf-settings input[type=\"radio\"], #wpo-wcpdf-settings select",function(a){a.isTrigger||f(a)}),a(document).on("select2:select select2:unselect","#wpo-wcpdf-settings select.wc-enhanced-select",f),a(document.body).on("wpo-wcpdf-media-upload-setting-updated",f),a(document).on("click",".wpo_remove_image_button, #wpo-wcpdf-settings .remove-requirement",f),a(document.body).on("click",".preview-data-wrapper .save-settings p input",function(b){a("#wpo-wcpdf-settings input#submit").trigger("click")}),a(document).on("click","img.preview-order-search-clear",function(b){b.preventDefault(),a(this).closest("div").find("input#preview-order-search").val(""),a(this).closest(".preview-data").find("#preview-order-search-results").children("a").remove(),a(this).closest(".preview-data").find("#preview-order-search-results").children(".error").remove(),a(this).closest(".preview-data").find("#preview-order-search-results").hide(),a(this).hide()}),a("#wpo-wcpdf-preview-wrapper ul.preview-data-option-list li").on("click",function(){let b=a(this).closest("ul").data("input-name"),c=a("#wpo-wcpdf-preview-wrapper :input[name="+b+"]");c.val(a(this).data("value")).trigger("change")}),x.on("change",function(){let b=a(this).val();if(b.length){let c=a(this).attr("name"),d=a("#wpo-wcpdf-preview-wrapper ul.preview-data-option-list[data-input-name="+c+"]"),e=d.find("li[data-value="+b+"]");d.parent().find(".current-label").text(e.text()),h()}}).trigger("change"),w.on("change",function(){h()}).trigger("change"),a("#preview-order-search").on("keyup paste",function(c){let d=a(this);d.addClass("ajax-waiting");let e="keyup"==c.type?1e3:0;b(),clearTimeout(s),s=setTimeout(function(){l(d)},e)}),function b(){a(".settings_category").not("#general").find(".form-table").hide(),a("#general > h2").addClass("active"),a(".settings_category h2").each(function(b){const c=localStorage.getItem("wcpdf_accordion_state_"+b);"true"===c&&a(this).addClass("active").next(".form-table").show()}),a(".settings_category h2").on("click",function(){const b=a(".settings_category h2").index(this);a(this).toggleClass("active").next(".form-table").slideToggle("fast",function(){const c=a(this).is(":visible");localStorage.setItem("wcpdf_accordion_state_"+b,c)})})}()}); \ No newline at end of file +jQuery(function(a){function b(){m=w.val(),n=x.val(),o=y.val(),p=z.val(),q=A.serialize()}function c(){w.val("").trigger("change")}function d(){!1==u.attr("data-preview-states-lock")&&(1200>=a(this).width()&&(1200=t||a(this).width()==t)&&("full"==u.attr("data-preview-state")?(u.find(".preview-document").show(),u.find(".sidebar").hide(),u.find(".slide-left").hide(),u.find(".slide-right").show(),u.attr("data-preview-states",3),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","sidebar"),u.addClass("static")):"closed"==u.attr("data-preview-state")&&a(this).width()!==t?(u.find(".preview-document").hide(),u.find(".sidebar").show(),u.find(".slide-left").show(),u.find(".slide-right").hide(),u.attr("data-preview-states",3),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state",""),u.removeClass("static")):(u.find(".preview-document, .sidebar").show(),u.find(".slide-left, .slide-right").show(),u.attr("data-preview-states",3),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state",""),u.removeClass("static")))),t=a(this).width()}function e(a){window.scrollTo(0,0);let b=a;setTimeout(function(){b.addClass("static")},300)}function f(b,c){g();let d=a(b.target);if(!i(d.attr("name"))){if(d.hasClass("remove-requirement")||"disable_for"==d.attr("id"))return;if(-1!==jQuery.inArray(b.type,["keyup","paste"])){if(d.is("input[type=\"checkbox\"], select"))return;c="keyup"==b.type?1e3:0}h(c)}}function g(b){a(".preview-data-wrapper .save-settings p").css("margin-right","0")}function h(c=0){$previewStates=a("#wpo-wcpdf-preview-wrapper").data("preview-states");"undefined"===$previewStates||1===$previewStates||(c="number"==typeof c?c:0,b(),clearTimeout(r),r=setTimeout(function(){j()},c))}function i(b){let c=!1;if(!b)return c;let d=b.includes("[")?b.match(/\[(.*?)\]/)[1]:b;return-1!==a.inArray(d,wpo_wcpdf_admin.preview_excluded_settings)&&(c=!0),c}function j(){console.log("Loading preview...");let b=wpo_wcpdf_admin.pdfjs_worker,c="preview-canvas",d={action:"wpo_wcpdf_preview",security:p,order_id:m,document_type:n,output_format:o,data:q};v.children(".notice").remove(),v.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),B=a.ajax({type:"POST",url:wpo_wcpdf_admin.ajaxurl,data:d,beforeSend:function(a,b){null!=B&&B.abort()},success:function(d,e,f){if(d.data.error)a("#"+c).remove(),v.append("

"+d.data.error+"

");else if(d.data.preview_data&&d.data.output_format)switch(a("#"+c).remove(),d.data.output_format){default:case"pdf":v.append(""),k(b,c,d.data.preview_data);break;case"ubl":let a=d.data.preview_data,e=a.replace(/&/g,"&").replace(//g,">").replace(/ /g," ").replace(/\n/g,"
");v.html("
"+e+"
")}v.unblock()},error:function(b,d,e){if("abort"!=d){let d=b.status+": "+b.statusText;a("#"+c).remove(),v.append("

"+d+"

"),v.unblock()}}})}function k(a,b,c){c=window.atob(c),pdfjsLib.GlobalWorkerOptions.workerSrc=a;let d=pdfjsLib.getDocument({data:c});d.promise.then(function(a){let c=1;a.getPage(1).then(function(a){let c=2,d=a.getViewport({scale:2}),e=document.getElementById(b),f=e.getContext("2d");e.height=d.height,e.width=d.width;let g={canvasContext:f,viewport:d},h=a.render(g);h.promise.then(function(){})})},function(a){console.error(a)})}function l(b){let c=b.closest(".preview-data").find("#preview-order-search-results"),d=b.val(),e=b.data("nonce"),f="wpo_wcpdf_preview_order_search",g={security:e,action:f,search:d,document_type:n};c.parent().find("img.preview-order-search-clear").hide(),c.children(".error").remove(),c.children("a").remove(),c.hide(),a.ajax({type:"POST",url:wpo_wcpdf_admin.ajaxurl,data:g,success:function(d){d.data&&(d.data.error?(c.append(""+d.data.error+""),c.show()):a.each(d.data,function(a,b){let d="#"+b.order_number+" - "+b.billing_first_name+" "+b.billing_last_name;0"+b.date_created+""+b.total+"";c.append(d+e),c.show()})),b.removeClass("ajax-waiting"),b.closest("div").find("img.preview-order-search-clear").show()}})}a(".wcpdf-extensions .more").hide(),a(".wcpdf-extensions > li").on("click",function(b){a(this).toggleClass("expanded"),a(this).find(".more").slideToggle()}),a(".edit-next-number").on("click",function(b){a(this).hide(),a(this).siblings("input").prop("disabled",!1),a(this).siblings(".save-next-number.button").show()}),a(".save-next-number").on("click",function(b){$input=a(this).siblings("input"),$input.addClass("ajax-waiting");let c=$input.val();if(0 h2").on("click",function(){a(this).parent().find("ul").toggleClass("active")}),a.each(wpo_wcpdf_admin.pointers,function(b,c){a(c.target).pointer({content:c.content,position:{edge:c.position.edge,align:c.position.align},pointerClass:c.pointer_class,pointerWidth:c.pointer_width,close:function(){jQuery.post(wpo_wcpdf_admin.ajaxurl,{pointer:b,action:"dismiss-wp-pointer"})}}),-1===a.inArray(b,wpo_wcpdf_admin.dismissed_pointers.split(","))&&a(c.target).pointer("open")}),a(".woocommerce-help-tip").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}),a("#wpo-wcpdf-preview-wrapper #due_date").on("change",function(){const b=a("#wpo-wcpdf-preview-wrapper #due_date"),c=a("#wpo-wcpdf-preview-wrapper #due_date_days");b.is(":checked")?c.prop("disabled",!1):c.prop("disabled",!0)}).trigger("change");let m,n,o,p,q,r,s,t,u=a("#wpo-wcpdf-preview-wrapper"),v=a("#wpo-wcpdf-preview-wrapper .preview"),w=a("#wpo-wcpdf-preview-wrapper input[name=\"order_id\"]"),x=a("#wpo-wcpdf-preview-wrapper input[name=\"document_type\"]"),y=a("#wpo-wcpdf-preview-wrapper input[name=\"output_format\"]"),z=a("#wpo-wcpdf-preview-wrapper input[name=\"nonce\"]"),A=a("#wpo-wcpdf-settings"),B=null;(function a(){x.val(x.data("default")).trigger("change")})(),c(),b(),t=a(window).width(),d(),a(window).on("resize",d),a(".slide-left").on("click",function(){let a=u.attr("data-preview-states"),b=u.attr("data-preview-state");u.find(".preview-data-wrapper ul").removeClass("active"),3==a?"closed"==b?(u.find(".preview-document").show(),u.find(".slide-right").show(),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state","closed")):(u.find(".slide-left").hide(),u.find(".sidebar").delay(300).hide(0),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","sidebar"),e(u)):(u.find(".preview-document").show(),u.find(".slide-left").hide(),u.find(".slide-right").show(),u.attr("data-preview-state","full"),u.attr("data-from-preview-state","closed"),e(u))}),a(".slide-right").on("click",function(){let a=u.attr("data-preview-states"),b=u.attr("data-preview-state");u.find(".preview-data-wrapper ul").removeClass("active"),3==a?"full"==b?(u.find(".slide-left").delay(400).show(0),u.find(".sidebar").show(),u.attr("data-preview-state","sidebar"),u.attr("data-from-preview-state","full")):(u.find(".preview-document").hide(300),u.find(".slide-right").hide(),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state","sidebar")):(u.find(".preview-document").hide(300),u.find(".slide-left").show(),u.find(".slide-right").hide(),u.attr("data-preview-state","closed"),u.attr("data-from-preview-state","full")),u.removeClass("static")}),a(".preview-document .preview-data p").on("click",function(){let b=a(this).closest(".preview-data");b.siblings(".preview-data").find("ul").removeClass("active"),b.find("ul").toggleClass("active")}),a(".preview-document .preview-data ul > li").on("click",function(){let b=a(this).closest(".preview-data");b.find("ul").toggleClass("active"),a(this).hasClass("order-search")?(b.find("p.last-order").hide(),b.find("input[name=\"preview-order-search\"]").addClass("active"),b.find("p.order-search").show().find(".order-search-label").text(a(this).text())):(b.find("p.last-order").show(),b.find("p.order-search").hide(),b.find("input[name=\"preview-order-search\"]").removeClass("active").val(""),b.find("#preview-order-search-results").hide(),b.find("img.preview-order-search-clear").hide(),c(),h())}),h(),a(document).on("wpo-wcpdf-settings-changed",function(a,b){g(),h(b)}),a(document).on("wpo-wcpdf-refresh-preview wpo_wcpdf_refresh_preview",function(a,b){h(b)}),a(document).on("click","#preview-order-search-results a",function(b){b.preventDefault(),a(".preview-document .order-search-label").text("#"+a(this).data("order_id")),w.val(a(this).data("order_id")).trigger("change"),a(this).closest("div").hide(),a(this).closest("div").children("a").remove(),h()}),a(document).on("keyup paste","#wpo-wcpdf-settings input, #wpo-wcpdf-settings textarea",f),a(document).on("change","#wpo-wcpdf-settings input[type=\"checkbox\"], #wpo-wcpdf-settings input[type=\"radio\"], #wpo-wcpdf-settings select",function(a){a.isTrigger||f(a)}),a(document).on("select2:select select2:unselect","#wpo-wcpdf-settings select.wc-enhanced-select",f),a(document.body).on("wpo-wcpdf-media-upload-setting-updated",f),a(document).on("click",".wpo_remove_image_button, #wpo-wcpdf-settings .remove-requirement",f),a(document.body).on("click",".preview-data-wrapper .save-settings p input",function(b){a("#wpo-wcpdf-settings input#submit").trigger("click")}),a(document).on("click","img.preview-order-search-clear",function(b){b.preventDefault(),a(this).closest("div").find("input#preview-order-search").val(""),a(this).closest(".preview-data").find("#preview-order-search-results").children("a").remove(),a(this).closest(".preview-data").find("#preview-order-search-results").children(".error").remove(),a(this).closest(".preview-data").find("#preview-order-search-results").hide(),a(this).hide()}),a("#wpo-wcpdf-preview-wrapper ul.preview-data-option-list li").on("click",function(){let b=a(this).closest("ul").data("input-name"),c=a("#wpo-wcpdf-preview-wrapper :input[name="+b+"]");c.val(a(this).data("value")).trigger("change")}),x.on("change",function(){let b=a(this).val();if(b.length){let c=a(this).attr("name"),d=a("#wpo-wcpdf-preview-wrapper ul.preview-data-option-list[data-input-name="+c+"]"),e=d.find("li[data-value="+b+"]");d.parent().find(".current-label").text(e.text()),h()}}).trigger("change"),w.on("change",function(){h()}).trigger("change"),a("#preview-order-search").on("keyup paste",function(c){let d=a(this);d.addClass("ajax-waiting");let e="keyup"==c.type?1e3:0;b(),clearTimeout(s),s=setTimeout(function(){l(d)},e)}),function b(){a(".settings_category").not("#general").find(".form-table").hide(),a("#general > h2").addClass("active"),a(".settings_category h2").each(function(b){const c=localStorage.getItem("wcpdf_accordion_state_"+b);"true"===c&&a(this).addClass("active").next(".form-table").show()}),a(".settings_category h2").on("click",function(){const b=a(".settings_category h2").index(this);a(this).toggleClass("active").next(".form-table").slideToggle("fast",function(){const c=a(this).is(":visible");localStorage.setItem("wcpdf_accordion_state_"+b,c)})})}()}); \ No newline at end of file From d26222fb7abaa71b434a524a74ec87d6889ac0d0 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 13 Dec 2024 12:36:21 +0000 Subject: [PATCH 20/69] Remove unused legacy notice code: `check_auto_increment_increment()` --- includes/Settings.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/includes/Settings.php b/includes/Settings.php index 600688855..869b75aea 100644 --- a/includes/Settings.php +++ b/includes/Settings.php @@ -62,9 +62,6 @@ public function __construct() { // settings capabilities add_filter( 'option_page_capability_wpo_wcpdf_general_settings', array( $this, 'user_settings_capability' ) ); - // admin notice for auto_increment_increment - // add_action( 'admin_notices', array( $this, 'check_auto_increment_increment') ); - // AJAX set number store add_action( 'wp_ajax_wpo_wcpdf_set_next_number', array( $this, 'set_number_store' ) ); @@ -157,17 +154,6 @@ public function user_can_manage_settings() { return current_user_can( $this->user_settings_capability() ); } - function check_auto_increment_increment() { - global $wpdb; - $row = $wpdb->get_row( "SHOW VARIABLES LIKE 'auto_increment_increment'" ); - if ( ! empty( $row ) && ! empty( $row->Value ) && $row->Value != 1 ) { - /* translators: database row value */ - $error = wp_kses_post( sprintf( __( "Warning! Your database has an AUTO_INCREMENT step size of %d, your invoice numbers may not be sequential. Enable the 'Calculate document numbers (slow)' setting in the Advanced tab to use an alternate method." , 'woocommerce-pdf-invoices-packing-slips' ), intval( $row->Value ) ) ); - printf( '

%s

', $error ); - } - } - - public function settings_page() { // feedback on settings save settings_errors(); From 7b55afdad8248e44c127194500d3d705360e5a71 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 13 Dec 2024 12:41:03 +0000 Subject: [PATCH 21/69] Fix: temp folder warning style issue (#930) --- assets/css/settings-styles.css | 6 ++++++ assets/css/settings-styles.min.css | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/assets/css/settings-styles.css b/assets/css/settings-styles.css index a883b8c46..a62674491 100644 --- a/assets/css/settings-styles.css +++ b/assets/css/settings-styles.css @@ -393,6 +393,12 @@ body.woocommerce_page_wpo_wcpdf_options_page { padding-top: 0.7em; } +#wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td p.description > span.wpo-warning { + width: 100%; + box-sizing: border-box; + word-wrap: break-word; +} + #wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td > input[type="text"], #wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td > input[type="url"], #wpo-wcpdf-preview-wrapper .sidebar .form-table > tbody > tr > td > select, diff --git a/assets/css/settings-styles.min.css b/assets/css/settings-styles.min.css index a28f7ba40..26706dc55 100644 --- a/assets/css/settings-styles.min.css +++ b/assets/css/settings-styles.min.css @@ -1 +1 @@ -span.wpo-warning{display:inline-block;border:1px solid red;border-left:4px solid red;padding:5px 15px;background-color:#fff}.wcpdf-extensions-ad,.wcpdf-promo-ad{position:relative;min-height:90px;border:1px solid #6e1edc;background-color:#f1e9fc;padding:15px;padding-left:100px;margin-top:30px}img.wpo-helper{position:absolute;bottom:0;left:3px}.wcpdf-extensions-ad h3,.wcpdf-promo-ad h3{margin:0;padding:20px;font-weight:400;font-family:serif;letter-spacing:-1px;font-size:2.25em}.wcpdf-promo-ad p{margin:0;padding:0 20px;font-size:1.15em}.wcpdf-promo-ad p.upgrade-tab{margin-top:30px;font-style:italic;font-size:1em}.wcpdf-promo-ad p.expiration{font-size:.8em;padding-top:8px}.wcpdf-extensions-ad a,.wcpdf-promo-ad a{color:#6e1edc}.wcpdf-extensions-ad a.dismiss,.wcpdf-promo-ad a.dismiss{padding:10px 20px}.wcpdf-promo-ad p strong.code{font-size:1.3em;font-family:serif;padding:.1em .4em;background:#6e1edc;color:#fff;border-radius:5px;font-weight:400}.wcpdf-extensions-ad i{padding-left:20px}.wcpdf-extensions-ad ul,.wcpdf-promo-ad ul{margin:0;margin-left:40px}.wcpdf-extensions li{margin:0}.wcpdf-extensions li ul{list-style-type:square;margin-top:.5em;margin-bottom:.5em}.wcpdf-extensions>li:before{content:"";border-color:transparent transparent transparent #111;border-style:solid;border-width:.35em .35em .35em .45em;display:block;height:0;width:0;left:-1em;top:.9em;position:relative}.wcpdf-extensions li:not(.expanded){cursor:pointer}.wcpdf-extensions .expanded:before{border-color:#111 transparent transparent transparent;left:-1.17em;border-width:.45em .45em .35em .35em!important}.wcpdf-extensions .more{padding:10px;background-color:#fff;border:1px solid #ccc;border-radius:5px}.wcpdf-extensions table td{vertical-align:top}.dropbox-logo{margin-bottom:-10px;margin-right:10px}.cloud-logo{margin-bottom:-10px;margin-top:-5px;margin-right:10px}#img-header_logo{max-height:200px;width:auto;max-width:100%}.multiple-text-input label{padding-right:1em}table.multiple-text-input td{padding:0}table.wcpdf_documents_settings_list{width:100%;border-collapse:collapse;border-spacing:0;background-color:#fff;border-top:2px solid #000}table.wcpdf_documents_settings_list tr.odd{background-color:#ebf5ff}table.wcpdf_documents_settings_list td{padding:5px}table.wcpdf_documents_settings_list a{text-decoration:none}table.wcpdf_documents_settings_list td.settings-icon{text-align:right}table.wcpdf_documents_settings_list td.title{font-weight:700}.wcpdf-settings-sections ul{height:3em}.wcpdf-settings-sections ul li{float:left;margin-right:10px}.wcpdf-settings-sections ul li a{text-decoration:none;display:inline-block;padding:.8em 1em;color:#50575e;border:1px solid #c3c4c7;box-sizing:border-box}.wcpdf-settings-sections ul li a.active{border:2px solid #51266b;padding:calc(.8em - 1px) calc(1em - 1px);color:#000}.wcpdf_document_settings_sections{position:relative}.wcpdf_document_settings_sections>h2{cursor:pointer;padding:1em .8em;margin:0;border:1px solid #c3c4c7;background:#fff}.wcpdf_document_settings_sections ul{background:#fff;list-style:none;margin:0;padding:0;width:100%;display:block;height:auto;display:none;box-sizing:border-box;position:absolute;border-left:1px solid #c3c4c7;border-right:1px solid #c3c4c7;z-index:1000;box-shadow:0 35px 35px -8px rgba(0,0,0,.1);-webkit-box-shadow:0 35px 35px -8px rgba(0,0,0,.1)}.wcpdf_document_settings_sections ul.active{display:block}.wcpdf_document_settings_sections ul li{box-sizing:border-box;padding:0;margin-bottom:0;border-bottom:1px solid #eaeaea;font-size:1.1em}.wcpdf_document_settings_sections ul li:last-child{border-color:#c3c4c7}.wcpdf_document_settings_sections ul li:hover{cursor:pointer;background:#51266b;color:#fff}.wcpdf_document_settings_sections ul li:hover a{color:#fff}.wcpdf_document_settings_sections ul li a{color:#000;text-decoration:none;padding:1.2em 1.6em;display:block}.wcpdf_document_settings_sections .arrow-down{font-size:.7em;color:#999;margin-left:8px;font-weight:400;float:right}.wcpdf_document_settings_sections p:hover,.wcpdf_document_settings_sections p:hover>.arrow-down{color:#222}.wcpdf_advanced_numbers_choose_table{margin-top:20px}.wcpdf_document_settings_document_output_formats{margin-bottom:30px}.edit-next-number{opacity:.5}.edit-next-number:hover{opacity:1;cursor:pointer}.wpo-wcpdf-pointer.wp-pointer-top .wp-pointer-arrow,.wpo-wcpdf-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#51266b}.wpo-wcpdf-pointer .wp-pointer-content h3{border-color:#51266b;background:#51266b}.wpo-wcpdf-pointer .wp-pointer-content h3:before{color:#51266b}body.woocommerce_page_wpo_wcpdf_options_page{background:#fdfdfd}.wrap [class$=icon32]+h2{font-size:18px;padding:1em}.wrap .notice{margin:15px 0 0}.nav-tab-wrapper:not(.wcpdf_debug_settings_sections>.nav-tab-wrapper) a.nav-tab{background:0 0;border:none;border-bottom:3px solid transparent;padding:1em 0;margin:0 1.2em;font-size:15px}.nav-tab-wrapper:not(.wcpdf_debug_settings_sections>.nav-tab-wrapper) a.nav-tab.nav-tab-active{border-bottom:3px solid #51266b}#wpo-wcpdf-preview-wrapper{width:100%;height:auto;position:relative;display:flex;align-items:flex-start}#wpo-wcpdf-preview-wrapper .preview-document,#wpo-wcpdf-preview-wrapper .sidebar{transition:.3s ease-in-out}#wpo-wcpdf-preview-wrapper .sidebar{height:auto;padding:4em 0 0 0;box-sizing:border-box;background:0 0;flex:0 0 35%;overflow-x:hidden}#wpo-wcpdf-preview-wrapper .sidebar>form{background:0 0!important;overflow:visible;padding:0;margin-left:2em;box-sizing:border-box;width:calc(100% - 4em);max-width:50vw}#wpo-wcpdf-preview-wrapper .sidebar>form.editor{max-width:none}#wpo-wcpdf-preview-wrapper .sidebar .form-table,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>th{display:block;width:100%;padding:0}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>th{padding-bottom:.6em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr:not(:last-child)>td{padding-bottom:2.4em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td p.description{font-size:.85em;padding-top:.7em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input[type=text],#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input[type=url],#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>select,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>textarea{max-width:none;width:100%}#wpo-wcpdf-preview-wrapper input[type=text][size],#wpo-wcpdf-preview-wrapper input[type=url][size]{width:auto!important;max-width:100%!important}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input#next_invoice_number{width:auto!important}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{display:grid;grid-template-columns:1fr 2fr;gap:4em}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2{border-bottom:1px solid #c3c4c7;padding:1em 0 1em 5px;margin:0;font-weight:400;color:#222;font-family:sans-serif;font-size:1.3em;letter-spacing:-.01em;position:relative;transition:transform .3s;cursor:pointer}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2~.form-table{border-left:1px solid #c3c4c7;border-right:1px solid #c3c4c7;border-bottom:1px solid #c3c4c7;padding:2em;margin-top:-1px;background:#fff;margin-bottom:20px}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2::after{content:'\f347';font-family:dashicons;font-size:16px;color:#82878c;position:absolute;right:5px;top:50%;transform:translateY(-50%);transition:transform .15s}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2:hover:after{color:#222}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2.active::after{transform:translateY(-50%) rotate(180deg)}#wpo-wcpdf-preview-wrapper .my_account_buttons_custom{margin-top:1em}#wpo-wcpdf-settings .form-table .ui-tabs-nav{padding-left:0!important;margin-left:0!important}#wpo-wcpdf-settings .translations input,#wpo-wcpdf-settings .translations textarea{width:100%}#wpo-wcpdf-settings .wcpdf-attachment-settings-hint{border-left:4px solid #51266b}#wpo-wcpdf-settings .notice-info.inline{border-left-color:#51266b}#wpo-wcpdf-settings table#document-link-access-type{margin-top:-15px}#wpo-wcpdf-settings table#document-link-access-type td.option{padding-left:0}#wpo-wcpdf-settings table#document-link-access-type td{padding-top:0;padding-bottom:6px;font-size:12px}#wpo-wcpdf-settings .system-status-table{margin-top:2em}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar{flex:0 0 100%}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=full] .sidebar{flex:0 0 95%;margin-left:-95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .sidebar{flex:0 0 35%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=full] .sidebar{margin-left:-35%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] .sidebar{transition-delay:.4s}#wpo-wcpdf-preview-wrapper .preview-document{padding:0;box-sizing:border-box;position:sticky;top:2.4em;flex:0 0 60%}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .preview-document{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .preview-document{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=full] .preview-document{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .preview-document{flex:0 0 60%;margin-right:-60%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .preview-document{flex:0 0 60%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=full] .preview-document{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] .preview-document{transition-delay:.4s}.preview-document .preview{width:100%;box-sizing:border-box;padding-right:5%}.preview-document .preview>#preview-ubl{width:100%;height:100%;overflow-wrap:anywhere;background-color:#222;color:#fff;padding:2em}.preview-document .preview>#preview-canvas{display:block;max-width:800px;max-height:85vh;width:auto!important;margin:0 auto;background:#fff;box-shadow:8px 8px 8px rgba(0,0,0,.1),-8px -8px 8px rgba(0,0,0,.02);-webkit-box-shadow:8px 8px 8px rgba(0,0,0,.1),-8px -8px 8px rgba(0,0,0,.02)}#wpo-wcpdf-preview-wrapper[data-preview-states="2"] #preview-canvas{max-height:170vh}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=sidebar] #preview-canvas{max-height:170vh;transition:max-height .4s ease-in-out .3s}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] #preview-canvas{transition:max-height .4s ease-in-out 0s}.preview-document .preview-data-wrapper{width:100%;height:4em}.preview-document .preview-data-wrapper .preview-document-type,.preview-document .preview-data-wrapper .preview-order-data{float:right}.preview-document .preview-data-wrapper .preview-document-type{margin-right:30px}.preview-document .preview-data-wrapper .preview-document-type ul>li{text-decoration:none;color:initial;padding:1.4em 1.6em}.preview-document .preview-data-wrapper .preview-document-type ul>li:hover{color:#fff!important}.preview-document .preview-data-wrapper .save-settings{padding:1em 0 0 0;float:right;overflow:hidden;position:relative}.preview-document .preview-data-wrapper .save-settings p{padding:0;margin:0 0 0 2em;position:relative;margin-right:-200px;transition:margin-right .3s ease-out}.preview-document .preview-data-wrapper .save-settings p:after{content:'';display:block;pointer-events:none;position:absolute;box-sizing:border-box;border-radius:3px;right:0;top:0;background:0 0;width:100%;height:100%;z-index:10;border:0 solid #fff;animation:border-pulse 4s infinite}@keyframes border-pulse{0%{border-color:rgba(255,255,255,0);border-width:8px}50%{border-color:#fff;border-width:0}}.preview-document .preview-data-wrapper .save-settings p input:focus{outline-width:0;box-shadow:none}.preview-document .preview-data p{padding:1.4em 0;margin:0;color:#666;text-align:right;cursor:pointer;font-weight:lighter;float:right}.preview-document .preview-data p.order-search{display:none}.preview-document .preview-data input{float:right;margin:1em 0 0 1em;padding:.1em .5em;width:20ch;margin-right:-25ch;display:none}.preview-document .preview-data input.active{margin-right:0;display:inline-block}.preview-document .preview-data ul{position:absolute;right:0;top:4em;background:#fff;box-shadow:0 0 25px -10px rgba(0,0,0,.2);-webkit-box-shadow:0 0 25px -10px rgba(0,0,0,.2);list-style:none;margin:0;padding:0;min-width:24em;display:block;height:0;overflow:hidden}.preview-document .preview-data ul.active{height:auto;z-index:1}.preview-document .preview-data ul li{box-sizing:border-box;padding:0;margin-bottom:0;border-bottom:1px solid #eaeaea;font-size:1.1em}.preview-document .preview-data ul li:hover{cursor:pointer;background:#51266b;color:#fff}.preview-document .preview-data ul li a,.preview-document .preview-data.preview-order-data ul li{display:block;padding:1.4em 1.6em}.preview-document .preview-data .arrow-down{font-size:.8em;color:#999;margin-left:8px}.preview-document .preview-data p:hover,.preview-document .preview-data p:hover>.arrow-down{color:#222}.preview-document .preview-data #preview-order-search-results{display:none;position:absolute;right:0;top:4em;width:300px;box-shadow:0 0 25px -10px rgba(0,0,0,.2);-webkit-box-shadow:0 0 25px -10px rgba(0,0,0,.2);padding:20px 0;background-color:#fff;z-index:99}.preview-document .preview-data #preview-order-search-results a{display:block;border-left:1px solid #999;border-right:1px solid #999;border-top:1px solid #999;color:#000;padding:10px;margin:0 20px;text-decoration:none;cursor:pointer}.preview-document .preview-data #preview-order-search-results a:last-child{border-bottom:1px solid #999}.preview-document .preview-data #preview-order-search-results a:hover{background-color:#51266b;color:#fff}.preview-document .preview-data #preview-order-search-results .order-number{font-weight:700}.preview-document .preview-data #preview-order-search-results .date,.preview-document .preview-data #preview-order-search-results .total{margin-top:6px;display:inline-block}.preview-document .preview-data #preview-order-search-results .total{float:right}.preview-document .preview-data #preview-order-search-results .error{margin:0 20px}.preview-document .preview-order-search-wrapper{position:relative;float:right}.preview-document .preview-order-search-wrapper img.preview-order-search-clear{position:absolute;width:30px;height:16px;top:22px;right:6px;display:none;cursor:pointer}#wpo-wcpdf-preview-wrapper .gutter{flex:0 0 5%;position:sticky;top:2.4em;height:170vh}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .gutter .slide-left,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .gutter .slide-left{float:right}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .gutter .slide-left{border:none}#wpo-wcpdf-preview-wrapper .slider{box-sizing:border-box;padding-top:2.4em;color:#999;font-weight:700;cursor:pointer;font-size:.7em;line-height:1em;width:50%;height:100%;float:left}#wpo-wcpdf-preview-wrapper .slider.slide-left{text-align:right;padding-right:10px;border-right:1px solid #ccc}#wpo-wcpdf-preview-wrapper .slider.slide-right{text-align:left;padding-left:10px;border-left:1px solid #ccc;display:none}#wpo-wcpdf-preview-wrapper .gutter-arrow{width:0;height:0;border-top:3px solid transparent;border-bottom:3px solid transparent;display:block}#wpo-wcpdf-preview-wrapper .arrow-left{border-right:7px solid #999;float:right}#wpo-wcpdf-preview-wrapper .arrow-right{border-left:7px solid #999}#wpo-wcpdf-preview-wrapper .slider:hover>.arrow-left{border-right:7px solid #222}#wpo-wcpdf-preview-wrapper .slider:hover>.arrow-right{border-left:7px solid #222}#wpo-wcpdf-preview-wrapper .slider.slide-left:after{position:absolute;top:1.55em;right:2em;font-size:1.4em;display:none}#wpo-wcpdf-preview-wrapper .slider.slide-right:after{position:absolute;top:1.55em;left:2em;font-size:1.4em;display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .gutter{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .gutter{height:100vh}#wpo-wcpdf-preview-wrapper[data-preview-state=full] .slide-right:after{display:inline-block}#wpo-wcpdf-preview-wrapper[data-preview-state=closed] .slide-left:after{display:inline-block}#wpo-wcpdf-preview-wrapper.static .gutter,#wpo-wcpdf-preview-wrapper.static .preview-document{position:static!important}#wpo-wcpdf-preview-wrapper.static .sidebar{height:170vh!important;overflow:hidden}#wpo-wcpdf-preview-wrapper input.readonly,#wpo-wcpdf-preview-wrapper input[readonly],#wpo-wcpdf-preview-wrapper textarea.readonly,#wpo-wcpdf-preview-wrapper textarea[readonly]{background-color:#f8f8f8}#wpo-wcpdf-preview-wrapper[data-preview-state=sidebar] .select2.select2-container{width:100%!important}.wcpdf_ubl_settings_sections{margin-bottom:4em}#wpo-wcpdf-preview-wrapper input#due_date_days{text-align:right}#wpo-wcpdf-preview-wrapper input#due_date_days:disabled{background-color:#eaeaea;color:#999}sup.wcpdf_beta{background-color:#51266b;color:#fff;font-size:7pt;padding:1px 2px;border-radius:2px}@media screen and (min-width:1920px){.preview-document .preview>#preview-canvas{max-width:900px}}@media screen and (max-width:1200px){.preview-document .preview>#preview-canvas{max-width:680px}.nav-tab-wrapper a.nav-tab{padding:1em 2em;margin:0 .5em .5em 0;border:1px solid #ccc;box-sizing:border-box;height:4em}.nav-tab-wrapper a.nav-tab.nav-tab-active{border:3px solid #51266b}.preview-document .preview>#preview-canvas{width:80vw!important}#wpo-wcpdf-preview-wrapper .sidebar>form{max-width:100%}#wpo-wcpdf-preview-wrapper[data-preview-state=closed] .select2.select2-container{width:100%!important}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{gap:2em}.preview-document .preview-data-wrapper{height:6em}.preview-document .preview-data p{padding:2.2em 0}#wpo-wcpdf-preview-wrapper .slider.slide-left:after,#wpo-wcpdf-preview-wrapper .slider.slide-right:after{top:1.5em;padding:1em;background:#fff;border:1px solid #ccc}#wpo-wcpdf-preview-wrapper .slider.slide-right:after{left:0}#wpo-wcpdf-preview-wrapper .slider.slide-left:after{right:0}#wpo-wcpdf-preview-wrapper .multiple-text-input tr td:nth-child(2),#wpo-wcpdf-preview-wrapper .multiple-text-input tr td:nth-child(3){float:left;margin-bottom:10px}#wpo-wcpdf-preview-wrapper .multiple-text-input tr td .woocommerce-help-tip:after{padding:.5em .8em;font-size:1.2em;line-height:inherit}}@media screen and (max-width:860px){#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{display:block}}div.upgrade-table-description{padding:0 0 3em 1em}div.upgrade-table-description h1{font-family:serif;letter-spacing:-1px;font-size:3em}div.upgrade-table-description p{font-size:1.1em}#upgrade-table{width:100%;border-collapse:collapse;font-size:1.2em;margin-bottom:3em}#upgrade-table td,#upgrade-table th{padding:.8em 2em;border-bottom:1px solid #ccc;text-align:center}#upgrade-table th{font-weight:400;font-size:1.1em}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:200px}#upgrade-table tr:last-child td{border:none}#upgrade-table td.feature-label{text-align:left;padding-left:1em;font-weight:700;width:500px}#upgrade-table td.feature-label span.description{display:inline-block;padding-top:10px;font-size:.8em;line-height:1.4em;font-weight:400;color:#555}#upgrade-table td span.feature-available{display:inline-block;width:24px;height:24px;background-repeat:no-repeat;background-size:cover}#upgrade-table a,div.upgrade-table-description a{color:#6e1edc;white-space:nowrap}#upgrade-table .upgrade-links h4{margin:1em 0 .5em 0}#upgrade-table .upgrade-links p{margin:0;font-style:oblique;font-size:.8em}#plugin-recommendations a.upgrade_button,#upgrade-table .upgrade-links a.upgrade_button{display:inline-block;background:#fff;padding:1em 3em 1em 2em;border-radius:12px;border:1px solid #6e1edc;text-decoration:none;margin:2em 0;position:relative}#plugin-recommendations a.upgrade_button:after,#upgrade-table .upgrade-links a.upgrade_button:after{content:' \2192';display:block;position:absolute;right:1.8em;top:1.1em;transition:.5s}#plugin-recommendations a.upgrade_button:hover:after,#upgrade-table .upgrade-links a.upgrade_button:hover:after{right:1.1em;font-weight:700}#plugin-recommendations a.upgrade_button:focus,#plugin-recommendations a.upgrade_button:hover,#upgrade-table .upgrade-links a.upgrade_button:focus,#upgrade-table .upgrade-links a.upgrade_button:hover{background:#6e1edc;color:#fcfbf7}#plugin-recommendations{border-radius:8px;background-color:#f1e9fc;padding:4em 3em}#plugin-recommendations .card-container{max-width:1100px;display:grid;grid-template-columns:repeat(3,1fr);grid-gap:3em;padding:2em 0}#plugin-recommendations .recommendation-card{margin-top:0;border-radius:6px;background-color:#fff;box-shadow:0 0 25px -10px rgba(0,0,0,.2);box-sizing:border-box;font-size:15px;overflow:hidden;transition:.2s}#plugin-recommendations .recommendation-card:nth-child(n+4){display:none}#plugin-recommendations .recommendation-card:hover{scale:1.02}#plugin-recommendations .recommendation-card.currently-installed{opacity:.5}#plugin-recommendations .recommendation-card .card-content{padding:0 4em 3em 2em}#plugin-recommendations .recommendation-card img{width:100%}#plugin-recommendations .recommendation-card h5{text-align:left;font-size:1.4em;line-height:1.3em;font-weight:700;margin:1em 0}#plugin-recommendations .recommendation-card p{text-align:left;padding-bottom:10px}#plugin-recommendations .recommendation-card a.upgrade_button{margin:0}#plugin-recommendations .recommendation-card span.currently-installed{font-size:.7em;color:#fff;background-color:#6e1edc;padding:1em 2em;border-radius:12px;margin:0;display:inline-block}@media screen and (max-width:1100px){#upgrade-table{font-size:1em;line-height:1.2em}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:25%;padding:.8em 1em}#upgrade-table td.last,#upgrade-table th.last{width:0;padding:0}#upgrade-table td.feature-label span.description{padding-top:6px}#plugin-recommendations .card-container{grid-gap:2em}}@media screen and (max-width:968px){#plugin-recommendations .card-container{grid-template-columns:repeat(1,1fr);padding-right:40%}}@media screen and (max-width:782px){#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td:has(input[type=checkbox]+input[type=text])>input{display:inline-block}}@media screen and (max-width:767px){#upgrade-table td.feature-label span.description{display:none}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:20%}#upgrade-table td.first{width:40%}#plugin-recommendations .card-container{padding-right:0}}@media screen and (max-width:649px){div.upgrade-table-description{padding-left:.8em}div.upgrade-table-description p{font-size:1em}#upgrade-table{font-size:.8em}#upgrade-table td,#upgrade-table th{padding:.5em .8em!important}#upgrade-table td span.feature-available{width:18px;height:18px}#upgrade-table .upgrade-links a{white-space:normal;padding:.6em .8em;border-radius:6px}#upgrade-table .upgrade-links a:after{display:none}#plugin-recommendations .card-container{justify-content:center}}@media screen and (max-width:782px){input[type=checkbox],input[type=radio]{margin-bottom:.5em}} \ No newline at end of file +span.wpo-warning{display:inline-block;border:1px solid red;border-left:4px solid red;padding:5px 15px;background-color:#fff}.wcpdf-extensions-ad,.wcpdf-promo-ad{position:relative;min-height:90px;border:1px solid #6e1edc;background-color:#f1e9fc;padding:15px;padding-left:100px;margin-top:30px}img.wpo-helper{position:absolute;bottom:0;left:3px}.wcpdf-extensions-ad h3,.wcpdf-promo-ad h3{margin:0;padding:20px;font-weight:400;font-family:serif;letter-spacing:-1px;font-size:2.25em}.wcpdf-promo-ad p{margin:0;padding:0 20px;font-size:1.15em}.wcpdf-promo-ad p.upgrade-tab{margin-top:30px;font-style:italic;font-size:1em}.wcpdf-promo-ad p.expiration{font-size:.8em;padding-top:8px}.wcpdf-extensions-ad a,.wcpdf-promo-ad a{color:#6e1edc}.wcpdf-extensions-ad a.dismiss,.wcpdf-promo-ad a.dismiss{padding:10px 20px}.wcpdf-promo-ad p strong.code{font-size:1.3em;font-family:serif;padding:.1em .4em;background:#6e1edc;color:#fff;border-radius:5px;font-weight:400}.wcpdf-extensions-ad i{padding-left:20px}.wcpdf-extensions-ad ul,.wcpdf-promo-ad ul{margin:0;margin-left:40px}.wcpdf-extensions li{margin:0}.wcpdf-extensions li ul{list-style-type:square;margin-top:.5em;margin-bottom:.5em}.wcpdf-extensions>li:before{content:"";border-color:transparent transparent transparent #111;border-style:solid;border-width:.35em .35em .35em .45em;display:block;height:0;width:0;left:-1em;top:.9em;position:relative}.wcpdf-extensions li:not(.expanded){cursor:pointer}.wcpdf-extensions .expanded:before{border-color:#111 transparent transparent transparent;left:-1.17em;border-width:.45em .45em .35em .35em!important}.wcpdf-extensions .more{padding:10px;background-color:#fff;border:1px solid #ccc;border-radius:5px}.wcpdf-extensions table td{vertical-align:top}.dropbox-logo{margin-bottom:-10px;margin-right:10px}.cloud-logo{margin-bottom:-10px;margin-top:-5px;margin-right:10px}#img-header_logo{max-height:200px;width:auto;max-width:100%}.multiple-text-input label{padding-right:1em}table.multiple-text-input td{padding:0}table.wcpdf_documents_settings_list{width:100%;border-collapse:collapse;border-spacing:0;background-color:#fff;border-top:2px solid #000}table.wcpdf_documents_settings_list tr.odd{background-color:#ebf5ff}table.wcpdf_documents_settings_list td{padding:5px}table.wcpdf_documents_settings_list a{text-decoration:none}table.wcpdf_documents_settings_list td.settings-icon{text-align:right}table.wcpdf_documents_settings_list td.title{font-weight:700}.wcpdf-settings-sections ul{height:3em}.wcpdf-settings-sections ul li{float:left;margin-right:10px}.wcpdf-settings-sections ul li a{text-decoration:none;display:inline-block;padding:.8em 1em;color:#50575e;border:1px solid #c3c4c7;box-sizing:border-box}.wcpdf-settings-sections ul li a.active{border:2px solid #51266b;padding:calc(.8em - 1px) calc(1em - 1px);color:#000}.wcpdf_document_settings_sections{position:relative}.wcpdf_document_settings_sections>h2{cursor:pointer;padding:1em .8em;margin:0;border:1px solid #c3c4c7;background:#fff}.wcpdf_document_settings_sections ul{background:#fff;list-style:none;margin:0;padding:0;width:100%;display:block;height:auto;display:none;box-sizing:border-box;position:absolute;border-left:1px solid #c3c4c7;border-right:1px solid #c3c4c7;z-index:1000;box-shadow:0 35px 35px -8px rgba(0,0,0,.1);-webkit-box-shadow:0 35px 35px -8px rgba(0,0,0,.1)}.wcpdf_document_settings_sections ul.active{display:block}.wcpdf_document_settings_sections ul li{box-sizing:border-box;padding:0;margin-bottom:0;border-bottom:1px solid #eaeaea;font-size:1.1em}.wcpdf_document_settings_sections ul li:last-child{border-color:#c3c4c7}.wcpdf_document_settings_sections ul li:hover{cursor:pointer;background:#51266b;color:#fff}.wcpdf_document_settings_sections ul li:hover a{color:#fff}.wcpdf_document_settings_sections ul li a{color:#000;text-decoration:none;padding:1.2em 1.6em;display:block}.wcpdf_document_settings_sections .arrow-down{font-size:.7em;color:#999;margin-left:8px;font-weight:400;float:right}.wcpdf_document_settings_sections p:hover,.wcpdf_document_settings_sections p:hover>.arrow-down{color:#222}.wcpdf_advanced_numbers_choose_table{margin-top:20px}.wcpdf_document_settings_document_output_formats{margin-bottom:30px}.edit-next-number{opacity:.5}.edit-next-number:hover{opacity:1;cursor:pointer}.wpo-wcpdf-pointer.wp-pointer-top .wp-pointer-arrow,.wpo-wcpdf-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#51266b}.wpo-wcpdf-pointer .wp-pointer-content h3{border-color:#51266b;background:#51266b}.wpo-wcpdf-pointer .wp-pointer-content h3:before{color:#51266b}body.woocommerce_page_wpo_wcpdf_options_page{background:#fdfdfd}.wrap [class$=icon32]+h2{font-size:18px;padding:1em}.wrap .notice{margin:15px 0 0}.nav-tab-wrapper:not(.wcpdf_debug_settings_sections>.nav-tab-wrapper) a.nav-tab{background:0 0;border:none;border-bottom:3px solid transparent;padding:1em 0;margin:0 1.2em;font-size:15px}.nav-tab-wrapper:not(.wcpdf_debug_settings_sections>.nav-tab-wrapper) a.nav-tab.nav-tab-active{border-bottom:3px solid #51266b}#wpo-wcpdf-preview-wrapper{width:100%;height:auto;position:relative;display:flex;align-items:flex-start}#wpo-wcpdf-preview-wrapper .preview-document,#wpo-wcpdf-preview-wrapper .sidebar{transition:.3s ease-in-out}#wpo-wcpdf-preview-wrapper .sidebar{height:auto;padding:4em 0 0 0;box-sizing:border-box;background:0 0;flex:0 0 35%;overflow-x:hidden}#wpo-wcpdf-preview-wrapper .sidebar>form{background:0 0!important;overflow:visible;padding:0;margin-left:2em;box-sizing:border-box;width:calc(100% - 4em);max-width:50vw}#wpo-wcpdf-preview-wrapper .sidebar>form.editor{max-width:none}#wpo-wcpdf-preview-wrapper .sidebar .form-table,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>th{display:block;width:100%;padding:0}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>th{padding-bottom:.6em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr:not(:last-child)>td{padding-bottom:2.4em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td p.description{font-size:.85em;padding-top:.7em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td p.description>span.wpo-warning{width:100%;box-sizing:border-box;word-wrap:break-word}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input[type=text],#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input[type=url],#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>select,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>textarea{max-width:none;width:100%}#wpo-wcpdf-preview-wrapper input[type=text][size],#wpo-wcpdf-preview-wrapper input[type=url][size]{width:auto!important;max-width:100%!important}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input#next_invoice_number{width:auto!important}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{display:grid;grid-template-columns:1fr 2fr;gap:4em}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2{border-bottom:1px solid #c3c4c7;padding:1em 0 1em 5px;margin:0;font-weight:400;color:#222;font-family:sans-serif;font-size:1.3em;letter-spacing:-.01em;position:relative;transition:transform .3s;cursor:pointer}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2~.form-table{border-left:1px solid #c3c4c7;border-right:1px solid #c3c4c7;border-bottom:1px solid #c3c4c7;padding:2em;margin-top:-1px;background:#fff;margin-bottom:20px}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2::after{content:'\f347';font-family:dashicons;font-size:16px;color:#82878c;position:absolute;right:5px;top:50%;transform:translateY(-50%);transition:transform .15s}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2:hover:after{color:#222}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2.active::after{transform:translateY(-50%) rotate(180deg)}#wpo-wcpdf-preview-wrapper .my_account_buttons_custom{margin-top:1em}#wpo-wcpdf-settings .form-table .ui-tabs-nav{padding-left:0!important;margin-left:0!important}#wpo-wcpdf-settings .translations input,#wpo-wcpdf-settings .translations textarea{width:100%}#wpo-wcpdf-settings .wcpdf-attachment-settings-hint{border-left:4px solid #51266b}#wpo-wcpdf-settings .notice-info.inline{border-left-color:#51266b}#wpo-wcpdf-settings table#document-link-access-type{margin-top:-15px}#wpo-wcpdf-settings table#document-link-access-type td.option{padding-left:0}#wpo-wcpdf-settings table#document-link-access-type td{padding-top:0;padding-bottom:6px;font-size:12px}#wpo-wcpdf-settings .system-status-table{margin-top:2em}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar{flex:0 0 100%}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=full] .sidebar{flex:0 0 95%;margin-left:-95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .sidebar{flex:0 0 35%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=full] .sidebar{margin-left:-35%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] .sidebar{transition-delay:.4s}#wpo-wcpdf-preview-wrapper .preview-document{padding:0;box-sizing:border-box;position:sticky;top:2.4em;flex:0 0 60%}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .preview-document{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .preview-document{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=full] .preview-document{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .preview-document{flex:0 0 60%;margin-right:-60%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .preview-document{flex:0 0 60%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=full] .preview-document{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] .preview-document{transition-delay:.4s}.preview-document .preview{width:100%;box-sizing:border-box;padding-right:5%}.preview-document .preview>#preview-ubl{width:100%;height:100%;overflow-wrap:anywhere;background-color:#222;color:#fff;padding:2em}.preview-document .preview>#preview-canvas{display:block;max-width:800px;max-height:85vh;width:auto!important;margin:0 auto;background:#fff;box-shadow:8px 8px 8px rgba(0,0,0,.1),-8px -8px 8px rgba(0,0,0,.02);-webkit-box-shadow:8px 8px 8px rgba(0,0,0,.1),-8px -8px 8px rgba(0,0,0,.02)}#wpo-wcpdf-preview-wrapper[data-preview-states="2"] #preview-canvas{max-height:170vh}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=sidebar] #preview-canvas{max-height:170vh;transition:max-height .4s ease-in-out .3s}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] #preview-canvas{transition:max-height .4s ease-in-out 0s}.preview-document .preview-data-wrapper{width:100%;height:4em}.preview-document .preview-data-wrapper .preview-document-type,.preview-document .preview-data-wrapper .preview-order-data{float:right}.preview-document .preview-data-wrapper .preview-document-type{margin-right:30px}.preview-document .preview-data-wrapper .preview-document-type ul>li{text-decoration:none;color:initial;padding:1.4em 1.6em}.preview-document .preview-data-wrapper .preview-document-type ul>li:hover{color:#fff!important}.preview-document .preview-data-wrapper .save-settings{padding:1em 0 0 0;float:right;overflow:hidden;position:relative}.preview-document .preview-data-wrapper .save-settings p{padding:0;margin:0 0 0 2em;position:relative;margin-right:-200px;transition:margin-right .3s ease-out}.preview-document .preview-data-wrapper .save-settings p:after{content:'';display:block;pointer-events:none;position:absolute;box-sizing:border-box;border-radius:3px;right:0;top:0;background:0 0;width:100%;height:100%;z-index:10;border:0 solid #fff;animation:border-pulse 4s infinite}@keyframes border-pulse{0%{border-color:rgba(255,255,255,0);border-width:8px}50%{border-color:#fff;border-width:0}}.preview-document .preview-data-wrapper .save-settings p input:focus{outline-width:0;box-shadow:none}.preview-document .preview-data p{padding:1.4em 0;margin:0;color:#666;text-align:right;cursor:pointer;font-weight:lighter;float:right}.preview-document .preview-data p.order-search{display:none}.preview-document .preview-data input{float:right;margin:1em 0 0 1em;padding:.1em .5em;width:20ch;margin-right:-25ch;display:none}.preview-document .preview-data input.active{margin-right:0;display:inline-block}.preview-document .preview-data ul{position:absolute;right:0;top:4em;background:#fff;box-shadow:0 0 25px -10px rgba(0,0,0,.2);-webkit-box-shadow:0 0 25px -10px rgba(0,0,0,.2);list-style:none;margin:0;padding:0;min-width:24em;display:block;height:0;overflow:hidden}.preview-document .preview-data ul.active{height:auto;z-index:1}.preview-document .preview-data ul li{box-sizing:border-box;padding:0;margin-bottom:0;border-bottom:1px solid #eaeaea;font-size:1.1em}.preview-document .preview-data ul li:hover{cursor:pointer;background:#51266b;color:#fff}.preview-document .preview-data ul li a,.preview-document .preview-data.preview-order-data ul li{display:block;padding:1.4em 1.6em}.preview-document .preview-data .arrow-down{font-size:.8em;color:#999;margin-left:8px}.preview-document .preview-data p:hover,.preview-document .preview-data p:hover>.arrow-down{color:#222}.preview-document .preview-data #preview-order-search-results{display:none;position:absolute;right:0;top:4em;width:300px;box-shadow:0 0 25px -10px rgba(0,0,0,.2);-webkit-box-shadow:0 0 25px -10px rgba(0,0,0,.2);padding:20px 0;background-color:#fff;z-index:99}.preview-document .preview-data #preview-order-search-results a{display:block;border-left:1px solid #999;border-right:1px solid #999;border-top:1px solid #999;color:#000;padding:10px;margin:0 20px;text-decoration:none;cursor:pointer}.preview-document .preview-data #preview-order-search-results a:last-child{border-bottom:1px solid #999}.preview-document .preview-data #preview-order-search-results a:hover{background-color:#51266b;color:#fff}.preview-document .preview-data #preview-order-search-results .order-number{font-weight:700}.preview-document .preview-data #preview-order-search-results .date,.preview-document .preview-data #preview-order-search-results .total{margin-top:6px;display:inline-block}.preview-document .preview-data #preview-order-search-results .total{float:right}.preview-document .preview-data #preview-order-search-results .error{margin:0 20px}.preview-document .preview-order-search-wrapper{position:relative;float:right}.preview-document .preview-order-search-wrapper img.preview-order-search-clear{position:absolute;width:30px;height:16px;top:22px;right:6px;display:none;cursor:pointer}#wpo-wcpdf-preview-wrapper .gutter{flex:0 0 5%;position:sticky;top:2.4em;height:170vh}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .gutter .slide-left,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .gutter .slide-left{float:right}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .gutter .slide-left{border:none}#wpo-wcpdf-preview-wrapper .slider{box-sizing:border-box;padding-top:2.4em;color:#999;font-weight:700;cursor:pointer;font-size:.7em;line-height:1em;width:50%;height:100%;float:left}#wpo-wcpdf-preview-wrapper .slider.slide-left{text-align:right;padding-right:10px;border-right:1px solid #ccc}#wpo-wcpdf-preview-wrapper .slider.slide-right{text-align:left;padding-left:10px;border-left:1px solid #ccc;display:none}#wpo-wcpdf-preview-wrapper .gutter-arrow{width:0;height:0;border-top:3px solid transparent;border-bottom:3px solid transparent;display:block}#wpo-wcpdf-preview-wrapper .arrow-left{border-right:7px solid #999;float:right}#wpo-wcpdf-preview-wrapper .arrow-right{border-left:7px solid #999}#wpo-wcpdf-preview-wrapper .slider:hover>.arrow-left{border-right:7px solid #222}#wpo-wcpdf-preview-wrapper .slider:hover>.arrow-right{border-left:7px solid #222}#wpo-wcpdf-preview-wrapper .slider.slide-left:after{position:absolute;top:1.55em;right:2em;font-size:1.4em;display:none}#wpo-wcpdf-preview-wrapper .slider.slide-right:after{position:absolute;top:1.55em;left:2em;font-size:1.4em;display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .gutter{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .gutter{height:100vh}#wpo-wcpdf-preview-wrapper[data-preview-state=full] .slide-right:after{display:inline-block}#wpo-wcpdf-preview-wrapper[data-preview-state=closed] .slide-left:after{display:inline-block}#wpo-wcpdf-preview-wrapper.static .gutter,#wpo-wcpdf-preview-wrapper.static .preview-document{position:static!important}#wpo-wcpdf-preview-wrapper.static .sidebar{height:170vh!important;overflow:hidden}#wpo-wcpdf-preview-wrapper input.readonly,#wpo-wcpdf-preview-wrapper input[readonly],#wpo-wcpdf-preview-wrapper textarea.readonly,#wpo-wcpdf-preview-wrapper textarea[readonly]{background-color:#f8f8f8}#wpo-wcpdf-preview-wrapper[data-preview-state=sidebar] .select2.select2-container{width:100%!important}.wcpdf_ubl_settings_sections{margin-bottom:4em}#wpo-wcpdf-preview-wrapper input#due_date_days{text-align:right}#wpo-wcpdf-preview-wrapper input#due_date_days:disabled{background-color:#eaeaea;color:#999}sup.wcpdf_beta{background-color:#51266b;color:#fff;font-size:7pt;padding:1px 2px;border-radius:2px}@media screen and (min-width:1920px){.preview-document .preview>#preview-canvas{max-width:900px}}@media screen and (max-width:1200px){.preview-document .preview>#preview-canvas{max-width:680px}.nav-tab-wrapper a.nav-tab{padding:1em 2em;margin:0 .5em .5em 0;border:1px solid #ccc;box-sizing:border-box;height:4em}.nav-tab-wrapper a.nav-tab.nav-tab-active{border:3px solid #51266b}.preview-document .preview>#preview-canvas{width:80vw!important}#wpo-wcpdf-preview-wrapper .sidebar>form{max-width:100%}#wpo-wcpdf-preview-wrapper[data-preview-state=closed] .select2.select2-container{width:100%!important}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{gap:2em}.preview-document .preview-data-wrapper{height:6em}.preview-document .preview-data p{padding:2.2em 0}#wpo-wcpdf-preview-wrapper .slider.slide-left:after,#wpo-wcpdf-preview-wrapper .slider.slide-right:after{top:1.5em;padding:1em;background:#fff;border:1px solid #ccc}#wpo-wcpdf-preview-wrapper .slider.slide-right:after{left:0}#wpo-wcpdf-preview-wrapper .slider.slide-left:after{right:0}#wpo-wcpdf-preview-wrapper .multiple-text-input tr td:nth-child(2),#wpo-wcpdf-preview-wrapper .multiple-text-input tr td:nth-child(3){float:left;margin-bottom:10px}#wpo-wcpdf-preview-wrapper .multiple-text-input tr td .woocommerce-help-tip:after{padding:.5em .8em;font-size:1.2em;line-height:inherit}}@media screen and (max-width:860px){#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{display:block}}div.upgrade-table-description{padding:0 0 3em 1em}div.upgrade-table-description h1{font-family:serif;letter-spacing:-1px;font-size:3em}div.upgrade-table-description p{font-size:1.1em}#upgrade-table{width:100%;border-collapse:collapse;font-size:1.2em;margin-bottom:3em}#upgrade-table td,#upgrade-table th{padding:.8em 2em;border-bottom:1px solid #ccc;text-align:center}#upgrade-table th{font-weight:400;font-size:1.1em}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:200px}#upgrade-table tr:last-child td{border:none}#upgrade-table td.feature-label{text-align:left;padding-left:1em;font-weight:700;width:500px}#upgrade-table td.feature-label span.description{display:inline-block;padding-top:10px;font-size:.8em;line-height:1.4em;font-weight:400;color:#555}#upgrade-table td span.feature-available{display:inline-block;width:24px;height:24px;background-repeat:no-repeat;background-size:cover}#upgrade-table a,div.upgrade-table-description a{color:#6e1edc;white-space:nowrap}#upgrade-table .upgrade-links h4{margin:1em 0 .5em 0}#upgrade-table .upgrade-links p{margin:0;font-style:oblique;font-size:.8em}#plugin-recommendations a.upgrade_button,#upgrade-table .upgrade-links a.upgrade_button{display:inline-block;background:#fff;padding:1em 3em 1em 2em;border-radius:12px;border:1px solid #6e1edc;text-decoration:none;margin:2em 0;position:relative}#plugin-recommendations a.upgrade_button:after,#upgrade-table .upgrade-links a.upgrade_button:after{content:' \2192';display:block;position:absolute;right:1.8em;top:1.1em;transition:.5s}#plugin-recommendations a.upgrade_button:hover:after,#upgrade-table .upgrade-links a.upgrade_button:hover:after{right:1.1em;font-weight:700}#plugin-recommendations a.upgrade_button:focus,#plugin-recommendations a.upgrade_button:hover,#upgrade-table .upgrade-links a.upgrade_button:focus,#upgrade-table .upgrade-links a.upgrade_button:hover{background:#6e1edc;color:#fcfbf7}#plugin-recommendations{border-radius:8px;background-color:#f1e9fc;padding:4em 3em}#plugin-recommendations .card-container{max-width:1100px;display:grid;grid-template-columns:repeat(3,1fr);grid-gap:3em;padding:2em 0}#plugin-recommendations .recommendation-card{margin-top:0;border-radius:6px;background-color:#fff;box-shadow:0 0 25px -10px rgba(0,0,0,.2);box-sizing:border-box;font-size:15px;overflow:hidden;transition:.2s}#plugin-recommendations .recommendation-card:nth-child(n+4){display:none}#plugin-recommendations .recommendation-card:hover{scale:1.02}#plugin-recommendations .recommendation-card.currently-installed{opacity:.5}#plugin-recommendations .recommendation-card .card-content{padding:0 4em 3em 2em}#plugin-recommendations .recommendation-card img{width:100%}#plugin-recommendations .recommendation-card h5{text-align:left;font-size:1.4em;line-height:1.3em;font-weight:700;margin:1em 0}#plugin-recommendations .recommendation-card p{text-align:left;padding-bottom:10px}#plugin-recommendations .recommendation-card a.upgrade_button{margin:0}#plugin-recommendations .recommendation-card span.currently-installed{font-size:.7em;color:#fff;background-color:#6e1edc;padding:1em 2em;border-radius:12px;margin:0;display:inline-block}@media screen and (max-width:1100px){#upgrade-table{font-size:1em;line-height:1.2em}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:25%;padding:.8em 1em}#upgrade-table td.last,#upgrade-table th.last{width:0;padding:0}#upgrade-table td.feature-label span.description{padding-top:6px}#plugin-recommendations .card-container{grid-gap:2em}}@media screen and (max-width:968px){#plugin-recommendations .card-container{grid-template-columns:repeat(1,1fr);padding-right:40%}}@media screen and (max-width:782px){#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td:has(input[type=checkbox]+input[type=text])>input{display:inline-block}}@media screen and (max-width:767px){#upgrade-table td.feature-label span.description{display:none}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:20%}#upgrade-table td.first{width:40%}#plugin-recommendations .card-container{padding-right:0}}@media screen and (max-width:649px){div.upgrade-table-description{padding-left:.8em}div.upgrade-table-description p{font-size:1em}#upgrade-table{font-size:.8em}#upgrade-table td,#upgrade-table th{padding:.5em .8em!important}#upgrade-table td span.feature-available{width:18px;height:18px}#upgrade-table .upgrade-links a{white-space:normal;padding:.6em .8em;border-radius:6px}#upgrade-table .upgrade-links a:after{display:none}#plugin-recommendations .card-container{justify-content:center}}@media screen and (max-width:782px){input[type=checkbox],input[type=radio]{margin-bottom:.5em}} \ No newline at end of file From e152c49a65ae88dbfc433fafa1e157c1f1374008 Mon Sep 17 00:00:00 2001 From: BrunoPavlinic98 <154232249+BrunoPavlinic98@users.noreply.github.com> Date: Mon, 16 Dec 2024 08:57:21 +0100 Subject: [PATCH 22/69] Fix: upgrade links not displaying correctly (#907) --- includes/Settings/SettingsUpgrade.php | 154 ++++++++++++++------------ views/upgrade-table.php | 95 +++++++++++----- 2 files changed, 153 insertions(+), 96 deletions(-) diff --git a/includes/Settings/SettingsUpgrade.php b/includes/Settings/SettingsUpgrade.php index 233e4bcda..9b97796a0 100644 --- a/includes/Settings/SettingsUpgrade.php +++ b/includes/Settings/SettingsUpgrade.php @@ -20,7 +20,7 @@ public static function instance() { } public function __construct() { - $this->extensions = array( 'pro' ); + $this->extensions = array( 'pro', 'templates' ); add_action( 'wpo_wcpdf_before_settings_page', array( $this, 'extensions_license_cache_notice' ), 10, 2 ); add_action( 'wpo_wcpdf_after_settings_page', array( $this, 'extension_overview' ), 10, 2 ); @@ -100,7 +100,7 @@ public function extension_overview( $tab, $section ) { 'https://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/using-the-customizer/', __( 'Learn more', 'woocommerce-pdf-invoices-packing-slips' ) ), - 'extensions' => array( 'bundle' ), + 'extensions' => array( 'templates', 'bundle' ), ), array( 'label' => __( 'Add custom data to your documents', 'woocommerce-pdf-invoices-packing-slips' ), @@ -110,21 +110,21 @@ public function extension_overview( $tab, $section ) { 'https://docs.wpovernight.com/woocommerce-pdf-invoices-packing-slips/using-custom-blocks/', __( 'Learn more', 'woocommerce-pdf-invoices-packing-slips' ) ), - 'extensions' => array( 'bundle' ), + 'extensions' => array( 'templates', 'bundle' ), ), array( 'label' => __( 'Additional PDF templates', 'woocommerce-pdf-invoices-packing-slips' ), 'description' => __( 'Make use of our Business or Modern template designs.', 'woocommerce-pdf-invoices-packing-slips' ), - 'extensions' => array( 'bundle' ), + 'extensions' => array( 'templates', 'bundle' ), ), array( 'label' => __( 'Add styling', 'woocommerce-pdf-invoices-packing-slips' ), 'description' => __( 'Easily change the look and feel of your documents by adding some custom CSS.', 'woocommerce-pdf-invoices-packing-slips' ), - 'extensions' => array( 'bundle' ), + 'extensions' => array( 'templates', 'bundle' ), ), ); - $extension_license_infos = $this->get_extension_license_infos(); + $extension_license_infos = $this->get_extension_license_infos( true ); $plugin_recommendations = array( array( @@ -214,10 +214,8 @@ public function extension_is_enabled( $extension ) { * @return array */ public function get_extension_license_infos( $ignore_cache = false ) { - $extensions = $this->extensions; - $license_info = ! $ignore_cache ? $this->get_extensions_license_data( 'cached' ) : array(); - $bundle_upgrade_link = ''; - $license_status = 'inactive'; + $extensions = $this->extensions; + $license_info = ! $ignore_cache ? $this->get_extensions_license_data( 'cached' ) : array(); if ( ! empty( $license_info ) ) { return $license_info; @@ -228,14 +226,13 @@ public function get_extension_license_infos( $ignore_cache = false ) { $args = array(); $request = null; $license_key = ''; - $sidekick = false; $updater = null; if ( $this->extension_is_enabled( $extension ) ) { - $extension_main_function = "WPO_WCPDF_".ucfirst( $extension ); + $extension_main_function = "WPO_WCPDF_" . ucfirst( $extension ); $updater = $extension_main_function()->updater; - if ( $extension == 'templates' && version_compare( $extension_main_function()->version, '2.20.0', '<=' ) ) { // 'updater' property had 'private' visibility + if ( 'templates' === $extension && version_compare( $extension_main_function()->version, '2.20.0', '<=' ) ) { // 'updater' property had 'private' visibility continue; } @@ -244,43 +241,13 @@ public function get_extension_license_infos( $ignore_cache = false ) { } // built-in updater - if ( is_callable( [ $updater, 'get_license_key' ] ) ) { + if ( is_callable( array( $updater, 'get_license_key' ) ) ) { $license_key = $updater->get_license_key(); - // sidekick (legacy) - } elseif ( property_exists( $updater, 'license_key' ) ) { - $license_slug = "wpo_wcpdf_{$extension}_license"; - $wpo_license_keys = get_option( 'wpocore_settings', array() ); - $license_key = isset( $wpo_license_keys[$license_slug] ) ? $wpo_license_keys[$license_slug] : $license_key; - $sidekick = true; } if ( ! empty( $license_key ) ) { $args['edd_action'] = 'check_license'; - $args['license_key'] = trim( $license_key ); - - // legacy - if ( $sidekick ) { - if ( ! class_exists( 'WPO_Update_Helper' ) ) { - include_once( $extension_main_function()->plugin_path() . '/updater/update-helper.php' ); - } - - $item_name = 'PDF Invoices & Packing Slips for WooCommerce - '; - $file = $extension_main_function()->plugin_path(); - $version = $extension_main_function()->version; - $author = 'WP Overnight'; - - switch ( $extension ) { - case 'pro': - $item_name = "{$item_name}Professional"; - break; - case 'templates': - $item_name = "{$item_name}Premium Templates"; - break; - } - - $updater = new \WPO_Update_Helper( $item_name, $file, $license_slug, $version, $author ); - } - + $args['license_key'] = $license_info[ $extension ]['license_key'] = trim( $license_key ); } else { continue; } @@ -288,31 +255,86 @@ public function get_extension_license_infos( $ignore_cache = false ) { if ( $updater && is_callable( array( $updater, 'remote_license_actions' ) ) && ! empty( $args ) ) { $request = $updater->remote_license_actions( $args ); - if ( is_object( $request ) && isset( $request->license ) ) { - $license_info[$extension]['status'] = $license_status = $request->license; - - if ( empty( $bundle_upgrade_link ) && ! empty( $request->bundle_upgrade ) && is_string( $request->bundle_upgrade ) ) { - $bundle_upgrade_link = $request->bundle_upgrade; // https://github.com/wpovernight/woocommerce-pdf-invoices-packing-slips/pull/503#issue-1678203436 - } + if ( is_wp_error( $request ) ) { + wcpdf_log_error( 'Unable to retrieve license data from the remote server for the extension ' . $extension . '. Error: ' . $response->get_error_message() ); + continue; } + + $license_info[ $extension ]['status'] = isset( $request->license ) ? $request->license : 'inactive'; + $license_info[ $extension ]['license_limit'] = isset( $request->license_limit ) ? $request->license_limit : 1; + $license_info[ $extension ]['license_id'] = isset( $request->license_id ) ? absint( $request->license_id ) : null; + $license_info[ $extension ]['bundle_license'] = isset( $request->bundle_license ) ? $request->bundle_license : false; } } } - - $extensions[] = 'bundle'; + + $extensions[] = 'bundle'; + $default_utm_tags = 'utm_medium=plugin&utm_source=ips&utm_campaign=upgrade-tab'; + $bundle_upgrade_url = ''; + $upgrade_tiers = array( + // license limit => upgrade ID + 'pro' => array( + 1 => 3, + 3 => 4, + 25 => 5, + ), + 'templates' => array( + 1 => 4, + 3 => 5, + 25 => 6, + ), + ); + foreach ( $extensions as $extension ) { - if ( ! empty( $bundle_upgrade_link ) && $license_status == 'valid' ) { - $license_info[$extension]['url'] = $bundle_upgrade_link; - } else { - switch ( $extension ) { - case 'pro': - $license_info[$extension]['url'] = 'https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional?utm_medium=plugin&utm_source=ips&utm_campaign=upgrade-tab&content=ips-pro-upgrade'; - break; - case 'bundle': - $license_info[$extension]['url'] = 'https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle?utm_medium=plugin&utm_source=ips&utm_campaign=upgrade-tab&content=ips-bundle-upgrade'; - break; - } + // set default URL + switch ( $extension ) { + case 'pro': + $pro_utm_tags = $default_utm_tags . '&utm_content=ips-pro-upgrade'; + $license_info[ $extension ]['url'] = "https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-professional/?{$pro_utm_tags}"; + break; + case 'templates': + case 'bundle': + $bundle_utm_tags = $default_utm_tags . '&utm_content=ips-plus-bundle-upgrade'; + $license_info[ $extension ]['url'] = "https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/?{$bundle_utm_tags}"; + break; + } + + // if bundle, no upgrade needed + if ( isset( $license_info[ $extension ]['bundle_license'] ) && $license_info[ $extension ]['bundle_license'] ) { + continue; + } + + // there's no license ID, can't be upgraded + if ( empty( $license_info[ $extension ]['license_id'] ) ) { + continue; } + + // check if the license is activated and valid + if ( empty( $license_info[ $extension ]['status'] ) || 'valid' !== $license_info[ $extension ]['status'] ) { + continue; + } + + // if bundle upgrade URL is already set, skip + if ( ! empty( $bundle_upgrade_url ) ) { + continue; + } + + // create upgrade URL + $license_id = $license_info[ $extension ]['license_id']; + $license_limit = $license_info[ $extension ]['license_limit']; + $upgrade_id = isset( $upgrade_tiers[ $extension ][ $license_limit ] ) ? $upgrade_tiers[ $extension ][ $license_limit ] : 0; + + if ( 0 === $upgrade_id ) { + continue; + } + + $upgrade_utm_tags = $default_utm_tags . '&utm_content=ips-plus-bundle-upgrade+upgrade-from-' . $extension; + $bundle_upgrade_url = "https://wpovernight.com/checkout/?edd_action=sl_license_upgrade&license_id={$license_id}&upgrade_id={$upgrade_id}&{$upgrade_utm_tags}"; + } + + // set bundle upgrade URL + if ( ! empty( $bundle_upgrade_url ) ) { + $license_info['bundle']['url'] = $bundle_upgrade_url; } update_option( 'wpo_wcpdf_extensions_license_cache', $license_info ); @@ -356,10 +378,6 @@ public function get_extensions_license_data( string $type = 'cached' ): array { } } - if ( isset( $data['templates'] ) ) { - unset( $data['templates'] ); - } - return $data; } diff --git a/views/upgrade-table.php b/views/upgrade-table.php index 6f1930137..b2838987d 100644 --- a/views/upgrade-table.php +++ b/views/upgrade-table.php @@ -18,8 +18,9 @@ - - + + + @@ -27,8 +28,8 @@ foreach ( $features as $feature ) { echo '' : ''; - foreach ( ['pro', 'bundle'] as $extension ) { - echo in_array( $extension, $feature['extensions'] ) ? '' : ''; + foreach ( ['pro', 'templates', 'bundle'] as $extension ) { + echo in_array( $extension, $feature['extensions'] ) ? '' : ''; } echo ''; } @@ -36,18 +37,37 @@ settings->upgrade->extension_is_enabled( $extension ); + + if ( $extension_is_enabled ) { + $extensions_enabled[] = $extension; + } else { + $extensions_disabled[] = $extension; + } + } // pro, templates & bundle columns foreach ( $extension_license_infos as $extension => $info ) { + $extension_is_enabled = in_array( $extension, $extensions_enabled ); + $bundle_is_enabled = array() === array_diff( array( 'pro', 'templates' ), $extensions_enabled ); + // enabled - if ( WPO_WCPDF()->settings->upgrade->extension_is_enabled( $extension ) ) { - $extensions_enabled[] = $extension; - + if ( $extension_is_enabled || $bundle_is_enabled ) { $title = __( 'Currently installed', 'woocommerce-pdf-invoices-packing-slips' ); - if ( empty( $info['status'] ) || $info['status'] != 'valid' ) { + + // if the bundle is enabled, display only "Bundle" as installed + if ( $bundle_is_enabled && 'bundle' !== $extension ) { + $title = ''; + } + + if ( ( empty( $info['status'] ) || 'valid' !== $info['status'] ) && 'bundle' !== $extension ) { $subtitle = sprintf( /* translators: learn more link */ __( 'License not yet activated: %s', 'woocommerce-pdf-invoices-packing-slips' ), @@ -57,34 +77,53 @@ $subtitle = ''; } - $extension_columns[$extension] = sprintf( - '', + $extension_columns[ $extension ] = sprintf( + '', + $extension, $title, $subtitle ); - // disabled (includes bundle) + // disabled } else { - $extensions_disabled[] = $extension; - if ( $info['url'] == 'is_bundled' ) { // extension license is bundled, no need to buy - $extension_columns[$extension] = ''; - } else { - $extension_columns[$extension] = sprintf( - '', - esc_url_raw( $info['url'] ), - __( 'Upgrade now', 'woocommerce-pdf-invoices-packing-slips' ) - ); + // add bundle to disabled extensions + if ( 'bundle' === $extension && ! in_array( $extension, $extensions_disabled ) ) { + $extensions_disabled[] = $extension; } + + $extension_columns[ $extension ] = sprintf( + '', + esc_url_raw( $info['url'] ), + __( 'Upgrade now', 'woocommerce-pdf-invoices-packing-slips' ) + ); } } - // maybe disable 1 extension or bundle column - foreach ( $extensions_disabled as $extension_disabled ) { - if ( ( count( $extensions_disabled ) < 3 && $extension_disabled != 'bundle' ) || ( count( $extensions_disabled ) == 1 && $extension_disabled == 'bundle' ) ) { - $extension_columns[$extension_disabled] = ''; - } + $styles = ''; + + switch ( implode( ',', $extensions_enabled ) . '-' . implode( ',', $extensions_disabled ) ) { + case 'pro-templates,bundle': + $styles .= '#upgrade-table .templates { display: none; }'; + break; + case 'templates-pro,bundle': + $styles .= '#upgrade-table .pro { display: none; }'; + break; + case 'pro,templates-': + $styles .= '#upgrade-table .templates { display: none; }'; + break; + case 'pro,templates-bundle': + $styles .= '#upgrade-table .templates { display: none; }'; + break; + case 'pro,templates,bundle-': + $styles .= '#upgrade-table .templates { display: none; }'; + break; + case '-pro,templates,bundle': + $styles .= '#upgrade-table .templates { display: none; }'; + break; } + echo ''; + foreach ( $extension_columns as $column ) { echo $column; } From af964d17563e172c69f8f082da91a88716f36d2f Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Mon, 16 Dec 2024 08:13:09 +0000 Subject: [PATCH 23/69] v3.9.1 --- ...woocommerce-pdf-invoices-packing-slips.pot | 822 +++++++++--------- readme.txt | 22 +- woocommerce-pdf-invoices-packingslips.php | 4 +- 3 files changed, 452 insertions(+), 396 deletions(-) diff --git a/languages/woocommerce-pdf-invoices-packing-slips.pot b/languages/woocommerce-pdf-invoices-packing-slips.pot index 022657ff7..8fbe450c8 100644 --- a/languages/woocommerce-pdf-invoices-packing-slips.pot +++ b/languages/woocommerce-pdf-invoices-packing-slips.pot @@ -2,36 +2,41 @@ # This file is distributed under the GPLv2 or later. msgid "" msgstr "" -"Project-Id-Version: PDF Invoices & Packing Slips for WooCommerce 3.9.0\n" +"Project-Id-Version: PDF Invoices & Packing Slips for WooCommerce 3.9.1\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2024-10-21T10:48:28+02:00\n" +"POT-Creation-Date: 2024-12-16T08:12:43+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"X-Generator: WP-CLI 2.7.1\n" +"X-Generator: WP-CLI 2.11.0\n" "X-Domain: woocommerce-pdf-invoices-packing-slips\n" #. Plugin Name of the plugin +#: woocommerce-pdf-invoices-packingslips.php #: views/settings-page.php:18 msgid "PDF Invoices & Packing Slips for WooCommerce" msgstr "" #. Plugin URI of the plugin +#: woocommerce-pdf-invoices-packingslips.php msgid "https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/" msgstr "" #. Description of the plugin +#: woocommerce-pdf-invoices-packingslips.php msgid "Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders." msgstr "" #. Author of the plugin +#: woocommerce-pdf-invoices-packingslips.php msgid "WP Overnight" msgstr "" #. Author URI of the plugin +#: woocommerce-pdf-invoices-packingslips.php msgid "https://www.wpovernight.com" msgstr "" @@ -50,15 +55,14 @@ msgstr "" #: includes/Admin.php:124 #: includes/Main.php:853 +#: includes/Settings/SettingsDebug.php:1131 #: views/attachment-settings-hint.php:12 #: views/extensions.php:121 #: views/promo.php:34 -#: woocommerce-pdf-invoices-packingslips.php:340 -#: woocommerce-pdf-invoices-packingslips.php:399 -#: woocommerce-pdf-invoices-packingslips.php:437 -#: woocommerce-pdf-invoices-packingslips.php:481 -#: woocommerce-pdf-invoices-packingslips.php:512 -#: woocommerce-pdf-invoices-packingslips.php:601 +#: woocommerce-pdf-invoices-packingslips.php:338 +#: woocommerce-pdf-invoices-packingslips.php:397 +#: woocommerce-pdf-invoices-packingslips.php:435 +#: woocommerce-pdf-invoices-packingslips.php:525 msgid "Hide this message" msgstr "" @@ -90,15 +94,15 @@ msgstr "" #: includes/Admin.php:322 #: includes/Admin.php:1342 -#: includes/Assets.php:229 -#: includes/Documents/Invoice.php:348 +#: includes/Assets.php:233 +#: includes/Documents/Invoice.php:354 #: includes/Main.php:1237 #: views/setup-wizard/display-options.php:81 msgid "Invoice Number" msgstr "" #: includes/Admin.php:323 -#: includes/Documents/Invoice.php:316 +#: includes/Documents/Invoice.php:322 #: includes/Documents/OrderDocumentMethods.php:1306 #: includes/Main.php:1238 #: views/setup-wizard/display-options.php:60 @@ -264,36 +268,36 @@ msgid "Preview" msgstr "" #: includes/Assets.php:121 -#: includes/Settings/SettingsDebug.php:929 +#: includes/Settings/SettingsDebug.php:1139 msgid "Settings" msgstr "" -#: includes/Assets.php:176 +#: includes/Assets.php:180 msgid "Document settings" msgstr "" -#: includes/Assets.php:177 +#: includes/Assets.php:181 msgid "Select a document in the dropdown menu above to edit its settings." msgstr "" -#: includes/Assets.php:188 +#: includes/Assets.php:192 msgid "The number should be smaller than 2147483647. Please note you should add your next document number without prefix, suffix or padding." msgstr "" -#: includes/Assets.php:262 +#: includes/Assets.php:266 msgid "Download" msgstr "" -#: includes/Assets.php:263 +#: includes/Assets.php:267 msgid "Are you sure you want to reset this settings? This cannot be undone." msgstr "" -#: includes/Assets.php:264 +#: includes/Assets.php:268 msgid "Please select a document type" msgstr "" #. translators: 1. open anchor tag, 2. close anchor tag -#: includes/Assets.php:269 +#: includes/Assets.php:273 msgid "Enabled: %1$sclick here%2$s to start using the tools." msgstr "" @@ -323,378 +327,408 @@ msgstr "" #. translators: document type #: includes/Documents/Invoice.php:131 -#: includes/Documents/Invoice.php:387 -#: includes/Documents/Invoice.php:396 -#: includes/Documents/Invoice.php:404 -#: includes/Documents/Invoice.php:408 +#: includes/Documents/Invoice.php:393 +#: includes/Documents/Invoice.php:402 +#: includes/Documents/Invoice.php:410 +#: includes/Documents/Invoice.php:414 msgid "invoice" msgid_plural "invoices" msgstr[0] "" msgstr[1] "" -#: includes/Documents/Invoice.php:216 -#: includes/Documents/Invoice.php:583 +#: includes/Documents/Invoice.php:222 +#: includes/Documents/Invoice.php:589 #: includes/Documents/PackingSlip.php:116 msgid "Enable" msgstr "" -#: includes/Documents/Invoice.php:227 -#: includes/Documents/Invoice.php:594 +#: includes/Documents/Invoice.php:233 +#: includes/Documents/Invoice.php:614 #: includes/Documents/PackingSlip.php:191 msgid "Attach to:" msgstr "" #. translators: directory path -#: includes/Documents/Invoice.php:235 -#: includes/Documents/Invoice.php:602 +#: includes/Documents/Invoice.php:241 +#: includes/Documents/Invoice.php:622 msgid "It looks like the temp folder (%s) is not writable, check the permissions for this folder! Without having write access to this folder, the plugin will not be able to email invoices." msgstr "" -#: includes/Documents/Invoice.php:241 +#: includes/Documents/Invoice.php:247 msgid "Disable for:" msgstr "" -#: includes/Documents/Invoice.php:250 +#: includes/Documents/Invoice.php:256 msgid "Select one or more statuses" msgstr "" -#: includes/Documents/Invoice.php:256 +#: includes/Documents/Invoice.php:262 msgid "Display shipping address" msgstr "" -#: includes/Documents/Invoice.php:263 -#: includes/Documents/Invoice.php:315 -#: includes/Documents/Invoice.php:347 +#: includes/Documents/Invoice.php:269 +#: includes/Documents/Invoice.php:321 +#: includes/Documents/Invoice.php:353 #: includes/Documents/PackingSlip.php:134 -#: views/advanced-status.php:169 -#: views/advanced-status.php:173 -#: views/advanced-status.php:204 -#: views/advanced-status.php:205 +#: views/advanced-status.php:47 +#: views/advanced-status.php:51 +#: views/advanced-status.php:82 +#: views/advanced-status.php:83 #: views/setup-wizard/display-options.php:20 #: views/setup-wizard/display-options.php:59 #: views/setup-wizard/display-options.php:80 msgid "No" msgstr "" -#: includes/Documents/Invoice.php:264 +#: includes/Documents/Invoice.php:270 #: views/setup-wizard/display-options.php:21 msgid "Only when different from billing address" msgstr "" -#: includes/Documents/Invoice.php:265 -#: includes/Documents/Invoice.php:434 +#: includes/Documents/Invoice.php:271 +#: includes/Documents/Invoice.php:440 #: includes/Documents/PackingSlip.php:136 #: views/setup-wizard/display-options.php:22 msgid "Always" msgstr "" -#: includes/Documents/Invoice.php:273 +#: includes/Documents/Invoice.php:279 #: includes/Documents/PackingSlip.php:144 msgid "Display email address" msgstr "" -#: includes/Documents/Invoice.php:284 +#: includes/Documents/Invoice.php:290 #: includes/Documents/PackingSlip.php:155 msgid "Display phone number" msgstr "" -#: includes/Documents/Invoice.php:295 +#: includes/Documents/Invoice.php:301 #: includes/Documents/PackingSlip.php:166 msgid "Display customer notes" msgstr "" -#: includes/Documents/Invoice.php:308 +#: includes/Documents/Invoice.php:314 msgid "Display invoice date" msgstr "" -#: includes/Documents/Invoice.php:317 +#: includes/Documents/Invoice.php:323 #: includes/Documents/OrderDocumentMethods.php:1307 #: views/setup-wizard/display-options.php:61 msgid "Order Date" msgstr "" -#: includes/Documents/Invoice.php:324 +#: includes/Documents/Invoice.php:330 msgid "Display due date" msgstr "" #. translators: number of days -#: includes/Documents/Invoice.php:331 +#: includes/Documents/Invoice.php:337 msgid "%s days" msgstr "" -#: includes/Documents/Invoice.php:340 +#: includes/Documents/Invoice.php:346 msgid "Display invoice number" msgstr "" -#: includes/Documents/Invoice.php:349 +#: includes/Documents/Invoice.php:355 #: views/setup-wizard/display-options.php:82 msgid "Order Number" msgstr "" -#: includes/Documents/Invoice.php:353 +#: includes/Documents/Invoice.php:359 msgid "Warning!" msgstr "" -#: includes/Documents/Invoice.php:354 +#: includes/Documents/Invoice.php:360 msgid "Using the Order Number as invoice number is not recommended as this may lead to gaps in the invoice number sequence (even when order numbers are sequential)." msgstr "" -#: includes/Documents/Invoice.php:355 +#: includes/Documents/Invoice.php:361 msgid "More information" msgstr "" -#: includes/Documents/Invoice.php:362 +#: includes/Documents/Invoice.php:368 msgid "Next invoice number (without prefix/suffix etc.)" msgstr "" -#: includes/Documents/Invoice.php:368 +#: includes/Documents/Invoice.php:374 msgid "This is the number that will be used for the next document. By default, numbering starts from 1 and increases for every new document. Note that if you override this and set it lower than the current/highest number, this could create duplicate numbers!" msgstr "" -#: includes/Documents/Invoice.php:374 +#: includes/Documents/Invoice.php:380 msgid "Number format" msgstr "" -#: includes/Documents/Invoice.php:382 +#: includes/Documents/Invoice.php:388 msgid "Prefix" msgstr "" -#: includes/Documents/Invoice.php:384 +#: includes/Documents/Invoice.php:390 msgid "If set, this value will be used as number prefix." msgstr "" #. translators: 1. document type, 2-3 placeholders -#: includes/Documents/Invoice.php:386 -#: includes/Documents/Invoice.php:395 +#: includes/Documents/Invoice.php:392 +#: includes/Documents/Invoice.php:401 msgid "You can use the %1$s year and/or month with the %2$s or %3$s placeholders respectively." msgstr "" -#: includes/Documents/Invoice.php:388 -#: includes/Documents/Invoice.php:397 +#: includes/Documents/Invoice.php:394 +#: includes/Documents/Invoice.php:403 msgid "Check the Docs article below to see all the available placeholders for prefix/suffix." msgstr "" -#: includes/Documents/Invoice.php:391 +#: includes/Documents/Invoice.php:397 msgid "Suffix" msgstr "" -#: includes/Documents/Invoice.php:393 +#: includes/Documents/Invoice.php:399 msgid "If set, this value will be used as number suffix." msgstr "" -#: includes/Documents/Invoice.php:400 +#: includes/Documents/Invoice.php:406 msgid "Padding" msgstr "" #. translators: document type -#: includes/Documents/Invoice.php:404 +#: includes/Documents/Invoice.php:410 msgid "Enter the number of digits you want to use as padding. For instance, enter 6 to display the %s number 123 as 000123, filling it with zeros until the number set as padding is reached." msgstr "" #. translators: document type -#: includes/Documents/Invoice.php:408 +#: includes/Documents/Invoice.php:414 msgid "For more information about setting up the number format and see the available placeholders for the prefix and suffix, check this article:" msgstr "" #. translators: document type -#: includes/Documents/Invoice.php:408 +#: includes/Documents/Invoice.php:414 msgid "Number format explained" msgstr "" #. translators: document type -#: includes/Documents/Invoice.php:408 +#: includes/Documents/Invoice.php:414 msgid "Note: Changes made to the number format will only be reflected on new orders. Also, if you have already created a custom %s number format with a filter, the above settings will be ignored." msgstr "" -#: includes/Documents/Invoice.php:414 +#: includes/Documents/Invoice.php:420 msgid "Reset invoice number yearly" msgstr "" -#: includes/Documents/Invoice.php:425 +#: includes/Documents/Invoice.php:431 msgid "Allow My Account invoice download" msgstr "" -#: includes/Documents/Invoice.php:432 +#: includes/Documents/Invoice.php:438 msgid "Only when an invoice is already created/emailed" msgstr "" -#: includes/Documents/Invoice.php:433 +#: includes/Documents/Invoice.php:439 msgid "Only for specific order statuses (define below)" msgstr "" -#: includes/Documents/Invoice.php:435 +#: includes/Documents/Invoice.php:441 msgid "Never" msgstr "" -#: includes/Documents/Invoice.php:450 +#: includes/Documents/Invoice.php:456 msgid "Enable invoice number column in the orders list" msgstr "" -#: includes/Documents/Invoice.php:461 +#: includes/Documents/Invoice.php:467 msgid "Enable invoice date column in the orders list" msgstr "" -#: includes/Documents/Invoice.php:472 +#: includes/Documents/Invoice.php:478 msgid "Enable invoice number search in the orders list" msgstr "" -#: includes/Documents/Invoice.php:478 +#: includes/Documents/Invoice.php:484 msgid "The search process may be slower on non-HPOS stores. For a more efficient search, you can utilize the HPOS feature, allowing you to search orders by invoice numbers using the search type selector." msgstr "" -#: includes/Documents/Invoice.php:484 +#: includes/Documents/Invoice.php:490 msgid "Disable for free orders" msgstr "" #. translators: zero number -#: includes/Documents/Invoice.php:491 +#: includes/Documents/Invoice.php:497 msgid "Disable document when the order total is %s" msgstr "" -#: includes/Documents/Invoice.php:497 +#: includes/Documents/Invoice.php:503 msgid "Mark as printed" msgstr "" -#: includes/Documents/Invoice.php:505 +#: includes/Documents/Invoice.php:511 msgid "Manually" msgstr "" -#: includes/Documents/Invoice.php:508 +#: includes/Documents/Invoice.php:514 msgid "On single order action" msgstr "" -#: includes/Documents/Invoice.php:509 +#: includes/Documents/Invoice.php:515 msgid "On bulk order action" msgstr "" -#: includes/Documents/Invoice.php:510 +#: includes/Documents/Invoice.php:516 msgid "On my account" msgstr "" -#: includes/Documents/Invoice.php:511 +#: includes/Documents/Invoice.php:517 msgid "On email attachment" msgstr "" -#: includes/Documents/Invoice.php:512 +#: includes/Documents/Invoice.php:518 msgid "On order document data (number and/or date set manually)" msgstr "" -#: includes/Documents/Invoice.php:517 +#: includes/Documents/Invoice.php:523 msgid "Allows you to mark the document as printed, manually (in the order page) or automatically (based on the document creation context you have selected)." msgstr "" -#: includes/Documents/Invoice.php:523 +#: includes/Documents/Invoice.php:529 msgid "Unmark as printed" msgstr "" -#: includes/Documents/Invoice.php:529 +#: includes/Documents/Invoice.php:535 msgid "Adds a link in the order page to allow to remove the printed mark." msgstr "" -#: includes/Documents/Invoice.php:535 +#: includes/Documents/Invoice.php:541 msgid "Always use most current settings" msgstr "" -#: includes/Documents/Invoice.php:541 +#: includes/Documents/Invoice.php:547 msgid "When enabled, the document will always reflect the most current settings (such as footer text, document name, etc.) rather than using historical settings." msgstr "" -#: includes/Documents/Invoice.php:543 +#: includes/Documents/Invoice.php:549 msgid "Caution: enabling this will also mean that if you change your company name or address in the future, previously generated documents will also be affected." msgstr "" -#: includes/Documents/Invoice.php:556 +#: includes/Documents/Invoice.php:562 msgid "Invoice numbers are created by a third-party extension." msgstr "" #. translators: link -#: includes/Documents/Invoice.php:559 +#: includes/Documents/Invoice.php:565 msgid "Configure it here." msgstr "" -#: includes/Documents/Invoice.php:608 +#: includes/Documents/Invoice.php:600 +msgid "Format" +msgstr "" + +#: includes/Documents/Invoice.php:607 +msgid "UBL 2.1" +msgstr "" + +#: includes/Documents/Invoice.php:628 msgid "Include encrypted PDF:" msgstr "" -#: includes/Documents/Invoice.php:614 -msgid "Include the PDF Invoice file encrypted in the UBL file." +#: includes/Documents/Invoice.php:634 +msgid "Embed the encrypted PDF invoice file within the UBL document. Note that this option may not be supported by all UBL formats." +msgstr "" + +#: includes/Documents/Invoice.php:657 +#: includes/Documents/Invoice.php:701 +#: includes/Documents/PackingSlip.php:229 +#: includes/Settings.php:163 +#: includes/Settings/SettingsDebug.php:682 +msgid "General" +msgstr "" + +#: includes/Documents/Invoice.php:666 +#: includes/Documents/PackingSlip.php:236 +msgid "Document details" +msgstr "" + +#: includes/Documents/Invoice.php:680 +msgid "Admin" +msgstr "" + +#: includes/Documents/Invoice.php:688 +#: includes/Settings.php:182 +msgid "Advanced" msgstr "" #. translators: 1. credit note title, 2. refund id -#: includes/Documents/OrderDocument.php:471 +#: includes/Documents/OrderDocument.php:482 msgid "%1$s (refund #%2$s) was regenerated." msgstr "" #. translators: 1. credit note title, 2. refund id -#: includes/Documents/OrderDocument.php:471 +#: includes/Documents/OrderDocument.php:482 msgid "%s was regenerated" msgstr "" #. translators: %s: document name -#: includes/Documents/OrderDocument.php:872 +#: includes/Documents/OrderDocument.php:883 msgid "%s Number:" msgstr "" #. translators: %s: document name -#: includes/Documents/OrderDocument.php:880 +#: includes/Documents/OrderDocument.php:891 msgid "%s Date:" msgstr "" -#: includes/Documents/OrderDocument.php:886 -#: includes/Main.php:1661 +#: includes/Documents/OrderDocument.php:897 +#: includes/Main.php:1723 msgid "Due Date:" msgstr "" -#: includes/Documents/OrderDocument.php:890 +#: includes/Documents/OrderDocument.php:901 msgid "Billing Address:" msgstr "" -#: includes/Documents/OrderDocument.php:893 +#: includes/Documents/OrderDocument.php:904 msgid "Shipping Address:" msgstr "" -#: includes/Documents/OrderDocument.php:896 +#: includes/Documents/OrderDocument.php:907 msgid "Order Number:" msgstr "" -#: includes/Documents/OrderDocument.php:899 +#: includes/Documents/OrderDocument.php:910 msgid "Order Date:" msgstr "" -#: includes/Documents/OrderDocument.php:902 +#: includes/Documents/OrderDocument.php:913 msgid "Payment Method:" msgstr "" -#: includes/Documents/OrderDocument.php:905 +#: includes/Documents/OrderDocument.php:916 #: languages/strings.php:6 msgid "Payment Date:" msgstr "" -#: includes/Documents/OrderDocument.php:908 +#: includes/Documents/OrderDocument.php:919 msgid "Shipping Method:" msgstr "" -#: includes/Documents/OrderDocument.php:911 +#: includes/Documents/OrderDocument.php:922 msgid "SKU:" msgstr "" -#: includes/Documents/OrderDocument.php:914 +#: includes/Documents/OrderDocument.php:925 msgid "Weight:" msgstr "" -#: includes/Documents/OrderDocument.php:917 +#: includes/Documents/OrderDocument.php:928 msgid "Notes:" msgstr "" -#: includes/Documents/OrderDocument.php:920 +#: includes/Documents/OrderDocument.php:931 msgid "Customer Notes:" msgstr "" -#: includes/Documents/OrderDocument.php:1544 +#: includes/Documents/OrderDocument.php:1565 msgid "Admin email" msgstr "" -#: includes/Documents/OrderDocument.php:1547 +#: includes/Documents/OrderDocument.php:1568 msgid "Manual email" msgstr "" @@ -720,7 +754,7 @@ msgid "Total ex. VAT" msgstr "" #: includes/Documents/OrderDocumentMethods.php:1111 -#: includes/Settings.php:438 +#: includes/Settings.php:427 #: ubl/Settings/TaxesSettings.php:170 msgid "Total" msgstr "" @@ -795,8 +829,8 @@ msgid "Could not find the order #%s." msgstr "" #: includes/Main.php:479 -#: includes/Settings.php:231 -#: includes/Settings.php:379 +#: includes/Settings.php:220 +#: includes/Settings.php:368 msgid "You do not have sufficient permissions to access this page." msgstr "" @@ -828,57 +862,62 @@ msgstr "" msgid "Nothing to delete!" msgstr "" +#: includes/Main.php:1292 +#: includes/Main.php:1323 +msgid "User" +msgstr "" + #. translators: 1. document title, 2. creation trigger -#: includes/Main.php:1274 +#: includes/Main.php:1300 msgid "PDF %1$s created via %2$s." msgstr "" #. translators: document title -#: includes/Main.php:1290 +#: includes/Main.php:1330 msgid "PDF %s deleted." msgstr "" -#: includes/Main.php:1305 +#: includes/Main.php:1347 msgid "manually" msgstr "" #. translators: 1. document title, 2. creation trigger -#: includes/Main.php:1311 +#: includes/Main.php:1353 msgid "%1$s document marked as printed via %2$s." msgstr "" #. translators: 1. document title, 2. creation trigger -#: includes/Main.php:1327 +#: includes/Main.php:1369 msgid "%1$s document unmark printed." msgstr "" -#: includes/Main.php:1412 +#: includes/Main.php:1456 msgid "single order action" msgstr "" -#: includes/Main.php:1413 +#: includes/Main.php:1457 msgid "bulk order action" msgstr "" -#: includes/Main.php:1414 +#: includes/Main.php:1458 msgid "my account" msgstr "" -#: includes/Main.php:1415 -msgid "email attachment" +#: includes/Main.php:1459 +msgid "order document data (number and/or date set manually)" msgstr "" -#: includes/Main.php:1416 -msgid "order document data (number and/or date set manually)" +#: includes/Main.php:1463 +msgid "email attachment" msgstr "" #. translators: 1. document type, 2. mark/unmark -#: includes/Main.php:1500 +#: includes/Main.php:1562 msgid "Document of type %1$s for the selected order could not be %2$s as printed." msgstr "" #. translators: document title -#: includes/Main.php:1597 +#: includes/Main.php:1659 msgid "Order %s Saved" msgstr "" @@ -895,77 +934,67 @@ msgstr "" msgid "Support Forum" msgstr "" -#. translators: database row value -#: includes/Settings.php:162 -msgid "Warning! Your database has an AUTO_INCREMENT step size of %d, your invoice numbers may not be sequential. Enable the 'Calculate document numbers (slow)' setting in the Advanced tab to use an alternate method." -msgstr "" - -#: includes/Settings.php:174 -#: includes/Settings/SettingsDebug.php:669 -msgid "General" -msgstr "" - -#: includes/Settings.php:178 +#: includes/Settings.php:167 msgid "Documents" msgstr "" -#: includes/Settings.php:185 +#: includes/Settings.php:174 msgid "UBL" msgstr "" -#: includes/Settings.php:193 -msgid "Advanced" -msgstr "" - -#: includes/Settings.php:198 +#: includes/Settings.php:187 msgid "Upgrade" msgstr "" -#: includes/Settings.php:271 +#: includes/Settings.php:260 msgid "Order not found!" msgstr "" -#: includes/Settings.php:274 +#: includes/Settings.php:263 msgid "Object found is not an order!" msgstr "" #. translators: order ID -#: includes/Settings.php:346 +#: includes/Settings.php:335 msgid "Document not available for order #%s, try selecting a different order." msgstr "" -#: includes/Settings.php:353 +#: includes/Settings.php:342 msgid "No WooCommerce orders found! Please consider adding your first order to see this preview." msgstr "" #. translators: error message -#: includes/Settings.php:363 +#: includes/Settings.php:352 msgid "Error trying to generate document: %s" msgstr "" -#: includes/Settings.php:437 +#: includes/Settings.php:426 #: includes/Tables/NumberStoreListTable.php:122 msgid "Date" msgstr "" -#: includes/Settings.php:445 +#: includes/Settings.php:434 msgid "No order(s) found!" msgstr "" -#: includes/Settings.php:448 +#: includes/Settings.php:437 msgid "An error occurred when trying to process your request!" msgstr "" #. translators: error message -#: includes/Settings.php:455 +#: includes/Settings.php:444 msgid "Error trying to get orders: %s" msgstr "" #. translators: total scheduled actions -#: includes/Settings.php:945 +#: includes/Settings.php:940 msgid "Only 1 scheduled action should exist for the yearly reset of the numbering system, but %s were found" msgstr "" +#: includes/Settings.php:1096 +msgid "Additional settings" +msgstr "" + #: includes/Settings/SettingsCallbacks.php:37 msgid "Warning! The settings below are meant for debugging/development only. Do not use them on a live website!" msgstr "" @@ -986,291 +1015,382 @@ msgstr "" msgid "Save" msgstr "" -#: includes/Settings/SettingsDebug.php:207 +#: includes/Settings/SettingsDebug.php:220 msgid "Temporary folder moved to" msgstr "" -#: includes/Settings/SettingsDebug.php:216 +#: includes/Settings/SettingsDebug.php:229 msgid "Fonts reinstalled!" msgstr "" -#: includes/Settings/SettingsDebug.php:224 +#: includes/Settings/SettingsDebug.php:237 msgid "Yearly reset numbering system rescheduled!" msgstr "" -#: includes/Settings/SettingsDebug.php:250 +#: includes/Settings/SettingsDebug.php:263 msgid "Released semaphore locks have been cleaned up!" msgstr "" -#: includes/Settings/SettingsDebug.php:258 +#: includes/Settings/SettingsDebug.php:271 msgid "Released legacy semaphore locks have been cleaned up!" msgstr "" -#: includes/Settings/SettingsDebug.php:266 +#: includes/Settings/SettingsDebug.php:279 msgid "Extensions' license cache cleared successfully!" msgstr "" -#: includes/Settings/SettingsDebug.php:294 +#: includes/Settings/SettingsDebug.php:307 msgid "Export settings type is empty!" msgstr "" -#: includes/Settings/SettingsDebug.php:331 +#: includes/Settings/SettingsDebug.php:344 msgid "Exported settings data is empty!" msgstr "" -#: includes/Settings/SettingsDebug.php:350 +#: includes/Settings/SettingsDebug.php:363 msgid "Failed to get contents from JSON file!" msgstr "" -#: includes/Settings/SettingsDebug.php:357 +#: includes/Settings/SettingsDebug.php:370 msgid "JSON file not found!" msgstr "" -#: includes/Settings/SettingsDebug.php:363 +#: includes/Settings/SettingsDebug.php:376 msgid "The JSON file data is corrupted!" msgstr "" -#: includes/Settings/SettingsDebug.php:374 +#: includes/Settings/SettingsDebug.php:387 msgid "The JSON file settings type is not supported on this store!" msgstr "" -#: includes/Settings/SettingsDebug.php:399 +#: includes/Settings/SettingsDebug.php:412 msgid "Couldn't determine the settings option for the import!" msgstr "" #. translators: settings type -#: includes/Settings/SettingsDebug.php:408 +#: includes/Settings/SettingsDebug.php:421 msgid "%s settings imported successfully!" msgstr "" #. translators: settings type -#: includes/Settings/SettingsDebug.php:416 +#: includes/Settings/SettingsDebug.php:429 msgid "The %s settings file you are trying to import is identical to your current settings, therefore, the settings were not imported." msgstr "" -#: includes/Settings/SettingsDebug.php:428 +#: includes/Settings/SettingsDebug.php:441 msgid "Reset settings type is empty!" msgstr "" #. translators: settings type -#: includes/Settings/SettingsDebug.php:467 +#: includes/Settings/SettingsDebug.php:480 msgid "%s settings reset not supported!" msgstr "" #. translators: settings type -#: includes/Settings/SettingsDebug.php:480 +#: includes/Settings/SettingsDebug.php:493 msgid "%s settings are already reset!" msgstr "" #. translators: settings type -#: includes/Settings/SettingsDebug.php:492 +#: includes/Settings/SettingsDebug.php:505 msgid "%s settings reset successfully!" msgstr "" #. translators: settings type -#: includes/Settings/SettingsDebug.php:500 +#: includes/Settings/SettingsDebug.php:513 msgid "An error occurred when trying to reset the %s settings." msgstr "" -#: includes/Settings/SettingsDebug.php:514 +#: includes/Settings/SettingsDebug.php:527 msgid "One or more request parameters missing." msgstr "" -#: includes/Settings/SettingsDebug.php:526 +#: includes/Settings/SettingsDebug.php:539 msgid "documents deleted." msgstr "" -#: includes/Settings/SettingsDebug.php:526 +#: includes/Settings/SettingsDebug.php:539 msgid "documents renumbered." msgstr "" -#: includes/Settings/SettingsDebug.php:557 +#: includes/Settings/SettingsDebug.php:570 msgid "Wrong date type selected." msgstr "" -#: includes/Settings/SettingsDebug.php:572 +#: includes/Settings/SettingsDebug.php:585 msgid "Unexpected results from the orders query." msgstr "" -#: includes/Settings/SettingsDebug.php:670 +#: includes/Settings/SettingsDebug.php:683 msgid "Debug" msgstr "" -#: includes/Settings/SettingsDebug.php:671 +#: includes/Settings/SettingsDebug.php:684 msgid "UBL Taxes" msgstr "" -#: includes/Settings/SettingsDebug.php:707 +#: includes/Settings/SettingsDebug.php:720 msgid "Document link access type" msgstr "" -#: includes/Settings/SettingsDebug.php:715 +#: includes/Settings/SettingsDebug.php:728 msgid "Logged in (recommended)" msgstr "" -#: includes/Settings/SettingsDebug.php:716 -#: includes/Settings/SettingsDebug.php:916 +#: includes/Settings/SettingsDebug.php:729 +#: includes/Settings/SettingsDebug.php:929 msgid "Guest" msgstr "" -#: includes/Settings/SettingsDebug.php:717 -#: includes/Settings/SettingsDebug.php:920 +#: includes/Settings/SettingsDebug.php:730 +#: includes/Settings/SettingsDebug.php:933 msgid "Full" msgstr "" -#: includes/Settings/SettingsDebug.php:734 +#: includes/Settings/SettingsDebug.php:747 msgid "Document access denied redirect page" msgstr "" -#: includes/Settings/SettingsDebug.php:742 +#: includes/Settings/SettingsDebug.php:755 msgid "Blank page with message (default)" msgstr "" -#: includes/Settings/SettingsDebug.php:743 +#: includes/Settings/SettingsDebug.php:756 msgid "Login page" msgstr "" -#: includes/Settings/SettingsDebug.php:744 +#: includes/Settings/SettingsDebug.php:757 msgid "My Account page" msgstr "" -#: includes/Settings/SettingsDebug.php:745 +#: includes/Settings/SettingsDebug.php:758 msgid "Custom page (enter below)" msgstr "" -#: includes/Settings/SettingsDebug.php:747 +#: includes/Settings/SettingsDebug.php:760 msgid "Select a frontend page to be used to redirect users when the document access is denied." msgstr "" -#: includes/Settings/SettingsDebug.php:760 +#: includes/Settings/SettingsDebug.php:773 msgid "Custom external URLs not allowed." msgstr "" -#: includes/Settings/SettingsDebug.php:766 +#: includes/Settings/SettingsDebug.php:779 msgid "Pretty document links" msgstr "" -#: includes/Settings/SettingsDebug.php:772 +#: includes/Settings/SettingsDebug.php:785 msgid "Changes the document links to a prettier URL scheme." msgstr "" -#: includes/Settings/SettingsDebug.php:778 +#: includes/Settings/SettingsDebug.php:791 msgid "Calculate document numbers (slow)" msgstr "" #. translators: 1. AUTO_INCREMENT, 2. one -#: includes/Settings/SettingsDebug.php:786 +#: includes/Settings/SettingsDebug.php:799 msgid "Document numbers (such as invoice numbers) are generated using %1$s by default. Use this setting if your database auto increments with more than %2$s." msgstr "" -#: includes/Settings/SettingsDebug.php:795 +#: includes/Settings/SettingsDebug.php:808 msgid "Enable debug output" msgstr "" -#: includes/Settings/SettingsDebug.php:801 +#: includes/Settings/SettingsDebug.php:814 msgid "Enable this option to output plugin errors if you're getting a blank page or other PDF generation issues." msgstr "" -#: includes/Settings/SettingsDebug.php:802 +#: includes/Settings/SettingsDebug.php:815 msgid "Caution! This setting may reveal errors (from other plugins) in other places on your site too, therefore this is not recommended to leave it enabled on live sites." msgstr "" #. translators: &debug=true -#: includes/Settings/SettingsDebug.php:805 +#: includes/Settings/SettingsDebug.php:818 msgid "You can also add %s to the URL to apply this on a per-order basis." msgstr "" -#: includes/Settings/SettingsDebug.php:813 +#: includes/Settings/SettingsDebug.php:826 msgid "Enable automatic cleanup" msgstr "" #. translators: number of days -#: includes/Settings/SettingsDebug.php:820 +#: includes/Settings/SettingsDebug.php:833 msgid "every %s days" msgstr "" -#: includes/Settings/SettingsDebug.php:824 +#: includes/Settings/SettingsDebug.php:837 msgid "Automatically clean up PDF files stored in the temporary folder (used for email attachments)" msgstr "" -#: includes/Settings/SettingsDebug.php:830 +#: includes/Settings/SettingsDebug.php:843 msgid "Output to HTML" msgstr "" -#: includes/Settings/SettingsDebug.php:836 +#: includes/Settings/SettingsDebug.php:849 msgid "Send the template output as HTML to the browser instead of creating a PDF." msgstr "" -#: includes/Settings/SettingsDebug.php:837 +#: includes/Settings/SettingsDebug.php:850 msgid "You can also add &output=html to the URL to apply this on a per-order basis." msgstr "" -#: includes/Settings/SettingsDebug.php:843 +#: includes/Settings/SettingsDebug.php:856 msgid "Embed Images" msgstr "" -#: includes/Settings/SettingsDebug.php:849 +#: includes/Settings/SettingsDebug.php:862 msgid "Embed images only if you are experiencing issues with them loading in your PDF. Please note that this option can significantly increase the file size." msgstr "" -#: includes/Settings/SettingsDebug.php:855 +#: includes/Settings/SettingsDebug.php:868 msgid "Log to order notes" msgstr "" -#: includes/Settings/SettingsDebug.php:861 +#: includes/Settings/SettingsDebug.php:874 msgid "Log PDF document creation, deletion, and mark/unmark as printed to order notes." msgstr "" -#: includes/Settings/SettingsDebug.php:867 +#: includes/Settings/SettingsDebug.php:880 msgid "Disable document preview" msgstr "" -#: includes/Settings/SettingsDebug.php:873 +#: includes/Settings/SettingsDebug.php:886 msgid "Disables the document preview on the plugin settings pages." msgstr "" -#: includes/Settings/SettingsDebug.php:879 +#: includes/Settings/SettingsDebug.php:892 msgid "Enable semaphore logs" msgstr "" -#: includes/Settings/SettingsDebug.php:885 +#: includes/Settings/SettingsDebug.php:898 msgid "Our plugin uses a semaphore class that prevents race conditions in multiple places in the code. Enable this setting only if you are having issues with document numbers, yearly reset or documents being assigned to the wrong order." msgstr "" -#: includes/Settings/SettingsDebug.php:891 +#: includes/Settings/SettingsDebug.php:904 msgid "Enable danger zone tools" msgstr "" -#: includes/Settings/SettingsDebug.php:897 +#: includes/Settings/SettingsDebug.php:910 msgid "Enables the danger zone tools. The actions performed by these tools are irreversible!" msgstr "" -#: includes/Settings/SettingsDebug.php:912 +#: includes/Settings/SettingsDebug.php:925 msgid "Logged in" msgstr "" -#: includes/Settings/SettingsDebug.php:913 +#: includes/Settings/SettingsDebug.php:926 msgid "Document can be accessed by logged in users only." msgstr "" -#: includes/Settings/SettingsDebug.php:917 +#: includes/Settings/SettingsDebug.php:930 msgid "Document can be accessed by logged in and guest users." msgstr "" -#: includes/Settings/SettingsDebug.php:921 +#: includes/Settings/SettingsDebug.php:934 msgid "Document can be accessed by everyone with the link." msgstr "" -#: includes/Settings/SettingsDebug.php:930 -#: views/advanced-status.php:325 +#: includes/Settings/SettingsDebug.php:957 +msgid "7.4 or superior" +msgstr "" + +#: includes/Settings/SettingsDebug.php:970 +msgid "Recommended, will use fallback functions" +msgstr "" + +#: includes/Settings/SettingsDebug.php:976 +msgid "Required if you have images in your documents" +msgstr "" + +#: includes/Settings/SettingsDebug.php:979 +msgid "Required when using .webp images" +msgstr "" + +#: includes/Settings/SettingsDebug.php:982 +msgid "Required if you have .webp images in your documents" +msgstr "" + +#: includes/Settings/SettingsDebug.php:985 +msgid "To compress PDF documents" +msgstr "" + +#: includes/Settings/SettingsDebug.php:988 +msgid "Recommended to compress PDF documents" +msgstr "" + +#: includes/Settings/SettingsDebug.php:991 +msgid "For better performances" +msgstr "" + +#: includes/Settings/SettingsDebug.php:994 +#: includes/Settings/SettingsDebug.php:1000 +msgid "Recommended for better performances" +msgstr "" + +#: includes/Settings/SettingsDebug.php:997 +msgid "Better with transparent PNG images" +msgstr "" + +#: includes/Settings/SettingsDebug.php:1003 +msgid "Required to detect custom templates and to clear the temp folder periodically" +msgstr "" + +#: includes/Settings/SettingsDebug.php:1006 +msgid "Check PHP disable_functions" +msgstr "" + +#. translators: tags +#: includes/Settings/SettingsDebug.php:1010 +msgid "Recommended: 128MB (more for plugin-heavy setups
See: %1$sIncreasing the WordPress Memory Limit%2$s" +msgstr "" + +#: includes/Settings/SettingsDebug.php:1015 +msgid "Allow remote stylesheets and images" +msgstr "" + +#: includes/Settings/SettingsDebug.php:1018 +msgid "allow_url_fopen disabled" +msgstr "" + +#: includes/Settings/SettingsDebug.php:1021 +msgid "Necessary to verify the MIME type of local images." +msgstr "" + +#: includes/Settings/SettingsDebug.php:1024 +msgid "fileinfo disabled" +msgstr "" + +#: includes/Settings/SettingsDebug.php:1027 +msgid "To compress and decompress font and image data" +msgstr "" + +#: includes/Settings/SettingsDebug.php:1030 +msgid "base64_decode disabled" +msgstr "" + +#: includes/Settings/SettingsDebug.php:1038 +msgid "Required for IMagick" +msgstr "" + +#: includes/Settings/SettingsDebug.php:1041 +msgid "ImageMagick library, integrated via the IMagick PHP extension for advanced image processing capabilities" +msgstr "" + +#. translators: 1: Plugin name, 2: Open anchor tag, 3: Close anchor tag +#: includes/Settings/SettingsDebug.php:1121 +msgid "Your server does not meet the requirements for %1$s. Please check the %2$sStatus page%3$s for more information." +msgstr "" + +#: includes/Settings/SettingsDebug.php:1140 +#: views/advanced-status.php:203 msgid "Status" msgstr "" -#: includes/Settings/SettingsDebug.php:931 +#: includes/Settings/SettingsDebug.php:1141 msgid "Tools" msgstr "" -#: includes/Settings/SettingsDebug.php:932 +#: includes/Settings/SettingsDebug.php:1142 msgid "Numbers" msgstr "" @@ -1398,42 +1518,54 @@ msgid "Shop Chamber of Commerce Number" msgstr "" #: includes/Settings/SettingsGeneral.php:203 +msgid "Shop Phone Number" +msgstr "" + +#: includes/Settings/SettingsGeneral.php:210 +msgid "Mandatory for certain UBL formats." +msgstr "" + +#: includes/Settings/SettingsGeneral.php:216 msgid "Shop Address" msgstr "" -#: includes/Settings/SettingsGeneral.php:218 +#: includes/Settings/SettingsGeneral.php:231 msgid "Footer: terms & conditions, policies, etc." msgstr "" -#: includes/Settings/SettingsGeneral.php:233 +#: includes/Settings/SettingsGeneral.php:246 msgid "Extra template fields" msgstr "" -#: includes/Settings/SettingsGeneral.php:239 +#: includes/Settings/SettingsGeneral.php:252 msgid "Extra field 1" msgstr "" -#: includes/Settings/SettingsGeneral.php:247 +#: includes/Settings/SettingsGeneral.php:260 msgid "This is footer column 1 in the Modern (Premium) template" msgstr "" -#: includes/Settings/SettingsGeneral.php:254 +#: includes/Settings/SettingsGeneral.php:267 msgid "Extra field 2" msgstr "" -#: includes/Settings/SettingsGeneral.php:262 +#: includes/Settings/SettingsGeneral.php:275 msgid "This is footer column 2 in the Modern (Premium) template" msgstr "" -#: includes/Settings/SettingsGeneral.php:269 +#: includes/Settings/SettingsGeneral.php:282 msgid "Extra field 3" msgstr "" -#: includes/Settings/SettingsGeneral.php:277 +#: includes/Settings/SettingsGeneral.php:290 msgid "This is footer column 3 in the Modern (Premium) template" msgstr "" -#: includes/Settings/SettingsGeneral.php:331 +#: includes/Settings/SettingsGeneral.php:350 +msgid "Extension" +msgstr "" + +#: includes/Settings/SettingsGeneral.php:354 msgid "Custom" msgstr "" @@ -1530,7 +1662,7 @@ msgstr "" #: includes/Settings/SettingsUpgrade.php:91 #: includes/Settings/SettingsUpgrade.php:101 #: includes/Settings/SettingsUpgrade.php:111 -#: views/upgrade-table.php:54 +#: views/upgrade-table.php:74 msgid "Learn more" msgstr "" @@ -2037,187 +2169,96 @@ msgstr "" msgid "Please select a number store!" msgstr "" -#: views/advanced-status.php:13 -msgid "7.2+ (7.4 or higher recommended)" -msgstr "" - -#: views/advanced-status.php:26 -msgid "Recommended, will use fallback functions" -msgstr "" - -#: views/advanced-status.php:32 -msgid "Required if you have images in your documents" -msgstr "" - -#: views/advanced-status.php:35 -msgid "Required when using .webp images" -msgstr "" - -#: views/advanced-status.php:38 -msgid "Required if you have .webp images in your documents" -msgstr "" - -#: views/advanced-status.php:47 -msgid "To compress PDF documents" -msgstr "" - -#: views/advanced-status.php:50 -msgid "Recommended to compress PDF documents" -msgstr "" - -#: views/advanced-status.php:53 -msgid "For better performances" -msgstr "" - -#: views/advanced-status.php:56 -#: views/advanced-status.php:62 -msgid "Recommended for better performances" -msgstr "" - -#: views/advanced-status.php:59 -msgid "Better with transparent PNG images" -msgstr "" - -#: views/advanced-status.php:65 -msgid "Required to detect custom templates and to clear the temp folder periodically" -msgstr "" - -#: views/advanced-status.php:68 -msgid "Check PHP disable_functions" -msgstr "" - -#. translators:
tags -#: views/advanced-status.php:72 -msgid "Recommended: 128MB (more for plugin-heavy setups
See: %1$sIncreasing the WordPress Memory Limit%2$s" -msgstr "" - -#: views/advanced-status.php:77 -msgid "Allow remote stylesheets and images" -msgstr "" - -#: views/advanced-status.php:80 -msgid "allow_url_fopen disabled" -msgstr "" - -#: views/advanced-status.php:83 -msgid "Necessary to verify the MIME type of local images." -msgstr "" - -#: views/advanced-status.php:86 -msgid "fileinfo disabled" -msgstr "" - -#: views/advanced-status.php:89 -msgid "To compress and decompress font and image data" -msgstr "" - -#: views/advanced-status.php:92 -msgid "base64_decode disabled" -msgstr "" - -#: views/advanced-status.php:100 -msgid "Required for IMagick" -msgstr "" - -#: views/advanced-status.php:103 -msgid "ImageMagick library, integrated via the IMagick PHP extension for advanced image processing capabilities" -msgstr "" - -#. translators:
tags -#: views/advanced-status.php:125 -msgid "Download %1$sthis addon%2$s to enable backwards compatibility." -msgstr "" - -#: views/advanced-status.php:132 +#: views/advanced-status.php:10 msgid "System Configuration" msgstr "" -#: views/advanced-status.php:138 +#: views/advanced-status.php:16 msgid "Required" msgstr "" -#: views/advanced-status.php:139 +#: views/advanced-status.php:17 msgid "Present" msgstr "" -#: views/advanced-status.php:158 -#: views/advanced-status.php:165 -#: views/advanced-status.php:204 -#: views/advanced-status.php:205 -#: views/advanced-status.php:270 +#: views/advanced-status.php:36 +#: views/advanced-status.php:43 +#: views/advanced-status.php:82 +#: views/advanced-status.php:83 +#: views/advanced-status.php:148 msgid "Yes" msgstr "" -#: views/advanced-status.php:188 +#: views/advanced-status.php:66 msgid "Documents status" msgstr "" -#: views/advanced-status.php:194 +#: views/advanced-status.php:72 msgid "Enabled" msgstr "" -#: views/advanced-status.php:195 -#: views/advanced-status.php:253 +#: views/advanced-status.php:73 +#: views/advanced-status.php:131 msgid "Yearly reset" msgstr "" -#: views/advanced-status.php:218 +#: views/advanced-status.php:96 msgid "Required to reset documents numeration" msgstr "" -#: views/advanced-status.php:219 +#: views/advanced-status.php:97 msgid "Yearly reset action not found" msgstr "" #. translators: total scheduled actions -#: views/advanced-status.php:237 +#: views/advanced-status.php:115 msgid "Only 1 scheduled action should exist, but %s were found" msgstr "" #. translators: 1. open anchor tag, 2. close anchor tag -#: views/advanced-status.php:245 +#: views/advanced-status.php:123 msgid "Scheduled action not found. Please reschedule it %1$shere%2$s." msgstr "" -#: views/advanced-status.php:281 +#: views/advanced-status.php:159 msgid "Writable" msgstr "" -#: views/advanced-status.php:282 +#: views/advanced-status.php:160 msgid "Not writable" msgstr "" -#: views/advanced-status.php:287 +#: views/advanced-status.php:165 msgid "Central temporary plugin folder" msgstr "" -#: views/advanced-status.php:293 +#: views/advanced-status.php:171 msgid "Temporary attachments folder" msgstr "" -#: views/advanced-status.php:299 +#: views/advanced-status.php:177 msgid "Temporary DOMPDF folder" msgstr "" -#: views/advanced-status.php:305 +#: views/advanced-status.php:183 msgid "DOMPDF fonts folder (needs to be writable for custom/remote fonts)" msgstr "" -#: views/advanced-status.php:318 +#: views/advanced-status.php:196 msgid "Write Permissions" msgstr "" -#: views/advanced-status.php:324 +#: views/advanced-status.php:202 msgid "Path" msgstr "" #. translators: 1,2. directory paths, 3. UPLOADS, 4. wpo_wcpdf_tmp_path, 5. attachments, 6. dompdf, 7. fonts -#: views/advanced-status.php:349 +#: views/advanced-status.php:227 msgid "The central temp folder is %1$s. By default, this folder is created in the WordPress uploads folder (%2$s), which can be defined by setting %3$s in wp-config.php. Alternatively, you can control the specific folder for PDF invoices by using the %4$s filter. Make sure this folder is writable and that the subfolders %5$s, %6$s and %7$s are present (these will be created by the plugin if the central temp folder is writable)." msgstr "" #. translators: directory path -#: views/advanced-status.php:365 +#: views/advanced-status.php:243 msgid "If the temporary folders were not automatically created by the plugin, verify that all the font files (from %s) are copied to the fonts folder. Normally, this is fully automated, but if your server has strict security settings, this automated copying may have been prohibited. In that case, you also need to make sure these folders get synchronized on plugin updates!" msgstr "" @@ -2271,7 +2312,7 @@ msgid "Remove released semaphore locks" msgstr "" #: views/advanced-tools.php:63 -msgid "Clean up the released semaphore locks from the database." +msgid "Clean up the released semaphore locks from the database. These locks prevent simultaneous document generation requests, ensuring correct document numbering. Once released, they are safe to remove." msgstr "" #: views/advanced-tools.php:66 @@ -2730,98 +2771,93 @@ msgid "Professional" msgstr "" #: views/upgrade-table.php:22 -msgid "Bundle" +msgid "Premium Templates" +msgstr "" + +#: views/upgrade-table.php:23 +msgid "Plus Bundle" msgstr "" -#: views/upgrade-table.php:49 -#: views/upgrade-table.php:116 +#: views/upgrade-table.php:63 +#: views/upgrade-table.php:155 msgid "Currently installed" msgstr "" #. translators: learn more link -#: views/upgrade-table.php:53 +#: views/upgrade-table.php:73 msgid "License not yet activated: %s" msgstr "" -#: views/upgrade-table.php:75 +#: views/upgrade-table.php:97 msgid "Upgrade now" msgstr "" -#: views/upgrade-table.php:98 +#: views/upgrade-table.php:137 msgid "You might also like these plugins..." msgstr "" -#: views/upgrade-table.php:101 +#: views/upgrade-table.php:140 msgid "Wow! It looks like you own all of our recommendations. Check out our shop for even more plugins." msgstr "" -#: views/upgrade-table.php:102 +#: views/upgrade-table.php:141 msgid "Visit shop" msgstr "" -#: views/upgrade-table.php:118 +#: views/upgrade-table.php:157 msgid "Buy now" msgstr "" #. translators: 1. open anchor tag, 2. close anchor tag, 3. Woo version -#: woocommerce-pdf-invoices-packingslips.php:194 +#: woocommerce-pdf-invoices-packingslips.php:192 msgid "PDF Invoices & Packing Slips for WooCommerce requires %1$sWooCommerce%2$s version %3$s or higher to be installed & activated!" msgstr "" #. translators: PHP version -#: woocommerce-pdf-invoices-packingslips.php:239 +#: woocommerce-pdf-invoices-packingslips.php:237 msgid "PDF Invoices & Packing Slips for WooCommerce requires PHP %s or higher." msgstr "" #. translators: tags -#: woocommerce-pdf-invoices-packingslips.php:245 +#: woocommerce-pdf-invoices-packingslips.php:243 msgid "We strongly recommend to %1$supdate your PHP version%2$s." msgstr "" #. translators: directory path -#: woocommerce-pdf-invoices-packingslips.php:337 +#: woocommerce-pdf-invoices-packingslips.php:335 msgid "The PDF files in %s are not currently protected due to your site running on NGINX." msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:338 +#: woocommerce-pdf-invoices-packingslips.php:336 msgid "To protect them, you must click the button below." msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:339 +#: woocommerce-pdf-invoices-packingslips.php:337 msgid "Generate random temporary folder name" msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:396 +#: woocommerce-pdf-invoices-packingslips.php:394 msgid "When sending emails with MailPoet 3 and the active sending method is MailPoet Sending Service or Your web host / web server, MailPoet does not include the PDF Invoices & Packing Slips for WooCommerce attachments in the emails." msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:397 +#: woocommerce-pdf-invoices-packingslips.php:395 msgid "To fix this you should select The default WordPress sending method (default) on the Advanced tab." msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:398 +#: woocommerce-pdf-invoices-packingslips.php:396 msgid "Change MailPoet sending method to WordPress (default)" msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:435 +#: woocommerce-pdf-invoices-packingslips.php:433 msgid "PDF Invoices & Packing Slips for WooCommerce detected that your current site locale is right-to-left (RTL) which the current PDF engine does not support it. Please consider installing our mPDF extension that is compatible." msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:436 +#: woocommerce-pdf-invoices-packingslips.php:434 msgid "Download mPDF extension" msgstr "" -#. translators: plugin name -#: woocommerce-pdf-invoices-packingslips.php:476 -msgid "Soon, our %s plugin and its extensions will no longer support PHP versions below 7.4. To ensure uninterrupted use and continued access to updates, please update your PHP version to 7.4 or higher as soon as possible. If you need assistance, please contact your hosting provider for support with the update." -msgstr "" - -#: woocommerce-pdf-invoices-packingslips.php:511 -msgid "PDF Invoices & Packing Slips for WooCommerce has detected that your PHP version is below 7.4. As a result, UBL features are disabled. To enable these features, please consider upgrading your PHP version." -msgstr "" - #. translators: legacy addon name -#: woocommerce-pdf-invoices-packingslips.php:596 +#: woocommerce-pdf-invoices-packingslips.php:520 msgid "While updating the PDF Invoices & Packing Slips for WooCommerce plugin we've noticed our legacy %s add-on was active on your site. This functionality is now incorporated into the core plugin. We've deactivated the add-on for you, and you are free to uninstall it." msgstr "" diff --git a/readme.txt b/readme.txt index 826a37d6d..fd16dbf02 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 Requires PHP: 7.4 -Stable tag: 3.9.1-beta-4 +Stable tag: 3.9.1 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -102,6 +102,26 @@ There's a setting on the Advanced tab of the settings page that allows you to to == Changelog == += 3.9.1 (2024-12-16) = +- New: Adds support for multiple UBL formats. +- New: Adds a shop phone number field for e-Invoice support. +- New: Adds user info to order notes when generating documents. +- New: Added an admin notice to inform when server requirements are not met. +- New: Raised the minimum PHP version requirement to 7.4. +- New: Removes space between items table and totals. +- New: Added sections to settings for better organization. +- Tweak: Improve the description of the "Remove released semaphore locks" tool. +- Fix: Upgrade links not displaying correctly. +- Fix: Temp folder warning style issue. +- Fix: Remove unused legacy notice code: `check_auto_increment_increment()`. +- Fix: AJAX preview loading when disabled on settings pages. +- Fix: UBL issue with empty tax on line items. +- Fix: jQuery `tipTip` function not available. +- Fix: Template item meta styling. +- Fix: Semaphore class name on two classes that were still using the previous name. +- Translations: Updated translation template (POT). +- Tested: Tested up to WooCommerce 9.5. + = 3.9.0 (2024-10-21) = * New: Updated `sabre/xml` library to version 4. * New: Added notice about dropping support for PHP versions below 7.4. diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index c57f423b7..3dc780336 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,7 +4,7 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.1-beta-4 + * Version: 3.9.1 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.1-beta-4'; + public $version = '3.9.1'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; From 07e43ed414648a2dcc6b6c8b1e6c45d672a4e363 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Mon, 16 Dec 2024 13:09:49 +0000 Subject: [PATCH 24/69] Update lint.yml --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 16aee144a..d3b8241d6 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: operating-system: ['ubuntu-latest'] - php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] + php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3'] steps: - name: Checkout Git repository From a86d3f48411b1d5cc8f4005c83c73fd31acedb06 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Mon, 16 Dec 2024 16:31:48 +0000 Subject: [PATCH 25/69] New: adds description to UBL format selector (#931) --- includes/Documents/Invoice.php | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/includes/Documents/Invoice.php b/includes/Documents/Invoice.php index 7dd214c58..fb5b11956 100644 --- a/includes/Documents/Invoice.php +++ b/includes/Documents/Invoice.php @@ -606,6 +606,7 @@ public function get_ubl_settings_fields( $option_name ) { 'options' => apply_filters( 'wpo_wcpdf_document_ubl_settings_formats', array( 'ubl_2_1' => __( 'UBL 2.1' , 'woocommerce-pdf-invoices-packing-slips' ), ), $this ), + 'description' => $this->get_ubl_format_description(), ) ), array( @@ -711,6 +712,46 @@ public function get_settings_categories( string $output_format ): array { return apply_filters( 'wpo_wcpdf_document_settings_categories', $settings_categories[ $output_format ] ?? array(), $output_format, $this ); } + + /** + * Get UBL Format setting description + * + * @return string + */ + private function get_ubl_format_description(): string { + $extensions_available = array(); + $ubl_format_description = ''; + + if ( ! class_exists( 'WPO_IPS_XRechnung' ) ) { + $extensions_available['xrechnung'] = array( + 'title' => __( 'EN16931 XRechnung', 'woocommerce-pdf-invoices-packing-slips' ), + 'url' => 'https://github.com/wpovernight/wpo-ips-xrechnung/releases/latest/', + ); + } + + if ( ! empty( $extensions_available ) ) { + $ubl_format_description = __( 'Formats available through extensions', 'woocommerce-pdf-invoices-packing-slips' ) . ':'; + + foreach ( $extensions_available as $extension ) { + $ubl_format_description .= ' ' . esc_html( $extension['title'] ) . ''; + + if ( next( $extensions_available ) ) { + $ubl_format_description .= ','; + } else { + $ubl_format_description .= '
'; + } + } + } + + $ubl_format_description .= sprintf( + /* translators: %1$s: opening link tag, %2$s: closing link tag */ + __( 'If the format you need isn\'t listed, please don\'t hesitate to %1$scontact us%2$s!', 'woocommerce-pdf-invoices-packing-slips' ), + '', + '' + ); + + return $ubl_format_description; + } } From 55d9e17594069b87cd2a6286cebf10ad0e945fc1 Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:33:32 +0330 Subject: [PATCH 26/69] Fix: issue on PHP extension loaded checks (#933) --- includes/Settings/SettingsDebug.php | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/includes/Settings/SettingsDebug.php b/includes/Settings/SettingsDebug.php index d66d10582..0f3b4902e 100644 --- a/includes/Settings/SettingsDebug.php +++ b/includes/Settings/SettingsDebug.php @@ -951,6 +951,11 @@ public function get_server_config(): array { $apc = extension_loaded( 'apc' ); $zop = extension_loaded( 'Zend OPcache' ); $op = extension_loaded( 'opcache' ); + $dom = extension_loaded( 'DOM' ); + $mbstring = extension_loaded( 'mbstring' ); + $gd = extension_loaded( 'gd' ); + $zlib = extension_loaded( 'zlib' ); + $fileinfo = extension_loaded( 'fileinfo' ); $server_configs = array( 'PHP version' => array( @@ -961,18 +966,18 @@ public function get_server_config(): array { 'DOMDocument extension' => array( 'required' => true, 'value' => phpversion( 'DOM' ), - 'result' => class_exists( 'DOMDocument' ), + 'result' => $dom, ), 'MBString extension' => array( 'required' => true, 'value' => phpversion( 'mbstring' ), - 'result' => function_exists( 'mb_send_mail' ), + 'result' => $mbstring, 'fallback' => __( 'Recommended, will use fallback functions', 'woocommerce-pdf-invoices-packing-slips' ), ), 'GD' => array( 'required' => true, 'value' => phpversion( 'gd' ), - 'result' => function_exists( 'imagecreate' ), + 'result' => $gd, 'fallback' => __( 'Required if you have images in your documents', 'woocommerce-pdf-invoices-packing-slips' ), ), 'WebP Support' => array( @@ -984,7 +989,7 @@ public function get_server_config(): array { 'Zlib' => array( 'required' => __( 'To compress PDF documents', 'woocommerce-pdf-invoices-packing-slips' ), 'value' => phpversion( 'zlib' ), - 'result' => function_exists( 'gzcompress' ), + 'result' => $zlib, 'fallback' => __( 'Recommended to compress PDF documents', 'woocommerce-pdf-invoices-packing-slips' ), ), 'opcache' => array( @@ -1007,7 +1012,12 @@ public function get_server_config(): array { ), 'WP Memory Limit' => array( /* translators: tags */ - 'required' => sprintf( __( 'Recommended: 128MB (more for plugin-heavy setups
See: %1$sIncreasing the WordPress Memory Limit%2$s', 'woocommerce-pdf-invoices-packing-slips' ), '
', '' ), + 'required' => __( 'Recommended: 128MB (especially for plugin-heavy setups)', 'woocommerce-pdf-invoices-packing-slips' ) . '
' . sprintf( + /* translators: 1: opening anchor tag, 2: closing anchor tag */ + __( 'See: %1$sIncreasing the WordPress Memory Limit%2$s', 'woocommerce-pdf-invoices-packing-slips' ), + '', + '' + ), 'value' => sprintf( 'WordPress: %s, PHP: %s', WP_MEMORY_LIMIT, $php_mem_limit ), 'result' => $memory_limit > 67108864, ), @@ -1020,7 +1030,7 @@ public function get_server_config(): array { 'fileinfo' => array ( 'required' => __( 'Necessary to verify the MIME type of local images.', 'woocommerce-pdf-invoices-packing-slips' ), 'value' => null, - 'result' => extension_loaded( 'fileinfo' ), + 'result' => $fileinfo, 'fallback' => __( 'fileinfo disabled', 'woocommerce-pdf-invoices-packing-slips' ), ), 'base64_decode' => array ( @@ -1089,7 +1099,7 @@ public function handle_server_requirement_notice(): void { $server_configs = $this->get_server_config(); foreach ( $server_configs as $config_name => $config ) { - if ( in_array( $config_name, array( 'opcache', 'GMagick or IMagick' ), true ) ) { + if ( in_array( $config_name, array( 'opcache', 'GMagick or IMagick', 'WP Memory Limit' ), true ) ) { continue; } From 34d84952790ec739c60399fa8e56256a97d8c50d Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Tue, 17 Dec 2024 09:07:20 +0000 Subject: [PATCH 27/69] v3.9.2 --- ...woocommerce-pdf-invoices-packing-slips.pot | 98 +++++++++++-------- readme.txt | 7 +- woocommerce-pdf-invoices-packingslips.php | 4 +- 3 files changed, 66 insertions(+), 43 deletions(-) diff --git a/languages/woocommerce-pdf-invoices-packing-slips.pot b/languages/woocommerce-pdf-invoices-packing-slips.pot index 8fbe450c8..19befa2b2 100644 --- a/languages/woocommerce-pdf-invoices-packing-slips.pot +++ b/languages/woocommerce-pdf-invoices-packing-slips.pot @@ -2,14 +2,14 @@ # This file is distributed under the GPLv2 or later. msgid "" msgstr "" -"Project-Id-Version: PDF Invoices & Packing Slips for WooCommerce 3.9.1\n" +"Project-Id-Version: PDF Invoices & Packing Slips for WooCommerce 3.9.2\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2024-12-16T08:12:43+00:00\n" +"POT-Creation-Date: 2024-12-17T09:06:58+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.11.0\n" "X-Domain: woocommerce-pdf-invoices-packing-slips\n" @@ -55,7 +55,7 @@ msgstr "" #: includes/Admin.php:124 #: includes/Main.php:853 -#: includes/Settings/SettingsDebug.php:1131 +#: includes/Settings/SettingsDebug.php:1141 #: views/attachment-settings-hint.php:12 #: views/extensions.php:121 #: views/promo.php:34 @@ -268,7 +268,7 @@ msgid "Preview" msgstr "" #: includes/Assets.php:121 -#: includes/Settings/SettingsDebug.php:1139 +#: includes/Settings/SettingsDebug.php:1149 msgid "Settings" msgstr "" @@ -343,14 +343,14 @@ msgid "Enable" msgstr "" #: includes/Documents/Invoice.php:233 -#: includes/Documents/Invoice.php:614 +#: includes/Documents/Invoice.php:615 #: includes/Documents/PackingSlip.php:191 msgid "Attach to:" msgstr "" #. translators: directory path #: includes/Documents/Invoice.php:241 -#: includes/Documents/Invoice.php:622 +#: includes/Documents/Invoice.php:623 msgid "It looks like the temp folder (%s) is not writable, check the permissions for this folder! Without having write access to this folder, the plugin will not be able to email invoices." msgstr "" @@ -624,36 +624,49 @@ msgstr "" msgid "UBL 2.1" msgstr "" -#: includes/Documents/Invoice.php:628 +#: includes/Documents/Invoice.php:629 msgid "Include encrypted PDF:" msgstr "" -#: includes/Documents/Invoice.php:634 +#: includes/Documents/Invoice.php:635 msgid "Embed the encrypted PDF invoice file within the UBL document. Note that this option may not be supported by all UBL formats." msgstr "" -#: includes/Documents/Invoice.php:657 -#: includes/Documents/Invoice.php:701 +#: includes/Documents/Invoice.php:658 +#: includes/Documents/Invoice.php:702 #: includes/Documents/PackingSlip.php:229 #: includes/Settings.php:163 #: includes/Settings/SettingsDebug.php:682 msgid "General" msgstr "" -#: includes/Documents/Invoice.php:666 +#: includes/Documents/Invoice.php:667 #: includes/Documents/PackingSlip.php:236 msgid "Document details" msgstr "" -#: includes/Documents/Invoice.php:680 +#: includes/Documents/Invoice.php:681 msgid "Admin" msgstr "" -#: includes/Documents/Invoice.php:688 +#: includes/Documents/Invoice.php:689 #: includes/Settings.php:182 msgid "Advanced" msgstr "" +#: includes/Documents/Invoice.php:727 +msgid "EN16931 XRechnung" +msgstr "" + +#: includes/Documents/Invoice.php:733 +msgid "Formats available through extensions" +msgstr "" + +#. translators: %1$s: opening link tag, %2$s: closing link tag +#: includes/Documents/Invoice.php:748 +msgid "If the format you need isn't listed, please don't hesitate to %1$scontact us%2$s!" +msgstr "" + #. translators: 1. credit note title, 2. refund id #: includes/Documents/OrderDocument.php:482 msgid "%1$s (refund #%2$s) was regenerated." @@ -1290,107 +1303,112 @@ msgstr "" msgid "Document can be accessed by everyone with the link." msgstr "" -#: includes/Settings/SettingsDebug.php:957 +#: includes/Settings/SettingsDebug.php:962 msgid "7.4 or superior" msgstr "" -#: includes/Settings/SettingsDebug.php:970 +#: includes/Settings/SettingsDebug.php:975 msgid "Recommended, will use fallback functions" msgstr "" -#: includes/Settings/SettingsDebug.php:976 +#: includes/Settings/SettingsDebug.php:981 msgid "Required if you have images in your documents" msgstr "" -#: includes/Settings/SettingsDebug.php:979 +#: includes/Settings/SettingsDebug.php:984 msgid "Required when using .webp images" msgstr "" -#: includes/Settings/SettingsDebug.php:982 +#: includes/Settings/SettingsDebug.php:987 msgid "Required if you have .webp images in your documents" msgstr "" -#: includes/Settings/SettingsDebug.php:985 +#: includes/Settings/SettingsDebug.php:990 msgid "To compress PDF documents" msgstr "" -#: includes/Settings/SettingsDebug.php:988 +#: includes/Settings/SettingsDebug.php:993 msgid "Recommended to compress PDF documents" msgstr "" -#: includes/Settings/SettingsDebug.php:991 +#: includes/Settings/SettingsDebug.php:996 msgid "For better performances" msgstr "" -#: includes/Settings/SettingsDebug.php:994 -#: includes/Settings/SettingsDebug.php:1000 +#: includes/Settings/SettingsDebug.php:999 +#: includes/Settings/SettingsDebug.php:1005 msgid "Recommended for better performances" msgstr "" -#: includes/Settings/SettingsDebug.php:997 +#: includes/Settings/SettingsDebug.php:1002 msgid "Better with transparent PNG images" msgstr "" -#: includes/Settings/SettingsDebug.php:1003 +#: includes/Settings/SettingsDebug.php:1008 msgid "Required to detect custom templates and to clear the temp folder periodically" msgstr "" -#: includes/Settings/SettingsDebug.php:1006 +#: includes/Settings/SettingsDebug.php:1011 msgid "Check PHP disable_functions" msgstr "" #. translators: tags -#: includes/Settings/SettingsDebug.php:1010 -msgid "Recommended: 128MB (more for plugin-heavy setups
See: %1$sIncreasing the WordPress Memory Limit%2$s" +#: includes/Settings/SettingsDebug.php:1015 +msgid "Recommended: 128MB (especially for plugin-heavy setups)" msgstr "" -#: includes/Settings/SettingsDebug.php:1015 +#. translators: 1: opening anchor tag, 2: closing anchor tag +#: includes/Settings/SettingsDebug.php:1017 +msgid "See: %1$sIncreasing the WordPress Memory Limit%2$s" +msgstr "" + +#: includes/Settings/SettingsDebug.php:1025 msgid "Allow remote stylesheets and images" msgstr "" -#: includes/Settings/SettingsDebug.php:1018 +#: includes/Settings/SettingsDebug.php:1028 msgid "allow_url_fopen disabled" msgstr "" -#: includes/Settings/SettingsDebug.php:1021 +#: includes/Settings/SettingsDebug.php:1031 msgid "Necessary to verify the MIME type of local images." msgstr "" -#: includes/Settings/SettingsDebug.php:1024 +#: includes/Settings/SettingsDebug.php:1034 msgid "fileinfo disabled" msgstr "" -#: includes/Settings/SettingsDebug.php:1027 +#: includes/Settings/SettingsDebug.php:1037 msgid "To compress and decompress font and image data" msgstr "" -#: includes/Settings/SettingsDebug.php:1030 +#: includes/Settings/SettingsDebug.php:1040 msgid "base64_decode disabled" msgstr "" -#: includes/Settings/SettingsDebug.php:1038 +#: includes/Settings/SettingsDebug.php:1048 msgid "Required for IMagick" msgstr "" -#: includes/Settings/SettingsDebug.php:1041 +#: includes/Settings/SettingsDebug.php:1051 msgid "ImageMagick library, integrated via the IMagick PHP extension for advanced image processing capabilities" msgstr "" #. translators: 1: Plugin name, 2: Open anchor tag, 3: Close anchor tag -#: includes/Settings/SettingsDebug.php:1121 +#: includes/Settings/SettingsDebug.php:1131 msgid "Your server does not meet the requirements for %1$s. Please check the %2$sStatus page%3$s for more information." msgstr "" -#: includes/Settings/SettingsDebug.php:1140 +#: includes/Settings/SettingsDebug.php:1150 #: views/advanced-status.php:203 msgid "Status" msgstr "" -#: includes/Settings/SettingsDebug.php:1141 +#: includes/Settings/SettingsDebug.php:1151 msgid "Tools" msgstr "" -#: includes/Settings/SettingsDebug.php:1142 +#: includes/Settings/SettingsDebug.php:1152 msgid "Numbers" msgstr "" diff --git a/readme.txt b/readme.txt index fd16dbf02..50a87db8d 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 Requires PHP: 7.4 -Stable tag: 3.9.1 +Stable tag: 3.9.2 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -102,6 +102,11 @@ There's a setting on the Advanced tab of the settings page that allows you to to == Changelog == += 3.9.2 (2024-12-17) = +- New: adds description to UBL format selector +- Fix: issue with PHP extension load checks +- Translations: Updated translation template (POT). + = 3.9.1 (2024-12-16) = - New: Adds support for multiple UBL formats. - New: Adds a shop phone number field for e-Invoice support. diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index 3dc780336..78fc165c7 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,7 +4,7 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.1 + * Version: 3.9.2 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.1'; + public $version = '3.9.2'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; From 9237b22915b035886a870de753ff45959fed8eed Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Wed, 18 Dec 2024 08:25:04 +0000 Subject: [PATCH 28/69] Fix: UBL shop country code (#934) --- ubl/Handlers/Common/AddressHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ubl/Handlers/Common/AddressHandler.php b/ubl/Handlers/Common/AddressHandler.php index 26edb45ea..23f32590a 100644 --- a/ubl/Handlers/Common/AddressHandler.php +++ b/ubl/Handlers/Common/AddressHandler.php @@ -82,7 +82,7 @@ public function return_supplier_party_details() { 'name' => 'cac:Country', 'value' => array( 'name' => 'cbc:IdentificationCode', - 'value' => get_option( 'woocommerce_default_country' ), + 'value' => wc_format_country_state_string( get_option( 'woocommerce_default_country', '' ) )['country'], 'attributes' => array( 'listID' => 'ISO3166-1:Alpha2', 'listAgencyID' => '6', From 15fcc4c4bf90df20c5f447841a839a08bb613d80 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Wed, 18 Dec 2024 09:36:24 +0000 Subject: [PATCH 29/69] Fix: abstract document `order_id` property var type (#935) --- includes/Documents/OrderDocument.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/Documents/OrderDocument.php b/includes/Documents/OrderDocument.php index 2e2490f3c..1786fa914 100644 --- a/includes/Documents/OrderDocument.php +++ b/includes/Documents/OrderDocument.php @@ -52,7 +52,7 @@ abstract class OrderDocument { /** * WC Order ID - * @var object + * @var int */ public $order_id; @@ -105,7 +105,7 @@ abstract class OrderDocument { */ public function __construct( $order = 0 ) { if ( is_numeric( $order ) && $order > 0 ) { - $this->order_id = $order; + $this->order_id = absint( $order ); $this->order = wc_get_order( $this->order_id ); } elseif ( $order instanceof \WC_Order || is_subclass_of( $order, '\WC_Abstract_Order') ) { $this->order_id = $order->get_id(); From c12108ce8c9082e1e9fe49c81186ee86cb2a3e85 Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Wed, 18 Dec 2024 13:07:11 +0330 Subject: [PATCH 30/69] New: document `calculate_due_date()` function (#874) --- includes/Documents/OrderDocument.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/includes/Documents/OrderDocument.php b/includes/Documents/OrderDocument.php index 1786fa914..111724ff6 100644 --- a/includes/Documents/OrderDocument.php +++ b/includes/Documents/OrderDocument.php @@ -342,7 +342,7 @@ public function is_enabled( $output_format = 'pdf' ) { return apply_filters( 'wpo_wcpdf_document_is_enabled', $is_enabled, $this->type, $output_format ); } - + /** * Get the UBL format * @@ -350,7 +350,7 @@ public function is_enabled( $output_format = 'pdf' ) { */ public function get_ubl_format() { $ubl_format = $this->get_setting( 'ubl_format', false, 'ubl' ); - + return apply_filters( 'wpo_wcpdf_document_ubl_format', $ubl_format, $this ); } @@ -1808,6 +1808,17 @@ public function get_due_date(): int { return 0; } + return $this->calculate_due_date( $due_date_days ); + } + + /** + * Calculate the due date. + * + * @param int $due_date_days + * + * @return int Due date timestamp. + */ + public function calculate_due_date( int $due_date_days ): int { $due_date_days = apply_filters_deprecated( 'wpo_wcpdf_due_date_days', array( $due_date_days, $this->get_type(), $this ), @@ -1816,11 +1827,11 @@ public function get_due_date(): int { ); $due_date_days = apply_filters( 'wpo_wcpdf_document_due_date_days', $due_date_days, $this ); - if ( 0 >= intval( $due_date_days ) ) { + if ( ! is_numeric( $due_date_days ) || intval( $due_date_days ) <= 0 ) { return 0; } - $document_creation_date = $this->get_date( $this->get_type(), $this->order ) ?? new \WC_DateTime( 'now', new \DateTimeZone( 'UTC' ) ); + $document_creation_date = $this->get_date( $this->get_type(), $this->order ) ?? new \WC_DateTime( 'now', new \DateTimeZone( wc_timezone_string() ) ); $base_date = apply_filters_deprecated( 'wpo_wcpdf_due_date_base_date', array( $document_creation_date, $this->get_type(), $this ), From 123cb314f7c3b4550eb9fa949284af2a0c07f752 Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Wed, 18 Dec 2024 15:57:52 +0330 Subject: [PATCH 31/69] New: Enable searching for multiple invoice numbers in the Orders list for HPOS setups (#918) --- includes/Compatibility/ThirdPartyPlugins.php | 27 +++++++++++++------- includes/Documents/Invoice.php | 18 ++++++------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/includes/Compatibility/ThirdPartyPlugins.php b/includes/Compatibility/ThirdPartyPlugins.php index 4064b197b..fe7d7e62a 100644 --- a/includes/Compatibility/ThirdPartyPlugins.php +++ b/includes/Compatibility/ThirdPartyPlugins.php @@ -212,11 +212,11 @@ public function add_yith_product_bundles_classes( string $classes, ?string $docu if ( empty( $order ) ) { return $classes; } - + if ( ! $order instanceof \WC_Abstract_Order ) { return $classes; } - + if ( empty( $item_id ) && ! empty( $classes ) ) { $item_id = $this->get_item_id_from_classes( $classes ); } @@ -226,7 +226,7 @@ public function add_yith_product_bundles_classes( string $classes, ?string $docu } else { return $classes; } - + $product = null; $bundled_by = null; @@ -378,7 +378,7 @@ function restore_wgm_thumbnails( $document_type, $document ) { } /** - * Adds invoice number filter to the search filters available in the admin order search. + * Adds "Invoice numbers" filter to the search filters available in the admin order search. * * @param array $options List of available filters. * @@ -388,7 +388,7 @@ function hpos_admin_search_filters( array $options ): array { if ( WPO_WCPDF()->admin->invoice_number_search_enabled() ) { $all = $options['all']; unset( $options['all'] ); - $options['invoice_number'] = __( 'Invoice number', 'woocommerce-pdf-invoices-packing-slips' ); + $options['invoice_numbers'] = __( 'Invoice numbers', 'woocommerce-pdf-invoices-packing-slips' ); $options['all'] = $all; } @@ -396,16 +396,25 @@ function hpos_admin_search_filters( array $options ): array { } /** - * Modifies the arguments passed to `wc_get_orders()` to support 'invoice_number' order search filter. + * Modifies the arguments passed to `wc_get_orders()` to support 'invoice_numbers' order search filter. * * @param array $order_query_args Arguments to be passed to `wc_get_orders()`. * * @return array */ function invoice_number_query_args( array $order_query_args ): array { - if ( isset( $order_query_args['search_filter'] ) && 'invoice_number' === $order_query_args['search_filter'] && isset( $order_query_args['s'] ) ) { - $order_query_args['meta_key'] = '_wcpdf_invoice_number'; - $order_query_args['meta_value'] = $order_query_args['s']; + if ( isset( $order_query_args['search_filter'] ) && 'invoice_numbers' === $order_query_args['search_filter'] && ! empty( $order_query_args['s'] ) ) { + $invoice_numbers = explode( ',', $order_query_args['s'] ); + $invoice_numbers = array_map( function ( $number ) { + return sanitize_text_field( trim( $number ) ); + }, $invoice_numbers ); + + $order_query_args['meta_query'] = $order_query_args['meta_query'] ?? array(); + $order_query_args['meta_query'][] = [ + 'key' => '_wcpdf_invoice_number', + 'value' => $invoice_numbers, + 'compare' => 'IN', + ]; $order_query_args['search_filter'] = 'all'; unset( $order_query_args['s'] ); } diff --git a/includes/Documents/Invoice.php b/includes/Documents/Invoice.php index fb5b11956..fed8f690a 100644 --- a/includes/Documents/Invoice.php +++ b/includes/Documents/Invoice.php @@ -481,7 +481,7 @@ public function get_pdf_settings_fields( $option_name ) { 'args' => array( 'option_name' => $option_name, 'id' => 'invoice_number_search', - 'description' => __( 'The search process may be slower on non-HPOS stores. For a more efficient search, you can utilize the
HPOS feature, allowing you to search orders by invoice numbers using the search type selector.', 'woocommerce-pdf-invoices-packing-slips' ), + 'description' => __( 'The search process may be slower on non-HPOS stores. For a more efficient search, you can utilize the HPOS feature to search for orders by invoice numbers using the search type selector. Additionally, it allows you to search for multiple orders using a comma-separated list of invoice numbers.', 'woocommerce-pdf-invoices-packing-slips' ), ) ), array( @@ -712,29 +712,29 @@ public function get_settings_categories( string $output_format ): array { return apply_filters( 'wpo_wcpdf_document_settings_categories', $settings_categories[ $output_format ] ?? array(), $output_format, $this ); } - + /** * Get UBL Format setting description - * + * * @return string */ private function get_ubl_format_description(): string { $extensions_available = array(); $ubl_format_description = ''; - + if ( ! class_exists( 'WPO_IPS_XRechnung' ) ) { $extensions_available['xrechnung'] = array( 'title' => __( 'EN16931 XRechnung', 'woocommerce-pdf-invoices-packing-slips' ), 'url' => 'https://github.com/wpovernight/wpo-ips-xrechnung/releases/latest/', ); } - + if ( ! empty( $extensions_available ) ) { $ubl_format_description = __( 'Formats available through extensions', 'woocommerce-pdf-invoices-packing-slips' ) . ':'; - + foreach ( $extensions_available as $extension ) { $ubl_format_description .= ' ' . esc_html( $extension['title'] ) . ''; - + if ( next( $extensions_available ) ) { $ubl_format_description .= ','; } else { @@ -742,14 +742,14 @@ private function get_ubl_format_description(): string { } } } - + $ubl_format_description .= sprintf( /* translators: %1$s: opening link tag, %2$s: closing link tag */ __( 'If the format you need isn\'t listed, please don\'t hesitate to %1$scontact us%2$s!', 'woocommerce-pdf-invoices-packing-slips' ), '', '' ); - + return $ubl_format_description; } From 70caebba86311aa185bdde7396a3bf682135f9cf Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Thu, 19 Dec 2024 16:47:29 +0000 Subject: [PATCH 32/69] v3.9.3 --- .../woocommerce-pdf-invoices-packing-slips.pot | 13 ++++++++----- readme.txt | 9 ++++++++- woocommerce-pdf-invoices-packingslips.php | 4 ++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/languages/woocommerce-pdf-invoices-packing-slips.pot b/languages/woocommerce-pdf-invoices-packing-slips.pot index 19befa2b2..490080049 100644 --- a/languages/woocommerce-pdf-invoices-packing-slips.pot +++ b/languages/woocommerce-pdf-invoices-packing-slips.pot @@ -2,14 +2,14 @@ # This file is distributed under the GPLv2 or later. msgid "" msgstr "" -"Project-Id-Version: PDF Invoices & Packing Slips for WooCommerce 3.9.2\n" +"Project-Id-Version: PDF Invoices & Packing Slips for WooCommerce 3.9.3\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2024-12-17T09:06:58+00:00\n" +"POT-Creation-Date: 2024-12-19T16:44:34+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.11.0\n" "X-Domain: woocommerce-pdf-invoices-packing-slips\n" @@ -302,8 +302,7 @@ msgid "Enabled: %1$sclick here%2$s to start using the tools." msgstr "" #: includes/Compatibility/ThirdPartyPlugins.php:391 -#: views/setup-wizard/display-options.php:73 -msgid "Invoice number" +msgid "Invoice numbers" msgstr "" #: includes/Documents/Invoice.php:24 @@ -543,7 +542,7 @@ msgid "Enable invoice number search in the orders list" msgstr "" #: includes/Documents/Invoice.php:484 -msgid "The search process may be slower on non-HPOS stores. For a more efficient search, you can utilize the HPOS feature, allowing you to search orders by invoice numbers using the search type selector." +msgid "The search process may be slower on non-HPOS stores. For a more efficient search, you can utilize the HPOS feature to search for orders by invoice numbers using the search type selector. Additionally, it allows you to search for multiple orders using a comma-separated list of invoice numbers." msgstr "" #: includes/Documents/Invoice.php:490 @@ -2720,6 +2719,10 @@ msgstr "" msgid "Invoice date" msgstr "" +#: views/setup-wizard/display-options.php:73 +msgid "Invoice number" +msgstr "" + #: views/setup-wizard/good-to-go.php:3 msgid "You are good to go!" msgstr "" diff --git a/readme.txt b/readme.txt index 50a87db8d..b23af5c27 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 Requires PHP: 7.4 -Stable tag: 3.9.2 +Stable tag: 3.9.3 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -102,6 +102,13 @@ There's a setting on the Advanced tab of the settings page that allows you to to == Changelog == += 3.9.3 (2024-12-19) = +* New: enable searching for multiple invoice numbers in the Orders list for HPOS setups +* New: `calculate_due_date()` document function +* Fix: correct the type of the abstract document `order_id` property +* Fix: UBL shop country code +* Translations: update translation template (POT) + = 3.9.2 (2024-12-17) = - New: adds description to UBL format selector - Fix: issue with PHP extension load checks diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index 78fc165c7..5678196a4 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,7 +4,7 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.2 + * Version: 3.9.3 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.2'; + public $version = '3.9.3'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; From a678fcd0a2fddd47024e1d04ee13edad6e9a74c8 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 20 Dec 2024 11:46:02 +0000 Subject: [PATCH 33/69] Tweak: move UBL support out of beta (#938) --- includes/Settings.php | 12 +++++------- includes/Settings/SettingsDocuments.php | 6 +++--- includes/Settings/SettingsUbl.php | 1 + 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/includes/Settings.php b/includes/Settings.php index 869b75aea..5b4f834b3 100644 --- a/includes/Settings.php +++ b/includes/Settings.php @@ -169,13 +169,11 @@ public function settings_page() { ), ) ); - if ( wcpdf_is_ubl_available() ) { - $settings_tabs['ubl'] = array( - 'title' => __( 'UBL', 'woocommerce-pdf-invoices-packing-slips' ), - 'preview_states' => 1, - 'beta' => true, - ); - } + $settings_tabs['ubl'] = array( + 'title' => __( 'Taxes', 'woocommerce-pdf-invoices-packing-slips' ), + 'preview_states' => 1, + //'beta' => true, + ); // add status and upgrade tabs last in row $settings_tabs['debug'] = array( diff --git a/includes/Settings/SettingsDocuments.php b/includes/Settings/SettingsDocuments.php index 84864d7ad..dd8375c74 100644 --- a/includes/Settings/SettingsDocuments.php +++ b/includes/Settings/SettingsDocuments.php @@ -83,9 +83,9 @@ public function output( $section ) { $active = ( $output_format == $document_output_format ) || ( 'pdf' !== $output_format && ! in_array( $output_format, $section_document->output_formats ) ) ? 'nav-tab-active' : ''; $tab_title = strtoupper( esc_html( $document_output_format ) ); - if ( 'ubl' === $document_output_format ) { - $tab_title .= ' beta'; - } + // if ( 'ubl' === $document_output_format ) { + // $tab_title .= ' beta'; + // } printf( '%4$s', esc_url( add_query_arg( 'output_format', $document_output_format ) ), esc_attr( $document_output_format ), $active, $tab_title ); } ?> diff --git a/includes/Settings/SettingsUbl.php b/includes/Settings/SettingsUbl.php index d84561803..39e27c460 100644 --- a/includes/Settings/SettingsUbl.php +++ b/includes/Settings/SettingsUbl.php @@ -59,6 +59,7 @@ public function output( $active_section ) { switch ( $active_section ) { default: case 'taxes': + echo '

' . esc_html__( 'To ensure compliance with e-invoicing requirements, please complete the Taxes Classification. This information is essential for accurately generating legally compliant invoices.', 'woocommerce-pdf-invoices-packing-slips' ) . '

'; $setting = new UblTaxSettings(); $setting->output(); break; From f559caa55435381a51bb4f6262a25e361b0fde6e Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Sun, 22 Dec 2024 19:46:42 +0000 Subject: [PATCH 34/69] New: Displays a notice if the yearly reset action is not scheduled (#942) --- woocommerce-pdf-invoices-packingslips.php | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index 5678196a4..ab0b3ecfb 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -76,6 +76,7 @@ public function __construct() { add_action( 'admin_notices', array( $this, 'nginx_detected' ) ); add_action( 'admin_notices', array( $this, 'mailpoet_mta_detected' ) ); add_action( 'admin_notices', array( $this, 'rtl_detected' ) ); + add_action( 'admin_notices', array( $this, 'yearly_reset_action_missing_notice' ) ); add_action( 'admin_notices', array( $this, 'legacy_addon_notices' ) ); add_action( 'init', array( '\\WPO\\IPS\\Semaphore', 'init_cleanup' ), 999 ); // wait AS to initialize @@ -452,6 +453,50 @@ public function rtl_detected() { } } } + + /** + * Yearly reset action missing notice + * + * @return void + */ + public function yearly_reset_action_missing_notice(): void { + if ( ! $this->settings->maybe_schedule_yearly_reset_numbers() ) { + return; + } + + if ( ! function_exists( 'as_get_scheduled_actions' ) ) { + return; + } + + $current_date = new \DateTime(); + $end_of_year = new \DateTime( 'last day of December' ); + $days_remaining = $current_date->diff( $end_of_year )->days; + + // Check if the current date is within the last 30 days of the year + if ( $days_remaining <= 30 && ! $this->settings->yearly_reset_action_is_scheduled() ) { + ob_start(); + ?> +
+

+

+
+ settings->schedule_yearly_reset_numbers(); + wcpdf_log_error( 'Yearly reset numbering system rescheduled!', 'info' ); + } + + wp_redirect( 'admin.php?page=wpo_wcpdf_options_page&tab=debug§ion=status' ); + exit; + } + } /** * Get an array of all active plugins, including multisite From c55545bb3b470c8f06e0e7ea620228833bac9961 Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Sun, 22 Dec 2024 23:23:36 +0330 Subject: [PATCH 35/69] New: Add a note to inform about more documents (#852) --- includes/Settings/SettingsDocuments.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/includes/Settings/SettingsDocuments.php b/includes/Settings/SettingsDocuments.php index dd8375c74..d77a1361c 100644 --- a/includes/Settings/SettingsDocuments.php +++ b/includes/Settings/SettingsDocuments.php @@ -69,6 +69,20 @@ public function output( $section ) { } ?> + +

+ + ', + '' + ); + ?> + +

+
Date: Sun, 22 Dec 2024 19:57:23 +0000 Subject: [PATCH 36/69] v3.9.4 --- ...woocommerce-pdf-invoices-packing-slips.pot | 95 +++++++++++-------- readme.txt | 9 +- woocommerce-pdf-invoices-packingslips.php | 4 +- 3 files changed, 65 insertions(+), 43 deletions(-) diff --git a/languages/woocommerce-pdf-invoices-packing-slips.pot b/languages/woocommerce-pdf-invoices-packing-slips.pot index 490080049..66914cf0b 100644 --- a/languages/woocommerce-pdf-invoices-packing-slips.pot +++ b/languages/woocommerce-pdf-invoices-packing-slips.pot @@ -2,14 +2,14 @@ # This file is distributed under the GPLv2 or later. msgid "" msgstr "" -"Project-Id-Version: PDF Invoices & Packing Slips for WooCommerce 3.9.3\n" +"Project-Id-Version: PDF Invoices & Packing Slips for WooCommerce 3.9.4\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2024-12-19T16:44:34+00:00\n" +"POT-Creation-Date: 2024-12-22T19:57:06+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.11.0\n" "X-Domain: woocommerce-pdf-invoices-packing-slips\n" @@ -59,10 +59,10 @@ msgstr "" #: views/attachment-settings-hint.php:12 #: views/extensions.php:121 #: views/promo.php:34 -#: woocommerce-pdf-invoices-packingslips.php:338 -#: woocommerce-pdf-invoices-packingslips.php:397 -#: woocommerce-pdf-invoices-packingslips.php:435 -#: woocommerce-pdf-invoices-packingslips.php:525 +#: woocommerce-pdf-invoices-packingslips.php:339 +#: woocommerce-pdf-invoices-packingslips.php:398 +#: woocommerce-pdf-invoices-packingslips.php:436 +#: woocommerce-pdf-invoices-packingslips.php:570 msgid "Hide this message" msgstr "" @@ -649,7 +649,7 @@ msgid "Admin" msgstr "" #: includes/Documents/Invoice.php:689 -#: includes/Settings.php:182 +#: includes/Settings.php:180 msgid "Advanced" msgstr "" @@ -766,7 +766,7 @@ msgid "Total ex. VAT" msgstr "" #: includes/Documents/OrderDocumentMethods.php:1111 -#: includes/Settings.php:427 +#: includes/Settings.php:425 #: ubl/Settings/TaxesSettings.php:170 msgid "Total" msgstr "" @@ -841,8 +841,8 @@ msgid "Could not find the order #%s." msgstr "" #: includes/Main.php:479 -#: includes/Settings.php:220 -#: includes/Settings.php:368 +#: includes/Settings.php:218 +#: includes/Settings.php:366 msgid "You do not have sufficient permissions to access this page." msgstr "" @@ -950,60 +950,60 @@ msgstr "" msgid "Documents" msgstr "" -#: includes/Settings.php:174 -msgid "UBL" +#: includes/Settings.php:173 +msgid "Taxes" msgstr "" -#: includes/Settings.php:187 +#: includes/Settings.php:185 msgid "Upgrade" msgstr "" -#: includes/Settings.php:260 +#: includes/Settings.php:258 msgid "Order not found!" msgstr "" -#: includes/Settings.php:263 +#: includes/Settings.php:261 msgid "Object found is not an order!" msgstr "" #. translators: order ID -#: includes/Settings.php:335 +#: includes/Settings.php:333 msgid "Document not available for order #%s, try selecting a different order." msgstr "" -#: includes/Settings.php:342 +#: includes/Settings.php:340 msgid "No WooCommerce orders found! Please consider adding your first order to see this preview." msgstr "" #. translators: error message -#: includes/Settings.php:352 +#: includes/Settings.php:350 msgid "Error trying to generate document: %s" msgstr "" -#: includes/Settings.php:426 +#: includes/Settings.php:424 #: includes/Tables/NumberStoreListTable.php:122 msgid "Date" msgstr "" -#: includes/Settings.php:434 +#: includes/Settings.php:432 msgid "No order(s) found!" msgstr "" -#: includes/Settings.php:437 +#: includes/Settings.php:435 msgid "An error occurred when trying to process your request!" msgstr "" #. translators: error message -#: includes/Settings.php:444 +#: includes/Settings.php:442 msgid "Error trying to get orders: %s" msgstr "" #. translators: total scheduled actions -#: includes/Settings.php:940 +#: includes/Settings.php:938 msgid "Only 1 scheduled action should exist for the yearly reset of the numbering system, but %s were found" msgstr "" -#: includes/Settings.php:1096 +#: includes/Settings.php:1094 msgid "Additional settings" msgstr "" @@ -1416,13 +1416,18 @@ msgstr "" msgid "untitled" msgstr "" +#. translators: 1. open anchor tag, 2. close anchor tag +#: includes/Settings/SettingsDocuments.php:78 +msgid "Looking for more documents? Learn more %1$shere%2$s." +msgstr "" + #. translators: 1. open anchor tag, 2. close anchor tag #: includes/Settings/SettingsGeneral.php:44 msgid "Requires the %1$sProfessional extension%2$s." msgstr "" #: includes/Settings/SettingsGeneral.php:50 -#: includes/Settings/SettingsUbl.php:153 +#: includes/Settings/SettingsUbl.php:154 msgid "General settings" msgstr "" @@ -1590,12 +1595,16 @@ msgstr "" msgid "Taxes classification" msgstr "" +#: includes/Settings/SettingsUbl.php:62 +msgid "To ensure compliance with e-invoicing requirements, please complete the Taxes Classification. This information is essential for accurately generating legally compliant invoices." +msgstr "" + #. translators: 1. General Settings, 2. UBL Settings -#: includes/Settings/SettingsUbl.php:152 +#: includes/Settings/SettingsUbl.php:153 msgid "You've enabled UBL output for a document, but some essential details are missing. Please ensure you've added your VAT and CoC numbers in the %1$s. Also, specify your tax rates in the %2$s." msgstr "" -#: includes/Settings/SettingsUbl.php:154 +#: includes/Settings/SettingsUbl.php:155 msgid "UBL settings" msgstr "" @@ -2830,55 +2839,63 @@ msgid "Buy now" msgstr "" #. translators: 1. open anchor tag, 2. close anchor tag, 3. Woo version -#: woocommerce-pdf-invoices-packingslips.php:192 +#: woocommerce-pdf-invoices-packingslips.php:193 msgid "PDF Invoices & Packing Slips for WooCommerce requires %1$sWooCommerce%2$s version %3$s or higher to be installed & activated!" msgstr "" #. translators: PHP version -#: woocommerce-pdf-invoices-packingslips.php:237 +#: woocommerce-pdf-invoices-packingslips.php:238 msgid "PDF Invoices & Packing Slips for WooCommerce requires PHP %s or higher." msgstr "" #. translators: tags -#: woocommerce-pdf-invoices-packingslips.php:243 +#: woocommerce-pdf-invoices-packingslips.php:244 msgid "We strongly recommend to %1$supdate your PHP version%2$s." msgstr "" #. translators: directory path -#: woocommerce-pdf-invoices-packingslips.php:335 +#: woocommerce-pdf-invoices-packingslips.php:336 msgid "The PDF files in %s are not currently protected due to your site running on NGINX." msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:336 +#: woocommerce-pdf-invoices-packingslips.php:337 msgid "To protect them, you must click the button below." msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:337 +#: woocommerce-pdf-invoices-packingslips.php:338 msgid "Generate random temporary folder name" msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:394 +#: woocommerce-pdf-invoices-packingslips.php:395 msgid "When sending emails with MailPoet 3 and the active sending method is MailPoet Sending Service or Your web host / web server, MailPoet does not include the PDF Invoices & Packing Slips for WooCommerce attachments in the emails." msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:395 +#: woocommerce-pdf-invoices-packingslips.php:396 msgid "To fix this you should select The default WordPress sending method (default) on the Advanced tab." msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:396 +#: woocommerce-pdf-invoices-packingslips.php:397 msgid "Change MailPoet sending method to WordPress (default)" msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:433 +#: woocommerce-pdf-invoices-packingslips.php:434 msgid "PDF Invoices & Packing Slips for WooCommerce detected that your current site locale is right-to-left (RTL) which the current PDF engine does not support it. Please consider installing our mPDF extension that is compatible." msgstr "" -#: woocommerce-pdf-invoices-packingslips.php:434 +#: woocommerce-pdf-invoices-packingslips.php:435 msgid "Download mPDF extension" msgstr "" +#: woocommerce-pdf-invoices-packingslips.php:480 +msgid "The year-end is approaching, and we noticed that your PDF Invoices & Packing Slips for WooCommerce plugin doesn't have the scheduled action to reset invoice numbers annually, even though you've explicitly enabled this setting in the document options. Click the button below to schedule the action before the year ends." +msgstr "" + +#: woocommerce-pdf-invoices-packingslips.php:481 +msgid "Schedule the action now" +msgstr "" + #. translators: legacy addon name -#: woocommerce-pdf-invoices-packingslips.php:520 +#: woocommerce-pdf-invoices-packingslips.php:565 msgid "While updating the PDF Invoices & Packing Slips for WooCommerce plugin we've noticed our legacy %s add-on was active on your site. This functionality is now incorporated into the core plugin. We've deactivated the add-on for you, and you are free to uninstall it." msgstr "" diff --git a/readme.txt b/readme.txt index b23af5c27..5b79b5473 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 Requires PHP: 7.4 -Stable tag: 3.9.3 +Stable tag: 3.9.4 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -102,7 +102,12 @@ There's a setting on the Advanced tab of the settings page that allows you to to == Changelog == -= 3.9.3 (2024-12-19) = += 3.9.4 (2024-12-23) = +* New: add a note to inform users about the availability of additional documents +* New: display a notice when the yearly reset action is not scheduled +* Tweak: transition UBL support out of beta +* Translations: update translation template (POT) + * New: enable searching for multiple invoice numbers in the Orders list for HPOS setups * New: `calculate_due_date()` document function * Fix: correct the type of the abstract document `order_id` property diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index ab0b3ecfb..ec4253192 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,7 +4,7 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.3 + * Version: 3.9.4 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.3'; + public $version = '3.9.4'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; From b7d3403dda6606f629678d1855782270e1955eed Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Tue, 24 Dec 2024 08:43:58 +0000 Subject: [PATCH 37/69] Fix: Incorrect treatment of UBL format setting as historical (#945) --- includes/Documents/OrderDocument.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/Documents/OrderDocument.php b/includes/Documents/OrderDocument.php index 111724ff6..878b363a3 100644 --- a/includes/Documents/OrderDocument.php +++ b/includes/Documents/OrderDocument.php @@ -295,6 +295,7 @@ public function get_non_historical_settings() { return apply_filters( 'wpo_wcpdf_non_historical_settings', array( 'enabled', 'attach_to_email_ids', + 'ubl_format', 'disable_for_statuses', 'number_format', // this is stored in the number data already! 'my_account_buttons', From 608f84924e27992cfe92a3baa238c16ad2c435fd Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Tue, 24 Dec 2024 12:34:01 +0000 Subject: [PATCH 38/69] Create project.yml --- .github/workflows/project.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/project.yml diff --git a/.github/workflows/project.yml b/.github/workflows/project.yml new file mode 100644 index 000000000..efef32681 --- /dev/null +++ b/.github/workflows/project.yml @@ -0,0 +1,16 @@ +name: Add Issues to Project + +on: + issues: + types: [opened] +env: + GITHUB_API_TOKEN: ${{ secrets.PAT }} + +jobs: + add_to_project: + runs-on: ubuntu-latest + steps: + - name: Assign new issues to the project + uses: tcassou/project-bot@2.0.0 + with: + project_url: 'https://github.com/orgs/wpovernight/projects/22' \ No newline at end of file From ae39c6b4c32cfc66739cd3d1d22a96090157c87b Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Thu, 26 Dec 2024 12:57:09 +0330 Subject: [PATCH 39/69] Tweak: Apply the filter before checking if `$settings_fields` is empty (#949) --- includes/Documents/PackingSlip.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/Documents/PackingSlip.php b/includes/Documents/PackingSlip.php index 496272e9c..8cc6bd9d0 100644 --- a/includes/Documents/PackingSlip.php +++ b/includes/Documents/PackingSlip.php @@ -205,8 +205,9 @@ public function init_settings() { $settings_fields = apply_filters( 'wpo_wcpdf_settings_fields_documents_packing_slip', $settings_fields, $page, $option_group, $option_name ); // Allow plugins to alter settings fields. + $settings_fields = apply_filters( "wpo_wcpdf_settings_fields_documents_{$this->type}_pdf", $settings_fields, $page, $option_group, $option_name, $this ); + if ( ! empty( $settings_fields ) ) { - $settings_fields = apply_filters( "wpo_wcpdf_settings_fields_documents_{$this->type}_pdf", $settings_fields, $page, $option_group, $option_name, $this ); WPO_WCPDF()->settings->add_settings_fields( $settings_fields, $page, $option_group, $option_name ); } } From 51bfdb50309ea88919d34b802b2cfcf90d6a7c8a Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Thu, 26 Dec 2024 16:22:36 +0330 Subject: [PATCH 40/69] Tweak: Allow 0 days for due date (#940) --- includes/Documents/OrderDocument.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/Documents/OrderDocument.php b/includes/Documents/OrderDocument.php index 878b363a3..f2dce05c4 100644 --- a/includes/Documents/OrderDocument.php +++ b/includes/Documents/OrderDocument.php @@ -1803,9 +1803,9 @@ public function get_number_store_year( $table_name ) { */ public function get_due_date(): int { $due_date = $this->get_setting( 'due_date' ); - $due_date_days = $this->get_setting( 'due_date_days' ); + $due_date_days = absint( $this->get_setting( 'due_date_days' ) ); - if ( empty( $this->order ) || empty( $due_date ) || empty( $due_date_days ) ) { + if ( empty( $this->order ) || empty( $due_date ) || $due_date_days < 0 ) { return 0; } @@ -1828,7 +1828,7 @@ public function calculate_due_date( int $due_date_days ): int { ); $due_date_days = apply_filters( 'wpo_wcpdf_document_due_date_days', $due_date_days, $this ); - if ( ! is_numeric( $due_date_days ) || intval( $due_date_days ) <= 0 ) { + if ( ! is_numeric( $due_date_days ) || intval( $due_date_days ) < 0 ) { return 0; } From a79a9fd89a71aeb29ae9390331a1b57dbf54b679 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 27 Dec 2024 16:55:55 +0000 Subject: [PATCH 41/69] New: Support for UBL Tax Category Reason (#947) --- includes/Settings/SettingsUbl.php | 18 ++- ubl/Documents/Document.php | 83 ++++++------ ubl/Handlers/Common/TaxTotalHandler.php | 69 ++++++---- ubl/Handlers/Invoice/InvoiceLineHandler.php | 75 +++++++---- ubl/Settings/TaxesSettings.php | 138 ++++++++++++++------ 5 files changed, 250 insertions(+), 133 deletions(-) diff --git a/includes/Settings/SettingsUbl.php b/includes/Settings/SettingsUbl.php index 39e27c460..156783e6c 100644 --- a/includes/Settings/SettingsUbl.php +++ b/includes/Settings/SettingsUbl.php @@ -109,14 +109,16 @@ public function save_order_taxes( $order ) { // read tax rate data from db if ( class_exists( '\WC_TAX' ) && is_callable( array( '\WC_TAX', '_get_tax_rate' ) ) ) { $tax_rate = \WC_Tax::_get_tax_rate( $tax_rate_id, OBJECT ); + if ( ! empty( $tax_rate ) && is_numeric( $tax_rate->tax_rate ) ) { // store percentage in tax item meta wc_update_order_item_meta( $item_id, '_wcpdf_rate_percentage', $tax_rate->tax_rate ); $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes' ); - $category = isset( $ubl_tax_settings['rate'][$tax_rate->tax_rate_id]['category'] ) ? $ubl_tax_settings['rate'][$tax_rate->tax_rate_id]['category'] : ''; - $scheme = isset( $ubl_tax_settings['rate'][$tax_rate->tax_rate_id]['scheme'] ) ? $ubl_tax_settings['rate'][$tax_rate->tax_rate_id]['scheme'] : ''; + $category = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['category'] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['category'] : ''; + $scheme = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['scheme'] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['scheme'] : ''; + $reason = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['reason'] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['reason'] : ''; $tax_rate_class = $tax_rate->tax_rate_class; if ( empty( $tax_rate_class ) ) { @@ -124,11 +126,15 @@ public function save_order_taxes( $order ) { } if ( empty( $category ) ) { - $category = isset( $ubl_tax_settings['class'][$tax_rate_class]['category'] ) ? $ubl_tax_settings['class'][$tax_rate_class]['category'] : ''; + $category = isset( $ubl_tax_settings['class'][ $tax_rate_class ]['category'] ) ? $ubl_tax_settings['class'][ $tax_rate_class ]['category'] : ''; } if ( empty( $scheme ) ) { - $scheme = isset( $ubl_tax_settings['class'][$tax_rate_class]['scheme'] ) ? $ubl_tax_settings['class'][$tax_rate_class]['scheme'] : ''; + $scheme = isset( $ubl_tax_settings['class'][ $tax_rate_class ]['scheme'] ) ? $ubl_tax_settings['class'][ $tax_rate_class ]['scheme'] : ''; + } + + if ( empty( $reason ) ) { + $reason = isset( $ubl_tax_settings['class'][ $tax_rate_class ]['reason'] ) ? $ubl_tax_settings['class'][ $tax_rate_class ]['reason'] : ''; } if ( ! empty( $category ) ) { @@ -138,6 +144,10 @@ public function save_order_taxes( $order ) { if ( ! empty( $scheme ) ) { wc_update_order_item_meta( $item_id, '_wcpdf_ubl_tax_scheme', $scheme ); } + + if ( ! empty( $reason ) ) { + wc_update_order_item_meta( $item_id, '_wcpdf_ubl_tax_reason', $reason ); + } } } } diff --git a/ubl/Documents/Document.php b/ubl/Documents/Document.php index c9b38bca9..66b7895f1 100644 --- a/ubl/Documents/Document.php +++ b/ubl/Documents/Document.php @@ -81,6 +81,7 @@ public function get_tax_rates() { // takes into account possible line item rounding settings as well // we still apply rounding on the total (for non-checkout orders) $order_tax_data[ $tax_data_key ]['total_tax'] = wc_round_tax_total( $tax_item['tax_amount'] ) + wc_round_tax_total( $tax_item['shipping_tax_amount'] ); + $rate_id = absint( $tax_item['rate_id'] ); if ( is_callable( array( $tax_item, 'get_rate_percent' ) ) && version_compare( '3.7.0', $this->order->get_version(), '>=' ) ) { $percentage = $tax_item->get_rate_percent(); @@ -89,35 +90,50 @@ public function get_tax_rates() { } if ( ! is_numeric( $percentage ) ) { - $percentage = $this->get_percentage_from_fallback( $tax_data, $tax_item['rate_id'] ); + $percentage = $this->get_percentage_from_fallback( $tax_data, $rate_id ); wc_update_order_item_meta( $tax_item_key, '_wcpdf_rate_percentage', $percentage ); } $category = wc_get_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_category', true ); if ( empty( $category ) ) { - $category = $this->get_category_from_fallback( $tax_data, $tax_item['rate_id'] ); + $category = $this->get_tax_data_from_fallback( 'category', $rate_id ); wc_update_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_category', $category ); } $scheme = wc_get_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_scheme', true ); if ( empty( $scheme ) ) { - $scheme = $this->get_scheme_from_fallback( $tax_data, $tax_item['rate_id'] ); + $scheme = $this->get_tax_data_from_fallback( 'scheme', $rate_id ); wc_update_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_scheme', $scheme ); } + + $reason = wc_get_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_reason', true ); + + if ( empty( $reason ) ) { + $reason = $this->get_tax_data_from_fallback( 'reason', $rate_id ); + wc_update_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_reason', $reason ); + } } $order_tax_data[ $tax_data_key ]['percentage'] = $percentage; $order_tax_data[ $tax_data_key ]['category'] = $category; $order_tax_data[ $tax_data_key ]['scheme'] = $scheme; + $order_tax_data[ $tax_data_key ]['reason'] = $reason; $order_tax_data[ $tax_data_key ]['name'] = ! empty( $tax_item['label'] ) ? $tax_item['label'] : $tax_item['name']; } return $order_tax_data; } - public function get_percentage_from_fallback( $tax_data, $rate_id ) { + /** + * Get percentage from fallback + * + * @param array $tax_data + * @param int $rate_id + * @return float|int + */ + public function get_percentage_from_fallback( array $tax_data, int $rate_id ) { $percentage = ( 0 != $tax_data['total_ex'] ) ? ( $tax_data['total_tax'] / $tax_data['total_ex'] ) * 100 : 0; if ( class_exists( '\WC_TAX' ) && is_callable( array( '\WC_TAX', '_get_tax_rate' ) ) ) { @@ -140,53 +156,40 @@ public function get_percentage_from_fallback( $tax_data, $rate_id ) { return $percentage; } - - public function get_category_from_fallback( $tax_data, $rate_id ) { - $category = ''; - - if ( class_exists( '\WC_TAX' ) && is_callable( array( '\WC_TAX', '_get_tax_rate' ) ) ) { - $tax_rate = \WC_Tax::_get_tax_rate( $rate_id, OBJECT ); - - if ( ! empty( $tax_rate ) && is_numeric( $tax_rate->tax_rate ) ) { - $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes' ); - $category = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['category'] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['category'] : ''; - $tax_rate_class = $tax_rate->tax_rate_class; - - if ( empty( $tax_rate_class ) ) { - $tax_rate_class = 'standard'; - } - - if ( empty( $category ) ) { - $category = isset( $ubl_tax_settings['class'][ $tax_rate_class ]['category'] ) ? $ubl_tax_settings['class'][ $tax_rate_class ]['category'] : ''; - } - } + + /** + * Get tax data from fallback + * + * @param string $key Can be category, scheme, or reason + * @param int $rate_id The tax rate ID + * @return string + */ + public function get_tax_data_from_fallback( string $key, int $rate_id ): string { + $result = ''; + + if ( ! in_array( $key, array( 'category', 'scheme', 'reason' ) ) ) { + return $result; } - - return $category; - } - - public function get_scheme_from_fallback( $tax_data, $rate_id ) { - $scheme = ''; - + if ( class_exists( '\WC_TAX' ) && is_callable( array( '\WC_TAX', '_get_tax_rate' ) ) ) { $tax_rate = \WC_Tax::_get_tax_rate( $rate_id, OBJECT ); - + if ( ! empty( $tax_rate ) && is_numeric( $tax_rate->tax_rate ) ) { $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes' ); - $scheme = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['scheme'] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['scheme'] : ''; + $result = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ][ $key ] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ][ $key ] : ''; $tax_rate_class = $tax_rate->tax_rate_class; - + if ( empty( $tax_rate_class ) ) { $tax_rate_class = 'standard'; } - - if ( empty( $scheme ) ) { - $scheme = isset( $ubl_tax_settings['class'][ $tax_rate_class ]['scheme'] ) ? $ubl_tax_settings['class'][ $tax_rate_class ]['scheme'] : ''; + + if ( empty( $result ) ) { + $result = isset( $ubl_tax_settings['class'][ $tax_rate_class ][ $key ] ) ? $ubl_tax_settings['class'][ $tax_rate_class ][ $key ] : ''; } } } - - return $scheme; - } + + return $result; + } } diff --git a/ubl/Handlers/Common/TaxTotalHandler.php b/ubl/Handlers/Common/TaxTotalHandler.php index f8fcd7bcc..8bfa43046 100644 --- a/ubl/Handlers/Common/TaxTotalHandler.php +++ b/ubl/Handlers/Common/TaxTotalHandler.php @@ -3,6 +3,7 @@ namespace WPO\IPS\UBL\Handlers\Common; use WPO\IPS\UBL\Handlers\UblHandler; +use WPO\IPS\UBL\Settings\TaxesSettings; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly @@ -11,7 +12,49 @@ class TaxTotalHandler extends UblHandler { public function handle( $data, $options = array() ) { - $formatted_tax_array = array_map( function( $item ) { + $taxReasons = TaxesSettings::get_available_reasons(); + + $formatted_tax_array = array_map( function( $item ) use ( $taxReasons ) { + $taxCategory = array( + array( + 'name' => 'cbc:ID', + 'value' => strtoupper( $item['category'] ), + ), + array( + 'name' => 'cbc:Name', + 'value' => $item['name'], + ), + array( + 'name' => 'cbc:Percent', + 'value' => round( $item['percentage'], 1 ), + ), + ); + + // Add TaxExemptionReason only if it's not empty + if ( ! empty( $item['reason'] ) ) { + $reasonKey = $item['reason']; + $reason = ! empty( $taxReasons[ $reasonKey ] ) ? $taxReasons[ $reasonKey ] : $reasonKey; + $taxCategory[] = array( + 'name' => 'cbc:TaxExemptionReasonCode', + 'value' => $reasonKey, + ); + $taxCategory[] = array( + 'name' => 'cbc:TaxExemptionReason', + 'value' => $reason, + ); + } + + // Place the TaxScheme after the TaxExemptionReason + $taxCategory[] = array( + 'name' => 'cac:TaxScheme', + 'value' => array( + array( + 'name' => 'cbc:ID', + 'value' => strtoupper( $item['scheme'] ), + ), + ), + ); + return array( 'name' => 'cac:TaxSubtotal', 'value' => array( @@ -31,29 +74,7 @@ public function handle( $data, $options = array() ) { ), array( 'name' => 'cac:TaxCategory', - 'value' => array( - array( - 'name' => 'cbc:ID', - 'value' => strtoupper( $item['category'] ), - ), - array( - 'name' => 'cbc:Name', - 'value' => $item['name'], - ), - array( - 'name' => 'cbc:Percent', - 'value' => round( $item['percentage'], 1 ), - ), - array( - 'name' => 'cac:TaxScheme', - 'value' => array( - array( - 'name' => 'cbc:ID', - 'value' => strtoupper( $item['scheme'] ), - ), - ), - ), - ), + 'value' => $taxCategory, ), ), ); diff --git a/ubl/Handlers/Invoice/InvoiceLineHandler.php b/ubl/Handlers/Invoice/InvoiceLineHandler.php index 52382bcd0..03d3fedfa 100644 --- a/ubl/Handlers/Invoice/InvoiceLineHandler.php +++ b/ubl/Handlers/Invoice/InvoiceLineHandler.php @@ -3,7 +3,7 @@ namespace WPO\IPS\UBL\Handlers\Invoice; use WPO\IPS\UBL\Handlers\UblHandler; -use Automattic\WooCommerce\Utilities\NumberUtil; +use WPO\IPS\UBL\Settings\TaxesSettings; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly @@ -12,7 +12,8 @@ class InvoiceLineHandler extends UblHandler { public function handle( $data, $options = array() ) { - $items = $this->document->order->get_items( array( 'line_item', 'fee', 'shipping' ) ); + $items = $this->document->order->get_items( array( 'line_item', 'fee', 'shipping' ) ); + $taxReasons = TaxesSettings::get_available_reasons(); // Build the tax totals array foreach ( $items as $item_id => $item ) { @@ -31,7 +32,48 @@ public function handle( $data, $options = array() ) { continue; } - $taxOrderData = $this->document->order_tax_data[ $tax_id ]; + $taxOrderData = $this->document->order_tax_data[ $tax_id ]; + + // Build the TaxCategory array + $taxCategory = array( + array( + 'name' => 'cbc:ID', + 'value' => strtoupper( $taxOrderData['category'] ), + ), + array( + 'name' => 'cbc:Name', + 'value' => $taxOrderData['name'], + ), + array( + 'name' => 'cbc:Percent', + 'value' => round( $taxOrderData['percentage'], 2 ), + ), + ); + + // Add TaxExemptionReason only if it's not empty + if ( ! empty( $taxOrderData['reason'] ) ) { + $reasonKey = $taxOrderData['reason']; + $reason = ! empty( $taxReasons[ $reasonKey ] ) ? $taxReasons[ $reasonKey ] : $reasonKey; + $taxCategory[] = array( + 'name' => 'cbc:TaxExemptionReasonCode', + 'value' => $reasonKey, + ); + $taxCategory[] = array( + 'name' => 'cbc:TaxExemptionReason', + 'value' => $reason, + ); + } + + // Place the TaxScheme after the TaxExemptionReason + $taxCategory[] = array( + 'name' => 'cac:TaxScheme', + 'value' => array( + array( + 'name' => 'cbc:ID', + 'value' => strtoupper( $taxOrderData['scheme'] ), + ), + ), + ); $taxSubtotal[] = array( 'name' => 'cac:TaxSubtotal', @@ -52,29 +94,7 @@ public function handle( $data, $options = array() ) { ), array( 'name' => 'cac:TaxCategory', - 'value' => array( - array( - 'name' => 'cbc:ID', - 'value' => strtoupper( $taxOrderData['category'] ), - ), - array( - 'name' => 'cbc:Name', - 'value' => $taxOrderData['name'], - ), - array( - 'name' => 'cbc:Percent', - 'value' => round( $taxOrderData['percentage'], 2 ), - ), - array( - 'name' => 'cac:TaxScheme', - 'value' => array( - array( - 'name' => 'cbc:ID', - 'value' => strtoupper( $taxOrderData['scheme'] ), - ), - ), - ), - ), + 'value' => $taxCategory, ), ), ); @@ -93,7 +113,7 @@ public function handle( $data, $options = array() ) { ), array( 'name' => 'cbc:LineExtensionAmount', - 'value' => NumberUtil::round( $item->get_total(), wc_get_price_decimals() ), + 'value' => round( $item->get_total(), 2 ), 'attributes' => array( 'currencyID' => $this->document->order->get_currency(), ), @@ -123,7 +143,6 @@ public function handle( $data, $options = array() ) { ), ); - $data[] = apply_filters( 'wpo_wc_ubl_handle_InvoiceLine', $invoiceLine, $data, $options, $item, $this ); // Empty this array at the end of the loop per item, so data doesn't stack diff --git a/ubl/Settings/TaxesSettings.php b/ubl/Settings/TaxesSettings.php index c0d02c976..a693694c3 100644 --- a/ubl/Settings/TaxesSettings.php +++ b/ubl/Settings/TaxesSettings.php @@ -52,7 +52,8 @@ public function output_table_for_tax_class( $slug, $name ) {
- + + @@ -76,15 +77,17 @@ public function output_table_for_tax_class( $slug, $name ) { $scheme = isset( $this->settings['rate'][ $result->tax_rate_id ]['scheme'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['scheme'] : ''; $category = isset( $this->settings['rate'][ $result->tax_rate_id ]['category'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['category'] : ''; + $reason = isset( $this->settings['rate'][ $result->tax_rate_id ]['reason'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['reason'] : ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; } } else { @@ -96,27 +99,53 @@ public function output_table_for_tax_class( $slug, $name ) { settings['class'][ $slug ]['scheme'] ) ? $this->settings['class'][ $slug ]['scheme'] : ''; + $scheme = isset( $this->settings['class'][ $slug ]['scheme'] ) ? $this->settings['class'][ $slug ]['scheme'] : ''; $category = isset( $this->settings['class'][ $slug ]['category'] ) ? $this->settings['class'][ $slug ]['category'] : ''; + $reason = isset( $this->settings['class'][ $slug ]['reason'] ) ? $this->settings['class'][ $slug ]['reason'] : ''; ?> - - + + +
   
' . $feature['label']; echo ! empty( $feature['description'] ) ? '
' . $feature['description'] . '
-- 
'.$result->tax_rate_country.''.$result->tax_rate_state.''.$postcode.''.$city.''.$result->tax_rate.''.$this->get_scheme_select( 'rate', $result->tax_rate_id, $scheme ).''.$this->get_category_select( 'rate', $result->tax_rate_id, $category ).'' . $result->tax_rate_country . '' . $result->tax_rate_state . '' . $postcode . '' . $city . '' . $result->tax_rate . '' . $this->get_select_for( 'scheme', 'rate', $result->tax_rate_id, $scheme ) . '' . $this->get_select_for( 'category', 'rate', $result->tax_rate_id, $category ) . '' . $this->get_select_for( 'reason', 'rate', $result->tax_rate_id, $reason ) . '
: get_scheme_select( 'class', $slug, $scheme ); ?>get_category_select( 'class', $slug, $category ); ?>get_select_for( 'scheme', 'class', $slug, $scheme ); ?>get_select_for( 'category', 'class', $slug, $category ); ?>get_select_for( 'reason', 'class', $slug, $reason ); ?>
'; - foreach ( $this->get_available_schemes() as $key => $value ) { - $select .= ''; + /** + * Get select field for tax rate + * + * @param string $for + * @param string $type + * @param string $id + * @param string $selected + * + * @return string + */ + public function get_select_for( string $for, string $type, string $id, string $selected ): string { + switch ( $for ) { + case 'scheme': + $options = $this->get_available_schemes(); + break; + case 'category': + $options = $this->get_available_categories(); + break; + case 'reason': + $options = self::get_available_reasons(); + break; + default: + $options = array(); + } + + $select = ''; return $select; } - public function get_available_schemes() { + public function get_available_schemes(): array { return array( 'vat' => __( 'Value added tax (VAT)', 'woocommerce-pdf-invoices-packing-slips' ), 'gst' => __( 'Goods and services tax (GST)', 'woocommerce-pdf-invoices-packing-slips' ), @@ -174,30 +203,65 @@ public function get_available_schemes() { ); } - public function get_category_select( $type, $id, $selected ) { - $select = ''; - return $select; + public function get_available_categories(): array { + return array( + 'AE' => __( 'VAT Reverse Charge', 'woocommerce-pdf-invoices-packing-slips' ), + 'E' => __( 'Exempt from Tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'S' => __( 'Standard rate', 'woocommerce-pdf-invoices-packing-slips' ), + 'Z' => __( 'Zero rated goods', 'woocommerce-pdf-invoices-packing-slips' ), + 'G' => __( 'Free export item, VAT not charged', 'woocommerce-pdf-invoices-packing-slips' ), + 'O' => __( 'Services outside scope of tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'K' => __( 'VAT exempt for EEA intra-community supply of goods and services', 'woocommerce-pdf-invoices-packing-slips' ), + 'L' => __( 'Canary Islands general indirect tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'M' => __( 'Tax for production, services and importation in Ceuta and Melilla', 'woocommerce-pdf-invoices-packing-slips' ), + 'B' => __( 'Transferred (VAT), In Italy', 'woocommerce-pdf-invoices-packing-slips' ), + ); } - public function get_available_categories() { + public static function get_available_reasons(): array { return array( - 's' => __( 'Standard rate', 'woocommerce-pdf-invoices-packing-slips' ), - 'aa' => __( 'Lower rate', 'woocommerce-pdf-invoices-packing-slips' ), - 'z' => __( 'Zero rated goods', 'woocommerce-pdf-invoices-packing-slips' ), - 'a' => __( 'Mixed tax rate', 'woocommerce-pdf-invoices-packing-slips' ), - 'ab' => __( 'Exempt for resale', 'woocommerce-pdf-invoices-packing-slips' ), - 'ac' => __( 'Value Added Tax (VAT) not now due for payment', 'woocommerce-pdf-invoices-packing-slips' ), - 'ad' => __( 'Value Added Tax (VAT) due from a previous invoice', 'woocommerce-pdf-invoices-packing-slips' ), - 'b' => __( 'Transferred (VAT)', 'woocommerce-pdf-invoices-packing-slips' ), - 'c' => __( 'Duty paid by supplier', 'woocommerce-pdf-invoices-packing-slips' ), - 'e' => __( 'Exempt from tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'g' => __( 'Free export item, tax not charged', 'woocommerce-pdf-invoices-packing-slips' ), - 'h' => __( 'Higher rate', 'woocommerce-pdf-invoices-packing-slips' ), - 'o' => __( 'Services outside scope of tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-79-C' => __( 'Exempt based on article 79, point c of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132' => __( 'Exempt based on article 132 of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1A' => __( 'Exempt based on article 132, section 1 (a) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1B' => __( 'Exempt based on article 132, section 1 (b) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1C' => __( 'Exempt based on article 132, section 1 (c) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1D' => __( 'Exempt based on article 132, section 1 (d) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1E' => __( 'Exempt based on article 132, section 1 (e) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1F' => __( 'Exempt based on article 132, section 1 (f) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1G' => __( 'Exempt based on article 132, section 1 (g) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1H' => __( 'Exempt based on article 132, section 1 (h) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1I' => __( 'Exempt based on article 132, section 1 (i) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1J' => __( 'Exempt based on article 132, section 1 (j) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1K' => __( 'Exempt based on article 132, section 1 (k) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1L' => __( 'Exempt based on article 132, section 1 (l) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1M' => __( 'Exempt based on article 132, section 1 (m) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1N' => __( 'Exempt based on article 132, section 1 (n) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1O' => __( 'Exempt based on article 132, section 1 (o) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1P' => __( 'Exempt based on article 132, section 1 (p) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-132-1Q' => __( 'Exempt based on article 132, section 1 (q) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143' => __( 'Exempt based on article 143 of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1A' => __( 'Exempt based on article 143, section 1 (a) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1B' => __( 'Exempt based on article 143, section 1 (b) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1C' => __( 'Exempt based on article 143, section 1 (c) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1D' => __( 'Exempt based on article 143, section 1 (d) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1E' => __( 'Exempt based on article 143, section 1 (e) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1F' => __( 'Exempt based on article 143, section 1 (f) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1FA' => __( 'Exempt based on article 143, section 1 (fa) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1G' => __( 'Exempt based on article 143, section 1 (g) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1H' => __( 'Exempt based on article 143, section 1 (h) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1I' => __( 'Exempt based on article 143, section 1 (i) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1J' => __( 'Exempt based on article 143, section 1 (j) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1K' => __( 'Exempt based on article 143, section 1 (k) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-143-1L' => __( 'Exempt based on article 143, section 1 (l) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-151' => __( 'Exempt based on article 151 of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-AE' => __( 'Reverse charge', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-D' => __( 'Intra-Community acquisition from second hand means of transport', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-F' => __( 'Intra-Community acquisition of second hand goods', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-G' => __( 'Export outside the EU', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-I' => __( 'Intra-Community acquisition of works of art', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-FR-FRANCHISE' => __( 'France domestic VAT franchise in base', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-FR-CNWVAT' => __( 'France domestic Credit Notes without VAT, due to supplier forfeit of VAT for discount', 'woocommerce-pdf-invoices-packing-slips' ), ); } + } From 30c5975fc3d473238c6befab9fbbb9008b4c348a Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 27 Dec 2024 16:57:40 +0000 Subject: [PATCH 42/69] v3.9.5-beta-1 --- readme.txt | 38 +++++++++++------------ woocommerce-pdf-invoices-packingslips.php | 16 +++++----- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/readme.txt b/readme.txt index 5b79b5473..366570821 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 Requires PHP: 7.4 -Stable tag: 3.9.4 +Stable tag: 3.9.5-beta-1 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -116,27 +116,27 @@ There's a setting on the Advanced tab of the settings page that allows you to to = 3.9.2 (2024-12-17) = - New: adds description to UBL format selector -- Fix: issue with PHP extension load checks +- Fix: issue with PHP extension load checks - Translations: Updated translation template (POT). = 3.9.1 (2024-12-16) = -- New: Adds support for multiple UBL formats. -- New: Adds a shop phone number field for e-Invoice support. -- New: Adds user info to order notes when generating documents. -- New: Added an admin notice to inform when server requirements are not met. -- New: Raised the minimum PHP version requirement to 7.4. -- New: Removes space between items table and totals. -- New: Added sections to settings for better organization. -- Tweak: Improve the description of the "Remove released semaphore locks" tool. -- Fix: Upgrade links not displaying correctly. -- Fix: Temp folder warning style issue. -- Fix: Remove unused legacy notice code: `check_auto_increment_increment()`. -- Fix: AJAX preview loading when disabled on settings pages. -- Fix: UBL issue with empty tax on line items. -- Fix: jQuery `tipTip` function not available. -- Fix: Template item meta styling. -- Fix: Semaphore class name on two classes that were still using the previous name. -- Translations: Updated translation template (POT). +- New: Adds support for multiple UBL formats. +- New: Adds a shop phone number field for e-Invoice support. +- New: Adds user info to order notes when generating documents. +- New: Added an admin notice to inform when server requirements are not met. +- New: Raised the minimum PHP version requirement to 7.4. +- New: Removes space between items table and totals. +- New: Added sections to settings for better organization. +- Tweak: Improve the description of the "Remove released semaphore locks" tool. +- Fix: Upgrade links not displaying correctly. +- Fix: Temp folder warning style issue. +- Fix: Remove unused legacy notice code: `check_auto_increment_increment()`. +- Fix: AJAX preview loading when disabled on settings pages. +- Fix: UBL issue with empty tax on line items. +- Fix: jQuery `tipTip` function not available. +- Fix: Template item meta styling. +- Fix: Semaphore class name on two classes that were still using the previous name. +- Translations: Updated translation template (POT). - Tested: Tested up to WooCommerce 9.5. = 3.9.0 (2024-10-21) = diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index ec4253192..e02a9de62 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,7 +4,7 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.4 + * Version: 3.9.5-beta-1 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.4'; + public $version = '3.9.5-beta-1'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; @@ -453,21 +453,21 @@ public function rtl_detected() { } } } - + /** * Yearly reset action missing notice - * + * * @return void */ public function yearly_reset_action_missing_notice(): void { if ( ! $this->settings->maybe_schedule_yearly_reset_numbers() ) { return; } - + if ( ! function_exists( 'as_get_scheduled_actions' ) ) { return; } - + $current_date = new \DateTime(); $end_of_year = new \DateTime( 'last day of December' ); $days_remaining = $current_date->diff( $end_of_year )->days; @@ -483,7 +483,7 @@ public function yearly_reset_action_missing_notice(): void { settings->schedule_yearly_reset_numbers(); wcpdf_log_error( 'Yearly reset numbering system rescheduled!', 'info' ); } - + wp_redirect( 'admin.php?page=wpo_wcpdf_options_page&tab=debug§ion=status' ); exit; } From d26c826d33828d10b18a16bf538040b4217da71b Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Tue, 31 Dec 2024 09:04:35 +0000 Subject: [PATCH 43/69] New: Add `cac:Price` support to UBL --- ubl/Handlers/Invoice/InvoiceLineHandler.php | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ubl/Handlers/Invoice/InvoiceLineHandler.php b/ubl/Handlers/Invoice/InvoiceLineHandler.php index 03d3fedfa..4e03a7f4a 100644 --- a/ubl/Handlers/Invoice/InvoiceLineHandler.php +++ b/ubl/Handlers/Invoice/InvoiceLineHandler.php @@ -140,6 +140,18 @@ public function handle( $data, $options = array() ) { ), ), ), + array( + 'name' => 'cac:Price', + 'value' => array( + array( + 'name' => 'cbc:PriceAmount', + 'value' => round( $this->get_item_unit_price( $item ), 2 ), + 'attributes' => array( + 'currencyID' => $this->document->order->get_currency(), + ), + ), + ), + ), ), ); @@ -152,4 +164,20 @@ public function handle( $data, $options = array() ) { return $data; } + /** + * Get the unit price of an item + * + * @param WC_Order_Item $item + * @return int|float + */ + private function get_item_unit_price( $item ) { + if ( is_a( $item, 'WC_Order_Item_Product' ) ) { + return $item->get_subtotal() / $item->get_quantity(); + } elseif ( is_a( $item, 'WC_Order_Item_Shipping' ) || is_a( $item, 'WC_Order_Item_Fee' ) ) { + return $item->get_total(); + } else { + return 0; + } + } + } From 17cfe6e20c273bd26baa94480fd01ced34e36026 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Tue, 31 Dec 2024 11:44:11 +0000 Subject: [PATCH 44/69] New: filters for UBL tax schemes, categories, and reasons (#960) --- ubl/Settings/TaxesSettings.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ubl/Settings/TaxesSettings.php b/ubl/Settings/TaxesSettings.php index a693694c3..e981bcd98 100644 --- a/ubl/Settings/TaxesSettings.php +++ b/ubl/Settings/TaxesSettings.php @@ -146,7 +146,7 @@ public function get_select_for( string $for, string $type, string $id, string $s } public function get_available_schemes(): array { - return array( + return apply_filters( 'wpo_wcpdf_ubl_tax_schemes', array( 'vat' => __( 'Value added tax (VAT)', 'woocommerce-pdf-invoices-packing-slips' ), 'gst' => __( 'Goods and services tax (GST)', 'woocommerce-pdf-invoices-packing-slips' ), 'aaa' => __( 'Petroleum tax', 'woocommerce-pdf-invoices-packing-slips' ), @@ -200,11 +200,11 @@ public function get_available_schemes(): array { 'tox' => __( 'Turnover tax', 'woocommerce-pdf-invoices-packing-slips' ), 'tta' => __( 'Tonnage taxes', 'woocommerce-pdf-invoices-packing-slips' ), 'vad' => __( 'Valuation deposit', 'woocommerce-pdf-invoices-packing-slips' ), - ); + ) ); } public function get_available_categories(): array { - return array( + return apply_filters( 'wpo_wcpdf_ubl_tax_categories', array( 'AE' => __( 'VAT Reverse Charge', 'woocommerce-pdf-invoices-packing-slips' ), 'E' => __( 'Exempt from Tax', 'woocommerce-pdf-invoices-packing-slips' ), 'S' => __( 'Standard rate', 'woocommerce-pdf-invoices-packing-slips' ), @@ -215,11 +215,11 @@ public function get_available_categories(): array { 'L' => __( 'Canary Islands general indirect tax', 'woocommerce-pdf-invoices-packing-slips' ), 'M' => __( 'Tax for production, services and importation in Ceuta and Melilla', 'woocommerce-pdf-invoices-packing-slips' ), 'B' => __( 'Transferred (VAT), In Italy', 'woocommerce-pdf-invoices-packing-slips' ), - ); + ) ); } public static function get_available_reasons(): array { - return array( + return apply_filters( 'wpo_wcpdf_ubl_tax_reasons', array( 'VATEX-EU-79-C' => __( 'Exempt based on article 79, point c of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), 'VATEX-EU-132' => __( 'Exempt based on article 132 of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), 'VATEX-EU-132-1A' => __( 'Exempt based on article 132, section 1 (a) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), @@ -261,7 +261,7 @@ public static function get_available_reasons(): array { 'VATEX-EU-I' => __( 'Intra-Community acquisition of works of art', 'woocommerce-pdf-invoices-packing-slips' ), 'VATEX-FR-FRANCHISE' => __( 'France domestic VAT franchise in base', 'woocommerce-pdf-invoices-packing-slips' ), 'VATEX-FR-CNWVAT' => __( 'France domestic Credit Notes without VAT, due to supplier forfeit of VAT for discount', 'woocommerce-pdf-invoices-packing-slips' ), - ); + ) ); } } From cf04043852e39b872e7099eb34d2ed5b05c8e70f Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Thu, 2 Jan 2025 09:35:52 +0000 Subject: [PATCH 45/69] Tweak: update UBL tax scheme keys to comply with UN/EDIFACT code format (#968) --- ubl/Settings/TaxesSettings.php | 106 ++++++++++++++++----------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/ubl/Settings/TaxesSettings.php b/ubl/Settings/TaxesSettings.php index e981bcd98..04b7dd950 100644 --- a/ubl/Settings/TaxesSettings.php +++ b/ubl/Settings/TaxesSettings.php @@ -147,59 +147,59 @@ public function get_select_for( string $for, string $type, string $id, string $s public function get_available_schemes(): array { return apply_filters( 'wpo_wcpdf_ubl_tax_schemes', array( - 'vat' => __( 'Value added tax (VAT)', 'woocommerce-pdf-invoices-packing-slips' ), - 'gst' => __( 'Goods and services tax (GST)', 'woocommerce-pdf-invoices-packing-slips' ), - 'aaa' => __( 'Petroleum tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'aab' => __( 'Provisional countervailing duty cash', 'woocommerce-pdf-invoices-packing-slips' ), - 'aac' => __( 'Provisional countervailing duty bond', 'woocommerce-pdf-invoices-packing-slips' ), - 'aad' => __( 'Tobacco tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'aae' => __( 'Energy fee', 'woocommerce-pdf-invoices-packing-slips' ), - 'aaf' => __( 'Coffee tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'aag' => __( 'Harmonised sales tax, Canadian', 'woocommerce-pdf-invoices-packing-slips' ), - 'aah' => __( 'Quebec sales tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'aai' => __( 'Canadian provincial sales tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'aaj' => __( 'Tax on replacement part', 'woocommerce-pdf-invoices-packing-slips' ), - 'aak' => __( 'Mineral oil tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'aal' => __( 'Special tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'add' => __( 'Anti-dumping duty', 'woocommerce-pdf-invoices-packing-slips' ), - 'bol' => __( 'Stamp duty (Imposta di Bollo)', 'woocommerce-pdf-invoices-packing-slips' ), - 'cap' => __( 'Agricultural levy', 'woocommerce-pdf-invoices-packing-slips' ), - 'car' => __( 'Car tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'coc' => __( 'Paper consortium tax (Italy)', 'woocommerce-pdf-invoices-packing-slips' ), - 'cst' => __( 'Commodity specific tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'cud' => __( 'Customs duty', 'woocommerce-pdf-invoices-packing-slips' ), - 'cvd' => __( 'Countervailing duty', 'woocommerce-pdf-invoices-packing-slips' ), - 'env' => __( 'Environmental tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'exc' => __( 'Excise duty', 'woocommerce-pdf-invoices-packing-slips' ), - 'exp' => __( 'Agricultural export rebate', 'woocommerce-pdf-invoices-packing-slips' ), - 'fet' => __( 'Federal excise tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'fre' => __( 'Free', 'woocommerce-pdf-invoices-packing-slips' ), - 'gnc' => __( 'General construction tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'ill' => __( 'Illuminants tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'imp' => __( 'Import tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'ind' => __( 'Individual tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'lac' => __( 'Business license fee', 'woocommerce-pdf-invoices-packing-slips' ), - 'lcn' => __( 'Local construction tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'ldp' => __( 'Light dues payable', 'woocommerce-pdf-invoices-packing-slips' ), - 'loc' => __( 'Local sales tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'lst' => __( 'Lust tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'mca' => __( 'Monetary compensatory amount', 'woocommerce-pdf-invoices-packing-slips' ), - 'mcd' => __( 'Miscellaneous cash deposit', 'woocommerce-pdf-invoices-packing-slips' ), - 'oth' => __( 'Other taxes', 'woocommerce-pdf-invoices-packing-slips' ), - 'pdb' => __( 'Provisional duty bond', 'woocommerce-pdf-invoices-packing-slips' ), - 'pdc' => __( 'Provisional duty cash', 'woocommerce-pdf-invoices-packing-slips' ), - 'prf' => __( 'Preference duty', 'woocommerce-pdf-invoices-packing-slips' ), - 'scn' => __( 'Special construction tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'sss' => __( 'Shifted social securities', 'woocommerce-pdf-invoices-packing-slips' ), - 'stt' => __( 'State/provincial sales tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'sup' => __( 'Suspended duty', 'woocommerce-pdf-invoices-packing-slips' ), - 'sur' => __( 'Surtax', 'woocommerce-pdf-invoices-packing-slips' ), - 'swt' => __( 'Shifted wage tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'tac' => __( 'Alcohol mark tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'tot' => __( 'Total', 'woocommerce-pdf-invoices-packing-slips' ), - 'tox' => __( 'Turnover tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'tta' => __( 'Tonnage taxes', 'woocommerce-pdf-invoices-packing-slips' ), - 'vad' => __( 'Valuation deposit', 'woocommerce-pdf-invoices-packing-slips' ), + 'VAT' => __( 'Value added tax (VAT)', 'woocommerce-pdf-invoices-packing-slips' ), + 'GST' => __( 'Goods and services tax (GST)', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAA' => __( 'Petroleum tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAB' => __( 'Provisional countervailing duty cash', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAC' => __( 'Provisional countervailing duty bond', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAD' => __( 'Tobacco tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAE' => __( 'Energy fee', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAF' => __( 'Coffee tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAG' => __( 'Harmonised sales tax, Canadian', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAH' => __( 'Quebec sales tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAI' => __( 'Canadian provincial sales tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAJ' => __( 'Tax on replacement part', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAK' => __( 'Mineral oil tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'AAL' => __( 'Special tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'ADD' => __( 'Anti-dumping duty', 'woocommerce-pdf-invoices-packing-slips' ), + 'BOL' => __( 'Stamp duty (Imposta di Bollo)', 'woocommerce-pdf-invoices-packing-slips' ), + 'CAP' => __( 'Agricultural levy', 'woocommerce-pdf-invoices-packing-slips' ), + 'CAR' => __( 'Car tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'COC' => __( 'Paper consortium tax (Italy)', 'woocommerce-pdf-invoices-packing-slips' ), + 'CST' => __( 'Commodity specific tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'CUD' => __( 'Customs duty', 'woocommerce-pdf-invoices-packing-slips' ), + 'CVD' => __( 'Countervailing duty', 'woocommerce-pdf-invoices-packing-slips' ), + 'ENV' => __( 'Environmental tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'EXC' => __( 'Excise duty', 'woocommerce-pdf-invoices-packing-slips' ), + 'EXP' => __( 'Agricultural export rebate', 'woocommerce-pdf-invoices-packing-slips' ), + 'FET' => __( 'Federal excise tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'FRE' => __( 'Free', 'woocommerce-pdf-invoices-packing-slips' ), + 'GNC' => __( 'General construction tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'ILL' => __( 'Illuminants tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'IMP' => __( 'Import tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'IND' => __( 'Individual tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'LAC' => __( 'Business license fee', 'woocommerce-pdf-invoices-packing-slips' ), + 'LCN' => __( 'Local construction tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'LDP' => __( 'Light dues payable', 'woocommerce-pdf-invoices-packing-slips' ), + 'LOC' => __( 'Local sales tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'LST' => __( 'Lust tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'MCA' => __( 'Monetary compensatory amount', 'woocommerce-pdf-invoices-packing-slips' ), + 'MCD' => __( 'Miscellaneous cash deposit', 'woocommerce-pdf-invoices-packing-slips' ), + 'OTH' => __( 'Other taxes', 'woocommerce-pdf-invoices-packing-slips' ), + 'PDB' => __( 'Provisional duty bond', 'woocommerce-pdf-invoices-packing-slips' ), + 'PDC' => __( 'Provisional duty cash', 'woocommerce-pdf-invoices-packing-slips' ), + 'PRF' => __( 'Preference duty', 'woocommerce-pdf-invoices-packing-slips' ), + 'SCN' => __( 'Special construction tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'SSS' => __( 'Shifted social securities', 'woocommerce-pdf-invoices-packing-slips' ), + 'STT' => __( 'State/provincial sales tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'SUP' => __( 'Suspended duty', 'woocommerce-pdf-invoices-packing-slips' ), + 'SUR' => __( 'Surtax', 'woocommerce-pdf-invoices-packing-slips' ), + 'SWT' => __( 'Shifted wage tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'TAC' => __( 'Alcohol mark tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'TOT' => __( 'Total', 'woocommerce-pdf-invoices-packing-slips' ), + 'TOX' => __( 'Turnover tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'TTA' => __( 'Tonnage taxes', 'woocommerce-pdf-invoices-packing-slips' ), + 'VAD' => __( 'Valuation deposit', 'woocommerce-pdf-invoices-packing-slips' ), ) ); } From 274127d851a843a6d78fb7ff85270914547fd049 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Thu, 2 Jan 2025 09:36:41 +0000 Subject: [PATCH 46/69] Fix: revert UBL Tax Categories to full UN/EDIFACT list (#966) --- ubl/Settings/TaxesSettings.php | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/ubl/Settings/TaxesSettings.php b/ubl/Settings/TaxesSettings.php index 04b7dd950..7f231712b 100644 --- a/ubl/Settings/TaxesSettings.php +++ b/ubl/Settings/TaxesSettings.php @@ -52,7 +52,7 @@ public function output_table_for_tax_class( $slug, $name ) { - + @@ -205,16 +205,27 @@ public function get_available_schemes(): array { public function get_available_categories(): array { return apply_filters( 'wpo_wcpdf_ubl_tax_categories', array( + 'A' => __( 'Mixed tax rate', 'woocommerce-pdf-invoices-packing-slips' ), + 'AA' => __( 'Lower rate', 'woocommerce-pdf-invoices-packing-slips' ), + 'AB' => __( 'Exempt for resale', 'woocommerce-pdf-invoices-packing-slips' ), + 'AC' => __( 'Value Added Tax (VAT) not now due for payment', 'woocommerce-pdf-invoices-packing-slips' ), + 'AD' => __( 'Value Added Tax (VAT) due from a previous invoice', 'woocommerce-pdf-invoices-packing-slips' ), 'AE' => __( 'VAT Reverse Charge', 'woocommerce-pdf-invoices-packing-slips' ), - 'E' => __( 'Exempt from Tax', 'woocommerce-pdf-invoices-packing-slips' ), - 'S' => __( 'Standard rate', 'woocommerce-pdf-invoices-packing-slips' ), - 'Z' => __( 'Zero rated goods', 'woocommerce-pdf-invoices-packing-slips' ), - 'G' => __( 'Free export item, VAT not charged', 'woocommerce-pdf-invoices-packing-slips' ), - 'O' => __( 'Services outside scope of tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'B' => __( 'Transferred (VAT)', 'woocommerce-pdf-invoices-packing-slips' ), + 'C' => __( 'Duty paid by supplier', 'woocommerce-pdf-invoices-packing-slips' ), + 'D' => __( 'Value Added Tax (VAT) margin scheme - travel agents', 'woocommerce-pdf-invoices-packing-slips' ), + 'E' => __( 'Exempt from tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'F' => __( 'Value Added Tax (VAT) margin scheme - second-hand goods', 'woocommerce-pdf-invoices-packing-slips' ), + 'G' => __( 'Free export item, tax not charged', 'woocommerce-pdf-invoices-packing-slips' ), + 'H' => __( 'Higher rate', 'woocommerce-pdf-invoices-packing-slips' ), + 'I' => __( 'Value Added Tax (VAT) margin scheme - works of art', 'woocommerce-pdf-invoices-packing-slips' ), + 'J' => __( 'Value Added Tax (VAT) margin scheme - collector\'s items and antiques', 'woocommerce-pdf-invoices-packing-slips' ), 'K' => __( 'VAT exempt for EEA intra-community supply of goods and services', 'woocommerce-pdf-invoices-packing-slips' ), 'L' => __( 'Canary Islands general indirect tax', 'woocommerce-pdf-invoices-packing-slips' ), 'M' => __( 'Tax for production, services and importation in Ceuta and Melilla', 'woocommerce-pdf-invoices-packing-slips' ), - 'B' => __( 'Transferred (VAT), In Italy', 'woocommerce-pdf-invoices-packing-slips' ), + 'O' => __( 'Services outside scope of tax', 'woocommerce-pdf-invoices-packing-slips' ), + 'S' => __( 'Standard rate', 'woocommerce-pdf-invoices-packing-slips' ), + 'Z' => __( 'Zero rated goods', 'woocommerce-pdf-invoices-packing-slips' ), ) ); } From ebb5d206daadd2cf1a7405646ae33c9e72157d7a Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Thu, 2 Jan 2025 09:37:44 +0000 Subject: [PATCH 47/69] New: enable Support for `cac:PaymentMeans` in UBL (#958) --- ubl/Documents/UblDocument.php | 2 +- ubl/Handlers/Common/PaymentMeansHandler.php | 101 +++++++++++++++++++- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/ubl/Documents/UblDocument.php b/ubl/Documents/UblDocument.php index 6d48cfbd8..17d2d67f0 100644 --- a/ubl/Documents/UblDocument.php +++ b/ubl/Documents/UblDocument.php @@ -63,7 +63,7 @@ public function get_format() { 'handler' => \WPO\IPS\UBL\Handlers\Common\DeliveryHandler::class, ), 'paymentmeans' => array( - 'enabled' => false, + 'enabled' => true, 'handler' => \WPO\IPS\UBL\Handlers\Common\PaymentMeansHandler::class, ), 'paymentterms' => array( diff --git a/ubl/Handlers/Common/PaymentMeansHandler.php b/ubl/Handlers/Common/PaymentMeansHandler.php index f1e807b46..578a50065 100644 --- a/ubl/Handlers/Common/PaymentMeansHandler.php +++ b/ubl/Handlers/Common/PaymentMeansHandler.php @@ -13,12 +13,107 @@ class PaymentMeansHandler extends UblHandler { public function handle( $data, $options = array() ) { $payment_means = array( 'name' => 'cac:PaymentMeans', - 'value' => array(), + 'value' => $this->get_payment_means(), ); - $data[] = apply_filters( 'wpo_wc_ubl_handle_PaymentMeans', $payment_means, $data, $options, $this ); - + $data[] = apply_filters( 'wpo_wc_ubl_handle_PaymentMeans', $payment_means, $options, $this ); + return $data; } + private function get_payment_means_code( string $payment_method ): string { + // Map WooCommerce payment methods to Payment Means Code + // All available codes: https://docs.peppol.eu/poacc/billing/3.0/2024-Q2/codelist/UNCL4461/ + $mapping = apply_filters( 'wpo_wc_ubl_payment_means_code_mapping', array( + 'cod' => '10', + 'bacs' => '30', + 'cheque' => '20', + 'paypal' => 'ZZZ', + 'stripe' => 'ZZZ', + ), $this ); + + return isset( $mapping[ $payment_method ] ) ? $mapping[ $payment_method ] : '97'; // Default to 'Other' + } + + public function get_payment_means(): array { + $payment_method = $this->document->order->get_payment_method(); + $payment_type_code = $this->get_payment_means_code( $payment_method ); + + $payment_means = array( + array( + 'name' => 'cbc:PaymentMeansCode', + 'value' => $payment_type_code, + ), + ); + + switch ( $payment_method ) { + case 'bacs': + $bank_accounts = get_option(' woocommerce_bacs_accounts', array() ); + + if ( ! empty( $bank_accounts ) && is_array( $bank_accounts ) ) { + $default_account = reset( $bank_accounts ); // Use the first bank account + + $payment_means[] = array( + 'name' => 'cac:PayeeFinancialAccount', + 'value' => array( + array( + 'name' => 'cbc:ID', + 'value' => $default_account['iban'] ?? '', + ), + array( + 'name' => 'cbc:Name', + 'value' => $default_account['account_name'] ?? $this->document->order_document->get_shop_name(), + ), + ), + ); + } + break; + + case 'paypal': + $paypal_transaction_id = $this->document->order->get_meta( '_transaction_id', true ); + + $payment_means[] = array( + 'name' => 'cac:PayeeFinancialAccount', + 'value' => array( + array( + 'name' => 'cbc:ID', + 'value' => $paypal_transaction_id, + ), + array( + 'name' => 'cbc:Name', + 'value' => 'PayPal', + ), + ), + ); + break; + + case 'stripe': + $stripe_source_id = $this->document->order->get_meta( '_stripe_source_id', true ); + + $payment_means[] = array( + 'name' => 'cac:PayeeFinancialAccount', + 'value' => array( + array( + 'name' => 'cbc:ID', + 'value' => $stripe_source_id, + ), + array( + 'name' => 'cbc:Name', + 'value' => 'Stripe', + ), + ), + ); + break; + + default: // Other Payment Methods + $payment_means[] = array( + 'name' => 'cbc:InstructionNote', + 'value' => $this->document->order->get_payment_method_title(), + ); + break; + } + + return $payment_means; + } + } From 416c3e91266d8a83aac23148ab933e1a1b4a9ac8 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Thu, 2 Jan 2025 10:25:40 +0000 Subject: [PATCH 48/69] Fix: postcode and city defaults in UBL tax output (#962) --- ubl/Settings/TaxesSettings.php | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/ubl/Settings/TaxesSettings.php b/ubl/Settings/TaxesSettings.php index 7f231712b..30164d4f9 100644 --- a/ubl/Settings/TaxesSettings.php +++ b/ubl/Settings/TaxesSettings.php @@ -61,27 +61,35 @@ public function output_table_for_tax_class( $slug, $name ) { if ( ! empty( $results ) ) { foreach ( $results as $result ) { $locationResults = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE tax_rate_id = %d;", $result->tax_rate_id ) ); - $postcode = $city = ''; - + $postcode = array(); + $city = array(); + foreach ( $locationResults as $locationResult ) { - if ( 'postcode' === $locationResult->location_type ) { - $postcode = $locationResult->location_code; + if ( ! isset( $locationResult->location_type ) ) { continue; } - - if ( 'city' === $locationResult->location_type ) { - $city = $locationResult->location_code; - continue; + + switch ( $locationResult->location_type ) { + case 'postcode': + $postcode[] = $locationResult->location_code; + break; + case 'city': + $city[] = $locationResult->location_code; + break; } } - + + $country = empty( $result->tax_rate_country ) ? '*' : $result->tax_rate_country; + $state = empty( $result->tax_rate_state ) ? '*' : $result->tax_rate_state; + $postcode = empty( $postcode ) ? '*' : implode( '; ', $postcode ); + $city = empty( $city ) ? '*' : implode( '; ', $city ); $scheme = isset( $this->settings['rate'][ $result->tax_rate_id ]['scheme'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['scheme'] : ''; $category = isset( $this->settings['rate'][ $result->tax_rate_id ]['category'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['category'] : ''; $reason = isset( $this->settings['rate'][ $result->tax_rate_id ]['reason'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['reason'] : ''; echo ''; - echo '' . $result->tax_rate_country . ''; - echo '' . $result->tax_rate_state . ''; + echo '' . $country . ''; + echo '' . $state . ''; echo '' . $postcode . ''; echo '' . $city . ''; echo '' . $result->tax_rate . ''; From 46316a64a48c8b0acaa24c7f2cf40755c4415984 Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Thu, 2 Jan 2025 15:27:04 +0330 Subject: [PATCH 49/69] New: Add global helper functions for UBL (#963) --- .../AdditionalDocumentReferenceHandler.php | 2 +- ubl/Handlers/Common/AddressHandler.php | 24 +++++++++---------- ubl/Handlers/Invoice/InvoiceLineHandler.php | 2 +- woocommerce-pdf-invoices-packingslips.php | 1 + wpo-ips-functions-ubl.php | 23 ++++++++++++++++++ 5 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 wpo-ips-functions-ubl.php diff --git a/ubl/Handlers/Common/AdditionalDocumentReferenceHandler.php b/ubl/Handlers/Common/AdditionalDocumentReferenceHandler.php index ab381cf60..0809796a6 100644 --- a/ubl/Handlers/Common/AdditionalDocumentReferenceHandler.php +++ b/ubl/Handlers/Common/AdditionalDocumentReferenceHandler.php @@ -21,7 +21,7 @@ public function handle( $data, $options = array() ) { ), array( 'name' => 'cbc:DocumentType', - 'value' => ! empty( $this->document->order_document->get_title() ) ? 'PDF '.$this->document->order_document->get_title() : '', + 'value' => ! empty( $this->document->order_document->get_title() ) ? wpo_ips_ubl_sanitize_string( 'PDF ' . $this->document->order_document->get_title() ) : '', ), array( 'name' => 'cac:Attachment', diff --git a/ubl/Handlers/Common/AddressHandler.php b/ubl/Handlers/Common/AddressHandler.php index 23f32590a..b1d32f15a 100644 --- a/ubl/Handlers/Common/AddressHandler.php +++ b/ubl/Handlers/Common/AddressHandler.php @@ -53,7 +53,7 @@ public function return_supplier_party_details() { 'name' => 'cac:PartyName', 'value' => array( 'name' => 'cbc:Name', - 'value' => $company, + 'value' => wpo_ips_ubl_sanitize_string( $company ), ), ), array( @@ -61,11 +61,11 @@ public function return_supplier_party_details() { 'value' => array( array( 'name' => 'cbc:StreetName', - 'value' => get_option( 'woocommerce_store_address' ), + 'value' => wpo_ips_ubl_sanitize_string( get_option( 'woocommerce_store_address' ) ), ), array( 'name' => 'cbc:CityName', - 'value' => get_option( 'woocommerce_store_city' ), + 'value' => wpo_ips_ubl_sanitize_string( get_option( 'woocommerce_store_city' ) ), ), array( 'name' => 'cbc:PostalZone', @@ -75,7 +75,7 @@ public function return_supplier_party_details() { 'name' => 'cac:AddressLine', 'value' => array( 'name' => 'cbc:Line', - 'value' => $address, + 'value' => wpo_ips_ubl_sanitize_string( $address ), ), ), array( @@ -117,14 +117,14 @@ public function return_supplier_party_details() { ), ); } - + if ( ! empty( $company ) && ! empty( $coc_number ) ) { $supplierPartyDetails[] = array( 'name' => 'cac:PartyLegalEntity', 'value' => array( array( 'name' => 'cbc:RegistrationName', - 'value' => $company, + 'value' => wpo_ips_ubl_sanitize_string( $company ), ), array( 'name' => 'cbc:CompanyID', @@ -146,7 +146,7 @@ public function return_supplier_party_details() { ), ), ); - + return $supplierPartyDetails; } @@ -200,7 +200,7 @@ public function return_customer_party( $data, $options = array() ) { 'name' => 'cac:PartyName', 'value' => array( 'name' => 'cbc:Name', - 'value' => $customerPartyName, + 'value' => wpo_ips_ubl_sanitize_string( $customerPartyName ), ), ), array( @@ -208,11 +208,11 @@ public function return_customer_party( $data, $options = array() ) { 'value' => array( array( 'name' => 'cbc:StreetName', - 'value' => $this->document->order->get_billing_address_1(), + 'value' => wpo_ips_ubl_sanitize_string( $this->document->order->get_billing_address_1() ), ), array( 'name' => 'cbc:CityName', - 'value' => $this->document->order->get_billing_city(), + 'value' => wpo_ips_ubl_sanitize_string( $this->document->order->get_billing_city() ), ), array( 'name' => 'cbc:PostalZone', @@ -222,7 +222,7 @@ public function return_customer_party( $data, $options = array() ) { 'name' => 'cac:AddressLine', 'value' => array( 'name' => 'cbc:Line', - 'value' => $this->document->order->get_billing_address_1() . '
' . $this->document->order->get_billing_address_2(), + 'value' => wpo_ips_ubl_sanitize_string( $this->document->order->get_billing_address_1() . ' ' . $this->document->order->get_billing_address_2() ), ), ), array( @@ -265,7 +265,7 @@ public function return_customer_party( $data, $options = array() ) { 'value' => array( array( 'name' => 'cbc:Name', - 'value' => $customerPartyContactName, + 'value' => wpo_ips_ubl_sanitize_string( $customerPartyContactName ), ), array( 'name' => 'cbc:ElectronicMail', diff --git a/ubl/Handlers/Invoice/InvoiceLineHandler.php b/ubl/Handlers/Invoice/InvoiceLineHandler.php index 4e03a7f4a..f199832b6 100644 --- a/ubl/Handlers/Invoice/InvoiceLineHandler.php +++ b/ubl/Handlers/Invoice/InvoiceLineHandler.php @@ -136,7 +136,7 @@ public function handle( $data, $options = array() ) { 'value' => array( array( 'name' => 'cbc:Name', - 'value' => $item->get_name(), + 'value' => wpo_ips_ubl_sanitize_string( $item->get_name() ), ), ), ), diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index e02a9de62..33321ca1c 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -145,6 +145,7 @@ public function includes() { // plugin functions include_once $this->plugin_path() . '/wpo-ips-functions.php'; + include_once $this->plugin_path() . '/wpo-ips-functions-ubl.php'; // Third party compatibility $this->third_party_plugins = \WPO\IPS\Compatibility\ThirdPartyPlugins::instance(); diff --git a/wpo-ips-functions-ubl.php b/wpo-ips-functions-ubl.php new file mode 100644 index 000000000..def68fe8e --- /dev/null +++ b/wpo-ips-functions-ubl.php @@ -0,0 +1,23 @@ + Date: Thu, 2 Jan 2025 11:58:41 +0000 Subject: [PATCH 50/69] v3.9.5-beta-2 --- readme.txt | 2 +- woocommerce-pdf-invoices-packingslips.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.txt b/readme.txt index 366570821..4ec347ff3 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 Requires PHP: 7.4 -Stable tag: 3.9.5-beta-1 +Stable tag: 3.9.5-beta-2 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index 33321ca1c..01105cc2e 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,7 +4,7 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.5-beta-1 + * Version: 3.9.5-beta-2 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.5-beta-1'; + public $version = '3.9.5-beta-2'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; From 0944cae27ec2b9c6faa573d9d040b921b5efad6d Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Thu, 2 Jan 2025 12:21:27 +0000 Subject: [PATCH 51/69] New: add `` element to UBL for buyer reference #970 --- ubl/Documents/UblDocument.php | 4 ++++ ubl/Handlers/Common/BuyerReferenceHandler.php | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 ubl/Handlers/Common/BuyerReferenceHandler.php diff --git a/ubl/Documents/UblDocument.php b/ubl/Documents/UblDocument.php index 17d2d67f0..24fe267c6 100644 --- a/ubl/Documents/UblDocument.php +++ b/ubl/Documents/UblDocument.php @@ -36,6 +36,10 @@ public function get_format() { 'enabled' => true, 'handler' => \WPO\IPS\UBL\Handlers\Common\DocumentCurrencyCodeHandler::class, ), + 'buyerreference' => array( + 'enabled' => false, + 'handler' => \WPO\IPS\UBL\Handlers\Common\BuyerReferenceHandler::class, + ), 'orderreference' => array( 'enabled' => true, 'handler' => \WPO\IPS\UBL\Handlers\Common\OrderReferenceHandler::class, diff --git a/ubl/Handlers/Common/BuyerReferenceHandler.php b/ubl/Handlers/Common/BuyerReferenceHandler.php new file mode 100644 index 000000000..aab26aa97 --- /dev/null +++ b/ubl/Handlers/Common/BuyerReferenceHandler.php @@ -0,0 +1,24 @@ + 'cbc:BuyerReference', + 'value' => $this->document->order->get_id(), + ); + + $data[] = apply_filters( 'wpo_wc_ubl_handle_BuyerReference', $buyerReference, $data, $options, $this ); + + return $data; + } + +} From e1fc14bb8db33e3f70505a8870e6d6cdd9654732 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Thu, 2 Jan 2025 12:22:02 +0000 Subject: [PATCH 52/69] Revert "New: add `` element to UBL for buyer reference" This reverts commit 0944cae27ec2b9c6faa573d9d040b921b5efad6d. --- ubl/Documents/UblDocument.php | 4 ---- ubl/Handlers/Common/BuyerReferenceHandler.php | 24 ------------------- 2 files changed, 28 deletions(-) delete mode 100644 ubl/Handlers/Common/BuyerReferenceHandler.php diff --git a/ubl/Documents/UblDocument.php b/ubl/Documents/UblDocument.php index 24fe267c6..17d2d67f0 100644 --- a/ubl/Documents/UblDocument.php +++ b/ubl/Documents/UblDocument.php @@ -36,10 +36,6 @@ public function get_format() { 'enabled' => true, 'handler' => \WPO\IPS\UBL\Handlers\Common\DocumentCurrencyCodeHandler::class, ), - 'buyerreference' => array( - 'enabled' => false, - 'handler' => \WPO\IPS\UBL\Handlers\Common\BuyerReferenceHandler::class, - ), 'orderreference' => array( 'enabled' => true, 'handler' => \WPO\IPS\UBL\Handlers\Common\OrderReferenceHandler::class, diff --git a/ubl/Handlers/Common/BuyerReferenceHandler.php b/ubl/Handlers/Common/BuyerReferenceHandler.php deleted file mode 100644 index aab26aa97..000000000 --- a/ubl/Handlers/Common/BuyerReferenceHandler.php +++ /dev/null @@ -1,24 +0,0 @@ - 'cbc:BuyerReference', - 'value' => $this->document->order->get_id(), - ); - - $data[] = apply_filters( 'wpo_wc_ubl_handle_BuyerReference', $buyerReference, $data, $options, $this ); - - return $data; - } - -} From 97dedb7682ba884ed2e1f3981e0428b7be0798d5 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Thu, 2 Jan 2025 13:43:25 +0000 Subject: [PATCH 53/69] New: add `` element to UBL for buyer reference (#971) --- ubl/Documents/UblDocument.php | 4 ++++ ubl/Handlers/Common/BuyerReferenceHandler.php | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 ubl/Handlers/Common/BuyerReferenceHandler.php diff --git a/ubl/Documents/UblDocument.php b/ubl/Documents/UblDocument.php index 17d2d67f0..24fe267c6 100644 --- a/ubl/Documents/UblDocument.php +++ b/ubl/Documents/UblDocument.php @@ -36,6 +36,10 @@ public function get_format() { 'enabled' => true, 'handler' => \WPO\IPS\UBL\Handlers\Common\DocumentCurrencyCodeHandler::class, ), + 'buyerreference' => array( + 'enabled' => false, + 'handler' => \WPO\IPS\UBL\Handlers\Common\BuyerReferenceHandler::class, + ), 'orderreference' => array( 'enabled' => true, 'handler' => \WPO\IPS\UBL\Handlers\Common\OrderReferenceHandler::class, diff --git a/ubl/Handlers/Common/BuyerReferenceHandler.php b/ubl/Handlers/Common/BuyerReferenceHandler.php new file mode 100644 index 000000000..aab26aa97 --- /dev/null +++ b/ubl/Handlers/Common/BuyerReferenceHandler.php @@ -0,0 +1,24 @@ + 'cbc:BuyerReference', + 'value' => $this->document->order->get_id(), + ); + + $data[] = apply_filters( 'wpo_wc_ubl_handle_BuyerReference', $buyerReference, $data, $options, $this ); + + return $data; + } + +} From 5056a31725af7623a6fa65542089708960cffed4 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Thu, 2 Jan 2025 13:49:59 +0000 Subject: [PATCH 54/69] v3.9.5-beta-3 --- readme.txt | 2 +- woocommerce-pdf-invoices-packingslips.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.txt b/readme.txt index 4ec347ff3..997e5a827 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 Requires PHP: 7.4 -Stable tag: 3.9.5-beta-2 +Stable tag: 3.9.5-beta-3 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index 01105cc2e..d33afd1be 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,7 +4,7 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.5-beta-2 + * Version: 3.9.5-beta-3 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.5-beta-2'; + public $version = '3.9.5-beta-3'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; From e9bb1aafb10a3bb0b144a1da11b97cb8e5f863b8 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 3 Jan 2025 11:02:40 +0000 Subject: [PATCH 55/69] New: add utility function for dynamic string translation (#975) --- wpo-ips-functions.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/wpo-ips-functions.php b/wpo-ips-functions.php index 31cc36a78..7c95e82a4 100644 --- a/wpo-ips-functions.php +++ b/wpo-ips-functions.php @@ -989,3 +989,20 @@ function wpo_wcpdf_get_simple_template_default_table_headers( $document ): array return apply_filters( 'wpo_wcpdf_simple_template_default_table_headers', $headers, $document ); } + +/** + * Dynamic string translation + * + * @param string $string + * @param string $textdomain + * @return string + */ +function wpo_wcpdf_dynamic_translate( string $string, string $textdomain ): string { + if ( ! function_exists( 'translate' ) ) { + return $string; + } + + $translation = translate( $string, $textdomain ); + + return $translation !== $string ? $translation : $string; // Fallback to original if not translated +} From 5cf65d017a055d5e8a930aba04402d1ec18e0472 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 3 Jan 2025 14:23:49 +0000 Subject: [PATCH 56/69] Tweak: improves the dynamic translate function (#978) --- includes/Settings/SettingsDebug.php | 12 ++++++++++++ wpo-ips-functions.php | 27 ++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/includes/Settings/SettingsDebug.php b/includes/Settings/SettingsDebug.php index 0f3b4902e..6d286f030 100644 --- a/includes/Settings/SettingsDebug.php +++ b/includes/Settings/SettingsDebug.php @@ -874,6 +874,18 @@ public function init_settings() { 'description' => __( 'Log PDF document creation, deletion, and mark/unmark as printed to order notes.', 'woocommerce-pdf-invoices-packing-slips' ), ) ), + array( + 'type' => 'setting', + 'id' => 'log_missing_translations', + 'title' => __( 'Log missing translations', 'woocommerce-pdf-invoices-packing-slips' ), + 'callback' => 'checkbox', + 'section' => 'debug_settings', + 'args' => array( + 'option_name' => $option_name, + 'id' => 'log_missing_translations', + 'description' => __( 'Enable this option to log dynamic strings that could not be translated. This can help you identify which strings need to be registered for translation.', 'woocommerce-pdf-invoices-packing-slips' ), + ) + ), array( 'type' => 'setting', 'id' => 'disable_preview', diff --git a/wpo-ips-functions.php b/wpo-ips-functions.php index 7c95e82a4..7a7167cc4 100644 --- a/wpo-ips-functions.php +++ b/wpo-ips-functions.php @@ -998,11 +998,32 @@ function wpo_wcpdf_get_simple_template_default_table_headers( $document ): array * @return string */ function wpo_wcpdf_dynamic_translate( string $string, string $textdomain ): string { - if ( ! function_exists( 'translate' ) ) { + $log_enabled = isset( WPO_WCPDF()->settings->debug_settings['log_missing_translations'] ); + $log_message = "Missing translation for: {$string} in textdomain: {$textdomain}"; + $multilingual_class = '\WPO\WC\PDF_Invoices_Pro\Multilingual_Full'; + $translation = ''; + + if ( empty( $string ) ) { + if ( $log_enabled ) { + wcpdf_log_error( $log_message, 'warning' ); + } return $string; } - $translation = translate( $string, $textdomain ); + // Check for multilingual support class + if ( class_exists( $multilingual_class ) && method_exists( $multilingual_class, 'maybe_get_string_translation' ) ) { + $translation = $multilingual_class::maybe_get_string_translation( $string, $textdomain ); + } + + // If multilingual didn't change the string, fall back to native translate() + if ( ( empty( $translation ) || $translation === $string ) && function_exists( 'translate' ) ) { + $translation = translate( $string, $textdomain ); + } + + // Log missing translations for debugging if it's still untranslated + if ( $translation === $string && $log_enabled ) { + wcpdf_log_error( $log_message, 'warning' ); + } - return $translation !== $string ? $translation : $string; // Fallback to original if not translated + return $translation ?: $string; } From 55d68bf8be0d455d653d245ea4f8166a3409b3f7 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 3 Jan 2025 15:12:34 +0000 Subject: [PATCH 57/69] New: UBL Tax settings now align with the latest settings option (#973) --- includes/Documents/OrderDocument.php | 2 -- includes/Main.php | 1 - ubl/Documents/Document.php | 46 ++++++++++++++++------------ 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/includes/Documents/OrderDocument.php b/includes/Documents/OrderDocument.php index f2dce05c4..743c8cc5b 100644 --- a/includes/Documents/OrderDocument.php +++ b/includes/Documents/OrderDocument.php @@ -1414,8 +1414,6 @@ public function output_ubl( $contents_only = false ) { $ubl_maker = wcpdf_get_ubl_maker(); $ubl_document = new UblDocument(); - $ubl_document->set_order( $this->order ); - $document = $contents_only ? $this : wcpdf_get_document( $this->get_type(), $this->order, true ); if ( $document ) { diff --git a/includes/Main.php b/includes/Main.php index 3d689b7ec..d2c56c3d5 100644 --- a/includes/Main.php +++ b/includes/Main.php @@ -256,7 +256,6 @@ public function get_document_ubl_attachment( $document, $tmp_path ) { $ubl_maker->set_file_path( $tmp_path ); $ubl_document = new UblDocument(); - $ubl_document->set_order( $document->order ); $ubl_document->set_order_document( $document ); $builder = new SabreBuilder(); diff --git a/ubl/Documents/Document.php b/ubl/Documents/Document.php index 66b7895f1..27f2ed7cf 100644 --- a/ubl/Documents/Document.php +++ b/ubl/Documents/Document.php @@ -29,6 +29,7 @@ public function set_order( \WC_Abstract_Order $order ) { public function set_order_document( OrderDocument $order_document ) { $this->order_document = $order_document; + $this->set_order( $order_document->order ); } abstract public function get_root_element(); @@ -69,9 +70,16 @@ public function get_tax_rates() { if ( empty( $tax_items ) ) { return $order_tax_data; } + + $use_historical_settings = $this->order_document->use_historical_settings(); // Loop through all the tax items... foreach ( $order_tax_data as $tax_data_key => $tax_data ) { + $percentage = 0; + $category = ''; + $scheme = ''; + $reason = ''; + foreach ( $tax_items as $tax_item_key => $tax_item ) { if ( $tax_item['rate_id'] !== $tax_data_key ) { continue; @@ -81,38 +89,38 @@ public function get_tax_rates() { // takes into account possible line item rounding settings as well // we still apply rounding on the total (for non-checkout orders) $order_tax_data[ $tax_data_key ]['total_tax'] = wc_round_tax_total( $tax_item['tax_amount'] ) + wc_round_tax_total( $tax_item['shipping_tax_amount'] ); - $rate_id = absint( $tax_item['rate_id'] ); if ( is_callable( array( $tax_item, 'get_rate_percent' ) ) && version_compare( '3.7.0', $this->order->get_version(), '>=' ) ) { $percentage = $tax_item->get_rate_percent(); } else { $percentage = wc_get_order_item_meta( $tax_item_key, '_wcpdf_rate_percentage', true ); } + + $rate_id = absint( $tax_item['rate_id'] ); if ( ! is_numeric( $percentage ) ) { $percentage = $this->get_percentage_from_fallback( $tax_data, $rate_id ); wc_update_order_item_meta( $tax_item_key, '_wcpdf_rate_percentage', $percentage ); } - $category = wc_get_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_category', true ); - - if ( empty( $category ) ) { - $category = $this->get_tax_data_from_fallback( 'category', $rate_id ); - wc_update_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_category', $category ); - } - - $scheme = wc_get_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_scheme', true ); - - if ( empty( $scheme ) ) { - $scheme = $this->get_tax_data_from_fallback( 'scheme', $rate_id ); - wc_update_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_scheme', $scheme ); - } + $fields = array( + 'category' => '_wcpdf_ubl_tax_category', + 'scheme' => '_wcpdf_ubl_tax_scheme', + 'reason' => '_wcpdf_ubl_tax_reason', + ); - $reason = wc_get_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_reason', true ); - - if ( empty( $reason ) ) { - $reason = $this->get_tax_data_from_fallback( 'reason', $rate_id ); - wc_update_order_item_meta( $tax_item_key, '_wcpdf_ubl_tax_reason', $reason ); + foreach ( $fields as $key => $meta_key ) { + $value = wc_get_order_item_meta( $tax_item_key, $meta_key, true ); + + if ( empty( $value ) || ! $use_historical_settings ) { + $value = $this->get_tax_data_from_fallback( $key, $rate_id ); + } + + if ( $use_historical_settings ) { + wc_update_order_item_meta( $tax_item_key, $meta_key, $value ); + } + + ${$key} = $value; } } From b572422a300b0dabacefcbb86dd4819923f9bef6 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 3 Jan 2025 16:17:54 +0000 Subject: [PATCH 58/69] Tweak: apply `wpo_wcpdf_dynamic_translate()` to dynamically translated strings (#982) --- includes/Documents/OrderDocumentMethods.php | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/includes/Documents/OrderDocumentMethods.php b/includes/Documents/OrderDocumentMethods.php index eddc6aff8..eadc46888 100644 --- a/includes/Documents/OrderDocumentMethods.php +++ b/includes/Documents/OrderDocumentMethods.php @@ -478,7 +478,7 @@ public function get_payment_method() { $payment_method_title = $this->order->get_payment_method_title(); } - $payment_method = __( $payment_method_title, 'woocommerce' ); + $payment_method = wpo_wcpdf_dynamic_translate( $payment_method_title, 'woocommerce' ); return apply_filters( 'wpo_wcpdf_payment_method', $payment_method, $this ); } @@ -509,7 +509,7 @@ public function payment_date() { * Return/Show shipping method */ public function get_shipping_method() { - $shipping_method = __( $this->order->get_shipping_method(), 'woocommerce' ); + $shipping_method = wpo_wcpdf_dynamic_translate( $this->order->get_shipping_method(), 'woocommerce' ); return apply_filters( 'wpo_wcpdf_shipping_method', $shipping_method, $this ); } public function shipping_method() { @@ -921,14 +921,8 @@ public function get_woocommerce_totals() { $label = substr_replace( $label, '', $colon, 1 ); } - $textdomain = 'woocommerce-pdf-invoices-packing-slips'; - if ( ! empty( $label ) ) { - if ( function_exists( 'WPO_WCPDF_Pro' ) && isset( \WPO_WCPDF_Pro()->multilingual_full ) && is_callable( array( \WPO_WCPDF_Pro()->multilingual_full, 'maybe_get_string_translation' ) ) ) { - $totals[ $key ]['label'] = \WPO_WCPDF_Pro()->multilingual_full->maybe_get_string_translation( $label, $textdomain ); - } else { - $totals[ $key ]['label'] = __( $label, $textdomain ); - } + $totals[ $key ]['label'] = wpo_wcpdf_dynamic_translate( $label, 'woocommerce-pdf-invoices-packing-slips' ); } } From a4e1c976c761ebb2a2e66b58774d38969ad185b8 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Fri, 3 Jan 2025 16:46:21 +0000 Subject: [PATCH 59/69] Fix: migrate UBL Tax Scheme settings (#980) --- includes/Install.php | 15 +++++++++++++++ readme.txt | 2 +- woocommerce-pdf-invoices-packingslips.php | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/includes/Install.php b/includes/Install.php index 2585c625e..b63646a7f 100644 --- a/includes/Install.php +++ b/includes/Install.php @@ -531,6 +531,21 @@ protected function upgrade( $installed_version ) { set_transient( 'wpo_wcpdf_flush_rewrite_rules', 'yes', HOUR_IN_SECONDS ); } } + + // 3.9.5-beta-4: migrate UBL tax schemes/categories + if ( version_compare( $installed_version, '3.9.5-beta-4', '<' ) ) { + $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes', array() ); + + if ( ! empty( $ubl_tax_settings ) ) { + array_walk_recursive( $ubl_tax_settings, function ( &$value, $key ) { + if ( in_array( $key, array( 'scheme', 'category' ) ) && ! empty( $value ) ) { + $value = strtoupper( $value ); + } + } ); + + update_option( 'wpo_wcpdf_settings_ubl_taxes', $ubl_tax_settings ); + } + } } diff --git a/readme.txt b/readme.txt index 997e5a827..0ceafd3f4 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 Requires PHP: 7.4 -Stable tag: 3.9.5-beta-3 +Stable tag: 3.9.5-beta-4 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index d33afd1be..4673dad31 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,7 +4,7 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.5-beta-3 + * Version: 3.9.5-beta-4 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.5-beta-3'; + public $version = '3.9.5-beta-4'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; From 9b5c0bd6f4381bb4c9a7f3b236f50786a2dd5c47 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Mon, 6 Jan 2025 09:01:02 +0000 Subject: [PATCH 60/69] New: add `cbc:BaseQuantity` support to UBL structure (#985) --- ubl/Handlers/Invoice/InvoiceLineHandler.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ubl/Handlers/Invoice/InvoiceLineHandler.php b/ubl/Handlers/Invoice/InvoiceLineHandler.php index f199832b6..40ff8232e 100644 --- a/ubl/Handlers/Invoice/InvoiceLineHandler.php +++ b/ubl/Handlers/Invoice/InvoiceLineHandler.php @@ -150,6 +150,13 @@ public function handle( $data, $options = array() ) { 'currencyID' => $this->document->order->get_currency(), ), ), + array( + 'name' => 'cbc:BaseQuantity', + 'value' => 1, // value should be 1, as we're using the unit price + 'attributes' => array( + 'unitCode' => 'EA', // EA = Each (https://docs.peppol.eu/pracc/catalogue/1.0/codelist/UNECERec20/) + ), + ), ), ), ), From 913b197a0f92293559056b3533d201005674032d Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Mon, 6 Jan 2025 15:30:18 +0000 Subject: [PATCH 61/69] Tweak: removes standard default selector for UBL Tax Reason (#987) --- ubl/Documents/Document.php | 2 +- ubl/Settings/TaxesSettings.php | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ubl/Documents/Document.php b/ubl/Documents/Document.php index 27f2ed7cf..6a265ae6a 100644 --- a/ubl/Documents/Document.php +++ b/ubl/Documents/Document.php @@ -183,7 +183,7 @@ public function get_tax_data_from_fallback( string $key, int $rate_id ): string $tax_rate = \WC_Tax::_get_tax_rate( $rate_id, OBJECT ); if ( ! empty( $tax_rate ) && is_numeric( $tax_rate->tax_rate ) ) { - $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes' ); + $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes', array() ); $result = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ][ $key ] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ][ $key ] : ''; $tax_rate_class = $tax_rate->tax_rate_class; diff --git a/ubl/Settings/TaxesSettings.php b/ubl/Settings/TaxesSettings.php index 30164d4f9..b87268b84 100644 --- a/ubl/Settings/TaxesSettings.php +++ b/ubl/Settings/TaxesSettings.php @@ -109,11 +109,10 @@ public function output_table_for_tax_class( $slug, $name ) { settings['class'][ $slug ]['scheme'] ) ? $this->settings['class'][ $slug ]['scheme'] : ''; $category = isset( $this->settings['class'][ $slug ]['category'] ) ? $this->settings['class'][ $slug ]['category'] : ''; - $reason = isset( $this->settings['class'][ $slug ]['reason'] ) ? $this->settings['class'][ $slug ]['reason'] : ''; ?> get_select_for( 'scheme', 'class', $slug, $scheme ); ?> get_select_for( 'category', 'class', $slug, $category ); ?> - get_select_for( 'reason', 'class', $slug, $reason ); ?> + @@ -131,6 +130,8 @@ public function output_table_for_tax_class( $slug, $name ) { * @return string */ public function get_select_for( string $for, string $type, string $id, string $selected ): string { + $default_name = ( 'reason' !== $for ) ? __( 'Default', 'woocommerce-pdf-invoices-packing-slips' ) : __( 'None', 'woocommerce-pdf-invoices-packing-slips' ); + switch ( $for ) { case 'scheme': $options = $this->get_available_schemes(); @@ -145,11 +146,12 @@ public function get_select_for( string $for, string $type, string $id, string $s $options = array(); } - $select = ''; foreach ( $options as $key => $value ) { $select .= ''; } $select .= ''; + return $select; } From a1feb761e7ba0223afc7e0e99028cfdf8eb90f2e Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Mon, 6 Jan 2025 15:31:38 +0000 Subject: [PATCH 62/69] v3.9.5-beta-5 --- readme.txt | 2 +- woocommerce-pdf-invoices-packingslips.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.txt b/readme.txt index 0ceafd3f4..8a29bc649 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ Tags: woocommerce, pdf, ubl, invoices, packing slips Requires at least: 4.4 Tested up to: 6.7 Requires PHP: 7.4 -Stable tag: 3.9.5-beta-4 +Stable tag: 3.9.5-beta-5 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html diff --git a/woocommerce-pdf-invoices-packingslips.php b/woocommerce-pdf-invoices-packingslips.php index 4673dad31..603d14afa 100644 --- a/woocommerce-pdf-invoices-packingslips.php +++ b/woocommerce-pdf-invoices-packingslips.php @@ -4,7 +4,7 @@ * Requires Plugins: woocommerce * Plugin URI: https://wpovernight.com/downloads/woocommerce-pdf-invoices-packing-slips-bundle/ * Description: Create, print & email PDF or UBL Invoices & PDF Packing Slips for WooCommerce orders. - * Version: 3.9.5-beta-4 + * Version: 3.9.5-beta-5 * Author: WP Overnight * Author URI: https://www.wpovernight.com * License: GPLv2 or later @@ -22,7 +22,7 @@ class WPO_WCPDF { - public $version = '3.9.5-beta-4'; + public $version = '3.9.5-beta-5'; public $version_php = '7.4'; public $version_woo = '3.3'; public $version_wp = '4.4'; From 966f8e5ca05665addd2c58592401c3a44c88ad0f Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Tue, 7 Jan 2025 11:58:48 +0000 Subject: [PATCH 63/69] Tweaks: enhance UBL Taxes default selector, 'None' Option, and Regeneration (#989) --- includes/Documents/OrderDocument.php | 42 ++++++++---- includes/Settings/SettingsUbl.php | 58 +--------------- ubl/Documents/Document.php | 56 +++------------- ubl/Handlers/Common/TaxTotalHandler.php | 2 +- ubl/Handlers/Invoice/InvoiceLineHandler.php | 2 +- ubl/Settings/TaxesSettings.php | 32 ++++++--- wpo-ips-functions-ubl.php | 73 +++++++++++++++++++++ 7 files changed, 139 insertions(+), 126 deletions(-) diff --git a/includes/Documents/OrderDocument.php b/includes/Documents/OrderDocument.php index 743c8cc5b..8a339b574 100644 --- a/includes/Documents/OrderDocument.php +++ b/includes/Documents/OrderDocument.php @@ -459,30 +459,48 @@ public function delete( $order = null ) { } public function regenerate( $order = null, $data = null ) { - $order = empty( $order ) ? $this->order : $order; + $order = empty( $order ) ? $this->order : $order; + $refund_id = false; + if ( empty( $order ) ) { - return; //Nothing to update + return; } // pass data to setter functions - if( ! empty( $data ) ) { + if ( ! empty( $data ) ) { $this->set_data( $data, $order ); $this->save(); } // save settings $this->save_settings( true ); - - //Add order note - $parent_order = $refund_id = false; - // If credit note - if ( $this->get_type() == 'credit-note' ) { + + // if credit note + if ( 'credit-note' === $this->get_type() ) { $refund_id = $order->get_id(); - $parent_order = wc_get_order( $order->get_parent_id() ); - } /*translators: 1. credit note title, 2. refund id */ - $note = $refund_id ? sprintf( __( '%1$s (refund #%2$s) was regenerated.', 'woocommerce-pdf-invoices-packing-slips' ), ucfirst( $this->get_title() ), $refund_id ) : sprintf( __( '%s was regenerated', 'woocommerce-pdf-invoices-packing-slips' ), ucfirst( $this->get_title() ) ); + $order = wc_get_order( $order->get_parent_id() ); + } + + // ubl + if ( $document->is_enabled( 'ubl' ) && wcpdf_is_ubl_available() ) { + wpo_ips_ubl_save_order_taxes( $order ); + } + + $note = $refund_id ? sprintf( + /* translators: 1. credit note title, 2. refund id */ + __( '%1$s (refund #%2$s) was regenerated.', 'woocommerce-pdf-invoices-packing-slips' ), + ucfirst( $this->get_title() ), + $refund_id + ) : sprintf( + /* translators: 1. document title */ + __( '%s was regenerated', 'woocommerce-pdf-invoices-packing-slips' ), + ucfirst( $this->get_title() ) + ); + $note = wp_kses( $note, 'strip' ); - $parent_order ? $parent_order->add_order_note( $note ) : $order->add_order_note( $note ); + + // add note to order + $order->add_order_note( $note ); do_action( 'wpo_wcpdf_regenerate_document', $this ); } diff --git a/includes/Settings/SettingsUbl.php b/includes/Settings/SettingsUbl.php index 156783e6c..8f2507bf8 100644 --- a/includes/Settings/SettingsUbl.php +++ b/includes/Settings/SettingsUbl.php @@ -86,7 +86,7 @@ public function save_taxes_on_order_totals( $and_taxes, $order ) { // it seems $and taxes is mostly false, meaning taxes are calculated separately, // but we still update just in case anything changed if ( ! empty( $order ) ) { - $this->save_order_taxes( $order ); + wpo_ips_ubl_save_order_taxes( $order ); } } @@ -96,61 +96,7 @@ public function save_taxes_on_checkout( $order_id, $posted_data, $order ) { } if ( $order ) { - $this->save_order_taxes( $order ); - } - } - - public function save_order_taxes( $order ) { - foreach ( $order->get_taxes() as $item_id => $tax_item ) { - if ( is_a( $tax_item, '\WC_Order_Item_Tax' ) && is_callable( array( $tax_item, 'get_rate_id' ) ) ) { - // get tax rate id from item - $tax_rate_id = $tax_item->get_rate_id(); - - // read tax rate data from db - if ( class_exists( '\WC_TAX' ) && is_callable( array( '\WC_TAX', '_get_tax_rate' ) ) ) { - $tax_rate = \WC_Tax::_get_tax_rate( $tax_rate_id, OBJECT ); - - if ( ! empty( $tax_rate ) && is_numeric( $tax_rate->tax_rate ) ) { - // store percentage in tax item meta - wc_update_order_item_meta( $item_id, '_wcpdf_rate_percentage', $tax_rate->tax_rate ); - - $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes' ); - - $category = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['category'] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['category'] : ''; - $scheme = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['scheme'] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['scheme'] : ''; - $reason = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['reason'] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ]['reason'] : ''; - $tax_rate_class = $tax_rate->tax_rate_class; - - if ( empty( $tax_rate_class ) ) { - $tax_rate_class = 'standard'; - } - - if ( empty( $category ) ) { - $category = isset( $ubl_tax_settings['class'][ $tax_rate_class ]['category'] ) ? $ubl_tax_settings['class'][ $tax_rate_class ]['category'] : ''; - } - - if ( empty( $scheme ) ) { - $scheme = isset( $ubl_tax_settings['class'][ $tax_rate_class ]['scheme'] ) ? $ubl_tax_settings['class'][ $tax_rate_class ]['scheme'] : ''; - } - - if ( empty( $reason ) ) { - $reason = isset( $ubl_tax_settings['class'][ $tax_rate_class ]['reason'] ) ? $ubl_tax_settings['class'][ $tax_rate_class ]['reason'] : ''; - } - - if ( ! empty( $category ) ) { - wc_update_order_item_meta( $item_id, '_wcpdf_ubl_tax_category', $category ); - } - - if ( ! empty( $scheme ) ) { - wc_update_order_item_meta( $item_id, '_wcpdf_ubl_tax_scheme', $scheme ); - } - - if ( ! empty( $reason ) ) { - wc_update_order_item_meta( $item_id, '_wcpdf_ubl_tax_reason', $reason ); - } - } - } - } + wpo_ips_ubl_save_order_taxes( $order ); } } diff --git a/ubl/Documents/Document.php b/ubl/Documents/Document.php index 6a265ae6a..68626f8cb 100644 --- a/ubl/Documents/Document.php +++ b/ubl/Documents/Document.php @@ -96,31 +96,28 @@ public function get_tax_rates() { $percentage = wc_get_order_item_meta( $tax_item_key, '_wcpdf_rate_percentage', true ); } - $rate_id = absint( $tax_item['rate_id'] ); + $tax_rate_id = absint( $tax_item['rate_id'] ); if ( ! is_numeric( $percentage ) ) { - $percentage = $this->get_percentage_from_fallback( $tax_data, $rate_id ); + $percentage = $this->get_percentage_from_fallback( $tax_data, $tax_rate_id ); wc_update_order_item_meta( $tax_item_key, '_wcpdf_rate_percentage', $percentage ); } - $fields = array( - 'category' => '_wcpdf_ubl_tax_category', - 'scheme' => '_wcpdf_ubl_tax_scheme', - 'reason' => '_wcpdf_ubl_tax_reason', - ); + $fields = array( 'category', 'scheme', 'reason' ); - foreach ( $fields as $key => $meta_key ) { - $value = wc_get_order_item_meta( $tax_item_key, $meta_key, true ); + foreach ( $fields as $field ) { + $meta_key = '_wcpdf_ubl_tax_' . $field; + $value = wc_get_order_item_meta( $tax_item_key, $meta_key, true ); - if ( empty( $value ) || ! $use_historical_settings ) { - $value = $this->get_tax_data_from_fallback( $key, $rate_id ); + if ( empty( $value ) || 'default' === $value || ! $use_historical_settings ) { + $value = wpo_ips_ubl_get_tax_data_from_fallback( $field, $tax_rate_id ); } if ( $use_historical_settings ) { wc_update_order_item_meta( $tax_item_key, $meta_key, $value ); } - ${$key} = $value; + ${$field} = $value; } } @@ -163,41 +160,6 @@ public function get_percentage_from_fallback( array $tax_data, int $rate_id ) { } return $percentage; - } - - /** - * Get tax data from fallback - * - * @param string $key Can be category, scheme, or reason - * @param int $rate_id The tax rate ID - * @return string - */ - public function get_tax_data_from_fallback( string $key, int $rate_id ): string { - $result = ''; - - if ( ! in_array( $key, array( 'category', 'scheme', 'reason' ) ) ) { - return $result; - } - - if ( class_exists( '\WC_TAX' ) && is_callable( array( '\WC_TAX', '_get_tax_rate' ) ) ) { - $tax_rate = \WC_Tax::_get_tax_rate( $rate_id, OBJECT ); - - if ( ! empty( $tax_rate ) && is_numeric( $tax_rate->tax_rate ) ) { - $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes', array() ); - $result = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ][ $key ] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ][ $key ] : ''; - $tax_rate_class = $tax_rate->tax_rate_class; - - if ( empty( $tax_rate_class ) ) { - $tax_rate_class = 'standard'; - } - - if ( empty( $result ) ) { - $result = isset( $ubl_tax_settings['class'][ $tax_rate_class ][ $key ] ) ? $ubl_tax_settings['class'][ $tax_rate_class ][ $key ] : ''; - } - } - } - - return $result; } } diff --git a/ubl/Handlers/Common/TaxTotalHandler.php b/ubl/Handlers/Common/TaxTotalHandler.php index 8bfa43046..5ea225ff6 100644 --- a/ubl/Handlers/Common/TaxTotalHandler.php +++ b/ubl/Handlers/Common/TaxTotalHandler.php @@ -31,7 +31,7 @@ public function handle( $data, $options = array() ) { ); // Add TaxExemptionReason only if it's not empty - if ( ! empty( $item['reason'] ) ) { + if ( ! empty( $item['reason'] ) && 'none' !== $item['reason'] ) { $reasonKey = $item['reason']; $reason = ! empty( $taxReasons[ $reasonKey ] ) ? $taxReasons[ $reasonKey ] : $reasonKey; $taxCategory[] = array( diff --git a/ubl/Handlers/Invoice/InvoiceLineHandler.php b/ubl/Handlers/Invoice/InvoiceLineHandler.php index 40ff8232e..a254c6ade 100644 --- a/ubl/Handlers/Invoice/InvoiceLineHandler.php +++ b/ubl/Handlers/Invoice/InvoiceLineHandler.php @@ -51,7 +51,7 @@ public function handle( $data, $options = array() ) { ); // Add TaxExemptionReason only if it's not empty - if ( ! empty( $taxOrderData['reason'] ) ) { + if ( ! empty( $taxOrderData['reason'] ) && 'none' !== $taxOrderData['reason'] ) { $reasonKey = $taxOrderData['reason']; $reason = ! empty( $taxReasons[ $reasonKey ] ) ? $taxReasons[ $reasonKey ] : $reasonKey; $taxCategory[] = array( diff --git a/ubl/Settings/TaxesSettings.php b/ubl/Settings/TaxesSettings.php index b87268b84..08675f7f7 100644 --- a/ubl/Settings/TaxesSettings.php +++ b/ubl/Settings/TaxesSettings.php @@ -83,9 +83,9 @@ public function output_table_for_tax_class( $slug, $name ) { $state = empty( $result->tax_rate_state ) ? '*' : $result->tax_rate_state; $postcode = empty( $postcode ) ? '*' : implode( '; ', $postcode ); $city = empty( $city ) ? '*' : implode( '; ', $city ); - $scheme = isset( $this->settings['rate'][ $result->tax_rate_id ]['scheme'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['scheme'] : ''; - $category = isset( $this->settings['rate'][ $result->tax_rate_id ]['category'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['category'] : ''; - $reason = isset( $this->settings['rate'][ $result->tax_rate_id ]['reason'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['reason'] : ''; + $scheme = isset( $this->settings['rate'][ $result->tax_rate_id ]['scheme'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['scheme'] : 'default'; + $category = isset( $this->settings['rate'][ $result->tax_rate_id ]['category'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['category'] : 'default'; + $reason = isset( $this->settings['rate'][ $result->tax_rate_id ]['reason'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['reason'] : 'default'; echo ''; echo '' . $country . ''; @@ -107,12 +107,13 @@ public function output_table_for_tax_class( $slug, $name ) { : settings['class'][ $slug ]['scheme'] ) ? $this->settings['class'][ $slug ]['scheme'] : ''; - $category = isset( $this->settings['class'][ $slug ]['category'] ) ? $this->settings['class'][ $slug ]['category'] : ''; + $scheme = isset( $this->settings['class'][ $slug ]['scheme'] ) ? $this->settings['class'][ $slug ]['scheme'] : 'default'; + $category = isset( $this->settings['class'][ $slug ]['category'] ) ? $this->settings['class'][ $slug ]['category'] : 'default'; + $reason = isset( $this->settings['class'][ $slug ]['reason'] ) ? $this->settings['class'][ $slug ]['reason'] : 'default'; ?> get_select_for( 'scheme', 'class', $slug, $scheme ); ?> get_select_for( 'category', 'class', $slug, $category ); ?> - + get_select_for( 'reason', 'class', $slug, $reason ); ?> @@ -130,7 +131,9 @@ public function output_table_for_tax_class( $slug, $name ) { * @return string */ public function get_select_for( string $for, string $type, string $id, string $selected ): string { - $default_name = ( 'reason' !== $for ) ? __( 'Default', 'woocommerce-pdf-invoices-packing-slips' ) : __( 'None', 'woocommerce-pdf-invoices-packing-slips' ); + $defaults = array( + 'default' => __( 'Default', 'woocommerce-pdf-invoices-packing-slips' ), + ); switch ( $for ) { case 'scheme': @@ -140,16 +143,27 @@ public function get_select_for( string $for, string $type, string $id, string $s $options = $this->get_available_categories(); break; case 'reason': - $options = self::get_available_reasons(); + $defaults['none'] = __( 'None', 'woocommerce-pdf-invoices-packing-slips' ); + $options = self::get_available_reasons(); break; default: $options = array(); } - $select = ''; + + foreach ( $defaults as $key => $value ) { + if ( 'class' === $type && 'default' === $key ) { + continue; + } + + $select .= ''; + } + foreach ( $options as $key => $value ) { $select .= ''; } + $select .= ''; return $select; diff --git a/wpo-ips-functions-ubl.php b/wpo-ips-functions-ubl.php index def68fe8e..bee428f83 100644 --- a/wpo-ips-functions-ubl.php +++ b/wpo-ips-functions-ubl.php @@ -21,3 +21,76 @@ function wpo_ips_ubl_sanitize_string( string $string ): string { $string = wp_strip_all_tags( $string ); return htmlspecialchars_decode( $string, ENT_QUOTES ); } + +/** + * Get UBL tax data from fallback + * + * @param string $key Can be category, scheme, or reason + * @param int $rate_id The tax rate ID + * @return string + */ +function wpo_ips_ubl_get_tax_data_from_fallback( string $key, int $rate_id ): string { + $result = ''; + + if ( ! in_array( $key, array( 'category', 'scheme', 'reason' ) ) ) { + return $result; + } + + if ( class_exists( '\WC_TAX' ) && is_callable( array( '\WC_TAX', '_get_tax_rate' ) ) ) { + $tax_rate = \WC_Tax::_get_tax_rate( $rate_id, OBJECT ); + + if ( ! empty( $tax_rate ) && is_numeric( $tax_rate->tax_rate ) ) { + $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes', array() ); + $result = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ][ $key ] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ][ $key ] : ''; + $tax_rate_class = $tax_rate->tax_rate_class; + + if ( empty( $tax_rate_class ) ) { + $tax_rate_class = 'standard'; + } + + if ( empty( $result ) || 'default' === $result ) { + $result = isset( $ubl_tax_settings['class'][ $tax_rate_class ][ $key ] ) ? $ubl_tax_settings['class'][ $tax_rate_class ][ $key ] : ''; + } + } + } + + return $result; +} + +/** + * Save UBL order taxes + * + * @param \WC_Abstract_Order $order + * @return void + */ +function wpo_ips_ubl_save_order_taxes( \WC_Abstract_Order $order ): void { + foreach ( $order->get_taxes() as $item_id => $tax_item ) { + if ( is_a( $tax_item, '\WC_Order_Item_Tax' ) && is_callable( array( $tax_item, 'get_rate_id' ) ) ) { + // get tax rate id from item + $tax_rate_id = $tax_item->get_rate_id(); + + // read tax rate data from db + if ( class_exists( '\WC_TAX' ) && is_callable( array( '\WC_TAX', '_get_tax_rate' ) ) ) { + $tax_rate = \WC_Tax::_get_tax_rate( $tax_rate_id, OBJECT ); + + if ( ! empty( $tax_rate ) && is_numeric( $tax_rate->tax_rate ) ) { + // store percentage in tax item meta + wc_update_order_item_meta( $item_id, '_wcpdf_rate_percentage', $tax_rate->tax_rate ); + + $ubl_tax_settings = get_option( 'wpo_wcpdf_settings_ubl_taxes', array() ); + $tax_fields = array( 'category', 'scheme', 'reason' ); + + foreach ( $tax_fields as $field ) { + $value = isset( $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ][ $field ] ) ? $ubl_tax_settings['rate'][ $tax_rate->tax_rate_id ][ $field ] : ''; + + if ( empty( $value ) || 'default' === $value ) { + $value = wpo_ips_ubl_get_tax_data_from_fallback( $field, $tax_rate_id ); + } + + wc_update_order_item_meta( $item_id, '_wcpdf_ubl_tax_' . $field, $value ); + } + } + } + } + } +} \ No newline at end of file From ad0c72ccb26b6b75e96c9621dd714c14fe177cc6 Mon Sep 17 00:00:00 2001 From: Mohamad <136313810+MohamadNateqi@users.noreply.github.com> Date: Wed, 8 Jan 2025 12:11:39 +0330 Subject: [PATCH 64/69] Fix: setting categories not applied to disabled documents (#993) --- includes/Settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/Settings.php b/includes/Settings.php index 5b4f834b3..ed783d9e4 100644 --- a/includes/Settings.php +++ b/includes/Settings.php @@ -1007,7 +1007,7 @@ public function move_setting_after_id( $settings, $insert_settings, $after_setti * @return void */ public function update_documents_settings_sections(): void { - $documents = WPO_WCPDF()->documents->get_documents(); + $documents = WPO_WCPDF()->documents->get_documents( 'all' ); foreach ( $documents as $document ) { foreach ( $document->output_formats as $output_format ) { From 71e9fe839d65318b75f9478238d1ff656afd5e57 Mon Sep 17 00:00:00 2001 From: Alexandre Faustino Date: Wed, 8 Jan 2025 09:48:26 +0000 Subject: [PATCH 65/69] Tweak: improves UBL taxes table (#991) --- assets/css/settings-styles.css | 4 + assets/css/settings-styles.min.css | 2 +- assets/js/ubl-script.js | 21 ++++ assets/js/ubl-script.min.js | 1 + includes/Assets.php | 23 ++++- includes/Settings/SettingsUbl.php | 1 + ubl/Settings/TaxesSettings.php | 152 ++++++++++++++++++++++++----- views/settings-page.php | 2 +- 8 files changed, 176 insertions(+), 30 deletions(-) create mode 100644 assets/js/ubl-script.js create mode 100644 assets/js/ubl-script.min.js diff --git a/assets/css/settings-styles.css b/assets/css/settings-styles.css index a62674491..0a0c383d7 100644 --- a/assets/css/settings-styles.css +++ b/assets/css/settings-styles.css @@ -516,6 +516,10 @@ body.woocommerce_page_wpo_wcpdf_options_page { flex: 0 0 100%; } +#wpo-wcpdf-preview-wrapper[data-preview-states="1"].ubl .sidebar > form { + max-width: 100%; +} + #wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state="closed"] .sidebar { flex: 0 0 95%; } diff --git a/assets/css/settings-styles.min.css b/assets/css/settings-styles.min.css index 26706dc55..99b701ad9 100644 --- a/assets/css/settings-styles.min.css +++ b/assets/css/settings-styles.min.css @@ -1 +1 @@ -span.wpo-warning{display:inline-block;border:1px solid red;border-left:4px solid red;padding:5px 15px;background-color:#fff}.wcpdf-extensions-ad,.wcpdf-promo-ad{position:relative;min-height:90px;border:1px solid #6e1edc;background-color:#f1e9fc;padding:15px;padding-left:100px;margin-top:30px}img.wpo-helper{position:absolute;bottom:0;left:3px}.wcpdf-extensions-ad h3,.wcpdf-promo-ad h3{margin:0;padding:20px;font-weight:400;font-family:serif;letter-spacing:-1px;font-size:2.25em}.wcpdf-promo-ad p{margin:0;padding:0 20px;font-size:1.15em}.wcpdf-promo-ad p.upgrade-tab{margin-top:30px;font-style:italic;font-size:1em}.wcpdf-promo-ad p.expiration{font-size:.8em;padding-top:8px}.wcpdf-extensions-ad a,.wcpdf-promo-ad a{color:#6e1edc}.wcpdf-extensions-ad a.dismiss,.wcpdf-promo-ad a.dismiss{padding:10px 20px}.wcpdf-promo-ad p strong.code{font-size:1.3em;font-family:serif;padding:.1em .4em;background:#6e1edc;color:#fff;border-radius:5px;font-weight:400}.wcpdf-extensions-ad i{padding-left:20px}.wcpdf-extensions-ad ul,.wcpdf-promo-ad ul{margin:0;margin-left:40px}.wcpdf-extensions li{margin:0}.wcpdf-extensions li ul{list-style-type:square;margin-top:.5em;margin-bottom:.5em}.wcpdf-extensions>li:before{content:"";border-color:transparent transparent transparent #111;border-style:solid;border-width:.35em .35em .35em .45em;display:block;height:0;width:0;left:-1em;top:.9em;position:relative}.wcpdf-extensions li:not(.expanded){cursor:pointer}.wcpdf-extensions .expanded:before{border-color:#111 transparent transparent transparent;left:-1.17em;border-width:.45em .45em .35em .35em!important}.wcpdf-extensions .more{padding:10px;background-color:#fff;border:1px solid #ccc;border-radius:5px}.wcpdf-extensions table td{vertical-align:top}.dropbox-logo{margin-bottom:-10px;margin-right:10px}.cloud-logo{margin-bottom:-10px;margin-top:-5px;margin-right:10px}#img-header_logo{max-height:200px;width:auto;max-width:100%}.multiple-text-input label{padding-right:1em}table.multiple-text-input td{padding:0}table.wcpdf_documents_settings_list{width:100%;border-collapse:collapse;border-spacing:0;background-color:#fff;border-top:2px solid #000}table.wcpdf_documents_settings_list tr.odd{background-color:#ebf5ff}table.wcpdf_documents_settings_list td{padding:5px}table.wcpdf_documents_settings_list a{text-decoration:none}table.wcpdf_documents_settings_list td.settings-icon{text-align:right}table.wcpdf_documents_settings_list td.title{font-weight:700}.wcpdf-settings-sections ul{height:3em}.wcpdf-settings-sections ul li{float:left;margin-right:10px}.wcpdf-settings-sections ul li a{text-decoration:none;display:inline-block;padding:.8em 1em;color:#50575e;border:1px solid #c3c4c7;box-sizing:border-box}.wcpdf-settings-sections ul li a.active{border:2px solid #51266b;padding:calc(.8em - 1px) calc(1em - 1px);color:#000}.wcpdf_document_settings_sections{position:relative}.wcpdf_document_settings_sections>h2{cursor:pointer;padding:1em .8em;margin:0;border:1px solid #c3c4c7;background:#fff}.wcpdf_document_settings_sections ul{background:#fff;list-style:none;margin:0;padding:0;width:100%;display:block;height:auto;display:none;box-sizing:border-box;position:absolute;border-left:1px solid #c3c4c7;border-right:1px solid #c3c4c7;z-index:1000;box-shadow:0 35px 35px -8px rgba(0,0,0,.1);-webkit-box-shadow:0 35px 35px -8px rgba(0,0,0,.1)}.wcpdf_document_settings_sections ul.active{display:block}.wcpdf_document_settings_sections ul li{box-sizing:border-box;padding:0;margin-bottom:0;border-bottom:1px solid #eaeaea;font-size:1.1em}.wcpdf_document_settings_sections ul li:last-child{border-color:#c3c4c7}.wcpdf_document_settings_sections ul li:hover{cursor:pointer;background:#51266b;color:#fff}.wcpdf_document_settings_sections ul li:hover a{color:#fff}.wcpdf_document_settings_sections ul li a{color:#000;text-decoration:none;padding:1.2em 1.6em;display:block}.wcpdf_document_settings_sections .arrow-down{font-size:.7em;color:#999;margin-left:8px;font-weight:400;float:right}.wcpdf_document_settings_sections p:hover,.wcpdf_document_settings_sections p:hover>.arrow-down{color:#222}.wcpdf_advanced_numbers_choose_table{margin-top:20px}.wcpdf_document_settings_document_output_formats{margin-bottom:30px}.edit-next-number{opacity:.5}.edit-next-number:hover{opacity:1;cursor:pointer}.wpo-wcpdf-pointer.wp-pointer-top .wp-pointer-arrow,.wpo-wcpdf-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#51266b}.wpo-wcpdf-pointer .wp-pointer-content h3{border-color:#51266b;background:#51266b}.wpo-wcpdf-pointer .wp-pointer-content h3:before{color:#51266b}body.woocommerce_page_wpo_wcpdf_options_page{background:#fdfdfd}.wrap [class$=icon32]+h2{font-size:18px;padding:1em}.wrap .notice{margin:15px 0 0}.nav-tab-wrapper:not(.wcpdf_debug_settings_sections>.nav-tab-wrapper) a.nav-tab{background:0 0;border:none;border-bottom:3px solid transparent;padding:1em 0;margin:0 1.2em;font-size:15px}.nav-tab-wrapper:not(.wcpdf_debug_settings_sections>.nav-tab-wrapper) a.nav-tab.nav-tab-active{border-bottom:3px solid #51266b}#wpo-wcpdf-preview-wrapper{width:100%;height:auto;position:relative;display:flex;align-items:flex-start}#wpo-wcpdf-preview-wrapper .preview-document,#wpo-wcpdf-preview-wrapper .sidebar{transition:.3s ease-in-out}#wpo-wcpdf-preview-wrapper .sidebar{height:auto;padding:4em 0 0 0;box-sizing:border-box;background:0 0;flex:0 0 35%;overflow-x:hidden}#wpo-wcpdf-preview-wrapper .sidebar>form{background:0 0!important;overflow:visible;padding:0;margin-left:2em;box-sizing:border-box;width:calc(100% - 4em);max-width:50vw}#wpo-wcpdf-preview-wrapper .sidebar>form.editor{max-width:none}#wpo-wcpdf-preview-wrapper .sidebar .form-table,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>th{display:block;width:100%;padding:0}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>th{padding-bottom:.6em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr:not(:last-child)>td{padding-bottom:2.4em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td p.description{font-size:.85em;padding-top:.7em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td p.description>span.wpo-warning{width:100%;box-sizing:border-box;word-wrap:break-word}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input[type=text],#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input[type=url],#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>select,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>textarea{max-width:none;width:100%}#wpo-wcpdf-preview-wrapper input[type=text][size],#wpo-wcpdf-preview-wrapper input[type=url][size]{width:auto!important;max-width:100%!important}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input#next_invoice_number{width:auto!important}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{display:grid;grid-template-columns:1fr 2fr;gap:4em}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2{border-bottom:1px solid #c3c4c7;padding:1em 0 1em 5px;margin:0;font-weight:400;color:#222;font-family:sans-serif;font-size:1.3em;letter-spacing:-.01em;position:relative;transition:transform .3s;cursor:pointer}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2~.form-table{border-left:1px solid #c3c4c7;border-right:1px solid #c3c4c7;border-bottom:1px solid #c3c4c7;padding:2em;margin-top:-1px;background:#fff;margin-bottom:20px}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2::after{content:'\f347';font-family:dashicons;font-size:16px;color:#82878c;position:absolute;right:5px;top:50%;transform:translateY(-50%);transition:transform .15s}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2:hover:after{color:#222}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2.active::after{transform:translateY(-50%) rotate(180deg)}#wpo-wcpdf-preview-wrapper .my_account_buttons_custom{margin-top:1em}#wpo-wcpdf-settings .form-table .ui-tabs-nav{padding-left:0!important;margin-left:0!important}#wpo-wcpdf-settings .translations input,#wpo-wcpdf-settings .translations textarea{width:100%}#wpo-wcpdf-settings .wcpdf-attachment-settings-hint{border-left:4px solid #51266b}#wpo-wcpdf-settings .notice-info.inline{border-left-color:#51266b}#wpo-wcpdf-settings table#document-link-access-type{margin-top:-15px}#wpo-wcpdf-settings table#document-link-access-type td.option{padding-left:0}#wpo-wcpdf-settings table#document-link-access-type td{padding-top:0;padding-bottom:6px;font-size:12px}#wpo-wcpdf-settings .system-status-table{margin-top:2em}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar{flex:0 0 100%}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=full] .sidebar{flex:0 0 95%;margin-left:-95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .sidebar{flex:0 0 35%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=full] .sidebar{margin-left:-35%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] .sidebar{transition-delay:.4s}#wpo-wcpdf-preview-wrapper .preview-document{padding:0;box-sizing:border-box;position:sticky;top:2.4em;flex:0 0 60%}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .preview-document{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .preview-document{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=full] .preview-document{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .preview-document{flex:0 0 60%;margin-right:-60%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .preview-document{flex:0 0 60%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=full] .preview-document{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] .preview-document{transition-delay:.4s}.preview-document .preview{width:100%;box-sizing:border-box;padding-right:5%}.preview-document .preview>#preview-ubl{width:100%;height:100%;overflow-wrap:anywhere;background-color:#222;color:#fff;padding:2em}.preview-document .preview>#preview-canvas{display:block;max-width:800px;max-height:85vh;width:auto!important;margin:0 auto;background:#fff;box-shadow:8px 8px 8px rgba(0,0,0,.1),-8px -8px 8px rgba(0,0,0,.02);-webkit-box-shadow:8px 8px 8px rgba(0,0,0,.1),-8px -8px 8px rgba(0,0,0,.02)}#wpo-wcpdf-preview-wrapper[data-preview-states="2"] #preview-canvas{max-height:170vh}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=sidebar] #preview-canvas{max-height:170vh;transition:max-height .4s ease-in-out .3s}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] #preview-canvas{transition:max-height .4s ease-in-out 0s}.preview-document .preview-data-wrapper{width:100%;height:4em}.preview-document .preview-data-wrapper .preview-document-type,.preview-document .preview-data-wrapper .preview-order-data{float:right}.preview-document .preview-data-wrapper .preview-document-type{margin-right:30px}.preview-document .preview-data-wrapper .preview-document-type ul>li{text-decoration:none;color:initial;padding:1.4em 1.6em}.preview-document .preview-data-wrapper .preview-document-type ul>li:hover{color:#fff!important}.preview-document .preview-data-wrapper .save-settings{padding:1em 0 0 0;float:right;overflow:hidden;position:relative}.preview-document .preview-data-wrapper .save-settings p{padding:0;margin:0 0 0 2em;position:relative;margin-right:-200px;transition:margin-right .3s ease-out}.preview-document .preview-data-wrapper .save-settings p:after{content:'';display:block;pointer-events:none;position:absolute;box-sizing:border-box;border-radius:3px;right:0;top:0;background:0 0;width:100%;height:100%;z-index:10;border:0 solid #fff;animation:border-pulse 4s infinite}@keyframes border-pulse{0%{border-color:rgba(255,255,255,0);border-width:8px}50%{border-color:#fff;border-width:0}}.preview-document .preview-data-wrapper .save-settings p input:focus{outline-width:0;box-shadow:none}.preview-document .preview-data p{padding:1.4em 0;margin:0;color:#666;text-align:right;cursor:pointer;font-weight:lighter;float:right}.preview-document .preview-data p.order-search{display:none}.preview-document .preview-data input{float:right;margin:1em 0 0 1em;padding:.1em .5em;width:20ch;margin-right:-25ch;display:none}.preview-document .preview-data input.active{margin-right:0;display:inline-block}.preview-document .preview-data ul{position:absolute;right:0;top:4em;background:#fff;box-shadow:0 0 25px -10px rgba(0,0,0,.2);-webkit-box-shadow:0 0 25px -10px rgba(0,0,0,.2);list-style:none;margin:0;padding:0;min-width:24em;display:block;height:0;overflow:hidden}.preview-document .preview-data ul.active{height:auto;z-index:1}.preview-document .preview-data ul li{box-sizing:border-box;padding:0;margin-bottom:0;border-bottom:1px solid #eaeaea;font-size:1.1em}.preview-document .preview-data ul li:hover{cursor:pointer;background:#51266b;color:#fff}.preview-document .preview-data ul li a,.preview-document .preview-data.preview-order-data ul li{display:block;padding:1.4em 1.6em}.preview-document .preview-data .arrow-down{font-size:.8em;color:#999;margin-left:8px}.preview-document .preview-data p:hover,.preview-document .preview-data p:hover>.arrow-down{color:#222}.preview-document .preview-data #preview-order-search-results{display:none;position:absolute;right:0;top:4em;width:300px;box-shadow:0 0 25px -10px rgba(0,0,0,.2);-webkit-box-shadow:0 0 25px -10px rgba(0,0,0,.2);padding:20px 0;background-color:#fff;z-index:99}.preview-document .preview-data #preview-order-search-results a{display:block;border-left:1px solid #999;border-right:1px solid #999;border-top:1px solid #999;color:#000;padding:10px;margin:0 20px;text-decoration:none;cursor:pointer}.preview-document .preview-data #preview-order-search-results a:last-child{border-bottom:1px solid #999}.preview-document .preview-data #preview-order-search-results a:hover{background-color:#51266b;color:#fff}.preview-document .preview-data #preview-order-search-results .order-number{font-weight:700}.preview-document .preview-data #preview-order-search-results .date,.preview-document .preview-data #preview-order-search-results .total{margin-top:6px;display:inline-block}.preview-document .preview-data #preview-order-search-results .total{float:right}.preview-document .preview-data #preview-order-search-results .error{margin:0 20px}.preview-document .preview-order-search-wrapper{position:relative;float:right}.preview-document .preview-order-search-wrapper img.preview-order-search-clear{position:absolute;width:30px;height:16px;top:22px;right:6px;display:none;cursor:pointer}#wpo-wcpdf-preview-wrapper .gutter{flex:0 0 5%;position:sticky;top:2.4em;height:170vh}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .gutter .slide-left,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .gutter .slide-left{float:right}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .gutter .slide-left{border:none}#wpo-wcpdf-preview-wrapper .slider{box-sizing:border-box;padding-top:2.4em;color:#999;font-weight:700;cursor:pointer;font-size:.7em;line-height:1em;width:50%;height:100%;float:left}#wpo-wcpdf-preview-wrapper .slider.slide-left{text-align:right;padding-right:10px;border-right:1px solid #ccc}#wpo-wcpdf-preview-wrapper .slider.slide-right{text-align:left;padding-left:10px;border-left:1px solid #ccc;display:none}#wpo-wcpdf-preview-wrapper .gutter-arrow{width:0;height:0;border-top:3px solid transparent;border-bottom:3px solid transparent;display:block}#wpo-wcpdf-preview-wrapper .arrow-left{border-right:7px solid #999;float:right}#wpo-wcpdf-preview-wrapper .arrow-right{border-left:7px solid #999}#wpo-wcpdf-preview-wrapper .slider:hover>.arrow-left{border-right:7px solid #222}#wpo-wcpdf-preview-wrapper .slider:hover>.arrow-right{border-left:7px solid #222}#wpo-wcpdf-preview-wrapper .slider.slide-left:after{position:absolute;top:1.55em;right:2em;font-size:1.4em;display:none}#wpo-wcpdf-preview-wrapper .slider.slide-right:after{position:absolute;top:1.55em;left:2em;font-size:1.4em;display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .gutter{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .gutter{height:100vh}#wpo-wcpdf-preview-wrapper[data-preview-state=full] .slide-right:after{display:inline-block}#wpo-wcpdf-preview-wrapper[data-preview-state=closed] .slide-left:after{display:inline-block}#wpo-wcpdf-preview-wrapper.static .gutter,#wpo-wcpdf-preview-wrapper.static .preview-document{position:static!important}#wpo-wcpdf-preview-wrapper.static .sidebar{height:170vh!important;overflow:hidden}#wpo-wcpdf-preview-wrapper input.readonly,#wpo-wcpdf-preview-wrapper input[readonly],#wpo-wcpdf-preview-wrapper textarea.readonly,#wpo-wcpdf-preview-wrapper textarea[readonly]{background-color:#f8f8f8}#wpo-wcpdf-preview-wrapper[data-preview-state=sidebar] .select2.select2-container{width:100%!important}.wcpdf_ubl_settings_sections{margin-bottom:4em}#wpo-wcpdf-preview-wrapper input#due_date_days{text-align:right}#wpo-wcpdf-preview-wrapper input#due_date_days:disabled{background-color:#eaeaea;color:#999}sup.wcpdf_beta{background-color:#51266b;color:#fff;font-size:7pt;padding:1px 2px;border-radius:2px}@media screen and (min-width:1920px){.preview-document .preview>#preview-canvas{max-width:900px}}@media screen and (max-width:1200px){.preview-document .preview>#preview-canvas{max-width:680px}.nav-tab-wrapper a.nav-tab{padding:1em 2em;margin:0 .5em .5em 0;border:1px solid #ccc;box-sizing:border-box;height:4em}.nav-tab-wrapper a.nav-tab.nav-tab-active{border:3px solid #51266b}.preview-document .preview>#preview-canvas{width:80vw!important}#wpo-wcpdf-preview-wrapper .sidebar>form{max-width:100%}#wpo-wcpdf-preview-wrapper[data-preview-state=closed] .select2.select2-container{width:100%!important}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{gap:2em}.preview-document .preview-data-wrapper{height:6em}.preview-document .preview-data p{padding:2.2em 0}#wpo-wcpdf-preview-wrapper .slider.slide-left:after,#wpo-wcpdf-preview-wrapper .slider.slide-right:after{top:1.5em;padding:1em;background:#fff;border:1px solid #ccc}#wpo-wcpdf-preview-wrapper .slider.slide-right:after{left:0}#wpo-wcpdf-preview-wrapper .slider.slide-left:after{right:0}#wpo-wcpdf-preview-wrapper .multiple-text-input tr td:nth-child(2),#wpo-wcpdf-preview-wrapper .multiple-text-input tr td:nth-child(3){float:left;margin-bottom:10px}#wpo-wcpdf-preview-wrapper .multiple-text-input tr td .woocommerce-help-tip:after{padding:.5em .8em;font-size:1.2em;line-height:inherit}}@media screen and (max-width:860px){#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{display:block}}div.upgrade-table-description{padding:0 0 3em 1em}div.upgrade-table-description h1{font-family:serif;letter-spacing:-1px;font-size:3em}div.upgrade-table-description p{font-size:1.1em}#upgrade-table{width:100%;border-collapse:collapse;font-size:1.2em;margin-bottom:3em}#upgrade-table td,#upgrade-table th{padding:.8em 2em;border-bottom:1px solid #ccc;text-align:center}#upgrade-table th{font-weight:400;font-size:1.1em}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:200px}#upgrade-table tr:last-child td{border:none}#upgrade-table td.feature-label{text-align:left;padding-left:1em;font-weight:700;width:500px}#upgrade-table td.feature-label span.description{display:inline-block;padding-top:10px;font-size:.8em;line-height:1.4em;font-weight:400;color:#555}#upgrade-table td span.feature-available{display:inline-block;width:24px;height:24px;background-repeat:no-repeat;background-size:cover}#upgrade-table a,div.upgrade-table-description a{color:#6e1edc;white-space:nowrap}#upgrade-table .upgrade-links h4{margin:1em 0 .5em 0}#upgrade-table .upgrade-links p{margin:0;font-style:oblique;font-size:.8em}#plugin-recommendations a.upgrade_button,#upgrade-table .upgrade-links a.upgrade_button{display:inline-block;background:#fff;padding:1em 3em 1em 2em;border-radius:12px;border:1px solid #6e1edc;text-decoration:none;margin:2em 0;position:relative}#plugin-recommendations a.upgrade_button:after,#upgrade-table .upgrade-links a.upgrade_button:after{content:' \2192';display:block;position:absolute;right:1.8em;top:1.1em;transition:.5s}#plugin-recommendations a.upgrade_button:hover:after,#upgrade-table .upgrade-links a.upgrade_button:hover:after{right:1.1em;font-weight:700}#plugin-recommendations a.upgrade_button:focus,#plugin-recommendations a.upgrade_button:hover,#upgrade-table .upgrade-links a.upgrade_button:focus,#upgrade-table .upgrade-links a.upgrade_button:hover{background:#6e1edc;color:#fcfbf7}#plugin-recommendations{border-radius:8px;background-color:#f1e9fc;padding:4em 3em}#plugin-recommendations .card-container{max-width:1100px;display:grid;grid-template-columns:repeat(3,1fr);grid-gap:3em;padding:2em 0}#plugin-recommendations .recommendation-card{margin-top:0;border-radius:6px;background-color:#fff;box-shadow:0 0 25px -10px rgba(0,0,0,.2);box-sizing:border-box;font-size:15px;overflow:hidden;transition:.2s}#plugin-recommendations .recommendation-card:nth-child(n+4){display:none}#plugin-recommendations .recommendation-card:hover{scale:1.02}#plugin-recommendations .recommendation-card.currently-installed{opacity:.5}#plugin-recommendations .recommendation-card .card-content{padding:0 4em 3em 2em}#plugin-recommendations .recommendation-card img{width:100%}#plugin-recommendations .recommendation-card h5{text-align:left;font-size:1.4em;line-height:1.3em;font-weight:700;margin:1em 0}#plugin-recommendations .recommendation-card p{text-align:left;padding-bottom:10px}#plugin-recommendations .recommendation-card a.upgrade_button{margin:0}#plugin-recommendations .recommendation-card span.currently-installed{font-size:.7em;color:#fff;background-color:#6e1edc;padding:1em 2em;border-radius:12px;margin:0;display:inline-block}@media screen and (max-width:1100px){#upgrade-table{font-size:1em;line-height:1.2em}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:25%;padding:.8em 1em}#upgrade-table td.last,#upgrade-table th.last{width:0;padding:0}#upgrade-table td.feature-label span.description{padding-top:6px}#plugin-recommendations .card-container{grid-gap:2em}}@media screen and (max-width:968px){#plugin-recommendations .card-container{grid-template-columns:repeat(1,1fr);padding-right:40%}}@media screen and (max-width:782px){#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td:has(input[type=checkbox]+input[type=text])>input{display:inline-block}}@media screen and (max-width:767px){#upgrade-table td.feature-label span.description{display:none}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:20%}#upgrade-table td.first{width:40%}#plugin-recommendations .card-container{padding-right:0}}@media screen and (max-width:649px){div.upgrade-table-description{padding-left:.8em}div.upgrade-table-description p{font-size:1em}#upgrade-table{font-size:.8em}#upgrade-table td,#upgrade-table th{padding:.5em .8em!important}#upgrade-table td span.feature-available{width:18px;height:18px}#upgrade-table .upgrade-links a{white-space:normal;padding:.6em .8em;border-radius:6px}#upgrade-table .upgrade-links a:after{display:none}#plugin-recommendations .card-container{justify-content:center}}@media screen and (max-width:782px){input[type=checkbox],input[type=radio]{margin-bottom:.5em}} \ No newline at end of file +span.wpo-warning{display:inline-block;border:1px solid red;border-left:4px solid red;padding:5px 15px;background-color:#fff}.wcpdf-extensions-ad,.wcpdf-promo-ad{position:relative;min-height:90px;border:1px solid #6e1edc;background-color:#f1e9fc;padding:15px;padding-left:100px;margin-top:30px}img.wpo-helper{position:absolute;bottom:0;left:3px}.wcpdf-extensions-ad h3,.wcpdf-promo-ad h3{margin:0;padding:20px;font-weight:400;font-family:serif;letter-spacing:-1px;font-size:2.25em}.wcpdf-promo-ad p{margin:0;padding:0 20px;font-size:1.15em}.wcpdf-promo-ad p.upgrade-tab{margin-top:30px;font-style:italic;font-size:1em}.wcpdf-promo-ad p.expiration{font-size:.8em;padding-top:8px}.wcpdf-extensions-ad a,.wcpdf-promo-ad a{color:#6e1edc}.wcpdf-extensions-ad a.dismiss,.wcpdf-promo-ad a.dismiss{padding:10px 20px}.wcpdf-promo-ad p strong.code{font-size:1.3em;font-family:serif;padding:.1em .4em;background:#6e1edc;color:#fff;border-radius:5px;font-weight:400}.wcpdf-extensions-ad i{padding-left:20px}.wcpdf-extensions-ad ul,.wcpdf-promo-ad ul{margin:0;margin-left:40px}.wcpdf-extensions li{margin:0}.wcpdf-extensions li ul{list-style-type:square;margin-top:.5em;margin-bottom:.5em}.wcpdf-extensions>li:before{content:"";border-color:transparent transparent transparent #111;border-style:solid;border-width:.35em .35em .35em .45em;display:block;height:0;width:0;left:-1em;top:.9em;position:relative}.wcpdf-extensions li:not(.expanded){cursor:pointer}.wcpdf-extensions .expanded:before{border-color:#111 transparent transparent transparent;left:-1.17em;border-width:.45em .45em .35em .35em!important}.wcpdf-extensions .more{padding:10px;background-color:#fff;border:1px solid #ccc;border-radius:5px}.wcpdf-extensions table td{vertical-align:top}.dropbox-logo{margin-bottom:-10px;margin-right:10px}.cloud-logo{margin-bottom:-10px;margin-top:-5px;margin-right:10px}#img-header_logo{max-height:200px;width:auto;max-width:100%}.multiple-text-input label{padding-right:1em}table.multiple-text-input td{padding:0}table.wcpdf_documents_settings_list{width:100%;border-collapse:collapse;border-spacing:0;background-color:#fff;border-top:2px solid #000}table.wcpdf_documents_settings_list tr.odd{background-color:#ebf5ff}table.wcpdf_documents_settings_list td{padding:5px}table.wcpdf_documents_settings_list a{text-decoration:none}table.wcpdf_documents_settings_list td.settings-icon{text-align:right}table.wcpdf_documents_settings_list td.title{font-weight:700}.wcpdf-settings-sections ul{height:3em}.wcpdf-settings-sections ul li{float:left;margin-right:10px}.wcpdf-settings-sections ul li a{text-decoration:none;display:inline-block;padding:.8em 1em;color:#50575e;border:1px solid #c3c4c7;box-sizing:border-box}.wcpdf-settings-sections ul li a.active{border:2px solid #51266b;padding:calc(.8em - 1px) calc(1em - 1px);color:#000}.wcpdf_document_settings_sections{position:relative}.wcpdf_document_settings_sections>h2{cursor:pointer;padding:1em .8em;margin:0;border:1px solid #c3c4c7;background:#fff}.wcpdf_document_settings_sections ul{background:#fff;list-style:none;margin:0;padding:0;width:100%;display:block;height:auto;display:none;box-sizing:border-box;position:absolute;border-left:1px solid #c3c4c7;border-right:1px solid #c3c4c7;z-index:1000;box-shadow:0 35px 35px -8px rgba(0,0,0,.1);-webkit-box-shadow:0 35px 35px -8px rgba(0,0,0,.1)}.wcpdf_document_settings_sections ul.active{display:block}.wcpdf_document_settings_sections ul li{box-sizing:border-box;padding:0;margin-bottom:0;border-bottom:1px solid #eaeaea;font-size:1.1em}.wcpdf_document_settings_sections ul li:last-child{border-color:#c3c4c7}.wcpdf_document_settings_sections ul li:hover{cursor:pointer;background:#51266b;color:#fff}.wcpdf_document_settings_sections ul li:hover a{color:#fff}.wcpdf_document_settings_sections ul li a{color:#000;text-decoration:none;padding:1.2em 1.6em;display:block}.wcpdf_document_settings_sections .arrow-down{font-size:.7em;color:#999;margin-left:8px;font-weight:400;float:right}.wcpdf_document_settings_sections p:hover,.wcpdf_document_settings_sections p:hover>.arrow-down{color:#222}.wcpdf_advanced_numbers_choose_table{margin-top:20px}.wcpdf_document_settings_document_output_formats{margin-bottom:30px}.edit-next-number{opacity:.5}.edit-next-number:hover{opacity:1;cursor:pointer}.wpo-wcpdf-pointer.wp-pointer-top .wp-pointer-arrow,.wpo-wcpdf-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#51266b}.wpo-wcpdf-pointer .wp-pointer-content h3{border-color:#51266b;background:#51266b}.wpo-wcpdf-pointer .wp-pointer-content h3:before{color:#51266b}body.woocommerce_page_wpo_wcpdf_options_page{background:#fdfdfd}.wrap [class$=icon32]+h2{font-size:18px;padding:1em}.wrap .notice{margin:15px 0 0}.nav-tab-wrapper:not(.wcpdf_debug_settings_sections>.nav-tab-wrapper) a.nav-tab{background:0 0;border:none;border-bottom:3px solid transparent;padding:1em 0;margin:0 1.2em;font-size:15px}.nav-tab-wrapper:not(.wcpdf_debug_settings_sections>.nav-tab-wrapper) a.nav-tab.nav-tab-active{border-bottom:3px solid #51266b}#wpo-wcpdf-preview-wrapper{width:100%;height:auto;position:relative;display:flex;align-items:flex-start}#wpo-wcpdf-preview-wrapper .preview-document,#wpo-wcpdf-preview-wrapper .sidebar{transition:.3s ease-in-out}#wpo-wcpdf-preview-wrapper .sidebar{height:auto;padding:4em 0 0 0;box-sizing:border-box;background:0 0;flex:0 0 35%;overflow-x:hidden}#wpo-wcpdf-preview-wrapper .sidebar>form{background:0 0!important;overflow:visible;padding:0;margin-left:2em;box-sizing:border-box;width:calc(100% - 4em);max-width:50vw}#wpo-wcpdf-preview-wrapper .sidebar>form.editor{max-width:none}#wpo-wcpdf-preview-wrapper .sidebar .form-table,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>th{display:block;width:100%;padding:0}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>th{padding-bottom:.6em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr:not(:last-child)>td{padding-bottom:2.4em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td p.description{font-size:.85em;padding-top:.7em}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td p.description>span.wpo-warning{width:100%;box-sizing:border-box;word-wrap:break-word}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input[type=text],#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input[type=url],#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>select,#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>textarea{max-width:none;width:100%}#wpo-wcpdf-preview-wrapper input[type=text][size],#wpo-wcpdf-preview-wrapper input[type=url][size]{width:auto!important;max-width:100%!important}#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td>input#next_invoice_number{width:auto!important}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{display:grid;grid-template-columns:1fr 2fr;gap:4em}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2{border-bottom:1px solid #c3c4c7;padding:1em 0 1em 5px;margin:0;font-weight:400;color:#222;font-family:sans-serif;font-size:1.3em;letter-spacing:-.01em;position:relative;transition:transform .3s;cursor:pointer}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2~.form-table{border-left:1px solid #c3c4c7;border-right:1px solid #c3c4c7;border-bottom:1px solid #c3c4c7;padding:2em;margin-top:-1px;background:#fff;margin-bottom:20px}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2::after{content:'\f347';font-family:dashicons;font-size:16px;color:#82878c;position:absolute;right:5px;top:50%;transform:translateY(-50%);transition:transform .15s}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2:hover:after{color:#222}#wpo-wcpdf-preview-wrapper .sidebar .settings_category h2.active::after{transform:translateY(-50%) rotate(180deg)}#wpo-wcpdf-preview-wrapper .my_account_buttons_custom{margin-top:1em}#wpo-wcpdf-settings .form-table .ui-tabs-nav{padding-left:0!important;margin-left:0!important}#wpo-wcpdf-settings .translations input,#wpo-wcpdf-settings .translations textarea{width:100%}#wpo-wcpdf-settings .wcpdf-attachment-settings-hint{border-left:4px solid #51266b}#wpo-wcpdf-settings .notice-info.inline{border-left-color:#51266b}#wpo-wcpdf-settings table#document-link-access-type{margin-top:-15px}#wpo-wcpdf-settings table#document-link-access-type td.option{padding-left:0}#wpo-wcpdf-settings table#document-link-access-type td{padding-top:0;padding-bottom:6px;font-size:12px}#wpo-wcpdf-settings .system-status-table{margin-top:2em}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar{flex:0 0 100%}#wpo-wcpdf-preview-wrapper[data-preview-states="1"].ubl .sidebar>form{max-width:100%}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=full] .sidebar{flex:0 0 95%;margin-left:-95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .sidebar{flex:0 0 35%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=full] .sidebar{margin-left:-35%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] .sidebar{transition-delay:.4s}#wpo-wcpdf-preview-wrapper .preview-document{padding:0;box-sizing:border-box;position:sticky;top:2.4em;flex:0 0 60%}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .preview-document{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .preview-document{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=full] .preview-document{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .preview-document{flex:0 0 60%;margin-right:-60%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .preview-document{flex:0 0 60%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=full] .preview-document{flex:0 0 95%}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] .preview-document{transition-delay:.4s}.preview-document .preview{width:100%;box-sizing:border-box;padding-right:5%}.preview-document .preview>#preview-ubl{width:100%;height:100%;overflow-wrap:anywhere;background-color:#222;color:#fff;padding:2em}.preview-document .preview>#preview-canvas{display:block;max-width:800px;max-height:85vh;width:auto!important;margin:0 auto;background:#fff;box-shadow:8px 8px 8px rgba(0,0,0,.1),-8px -8px 8px rgba(0,0,0,.02);-webkit-box-shadow:8px 8px 8px rgba(0,0,0,.1),-8px -8px 8px rgba(0,0,0,.02)}#wpo-wcpdf-preview-wrapper[data-preview-states="2"] #preview-canvas{max-height:170vh}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=sidebar] #preview-canvas{max-height:170vh;transition:max-height .4s ease-in-out .3s}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-from-preview-state=full] #preview-canvas{transition:max-height .4s ease-in-out 0s}.preview-document .preview-data-wrapper{width:100%;height:4em}.preview-document .preview-data-wrapper .preview-document-type,.preview-document .preview-data-wrapper .preview-order-data{float:right}.preview-document .preview-data-wrapper .preview-document-type{margin-right:30px}.preview-document .preview-data-wrapper .preview-document-type ul>li{text-decoration:none;color:initial;padding:1.4em 1.6em}.preview-document .preview-data-wrapper .preview-document-type ul>li:hover{color:#fff!important}.preview-document .preview-data-wrapper .save-settings{padding:1em 0 0 0;float:right;overflow:hidden;position:relative}.preview-document .preview-data-wrapper .save-settings p{padding:0;margin:0 0 0 2em;position:relative;margin-right:-200px;transition:margin-right .3s ease-out}.preview-document .preview-data-wrapper .save-settings p:after{content:'';display:block;pointer-events:none;position:absolute;box-sizing:border-box;border-radius:3px;right:0;top:0;background:0 0;width:100%;height:100%;z-index:10;border:0 solid #fff;animation:border-pulse 4s infinite}@keyframes border-pulse{0%{border-color:rgba(255,255,255,0);border-width:8px}50%{border-color:#fff;border-width:0}}.preview-document .preview-data-wrapper .save-settings p input:focus{outline-width:0;box-shadow:none}.preview-document .preview-data p{padding:1.4em 0;margin:0;color:#666;text-align:right;cursor:pointer;font-weight:lighter;float:right}.preview-document .preview-data p.order-search{display:none}.preview-document .preview-data input{float:right;margin:1em 0 0 1em;padding:.1em .5em;width:20ch;margin-right:-25ch;display:none}.preview-document .preview-data input.active{margin-right:0;display:inline-block}.preview-document .preview-data ul{position:absolute;right:0;top:4em;background:#fff;box-shadow:0 0 25px -10px rgba(0,0,0,.2);-webkit-box-shadow:0 0 25px -10px rgba(0,0,0,.2);list-style:none;margin:0;padding:0;min-width:24em;display:block;height:0;overflow:hidden}.preview-document .preview-data ul.active{height:auto;z-index:1}.preview-document .preview-data ul li{box-sizing:border-box;padding:0;margin-bottom:0;border-bottom:1px solid #eaeaea;font-size:1.1em}.preview-document .preview-data ul li:hover{cursor:pointer;background:#51266b;color:#fff}.preview-document .preview-data ul li a,.preview-document .preview-data.preview-order-data ul li{display:block;padding:1.4em 1.6em}.preview-document .preview-data .arrow-down{font-size:.8em;color:#999;margin-left:8px}.preview-document .preview-data p:hover,.preview-document .preview-data p:hover>.arrow-down{color:#222}.preview-document .preview-data #preview-order-search-results{display:none;position:absolute;right:0;top:4em;width:300px;box-shadow:0 0 25px -10px rgba(0,0,0,.2);-webkit-box-shadow:0 0 25px -10px rgba(0,0,0,.2);padding:20px 0;background-color:#fff;z-index:99}.preview-document .preview-data #preview-order-search-results a{display:block;border-left:1px solid #999;border-right:1px solid #999;border-top:1px solid #999;color:#000;padding:10px;margin:0 20px;text-decoration:none;cursor:pointer}.preview-document .preview-data #preview-order-search-results a:last-child{border-bottom:1px solid #999}.preview-document .preview-data #preview-order-search-results a:hover{background-color:#51266b;color:#fff}.preview-document .preview-data #preview-order-search-results .order-number{font-weight:700}.preview-document .preview-data #preview-order-search-results .date,.preview-document .preview-data #preview-order-search-results .total{margin-top:6px;display:inline-block}.preview-document .preview-data #preview-order-search-results .total{float:right}.preview-document .preview-data #preview-order-search-results .error{margin:0 20px}.preview-document .preview-order-search-wrapper{position:relative;float:right}.preview-document .preview-order-search-wrapper img.preview-order-search-clear{position:absolute;width:30px;height:16px;top:22px;right:6px;display:none;cursor:pointer}#wpo-wcpdf-preview-wrapper .gutter{flex:0 0 5%;position:sticky;top:2.4em;height:170vh}#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .gutter .slide-left,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .gutter .slide-left{float:right}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .gutter .slide-left{border:none}#wpo-wcpdf-preview-wrapper .slider{box-sizing:border-box;padding-top:2.4em;color:#999;font-weight:700;cursor:pointer;font-size:.7em;line-height:1em;width:50%;height:100%;float:left}#wpo-wcpdf-preview-wrapper .slider.slide-left{text-align:right;padding-right:10px;border-right:1px solid #ccc}#wpo-wcpdf-preview-wrapper .slider.slide-right{text-align:left;padding-left:10px;border-left:1px solid #ccc;display:none}#wpo-wcpdf-preview-wrapper .gutter-arrow{width:0;height:0;border-top:3px solid transparent;border-bottom:3px solid transparent;display:block}#wpo-wcpdf-preview-wrapper .arrow-left{border-right:7px solid #999;float:right}#wpo-wcpdf-preview-wrapper .arrow-right{border-left:7px solid #999}#wpo-wcpdf-preview-wrapper .slider:hover>.arrow-left{border-right:7px solid #222}#wpo-wcpdf-preview-wrapper .slider:hover>.arrow-right{border-left:7px solid #222}#wpo-wcpdf-preview-wrapper .slider.slide-left:after{position:absolute;top:1.55em;right:2em;font-size:1.4em;display:none}#wpo-wcpdf-preview-wrapper .slider.slide-right:after{position:absolute;top:1.55em;left:2em;font-size:1.4em;display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .gutter{display:none}#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=sidebar] .gutter{height:100vh}#wpo-wcpdf-preview-wrapper[data-preview-state=full] .slide-right:after{display:inline-block}#wpo-wcpdf-preview-wrapper[data-preview-state=closed] .slide-left:after{display:inline-block}#wpo-wcpdf-preview-wrapper.static .gutter,#wpo-wcpdf-preview-wrapper.static .preview-document{position:static!important}#wpo-wcpdf-preview-wrapper.static .sidebar{height:170vh!important;overflow:hidden}#wpo-wcpdf-preview-wrapper input.readonly,#wpo-wcpdf-preview-wrapper input[readonly],#wpo-wcpdf-preview-wrapper textarea.readonly,#wpo-wcpdf-preview-wrapper textarea[readonly]{background-color:#f8f8f8}#wpo-wcpdf-preview-wrapper[data-preview-state=sidebar] .select2.select2-container{width:100%!important}.wcpdf_ubl_settings_sections{margin-bottom:4em}#wpo-wcpdf-preview-wrapper input#due_date_days{text-align:right}#wpo-wcpdf-preview-wrapper input#due_date_days:disabled{background-color:#eaeaea;color:#999}sup.wcpdf_beta{background-color:#51266b;color:#fff;font-size:7pt;padding:1px 2px;border-radius:2px}@media screen and (min-width:1920px){.preview-document .preview>#preview-canvas{max-width:900px}}@media screen and (max-width:1200px){.preview-document .preview>#preview-canvas{max-width:680px}.nav-tab-wrapper a.nav-tab{padding:1em 2em;margin:0 .5em .5em 0;border:1px solid #ccc;box-sizing:border-box;height:4em}.nav-tab-wrapper a.nav-tab.nav-tab-active{border:3px solid #51266b}.preview-document .preview>#preview-canvas{width:80vw!important}#wpo-wcpdf-preview-wrapper .sidebar>form{max-width:100%}#wpo-wcpdf-preview-wrapper[data-preview-state=closed] .select2.select2-container{width:100%!important}#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{gap:2em}.preview-document .preview-data-wrapper{height:6em}.preview-document .preview-data p{padding:2.2em 0}#wpo-wcpdf-preview-wrapper .slider.slide-left:after,#wpo-wcpdf-preview-wrapper .slider.slide-right:after{top:1.5em;padding:1em;background:#fff;border:1px solid #ccc}#wpo-wcpdf-preview-wrapper .slider.slide-right:after{left:0}#wpo-wcpdf-preview-wrapper .slider.slide-left:after{right:0}#wpo-wcpdf-preview-wrapper .multiple-text-input tr td:nth-child(2),#wpo-wcpdf-preview-wrapper .multiple-text-input tr td:nth-child(3){float:left;margin-bottom:10px}#wpo-wcpdf-preview-wrapper .multiple-text-input tr td .woocommerce-help-tip:after{padding:.5em .8em;font-size:1.2em;line-height:inherit}}@media screen and (max-width:860px){#wpo-wcpdf-preview-wrapper[data-preview-states="1"] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="2"][data-preview-state=closed] .sidebar .form-table>tbody>tr,#wpo-wcpdf-preview-wrapper[data-preview-states="3"][data-preview-state=closed] .sidebar .form-table>tbody>tr{display:block}}div.upgrade-table-description{padding:0 0 3em 1em}div.upgrade-table-description h1{font-family:serif;letter-spacing:-1px;font-size:3em}div.upgrade-table-description p{font-size:1.1em}#upgrade-table{width:100%;border-collapse:collapse;font-size:1.2em;margin-bottom:3em}#upgrade-table td,#upgrade-table th{padding:.8em 2em;border-bottom:1px solid #ccc;text-align:center}#upgrade-table th{font-weight:400;font-size:1.1em}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:200px}#upgrade-table tr:last-child td{border:none}#upgrade-table td.feature-label{text-align:left;padding-left:1em;font-weight:700;width:500px}#upgrade-table td.feature-label span.description{display:inline-block;padding-top:10px;font-size:.8em;line-height:1.4em;font-weight:400;color:#555}#upgrade-table td span.feature-available{display:inline-block;width:24px;height:24px;background-repeat:no-repeat;background-size:cover}#upgrade-table a,div.upgrade-table-description a{color:#6e1edc;white-space:nowrap}#upgrade-table .upgrade-links h4{margin:1em 0 .5em 0}#upgrade-table .upgrade-links p{margin:0;font-style:oblique;font-size:.8em}#plugin-recommendations a.upgrade_button,#upgrade-table .upgrade-links a.upgrade_button{display:inline-block;background:#fff;padding:1em 3em 1em 2em;border-radius:12px;border:1px solid #6e1edc;text-decoration:none;margin:2em 0;position:relative}#plugin-recommendations a.upgrade_button:after,#upgrade-table .upgrade-links a.upgrade_button:after{content:' \2192';display:block;position:absolute;right:1.8em;top:1.1em;transition:.5s}#plugin-recommendations a.upgrade_button:hover:after,#upgrade-table .upgrade-links a.upgrade_button:hover:after{right:1.1em;font-weight:700}#plugin-recommendations a.upgrade_button:focus,#plugin-recommendations a.upgrade_button:hover,#upgrade-table .upgrade-links a.upgrade_button:focus,#upgrade-table .upgrade-links a.upgrade_button:hover{background:#6e1edc;color:#fcfbf7}#plugin-recommendations{border-radius:8px;background-color:#f1e9fc;padding:4em 3em}#plugin-recommendations .card-container{max-width:1100px;display:grid;grid-template-columns:repeat(3,1fr);grid-gap:3em;padding:2em 0}#plugin-recommendations .recommendation-card{margin-top:0;border-radius:6px;background-color:#fff;box-shadow:0 0 25px -10px rgba(0,0,0,.2);box-sizing:border-box;font-size:15px;overflow:hidden;transition:.2s}#plugin-recommendations .recommendation-card:nth-child(n+4){display:none}#plugin-recommendations .recommendation-card:hover{scale:1.02}#plugin-recommendations .recommendation-card.currently-installed{opacity:.5}#plugin-recommendations .recommendation-card .card-content{padding:0 4em 3em 2em}#plugin-recommendations .recommendation-card img{width:100%}#plugin-recommendations .recommendation-card h5{text-align:left;font-size:1.4em;line-height:1.3em;font-weight:700;margin:1em 0}#plugin-recommendations .recommendation-card p{text-align:left;padding-bottom:10px}#plugin-recommendations .recommendation-card a.upgrade_button{margin:0}#plugin-recommendations .recommendation-card span.currently-installed{font-size:.7em;color:#fff;background-color:#6e1edc;padding:1em 2em;border-radius:12px;margin:0;display:inline-block}@media screen and (max-width:1100px){#upgrade-table{font-size:1em;line-height:1.2em}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:25%;padding:.8em 1em}#upgrade-table td.last,#upgrade-table th.last{width:0;padding:0}#upgrade-table td.feature-label span.description{padding-top:6px}#plugin-recommendations .card-container{grid-gap:2em}}@media screen and (max-width:968px){#plugin-recommendations .card-container{grid-template-columns:repeat(1,1fr);padding-right:40%}}@media screen and (max-width:782px){#wpo-wcpdf-preview-wrapper .sidebar .form-table>tbody>tr>td:has(input[type=checkbox]+input[type=text])>input{display:inline-block}}@media screen and (max-width:767px){#upgrade-table td.feature-label span.description{display:none}#upgrade-table td:not(.last),#upgrade-table th:not(.last){width:20%}#upgrade-table td.first{width:40%}#plugin-recommendations .card-container{padding-right:0}}@media screen and (max-width:649px){div.upgrade-table-description{padding-left:.8em}div.upgrade-table-description p{font-size:1em}#upgrade-table{font-size:.8em}#upgrade-table td,#upgrade-table th{padding:.5em .8em!important}#upgrade-table td span.feature-available{width:18px;height:18px}#upgrade-table .upgrade-links a{white-space:normal;padding:.6em .8em;border-radius:6px}#upgrade-table .upgrade-links a:after{display:none}#plugin-recommendations .card-container{justify-content:center}}@media screen and (max-width:782px){input[type=checkbox],input[type=radio]{margin-bottom:.5em}} \ No newline at end of file diff --git a/assets/js/ubl-script.js b/assets/js/ubl-script.js new file mode 100644 index 000000000..7b7a3bde8 --- /dev/null +++ b/assets/js/ubl-script.js @@ -0,0 +1,21 @@ +jQuery( function ( $ ) { + + $( 'select[name^="wpo_wcpdf_settings_ubl_taxes"][name$="[scheme]"], \ + select[name^="wpo_wcpdf_settings_ubl_taxes"][name$="[category]"], \ + select[name^="wpo_wcpdf_settings_ubl_taxes"][name$="[reason]"]' + ).on( 'change', function () { + let currentValue = $( this ).data( 'current' ); + let newValue = $( this ).find( 'option:selected' ).val(); + let $current = $( this ).closest( 'td, th' ).find( '.current' ); + let newHtml = `${wpo_wcpdf_ubl.new}: ${newValue} (${wpo_wcpdf_ubl.unsaved})`; + let oldHtml = `${wpo_wcpdf_ubl.code}: ${currentValue}`; + + // Only update the '.current' element if the value has changed + if ( newValue !== currentValue ) { + $current.html( newHtml ); + } else { + $current.html( oldHtml ); + } + } ); + +} ); diff --git a/assets/js/ubl-script.min.js b/assets/js/ubl-script.min.js new file mode 100644 index 000000000..736392422 --- /dev/null +++ b/assets/js/ubl-script.min.js @@ -0,0 +1 @@ +jQuery(function(a){a("select[name^=\"wpo_wcpdf_settings_ubl_taxes\"][name$=\"[scheme]\"], \t\tselect[name^=\"wpo_wcpdf_settings_ubl_taxes\"][name$=\"[category]\"], \t\tselect[name^=\"wpo_wcpdf_settings_ubl_taxes\"][name$=\"[reason]\"]").on("change",function(){let b=a(this).data("current"),c=a(this).find("option:selected").val(),d=a(this).closest("td, th").find(".current"),e=`${wpo_wcpdf_ubl.new}: ${c} (${wpo_wcpdf_ubl.unsaved})`,f=`${wpo_wcpdf_ubl.code}: ${b}`;c===b?d.html(f):d.html(e)})}); \ No newline at end of file diff --git a/includes/Assets.php b/includes/Assets.php index 5ac10cd24..05454b94e 100644 --- a/includes/Assets.php +++ b/includes/Assets.php @@ -236,7 +236,7 @@ public function backend_scripts_styles ( $hook ) { } // status/debug page scripts - if ( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'wpo_wcpdf_options_page' && isset( $_REQUEST['tab'] ) && $_REQUEST['tab'] == 'debug' ) { + if ( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'wpo_wcpdf_options_page' && isset( $_REQUEST['tab'] ) && 'debug' === $_REQUEST['tab'] ) { wp_enqueue_style( 'wpo-wcpdf-jquery-ui-styles', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css' @@ -279,6 +279,27 @@ public function backend_scripts_styles ( $hook ) { ); } + + // ubl taxes + if ( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'wpo_wcpdf_options_page' && isset( $_REQUEST['tab'] ) && 'ubl' === $_REQUEST['tab'] ) { + wp_enqueue_script( + 'wpo-wcpdf-ubl', + WPO_WCPDF()->plugin_url() . '/assets/js/ubl-script' . $suffix . '.js', + array( 'jquery' ), + WPO_WCPDF_VERSION, + true + ); + + wp_localize_script( + 'wpo-wcpdf-ubl', + 'wpo_wcpdf_ubl', + array( + 'code' => __( 'Code', 'woocommerce-pdf-invoices-packing-slips' ), + 'new' => __( 'New', 'woocommerce-pdf-invoices-packing-slips' ), + 'unsaved' => __( 'unsaved', 'woocommerce-pdf-invoices-packing-slips' ), + ) + ); + } } } diff --git a/includes/Settings/SettingsUbl.php b/includes/Settings/SettingsUbl.php index 8f2507bf8..0e5ecead4 100644 --- a/includes/Settings/SettingsUbl.php +++ b/includes/Settings/SettingsUbl.php @@ -60,6 +60,7 @@ public function output( $active_section ) { default: case 'taxes': echo '

' . esc_html__( 'To ensure compliance with e-invoicing requirements, please complete the Taxes Classification. This information is essential for accurately generating legally compliant invoices.', 'woocommerce-pdf-invoices-packing-slips' ) . '

'; + echo '

' . esc_html__( 'Note', 'woocommerce-pdf-invoices-packing-slips' ) . ': ' . esc_html__( 'Each rate line allows you to configure the tax scheme, category, and reason. If these values are set to "Default," they will automatically inherit the settings selected in the "Tax class default" dropdowns at the bottom of the table.', 'woocommerce-pdf-invoices-packing-slips' ) . '

'; $setting = new UblTaxSettings(); $setting->output(); break; diff --git a/ubl/Settings/TaxesSettings.php b/ubl/Settings/TaxesSettings.php index 08675f7f7..67a5c0515 100644 --- a/ubl/Settings/TaxesSettings.php +++ b/ubl/Settings/TaxesSettings.php @@ -43,17 +43,18 @@ public function output_table_for_tax_class( $slug, $name ) { ?>

- +
- - + + - - - - + + + + + @@ -79,27 +80,56 @@ public function output_table_for_tax_class( $slug, $name ) { } } - $country = empty( $result->tax_rate_country ) ? '*' : $result->tax_rate_country; - $state = empty( $result->tax_rate_state ) ? '*' : $result->tax_rate_state; - $postcode = empty( $postcode ) ? '*' : implode( '; ', $postcode ); - $city = empty( $city ) ? '*' : implode( '; ', $city ); - $scheme = isset( $this->settings['rate'][ $result->tax_rate_id ]['scheme'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['scheme'] : 'default'; - $category = isset( $this->settings['rate'][ $result->tax_rate_id ]['category'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['category'] : 'default'; - $reason = isset( $this->settings['rate'][ $result->tax_rate_id ]['reason'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['reason'] : 'default'; + $country = empty( $result->tax_rate_country ) ? '*' : $result->tax_rate_country; + $state = empty( $result->tax_rate_state ) ? '*' : $result->tax_rate_state; + $postcode = empty( $postcode ) ? '*' : implode( '; ', $postcode ); + $city = empty( $city ) ? '*' : implode( '; ', $city ); + + $scheme = isset( $this->settings['rate'][ $result->tax_rate_id ]['scheme'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['scheme'] : 'default'; + $scheme_default = isset( $this->settings['class'][ $slug ]['scheme'] ) ? $this->settings['class'][ $slug ]['scheme'] : 'default'; + $scheme_code = ( 'default' === $scheme ) ? $scheme_default : $scheme; + $category = isset( $this->settings['rate'][ $result->tax_rate_id ]['category'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['category'] : 'default'; + $category_default = isset( $this->settings['class'][ $slug ]['category'] ) ? $this->settings['class'][ $slug ]['category'] : 'default'; + $category_code = ( 'default' === $category ) ? $category_default : $category; + + $reason = isset( $this->settings['rate'][ $result->tax_rate_id ]['reason'] ) ? $this->settings['rate'][ $result->tax_rate_id ]['reason'] : 'default'; + $reason_default = isset( $this->settings['class'][ $slug ]['reason'] ) ? $this->settings['class'][ $slug ]['reason'] : 'default'; + $reason_code = ( 'default' === $reason ) ? $reason_default : $reason; + echo ''; echo ''; echo ''; echo ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; } } else { - echo ''; + echo ''; } ?> @@ -111,9 +141,35 @@ public function output_table_for_tax_class( $slug, $name ) { $category = isset( $this->settings['class'][ $slug ]['category'] ) ? $this->settings['class'][ $slug ]['category'] : 'default'; $reason = isset( $this->settings['class'][ $slug ]['reason'] ) ? $this->settings['class'][ $slug ]['reason'] : 'default'; ?> - - - + + + +
' . $country . '' . $state . '' . $postcode . '' . $city . '' . $result->tax_rate . '' . $this->get_select_for( 'scheme', 'rate', $result->tax_rate_id, $scheme ) . '' . $this->get_select_for( 'category', 'rate', $result->tax_rate_id, $category ) . '' . $this->get_select_for( 'reason', 'rate', $result->tax_rate_id, $reason ) . '' . wc_round_tax_total( $result->tax_rate ) . '%'; + echo $this->get_select_for( 'scheme', 'rate', $result->tax_rate_id, $scheme ); + echo '
' . __( 'Code', 'woocommerce-pdf-invoices-packing-slips' ) . ': ' . $scheme_code . '
'; + echo '
'; + echo $this->get_select_for( 'category', 'rate', $result->tax_rate_id, $category ); + echo '
' . __( 'Code', 'woocommerce-pdf-invoices-packing-slips' ) . ': ' . $category_code . '
'; + echo '
'; + echo $this->get_select_for( 'reason', 'rate', $result->tax_rate_id, $reason ); + echo '
' . __( 'Code', 'woocommerce-pdf-invoices-packing-slips' ) . ': ' . $reason_code . '
'; + echo '
'; + + foreach ( $this->get_available_remarks() as $field => $remarks ) { + foreach ( array( 'scheme', 'category', 'reason' ) as $f ) { + if ( isset( $remarks[ ${$f} ] ) ) { + echo '

' . ${$f} . ': ' . $remarks[ ${$f} ] . '

'; + } + } + } + + echo '
' . __( 'No taxes found for this class.', 'woocommerce-pdf-invoices-packing-slips' ) . '
' . __( 'No taxes found for this class.', 'woocommerce-pdf-invoices-packing-slips' ) . '
get_select_for( 'scheme', 'class', $slug, $scheme ); ?>get_select_for( 'category', 'class', $slug, $category ); ?>get_select_for( 'reason', 'class', $slug, $reason ); ?> + get_select_for( 'scheme', 'class', $slug, $scheme ); + echo '
' . __( 'Code', 'woocommerce-pdf-invoices-packing-slips' ) . ': ' . $scheme . '
'; + ?> +
+ get_select_for( 'category', 'class', $slug, $category ); + echo '
' . __( 'Code', 'woocommerce-pdf-invoices-packing-slips' ) . ': ' . $category . '
'; + ?> +
+ get_select_for( 'reason', 'class', $slug, $reason ); + echo '
' . __( 'Code', 'woocommerce-pdf-invoices-packing-slips' ) . ': ' . $reason . '
'; + ?> +
+ get_available_remarks() as $field => $remarks ) { + foreach ( array( 'scheme', 'category', 'reason' ) as $f ) { + if ( isset( $remarks[ ${$f} ] ) ) { + echo '

' . ${$f} . ': ' . $remarks[ ${$f} ] . '

'; + } + } + } + ?> +
@@ -150,7 +206,7 @@ public function get_select_for( string $for, string $type, string $id, string $s $options = array(); } - $select = ''; foreach ( $defaults as $key => $value ) { if ( 'class' === $type && 'default' === $key ) { @@ -288,15 +344,57 @@ public static function get_available_reasons(): array { 'VATEX-EU-143-1J' => __( 'Exempt based on article 143, section 1 (j) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), 'VATEX-EU-143-1K' => __( 'Exempt based on article 143, section 1 (k) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), 'VATEX-EU-143-1L' => __( 'Exempt based on article 143, section 1 (l) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), - 'VATEX-EU-151' => __( 'Exempt based on article 151 of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-148' => __( 'Exempt based on article 148 of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-148-A' => __( 'Exempt based on article 148, section (a) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-148-B' => __( 'Exempt based on article 148, section (b) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-148-C' => __( 'Exempt based on article 148, section (c) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-148-D' => __( 'Exempt based on article 148, section (d) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-148-E' => __( 'Exempt based on article 148, section (e) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-148-F' => __( 'Exempt based on article 148, section (f) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-148-G' => __( 'Exempt based on article 148, section (g) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-151-1A' => __( 'Exempt based on article 151, section 1 (a) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-151-1AA' => __( 'Exempt based on article 151, section 1 (aa) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-151-1B' => __( 'Exempt based on article 151, section 1 (b) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-151-1C' => __( 'Exempt based on article 151, section 1 (c) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-151-1D' => __( 'Exempt based on article 151, section 1 (d) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-151-1E' => __( 'Exempt based on article 151, section 1 (e) of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-309' => __( 'Exempt based on article 309 of Council Directive 2006/112/EC', 'woocommerce-pdf-invoices-packing-slips' ), 'VATEX-EU-AE' => __( 'Reverse charge', 'woocommerce-pdf-invoices-packing-slips' ), - 'VATEX-EU-D' => __( 'Intra-Community acquisition from second hand means of transport', 'woocommerce-pdf-invoices-packing-slips' ), - 'VATEX-EU-F' => __( 'Intra-Community acquisition of second hand goods', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-D' => __( 'Travel agents VAT scheme.', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-F' => __( 'Second hand goods VAT scheme.', 'woocommerce-pdf-invoices-packing-slips' ), 'VATEX-EU-G' => __( 'Export outside the EU', 'woocommerce-pdf-invoices-packing-slips' ), - 'VATEX-EU-I' => __( 'Intra-Community acquisition of works of art', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-I' => __( 'Works of art VAT scheme.', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-IC' => __( 'Intra-community supply', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-J' => __( 'Collectors items and antiques VAT scheme.', 'woocommerce-pdf-invoices-packing-slips' ), + 'VATEX-EU-O' => __( 'Not subject to VAT', 'woocommerce-pdf-invoices-packing-slips' ), 'VATEX-FR-FRANCHISE' => __( 'France domestic VAT franchise in base', 'woocommerce-pdf-invoices-packing-slips' ), 'VATEX-FR-CNWVAT' => __( 'France domestic Credit Notes without VAT, due to supplier forfeit of VAT for discount', 'woocommerce-pdf-invoices-packing-slips' ), ) ); } + + /** + * Get available remarks + * + * @return array + */ + public function get_available_remarks(): array { + /* translators: %s: tax category code */ + $reason_common_remark = __( 'Only use with tax category code %s', 'woocommerce-pdf-invoices-packing-slips' ); + + return apply_filters( 'wpo_wcpdf_ubl_tax_remarks', array( + 'scheme' => array(), + 'category' => array(), + 'reason' => array( + 'VATEX-EU-AE' => sprintf( $reason_common_remark, 'AE' ), + 'VATEX-EU-D' => sprintf( $reason_common_remark, 'E' ), + 'VATEX-EU-F' => sprintf( $reason_common_remark, 'E' ), + 'VATEX-EU-G' => sprintf( $reason_common_remark, 'G' ), + 'VATEX-EU-I' => sprintf( $reason_common_remark, 'E' ), + 'VATEX-EU-IC' => sprintf( $reason_common_remark, 'K' ), + 'VATEX-EU-J' => sprintf( $reason_common_remark, 'E' ), + 'VATEX-EU-O' => sprintf( $reason_common_remark, 'O' ), + ), + ) ); + } } diff --git a/views/settings-page.php b/views/settings-page.php index 98a3a7684..866077dca 100644 --- a/views/settings-page.php +++ b/views/settings-page.php @@ -58,7 +58,7 @@ $preview_states = isset( $settings_tabs[ $active_tab ]['preview_states'] ) ? $settings_tabs[ $active_tab ]['preview_states'] : 1; $preview_states_lock = $preview_states == 3 ? false : true; ?> -
+