Fix export page role issue
This commit is contained in:
@@ -71,6 +71,10 @@ class User(db.Model):
|
|||||||
"""Check if user has staff-level permissions (includes new roles)"""
|
"""Check if user has staff-level permissions (includes new roles)"""
|
||||||
return self.role in STAFF_LEVEL_ROLES
|
return self.role in STAFF_LEVEL_ROLES
|
||||||
|
|
||||||
|
def has_export_permissions(user_role):
|
||||||
|
"""Check if user role has export permissions"""
|
||||||
|
return user_role in ['admin', 'payroll']
|
||||||
|
|
||||||
def get_role_display_name(self):
|
def get_role_display_name(self):
|
||||||
"""Get user-friendly role name"""
|
"""Get user-friendly role name"""
|
||||||
role_names = {
|
role_names = {
|
||||||
@@ -3001,7 +3005,7 @@ def toggle_qr_status_api(qr_id):
|
|||||||
return redirect(url_for('dashboard'))
|
return redirect(url_for('dashboard'))
|
||||||
|
|
||||||
@app.route('/attendance')
|
@app.route('/attendance')
|
||||||
# @admin_required
|
@login_required
|
||||||
def attendance_report():
|
def attendance_report():
|
||||||
"""Safe attendance report with backward compatibility for location_accuracy and fixed datetime handling"""
|
"""Safe attendance report with backward compatibility for location_accuracy and fixed datetime handling"""
|
||||||
try:
|
try:
|
||||||
@@ -3009,6 +3013,7 @@ def attendance_report():
|
|||||||
|
|
||||||
# Log attendance report access
|
# Log attendance report access
|
||||||
try:
|
try:
|
||||||
|
user_role = session.get('role', 'unknown')
|
||||||
logger_handler.logger.info(f"User {session.get('username', 'unknown')} accessed attendance report")
|
logger_handler.logger.info(f"User {session.get('username', 'unknown')} accessed attendance report")
|
||||||
except Exception as log_error:
|
except Exception as log_error:
|
||||||
print(f"⚠️ Logging error (non-critical): {log_error}")
|
print(f"⚠️ Logging error (non-critical): {log_error}")
|
||||||
@@ -3090,7 +3095,7 @@ def attendance_report():
|
|||||||
conditions.append("ad.employee_id LIKE :employee")
|
conditions.append("ad.employee_id LIKE :employee")
|
||||||
params['employee'] = f"%{employee_filter}%"
|
params['employee'] = f"%{employee_filter}%"
|
||||||
|
|
||||||
# FIXED: Apply project filter using SQL approach (not ORM)
|
# Apply project filter using SQL approach (not ORM)
|
||||||
if project_filter:
|
if project_filter:
|
||||||
conditions.append("qc.project_id = :project_id")
|
conditions.append("qc.project_id = :project_id")
|
||||||
params['project_id'] = int(project_filter)
|
params['project_id'] = int(project_filter)
|
||||||
@@ -3279,7 +3284,8 @@ def attendance_report():
|
|||||||
project_filter=project_filter,
|
project_filter=project_filter,
|
||||||
today_date=today_date,
|
today_date=today_date,
|
||||||
current_date_formatted=current_date_formatted,
|
current_date_formatted=current_date_formatted,
|
||||||
has_location_accuracy_feature=has_location_accuracy)
|
has_location_accuracy_feature=has_location_accuracy,
|
||||||
|
user_role=user_role)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"❌ Error loading attendance report: {e}")
|
print(f"❌ Error loading attendance report: {e}")
|
||||||
@@ -3491,14 +3497,21 @@ def attendance_stats_api():
|
|||||||
return jsonify({'error': 'Failed to fetch attendance statistics'}), 500
|
return jsonify({'error': 'Failed to fetch attendance statistics'}), 500
|
||||||
|
|
||||||
@app.route('/export-configuration')
|
@app.route('/export-configuration')
|
||||||
@admin_required
|
@login_required
|
||||||
def export_configuration():
|
def export_configuration():
|
||||||
"""Route to display export configuration page"""
|
"""Route to display export configuration page"""
|
||||||
try:
|
try:
|
||||||
print("📊 Export configuration route accessed")
|
print("📊 Export configuration route accessed")
|
||||||
|
# Check if user has export permissions
|
||||||
|
user_role = session.get('role')
|
||||||
|
if user_role not in ['admin', 'payroll']:
|
||||||
|
logger_handler.logger.warning(f"User {session.get('username', 'unknown')} (role: {user_role}) attempted to access export configuration without permissions")
|
||||||
|
flash('Access denied. Only administrators and payroll staff can access export configuration.', 'error')
|
||||||
|
return redirect(url_for('attendance_report'))
|
||||||
|
|
||||||
# Log export configuration access using your existing logger
|
# Log export configuration access using your existing logger
|
||||||
try:
|
try:
|
||||||
|
logger_handler.logger.info(f"User {session.get('username', 'unknown')} (role: {user_role}) accessed export configuration")
|
||||||
logger_handler.logger.info(f"User {session.get('username', 'unknown')} accessed export configuration page")
|
logger_handler.logger.info(f"User {session.get('username', 'unknown')} accessed export configuration page")
|
||||||
except Exception as log_error:
|
except Exception as log_error:
|
||||||
print(f"⚠️ Logging error (non-critical): {log_error}")
|
print(f"⚠️ Logging error (non-critical): {log_error}")
|
||||||
@@ -3573,10 +3586,16 @@ def export_configuration():
|
|||||||
return redirect(url_for('attendance_report'))
|
return redirect(url_for('attendance_report'))
|
||||||
|
|
||||||
@app.route('/generate-excel-export', methods=['POST'])
|
@app.route('/generate-excel-export', methods=['POST'])
|
||||||
@admin_required
|
@login_required
|
||||||
def generate_excel_export():
|
def generate_excel_export():
|
||||||
"""Generate and download Excel file with selected columns in specified order"""
|
"""Generate and download Excel file with selected columns in specified order"""
|
||||||
try:
|
try:
|
||||||
|
user_role = session.get('role')
|
||||||
|
if user_role not in ['admin', 'payroll']:
|
||||||
|
logger_handler.logger.warning(f"User {session.get('username', 'unknown')} (role: {user_role}) attempted unauthorized Excel export")
|
||||||
|
flash('Access denied. Only administrators and payroll staff can export data.', 'error')
|
||||||
|
return redirect(url_for('attendance_report'))
|
||||||
|
|
||||||
print("📊 Excel export generation started")
|
print("📊 Excel export generation started")
|
||||||
|
|
||||||
# Log export action using your existing logger
|
# Log export action using your existing logger
|
||||||
|
|||||||
@@ -1017,8 +1017,19 @@ function exportAttendanceWithAccuracy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function exportAttendance() {
|
function exportAttendance() {
|
||||||
|
// Check user role before proceeding
|
||||||
|
const userRole = window.userRole; // Read from global variable set in template
|
||||||
|
console.log("Template - session.role:", '{{ session.role }}');
|
||||||
|
console.log("Template - window.userRole set to:", window.userRole);
|
||||||
|
|
||||||
|
if (!['admin', 'payroll'].includes(userRole)) {
|
||||||
|
console.log("Export access denied - insufficient privileges");
|
||||||
|
alert("Access denied. Only administrators and payroll staff can export data.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Log export action
|
// Log export action
|
||||||
console.log("Export button clicked - redirecting to configuration page");
|
console.log(`Export button clicked by ${userRole} - redirecting to configuration page`);
|
||||||
|
|
||||||
// Get current filters
|
// Get current filters
|
||||||
const currentFilters = getCurrentFilters();
|
const currentFilters = getCurrentFilters();
|
||||||
@@ -1053,6 +1064,15 @@ function getCurrentFilters() {
|
|||||||
|
|
||||||
// Add a quick CSV export function as backup (keep existing functionality)
|
// Add a quick CSV export function as backup (keep existing functionality)
|
||||||
function exportAttendanceCSV() {
|
function exportAttendanceCSV() {
|
||||||
|
// Check user role before proceeding
|
||||||
|
const userRole = window.userRole;
|
||||||
|
|
||||||
|
if (!['admin', 'payroll'].includes(userRole)) {
|
||||||
|
console.log("CSV export access denied - insufficient privileges");
|
||||||
|
alert("Access denied. Only administrators and payroll staff can export data.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Build export URL with current filters for CSV
|
// Build export URL with current filters for CSV
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
const filters = getCurrentFilters();
|
const filters = getCurrentFilters();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="attendance-page">
|
<div class="attendance-page" data-user-role="{{ session.role }}">
|
||||||
<!-- Header Section -->
|
<!-- Header Section -->
|
||||||
<div class="attendance-header">
|
<div class="attendance-header">
|
||||||
<div class="header-content">
|
<div class="header-content">
|
||||||
@@ -22,10 +22,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
|
{% if session.role in ['admin', 'payroll'] %}
|
||||||
<button onclick="exportAttendance()" class="btn btn-success">
|
<button onclick="exportAttendance()" class="btn btn-success">
|
||||||
<i class="fas fa-download"></i>
|
<i class="fas fa-download"></i>
|
||||||
Export Data
|
Export Data
|
||||||
</button>
|
</button>
|
||||||
|
{% endif %}
|
||||||
<button onclick="refreshReport()" class="btn btn-secondary">
|
<button onclick="refreshReport()" class="btn btn-secondary">
|
||||||
<i class="fas fa-sync-alt"></i>
|
<i class="fas fa-sync-alt"></i>
|
||||||
Refresh
|
Refresh
|
||||||
@@ -622,5 +624,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
console.log('✅ Admin/Payroll edit/delete buttons have been activated');
|
console.log('✅ Admin/Payroll edit/delete buttons have been activated');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
window.userRole = '{{ session.role }}';
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user