""" Dry-run del IncomingPayment: para una o más órdenes de una tienda descarga detalle y transacciones de Shopify (GET), toma la Invoice de SAP si la orden ya está integrada (GET) o una sintética si no, y muestra el JSON de pago que se enviaría. NO escribe en SAP ni en la base de datos. Uso: python -m tools.probar_pago [...] """ import json import sys from decimal import Decimal from pathlib import Path from core.config import cargar_config_tienda from core.db import db_session from core.sap import SAPServiceLayerClient from core.shopify_client import ShopifyClient from domain.payment import PaymentConfigError, construir_incoming_payment, transacciones_efectivas STORES_DIR = Path(__file__).resolve().parent.parent / "config" / "stores" def _invoice(sap: SAPServiceLayerClient, store_code: str, order_id: int, detalle: dict) -> tuple[dict, str]: with db_session() as conn: row = conn.execute( """ SELECT d.sap_doc_entry FROM order_documents d JOIN orders o ON o.sys_id = d.order_sys_id WHERE o.store_code = ? AND o.shopify_order_id = ? AND d.doc_type = 'INVOICE' AND d.status = 'created' """, (store_code, order_id), ).fetchone() if row: return sap.forward("GET", f"Invoices({row['sap_doc_entry']})").json(), f"Invoice real DocEntry {row['sap_doc_entry']}" sintetica = { "DocEntry": 0, "CardCode": "C99998", "CardName": "(Invoice sintética)", "DocDate": detalle["created_at"][:10], "DocumentLines": [{"Quantity": 1, "PriceAfterVAT": float(detalle["total_price"])}], } return sintetica, "Invoice sintética (orden aún sin Invoice en SAP)" def main() -> None: store_code, ids = sys.argv[1], [int(x) for x in sys.argv[2:]] cfg = cargar_config_tienda(STORES_DIR / f"{store_code}.json") shopify = ShopifyClient.from_store_config(cfg["shopify"]) sap = SAPServiceLayerClient.from_store_config(cfg["sap_connection"]) for order_id in ids: print(f"\n===== Orden {order_id} =====") detalle = shopify.obtener_orden(order_id) transacciones = shopify.obtener_transacciones(order_id) invoice, origen = _invoice(sap, store_code, order_id, detalle) total = sum(Decimal(str(l["Quantity"])) * Decimal(str(l["PriceAfterVAT"])) for l in invoice["DocumentLines"]) print(f"{detalle.get('name')} | payment_gateway_names={detalle.get('payment_gateway_names')} | total_price={detalle.get('total_price')}") print(f"{len(transacciones)} transacciones -> {len(transacciones_efectivas(transacciones))} efectivas | {origen} | total Invoice={total}") try: payload = construir_incoming_payment(detalle, transacciones, cfg, invoice, invoice["DocEntry"], float(total)) print(json.dumps(payload, indent=2, ensure_ascii=False)) except PaymentConfigError as exc: print(f"ERROR (no se crearía el pago): {exc}") if __name__ == "__main__": main()