# Duplicate Report Feature ## Overview Added a duplicate functionality for reports/shifts that allows users to create a complementary shift (day ↔ night) based on an existing report, but only when the report sheet is not complete. ## Feature Details ### ✅ **Functionality** - **Duplicate Button**: Available next to "View" for each report - **Opposite Shift**: Automatically creates the opposite shift (day → night, night → day) - **Data Copying**: Copies all report data EXCEPT stoppages - **User Assignment**: Assigns the duplicate to the current user - **Sheet Management**: Automatically manages the report sheet relationships ### ✅ **Validation Rules** 1. **Date Restriction**: Cannot duplicate reports older than the day before current date (for all auth levels) 2. **Universal Access**: All users (auth level 1+) can duplicate any report 3. **Sheet Completeness**: Cannot duplicate if the sheet already has both day and night shifts 4. **Shift Existence**: Cannot duplicate if the opposite shift already exists for the same date/location 5. **User Confirmation**: Requires confirmation before duplicating ### ✅ **What Gets Copied** - ✅ Area, Dredger Location, Reclamation Location - ✅ Dredger Line Length, Shore Connection - ✅ Reclamation Height (base + extra) - ✅ Pipeline Length (main, ext1, reserve, ext2) - ✅ Equipment Statistics (Dozers, Exc, Loaders, Foreman, Laborer) - ✅ Time Sheet entries - ✅ Notes ### ❌ **What Gets Excluded** - ❌ Stoppages (empty array) - ❌ Original shift type (automatically inverted) - ❌ Original employee assignment (assigned to current user) ## Technical Implementation ### **Database Logic** ```typescript // Check if report is too old (before day before current date) const reportDate = new Date(originalReport.createdDate); const dayBeforeToday = new Date(); dayBeforeToday.setDate(dayBeforeToday.getDate() - 1); dayBeforeToday.setHours(0, 0, 0, 0); if (reportDate < dayBeforeToday) { return error("Cannot duplicate reports older than yesterday"); } // Check if sheet is complete (has both shifts) const existingSheet = await prisma.sheet.findUnique({ where: { areaId_dredgerLocationId_reclamationLocationId_date: { areaId: originalReport.areaId, dredgerLocationId: originalReport.dredgerLocationId, reclamationLocationId: originalReport.reclamationLocationId, date: dateString } } }); // Prevent duplication if sheet is complete if (existingSheet && existingSheet.dayShiftId && existingSheet.nightShiftId) { return error("Cannot duplicate - sheet is complete"); } ``` ### **Shift Inversion** ```typescript const newShift = originalReport.shift === 'day' ? 'night' : 'day'; ``` ### **Data Duplication** ```typescript const duplicateReport = await prisma.report.create({ data: { employeeId: user.id, // Current user shift: newShift, // Opposite shift // ... all other fields copied stoppages: [], // Empty stoppages } }); ``` ## User Interface ### **Desktop View** - **Location**: Next to "View" button in the actions column - **Button**: Green "Duplicate" button with hover tooltip - **Confirmation**: Shows which shift will be created ### **Mobile View** - **Location**: Below "View Details" button - **Button**: Full-width green button with descriptive text - **Text**: "Duplicate as Night Shift" or "Duplicate as Day Shift" ### **Confirmation Dialog** ``` "Are you sure you want to duplicate this day shift as a night shift? Stoppages will not be copied." ``` ## Error Handling ### **Validation Errors** 1. **Date Restriction**: "Cannot duplicate reports older than yesterday" 2. **Sheet Complete**: "Cannot duplicate report - sheet is already complete with both day and night shifts" 3. **Shift Exists**: "Cannot duplicate report - night shift already exists for this date and location" 4. **General Error**: "Failed to duplicate report" ### **Success Message** ``` "Report duplicated successfully as night shift!" ``` ## Use Cases ### **Primary Use Case** 1. User creates a day shift report 2. Realizes they need a night shift for the same location/date 3. Clicks "Duplicate" on the day shift 4. System creates a night shift with same operational data 5. User can then edit the night shift to add specific stoppages and time sheet adjustments ### **Business Logic** - **Operational Continuity**: Same equipment, locations, and basic setup - **Shift-Specific Data**: Stoppages are shift-specific and not copied - **User Ownership**: Each user owns their duplicated reports - **Sheet Completion**: Helps complete report sheets efficiently ## Security & Permissions ### **Access Control** - **All Users (Level 1+)**: Can duplicate any report within the allowed date range - **Date Restriction**: Reports older than the day before current date cannot be duplicated - **Sheet Validation**: Server-side validation prevents invalid duplications ### **Data Integrity** - **Sheet Management**: Automatically updates sheet relationships - **Unique Constraints**: Prevents duplicate shifts for same date/location - **Transaction Safety**: Uses database transactions for consistency ## Benefits 1. **Efficiency**: Quickly create complementary shifts 2. **Consistency**: Maintains operational data consistency 3. **Flexibility**: Allows shift-specific customizations 4. **User-Friendly**: Simple one-click duplication with clear feedback 5. **Data Integrity**: Maintains proper sheet relationships and validation The duplicate feature streamlines the process of creating complementary shifts while maintaining data integrity and proper validation rules.