97 lines
2.7 KiB
TypeScript
97 lines
2.7 KiB
TypeScript
import {
|
|
updateAssignment,
|
|
updateDemandRequirement,
|
|
} from "@capakraken/application";
|
|
import type { PrismaClient } from "@capakraken/db";
|
|
import {
|
|
assertTimelineProjectShiftValid,
|
|
buildTimelineProjectShiftEventPayload,
|
|
buildTimelineProjectShiftValidation,
|
|
type LoadedTimelineShiftContext,
|
|
} from "./timeline-shift-support.js";
|
|
import {
|
|
buildTimelineProjectDateRangeUpdate,
|
|
buildTimelineProjectShiftAuditChanges,
|
|
buildTimelineShiftedAssignmentUpdate,
|
|
recalculateShiftedAssignmentDailyCost,
|
|
} from "./timeline-shift-mutation-support.js";
|
|
|
|
export interface ApplyTimelineProjectShiftInput {
|
|
db: PrismaClient;
|
|
projectId: string;
|
|
newStartDate: Date;
|
|
newEndDate: Date;
|
|
context: LoadedTimelineShiftContext;
|
|
}
|
|
|
|
export async function applyTimelineProjectShift(input: ApplyTimelineProjectShiftInput) {
|
|
const validation = buildTimelineProjectShiftValidation({
|
|
context: input.context,
|
|
newStartDate: input.newStartDate,
|
|
newEndDate: input.newEndDate,
|
|
});
|
|
assertTimelineProjectShiftValid(validation);
|
|
|
|
const updatedProject = await input.db.$transaction(async (tx) => {
|
|
const projectRecord = await tx.project.update({
|
|
where: { id: input.projectId },
|
|
data: buildTimelineProjectDateRangeUpdate(input),
|
|
});
|
|
|
|
for (const demandRequirement of input.context.demandRequirements) {
|
|
await updateDemandRequirement(
|
|
tx as unknown as Parameters<typeof updateDemandRequirement>[0],
|
|
demandRequirement.id,
|
|
buildTimelineProjectDateRangeUpdate(input),
|
|
);
|
|
}
|
|
|
|
for (const assignment of input.context.assignments) {
|
|
const dailyCostCents = await recalculateShiftedAssignmentDailyCost({
|
|
db: input.db,
|
|
assignment,
|
|
newStartDate: input.newStartDate,
|
|
newEndDate: input.newEndDate,
|
|
});
|
|
|
|
await updateAssignment(
|
|
tx as unknown as Parameters<typeof updateAssignment>[0],
|
|
assignment.id,
|
|
buildTimelineShiftedAssignmentUpdate({
|
|
newStartDate: input.newStartDate,
|
|
newEndDate: input.newEndDate,
|
|
dailyCostCents,
|
|
}),
|
|
);
|
|
}
|
|
|
|
await tx.auditLog.create({
|
|
data: {
|
|
entityType: "Project",
|
|
entityId: input.projectId,
|
|
action: "SHIFT",
|
|
changes: buildTimelineProjectShiftAuditChanges({
|
|
project: input.context.project,
|
|
newStartDate: input.newStartDate,
|
|
newEndDate: input.newEndDate,
|
|
validation,
|
|
}),
|
|
},
|
|
});
|
|
|
|
return projectRecord;
|
|
});
|
|
|
|
return {
|
|
project: updatedProject,
|
|
validation,
|
|
event: buildTimelineProjectShiftEventPayload({
|
|
projectId: input.projectId,
|
|
newStartDate: input.newStartDate,
|
|
newEndDate: input.newEndDate,
|
|
validation,
|
|
assignments: input.context.assignments,
|
|
}),
|
|
};
|
|
}
|