feat(mi-dia): tabs Mis oportunidades/Mis apartados con fases y cotizador vinculado
- Resumen Mi día: misOportunidades.items (lista de trabajo con perfil y último cambio) y misApartados (Vendedor = yo, estados no finales) - Nuevos endpoints: POST /oportunidades/:id/etapa (Agendo Cita, Afluencia, Cotizador, Aparto, No Asistio, Abandono; con fecha de cita) y POST /apartados/:id/estado (pipeline Enkontrol: Pago Apartado → Firma Cliente (Venta) / Cancelacion Apartado); ambos mueven el item al grupo Monday correspondiente - Mi día: tabs Mis leads / Mis oportunidades / Mis apartados; botón Cotizar abre /quote con el cliente prellenado y la oportunidad ligada - Cotizador: prefill desde query params (cliente, teléfono, email, desarrollo, unidad) y envío de oportunidadId; al guardar, el API actualiza ESE item (Precio final, Tipo propuesta, etapa Cotizador) en vez de buscar por teléfono o crear duplicado - grupos-estado: 'Cancelacion Apartado' → Historico - Estados finales de apartado: agrega Firma Cliente (Venta) y Cancelacion Apartado - Tests: 455 API + 14 mi-dia + 88 cotizador, todo en verde
This commit is contained in:
68
api-gateway/src/controllers/apartados.controller.test.ts
Normal file
68
api-gateway/src/controllers/apartados.controller.test.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
cambiarEstadoApartado,
|
||||
FASES_APARTADO_PERMITIDAS,
|
||||
} from './apartados.controller.js'
|
||||
|
||||
/** Monday mockeado: registra cambios de columna y movimientos de grupo */
|
||||
function mondayMock(grupoActual = 'topics') {
|
||||
return {
|
||||
cambios: [] as { boardId: string; itemId: string; columna: string; valor: unknown }[],
|
||||
movimientos: [] as { itemId: string; grupo: string }[],
|
||||
async cambiarValorColumna(boardId: string, itemId: string, columna: string, valor: string | number | boolean) {
|
||||
this.cambios.push({ boardId, itemId, columna, valor })
|
||||
},
|
||||
async columnaIdPorTitulo(_boardId: string, titulo: string) {
|
||||
return titulo === 'Estado' ? 'status' : null
|
||||
},
|
||||
async getItemConGrupo(itemId: string) {
|
||||
return {
|
||||
id: itemId,
|
||||
name: 'Cliente Demo',
|
||||
groupId: grupoActual,
|
||||
column_values: [
|
||||
{ id: 'status', text: (this.cambios.find((c) => c.columna === 'Estado')?.valor as string) ?? '', value: '{}' },
|
||||
],
|
||||
}
|
||||
},
|
||||
async moverItemAGrupo(itemId: string, grupo: string) {
|
||||
this.movimientos.push({ itemId, grupo })
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
describe('cambiarEstadoApartado (POST /api/apartados/:id/estado)', () => {
|
||||
it('cambia la fase (board 666 = MONDAY_BOARD_APARTADO de test)', async () => {
|
||||
const monday = mondayMock()
|
||||
await cambiarEstadoApartado(monday, 'apt-1', 'Alta Enkontrol')
|
||||
expect(monday.cambios).toEqual([
|
||||
{ boardId: '666', itemId: 'apt-1', columna: 'Estado', valor: 'Alta Enkontrol' },
|
||||
])
|
||||
// 'Alta Enkontrol' mapea al grupo topics: ya estaba ahí → no se mueve
|
||||
expect(monday.movimientos).toEqual([])
|
||||
})
|
||||
|
||||
it('Firma Cliente (Venta) mueve el item a "Clientes Activos"', async () => {
|
||||
const monday = mondayMock()
|
||||
await cambiarEstadoApartado(monday, 'apt-2', 'Firma Cliente (Venta)')
|
||||
expect(monday.movimientos).toEqual([{ itemId: 'apt-2', grupo: 'group_mm6sx3rn' }])
|
||||
})
|
||||
|
||||
it('Cancelacion Apartado mueve el item a "Historico"', async () => {
|
||||
const monday = mondayMock()
|
||||
await cambiarEstadoApartado(monday, 'apt-3', 'Cancelacion Apartado')
|
||||
expect(monday.movimientos).toEqual([{ itemId: 'apt-3', grupo: 'group_mm6s2yyx' }])
|
||||
})
|
||||
|
||||
it('las fases permitidas son los labels reales del board Apartado', () => {
|
||||
expect(FASES_APARTADO_PERMITIDAS).toEqual([
|
||||
'Pago Apartado',
|
||||
'Alta Enkontrol',
|
||||
'Entrego Documentacion',
|
||||
'Cita Clientes',
|
||||
'Contrato Enkontrol',
|
||||
'Firma Cliente (Venta)',
|
||||
'Cancelacion Apartado',
|
||||
])
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user