hospital-management/templates/hr/time_entry_approve.html
2025-08-12 13:33:25 +03:00

389 lines
18 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}Approve Time Entry | HR Management{% endblock %}
{% block css %}
<style>
.time-entry-header {
background-color: #f8f9fa;
border-radius: 5px;
padding: 20px;
margin-bottom: 20px;
}
.approval-card {
background-color: #f8f9fa;
border-radius: 5px;
padding: 15px;
}
.status-badge {
font-size: 14px;
padding: 8px 15px;
border-radius: 30px;
}
.status-pending {
background-color: #fff3cd;
color: #856404;
border: 1px solid #ffeeba;
}
.time-summary-card {
border-left: 4px solid #2d62ed;
}
</style>
{% endblock %}
{% block content %}
<!-- begin breadcrumb -->
<ol class="breadcrumb float-xl-end">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Home</a></li>
<li class="breadcrumb-item"><a href="{% url 'hr:dashboard' %}">HR</a></li>
<li class="breadcrumb-item"><a href="{% url 'hr:time_entry_list' %}">Time Entries</a></li>
<li class="breadcrumb-item"><a href="{% url 'hr:time_entry_detail' time_entry.id %}">Time Entry Details</a></li>
<li class="breadcrumb-item active">Approve Time Entry</li>
</ol>
<!-- end breadcrumb -->
<!-- begin page-header -->
<h1 class="page-header">Approve Time Entry</h1>
<!-- end page-header -->
<!-- begin row -->
<div class="row">
<!-- begin col-8 -->
<div class="col-xl-8">
<!-- begin panel -->
<div class="panel panel-inverse">
<!-- begin panel-heading -->
<div class="panel-heading">
<h4 class="panel-title">Time Entry Approval</h4>
<div class="panel-heading-btn">
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
<a href="javascript:;" class="btn btn-xs btn-icon btn-success" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>
<a href="javascript:;" class="btn btn-xs btn-icon btn-warning" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
</div>
</div>
<!-- end panel-heading -->
<!-- begin panel-body -->
<div class="panel-body">
<!-- Time Entry Header -->
<div class="time-entry-header">
<div class="row">
<div class="col-md-6">
<div class="d-flex align-items-center">
<div class="avatar avatar-lg me-3">
<img src="{% static 'img/user/default-avatar.jpg' %}" alt="{{ time_entry.employee.get_full_name }}" class="rounded-circle">
</div>
<div>
<h4 class="mb-0">{{ time_entry.employee.get_full_name }}</h4>
<p class="text-muted mb-0">{{ time_entry.employee.job_title }}</p>
<p class="text-muted mb-0">
{% if time_entry.employee.department %}
{{ time_entry.employee.department.name }}
{% else %}
No Department
{% endif %}
</p>
</div>
</div>
</div>
<div class="col-md-6 text-md-end mt-3 mt-md-0">
<span class="status-badge status-pending">
<i class="fas fa-hourglass-half"></i> Pending Approval
</span>
</div>
</div>
</div>
<!-- Time Entry Details -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title mb-0">Time Details</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<table class="table table-borderless">
<tbody>
<tr>
<th width="40%">Date:</th>
<td>{{ time_entry.date|date:"F d, Y" }}</td>
</tr>
<tr>
<th>Start Time:</th>
<td>{{ time_entry.start_time|time:"H:i" }}</td>
</tr>
<tr>
<th>End Time:</th>
<td>{{ time_entry.end_time|time:"H:i" }}</td>
</tr>
<tr>
<th>Total Hours:</th>
<td>
<strong>{{ time_entry.hours }}</strong>
{% if time_entry.is_overtime %}
<span class="badge bg-danger ms-2">Overtime</span>
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-6">
<table class="table table-borderless">
<tbody>
<tr>
<th width="40%">Type:</th>
<td>
{% if time_entry.is_overtime %}
Overtime
{% else %}
Regular
{% endif %}
</td>
</tr>
<tr>
<th>Location:</th>
<td>{{ time_entry.location|default:"Not specified" }}</td>
</tr>
<tr>
<th>Break Duration:</th>
<td>{{ time_entry.break_duration|default:"0" }} minutes</td>
</tr>
<tr>
<th>Created:</th>
<td>{{ time_entry.created_at|date:"F d, Y H:i" }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Description -->
{% if time_entry.description %}
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title mb-0">Description</h5>
</div>
<div class="card-body">
<p class="mb-0">{{ time_entry.description|linebreaks }}</p>
</div>
</div>
{% endif %}
<!-- Approval Form -->
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Approval Decision</h5>
</div>
<div class="card-body">
<form method="post">
{% csrf_token %}
<!-- Form Errors -->
{% if form.errors %}
<div class="alert alert-danger">
<h5><i class="fas fa-exclamation-circle"></i> Please correct the errors below:</h5>
<ul class="mb-0">
{% for field in form %}
{% for error in field.errors %}
<li>{{ field.label }}: {{ error }}</li>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="mb-4">
<label class="form-label">Decision <span class="text-danger">*</span></label>
<div class="d-flex gap-3">
<div class="form-check">
<input class="form-check-input" type="radio" name="decision" id="decision_approve" value="approve" checked>
<label class="form-check-label" for="decision_approve">
<i class="fas fa-check-circle text-success"></i> Approve
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="decision" id="decision_reject" value="reject">
<label class="form-check-label" for="decision_reject">
<i class="fas fa-times-circle text-danger"></i> Reject
</label>
</div>
</div>
</div>
<div class="mb-3" id="approval_notes_container">
<label for="approval_notes" class="form-label">Approval Notes</label>
<textarea class="form-control" id="approval_notes" name="approval_notes" rows="3"></textarea>
<div class="form-text">Optional notes for the approval</div>
</div>
<div class="mb-3" id="rejection_reason_container" style="display: none;">
<label for="rejection_reason" class="form-label">Rejection Reason <span class="text-danger">*</span></label>
<textarea class="form-control" id="rejection_reason" name="rejection_reason" rows="3"></textarea>
<div class="form-text">Please provide a reason for rejecting this time entry</div>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="notify_employee" name="notify_employee" checked>
<label class="form-check-label" for="notify_employee">
Notify employee of decision
</label>
</div>
<div class="d-flex justify-content-between mt-4">
<a href="{% url 'hr:time_entry_detail' time_entry.id %}" class="btn btn-secondary">
<i class="fas fa-arrow-left"></i> Back to Details
</a>
<button type="submit" class="btn btn-primary" id="submit_button">
<i class="fas fa-check"></i> Approve Time Entry
</button>
</div>
</form>
</div>
</div>
</div>
<!-- end panel-body -->
</div>
<!-- end panel -->
</div>
<!-- end col-8 -->
<!-- begin col-4 -->
<div class="col-xl-4">
<!-- Time Summary -->
<div class="card mb-4 time-summary-card">
<div class="card-header">
<h5 class="card-title mb-0">Time Summary</h5>
</div>
<div class="card-body">
<div class="mb-3">
<h6>Current Week</h6>
<div class="d-flex justify-content-between">
<span>Regular Hours:</span>
<strong>{{ weekly_regular_hours|default:"0" }}</strong>
</div>
<div class="d-flex justify-content-between">
<span>Overtime Hours:</span>
<strong>{{ weekly_overtime_hours|default:"0" }}</strong>
</div>
<div class="d-flex justify-content-between">
<span>Total Hours:</span>
<strong>{{ weekly_total_hours|default:"0" }}</strong>
</div>
</div>
<div>
<h6>Current Month</h6>
<div class="d-flex justify-content-between">
<span>Regular Hours:</span>
<strong>{{ monthly_regular_hours|default:"0" }}</strong>
</div>
<div class="d-flex justify-content-between">
<span>Overtime Hours:</span>
<strong>{{ monthly_overtime_hours|default:"0" }}</strong>
</div>
<div class="d-flex justify-content-between">
<span>Total Hours:</span>
<strong>{{ monthly_total_hours|default:"0" }}</strong>
</div>
</div>
</div>
</div>
<!-- Approval Guidelines -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title mb-0">Approval Guidelines</h5>
</div>
<div class="card-body">
<ul class="mb-0">
<li>Verify that the hours reported are accurate</li>
<li>Check for any scheduling conflicts</li>
<li>Ensure overtime was properly authorized</li>
<li>Confirm the work description matches the time reported</li>
<li>Review the employee's time summary for the week</li>
<li>Provide clear reasons if rejecting the time entry</li>
</ul>
</div>
</div>
<!-- Recent Time Entries -->
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Recent Time Entries</h5>
</div>
<div class="card-body">
<div class="list-group list-group-flush">
{% for entry in recent_entries %}
<a href="{% url 'hr:time_entry_detail' entry.id %}" class="list-group-item list-group-item-action">
<div class="d-flex justify-content-between">
<div>
<h6 class="mb-1">{{ entry.date|date:"M d, Y" }}</h6>
<p class="mb-1">{{ entry.start_time|time:"H:i" }} - {{ entry.end_time|time:"H:i" }}</p>
</div>
<div>
<span class="badge {% if entry.status == 'APPROVED' %}bg-success{% elif entry.status == 'REJECTED' %}bg-danger{% else %}bg-warning{% endif %}">
{{ entry.get_status_display }}
</span>
<div class="text-end">{{ entry.hours }} hrs</div>
</div>
</div>
</a>
{% empty %}
<div class="text-center py-3">
<p class="mb-0">No recent time entries found.</p>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
<!-- end col-4 -->
</div>
<!-- end row -->
{% endblock %}
{% block js %}
<script>
$(document).ready(function() {
// Toggle between approval and rejection fields
$('input[name="decision"]').change(function() {
var decision = $('input[name="decision"]:checked').val();
if (decision === 'approve') {
$('#approval_notes_container').show();
$('#rejection_reason_container').hide();
$('#submit_button').html('<i class="fas fa-check"></i> Approve Time Entry');
$('#submit_button').removeClass('btn-danger').addClass('btn-primary');
} else {
$('#approval_notes_container').hide();
$('#rejection_reason_container').show();
$('#submit_button').html('<i class="fas fa-times"></i> Reject Time Entry');
$('#submit_button').removeClass('btn-primary').addClass('btn-danger');
}
});
// Form validation
$('form').submit(function(e) {
var decision = $('input[name="decision"]:checked').val();
if (decision === 'reject') {
var rejectionReason = $('#rejection_reason').val().trim();
if (!rejectionReason) {
e.preventDefault();
alert('Please provide a reason for rejecting this time entry.');
$('#rejection_reason').focus();
}
}
});
});
</script>
{% endblock %}