|
|
|
@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
import { TaskService } from '../../../tasks/service';
|
|
|
|
|
|
|
|
import { GroupSyncService } from '../../group-sync';
|
|
|
|
|
|
|
|
import { ICONS } from '../../../utils/icons';
|
|
|
|
|
|
|
|
import { codeId, formatDDMM, italic } from '../../../utils/formatting';
|
|
|
|
|
|
|
|
import { parseMultipleIds, resolveTaskIdFromInput, enforceMembership } from '../shared';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Ctx = {
|
|
|
|
|
|
|
|
sender: string;
|
|
|
|
|
|
|
|
groupId: string;
|
|
|
|
|
|
|
|
message: string;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Msg = {
|
|
|
|
|
|
|
|
recipient: string;
|
|
|
|
|
|
|
|
message: string;
|
|
|
|
|
|
|
|
mentions?: string[];
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function handleTomar(context: Ctx): Promise<Msg[]> {
|
|
|
|
|
|
|
|
const tokens = (context.message || '').trim().split(/\s+/);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { ids, truncated } = parseMultipleIds(tokens.slice(2), 10);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Sin IDs: ayuda de uso
|
|
|
|
|
|
|
|
if (ids.length === 0) {
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: 'ℹ️ Uso: `/t tomar 26` o múltiples: `/t tomar 12 19 50` o `/t tomar 12,19,50` (máx. 10)'
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Caso de 1 ID: mantener comportamiento actual
|
|
|
|
|
|
|
|
if (ids.length === 1) {
|
|
|
|
|
|
|
|
const idInput = ids[0];
|
|
|
|
|
|
|
|
const resolvedId = resolveTaskIdFromInput(idInput);
|
|
|
|
|
|
|
|
if (!resolvedId) {
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: `⚠️ Tarea ${codeId(idInput)} no encontrada.`
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const task = TaskService.getTaskById(resolvedId);
|
|
|
|
|
|
|
|
if (!task) {
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: `⚠️ Tarea ${codeId(resolvedId)} no encontrada.`
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!enforceMembership(context.sender, task)) {
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: 'No puedes tomar esta tarea porque no eres de este grupo.'
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const res = TaskService.claimTask(resolvedId, context.sender);
|
|
|
|
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (res.status === 'not_found') {
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: `⚠️ Tarea ${codeId(resolvedId)} no encontrada.`
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res.status === 'completed') {
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: `ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res.status === 'already') {
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: `ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya la tenías — ${res.task?.description || '(sin descripción)'}${due}`
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const lines = [
|
|
|
|
|
|
|
|
italic(`${ICONS.take} Has tomado ${codeId(resolvedId, res.task?.display_code)}`),
|
|
|
|
|
|
|
|
`${res.task?.description || '(sin descripción)'}`,
|
|
|
|
|
|
|
|
res.task?.due_date ? `${ICONS.date} ${formatDDMM(res.task?.due_date)}` : ''
|
|
|
|
|
|
|
|
].filter(Boolean);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: lines.join('\n')
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Modo múltiple
|
|
|
|
|
|
|
|
let cntClaimed = 0, cntAlready = 0, cntCompleted = 0, cntNotFound = 0, cntBlocked = 0;
|
|
|
|
|
|
|
|
const lines: string[] = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (truncated) {
|
|
|
|
|
|
|
|
lines.push('⚠️ Se procesarán solo los primeros 10 IDs.');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const idInput of ids) {
|
|
|
|
|
|
|
|
const resolvedId = resolveTaskIdFromInput(idInput);
|
|
|
|
|
|
|
|
if (!resolvedId) {
|
|
|
|
|
|
|
|
lines.push(`⚠️ ${codeId(idInput)} no encontrada.`);
|
|
|
|
|
|
|
|
cntNotFound++;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const task = TaskService.getTaskById(resolvedId);
|
|
|
|
|
|
|
|
if (task && !enforceMembership(context.sender, task)) {
|
|
|
|
|
|
|
|
lines.push(`🚫 ${codeId(resolvedId)} — no permitido (no eres miembro activo).`);
|
|
|
|
|
|
|
|
cntBlocked++;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const res = TaskService.claimTask(resolvedId, context.sender);
|
|
|
|
|
|
|
|
const due = res.task?.due_date ? ` — ${ICONS.date} ${formatDDMM(res.task?.due_date)}` : '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (res.status === 'already') {
|
|
|
|
|
|
|
|
lines.push(`ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya la tenías — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
|
|
|
|
cntAlready++;
|
|
|
|
|
|
|
|
} else if (res.status === 'claimed') {
|
|
|
|
|
|
|
|
lines.push(`${ICONS.take} ${codeId(resolvedId, res.task?.display_code)} tomada — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
|
|
|
|
cntClaimed++;
|
|
|
|
|
|
|
|
} else if (res.status === 'completed') {
|
|
|
|
|
|
|
|
lines.push(`ℹ️ ${codeId(resolvedId, res.task?.display_code)} ya estaba completada — ${res.task?.description || '(sin descripción)'}${due}`);
|
|
|
|
|
|
|
|
cntCompleted++;
|
|
|
|
|
|
|
|
} else if (res.status === 'not_found') {
|
|
|
|
|
|
|
|
lines.push(`⚠️ ${codeId(resolvedId)} no encontrada.`);
|
|
|
|
|
|
|
|
cntNotFound++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Resumen final
|
|
|
|
|
|
|
|
const summary: string[] = [];
|
|
|
|
|
|
|
|
if (cntClaimed) summary.push(`tomadas ${cntClaimed}`);
|
|
|
|
|
|
|
|
if (cntAlready) summary.push(`ya las tenías ${cntAlready}`);
|
|
|
|
|
|
|
|
if (cntCompleted) summary.push(`ya completadas ${cntCompleted}`);
|
|
|
|
|
|
|
|
if (cntNotFound) summary.push(`no encontradas ${cntNotFound}`);
|
|
|
|
|
|
|
|
if (cntBlocked) summary.push(`bloqueadas ${cntBlocked}`);
|
|
|
|
|
|
|
|
if (summary.length) {
|
|
|
|
|
|
|
|
lines.push('');
|
|
|
|
|
|
|
|
lines.push(`Resumen: ${summary.join(', ')}.`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [{
|
|
|
|
|
|
|
|
recipient: context.sender,
|
|
|
|
|
|
|
|
message: lines.join('\n')
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
}
|