Magento 2 How to get/group orders by shipping addresses
-
27-12-2020 - |
Вопрос
Seems like Magento doesn't have a way to get all orders by shipping addresses. This is obviously because of the following:
- Magento doesn't store addresses as unique entities, this means every time there is an order, Magento will create a new entity for that address even if already exists and is exactly the same.
- Because its a new entity, every time an order is placed it will have its unique
entity_id
which is then stored against thesales_order
table under theshipping_address_id
column. This means we will not be able to easily check how many orders have been done under a specific address because they all have differententity_id
(unique keys).
So has anyone every come across this before or can you think of a way of achieve this?
EDIT:
Here is some context why I need this.
We basically want a way to flag addresses as trusted if it has x amount of non-refunded orders between z timeframe. When a customer checks out the input address will be lookup on a table with trusted addresses if it is found then it is sent to our fraud system to do extra validations with the address set as trusted.
Решение
So done some research, this is obviously going to take a loot of resources and time to do on the fly. Here is my current approach to this issue which seems to work pretty well.
Because we can't really get orders by addresses in a easy way, every time an order is place a new entry is added for the address being used under sales_order_address
. I came up with this query which concatenates the street
, city
and country
of the sales_order_address
and then groups all other matching addresses which doing a JOIN to the sales_order
table to check if the entity_id
of the sales_order
table record matches the parent_id
of the sales_order_address
table.
SELECT
CONCAT(order_addresses.`street`, order_addresses.`city`, order_addresses.`country_id`) AS address,
COUNT(*) AS 'order_count'
FROM `sales_order_address` AS `order_addresses`
LEFT JOIN `sales_order` AS `sales` ON sales.`entity_id` = order_addresses.`parent_id`
WHERE order_addresses.`address_type` = "shipping"
AND sales.`base_total_refunded` IS NULL
AND sales.`status` = "complete"
AND sales.`state` = "complete"
AND DATE(sales.`created_at`) >= DATE(NOW() - INTERVAL [THIS_IS_A_SYSTEM_VALUE] MONTH)
GROUP BY address
HAVING order_count > [THIS_IS_A_SYSTEM_VALUE]
The above query will be run occasionally every month and once a customer places an order there will be an observer which will look up into a temporary table which was created from the above SELECT and then if the address is trusted it will sent the required information to our fraud system.
Here is a link to my git repo where I will be posting useful SQL queries for Magento 2.