Question

In Magento 2, I try to get addresses collection from table 'customer_address_entity', filter by updated_at field.

I know I can get addresses for customer with this :

$customer = $this->_customerRepository->getById($customerId);
$addresses = $customer->getAddresses();

I don't want to load every customer, is there a way to get addresses collection like this, but instead of '_customerFactory' is there a '_addressFactory' method ?:

$collection = $this->_customerFactory->create()->getCollection()
                ->addAttributeToSelect("*")
                ->addAttributeToFilter("updated_at", array("gteq" => $start))
                ->addAttributeToFilter("updated_at", array("lteq" => $end))
                ->load();
Was it helpful?

Solution

Yes, you can use the Customer Address repository - see Magento\Customer\Api\AddressRepositoryInterface::getList()

You need to use SearchCriteriaBuilder with FilterBuilder & FilterGroupBuilder. Here is an example - but you should add these are dependencies in your construct, of course, not using objectManager.

$customerAddressRepository = $objectManager->get(\Magento\Customer\Api\AddressRepositoryInterface::class);
$filterBuilder = $objectManager->get(\Magento\Framework\Api\FilterBuilder::class);
$filterGroupBuilder = $objectManager->get(\Magento\Framework\Api\Search\FilterGroupBuilder::class);
$searchCriteriaBuilder = $objectManager->get(\Magento\Framework\Api\SearchCriteriaBuilder::class);

$filter1 = $filterBuilder->setField('updated_at')->setValue($startDate)->setConditionType('gteq')->create();
$filterGroup1 = $filterGroupBuilder->setFilters([$filter1])->create();

$filter2 = $filterBuilder->setField('updated_at')->setValue($endDate)->setConditionType('lteq')->create();
$filterGroup2 = $filterGroupBuilder->setFilters([$filter2])->create();

$searchCriteria = $searchCriteriaBuilder->setFilterGroups([$filterGroup1, $filterGroup2])->create();
$addresses = $customerAddressRepository->getList($searchCriteria)->getItems();

foreach ($addresses as $address) {
  echo $address->getFirstName().' '.$address->getLastName().'<br>';
  foreach($address->getStreet() as $street) {
    echo $street.'<br>';
  }
  echo $address->getCity().', '.$address->getRegion()->getRegion().', '.$address->getCountryId().'<br><br>';
}

You can add more Filters to each FilterGroup - that would be an OR condition.

Each FilterGroup is an AND condition. See reference for searching repositories

OTHER TIPS

Bernieu2 answer is right but If you have customer address ids You can use AddressRepositoryInterface's getById method to directly load customer addresses

public function __construct(
        \Magento\Customer\Api\CustomerRepositoryInterface $customer,
        \Magento\Customer\Api\AddressRepositoryInterface $addressInterface,
) {
        parent::__construct($context);
        $this->_customer = $customer;
        $this->addressInterface = $addressInterface;

}

        $billling_address_id = $customer->getDefaultBilling();
        $billling_address = $this->addressInterface->getById($billling_address_id);
        $phone  = $billling_address->getTelephone();
        $postcode  = $billling_address->getPostcode();
        $region  = $billling_address->getRegion()->getRegion();
        $country  = $billling_address->getCountryId();
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top