|
|
|
@ -71,7 +71,7 @@ export class CommandService {
|
|
|
|
if (low >= todayYMD) {
|
|
|
|
if (low >= todayYMD) {
|
|
|
|
dateCandidates.push({ index: i, ymd: low });
|
|
|
|
dateCandidates.push({ index: i, ymd: low });
|
|
|
|
dateTokenIndexes.add(i);
|
|
|
|
dateTokenIndexes.add(i);
|
|
|
|
}
|
|
|
|
const task = TaskService.getTaskById(resolvedId)!;
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -107,6 +107,14 @@ export class CommandService {
|
|
|
|
return { action, description, dueDate };
|
|
|
|
return { action, description, dueDate };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static async processTareaCommand(
|
|
|
|
private static async processTareaCommand(
|
|
|
|
context: CommandContext
|
|
|
|
context: CommandContext
|
|
|
|
): Promise<CommandResponse[]> {
|
|
|
|
): Promise<CommandResponse[]> {
|
|
|
|
@ -222,7 +230,7 @@ export class CommandService {
|
|
|
|
recipient: context.sender,
|
|
|
|
recipient: context.sender,
|
|
|
|
message: '_Este comando se usa en grupos. Prueba:_ `/t ver mis`'
|
|
|
|
message: '_Este comando se usa en grupos. Prueba:_ `/t ver mis`'
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
const task = TaskService.getTaskById(resolvedId)!;
|
|
|
|
if (!GroupSyncService.isGroupActive(context.groupId)) {
|
|
|
|
if (!GroupSyncService.isGroupActive(context.groupId)) {
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
recipient: context.sender,
|
|
|
|
recipient: context.sender,
|
|
|
|
@ -242,7 +250,7 @@ export class CommandService {
|
|
|
|
const rendered = items.map((t) => {
|
|
|
|
const rendered = items.map((t) => {
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${ICONS.unassigned} sin responsable`;
|
|
|
|
return `- ${codeId(t.id, t.display_code)} ${t.description || '(sin descripción)'}${datePart} — ${ICONS.unassigned} sin responsable`;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const total = TaskService.countGroupUnassigned(context.groupId);
|
|
|
|
const total = TaskService.countGroupUnassigned(context.groupId);
|
|
|
|
@ -291,7 +299,7 @@ export class CommandService {
|
|
|
|
: `${t.assignees!.length > 1 ? '👥' : '👤'} ${names.join(', ')}`;
|
|
|
|
: `${t.assignees!.length > 1 ? '👥' : '👤'} ${names.join(', ')}`;
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${owner}`;
|
|
|
|
return `- ${codeId(t.id, t.display_code)} ${t.description || '(sin descripción)'}${datePart} — ${owner}`;
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
sections.push(...rendered);
|
|
|
|
sections.push(...rendered);
|
|
|
|
sections.push('');
|
|
|
|
sections.push('');
|
|
|
|
@ -323,7 +331,7 @@ export class CommandService {
|
|
|
|
const renderedUnassigned = unassigned.map((t) => {
|
|
|
|
const renderedUnassigned = unassigned.map((t) => {
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${ICONS.unassigned} sin responsable`;
|
|
|
|
return `- ${codeId(t.id, t.display_code)} ${t.description || '(sin descripción)'}${datePart} — ${ICONS.unassigned} sin responsable`;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
sections.push(...renderedUnassigned);
|
|
|
|
sections.push(...renderedUnassigned);
|
|
|
|
|
|
|
|
|
|
|
|
@ -352,7 +360,7 @@ export class CommandService {
|
|
|
|
const renderedUnassigned = unassigned.map((t) => {
|
|
|
|
const renderedUnassigned = unassigned.map((t) => {
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${ICONS.unassigned} sin responsable`;
|
|
|
|
return `- ${codeId(t.id, t.display_code)} ${t.description || '(sin descripción)'}${datePart} — ${ICONS.unassigned} sin responsable`;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
sections.push(...renderedUnassigned);
|
|
|
|
sections.push(...renderedUnassigned);
|
|
|
|
|
|
|
|
|
|
|
|
@ -418,7 +426,7 @@ export class CommandService {
|
|
|
|
: `${t.assignees!.length > 1 ? '👥' : '👤'} ${names.join(', ')}`;
|
|
|
|
: `${t.assignees!.length > 1 ? '👥' : '👤'} ${names.join(', ')}`;
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${owner}`;
|
|
|
|
return `- ${codeId(t.id, t.display_code)} ${t.description || '(sin descripción)'}${datePart} — ${owner}`;
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
const total = TaskService.countGroupPending(context.groupId);
|
|
|
|
const total = TaskService.countGroupPending(context.groupId);
|
|
|
|
@ -469,7 +477,7 @@ export class CommandService {
|
|
|
|
: `${t.assignees!.length > 1 ? '👥' : '👤'} ${names.join(', ')}`;
|
|
|
|
: `${t.assignees!.length > 1 ? '👥' : '👤'} ${names.join(', ')}`;
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const isOverdue = t.due_date ? t.due_date < todayYMD : false;
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
const datePart = t.due_date ? ` — ${isOverdue ? `${ICONS.warn} ` : ''}${ICONS.date} ${formatDDMM(t.due_date)}` : '';
|
|
|
|
return `- ${codeId(t.id)} ${t.description || '(sin descripción)'}${datePart} — ${owner}`;
|
|
|
|
return `- ${codeId(t.id, t.display_code)} ${t.description || '(sin descripción)'}${datePart} — ${owner}`;
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
sections.push(...rendered);
|
|
|
|
sections.push(...rendered);
|
|
|
|
sections.push('');
|
|
|
|
sections.push('');
|
|
|
|
@ -516,9 +524,16 @@ export class CommandService {
|
|
|
|
|
|
|
|
|
|
|
|
// Caso de 1 ID: mantener comportamiento actual
|
|
|
|
// Caso de 1 ID: mantener comportamiento actual
|
|
|
|
if (ids.length === 1) {
|
|
|
|
if (ids.length === 1) {
|
|
|
|
const id = ids[0];
|
|
|
|
const idInput = ids[0];
|
|
|
|
|
|
|
|
const resolvedId = this.resolveTaskIdFromInput(idInput);
|
|
|
|
|
|
|
|
if (!resolvedId) {
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: `⚠️ Tarea ${codeId(idInput)} no encontrada.`
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const task = TaskService.getTaskById(id);
|
|
|
|
const task = TaskService.getTaskById(resolvedId);
|
|
|
|
if (!task) {
|
|
|
|
if (!task) {
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
recipient: context.sender,
|
|
|
|
recipient: context.sender,
|
|
|
|
@ -533,7 +548,7 @@ export class CommandService {
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const res = TaskService.completeTask(id, context.sender);
|
|
|
|
const res = TaskService.completeTask(resolvedId, context.sender);
|
|
|
|
const who = (await ContactsService.getDisplayName(context.sender)) || context.sender;
|
|
|
|
const who = (await ContactsService.getDisplayName(context.sender)) || context.sender;
|
|
|
|
if (res.status === 'not_found') {
|
|
|
|
if (res.status === 'not_found') {
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
@ -545,14 +560,14 @@ export class CommandService {
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
recipient: context.sender,
|
|
|
|
recipient: context.sender,
|
|
|
|
message: `ℹ️ ${codeId(id)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`
|
|
|
|
message: `ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
recipient: context.sender,
|
|
|
|
recipient: context.sender,
|
|
|
|
message: `${ICONS.complete} ${codeId(id)} completada — ${res.task?.description || '(sin descripción)'}${due}`
|
|
|
|
message: `${ICONS.complete} ${codeId(resolvedId, res.task?.display_code)} completada — ${res.task?.description || '(sin descripción)'}${due}`
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -565,10 +580,10 @@ export class CommandService {
|
|
|
|
lines.push('⚠️ Se procesarán solo los primeros 10 IDs.');
|
|
|
|
lines.push('⚠️ Se procesarán solo los primeros 10 IDs.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (const id of ids) {
|
|
|
|
for (const idInput of ids) {
|
|
|
|
const task = TaskService.getTaskById(id);
|
|
|
|
const resolvedId = this.resolveTaskIdFromInput(idInput);
|
|
|
|
if (!task) {
|
|
|
|
if (!resolvedId) {
|
|
|
|
lines.push(`⚠️ ${codeId(id)} no encontrada.`);
|
|
|
|
lines.push(`⚠️ ${codeId(idInput)} no encontrada.`);
|
|
|
|
cntNotFound++;
|
|
|
|
cntNotFound++;
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -579,16 +594,16 @@ export class CommandService {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const res = TaskService.completeTask(id, context.sender);
|
|
|
|
const res = TaskService.completeTask(resolvedId, context.sender);
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
if (res.status === 'already') {
|
|
|
|
if (res.status === 'already') {
|
|
|
|
lines.push(`ℹ️ ${codeId(id)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
lines.push(`ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
cntAlready++;
|
|
|
|
cntAlready++;
|
|
|
|
} else if (res.status === 'updated') {
|
|
|
|
} else if (res.status === 'updated') {
|
|
|
|
lines.push(`${ICONS.complete} ${codeId(id)} completada — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
lines.push(`${ICONS.complete} ${codeId(resolvedId, res.task?.display_code)} completada — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
cntUpdated++;
|
|
|
|
cntUpdated++;
|
|
|
|
} else if (res.status === 'not_found') {
|
|
|
|
} else if (res.status === 'not_found') {
|
|
|
|
lines.push(`⚠️ ${codeId(id)} no encontrada.`);
|
|
|
|
lines.push(`⚠️ ${codeId(resolvedId)} no encontrada.`);
|
|
|
|
cntNotFound++;
|
|
|
|
cntNotFound++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -636,9 +651,17 @@ export class CommandService {
|
|
|
|
|
|
|
|
|
|
|
|
// Caso de 1 ID: mantener comportamiento actual
|
|
|
|
// Caso de 1 ID: mantener comportamiento actual
|
|
|
|
if (ids.length === 1) {
|
|
|
|
if (ids.length === 1) {
|
|
|
|
const id = ids[0];
|
|
|
|
const idInput = ids[0];
|
|
|
|
|
|
|
|
|
|
|
|
const task = TaskService.getTaskById(id);
|
|
|
|
const resolvedId = this.resolveTaskIdFromInput(idInput);
|
|
|
|
|
|
|
|
if (!resolvedId) {
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: `⚠️ Tarea ${codeId(idInput)} no encontrada.`
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const task = TaskService.getTaskById(resolvedId);
|
|
|
|
if (!task) {
|
|
|
|
if (!task) {
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
recipient: context.sender,
|
|
|
|
recipient: context.sender,
|
|
|
|
@ -653,7 +676,7 @@ export class CommandService {
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const res = TaskService.claimTask(id, context.sender);
|
|
|
|
const res = TaskService.claimTask(resolvedId, context.sender);
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
|
|
|
|
|
|
|
|
if (res.status === 'not_found') {
|
|
|
|
if (res.status === 'not_found') {
|
|
|
|
@ -665,18 +688,18 @@ export class CommandService {
|
|
|
|
if (res.status === 'completed') {
|
|
|
|
if (res.status === 'completed') {
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
recipient: context.sender,
|
|
|
|
recipient: context.sender,
|
|
|
|
message: `ℹ️ ${codeId(id)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`
|
|
|
|
message: `ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (res.status === 'already') {
|
|
|
|
if (res.status === 'already') {
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
recipient: context.sender,
|
|
|
|
recipient: context.sender,
|
|
|
|
message: `ℹ️ ${codeId(id)} ya la tenías — ${res.task?.description || '(sin descripción)'}${due}`
|
|
|
|
message: `ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya la tenías — ${res.task?.description || '(sin descripción)'}${due}`
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const lines = [
|
|
|
|
const lines = [
|
|
|
|
italic(`${ICONS.take} Has tomado ${codeId(id)}`),
|
|
|
|
italic(`${ICONS.take} Has tomado ${codeId(resolvedId, res.task?.display_code)}`),
|
|
|
|
`${res.task?.description || '(sin descripción)'}`,
|
|
|
|
`${res.task?.description || '(sin descripción)'}`,
|
|
|
|
res.task?.due_date ? `${ICONS.date} ${formatDDMM(res.task?.due_date)}` : ''
|
|
|
|
res.task?.due_date ? `${ICONS.date} ${formatDDMM(res.task?.due_date)}` : ''
|
|
|
|
].filter(Boolean);
|
|
|
|
].filter(Boolean);
|
|
|
|
@ -695,10 +718,10 @@ export class CommandService {
|
|
|
|
lines.push('⚠️ Se procesarán solo los primeros 10 IDs.');
|
|
|
|
lines.push('⚠️ Se procesarán solo los primeros 10 IDs.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (const id of ids) {
|
|
|
|
for (const idInput of ids) {
|
|
|
|
const task = TaskService.getTaskById(id);
|
|
|
|
const resolvedId = this.resolveTaskIdFromInput(idInput);
|
|
|
|
if (!task) {
|
|
|
|
if (!resolvedId) {
|
|
|
|
lines.push(`⚠️ ${codeId(id)} no encontrada.`);
|
|
|
|
lines.push(`⚠️ ${codeId(idInput)} no encontrada.`);
|
|
|
|
cntNotFound++;
|
|
|
|
cntNotFound++;
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -709,19 +732,19 @@ export class CommandService {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const res = TaskService.claimTask(id, context.sender);
|
|
|
|
const res = TaskService.claimTask(resolvedId, context.sender);
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
if (res.status === 'already') {
|
|
|
|
if (res.status === 'already') {
|
|
|
|
lines.push(`ℹ️ ${codeId(id)} ya la tenías — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
lines.push(`ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya la tenías — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
cntAlready++;
|
|
|
|
cntAlready++;
|
|
|
|
} else if (res.status === 'claimed') {
|
|
|
|
} else if (res.status === 'claimed') {
|
|
|
|
lines.push(`${ICONS.take} ${codeId(id)} tomada — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
lines.push(`${ICONS.take} ${codeId(resolvedId, res.task?.display_code)} tomada — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
cntClaimed++;
|
|
|
|
cntClaimed++;
|
|
|
|
} else if (res.status === 'completed') {
|
|
|
|
} else if (res.status === 'completed') {
|
|
|
|
lines.push(`ℹ️ ${codeId(id)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
lines.push(`ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
cntCompleted++;
|
|
|
|
cntCompleted++;
|
|
|
|
} else if (res.status === 'not_found') {
|
|
|
|
} else if (res.status === 'not_found') {
|
|
|
|
lines.push(`⚠️ ${codeId(id)} no encontrada.`);
|
|
|
|
lines.push(`⚠️ ${codeId(resolvedId)} no encontrada.`);
|
|
|
|
cntNotFound++;
|
|
|
|
cntNotFound++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -747,15 +770,23 @@ export class CommandService {
|
|
|
|
// Soltar tarea (con validación opcional de membresía)
|
|
|
|
// Soltar tarea (con validación opcional de membresía)
|
|
|
|
if (action === 'soltar') {
|
|
|
|
if (action === 'soltar') {
|
|
|
|
const idToken = tokens[2];
|
|
|
|
const idToken = tokens[2];
|
|
|
|
const id = idToken ? parseInt(idToken, 10) : NaN;
|
|
|
|
const idInput = idToken ? parseInt(idToken, 10) : NaN;
|
|
|
|
if (!id || Number.isNaN(id)) {
|
|
|
|
if (!idInput || Number.isNaN(idInput)) {
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
recipient: context.sender,
|
|
|
|
recipient: context.sender,
|
|
|
|
message: 'ℹ️ Uso: `/t soltar 26`'
|
|
|
|
message: 'ℹ️ Uso: `/t soltar 26`'
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const task = TaskService.getTaskById(id);
|
|
|
|
const resolvedId = this.resolveTaskIdFromInput(idInput);
|
|
|
|
|
|
|
|
if (!resolvedId) {
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: `⚠️ Tarea ${codeId(idInput)} no encontrada.`
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const task = TaskService.getTaskById(resolvedId);
|
|
|
|
if (!task) {
|
|
|
|
if (!task) {
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
recipient: context.sender,
|
|
|
|
recipient: context.sender,
|
|
|
|
@ -770,7 +801,7 @@ export class CommandService {
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const res = TaskService.unassignTask(id, context.sender);
|
|
|
|
const res = TaskService.unassignTask(resolvedId, context.sender);
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
|
|
|
|
|
|
|
|
if (res.status === 'not_found') {
|
|
|
|
if (res.status === 'not_found') {
|
|
|
|
@ -794,7 +825,7 @@ export class CommandService {
|
|
|
|
|
|
|
|
|
|
|
|
if (res.now_unassigned) {
|
|
|
|
if (res.now_unassigned) {
|
|
|
|
const lines = [
|
|
|
|
const lines = [
|
|
|
|
`${ICONS.unassigned} ${codeId(id)}`,
|
|
|
|
`${ICONS.unassigned} ${codeId(resolvedId, res.task?.display_code)}`,
|
|
|
|
`${res.task?.description || '(sin descripción)'}`,
|
|
|
|
`${res.task?.description || '(sin descripción)'}`,
|
|
|
|
res.task?.due_date ? `${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '',
|
|
|
|
res.task?.due_date ? `${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '',
|
|
|
|
italic('queda sin responsable.')
|
|
|
|
italic('queda sin responsable.')
|
|
|
|
@ -806,7 +837,7 @@ export class CommandService {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const lines = [
|
|
|
|
const lines = [
|
|
|
|
`${ICONS.unassign} ${codeId(id)}`,
|
|
|
|
`${ICONS.unassign} ${codeId(resolvedId, res.task?.display_code)}`,
|
|
|
|
`${res.task?.description || '(sin descripción)'}`,
|
|
|
|
`${res.task?.description || '(sin descripción)'}`,
|
|
|
|
res.task?.due_date ? `${ICONS.date} ${formatDDMM(res.task?.due_date)}` : ''
|
|
|
|
res.task?.due_date ? `${ICONS.date} ${formatDDMM(res.task?.due_date)}` : ''
|
|
|
|
].filter(Boolean);
|
|
|
|
].filter(Boolean);
|
|
|
|
@ -964,6 +995,9 @@ export class CommandService {
|
|
|
|
}))
|
|
|
|
}))
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Recuperar la tarea creada para obtener display_code asignado
|
|
|
|
|
|
|
|
const createdTask = TaskService.getTaskById(taskId);
|
|
|
|
|
|
|
|
|
|
|
|
const mentionsForSending = assignmentUserIds.map(uid => `${uid}@s.whatsapp.net`);
|
|
|
|
const mentionsForSending = assignmentUserIds.map(uid => `${uid}@s.whatsapp.net`);
|
|
|
|
|
|
|
|
|
|
|
|
// Resolver nombres útiles
|
|
|
|
// Resolver nombres útiles
|
|
|
|
@ -986,7 +1020,7 @@ export class CommandService {
|
|
|
|
? `${ICONS.unassigned} sin responsable${groupName ? ` (${groupName})` : ''}`
|
|
|
|
? `${ICONS.unassigned} sin responsable${groupName ? ` (${groupName})` : ''}`
|
|
|
|
: `${assignmentUserIds.length > 1 ? '👥' : '👤'} ${assignedDisplayNames.join(', ')}`;
|
|
|
|
: `${assignmentUserIds.length > 1 ? '👥' : '👤'} ${assignedDisplayNames.join(', ')}`;
|
|
|
|
const ackLines = [
|
|
|
|
const ackLines = [
|
|
|
|
`${ICONS.create} ${codeId(taskId)} ${description || '(sin descripción)'}`,
|
|
|
|
`${ICONS.create} ${codeId(taskId, createdTask?.display_code)} ${description || '(sin descripción)'}`,
|
|
|
|
dueFmt ? `${ICONS.date} ${dueFmt}` : null,
|
|
|
|
dueFmt ? `${ICONS.date} ${dueFmt}` : null,
|
|
|
|
ownerPart
|
|
|
|
ownerPart
|
|
|
|
].filter(Boolean);
|
|
|
|
].filter(Boolean);
|
|
|
|
@ -1002,7 +1036,7 @@ export class CommandService {
|
|
|
|
responses.push({
|
|
|
|
responses.push({
|
|
|
|
recipient: uid,
|
|
|
|
recipient: uid,
|
|
|
|
message: [
|
|
|
|
message: [
|
|
|
|
`${ICONS.assignNotice} ${codeId(taskId)}`,
|
|
|
|
`${ICONS.assignNotice} ${codeId(taskId, createdTask?.display_code)}`,
|
|
|
|
`${description || '(sin descripción)'}`,
|
|
|
|
`${description || '(sin descripción)'}`,
|
|
|
|
formatDDMM(dueDate) ? `${ICONS.date} ${formatDDMM(dueDate)}` : null,
|
|
|
|
formatDDMM(dueDate) ? `${ICONS.date} ${formatDDMM(dueDate)}` : null,
|
|
|
|
groupName ? `Grupo: ${groupName}` : null,
|
|
|
|
groupName ? `Grupo: ${groupName}` : null,
|
|
|
|
|