diff --git a/assets/scripts/admin/admin.ts b/assets/scripts/admin/admin.ts index 15305b4..127aeca 100644 --- a/assets/scripts/admin/admin.ts +++ b/assets/scripts/admin/admin.ts @@ -1,9 +1,11 @@ import { WpRouter } from '@wptoolset/router'; import { CompanySettingsController } from './controllers/company-settings.controller'; import { SlipSettingsController } from './controllers/slip-settings.controller'; +import { OrderEditController } from './controllers/order-edit.controller'; document.addEventListener('DOMContentLoaded', () => new WpRouter({ + wcsrbOrderEdit: () => new OrderEditController(), wcsrbCompanySettings: () => new CompanySettingsController(), wcsrbSlipSettings: () => new SlipSettingsController(), }).loadEvents(), diff --git a/assets/scripts/admin/controllers/order-edit.controller.ts b/assets/scripts/admin/controllers/order-edit.controller.ts new file mode 100644 index 0000000..bea4738 --- /dev/null +++ b/assets/scripts/admin/controllers/order-edit.controller.ts @@ -0,0 +1,16 @@ +const $ = jQuery; + +export class OrderEditController { + init(): void {} + + finalize(): void { + $(document.body).on('click', 'button.wcsrb-copy-ips-qr', (e) => this.copyIpsQrCode(e)); + } + + private copyIpsQrCode(e: JQuery.ClickEvent): void { + e.preventDefault(); + navigator.clipboard.writeText($(e.target).data('ips').s).then(() => { + $(e.target).parent().find('.ips-qr-copy-success').fadeIn('fast').delay(800).fadeOut('fast'); + }); + } +} diff --git a/assets/styles/admin.scss b/assets/styles/admin.scss index 2dba6d2..d2ce06e 100644 --- a/assets/styles/admin.scss +++ b/assets/styles/admin.scss @@ -14,3 +14,13 @@ user-select: none; } } + +#wcsrb-ips-qr-code { + .ips-qr-copy-success { + display: inline-block; + line-height: 30px; + min-height: 30px; + margin-left: 10px; + color: rgb(134, 212, 76); + } +} diff --git a/assets/styles/email/template.scss b/assets/styles/email/template.scss new file mode 100644 index 0000000..8ce8277 --- /dev/null +++ b/assets/styles/email/template.scss @@ -0,0 +1,11 @@ +#outer_wrapper > tr:first-child > td:nth-child(2) { + width: 800px !important; +} + +#template_body, +#template_container, +#template_footer, +#wrapper { + width: 100% !important; + max-width: 800px !important; +} diff --git a/assets/webpack/wpwp.config.ts b/assets/webpack/wpwp.config.ts index b3d8f23..d034f1d 100644 --- a/assets/webpack/wpwp.config.ts +++ b/assets/webpack/wpwp.config.ts @@ -10,6 +10,10 @@ const config: Partial = { name: 'front', files: ['./scripts/frontend/main.ts', './styles/main.scss'], }, + { + name: 'email', + files: ['./styles/email/template.scss'], + }, ], paths: { scripts: { src: 'scripts', dist: 'js' }, diff --git a/composer.lock b/composer.lock index e518cf0..c38ad91 100644 --- a/composer.lock +++ b/composer.lock @@ -638,7 +638,7 @@ }, { "name": "x-wp/helper-functions", - "version": "v1.13.1", + "version": "v1.13.4", "source": { "type": "git", "url": "https://github.com/x-wp/helper-functions.git", @@ -688,13 +688,13 @@ ], "support": { "issues": "https://github.com/x-wp/helper-functions/issues", - "source": "https://github.com/x-wp/helper-functions/tree/v1.13.1" + "source": "https://github.com/x-wp/helper-functions/tree/v1.13.4" }, "time": "2024-09-23T14:26:03+00:00" }, { "name": "x-wp/helper-traits", - "version": "v1.13.1", + "version": "v1.13.4", "source": { "type": "git", "url": "https://github.com/x-wp/helper-traits.git", @@ -740,26 +740,27 @@ ], "support": { "issues": "https://github.com/x-wp/helper-traits/issues", - "source": "https://github.com/x-wp/helper-traits/tree/v1.13.1" + "source": "https://github.com/x-wp/helper-traits/tree/v1.13.4" }, "time": "2024-09-18T12:43:44+00:00" }, { "name": "x-wp/helper-woocommerce", - "version": "v1.13.1", + "version": "v1.13.4", "source": { "type": "git", "url": "https://github.com/x-wp/helper-woocommerce.git", - "reference": "15d74e968ca875df0cdd5084337c7fed4a03c3cb" + "reference": "2b8c5483ef604079ec79df1c6bc412b87fd8569f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/x-wp/helper-woocommerce/zipball/15d74e968ca875df0cdd5084337c7fed4a03c3cb", - "reference": "15d74e968ca875df0cdd5084337c7fed4a03c3cb", + "url": "https://api.github.com/repos/x-wp/helper-woocommerce/zipball/2b8c5483ef604079ec79df1c6bc412b87fd8569f", + "reference": "2b8c5483ef604079ec79df1c6bc412b87fd8569f", "shasum": "" }, "require": { - "php": ">=8.0" + "php": ">=8.0", + "x-wp/helper-functions": "^1.13" }, "suggest": { "automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package." @@ -790,9 +791,9 @@ ], "support": { "issues": "https://github.com/x-wp/helper-woocommerce/issues", - "source": "https://github.com/x-wp/helper-woocommerce/tree/v1.13.1" + "source": "https://github.com/x-wp/helper-woocommerce/tree/v1.13.4" }, - "time": "2024-09-25T09:23:08+00:00" + "time": "2024-09-27T15:59:21+00:00" }, { "name": "x-wp/wc-template-customizer", @@ -1448,16 +1449,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.31.0", + "version": "1.32.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "249f15fb843bf240cf058372dad29e100cee6c17" + "reference": "6ca22b154efdd9e3c68c56f5d94670920a1c19a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/249f15fb843bf240cf058372dad29e100cee6c17", - "reference": "249f15fb843bf240cf058372dad29e100cee6c17", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6ca22b154efdd9e3c68c56f5d94670920a1c19a4", + "reference": "6ca22b154efdd9e3c68c56f5d94670920a1c19a4", "shasum": "" }, "require": { @@ -1489,22 +1490,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.31.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.32.0" }, - "time": "2024-09-22T11:32:18+00:00" + "time": "2024-09-26T07:23:32+00:00" }, { "name": "phpstan/phpstan", - "version": "1.12.4", + "version": "1.12.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "ffa517cb918591b93acc9b95c0bebdcd0e4538bd" + "reference": "7e6c6cb7cecb0a6254009a1a8a7d54ec99812b17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ffa517cb918591b93acc9b95c0bebdcd0e4538bd", - "reference": "ffa517cb918591b93acc9b95c0bebdcd0e4538bd", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7e6c6cb7cecb0a6254009a1a8a7d54ec99812b17", + "reference": "7e6c6cb7cecb0a6254009a1a8a7d54ec99812b17", "shasum": "" }, "require": { @@ -1549,7 +1550,7 @@ "type": "github" } ], - "time": "2024-09-19T07:58:01+00:00" + "time": "2024-09-26T12:45:22+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", diff --git a/config/pg-slip-settings.php b/config/pg-slip-settings.php index bca44b8..d8f66fb 100644 --- a/config/pg-slip-settings.php +++ b/config/pg-slip-settings.php @@ -6,26 +6,75 @@ * @see Payment_Slip_Gateway */ +use Automattic\WooCommerce\Utilities\LoggingUtil; + defined( 'ABSPATH' ) || exit; +$display_opts = static fn( $desc ) => array( + 'title' => __( 'Visibility', 'serbian-addons-for-woocommerce' ), + 'type' => 'multiselect', + 'options' => array( + 'order' => __( 'Store pages', 'serbian-addons-for-woocommerce' ), + 'email' => __( 'Customer e-mails', 'serbian-addons-for-woocommerce' ), + ), + 'default' => array(), + 'description' => $desc, + 'desc_tip' => true, + 'custom_attributes' => array( + 'data-placeholder' => __( 'Select locations for display', 'serbian-addons-for-woocommerce' ), + 'data-allow_clear' => 'true', + ), + 'class' => 'wc-enhanced-select', +); + +$qr_img_desc = static function ( int $icon ) { + $desc = array(); + + $desc[] = sprintf( + // translators: %1$s customizer link html. + __( 'You can set the image via %1$s', 'serbian-addons-for-woocommerce' ), + sprintf( + '%2$s (%3$s)', + esc_url( admin_url( 'customize.php' ) ), + esc_html__( 'Customizer', 'default' ), + esc_html__( 'Site Identity', 'default' ), + ), + ); + + if ( 0 < $icon ) { + $desc[] = sprintf( + // translators: %s current image HTML. + __( 'Current image: %s', 'serbian-addons-for-woocommerce' ), + wp_get_attachment_image( + get_option( 'site_icon' ), + array( 16, 16 ), + false, + ), + ); + } + + return implode( '
', $desc ); +}; + + return array( 'enabled' => array( - 'title' => __( 'Enable/Disable', 'serbian-addons-for-woocommerce' ), + 'title' => __( 'Enabled', 'woocommerce' ), 'label' => __( 'Enable Payment Slip', 'serbian-addons-for-woocommerce' ), 'type' => 'checkbox', 'default' => 'no', ), 'title' => array( - 'title' => __( 'Title', 'serbian-addons-for-woocommerce' ), - 'type' => 'text', - 'description' => __( 'This controls the title which the user sees during checkout.', 'serbian-addons-for-woocommerce' ), - 'default' => 'Payment Slip', + 'title' => __( 'Title', 'woocommerce' ), + 'type' => 'safe_text', + 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), + 'default' => __( 'Payment Slip', 'serbian-addons-for-woocommerce' ), 'desc_tip' => true, ), 'description' => array( - 'title' => __( 'Description', 'serbian-addons-for-woocommerce' ), + 'title' => __( 'Description', 'woocommerce' ), 'type' => 'text', - 'description' => __( 'This controls the description which the user sees during checkout.', 'serbian-addons-for-woocommerce' ), + 'description' => __( 'Payment method description that the customer will see on your checkout.', 'woocommerce' ), 'default' => __( 'Pay by sending us money via wire transfer', 'serbian-addons-for-woocommerce' ), 'desc_tip' => true, ), @@ -36,6 +85,8 @@ 'type' => 'title', 'description' => '', ), + 'display' => $display_opts( __( 'Where to display the QR Code', 'serbian-addons-for-woocommerce' ) ), + 'style' => array( 'title' => __( 'Style', 'serbian-addons-for-woocommerce' ), 'type' => 'select', @@ -58,6 +109,7 @@ '', '', ), + 'default' => '', ), 'payment_code' => array( 'title' => __( 'Payment code', 'serbian-addons-for-woocommerce' ), @@ -108,12 +160,7 @@ 'description' => __( 'Settings for NBS IPS QR Code', 'serbian-addons-for-woocommerce' ), ), - 'qrcode_shown' => array( - 'title' => __( 'Show QR code', 'serbian-addons-for-woocommerce' ), - 'type' => 'checkbox', - 'label' => __( 'Show QR code on the payment slip', 'serbian-addons-for-woocommerce' ), - 'default' => 'yes', - ), + 'qrcode_shown' => $display_opts( __( 'Where to display the payment slip', 'serbian-addons-for-woocommerce' ) ), 'qrcode_color' => array( 'title' => __( 'Dot color', 'serbian-addons-for-woocommerce' ), @@ -132,23 +179,15 @@ ), 'qrcode_image' => array( - 'title' => __( 'Show image', 'serbian-addons-for-woocommerce' ), - 'type' => 'checkbox', - 'label' => __( 'Show image on QR code', 'serbian-addons-for-woocommerce' ), - 'default' => 'yes', - 'desc_tip' => __( 'Image that will be shown on the QR code. ', 'serbian-addons-for-woocommerce' ), - 'description' => static fn() => sprintf( - // translators: %1$s opening link tag, %2$s Customizer title, %3$s closing link tag, %3$s current image HTML. - __( 'You can set it in %1$s%2$s%3$s. Current image is: %4$s', 'serbian-addons-for-woocommerce' ), - '', - __( 'Customizer', 'default' ), - '', - wp_get_attachment_image( - get_option( 'site_icon' ), - array( 16, 16 ), - false, - ), - ), + 'title' => __( 'Show image', 'serbian-addons-for-woocommerce' ), + 'type' => 'checkbox', + 'label' => __( 'Show image on QR code', 'serbian-addons-for-woocommerce' ), + 'default' => 'yes', + 'desc_tip' => __( 'Image that will be shown on the QR code. ', 'serbian-addons-for-woocommerce' ), + 'description' => static fn() => $qr_img_desc( intval( get_option( 'site_icon', 0 ) ) ), + 'custom_attributes' => static fn() => 0 === intval( get_option( 'site_icon', 0 ) ) + ? array( 'disabled' => 'disabled' ) + : array(), ), // Advanced Settings. @@ -158,18 +197,14 @@ 'description' => '', ), 'debug' => array( - 'title' => __( 'Debug log', 'serbian-addons-for-woocommerce' ), + 'title' => __( 'Debug log', 'woocommerce' ), 'type' => 'checkbox', - 'label' => __( 'Enable logging', 'serbian-addons-for-woocommerce' ), + 'label' => __( 'Enable logging', 'woocommerce' ), 'default' => 'no', 'description' => static fn() => sprintf( - // translators: %1$s log file path, %2$s line break. - __( - 'Log Payment Slip events, inside %1$s %2$sNote: this may log personal information. We recommend using this for debugging purposes only and deleting the logs when finished.', - 'serbian-addons-for-woocommerce', - ), - '' . WC_Log_Handler_File::get_log_file_path( 'payment-slip' ) . '', - '
', + // translators: %s is a placeholder for a URL. + __( 'Log Payment Slip events and review them on the Logs screen.
Note: this may log personal information. We recommend using this for debugging purposes only and deleting the logs when finished.', 'serbian-addons-for-woocommerce' ), + esc_url( LoggingUtil::get_logs_tab_url() ), ), ), diff --git a/gen.http b/gen.http new file mode 100644 index 0000000..b0165d3 --- /dev/null +++ b/gen.http @@ -0,0 +1,17 @@ +POST https://www.nbs.rs/QRcode/api/qr/v1/generate?lang=en_US +Accept: application/json +Content-Type: text/plain +Host: www.nbs.rs +Origin: https://ips.nbs.rs + +K:PR|V:01|C:1|R:160000000042863406|N:SGI +Pozeska +11000 Beograd, Srbija|I:RSD45,00|P:Miroslavski Astalovski Šćekić|SF:289|S:Plaćanje narudžbine|RO:97481472024 + +### + +POST https://www.nbs.rs/QRcode/api/qr/v1/generate?lang=sr_RS_latn + +K:PR|V:01|C:1|R:160000000042863406|N:SGI +Pozeska +11000 Beograd, Srbija|I:RSD45,01|P:Miroslavski Astalovski Šćekić|SF:289|S:Plaćanje narudžbine|RO:974814720241 diff --git a/languages/serbian-addons-for-woocommerce-sr_RS.mo b/languages/serbian-addons-for-woocommerce-sr_RS.mo index 650168b..350ca77 100644 Binary files a/languages/serbian-addons-for-woocommerce-sr_RS.mo and b/languages/serbian-addons-for-woocommerce-sr_RS.mo differ diff --git a/languages/serbian-addons-for-woocommerce-sr_RS.po b/languages/serbian-addons-for-woocommerce-sr_RS.po index d8811d0..e493f49 100644 --- a/languages/serbian-addons-for-woocommerce-sr_RS.po +++ b/languages/serbian-addons-for-woocommerce-sr_RS.po @@ -2,7 +2,7 @@ # This file is distributed under the same license as the Plugins - Serbian Addons for WooCommerce - Stable (latest release) package. msgid "" msgstr "" -"PO-Revision-Date: 2024-09-25 10:40+0000\n" +"PO-Revision-Date: 2024-09-27 21:56+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -12,7 +12,11 @@ msgstr "" "Language: sr_RS\n" "Project-Id-Version: Plugins - Serbian Addons for WooCommerce - Stable " "(latest release)\n" -"Language-Team: Српски језик" +"Language-Team: Српски језик\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-09-27 21:55+0000\n" +"Last-Translator: \n" +"X-Loco-Version: 2.6.11; wp-6.6.2" #: woocommerce/checkout/payment-slip-qr-code.php:40 msgid "" @@ -20,85 +24,81 @@ msgid "" msgstr " Безбедност гарантују стандарди и прописи Народне Банке Србије" #. Translators: %d is the payment code. -#: lib/Utils/wcsrb-settings.php:52 +#: lib/Functions/wcsrb-settings.php:52 msgid "%d - Final expenses" msgstr "%d - Финална потрошња" #. Translators: %d is the payment code. -#: lib/Utils/wcsrb-settings.php:50 +#: lib/Functions/wcsrb-settings.php:50 msgid "%d - Interim expenses" msgstr "%d - Међуфазна потрошња" #. Translators: %d is the payment code. -#: lib/Utils/wcsrb-settings.php:61 +#: lib/Functions/wcsrb-settings.php:61 msgid "%d - Other transactions" msgstr "%d - Остале трансакције" #. Translators: %d is the payment code. -#: lib/Utils/wcsrb-settings.php:57 +#: lib/Functions/wcsrb-settings.php:57 msgid "%d - Transactions on behalf of a person" msgstr "%d - Трансакције по налогу грађана" #. Translators: %s is the bank name. -#: lib/Utils/wcsrb-helpers.php:37 +#: lib/Functions/wcsrb-helpers.php:37 msgid "%s Bank" msgstr "%s Банка" -#: woocommerce/checkout/payment-slip.php:144 +#: woocommerce/checkout/payment-slip.php:151 msgid "Account payable" msgstr "Рачун примаоца" -#: config/pg-slip-settings.php:40 -msgid "Add to e-mail" -msgstr "" - -#: lib/Utils/wcsrb-helpers.php:46 +#: lib/Functions/wcsrb-helpers.php:46 msgid "Addiko" msgstr "Адико" -#: lib/Order/Field_Display.php:134 +#: lib/Core/Address_Display_Controller.php:116 msgctxt "Address display" msgid "Company Number" msgstr "МБ" -#: lib/Order/Field_Display.php:140 +#: lib/Core/Address_Display_Controller.php:121 msgctxt "Address display" msgid "Tax Identification Number" msgstr "ПИБ" -#: config/pg-slip-settings.php:169 +#: config/pg-slip-settings.php:195 msgid "Advanced Settings" msgstr "Напредна подешавања" -#: lib/Utils/wcsrb-helpers.php:40 +#: lib/Functions/wcsrb-helpers.php:40 msgid "AIK" msgstr "АИК" -#: lib/Utils/wcsrb-helpers.php:48 +#: lib/Functions/wcsrb-helpers.php:48 msgid "Alta" msgstr "Алта" -#: woocommerce/checkout/payment-slip.php:114 +#: woocommerce/checkout/payment-slip.php:121 msgid "Amount" msgstr "Износ" -#: lib/Utils/wcsrb-helpers.php:63 +#: lib/Functions/wcsrb-helpers.php:63 msgid "API" msgstr "АПИ" -#: lib/Utils/wcsrb-payment-slip.php:40 lib/Utils/wcsrb-settings.php:44 +#: lib/Functions/wcsrb-payment-slip.php:94 lib/Functions/wcsrb-settings.php:44 msgid "Automatic" msgstr "Аутоматски" -#: lib/Utils/wcsrb-helpers.php:45 +#: lib/Functions/wcsrb-helpers.php:45 msgid "Banca Intesa" msgstr "Банка Интеза" -#: config/pg-slip-settings.php:57 +#: config/pg-slip-settings.php:102 msgid "Bank account" msgstr "Жиро рачун" -#: config/pg-slip-settings.php:60 +#: config/pg-slip-settings.php:105 msgid "Bank account number" msgstr "Број рачуна" @@ -110,7 +110,7 @@ msgstr "Жиро рачуни" msgid "Bank accounts of your business." msgstr "Жиро рачуни ваше фирме." -#: lib/Utils/wcsrb-helpers.php:65 +#: lib/Functions/wcsrb-helpers.php:65 msgid "Bank of China" msgstr "Кинеска банка" @@ -126,7 +126,7 @@ msgstr "" "опције ће пресловити валуту" #. translators: %1$s line break. -#: config/pg-slip-settings.php:89 +#: config/pg-slip-settings.php:135 msgid "" "Choosing the model 97 will automatically set the payment reference.%1$sWe " "recommend using model 97 because payment processor guarantees verbatim " @@ -138,15 +138,15 @@ msgstr "" "позива на број одобрења само ако је позив на број уписан у складу са моделом " "97 " -#: config/pg-slip-settings.php:49 +#: config/pg-slip-settings.php:94 msgid "Classic" msgstr "Класични" -#: config/pg-slip-settings.php:143 +#: config/pg-slip-settings.php:177 msgid "Color of the corner dots on the QR code" msgstr "Боја тачака у углу QR кôда" -#: config/pg-slip-settings.php:135 +#: config/pg-slip-settings.php:169 msgid "Color of the dots on the QR code" msgstr "Боја тачака QR кôда" @@ -154,8 +154,8 @@ msgstr "Боја тачака QR кôда" msgid "Companies and persons" msgstr "Физичка и правна лица" -#: lib/Utils/wcsrb-helpers.php:17 lib/Utils/wcsrb-settings.php:48 -#: lib/Utils/wcsrb-settings.php:67 lib/Utils/wcsrb-settings.php:71 +#: lib/Functions/wcsrb-helpers.php:17 lib/Functions/wcsrb-settings.php:48 +#: lib/Functions/wcsrb-settings.php:67 lib/Functions/wcsrb-settings.php:71 msgid "Company" msgstr "Правно лице" @@ -163,19 +163,26 @@ msgstr "Правно лице" msgid "Company information" msgstr "Подаци о фирми" -#: lib/Checkout/Field_Validator.php:117 +#: lib/Services/Field_Validator.php:156 msgid "Company name is required" msgstr "Морате унети име фирме" -#: lib/Checkout/Field_Customizer.php:183 lib/Order/Field_Display.php:186 +#: lib/Core/Address_Admin_Controller.php:70 +#: lib/Core/Address_Admin_Controller.php:140 +#: lib/Functions/wcsrb-address-field-fns.php:19 msgid "Company Number" msgstr "Матични број" -#: lib/Checkout/Field_Validator.php:122 +#: lib/Core/Address_Admin_Controller.php:27 +msgid "Company Number is invalid" +msgstr "Матични број компаније није исправан" + +#: lib/Services/Field_Validator.php:162 msgid "Company number is invalid" msgstr "Матични број фирме није валидан" -#: lib/Checkout/Field_Validator.php:127 +#: lib/Core/Address_Admin_Controller.php:26 +#: lib/Services/Field_Validator.php:168 msgid "Company Tax Number is invalid" msgstr "ПИБ није валидан" @@ -183,54 +190,57 @@ msgstr "ПИБ није валидан" msgid "Confirm with your PIN or fingerprint" msgstr "Потврдите плаћање ПИН кодом или отиском прста" -#: config/pg-slip-settings.php:140 +#: lib/Admin/Order_Edit_Page_Controller.php:128 +msgid "Copied!" +msgstr "Копирано!" + +#: lib/Admin/Order_Edit_Page_Controller.php:127 +msgid "Copy IPS QR string" +msgstr "Копирај ИПС QR запис" + +#: config/pg-slip-settings.php:174 msgid "Corner dot color" msgstr "Боја тачака у угловима" -#: lib/Utils/wcsrb-helpers.php:59 +#: lib/Functions/wcsrb-helpers.php:59 msgid "Credit Agricole" msgstr "Кредит агриколе" -#: lib/Utils/wcsrb-payment-slip.php:64 +#. translators: %s current image HTML. +#: config/pg-slip-settings.php:47 +msgid "Current image: %s" +msgstr "Тренутна слика: %s" + +#: config/pg-slip-settings.php:18 +msgid "Customer e-mails" +msgstr "Е-пошта послата купцу" + +#: lib/Functions/wcsrb-payment-slip.php:118 msgid "Customer ID" msgstr "Идентификатор купца" -#: lib/Checkout/Field_Customizer.php:149 lib/Order/Field_Display.php:178 +#: lib/Core/Address_Admin_Controller.php:63 +#: lib/Core/Address_Admin_Controller.php:132 +#: lib/Core/Address_Field_Controller.php:34 msgid "Customer type" msgstr "Купујем као" -#: config/pg-slip-settings.php:174 -msgid "Debug log" -msgstr "Лог за дебаговање" - -#: config/pg-slip-settings.php:53 +#: config/pg-slip-settings.php:98 msgid "Defines the style of the payment slip" msgstr "Изглед опште уплатнице" -#: config/pg-slip-settings.php:26 -msgid "Description" -msgstr "Опис" - -#: lib/Utils/wcsrb-helpers.php:43 +#: lib/Functions/wcsrb-helpers.php:43 msgid "Direct" msgstr "Директна" -#: config/pg-slip-settings.php:132 +#: config/pg-slip-settings.php:166 msgid "Dot color" msgstr "Боја тачака" -#: config/pg-slip-settings.php:176 -msgid "Enable logging" -msgstr "Омогући логовање" - -#: config/pg-slip-settings.php:14 +#: config/pg-slip-settings.php:63 msgid "Enable Payment Slip" msgstr "Активирај плаћање општом уплатницом" -#: config/pg-slip-settings.php:13 -msgid "Enable/Disable" -msgstr "Активирај/Деактивирај" - #: config/settings.php:23 msgid "Enabled customer types" msgstr "Дозвољени типови купаца" @@ -239,26 +249,22 @@ msgstr "Дозвољени типови купаца" msgid "Enter bank account" msgstr "Унесите жиро рачун" -#: lib/Checkout/Field_Customizer.php:184 -msgid "Enter MB" -msgstr "" - -#: lib/Checkout/Field_Customizer.php:193 -msgid "Enter PIB" -msgstr "" - -#: lib/Utils/wcsrb-helpers.php:60 +#: lib/Functions/wcsrb-helpers.php:60 msgid "Erste" msgstr "Ерсте" -#: lib/Utils/wcsrb-helpers.php:52 +#: lib/Functions/wcsrb-helpers.php:52 msgid "Eurobank Direct" msgstr "Еуробанк Директна" -#: lib/Utils/wcsrb-helpers.php:42 +#: lib/Functions/wcsrb-helpers.php:42 msgid "Expobank" msgstr "Експобанк" +#: lib/Core/Address_Admin_Controller.php:25 +msgid "Field is required" +msgstr "Поље не сме бити празно" + #: config/settings.php:35 msgid "Field removal" msgstr "Сакривање поља" @@ -271,17 +277,17 @@ msgstr "Општа подешавања" msgid "General settings for Serbian Addons for WooCommerce" msgstr "Општа подешавања српских додатака за WooCommerce" -#: lib/Utils/wcsrb-helpers.php:44 +#: lib/Functions/wcsrb-helpers.php:44 msgid "Halkbank" msgstr "Халкбанк" -#: lib/Gateway/Gateway_Payment_Slip.php:151 +#: lib/Gateway/Gateway_Payment_Slip.php:50 msgid "Have your customers pay you by sending you money via wire transfer." msgstr "" "Плаћање општом уплатницом у поштама и банкама србије са опцијом генерисања " "НБС ИПС QR кôда" -#: lib/Admin/Plugin_Settings_Page.php:63 +#: lib/Admin/Plugin_Settings_Page.php:64 msgid "here" msgstr "овде" @@ -299,7 +305,7 @@ msgstr "https://oblak.studio" msgid "https://oblak.studio/open-source/srpski-woocommerce" msgstr "https://oblak.studio/open-source/srpski-woocommerce" -#: config/pg-slip-settings.php:152 +#: config/pg-slip-settings.php:186 msgid "Image that will be shown on the QR code. " msgstr "Слика која ће бити приказана у средини QR кôда " @@ -308,46 +314,52 @@ msgid "Instant payment" msgstr "Инстант плаћање" #. Translators: %s is the invalid bank account number. -#: lib/Admin/Plugin_Settings_Page.php:153 +#: lib/Admin/Plugin_Settings_Page.php:154 msgid "Invalid bank account number: %s" -msgstr "" +msgstr "Неисправан број рачуна: %s" -#: lib/Gateway/Gateway_Payment_Slip_IPS_Handler.php:328 +#: lib/Admin/Order_Edit_Page_Controller.php:77 +#: lib/Gateway/Gateway_Payment_Slip_IPS_Handler.php:192 msgid "IPS QR Code" msgstr "ИПС QR кôд" -#. translators: %1$s log file path, %2$s line break. -#: config/pg-slip-settings.php:180 +#. translators: %s is a placeholder for a URL. +#: config/pg-slip-settings.php:206 +#| msgid "" +#| "Log Payment Slip events and review them on the Logs " +#| "screen. Note: this may log personal information. We recommend using " +#| "this for debugging purposes only and deleting the logs when finished." msgid "" -"Log Payment Slip events, inside %1$s %2$sNote: this may log personal " -"information. We recommend using this for debugging purposes only and " -"deleting the logs when finished." +"Log Payment Slip events and review them on the Logs screen" +".
Note: this may log personal information. We recommend using this for " +"debugging purposes only and deleting the logs when finished." msgstr "" -"Логуј догађаје Опште Уплатнице унутар %1$s %2$s Напомена: Лог датотека може " -"садржати личне информације. Препоручујемо Вам да користите ово само у сврху " -"дебаговања, као и да обришете логове након завршетка." +"Бележи догађаје Опште Уплатнице које можете прегледати на " +"Страници логова.
Напомена: Лог датотека може садржати личне " +"информације. Препоручујемо Вам да користите ово само у сврху дебаговања, као " +"и да обришете логове након завршетка." -#: lib/Utils/wcsrb-helpers.php:64 +#: lib/Functions/wcsrb-helpers.php:64 msgid "Mirabank" msgstr "Мирабанк" -#: lib/Utils/wcsrb-helpers.php:41 +#: lib/Functions/wcsrb-helpers.php:41 msgid "Mobi" msgstr "Моби" -#: woocommerce/checkout/payment-slip.php:159 +#: woocommerce/checkout/payment-slip.php:166 msgid "Model" msgstr "Модел" -#: lib/Utils/wcsrb-payment-slip.php:41 +#: lib/Functions/wcsrb-payment-slip.php:95 msgid "Model 97" msgstr "Модел 97" -#: config/pg-slip-settings.php:50 +#: config/pg-slip-settings.php:95 msgid "Modern" msgstr "Модеран" -#: lib/Utils/wcsrb-helpers.php:61 +#: lib/Functions/wcsrb-helpers.php:61 msgid "MTS" msgstr "МТС" @@ -355,56 +367,60 @@ msgstr "МТС" msgid "Name of your business" msgstr "Име ваше фирме" -#: lib/Utils/wcsrb-helpers.php:57 +#: lib/Functions/wcsrb-helpers.php:57 msgid "NLB" msgstr "НЛБ" -#: lib/Utils/wcsrb-helpers.php:50 +#: lib/Functions/wcsrb-helpers.php:50 msgid "NLB Commercial" msgstr "НЛБ Комерцијална" +#: lib/Admin/Order_Edit_Page_Controller.php:99 +msgid "No IPS QR code available for this order." +msgstr "ИПС QR кôд није доступан за ову наруџбину" + #. Author of the plugin #: serbian-addons-for-woocommerce.php msgid "Oblak Studio" msgstr "Облак Студио" -#: lib/Utils/wcsrb-helpers.php:62 +#: lib/Functions/wcsrb-helpers.php:62 msgid "Opportunity" msgstr "Опортунити" -#: lib/Utils/wcsrb-payment-slip.php:67 +#: lib/Functions/wcsrb-payment-slip.php:121 msgid "Order date" msgstr "Датум наруџбине" -#: lib/Utils/wcsrb-payment-slip.php:68 +#: lib/Functions/wcsrb-payment-slip.php:122 msgid "Order ID" msgstr "Идентификатор наруџбине" -#: lib/Utils/wcsrb-payment-slip.php:69 +#: lib/Functions/wcsrb-payment-slip.php:123 msgid "Order number" msgstr "Број наруџбине" -#: config/pg-slip-settings.php:108 +#: config/pg-slip-settings.php:154 msgid "Order payment" msgstr "Плаћање наруџбине" -#: lib/Utils/wcsrb-helpers.php:54 +#: lib/Functions/wcsrb-helpers.php:54 msgid "OTP" msgstr "ОТП" -#: config/pg-slip-settings.php:29 +#: config/pg-slip-settings.php:78 msgid "Pay by sending us money via wire transfer" msgstr "Платите наруџбину општом уплатницом" -#: config/pg-slip-settings.php:69 woocommerce/checkout/payment-slip.php:98 +#: config/pg-slip-settings.php:115 woocommerce/checkout/payment-slip.php:105 msgid "Payment code" msgstr "Шифра плаћања" -#: config/pg-slip-settings.php:74 +#: config/pg-slip-settings.php:120 msgid "Payment code on the payment slip" msgstr "Шифра плаћања која ће бити приказана на општој уплатници" -#: woocommerce/checkout/payment-slip.php:28 +#: woocommerce/checkout/payment-slip.php:35 msgid "Payment instructions" msgstr "Инструкције за уплату" @@ -412,51 +428,55 @@ msgstr "Инструкције за уплату" msgid "Payment is complete" msgstr "Плаћање је извршено" -#: config/pg-slip-settings.php:82 +#: config/pg-slip-settings.php:128 msgid "Payment model" msgstr "Модел плаћања" -#: config/pg-slip-settings.php:86 +#: config/pg-slip-settings.php:132 msgid "Payment model for the payment reference" msgstr "Модел за позив на број" -#: config/pg-slip-settings.php:106 woocommerce/checkout/payment-slip.php:58 +#: config/pg-slip-settings.php:152 woocommerce/checkout/payment-slip.php:65 msgid "Payment purpose" msgstr "Сврха уплате" -#: config/pg-slip-settings.php:95 woocommerce/checkout/payment-slip.php:167 +#: config/pg-slip-settings.php:141 woocommerce/checkout/payment-slip.php:174 msgid "Payment reference" msgstr "Позив на број" -#: lib/Gateway/Gateway_Payment_Slip.php:155 +#: config/pg-slip-settings.php:71 lib/Gateway/Gateway_Payment_Slip.php:49 msgid "Payment Slip" msgstr "Општа уплатница" -#: lib/Utils/wcsrb-helpers.php:16 lib/Utils/wcsrb-settings.php:54 -#: lib/Utils/wcsrb-settings.php:68 lib/Utils/wcsrb-settings.php:74 +#: lib/Functions/wcsrb-helpers.php:16 lib/Functions/wcsrb-settings.php:54 +#: lib/Functions/wcsrb-settings.php:68 lib/Functions/wcsrb-settings.php:74 msgid "Person" msgstr "Физичко лице" -#: lib/Utils/wcsrb-helpers.php:49 +#: lib/Functions/wcsrb-helpers.php:49 msgid "Postal Savings" msgstr "Поштанска штедионица" -#: lib/Utils/wcsrb-helpers.php:51 +#: lib/Functions/wcsrb-helpers.php:51 msgid "ProCredit" msgstr "ПроКредит" -#: config/pg-slip-settings.php:112 +#: config/pg-slip-settings.php:158 msgid "QR Code" msgstr "QR кôд" -#: lib/Utils/wcsrb-helpers.php:53 +#: lib/Functions/wcsrb-helpers.php:53 msgid "Raiffeisen" msgstr "Рајфајзен" -#: woocommerce/checkout/payment-slip.php:73 +#: woocommerce/checkout/payment-slip.php:80 msgid "Reciever" msgstr "Прималац" +#: lib/Admin/Order_Edit_Page_Controller.php:61 +msgid "Regenerate IPS QR code" +msgstr "Поново изради ИПС QR кôд" + #: config/settings.php:38 msgid "Remove unneeded fields from the checkout page" msgstr "Уклоните непотребна поља на страници за куповину" @@ -465,7 +485,7 @@ msgstr "Уклоните непотребна поља на страници з msgid "Removes Address 2 and State fields" msgstr "Активирање ове опције ће сакрити поља Адреса 2 и Округ" -#: lib/Utils/wcsrb-helpers.php:55 +#: lib/Functions/wcsrb-helpers.php:55 msgid "Sberbank" msgstr "Сбербанк" @@ -473,7 +493,7 @@ msgstr "Сбербанк" msgid "Scan the QR code" msgstr "Скенирајте QR кôд" -#: lib/Utils/wcsrb-settings.php:20 +#: lib/Functions/wcsrb-settings.php:20 msgid "Select bank account" msgstr "Одаберите жиро рачун" @@ -481,81 +501,71 @@ msgstr "Одаберите жиро рачун" msgid "Select IPS SCAN in the m-banking app" msgstr "Одаберите ИПС Скенирај у м-банкинг апликацији" -#: woocommerce/checkout/payment-slip.php:42 +#: config/pg-slip-settings.php:24 +msgid "Select locations for display" +msgstr "Одаберите места" + +#: woocommerce/checkout/payment-slip.php:49 msgid "Sender" msgstr "Пошиљаоц" -#: lib/Utils/wcsrb-helpers.php:56 +#: lib/Functions/wcsrb-helpers.php:56 msgid "Serbian" msgstr "Српски" -#: lib/Admin/Plugin_Settings_Page.php:24 +#: lib/Admin/Plugin_Settings_Page.php:25 msgid "Serbian Addons" msgstr "Српски додаци" #. Plugin Name of the plugin -#: serbian-addons-for-woocommerce.php lib/Core/Installer.php:28 +#: serbian-addons-for-woocommerce.php lib/Utils/Installer.php:28 msgid "Serbian Addons for WooCommerce" msgstr "Српски додаци за WooCommerce" -#: lib/Gateway/Gateway_Payment_Slip.php:184 +#: lib/Gateway/Gateway_Payment_Slip.php:120 msgid "Serbian Payment Slip does not support your store currency." msgstr "Плаћање општом уплатницом није подржано за вашу валуту." -#: lib/Gateway/Gateway_Payment_Slip.php:194 +#: lib/Gateway/Gateway_Payment_Slip.php:124 msgid "Serbian Payment Slip requires at least one bank account." msgstr "Плаћање општом уплатницом захтева бар један унет жиро рачун" -#: lib/Core/Installer.php:45 lib/Core/Installer.php:46 +#: lib/Utils/Installer.php:45 lib/Utils/Installer.php:46 msgid "Settings" msgstr "Подешавања" -#: config/pg-slip-settings.php:114 +#: config/pg-slip-settings.php:160 msgid "Settings for NBS IPS QR Code" msgstr "Подешавања за НБС ИПС QR кôд" -#: config/pg-slip-settings.php:148 +#: config/pg-slip-settings.php:182 msgid "Show image" msgstr "Прикажи слику" -#: config/pg-slip-settings.php:150 +#: config/pg-slip-settings.php:184 msgid "Show image on QR code" msgstr "Прикажи слику на QR кôду" -#: config/pg-slip-settings.php:42 -msgid "Show payment slip in the order confirmation e-mail" -msgstr "" - -#: config/pg-slip-settings.php:118 -msgid "Show QR code" -msgstr "Прикажи QR кôд" - -#: config/pg-slip-settings.php:125 -msgid "Show QR code in emails" -msgstr "" - -#: config/pg-slip-settings.php:127 -msgid "Show QR code in order confirmation emails" -msgstr "" - -#: config/pg-slip-settings.php:120 -msgid "Show QR code on the payment slip" -msgstr "Прикажи QR кôд на општој уплатници" - -#: config/pg-slip-settings.php:35 +#: config/pg-slip-settings.php:84 msgid "Slip settings" msgstr "Подешавања уплатнице" +#: config/pg-slip-settings.php:17 +msgid "Store pages" +msgstr "Странице продавнице" + #. Translators: %s is a link to the company settings page. -#: lib/Admin/Plugin_Settings_Page.php:59 +#: lib/Admin/Plugin_Settings_Page.php:60 msgid "Store settings have been moved %s" msgstr "Подешавања продавнице су премештена %s" -#: config/pg-slip-settings.php:46 +#: config/pg-slip-settings.php:91 msgid "Style" msgstr "Изглед" -#: lib/Checkout/Field_Customizer.php:192 lib/Order/Field_Display.php:191 +#: lib/Core/Address_Admin_Controller.php:75 +#: lib/Core/Address_Admin_Controller.php:145 +#: lib/Functions/wcsrb-address-field-fns.php:26 msgid "Tax Number" msgstr "ПИБ" @@ -567,18 +577,6 @@ msgstr "" "НБС ИПС QR кôд је иновативни начин за инстант плаћање коришћењем мобилних " "уређаја" -#: config/pg-slip-settings.php:28 -msgid "This controls the description which the user sees during checkout." -msgstr "Опис који ће купац видети приликом куповине" - -#: config/pg-slip-settings.php:21 -msgid "This controls the title which the user sees during checkout." -msgstr "Назив који ће купац видети приликом куповине" - -#: config/pg-slip-settings.php:19 -msgid "Title" -msgstr "Назив" - #: config/settings.php:43 msgid "Transliterate currency symbol" msgstr "Преслови валуту" @@ -587,7 +585,7 @@ msgstr "Преслови валуту" msgid "Transliterate currency symbol to latin script" msgstr "Пресловљава валуту у латиницу" -#: lib/Utils/wcsrb-helpers.php:47 +#: lib/Functions/wcsrb-helpers.php:47 msgid "UniCredit" msgstr "УниКредит" @@ -600,20 +598,32 @@ msgstr "" "Raзни додаци и подешавања која ће ускладити вашу продавницу са српским " "књиговодстевним прописима." -#: lib/Utils/wcsrb-helpers.php:58 +#: config/pg-slip-settings.php:14 +msgid "Visibility" +msgstr "Видљивост" + +#: lib/Functions/wcsrb-helpers.php:58 msgid "Vojvodjanska" msgstr "Војвођанска" +#: config/pg-slip-settings.php:163 +msgid "Where to display the payment slip" +msgstr "Места на којима ће бити приказана уплатница" + +#: config/pg-slip-settings.php:88 +msgid "Where to display the QR Code" +msgstr "Места на којима ће бити приказан QR кôд" + #: config/settings.php:26 msgid "Which customer types can shop on the store" msgstr "Дефинише који типови купаца могу да праве наруџбине" #. translators: %1$s opening link tag, %2$s closing link tag. -#: config/pg-slip-settings.php:63 +#: config/pg-slip-settings.php:108 msgid "You can add your bank account details in the %1$sCompany settings%2$s ." -msgstr "Можете додати ваш банковни рачун у %1$sПодешвањима компаније%2$s" +msgstr "Можете додати ваш банковни рачун у %1$sПодешaвањима фирме%2$s" -#: config/pg-slip-settings.php:73 +#: config/pg-slip-settings.php:119 msgid "" "You can choose a payment code only if you limit checkout to a single " "customer type." @@ -621,7 +631,7 @@ msgstr "" "Можете одабрати шифру плаћања само ако ограничите куповину на одређени тип " "купца" -#. translators: %1$s opening link tag, %2$s Customizer title, %3$s closing link tag, %3$s current image HTML. -#: config/pg-slip-settings.php:155 -msgid "You can set it in %1$s%2$s%3$s. Current image is: %4$s" -msgstr "Слику можете подесити овде: %1$s%2$s%3$s. Тренутна слика: %4$s" +#. translators: %1$s customizer link html. +#: config/pg-slip-settings.php:35 +msgid "You can set the image via %1$s" +msgstr "Слику можете изменити користећи %1$s" diff --git a/languages/serbian-addons-for-woocommerce.pot b/languages/serbian-addons-for-woocommerce.pot index 7cf9b7d..833e7fd 100644 --- a/languages/serbian-addons-for-woocommerce.pot +++ b/languages/serbian-addons-for-woocommerce.pot @@ -9,14 +9,14 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2024-09-25T12:39:15+02:00\n" +"POT-Creation-Date: 2024-09-27T23:55:38+02:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.10.0\n" "X-Domain: serbian-addons-for-woocommerce\n" #. Plugin Name of the plugin #: serbian-addons-for-woocommerce.php -#: lib/Core/Installer.php:28 +#: lib/Utils/Installer.php:28 msgid "Serbian Addons for WooCommerce" msgstr "" @@ -48,187 +48,169 @@ msgstr "" msgid "Name of your business" msgstr "" -#: config/pg-slip-settings.php:13 -msgid "Enable/Disable" +#: config/pg-slip-settings.php:14 +msgid "Visibility" msgstr "" -#: config/pg-slip-settings.php:14 -msgid "Enable Payment Slip" +#: config/pg-slip-settings.php:17 +msgid "Store pages" msgstr "" -#: config/pg-slip-settings.php:19 -msgid "Title" +#: config/pg-slip-settings.php:18 +msgid "Customer e-mails" msgstr "" -#: config/pg-slip-settings.php:21 -msgid "This controls the title which the user sees during checkout." +#: config/pg-slip-settings.php:24 +msgid "Select locations for display" msgstr "" -#: config/pg-slip-settings.php:26 -msgid "Description" +#. translators: %1$s customizer link html. +#: config/pg-slip-settings.php:35 +msgid "You can set the image via %1$s" msgstr "" -#: config/pg-slip-settings.php:28 -msgid "This controls the description which the user sees during checkout." +#. translators: %s current image HTML. +#: config/pg-slip-settings.php:47 +msgid "Current image: %s" msgstr "" -#: config/pg-slip-settings.php:29 -msgid "Pay by sending us money via wire transfer" +#: config/pg-slip-settings.php:63 +msgid "Enable Payment Slip" msgstr "" -#: config/pg-slip-settings.php:35 -msgid "Slip settings" +#: config/pg-slip-settings.php:71 +#: lib/Gateway/Gateway_Payment_Slip.php:49 +msgid "Payment Slip" +msgstr "" + +#: config/pg-slip-settings.php:78 +msgid "Pay by sending us money via wire transfer" msgstr "" -#: config/pg-slip-settings.php:40 -msgid "Add to e-mail" +#: config/pg-slip-settings.php:84 +msgid "Slip settings" msgstr "" -#: config/pg-slip-settings.php:42 -msgid "Show payment slip in the order confirmation e-mail" +#: config/pg-slip-settings.php:88 +msgid "Where to display the QR Code" msgstr "" -#: config/pg-slip-settings.php:46 +#: config/pg-slip-settings.php:91 msgid "Style" msgstr "" -#: config/pg-slip-settings.php:49 +#: config/pg-slip-settings.php:94 msgid "Classic" msgstr "" -#: config/pg-slip-settings.php:50 +#: config/pg-slip-settings.php:95 msgid "Modern" msgstr "" -#: config/pg-slip-settings.php:53 +#: config/pg-slip-settings.php:98 msgid "Defines the style of the payment slip" msgstr "" -#: config/pg-slip-settings.php:57 +#: config/pg-slip-settings.php:102 msgid "Bank account" msgstr "" -#: config/pg-slip-settings.php:60 +#: config/pg-slip-settings.php:105 msgid "Bank account number" msgstr "" #. translators: %1$s opening link tag, %2$s closing link tag. -#: config/pg-slip-settings.php:63 +#: config/pg-slip-settings.php:108 msgid "You can add your bank account details in the %1$sCompany settings%2$s ." msgstr "" -#: config/pg-slip-settings.php:69 -#: woocommerce/checkout/payment-slip.php:98 +#: config/pg-slip-settings.php:115 +#: woocommerce/checkout/payment-slip.php:105 msgid "Payment code" msgstr "" -#: config/pg-slip-settings.php:73 +#: config/pg-slip-settings.php:119 msgid "You can choose a payment code only if you limit checkout to a single customer type." msgstr "" -#: config/pg-slip-settings.php:74 +#: config/pg-slip-settings.php:120 msgid "Payment code on the payment slip" msgstr "" -#: config/pg-slip-settings.php:82 +#: config/pg-slip-settings.php:128 msgid "Payment model" msgstr "" -#: config/pg-slip-settings.php:86 +#: config/pg-slip-settings.php:132 msgid "Payment model for the payment reference" msgstr "" #. translators: %1$s line break. -#: config/pg-slip-settings.php:89 +#: config/pg-slip-settings.php:135 msgid "Choosing the model 97 will automatically set the payment reference.%1$sWe recommend using model 97 because payment processor guarantees verbatim reference transfer only if it is done via model 97 " msgstr "" -#: config/pg-slip-settings.php:95 -#: woocommerce/checkout/payment-slip.php:167 +#: config/pg-slip-settings.php:141 +#: woocommerce/checkout/payment-slip.php:174 msgid "Payment reference" msgstr "" -#: config/pg-slip-settings.php:106 -#: woocommerce/checkout/payment-slip.php:58 +#: config/pg-slip-settings.php:152 +#: woocommerce/checkout/payment-slip.php:65 msgid "Payment purpose" msgstr "" -#: config/pg-slip-settings.php:108 +#: config/pg-slip-settings.php:154 msgid "Order payment" msgstr "" -#: config/pg-slip-settings.php:112 +#: config/pg-slip-settings.php:158 msgid "QR Code" msgstr "" -#: config/pg-slip-settings.php:114 +#: config/pg-slip-settings.php:160 msgid "Settings for NBS IPS QR Code" msgstr "" -#: config/pg-slip-settings.php:118 -msgid "Show QR code" +#: config/pg-slip-settings.php:163 +msgid "Where to display the payment slip" msgstr "" -#: config/pg-slip-settings.php:120 -msgid "Show QR code on the payment slip" -msgstr "" - -#: config/pg-slip-settings.php:125 -msgid "Show QR code in emails" -msgstr "" - -#: config/pg-slip-settings.php:127 -msgid "Show QR code in order confirmation emails" -msgstr "" - -#: config/pg-slip-settings.php:132 +#: config/pg-slip-settings.php:166 msgid "Dot color" msgstr "" -#: config/pg-slip-settings.php:135 +#: config/pg-slip-settings.php:169 msgid "Color of the dots on the QR code" msgstr "" -#: config/pg-slip-settings.php:140 +#: config/pg-slip-settings.php:174 msgid "Corner dot color" msgstr "" -#: config/pg-slip-settings.php:143 +#: config/pg-slip-settings.php:177 msgid "Color of the corner dots on the QR code" msgstr "" -#: config/pg-slip-settings.php:148 +#: config/pg-slip-settings.php:182 msgid "Show image" msgstr "" -#: config/pg-slip-settings.php:150 +#: config/pg-slip-settings.php:184 msgid "Show image on QR code" msgstr "" -#: config/pg-slip-settings.php:152 +#: config/pg-slip-settings.php:186 msgid "Image that will be shown on the QR code. " msgstr "" -#. translators: %1$s opening link tag, %2$s Customizer title, %3$s closing link tag, %3$s current image HTML. -#: config/pg-slip-settings.php:155 -msgid "You can set it in %1$s%2$s%3$s. Current image is: %4$s" -msgstr "" - -#: config/pg-slip-settings.php:169 +#: config/pg-slip-settings.php:195 msgid "Advanced Settings" msgstr "" -#: config/pg-slip-settings.php:174 -msgid "Debug log" -msgstr "" - -#: config/pg-slip-settings.php:176 -msgid "Enable logging" -msgstr "" - -#. translators: %1$s log file path, %2$s line break. -#: config/pg-slip-settings.php:180 -msgid "Log Payment Slip events, inside %1$s %2$sNote: this may log personal information. We recommend using this for debugging purposes only and deleting the logs when finished." +#. translators: %s is a placeholder for a URL. +#: config/pg-slip-settings.php:206 +msgid "Log Payment Slip events and review them on the Logs screen.
Note: this may log personal information. We recommend using this for debugging purposes only and deleting the logs when finished." msgstr "" #: config/settings.php:16 @@ -291,266 +273,283 @@ msgstr "" msgid "Enter bank account" msgstr "" -#: lib/Admin/Plugin_Settings_Page.php:24 -msgid "Serbian Addons" -msgstr "" - -#. Translators: %s is a link to the company settings page. -#: lib/Admin/Plugin_Settings_Page.php:59 -msgid "Store settings have been moved %s" +#: lib/Admin/Order_Edit_Page_Controller.php:61 +msgid "Regenerate IPS QR code" msgstr "" -#: lib/Admin/Plugin_Settings_Page.php:63 -msgid "here" +#: lib/Admin/Order_Edit_Page_Controller.php:77 +#: lib/Gateway/Gateway_Payment_Slip_IPS_Handler.php:192 +msgid "IPS QR Code" msgstr "" -#. Translators: %s is the invalid bank account number. -#: lib/Admin/Plugin_Settings_Page.php:153 -msgid "Invalid bank account number: %s" +#: lib/Admin/Order_Edit_Page_Controller.php:99 +msgid "No IPS QR code available for this order." msgstr "" -#: lib/Checkout/Field_Customizer.php:149 -#: lib/Order/Field_Display.php:178 -msgid "Customer type" +#: lib/Admin/Order_Edit_Page_Controller.php:127 +msgid "Copy IPS QR string" msgstr "" -#: lib/Checkout/Field_Customizer.php:183 -#: lib/Order/Field_Display.php:186 -msgid "Company Number" +#: lib/Admin/Order_Edit_Page_Controller.php:128 +msgid "Copied!" msgstr "" -#: lib/Checkout/Field_Customizer.php:184 -msgid "Enter MB" +#: lib/Admin/Plugin_Settings_Page.php:25 +msgid "Serbian Addons" msgstr "" -#: lib/Checkout/Field_Customizer.php:192 -#: lib/Order/Field_Display.php:191 -msgid "Tax Number" +#. Translators: %s is a link to the company settings page. +#: lib/Admin/Plugin_Settings_Page.php:60 +msgid "Store settings have been moved %s" msgstr "" -#: lib/Checkout/Field_Customizer.php:193 -msgid "Enter PIB" +#: lib/Admin/Plugin_Settings_Page.php:64 +msgid "here" msgstr "" -#: lib/Checkout/Field_Validator.php:117 -msgid "Company name is required" +#. Translators: %s is the invalid bank account number. +#: lib/Admin/Plugin_Settings_Page.php:154 +msgid "Invalid bank account number: %s" msgstr "" -#: lib/Checkout/Field_Validator.php:122 -msgid "Company number is invalid" +#: lib/Core/Address_Admin_Controller.php:25 +msgid "Field is required" msgstr "" -#: lib/Checkout/Field_Validator.php:127 +#: lib/Core/Address_Admin_Controller.php:26 +#: lib/Services/Field_Validator.php:168 msgid "Company Tax Number is invalid" msgstr "" -#: lib/Core/Installer.php:45 -#: lib/Core/Installer.php:46 -msgid "Settings" -msgstr "" - -#: lib/Gateway/Gateway_Payment_Slip.php:151 -msgid "Have your customers pay you by sending you money via wire transfer." -msgstr "" - -#: lib/Gateway/Gateway_Payment_Slip.php:155 -msgid "Payment Slip" +#: lib/Core/Address_Admin_Controller.php:27 +msgid "Company Number is invalid" msgstr "" -#: lib/Gateway/Gateway_Payment_Slip.php:184 -msgid "Serbian Payment Slip does not support your store currency." +#: lib/Core/Address_Admin_Controller.php:63 +#: lib/Core/Address_Admin_Controller.php:132 +#: lib/Core/Address_Field_Controller.php:34 +msgid "Customer type" msgstr "" -#: lib/Gateway/Gateway_Payment_Slip.php:194 -msgid "Serbian Payment Slip requires at least one bank account." +#: lib/Core/Address_Admin_Controller.php:70 +#: lib/Core/Address_Admin_Controller.php:140 +#: lib/Functions/wcsrb-address-field-fns.php:19 +msgid "Company Number" msgstr "" -#: lib/Gateway/Gateway_Payment_Slip_IPS_Handler.php:328 -msgid "IPS QR Code" +#: lib/Core/Address_Admin_Controller.php:75 +#: lib/Core/Address_Admin_Controller.php:145 +#: lib/Functions/wcsrb-address-field-fns.php:26 +msgid "Tax Number" msgstr "" -#: lib/Order/Field_Display.php:134 +#: lib/Core/Address_Display_Controller.php:116 msgctxt "Address display" msgid "Company Number" msgstr "" -#: lib/Order/Field_Display.php:140 +#: lib/Core/Address_Display_Controller.php:121 msgctxt "Address display" msgid "Tax Identification Number" msgstr "" -#: lib/Utils/wcsrb-helpers.php:16 -#: lib/Utils/wcsrb-settings.php:54 -#: lib/Utils/wcsrb-settings.php:68 -#: lib/Utils/wcsrb-settings.php:74 +#: lib/Functions/wcsrb-helpers.php:16 +#: lib/Functions/wcsrb-settings.php:54 +#: lib/Functions/wcsrb-settings.php:68 +#: lib/Functions/wcsrb-settings.php:74 msgid "Person" msgstr "" -#: lib/Utils/wcsrb-helpers.php:17 -#: lib/Utils/wcsrb-settings.php:48 -#: lib/Utils/wcsrb-settings.php:67 -#: lib/Utils/wcsrb-settings.php:71 +#: lib/Functions/wcsrb-helpers.php:17 +#: lib/Functions/wcsrb-settings.php:48 +#: lib/Functions/wcsrb-settings.php:67 +#: lib/Functions/wcsrb-settings.php:71 msgid "Company" msgstr "" #. Translators: %s is the bank name. -#: lib/Utils/wcsrb-helpers.php:37 +#: lib/Functions/wcsrb-helpers.php:37 msgid "%s Bank" msgstr "" -#: lib/Utils/wcsrb-helpers.php:40 +#: lib/Functions/wcsrb-helpers.php:40 msgid "AIK" msgstr "" -#: lib/Utils/wcsrb-helpers.php:41 +#: lib/Functions/wcsrb-helpers.php:41 msgid "Mobi" msgstr "" -#: lib/Utils/wcsrb-helpers.php:42 +#: lib/Functions/wcsrb-helpers.php:42 msgid "Expobank" msgstr "" -#: lib/Utils/wcsrb-helpers.php:43 +#: lib/Functions/wcsrb-helpers.php:43 msgid "Direct" msgstr "" -#: lib/Utils/wcsrb-helpers.php:44 +#: lib/Functions/wcsrb-helpers.php:44 msgid "Halkbank" msgstr "" -#: lib/Utils/wcsrb-helpers.php:45 +#: lib/Functions/wcsrb-helpers.php:45 msgid "Banca Intesa" msgstr "" -#: lib/Utils/wcsrb-helpers.php:46 +#: lib/Functions/wcsrb-helpers.php:46 msgid "Addiko" msgstr "" -#: lib/Utils/wcsrb-helpers.php:47 +#: lib/Functions/wcsrb-helpers.php:47 msgid "UniCredit" msgstr "" -#: lib/Utils/wcsrb-helpers.php:48 +#: lib/Functions/wcsrb-helpers.php:48 msgid "Alta" msgstr "" -#: lib/Utils/wcsrb-helpers.php:49 +#: lib/Functions/wcsrb-helpers.php:49 msgid "Postal Savings" msgstr "" -#: lib/Utils/wcsrb-helpers.php:50 +#: lib/Functions/wcsrb-helpers.php:50 msgid "NLB Commercial" msgstr "" -#: lib/Utils/wcsrb-helpers.php:51 +#: lib/Functions/wcsrb-helpers.php:51 msgid "ProCredit" msgstr "" -#: lib/Utils/wcsrb-helpers.php:52 +#: lib/Functions/wcsrb-helpers.php:52 msgid "Eurobank Direct" msgstr "" -#: lib/Utils/wcsrb-helpers.php:53 +#: lib/Functions/wcsrb-helpers.php:53 msgid "Raiffeisen" msgstr "" -#: lib/Utils/wcsrb-helpers.php:54 +#: lib/Functions/wcsrb-helpers.php:54 msgid "OTP" msgstr "" -#: lib/Utils/wcsrb-helpers.php:55 +#: lib/Functions/wcsrb-helpers.php:55 msgid "Sberbank" msgstr "" -#: lib/Utils/wcsrb-helpers.php:56 +#: lib/Functions/wcsrb-helpers.php:56 msgid "Serbian" msgstr "" -#: lib/Utils/wcsrb-helpers.php:57 +#: lib/Functions/wcsrb-helpers.php:57 msgid "NLB" msgstr "" -#: lib/Utils/wcsrb-helpers.php:58 +#: lib/Functions/wcsrb-helpers.php:58 msgid "Vojvodjanska" msgstr "" -#: lib/Utils/wcsrb-helpers.php:59 +#: lib/Functions/wcsrb-helpers.php:59 msgid "Credit Agricole" msgstr "" -#: lib/Utils/wcsrb-helpers.php:60 +#: lib/Functions/wcsrb-helpers.php:60 msgid "Erste" msgstr "" -#: lib/Utils/wcsrb-helpers.php:61 +#: lib/Functions/wcsrb-helpers.php:61 msgid "MTS" msgstr "" -#: lib/Utils/wcsrb-helpers.php:62 +#: lib/Functions/wcsrb-helpers.php:62 msgid "Opportunity" msgstr "" -#: lib/Utils/wcsrb-helpers.php:63 +#: lib/Functions/wcsrb-helpers.php:63 msgid "API" msgstr "" -#: lib/Utils/wcsrb-helpers.php:64 +#: lib/Functions/wcsrb-helpers.php:64 msgid "Mirabank" msgstr "" -#: lib/Utils/wcsrb-helpers.php:65 +#: lib/Functions/wcsrb-helpers.php:65 msgid "Bank of China" msgstr "" -#: lib/Utils/wcsrb-payment-slip.php:40 -#: lib/Utils/wcsrb-settings.php:44 +#: lib/Functions/wcsrb-payment-slip.php:94 +#: lib/Functions/wcsrb-settings.php:44 msgid "Automatic" msgstr "" -#: lib/Utils/wcsrb-payment-slip.php:41 +#: lib/Functions/wcsrb-payment-slip.php:95 msgid "Model 97" msgstr "" -#: lib/Utils/wcsrb-payment-slip.php:64 +#: lib/Functions/wcsrb-payment-slip.php:118 msgid "Customer ID" msgstr "" -#: lib/Utils/wcsrb-payment-slip.php:67 +#: lib/Functions/wcsrb-payment-slip.php:121 msgid "Order date" msgstr "" -#: lib/Utils/wcsrb-payment-slip.php:68 +#: lib/Functions/wcsrb-payment-slip.php:122 msgid "Order ID" msgstr "" -#: lib/Utils/wcsrb-payment-slip.php:69 +#: lib/Functions/wcsrb-payment-slip.php:123 msgid "Order number" msgstr "" -#: lib/Utils/wcsrb-settings.php:20 +#: lib/Functions/wcsrb-settings.php:20 msgid "Select bank account" msgstr "" #. Translators: %d is the payment code. -#: lib/Utils/wcsrb-settings.php:50 +#: lib/Functions/wcsrb-settings.php:50 msgid "%d - Interim expenses" msgstr "" #. Translators: %d is the payment code. -#: lib/Utils/wcsrb-settings.php:52 +#: lib/Functions/wcsrb-settings.php:52 msgid "%d - Final expenses" msgstr "" #. Translators: %d is the payment code. -#: lib/Utils/wcsrb-settings.php:57 +#: lib/Functions/wcsrb-settings.php:57 msgid "%d - Transactions on behalf of a person" msgstr "" #. Translators: %d is the payment code. -#: lib/Utils/wcsrb-settings.php:61 +#: lib/Functions/wcsrb-settings.php:61 msgid "%d - Other transactions" msgstr "" +#: lib/Gateway/Gateway_Payment_Slip.php:50 +msgid "Have your customers pay you by sending you money via wire transfer." +msgstr "" + +#: lib/Gateway/Gateway_Payment_Slip.php:120 +msgid "Serbian Payment Slip does not support your store currency." +msgstr "" + +#: lib/Gateway/Gateway_Payment_Slip.php:124 +msgid "Serbian Payment Slip requires at least one bank account." +msgstr "" + +#: lib/Services/Field_Validator.php:156 +msgid "Company name is required" +msgstr "" + +#: lib/Services/Field_Validator.php:162 +msgid "Company number is invalid" +msgstr "" + +#: lib/Utils/Installer.php:45 +#: lib/Utils/Installer.php:46 +msgid "Settings" +msgstr "" + #: woocommerce/checkout/payment-slip-qr-code.php:26 msgid "Instant payment" msgstr "" @@ -583,26 +582,26 @@ msgstr "" msgid "Payment is complete" msgstr "" -#: woocommerce/checkout/payment-slip.php:28 +#: woocommerce/checkout/payment-slip.php:35 msgid "Payment instructions" msgstr "" -#: woocommerce/checkout/payment-slip.php:42 +#: woocommerce/checkout/payment-slip.php:49 msgid "Sender" msgstr "" -#: woocommerce/checkout/payment-slip.php:73 +#: woocommerce/checkout/payment-slip.php:80 msgid "Reciever" msgstr "" -#: woocommerce/checkout/payment-slip.php:114 +#: woocommerce/checkout/payment-slip.php:121 msgid "Amount" msgstr "" -#: woocommerce/checkout/payment-slip.php:144 +#: woocommerce/checkout/payment-slip.php:151 msgid "Account payable" msgstr "" -#: woocommerce/checkout/payment-slip.php:159 +#: woocommerce/checkout/payment-slip.php:166 msgid "Model" msgstr "" diff --git a/lib/Admin/Admin_Core.php b/lib/Admin/Admin_Core.php index bc83686..ba1e376 100644 --- a/lib/Admin/Admin_Core.php +++ b/lib/Admin/Admin_Core.php @@ -8,6 +8,7 @@ namespace Oblak\WCSRB\Admin; +use Automattic\WooCommerce\Utilities\OrderUtil; use Oblak\WP\Abstracts\Hook_Caller; use Oblak\WP\Decorators\Filter; use Oblak\WP\Decorators\Hookable; @@ -39,6 +40,10 @@ public function add_router_classes( $classes ) { $classes .= ' wcsrb-slip-settings '; } + if ( OrderUtil::is_new_order_screen() || OrderUtil::is_order_edit_screen() ) { + $classes .= ' wcsrb-order-edit '; + } + return $classes; } diff --git a/lib/Admin/Order_Edit_Page_Controller.php b/lib/Admin/Order_Edit_Page_Controller.php new file mode 100644 index 0000000..b3a951c --- /dev/null +++ b/lib/Admin/Order_Edit_Page_Controller.php @@ -0,0 +1,131 @@ +exists( $file ) ) { + exit; + } + + \wc_nocache_headers(); + \header( "Content-Disposition: inline; filename=\"ips-qr-order-{$order->get_id()}\"" ); + \header( 'Content-Length: ' . \xwp_wpfs()->size( $file ) ); + \header( 'Content-Type: image/jpeg' ); + \header( 'Date: ' . \gmdate( 'D, d M Y H:i:s T', \xwp_wpfs()->mtime( $file ) ) ); + + echo \xwp_wpfs()->get_contents( $file ); // phpcs:ignore + + exit; + } + + /** + * Adds the IPS Regeneration action to the order actions metabox + * + * @param array $actions Order actions. + * @param WC_Order $order Order object. + * @return array + */ + #[Action( tag: 'woocommerce_order_actions' )] + public function add_action_to_metabox( array $actions, WC_Order $order ): array { + if ( \wcsrb_order_has_slip( $order, true ) ) { + $actions['wcsrb_gen_ips'] = \__( 'Regenerate IPS QR code', 'serbian-addons-for-woocommerce' ); + } + + return $actions; + } + + /** + * Adds the IPS QR code metabox to the order view page + */ + #[Action( tag: 'add_meta_boxes' )] + public function add_ips_qr_metabox() { + $screen_id = \get_current_screen()?->id ?? ''; + + foreach ( \wc_get_order_types( 'order-meta-boxes' ) as $type ) { + \add_meta_box( + 'wcsrb-ips-qr-code', + \__( 'IPS QR Code', 'serbian-addons-for-woocommerce' ), + array( $this, 'qrcode_metabox' ), + $screen_id, + 'side', + ); + } + } + + /** + * Displays the IPS QR code metabox + * + * @param WC_Order|WP_Post $post Order object. + */ + public function qrcode_metabox( $post ) { + global $theorder; + + // @phpstan-ignore argument.type + OrderUtil::init_theorder_object( $post ); + + if ( ! \wcsrb_order_has_qrcode( $theorder ) ) { + return \printf( + '

%s

', + \esc_html__( 'No IPS QR code available for this order.', 'serbian-addons-for-woocommerce' ), + ); + } + + \printf( + <<<'HTML' + + HTML, + \esc_url( + \add_query_arg( + array( + 'action' => 'wcsrb_view_ips_qr_code', + 'order_id' => $theorder->get_id(), + 'security' => \wp_create_nonce( 'wcsrb-view-ips-qr-code' ), + ), + \admin_url( 'admin-ajax.php' ), + ), + ), + ); + + \printf( + <<<'HTML' + + + HTML, + \wc_esc_json( + \wp_json_encode( array( 's' => \WCSRB()->payments()->get_qr_string( $theorder ) ) ), + ), + \esc_html__( 'Copy IPS QR string', 'serbian-addons-for-woocommerce' ), + \esc_html__( 'Copied!', 'serbian-addons-for-woocommerce' ), + ); + } +} diff --git a/lib/App.php b/lib/App.php index ea9fb14..6244868 100644 --- a/lib/App.php +++ b/lib/App.php @@ -8,6 +8,7 @@ namespace Oblak\WCSRB; use Oblak\WCSRB\Services\Field_Validator; +use Oblak\WCSRB\Utils\Payments; use Oblak\WooCommerce\Serbian_Addons as Legacy; use Oblak\WP\Decorators\Action; use Oblak\WP\Decorators\Filter; @@ -38,6 +39,13 @@ class App { */ protected Field_Validator $validator; + /** + * Payments utility instance. + * + * @var Payments + */ + protected Payments $payments; + /** * Private constructor */ @@ -53,6 +61,7 @@ protected function __construct() { protected function get_dependencies(): array { return array( Admin\Admin_Core::class, + Admin\Order_Edit_Page_Controller::class, Core\Address_Admin_Controller::class, Core\Address_Display_Controller::class, Core\Address_Field_Controller::class, @@ -109,7 +118,7 @@ public function load_plugin_settings() { $this->settings['company'] = array( 'accounts' => \wcsrb_get_bank_accounts(), - 'address' => \get_option( 'woocommerce_store_address', '' ), + 'address_1' => \get_option( 'woocommerce_store_address', '' ), 'address_2' => \get_option( 'woocommerce_store_address_2', '' ), 'city' => \get_option( 'woocommerce_store_city', '' ), 'country' => \wc_get_base_location()['country'], @@ -192,4 +201,13 @@ public function check_asset_necessity( bool $load, string $script ) { public function validator(): Field_Validator { return $this->validator ??= new Field_Validator(); } + + /** + * Gets the payments utility instance. + * + * @return Payments + */ + public function payments(): Payments { + return $this->payments ??= new Payments(); + } } diff --git a/lib/Core/Address_Display_Controller.php b/lib/Core/Address_Display_Controller.php index 89d4ac5..54a5a19 100644 --- a/lib/Core/Address_Display_Controller.php +++ b/lib/Core/Address_Display_Controller.php @@ -25,10 +25,10 @@ class Address_Display_Controller extends Hook_Caller { public function modify_address_format( $formats ) { \add_filter( 'woocommerce_formatted_address_force_country_display', '__return_true' ); - $formats['RS'] = "{name}\n{company}\n{mb}\n{pib}\n{address_1}\n{address_2}\n{postcode} {city}, {state} {country}"; + $formats['RS'] = "{name}\n{company}\n{mb}\n{pib}\n{address_1} {address_2}\n{postcode} {city}, {state} {country}"; if ( \WCSRB()->get_settings( 'core', 'remove_unneeded_fields' ) ) { - $formats['RS'] = \str_replace( array( '{state}', '{address_2}' ), '', $formats['RS'] ); + $formats['RS'] = \str_replace( array( '{state}', ' {address_2}' ), '', $formats['RS'] ); } return $formats; @@ -105,7 +105,7 @@ public function modify_order_formatted_address( $address, $order ) { protected function get_replacement_values( WC_Customer|WC_Order $target ): array { $data = \wcsrb_get_company_data( $target ); if ( 'company' !== $data['type'] ) { - return array(); + return array( 'company' => "\n" ); } return array( diff --git a/lib/Functions/wcsrb-address-field-fns.php b/lib/Functions/wcsrb-address-field-fns.php index 5f3bf30..a73ae4d 100644 --- a/lib/Functions/wcsrb-address-field-fns.php +++ b/lib/Functions/wcsrb-address-field-fns.php @@ -15,20 +15,18 @@ function wcsrb_get_company_fields(): array { $fields = array( 'mb' => array( - 'class' => array( 'form-row-first', 'address-field', 'entity-type-toggle', 'shown' ), - 'label' => \__( 'Company Number', 'serbian-addons-for-woocommerce' ), - 'placeholder' => \__( 'Enter MB', 'serbian-addons-for-woocommerce' ), - 'priority' => 31, - 'type' => 'text', - 'validate' => array( 'mb' ), + 'class' => array( 'form-row-first', 'address-field', 'entity-type-toggle', 'shown' ), + 'label' => \__( 'Company Number', 'serbian-addons-for-woocommerce' ), + 'priority' => 31, + 'type' => 'text', + 'validate' => array( 'mb' ), ), 'pib' => array( - 'class' => array( 'form-row-last', 'address-field', 'entity-type-toggle', 'shown' ), - 'label' => \__( 'Tax Number', 'serbian-addons-for-woocommerce' ), - 'placeholder' => \__( 'Enter PIB', 'serbian-addons-for-woocommerce' ), - 'priority' => 32, - 'type' => 'text', - 'validate' => array( 'pib' ), + 'class' => array( 'form-row-last', 'address-field', 'entity-type-toggle', 'shown' ), + 'label' => \__( 'Tax Number', 'serbian-addons-for-woocommerce' ), + 'priority' => 32, + 'type' => 'text', + 'validate' => array( 'pib' ), ), ); diff --git a/lib/Functions/wcsrb-payment-slip.php b/lib/Functions/wcsrb-payment-slip.php index e7d43f3..d5148b7 100644 --- a/lib/Functions/wcsrb-payment-slip.php +++ b/lib/Functions/wcsrb-payment-slip.php @@ -6,6 +6,60 @@ * @subpackage Utils */ +use Oblak\WooCommerce\Serbian_Addons\QR\QR_Code_Handler; + +/** + * Get the Payment Slip gateway. + * + * @return Oblak\WooCommerce\Serbian_Addons\Gateway\Gateway_Payment_Slip The Payment Slip gateway. + */ +function wcsrb_slip_gw(): Oblak\WooCommerce\Serbian_Addons\Gateway\Gateway_Payment_Slip { + return WC()->payment_gateways()->payment_gateways()['wcsrb_payment_slip']; +} + +/** + * Check if the order has a payment slip. + * + * @param null|int|WC_Order $order The order. + * @param bool $unpaid_only Whether to check only for unpaid orders. + * @return bool Whether the order has a payment slip. + */ +function wcsrb_order_has_slip( null|int|WC_Order $order, bool $unpaid_only = false ): bool { + if ( ! ( $order instanceof WC_Order ) ) { + $order = wc_get_order( $order ?? false ); + } + + return $order && + 'wcsrb_payment_slip' === $order->get_payment_method() && + ( ! $unpaid_only || ! $order->is_paid() ); +} + +/** + * Check if we can display the payment slip. + * + * @param null|int|WC_Order $order The order. + * @param 'order'|'email' $where Where to display the payment slip. + * @param bool $unpaid Whether to display only unpaid orders. + * @return bool + */ +function wcsrb_can_display_slip( null|int|WC_Order $order, string $where, bool $unpaid = true ): bool { + return wcsrb_order_has_slip( $order, $unpaid ) && + in_array( $where, wcsrb_slip_gw()->display, true ); +} + +/** + * Check if we can display the QR Code. + * + * @param null|int|WC_Order $order The order. + * @param 'order'|'email' $where Where to display the payment slip. + * @param bool $unpaid Whether to display only unpaid orders. + * @return bool + */ +function wcsrb_can_display_qr( null|int|WC_Order $order, string $where, bool $unpaid = true ): bool { + return wcsrb_order_has_slip( $order, $unpaid ) && + in_array( $where, wcsrb_slip_gw()->qrcode_shown, true ); +} + /** * Get the available payment models. * @@ -163,14 +217,13 @@ function wcsrb_string_to_reference( $letter ): int { function wcsrb_calculate_number_for_reference( $order_number ): int { $length = strlen( $order_number ); $result = ''; - for ( $i = 0; $i < $length; $i++ ) { - if ( ctype_alpha( $order_number[ $i ] ) ) { - $result .= wcsrb_string_to_reference( $order_number[ $i ] ); - continue; - } - $result .= $order_number[ $i ]; + for ( $i = 0; $i < $length; $i++ ) { + $result .= ctype_alpha( $order_number[ $i ] ) + ? wcsrb_string_to_reference( $order_number[ $i ] ) + : $order_number[ $i ]; } + return (int) $result * 100; } @@ -182,3 +235,13 @@ function wcsrb_calculate_number_for_reference( $order_number ): int { function wcsrb_get_ips_basedir(): string { return wp_upload_dir()['basedir'] . '/wcrs-ips'; } + +/** + * Check if the order has a QR Code. + * + * @param null|int|WC_Order $order The order. + * @return bool + */ +function wcsrb_order_has_qrcode( null|int|WC_Order $order ): bool { + return wcsrb_order_has_slip( $order ) && xwp_wpfs()->exists( QR_Code_Handler::get_filename( $order ) ); +} diff --git a/lib/Gateway/Gateway_Payment_Slip.php b/lib/Gateway/Gateway_Payment_Slip.php index 38c629a..ddd4657 100644 --- a/lib/Gateway/Gateway_Payment_Slip.php +++ b/lib/Gateway/Gateway_Payment_Slip.php @@ -1,4 +1,4 @@ - 'wcsrb_payment_slip', + 'method_title' => \__( 'Payment Slip', 'serbian-addons-for-woocommerce' ), + 'method_description' => \__( 'Have your customers pay you by sending you money via wire transfer.', 'serbian-addons-for-woocommerce' ), + 'has_fields' => false, + ); + } /** - * Company data. - * - * @var array + * {@inheritDoc} */ - protected $company_data; + protected function get_raw_form_fields(): array { + return include WCRS_PLUGIN_PATH . 'config/pg-slip-settings.php'; + } /** - * Class constructor. + * Loads settings from the database. */ - public function __construct() { - parent::__construct(); - - $this->company_data = WCSRB()->get_settings( 'company' ); - - self::$log_enabled[ self::$log_id ] = $this->debug; - - if ( ! is_wp_error( $this->is_valid_for_use() ) && wc_string_to_bool( $this->enabled ) ) { - new Gateway_Payment_Slip_Data_Handler( $this->get_available_settings() ); - new Gateway_Payment_Slip_IPS_Handler( $this->get_available_settings() ); - - \xwp_invoke_hooked_methods( $this ); + public function init_settings() { + parent::init_settings(); + if ( ! \is_array( $this->settings['qrcode_shown'] ) ) { + $this->settings['qrcode_shown'] = 'yes' === $this->settings['qrcode_shown'] + ? 'order,email' + : ''; } + $this->settings['qrcode_shown'] = \wc_string_to_array( $this->settings['qrcode_shown'] ); + $this->settings['qrcode_image'] = \wc_bool_to_string( 0 < \intval( \get_option( 'site_icon', 0 ) ) && \wc_string_to_bool( $this->settings['qrcode_image'] ) ); + $this->settings['display'] = \wc_string_to_array( $this->settings['display'] ); + $this->settings['company'] = \WCSRB()->get_settings( 'company' ); } /** * {@inheritDoc} */ - protected function get_base_props(): array { - return array( - 'id' => 'wcsrb_payment_slip', - 'method_title' => __( 'Payment Slip', 'serbian-addons-for-woocommerce' ), - 'method_description' => __( 'Have your customers pay you by sending you money via wire transfer.', 'serbian-addons-for-woocommerce' ), - 'has_fields' => false, - ); + public function init_gateway(): void { + if ( \is_wp_error( $this->is_valid_for_use() ) || ! \wc_string_to_bool( $this->enabled ) ) { + return; + } + + new Gateway_Payment_Slip_IPS_Handler( $this->get_options() ); + + \xwp_invoke_hooked_methods( $this ); } /** * {@inheritDoc} */ - protected function get_raw_form_fields(): array { - return include WCRS_PLUGIN_PATH . 'config/pg-slip-settings.php'; + public function get_post_data() { + $data = \xwp_post_arr(); + + $data[ $this->get_option_key() . '_display' ] ??= array(); + $data[ $this->get_option_key() . '_qrcode_shown' ] ??= array(); + + return $data; } /** * {@inheritDoc} */ public function needs_setup() { - return empty( $this->bank_account ) || ! validateBankAccount( $this->bank_account ) || is_wp_error( $this->is_valid_for_use() ); + return ! $this->bank_account || + ! validateBankAccount( $this->bank_account ) || + \is_wp_error( $this->is_valid_for_use() ); } /** @@ -160,21 +115,23 @@ public function needs_setup() { * * @return bool|WP_Error */ - public function is_valid_for_use(): bool|WP_Error { - if ( ! in_array( get_woocommerce_currency(), array( 'RSD', 'РСД', 'din', 'din.' ), true ) ) { - return new WP_Error( 'invalid_currency', __( 'Serbian Payment Slip does not support your store currency.', 'serbian-addons-for-woocommerce' ) ); - } elseif ( empty( WCSRB()->get_settings( 'company', 'accounts' ) ) ) { - return new WP_Error( 'invalid_bank_account', __( 'Serbian Payment Slip requires at least one bank account.', 'serbian-addons-for-woocommerce' ) ); - } else { - return true; + public function is_valid_for_use(): bool|\WP_Error { + if ( ! \in_array( \get_woocommerce_currency(), array( 'RSD', 'РСД', 'din', 'din.' ), true ) ) { + return new \WP_Error( 'invalid_currency', \__( 'Serbian Payment Slip does not support your store currency.', 'serbian-addons-for-woocommerce' ) ); } + + if ( ! \WCSRB()->get_settings( 'company', 'accounts' ) ) { + return new \WP_Error( 'invalid_bank_account', \__( 'Serbian Payment Slip requires at least one bank account.', 'serbian-addons-for-woocommerce' ) ); + } + + return true; } /** * {@inheritDoc} */ public function process_payment( $order_id ) { - $order = wc_get_order( $order_id ); + $order = \wc_get_order( $order_id ); $default_order_status = 'on-hold'; @@ -187,15 +144,15 @@ public function process_payment( $order_id ) { * * @since 2.3.0 */ - $order_status = apply_filters( 'wcsrb_payment_slip_payment_order_status', $default_order_status, $order ); + $order_status = \apply_filters( 'wcsrb_payment_slip_payment_order_status', $default_order_status, $order ); if ( $order->get_total() > 0 ) { - $order->update_status( $order_status, __( 'Awaiting payment', 'woocommerce' ) ); + $order->update_status( $order_status, \__( 'Awaiting payment', 'woocommerce' ) ); } else { $order->payment_complete(); } - WC()->cart->empty_cart(); + \WC()->cart->empty_cart(); return array( 'result' => 'success', @@ -203,6 +160,30 @@ public function process_payment( $order_id ) { ); } + /** + * Adds payment slip metadata to the order + * + * @param int|WC_Order $order Order ID or object. + */ + #[Action( tag: 'woocommerce_new_order', priority: 10 )] + #[Action( tag: 'woocommerce_order_action_wcsrb_gen_ips', priority: 10 )] + public function add_payment_data( int|WC_Order $order ) { + $order = \wc_get_order( $order ); + + $data = array( + 'model' => $this->payment_model, + 'reference' => $this->payment_reference, + 'purpose' => $this->payment_purpose, + 'code' => $this->payment_code, + 'account' => $this->bank_account, + ); + + $order->delete_meta_data( '_payment_slip_data' ); + $order->delete_meta_data( '_payment_slip_ips_data' ); + $order->update_meta_data( '_wcsrb_payment_data', $data ); + $order->save(); + } + /** * Displays the payment slip on the thank you page * @@ -211,20 +192,20 @@ public function process_payment( $order_id ) { #[Action( tag: 'woocommerce_thankyou_wcsrb_payment_slip', priority: 100 )] #[Action( tag: 'woocommerce_view_order', priority: 7 )] public function show_payment_slip( $order_id ) { - $order = wc_get_order( $order_id ); + $order = \wc_get_order( $order_id ); - if ( 'wcsrb_payment_slip' !== $order->get_payment_method() || $order->is_paid() ) { + if ( ! \wcsrb_can_display_slip( $order, 'order' ) ) { return; } - wc_get_template( + \wc_get_template( 'checkout/payment-slip.php', - array_merge( - $order->get_meta( '_payment_slip_data', true ), + \array_merge( + \WCSRB()->payments()->get_data( $order ), array( 'style' => $this->style, 'order_id' => $order_id, - ) + ), ), ); } @@ -234,17 +215,15 @@ public function show_payment_slip( $order_id ) { * * @param string $css Email CSS. * @param WC_Email $email Email object. - * @return string Modified email CSS. + * @return string Modified email CSS. */ #[Filter( tag: 'woocommerce_email_styles', priority: 9999 )] - public function add_css_to_emails( $css, $email ) { - // @phpstan-ignore method.nonObject, nullsafe.neverNull - if ( 'customer_on_hold_order' !== $email->id || 'wcsrb_payment_slip' !== $email->object?->get_payment_method() ) { - return $css; + public function add_css_to_emails( string $css, WC_Email $email ) { + if ( 'customer_on_hold_order' === $email->id && \wcsrb_order_has_slip( $email->object, true ) ) { + $css .= \WCSRB()->asset_data( 'css/email/template.css' ) . "\n"; + $css .= \WCSRB()->asset_data( 'css/front/main.css' ) . "\n"; } - $css .= WCSRB()->asset_data( 'css/front/main.css' ); - return $css; } @@ -257,13 +236,12 @@ public function add_css_to_emails( $css, $email ) { * @param WC_Email $email Email object. */ #[Action( tag: 'woocommerce_email_order_details', priority: 50 )] - public function add_payment_slip_to_email( $order, $sent_to_admin, $plain_text, $email ) { + public function add_payment_slip_to_email( $order, $sent_to_admin, $plain_text, WC_Email $email ) { if ( + $plain_text || + $sent_to_admin || 'customer_on_hold_order' !== $email->id || - $sent_to_admin || $plain_text || - // @phpstan-ignore method.nonObject - 'wcsrb_payment_slip' !== $email->object->get_payment_method() || - $order->is_paid() + ! \wcsrb_can_display_slip( $email->object, 'email' ) ) { return; } @@ -272,14 +250,14 @@ public function add_payment_slip_to_email( $order, $sent_to_admin, $plain_text, echo '
'; - wc_get_template( + \wc_get_template( 'checkout/payment-slip.php', - array_merge( - $order->get_meta( '_payment_slip_data', true ), + \array_merge( + \WCSRB()->payments()->get_data( $order ), array( 'style' => $this->style, 'order_id' => $order->get_id(), - ) + ), ), ); diff --git a/lib/Gateway/Gateway_Payment_Slip_Data_Handler.php b/lib/Gateway/Gateway_Payment_Slip_Data_Handler.php deleted file mode 100644 index 5ed6b8a..0000000 --- a/lib/Gateway/Gateway_Payment_Slip_Data_Handler.php +++ /dev/null @@ -1,233 +0,0 @@ - $options Gateway options. - */ - public function __construct( - /** - * Gateway options - * - * @var array - */ - protected array $options, - ) { - $this->options['company_data'] = \WCSRB()->get_settings( 'company' ); - - parent::__construct(); - } - - /** - * Adds payment slip metadata to the order - * - * @param int $order_id Order ID. - * @param WC_Order $order Order object. - */ - #[Action( tag: 'woocommerce_new_order', priority: 10 )] - public function add_slip_metadata( int $order_id, WC_Order $order ) { - $slip_data = array(); - - foreach ( $this->get_slip_data_keys() as $key ) { - $slip_data[ $key ] = $this->{"get_$key"}( $order ); - } - - $order->update_meta_data( '_payment_slip_data', $slip_data ); - $order->save(); - } - - /** - * Get the payment slip data keys - * - * @return string[] The payment slip data keys. - */ - protected function get_slip_data_keys(): array { - $slip_data_keys = array( - 'customer', - 'purpose', - 'company', - 'code', - 'currency', - 'total', - 'account', - 'model', - 'reference', - ); - - // phpcs:ignore WooCommerce.Commenting - return \apply_filters( 'woocommerce_serbian_payment_slip_data_keys', $slip_data_keys ); - } - - /** - * Get the customer data for the order. - * - * @param WC_Order $order Order object. - * @return string The customer. - */ - protected function get_customer( WC_Order $order ): string { - \add_filter( - 'woocommerce_formatted_address_replacements', - array( $this, 'remove_extra_address_replacements' ), - PHP_INT_MAX, - 1, - ); - - return $order->get_formatted_billing_address(); - } - - /** - * Get the payment purpose for the order - * - * @param WC_Order $order Order object. - * @return string The payment purpose. - */ - protected function get_purpose( $order ) { - $purpose = $this->options['payment_purpose']; - - /** - * Filters the payment slip payment purpose. - * - * @param string $purpose The payment purpose. - * @param WC_Order $order The order object. - * @return string Modified payment purpose. - * - * @since 2.3.0 - */ - return \apply_filters( 'woocommerce_serbian_payment_slip_purpose', $purpose, $order ); - } - - /** - * Formats the company data for the payment slip - * - * @param WC_Order $order Whether or not the data is for the QR code. - * @return string The formatted company data. - */ - protected function get_company( $order ) { - return \sprintf( - '%s
%s %s
%s %s, %s', - $this->options['company_data']['name'], - $this->options['company_data']['address'], - $this->options['company_data']['address_2'], - $this->options['company_data']['postcode'], - $this->options['company_data']['city'], - // @phpstan-ignore property.notFound - \WC()->countries->countries[ $this->options['company_data']['country'] ], - ); - } - - /** - * Get the payment code for the order - * - * @param WC_Order $order Order object. - * @return string The payment code. - */ - protected function get_code( $order ) { - if ( 'auto' !== $this->options['payment_code'] ) { - return $this->options['payment_code']; - } - - if ( 'company' === $order->get_meta( '_billing_type', true ) ) { - return '221'; - } - - return '289'; - } - - /** - * Get the currency for the order - * - * @param WC_Order $order Order object. - * @return string The currency. - */ - protected function get_currency( $order ) { - return $order->get_currency(); - } - - /** - * Get the total for the order - * - * @param WC_Order $order Order object. - * @return float - */ - protected function get_total( $order ) { - return floatval( $order->get_total( 'edit' ) ); - } - - /** - * Get the account for the order - * - * @param WC_Order $order Order object. - * @return string The account. - */ - protected function get_account( $order ) { - return \wcsrb_format_bank_acct( $this->options['bank_account'] ); - } - - /** - * Get the payment model for the order - * - * @param WC_Order $order Order object. - * @return string The payment model. - */ - protected function get_model( $order ) { - $model = \wcsrb_get_payment_models()[ $this->options['payment_model'] ]; - - if ( empty( $model ) ) { - $model = '00'; - } - - /** - * Filters the payment slip payment model. - * - * @param string $model The payment model. - * @param WC_Order $order The order object. - * @return string Modified payment model. - * - * @since 2.3.0 - */ - return \apply_filters( 'woocommerce_serbian_payment_slip_model', $model, $order ); - } - - /** - * Get the order reference number for the given order. - * - * @param WC_Order $order Order object. - * @return string Alphanumeric order reference number. - */ - protected function get_reference( $order ) { - $replacements = \wcsrb_get_payment_reference_replacement_pairs( $order ); - - return \strtr( $this->options['payment_reference'], $replacements ); - } - - /** - * Removes the extra address replacements - * - * @param array $replacements The address replacements. - * @return array The modified address replacements. - */ - public function remove_extra_address_replacements( $replacements ) { - \remove_filter( - 'woocommerce_formatted_address_replacements', - array( $this, 'remove_extra_address_replacements' ), - PHP_INT_MAX, - ); - // phpcs:ignore WordPress.Arrays - return \array_merge( $replacements, array( '{mb}' => '', '{pib}' => '' ) ); - } -} diff --git a/lib/Gateway/Gateway_Payment_Slip_IPS_Handler.php b/lib/Gateway/Gateway_Payment_Slip_IPS_Handler.php index ededba5..4c8d24d 100644 --- a/lib/Gateway/Gateway_Payment_Slip_IPS_Handler.php +++ b/lib/Gateway/Gateway_Payment_Slip_IPS_Handler.php @@ -36,55 +36,23 @@ public function __construct( parent::__construct(); } - //phpcs:disable Squiz.Commenting.InlineComment.WrongStyle - #region IPS Data - //phpcs:enable Squiz.Commenting.InlineComment.WrongStyle - - /** - * Adds payment slip metadata to the order - * - * @param int $order_id Order ID. - * @param WC_Order $order Order object. - */ - #[Action( tag: 'woocommerce_new_order', priority: 20 )] - public function add_ips_metadata( int $order_id, WC_Order $order ) { - $ips_fmtd_arr = array(); - - foreach ( $this->format_ips_data( $order ) as $key => $value ) { - $ips_fmtd_arr[] = \sprintf( '%s:%s', $key, $value ); - } - - if ( ! $ips_fmtd_arr ) { - return; - } - - $order->update_meta_data( '_payment_slip_ips_data', \implode( '|', $ips_fmtd_arr ) ); - $order->save(); - } - /** - * Triggers the QR code generation + * Generates the QR code for the IPS payment slip. * - * @param int $order_id Order ID. - * @param WC_Order $order Order object. + * @param int|WC_Order $order The order object. */ #[Action( tag: 'woocommerce_new_order', priority: 30 )] - public function add_qr_code_action( int $order_id, WC_Order $order ) { - $qr_string = $order->get_meta( '_payment_slip_ips_data', true ); + #[Action( tag: 'woocommerce_order_action_wcsrb_gen_ips', priority: 30 )] + public function generate_qr_code( int|WC_Order $order ) { + $order = \wc_get_order( $order ); - if ( empty( $qr_string ) ) { + if ( ! \wcsrb_order_has_slip( $order ) ) { return; } - /** - * Generate the QR code for the IPS payment slip. - * - * @param WC_Order $order The order object. - * @param array $options The gateway options. - * - * @since 3.3.0 - */ - \do_action( 'woocommerce_serbian_generate_ips_qr_code', $order, $this->options ); + QR_Code_Handler::instance() + ->init( $this->get_qr_code_options( \wcsrb_slip_gw()->get_options() ) ) + ->create_file( $order ); } /** @@ -96,7 +64,7 @@ public function add_qr_code_action( int $order_id, WC_Order $order ) { #[Action( tag: 'woocommerce_before_trash_order', priority: 20 )] #[Action( tag: 'woocommerce_order_status_completed', priority: 20 )] public function delete_order_qr_code( int $order_id ) { - $filename = QR_Code_Handler::instance()->get_filename( \wc_get_order( $order_id ) ); + $filename = QR_Code_Handler::get_filename( \wc_get_order( $order_id ) ); if ( ! $filename || ! \xwp_wpfs()->exists( $filename ) ) { return; @@ -105,159 +73,13 @@ public function delete_order_qr_code( int $order_id ) { \xwp_wpfs()->delete( $filename ); } - /** - * Adds payment slip metadata to the order - * - * @param WC_Order|null $order Order object. - */ - public function format_ips_data( $order ): array { - $slip_data = $order->get_meta( '_payment_slip_data', true ); - - if ( ! $slip_data ) { - return array(); - } - - $qr_data = array(); - - foreach ( $this->get_ips_data_keys() as $key => $keys ) { - $value = ''; - - foreach ( $keys as $prop ) { - $value .= match ( true ) { - method_exists( $this, "format_{$prop}" ) => $this->{"format_{$prop}"}( $slip_data[ $prop ] ), - (bool) preg_match( '
', $slip_data[ $prop ] ?? '' ) => preg_replace( '//', "\n", $slip_data[ $prop ] ), - array_key_exists( $prop, $slip_data ) => $slip_data[ $prop ], - default => $prop, - }; - } - - $qr_data[ $key ] = $value; - } - - return $qr_data; - } - - /** - * Get the IPS QR data keys - * - * @return array> The IPS QR data keys - */ - protected function get_ips_data_keys(): array { - return array( - 'K' => array( 'PR' ), - 'V' => array( '01' ), - 'C' => array( '1' ), - 'R' => array( 'account' ), - 'N' => array( 'company' ), - 'I' => array( 'currency', 'total' ), - 'P' => array( 'customer' ), - 'SF' => array( 'code' ), - 'S' => array( 'purpose' ), - 'RO' => array( 'model', 'reference' ), - ); - } - - /** - * Format the account number - * - * @param string $account The account number. - * @return string - */ - protected function format_account( string $account ): string { - $parts = \explode( '-', $account ); - $parts[1] = \str_pad( $parts[1], 13, '0', STR_PAD_LEFT ); - - return \implode( '', $parts ); - } - - /** - * Format the company data - * - * @param string $company The company data. - * @return string - */ - protected function format_company( string $company ): string { - return $this->shorten_tag( $company ); - } - - /** - * Format the customer data - * - * @param string $customer The customer data. - * @return string - */ - protected function format_customer( string $customer ): string { - return $this->shorten_tag( $customer ); - } - - /** - * Shortens the tag to 70 characters - * - * @param string $tag The tag. - * @return string - */ - protected function shorten_tag( string $tag ): string { - $tag = preg_replace( '//', "\n", $tag ); - $count = 1; - $length = strlen( $tag ); - - while ( 70 < $length && $count > 0 ) { - $tag = preg_replace( "/\n.*$/", '', $tag, -1, $count ); - $length = strlen( $tag ); - } - - if ( 70 < $length && 0 === $count ) { - $tag = substr( $tag, 0, 70 ); - } - - return $tag; - } - - /** - * Format the total - * - * @param float $total The total. - * @return string - */ - protected function format_total( float $total ): string { - return \number_format( $total, 2, ',', '' ); - } - - /** - * Format the payment model - * - * @param string $model Payment model. - * @return string - */ - protected function format_model( string $model ) { - return empty( $model ) ? '00' : $model; - } - - /** - * Format the reference - * - * @param string $reference The reference. - * @return string - */ - protected function format_reference( string $reference ): string { - return \str_replace( '-', '', $reference ); - } - - //phpcs:disable Squiz.Commenting.InlineComment.WrongStyle - #endregion - //phpcs:enable Squiz.Commenting.InlineComment.WrongStyle - - //phpcs:disable Squiz.Commenting.InlineComment.WrongStyle - #region QR Creation - //phpcs:enable Squiz.Commenting.InlineComment.WrongStyle - /** * Get the QR code options * * @param array $options The gateway options. * @return array */ - protected function get_qr_code_options( array $options ): array { + private function get_qr_code_options( array $options ): array { $module_values = array( QRMatrix::M_ALIGNMENT => $options['qrcode_color'], // Aligment. @@ -307,21 +129,6 @@ protected function get_qr_code_options( array $options ): array { return $args; } - /** - * Generates the QR code for the IPS payment slip. - * - * @param WC_Order $order The order object. - * @param array $options The gateway options. - */ - #[Action( tag: 'woocommerce_serbian_generate_ips_qr_code' )] - public function generate_qr_code( WC_Order $order, array $options, ) { - QR_Code_Handler::instance()->init( $this->get_qr_code_options( $options ) )->create_file( $order ); - } - - //phpcs:disable Squiz.Commenting.InlineComment.WrongStyle - #endregion - //phpcs:enable Squiz.Commenting.InlineComment.WrongStyle - /** * Show QR Code on the thank you page, and order details. * @@ -332,7 +139,7 @@ public function generate_qr_code( WC_Order $order, array $options, ) { public function show_qr_code( $order_id ) { $order = \wc_get_order( $order_id ); - if ( 'wcsrb_payment_slip' !== $order->get_payment_method() || ! $this->options['qrcode_shown'] || $order->is_paid() ) { + if ( ! \wcsrb_can_display_qr( $order, 'order' ) ) { return; } @@ -355,7 +162,7 @@ public function add_qr_code_to_email( $order, $sent_to_admin, $plain_text, $emai if ( 'customer_on_hold_order' !== $email->id || $sent_to_admin || $plain_text || - 'wcsrb_payment_slip' !== $order->get_payment_method() + ! \wcsrb_can_display_qr( $order, 'email' ) ) { return; } @@ -379,11 +186,11 @@ public function add_qr_code_to_email( $order, $sent_to_admin, $plain_text, $emai * @param string $type The template type. Can be 'display' or 'email'. * @return array */ - protected function get_template_args( WC_Order $order, string $type ): array { + private function get_template_args( WC_Order $order, string $type ): array { $qrc = QR_Code_Handler::instance()->init( $this->get_qr_code_options( $this->options ) ); return array( 'alt' => \__( 'IPS QR Code', 'serbian-addons-for-woocommerce' ), - 'path' => $qrc->get_filename( $order ), + 'path' => $qrc::get_filename( $order ), 'src' => 'email' === $type ? 'cid:ips-qr-code' : $qrc->get_file_base64( $order ), @@ -396,7 +203,7 @@ protected function get_template_args( WC_Order $order, string $type ): array { * @param PHPMailer $phpmailer The PHPMailer object. * @param string $filepath The QR code file path. */ - protected function add_inline_image( PHPMailer &$phpmailer, string $filepath ) { + private function add_inline_image( PHPMailer &$phpmailer, string $filepath ) { $phpmailer->addEmbeddedImage( $filepath, 'ips-qr-code', 'ips-qr-code.jpg' ); } } diff --git a/lib/QR/QR_Code_Handler.php b/lib/QR/QR_Code_Handler.php index 1345051..72b8e5f 100644 --- a/lib/QR/QR_Code_Handler.php +++ b/lib/QR/QR_Code_Handler.php @@ -26,13 +26,6 @@ class QR_Code_Handler { */ protected ?QRCode $qr_gen = null; - /** - * QR Code base directory. - * - * @var string - */ - protected string $basedir; - /** * Is the QR Code handler initialized? * @@ -40,13 +33,6 @@ class QR_Code_Handler { */ protected static bool $initialized = false; - /** - * Constructor. - */ - protected function __construct() { - $this->basedir = WCRS_IPS_DIR; - } - /** * Choose the best QR Code implementation. * @@ -178,13 +164,13 @@ public function save_file( string $qr_code, string $file ): bool { */ public function create_file( WC_Order $order, string $format = 'jpg', ?array $args = null ): bool { $qr_code = $this->create_qr_code( - $order->get_meta( '_payment_slip_ips_data', true ), + \WCSRB()->payments()->get_qr_string( $order ), $args, ); return $this->save_file( $qr_code, - $this->get_filename( $order, $format ), + static::get_filename( $order, $format ), ); } @@ -197,7 +183,7 @@ public function create_file( WC_Order $order, string $format = 'jpg', ?array $ar * @return string|false File data, or false if the file does not exist. */ public function get_file( WC_Order $order, string $format = 'jpg', bool $force = false ): string|false { - $filepath = $this->get_filename( $order, $format ); + $filepath = static::get_filename( $order, $format ); if ( ! $force && \file_exists( $filepath ) ) { return \wp_load_filesystem()->get_contents( $filepath ); @@ -219,7 +205,7 @@ public function get_file( WC_Order $order, string $format = 'jpg', bool $force = * @return string|false File data, or false if the file does not exist. */ public function get_file_base64( WC_Order $order, string $format = 'jpg', bool $force = false ): string|false { - $filepath = $this->get_filename( $order, $format ); + $filepath = self::get_filename( $order, $format ); $file = null; if ( ! $force && \file_exists( $filepath ) ) { @@ -240,18 +226,24 @@ public function get_file_base64( WC_Order $order, string $format = 'jpg', bool $ /** * Gets the QR Code file name. * - * @param WC_Order $order Order object. - * @param string $format File format. - * @param bool $with_basedir Whether to include the base directory. + * @param null|false|WC_Order $order Order object. + * @param string $format File format. + * @param bool $with_basedir Whether to include the base directory. * @return string The file name. */ - public function get_filename( WC_Order $order, string $format = 'jpg', bool $with_basedir = true ): string { + public static function get_filename( null|bool|WC_Order $order, string $format = 'jpg', bool $with_basedir = true ): string { + $order = ! ( $order instanceof WC_Order ) && $order ? \wc_get_order( $order ) : $order; + + if ( ! $order ) { + return ''; + } + return \sprintf( '%4$s%1$s-%2$s.%3$s', $order->get_id(), $order->get_order_key(), $format, - $with_basedir ? \trailingslashit( $this->basedir ) : '', + $with_basedir ? \trailingslashit( WCRS_IPS_DIR ) : '', ); } } diff --git a/lib/Utils/Payments.php b/lib/Utils/Payments.php new file mode 100644 index 0000000..b3f54a0 --- /dev/null +++ b/lib/Utils/Payments.php @@ -0,0 +1,269 @@ + $replacements Address replacements. + * @return array + */ + #[Filter( tag: 'woocommerce_formatted_address_replacements', priority: 9999 )] + public function remove_replacements( array $replacements ): array { + if ( $this->formatting ) { + $replacements['{mb}'] = ''; + $replacements['{pib}'] = ''; + } + + return $replacements; + } + + /** + * Formats the order data for the payment slip or the IPS QR code + * + * @param WC_Order $order Order object. + * @param string $context Context of the data. + */ + public function format_order_data( WC_Order $order, string $context = 'display' ): array { + $data = $order->get_meta( '_payment_slip_data', true ) + ?: + $order->get_meta( '_wcsrb_payment_data', true ); + + return array( + 'account' => $this->format_account( $data['account'], $context ), + 'code' => $this->format_code( $data['code'], $order ), + 'company' => $this->format_address( $this->get_company_data(), $context ), + 'currency' => $order->get_currency(), + 'customer' => $this->format_address( $order, $context ), + 'model' => $this->format_model( $data['model'], $context ), + 'purpose' => $this->format_purpose( $data['purpose'], $context ), + 'reference' => $this->format_reference( $data['reference'], $order, $context ), + 'total' => $this->format_total( $order, $context ), + ); + } + + /** + * Gets the data for the IPS QR code + * + * @param WC_Order $order Order object. + * @param string $context Context of the data. + */ + public function get_data( WC_Order $order, string $context = 'display' ): array { + $data = $this->format_order_data( $order, $context ); + + if ( 'display' === $context ) { + return $data; + } + + //phpcs:disable SlevomatCodingStandard.Arrays.AlphabeticallySortedByKeys.IncorrectKeyOrder + $args = array( + 'K' => array( 'PR' ), + 'V' => array( '01' ), + 'C' => array( '1' ), + 'R' => array( 'account' ), + 'N' => array( 'company' ), + 'I' => array( 'currency', 'total' ), + 'P' => array( 'customer' ), + 'SF' => array( 'code' ), + 'S' => array( 'purpose' ), + 'RO' => array( 'model', 'reference' ), + ); + //phpcs:enable SlevomatCodingStandard.Arrays.AlphabeticallySortedByKeys.IncorrectKeyOrder + + foreach ( $args as $key => $keys ) { + $value = ''; + + foreach ( $keys as $prop ) { + $value .= $data[ $prop ] ?? $prop; + } + + $args[ $key ] = $value; + } + + return $args; + } + + /** + * Gets the IPS QR code string + * + * @param WC_Order $order Order object. + * @return string The IPS QR code string. + */ + public function get_qr_string( WC_Order $order ): string { + $parts = array(); + + foreach ( $this->get_data( $order, 'ips' ) as $key => $value ) { + $parts[] = $key . ':' . $value; + } + + return \implode( '|', $parts ); + } + + /** + * Formats the payment reference + * + * @param string $reference Payment reference. + * @param WC_Order $order Order object. + * @param string $context Context of the data. + * @return string Formatted payment reference. + */ + private function format_reference( string $reference, WC_Order $order, string $context ): string { + $replacements = \wcsrb_get_payment_reference_replacement_pairs( $order ); + $reference = \strtr( $reference, $replacements ); + return 'display' === $context ? $reference : \str_replace( '-', '', $reference ); + } + + /** + * Formats the payment model + * + * @param string $model Payment model. + * @param string $context Context of the data. + * @return string Formatted payment model. + */ + private function format_model( string $model, string $context ): string { + if ( 'mod97' === $model ) { + return '97'; + } + + return 'ips' === $context ? '00' : ''; + } + + /** + * Formats the payment code + * + * @param string $code Payment code. + * @param WC_Order $order Order object. + * @return string Formatted payment code. + */ + private function format_code( string $code, WC_Order $order ): string { + $type = $order->get_meta( '_billing_type', true ); + + return match ( true ) { + 'auto' !== $code => $code, + 'company' === $type => '221', + 'person' === $type => '289', + default => '289', + }; + } + + /** + * Formats the payment purpose + * + * @param string $purpose Payment purpose. + * @param string $context Context of the data. + * @return string Formatted payment purpose. + */ + private function format_purpose( string $purpose, string $context ): string { + return 'display' === $context + ? $purpose + : $this->shorten_address( $purpose ); + } + + /** + * Formats the bank account + * + * @param string $account Bank account. + * @param string $context Context of the data. + * @return string Formatted bank account. + */ + private function format_account( string $account, string $context ): string { + return 'display' === $context + ? \wcsrb_format_bank_acct( $account ) + : \wcsrb_format_bank_acct( $account, 'long', '' ); + } + + /** + * Formats the total amount + * + * @param WC_Order $order Order object. + * @param string $context Context of the data. + * @return float|string Formatted total amount. + */ + private function format_total( WC_Order $order, string $context ): float|string { + return 'display' === $context + ? \floatval( $order->get_total( 'edit' ) ) + : \number_format( \floatval( $order->get_total( 'edit' ) ), 2, ',', '' ); + } + + /** + * Formats the address + * + * @param WC_Order|WC_Customer|array $target Customer or Order object. + * @param string $context Context of the data. + * @return string Formatted address. + */ + public function format_address( WC_Order|WC_Customer|array $target, string $context = 'display' ): string { + $this->formatting = true; + + $address = match ( true ) { + $target instanceof WC_Order => $target->get_formatted_billing_address(), + $target instanceof WC_Customer => \wc_get_account_formatted_address( 'billing', $target ), + default => \WC()->countries->get_formatted_address( $target ), + }; + + $this->formatting = false; + + return 'ips' === $context ? $this->shorten_address( $address ) : $address; + } + + /** + * Shortens the address to fit the IPS QR code + * + * @param string $address Address to shorten. + * @return string Shortened address. + */ + private function shorten_address( string $address ): string { + $address = \preg_replace( '//', "\n", $address ); + $count = 1; + $length = \strlen( $address ); + + while ( 70 < $length && $count > 0 ) { + $address = \preg_replace( "/\n.*$/", '', $address, -1, $count ); + $length = \strlen( $address ); + } + + if ( 70 < $length && 0 === $count ) { + $address = \substr( $address, 0, 70 ); + } + + return \trim( $address ); + } + + /** + * Gets the company data + * + * @return array Company data. + */ + protected function get_company_data(): array { + $data = \WCSRB()->get_settings( 'company' ); + + $data['company'] = $data['name']; + $data['accounts'] = ''; + $data['name'] = ''; + + return $data; + } +} diff --git a/phpstan.neon b/phpstan.neon index e1aae71..7e74790 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -11,6 +11,10 @@ parameters: bootstrapFiles: - vendor/php-stubs/woocommerce-stubs/woocommerce-stubs.php ignoreErrors: + - + identifier: argument.type + paths: + - lib/Utils/Payments.php - identifier: constant.notFound paths: