diff --git a/offers/management/commands/seed_exchange.py b/offers/management/commands/seed_exchange.py index d9d5672..9408b9c 100644 --- a/offers/management/commands/seed_exchange.py +++ b/offers/management/commands/seed_exchange.py @@ -24,6 +24,17 @@ AFRICAN_COUNTRIES = [ ("Togo", "TG", 6.1725, 1.2314), # Lomé ] +# Supplier name building blocks +SUPPLIER_PREFIXES = [ + "Amber", "Delta", "Atlas", "Nova", "Summit", "Orion", "Cedar", "Prairie", + "Horizon", "Lumen", "Vertex", "Harbor", "Nile", "Savanna", "Marlin", + "Everest", "Cascade", "Cobalt", "Aurora", "Mosaic", "Meridian", "Granite", +] +SUPPLIER_SUFFIXES = [ + "Agro", "Trade", "Commodities", "Exports", "Supply", "Foods", "Farms", + "Harvest", "Producers", "Logistics", "Trading", "Cooperative", +] + # Products will be fetched from Odoo at runtime # Format: (name, category, uuid) - populated by _fetch_products_from_odoo() @@ -44,6 +55,12 @@ class Command(BaseCommand): default=50, help="How many offers to create (default: 50)", ) + parser.add_argument( + "--product-count", + type=int, + default=10, + help="How many distinct products to use (default: 10)", + ) parser.add_argument( "--clear", action="store_true", @@ -84,6 +101,7 @@ class Command(BaseCommand): suppliers_count = max(0, options["suppliers"]) offers_count = max(0, options["offers"]) + product_count = max(1, options["product_count"]) use_workflow = not options["no_workflow"] geo_url = options["geo_url"] odoo_url = options["odoo_url"] @@ -105,6 +123,11 @@ class Command(BaseCommand): return self.stdout.write(f"Filtered to {len(products)} products matching '{product_filter}'") + # Limit to product_count distinct items (random sample if possible) + if len(products) > product_count: + products = random.sample(products, product_count) + self.stdout.write(f"Using {len(products)} products for seeding") + # Fetch African hubs from geo service self.stdout.write("Fetching African hubs from geo service...") hubs = self._fetch_african_hubs(geo_url) @@ -279,6 +302,7 @@ class Command(BaseCommand): def _create_suppliers(self, count: int, hubs: list) -> list: """Create supplier profiles in African countries""" created = [] + used_names = set() for idx in range(count): hub = random.choice(hubs) if hubs else None country, country_code = self._get_random_african_country() @@ -292,11 +316,17 @@ class Command(BaseCommand): lat += random.uniform(-0.5, 0.5) lng += random.uniform(-0.5, 0.5) + name = self._generate_supplier_name(country, used_names) + description = ( + f"{name} is a reliable supplier based in {country}, " + "focused on consistent quality and transparent logistics." + ) + profile = SupplierProfile.objects.create( uuid=str(uuid.uuid4()), team_uuid=str(uuid.uuid4()), - name=f"Cocoa Supplier {idx + 1} ({country})", - description=f"Premium cocoa supplier from {country}. Specializing in high-quality cocoa beans.", + name=name, + description=description, country=country, country_code=country_code, logo_url="", @@ -308,6 +338,20 @@ class Command(BaseCommand): created.append(profile) return created + def _generate_supplier_name(self, country: str, used_names: set) -> str: + """Generate a readable supplier name with low collision probability.""" + for _ in range(50): + prefix = random.choice(SUPPLIER_PREFIXES) + suffix = random.choice(SUPPLIER_SUFFIXES) + name = f\"{prefix} {suffix}\" + if name not in used_names: + used_names.add(name) + return name + # Fallback with country tag to avoid collisions + name = f\"{random.choice(SUPPLIER_PREFIXES)} {random.choice(SUPPLIER_SUFFIXES)} {country}\" + used_names.add(name) + return name + def _create_offers_via_workflow(self, count: int, hubs: list, products: list) -> list: """Create offers via Temporal workflow (syncs to graph)""" created = []