Update
This commit is contained in:
1 parent
c01d747352
commit
235c19e51b
10 files changed
+175
-31
No files matched your search
+87
-8
@@ -354,6 +354,7 @@ type ZammadTicketImport = {
|
||||
teamspaceBudgetMinutes: number | null;
|
||||
teamspaceProject: string | null;
|
||||
teamspaceProjects: string[];
|
||||
pendingTime: string | null;
|
||||
};
|
||||
|
||||
type ZammadSyncExistingFields = {
|
||||
@@ -363,6 +364,7 @@ type ZammadSyncExistingFields = {
|
||||
projectName: boolean;
|
||||
budget: boolean;
|
||||
overrideBudget: boolean;
|
||||
pendingTodo: boolean;
|
||||
};
|
||||
|
||||
type ZammadSyncChange = {
|
||||
@@ -490,10 +492,17 @@ function parseZammadTeamspaceProjects(value: unknown) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return value
|
||||
.split("+")
|
||||
.map((part) => part.trim())
|
||||
.filter(Boolean);
|
||||
return value.match(/[^\s+]+/g) ?? [];
|
||||
}
|
||||
|
||||
function parseZammadPendingTime(value: unknown) {
|
||||
if (typeof value !== "string" || !value.trim()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const date = new Date(value);
|
||||
|
||||
return Number.isNaN(date.getTime()) ? null : date.toISOString();
|
||||
}
|
||||
|
||||
function zammadPreferenceValue(ticket: Record<string, unknown>, key: string) {
|
||||
@@ -700,7 +709,8 @@ function zammadTicketImportFromRaw(rawTicket: Record<string, unknown>, fallbackT
|
||||
preferences,
|
||||
teamspaceBudgetMinutes: parseZammadBudgetMinutes(zammadPreferenceValue(rawTicket, "gesamtbudget")),
|
||||
teamspaceProject: teamspaceProjects[0] ?? null,
|
||||
teamspaceProjects
|
||||
teamspaceProjects,
|
||||
pendingTime: parseZammadPendingTime(zammadPreferenceValue(rawTicket, "pending_time"))
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1883,7 +1893,8 @@ function zammadSyncExistingFields(value: unknown): ZammadSyncExistingFields {
|
||||
type: optionalBoolean(source.type, false),
|
||||
projectName: optionalBoolean(source.projectName, false),
|
||||
budget: optionalBoolean(source.budget, false),
|
||||
overrideBudget: optionalBoolean(source.overrideBudget, false)
|
||||
overrideBudget: optionalBoolean(source.overrideBudget, false),
|
||||
pendingTodo: optionalBoolean(source.pendingTodo, false)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2014,7 +2025,8 @@ function zammadSyncSnapshot(zammadTicket: ZammadTicketImport) {
|
||||
preferences: zammadTicket.preferences,
|
||||
teamspaceProject: zammadTicket.teamspaceProject,
|
||||
teamspaceProjects: zammadTicket.teamspaceProjects,
|
||||
teamspaceBudgetMinutes: zammadTicket.teamspaceBudgetMinutes
|
||||
teamspaceBudgetMinutes: zammadTicket.teamspaceBudgetMinutes,
|
||||
pendingTime: zammadTicket.pendingTime
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2051,7 +2063,8 @@ function zammadTicketFromSyncSnapshot(snapshot: Record<string, unknown> | null):
|
||||
teamspaceProject: typeof snapshot.teamspaceProject === "string" && snapshot.teamspaceProject.trim() ? snapshot.teamspaceProject.trim() : null,
|
||||
teamspaceProjects: Array.isArray(snapshot.teamspaceProjects)
|
||||
? snapshot.teamspaceProjects.map((entry) => (typeof entry === "string" ? entry.trim() : "")).filter(Boolean)
|
||||
: parseZammadTeamspaceProjects(snapshot.teamspaceProject)
|
||||
: parseZammadTeamspaceProjects(snapshot.teamspaceProject),
|
||||
pendingTime: parseZammadPendingTime(snapshot.pendingTime)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2160,6 +2173,63 @@ function formatTeamspaceProjectList(projects: Array<string | null | undefined>)
|
||||
return projects.map((project) => project?.trim()).filter(Boolean).join(" + ");
|
||||
}
|
||||
|
||||
function zammadPendingTodoPayload(zammadTicket: ZammadTicketImport) {
|
||||
if ((zammadTicket.zammadStateId !== 3 && zammadTicket.zammadStateId !== 7) || !zammadTicket.pendingTime) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const kind = zammadTicket.zammadStateId === 7 ? "Abschluss" : "Erinnerung";
|
||||
const day = zammadTicket.pendingTime.slice(0, 10);
|
||||
const ticketLabel = zammadTicket.ticketNumber.replace(/^Ticket#?/i, "").replace(/^#/, "");
|
||||
|
||||
return {
|
||||
day,
|
||||
title: `${kind} ${ticketLabel ? `Ticket#${ticketLabel}` : "Ticket"}`,
|
||||
description: `${kind} für dieses Ticket prüfen.`
|
||||
};
|
||||
}
|
||||
|
||||
async function zammadPendingTodoExists(client: QueryClient, ticketId: string, userId: string, zammadTicket: ZammadTicketImport) {
|
||||
const payload = zammadPendingTodoPayload(zammadTicket);
|
||||
|
||||
if (!payload) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const result = await client.query<{ exists: boolean }>(
|
||||
`
|
||||
SELECT EXISTS (
|
||||
SELECT 1
|
||||
FROM ticket_todos
|
||||
WHERE ticket_id = $1
|
||||
AND user_id = $2
|
||||
AND title = $3
|
||||
AND starts_on = $4::date
|
||||
AND ends_on = $4::date
|
||||
) AS exists;
|
||||
`,
|
||||
[ticketId, userId, payload.title, payload.day]
|
||||
);
|
||||
|
||||
return Boolean(result.rows[0]?.exists);
|
||||
}
|
||||
|
||||
async function ensureZammadPendingTodo(client: QueryClient, ticketId: string, userId: string, zammadTicket: ZammadTicketImport) {
|
||||
const payload = zammadPendingTodoPayload(zammadTicket);
|
||||
|
||||
if (!payload || await zammadPendingTodoExists(client, ticketId, userId, zammadTicket)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await client.query(
|
||||
`
|
||||
INSERT INTO ticket_todos (ticket_id, user_id, title, description, priority, starts_on, ends_on, sort_order)
|
||||
VALUES ($1, $2, $3, $4, 'high', $5::date, $5::date, (SELECT COALESCE(MAX(sort_order), 0) + 1024 FROM ticket_todos WHERE user_id = $2));
|
||||
`,
|
||||
[ticketId, userId, payload.title, payload.description, payload.day]
|
||||
);
|
||||
}
|
||||
|
||||
async function syncProjectTeamspaceEntriesFromZammad(
|
||||
client: QueryClient,
|
||||
projectId: string,
|
||||
@@ -2251,6 +2321,11 @@ async function planExistingZammadTicketSync(
|
||||
addSyncChange(changes, "Zammad-Priorität", localTicket.zammad_priority_id, zammadTicket.zammadPriorityId);
|
||||
addSyncChange(changes, "Zammad-Status", localTicket.zammad_state_id, zammadTicket.zammadStateId);
|
||||
|
||||
const pendingTodo = zammadPendingTodoPayload(zammadTicket);
|
||||
if (fields.pendingTodo && pendingTodo && !(await zammadPendingTodoExists(client, localTicket.id, userId, zammadTicket))) {
|
||||
changes.push({ field: "ToDo", from: null, to: `${pendingTodo.title} (${pendingTodo.day})` });
|
||||
}
|
||||
|
||||
if (zammadTicket.workType === "support" && zammadTicket.zammadStateId === 4) {
|
||||
return changes.length > 0
|
||||
? {
|
||||
@@ -2579,6 +2654,10 @@ async function applyZammadTicketSync(
|
||||
);
|
||||
}
|
||||
|
||||
if (fields.pendingTodo) {
|
||||
await ensureZammadPendingTodo(client, localTicket.id, userId, zammadTicket);
|
||||
}
|
||||
|
||||
if (!metadataOnly && fields.type && zammadTicket.workType === "support") {
|
||||
await deleteAllProjectDataForTicket(client, localTicket.id);
|
||||
await client.query(
|
||||
|
||||
Reference in new issue
Block a user