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

# Productos

> Crear, consultar, actualizar y eliminar productos

**Permiso requerido:** `products`

<Note>
  Estos endpoints usan el formato de respuesta heredado `{ success, data, message }`.
</Note>

## Listar productos de una sucursal

```http theme={null}
GET /products/branch/{branch_id}
```

Devuelve los productos activos con su unidad de medida, categoría y porciones.

## Consultar producto

```http theme={null}
GET /products/{id}
```

Incluye `portions` y `components` cuando el producto tiene composición.

## Crear producto

```http theme={null}
POST /products
```

```json theme={null}
{
  "name": "Refresco 350ml",
  "sku": "BEB-001",
  "price_before_taxes": 1.11,
  "cost": 0.70,
  "tax_method": "is_taxed",
  "composition_type": "simple",
  "product_type": "phisical",
  "product_category_id": "uuid",
  "product_measurement_id": "uuid",
  "branch_id": "uuid",
  "availability": 100,
  "limit_availability": 10,
  "tax_ids": ["uuid-del-iva"]
}
```

| Campo | Requerido | Descripción |
| - | - | - |
| `name` | Sí | Nombre del producto. |
| `price_before_taxes` | Sí | Precio de venta sin impuestos. |
| `product_category_id` | Sí | Categoría. Ver `GET /product-categories`. |
| `product_measurement_id` | Sí | Unidad de medida. Ver `GET /product-measurements`. |
| `product_type` | Sí | `phisical` (bien), `service` (servicio) o `both`. |
| `tax_method` | Sí | `is_taxed` (gravado), `is_exent` (exento) o `is_not_subject` (no sujeto). |
| `composition_type` | Sí | `simple`, `with_portions` o `with_recipe`. |
| `branch_id` | Sí | Sucursal. |
| `availability` | Sí | Existencia inicial. |
| `limit_availability` | Sí | Existencia mínima (alerta de reorden). |
| `sku` | No | Código interno. |
| `cost` | No | Costo unitario. |
| `tax_ids` | No | IDs de los impuestos del producto. Obtén los válidos con [`GET /taxes/branch/{branch_id}`](#impuestos-del-producto). |

Al crear un bien con `availability` mayor a 0 se registra automáticamente una entrada de inventario.

## Impuestos del producto

Los impuestos se asignan con `tax_ids`. Son los que FileXpress usa para calcular los impuestos cuando el producto se vende desde la web, el POS o la app.

<Warning>
  `tax_method: "is_taxed"` solo marca el producto como gravado; **no le asigna impuestos**. Envía siempre `tax_ids` con al menos el IVA en productos gravados. Sin él, al vender el producto desde la web o el POS no se calcula el IVA.
</Warning>

<Steps>
  <Step title="Consultar los impuestos de la sucursal">
    ```http theme={null}
    GET /taxes/branch/{branch_id}
    ```

    Devuelve los impuestos del país de la sucursal. `is_default: true` indica el impuesto principal (el IVA en El Salvador).
  </Step>

  <Step title="Enviar sus IDs en tax_ids al crear o actualizar el producto" />
</Steps>

```json theme={null}
{
  "status": true,
  "data": [
    { "id": "uuid", "name": "IVA", "number_code": "20", "tax_type": "percentage", "percent": 0.13, "value": 0, "is_default": true, "document_types": null, "country_code": "SV" },
    { "id": "uuid", "name": "FOVIAL", "number_code": "D1", "tax_type": "fixed_unit", "percent": 0, "value": 0.20, "is_default": false, "document_types": null, "country_code": "SV" }
  ]
}
```

| Campo | Descripción |
| - | - |
| `tax_type` | `percentage` (porcentaje sobre la base gravada, en `percent`) o `fixed_unit` (monto fijo por unidad, en `value`). |
| `number_code` | Código del impuesto según Hacienda. |
| `document_types` | Tipos de documento a los que aplica (`null` = todos). |

**Reglas**

* Solo se aceptan impuestos del país de la sucursal del producto; un ID inválido responde error de validación.
* En la creación, si no envías `tax_ids` el producto queda sin impuestos.
* En la actualización, si no envías `tax_ids` se conservan los impuestos actuales; si envías `[]` se quitan todos.
* Las respuestas de productos incluyen `taxes` con los impuestos asignados.

### Producto con porciones

Con `composition_type: "with_portions"` son obligatorios `base_unit_quantity` y `base_unit`:

```json theme={null}
{
  "base_unit_quantity": 1000,
  "base_unit": "ml",
  "portions": [
    { "portion_name": "Vaso 250ml", "portion_quantity": 250, "portion_unit": "ml", "portion_price": 0.44, "is_active": true }
  ]
}
```

### Producto con receta

Con `composition_type: "with_recipe"`:

```json theme={null}
{
  "components": [
    { "component_product_id": "uuid-ingrediente", "quantity_needed": 2, "unit_type": "base" }
  ]
}
```

## Actualizar producto

```http theme={null}
PUT /products/{id}
```

Acepta los mismos campos que la creación, incluido `tax_ids`. Si cambia `availability`, se registra un ajuste de inventario. Si cambia `composition_type`, las porciones o componentes anteriores se reemplazan.

## Eliminar producto

```http theme={null}
DELETE /products/{id}
```

Eliminación lógica: el producto deja de aparecer en los listados.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.