refactor(api): extract timeline allocation batch shift support
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
buildSplitAllocationReadModel,
|
||||
createAssignment,
|
||||
findAllocationEntry,
|
||||
loadAllocationEntry,
|
||||
updateAllocationEntry,
|
||||
} from "@capakraken/application";
|
||||
@@ -25,11 +24,10 @@ import {
|
||||
buildTimelineAllocationEntryUpdate,
|
||||
buildTimelineAllocationMetadata,
|
||||
buildTimelineAllocationUpdateAuditChanges,
|
||||
buildTimelineBatchShiftAuditChanges,
|
||||
buildTimelineQuickAssignAssignmentInput,
|
||||
shiftTimelineAllocationWindow,
|
||||
validateTimelineAllocationDateRanges,
|
||||
} from "./timeline-allocation-mutation-support.js";
|
||||
import { applyTimelineBatchAllocationShift } from "./timeline-allocation-shift-support.js";
|
||||
import { calculateTimelineAllocationDailyCost } from "./timeline-cost-support.js";
|
||||
|
||||
export const timelineAllocationMutationProcedures = {
|
||||
@@ -227,63 +225,11 @@ export const timelineAllocationMutationProcedures = {
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
requirePermission(ctx, PermissionKey.MANAGE_ALLOCATIONS);
|
||||
|
||||
if (input.daysDelta === 0) {
|
||||
return { count: 0 };
|
||||
}
|
||||
|
||||
const entries = await Promise.all(
|
||||
input.allocationIds.map((allocationId) => findAllocationEntry(ctx.db, allocationId)),
|
||||
);
|
||||
const resolved = entries.filter(
|
||||
(entry): entry is NonNullable<typeof entry> => entry !== null,
|
||||
);
|
||||
|
||||
if (resolved.length === 0) {
|
||||
throw new TRPCError({ code: "NOT_FOUND", message: "No allocations found" });
|
||||
}
|
||||
|
||||
const results = await ctx.db.$transaction(async (tx) => {
|
||||
const updated = [];
|
||||
for (const entry of resolved) {
|
||||
const existing = entry.entry;
|
||||
const shiftedWindow = shiftTimelineAllocationWindow({
|
||||
startDate: existing.startDate,
|
||||
endDate: existing.endDate,
|
||||
daysDelta: input.daysDelta,
|
||||
mode: input.mode,
|
||||
});
|
||||
|
||||
const result = await updateAllocationEntry(
|
||||
tx as unknown as Parameters<typeof updateAllocationEntry>[0],
|
||||
{
|
||||
id: existing.id,
|
||||
demandRequirementUpdate: {
|
||||
startDate: shiftedWindow.startDate,
|
||||
endDate: shiftedWindow.endDate,
|
||||
},
|
||||
assignmentUpdate: {
|
||||
startDate: shiftedWindow.startDate,
|
||||
endDate: shiftedWindow.endDate,
|
||||
},
|
||||
},
|
||||
);
|
||||
updated.push(result.allocation);
|
||||
}
|
||||
|
||||
await tx.auditLog.create({
|
||||
data: {
|
||||
entityType: "Allocation",
|
||||
entityId: input.allocationIds.join(","),
|
||||
action: "UPDATE",
|
||||
changes: buildTimelineBatchShiftAuditChanges({
|
||||
mode: input.mode,
|
||||
daysDelta: input.daysDelta,
|
||||
count: resolved.length,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
return updated;
|
||||
const results = await applyTimelineBatchAllocationShift({
|
||||
db: ctx.db as PrismaClient,
|
||||
allocationIds: input.allocationIds,
|
||||
daysDelta: input.daysDelta,
|
||||
mode: input.mode,
|
||||
});
|
||||
|
||||
for (const allocation of results) {
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import { findAllocationEntry, updateAllocationEntry } from "@capakraken/application";
|
||||
import type { PrismaClient } from "@capakraken/db";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import {
|
||||
buildTimelineBatchShiftAuditChanges,
|
||||
shiftTimelineAllocationWindow,
|
||||
type TimelineBatchShiftMode,
|
||||
} from "./timeline-allocation-mutation-support.js";
|
||||
|
||||
export async function applyTimelineBatchAllocationShift(input: {
|
||||
db: PrismaClient;
|
||||
allocationIds: string[];
|
||||
daysDelta: number;
|
||||
mode: TimelineBatchShiftMode;
|
||||
}) {
|
||||
if (input.daysDelta === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const entries = await Promise.all(
|
||||
input.allocationIds.map((allocationId) => findAllocationEntry(input.db, allocationId)),
|
||||
);
|
||||
const resolved = entries.filter(
|
||||
(entry): entry is NonNullable<typeof entry> => entry !== null,
|
||||
);
|
||||
|
||||
if (resolved.length === 0) {
|
||||
throw new TRPCError({ code: "NOT_FOUND", message: "No allocations found" });
|
||||
}
|
||||
|
||||
return input.db.$transaction(async (tx) => {
|
||||
const updated = [];
|
||||
for (const entry of resolved) {
|
||||
const existing = entry.entry;
|
||||
const shiftedWindow = shiftTimelineAllocationWindow({
|
||||
startDate: existing.startDate,
|
||||
endDate: existing.endDate,
|
||||
daysDelta: input.daysDelta,
|
||||
mode: input.mode,
|
||||
});
|
||||
|
||||
const result = await updateAllocationEntry(
|
||||
tx as unknown as Parameters<typeof updateAllocationEntry>[0],
|
||||
{
|
||||
id: existing.id,
|
||||
demandRequirementUpdate: {
|
||||
startDate: shiftedWindow.startDate,
|
||||
endDate: shiftedWindow.endDate,
|
||||
},
|
||||
assignmentUpdate: {
|
||||
startDate: shiftedWindow.startDate,
|
||||
endDate: shiftedWindow.endDate,
|
||||
},
|
||||
},
|
||||
);
|
||||
updated.push(result.allocation);
|
||||
}
|
||||
|
||||
await tx.auditLog.create({
|
||||
data: {
|
||||
entityType: "Allocation",
|
||||
entityId: input.allocationIds.join(","),
|
||||
action: "UPDATE",
|
||||
changes: buildTimelineBatchShiftAuditChanges({
|
||||
mode: input.mode,
|
||||
daysDelta: input.daysDelta,
|
||||
count: resolved.length,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
return updated;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user