#!/usr/bin/env python3 """ Check shipment status directly from Letzshop API. Usage: python scripts/check_letzshop_shipment.py YOUR_API_KEY [SHIPMENT_ID_OR_ORDER_NUMBER] Example: python scripts/check_letzshop_shipment.py abc123 nvDv5RQEmCwbjo python scripts/check_letzshop_shipment.py abc123 R532332163 """ import json import sys import requests ENDPOINT = "https://letzshop.lu/graphql" # Query template - state is interpolated since Letzshop has enum issues QUERY_SHIPMENTS_TEMPLATE = """ query GetShipmentsPaginated($first: Int!, $after: String) {{ shipments(state: {state}, first: $first, after: $after) {{ pageInfo {{ hasNextPage endCursor }} nodes {{ id number state order {{ id number email total completedAt locale shipAddress {{ firstName lastName merchant streetName streetNumber city zipCode phone country {{ iso }} }} }} inventoryUnits {{ id state variant {{ id sku mpn price tradeId {{ number parser }} product {{ name {{ en fr de }} }} }} }} }} }} }} """ def search_shipment(api_key: str, search_term: str): """Search for a shipment across all states.""" headers = { "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", } # States to search through states = ["shipped", "confirmed", "unconfirmed", "declined"] print(f"Searching for: {search_term}") print("=" * 60) for state in states: print(f"\nSearching in state: {state}...") query = QUERY_SHIPMENTS_TEMPLATE.format(state=state) # Paginate through results has_next = True after = None page = 0 while has_next and page < 20: # Max 20 pages to avoid infinite loop page += 1 variables = {"first": 50, "after": after} response = requests.post( ENDPOINT, headers=headers, json={"query": query, "variables": variables}, ) if response.status_code != 200: print(f" Error: HTTP {response.status_code}") break data = response.json() if "errors" in data: print(f" GraphQL errors: {data['errors']}") break result = data.get("data", {}).get("shipments", {}) nodes = result.get("nodes", []) page_info = result.get("pageInfo", {}) # Search for matching shipment for shipment in nodes: shipment_id = shipment.get("id", "") shipment_number = shipment.get("number", "") order = shipment.get("order", {}) order_number = order.get("number", "") # Check if this matches our search term if (search_term in (shipment_id, order_number) or search_term in shipment_id or search_term in shipment_number or search_term in order_number): print(f"\n{'=' * 60}") print("FOUND SHIPMENT!") print(f"{'=' * 60}") print("\n--- Shipment Info ---") print(f" ID: {shipment.get('id')}") print(f" Number: {shipment.get('number')}") print(f" State: {shipment.get('state')}") print("\n--- Order Info ---") print(f" Order ID: {order.get('id')}") print(f" Order Number: {order.get('number')}") print(f" Email: {order.get('email')}") print(f" Total: {order.get('total')}") print(f" Completed At: {order.get('completedAt')}") ship_addr = order.get("shipAddress", {}) if ship_addr: print("\n--- Shipping Address ---") print(f" Name: {ship_addr.get('firstName')} {ship_addr.get('lastName')}") print(f" Street: {ship_addr.get('streetName')} {ship_addr.get('streetNumber')}") print(f" City: {ship_addr.get('zipCode')} {ship_addr.get('city')}") country = ship_addr.get("country", {}) print(f" Country: {country.get('iso')}") print("\n--- Inventory Units ---") units = shipment.get("inventoryUnits", []) for i, unit in enumerate(units, 1): print(f" Unit {i}:") print(f" ID: {unit.get('id')}") print(f" State: {unit.get('state')}") variant = unit.get("variant", {}) print(f" SKU: {variant.get('sku')}") trade_id = variant.get("tradeId", {}) print(f" GTIN: {trade_id.get('number')}") product = variant.get("product", {}) name = product.get("name", {}) print(f" Product: {name.get('en')}") print("\n--- Raw Response ---") print(json.dumps(shipment, indent=2, default=str)) return shipment has_next = page_info.get("hasNextPage", False) after = page_info.get("endCursor") if not has_next: print(f" Searched {page} page(s), {len(nodes)} shipments in last page") print(f"\nShipment not found for: {search_term}") return None if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: python scripts/check_letzshop_shipment.py YOUR_API_KEY [SHIPMENT_ID_OR_ORDER_NUMBER]") print("\nExample:") print(" python scripts/check_letzshop_shipment.py abc123 nvDv5RQEmCwbjo") print(" python scripts/check_letzshop_shipment.py abc123 R532332163") sys.exit(1) api_key = sys.argv[1] # Default to the order number R532332163 search_term = sys.argv[2] if len(sys.argv) > 2 else "R532332163" search_shipment(api_key, search_term)