1

We have installed B2B Module and we want to display company shipping address instead of customer default shipping address. The customer is associate with this company. Ex: Company admin has own email: [email protected] user type is company admin Customer has own email: [email protected] user type is company user

Any one provide solution

4
  • Have you found any solutions ?
    – Ahmed Atef
    Mar 27, 2022 at 20:57
  • still i not found any solution
    – Vishal
    Mar 28, 2022 at 6:40
  • Company doesn't have shipping address (Legal address is not shipping address). My workaround is to add all shipping addresses to the company administrator and added a plugin to CustomerInterface to return all admin addresses, default shipping address Id and default billing address id to all Company users. so All company customers can place order using company admin shipping addresses and it worked. I can share the solution if you want
    – Ahmed Atef
    Mar 31, 2022 at 10:05
  • Please share your solution
    – Vishal
    Apr 1, 2022 at 17:48

1 Answer 1

1

Well, Since Company doesn't have address entities, I have moved all needed shipping addresses for the company under the company administrator customer id, and override getAdresses() Method of other company users to return the company admin.

define CustomerInterfacePlugin in etc/di.xml

<type name="Magento\Customer\Api\Data\CustomerInterface">
    <plugin name="replace_customer_addresses_with_company_admin_address"
            type="Vendor\Module\Plugin\CustomerInterfacePlugin"
            disabled="false"
            />
</type>

Override needed methods

use Magento\Company\Api\CompanyManagementInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;

class CustomerInterfacePlugin
{
    protected $companyRepository;
    protected $customerRepository;
    public function __construct(
        CompanyManagementInterface $companyRepository,
        CustomerRepositoryInterface $customerRepository
    )
    {
        $this->companyRepository = $companyRepository;
        $this->customerRepository = $customerRepository;
    }

    public function aroundGetAddresses(
        \Magento\Customer\Api\Data\CustomerInterface $customer,
        \closure $proceed
    ){
        // customer id not yet created
        if(!$customer->getId())
            return $proceed();

        $company = $this->companyRepository->getByCustomerId($customer->getId());
        if($company){
            $superCustomer = $this->customerRepository->getById($company->getSuperUserId());
            // if same customer id proceed else return super customer addresses
            if($superCustomer->getId() != $customer->getId())
                return $superCustomer->getAddresses();
        }
        return $proceed();
    }
    public function aroundGetDefaultShipping(
        \Magento\Customer\Api\Data\CustomerInterface $customer,
        \closure $proceed
    ){
        // customer id not yet created
        if(!$customer->getId())
            return $proceed();

        $company = $this->companyRepository->getByCustomerId($customer->getId());
        if($company){
            $superCustomer = $this->customerRepository->getById($company->getSuperUserId());
            // if same customer id proceed else return super customer addresses
            if($superCustomer->getId() != $customer->getId())
                return $superCustomer->getDefaultShipping();
        }
        return $proceed();
    }
    public function aroundGetDefaultBilling(
        \Magento\Customer\Api\Data\CustomerInterface $customer,
        \closure $proceed
    ){
        // customer id not yet created
        if(!$customer->getId())
            return $proceed();

        $company = $this->companyRepository->getByCustomerId($customer->getId());
        if($company){
            $superCustomer = $this->customerRepository->getById($company->getSuperUserId());
            // if same customer id proceed else return super customer addresses
            if($superCustomer->getId() != $customer->getId())
                return $superCustomer->getDefaultBilling();
        }
        return $proceed();
    }

}

The above plugin will return all addresses from company super user to all company users, also will return default billing and default shipping address from company super user. If any company user has logged in and tried to checkout he will be able to use any one of company super user addresses, but he will face a validation issue in the last step Provided customer ID "%customer_id" isn't related to current customer address so we have to override validation method also. add validator plugin to etc/di.xml

 <type name="Magento\Customer\Model\Address\Validator\Customer">
    <plugin name="replace_customer_validation_with_company_admin_address"
            type="Vendor\Module\Plugin\Address\Validator\CustomerPlugin"
            disabled="false"
            />
</type>

override validate method in Vendor/Module/Plugin/Address/Validator/CustomerPlugin.php


use Magento\Company\Api\CompanyManagementInterface;
use Magento\Customer\Model\Address\AbstractAddress;
use Magento\Customer\Model\AddressFactory;
use Magento\Quote\Api\Data\AddressInterface as QuoteAddressInterface;

class CustomerPlugin
{
    /**
     * @var AddressFactory
     */
    private $addressFactory;
    private $companyManagement;

    /**
     * @param AddressFactory $addressFactory
     */
    public function __construct(
        AddressFactory $addressFactory,
        CompanyManagementInterface $companyManagement
    )
    {
        $this->addressFactory = $addressFactory;
        $this->companyManagement = $companyManagement;
    }
    public function aroundValidate(
        \Magento\Customer\Model\Address\Validator\Customer $subject,
        \closure $proceed,
        AbstractAddress $address
    )
    {
        $errors = [];
        $addressId = $address instanceof QuoteAddressInterface ? $address->getCustomerAddressId() : $address->getId();
        if ($addressId !== null) {
            $addressCustomerId = (int)$address->getCustomerId();
            // may return company administrator admin id
            $originalAddressCustomerId = (int)$this->addressFactory->create()
                ->load($addressId)
                ->getCustomerId();
            if ($originalAddressCustomerId !== 0 && $originalAddressCustomerId !== $addressCustomerId) {
                $company = $this->companyManagement->getByCustomerId($addressCustomerId);
                if(!$company || ($company->getSuperUserId() != $originalAddressCustomerId) ){
                    $errors[] = __(
                        'Provided customer ID "%customer_id" isn\'t related to current customer address.',
                        ['customer_id' => $addressCustomerId]
                    );
                }
            }
        }
        return $errors;
    }
}

and that's it, Company users should be able to select any shipping addresses from company super user during checkout without any problem.

4
  • Very rightly covered Ahmed. May 31, 2023 at 12:55
  • I am getting issue as Invalid method Magento\Customer\Model\Address::isDefaultShipping. Any idea about this @Ahmed Atef?
    – aravind
    Jun 6, 2023 at 14:59
  • @aravind the method is getDefaultShipping not isDefaultShipping
    – Ahmed Atef
    Jun 7, 2023 at 7:24
  • @AhmedAtef Everything seems to be working but when I tried to login/forgot password for its subuser - parent address id gets updated and causing the issue
    – aravind
    Jun 13, 2023 at 13:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.