> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lapyme.com.ar/llms.txt
> Use this file to discover all available pages before exploring further.

# Presupuestos

> Listá, creá, reemplazá y eliminá presupuestos con importes canónicos y reservas de stock seguras.

La API de presupuestos permite sincronizar borradores comerciales sin copiar la
lógica de numeración, impuestos, descuentos ni reservas de La Pyme.

Las lecturas requieren `quotes:read`:

* `GET /api/v1/quotes`
* `GET /api/v1/quotes/{quote_id}`

Las escrituras requieren `quotes:write` e `Idempotency-Key`:

* `POST /api/v1/quotes`
* `PUT /api/v1/quotes/{quote_id}`
* `DELETE /api/v1/quotes/{quote_id}`

## Crear un presupuesto

Enviá el cliente y por lo menos una línea. Los importes usan centavos. La Pyme
asigna `number`, calcula `subtotal`, `tax_amount`, `discount_amount` y `total`,
y guarda los datos de auditoría.

En `items[].discount`, un descuento `amount` usa centavos enteros. Un descuento
`percentage` puede usar decimales, pero debe estar entre `0` y `100`.

```bash theme={null}
curl -X POST "https://api.lapyme.com.ar/api/v1/quotes" \
  -H "Authorization: Bearer $LAPYME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: erp:quote:Q-1042" \
  -d '{
    "customer_id": "550e8400-e29b-41d4-a716-446655440802",
    "items": [
      {
        "product_id": "550e8400-e29b-41d4-a716-446655440804",
        "quantity": 2,
        "unit_price": 12100
      }
    ],
    "expires_at": "2026-09-15",
    "notes": "Entrega coordinada",
    "reservation": { "enabled": false }
  }'
```

No envíes `number`, `formatted_number`, `status`, `subtotal`, `tax_amount`,
`discount_amount`, `total`, `created_at`, `updated_at` ni
`converted_sale_id`. El contrato rechaza estos campos y otros campos
desconocidos.

La respuesta incluye el recurso persistido. `idempotent_replay` es `true`
cuando la misma clave y el mismo cuerpo ya habían terminado con éxito.

## Listar y obtener

La colección se ordena por `created_at` e `id` descendentes. Podés usar:

* `query` para buscar por cliente o número de presupuesto.
* `customer_id` para filtrar un cliente.
* `status` con `draft`, `sent`, `accepted`, `rejected`, `expired` o
  `converted`.
* `limit` y `cursor` para paginar.

```bash theme={null}
curl "https://api.lapyme.com.ar/api/v1/quotes?status=draft&customer_id=550e8400-e29b-41d4-a716-446655440802&limit=25" \
  -H "Authorization: Bearer $LAPYME_API_KEY"
```

La lista devuelve importes de cabecera e `items_count`. Usá el detalle para
leer los datos persistidos de cada línea, los totales históricos de cabecera,
las notas, el vencimiento y la reserva activa. Las líneas no incluyen
`subtotal`, `tax_amount` ni `total` porque el presupuesto no guarda hechos
impositivos exactos por línea.

## Reemplazar un borrador

`PUT` reemplaza la representación mutable completa. Incluí de nuevo el cliente
y todas las líneas que deben quedar guardadas. Omitir `price_list_id`,
`salesperson_member_id`, `expires_at`, `notes`, `global_discount_amount` o
`reservation` los limpia o vuelve a su valor default.

Solo podés reemplazar un presupuesto con `status: "draft"`. Otro estado
responde `409 STATE_CONFLICT` con el detalle estable `QUOTE_NOT_DRAFT`.

## Reservar stock

Para reservar, cada línea de producto físico debe tener `warehouse_id` y la
reserva debe incluir `reserved_through_date`:

```json theme={null}
{
  "reservation": {
    "enabled": true,
    "reserved_through_date": "2026-09-30"
  }
}
```

La respuesta puede incluir `warnings` con `product_id`, `warehouse_id`,
`requested_quantity` y `available_quantity`. Estas advertencias informan stock
insuficiente cuando la política de la organización permite continuar. Si la
política bloquea stock negativo, la API responde `422` y no guarda cambios.

`reserved_through_date` debe ser la fecha actual de Argentina o una fecha
posterior. Si también enviás `expires_at`, debe ser igual o anterior a esa
fecha. La API rechaza reservas vencidas y reservas que terminen después del
presupuesto.

Un `PUT` ajusta o libera la reserva dentro de la misma transacción que actualiza
el presupuesto. Un `DELETE` de borrador libera la reserva activa y elimina el
presupuesto de forma atómica. La respuesta de eliminación informa
`reservation_released`.

## Idempotencia y errores

Repetí la misma operación con la misma `Idempotency-Key` después de un timeout
o un error `5xx`. Reusar la clave con otro cuerpo devuelve
`409 IDEMPOTENCY_CONFLICT`. Las referencias inexistentes, inactivas, ocultas o
de otra organización devuelven `404` sin revelar datos de otro tenant.

Las validaciones ocurren antes de confirmar el presupuesto. Un error de
cliente, producto, depósito, vendedor, estado o stock no deja una numeración,
reserva o presupuesto parcial.
