Question

I'm trying to update customers right after they register on the platform but I'm having some difficulties saving the data.

What I'm trying to do is to add customers to groups based on their country, and also creating a new address for them and set it as the default shipping and billing address. The issue I am seeing is that I cannot save both things at the same time, is one or the other, depending on which one is saved second.

If I update the group id and save the customer, then create the address, only the address will show up in the admin. If I do it in reverse order, add the address on customer and then save customer group id, I will only see the group ID in the admin, note that the address will save on the customer, only that is not set as the default shipping and billing address.

I'm not sure if I'm missing anything related to Repository Interfaces and how these work, or if there's anything I'm doing wrong.

So you all know, I also tried using two different events, customer_register_success and customer_save_after, but the outcome was the same as using only one event, nothing different whatsoever.

Here's how the customers look in the admin after saving them.

enter image description here

This is for the customer I saved the address first, and then the group ID.

enter image description here

Here's the XML Event

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="customer_register_success">
        <observer instance="DryRun\Various\Observer\Customer\RegisterSuccess" name="dryrun_various_observer_customer_registersuccess_customer_register_success"/>
    </event>
</config>

Here's the Observer

<?php
/**
 * Copyright ©  All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace DryRun\Various\Observer\Customer;

class RegisterSuccess implements \Magento\Framework\Event\ObserverInterface
{
    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $scopeConfig;
    
    /**
     * @var \Magento\Customer\Api\CustomerRepositoryInterface
     */
    protected $customerRepository;
    
    /**
     * @var \Magento\Customer\Model\GroupFactory
     */
    protected $customerGroupFactory;
    
    /**
     * @var \Magento\Customer\Api\AddressRepositoryInterface
     */
    protected $addressRepository;
    
    /**
     * @var \Magento\Customer\Api\Data\AddressInterfaceFactory
     */
    protected $addressDataFactory;
    
    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;
    
    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Customer\Model\GroupFactory $customerGroupFactory,
        \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
        \Magento\Customer\Api\AddressRepositoryInterface $addressRepository,
        \Magento\Customer\Api\Data\AddressInterfaceFactory $addressDataFactory,
        \Psr\Log\LoggerInterface $logger 
    ) {
        $this->scopeConfig = $scopeConfig;
        $this->customerRepository = $customerRepository;
        $this->customerGroupFactory = $customerGroupFactory;
        $this->addressRepository = $addressRepository;
        $this->addressDataFactory = $addressDataFactory;
        $this->logger = $logger;  
    }
    
    /**
     * Execute observer
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(
        \Magento\Framework\Event\Observer $observer
    ) {
        $customer = $observer->getCustomer();
        
        if(!$customer->getId()) {
            return;
        }
            
        $accountController = $observer->getAccountController();
        $countryId = $accountController->getRequest()->getParam("country_id");
        
        $this->createCustomerAddress($customer, $countryId);
        $this->assignCustomerToGroup($customer, $countryId);
    }
    
    
    public function assignCustomerToGroup($customer, $countryId) {

        try {

            $EUCountries = $this->scopeConfig->getValue('general/country/eu_countries', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
            $EUCountries = explode(',', $EUCountries);
            
            if (in_array($countryId, $EUCountries)) {
                if ($countryId === 'GB') {
                    $targetGroup = 10; // 'Customer in -GB-';
                } else {
                    $targetGroup = 8; // 'Consumer B2C (inside EU)';
                }
            } else {
                $targetGroup = 9; // 'General Customer (outside EU)';
            }
            
            $customer->setGroupId($targetGroup);
            $this->customerRepository->save($customer);
            
        } catch (Exception $e) { 
            $this->logger->debug("ERROR adding customer to group: " . $e->getMessage());
        }
    }
    
    public function createCustomerAddress($customer, $countryID){

        try{
            
            $address = $this->addressDataFactory->create();
            $address->setFirstname($customer->getFirstname())
                ->setLastname($customer->getLastname())
                ->setStreet(array("0" => "-", "1" => "-"))
                ->setCity("-")
                ->setPostcode("0000 00")
                ->setTelephone("-")
                ->setCountryId($countryID)
                ->setCustomerId($customer->getId())
                ->setIsDefaultBilling("1")
                ->setIsDefaultShipping("1")
                // ->setSaveInAddressBook("1") # Call to undefined method Magento\Customer\Model\Data\Address::setSaveInAddressBook()
                ;
                
            $this->addressRepository->save($address);
        }
        catch(Exception $e){
            $this->logger->debug("ERROR adding customer address: " . $e->getMessage());
        }
    }
}

Any suggestions are appreciated, thanks!

Was it helpful?

Solution

Good news, I was able to find a solution to this. But still, the solution does not provide any answers to why it wasn't working before. So if you have a reason for this, post it - I'm sure we all can learn from it.

What I had to do was to save the address a second time with setIsDefaultBilling("1") and setIsDefaultShipping("1")

So the flow is this:

  • create address and add to customer
  • update customer (add to group)
  • save address again
<?php
/**
 * Copyright ©  All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace DryRun\Various\Observer\Customer;

class RegisterSuccess implements \Magento\Framework\Event\ObserverInterface
{
    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $scopeConfig;
    
    /**
     * @var \Magento\Customer\Api\CustomerRepositoryInterface
     */
    protected $customerRepository;
    
    /**
     * @var \Magento\Customer\Model\GroupFactory
     */
    protected $customerGroupFactory;
    
    /**
     * @var \Magento\Customer\Api\AddressRepositoryInterface
     */
    protected $addressRepository;
    
    /**
     * @var \Magento\Customer\Api\Data\AddressInterfaceFactory
     */
    protected $addressDataFactory;
    
    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;
    
    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Customer\Model\GroupFactory $customerGroupFactory,
        \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
        \Magento\Customer\Api\AddressRepositoryInterface $addressRepository,
        \Magento\Customer\Api\Data\AddressInterfaceFactory $addressDataFactory,
        \Psr\Log\LoggerInterface $logger 
    ) {
        $this->scopeConfig = $scopeConfig;
        $this->customerRepository = $customerRepository;
        $this->customerGroupFactory = $customerGroupFactory;
        $this->addressRepository = $addressRepository;
        $this->addressDataFactory = $addressDataFactory;
        $this->logger = $logger;  
    }
    
    /**
     * Execute observer
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(
        \Magento\Framework\Event\Observer $observer
    ) {
        $customer = $observer->getCustomer();
        
        if(!$customer->getId()) {
            return;
        }
            
        $accountController = $observer->getAccountController();
        $countryId = $accountController->getRequest()->getParam("country_id");
        
        $address = $this->createCustomerAddress($customer, $countryId);
        $this->assignCustomerToGroup($customer, $countryId);

        ## NEW
        $this->setDefaultAddress($address);
    }
    
    
    public function assignCustomerToGroup($customer, $countryId) {

        try {

            $EUCountries = $this->scopeConfig->getValue('general/country/eu_countries', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
            $EUCountries = explode(',', $EUCountries);
            
            if (in_array($countryId, $EUCountries)) {
                if ($countryId === 'GB') {
                    $targetGroup = 10; // 'Customer in -GB-';
                } else {
                    $targetGroup = 8; // 'Consumer B2C (inside EU)';
                }
            } else {
                $targetGroup = 9; // 'General Customer (outside EU)';
            }
            
            $customer->setGroupId($targetGroup);
            $this->customerRepository->save($customer);
            
        } catch (Exception $e) { 
            $this->logger->debug("ERROR adding customer to group: " . $e->getMessage());
        }
    }
    
    public function createCustomerAddress($customer, $countryID){

        try{
            
            $address = $this->addressDataFactory->create();
            $address->setFirstname($customer->getFirstname())
                ->setLastname($customer->getLastname())
                ->setStreet(array("0" => "-", "1" => "-"))
                ->setCity("-")
                ->setPostcode("0000 00")
                ->setTelephone("-")
                ->setCountryId($countryID)
                ->setCustomerId($customer->getId())
                ->setIsDefaultBilling("1")
                ->setIsDefaultShipping("1")
                // ->setSaveInAddressBook("1") # Call to undefined method Magento\Customer\Model\Data\Address::setSaveInAddressBook()
                ;
                
            return $this->addressRepository->save($address);
        }
        catch(Exception $e){
            $this->logger->debug("ERROR adding customer address: " . $e->getMessage());
        }
    }
    
    ## NEW
    public function setDefaultAddress($address) {
        
        $address->setIsDefaultBilling("1")
                ->setIsDefaultShipping("1");
                
        $this->addressRepository->save($address);
    }**
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top