Jump to content

[PS 8.1.1] Custom fields in Customer Address Form


Recommended Posts

Hi guys, this is my first post. So, please, be kindly :D

However, i 'm building a new ecommerce with latest PS 8.1.1. 

I'm in Italy, so i have to add two string fields (PEC and SDI) to address form. In past i integrated those fields with some custom override, but i don't like that solution. So, this time i started to build a custom module for this purpose. And, for backoffice, works like a charme as you can see in the below image.
image.thumb.png.71c781f3900177d5a38a8cc6a5ae7f0b.png

I used ObjectModel with CQRS Pattern. My module creates a new table in DB, 1 to 1 with customeraddress table, where to store values.

I used this 3 hooks:
1. actionCustomerAddressFormBuilderModifier (to edit the form)
2. actionAfterCreateCustomerAddressFormHandler (to save values on create address)
3. actionAfterUpdateCustomerAddressFormHandler (to update values on update address)

 

So, all great... but the fields are add only in backoffice form.
In frontend, i don't have the fields:
image.thumb.png.2c663fc358349a5277c91277598a7435.png

All the cache are disabled, however i clean them several times. Maybe i have to use another - specific - hook?
But, in official documentation, i read this:
image.thumb.png.26115df2c795348b3b71d97059e12538.png
 

What am I doing wrong? 

It is possible integrate some custom fields without any core modifications or overrides? Will could I add this fields in invoice, modifying only the template?
It is very frustrating can't add custom fields in a more easy way... this would be a native features in my opinion.

Link to comment
Share on other sites

[UPDATE]

Yes, it necessary use "AdditionalCustomerAddressFields" hook, to add fields in front office. 

Now, I'm trying to add a simple validation, using "ActionValidateCustomerAddressForm":

public function hookActionValidateCustomerAddressForm(array $params){
        $ret = 1;

        $sdi = Tools::getValue('sdi') ?? null;
        $pec = Tools::getValue('pec') ?? null;

        if($sdi && strlen($sdi) != 7 ){
            $ret = 0;
        }

        if($pec && !filter_var($pec, FILTER_VALIDATE_EMAIL)){
            $ret = 0;
        }

        return $ret;

    }

I return an integer value (and not boolean) 'cause Hook::exec native call, convert return into string. "false" value is converted into an empty string and this is interpreted as "not errors". 


So, now, the sent form fail if validation fail, but I don't know how to add error status to fields:
image.thumb.png.fc331e8e2b2e36bbfaa8088188eb80a2.png

Link to comment
Share on other sites

15 hours ago, endriu107 said:

It should be something like: 

$this->error[] = $this->l('something went wrong.');

Hi endriu107 and thank you. I solved using Context for "top error messages":
 

$context = Context::getContext();
$context->controller->errors[] = $this->l('Il codice SDI deve essere di 7 caratteri o numeri. Se non sei sicuro o non ne possiedi uno, lascia il campo vuoto');

But this don't higlight the field. To do that, i used addError method to field. But the field is declared into another method (another hook). So is necessary assign the field in a class attribute, to access it in other methods:

 

<?php
/**
 * Class MC_FatturaElettronica
 */
class MC_FatturaElettronica extends Module
{
    /**
     * @var Connection
     */
    private $connection;

    private $field_sdi;
    private $field_pec;


[...]

	/* THIS HOOK STARTS IN FORM RENDERING */
	public function hookAdditionalCustomerAddressFields(array $params){
        $sdi = "";
        $pec = "";
        if ($addressId = Tools::getValue('id_address')) {
            $result = $this->getSdiPecFromDB($addressId);
            if($result){
                $sdi = $result['sdi'];
                $pec = $result['pec'];
            }
        }
        if(!$this->field_sdi){
            $this->field_sdi = (new FormField())
                ->setName("sdi")
                ->setLabel("SDI")
                ->setRequired(false)
                ->setType('text');
        }
        if(!$this->field_pec){
            $this->field_pec = (new FormField())
                ->setName("pec")
                ->setLabel("PEC")
                ->setRequired(false)
                ->setType('text');
        }
        return [
            $this->field_sdi->setValue($sdi),
            $this->field_pec->setValue($pec),
        ];
    }

public function hookActionValidateCustomerAddressForm(array $params){
        $ret = 1;
        $context = Context::getContext();
        $sdi = Tools::getValue('sdi') ?? null;
        $pec = Tools::getValue('pec') ?? null;
        if($sdi && strlen($sdi) != 7 ){
            $ret = 0;
            //$context->controller->errors[] = $this->l('Il codice SDI deve essere di 7 caratteri o numeri. Se non sei sicuro o non ne possiedi uno, lascia il campo vuoto');
            $this->field_sdi->addError(
                $context->getTranslator()->trans(
                    'Il codice SDI deve essere di 7 caratteri o numeri. Se non sei sicuro o non ne possiedi uno, lascia il campo vuoto',
                    [],
                    'Shop.Forms.Errors'
                )
            );
        }
        if($pec && !Validate::isEmail($pec)){
            $ret = 0;
            //$context->controller->errors[] = $this->l('L\'indirizzo PEC non sembra essere corretto.');
            $this->field_pec->addError(
                $context->getTranslator()->trans(
                    'L\'indirizzo PEC non sembra essere corretto.',
                    [],
                    'Shop.Forms.Errors'
                )
            );
        }
        return $ret;
    }

[...]
	
Link to comment
Share on other sites

 

I give up! After a few days of development... I see that it is impossible to add some fields to the customer address without overrides.
This is because (in 2023) all the necessary hooks are still missing. For example, I'm missing the hooks to add my custom fields in the address format:
 

image.thumb.png.1cc090eb5727c4768fb74e7c0114d7d0.png

I tried adding the fields with some code, but it requires editing some core files. So, it's more efficient to override the address class and add the fields directly into the address table... very frustrating for a developer.

Anyway, if anyone have a better solution, I'm here.

Thanks

  • Like 1
Link to comment
Share on other sites

  • 10 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...