From d466e6d14a8649b65f2813ee4f17b1a84c2dd228 Mon Sep 17 00:00:00 2001 From: RafaMelazzo Date: Thu, 12 Sep 2024 18:23:39 -0300 Subject: [PATCH 01/12] feat: added document field to checkout --- .../front/checkout/checkoutFields.js | 25 +++ languages/woo-pagarme-payments-pt_BR.mo | Bin 39601 -> 40311 bytes languages/woo-pagarme-payments-pt_BR.po | 28 ++- src/Action/ActionsRunner.php | 6 +- src/Action/CustomerFieldsActions.php | 212 ++++++++++++++++++ src/Action/OrderActions.php | 5 +- src/Controller/Checkout/CustomerFields.php | 25 +++ src/Helper/Utils.php | 56 +++++ 8 files changed, 353 insertions(+), 4 deletions(-) create mode 100644 assets/javascripts/front/checkout/checkoutFields.js create mode 100644 src/Action/CustomerFieldsActions.php create mode 100644 src/Controller/Checkout/CustomerFields.php diff --git a/assets/javascripts/front/checkout/checkoutFields.js b/assets/javascripts/front/checkout/checkoutFields.js new file mode 100644 index 00000000..1103cfa8 --- /dev/null +++ b/assets/javascripts/front/checkout/checkoutFields.js @@ -0,0 +1,25 @@ +/* globals wc_pagarme_checkout */ +/* jshint esversion: 6 */ +let pagarmeCustomerFields = { + billingDocumentField: jQuery('#billing_document'), + shippingDocumentField: jQuery('#shipping_document'), + documentMasks: ['000.000.000-00999', '00.000.000/0000-00'], + documentMaskOptions: { + onKeyPress: function (document, e, field, options) { + const masks = pagarmeCustomerFields.documentMasks, + mask = document.length > 14 ? masks[1] : masks[0]; + field.mask(mask, options); + } + }, + + applyDocumentMask() { + this.billingDocumentField.mask(this.documentMasks[0], this.documentMaskOptions); + this.shippingDocumentField.mask(this.documentMasks[0], this.documentMaskOptions); + }, + + start: function () { + this.applyDocumentMask(); + } +}; + +pagarmeCustomerFields.start(); diff --git a/languages/woo-pagarme-payments-pt_BR.mo b/languages/woo-pagarme-payments-pt_BR.mo index 12535bd8fc0846a1622131e287be81157a5ad882..b715f6eec752ec5f13ede2e6a3132ebff584bfa1 100644 GIT binary patch delta 9103 zcmb8zcYM{={m1bWMiwDJSb;EZfIxr@5(p5$Faxqe3^HZikPAsnav=j{$Ylft1O-zO z1qH>eh!_RqEJXzrMG&P@3y!*Htwkwf`+DDV;-kOEqyPNAkACtz<2%mxbI$o*?EYsO z{QO*lz`2-4w;PU)A;xsTk|<+3HZbOeShX6{C*GK7Ov9cy40~WPHpAO+I^Ks|W-ehE z{)W0Pw2Lv3*c!RD@!-9fjH8SRm=hFq!&Y65nSetu6E|QU9>&SorkgQ+u^8LqJ=hBC zFcjayaC{e2@f@aObb>J%I2;Gyb=Vg7VI0plM=0pcKXDzVI}f8Ci!Cq}HNfG>SWFSd z;b!cNk6<+(!%)oOWSut!TjEmGKsP(@LrygZF^=b(a};*qzpyE8OEe||@5k2o1S-X^ zU?c3vJT%5G*aQ<%5AKJWlEJ9!#^XWsVi>mTWzUO8otKCK-Dn^MJva*+;sn%di-@7T*li{R>f3T8$dW4%8IwP9pyr=_@p7WXCZd z&!7e}DA{Ia6skWDHIUh;ffV5(tak0AQ|yECP;*{{x^5*7#0@wL|AbnEodYaYbqqkJ z$t*&>*FkJs5?Lxb_360lkRIRNyFu zW)#jL>(6|LN?DsUb^xZMcENb;gtJitS%ERQ(Rnv2rB7lvJdIlY7hQW(7LZ;r4fR6T zAOi`QV%JdRtVX?g4QfEUkb9UTsDWNYWgvo&fd&+hy74eqFGgLr0sG;8WOmGFH~?GG zsEkj*Q0@P96qKq>!3Mr)$n={#QLFqltiXs2)&t&vO5L-#4Bx_*IJUq2K+Q(2ovo;~ zwF7H#59-ARFp6F{631x&mr=;Y1IYhO7{e>Vq4+pHf?DNM`7AcaN^FPgP!HIJ%FIKk zMR^cg;VIPlpQF~mFQ|bx<}Fl@!+^egi4-(<+1MM4ur1#1+>08(tEd5ff_me)!R`y` z9FBUk$*3t?iF(kJ$j^a!5w&*CV=R6dnXEWSoKRaWBT;dSoQGP~i%}zAiud3qSMQz8o~E9Ky73RFfnP=swi|6C$1Lst_N=hRG|WJ~;aq1iYL2R$H=}mNz1SD)P^tbFL-7J?z?YrPue7_WD{4`X zL9MaLsLXhA70)-TD1>9kSo`AZd zdo|Wk-|pJ;rrO0iAGH?BP*YQdnv&a54|*PTpSN%po=0VP$Ta(*3S3V?seS|-;>W0w zeujF(3&<>(@afDmPDibg!>G)BiZiesf4o?MY4|Q`&4kUg4@yEU%Gs!aEx-o){a;F< ziqZ;Coml^ zA{)UZ&DEEb`CmdIpN40VJ`*?3{=;DzcBZ}$+v5pTs=spn9W$u^f&(#y*H>y6Vm9u< z*7zlM!hfUg*NKNU!7PjoP#8x+515a-;Yw5nol{3{i`Y0w-GzyUZO^KdP);LUre8zdFl zH_ku}d=9F;(A5`X81?0@eXVQXgi8H3)PN75GH{}h{Hx((*Kx^pv?{VG?SX^n&qk$k z6>4`phPv)~)WA=prs@mS8;2F!48&s+^+eRbrl4MUHZohLC_q80{!P?&`v4>GJJgMT z!32!DmW7AusP>K}_DhzA-KpoG+N&@JH{cTdGxowsrFOe6!({4DpxOf;P|%3N%IqAs z#3<_BP>V7R+u{UVfd!}meuRF161zk{xqi|=ig8^W3>R(|TUcy9dTW;TI7{*hdfjx0Krr`sqHFE~jF{Z*U(rnbO z$Z<}=RGx2UQOLqg$V;0yZ~_jlv~#;2Z=${ryWoH-yGv%GQhpn13U=ded=RzR#;^cV za1u_$l{giTqh7S@b>yG*WC|%fj;B#6UVXj2@h;SA-izUQ1eLwG2~*YvGZ!!uDQNo?p+;PT z`mk(AEv7xFxqlMdD+td$74R8{wKOZ&Mt55^F4K*c?V{rc;qtK0p zQ}_!0jCzw7)*17<+EJ_d?i=0DGJ2?=MZM7_?1D)*+5SmbK)nj{bROnn@_L)Gm8dW7 zO&H0vni>ik**&O5^eiexCouzmKwZ#%gPo#u)PM$|26`1H;zHC^Zb4;WH)@V+ky$kF zxc(^{Z3cW8{Qv*fP|%#M$8NY2L-COFC^n>i0u%5ZRBA6`IJUjnE?N&Br#=b4#SWWT z`53v`PSNYwllqU?Tm84N|8>JFS(*c|4CC=ZRQpj($L~`(p0t>j;YpJ?cVy>GM5!W8P8F&SULUicO21Jk<3 z{)fg0Or^dC^+r#j`p=;T)Z`EL`ZUx)=c2wFTX7oh4Nyo3;ro5N{YPYPh8spl0cuT@ zpyu{QY=Zl+F+Put@DO_NH5`tgV{`0zhg}cMlJ%TbvQ+(Dr&g*t47C-D@1 zhT3j*+wFEdjhgH8s7!o;%1p~U?P42_5!A27#W)9Z@oh}U_`B?{?A55Xv>u!Ce6xu{ z8yfDy>9`+PVdM@w!kcjr^}Wc)(0qZ#xNxUU`6<*Y{|&RS)7|y~voVIc7aL$DlIY;^ zJbzmROU(Zx6c!OLs*y9^3wE%r+}We4A0)0P+R(#{+!T%(qHG=ZonoX%0EXraf)b2qldUcjqcdsEX7}4c{5()Zj_80h!P^r zwYk$wrK>+ogBG_AZDSp)^+(TtiAdo@en(6NR-=v;?&2XBPkj%e&odh&c%635n}oLQ zlf(yvj_(M5b4*jNWA~W{iDATALdUhVSK6Wp?4poI!$hJhv4#4TIGKo}>?5uvbgZY1 z4_olpPWAirhhrVFjJ^xl6JNuDSb(#MpNaO=J$R0|mw21F-@XT1h0gk8YJCBtTzfRG zCJKo(+P@@TC8klo64&7<;xOf9L?fd9m`~vV5l??JY>78xBGy0O@bxu!6E71Ni6lBZ z6Z-VdAPOkofK%`Z)bVFa@Vl?#SFT>fIb(?))cfHfe8=^PakLfI*ERo-5wmC*#C={>%6+SAN_%7MpY45LXvRh)YDKDjZ(=pS49Zo$_cR(1<_XX$&RO zU8guhTtl27Vu>z`5Vzcs!495IRDr>*(Z6q8vxLt*fte<^|8PpXtVwhlT{#F~8NE zkV``^{2N9RuMibPQzDGe(VPBoTQnbGCiN)H$NFOmg#pxm#9_FQxRIDeeIfA=Vkz~T zh*f&Nmj)f>G-MG|2_54sW-Cr}WgmT?xpEzjBD&Ky*Inbff;_|DKe~ok`e(ZGZf6*6 z$(sK=i1kDj4NI^Tqwx!(73KdvuK%z47}qfg*SPk4%1bEsCwfuVKTdQ^aQ(+@)jWj# zh`@9F+2=yNg}Z?@Xe74pBtQ*F*%d*Y*D56tTpghy+zQwi9!R#+v_m z?&f9qlzKS^6FZ43X!{r+B^J5!D4Gw6;R@H5LphtMrk+h)P5CrYe+;56*PZ(Z8aomF zgPqDhN2=>wjvI+u+GgP5U@t!!_&#ym)#qY+Vm{}@5Z_S#3vra#M%+sHi7xc{iSH@D zOLU}c5(=*O_!oE*Dm;k^wWXf78bx^v3d(&I6`lfbrMEUUp<$!YqLPxLvV}E$dZtC@ zj`sM=JtK2+$JNg5nHd`9pI=q#E32&CmfECEfP$~wWcI2o z_xUP4W!_SrQ0T9!@YUbYTUOvH^A#;D%=cH77yA7LweO9&rA1_Ba-U33TIQg>88u}y z&W2>vj-NR+w8=<+>7o*!UejN@VcwQTQ4744Rps2222ammJJYmCei?-(z7B z_3!Dg4KLjmTl3fIu$tcMq7%r#lEe3sAHVWZ=J(9^mM-#px-YKsR}QYfrp7ZTHY}kc zn4+4K)h%^pT76Rd|MLd*m-;;gK2onsYqzeO)}XPkY)O&7=JT5-B;@!@eaxz-yvm#8 fDLedJsjr-~y^Ns3>+yN=y+!5a{@V2QftddQ9HE~$ delta 8467 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 Wb$xtF*RAhcTCpmuJmi6yb^i~I2J_kg diff --git a/languages/woo-pagarme-payments-pt_BR.po b/languages/woo-pagarme-payments-pt_BR.po index 9a059bd1..88398010 100644 --- a/languages/woo-pagarme-payments-pt_BR.po +++ b/languages/woo-pagarme-payments-pt_BR.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: WooCommerce Pagar.me Payments 1.0\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/woo-pagarme-payments\n" "POT-Creation-Date: 2018-06-22 13:58-0300\n" -"PO-Revision-Date: 2024-08-21 11:52-0300\n" +"PO-Revision-Date: 2024-09-09 19:35-0300\n" "Last-Translator: Pagar.me\n" "Language-Team: \n" "Language: pt_BR\n" @@ -13,7 +13,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 3.4.3\n" +"X-Generator: Poedit 3.5\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c;_nc:1,2;_x:1,2c;_ex:1,2c;" "_nx:4c,1,2;_nx_noop:4c,1,2\n" @@ -1494,3 +1494,27 @@ msgstr "" msgid "Error processing payment. Please try again later." msgstr "Erro ao processar o pagamento. Por favor tente novamente mais tarde." + +msgid "Document" +msgstr "Documento" + +msgid "CPF or CNPJ" +msgstr "CPF ou CNPJ" + +msgid "Billing" +msgstr "faturamento" + +msgid "Shipping" +msgstr "envio" + +msgid "Please, enter a valid document number in the %s Document." +msgstr "Por favor, digite um número de documento válido no campo Documento de %s." + +msgid "Please, enter a valid %s number in the %s Document." +msgstr "Por favor, digite um número de %s válido no campo "Documento" do endereço de %s." + +msgid "Street name, house number and neighbourhood" +msgstr "Nome da rua, número da casa e bairro" + +msgid "Additional address data" +msgstr "Complemento" diff --git a/src/Action/ActionsRunner.php b/src/Action/ActionsRunner.php index c19ae217..b08e23b8 100644 --- a/src/Action/ActionsRunner.php +++ b/src/Action/ActionsRunner.php @@ -2,10 +2,14 @@ namespace Woocommerce\Pagarme\Action; +/** + * @uses CustomerFieldsActions, OrderActions + */ class ActionsRunner implements RunnerInterface { private $actionClasses = [ - "OrderActions" + "OrderActions", + "CustomerFieldsActions" ]; public function run() diff --git a/src/Action/CustomerFieldsActions.php b/src/Action/CustomerFieldsActions.php new file mode 100644 index 00000000..b8ad8f01 --- /dev/null +++ b/src/Action/CustomerFieldsActions.php @@ -0,0 +1,212 @@ +customerFields = new CustomerFields(); + } + + public function run() + { + add_filter('woocommerce_checkout_init', array($this, 'enqueueScript')); + add_filter('woocommerce_default_address_fields', array($this, 'overrideAddressFields')); + add_filter('woocommerce_checkout_fields', array($this, 'addDocumentField')); + add_action('woocommerce_checkout_process', array($this, 'validateDocument')); + } + + public function enqueueScript() + { + $parameters = Utils::getRegisterScriptParameters('front/checkout', 'checkoutFields', ['jquery.mask']); + wp_register_script( + 'pagarme_customer_fields', + $parameters['src'], + $parameters['deps'], + $parameters['ver'] + ); + wp_enqueue_script('pagarme_customer_fields'); + } + + /** + * @param array $fields + * + * @return array + */ + public function addDocumentField(array $fields): array + { + if ($this->customerFields->hasDocumentField($fields)) { + return $fields; + } + + foreach (self::ADDRESS_TYPES as $addressType) { + $fields[$addressType]["{$addressType}_document"] = array( + 'label' => __('Document', 'woo-pagarme-payments'), + 'placeholder' => __('CPF or CNPJ', 'woo-pagarme-payments'), + 'required' => true, + 'class' => array('form-row-wide'), + 'priority' => 25 + ); + } + + return $fields; + } + + /** + * @return void + * @uses isValidCnpj() + * @uses isValidCpf() + */ + public function validateDocument() + { + foreach (self::ADDRESS_TYPES as $addressType) { + $document = $_POST["{$addressType}_document"]; + + if (!$document) { + continue; + } + + $documentNumber = preg_replace('/\D/', '', $document); + $documentLength = strlen($documentNumber); + + if ($documentLength !== 11 && $documentLength !== 14) { + $errorMessage = sprintf( + __( + 'Please, enter a valid document number in the %s Document.', + 'woo-pagarme-payments' + ), + __( + ucwords($addressType), + 'woo-pagarme-payments' + ) + ); + + wc_add_notice($errorMessage, 'error'); + continue; + } + + $documentType = $documentLength === 11 ? self::DOCUMENT_TYPES[0] : self::DOCUMENT_TYPES[1]; + $functionName = 'isValid' . ucwords($documentType); + $isValidDocument = $this->{$functionName}($documentNumber); + + if (!$isValidDocument) { + $errorMessage = sprintf( + __( + 'Please, enter a valid %s number in the %s Document.', + 'woo-pagarme-payments' + ), + strtoupper($documentType), + __( + ucwords($addressType), + 'woo-pagarme-payments' + ) + ); + wc_add_notice($errorMessage, 'error'); + } + } + } + + /** + * @param array $fields + * + * @return array + */ + public function overrideAddressFields(array $fields): array + { + $fields['address_1']['placeholder'] = __( + 'Street name, house number and neighbourhood', + 'woo-pagarme-payments' + ); + $fields['address_2']['label'] = __( + 'Additional address data', + 'woo-pagarme-payments' + ); + $fields['address_2']['label_class'] = ''; + + return $fields; + } + + /** + * @param $cpf + * + * @return bool + */ + private function isValidCpf($cpf): bool + { + if (strlen($cpf) !== 11 || preg_match('/(\d)\1{10}/', $cpf)) { + return false; + } + + for ($t = 9; $t < 11; $t ++) { + for ($d = 0, $c = 0; $c < $t; $c ++) { + $d += $cpf[$c] * (($t + 1) - $c); + } + $d = ((10 * $d) % 11) % 10; + if ($cpf[$c] != $d) { + return false; + } + } + + return true; + } + + /** + * @param $cnpj + * + * @return bool + */ + private function isValidCnpj($cnpj): bool + { + if (strlen($cnpj) != 14 || preg_match('/(\d)\1{13}/', $cnpj)) { + return false; + } + + for ($i = 0, $j = 5, $sum = 0; $i < 12; $i ++) { + $sum += $cnpj[$i] * $j; + $j = ($j == 2) ? 9 : $j - 1; + } + + $remainder = $sum % 11; + + if ($cnpj[12] != ($remainder < 2 ? 0 : 11 - $remainder)) { + return false; + } + + for ($i = 0, $j = 6, $sum = 0; $i < 13; $i ++) { + $sum += $cnpj[$i] * $j; + $j = ($j == 2) ? 9 : $j - 1; + } + + $remainder = $sum % 11; + + return $cnpj[13] == ($remainder < 2 ? 0 : 11 - $remainder); + } +} diff --git a/src/Action/OrderActions.php b/src/Action/OrderActions.php index 8700f285..9882d514 100644 --- a/src/Action/OrderActions.php +++ b/src/Action/OrderActions.php @@ -4,6 +4,9 @@ use Woocommerce\Pagarme\Model\Order; +/** + * @used-by ActionsRunner + */ class OrderActions implements RunnerInterface { @@ -31,7 +34,7 @@ public function showInstallmentFeesToCustomer($total_rows, $order, $tax_display) if (!$orderPagarme->isPagarmePaymentMethod()) { return $total_rows; } - + $total = $order->get_total(); $installmentsValue = $orderPagarme->get_meta('pagarme_card_tax'); if (empty($installmentsValue)) { diff --git a/src/Controller/Checkout/CustomerFields.php b/src/Controller/Checkout/CustomerFields.php new file mode 100644 index 00000000..ceb8546d --- /dev/null +++ b/src/Controller/Checkout/CustomerFields.php @@ -0,0 +1,25 @@ + self::getScriptUrl($path, $fileName), + 'deps' => self::setScriptDeps($deps), + 'ver' => self::getScriptVersion($path, $fileName) + ]; + } } From 34349f8cf4bba7881496a3216f62e298c407b53c Mon Sep 17 00:00:00 2001 From: RafaMelazzo Date: Thu, 19 Sep 2024 17:31:15 -0300 Subject: [PATCH 02/12] refactor: document validation --- .../front/checkout/checkoutFields.js | 33 +++- languages/woo-pagarme-payments-pt_BR.mo | Bin 40311 -> 40470 bytes languages/woo-pagarme-payments-pt_BR.po | 13 +- src/Action/CustomerFieldsActions.php | 128 ++++++-------- src/Controller/Checkout/CustomerFields.php | 161 ++++++++++++++++++ 5 files changed, 248 insertions(+), 87 deletions(-) diff --git a/assets/javascripts/front/checkout/checkoutFields.js b/assets/javascripts/front/checkout/checkoutFields.js index 1103cfa8..df00258c 100644 --- a/assets/javascripts/front/checkout/checkoutFields.js +++ b/assets/javascripts/front/checkout/checkoutFields.js @@ -1,9 +1,12 @@ /* globals wc_pagarme_checkout */ /* jshint esversion: 6 */ -let pagarmeCustomerFields = { - billingDocumentField: jQuery('#billing_document'), - shippingDocumentField: jQuery('#shipping_document'), - documentMasks: ['000.000.000-00999', '00.000.000/0000-00'], +const pagarmeCustomerFields = { + billingDocumentId: 'billing_document', + shippingDocumentId: 'shipping_document', + documentMasks: [ + '000.000.000-00999', + '00.000.000/0000-00' + ], documentMaskOptions: { onKeyPress: function (document, e, field, options) { const masks = pagarmeCustomerFields.documentMasks, @@ -13,12 +16,30 @@ let pagarmeCustomerFields = { }, applyDocumentMask() { - this.billingDocumentField.mask(this.documentMasks[0], this.documentMaskOptions); - this.shippingDocumentField.mask(this.documentMasks[0], this.documentMaskOptions); + jQuery('#' + this.billingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); + jQuery('#' + this.shippingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); + }, + + addEventListener() { + jQuery(document.body).on('checkout_error', function () { + const documentFieldIds = [ + pagarmeCustomerFields.billingDocumentId, + pagarmeCustomerFields.shippingDocumentId + ]; + jQuery.each(documentFieldIds, function () { + const documentField = jQuery('#' + this + '_field'); + if (jQuery('.woocommerce-error li[data-pagarme-error="' + this + '"]').length) { + documentField.addClass('woocommerce-invalid'); + } else { + documentField.removeClass('woocommerce-invalid'); + } + }); + }); }, start: function () { this.applyDocumentMask(); + this.addEventListener(); } }; diff --git a/languages/woo-pagarme-payments-pt_BR.mo b/languages/woo-pagarme-payments-pt_BR.mo index b715f6eec752ec5f13ede2e6a3132ebff584bfa1..8228554898ae7942d6fb6a79ae2dd00bdfafe1e9 100644 GIT binary patch delta 8793 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 Ksk!-FDfr(UR5|Pb delta 8630 zcmZwLd03WJ8prViDw~Q5h#;b%A}EW3A_9s_qPYR#ZsM*inMSC&<%?Unmdj+CrWS3M zTiIw#TH{!$Ww~TyH4SEtR<=&ln2u@l{k`YdHGj-=&CTaN=RC`K&horA8xH#Z@+V(U zO-Sv>495x|W18XAdd5Wi8gnp0wZ?RaH6|ESu`Tw%cr3#PxDH3))5vA!2KwVI)OCI> zjS0fW$gNEbK84BH+Zc~INunEuwK8TPcEwCwj)iyx2V;0^V>)6PHpQ(NhSlhYA7B7} zgzd2g(=a&Bm~`xk8TbG;!95to^UYBbz4=AgVA}97$`RNI+oL+z6X}a7#VA~jEpP`e z!Q<$Md7P~ChGHnrL3MPs^J(N%a{!}wzNsPEjQ_#jvNf9FP7O+0LF9i#jg>J-SgB5II$nT5I27yRxJ1TZLpha-hPVs^aTBVCRnC1_m+}$R z+@C~sKp`M+<33v|Gk*s7p zGQCmlg{Y1cp*m8EhjEFk?~`I5REV1MQq*+|unR87(fAkCB5dJdsj49ZnI>}|>dl@& zJ?K3Q#&cL7FQYE}8TEjAoLr8vsG(nvnvyN3sjb3#xWm=&M|J2BYNR~JNE(pTAnVV3 zj~cS@RCWNSp?1LlY>q{!j?BjpT;Y5YHKcp7HJ(MS{_C#3J_|@Mn2LI#yOEA~Oqr{g z>0E+(^Yy3>ZA0#1j-onx9W?@hd<@i~Sk#SsxN;fly5-mjUq)ufT*eFxqf#S25dF0O zmy&3xR(UJ8uBQ5H)nK;avOxL$P0H`++J#t(~=~wY3@7V-@Pf zGU!D+yaW4c|4$<+!2QVoj6dBg#qPKhcc51JFg}Y7aRx@>Qq%*sp+@F;)S^6qVR#00 z{+FmVa1GV*I=qF-QRvZ^FM&jJmy3y5icRn_=PpzS-bQusBI=E!vfUTb*%S3! z(eCzJ-l~V~V1Hx-nS5-ImB@NEdr|khh`#tEYAXKaAz4Hc*weoGDr`h~qbt9N+Ryt@ zZ*U0tpEswwM?YM+4m4wPdo&czVig1YY>)QB8Ltr5?sBnc!xpoT2s4!gKI zp|(vPYUt;qJ{${CQ?m-SxHh17@nH+f2T(UYht2U@)SK7sZH+*6AkLOOCWk~93_#s* z9BNgUqk29Ex8f>SPRwObQ_ex%_(xR7Z(nuaf(M;z`)UJ36J7P6zsJ}x$yo&1ZO=rV9?XGHtTGV|}YiuxTWX5A9 z&o`AM0qE1u{&)nT%CV>$wnGhZH&jOlp&mHcISRD~#-lpC8g+dYrr}OJi0APe+|u8U z=&}LKzxHeVK)VYHQHy2?HpAyI9gkpZyp9^m=7a15b1;r_87AWz?2d0>OT2~g7@KFm zAN}wy%EhQDtqMps`r z%r4f6sI@Q+H8nF)Q}P(=^QaN-I^2G!JhMqO)H|>ieu3)gWz-v9MP|VS zj9{K|1Zs^OL5<8M9Ep+q8IKj1iXWlYjQ=S6pd{3yEJAf`3i|5ze-6n^viTTH!%uWm zZ{Sm8f7jztBXk$4Ba=}#`Xg$)zJcL*+?79fV3x;!-6-vF%7RH8^I)v)t8j{ zpG7i(ir0`f6E)8M!(lGApu7j0;z`s{Uvd5u(+9MAQuzphn!8i7$*2dhzU{3dD^VZapoW}l$0 zyM&SWEo#dAitR3IfVC*c7c>4EibN_j#~GM`1F#SmBMaXA6?KE868pyKsE&_8)t9(( zIr>wc=js=``c1*hQL)+7)@uq1c}1o6#gW zxC(h`^BxYw>=|}$m*K;d_h3uRm}z&(DAbUzLruYU+>Xzo7F%ByKnmvLAY6dM@C52b zTRp(|vz|-|$xb|r8sdes?TxpgR`V_lz@w-kJcSzaOQ@+bb8LMKYVD+BIQDYok*E=z zf*P?!sE$1|hw*Pr@*x!w_%&)Z`_AP*kFYJO{a)0A7h@ybh&t~@)Y>_XnyRa)wc$U{ zmOG)gWiGyqlTgnIXC>=C?dLQ8y09k|e4b4q*2Y&+Ls*T$co-YtDI9^HV-#jSXdQ~W zaXD&AR-ih#5u4$g*a<&#?Tr@L#oNL|q7LMu7S}M;(5U_e+>Lv1I33ju{VQz;Q?LW& zj@TI|IX9ypKqKA zJQ1}fW??Jzpr)z{L$Mko@qJhSC91q=CI)}f|kCwlk)agx?loWZy77u1^^Tx!g_ zszP_A5j;yS#GB&4b`D6R7dZ^1T02ProY)8%UK4ccnhpv6-3OfRm(fj}Z zEh5pJEyLEh1^w`_^BC5md=lgEL)6e-#{g`y(k|Kr+u39gF&Iti|ED%R>_9!}t3!`;W*(y6aEFB-EOiikjPpurBVwI`}%) z#={tc?_f{-5*uRM$L-q4!eGh;s0WXA&O?o~=W&uIB-I#(r|}G4Ms2t1jdnYpMa}hj z)JS}V8kx{dcCq!uK*~d~9LHb*p29SYeZv0A4neJ@Wmuo*n^h#?R6Kzr@MWyTpv|_2 zD=~}mF63iqzQQsr-eQOR3~H6%!W?Y=qif14QwlSb|1Hi%+QprcqL~?Eh&-c!k zPHg5b4s>dmqSe5`OM8FAy#@XZCO#!vbMB?vmDt7QucAilqAQE7!~i1Q-M<%l{;d{{ zd4v{X1J`(vawYjdyaRv6y9i(MX_$t71Uu9F5n^Nfe!NRIg|^>ZjfVd}E)T_9E(hkH zzf*`-L|-mCjdO@Ra!puw_&X6v=m?@t^REwyjv}4MQHC$$O`?e^ILcj{@-GSfC;bDi z?m?{Uqw(jspEyI*qB4f)rb>4#cixM?x_mX>?QWEe%ZaH(s;hISnHjG90u@@^I<$>- zEYu%8{|zFA6Zsu66}SX-%y$=e#aPN!gg(z~5bt%`HSZJJwtI=s2p!)O{N|YYT*vM+ z&k;R{#e|M~sGng|kr3LVlHi0 zu`RxXU2qZ>5x)>kDaT+9@f2~2c*ed5TZP8k$FSQ8)^qj2xR59zQmOx%c$*kb`A%Gl zy@?~_bBWr-?PDUzej=9k1{jJfF#&Hs-|+P{PZDnu*NG$=TM+v6jwB|LKZrwdH|qG< z;{EO`z2eHHoYRkpr`!n-u6!|{>%6S zm+y4;!-kyK)s@9j;s%ka0>^mTU$dzhLEeY()aFkcD*cEw*C@^rcM~Ux5Mn0b;oR?V z0G`M92pv9@bu@P-kw=j?apeWhLho7jGhK(gyN`Dr^IOdc1yr=de_#;t7EwXeC;SN= ziL?jU)Lg(!%Jpyp-adwsWKjMIdtfo~5HXr^G4U^A4&{f5NCC)0M><<;1mXhYptca3ZE@<;yu*;Pc)KFa0Wo&MA%YyKZ6mJu_ln1%OZFn&dZ zk^k>8`+v%PT|+)Da`h9)XOVX%+L7xYCpreY_T#o_p2tpv=TH3E<0}8@oR8yNo{rh> zVpsJ$`P7dgN~!sV2qbp7)@x1?LHvb?Q-Nb6F@~t4`5)(QJ`G<{D@Qi5h3H1z7x*G^ zpF5A#d`|RKxVk*@Tw)33Tw)0MS>pDQMO}eA_YYJyCpvo@HU1p!UE@4lLF}V$B$j(y z`O&~nh!d_n7Ml_iIVXhpmi%wTF=7MpC^4OAN!xVd2l9`IXmS%bX?D!?DKT*sF$ray;i;d4*e{t0QfDV~4shL?F)Av1f_uqZ?JyP^>pwEno campo Documento msgid "Please, enter a valid %s number in the %s Document." msgstr "Por favor, digite um número de %s válido no campo "Documento" do endereço de %s." +msgid "%s Document" +msgstr "Documento de %s" + +msgid "Billing" +msgstr "Faturamento" + +msgid "Shipping" +msgstr "Envio" + msgid "Street name, house number and neighbourhood" msgstr "Nome da rua, número da casa e bairro" diff --git a/src/Action/CustomerFieldsActions.php b/src/Action/CustomerFieldsActions.php index b8ad8f01..64a51245 100644 --- a/src/Action/CustomerFieldsActions.php +++ b/src/Action/CustomerFieldsActions.php @@ -20,15 +20,6 @@ */ class CustomerFieldsActions implements RunnerInterface { - const ADDRESS_TYPES = [ - 'billing', - 'shipping' - ]; - const DOCUMENT_TYPES = [ - 'cpf', - 'cnpj', - ]; - private $customerFields; public function __construct() @@ -39,9 +30,17 @@ public function __construct() public function run() { add_filter('woocommerce_checkout_init', array($this, 'enqueueScript')); - add_filter('woocommerce_default_address_fields', array($this, 'overrideAddressFields')); add_filter('woocommerce_checkout_fields', array($this, 'addDocumentField')); add_action('woocommerce_checkout_process', array($this, 'validateDocument')); + add_action( + 'woocommerce_admin_order_data_after_billing_address', + array($this, 'displayBillingDocumentOrderMeta') + ); + add_action( + 'woocommerce_admin_order_data_after_shipping_address', + array($this, 'displayShippingDocumentOrderMeta') + ); + add_filter('woocommerce_default_address_fields', array($this, 'overrideAddressFields')); } public function enqueueScript() @@ -67,7 +66,7 @@ public function addDocumentField(array $fields): array return $fields; } - foreach (self::ADDRESS_TYPES as $addressType) { + foreach ($this->customerFields::ADDRESS_TYPES as $addressType) { $fields[$addressType]["{$addressType}_document"] = array( 'label' => __('Document', 'woo-pagarme-payments'), 'placeholder' => __('CPF or CNPJ', 'woo-pagarme-payments'), @@ -82,13 +81,14 @@ public function addDocumentField(array $fields): array /** * @return void - * @uses isValidCnpj() - * @uses isValidCpf() + * @uses CustomerFields::isValidCnpj() + * @uses CustomerFields::isValidCpf() */ public function validateDocument() { - foreach (self::ADDRESS_TYPES as $addressType) { - $document = $_POST["{$addressType}_document"]; + foreach ($this->customerFields::ADDRESS_TYPES as $addressType) { + $fieldName = "{$addressType}_document"; + $document = $_POST[$fieldName]; if (!$document) { continue; @@ -103,19 +103,22 @@ public function validateDocument() 'Please, enter a valid document number in the %s Document.', 'woo-pagarme-payments' ), - __( - ucwords($addressType), + _x( + ucfirst($addressType), + 'checkout-document-error', 'woo-pagarme-payments' ) ); - wc_add_notice($errorMessage, 'error'); + wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); continue; } - $documentType = $documentLength === 11 ? self::DOCUMENT_TYPES[0] : self::DOCUMENT_TYPES[1]; - $functionName = 'isValid' . ucwords($documentType); - $isValidDocument = $this->{$functionName}($documentNumber); + $documentType = $documentLength === 11 + ? $this->customerFields::DOCUMENT_TYPES[0] + : $this->customerFields::DOCUMENT_TYPES[1]; + $functionName = 'isValid' . ucfirst($documentType); + $isValidDocument = $this->customerFields->{$functionName}($documentNumber); if (!$isValidDocument) { $errorMessage = sprintf( @@ -124,16 +127,37 @@ public function validateDocument() 'woo-pagarme-payments' ), strtoupper($documentType), - __( - ucwords($addressType), + _x( + ucfirst($addressType), + 'checkout-document-error', 'woo-pagarme-payments' ) ); - wc_add_notice($errorMessage, 'error'); + wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); } } } + /** + * @param $order + * + * @return void + */ + public function displayBillingDocumentOrderMeta($order) + { + $this->customerFields->displayDocumentOrderMeta($order, $this->customerFields::ADDRESS_TYPES[0]); + } + + /** + * @param $order + * + * @return void + */ + public function displayShippingDocumentOrderMeta($order) + { + $this->customerFields->displayDocumentOrderMeta($order, $this->customerFields::ADDRESS_TYPES[1]); + } + /** * @param array $fields * @@ -153,60 +177,4 @@ public function overrideAddressFields(array $fields): array return $fields; } - - /** - * @param $cpf - * - * @return bool - */ - private function isValidCpf($cpf): bool - { - if (strlen($cpf) !== 11 || preg_match('/(\d)\1{10}/', $cpf)) { - return false; - } - - for ($t = 9; $t < 11; $t ++) { - for ($d = 0, $c = 0; $c < $t; $c ++) { - $d += $cpf[$c] * (($t + 1) - $c); - } - $d = ((10 * $d) % 11) % 10; - if ($cpf[$c] != $d) { - return false; - } - } - - return true; - } - - /** - * @param $cnpj - * - * @return bool - */ - private function isValidCnpj($cnpj): bool - { - if (strlen($cnpj) != 14 || preg_match('/(\d)\1{13}/', $cnpj)) { - return false; - } - - for ($i = 0, $j = 5, $sum = 0; $i < 12; $i ++) { - $sum += $cnpj[$i] * $j; - $j = ($j == 2) ? 9 : $j - 1; - } - - $remainder = $sum % 11; - - if ($cnpj[12] != ($remainder < 2 ? 0 : 11 - $remainder)) { - return false; - } - - for ($i = 0, $j = 6, $sum = 0; $i < 13; $i ++) { - $sum += $cnpj[$i] * $j; - $j = ($j == 2) ? 9 : $j - 1; - } - - $remainder = $sum % 11; - - return $cnpj[13] == ($remainder < 2 ? 0 : 11 - $remainder); - } } diff --git a/src/Controller/Checkout/CustomerFields.php b/src/Controller/Checkout/CustomerFields.php index ceb8546d..36ce8c49 100644 --- a/src/Controller/Checkout/CustomerFields.php +++ b/src/Controller/Checkout/CustomerFields.php @@ -12,6 +12,15 @@ class CustomerFields { + const ADDRESS_TYPES = [ + 'billing', + 'shipping' + ]; + const DOCUMENT_TYPES = [ + 'cpf', + 'cnpj', + ]; + /** * @param $fields * @@ -22,4 +31,156 @@ public function hasDocumentField($fields): bool return array_key_exists('billing_cpf', $fields['billing']) || array_key_exists('billing_cnpj', $fields['billing']); } + + /** + * @param string $cpf + * + * @return bool + */ + public function isValidCpf(string $cpf): bool + { + if (!$this->isValidCpfFormat($cpf)) { + return false; + } + + for ($digit = 9; $digit < 11; $digit ++) { + if (!$this->isValidCpfDigit($cpf, $digit)) { + return false; + } + } + + return true; + } + + /** + * @param string $cnpj + * + * @return bool + */ + public function isValidCnpj(string $cnpj): bool + { + if (!$this->isValidCnpjFormat($cnpj)) { + return false; + } + + $firstCheckDigit = $this->calculateCnpjCheckDigit(substr($cnpj, 0, 12), 5); + if ($cnpj[12] != $firstCheckDigit) { + return false; + } + + $secondCheckDigit = $this->calculateCnpjCheckDigit(substr($cnpj, 0, 13), 6); + + return $cnpj[13] == $secondCheckDigit; + } + + public function displayDocumentOrderMeta($order, $addressType) + { + if (!$order) { + return; + } + + $documentNumber = esc_html($order->get_meta($this->getDocumentMetaNameByAddressType($addressType), true)); + + if (!$documentNumber) { + return; + } + + $metaLabel = sprintf( + __( + '%s Document', + 'woo-pagarme-payments' + ), + __( + ucfirst($addressType), + 'woo-pagarme-payments' + ) + ); + + echo "

{$metaLabel}: {$documentNumber}

"; + } + + /** + * @param string $addressType + * + * @return string + */ + private function getDocumentMetaNameByAddressType(string $addressType): string + { + return "_{$addressType}_document"; + } + + /** + * @param string $cpf + * + * @return bool + */ + private function isValidCpfFormat(string $cpf): bool + { + // Check if CPF length is exactly 11 and not all digits are the same + return strlen($cpf) === 11 && !preg_match('/(\d)\1{10}/', $cpf); + } + + /** + * @param string $cpf + * @param int $digit + * + * @return bool + */ + private function isValidCpfDigit(string $cpf, int $digit): bool + { + $calculatedDigit = $this->calculateCpfDigit($cpf, $digit); + + return $cpf[$digit] == $calculatedDigit; + } + + /** + * @param string $cpf + * @param int $digit + * + * @return int + */ + private function calculateCpfDigit(string $cpf, int $digit): int + { + $sum = 0; + + for ($i = 0; $i < $digit; $i ++) { + $sum += $cpf[$i] * (($digit + 1) - $i); + } + + $remainder = (10 * $sum) % 11; + + return ($remainder === 10) ? 0 : $remainder; + } + + /** + * @param string $cnpj + * + * @return bool + */ + private function isValidCnpjFormat(string $cnpj): bool + { + // Check if CNPJ is 14 characters long and not a sequence of repeated digits + return strlen($cnpj) == 14 && !preg_match('/(\d)\1{13}/', $cnpj); + } + + /** + * @param string $cnpj + * @param int $initialWeight + * + * @return int + */ + private function calculateCnpjCheckDigit(string $cnpj, int $initialWeight): int + { + $sum = 0; + $weight = $initialWeight; + + for ($i = 0; $i < strlen($cnpj); $i ++) { + $sum += $cnpj[$i] * $weight; + $weight = ($weight == 2) ? 9 : $weight - 1; + } + + $remainder = $sum % 11; + + return ($remainder < 2) ? 0 : 11 - $remainder; + } } From 6800b67f48734b53af75ae35e40b1d810aaba62b Mon Sep 17 00:00:00 2001 From: RafaMelazzo Date: Tue, 24 Sep 2024 15:20:35 -0300 Subject: [PATCH 03/12] feat: accepting single line address --- .../front/checkout/checkoutFields.js | 10 ++-- .../WoocommercePlatformOrderDecorator.php | 26 ++++++---- src/Helper/Utils.php | 32 +++++++++++-- src/Model/Order.php | 14 ++++-- src/Model/Payment/AbstractPayment.php | 15 ++++-- src/Service/CustomerService.php | 37 +++++++++++---- .../Configuration/AddressAttributes.php | 4 +- .../src/Middle/Model/Customer/Address.php | 15 ++++-- .../src/Payment/Aggregates/Address.php | 47 +++++++++++++------ .../src/Payment/Factories/AddressFactory.php | 16 +++++-- 10 files changed, 162 insertions(+), 54 deletions(-) diff --git a/assets/javascripts/front/checkout/checkoutFields.js b/assets/javascripts/front/checkout/checkoutFields.js index df00258c..d7bdc9a4 100644 --- a/assets/javascripts/front/checkout/checkoutFields.js +++ b/assets/javascripts/front/checkout/checkoutFields.js @@ -27,11 +27,13 @@ const pagarmeCustomerFields = { pagarmeCustomerFields.shippingDocumentId ]; jQuery.each(documentFieldIds, function () { - const documentField = jQuery('#' + this + '_field'); - if (jQuery('.woocommerce-error li[data-pagarme-error="' + this + '"]').length) { - documentField.addClass('woocommerce-invalid'); + const documentField = '#' + this + '_field', + isDocumentEmpty = jQuery('.woocommerce-error li[data-id="' + this + '"]').length, + isDocumentInvalid = jQuery('.woocommerce-error li[data-pagarme-error="' + this + '"]').length; + if (isDocumentEmpty || isDocumentInvalid) { + jQuery(documentField).addClass('woocommerce-invalid'); } else { - documentField.removeClass('woocommerce-invalid'); + jQuery(documentField).removeClass('woocommerce-invalid'); } }); }); diff --git a/src/Concrete/WoocommercePlatformOrderDecorator.php b/src/Concrete/WoocommercePlatformOrderDecorator.php index c44dec4f..5c2ec31a 100644 --- a/src/Concrete/WoocommercePlatformOrderDecorator.php +++ b/src/Concrete/WoocommercePlatformOrderDecorator.php @@ -460,7 +460,8 @@ private function getRegisteredCustomer($woocommerceCustomerId) if (empty($document['value'])) { $customerPlatform = new WC_Customer($woocommerceCustomerId); $document['value'] = $customerPlatform->get_meta("billing_cpf") ?? - $customerPlatform->get_meta("billing_cnpj"); + $customerPlatform->get_meta("billing_cnpj") ?? + $customerPlatform->get_meta("billing_document"); } $homeNumber = $phones["home_phone"]["complete_phone"]; $mobileNumber = $phones["mobile_phone"]["complete_phone"]; @@ -534,7 +535,7 @@ private function getGuestCustomer() $cleanDocument = preg_replace( '/\D/', '', - $document["value"] + $document['value'] ); $customer->setDocument($cleanDocument); @@ -1116,6 +1117,9 @@ public function getShipping() return $shipping; } + /** + * @throws Exception + */ protected function getAddress($platformAddress) { $config = new Config(); @@ -1123,21 +1127,27 @@ protected function getAddress($platformAddress) return null; } + $multipleLineStreet = !empty($platformAddress["number"]) && !empty($platformAddress["neighborhood"]); + $address = new Address(); $this->validateAddressFields($platformAddress); - $address->setStreet($platformAddress["street"]); - $address->setNumber($platformAddress["number"]); - $address->setNeighborhood($platformAddress["neighborhood"]); + $address->setStreet($platformAddress["street"], $multipleLineStreet); $address->setComplement($platformAddress["complement"]); - $address->setCity($platformAddress["city"]); $address->setCountry($platformAddress["country"]); $address->setZipCode($platformAddress["zip_code"]); - $address->setState($platformAddress["state"]); + if (!empty($platformAddress["number"])) { + $address->setNumber($platformAddress["number"]); + } + + if (!empty($platformAddress["neighborhood"])) { + $address->setNeighborhood($platformAddress["neighborhood"]); + } + return $address; } @@ -1167,8 +1177,6 @@ private function validateAddressFields($platformAddress) { $requiredFields = [ 'street', - 'number', - 'neighborhood', 'city', 'country', 'zip_code', diff --git a/src/Helper/Utils.php b/src/Helper/Utils.php index df55d800..b4e55ff9 100644 --- a/src/Helper/Utils.php +++ b/src/Helper/Utils.php @@ -470,16 +470,21 @@ public static function get_phone_country_code($country) */ public static function build_customer_address_from_order(Order $order) { - return array( + $address = array( 'street' => substr($order->getWcOrder()->get_billing_address_1(), 0, 64), - 'number' => substr($order->get_meta('billing_number'), 0, 15), 'complement' => substr($order->getWcOrder()->get_billing_address_2(), 0, 64), 'zip_code' => preg_replace('/[^\d]+/', '', $order->getWcOrder()->get_billing_postcode()), - 'neighborhood' => substr($order->get_meta('billing_neighborhood'), 0, 64), 'city' => substr($order->get_meta('billing_city'), 0, 64), 'state' => substr($order->get_meta('billing_state'), 0, 2), 'country' => 'BR' ); + + if (!empty($order->get_meta('billing_number')) && !empty($order->get_meta('billing_neighborhood'))) { + $address['number'] = substr($order->get_meta('billing_number'), 0, 15); + $address['neighborhood'] = substr($order->get_meta('billing_neighborhood'), 0, 64); + } + + return $address; } /** @@ -503,12 +508,33 @@ public static function build_document_from_order(Order $order) ); } + if (!empty($order->get_meta('billing_document'))) { + $document = $order->get_meta('billing_document'); + $documentType = self::getCustomerType($document); + return array( + 'type' => $documentType, + 'value' => $document, + ); + } + return array( 'type' => '', 'value' => '', ); } + public static function getCustomerType($document): string + { + $documentNumber = preg_replace('/\D/', '', $document ?? ''); + return strlen($documentNumber) === 14 ? 'company' : 'individual'; + } + + public static function getDocumentType($document): string + { + $documentNumber = preg_replace('/\D/', '', $document ?? ''); + return strlen($documentNumber) === 14 ? 'cnpj' : 'cp'; + } + /** * @param Order $order * diff --git a/src/Model/Order.php b/src/Model/Order.php index 0a66631d..9cbdb14c 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -188,15 +188,23 @@ public function get_charges() */ public function get_shipping_info() { - return array( + $address = array( 'address_1' => $this->handle_shipping_properties('address_1'), - 'number' => $this->handle_shipping_properties('number'), 'address_2' => $this->handle_shipping_properties('address_2'), 'postcode' => $this->handle_shipping_properties('postcode'), - 'neighborhood' => $this->handle_shipping_properties('neighborhood'), 'city' => $this->handle_shipping_properties('city'), 'state' => $this->handle_shipping_properties('state'), ); + + if (!empty($this->handle_shipping_properties('number'))) { + $address['number'] = $this->handle_shipping_properties('number'); + } + + if (!empty($this->handle_shipping_properties('neighborhood'))) { + $address['neighborhood'] = $this->handle_shipping_properties('neighborhood'); + } + + return $address; } private function handle_shipping_properties($prop) diff --git a/src/Model/Payment/AbstractPayment.php b/src/Model/Payment/AbstractPayment.php index e0a45ffc..99cd4e16 100644 --- a/src/Model/Payment/AbstractPayment.php +++ b/src/Model/Payment/AbstractPayment.php @@ -236,16 +236,25 @@ protected function getBillingAddressFromCustomer($customer, WC_Order $wc_order) if (empty($addressArray)) { $addressArray = $this->getCustomerAddressFromWcOrder($wc_order); } - return [ + + $address = [ 'street' => $addressArray["street"], 'complement' => $addressArray["complement"], - 'number' => $addressArray["number"], 'zip_code' => $addressArray["zip_code"], - 'neighborhood' => $addressArray["neighborhood"], 'city' => $addressArray["city"], 'state' => $addressArray["state"], 'country' => $addressArray["country"] ]; + + if (!empty($addressArray['number'])) { + $address['number'] = $addressArray['number']; + } + + if (!empty($addressArray['neighborhood'])) { + $address['neighborhood'] = $addressArray['neighborhood']; + } + + return $address; } /** diff --git a/src/Service/CustomerService.php b/src/Service/CustomerService.php index 2b12432f..79500b92 100644 --- a/src/Service/CustomerService.php +++ b/src/Service/CustomerService.php @@ -3,6 +3,7 @@ namespace Woocommerce\Pagarme\Service; use WC_Customer; +use Woocommerce\Pagarme\Helper\Utils; use Woocommerce\Pagarme\Model\CoreAuth; use Pagarme\Core\Middle\Model\Customer; use Pagarme\Core\Middle\Proxy\CustomerProxy; @@ -58,38 +59,58 @@ public function createAddress($addressData) $address->setCountry($addressData['country']); $address->setState($addressData['state']); $address->setCity($addressData['city']); - $address->setNeighborhood($addressData['neighborhood']); $address->setZipCode($addressData['zipcode']); $address->setStreet($addressData['street']); - $address->setNumber($addressData['number']); $address->setComplement($addressData['complement']); + + if (!empty($addressData['number'])) { + $address->setNumber($addressData['number']); + } + + if (!empty($addressData['neighborhood'])) { + $address->setNeighborhood($addressData['neighborhood']); + } + return $address; } - + public function extractCustomerDataByWcOrder($wcOrder) { $billingData = $wcOrder->get_data()['billing']; + $document = $wcOrder->get_meta('_billing_cpf'); if (empty($document)) { $document = $wcOrder->get_meta('_billing_cnpj'); } - return [ + if (empty($document)) { + $document = $wcOrder->get_meta('_billing_document'); + } + + $customerData = [ 'code' => $wcOrder->get_customer_id(), 'email' => $billingData['email'], 'name' => $billingData['first_name'] . ' ' . $billingData['last_name'], 'document' => $document, - 'document_type' => empty($wcOrder->get_meta('_billing_cnpj')) ? 'cpf' : 'cnpj', + 'document_type' => Utils::getDocumentType($document), 'home_phone' => $billingData['phone'], 'mobile_phone' => $wcOrder->get_meta('_billing_cellphone'), 'street' => $billingData['street'], - 'neighborhood' => $billingData['neighborhood'], - 'number' => $billingData['number'], 'country' => $billingData['country'], 'city' => $billingData['city'], 'state' => $billingData['state'], 'complement' => $billingData['complement'], 'zipcode' => $billingData['postcode'] ]; + + if (!empty($billingData['number'])) { + $customerData['number'] = $billingData['number']; + } + + if (!empty($billingData['neighborhood'])) { + $customerData['neighborhood'] = $billingData['neighborhood']; + } + + return $customerData; } public function saveOnPlatform($customer) @@ -116,4 +137,4 @@ public function save($customer) $wcCustomer->add_meta_data('_pagarme_customer_id', $customer->getPagarmeId(), true); $wcCustomer->save(); } -} \ No newline at end of file +} diff --git a/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/Configuration/AddressAttributes.php b/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/Configuration/AddressAttributes.php index 6b4068ab..41734b7c 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/Configuration/AddressAttributes.php +++ b/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/Configuration/AddressAttributes.php @@ -46,7 +46,7 @@ public function getStreet() */ public function getNumber() { - return $this->number; + return $this->number ?? ''; } /** @@ -54,7 +54,7 @@ public function getNumber() */ public function getNeighborhood() { - return $this->neighborhood; + return $this->neighborhood ?? ''; } /** diff --git a/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Customer/Address.php b/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Customer/Address.php index 10c777a7..e0609ca9 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Customer/Address.php +++ b/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Customer/Address.php @@ -93,15 +93,24 @@ public function getNumber() { return $this->number ?? ""; } - + public function getComplement() { return $this->complement ?? ""; } - + public function getLine1() { - $address = [$this->getNumber(), $this->getStreet(), $this->getNeighborhood()]; + if (!empty($this->getNumber())) { + $address[] = $this->getNumber(); + } + + $address[] = $this->getStreet(); + + if (!empty($this->getNeighborhood())) { + $address[] = $this->getNeighborhood(); + } + return implode(self::ADDRESS_SEPARATOR, $address); } diff --git a/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php b/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php index a692f65a..ee35d90e 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php +++ b/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php @@ -56,7 +56,7 @@ public function __construct() */ public function getNumber() { - return $this->number; + return $this->number ?? ''; } /** @@ -105,16 +105,16 @@ public function getStreet() * @return Address * @throws \Exception */ - public function setStreet($street) + public function setStreet($street, $multipleLineStreet = true) { - $streetWithoutComma = str_replace( - self::ADDRESS_LINE_SEPARATOR, + $street = str_replace( + $multipleLineStreet ? self::ADDRESS_LINE_SEPARATOR : '', '', $street ?? '' ); $streetWithoutLineBreaks = StringFunctionsHelper::removeLineBreaks( - $streetWithoutComma + $street ); $this->street = substr($streetWithoutLineBreaks, 0, 64); @@ -137,7 +137,7 @@ public function setStreet($street) */ public function getNeighborhood() { - return $this->neighborhood; + return $this->neighborhood ?? ''; } /** @@ -289,12 +289,17 @@ public function setCountry($country) public function getLine1() { - $line = []; - $line[] = $this->getNumber(); + if ($this->getNumber()) { + $line[] = $this->getNumber(); + } + $line[] = $this->getStreet(); - $line[] = $this->getNeighborhood(); - return implode (self::ADDRESS_LINE_SEPARATOR, $line); + if ($this->getNeighborhood()) { + $line[] = $this->getNeighborhood(); + } + + return implode(self::ADDRESS_LINE_SEPARATOR, $line); } public function getLine2() @@ -336,7 +341,7 @@ public function setState($state) /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/jsonserializable.jsonserialize.php - * @return string data which can be serialized by json_encode, + * @return \stdClass data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4.0 */ @@ -345,9 +350,7 @@ public function jsonSerialize() { $obj = new \stdClass(); - $obj->number = $this->number; $obj->street = $this->street; - $obj->neighborhood = $this->neighborhood; $obj->complement = $this->complement; $obj->zipCode = $this->zipCode; $obj->city = $this->city; @@ -356,6 +359,14 @@ public function jsonSerialize() $obj->line1 = $this->getLine1(); $obj->line2 = $this->getLine2(); + if (!empty($this->number)) { + $obj->number = $this->number; + } + + if (!empty($this->neighborhood)) { + $obj->neighborhood = $this->neighborhood; + } + return $obj; } @@ -371,12 +382,18 @@ public function convertToSDKRequest() $addressRequest->country = $this->getCountry(); $addressRequest->line1 = $this->getLine1(); $addressRequest->line2 = $this->getLine2(); - $addressRequest->neighborhood = $this->getNeighborhood(); - $addressRequest->number = $this->getNumber(); $addressRequest->state = $this->getState(); $addressRequest->street = $this->getStreet(); $addressRequest->zipCode = $this->getZipCode(); + if ($this->getNumber()){ + $addressRequest->number = $this->getNumber(); + } + + if ($this->getNeighborhood()){ + $addressRequest->neighborhood = $this->getNeighborhood(); + } + return $addressRequest; } diff --git a/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php b/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php index 7e8b4403..5b1fcd70 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php +++ b/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php @@ -10,17 +10,25 @@ public function createFromJson($json) { $data = json_decode($json); + $multipleLineStreet = !empty($data->number) && !empty($data->neighborhood); + $address = new Address(); - $address->setStreet($data->street); - $address->setNumber($data->number); - $address->setNeighborhood($data->neighborhood); + $address->setStreet($data->street, $multipleLineStreet); $address->setComplement($data->complement); $address->setCity($data->city); $address->setState($data->state); $address->setZipCode($data->zipCode); $address->setCountry('BR'); + if (!empty($data->number)) { + $address->setNumber($data->number); + } + + if (!empty($data->neighborhood)) { + $address->setNeighborhood($data->neighborhood); + } + return $address; } -} \ No newline at end of file +} From b9525269a32404d237b195d7398a1fd33b0a372e Mon Sep 17 00:00:00 2001 From: RafaMelazzo Date: Wed, 25 Sep 2024 10:33:31 -0300 Subject: [PATCH 04/12] refactor: accepting single line address --- .../WoocommercePlatformOrderDecorator.php | 14 ++--- src/Helper/Utils.php | 27 +++++----- src/Model/Checkout.php | 2 + src/Model/Order.php | 14 ++--- src/Model/Payment/AbstractPayment.php | 14 ++--- src/Service/CustomerService.php | 10 +--- .../Configuration/AddressAttributes.php | 4 +- .../src/Payment/Aggregates/Address.php | 52 ++++--------------- .../src/Payment/Factories/AddressFactory.php | 14 ++--- 9 files changed, 44 insertions(+), 107 deletions(-) diff --git a/src/Concrete/WoocommercePlatformOrderDecorator.php b/src/Concrete/WoocommercePlatformOrderDecorator.php index 5c2ec31a..8d23f601 100644 --- a/src/Concrete/WoocommercePlatformOrderDecorator.php +++ b/src/Concrete/WoocommercePlatformOrderDecorator.php @@ -1127,27 +1127,19 @@ protected function getAddress($platformAddress) return null; } - $multipleLineStreet = !empty($platformAddress["number"]) && !empty($platformAddress["neighborhood"]); - $address = new Address(); $this->validateAddressFields($platformAddress); - $address->setStreet($platformAddress["street"], $multipleLineStreet); + $address->setStreet($platformAddress["street"]); + $address->setNumber($platformAddress["number"] ?? '0'); $address->setComplement($platformAddress["complement"]); + $address->setNeighborhood($platformAddress["neighborhood"]); $address->setCity($platformAddress["city"]); $address->setCountry($platformAddress["country"]); $address->setZipCode($platformAddress["zip_code"]); $address->setState($platformAddress["state"]); - if (!empty($platformAddress["number"])) { - $address->setNumber($platformAddress["number"]); - } - - if (!empty($platformAddress["neighborhood"])) { - $address->setNeighborhood($platformAddress["neighborhood"]); - } - return $address; } diff --git a/src/Helper/Utils.php b/src/Helper/Utils.php index b4e55ff9..a02296b7 100644 --- a/src/Helper/Utils.php +++ b/src/Helper/Utils.php @@ -470,21 +470,16 @@ public static function get_phone_country_code($country) */ public static function build_customer_address_from_order(Order $order) { - $address = array( + return array( 'street' => substr($order->getWcOrder()->get_billing_address_1(), 0, 64), + 'number' => substr($order->get_meta('billing_number'), 0, 15), 'complement' => substr($order->getWcOrder()->get_billing_address_2(), 0, 64), 'zip_code' => preg_replace('/[^\d]+/', '', $order->getWcOrder()->get_billing_postcode()), + 'neighborhood' => substr($order->get_meta('billing_neighborhood'), 0, 64), 'city' => substr($order->get_meta('billing_city'), 0, 64), 'state' => substr($order->get_meta('billing_state'), 0, 2), 'country' => 'BR' ); - - if (!empty($order->get_meta('billing_number')) && !empty($order->get_meta('billing_neighborhood'))) { - $address['number'] = substr($order->get_meta('billing_number'), 0, 15); - $address['neighborhood'] = substr($order->get_meta('billing_neighborhood'), 0, 64); - } - - return $address; } /** @@ -532,7 +527,7 @@ public static function getCustomerType($document): string public static function getDocumentType($document): string { $documentNumber = preg_replace('/\D/', '', $document ?? ''); - return strlen($documentNumber) === 14 ? 'cnpj' : 'cp'; + return strlen($documentNumber) === 14 ? 'cnpj' : 'cpf'; } /** @@ -596,20 +591,28 @@ public static function build_customer_shipping_from_wc_order(WC_Order $wc_order) $total = self::format_order_price($wc_order->get_shipping_total()); $shipping = $order->get_shipping_info(); - return array( + $customerShipping = array( 'amount' => $total, 'description' => $method, 'address' => array( 'street' => substr($shipping['address_1'], 0, 64), - 'number' => substr($shipping['number'], 0, 15), 'complement' => substr($shipping['address_2'], 0, 64), 'zip_code' => substr(preg_replace('/[^\d]+/', '', $shipping['postcode']), 0, 16), - 'neighborhood' => substr($shipping['neighborhood'], 0, 64), 'city' => substr($shipping['city'], 0, 64), 'state' => substr($shipping['state'], 0, 2), 'country' => 'BR', ), ); + + if (!empty($shipping['number'])) { + $customerShipping['address']['number'] = substr($shipping['number'], 0, 15); + } + + if (!empty($shipping['neighborhood'])) { + $customerShipping['address']['neighborhood'] = substr($shipping['neighborhood'], 0, 64); + } + + return $customerShipping; } /** diff --git a/src/Model/Checkout.php b/src/Model/Checkout.php index 217c114f..63dea90b 100644 --- a/src/Model/Checkout.php +++ b/src/Model/Checkout.php @@ -72,6 +72,7 @@ public function __construct( public function validateCheckout($fields, $errors) { if ( + isset($fields['billing_number']) && $fields['billing_number'] === 0 && !key_exists('billing_number_required', $errors->errors) ) { @@ -82,6 +83,7 @@ public function validateCheckout($fields, $errors) } if ( $fields['ship_to_different_address'] && + isset($fields['shipping_number']) && $fields['shipping_number'] === 0 && !key_exists('shipping_number_required', $errors->errors) ) { diff --git a/src/Model/Order.php b/src/Model/Order.php index 9cbdb14c..0a66631d 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -188,23 +188,15 @@ public function get_charges() */ public function get_shipping_info() { - $address = array( + return array( 'address_1' => $this->handle_shipping_properties('address_1'), + 'number' => $this->handle_shipping_properties('number'), 'address_2' => $this->handle_shipping_properties('address_2'), 'postcode' => $this->handle_shipping_properties('postcode'), + 'neighborhood' => $this->handle_shipping_properties('neighborhood'), 'city' => $this->handle_shipping_properties('city'), 'state' => $this->handle_shipping_properties('state'), ); - - if (!empty($this->handle_shipping_properties('number'))) { - $address['number'] = $this->handle_shipping_properties('number'); - } - - if (!empty($this->handle_shipping_properties('neighborhood'))) { - $address['neighborhood'] = $this->handle_shipping_properties('neighborhood'); - } - - return $address; } private function handle_shipping_properties($prop) diff --git a/src/Model/Payment/AbstractPayment.php b/src/Model/Payment/AbstractPayment.php index 99cd4e16..e0260b73 100644 --- a/src/Model/Payment/AbstractPayment.php +++ b/src/Model/Payment/AbstractPayment.php @@ -237,24 +237,16 @@ protected function getBillingAddressFromCustomer($customer, WC_Order $wc_order) $addressArray = $this->getCustomerAddressFromWcOrder($wc_order); } - $address = [ + return [ 'street' => $addressArray["street"], 'complement' => $addressArray["complement"], + 'number' => $addressArray["number"], 'zip_code' => $addressArray["zip_code"], + 'neighborhood' => $addressArray["neighborhood"], 'city' => $addressArray["city"], 'state' => $addressArray["state"], 'country' => $addressArray["country"] ]; - - if (!empty($addressArray['number'])) { - $address['number'] = $addressArray['number']; - } - - if (!empty($addressArray['neighborhood'])) { - $address['neighborhood'] = $addressArray['neighborhood']; - } - - return $address; } /** diff --git a/src/Service/CustomerService.php b/src/Service/CustomerService.php index 79500b92..0d2ea65c 100644 --- a/src/Service/CustomerService.php +++ b/src/Service/CustomerService.php @@ -59,18 +59,12 @@ public function createAddress($addressData) $address->setCountry($addressData['country']); $address->setState($addressData['state']); $address->setCity($addressData['city']); + $address->setNeighborhood($addressData['neighborhood']); $address->setZipCode($addressData['zipcode']); $address->setStreet($addressData['street']); + $address->setNumber($addressData['number']); $address->setComplement($addressData['complement']); - if (!empty($addressData['number'])) { - $address->setNumber($addressData['number']); - } - - if (!empty($addressData['neighborhood'])) { - $address->setNeighborhood($addressData['neighborhood']); - } - return $address; } diff --git a/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/Configuration/AddressAttributes.php b/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/Configuration/AddressAttributes.php index 41734b7c..6b4068ab 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/Configuration/AddressAttributes.php +++ b/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/Configuration/AddressAttributes.php @@ -46,7 +46,7 @@ public function getStreet() */ public function getNumber() { - return $this->number ?? ''; + return $this->number; } /** @@ -54,7 +54,7 @@ public function getNumber() */ public function getNeighborhood() { - return $this->neighborhood ?? ''; + return $this->neighborhood; } /** diff --git a/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php b/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php index ee35d90e..514aa9ff 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php +++ b/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php @@ -56,7 +56,7 @@ public function __construct() */ public function getNumber() { - return $this->number ?? ''; + return $this->number; } /** @@ -78,8 +78,7 @@ public function setNumber($number) $this->number = substr($numberWithoutLineBreaks, 0, 15); - if (empty($this->number) && ($this->number === null || !is_numeric(trim($this->number)))) { - + if (!empty($this->number) && !is_numeric(trim($this->number))) { $inputName = $this->i18n->getDashboard('number'); $message = $this->i18n->getDashboard( "The %s should not be empty!", @@ -105,14 +104,8 @@ public function getStreet() * @return Address * @throws \Exception */ - public function setStreet($street, $multipleLineStreet = true) + public function setStreet($street) { - $street = str_replace( - $multipleLineStreet ? self::ADDRESS_LINE_SEPARATOR : '', - '', - $street ?? '' - ); - $streetWithoutLineBreaks = StringFunctionsHelper::removeLineBreaks( $street ); @@ -159,17 +152,6 @@ public function setNeighborhood($neighborhood) $this->neighborhood = substr($neighborhoodWithoutLineBreaks, 0, 64); - if (empty($this->neighborhood)) { - - $inputName = $this->i18n->getDashboard('neighborhood'); - $message = $this->i18n->getDashboard( - "The %s should not be empty!", - $inputName - ); - - throw new \Exception($message, 400); - } - return $this; } @@ -351,7 +333,9 @@ public function jsonSerialize() $obj = new \stdClass(); $obj->street = $this->street; + $obj->number = $this->number ?? '0'; $obj->complement = $this->complement; + $obj->neighborhood = $this->neighborhood; $obj->zipCode = $this->zipCode; $obj->city = $this->city; $obj->state = $this->state; @@ -359,14 +343,6 @@ public function jsonSerialize() $obj->line1 = $this->getLine1(); $obj->line2 = $this->getLine2(); - if (!empty($this->number)) { - $obj->number = $this->number; - } - - if (!empty($this->neighborhood)) { - $obj->neighborhood = $this->neighborhood; - } - return $obj; } @@ -377,22 +353,16 @@ public function convertToSDKRequest() { $addressRequest = new CreateAddressRequest(); - $addressRequest->city = $this->getCity(); + $addressRequest->street = $this->getStreet(); + $addressRequest->number = $this->getNumber(); $addressRequest->complement = $this->getComplement(); + $addressRequest->neighborhood = $this->getNeighborhood(); + $addressRequest->city = $this->getCity(); + $addressRequest->state = $this->getState(); $addressRequest->country = $this->getCountry(); + $addressRequest->zipCode = $this->getZipCode(); $addressRequest->line1 = $this->getLine1(); $addressRequest->line2 = $this->getLine2(); - $addressRequest->state = $this->getState(); - $addressRequest->street = $this->getStreet(); - $addressRequest->zipCode = $this->getZipCode(); - - if ($this->getNumber()){ - $addressRequest->number = $this->getNumber(); - } - - if ($this->getNeighborhood()){ - $addressRequest->neighborhood = $this->getNeighborhood(); - } return $addressRequest; } diff --git a/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php b/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php index 5b1fcd70..7ada97b5 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php +++ b/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php @@ -10,25 +10,17 @@ public function createFromJson($json) { $data = json_decode($json); - $multipleLineStreet = !empty($data->number) && !empty($data->neighborhood); - $address = new Address(); - $address->setStreet($data->street, $multipleLineStreet); + $address->setStreet($data->street); + $address->setNumber($data->number); $address->setComplement($data->complement); + $address->setNeighborhood($data->neighborhood); $address->setCity($data->city); $address->setState($data->state); $address->setZipCode($data->zipCode); $address->setCountry('BR'); - if (!empty($data->number)) { - $address->setNumber($data->number); - } - - if (!empty($data->neighborhood)) { - $address->setNeighborhood($data->neighborhood); - } - return $address; } } From 8e04402146bc3f464f426e2a679b0dcad51c79aa Mon Sep 17 00:00:00 2001 From: RafaMelazzo Date: Wed, 25 Sep 2024 14:22:23 -0300 Subject: [PATCH 05/12] feat: added billing_document to admin validation --- .../WoocommercePlatformOrderDecorator.php | 2 +- src/Helper/Utils.php | 14 +-- .../src/Payment/Aggregates/Address.php | 2 +- woo-pagarme-payments.php | 97 ++++++++++++------- 4 files changed, 67 insertions(+), 48 deletions(-) diff --git a/src/Concrete/WoocommercePlatformOrderDecorator.php b/src/Concrete/WoocommercePlatformOrderDecorator.php index 8d23f601..5d75d838 100644 --- a/src/Concrete/WoocommercePlatformOrderDecorator.php +++ b/src/Concrete/WoocommercePlatformOrderDecorator.php @@ -1132,7 +1132,7 @@ protected function getAddress($platformAddress) $this->validateAddressFields($platformAddress); $address->setStreet($platformAddress["street"]); - $address->setNumber($platformAddress["number"] ?? '0'); + $address->setNumber($platformAddress["number"]); $address->setComplement($platformAddress["complement"]); $address->setNeighborhood($platformAddress["neighborhood"]); $address->setCity($platformAddress["city"]); diff --git a/src/Helper/Utils.php b/src/Helper/Utils.php index a02296b7..6c9ba04e 100644 --- a/src/Helper/Utils.php +++ b/src/Helper/Utils.php @@ -591,28 +591,20 @@ public static function build_customer_shipping_from_wc_order(WC_Order $wc_order) $total = self::format_order_price($wc_order->get_shipping_total()); $shipping = $order->get_shipping_info(); - $customerShipping = array( + return array( 'amount' => $total, 'description' => $method, 'address' => array( 'street' => substr($shipping['address_1'], 0, 64), + 'number' => substr($shipping['number'], 0, 15), 'complement' => substr($shipping['address_2'], 0, 64), 'zip_code' => substr(preg_replace('/[^\d]+/', '', $shipping['postcode']), 0, 16), + 'neighborhood' => substr($shipping['neighborhood'], 0, 64), 'city' => substr($shipping['city'], 0, 64), 'state' => substr($shipping['state'], 0, 2), 'country' => 'BR', ), ); - - if (!empty($shipping['number'])) { - $customerShipping['address']['number'] = substr($shipping['number'], 0, 15); - } - - if (!empty($shipping['neighborhood'])) { - $customerShipping['address']['neighborhood'] = substr($shipping['neighborhood'], 0, 64); - } - - return $customerShipping; } /** diff --git a/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php b/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php index 514aa9ff..b1ac1372 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php +++ b/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php @@ -333,7 +333,7 @@ public function jsonSerialize() $obj = new \stdClass(); $obj->street = $this->street; - $obj->number = $this->number ?? '0'; + $obj->number = $this->number; $obj->complement = $this->complement; $obj->neighborhood = $this->neighborhood; $obj->zipCode = $this->zipCode; diff --git a/woo-pagarme-payments.php b/woo-pagarme-payments.php index 953da138..fd73b488 100644 --- a/woo-pagarme-payments.php +++ b/woo-pagarme-payments.php @@ -18,7 +18,6 @@ use Woocommerce\Pagarme\Model\Config; use Woocommerce\Pagarme\Model\FeatureCompatibilization; - const BRAZILIAN_MARKET_URL = 'https://wordpress.org/plugins/woocommerce-extra-checkout-fields-for-brazil/'; const PAGARME_REQUIREMENTS_URL = 'https://docs.pagar.me/docs/requisitos-de-instala%C3%A7%C3%A3o-woocommerce'; @@ -30,6 +29,7 @@ /** * Renders custom Wordpress Notice on every admin pages. + * * @param string $message Message displayed on the notice. * @param array $buttons Optional. An array of buttons arrays, generated with the wcmpSingleButtonArray function. * @param string $type Optional. The type of the notice. @@ -57,11 +57,11 @@ function wcmpRenderAdminNoticeHtml($message, $buttons = [], $type = 'error', $in wp_set_script_translations( 'pagarme-notice-js', 'woo-pagarme-payments', - plugin_dir_path( __FILE__ ) . 'languages/' + plugin_dir_path(__FILE__) . 'languages/' ); wp_localize_script('pagarme-notice-js', 'pagarmeNotice', $noticesL10n); } -?> + ?>
@@ -79,7 +79,7 @@ function wcmpRenderAdminNoticeHtml($message, $buttons = [], $type = 'error', $in
- $label, - 'url' => $url, - 'type' => $type, + 'label' => $label, + 'url' => $url, + 'type' => $type, 'target' => $target, - 'class' => $class + 'class' => $class ); } /** * @param array $buttons Array of arrays, each containing the keys `label`, `url`, `type`, `target` and `class`. + * * @return string */ function wcmpAddNoticeButton($buttons) @@ -138,20 +140,23 @@ function wcmpAdminNoticePhpVersion() if (version_compare(PHP_VERSION, '7.1', '<')) { wcmpLoadNotice('AdminNoticePhpVersion'); + return; } -function wcmpIsPluginInstalled($pluginBasename) { +function wcmpIsPluginInstalled($pluginBasename) +{ $isInstalled = false; if (function_exists('get_plugins')) { - $allPlugins = get_plugins(); + $allPlugins = get_plugins(); $isInstalled = !empty($allPlugins[$pluginBasename]); } return $isInstalled; } -function wcmpGetPluginButton($pluginBasename, $pluginName) { +function wcmpGetPluginButton($pluginBasename, $pluginName) +{ $button = []; if (wcmpIsPluginInstalled($pluginBasename) && current_user_can('install_plugins')) { @@ -195,7 +200,7 @@ function wcmpAdminNoticePermalink() wcmpRenderAdminNoticeHtml( __( 'Permalink structure in Wordpress Settings must be different from “Plain”. ' . - 'Please correct this setting to be able to transact with Pagar.me.', + 'Please correct this setting to be able to transact with Pagar.me.', 'woo-pagarme-payments' ), array( @@ -213,35 +218,40 @@ function wcmpAdminNoticeCheckoutFields() return; } + if (!class_exists('WC_Session')) { + include_once WP_PLUGIN_DIR . '/woocommerce/includes/abstracts/abstract-wc-session.php'; + } + + WC()->session = new WC_Session_Handler; + WC()->customer = new WC_Customer; + $billingFields = WC()->checkout->get_checkout_fields()['billing']; + $missingFields = []; $requiredFields = [ 'billing_cpf', 'billing_cnpj', + 'billing_document', 'billing_first_name', 'billing_last_name', ]; + if (!(new Config())->getAllowNoAddress()) { $requiredFields[] = 'billing_address_1'; - $requiredFields[] = 'billing_number'; $requiredFields[] = 'billing_address_2'; - $requiredFields[] = 'billing_neighborhood'; $requiredFields[] = 'billing_country'; $requiredFields[] = 'billing_city'; $requiredFields[] = 'billing_state'; $requiredFields[] = 'billing_postcode'; } - $checkoutFields = WC()->countries->get_address_fields(WC()->countries->get_base_country()); foreach ($requiredFields as $field) { - if (!array_key_exists($field, $checkoutFields)) { + if (!array_key_exists($field, $billingFields)) { $missingFields[] = $field; } } - if ((in_array('billing_cpf', $missingFields) && !in_array('billing_cnpj', $missingFields)) || - (in_array('billing_cnpj', $missingFields) && !in_array('billing_cpf', $missingFields)) - ) { - array_shift($missingFields); + if (hasAnyBillingDocument($missingFields)) { + $missingFields = array_slice($missingFields, 2); } if (empty($missingFields)) { @@ -260,7 +270,7 @@ function wcmpAdminNoticeCheckoutFields() $message .= '

'; $message .= sprintf( __('You can install %s or any other plugin of your choice to add the missing fields. %sRead ' - . 'documentation »%s', 'woo-pagarme-payments'), + . 'documentation »%s', 'woo-pagarme-payments'), sprintf( 'Brazilian Market on WooCommerce', BRAZILIAN_MARKET_URL @@ -289,6 +299,12 @@ function wcmpLoadInstances() do_action('wcmp_init'); } +/** + * @return void + * @uses wcmpAdminNoticeWoocommerce() + * @uses wcmpAdminNoticePermalink() + * @uses wcmpAdminNoticeCheckoutFields() + */ function wcmpPluginsLoadedCheck() { $woocommerce = class_exists('WooCommerce'); @@ -311,9 +327,20 @@ function wcmpPluginsLoadedCheck() } add_action('plugins_loaded', 'wcmpPluginsLoadedCheck', 0); -add_action( 'before_woocommerce_init', 'checkCompatibilityWithFeatures', 0); +add_action('before_woocommerce_init', 'checkCompatibilityWithFeatures', 0); add_action('woocommerce_blocks_loaded', 'addWoocommerceSupportedBlocks'); +function hasAnyBillingDocument($missingFields) +{ + $hasCpf = in_array('billing_cpf', $missingFields); + $hasCnpj = in_array('billing_cnpj', $missingFields); + $hasDocument = in_array('billing_document', $missingFields); + + return ($hasCpf && (!$hasCnpj || !$hasDocument)) + || ($hasCnpj && (!$hasCpf || !$hasDocument)) + || ($hasDocument && (!$hasCpf || !$hasCnpj)); +} + function checkCompatibilityWithFeatures() { $compatibilization = new FeatureCompatibilization(); @@ -334,8 +361,8 @@ function versionUpdateWarning($currentVersion, $newVersion) if ($currentVersionMajorPart >= $newVersionMajorPart) { return; } -?> -


+ ?> +

@@ -347,9 +374,9 @@ function versionUpdateWarning($currentVersion, $newVersion) printf( esc_html__( 'This new release contains crucial architecture and functionality updates. ' . - 'We highly recommend you %1$sbackup your site before upgrading%2$s. ' . - 'It is highly recommended to perform and validate the update first in the staging ' . - 'environment before performing the update in production.', + 'We highly recommend you %1$sbackup your site before upgrading%2$s. ' . + 'It is highly recommended to perform and validate the update first in the staging ' . + 'environment before performing the update in production.', 'woo-pagarme-payments' ), '', @@ -359,7 +386,7 @@ function versionUpdateWarning($currentVersion, $newVersion)
-get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_configuration'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -408,7 +435,7 @@ function wcmpCreateCoreCustomerTable($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_customer'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -427,7 +454,7 @@ function wcmpCreateCoreChargeTable($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_charge'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -454,7 +481,7 @@ function wcmpCreateCoreOrderTable($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_order'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -474,7 +501,7 @@ function wcmpCreateCoreTransactionTable($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_transaction'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -506,7 +533,7 @@ function wcmpCreateCoreSavedCardTable($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_saved_card'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -530,7 +557,7 @@ function wcmpCreateCoreHubInstallToken($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_hub_install_token'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} From e586dcb6d8eb147a962c04e7a531fc3e4e08afa8 Mon Sep 17 00:00:00 2001 From: Fabiano Mallmann <25328512+fabiano-mallmann@users.noreply.github.com> Date: Wed, 25 Sep 2024 15:55:05 -0300 Subject: [PATCH 06/12] feat: add field document on checkout blocks --- .../front/checkout/checkoutFields.js | 12 +- src/Action/CustomerFieldsActions.php | 36 ++- src/Model/Payment/PostFormatter.php | 2 + tests/Block/Checkout/GatewayTest.php | 231 ++++++++++++------ 4 files changed, 211 insertions(+), 70 deletions(-) diff --git a/assets/javascripts/front/checkout/checkoutFields.js b/assets/javascripts/front/checkout/checkoutFields.js index d7bdc9a4..cfd73aa0 100644 --- a/assets/javascripts/front/checkout/checkoutFields.js +++ b/assets/javascripts/front/checkout/checkoutFields.js @@ -3,6 +3,9 @@ const pagarmeCustomerFields = { billingDocumentId: 'billing_document', shippingDocumentId: 'shipping_document', + billingPagarmeDocumentId: 'billing-address-document', + shippingPagarmeDocumentId: 'shipping-address-document', + documentMasks: [ '000.000.000-00999', '00.000.000/0000-00' @@ -18,13 +21,20 @@ const pagarmeCustomerFields = { applyDocumentMask() { jQuery('#' + this.billingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); jQuery('#' + this.shippingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); + jQuery('#' + this.billingPagarmeDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); + jQuery('#' + this.shippingPagarmeDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); }, addEventListener() { + jQuery(document.body).on('DOMContentLoaded', function () { + pagarmeCustomerFields.applyDocumentMask(); + }); jQuery(document.body).on('checkout_error', function () { const documentFieldIds = [ pagarmeCustomerFields.billingDocumentId, - pagarmeCustomerFields.shippingDocumentId + pagarmeCustomerFields.shippingDocumentId, + pagarmeCustomerFields.billingPagarmeDocumentId, + pagarmeCustomerFields.shippingPagarmeDocumentId ]; jQuery.each(documentFieldIds, function () { const documentField = '#' + this + '_field', diff --git a/src/Action/CustomerFieldsActions.php b/src/Action/CustomerFieldsActions.php index 64a51245..fe990fea 100644 --- a/src/Action/CustomerFieldsActions.php +++ b/src/Action/CustomerFieldsActions.php @@ -50,7 +50,8 @@ public function enqueueScript() 'pagarme_customer_fields', $parameters['src'], $parameters['deps'], - $parameters['ver'] + $parameters['ver'], + true ); wp_enqueue_script('pagarme_customer_fields'); } @@ -79,6 +80,39 @@ public function addDocumentField(array $fields): array return $fields; } + public function addDocumentFieldOnCheckoutBlocks() { + + if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) { + return; + } + woocommerce_register_additional_checkout_field( + array( + 'id' => 'address/document', + 'label' => 'CPF ou CNPJ', + 'location' => 'address', + 'type' => 'text', + 'class' => array( 'form-row-wide' ), + 'required' => true, + 'index' => 25, + 'show_in_order_confirmation' => true, + 'sanitize_callback' => function( $field_value ) { + return str_replace( ' ', '', $field_value ); + }, + ), + ); + + add_action( + 'woocommerce_validate_additional_field', + function ( \WP_Error $errors, $field_key, $field_value ) { + if ( 'address/document' === $field_key ) { + $this->validateDocument() + } + }, + 10, + 3 + ); + } + /** * @return void * @uses CustomerFields::isValidCnpj() diff --git a/src/Model/Payment/PostFormatter.php b/src/Model/Payment/PostFormatter.php index a914fff8..f5479a01 100644 --- a/src/Model/Payment/PostFormatter.php +++ b/src/Model/Payment/PostFormatter.php @@ -96,6 +96,8 @@ public function assemblePaymentRequest() public function formatReactCheckout() { if (!empty($_POST['pagarme']) && is_string($_POST['pagarme'])) { + $_POST['billing_document'] = $_POST['address/document']; + $_POST['shipping_document'] = $_POST['address/document']; $_POST['pagarme'] = json_decode($_POST['pagarme'], true); } } diff --git a/tests/Block/Checkout/GatewayTest.php b/tests/Block/Checkout/GatewayTest.php index 8259af90..8bb2dd5e 100644 --- a/tests/Block/Checkout/GatewayTest.php +++ b/tests/Block/Checkout/GatewayTest.php @@ -1,87 +1,182 @@ customerFields = new CustomerFields(); + } - global $wp; - $wp = new stdClass; + public function run() + { + add_filter('woocommerce_checkout_init', array($this, 'enqueueScript')); + add_filter('woocommerce_checkout_fields', array($this, 'addDocumentField')); + add_action('woocommerce_checkout_process', array($this, 'validateDocument')); + add_action( + 'woocommerce_admin_order_data_after_billing_address', + array($this, 'displayBillingDocumentOrderMeta') + ); + add_action( + 'woocommerce_admin_order_data_after_shipping_address', + array($this, 'displayShippingDocumentOrderMeta') + ); + add_filter('woocommerce_default_address_fields', array($this, 'overrideAddressFields')); + } - Brain\Monkey\setUp(); + public function enqueueScript() + { + $parameters = Utils::getRegisterScriptParameters('front/checkout', 'checkoutFields', ['jquery.mask']); + wp_register_script( + 'pagarme_customer_fields', + $parameters['src'], + $parameters['deps'], + $parameters['ver'] + ); + wp_enqueue_script('pagarme_customer_fields'); } - public function tearDown(): void + + /** + * @param array $fields + * + * @return array + */ + public function addDocumentField(array $fields): array + { + if ($this->customerFields->hasDocumentField($fields)) { + return $fields; + } + + foreach ($this->customerFields::ADDRESS_TYPES as $addressType) { + $fields[$addressType]["{$addressType}_document"] = array( + 'label' => __('Document', 'woo-pagarme-payments'), + 'placeholder' => __('CPF or CNPJ', 'woo-pagarme-payments'), + 'required' => true, + 'class' => array('form-row-wide'), + 'priority' => 25 + ); + } + + return $fields; + } + + /** + * @return void + * @uses CustomerFields::isValidCnpj() + * @uses CustomerFields::isValidCpf() + */ + public function validateDocument() + array( + 'id' => 'pagarme/document', { - parent::tearDown(); + foreach ($this->customerFields::ADDRESS_TYPES as $addressType) { + $fieldName = "{$addressType}_document"; + $document = $_POST[$fieldName]; + + if (!$document) { + continue; + } + + $documentNumber = preg_replace('/\D/', '', $document); + $documentLength = strlen($documentNumber); + + if ($documentLength !== 11 && $documentLength !== 14) { + $errorMessage = sprintf( + __( + 'Please, enter a valid document number in the %s Document.', + 'woo-pagarme-payments' + ), + _x( + ucfirst($addressType), + 'checkout-document-error', + 'woo-pagarme-payments' + ) + ); + + wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); + continue; + } + + $documentType = $documentLength === 11 + ? $this->customerFields::DOCUMENT_TYPES[0] + : $this->customerFields::DOCUMENT_TYPES[1]; + $functionName = 'isValid' . ucfirst($documentType); + $isValidDocument = $this->customerFields->{$functionName}($documentNumber); + + if (!$isValidDocument) { + $errorMessage = sprintf( + __( + 'Please, enter a valid %s number in the %s Document.', + 'woo-pagarme-payments' + ), + strtoupper($documentType), + _x( + ucfirst($addressType), + 'checkout-document-error', + 'woo-pagarme-payments' + ) + ); + wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); + } + } + } - Mockery::close(); - Brain\Monkey\tearDown(); + /** + * @param $order + * + * @return void + */ + public function displayBillingDocumentOrderMeta($order) + { + $this->customerFields->displayDocumentOrderMeta($order, $this->customerFields::ADDRESS_TYPES[0]); } - public function testCartTotalsWithoutOrderPayShouldReturnCartTotal() + /** + * @param $order + * + * @return void + */ + public function displayShippingDocumentOrderMeta($order) { - $jsonMock = Mockery::mock(Json::class); - $configMock = Mockery::mock(Config::class); - $gatewayModelMock = Mockery::mock(GatewayModel::class); - $data = [ - 'config' => $configMock, - 'gateway' => $gatewayModelMock, - ]; - - global $wp; - $wp->query_vars = [ - 'order-pay' => 1 - ]; - - $orderMock = Mockery::mock(WC_Order::class); - $orderMock->shouldReceive('get_total') - ->andReturn(10); - - Brain\Monkey\Functions\stubs([ - 'wc_get_order' => $orderMock - ]); - - $gatewayBlock = new Gateway($jsonMock, $data); - $this->assertEquals(10, $gatewayBlock->getCartTotals()); + $this->customerFields->displayDocumentOrderMeta($order, $this->customerFields::ADDRESS_TYPES[1]); } - public function testCartTotalsWithOrderPayShouldReturnOrderTotal() + /** + * @param array $fields + * + * @return array + */ + public function overrideAddressFields(array $fields): array { - $jsonMock = Mockery::mock(Json::class); - - $configMock = Mockery::mock(Config::class); - $gatewayModelMock = Mockery::mock(GatewayModel::class); - $data = [ - 'config' => $configMock, - 'gateway' => $gatewayModelMock, - ]; - - global $wp; - $wp->query_vars = []; - - $wcCheckoutMock = Mockery::mock(WC_Cart::class); - $wcCheckoutMock->total = 20; - $woocommerce = new stdClass(); - $woocommerce->cart = $wcCheckoutMock; - Brain\Monkey\Functions\stubs([ - 'WC' => $woocommerce, - ]); - - $gatewayBlock = new Gateway($jsonMock, $data); - $this->assertEquals(20, $gatewayBlock->getCartTotals()); + $fields['address_1']['placeholder'] = __( + 'Street name, house number and neighbourhood', + 'woo-pagarme-payments' + ); + $fields['address_2']['label'] = __( + 'Additional address data', + 'woo-pagarme-payments' + ); + $fields['address_2']['label_class'] = ''; + + return $fields; } } From 215348b06bc13ae2603632671027138e6789169d Mon Sep 17 00:00:00 2001 From: Fabiano Mallmann <25328512+fabiano-mallmann@users.noreply.github.com> Date: Wed, 25 Sep 2024 17:31:32 -0300 Subject: [PATCH 07/12] feat: add document field to checkoutblocks --- woo-pagarme-payments.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/woo-pagarme-payments.php b/woo-pagarme-payments.php index fd73b488..c4f8a78e 100644 --- a/woo-pagarme-payments.php +++ b/woo-pagarme-payments.php @@ -17,6 +17,7 @@ use Woocommerce\Pagarme\Model\Config; use Woocommerce\Pagarme\Model\FeatureCompatibilization; +use Woocommerce\Pagarme\Action\CustomerFieldsActions; const BRAZILIAN_MARKET_URL = 'https://wordpress.org/plugins/woocommerce-extra-checkout-fields-for-brazil/'; const PAGARME_REQUIREMENTS_URL = 'https://docs.pagar.me/docs/requisitos-de-instala%C3%A7%C3%A3o-woocommerce'; @@ -329,6 +330,10 @@ function wcmpPluginsLoadedCheck() add_action('plugins_loaded', 'wcmpPluginsLoadedCheck', 0); add_action('before_woocommerce_init', 'checkCompatibilityWithFeatures', 0); add_action('woocommerce_blocks_loaded', 'addWoocommerceSupportedBlocks'); +add_action('woocommerce_blocks_loaded', 'addDocumentFieldOnCheckoutblocks'); + + + function hasAnyBillingDocument($missingFields) { @@ -341,6 +346,12 @@ function hasAnyBillingDocument($missingFields) || ($hasDocument && (!$hasCpf || !$hasCnpj)); } +function addDocumentFieldOnCheckoutblocks() +{ + $checkoutFields = new CustomerFieldsActions(); + $checkoutFields->addDocumentFieldOnCheckoutBlocks(); +} + function checkCompatibilityWithFeatures() { $compatibilization = new FeatureCompatibilization(); From aa23de547d07ba6adc4cb67940deb47184619e72 Mon Sep 17 00:00:00 2001 From: RafaMelazzo Date: Thu, 26 Sep 2024 15:20:44 -0300 Subject: [PATCH 08/12] feat: added address modification flag --- languages/woo-pagarme-payments-pt_BR.mo | Bin 40470 -> 41137 bytes languages/woo-pagarme-payments-pt_BR.po | 20 +- src/Action/CustomerFieldsActions.php | 48 ++--- src/Controller/Settings.php | 12 ++ src/Model/Config.php | 5 + tests/Block/Checkout/GatewayTest.php | 231 +++++++----------------- woo-pagarme-payments.php | 18 +- 7 files changed, 131 insertions(+), 203 deletions(-) diff --git a/languages/woo-pagarme-payments-pt_BR.mo b/languages/woo-pagarme-payments-pt_BR.mo index 8228554898ae7942d6fb6a79ae2dd00bdfafe1e9..5dbabcf4eeb3cd857728f51c624c2c08b0b28f52 100644 GIT binary patch delta 9200 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 diff --git a/languages/woo-pagarme-payments-pt_BR.po b/languages/woo-pagarme-payments-pt_BR.po index 442dab83..01ce14b5 100644 --- a/languages/woo-pagarme-payments-pt_BR.po +++ b/languages/woo-pagarme-payments-pt_BR.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: WooCommerce Pagar.me Payments 1.0\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/woo-pagarme-payments\n" "POT-Creation-Date: 2018-06-22 13:58-0300\n" -"PO-Revision-Date: 2024-09-16 14:34-0300\n" +"PO-Revision-Date: 2024-09-26 13:37-0300\n" "Last-Translator: Pagar.me\n" "Language-Team: \n" "Language: pt_BR\n" @@ -423,6 +423,16 @@ msgstr "Logs" msgid "Log Pagar.me events, you can check this log in WooCommerce>Status>Logs." msgstr "Registra eventos da Pagar.me, você pode conferir esse arquivo de log em WooCommerce>Status>Logs." +msgid "Modify address fields" +msgstr "Modificar campos de endereço" + +msgid "" +"Corrects the 'label' and 'placeholder' attributes of the 'Address' and 'Complement' fields to instruct users on how " +"to fill them in correctly." +msgstr "" +"Corrige os atributos 'label' e 'placeholder' dos campos de 'Endereço' e 'Complemento' para instruir os usuários no " +"preenchimento correto dos mesmos." + msgid "Allow order without address" msgstr "Permitir compras sem endereço" @@ -849,8 +859,12 @@ msgid "The following checkout fields are required, but were not found:" msgstr "Os seguintes campos de checkout são obrigatórios, mas não foram encontrados:" #: woo-pagarme-payments.php:194 -msgid "Please, make sure to include them for Pagar.me module to work." -msgstr "Por favor, certifique-se de incluí-los para que o módulo da Pagar.me funcione." +msgid "" +"Please, make sure to include them for Pagar.me plugin to work. If you are customizing the checkout, the address " +"fields must have the 'name' attribute exactly as listed above. %sRead documentation »%s" +msgstr "" +"Por favor, certifique-se de incluí-los para que o plugin Pagar.me funcione. Se você estiver personalizando o " +"checkout, os campos de endereço devem ter o atributo 'name' exatamente como listado acima. %sLeia a documentação »%s" msgid "You can install %s or any other plugin of your choice to add the missing fields. %sRead documentation »%s" msgstr "" diff --git a/src/Action/CustomerFieldsActions.php b/src/Action/CustomerFieldsActions.php index fe990fea..2aab4bdd 100644 --- a/src/Action/CustomerFieldsActions.php +++ b/src/Action/CustomerFieldsActions.php @@ -12,6 +12,7 @@ use Woocommerce\Pagarme\Controller\Checkout\CustomerFields; use Woocommerce\Pagarme\Helper\Utils; +use Woocommerce\Pagarme\Model\Config; defined('ABSPATH') || exit; @@ -80,36 +81,29 @@ public function addDocumentField(array $fields): array return $fields; } - public function addDocumentFieldOnCheckoutBlocks() { - - if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) { + /** + * @throws \Exception + */ + public function addDocumentFieldOnCheckoutBlocks() + { + if (!function_exists('woocommerce_register_additional_checkout_field')) { return; } + woocommerce_register_additional_checkout_field( array( - 'id' => 'address/document', - 'label' => 'CPF ou CNPJ', - 'location' => 'address', - 'type' => 'text', - 'class' => array( 'form-row-wide' ), - 'required' => true, - 'index' => 25, + 'id' => 'address/document', + 'label' => __('CPF or CNPJ', 'woo-pagarme-payments'), + 'location' => 'address', + 'type' => 'text', + 'class' => array('form-row-wide'), + 'required' => true, + 'index' => 25, 'show_in_order_confirmation' => true, - 'sanitize_callback' => function( $field_value ) { - return str_replace( ' ', '', $field_value ); + 'sanitize_callback' => function ($field_value) { + return str_replace(' ', '', $field_value); }, - ), - ); - - add_action( - 'woocommerce_validate_additional_field', - function ( \WP_Error $errors, $field_key, $field_value ) { - if ( 'address/document' === $field_key ) { - $this->validateDocument() - } - }, - 10, - 3 + ) ); } @@ -199,6 +193,12 @@ public function displayShippingDocumentOrderMeta($order) */ public function overrideAddressFields(array $fields): array { + $config = new Config(); + + if (!$config->getModifyAddress()) { + return $fields; + } + $fields['address_1']['placeholder'] = __( 'Street name, house number and neighbourhood', 'woo-pagarme-payments' diff --git a/src/Controller/Settings.php b/src/Controller/Settings.php index 2177667a..30383725 100644 --- a/src/Controller/Settings.php +++ b/src/Controller/Settings.php @@ -143,6 +143,18 @@ private function setSectionsFields(array $value = null) 'options' => $this->yesNoOptions->toLabelsArray(), 'default' => strtolower(Yesno::NO), ], + [ + 'fieldObject' => Select::class, + 'id' => 'modify_address', + 'title' => 'Modify address fields', + 'options' => $this->yesNoOptions->toLabelsArray(), + 'default' => strtolower(Yesno::YES), + 'description' => [ + 'format' => "Corrects the 'label' and 'placeholder' attributes of the 'Address' and " + . "'Complement' fields to instruct users on how to fill them in correctly.", + 'values' => [] + ], + ], [ 'fieldObject' => Select::class, 'id' => 'allow_no_address', diff --git a/src/Model/Config.php b/src/Model/Config.php index c5723567..78178c1d 100644 --- a/src/Model/Config.php +++ b/src/Model/Config.php @@ -263,6 +263,11 @@ public function getMulticustomers() return $this->isEnabled('multicustomers'); } + public function getModifyAddress() + { + return $this->isEnabled('modify_address'); + } + public function getAllowNoAddress() { return $this->isEnabled('allow_no_address'); diff --git a/tests/Block/Checkout/GatewayTest.php b/tests/Block/Checkout/GatewayTest.php index 8bb2dd5e..51fc3f3e 100644 --- a/tests/Block/Checkout/GatewayTest.php +++ b/tests/Block/Checkout/GatewayTest.php @@ -1,182 +1,87 @@ customerFields = new CustomerFields(); - } + parent::setUp(); - public function run() - { - add_filter('woocommerce_checkout_init', array($this, 'enqueueScript')); - add_filter('woocommerce_checkout_fields', array($this, 'addDocumentField')); - add_action('woocommerce_checkout_process', array($this, 'validateDocument')); - add_action( - 'woocommerce_admin_order_data_after_billing_address', - array($this, 'displayBillingDocumentOrderMeta') - ); - add_action( - 'woocommerce_admin_order_data_after_shipping_address', - array($this, 'displayShippingDocumentOrderMeta') - ); - add_filter('woocommerce_default_address_fields', array($this, 'overrideAddressFields')); - } + global $wp; + $wp = new stdClass; - public function enqueueScript() - { - $parameters = Utils::getRegisterScriptParameters('front/checkout', 'checkoutFields', ['jquery.mask']); - wp_register_script( - 'pagarme_customer_fields', - $parameters['src'], - $parameters['deps'], - $parameters['ver'] - ); - wp_enqueue_script('pagarme_customer_fields'); + Brain\Monkey\setUp(); } - - /** - * @param array $fields - * - * @return array - */ - public function addDocumentField(array $fields): array - { - if ($this->customerFields->hasDocumentField($fields)) { - return $fields; - } - - foreach ($this->customerFields::ADDRESS_TYPES as $addressType) { - $fields[$addressType]["{$addressType}_document"] = array( - 'label' => __('Document', 'woo-pagarme-payments'), - 'placeholder' => __('CPF or CNPJ', 'woo-pagarme-payments'), - 'required' => true, - 'class' => array('form-row-wide'), - 'priority' => 25 - ); - } - - return $fields; - } - - /** - * @return void - * @uses CustomerFields::isValidCnpj() - * @uses CustomerFields::isValidCpf() - */ - public function validateDocument() - array( - 'id' => 'pagarme/document', + public function tearDown(): void { - foreach ($this->customerFields::ADDRESS_TYPES as $addressType) { - $fieldName = "{$addressType}_document"; - $document = $_POST[$fieldName]; - - if (!$document) { - continue; - } - - $documentNumber = preg_replace('/\D/', '', $document); - $documentLength = strlen($documentNumber); - - if ($documentLength !== 11 && $documentLength !== 14) { - $errorMessage = sprintf( - __( - 'Please, enter a valid document number in the %s Document.', - 'woo-pagarme-payments' - ), - _x( - ucfirst($addressType), - 'checkout-document-error', - 'woo-pagarme-payments' - ) - ); - - wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); - continue; - } - - $documentType = $documentLength === 11 - ? $this->customerFields::DOCUMENT_TYPES[0] - : $this->customerFields::DOCUMENT_TYPES[1]; - $functionName = 'isValid' . ucfirst($documentType); - $isValidDocument = $this->customerFields->{$functionName}($documentNumber); - - if (!$isValidDocument) { - $errorMessage = sprintf( - __( - 'Please, enter a valid %s number in the %s Document.', - 'woo-pagarme-payments' - ), - strtoupper($documentType), - _x( - ucfirst($addressType), - 'checkout-document-error', - 'woo-pagarme-payments' - ) - ); - wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); - } - } - } + parent::tearDown(); - /** - * @param $order - * - * @return void - */ - public function displayBillingDocumentOrderMeta($order) - { - $this->customerFields->displayDocumentOrderMeta($order, $this->customerFields::ADDRESS_TYPES[0]); + Mockery::close(); + Brain\Monkey\tearDown(); } - /** - * @param $order - * - * @return void - */ - public function displayShippingDocumentOrderMeta($order) + public function testCartTotalsWithoutOrderPayShouldReturnCartTotal() { - $this->customerFields->displayDocumentOrderMeta($order, $this->customerFields::ADDRESS_TYPES[1]); + $jsonMock = Mockery::mock(Json::class); + $configMock = Mockery::mock(Config::class); + $gatewayModelMock = Mockery::mock(GatewayModel::class); + $data = [ + 'config' => $configMock, + 'gateway' => $gatewayModelMock, + ]; + + global $wp; + $wp->query_vars = [ + 'order-pay' => 1 + ]; + + $orderMock = Mockery::mock(WC_Order::class); + $orderMock->shouldReceive('get_total') + ->andReturn(10); + + Brain\Monkey\Functions\stubs([ + 'wc_get_order' => $orderMock + ]); + + $gatewayBlock = new Gateway($jsonMock, $data); + $this->assertEquals(10, $gatewayBlock->getCartTotals()); } - /** - * @param array $fields - * - * @return array - */ - public function overrideAddressFields(array $fields): array + public function testCartTotalsWithOrderPayShouldReturnOrderTotal() { - $fields['address_1']['placeholder'] = __( - 'Street name, house number and neighbourhood', - 'woo-pagarme-payments' - ); - $fields['address_2']['label'] = __( - 'Additional address data', - 'woo-pagarme-payments' - ); - $fields['address_2']['label_class'] = ''; - - return $fields; + $jsonMock = Mockery::mock(Json::class); + + $configMock = Mockery::mock(Config::class); + $gatewayModelMock = Mockery::mock(GatewayModel::class); + $data = [ + 'config' => $configMock, + 'gateway' => $gatewayModelMock, + ]; + + global $wp; + $wp->query_vars = []; + + $wcCheckoutMock = Mockery::mock(WC_Cart::class); + $wcCheckoutMock->total = 20; + $woocommerce = new stdClass(); + $woocommerce->cart = $wcCheckoutMock; + Brain\Monkey\Functions\stubs([ + 'WC' => $woocommerce, + ]); + + $gatewayBlock = new Gateway($jsonMock, $data); + $this->assertEquals(20, $gatewayBlock->getCartTotals()); } } diff --git a/woo-pagarme-payments.php b/woo-pagarme-payments.php index c4f8a78e..8bbd6aed 100644 --- a/woo-pagarme-payments.php +++ b/woo-pagarme-payments.php @@ -19,7 +19,6 @@ use Woocommerce\Pagarme\Model\FeatureCompatibilization; use Woocommerce\Pagarme\Action\CustomerFieldsActions; -const BRAZILIAN_MARKET_URL = 'https://wordpress.org/plugins/woocommerce-extra-checkout-fields-for-brazil/'; const PAGARME_REQUIREMENTS_URL = 'https://docs.pagar.me/docs/requisitos-de-instala%C3%A7%C3%A3o-woocommerce'; if (!defined('ABSPATH') || !function_exists('add_action')) { @@ -233,7 +232,7 @@ function wcmpAdminNoticeCheckoutFields() 'billing_cnpj', 'billing_document', 'billing_first_name', - 'billing_last_name', + 'billing_last_name' ]; if (!(new Config())->getAllowNoAddress()) { @@ -267,21 +266,17 @@ function wcmpAdminNoticeCheckoutFields() } $message .= '

'; - $message .= __('Please, make sure to include them for Pagar.me module to work.', 'woo-pagarme-payments'); - $message .= '

'; $message .= sprintf( - __('You can install %s or any other plugin of your choice to add the missing fields. %sRead ' - . 'documentation »%s', 'woo-pagarme-payments'), - sprintf( - 'Brazilian Market on WooCommerce', - BRAZILIAN_MARKET_URL - ), + __("Please, make sure to include them for Pagar.me plugin to work. If you are customizing the " + . "checkout, the address fields must have the 'name' attribute exactly as listed above. %sRead " + . "documentation »%s", "woo-pagarme-payments"), sprintf( '', PAGARME_REQUIREMENTS_URL ), '' ); + $message .= '

'; wcmpRenderAdminNoticeHtml($message); } @@ -332,9 +327,6 @@ function wcmpPluginsLoadedCheck() add_action('woocommerce_blocks_loaded', 'addWoocommerceSupportedBlocks'); add_action('woocommerce_blocks_loaded', 'addDocumentFieldOnCheckoutblocks'); - - - function hasAnyBillingDocument($missingFields) { $hasCpf = in_array('billing_cpf', $missingFields); From e323e7956dc2275a612b5d01cc18d03b67e7dd10 Mon Sep 17 00:00:00 2001 From: RafaMelazzo Date: Mon, 30 Sep 2024 09:45:49 -0300 Subject: [PATCH 09/12] refactor: document validation and condition to add in checkout blocks --- .../front/checkout/checkoutFields.js | 22 +- src/Action/CustomerFieldsActions.php | 66 +----- src/Controller/Checkout/CustomerFields.php | 224 ++++++++++++++++-- woo-pagarme-payments.php | 7 - 4 files changed, 225 insertions(+), 94 deletions(-) diff --git a/assets/javascripts/front/checkout/checkoutFields.js b/assets/javascripts/front/checkout/checkoutFields.js index cfd73aa0..6eab8876 100644 --- a/assets/javascripts/front/checkout/checkoutFields.js +++ b/assets/javascripts/front/checkout/checkoutFields.js @@ -3,9 +3,9 @@ const pagarmeCustomerFields = { billingDocumentId: 'billing_document', shippingDocumentId: 'shipping_document', - billingPagarmeDocumentId: 'billing-address-document', - shippingPagarmeDocumentId: 'shipping-address-document', - + blocksBillingDocumentId: 'billing-address-document', + blocksShippingDocumentId: 'shipping-address-document', + documentMasks: [ '000.000.000-00999', '00.000.000/0000-00' @@ -21,20 +21,17 @@ const pagarmeCustomerFields = { applyDocumentMask() { jQuery('#' + this.billingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); jQuery('#' + this.shippingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); - jQuery('#' + this.billingPagarmeDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); - jQuery('#' + this.shippingPagarmeDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); + jQuery('#' + this.blocksBillingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); + jQuery('#' + this.blocksShippingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); }, addEventListener() { - jQuery(document.body).on('DOMContentLoaded', function () { - pagarmeCustomerFields.applyDocumentMask(); - }); jQuery(document.body).on('checkout_error', function () { const documentFieldIds = [ pagarmeCustomerFields.billingDocumentId, pagarmeCustomerFields.shippingDocumentId, - pagarmeCustomerFields.billingPagarmeDocumentId, - pagarmeCustomerFields.shippingPagarmeDocumentId + pagarmeCustomerFields.blocksBillingDocumentId, + pagarmeCustomerFields.blocksShippingDocumentId ]; jQuery.each(documentFieldIds, function () { const documentField = '#' + this + '_field', @@ -50,8 +47,11 @@ const pagarmeCustomerFields = { }, start: function () { - this.applyDocumentMask(); this.addEventListener(); + + setTimeout(function() { + pagarmeCustomerFields.applyDocumentMask(); + }, 2000); } }; diff --git a/src/Action/CustomerFieldsActions.php b/src/Action/CustomerFieldsActions.php index 2aab4bdd..aa755749 100644 --- a/src/Action/CustomerFieldsActions.php +++ b/src/Action/CustomerFieldsActions.php @@ -10,6 +10,7 @@ namespace Woocommerce\Pagarme\Action; +use Exception; use Woocommerce\Pagarme\Controller\Checkout\CustomerFields; use Woocommerce\Pagarme\Helper\Utils; use Woocommerce\Pagarme\Model\Config; @@ -32,6 +33,7 @@ public function run() { add_filter('woocommerce_checkout_init', array($this, 'enqueueScript')); add_filter('woocommerce_checkout_fields', array($this, 'addDocumentField')); + add_action('woocommerce_init', array($this, 'addDocumentFieldOnCheckoutBlocks')); add_action('woocommerce_checkout_process', array($this, 'validateDocument')); add_action( 'woocommerce_admin_order_data_after_billing_address', @@ -82,11 +84,14 @@ public function addDocumentField(array $fields): array } /** - * @throws \Exception + * @throws Exception */ public function addDocumentFieldOnCheckoutBlocks() { - if (!function_exists('woocommerce_register_additional_checkout_field')) { + if ( + $this->customerFields->hasCheckoutBlocksDocumentField() + || !function_exists('woocommerce_register_additional_checkout_field') + ) { return; } @@ -100,8 +105,8 @@ public function addDocumentFieldOnCheckoutBlocks() 'required' => true, 'index' => 25, 'show_in_order_confirmation' => true, - 'sanitize_callback' => function ($field_value) { - return str_replace(' ', '', $field_value); + 'validate_callback' => function ($documentNumber) { + return $this->customerFields->validateCheckoutBlocksDocument($documentNumber); }, ) ); @@ -109,61 +114,10 @@ public function addDocumentFieldOnCheckoutBlocks() /** * @return void - * @uses CustomerFields::isValidCnpj() - * @uses CustomerFields::isValidCpf() */ public function validateDocument() { - foreach ($this->customerFields::ADDRESS_TYPES as $addressType) { - $fieldName = "{$addressType}_document"; - $document = $_POST[$fieldName]; - - if (!$document) { - continue; - } - - $documentNumber = preg_replace('/\D/', '', $document); - $documentLength = strlen($documentNumber); - - if ($documentLength !== 11 && $documentLength !== 14) { - $errorMessage = sprintf( - __( - 'Please, enter a valid document number in the %s Document.', - 'woo-pagarme-payments' - ), - _x( - ucfirst($addressType), - 'checkout-document-error', - 'woo-pagarme-payments' - ) - ); - - wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); - continue; - } - - $documentType = $documentLength === 11 - ? $this->customerFields::DOCUMENT_TYPES[0] - : $this->customerFields::DOCUMENT_TYPES[1]; - $functionName = 'isValid' . ucfirst($documentType); - $isValidDocument = $this->customerFields->{$functionName}($documentNumber); - - if (!$isValidDocument) { - $errorMessage = sprintf( - __( - 'Please, enter a valid %s number in the %s Document.', - 'woo-pagarme-payments' - ), - strtoupper($documentType), - _x( - ucfirst($addressType), - 'checkout-document-error', - 'woo-pagarme-payments' - ) - ); - wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); - } - } + $this->customerFields->validateDocument(); } /** diff --git a/src/Controller/Checkout/CustomerFields.php b/src/Controller/Checkout/CustomerFields.php index 36ce8c49..b087bbb7 100644 --- a/src/Controller/Checkout/CustomerFields.php +++ b/src/Controller/Checkout/CustomerFields.php @@ -10,6 +10,13 @@ namespace Woocommerce\Pagarme\Controller\Checkout; +use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields; +use Automattic\WooCommerce\Blocks\Package; +use Exception; +use InvalidArgumentException; +use Woocommerce\Pagarme\Helper\Utils; +use WP_Error; + class CustomerFields { const ADDRESS_TYPES = [ @@ -21,6 +28,31 @@ class CustomerFields 'cnpj', ]; + /** + * @return bool + * @throws Exception + */ + public function hasCheckoutBlocksDocumentField() + { + $checkoutFields = Package::container()->get(CheckoutFields::class); + $possibleNames = array_merge( + self::DOCUMENT_TYPES, + [ + 'document' + ] + ); + + foreach ($possibleNames as $possibleName) { + $hasDocument = preg_grep("/{$possibleName}/", $checkoutFields->get_address_fields_keys()); + + if ($hasDocument) { + return true; + } + } + + return false; + } + /** * @param $fields * @@ -33,46 +65,157 @@ public function hasDocumentField($fields): bool } /** - * @param string $cpf + * @return void + */ + public function validateDocument() + { + foreach (self::ADDRESS_TYPES as $addressType) { + $fieldName = "{$addressType}_document"; + $document = $_POST[$fieldName]; + + if (!$document) { + continue; + } + + $documentNumber = preg_replace('/\D/', '', $document); + + if ($this->isValidDocumentLength($documentNumber)) { + $errorMessage = sprintf( + __( + 'Please, enter a valid document number in the %s Document.', + 'woo-pagarme-payments' + ), + _x( + ucfirst($addressType), + 'checkout-document-error', + 'woo-pagarme-payments' + ) + ); + + wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); + continue; + } + + if (!$this->isValidDocument($documentNumber)) { + $documentType = $this->getDocumentType($documentNumber); + $errorMessage = sprintf( + __( + 'Please, enter a valid %s number in the %s Document.', + 'woo-pagarme-payments' + ), + strtoupper($documentType), + _x( + ucfirst($addressType), + 'checkout-document-error', + 'woo-pagarme-payments' + ) + ); + wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); + } + } + } + + /** + * @param $documentNumber * * @return bool */ - public function isValidCpf(string $cpf): bool + private function isValidDocumentLength($documentNumber): bool { - if (!$this->isValidCpfFormat($cpf)) { - return false; - } + $documentLength = strlen($documentNumber); - for ($digit = 9; $digit < 11; $digit ++) { - if (!$this->isValidCpfDigit($cpf, $digit)) { - return false; - } + return $documentLength !== 11 && $documentLength !== 14; + } + + /** + * @param $documentNumber + * + * @return mixed + * @uses isValidCnpj() + * @uses isValidCpf() + */ + private function isValidDocument($documentNumber) + { + $documentType = $this->getDocumentType($documentNumber); + $functionName = $this->getDocumentValidationFunctionName($documentType); + + return $this->{$functionName}($documentNumber); + } + + /** + * @param $documentNumber + * + * @return string + */ + private function getDocumentType($documentNumber): string + { + return Utils::getDocumentType($documentNumber); + } + + /** + * @param string $documentType Must be one of the two values: `cpf` or `cnpj` + * + * @return string + */ + private function getDocumentValidationFunctionName(string $documentType): string + { + if ($documentType !== self::DOCUMENT_TYPES[0] && $documentType !== self::DOCUMENT_TYPES[1]) { + throw new InvalidArgumentException(); } - return true; + return 'isValid' . ucfirst($documentType); } /** - * @param string $cnpj + * @param $documentNumber * - * @return bool + * @return true|WP_Error */ - public function isValidCnpj(string $cnpj): bool + public function validateCheckoutBlocksDocument($documentNumber) { - if (!$this->isValidCnpjFormat($cnpj)) { - return false; + $documentNumber = preg_replace('/\D/', '', $documentNumber); + $errorCode = 'pagarme_invalid_document'; + + if ($this->isValidDocumentLength($documentNumber)) { + $errorMessage = __( + 'Please, enter a valid document number.', + 'woo-pagarme-payments' + ); + + return new WP_Error( + $errorCode, + $errorMessage + ); } - $firstCheckDigit = $this->calculateCnpjCheckDigit(substr($cnpj, 0, 12), 5); - if ($cnpj[12] != $firstCheckDigit) { - return false; + if (!$this->isValidDocument($documentNumber)) { + $documentType = $this->getDocumentType($documentNumber); + $errorMessage = sprintf( + __( + 'Please, enter a valid %s number.', + 'woo-pagarme-payments' + ), + strtoupper($documentType) + ); + + return new WP_Error( + $errorCode, + $errorMessage + ); } - $secondCheckDigit = $this->calculateCnpjCheckDigit(substr($cnpj, 0, 13), 6); + $wpError = new WP_Error(); + $wpError->remove($errorCode); - return $cnpj[13] == $secondCheckDigit; + return $wpError; } + /** + * @param $order + * @param $addressType + * + * @return void + */ public function displayDocumentOrderMeta($order, $addressType) { if (!$order) { @@ -109,6 +252,26 @@ private function getDocumentMetaNameByAddressType(string $addressType): string return "_{$addressType}_document"; } + /** + * @param string $cpf + * + * @return bool + */ + private function isValidCpf(string $cpf): bool + { + if (!$this->isValidCpfFormat($cpf)) { + return false; + } + + for ($digit = 9; $digit < 11; $digit ++) { + if (!$this->isValidCpfDigit($cpf, $digit)) { + return false; + } + } + + return true; + } + /** * @param string $cpf * @@ -152,6 +315,27 @@ private function calculateCpfDigit(string $cpf, int $digit): int return ($remainder === 10) ? 0 : $remainder; } + /** + * @param string $cnpj + * + * @return bool + */ + private function isValidCnpj(string $cnpj): bool + { + if (!$this->isValidCnpjFormat($cnpj)) { + return false; + } + + $firstCheckDigit = $this->calculateCnpjCheckDigit(substr($cnpj, 0, 12), 5); + if ($cnpj[12] != $firstCheckDigit) { + return false; + } + + $secondCheckDigit = $this->calculateCnpjCheckDigit(substr($cnpj, 0, 13), 6); + + return $cnpj[13] == $secondCheckDigit; + } + /** * @param string $cnpj * diff --git a/woo-pagarme-payments.php b/woo-pagarme-payments.php index 8bbd6aed..3561e7d6 100644 --- a/woo-pagarme-payments.php +++ b/woo-pagarme-payments.php @@ -325,7 +325,6 @@ function wcmpPluginsLoadedCheck() add_action('plugins_loaded', 'wcmpPluginsLoadedCheck', 0); add_action('before_woocommerce_init', 'checkCompatibilityWithFeatures', 0); add_action('woocommerce_blocks_loaded', 'addWoocommerceSupportedBlocks'); -add_action('woocommerce_blocks_loaded', 'addDocumentFieldOnCheckoutblocks'); function hasAnyBillingDocument($missingFields) { @@ -338,12 +337,6 @@ function hasAnyBillingDocument($missingFields) || ($hasDocument && (!$hasCpf || !$hasCnpj)); } -function addDocumentFieldOnCheckoutblocks() -{ - $checkoutFields = new CustomerFieldsActions(); - $checkoutFields->addDocumentFieldOnCheckoutBlocks(); -} - function checkCompatibilityWithFeatures() { $compatibilization = new FeatureCompatibilization(); From a50f53f6d2d33a59890f5841145c9a27dc04ff18 Mon Sep 17 00:00:00 2001 From: RafaMelazzo Date: Mon, 30 Sep 2024 13:55:35 -0300 Subject: [PATCH 10/12] refactor: checkout blocks document validation and removed dash url validation --- languages/woo-pagarme-payments-pt_BR.mo | Bin 41137 -> 40720 bytes languages/woo-pagarme-payments-pt_BR.po | 24 ++++--------- src/Action/CustomerFieldsActions.php | 23 +++++++++--- src/Controller/Checkout/CustomerFields.php | 26 ++++++++------ src/Controller/HubAccounts.php | 10 ------ src/Helper/Utils.php | 6 ++-- src/Service/CustomerService.php | 2 +- .../src/Middle/Model/Account.php | 33 ------------------ 8 files changed, 44 insertions(+), 80 deletions(-) diff --git a/languages/woo-pagarme-payments-pt_BR.mo b/languages/woo-pagarme-payments-pt_BR.mo index 5dbabcf4eeb3cd857728f51c624c2c08b0b28f52..49c935417885f0ce670a3c40c488dd5268b8deef 100644 GIT binary patch delta 5530 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 delta 5791 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 BhSvZ9 diff --git a/languages/woo-pagarme-payments-pt_BR.po b/languages/woo-pagarme-payments-pt_BR.po index 01ce14b5..43d4e39e 100644 --- a/languages/woo-pagarme-payments-pt_BR.po +++ b/languages/woo-pagarme-payments-pt_BR.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: WooCommerce Pagar.me Payments 1.0\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/woo-pagarme-payments\n" "POT-Creation-Date: 2018-06-22 13:58-0300\n" -"PO-Revision-Date: 2024-09-26 13:37-0300\n" +"PO-Revision-Date: 2024-09-30 12:07-0300\n" "Last-Translator: Pagar.me\n" "Language-Team: \n" "Language: pt_BR\n" @@ -1237,22 +1237,6 @@ msgstr "" "Sua conta está desativada na Dash da Pagar.me. Por favor, entre em contato com o nosso time de atendimento para " "habilitá-la." -#: src/Controller/HubAccounts.php:90 src/Controller/HubAccounts.php:96 -msgid "" -"No domain registered on Pagar.me Dash. Please enter your website's domain on the Dash to be able to process payment " -"in your store." -msgstr "" -"Nenhum domínio cadastrado na Dash da Pagar.me. Por favor, insira o domínio do seu site na Dash para poder processar o " -"pagamento em sua loja." - -#: src/Controller/HubAccounts.php:90 src/Controller/HubAccounts.php:96 -msgid "" -"The registered domain is different from the URL of your website. Please correct the domain configured on the Dash to " -"be able to process payment in your store." -msgstr "" -"O domínio cadastrado é diferente da URL do seu site. Por favor, corrija o domínio configurado na Dash para poder " -"processar o pagamento em sua loja." - msgid "" "Pix payment method is enabled on your store, but disabled on Pagar.me Dash. Please, access the Dash configurations " "and enable it to be able to process Pix payment on your store." @@ -1523,6 +1507,12 @@ msgctxt "checkout-document-error" msgid "Shipping" msgstr "envio" +msgid "Please, enter a valid document number." +msgstr "Por favor, digite um número de documento válido." + +msgid "Please, enter a valid %s number." +msgstr "Por favor, digite um número de %s válido." + msgid "Please, enter a valid document number in the %s Document." msgstr "Por favor, digite um número de documento válido no campo Documento de %s." diff --git a/src/Action/CustomerFieldsActions.php b/src/Action/CustomerFieldsActions.php index aa755749..b48a6bb7 100644 --- a/src/Action/CustomerFieldsActions.php +++ b/src/Action/CustomerFieldsActions.php @@ -14,6 +14,7 @@ use Woocommerce\Pagarme\Controller\Checkout\CustomerFields; use Woocommerce\Pagarme\Helper\Utils; use Woocommerce\Pagarme\Model\Config; +use WP_Error; defined('ABSPATH') || exit; @@ -33,8 +34,9 @@ public function run() { add_filter('woocommerce_checkout_init', array($this, 'enqueueScript')); add_filter('woocommerce_checkout_fields', array($this, 'addDocumentField')); - add_action('woocommerce_init', array($this, 'addDocumentFieldOnCheckoutBlocks')); add_action('woocommerce_checkout_process', array($this, 'validateDocument')); + add_action('woocommerce_init', array($this, 'addDocumentFieldOnCheckoutBlocks')); + add_action('woocommerce_validate_additional_field', array($this, 'validateCheckoutBlocksDocument'), 10, 3); add_action( 'woocommerce_admin_order_data_after_billing_address', array($this, 'displayBillingDocumentOrderMeta') @@ -104,10 +106,7 @@ public function addDocumentFieldOnCheckoutBlocks() 'class' => array('form-row-wide'), 'required' => true, 'index' => 25, - 'show_in_order_confirmation' => true, - 'validate_callback' => function ($documentNumber) { - return $this->customerFields->validateCheckoutBlocksDocument($documentNumber); - }, + 'show_in_order_confirmation' => true ) ); } @@ -120,6 +119,20 @@ public function validateDocument() $this->customerFields->validateDocument(); } + /** + * @param WP_Error $errors + * @param $fieldKey + * @param $documentNumber + * + * @return void + */ + public function validateCheckoutBlocksDocument(WP_Error $errors, $fieldKey, $documentNumber) + { + if ($fieldKey == 'address/document') { + $this->customerFields->validateCheckoutBlocksDocument($errors, $documentNumber); + } + } + /** * @param $order * diff --git a/src/Controller/Checkout/CustomerFields.php b/src/Controller/Checkout/CustomerFields.php index b087bbb7..2bf63961 100644 --- a/src/Controller/Checkout/CustomerFields.php +++ b/src/Controller/Checkout/CustomerFields.php @@ -79,7 +79,7 @@ public function validateDocument() $documentNumber = preg_replace('/\D/', '', $document); - if ($this->isValidDocumentLength($documentNumber)) { + if (!$this->isValidDocumentLength($documentNumber)) { $errorMessage = sprintf( __( 'Please, enter a valid document number in the %s Document.', @@ -124,7 +124,7 @@ private function isValidDocumentLength($documentNumber): bool { $documentLength = strlen($documentNumber); - return $documentLength !== 11 && $documentLength !== 14; + return $documentLength === 11 || $documentLength === 14; } /** @@ -149,7 +149,7 @@ private function isValidDocument($documentNumber) */ private function getDocumentType($documentNumber): string { - return Utils::getDocumentType($documentNumber); + return Utils::getDocumentTypeByDocumentNumber($documentNumber); } /** @@ -167,25 +167,28 @@ private function getDocumentValidationFunctionName(string $documentType): string } /** + * @param WP_Error $errors * @param $documentNumber * - * @return true|WP_Error + * @return WP_Error */ - public function validateCheckoutBlocksDocument($documentNumber) + public function validateCheckoutBlocksDocument(WP_Error $errors, $documentNumber) { $documentNumber = preg_replace('/\D/', '', $documentNumber); $errorCode = 'pagarme_invalid_document'; - if ($this->isValidDocumentLength($documentNumber)) { + if (!$this->isValidDocumentLength($documentNumber)) { $errorMessage = __( 'Please, enter a valid document number.', 'woo-pagarme-payments' ); - return new WP_Error( + $errors->add( $errorCode, $errorMessage ); + + return $errors; } if (!$this->isValidDocument($documentNumber)) { @@ -198,16 +201,17 @@ public function validateCheckoutBlocksDocument($documentNumber) strtoupper($documentType) ); - return new WP_Error( + $errors->add( $errorCode, $errorMessage ); + + return $errors; } - $wpError = new WP_Error(); - $wpError->remove($errorCode); + $errors->remove($errorCode); - return $wpError; + return $errors; } /** diff --git a/src/Controller/HubAccounts.php b/src/Controller/HubAccounts.php index 178c19e0..a1cffbe5 100644 --- a/src/Controller/HubAccounts.php +++ b/src/Controller/HubAccounts.php @@ -171,16 +171,6 @@ private function getHubAccountErrorsNotices() $noticesList = [ Account::ACCOUNT_DISABLED => 'Your account is disabled on Pagar.me Dash. ' . 'Please, contact our support team to enable it.', - Account::DOMAIN_EMPTY => [ - 'message' => 'No domain registered on Pagar.me Dash. Please enter your website\'s domain on the Dash ' - . 'to be able to process payment in your store.', - 'buttons' => $this->getHubNoticeButtons('account-config') - ], - Account::DOMAIN_INCORRECT => [ - 'message' => 'The registered domain is different from the URL of your website. Please correct the ' - . 'domain configured on the Dash to be able to process payment in your store.', - 'buttons' => $this->getHubNoticeButtons('account-config') - ], Account::WEBHOOK_INCORRECT => [ 'message' => 'The URL for receiving webhook registered in Pagar.me Dash is different from the URL of ' . 'your website. Please, click the button below to access the Hub and click the Delete > Confirm ' diff --git a/src/Helper/Utils.php b/src/Helper/Utils.php index 6c9ba04e..a0cebd39 100644 --- a/src/Helper/Utils.php +++ b/src/Helper/Utils.php @@ -505,7 +505,7 @@ public static function build_document_from_order(Order $order) if (!empty($order->get_meta('billing_document'))) { $document = $order->get_meta('billing_document'); - $documentType = self::getCustomerType($document); + $documentType = self::getCustomerTypeByDocumentNumber($document); return array( 'type' => $documentType, 'value' => $document, @@ -518,13 +518,13 @@ public static function build_document_from_order(Order $order) ); } - public static function getCustomerType($document): string + public static function getCustomerTypeByDocumentNumber($document): string { $documentNumber = preg_replace('/\D/', '', $document ?? ''); return strlen($documentNumber) === 14 ? 'company' : 'individual'; } - public static function getDocumentType($document): string + public static function getDocumentTypeByDocumentNumber($document): string { $documentNumber = preg_replace('/\D/', '', $document ?? ''); return strlen($documentNumber) === 14 ? 'cnpj' : 'cpf'; diff --git a/src/Service/CustomerService.php b/src/Service/CustomerService.php index 0d2ea65c..e04ed5cc 100644 --- a/src/Service/CustomerService.php +++ b/src/Service/CustomerService.php @@ -85,7 +85,7 @@ public function extractCustomerDataByWcOrder($wcOrder) 'email' => $billingData['email'], 'name' => $billingData['first_name'] . ' ' . $billingData['last_name'], 'document' => $document, - 'document_type' => Utils::getDocumentType($document), + 'document_type' => Utils::getDocumentTypeByDocumentNumber($document), 'home_phone' => $billingData['phone'], 'mobile_phone' => $wcOrder->get_meta('_billing_cellphone'), 'street' => $billingData['street'], diff --git a/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Account.php b/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Account.php index b4f61292..6bcedd5f 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Account.php +++ b/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Account.php @@ -11,10 +11,6 @@ class Account extends ModelWithErrors { const ACCOUNT_DISABLED = 'accountDisabled'; - const DOMAIN_EMPTY = 'domainEmpty'; - - const DOMAIN_INCORRECT = 'domainIncorrect'; - const WEBHOOK_INCORRECT = 'webhookIncorrect'; const MULTIPAYMENTS_DISABLED = 'multiPaymentsDisabled'; @@ -242,7 +238,6 @@ public function setDebitCardSettings($debitCardSettings) public function validate($storeSettings = null) { $this->validateAccountEnabled(); - $this->validateDomain($storeSettings); $this->validateWebhooks($storeSettings); $this->validateMultiBuyer(); $this->validateMultiPayments(); @@ -265,34 +260,6 @@ private function validateAccountEnabled() } } - /** - * @param StoreSettings|null $storeSettings - * @return void - */ - private function validateDomain($storeSettings = null) - { - $domains = $this->getDomains(); - if (empty($domains) && (empty($storeSettings) || !$storeSettings->isSandbox())) { - $this->addError(self::DOMAIN_EMPTY); - return; - } - - if ($this->canNotValidateUrlSetting($storeSettings)) { - return; - } - - $siteUrls = $storeSettings->getStoreUrls(); - foreach ($domains as $domain) { - foreach ($siteUrls as $siteUrl) { - if (strpos($siteUrl, $domain) !== false) { - return; - } - } - } - - $this->addError(self::DOMAIN_INCORRECT); - } - /** * @param StoreSettings|null $storeSettings * @return void From 903f1b23ff020e4842060e56b08fa45bc4e5648c Mon Sep 17 00:00:00 2001 From: RafaMelazzo Date: Wed, 2 Oct 2024 11:10:56 -0300 Subject: [PATCH 11/12] fix: sending document on checkout blocks --- .../front/checkout/checkoutFields.js | 4 +- src/Helper/Utils.php | 38 ++++++++----------- src/Model/Payment/PostFormatter.php | 2 - woo-pagarme-payments.php | 4 -- 4 files changed, 18 insertions(+), 30 deletions(-) diff --git a/assets/javascripts/front/checkout/checkoutFields.js b/assets/javascripts/front/checkout/checkoutFields.js index 6eab8876..5db98f11 100644 --- a/assets/javascripts/front/checkout/checkoutFields.js +++ b/assets/javascripts/front/checkout/checkoutFields.js @@ -7,7 +7,7 @@ const pagarmeCustomerFields = { blocksShippingDocumentId: 'shipping-address-document', documentMasks: [ - '000.000.000-00999', + '000.000.000-009999', '00.000.000/0000-00' ], documentMaskOptions: { @@ -51,7 +51,7 @@ const pagarmeCustomerFields = { setTimeout(function() { pagarmeCustomerFields.applyDocumentMask(); - }, 2000); + }, 5000); } }; diff --git a/src/Helper/Utils.php b/src/Helper/Utils.php index a0cebd39..776103c0 100644 --- a/src/Helper/Utils.php +++ b/src/Helper/Utils.php @@ -487,34 +487,28 @@ public static function build_customer_address_from_order(Order $order) * * @return array|string[] */ - public static function build_document_from_order(Order $order) + public static function build_document_from_order(Order $order): array { - if (!empty($order->get_meta('billing_cpf'))) { - return array( - 'type' => 'individual', - 'value' => $order->get_meta('billing_cpf'), - ); - } - - if (!empty($order->get_meta('billing_cnpj'))) { - return array( - 'type' => 'company', - 'value' => $order->get_meta('billing_cnpj'), - ); - } + $documentFields = [ + 'billing_cpf', + 'billing_cnpj', + 'billing_document', + 'wc_billing/address/document' + ]; - if (!empty($order->get_meta('billing_document'))) { - $document = $order->get_meta('billing_document'); - $documentType = self::getCustomerTypeByDocumentNumber($document); - return array( - 'type' => $documentType, - 'value' => $document, - ); + foreach ($documentFields as $field) { + if (!empty($order->get_meta($field))) { + $document = $order->get_meta($field); + return [ + 'type' => self::getCustomerTypeByDocumentNumber($document), + 'value' => $document + ]; + } } return array( 'type' => '', - 'value' => '', + 'value' => '' ); } diff --git a/src/Model/Payment/PostFormatter.php b/src/Model/Payment/PostFormatter.php index f5479a01..a914fff8 100644 --- a/src/Model/Payment/PostFormatter.php +++ b/src/Model/Payment/PostFormatter.php @@ -96,8 +96,6 @@ public function assemblePaymentRequest() public function formatReactCheckout() { if (!empty($_POST['pagarme']) && is_string($_POST['pagarme'])) { - $_POST['billing_document'] = $_POST['address/document']; - $_POST['shipping_document'] = $_POST['address/document']; $_POST['pagarme'] = json_decode($_POST['pagarme'], true); } } diff --git a/woo-pagarme-payments.php b/woo-pagarme-payments.php index 3561e7d6..dbf94a4c 100644 --- a/woo-pagarme-payments.php +++ b/woo-pagarme-payments.php @@ -218,10 +218,6 @@ function wcmpAdminNoticeCheckoutFields() return; } - if (!class_exists('WC_Session')) { - include_once WP_PLUGIN_DIR . '/woocommerce/includes/abstracts/abstract-wc-session.php'; - } - WC()->session = new WC_Session_Handler; WC()->customer = new WC_Customer; $billingFields = WC()->checkout->get_checkout_fields()['billing']; From da0fd22c38650f95d5fcdee9a91c823c3c71c442 Mon Sep 17 00:00:00 2001 From: RafaMelazzo Date: Wed, 2 Oct 2024 14:01:40 -0300 Subject: [PATCH 12/12] refactor: getDocumentValidationFunctionName condition --- src/Controller/Checkout/CustomerFields.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/Checkout/CustomerFields.php b/src/Controller/Checkout/CustomerFields.php index 2bf63961..f99990c1 100644 --- a/src/Controller/Checkout/CustomerFields.php +++ b/src/Controller/Checkout/CustomerFields.php @@ -159,7 +159,7 @@ private function getDocumentType($documentNumber): string */ private function getDocumentValidationFunctionName(string $documentType): string { - if ($documentType !== self::DOCUMENT_TYPES[0] && $documentType !== self::DOCUMENT_TYPES[1]) { + if (in_array($documentType, self::ADDRESS_TYPES, true)) { throw new InvalidArgumentException(); }