From f1f974bd2ad0100bd35605aab5f4754e4b92d150 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Mon, 16 Feb 2026 03:55:08 +0100 Subject: [PATCH] added unavailable flavors --- .../commands/seed_legacy_flavors.py | 91 +++++++++++++++++++ .../api/management/commands/sync_flavors.py | 28 ++---- 2 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 backend/api/management/commands/seed_legacy_flavors.py diff --git a/backend/api/management/commands/seed_legacy_flavors.py b/backend/api/management/commands/seed_legacy_flavors.py new file mode 100644 index 0000000..cb0e2f7 --- /dev/null +++ b/backend/api/management/commands/seed_legacy_flavors.py @@ -0,0 +1,91 @@ +import json +import urllib.request +import re +from django.core.management.base import BaseCommand +from api.models import Category, Flavor + +class Command(BaseCommand): + help = 'Adds legacy flavors that are no longer in the official API' + + def handle(self, *args, **options): + # Ensure categories exist + energy = Category.objects.get(slug='energy') + hydration = Category.objects.get(slug='hydration') + iced_tea = Category.objects.get(slug='iced-tea') + + legacy_data = [ + # Hitschies Collab + { + 'name': 'Hitschies Drachenzunge (Blue Raspberry)', + 'category': energy, + 'description': 'The legendary sour blue raspberry flavor from the Hitschies collaboration.', + 'image_url': 'https://weareholy.com/cdn/shop/files/Holy_Energy_Hitschies_Sour_Dragon_Tongue_Tub_720x.png', + }, + { + 'name': 'Hitschies Apple Alligator', + 'category': energy, + 'description': 'Sour apple flavor from the Hitschies collaboration.', + 'image_url': 'https://weareholy.com/cdn/shop/files/Holy_Energy_Hitschies_Apple_Alligator_Tub_720x.png', + }, + { + 'name': 'Hitschies Fruity Frog', + 'category': energy, + 'description': 'Peach and raspberry mix from the Hitschies collaboration.', + 'image_url': 'https://weareholy.com/cdn/shop/files/Holy_Energy_Hitschies_Fruity_Frog_Tub_720x.png', + }, + # Holydays 2024 + { + 'name': 'Dolphin Daiquiri', + 'category': energy, + 'description': 'Strawberry and lime cocktail flavor from Holydays 2024.', + 'image_url': 'https://weareholy.com/cdn/shop/files/HOLY_Energy_Holydays_Cocktail_Daiquiri_Dolphin_Tub_720x.png', + }, + { + 'name': 'Crab Caipirinha', + 'category': energy, + 'description': 'Lime and cane sugar cocktail flavor from Holydays 2024.', + 'image_url': 'https://weareholy.com/cdn/shop/files/HOLY_Energy_Holydays_Cocktail_Caipirinha_Crab_Tub_720x.png', + }, + { + 'name': 'Makau Mojito', + 'category': energy, + 'description': 'Lime and mint cocktail flavor from Holydays 2024.', + 'image_url': 'https://weareholy.com/cdn/shop/files/HOLY_Energy_Holydays_Cocktail_Mojito_Makau_Tub_720x.png', + }, + # Others + { + 'name': 'Frosty Fox (Eisbonbon)', + 'category': energy, + 'description': 'Limited ice candy flavor released for Black Week 2024.', + 'image_url': 'https://weareholy.com/cdn/shop/files/HOLY_Energy_Frosty_Fox_Tub_720x.png', + }, + { + 'name': 'Bubblegum Butterfly', + 'category': energy, + 'description': 'A classic pink bubblegum flavor that occasionally returns as a limited edition.', + 'image_url': 'https://weareholy.com/cdn/shop/files/HOLY_Energy_Bubblegum_Butterfly_Tub_720x.png', + }, + { + 'name': 'Knossi Edition Drachenfrucht', + 'category': hydration, + 'description': 'Special Dragonfruit flavor in collaboration with Knossi.', + 'image_url': 'https://weareholy.com/cdn/shop/files/HOLY_Hydration_Knossi_Edition_Tub_720x.png', + } + ] + + for data in legacy_data: + flavor, created = Flavor.objects.update_or_create( + name=data['name'], + defaults={ + 'category': data['category'], + 'description': data['description'], + 'image_url': data['image_url'], + 'is_available': False, + 'external_id': None + } + ) + + if created: + self.stdout.write(self.style.SUCCESS(f"Added legacy flavor: {data['name']}")) + else: + self.stdout.write(self.style.SUCCESS(f"Updated legacy flavor: {data['name']}")) diff --git a/backend/api/management/commands/sync_flavors.py b/backend/api/management/commands/sync_flavors.py index 3839815..c6ed03b 100644 --- a/backend/api/management/commands/sync_flavors.py +++ b/backend/api/management/commands/sync_flavors.py @@ -40,14 +40,9 @@ class Command(BaseCommand): created_count = 0 updated_count = 0 - synced_ids = [] + synced_external_ids = [] for p in products: - # ... (previous logic for title, tags, category etc.) - title = p.get('title') - # ... (omitting for brevity in thought, but I will write full loop) - # Actually I need the full loop content to replace correctly. - # I will use a more targeted replacement. title = p.get('title') tags = p.get('tags', []) product_type = p.get('product_type', '').lower() @@ -60,17 +55,10 @@ class Command(BaseCommand): title_lower = title.lower() # Check for Packs/Bundles/Samples - # We prioritize explicit "Pack" keywords in the title. - # We DO NOT rely solely on product_type 'Energy Bundle' because some single tubs might be mislabeled or the API uses that for all energy products. - is_pack = False pack_keywords = ['bundle', 'set', 'box', 'probe', 'sample', 'taster', 'starter', 'collection', 'probier'] - - # Check title keywords (strong indicator) if any(k in title_lower for k in pack_keywords): is_pack = True - - # Check for "Shaker" or "Merch" specifically if 'shaker' in title_lower or 'merch' in tags_lower: is_pack = True @@ -86,15 +74,10 @@ class Command(BaseCommand): elif 'milkshake' in tags_lower: category = cat_map['milkshake'] - # If still no category (and not explicitly a pack yet), check loosely if not category: if 'shaker' in tags_lower: category = cat_map['packs'] else: - # Fallback: if we can't classify it, maybe it's just a general item/pack - # But let's be careful not to hide real flavors. - # If it has no known tag, skip it or put in Packs? - # Let's skip unknown stuff to keep the list clean. continue # Check availability @@ -113,7 +96,6 @@ class Command(BaseCommand): shop_url = f"https://weareholy.com/products/{handle}" if handle else None # Create or update - # Try finding by external_id first, then by name flavor = Flavor.objects.filter(external_id=p['id']).first() if not flavor: flavor = Flavor.objects.filter(name=title).first() @@ -139,5 +121,11 @@ class Command(BaseCommand): is_available=is_available ) created_count += 1 + + synced_external_ids.append(p['id']) - self.stdout.write(self.style.SUCCESS(f"Finished! Created: {created_count}, Updated: {updated_count}")) + # Mark flavors NOT in the sync as unavailable (only for those that have an external_id) + # This keeps manually added flavors (with external_id=None) as they are. + discontinued_count = Flavor.objects.filter(external_id__isnull=False).exclude(external_id__in=synced_external_ids).update(is_available=False) + + self.stdout.write(self.style.SUCCESS(f"Finished! Created: {created_count}, Updated: {updated_count}, Marked Unavailable: {discontinued_count}"))