104 lines
4.6 KiB
TypeScript
104 lines
4.6 KiB
TypeScript
import { sql } from "drizzle-orm";
|
|
import { authorize, rows, TimeService } from "../../modules/time-v2/service";
|
|
import { timeActor, uuid } from "./time-v2";
|
|
import { FastifyInstance } from 'fastify'
|
|
import { StaffTimeEntryConnect } from '../../types/staff'
|
|
import { asc, eq } from "drizzle-orm";
|
|
import { stafftimenetryconnects } from "../../../db/schema";
|
|
|
|
export default async function staffTimeConnectRoutes(server: FastifyInstance) {
|
|
server.addHook('preHandler', async (req, reply) => {
|
|
try {
|
|
const a = timeActor(req), params = req.params as any;
|
|
const id = uuid(params.id || params.connectId);
|
|
const [owner] = await rows(server.db, params.id
|
|
? sql`SELECT e.user_id,e.id FROM staff_time_entries e WHERE e.id=${id}::uuid AND e.tenant_id=${a.tenant}`
|
|
: sql`SELECT e.user_id,e.id FROM staff_time_entry_connects c JOIN staff_time_entries e ON e.id=c.time_entry_id WHERE c.id=${id}::uuid AND e.tenant_id=${a.tenant}`);
|
|
if (!owner) return reply.code(404).send({error:'Zeiteintrag nicht gefunden.'});
|
|
authorize(a,owner.user_id,req.method === 'GET' ? 'read' : 'write');
|
|
const service = new TimeService(server.db);
|
|
if (await service.active(a,owner.user_id)) {
|
|
if (req.method !== 'GET') return reply.code(409).send({error:'Projektzeiten unter 2.0 → Zeiterfassung bearbeiten.'});
|
|
const [origin] = await rows(server.db,sql`SELECT span_id FROM staff_time_span_origins WHERE tenant_id=${a.tenant} AND source_kind='entry' AND source_id=${owner.id}::uuid`);
|
|
const span = origin ? await service.get(a,origin.span_id) : null;
|
|
return reply.send((span?.projects || []).map(p => ({...p,stopped_at:p.ended_at})));
|
|
}
|
|
} catch (e:any) { return reply.code(e.statusCode || 400).send({error:e.message}); }
|
|
});
|
|
|
|
|
|
// ▶ Connect anlegen
|
|
server.post<{ Params: { id: string }, Body: Omit<StaffTimeEntryConnect, 'id' | 'time_entry_id'> }>(
|
|
'/staff/time/:id/connects',
|
|
async (req, reply) => {
|
|
const { id } = req.params
|
|
const { started_at, stopped_at, project_id, notes } = req.body
|
|
const parsedProjectId = project_id ? Number(project_id) : null
|
|
|
|
const data = await server.db
|
|
.insert(stafftimenetryconnects)
|
|
.values({
|
|
stafftimeentry: id,
|
|
started_at: new Date(started_at),
|
|
stopped_at: new Date(stopped_at),
|
|
project_id: parsedProjectId,
|
|
notes
|
|
})
|
|
.returning()
|
|
|
|
return reply.send(data[0])
|
|
}
|
|
)
|
|
|
|
// ▶ Connects abrufen
|
|
server.get<{ Params: { id: string } }>(
|
|
'/staff/time/:id/connects',
|
|
async (req, reply) => {
|
|
const { id } = req.params
|
|
const data = await server.db
|
|
.select()
|
|
.from(stafftimenetryconnects)
|
|
.where(eq(stafftimenetryconnects.stafftimeentry, id))
|
|
.orderBy(asc(stafftimenetryconnects.started_at))
|
|
|
|
return reply.send(data)
|
|
}
|
|
)
|
|
|
|
// ▶ Connect aktualisieren
|
|
server.patch<{ Params: { connectId: string }, Body: Partial<StaffTimeEntryConnect> }>(
|
|
'/staff/time/connects/:connectId',
|
|
async (req, reply) => {
|
|
const { connectId } = req.params
|
|
const patchData = Object.fromEntries(Object.entries(req.body).filter(([key]) =>
|
|
['started_at', 'stopped_at', 'project_id', 'notes'].includes(key))) as any
|
|
if (patchData.started_at) patchData.started_at = new Date(patchData.started_at)
|
|
if (patchData.stopped_at) patchData.stopped_at = new Date(patchData.stopped_at)
|
|
if (patchData.project_id !== undefined) {
|
|
patchData.project_id = patchData.project_id ? Number(patchData.project_id) : null
|
|
}
|
|
|
|
const data = await server.db
|
|
.update(stafftimenetryconnects)
|
|
.set({ ...patchData, updated_at: new Date() })
|
|
.where(eq(stafftimenetryconnects.id, connectId))
|
|
.returning()
|
|
|
|
return reply.send(data[0])
|
|
}
|
|
)
|
|
|
|
// ▶ Connect löschen
|
|
server.delete<{ Params: { connectId: string } }>(
|
|
'/staff/time/connects/:connectId',
|
|
async (req, reply) => {
|
|
const { connectId } = req.params
|
|
await server.db
|
|
.delete(stafftimenetryconnects)
|
|
.where(eq(stafftimenetryconnects.id, connectId))
|
|
|
|
return reply.send({ success: true })
|
|
}
|
|
)
|
|
}
|