#!/usr/bin/env python3 """ Create a dummy Letzshop order for testing purposes. This script creates a realistic Letzshop order in the database without calling the actual Letzshop API. Useful for testing the order UI and workflow. Usage: python scripts/create_dummy_letzshop_order.py --store-id 1 python scripts/create_dummy_letzshop_order.py --store-id 1 --status confirmed python scripts/create_dummy_letzshop_order.py --store-id 1 --with-tracking """ import argparse import random import string import sys from datetime import UTC, datetime, timedelta from pathlib import Path # Add project root to path sys.path.insert(0, str(Path(__file__).parent.parent)) from app.core.database import SessionLocal from app.modules.catalog.models import Product from app.modules.orders.models import Order, OrderItem from app.modules.tenancy.models import Store def generate_order_number(): """Generate a realistic Letzshop order number like R532332163.""" return f"R{random.randint(100000000, 999999999)}" # noqa: SEC042 def generate_shipment_number(): """Generate a realistic shipment number like H74683403433.""" return f"H{random.randint(10000000000, 99999999999)}" # noqa: SEC042 def generate_hash_id(): """Generate a realistic hash ID like nvDv5RQEmCwbjo.""" chars = string.ascii_letters + string.digits return "".join(random.choice(chars) for _ in range(14)) # noqa: SEC042 def create_dummy_order( db, store_id: int, status: str = "pending", with_tracking: bool = False, carrier: str = "greco", items_count: int = 2, ): """Create a dummy Letzshop order with realistic data.""" # Verify store exists store = db.query(Store).filter(Store.id == store_id).first() if not store: print(f"Error: Store with ID {store_id} not found") return None # Get some products from the store (or create placeholder if none exist) products = db.query(Product).filter( Product.store_id == store_id, Product.is_active == True ).limit(items_count).all() if not products: print(f"Warning: No active products found for store {store_id}, creating placeholder") # Create placeholder products with prices in cents products = [ Product( store_id=store_id, store_sku="TEST-001", gtin="4006381333931", gtin_type="ean13", price_cents=2999, # €29.99 is_active=True, is_featured=False, ), Product( store_id=store_id, store_sku="TEST-002", gtin="5901234123457", gtin_type="ean13", price_cents=4999, # €49.99 is_active=True, is_featured=False, ), ] for p in products: db.add(p) # noqa: PERF006 db.flush() # Generate order data order_number = generate_order_number() shipment_number = generate_shipment_number() hash_id = generate_hash_id() order_date = datetime.now(UTC) - timedelta(days=random.randint(0, 7)) # noqa: SEC042 # Customer data first_names = ["Jean", "Marie", "Pierre", "Sophie", "Michel", "Anne", "Thomas", "Claire"] last_names = ["Dupont", "Martin", "Bernard", "Dubois", "Thomas", "Robert", "Richard", "Petit"] cities = ["Luxembourg", "Esch-sur-Alzette", "Differdange", "Dudelange", "Ettelbruck"] customer_first = random.choice(first_names) # noqa: SEC042 customer_last = random.choice(last_names) # noqa: SEC042 customer_email = f"{customer_first.lower()}.{customer_last.lower()}@example.lu" # Calculate totals in cents subtotal_cents = sum((p.price_cents or 0) * random.randint(1, 3) for p in products[:items_count]) # noqa: SEC042 shipping_cents = 595 # €5.95 total_cents = subtotal_cents + shipping_cents # Create the order order = Order( store_id=store_id, customer_id=1, # Placeholder customer ID order_number=f"LS-{store_id}-{order_number}", channel="letzshop", external_order_id=f"gid://letzshop/Order/{random.randint(10000, 99999)}", # noqa: SEC042 external_order_number=order_number, external_shipment_id=hash_id, shipment_number=shipment_number, shipping_carrier=carrier, status=status, subtotal_cents=subtotal_cents, tax_amount_cents=0, shipping_amount_cents=shipping_cents, discount_amount_cents=0, total_amount_cents=total_cents, currency="EUR", # Customer snapshot customer_first_name=customer_first, customer_last_name=customer_last, customer_email=customer_email, customer_phone=f"+352 {random.randint(600000, 699999)}", # noqa: SEC042 customer_locale="fr", # Shipping address ship_first_name=customer_first, ship_last_name=customer_last, ship_company=None, ship_address_line_1=f"{random.randint(1, 200)} Rue du Test", # noqa: SEC042 ship_address_line_2=None, ship_city=random.choice(cities), # noqa: SEC042 ship_postal_code=f"L-{random.randint(1000, 9999)}", # noqa: SEC042 ship_country_iso="LU", # Billing address (same as shipping) bill_first_name=customer_first, bill_last_name=customer_last, bill_company=None, bill_address_line_1=f"{random.randint(1, 200)} Rue du Test", # noqa: SEC042 bill_address_line_2=None, bill_city=random.choice(cities), # noqa: SEC042 bill_postal_code=f"L-{random.randint(1000, 9999)}", # noqa: SEC042 bill_country_iso="LU", # Timestamps order_date=order_date, ) # Set status-specific timestamps if status in ["processing", "shipped", "delivered"]: order.confirmed_at = order_date + timedelta(hours=random.randint(1, 24)) # noqa: SEC042 if status in ["shipped", "delivered"]: order.shipped_at = order.confirmed_at + timedelta(days=random.randint(1, 3)) # noqa: SEC042 if status == "delivered": order.delivered_at = order.shipped_at + timedelta(days=random.randint(1, 5)) # noqa: SEC042 if status == "cancelled": order.cancelled_at = order_date + timedelta(hours=random.randint(1, 48)) # noqa: SEC042 # Add tracking if requested if with_tracking or status == "shipped": order.tracking_number = f"LU{random.randint(100000000, 999999999)}" # noqa: SEC042 order.tracking_provider = carrier if carrier == "greco": order.tracking_url = f"https://dispatchweb.fr/Tracky/Home/{shipment_number}" db.add(order) db.flush() # Create order items with prices in cents for _i, product in enumerate(products[:items_count]): quantity = random.randint(1, 3) # noqa: SEC042 unit_price_cents = product.price_cents or 0 product_name = product.get_title("en") or f"Product {product.id}" item = OrderItem( order_id=order.id, product_id=product.id, product_name=product_name, product_sku=product.store_sku, gtin=product.gtin, gtin_type=product.gtin_type, quantity=quantity, unit_price_cents=unit_price_cents, total_price_cents=unit_price_cents * quantity, external_item_id=f"gid://letzshop/InventoryUnit/{random.randint(10000, 99999)}", # noqa: SEC042 item_state="confirmed_available" if status != "pending" else None, inventory_reserved=status != "pending", inventory_fulfilled=status in ["shipped", "delivered"], needs_product_match=False, ) db.add(item) db.commit() db.refresh(order) return order def main(): parser = argparse.ArgumentParser(description="Create a dummy Letzshop order for testing") parser.add_argument("--store-id", type=int, required=True, help="Store ID to create order for") parser.add_argument( "--status", choices=["pending", "processing", "shipped", "delivered", "cancelled"], default="pending", help="Order status (default: pending)" ) parser.add_argument( "--carrier", choices=["greco", "colissimo", "xpresslogistics"], default="greco", help="Shipping carrier (default: greco)" ) parser.add_argument("--with-tracking", action="store_true", help="Add tracking information") parser.add_argument("--items", type=int, default=2, help="Number of items in order (default: 2)") args = parser.parse_args() db = SessionLocal() try: print(f"Creating dummy Letzshop order for store {args.store_id}...") print(f" Status: {args.status}") print(f" Carrier: {args.carrier}") print(f" Items: {args.items}") print(f" With tracking: {args.with_tracking}") print() order = create_dummy_order( db, store_id=args.store_id, status=args.status, with_tracking=args.with_tracking, carrier=args.carrier, items_count=args.items, ) if order: print("Order created successfully!") print() print("Order Details:") print(f" ID: {order.id}") print(f" Internal Number: {order.order_number}") print(f" Letzshop Order Number: {order.external_order_number}") print(f" Shipment Number: {order.shipment_number}") print(f" Hash ID: {order.external_shipment_id}") print(f" Carrier: {order.shipping_carrier}") print(f" Status: {order.status}") print(f" Total: {order.total_amount} {order.currency}") print(f" Customer: {order.customer_first_name} {order.customer_last_name}") print(f" Email: {order.customer_email}") print(f" Items: {len(order.items)}") if order.tracking_number: print(f" Tracking: {order.tracking_number}") if order.tracking_url: print(f" Tracking URL: {order.tracking_url}") print() print(f"View order at: http://localhost:8000/admin/letzshop/orders/{order.id}") finally: db.close() if __name__ == "__main__": main()