""" Utilidad puntual (no forma parte del pipeline recurrente): crea un StockTransfer directo entre dos almacenes para todos los SKU del grupo de artículos indicado. Uso: .venv/bin/python tools/transferir_stock.py config/stores/snobbycl.json \ --from 8801 --to 7701 --quantity 500 Agregar --apply para ejecutar el POST real (por defecto es dry-run). """ import argparse import json import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from core.config import cargar_config_tienda from core.errors import SAPServiceLayerError from core.sap import SAPServiceLayerClient from tools.cargar_entrada_mercancia import obtener_skus_grupo, ITEMS_GROUP_CODE def main(store_config_path: str, from_wh: str, to_wh: str, quantity: float, dry_run: bool) -> None: store_config = cargar_config_tienda(store_config_path) sap = SAPServiceLayerClient.from_store_config(store_config["sap_connection"]) skus = obtener_skus_grupo(sap, ITEMS_GROUP_CODE) print(f"SKUs encontrados en grupo {ITEMS_GROUP_CODE}: {len(skus)}") document_lines = [ { "ItemCode": sku, "Quantity": quantity, "FromWarehouseCode": from_wh, "WarehouseCode": to_wh, } for sku in skus ] payload = {"StockTransferLines": document_lines} if dry_run: print(json.dumps(payload["StockTransferLines"][:3], indent=2, ensure_ascii=False)) print(f"... ({len(document_lines)} líneas en total, de {from_wh} a {to_wh}, cantidad={quantity})") print("(dry-run: no se envió nada a SAP, correr con --apply para crear el documento)") return try: resp = sap.forward("POST", "StockTransfers", json_data=payload) data = resp.json() print(f"StockTransfer creado. DocEntry={data.get('DocEntry')} DocNum={data.get('DocNum')}") except SAPServiceLayerError as exc: print(f"ERROR creando el StockTransfer: {exc.detail}") if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("store_config") parser.add_argument("--from", dest="from_wh", required=True) parser.add_argument("--to", dest="to_wh", required=True) parser.add_argument("--quantity", type=float, required=True) parser.add_argument("--apply", action="store_true", help="Ejecuta el POST real (por defecto es dry-run)") args = parser.parse_args() main(args.store_config, args.from_wh, args.to_wh, args.quantity, dry_run=not args.apply)