/** * Auto-calculate pause based on German break rules * @param {number} grossHours - Total work hours * @returns {number} - Pause in minutes */ function calculateAutoPause(grossHours) { if (grossHours > 9) { return 45; } else if (grossHours > 6) { return 30; } return 0; } /** * Calculate net hours with pause and 10-hour cap * @param {string} startTime - Format: "HH:MM" * @param {string} endTime - Format: "HH:MM" * @param {number|null} pauseMinutes - Manual pause in minutes (null for auto-calculation) * @returns {object} - { grossHours, pauseMinutes, netHours } */ function calculateNetHours(startTime, endTime, pauseMinutes = null) { const [startHour, startMin] = startTime.split(':').map(Number); const [endHour, endMin] = endTime.split(':').map(Number); const startTotalMin = startHour * 60 + startMin; const endTotalMin = endHour * 60 + endMin; // Handle overnight shifts let diffMin = endTotalMin - startTotalMin; if (diffMin < 0) { diffMin += 24 * 60; // Add 24 hours } const grossHours = diffMin / 60; // Calculate required minimum pause based on gross hours const requiredMinPause = calculateAutoPause(grossHours); // Determine actual pause to use let actualPause; if (pauseMinutes !== null && pauseMinutes !== undefined) { // Manual pause provided - enforce minimum actualPause = Math.max(pauseMinutes, requiredMinPause); } else { // No pause provided - use required minimum actualPause = requiredMinPause; } // Calculate net hours const netMinutes = diffMin - actualPause; let netHours = netMinutes / 60; // Cap at 10 hours if (netHours > 10) { netHours = 10.0; } return { grossHours: parseFloat(grossHours.toFixed(2)), pauseMinutes: actualPause, netHours: parseFloat(netHours.toFixed(2)) }; } module.exports = { calculateAutoPause, calculateNetHours };