I want to Create a new address type "neighbors address / alternate address
" . To assign it to customer i have created new customer attribute ( just like "default_shipping
" and "default_billing
" ) "alternate_address
" and saved address_id
against it . But how to integrate it with Quote and order . They only save a string "shipping or billing" in address_type
column . Where i would like to have it as alternate
Magento 2.2 – Add New Address Type to Customer
customer-addressmagento2.2quotesales-order
Related Solutions
First of all I want to say that the address_type
is not used for customer addresses. It is used only for quote and order addresses, so there is no need to use that in order to flag your own address type.
if you need to retrieve only your store finder addresses I have an idea, but later on that.
First, you will need to create a new module to handle your new address type in order not to change the core code.
Let's call this module StackExchange_Storefinder
.
You will need the following files:
app/etc/modules/StackExchange_Storefinder.xml
- the declaration file:
<?xml version="1.0"?>
<config>
<modules>
<StackExchange_Storefinder>
<codePool>local</codePool>
<active>true</active>
<depends>
<Mage_Customer />
<Mage_Adminhtml />
</depends>
</StackExchange_Storefinder>
</modules>
</config>
app/code/local/StackExchange_Storefinder/etc/config.xml
- the configuration file
<?xml version="1.0"?>
<config>
<modules>
<StackExchange_Storefinder>
<version>1.0.0</version>
</StackExchange_Storefinder>
</modules>
<global>
<resources>
<stackexchange_storefinder_setup>
<setup>
<module>StackExchange_Storefinder</module>
<class>Mage_Customer_Model_Resource_Setup</class>
</setup>
</stackexchange_storefinder_setup>
</resources>
<models>
<stackexchange_storefinder>
<class>StackExchange_Storefinder_Model</class>
</stackexchange_storefinder>
</models>
<helpers>
<stackexchange_storefinder>
<class>StackExchange_Storefinder_Helper</class>
</stackexchange_storefinder>
</helpers>
<blocks>
<stackexchange_storefinder>
<class>StackExchange_Storefinder_Block</class>
</stackexchange_storefinder>
<adminhtml>
<rewrite>
<customer_edit_tab_addresses>Stackexchange_Storefinder_Block_Adminhtml_Customer_Edit_Tab_Addresses</customer_edit_tab_addresses>
</rewrite>
</adminhtml>
</blocks>
</global>
<adminhtml>
<events>
<adminhtml_customer_prepare_save>
<observers>
<stackexchange_storefinder>
<class>stackexchange_storefinder/adminhtml_observer</class>
<method>checkStoreFinderAddress</method>
</stackexchange_storefinder>
</observers>
</adminhtml_customer_prepare_save>
</events>
</adminhtml>
</config>
app/code/local/StackExchange/Storefinder/sql/stackexchange_storefinder_setup/install-1.0.0.php
- the install script that adds a new customer attribute to store the store finder address id (just like billing and shipping).
<?php
/** @var Mage_Customer_Model_Resource_Setup $this */
$this->addAttribute(
'customer',
'default_store_finder_id',
array(
'type' => 'int',
'label' => 'Default Store Finder Address',
'input' => 'text',
'backend' => 'stackexchange_storefinder/customer_attribute_backend_storefinder',
'required' => false,
'sort_order' => 82,
'visible' => false,
)
);
app/code/local/StackExchange/Storefinder/Model/Customer/Attribute/Backend/Storefinder.php
- the backend model of the store finder attribute:
<?php
class StackExchange_Storefinder_Model_Customer_Attribute_Backend_Storefinder extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract
{
public function beforeSave($object)
{
$helper = $this->_getHelper();
$defaultStoreFinder = $helper->getDefaultStorefinder($object);
if (is_null($defaultStoreFinder)) {
$object->setData('default_store_finder_id', null);
}
}
public function afterSave($object)
{
if ($defaultStoreFinder = $this->_getHelper()->getDefaultStorefinder($object))
{
$addressId = false;
/**
* post_index set in customer save action for address
* this is $_POST array index for address
*/
foreach ($object->getAddresses() as $address) {
if ($address->getPostIndex() == $defaultStoreFinder) {
$addressId = $address->getId();
}
}
if ($addressId) {
$object->setDefaultStoreFinderId($addressId);
$this->getAttribute()->getEntity()
->saveAttribute($object, $this->getAttribute()->getAttributeCode());
}
}
}
/**
* @return StackExchange_Storefinder_Helper_Address
*/
protected function _getHelper()
{
return Mage::helper('stackexchange_storefinder/address');
}
}
app/code/local/StackExchange/Storefinder/Helper/Address.php
- a helper so you won't rewrite the customer model:
<?php
class StackExchange_Storefinder_Helper_Address extends Mage_Core_Helper_Abstract
{
public function getDefaultStorefinder(Mage_Customer_Model_Customer $customer)
{
return $customer->getData('default_store_finder_id');
}
public function getDefaultStorefinderAddress(Mage_Customer_Model_Customer $customer)
{
return $customer->getPrimaryAddress($customer->getData('default_store_finder_id'));
}
}
app/code/local/StackExchange/Storefinder/Block/Adminhtml/Customer/Edit/Tab/Addresses.php
- rewrite the admin address block to add the new radio button
<?php
class Stackexchange_Storefinder_Block_Adminhtml_Customer_Edit_Tab_Addresses
extends Mage_Adminhtml_Block_Customer_Edit_Tab_Addresses
{
public function __construct()
{
parent::__construct();
$this->setTemplate('stackexchange_storefinder/tab/addresses.phtml');
}
}
app/design/adminhtml/default/default/template/stackexchange_storefinder/tab/addresses.phtml
- the new address admin template. Same as the default one but with one extra radio button. I wrote this in a gist because it's too big to put in here
app/code/local/StackExchange/Storefinder/Model/Adminhtml/Observer.php
- an observer for the customer save event so the new address flag will be recognized:
<?php
class StackExchange_Storefinder_Model_Adminhtml_Observer
{
public function checkStoreFinderAddress($observer)
{
/** @var Mage_Customer_Model_Customer $customer */
$customer = $observer->getCustomer();
/** @var Mage_Core_Controller_Request_Http $request */
$request = $observer->getRequest();
$data = $request->getPost();
if (isset($data['account']['default_storefinder'])) {
$customer->setData('default_store_finder_id', $data['account']['default_storefinder']);
}
}
}
app/code/local/StackExchange/Storefinder/Helper/Data.php
- the module default helper. Not sure this is needed.
<?php
class StackExchange_Storefinder_Helper_Data extends Mage_Core_Helper_Abstract
{
}
When you are done clear the cache.
Now, in order to get all addresses that have this new flag set, you first need to get all the customers and get the value of $customer->getDefaultStoreFinderId()
and then get the address collection where the id is in the values collected above.
But from my point of view, these is a totally different question. First check if you can add a third address type by using the code above.
[EDIT]
To get all the addresses that are marked as store finder you need to do something like this:
$customerCollection = Mage::getModel('customer/customer')->getCollection()
->addAttributeToSelect('default_store_finder_id');
$addressIds = array();
foreach ($customerCollection as $customer) {
$addressId = $customer->getDefaultStoreFinderId();
if ($addressId) {
$addressIds[] = $addressId;
}
}
if (count($addressIds)) {
$addresses = Mage::getModel('customer/address')->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('entity_id', array('in' => $addressIds));
//do what you need with $addresses.
}
Custom customer attributes will never just 'appear' on the frontend like they do in the backend. The code that displays them on the frontend is located in a custom phtml file.
Magento EE has this functionality built in. I'm not suggesting you NEED to spend that money, I'm just saying it has it. If you want to go ahead and attempt to add custom attributes, it's somewhat complex.
First of all, you must do all of this in a module or it just isn't going to work right, and it's going to be hard to debug/upgrade later.
You have to do these things:
- Create the attribute (you've done this if it shows up in admin)
- override the frontend layout for referenceContainer form.additional.info
- add a template phtml file to show the additional attribute(s)
- add a block PHP file to load the new attributes and create the HTML
- other things like learn how to automate the process and load multiples instead of hard coding it to load just the name of the one you created.
You can load your custom attributes in the Block PHP. Then just add your layout to the customer_account_create.xml
like this:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<update handle="customer_form_template_handle"/>
<body>
<referenceContainer name="form.additional.info">
<block class="Company\Customformattributes\Block\FormCustomer" template="Company_Customformattributes::customattributes.phtml" name="customer_form_user_attributes" cacheable="false">
<action method="setFormCode">
<argument name="code" xsi:type="string">customer_account_edit</argument>
</action>
<action method="setEntityModelClass">
<argument name="code" xsi:type="string">Magento\Customer\Model\Customer</argument>
</action>
</block>
</referenceContainer>
</body>
</page>
This is the magic sauce to get your block PHP to load, to get your phtml to load, and to get it into the correct page.
This isn't a full answer honestly, there is a lot more to it, but you get the basic idea.
Best Answer
To solve the issue i created a plugin
And in plugin class
This is old implementation(In after plugin there were no input parameter) and might not be best implementation. Try if you can avoid around plugin and also call proceed .