diff --git a/README.md b/README.md index a072b66..dfa436e 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ If you need to set it up in your theme or plugin, you can use following filters add_filter( 'woolab_icdic_vies_check', '__return_true' ); + add_filter( 'woolab_icdic_ignore_check_fail', '__return_true' ); + add_filter( 'woolab_icdic_vat_exempt_enabled', function(){ return "no"; // or "yes" } ); diff --git a/assets/js/admin.js b/assets/js/admin.js index 7a54758..64f41b4 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -7,9 +7,18 @@ var vies_check = $('#woolab_icdic_vies_check'); if (ares_check.length) { - enableActive(ares_check); + enableAresActive(ares_check); + enableIgnoreCheckFailActive(ares_check, vies_check); ares_check.change(function () { - enableActive(ares_check); + enableAresActive(ares_check); + enableIgnoreCheckFailActive(ares_check, vies_check); + }); + } + + if (vies_check.length) { + enableIgnoreCheckFailActive(ares_check, vies_check); + vies_check.change(function () { + enableIgnoreCheckFailActive(ares_check, vies_check); }); } @@ -31,7 +40,7 @@ } }); - function enableActive(ares_check) { + function enableAresActive(ares_check) { var active = $('#woolab_icdic_ares_fill'); if (ares_check.prop("checked") == true) { @@ -40,4 +49,14 @@ active.prop("disabled", true).prop("checked", false); } } + + function enableIgnoreCheckFailActive(ares_check, vies_check) { + var checkbox = $('#woolab_icdic_ignore_check_fail'); + + if (ares_check.prop('checked') || vies_check.prop('checked')) { + checkbox.prop('disabled', false); + } else { + checkbox.prop('disabled', true).prop('checked', false); + } + } })(jQuery); \ No newline at end of file diff --git a/assets/js/admin.min.js b/assets/js/admin.min.js index a1819b5..98dbe0c 100644 --- a/assets/js/admin.min.js +++ b/assets/js/admin.min.js @@ -1 +1 @@ -"use strict";!function(c){function i(i){var o=c("#woolab_icdic_ares_fill");1==i.prop("checked")?o.prop("disabled",!1):o.prop("disabled",!0).prop("checked",!1)}c(document).ready(function(){var o=c("#woolab_icdic_ares_check"),e=c("#woolab_icdic_vies_check");o.length&&(i(o),o.change(function(){i(o)})),e.length&&(woolab.soap||e.prop("disabled",!0).prop("checked",!1)),c(".woolab-icdic-notice").length&&c(".woolab-icdic-notice").on("click",".notice-dismiss",function(){c.ajax({url:ajaxurl,data:{action:"woolab_icdic_notice_dismiss"}})})})}(jQuery); \ No newline at end of file +"use strict";!function(c){function o(o){var i=c("#woolab_icdic_ares_fill");1==o.prop("checked")?i.prop("disabled",!1):i.prop("disabled",!0).prop("checked",!1)}function i(o,i){var e=c("#woolab_icdic_ignore_check_fail");o.prop("checked")||i.prop("checked")?e.prop("disabled",!1):e.prop("disabled",!0).prop("checked",!1)}c(document).ready(function(){var e=c("#woolab_icdic_ares_check"),a=c("#woolab_icdic_vies_check");e.length&&(o(e),i(e,a),e.change(function(){o(e),i(e,a)})),a.length&&(i(e,a),a.change(function(){i(e,a)})),a.length&&(woolab.soap||a.prop("disabled",!0).prop("checked",!1)),c(".woolab-icdic-notice").length&&c(".woolab-icdic-notice").on("click",".notice-dismiss",function(){c.ajax({url:ajaxurl,data:{action:"woolab_icdic_notice_dismiss"}})})})}(jQuery); \ No newline at end of file diff --git a/assets/js/public.js b/assets/js/public.js index 5a3d24f..b005ecd 100644 --- a/assets/js/public.js +++ b/assets/js/public.js @@ -233,6 +233,7 @@ if (woolab.ares_fill) { // Compatibility with Fluid Checkout for WooCommerce – Lite + // https://wordpress.org/support/topic/compatibility-with-kybernaut-ico-dic-plugin/ if ($('#billing_same_as_shipping') && $('#billing_same_as_shipping').is(':checked')) { // Check whether the CollapsibleBlock library is available if (window.CollapsibleBlock) { @@ -290,7 +291,10 @@ } ares_remove_disabled_from_input(); - ico_class.append('' + data.error + ''); + + if (!data.internal_error || !woolab.ignore_check_fail) { + ico_class.append('' + data.error + ''); + } } } else { ares_error(ico_class); @@ -325,11 +329,14 @@ function ares_error(ico_class) { if (woolab.ares_fill) { - $('#billing_company').val(''); - $('#billing_dic').val(''); - $('#billing_postcode').val(''); - $('#billing_city').val(''); - $('#billing_address_1').val(''); + if (!woolab.ignore_check_fail) { + $('#billing_company').val(''); + $('#billing_dic').val(''); + $('#billing_postcode').val(''); + $('#billing_city').val(''); + $('#billing_address_1').val(''); + } + ares_remove_disabled_from_input(); } diff --git a/assets/js/public.min.js b/assets/js/public.min.js index 9f060f3..6c2560f 100644 --- a/assets/js/public.min.js +++ b/assets/js/public.min.js @@ -1 +1 @@ -"use strict";!function(i){var l="";function e(){var e;switch(woolab.ares_fill&&(i(".woolab-ic-dic-tip").remove(),c()),i("#billing_ic_field").slideDown(),i("#billing_dic_field").slideDown(),i("#billing_country").val()){case"SK":i("#billing_dic_dph_field").slideDown(),i("#billing_dic_field > label").addClass("woolab-ic-dic-required");break;case"CZ":i("#billing_dic_dph_field").slideUp(),i("#billing_dic_field > label").removeClass("woolab-ic-dic-required");break;default:i("#billing_dic_dph_field").slideUp(),i("#billing_dic_field > label").removeClass("woolab-ic-dic-required")}woolab.ares_check&&(t(e=i("#billing_ic")),i(document.body).on("focusin","#billing_ic",function(){l=e.val()}),e.donetyping(function(){(e=i("#billing_ic")).val()!==l&&t(e)},500)),i("#billing_company_field").slideDown()}function o(){var l="SK"==i("#billing_country").val()?"billing_dic_dph":"billing_dic";i("#billing_company, #billing_ic, #billing_dic, #billing_dic_dph").each(function(e,o){o.getAttribute("data-value")&&(o.value=o.getAttribute("data-value"),o.id==l&&o.value.length&&i(document.body).trigger("update_checkout"))})}function n(i){i.removeClass("kbnt-wrong").removeClass("woocommerce-invalid")}function a(i){i.addClass("kbnt-wrong").addClass("woocommerce-invalid").removeClass("woocommerce-validated")}function c(){i("#billing_company").removeAttr("readonly"),i("#billing_dic").removeAttr("readonly"),i("#billing_postcode").removeAttr("readonly"),i("#billing_city").removeAttr("readonly"),i("#billing_address_1").removeAttr("readonly")}function t(e){if("CZ"===i("#billing_country").val()){var o=e.val();if(o!==l){var t=i("#billing_ic_field"),r=''+woolab.l18n_not_valid+"";i(".woolab-ic-dic-tip").remove(),n(t),t.removeClass("kbnt-ok").removeClass("woocommerce-validated"),7!=o.length&&8!=o.length||null==o.match(/^[0-9]+$/)?(c(),o.length>0?a(t):n(t)):i.ajax({url:woolab.ajaxurl,data:{action:"ajaxAres",ico:o},beforeSend:function(){t.addClass("kbnt-validating"),t.append(''+woolab.l18n_validating+"")},success:function(l){if(t.removeClass("kbnt-validating"),l)if(0==(l=JSON.parse(l)).error){if(i(".woolab-ic-dic-tip").remove(),t.addClass("kbnt-ok").addClass("woocommerce-validated").removeClass("woocommerce-invalid"),woolab.ares_fill){if(i("#billing_same_as_shipping")&&i("#billing_same_as_shipping").is(":checked")&&window.CollapsibleBlock){document.querySelector("#billing_same_as_shipping").checked=!1;var e=document.querySelector("#woocommerce-billing-fields__field-wrapper");e&&CollapsibleBlock.expand(e);var o=document.querySelector("#fc-expansible-form-section__toggle-plus--billing_company"),n=document.querySelector("#fc-expansible-form-section__content--billing_company");o&&CollapsibleBlock.collapse(o),n&&CollapsibleBlock.expand(n);var a=document.querySelector("#fc-expansible-form-section__toggle-plus--billing_dic"),s=document.querySelector("#fc-expansible-form-section__content--billing_dic");a&&CollapsibleBlock.collapse(a),s&&CollapsibleBlock.expand(s)}i("#billing_company").val(l.spolecnost).attr("readonly",!0),i("#billing_dic").val(l.dic).attr("readonly",!0),i("#billing_address_1").val(l.adresa).attr("readonly",!0),i("#billing_postcode").val(l.psc).attr("readonly",!0),i("#billing_city").val(l.mesto).attr("readonly",!0),t.append(''+woolab.l18n_ok+""),i("body").trigger("update_checkout")}}else d(t),i(".woolab-ic-dic-tip").length>0&&i(".woolab-ic-dic-tip").remove(),c(),t.append(''+l.error+"");else d(t),0==i(".woolab-ic-dic-tip").length&&(c(),t.append(r))},error:function(l){0==i(".woolab-ic-dic-tip").length&&(e.val(""),d(t),t.append(''+woolab.l18n_error+""))}}),l=e.val()}}}function d(l){woolab.ares_fill&&(i("#billing_company").val(""),i("#billing_dic").val(""),i("#billing_postcode").val(""),i("#billing_city").val(""),i("#billing_address_1").val(""),c()),a(l)}i.fn.extend({donetyping:function(l,e){e=e||1e3;var o,n=function(i){o&&(o=null,l.call(i))};return this.each(function(l,a){var c=i(a);c.is(":input")&&i(document.body).on("keyup keypress paste",a,function(i){"keyup"==i.type&&8!=i.keyCode||(o&&clearTimeout(o),o=setTimeout(function(){n(a)},e))}),c.is(":input")&&i(document.body).on("blur",a,function(){n(a)})})}}),i(document).ready(function(){i(document.body).on("input",".woolab-ic-dic-no_spaces input",function(){i(this).val(function(i,l){return l.replace(/\s+/g,"")})});var l=i("#billing_iscomp");l.length&&!l.prop("checked")||(o(),e()),i(document.body).on("change","#billing_country, #billing_iscomp",function(){var l,n=i("#billing_iscomp");!n.length||n.prop("checked")?(o(),e()):(i(".woolab-ic-dic-toggle").slideUp(),l="SK"==i("#billing_country").val()?"billing_dic_dph":"billing_dic",i("#billing_company, #billing_ic, #billing_dic, #billing_dic_dph").each(function(e,o){o.setAttribute("data-value",o.value),o.id==l&&o.value.length&&i(document.body).trigger("update_checkout"),o.value=""}))}),i("#billing_dic, #billing_dic_dph").donetyping(function(){var l=i("#billing_country").val();"SK"!=l&&"billing_dic"==this.id&&i(document.body).trigger("update_checkout"),"SK"==l&&"billing_dic_dph"==this.id&&i(document.body).trigger("update_checkout")},750)})}(jQuery); \ No newline at end of file +"use strict";!function(i){var l="";function e(){var e;switch(woolab.ares_fill&&(i(".woolab-ic-dic-tip").remove(),c()),i("#billing_ic_field").slideDown(),i("#billing_dic_field").slideDown(),i("#billing_country").val()){case"SK":i("#billing_dic_dph_field").slideDown(),i("#billing_dic_field > label").addClass("woolab-ic-dic-required");break;case"CZ":i("#billing_dic_dph_field").slideUp(),i("#billing_dic_field > label").removeClass("woolab-ic-dic-required");break;default:i("#billing_dic_dph_field").slideUp(),i("#billing_dic_field > label").removeClass("woolab-ic-dic-required")}woolab.ares_check&&(t(e=i("#billing_ic")),i(document.body).on("focusin","#billing_ic",function(){l=e.val()}),e.donetyping(function(){(e=i("#billing_ic")).val()!==l&&t(e)},500)),i("#billing_company_field").slideDown()}function o(){var l="SK"==i("#billing_country").val()?"billing_dic_dph":"billing_dic";i("#billing_company, #billing_ic, #billing_dic, #billing_dic_dph").each(function(e,o){o.getAttribute("data-value")&&(o.value=o.getAttribute("data-value"),o.id==l&&o.value.length&&i(document.body).trigger("update_checkout"))})}function n(i){i.removeClass("kbnt-wrong").removeClass("woocommerce-invalid")}function a(i){i.addClass("kbnt-wrong").addClass("woocommerce-invalid").removeClass("woocommerce-validated")}function c(){i("#billing_company").removeAttr("readonly"),i("#billing_dic").removeAttr("readonly"),i("#billing_postcode").removeAttr("readonly"),i("#billing_city").removeAttr("readonly"),i("#billing_address_1").removeAttr("readonly")}function t(e){if("CZ"===i("#billing_country").val()){var o=e.val();if(o!==l){var t=i("#billing_ic_field"),r=''+woolab.l18n_not_valid+"";i(".woolab-ic-dic-tip").remove(),n(t),t.removeClass("kbnt-ok").removeClass("woocommerce-validated"),7!=o.length&&8!=o.length||null==o.match(/^[0-9]+$/)?(c(),o.length>0?a(t):n(t)):i.ajax({url:woolab.ajaxurl,data:{action:"ajaxAres",ico:o},beforeSend:function(){t.addClass("kbnt-validating"),t.append(''+woolab.l18n_validating+"")},success:function(l){if(t.removeClass("kbnt-validating"),l)if(0==(l=JSON.parse(l)).error){if(i(".woolab-ic-dic-tip").remove(),t.addClass("kbnt-ok").addClass("woocommerce-validated").removeClass("woocommerce-invalid"),woolab.ares_fill){if(i("#billing_same_as_shipping")&&i("#billing_same_as_shipping").is(":checked")&&window.CollapsibleBlock){document.querySelector("#billing_same_as_shipping").checked=!1;var e=document.querySelector("#woocommerce-billing-fields__field-wrapper");e&&CollapsibleBlock.expand(e);var o=document.querySelector("#fc-expansible-form-section__toggle-plus--billing_company"),n=document.querySelector("#fc-expansible-form-section__content--billing_company");o&&CollapsibleBlock.collapse(o),n&&CollapsibleBlock.expand(n);var a=document.querySelector("#fc-expansible-form-section__toggle-plus--billing_dic"),s=document.querySelector("#fc-expansible-form-section__content--billing_dic");a&&CollapsibleBlock.collapse(a),s&&CollapsibleBlock.expand(s)}i("#billing_company").val(l.spolecnost).attr("readonly",!0),i("#billing_dic").val(l.dic).attr("readonly",!0),i("#billing_address_1").val(l.adresa).attr("readonly",!0),i("#billing_postcode").val(l.psc).attr("readonly",!0),i("#billing_city").val(l.mesto).attr("readonly",!0),t.append(''+woolab.l18n_ok+""),i("body").trigger("update_checkout")}}else d(t),i(".woolab-ic-dic-tip").length>0&&i(".woolab-ic-dic-tip").remove(),c(),l.internal_error&&woolab.ignore_check_fail||t.append(''+l.error+"");else d(t),0==i(".woolab-ic-dic-tip").length&&(c(),t.append(r))},error:function(l){0==i(".woolab-ic-dic-tip").length&&(e.val(""),d(t),t.append(''+woolab.l18n_error+""))}}),l=e.val()}}}function d(l){woolab.ares_fill&&(woolab.ignore_check_fail||(i("#billing_company").val(""),i("#billing_dic").val(""),i("#billing_postcode").val(""),i("#billing_city").val(""),i("#billing_address_1").val("")),c()),a(l)}i.fn.extend({donetyping:function(l,e){e=e||1e3;var o,n=function(i){o&&(o=null,l.call(i))};return this.each(function(l,a){var c=i(a);c.is(":input")&&i(document.body).on("keyup keypress paste",a,function(i){"keyup"==i.type&&8!=i.keyCode||(o&&clearTimeout(o),o=setTimeout(function(){n(a)},e))}),c.is(":input")&&i(document.body).on("blur",a,function(){n(a)})})}}),i(document).ready(function(){i(document.body).on("input",".woolab-ic-dic-no_spaces input",function(){i(this).val(function(i,l){return l.replace(/\s+/g,"")})});var l=i("#billing_iscomp");l.length&&!l.prop("checked")||(o(),e()),i(document.body).on("change","#billing_country, #billing_iscomp",function(){var l,n=i("#billing_iscomp");!n.length||n.prop("checked")?(o(),e()):(i(".woolab-ic-dic-toggle").slideUp(),l="SK"==i("#billing_country").val()?"billing_dic_dph":"billing_dic",i("#billing_company, #billing_ic, #billing_dic, #billing_dic_dph").each(function(e,o){o.setAttribute("data-value",o.value),o.id==l&&o.value.length&&i(document.body).trigger("update_checkout"),o.value=""}))}),i("#billing_dic, #billing_dic_dph").donetyping(function(){var l=i("#billing_country").val();"SK"!=l&&"billing_dic"==this.id&&i(document.body).trigger("update_checkout"),"SK"==l&&"billing_dic_dph"==this.id&&i(document.body).trigger("update_checkout")},750)})}(jQuery); \ No newline at end of file diff --git a/includes/ares.php b/includes/ares.php index 3403cac..2ed1859 100644 --- a/includes/ares.php +++ b/includes/ares.php @@ -32,7 +32,7 @@ function woolab_icdic_ares( $ico = '' ) { $body = wp_remote_retrieve_body($response); $data = json_decode($body); - if ( $status_code == 200 && $data ) { + if ( $status_code === 200 && $data ) { $return = array( 'error' => false ); $return['spolecnost'] = $data->obchodniJmeno ?? ''; @@ -49,14 +49,20 @@ function woolab_icdic_ares( $ico = '' ) { $return['psc'] = $data->sidlo->psc; $return['mesto'] = $data->sidlo->nazevMestskehoObvodu ?? $data->sidlo->nazevObce; - } elseif ( $status_code == 404 ) { + } elseif ( $status_code === 404 ) { $return = array( 'error' => __('Entity doesn\'t exist in ARES.', 'woolab-ic-dic')); } else { - $return = array( 'error' => __('ARES is not responding', 'woolab-ic-dic')); + $return = array( + 'error' => __('ARES is not responding.', 'woolab-ic-dic'), + 'internal_error' => true, + ); } } else { - $return = array( 'error' => __('An error occured while connecting to ARES, try it again later.', 'woolab-ic-dic')); + $return = array( + 'error' => __('An error occured while connecting to ARES, try it again later.', 'woolab-ic-dic'), + 'internal_error' => true, + ); } return $return; diff --git a/includes/filters-actions.php b/includes/filters-actions.php index 32c495c..f6734ed 100644 --- a/includes/filters-actions.php +++ b/includes/filters-actions.php @@ -4,6 +4,7 @@ use KybernautIcDicDeps\Ibericode\Vat\Countries; use KybernautIcDicDeps\Ibericode\Vat\Validator; +use KybernautIcDicDeps\Ibericode\Vat\Vies\ViesException; if ( ! defined( 'WPINC' ) ) { die; @@ -155,7 +156,12 @@ function woolab_icdic_checkout_field_process() { return false; } - $country = $_POST['billing_country']; + $country = $_POST['billing_country']; + $ignore_vat_check_fail = woolab_icdic_ignore_check_fail(); + + // Flag to check if VAT check fail was ignored. + // The information will be saved in the order meta in woocommerce_new_order hook. + $vat_check_fail_ignored = false; // BUSINESS ID if ( isset( $_POST['billing_ic'] ) && $_POST['billing_ic'] ) { @@ -175,7 +181,13 @@ function woolab_icdic_checkout_field_process() { $ares = woolab_icdic_ares( $ico ); if ( $ares ) { if ( $ares['error'] ) { - wc_add_notice( __( 'Enter a valid Business ID', 'woolab-ic-dic' ) . ' ' . $ares['error'], 'error' ); + $is_internal_error = ( ! empty( $ares['internal_error'] ) ); + + if ( $is_internal_error && $ignore_vat_check_fail ) { + $vat_check_fail_ignored = true; + } else { + wc_add_notice( __( 'Enter a valid Business ID', 'woolab-ic-dic' ) . ' ' . $ares['error'], 'error' ); + } } elseif ( woolab_icdic_ares_fill() ) { if ( isset( $_POST['billing_dic'] ) && wc_clean( wp_unslash($_POST['billing_dic'])) != $ares['dic'] ) { $missing_fields[] = __( 'Business ID', 'woocommerce' ); @@ -197,7 +209,11 @@ function woolab_icdic_checkout_field_process() { } } } else { - wc_add_notice( __( 'Unexpected error occurred. Try it again.', 'woolab-ic-dic' ), 'error' ); + if ( $ignore_vat_check_fail ) { + $vat_check_fail_ignored = true; + } else { + wc_add_notice( __( 'Unexpected error occurred. Try it again.', 'woolab-ic-dic' ), 'error' ); + } } // ARES Check Disabled @@ -247,8 +263,18 @@ function woolab_icdic_checkout_field_process() { wc_add_notice( __( 'VAT number has not correct format', 'woolab-ic-dic' ), 'error' ); } - if ( ! $validator->validateVatNumber( $dic )) { - wc_add_notice( __( 'Enter a valid VAT number', 'woolab-ic-dic' ), 'error' ); + try { + $vat_number_valid = $validator->validateVatNumber( $dic ); + + if ( ! $vat_number_valid ) { + wc_add_notice( __( 'Enter a valid VAT number', 'woolab-ic-dic' ), 'error' ); + } + } catch ( ViesException $exception ) { + if ( $ignore_vat_check_fail ) { + $vat_check_fail_ignored = true; + } else { + wc_add_notice( __( 'Could not validate VAT number.', 'woolab-ic-dic' ), 'error' ); + } } // Validate CZ and SK mathematicaly @@ -299,8 +325,18 @@ function woolab_icdic_checkout_field_process() { $validator = new Validator(); - if ( ! $validator->validateVatNumber( $dic_dph )) { - wc_add_notice( _x( 'Enter a valid VAT number', 'IC DPH', 'woolab-ic-dic' ), 'error' ); + try { + $vat_number_valid = $validator->validateVatNumber( $dic_dph ); + + if ( ! $vat_number_valid ) { + wc_add_notice( _x( 'Enter a valid VAT number', 'IC DPH', 'woolab-ic-dic' ), 'error' ); + } + } catch ( ViesException $exception ) { + if ( $ignore_vat_check_fail ) { + $vat_check_fail_ignored = true; + } else { + wc_add_notice( __( 'Could not validate VAT number.', 'woolab-ic-dic' ), 'error' ); + } } } else { @@ -320,6 +356,9 @@ function woolab_icdic_checkout_field_process() { } } + // Set flag about Business ID or VAT number check fails. + WC()->session->set( 'woolab_icdic_vat_check_fail_ignored', $vat_check_fail_ignored ); + } // My address formatted @@ -419,20 +458,29 @@ function woolab_icdic_set_vat_exempt_for_customer() { return; } - $vat_num = null; - $wc_countries = new WC_Countries(); - $base_country = $wc_countries->get_base_country(); - $base_country = apply_filters( 'woolab_icdic_base_country', $base_country ); - $is_vat_exempt = false; + $vat_num = null; + $wc_countries = new WC_Countries(); + $base_country = $wc_countries->get_base_country(); + $base_country = apply_filters( 'woolab_icdic_base_country', $base_country ); + $ignore_vat_check_fail = woolab_icdic_ignore_check_fail(); + $is_vat_exempt = false; if (!empty($customer->get_meta('billing_country')) && $customer->get_meta('billing_country') !== $base_country) { $vat_num = $customer->get_meta('billing_country') == 'SK' ? $customer->get_meta('billing_dic_dph') : $customer->get_meta('billing_dic'); } if (!empty($vat_num)) { - $validator = new Validator(); + $validator = new Validator(); if ( $validator->validateVatNumberFormat( $vat_num ) ) { - $is_vat_exempt = $validator->validateVatNumber( $vat_num ); + try { + $is_vat_exempt = $validator->validateVatNumber( $vat_num ); + } catch ( ViesException $exception ) { + if ( $ignore_vat_check_fail ) { + $is_vat_exempt = true; + } else { + throw $exception; + } + } } } @@ -450,12 +498,13 @@ function woolab_icdic_validate_vat_exempt_for_company( $post_data ) { $data = array(); wp_parse_str($post_data, $data); - $wc_countries = new WC_Countries(); - $base_country = $wc_countries->get_base_country(); - $base_country = apply_filters( 'woolab_icdic_base_country', $base_country ); - $country = $data['billing_country']; - $vat_countries = $wc_countries->get_european_union_countries('eu_vat'); - $is_eu_country = in_array($country, $vat_countries); + $wc_countries = new WC_Countries(); + $base_country = $wc_countries->get_base_country(); + $base_country = apply_filters( 'woolab_icdic_base_country', $base_country ); + $country = $data['billing_country']; + $vat_countries = $wc_countries->get_european_union_countries('eu_vat'); + $is_eu_country = in_array($country, $vat_countries); + $ignore_vat_check_fail = woolab_icdic_ignore_check_fail(); if ($country === $base_country || !$is_eu_country) { // Skip check if company's billing country is the same as store's country or if company's billing country is not EU VAT country. @@ -469,7 +518,15 @@ function woolab_icdic_validate_vat_exempt_for_company( $post_data ) { $is_vat_exempt = false; if ( $validator->validateVatNumberFormat( $vat_num ) ) { - $is_vat_exempt = $validator->validateVatNumber( $vat_num ); + try { + $is_vat_exempt = $validator->validateVatNumber( $vat_num ); + } catch ( ViesException $exception ) { + if ( $ignore_vat_check_fail ) { + $is_vat_exempt = true; + } else { + throw $exception; + } + } } $is_vat_exempt = apply_filters( 'woolab_icdic_vat_exempt_company', $is_vat_exempt, $data ); @@ -480,6 +537,27 @@ function woolab_icdic_validate_vat_exempt_for_company( $post_data ) { } } +/** + * Saves order metadata on WooCommerce checkout. + * @param int $order_id + */ +function woolab_icdic_save_order_metadata( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( ! $order instanceof WC_Order ) { + return; + } + + $vat_check_fail_ignored = WC()->session->get( 'woolab_icdic_vat_check_fail_ignored' ); + + $order->update_meta_data( + 'woolab_icdic_vat_check_fail_ignored', + $vat_check_fail_ignored ? 'yes' : 'no' + ); + + $order->save_meta_data(); +} + // admin function woolab_icdic_customer_meta_fields($fields) { $fields['billing']['fields'] += array( @@ -632,6 +710,132 @@ function woolab_icdic_process_shop_order ( $post_id, $post ) { } +/** + * Show notice about Business ID or VAT number check error + * below order number on orders table view. + * @param string $column Column ID. + * @param int $post_id Post ID. + */ +function woolab_icdic_show_check_failed_notice_on_orders_table( $column, $post_id ) { + if ( $column !== 'order_number' ) { + return; + } + + $order = wc_get_order( $post_id ); + $check_failed = ( $order instanceof WC_Order ) + ? ( $order->get_meta( 'woolab_icdic_vat_check_fail_ignored' ) === 'yes' ) + : false; + + if ( ! $check_failed ) { + return; + } + + ?> + +
+ + + + + get_meta( 'woolab_icdic_vat_check_fail_ignored' ) === 'yes' ) + : false; + + if ( ! $check_failed ) { + return; + } + + ?> + + + + +
+ + get_meta( 'woolab_icdic_vat_check_fail_ignored' ) === 'yes' ); + + if ( ! $check_failed ) { + return; + } + + ?> + +
+

+
+ + +

+
+ + get_meta( 'woolab_icdic_vat_check_fail_ignored' ) === 'yes' ); + + if ( ! $check_failed ) { + return; + } + + ob_start(); + + ?> + +

+
+ + +

+ + 'checkbox', 'disabled' => $vat_check_disabled, ); + $settings[] = array( + 'title' => __( 'Ignore when ARES or VIES check fails for technical reasons', 'woolab-ic-dic' ), + 'desc' => __( 'Allow the creation of an order if the verification of the Business ID in ARES or the VAT number in the European VIES database fails for technical reasons.', 'woolab-ic-dic' ), + 'id' => 'woolab_icdic_ignore_check_fail', + 'default' => 'no', + 'type' => 'checkbox', + ); $settings[] = array( 'title' => __( 'Toggle fields visibility', 'woolab-ic-dic' ), 'desc' => __( 'Enable toggle switch to show/hide input fields', 'woolab-ic-dic' ) . ( class_exists("FluidCheckout") ? '
' . __("This feature is not compatible with Fluid Checkout for WooCommerce.", 'woolab-ic-dic') . '': ""), diff --git a/languages/woolab-ic-dic.pot b/languages/woolab-ic-dic.pot index 01dad4f..a820571 100644 --- a/languages/woolab-ic-dic.pot +++ b/languages/woolab-ic-dic.pot @@ -1,31 +1,26 @@ -# Copyright (C) 2023 woolab-ic-dic +# Copyright (C) 2024 woolab-ic-dic # This file is distributed under the same license as the woolab-ic-dic package. -#, fuzzy msgid "" msgstr "" "Project-Id-Version: woolab-ic-dic\n" -"Report-Msgid-Bugs-To: https://kybernaut.cz/kontakt/\n" -"POT-Creation-Date: \n" -"PO-Revision-Date: \n" -"Last-Translator: Karolína Vyskočilová \n" -"Language-Team: Kybernaut \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language-Team: Kybernaut \n" +"Last-Translator: Karolína Vyskočilová \n" +"Report-Msgid-Bugs-To: https://kybernaut.cz/kontakt/\n" "X-Poedit-Basepath: ..\n" "X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n" -"X-Poedit-SourceCharset: UTF-8\n" -"X-Generator: Poedit 3.2\n" "X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPathExcluded-0: *.js\n" +"X-Poedit-SourceCharset: UTF-8\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #: includes/admin-notice.php:9 -#, php-format msgid "Kybernaut IČO DIČ has now settings, go to the %1$s page and check it out!" msgstr "" -#: includes/admin-notice.php:9 includes/filters-actions.php:603 +#: includes/admin-notice.php:9, includes/filters-actions.php:789 msgid "Settings" msgstr "" @@ -33,231 +28,240 @@ msgstr "" msgid "Business ID not set." msgstr "" +#: includes/ares.php:23 +msgid "Business ID must be a number and 8 digits long." +msgstr "" + #: includes/ares.php:53 msgid "Entity doesn't exist in ARES." msgstr "" -#: includes/ares.php:58 -msgid "ARES is not responding" +#: includes/ares.php:56 +msgid "ARES is not responding." msgstr "" #: includes/ares.php:63 -msgid "WP ERROR, can't connect." +msgid "An error occured while connecting to ARES, try it again later." msgstr "" -#: includes/filters-actions.php:18 -msgid "View GitHub" +#: includes/compatibility/pdf-invoices-and-packing-slips-for-woocommerce.php:30, includes/filters-actions.php:33, includes/filters-actions.php:116, includes/filters-actions.php:565, includes/filters-actions.php:588 +msgid "Business ID" msgstr "" -#: includes/filters-actions.php:18 -msgid "GitHub" +#: includes/compatibility/pdf-invoices-and-packing-slips-for-woocommerce.php:33, includes/filters-actions.php:41, includes/filters-actions.php:124, includes/filters-actions.php:569, includes/filters-actions.php:592 +msgid "Tax ID" msgstr "" -#: includes/filters-actions.php:19 -msgid "Write a Review" +#: includes/compatibility/pdf-invoices-and-packing-slips-for-woocommerce.php:36, includes/filters-actions.php:49, includes/filters-actions.php:135, includes/filters-actions.php:573, includes/filters-actions.php:596 +msgid "VAT reg. no." msgstr "" -#: includes/filters-actions.php:32 includes/filters-actions.php:115 -#: includes/filters-actions.php:181 includes/filters-actions.php:459 -#: includes/filters-actions.php:482 -msgid "Business ID" +#: includes/filters-actions.php:19 +msgid "View GitHub" msgstr "" -#: includes/filters-actions.php:33 includes/filters-actions.php:116 -msgctxt "placeholder" -msgid "Business ID" +#: includes/filters-actions.php:19 +msgid "GitHub" msgstr "" -#: includes/filters-actions.php:40 includes/filters-actions.php:123 -#: includes/filters-actions.php:463 includes/filters-actions.php:486 -msgid "Tax ID" +#: includes/filters-actions.php:20, includes/filters-actions.php:20 +msgid "Write a Review" msgstr "" -#: includes/filters-actions.php:41 includes/filters-actions.php:124 +#: includes/filters-actions.php:34, includes/filters-actions.php:117 msgctxt "placeholder" -msgid "Tax ID" +msgid "Business ID" msgstr "" -#: includes/filters-actions.php:48 includes/filters-actions.php:134 -#: includes/filters-actions.php:467 includes/filters-actions.php:490 -msgid "VAT reg. no." +#: includes/filters-actions.php:42, includes/filters-actions.php:125 +msgctxt "placeholder" +msgid "Tax ID" msgstr "" -#: includes/filters-actions.php:49 includes/filters-actions.php:135 +#: includes/filters-actions.php:50, includes/filters-actions.php:136 msgctxt "placeholder" msgid "VAT reg. no." msgstr "" -#: includes/filters-actions.php:65 +#: includes/filters-actions.php:66 msgid "Buying as a company" msgstr "" -#: includes/filters-actions.php:98 includes/filters-actions.php:99 -msgid "required" -msgstr "" - -#: includes/filters-actions.php:100 +#: includes/filters-actions.php:101 msgid "Tax ID (optional, enter only if you are a VAT payer)" msgstr "" -#: includes/filters-actions.php:105 includes/filters-actions.php:184 -msgid "Company" -msgstr "" - -#: includes/filters-actions.php:178 includes/filters-actions.php:205 -#: includes/filters-actions.php:212 +#: includes/filters-actions.php:189, includes/filters-actions.php:221, includes/filters-actions.php:228 msgid "Enter a valid Business ID" msgstr "" -#: includes/filters-actions.php:187 -msgid "Postcode / ZIP" -msgstr "" - -#: includes/filters-actions.php:190 -msgid "Town / City" -msgstr "" - -#: includes/filters-actions.php:193 -msgid "Address" -msgstr "" - -#: includes/filters-actions.php:196 -#, php-format +#: includes/filters-actions.php:208 msgid "%s is not corresponding to ARES." msgid_plural "%s are not corresponding to ARES." msgstr[0] "" msgstr[1] "" -#: includes/filters-actions.php:200 woolab-ic-dic.php:124 +#: includes/filters-actions.php:215, woolab-ic-dic.php:133 msgid "Unexpected error occurred. Try it again." msgstr "" -#: includes/filters-actions.php:241 +#: includes/filters-actions.php:257, includes/filters-actions.php:319 +msgid "The billing country does not correspond to the country of the VAT number." +msgstr "" + +#: includes/filters-actions.php:263 msgid "VAT number has not correct format" msgstr "" -#: includes/filters-actions.php:245 includes/filters-actions.php:252 +#: includes/filters-actions.php:270, includes/filters-actions.php:284 msgid "Enter a valid VAT number" msgstr "" -#: includes/filters-actions.php:257 includes/filters-actions.php:270 +#: includes/filters-actions.php:276, includes/filters-actions.php:338 +msgid "Could not validate VAT number." +msgstr "" + +#: includes/filters-actions.php:289, includes/filters-actions.php:302 msgid "Enter a valid Tax ID" msgstr "" -#: includes/filters-actions.php:291 includes/filters-actions.php:297 +#: includes/filters-actions.php:332, includes/filters-actions.php:345 msgctxt "IC DPH" msgid "Enter a valid VAT number" msgstr "" -#: includes/filters-actions.php:305 +#: includes/filters-actions.php:353 msgid "Tax ID or VAT number is not valid." msgstr "" -#: includes/filters-actions.php:337 includes/filters-actions.php:340 +#: includes/filters-actions.php:404, includes/filters-actions.php:407 msgid "Business ID: " msgstr "" -#: includes/filters-actions.php:338 includes/filters-actions.php:341 +#: includes/filters-actions.php:405, includes/filters-actions.php:408 msgid "Tax ID: " msgstr "" -#: includes/filters-actions.php:339 includes/filters-actions.php:342 +#: includes/filters-actions.php:406, includes/filters-actions.php:409 msgid "VAT reg. no.: " msgstr "" -#: includes/filters-actions.php:603 +#: includes/filters-actions.php:729, includes/filters-actions.php:772 +msgid "Caution!" +msgstr "" + +#: includes/filters-actions.php:730, includes/filters-actions.php:773 +msgid "Verification of VAT number has failed." +msgstr "" + +#: includes/filters-actions.php:731, includes/filters-actions.php:774 +msgid "Please, make sure the VAT number is valid before processing the order." +msgstr "" + +#: includes/filters-actions.php:789 msgid "View Kybernaut IČO DIČ settings" msgstr "" -#: includes/settings.php:7 includes/settings.php:10 +#: includes/settings.php:10, includes/settings.php:13 msgid "Enable validation of VAT number in EU database VIES." msgstr "" -#: includes/settings.php:10 +#: includes/settings.php:13 msgid "To enable this feature, turn on Soap Client (ask your hosting)." msgstr "" -#: includes/settings.php:14 +#: includes/settings.php:18 msgid "Enable VAT exemption for valid EU VAT numbers" msgstr "" -#: includes/settings.php:18 +#: includes/settings.php:22 msgid "To enable this feature, turn on taxes in your store." msgstr "" -#: includes/settings.php:26 +#: includes/settings.php:31 msgid "To enable this feature, set your base country to one of the EU VAT countries." msgstr "" -#: includes/settings.php:30 +#: includes/settings.php:41 msgid "Kybernaut IČO DIČ options" msgstr "" -#: includes/settings.php:30 +#: includes/settings.php:41 msgid "The following options affect how Business ID and VAT number behaves." msgstr "" -#: includes/settings.php:32 +#: includes/settings.php:43 msgid "CZ: Validate Business ID in ARES" msgstr "" -#: includes/settings.php:33 +#: includes/settings.php:44 msgid "Enable validation of Business ID in Czech database ARES." msgstr "" -#: includes/settings.php:39 +#: includes/settings.php:50 msgid "CZ: Validate and autofill based on ARES" msgstr "" -#: includes/settings.php:40 +#: includes/settings.php:51 msgid "Enable autofill and validation for Company, VAT number, Address, City, and Postcode fields based on Czech database ARES. Requires checked the option above." msgstr "" -#: includes/settings.php:46 +#: includes/settings.php:57 msgid "EU: Validate VAT number in VIES" msgstr "" -#: includes/settings.php:53 +#: includes/settings.php:65 msgid "EU: VAT exempt" msgstr "" -#: includes/settings.php:60 +#: includes/settings.php:73 +msgid "Ignore when ARES or VIES check fails for technical reasons" +msgstr "" + +#: includes/settings.php:74 +msgid "Allow the creation of an order if the verification of the Business ID in ARES or the VAT number in the European VIES database fails for technical reasons." +msgstr "" + +#: includes/settings.php:80 msgid "Toggle fields visibility" msgstr "" -#: includes/settings.php:61 +#: includes/settings.php:81 msgid "Enable toggle switch to show/hide input fields" msgstr "" -#: includes/settings.php:67 +#: includes/settings.php:81, includes/settings.php:89 +msgid "This feature is not compatible with Fluid Checkout for WooCommerce." +msgstr "" + +#: includes/settings.php:88 msgid "Move Country to top" msgstr "" -#: includes/settings.php:68 +#: includes/settings.php:89 msgid "Move Country field above the \"Buying as a company\" toggle" msgstr "" -#: woolab-ic-dic.php:53 +#: woolab-ic-dic.php:57 msgid "Kybernaut IČ DIČ" msgstr "" -#: woolab-ic-dic.php:54 +#: woolab-ic-dic.php:58 msgid "WooCommerce" msgstr "" -#: woolab-ic-dic.php:57 -#, php-format +#: woolab-ic-dic.php:61 msgid "%1$s requires %2$s to function. Please activate %2$s before you activate %1$s. This plugin has been deactivated." msgstr "" -#: woolab-ic-dic.php:123 +#: woolab-ic-dic.php:132 msgid "Business ID is invalid." msgstr "" -#: woolab-ic-dic.php:125 +#: woolab-ic-dic.php:134 msgid "Information loaded succesfully from ARES." msgstr "" -#: woolab-ic-dic.php:126 +#: woolab-ic-dic.php:135 msgid "Validating data in ARES." msgstr "" diff --git a/readme.txt b/readme.txt index bb694f2..492c917 100644 --- a/readme.txt +++ b/readme.txt @@ -130,6 +130,10 @@ Either post it on [GitHub](https://github.com/vyskoczilova/kybernaut-ic-dic) or == Changelog == += 1.8.3 () = + +* Feature: New checkbox "Ignore when ARES or VIES check fails for technical reasons" in plugin settings. If this option is enabled and validation of business ID or VAT number fails for technical reason (not because it is invalid), an order is placed. For orders at which validation fails, there is an alert at admin edit screen and in admin e-mails. Big thanks to [@PavelVybiral](https://github.com/PavelVybiral) [#72](https://github.com/vyskoczilova/kybernaut-ic-dic/pull/72) + = 1.8.2 (2024-01-09) = * Feature: added support for [WooCommerce PDF Invoices and Packing Slips for WooCommerce](https://wordpress.org/plugins/pdf-invoices-and-packing-slips-for-woocommerce/) by Acowebs (sponsored by [tuningmotocyklov.sk](https://www.tuningmotocyklov.sk)) diff --git a/src/js/admin.js b/src/js/admin.js index 5ea2bcf..43c4813 100644 --- a/src/js/admin.js +++ b/src/js/admin.js @@ -7,9 +7,20 @@ var vies_check = $('#woolab_icdic_vies_check'); if ( ares_check.length ) { - enableActive( ares_check ); + enableAresActive( ares_check ); + enableIgnoreCheckFailActive( ares_check, vies_check ); + ares_check.change( function(){ - enableActive( ares_check ); + enableAresActive( ares_check ); + enableIgnoreCheckFailActive( ares_check, vies_check ); + }); + } + + if ( vies_check.length ) { + enableIgnoreCheckFailActive( ares_check, vies_check ); + + vies_check.change( function(){ + enableIgnoreCheckFailActive( ares_check, vies_check ); }); } @@ -32,7 +43,7 @@ }); - function enableActive( ares_check ) { + function enableAresActive( ares_check ) { var active = $('#woolab_icdic_ares_fill'); if ( ares_check.prop( "checked" ) == true) { @@ -42,5 +53,19 @@ } } + + function enableIgnoreCheckFailActive( ares_check, vies_check ) { + + var checkbox = $( '#woolab_icdic_ignore_check_fail' ); + + if ( ares_check.prop( 'checked' ) || vies_check.prop( 'checked' ) ) { + checkbox.prop('disabled', false); + } else { + checkbox + .prop( 'disabled', true ) + .prop( 'checked', false ); + } + + } })( jQuery ); \ No newline at end of file diff --git a/src/js/public.js b/src/js/public.js index 71bcc04..b461486 100644 --- a/src/js/public.js +++ b/src/js/public.js @@ -276,12 +276,18 @@ } } else { + ares_error( ico_class ); if ( $('.woolab-ic-dic-tip').length > 0 ) { $('.woolab-ic-dic-tip').remove(); } + ares_remove_disabled_from_input(); - ico_class.append( ''+data.error+'' ); + + if ( ! data.internal_error || ! woolab.ignore_check_fail ) { + ico_class.append('' + data.error + ''); + } + } } else { @@ -318,13 +324,17 @@ function ares_error ( ico_class ) { if ( woolab.ares_fill ) { - $('#billing_company').val(''); - $('#billing_dic').val(''); - $('#billing_postcode').val(''); - $('#billing_city').val(''); - $('#billing_address_1').val(''); + if ( ! woolab.ignore_check_fail ) { + $('#billing_company').val(''); + $('#billing_dic').val(''); + $('#billing_postcode').val(''); + $('#billing_city').val(''); + $('#billing_address_1').val(''); + } + ares_remove_disabled_from_input(); } + woolab_add_class_wrong( ico_class ); } diff --git a/tests/unit/AresTest.php b/tests/unit/AresTest.php index be6b353..941ca17 100644 --- a/tests/unit/AresTest.php +++ b/tests/unit/AresTest.php @@ -68,7 +68,7 @@ public function testWpError() { ]); $this->assertEquals( - array( 'error' => __('An error occured while connecting to ARES, try it again later.', 'kybernaut-messenger')), + array( 'error' => __('An error occured while connecting to ARES, try it again later.', 'kybernaut-messenger'), 'internal_error' => true), woolab_icdic_ares(88922961) ); @@ -128,8 +128,13 @@ public function testOtherStatusCode() { 'return' => 500 ]); + WP_Mock::userFunction('wp_remote_retrieve_body', [ + 'times' => 1, + 'return_arg' => 0, + ]); + $this->assertEquals( - array( 'error' => __('ARES is not responding', 'kybernaut-messenger')), + array( 'error' => __('ARES is not responding.', 'kybernaut-messenger'), 'internal_error' => true), woolab_icdic_ares(88922961) ); } diff --git a/woolab-ic-dic.php b/woolab-ic-dic.php index 56a433e..accc754 100644 --- a/woolab-ic-dic.php +++ b/woolab-ic-dic.php @@ -98,6 +98,11 @@ function woolab_icdic_plugin_admin_notice() { add_filter( 'default_checkout_billing_iscomp', 'woolab_icdic_toggle_iscomp_field', 10, 2 ); add_action( 'init', 'woolab_icdic_set_vat_exempt_for_customer', 10, 1 ); add_action( 'woocommerce_checkout_update_order_review', 'woolab_icdic_validate_vat_exempt_for_company', 10, 1 ); + add_action( 'woocommerce_checkout_update_order_meta', 'woolab_icdic_save_order_metadata' ); + add_action( 'manage_shop_order_posts_custom_column', 'woolab_icdic_show_check_failed_notice_on_orders_table', 20, 2 ); // HPOS not enabled. + add_action( 'woocommerce_shop_order_list_table_custom_column', 'woolab_icdic_show_check_failed_notice_on_orders_table_hpos', 10, 2 ); // HPOS alternative of "manage_shop_order_posts_custom_column" above. + add_action( 'woocommerce_admin_order_data_after_billing_address', 'woolab_icdic_show_check_failed_notice_on_order_edit' ); + add_action( 'woocommerce_email_order_details', 'woolab_icdic_show_check_failed_notice_on_admin_email', 5, 3 ); if ( version_compare( WC_VERSION, '2.7', '<' )) { add_filter( 'woocommerce_found_customer_details', 'woolab_icdic_ajax_get_customer_details_old_woo', 10, 1 ); @@ -133,6 +138,7 @@ function woolab_icdic_enqueue_scripts() { 'l18n_validating' => __('Validating data in ARES.', 'woolab-ic-dic'), 'ares_check' => woolab_icdic_ares_check(), 'ares_fill' => woolab_icdic_ares_fill(), + 'ignore_check_fail' => woolab_icdic_ignore_check_fail(), )); if ( apply_filters( 'woolab_icdic_toggle', get_option('woolab_icdic_toggle_switch', 'no') ) === 'yes') { wp_enqueue_style( 'woolab-icdic-public-css', WOOLAB_IC_DIC_URL . 'assets/css/style.css', null, WOOLAB_IC_DIC_VERSION ); @@ -161,6 +167,11 @@ function woolab_icdic_vies_check() { } +function woolab_icdic_ignore_check_fail() { + $option = woolab_icdic_get_option( 'woolab_icdic_ignore_check_fail', 'no' ); + return apply_filters( 'woolab_icdic_ignore_check_fail', $option ); +} + function woolab_icdic_get_option( $name, $default = 'yes' ) { $option = get_option( $name, $default );