El sistema trata toda entrada de inventario como compra al proveedor:
apps/api/src/modules/inventory-movement/inventory-movement.service.ts:79-83 actualiza Supplier.lastSupply en cualquier movimiento in, incluidas las devoluciones de venta (historial/page.tsx, "Devolución venta #N") y los ajustes por conteo físico (inventario/[id]/page.tsx, "Ajuste por conteo físico").
La pantalla del proveedor (apps/web/src/app/admin/proveedores/[id]/page.tsx:24-29) lista como "compras" todas las entradas de sus productos, con las devoluciones y los ajustes incluidos.
El único dato para distinguirlas es el texto libre reason.
Entorno
local
Módulos
Proveedores, Inventario / almacenes, Punto de venta (POS), API / backend
Severidad
Molesta; hay workaround
Pasos para reproducir
Tener un producto con proveedor asignado y anotar su "Último abastecimiento".
Vender el producto y luego hacer la devolución desde Historial de ventas.
Abrir el detalle del proveedor.
Repetir con un conteo físico que aumente el stock del producto.
Esperado
La fecha de último abastecimiento y la lista de compras del proveedor solo reflejan entradas por compra.
Actual
La devolución y el ajuste cambian la fecha de último abastecimiento y aparecen en la lista de compras del proveedor.
Evidencia
Encontrado en auditoría de código; no reproducido en ejecución.
// inventory-movement.service.ts — en la rama de entrada, sin importar el motivo
const product= await this.productService.findById({ id: data.productId }).catch(()=> null);if(product?.supplierId){
await this.supplierService.update({ id: product.supplierId }, { lastSupply: new Date().toISOString()});}
// proveedores/[id]/page.tsx:27
.filter((m)=> m.type ==="in"&& supplierProductIds.has(m.productId))
Arreglo sugerido: agregar a InventoryMovement un campo de motivo con valores cerrados (purchase, sale, return, adjustment), como enum del contrato (#2). Actualizar lastSupply y listar compras solo con purchase. Workaround: revisar el texto de reason en la lista.
¿Está también en producción?
Sí — este issue no basta; hay que abrir un Incidente / hotfix
No — solo local / staging
No sé
Antes de abrir
Busqué un issue duplicado
### Qué pasa
El sistema trata toda entrada de inventario como compra al proveedor:
- `apps/api/src/modules/inventory-movement/inventory-movement.service.ts:79-83` actualiza `Supplier.lastSupply` en **cualquier** movimiento `in`, incluidas las devoluciones de venta (`historial/page.tsx`, "Devolución venta #N") y los ajustes por conteo físico (`inventario/[id]/page.tsx`, "Ajuste por conteo físico").
- La pantalla del proveedor (`apps/web/src/app/admin/proveedores/[id]/page.tsx:24-29`) lista como "compras" todas las entradas de sus productos, con las devoluciones y los ajustes incluidos.
El único dato para distinguirlas es el texto libre `reason`.
### Entorno
local
### Módulos
Proveedores, Inventario / almacenes, Punto de venta (POS), API / backend
### Severidad
Molesta; hay workaround
### Pasos para reproducir
1. Tener un producto con proveedor asignado y anotar su "Último abastecimiento".
2. Vender el producto y luego hacer la devolución desde **Historial de ventas**.
3. Abrir el detalle del proveedor.
4. Repetir con un conteo físico que aumente el stock del producto.
### Esperado
La fecha de último abastecimiento y la lista de compras del proveedor solo reflejan entradas por compra.
### Actual
La devolución y el ajuste cambian la fecha de último abastecimiento y aparecen en la lista de compras del proveedor.
### Evidencia
```shell
Encontrado en auditoría de código; no reproducido en ejecución.
// inventory-movement.service.ts — en la rama de entrada, sin importar el motivo
const product = await this.productService.findById({ id: data.productId }).catch(() => null);
if (product?.supplierId) {
await this.supplierService.update({ id: product.supplierId }, { lastSupply: new Date().toISOString() });
}
// proveedores/[id]/page.tsx:27
.filter((m) => m.type === "in" && supplierProductIds.has(m.productId))
```
Arreglo sugerido: agregar a `InventoryMovement` un campo de motivo con valores cerrados (`purchase`, `sale`, `return`, `adjustment`), como enum del contrato (#2). Actualizar `lastSupply` y listar compras solo con `purchase`. Workaround: revisar el texto de `reason` en la lista.
### ¿Está también en producción?
- [ ] Sí — este issue no basta; hay que abrir un Incidente / hotfix
- [ ] No — solo local / staging
- [x] No sé
### Antes de abrir
- [x] Busqué un issue duplicado
Emmanuel
was assigned by Carlos2026-10-02 20:03:30 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Qué pasa
El sistema trata toda entrada de inventario como compra al proveedor:
apps/api/src/modules/inventory-movement/inventory-movement.service.ts:79-83actualizaSupplier.lastSupplyen cualquier movimientoin, incluidas las devoluciones de venta (historial/page.tsx, "Devolución venta #N") y los ajustes por conteo físico (inventario/[id]/page.tsx, "Ajuste por conteo físico").apps/web/src/app/admin/proveedores/[id]/page.tsx:24-29) lista como "compras" todas las entradas de sus productos, con las devoluciones y los ajustes incluidos.El único dato para distinguirlas es el texto libre
reason.Entorno
local
Módulos
Proveedores, Inventario / almacenes, Punto de venta (POS), API / backend
Severidad
Molesta; hay workaround
Pasos para reproducir
Esperado
La fecha de último abastecimiento y la lista de compras del proveedor solo reflejan entradas por compra.
Actual
La devolución y el ajuste cambian la fecha de último abastecimiento y aparecen en la lista de compras del proveedor.
Evidencia
Arreglo sugerido: agregar a
InventoryMovementun campo de motivo con valores cerrados (purchase,sale,return,adjustment), como enum del contrato (#2). ActualizarlastSupplyy listar compras solo conpurchase. Workaround: revisar el texto dereasonen la lista.¿Está también en producción?
Antes de abrir