feat(schema): add bounds filtering to list endpoints
All checks were successful
Build Docker Image / build (push) Successful in 1m16s
All checks were successful
Build Docker Image / build (push) Successful in 1m16s
Add west, south, east, north params to: - hubs_list - suppliers_list - products_list This enables filtering by map viewport bounds for the catalog.
This commit is contained in:
@@ -365,6 +365,10 @@ class Query(graphene.ObjectType):
|
||||
offset=graphene.Int(default_value=0, description="Offset for pagination"),
|
||||
country=graphene.String(description="Filter by country name"),
|
||||
transport_type=graphene.String(description="Filter by transport type"),
|
||||
west=graphene.Float(description="Bounding box west longitude"),
|
||||
south=graphene.Float(description="Bounding box south latitude"),
|
||||
east=graphene.Float(description="Bounding box east longitude"),
|
||||
north=graphene.Float(description="Bounding box north latitude"),
|
||||
description="Get paginated list of logistics hubs",
|
||||
)
|
||||
|
||||
@@ -373,6 +377,10 @@ class Query(graphene.ObjectType):
|
||||
limit=graphene.Int(default_value=50, description="Max results"),
|
||||
offset=graphene.Int(default_value=0, description="Offset for pagination"),
|
||||
country=graphene.String(description="Filter by country name"),
|
||||
west=graphene.Float(description="Bounding box west longitude"),
|
||||
south=graphene.Float(description="Bounding box south latitude"),
|
||||
east=graphene.Float(description="Bounding box east longitude"),
|
||||
north=graphene.Float(description="Bounding box north latitude"),
|
||||
description="Get paginated list of suppliers from graph",
|
||||
)
|
||||
|
||||
@@ -380,6 +388,10 @@ class Query(graphene.ObjectType):
|
||||
ProductType,
|
||||
limit=graphene.Int(default_value=50, description="Max results"),
|
||||
offset=graphene.Int(default_value=0, description="Offset for pagination"),
|
||||
west=graphene.Float(description="Bounding box west longitude"),
|
||||
south=graphene.Float(description="Bounding box south latitude"),
|
||||
east=graphene.Float(description="Bounding box east longitude"),
|
||||
north=graphene.Float(description="Bounding box north latitude"),
|
||||
description="Get paginated list of products from graph",
|
||||
)
|
||||
|
||||
@@ -1683,30 +1695,52 @@ class Query(graphene.ObjectType):
|
||||
logger.error("Error finding route to coordinates: %s", e)
|
||||
return None
|
||||
|
||||
def resolve_hubs_list(self, info, limit=50, offset=0, country=None, transport_type=None):
|
||||
def resolve_hubs_list(self, info, limit=50, offset=0, country=None, transport_type=None,
|
||||
west=None, south=None, east=None, north=None):
|
||||
"""Get paginated list of logistics hubs."""
|
||||
db = get_db()
|
||||
|
||||
aql = """
|
||||
# Build bounds filter if all bounds are provided
|
||||
bounds_filter = ""
|
||||
if west is not None and south is not None and east is not None and north is not None:
|
||||
bounds_filter = """
|
||||
FILTER node.latitude != null AND node.longitude != null
|
||||
FILTER node.latitude >= @south AND node.latitude <= @north
|
||||
FILTER node.longitude >= @west AND node.longitude <= @east
|
||||
"""
|
||||
|
||||
aql = f"""
|
||||
FOR node IN nodes
|
||||
FILTER node.node_type == 'logistics' OR node.node_type == null
|
||||
FILTER node.product_uuid == null
|
||||
LET types = node.transport_types != null ? node.transport_types : []
|
||||
FILTER @transport_type == null OR @transport_type IN types
|
||||
FILTER @country == null OR node.country == @country
|
||||
{bounds_filter}
|
||||
SORT node.name ASC
|
||||
LIMIT @offset, @limit
|
||||
RETURN node
|
||||
"""
|
||||
|
||||
try:
|
||||
cursor = db.aql.execute(aql, bind_vars={
|
||||
'transport_type': transport_type,
|
||||
'country': country,
|
||||
'offset': offset,
|
||||
'limit': limit,
|
||||
bind_vars = {
|
||||
'transport_type': transport_type,
|
||||
'country': country,
|
||||
'offset': offset,
|
||||
'limit': limit,
|
||||
}
|
||||
|
||||
# Only add bounds to bind_vars if they are used
|
||||
if west is not None and south is not None and east is not None and north is not None:
|
||||
bind_vars.update({
|
||||
'west': west,
|
||||
'south': south,
|
||||
'east': east,
|
||||
'north': north,
|
||||
})
|
||||
|
||||
try:
|
||||
cursor = db.aql.execute(aql, bind_vars=bind_vars)
|
||||
|
||||
hubs = []
|
||||
for node in cursor:
|
||||
hubs.append(NodeType(
|
||||
@@ -1726,26 +1760,48 @@ class Query(graphene.ObjectType):
|
||||
logger.error("Error getting hubs list: %s", e)
|
||||
return []
|
||||
|
||||
def resolve_suppliers_list(self, info, limit=50, offset=0, country=None):
|
||||
def resolve_suppliers_list(self, info, limit=50, offset=0, country=None,
|
||||
west=None, south=None, east=None, north=None):
|
||||
"""Get paginated list of suppliers from graph."""
|
||||
db = get_db()
|
||||
|
||||
aql = """
|
||||
# Build bounds filter if all bounds are provided
|
||||
bounds_filter = ""
|
||||
if west is not None and south is not None and east is not None and north is not None:
|
||||
bounds_filter = """
|
||||
FILTER node.latitude != null AND node.longitude != null
|
||||
FILTER node.latitude >= @south AND node.latitude <= @north
|
||||
FILTER node.longitude >= @west AND node.longitude <= @east
|
||||
"""
|
||||
|
||||
aql = f"""
|
||||
FOR node IN nodes
|
||||
FILTER node.node_type == 'supplier'
|
||||
FILTER @country == null OR node.country == @country
|
||||
{bounds_filter}
|
||||
SORT node.name ASC
|
||||
LIMIT @offset, @limit
|
||||
RETURN node
|
||||
"""
|
||||
|
||||
try:
|
||||
cursor = db.aql.execute(aql, bind_vars={
|
||||
'country': country,
|
||||
'offset': offset,
|
||||
'limit': limit,
|
||||
bind_vars = {
|
||||
'country': country,
|
||||
'offset': offset,
|
||||
'limit': limit,
|
||||
}
|
||||
|
||||
# Only add bounds to bind_vars if they are used
|
||||
if west is not None and south is not None and east is not None and north is not None:
|
||||
bind_vars.update({
|
||||
'west': west,
|
||||
'south': south,
|
||||
'east': east,
|
||||
'north': north,
|
||||
})
|
||||
|
||||
try:
|
||||
cursor = db.aql.execute(aql, bind_vars=bind_vars)
|
||||
|
||||
suppliers = []
|
||||
for node in cursor:
|
||||
suppliers.append(SupplierType(
|
||||
@@ -1760,30 +1816,52 @@ class Query(graphene.ObjectType):
|
||||
logger.error("Error getting suppliers list: %s", e)
|
||||
return []
|
||||
|
||||
def resolve_products_list(self, info, limit=50, offset=0):
|
||||
def resolve_products_list(self, info, limit=50, offset=0,
|
||||
west=None, south=None, east=None, north=None):
|
||||
"""Get paginated list of products from graph."""
|
||||
db = get_db()
|
||||
|
||||
aql = """
|
||||
# Build bounds filter if all bounds are provided
|
||||
bounds_filter = ""
|
||||
if west is not None and south is not None and east is not None and north is not None:
|
||||
bounds_filter = """
|
||||
FILTER node.latitude != null AND node.longitude != null
|
||||
FILTER node.latitude >= @south AND node.latitude <= @north
|
||||
FILTER node.longitude >= @west AND node.longitude <= @east
|
||||
"""
|
||||
|
||||
aql = f"""
|
||||
FOR node IN nodes
|
||||
FILTER node.node_type == 'offer'
|
||||
FILTER node.product_uuid != null
|
||||
{bounds_filter}
|
||||
COLLECT product_uuid = node.product_uuid INTO offers
|
||||
LET first_offer = FIRST(offers).node
|
||||
SORT first_offer.product_name ASC
|
||||
LIMIT @offset, @limit
|
||||
RETURN {
|
||||
RETURN {{
|
||||
uuid: product_uuid,
|
||||
name: first_offer.product_name
|
||||
}
|
||||
}}
|
||||
"""
|
||||
|
||||
try:
|
||||
cursor = db.aql.execute(aql, bind_vars={
|
||||
'offset': offset,
|
||||
'limit': limit,
|
||||
bind_vars = {
|
||||
'offset': offset,
|
||||
'limit': limit,
|
||||
}
|
||||
|
||||
# Only add bounds to bind_vars if they are used
|
||||
if west is not None and south is not None and east is not None and north is not None:
|
||||
bind_vars.update({
|
||||
'west': west,
|
||||
'south': south,
|
||||
'east': east,
|
||||
'north': north,
|
||||
})
|
||||
|
||||
try:
|
||||
cursor = db.aql.execute(aql, bind_vars=bind_vars)
|
||||
|
||||
products = [ProductType(uuid=p['uuid'], name=p.get('name')) for p in cursor]
|
||||
logger.info("Returning %d products (offset=%d, limit=%d)", len(products), offset, limit)
|
||||
return products
|
||||
|
||||
Reference in New Issue
Block a user