import { db } from "@/database/db"; import { tool, userTool } from "@/database/schema"; import { dbGetAll } from "@/lib/db/drizzle-client"; import { UserId } from "@/server/user/domain/models"; import { and, asc, eq, inArray, sql } from "drizzle-orm"; import { DeleteTool, Tool, UserTool, UserToolQuery } from "../domain/models"; import { createLogRecord } from "@/server/log"; import { ToolRepository } from "../domain/repositories"; import { DeleteUserToolDto } from "../application/dto"; class ToolRepositoryImpl implements ToolRepository { async getAll(): Promise { return dbGetAll("tool", { with: { userTool: { with: { user: true, }, }, }, orderBy: [asc(tool.id)], }); } async create(data: Tool, userId: UserId): Promise { await db.transaction(async (tx) => { const createPromise = tx.insert(tool).values(data).returning(); const logRecordPromise = createLogRecord(tx, { userId: userId.value, modifiedItem: `Herramienta-${data.name}`, eventType: "crear", tableName: "tool", item: data, }); await Promise.all([createPromise, logRecordPromise]); }); return data; } async delete(input: DeleteTool, userId: UserId): Promise { return await db.transaction(async (tx) => { const deletedTools = await tx .delete(tool) .where(inArray(tool.id, input.toolIds)) .returning(); const logRecordPromises = deletedTools.map((item) => createLogRecord(tx, { userId: userId.value, modifiedItem: `Material-${item.name}`, eventType: "eliminar", tableName: "materials", item: item, }) ); await Promise.all([...logRecordPromises]); return deletedTools; }); } async getUserTools(userId: UserId): Promise { const data = await db .select({ id: tool.id, name: tool.name, inStock: tool.quantity, assigned: userTool.quantity, totalAssignedUsers: sql`SUM(COALESCE(${userTool.quantity}, 0))`, }) .from(tool) .innerJoin( userTool, and(eq(tool.id, userTool.toolId), eq(userTool.userId, userId.value)) ) .groupBy(tool.id, userTool.quantity); return data as UserToolQuery[]; } async assignUserTools(data: UserTool[]): Promise { await db.transaction(async (tx) => { const assignToolPromises = data.map((item) => tx .insert(userTool) .values({ id: item.id!, ...item }) .onConflictDoUpdate({ target: [userTool.userId, userTool.toolId], set: { quantity: sql`${userTool.quantity} + ${item.quantity}` }, }) ); const logRecordPromises = data.map((item) => createLogRecord(tx, { userId: item.userId, modifiedItem: `Tool-${item.toolName}-asignada`, eventType: "crear", tableName: "userTool", item: item, }) ); await Promise.all([...assignToolPromises, ...logRecordPromises]); }); return data; } async deleteUserTools(data: DeleteUserToolDto[]):Promise{ await db.transaction(async(tx)=>{ const deleleUserTools = data?.map(({ toolId, userId }) => { return tx .delete(userTool) .where( and(eq(userTool.userId, userId), eq(userTool.toolId, toolId)) ); }); const logRecordPromises = data.map((item) => createLogRecord(tx, { userId: item?.userId!, modifiedItem: `Tool-${item?.toolName}-eliminada`, eventType: 'eliminar', tableName: "userTool", item: item!, }) ); await Promise.all([...deleleUserTools,...logRecordPromises]) }) return data } async updateAssignUserTools(data: UserTool[]): Promise { await db.transaction(async (tx) => { const updateAssignToolPromises = data.map((item) => tx .update(userTool) .set({ quantity: item?.quantity }) .where( and( eq(userTool.toolId, item?.toolId), eq(userTool.userId, item.userId) ) ) ); const logRecordPromises = data.map((item) => createLogRecord(tx, { userId: item?.userId!, modifiedItem: `Tool-${item?.toolName}-actualizada`, eventType: 'modificar', tableName: "userTool", item: item!, }) ); await Promise.all([...updateAssignToolPromises, ...logRecordPromises]); }); return data!; } async update( data: Partial, userId: UserId ): Promise> { await db.transaction(async (tx) => { const updatesPromises = data.map((item) => { return db .update(tool) .set(item!) .where(eq(tool.id, item?.id!)) .returning(); }); const logRecordPromises = data.map((item) => createLogRecord(tx, { userId: userId.value, modifiedItem: `Tool-${item?.name}-actualizada`, eventType: "crear", tableName: "tool", item: item!, }) ); await Promise.all([...updatesPromises, ...logRecordPromises]); }); return data; } } export const defaultToolRepository = new ToolRepositoryImpl();