diff --git a/src/services/command.ts b/src/services/command.ts index 751c86a..7cb3e0b 100644 --- a/src/services/command.ts +++ b/src/services/command.ts @@ -156,11 +156,8 @@ export class CommandService { } private static resolveTaskIdFromInput(n: number): number | null { - // Resolver primero por display_code en tareas activas; si no, por PK const byCode = TaskService.getActiveTaskByDisplayCode(n); - if (byCode) return byCode.id; - const byId = TaskService.getTaskById(n); - return byId ? byId.id : null; + return byCode ? byCode.id : null; } private static async processTareaCommand( @@ -903,7 +900,7 @@ export class CommandService { if (res.now_unassigned) { const lines = [ - `${ICONS.unassigned} ${codeId(resolvedId, res.task?.display_code)} (${resolvedId})`, + `${ICONS.unassigned} ${codeId(resolvedId, res.task?.display_code)}`, `${res.task?.description || '(sin descripción)'}`, res.task?.due_date ? `${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '', italic('queda sin responsable.') @@ -1279,8 +1276,8 @@ export class CommandService { `${description || '(sin descripción)'}`, formatDDMM(dueDate) ? `${ICONS.date} ${formatDDMM(dueDate)}` : null, groupName ? `Grupo: ${groupName}` : null, - `- Completar: \`/t x ${taskId}\``, - `- Soltar: \`/t soltar ${taskId}\`` + `- Completar: \`/t x ${createdTask?.display_code}\``, + `- Soltar: \`/t soltar ${createdTask?.display_code}\`` ].filter(Boolean).join('\n'), mentions: [creatorJid] }); diff --git a/src/tasks/service.ts b/src/tasks/service.ts index b3014c4..847d718 100644 --- a/src/tasks/service.ts +++ b/src/tasks/service.ts @@ -607,7 +607,7 @@ export class TaskService { const row = this.dbInstance.prepare(` SELECT id, description, due_date, display_code FROM tasks - WHERE display_code = ? AND COALESCE(completed, 0) = 0 + WHERE display_code = ? AND COALESCE(completed, 0) = 0 AND completed_at IS NULL LIMIT 1 `).get(displayCode) as any; if (!row) return null; diff --git a/tests/unit/services/command.claim-unassign.test.ts b/tests/unit/services/command.claim-unassign.test.ts index c0c2683..acd9c73 100644 --- a/tests/unit/services/command.claim-unassign.test.ts +++ b/tests/unit/services/command.claim-unassign.test.ts @@ -36,6 +36,15 @@ describe('CommandService - /t tomar y /t soltar', () => { return taskId; } + function getDisplayCode(id: number): number { + const row = memdb.prepare('SELECT display_code FROM tasks WHERE id = ?').get(id) as any; + return Number(row?.display_code || 0); + } + + function code4(n: number): string { + return '`' + String(n).padStart(4, '0') + '`'; + } + const ctx = (sender: string, message: string) => ({ sender, groupId: '', // DM o vacío; sin relevancia para tomar/soltar @@ -57,13 +66,14 @@ describe('CommandService - /t tomar y /t soltar', () => { it('tomar: happy y luego already', async () => { const taskId = createTask('Desc tomar', '999', '2025-09-12'); - const r1 = await CommandService.handle(ctx('111', `/t tomar ${taskId}`)); + const dc = getDisplayCode(taskId); + const r1 = await CommandService.handle(ctx('111', `/t tomar ${dc}`)); expect(r1[0].message).toContain('Has tomado'); - expect(r1[0].message).toContain(String(taskId)); + expect(r1[0].message).toContain(code4(dc)); expect(r1[0].message).toContain('Desc tomar'); expect(r1[0].message).toContain('📅'); // formato dd/MM - const r2 = await CommandService.handle(ctx('111', `/t tomar ${taskId}`)); + const r2 = await CommandService.handle(ctx('111', `/t tomar ${dc}`)); expect(r2[0].message).toContain('ya la tenías'); }); @@ -72,7 +82,8 @@ describe('CommandService - /t tomar y /t soltar', () => { const comp = TaskService.completeTask(taskId, '111'); expect(comp.status).toBe('updated'); - const res = await CommandService.handle(ctx('222', `/t tomar ${taskId}`)); + const dc = getDisplayCode(taskId); + const res = await CommandService.handle(ctx('222', `/t tomar ${dc}`)); expect(res[0].message).toContain('ya estaba completada'); }); @@ -88,13 +99,15 @@ describe('CommandService - /t tomar y /t soltar', () => { it('soltar: personal única asignación → denegado', async () => { const taskId = createTask('Desc soltar', '999', '2025-09-12', ['111']); - const res = await CommandService.handle(ctx('111', `/t soltar ${taskId}`)); + const dc = getDisplayCode(taskId); + const res = await CommandService.handle(ctx('111', `/t soltar ${dc}`)); expect(res[0].message).toContain('No puedes soltar una tarea personal. Márcala como completada para eliminarla'); }); it('soltar: not_assigned muestra mensaje informativo', async () => { const taskId = createTask('Nunca asignada a 111', '999', null, ['222']); - const res = await CommandService.handle(ctx('111', `/t soltar ${taskId}`)); + const dc = getDisplayCode(taskId); + const res = await CommandService.handle(ctx('111', `/t soltar ${dc}`)); expect(res[0].message).toContain('no la tenías asignada'); }); @@ -103,7 +116,8 @@ describe('CommandService - /t tomar y /t soltar', () => { const comp = TaskService.completeTask(taskId, '111'); expect(comp.status).toBe('updated'); - const res = await CommandService.handle(ctx('111', `/t soltar ${taskId}`)); + const dc = getDisplayCode(taskId); + const res = await CommandService.handle(ctx('111', `/t soltar ${dc}`)); expect(res[0].message).toContain('ya estaba completada'); }); });