[FIX] ATTENDANCE: Fixed time runner not running for the first check-in
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -4,4 +4,4 @@
|
||||
<div class="" data-target="#penaltyViewModal" data-toggle="oh-modal-toggle" hx-get="{% url "view-penalties" %}?late_early_id={{instance.id}}" hx-target="#penaltyViewModalBody" align="center" style="background-color: rgba(229, 79, 56, 0.036); border: 2px solid rgb(229, 79, 56); border-radius: 18px; padding: 10px; font-weight: bold; width: 150px;" onclick="event.stopPropagation();">Penalties :{{instance.get_penalties_count}}</div>
|
||||
{% else %}
|
||||
<div class="" style="background-color: rgba(144, 238, 144, 0.036); border: 2px solid rgb(144, 238, 144); border-radius: 18px; padding: 10px; width: 150px;" align="center">No Penalties</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -5,4 +5,4 @@
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% trans "Nil" %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -7,6 +7,8 @@ This module is used register endpoints to the check-in check-out functionalities
|
||||
import ipaddress
|
||||
import logging
|
||||
|
||||
from django.shortcuts import render
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
from datetime import date, datetime, timedelta
|
||||
|
||||
@@ -292,50 +294,8 @@ def clock_in(request):
|
||||
end_time=end_time_sec,
|
||||
in_datetime=datetime_now,
|
||||
)
|
||||
script = ""
|
||||
hidden_label = ""
|
||||
time_runner_enabled = timerunner_enabled(request)["enabled_timerunner"]
|
||||
mouse_in = ""
|
||||
mouse_out = ""
|
||||
if time_runner_enabled:
|
||||
script = """
|
||||
<script>
|
||||
$(".time-runner").removeClass("stop-runner");
|
||||
run = 1;
|
||||
at_work_seconds = {at_work_seconds_forecasted};
|
||||
</script>
|
||||
""".format(
|
||||
at_work_seconds_forecasted=employee.get_forecasted_at_work()[
|
||||
"forecasted_at_work_seconds"
|
||||
]
|
||||
)
|
||||
hidden_label = """
|
||||
style="display:none"
|
||||
"""
|
||||
mouse_in = """ onmouseenter = "$(this).find('span').show();$(this).find('.time-runner').hide();" """
|
||||
mouse_out = """ onmouseleave = "$(this).find('span').hide();$(this).find('.time-runner').show();" """
|
||||
|
||||
return HttpResponse(
|
||||
"""
|
||||
<button class="oh-btn oh-btn--warning-outline check-in mr-2"
|
||||
{mouse_in}
|
||||
{mouse_out}
|
||||
hx-get="/attendance/clock-out"
|
||||
hx-target='#attendance-activity-container'
|
||||
hx-swap='innerHTML'><ion-icon class="oh-navbar__clock-icon mr-2
|
||||
text-warning"
|
||||
name="exit-outline"></ion-icon>
|
||||
<span {hidden_label} class="hr-check-in-out-text">{check_out}</span>
|
||||
<div class="time-runner"></div>
|
||||
</button>
|
||||
{script}
|
||||
""".format(
|
||||
check_out=_("Check-Out"),
|
||||
script=script,
|
||||
hidden_label=hidden_label,
|
||||
mouse_in=mouse_in,
|
||||
mouse_out=mouse_out,
|
||||
)
|
||||
return render(
|
||||
request, "attendance/components/in_out_component.html", {"run": 1}
|
||||
)
|
||||
return HttpResponse(
|
||||
_(
|
||||
@@ -549,52 +509,10 @@ def clock_out(request):
|
||||
shift=shift,
|
||||
)
|
||||
|
||||
script = ""
|
||||
hidden_label = ""
|
||||
time_runner_enabled = timerunner_enabled(request)["enabled_timerunner"]
|
||||
mouse_in = ""
|
||||
mouse_out = ""
|
||||
if time_runner_enabled:
|
||||
script = """
|
||||
<script>
|
||||
$(document).ready(function () {{
|
||||
$('.at-work-seconds').html(secondsToDuration({at_work_seconds_forecasted}))
|
||||
}});
|
||||
run = 0;
|
||||
at_work_seconds = {at_work_seconds_forecasted};
|
||||
</script>
|
||||
""".format(
|
||||
at_work_seconds_forecasted=employee.get_forecasted_at_work()[
|
||||
"forecasted_at_work_seconds"
|
||||
],
|
||||
)
|
||||
hidden_label = """
|
||||
style="display:none"
|
||||
"""
|
||||
mouse_in = """ onmouseenter="$(this).find('div.at-work-seconds').hide();$(this).find('span').show();" """
|
||||
mouse_out = """onmouseleave="$(this).find('div.at-work-seconds').show();$(this).find('span').hide();" """
|
||||
return HttpResponse(
|
||||
"""
|
||||
<button class="oh-btn oh-btn--success-outline mr-2"
|
||||
{mouse_in}
|
||||
{mouse_out}
|
||||
hx-get="/attendance/clock-in"
|
||||
hx-target='#attendance-activity-container'
|
||||
hx-swap='innerHTML'>
|
||||
<ion-icon class="oh-navbar__clock-icon mr-2 text-success"
|
||||
name="enter-outline"></ion-icon>
|
||||
<span class="hr-check-in-out-text" {hidden_label} >{check_in}</span>
|
||||
<div class="at-work-seconds"></div>
|
||||
</button>
|
||||
{script}
|
||||
""".format(
|
||||
check_in=_("Check-In"),
|
||||
script=script,
|
||||
hidden_label=hidden_label,
|
||||
mouse_in=mouse_in,
|
||||
mouse_out=mouse_out,
|
||||
)
|
||||
return render(
|
||||
request, "attendance/components/in_out_component.html", {"run": 1}
|
||||
)
|
||||
|
||||
else:
|
||||
messages.error(request, _("Check in/Check out feature is not enabled."))
|
||||
return HttpResponse("<script>location.reload();</script>")
|
||||
|
||||
@@ -4,6 +4,9 @@ var whiteLabelCompany = $("#whiteLabelCompany").data("company");
|
||||
|
||||
// time-runner
|
||||
function secondsToDuration(seconds) {
|
||||
if (seconds < 0){
|
||||
seconds = 0
|
||||
}
|
||||
var hours = Math.floor(seconds / 3600);
|
||||
var minutes = Math.floor((seconds % 3600) / 60);
|
||||
var remainingSeconds = Math.floor(seconds % 60);
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
{% if request.user|is_clocked_in and get_forecasted_at_work.has_attendance %}
|
||||
<button class="check checkout" hx-get="{% url 'clock-out' %}" hx-target='#attendance-activity-container' hx-swap='innerHTML'>
|
||||
<span class="date">
|
||||
<i class="fa-solid fa-right-from-bracket pe-2"></i> {% if get_forecasted_at_work.has_attendance %} <div class="time-runner"></div> {% endif %}
|
||||
<i class="fa-solid fa-right-from-bracket pe-2"></i><div class="time-runner"></div>
|
||||
</span>
|
||||
<span class="con hr-Check-In-out-text">{% trans "Check Out" %}</span>
|
||||
</button>
|
||||
<span class="at_work_seconds" data-at-work-seconds = "{{ request.user.employee_get.get_forecasted_at_work.forecasted_at_work_seconds }}" data-run= "{{run|default:1}}" ></span>
|
||||
<span class="at_work_seconds" data-at-work-seconds = "{{ get_forecasted_at_work.forecasted_at_work_seconds|default:0 }}" data-run= "{{run|default:1}}" ></span>
|
||||
|
||||
{% else %}
|
||||
<button class="check checkin" hx-get="{% url 'clock-in' %}" hx-target='#attendance-activity-container' hx-swap='innerHTML'>
|
||||
@@ -20,11 +20,11 @@
|
||||
</span>
|
||||
<span class="con">{% trans "Check In" %}</span>
|
||||
</button>
|
||||
<span class="at_work_seconds" data-at-work-seconds = "{{ request.user.employee_get.get_forecasted_at_work.forecasted_at_work_seconds }}" data-run= "{{run|default:0}}" ></span>
|
||||
<span class="at_work_seconds" data-at-work-seconds = "{{ get_forecasted_at_work.forecasted_at_work_seconds|default:0 }}" data-run= "{{run|default:0}}" ></span>
|
||||
{% if enabled_timerunner %}
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('.at-work-seconds').html(secondsToDuration({{get_forecasted_at_work.forecasted_at_work_seconds}}))
|
||||
$('.at-work-seconds').html(secondsToDuration({{get_forecasted_at_work.forecasted_at_work_seconds}}))
|
||||
});
|
||||
run = 0
|
||||
</script>
|
||||
@@ -36,66 +36,39 @@
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
var at_work_seconds = $(".at_work_seconds").data("at-work-seconds");
|
||||
var run = $(".at_work_seconds").data("run");
|
||||
var whiteLabelCompany = $("#whiteLabelCompany").data("company");
|
||||
|
||||
{% comment %} <script>
|
||||
|
||||
var at_work_seconds = {{ request.user.employee_get.get_forecasted_at_work.forecasted_at_work_seconds }}
|
||||
var run = {{run|default:0}};
|
||||
|
||||
// time-runner
|
||||
function secondsToDuration(seconds) {
|
||||
var hours = Math.floor(seconds / 3600);
|
||||
var minutes = Math.floor((seconds % 3600) / 60);
|
||||
var remainingSeconds = Math.floor(seconds % 60);
|
||||
|
||||
// add leading zeros if necessary
|
||||
var formattedHours = (hours < 10) ? "0" + hours : hours;
|
||||
var formattedMinutes = (minutes < 10) ? "0" + minutes : minutes;
|
||||
var formattedSeconds = (remainingSeconds < 10) ? "0" + remainingSeconds : remainingSeconds;
|
||||
|
||||
return formattedHours + ":" + formattedMinutes + ":" + formattedSeconds;
|
||||
}
|
||||
|
||||
// accessing initial worked hours from the user
|
||||
$(".time-runner").not("title").html(secondsToDuration(at_work_seconds));
|
||||
$("title.time-runner").html("{{white_label_company_name}} | " + secondsToDuration(at_work_seconds));
|
||||
setInterval(() => {
|
||||
if (run) {
|
||||
at_work_seconds = parseInt(at_work_seconds) + 1
|
||||
$("div.time-runner").html(secondsToDuration(at_work_seconds));
|
||||
$("title").html("{{white_label_company_name}} | " + secondsToDuration(at_work_seconds));
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
function switchTab(e) {
|
||||
let parentContainerEl = e.target.closest(".oh-tabs");
|
||||
let tabElement = e.target.closest(".oh-tabs__tab");
|
||||
let targetSelector = e.target.dataset.target;
|
||||
let targetEl = parentContainerEl
|
||||
? parentContainerEl.querySelector(targetSelector)
|
||||
: null;
|
||||
|
||||
// Highlight active tabs
|
||||
if (tabElement && !tabElement.classList.contains("oh-tabs__tab--active")) {
|
||||
parentContainerEl
|
||||
.querySelectorAll(".oh-tabs__tab--active")
|
||||
.forEach(function (item) {
|
||||
item.classList.remove("oh-tabs__tab--active");
|
||||
});
|
||||
|
||||
if (!tabElement.classList.contains("oh-tabs__new-tab")) {
|
||||
tabElement.classList.add("oh-tabs__tab--active");
|
||||
// time-runner
|
||||
function secondsToDuration(seconds) {
|
||||
if (seconds < 0){
|
||||
seconds = 0
|
||||
}
|
||||
var hours = Math.floor(seconds / 3600);
|
||||
var minutes = Math.floor((seconds % 3600) / 60);
|
||||
var remainingSeconds = Math.floor(seconds % 60);
|
||||
|
||||
var formattedHours = (hours < 10) ? "0" + hours : hours;
|
||||
var formattedMinutes = (minutes < 10) ? "0" + minutes : minutes;
|
||||
var formattedSeconds = (remainingSeconds < 10) ? "0" + remainingSeconds : remainingSeconds;
|
||||
|
||||
return formattedHours + ":" + formattedMinutes + ":" + formattedSeconds;
|
||||
}
|
||||
|
||||
// Switch tabs
|
||||
if (targetEl && !targetEl.classList.contains("oh-tabs__content--active")) {
|
||||
parentContainerEl
|
||||
.querySelectorAll(".oh-tabs__content--active")
|
||||
.forEach(function (item) {
|
||||
item.classList.remove("oh-tabs__content--active");
|
||||
});
|
||||
targetEl.classList.add("oh-tabs__content--active");
|
||||
if (window.timeRunnerInterval) {
|
||||
clearInterval(window.timeRunnerInterval);
|
||||
}
|
||||
}
|
||||
</script> {% endcomment %}
|
||||
|
||||
$(".time-runner").not("title").html(secondsToDuration(at_work_seconds));
|
||||
$("title.time-runner").html(` ${whiteLabelCompany} | ` + secondsToDuration(at_work_seconds));
|
||||
|
||||
if (run) {
|
||||
window.timeRunnerInterval = setInterval(() => {
|
||||
at_work_seconds = parseInt(at_work_seconds) + 1;
|
||||
$("div.time-runner").html(secondsToDuration(at_work_seconds));
|
||||
$("title").html(` ${whiteLabelCompany} | ` + secondsToDuration(at_work_seconds));
|
||||
}, 1000);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
$("#sortable li").each(function (index) {
|
||||
order.push($(this).data("id"));
|
||||
});
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: "{% url 'update-stage-sequence' offboarding.id %}",
|
||||
method: "POST",
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
{% endif %}
|
||||
{% if perms.recruitment.delete_stage %}
|
||||
<li class="oh-dropdown__item oh-dropdown__link--danger">
|
||||
|
||||
|
||||
<a data-toggle="oh-modal-toggle"
|
||||
data-target="#deleteConfirmation"
|
||||
hx-get="{% url 'generic-delete' %}?model=recruitment.Stage&pk={{stage.pk}}"
|
||||
@@ -38,16 +38,16 @@
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
<div
|
||||
class="oh-tabs__movable-body position-relative"
|
||||
hx-get="{% url "candidate-lists-cbv" stage.pk stage.recruitment_id.pk %}?{{request.GET.urlencode}}"
|
||||
hx-trigger="load"
|
||||
|
||||
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -62,4 +62,3 @@
|
||||
badge.attr("title", title);
|
||||
</script>
|
||||
</div>
|
||||
|
||||
@@ -42,11 +42,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
<div
|
||||
class="oh-tabs__movable-body position-relative"
|
||||
hx-get="{{url}}?{% for parameter in parameters %}{{parameter|format:group}}&{% endfor %}{{request.GET.urlencode}}"
|
||||
hx-trigger="load"
|
||||
|
||||
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -62,4 +62,3 @@
|
||||
badge.attr("title", title);
|
||||
</script>
|
||||
</div>
|
||||
|
||||
@@ -32,11 +32,10 @@
|
||||
<div id="attendance-activity-container">
|
||||
{% include "attendance/components/in_out_component.html" %}
|
||||
</div>
|
||||
<script src="{% static 'horilla_theme/assets/js/timeRunner.js' %}"></script>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<button
|
||||
class="hidden md:block p-2 group text-primary-600 w-12 h-12 bg-primary-100 hover:bg-primary-600 rounded-full transition duration-300 flex items-center justify-center"
|
||||
class="md:block p-2 group text-primary-600 w-12 h-12 bg-primary-100 hover:bg-primary-600 rounded-full transition duration-300 flex items-center justify-center"
|
||||
>
|
||||
<a href="{% url 'general-settings' %}">
|
||||
<i
|
||||
|
||||
Reference in New Issue
Block a user