---
name: shopify-costo-descuentos
description: "Solo lectura: mide cuánto dinero (en la moneda de la tienda) se ha dado en descuentos por semana, mes o trimestre, desglosado por tipo de descuento y por código. Úsala cuando quieras saber si tu gasto en descuentos sube o baja y qué campañas lo impulsan."
---

## Propósito
Mide cuánto dinero regaló la tienda en descuentos a lo largo del tiempo, agrupado por semana, mes o trimestre, y desglosado por código de descuento y por tipo de descuento (porcentaje / monto fijo / envío gratis / automático). Responde a la pregunta: «¿nuestro gasto en descuentos va en aumento o en descenso, y qué campañas lo están impulsando?». Solo lectura: no hace cambios. Complementa a `shopify-roi-descuentos` (retorno por descuento) con una vista en el tiempo del costo total.

## Requisitos
- Sesión autenticada de Shopify CLI: `shopify store auth --store <tu-tienda>.myshopify.com --scopes read_orders`
- Las consultas se ejecutan con `shopify store execute`.
- Permisos (scopes) de API: `read_orders`

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | string | sí | — | Dominio de la tienda (p. ej., mitienda.myshopify.com) |
| period | string | no | month | Tamaño de cada periodo: `week`, `month` o `quarter` |
| periods_back | integer | no | 12 | Cantidad de periodos que se reportan |
| top_codes | integer | no | 10 | Cuántos de los códigos de descuento principales se muestran por separado; el resto se agrupa como `other` |
| include_shipping_discounts | bool | no | true | Si los descuentos en envío se suman a los totales |
| format | string | no | human | Formato de salida: `human` o `json` |

## Seguridad

> ℹ️ Skill de solo lectura: no ejecuta mutaciones. Puedes correrla en cualquier momento sin riesgo.

## Pasos

1. Calcula la ventana a partir de `period` × `periods_back` (p. ej., `month` × 12 → los últimos 12 meses calendario, desde el primer día del periodo de hace 11 meses)

2. **OPERACIÓN:** `orders` — consulta
   **Entradas:** `query: "created_at:>='<window_start>' financial_status:paid"`, `first: 250`, selecciona `createdAt`, `discountCodes`, `currentTotalDiscountsSet`, `totalDiscountsSet`, `cartDiscountAmountSet`, `discountApplications { allocationMethod, targetType, value, ... on DiscountCodeApplication { code }, ... on AutomaticDiscountApplication { title }, ... on ManualDiscountApplication { title } }`, `shippingLines { discountAllocations { allocatedAmountSet } }` y el cursor de paginación
   **Resultado esperado:** Todos los pedidos pagados de la ventana con sus datos de descuento; pagina hasta que `hasNextPage: false`

3. Para cada pedido, asigna el costo del descuento:
   - `cart_discount` = `currentTotalDiscountsSet.shopMoney.amount`
   - `shipping_discount` = suma de `shippingLines.discountAllocations.allocatedAmountSet` (solo si `include_shipping_discounts: true`)
   - `total_discount` = cart_discount + shipping_discount
   - Asignación por código: usa el primer `discountApplications.code` en los descuentos con código, y `title` en los automáticos o manuales

4. Ubica cada pedido en su periodo (semana del año, año-mes o año-trimestre) y suma:
   - Costo total en descuentos por periodo
   - Por código de descuento y por periodo
   - Por tipo de descuento y por periodo (porcentaje, monto fijo, envío, automático)

5. Identifica los códigos con mayor costo total en toda la ventana; suma el resto como `other`

## Operaciones GraphQL

```graphql
# orders:query — validada con api_version 2025-01
query DiscountCostTrend($query: String!, $after: String) {
  orders(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        name
        createdAt
        discountCodes
        currentTotalDiscountsSet { shopMoney { amount currencyCode } }
        totalDiscountsSet { shopMoney { amount currencyCode } }
        cartDiscountAmountSet { shopMoney { amount currencyCode } }
        discountApplications(first: 10) {
          edges {
            node {
              allocationMethod
              targetType
              targetSelection
              value {
                ... on PricingPercentageValue { percentage }
                ... on MoneyV2 { amount currencyCode }
              }
              ... on DiscountCodeApplication { code }
              ... on AutomaticDiscountApplication { title }
              ... on ManualDiscountApplication { title description }
            }
          }
        }
        shippingLines(first: 5) {
          edges {
            node {
              title
              discountAllocations {
                allocatedAmountSet { shopMoney { amount currencyCode } }
              }
            }
          }
        }
      }
    }
    pageInfo { hasNextPage endCursor }
  }
}
```

## Seguimiento de la sesión

**Claude DEBE mostrar lo siguiente en cada etapa. Es obligatorio.**

**Al iniciar**, muestra:
```
╔══════════════════════════════════════════════╗
║  SKILL: shopify-costo-descuentos             ║
║  Tienda: <dominio de la tienda>              ║
║  Periodo: <period> × <periods_back>          ║
║  Inicio: <AAAA-MM-DD HH:MM UTC>              ║
╚══════════════════════════════════════════════╝
```

**Después de cada paso**, muestra:
```
[N/TOTAL] <CONSULTA|MUTACIÓN>  <OperationName>
          → Parámetros: <resumen breve de las entradas clave>
          → Resultado: <cantidad o desenlace>
```

**Al terminar**, muestra:

Para `format: human` (predeterminado):
```
══════════════════════════════════════════════
COSTO DE DESCUENTOS EN EL TIEMPO  (últimos <periods_back> periodos de <period>)
  Montos en la moneda de la tienda.
  Costo total en descuentos:  <monto>
  Promedio por periodo:       <monto>
  Último periodo:             <monto>   (<delta_vs_prev_pct>% frente al anterior)

  Por periodo:
    2025-Q1  <n>   (carrito <n> / envío <n>)
    2025-Q2  <n>   (carrito <n> / envío <n>)

  Por tipo de descuento:
    código          <n>   (<pct>%)
    automático      <n>   (<pct>%)
    manual          <n>   (<pct>%)
    envío           <n>   (<pct>%)

  Códigos principales (por costo total):
    "<código>"      <n>   (<pct>%)
    "<código>"      <n>   (<pct>%)
    otros           <n>   (<pct>%)

  Archivo: discount_cost_trend_<fecha>.csv
══════════════════════════════════════════════
```

Para `format: json`, muestra:
```json
{
  "skill": "shopify-costo-descuentos",
  "store": "<dominio>",
  "period": "month",
  "periods_back": 12,
  "total_discount_cost": 0,
  "by_bucket": [],
  "by_type": { "code": 0, "automatic": 0, "manual": 0, "shipping": 0 },
  "top_codes": [],
  "currency": "<moneda de la tienda>",
  "output_file": "discount_cost_trend_<fecha>.csv"
}
```

## Formato de salida
Archivo CSV `discount_cost_trend_<AAAA-MM-DD>.csv` con las columnas:
`bucket`, `discount_code_or_title`, `discount_type`, `orders_count`, `cart_discount`, `shipping_discount`, `total_discount`, `currency`

## Manejo de errores
| Error | Causa | Solución |
|-------|-------|----------|
| `THROTTLED` | Se superó el límite de solicitudes de la API | Espera 2 segundos y reintenta hasta 3 veces |
| Códigos de descuento combinados | Varios códigos en un mismo pedido | Reparte el costo entre los códigos según la proporción de su `value`, o márcalo como `multi-code` si son iguales |
| Descuento manual sin título | Lo ingresó un cajero sin título | Agrúpalo como `manual:untitled` |
| Pedidos en varias monedas | La moneda de presentación es distinta de la moneda de la tienda | Suma sobre `shopMoney.amount` (moneda de la tienda) para que los totales sean consistentes |

## Buenas prácticas
- Usa `period: week` en negocios muy promocionales con campañas frecuentes; `period: month` en tiendas con ofertas permanentes y estables; `period: quarter` para reportes a la junta o a los socios.
- Una tendencia plana o al alza sin campañas activas suele indicar que **los descuentos automáticos se están acumulando**: revisa los descuentos automáticos que no tienen fecha de fin.
- Compara el último periodo con `shopify-roi-descuentos` para verificar que el aumento de costo esté trayendo un aumento equivalente en ingresos.
- Usa `include_shipping_discounts: false` si tu contabilidad registra el subsidio de envío aparte de los descuentos en productos.
- Automatízala cada mes: si el gasto en descuentos se pasa del presupuesto, debería activar una revisión financiera antes de que aparezca en los reportes de margen.
