Add functionality to copy weekly shift assignments to the following week
Introduce a new POST API endpoint `/api/shift-assignments/copy-week` to duplicate existing shift assignments and their associated shifts for a specified location and week, automatically adjusting dates by adding 7 days. Replit-Commit-Author: Agent Replit-Commit-Session-Id: e0b5b11c-5b75-4389-8ea9-5f3cd9332f88 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/6d543d2c-20b9-4ea6-93fe-70fe9b1d9f80/e0b5b11c-5b75-4389-8ea9-5f3cd9332f88/EDxr1e6
This commit is contained in:
parent
36bfad3815
commit
0b64fd2f08
123
server/routes.ts
123
server/routes.ts
@ -1337,6 +1337,129 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
// Copy weekly shift assignments to next week
|
||||
app.post("/api/shift-assignments/copy-week", isAuthenticated, async (req, res) => {
|
||||
try {
|
||||
const { weekStart, location } = req.body;
|
||||
|
||||
if (!weekStart || !location) {
|
||||
return res.status(400).json({ message: "Missing required fields: weekStart, location" });
|
||||
}
|
||||
|
||||
// Parse week start date
|
||||
const [year, month, day] = weekStart.split("-").map(Number);
|
||||
if (!year || !month || !day) {
|
||||
return res.status(400).json({ message: "Invalid weekStart format. Expected YYYY-MM-DD" });
|
||||
}
|
||||
|
||||
// Calculate week boundaries (Monday to Sunday)
|
||||
const weekStartDate = new Date(year, month - 1, day, 0, 0, 0, 0);
|
||||
const weekEndDate = new Date(year, month - 1, day + 6, 23, 59, 59, 999);
|
||||
|
||||
console.log("📋 Copying weekly shifts:", {
|
||||
weekStart: weekStartDate.toISOString(),
|
||||
weekEnd: weekEndDate.toISOString(),
|
||||
location
|
||||
});
|
||||
|
||||
// Transaction: copy all shifts and assignments
|
||||
const result = await db.transaction(async (tx) => {
|
||||
// 1. Find all shifts in the source week filtered by location
|
||||
const sourceShifts = await tx
|
||||
.select({
|
||||
shift: shifts,
|
||||
site: sites
|
||||
})
|
||||
.from(shifts)
|
||||
.innerJoin(sites, eq(shifts.siteId, sites.id))
|
||||
.where(
|
||||
and(
|
||||
gte(shifts.startTime, weekStartDate),
|
||||
lte(shifts.startTime, weekEndDate),
|
||||
eq(sites.location, location)
|
||||
)
|
||||
);
|
||||
|
||||
if (sourceShifts.length === 0) {
|
||||
throw new Error("Nessun turno trovato nella settimana selezionata");
|
||||
}
|
||||
|
||||
console.log(`📋 Found ${sourceShifts.length} shifts to copy`);
|
||||
|
||||
let copiedShiftsCount = 0;
|
||||
let copiedAssignmentsCount = 0;
|
||||
|
||||
// 2. For each shift, copy to next week (+7 days)
|
||||
for (const { shift: sourceShift, site } of sourceShifts) {
|
||||
// Calculate new dates (+7 days)
|
||||
const newStartTime = new Date(sourceShift.startTime);
|
||||
newStartTime.setDate(newStartTime.getDate() + 7);
|
||||
|
||||
const newEndTime = new Date(sourceShift.endTime);
|
||||
newEndTime.setDate(newEndTime.getDate() + 7);
|
||||
|
||||
// Create new shift
|
||||
const [newShift] = await tx
|
||||
.insert(shifts)
|
||||
.values({
|
||||
siteId: sourceShift.siteId,
|
||||
startTime: newStartTime,
|
||||
endTime: newEndTime,
|
||||
status: "planned",
|
||||
vehicleId: sourceShift.vehicleId,
|
||||
notes: sourceShift.notes,
|
||||
})
|
||||
.returning();
|
||||
|
||||
copiedShiftsCount++;
|
||||
|
||||
// 3. Copy all assignments for this shift
|
||||
const sourceAssignments = await tx
|
||||
.select()
|
||||
.from(shiftAssignments)
|
||||
.where(eq(shiftAssignments.shiftId, sourceShift.id));
|
||||
|
||||
for (const sourceAssignment of sourceAssignments) {
|
||||
// Calculate new planned times (+7 days)
|
||||
const newPlannedStart = new Date(sourceAssignment.plannedStartTime);
|
||||
newPlannedStart.setDate(newPlannedStart.getDate() + 7);
|
||||
|
||||
const newPlannedEnd = new Date(sourceAssignment.plannedEndTime);
|
||||
newPlannedEnd.setDate(newPlannedEnd.getDate() + 7);
|
||||
|
||||
// Create new assignment
|
||||
await tx
|
||||
.insert(shiftAssignments)
|
||||
.values({
|
||||
shiftId: newShift.id,
|
||||
guardId: sourceAssignment.guardId,
|
||||
plannedStartTime: newPlannedStart,
|
||||
plannedEndTime: newPlannedEnd,
|
||||
isArmedOnDuty: sourceAssignment.isArmedOnDuty,
|
||||
assignedVehicleId: sourceAssignment.assignedVehicleId,
|
||||
});
|
||||
|
||||
copiedAssignmentsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return { copiedShiftsCount, copiedAssignmentsCount };
|
||||
});
|
||||
|
||||
res.json({
|
||||
message: `Settimana copiata con successo: ${result.copiedShiftsCount} turni, ${result.copiedAssignmentsCount} assegnazioni`,
|
||||
copiedShifts: result.copiedShiftsCount,
|
||||
copiedAssignments: result.copiedAssignmentsCount,
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error("❌ Error copying weekly shifts:", error);
|
||||
res.status(500).json({
|
||||
message: error.message || "Errore durante la copia dei turni settimanali",
|
||||
error: String(error)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Assign guard to site/date with specific time slot (supports multi-day assignments)
|
||||
app.post("/api/general-planning/assign-guard", isAuthenticated, async (req, res) => {
|
||||
try {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user