diff --git a/geo_app/schema.py b/geo_app/schema.py index b826f47..dfb2e2e 100644 --- a/geo_app/schema.py +++ b/geo_app/schema.py @@ -256,6 +256,19 @@ class Query(graphene.ObjectType): description="Get products available near a hub", ) + suppliers_for_product = graphene.List( + SupplierType, + product_uuid=graphene.String(required=True), + description="Get suppliers that offer a specific product", + ) + + hubs_for_product = graphene.List( + NodeType, + product_uuid=graphene.String(required=True), + radius_km=graphene.Float(default_value=500), + description="Get hubs where a product is available nearby", + ) + offers_by_hub = graphene.List( ProductRouteOptionType, hub_uuid=graphene.String(required=True), @@ -885,6 +898,70 @@ class Query(graphene.ObjectType): logger.error("Error getting products near hub: %s", e) return [] + def resolve_suppliers_for_product(self, info, product_uuid): + """Get unique suppliers that have offers for this product.""" + db = get_db() + aql = """ + FOR node IN nodes + FILTER node.node_type == 'offer' + FILTER node.product_uuid == @product_uuid + FILTER node.supplier_uuid != null + COLLECT supplier_uuid = node.supplier_uuid + RETURN { uuid: supplier_uuid } + """ + try: + cursor = db.aql.execute(aql, bind_vars={'product_uuid': product_uuid}) + suppliers = [SupplierType(uuid=s['uuid']) for s in cursor] + logger.info("Found %d suppliers for product %s", len(suppliers), product_uuid) + return suppliers + except Exception as e: + logger.error("Error getting suppliers for product: %s", e) + return [] + + def resolve_hubs_for_product(self, info, product_uuid, radius_km=500): + """Get hubs that have this product available within radius.""" + db = get_db() + aql = """ + FOR offer IN nodes + FILTER offer.node_type == 'offer' + FILTER offer.product_uuid == @product_uuid + FILTER offer.latitude != null AND offer.longitude != null + FOR hub IN nodes + FILTER hub.node_type == 'logistics' OR hub.node_type == null + FILTER hub.latitude != null AND hub.longitude != null + LET dist = DISTANCE(offer.latitude, offer.longitude, hub.latitude, hub.longitude) / 1000 + FILTER dist <= @radius_km + COLLECT hub_uuid = hub._key, hub_name = hub.name, + hub_lat = hub.latitude, hub_lon = hub.longitude, + hub_country = hub.country, hub_country_code = hub.country_code, + hub_transport = hub.transport_types + RETURN { + uuid: hub_uuid, + name: hub_name, + latitude: hub_lat, + longitude: hub_lon, + country: hub_country, + country_code: hub_country_code, + transport_types: hub_transport + } + """ + try: + cursor = db.aql.execute(aql, bind_vars={'product_uuid': product_uuid, 'radius_km': radius_km}) + hubs = [NodeType( + uuid=h['uuid'], + name=h['name'], + latitude=h['latitude'], + longitude=h['longitude'], + country=h['country'], + country_code=h.get('country_code'), + transport_types=h.get('transport_types') + ) for h in cursor] + logger.info("Found %d hubs for product %s", len(hubs), product_uuid) + return hubs + except Exception as e: + logger.error("Error getting hubs for product: %s", e) + return [] + def resolve_offers_by_hub(self, info, hub_uuid, product_uuid, limit=10): """ Get offers for a product with routes to hub.