fixed overtime calculation

This commit is contained in:
Jörg Henke
2024-01-05 21:18:32 +01:00
parent 1f71d9edeb
commit e38f62fa72
4 changed files with 171 additions and 119 deletions

View File

@ -7,7 +7,7 @@ plugins {
apply plugin: 'io.spring.dependency-management'
group = 'de.jottyfan'
version = '1.4.5'
version = '1.4.6'
description = """timetrack"""

View File

@ -242,4 +242,20 @@ public class DoneController extends CommonController {
bean.getIncludeSaturday(), bean.getIncludeSunday());
return "redirect:/done/list";
}
@RolesAllowed("timetrack_user")
@GetMapping("/done/slot/back")
public String oneMonthBack(Model model, @ModelAttribute("doneModel") DoneModel doneModel) {
LocalDate day = doneModel.getDay();
doneModel.setDay(day.minusMonths(1));
return "redirect:/done/list";
}
@RolesAllowed("timetrack_user")
@GetMapping("/done/slot/forward")
public String oneMonthForward(Model model, @ModelAttribute("doneModel") DoneModel doneModel) {
LocalDate day = doneModel.getDay();
doneModel.setDay(day.plusMonths(1));
return "redirect:/done/list";
}
}

View File

@ -95,17 +95,17 @@ public class DoneRepository {
Field<Integer> OVERTIME = DSL.field("overtime", Integer.class);
SelectHavingStep<Record1<Integer>> sql = jooq
// @formatter:off
.select(T_OVERTIME.OVERTIME_MINUTES.plus(DSL.sum(DSL.extract(V_DAY.WORKTIME, DatePart.MINUTE).minus(T_REQUIRED_WORKTIME.REQUIRED_MINUTES))).as(OVERTIME))
.select(T_OVERTIME.OVERTIME_MINUTES.plus(DSL.sum(DSL.extract(V_DAY.WORKTIME, DatePart.EPOCH).div(60).minus(T_REQUIRED_WORKTIME.REQUIRED_MINUTES))).as(OVERTIME))
.from(V_DAY)
.innerJoin(T_REQUIRED_WORKTIME).on(T_REQUIRED_WORKTIME.DAY.eq(V_DAY.DAY).and(T_REQUIRED_WORKTIME.FK_LOGIN.eq(V_DAY.FK_LOGIN)))
.innerJoin(T_OVERTIME).on(T_OVERTIME.FK_LOGIN.eq(V_DAY.FK_LOGIN))
.innerJoin(T_LOGIN).on(T_LOGIN.PK.eq(V_DAY.FK_LOGIN))
.where(T_OVERTIME.IMPACT.ge(V_DAY.DAY.cast(LocalDateTime.class)))
.where(T_OVERTIME.IMPACT.le(V_DAY.DAY.cast(LocalDateTime.class)))
.and(V_DAY.DAY.le(day))
.and(T_LOGIN.LOGIN.eq(login))
.groupBy(V_DAY.FK_LOGIN, T_OVERTIME.OVERTIME_MINUTES);
// @formatter:on
LOGGER.trace(sql);
LOGGER.info(sql);
return sql.fetchOne(OVERTIME);
}

View File

@ -1,6 +1,5 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security" layout:decorate="~{layout/main.html}">
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security" layout:decorate="~{layout/main.html}">
<head>
<title>Arbeitszeit</title>
</head>
@ -8,8 +7,10 @@
<font layout:fragment="title">Arbeitszeit</font>
<ul layout:fragment="menuitem">
<li class="nav-item" sec:authorize="hasRole('timetrack_user')">
<a class="nav-link btn btn-primary btn-white-text" th:href="@{/done/list/previousday}" style="width: 50px; float: left;"><i class="fa fa-chevron-left"></i></a>
<form th:action="@{/done/list}" th:object="${doneModel}" method="post" style="float:left;">
<a class="nav-link btn btn-primary btn-white-text" th:href="@{/done/list/previousday}" style="width: 50px; float: left;">
<i class="fa fa-chevron-left"></i>
</a>
<form th:action="@{/done/list}" th:object="${doneModel}" method="post" style="float: left;">
<div class="nav-link" style="padding-top: 5px !important; padding-bottom: 0px !important">
<div class="input-group input-group-sm mb-3" style="margin-bottom: 0px !important">
<input type="date" class="form-control" th:value="*{day}" th:field="*{day}" />
@ -17,43 +18,60 @@
</div>
</div>
</form>
<a class="nav-link btn btn-primary btn-white-text" th:href="@{/done/list/nextday}" style="width: 50px; float: left;"><i class="fa fa-chevron-right"></i></a>
<a class="nav-link btn btn-primary btn-white-text" th:href="@{/done/list/nextday}" style="width: 50px; float: left;">
<i class="fa fa-chevron-right"></i>
</a>
</li>
</ul>
<ul layout:fragment="menu">
<li class="nav-item" sec:authorize="hasRole('timetrack_user')">
<table>
<tr>
<td><a class="nav-link btn btn-success btn-white-text" th:href="@{/done/add/{day}(day=${doneModel.day})}">Neuer
Eintrag</a></td>
<td><a class="nav-link btn btn-success btn-white-text" th:href="@{/done/add/{day}(day=${doneModel.day})}">Neuer Eintrag</a></td>
<td>
<div class="dropdown">
<button class="btn btn-white-text dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Letzte Einträge
</button>
<button class="btn btn-white-text dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Letzte Einträge</button>
<ul class="dropdown-menu">
<li th:each="recent : ${recentList}">
<a class="dropdown-item" th:href="@{/done/addrecent/{id}(id=${recent.pk})}"
th:text="${(recent.getJobName()!=null?recent.getJobName():'') + '@' + (recent.getProject()!=null?recent.getProject().getName():'') + (recent.getModule()!=null? ', ' + recent.getModule().getName() : '')}"></a>
th:text="${(recent.getJobName()!=null?recent.getJobName():'') + '@' + (recent.getProject()!=null?recent.getProject().getName():'') + (recent.getModule()!=null? ', ' + recent.getModule().getName() : '')}"></a>
</li>
</ul>
</div>
</td>
<td style="padding-left: 8px"><a class="nav-link btn-list" th:href="@{/done/list}"><i class="fas fa-sync"></i></a></td>
<td style="padding-left: 8px"><a class="nav-link btn-list" th:href="@{/done/list}">
<i class="fas fa-sync"></i>
</a></td>
</tr>
</table>
</li>
</ul>
<main layout:fragment="content">
<ul class="nav nav-tabs navback" role="tablist">
<li class="nav-item"><a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_list">Liste</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_schedule">Kalender</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_project">Projekt</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_module">Modul</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_job">Aufgabe</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_billing">Abrechnung</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_overtime">Überstunden</a></li>
<li class="nav-item"><a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_slot">Slots</a></li>
<li class="nav-item">
<a class="nav-link navlinkstyle active" data-bs-toggle="tab" href="#div_list">Liste</a>
</li>
<li class="nav-item">
<a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_schedule">Kalender</a>
</li>
<li class="nav-item">
<a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_project">Projekt</a>
</li>
<li class="nav-item">
<a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_module">Modul</a>
</li>
<li class="nav-item">
<a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_job">Aufgabe</a>
</li>
<li class="nav-item">
<a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_billing">Abrechnung</a>
</li>
<li class="nav-item">
<a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_overtime">Überstunden</a>
</li>
<li class="nav-item">
<a class="nav-link navlinkstyle" data-bs-toggle="tab" href="#div_slot">Slots</a>
</li>
</ul>
<div class="tabdivblurred tab-content">
<div id="div_list" class="tab-pane active tab-pane-table">
@ -71,33 +89,44 @@
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Favoriten</button>
<ul class="dropdown-menu">
<li th:each="f : ${favorites}">
<a class="dropdown-item" th:href="@{/done/usefav/{id}(id=${f.fkFavorite})}"><span th:text="${f.project} + ' ' + ${f.module} + ' ' + ${f.job}"></span></a>
<a class="dropdown-item" th:href="@{/done/usefav/{id}(id=${f.fkFavorite})}">
<span th:text="${f.project} + ' ' + ${f.module} + ' ' + ${f.job}"></span>
</a>
</li>
</ul>
</div>
</div>
</th>
</tr>
</thead>
<tbody>
<tr th:each="done : ${doneList}">
<td><a class="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}"><span th:text="${done.timeNote}"></span></a>
<a th:if="${done.timeUntil == null}" style="margin-left: 4px" class="btn-list" th:href="@{/done/end/{id}(id=${done.pk})}" title="aktuelle Uhrzeit setzen"><i class="fa fa-clock"></i></a>
</td>
<td><a class="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}"><span th:text="${done.timeDiff}"></span></a></td>
<td><a class="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}"><span class="boldtext"
th:text="${done.project?.name}"></span></a></td>
<td><a class="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}"><span class="boldtext"
th:text="${done.module?.name}"></span></a></td>
<td><a class="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}"><span class="boldtext"
th:text="${done.activity?.name}"></span></a></td>
<td><span th:text="${done.billing.shortcut}" th:class="'billing ' + ${done.billing.csskey}"
th:if="${done.billing != null}"></span></td>
<td>
<a class="btn-list" th:href="@{/done/copy/{id}(id=${done.pk})}" title="Aufgabe neu beginnen"><i class="fa fa-copy"></i></a>
<a class="btn-list" th:href="@{/done/edit/{id}(id=${done.pk})}" title="Eintrag bearbeiten"><i class="fa fa-edit"></i></a>
<a class="btn-list" th:href="@{/done/favorize/{id}(id=${done.pk})}" title="als Favorit speichern" th:if="${!done.isFavorite}"><i class="far fa-star golden"></i></a>
<a class="btn-list" th:href="@{/done/unfavorize/{id}(id=${done.pk})}" title="Favoritenstatus entfernen" th:if="${done.isFavorite}"><i class="fas fa-star golden"></i></a>
</td>
<td><a class="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}">
<span th:text="${done.timeNote}"></span>
</a> <a th:if="${done.timeUntil == null}" style="margin-left: 4px" class="btn-list" th:href="@{/done/end/{id}(id=${done.pk})}" title="aktuelle Uhrzeit setzen">
<i class="fa fa-clock"></i>
</a></td>
<td><a class="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}">
<span th:text="${done.timeDiff}"></span>
</a></td>
<td><a class="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}">
<span class="boldtext" th:text="${done.project?.name}"></span>
</a></td>
<td><a class="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}">
<span class="boldtext" th:text="${done.module?.name}"></span>
</a></td>
<td><a class="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}">
<span class="boldtext" th:text="${done.activity?.name}"></span>
</a></td>
<td><span th:text="${done.billing.shortcut}" th:class="'billing ' + ${done.billing.csskey}" th:if="${done.billing != null}"></span></td>
<td><a class="btn-list" th:href="@{/done/copy/{id}(id=${done.pk})}" title="Aufgabe neu beginnen">
<i class="fa fa-copy"></i>
</a> <a class="btn-list" th:href="@{/done/edit/{id}(id=${done.pk})}" title="Eintrag bearbeiten">
<i class="fa fa-edit"></i>
</a> <a class="btn-list" th:href="@{/done/favorize/{id}(id=${done.pk})}" title="als Favorit speichern" th:if="${!done.isFavorite}">
<i class="far fa-star golden"></i>
</a> <a class="btn-list" th:href="@{/done/unfavorize/{id}(id=${done.pk})}" title="Favoritenstatus entfernen" th:if="${done.isFavorite}">
<i class="fas fa-star golden"></i>
</a></td>
</tr>
</tbody>
<tfoot>
@ -111,14 +140,10 @@
</tr>
<tr>
<td></td>
<td><span th:if="${sum.getBillingTime('WP2') != '0,0 h'}"><span class="billing WP2">WP2</span><span
th:text="${sum.getBillingTime('WP2')}" class="distfat"></span></span></td>
<td><span th:if="${sum.getBillingTime('WP4') != '0,0 h'}"><span class="billing WP4">WP4</span><span
th:text="${sum.getBillingTime('WP4')}" class="distfat"></span></span></td>
<td><span th:if="${sum.getBillingTime('WP5') != '0,0 h'}"><span class="billing WP5">WP5</span><span
th:text="${sum.getBillingTime('WP5')}" class="distfat"></span></span></td>
<td><span th:if="${sum.getBillingTime('TA3') != '0,0 h'}"><span class="billing TA3">TA3</span><span
th:text="${sum.getBillingTime('TA3')}" class="distfat"></span></span></td>
<td><span th:if="${sum.getBillingTime('WP2') != '0,0 h'}"><span class="billing WP2">WP2</span><span th:text="${sum.getBillingTime('WP2')}" class="distfat"></span></span></td>
<td><span th:if="${sum.getBillingTime('WP4') != '0,0 h'}"><span class="billing WP4">WP4</span><span th:text="${sum.getBillingTime('WP4')}" class="distfat"></span></span></td>
<td><span th:if="${sum.getBillingTime('WP5') != '0,0 h'}"><span class="billing WP5">WP5</span><span th:text="${sum.getBillingTime('WP5')}" class="distfat"></span></span></td>
<td><span th:if="${sum.getBillingTime('TA3') != '0,0 h'}"><span class="billing TA3">TA3</span><span th:text="${sum.getBillingTime('TA3')}" class="distfat"></span></span></td>
<td colspan="2"><span class="billing">X</span><span th:text="${sum.getBillingTime(null)}" class="distfat"></span></td>
</tr>
</tfoot>
@ -140,13 +165,14 @@
<tr th:each="project : ${projectList}">
<td><span th:text="${project.name}"></span></td>
<td><span th:text="${project.percentUsage}"></span></td>
<td><a th:href="@{/done/edit/project/{id}(id=${project.pk})}" th:title="${project.pk}"><i class="fa fa-edit"></i></a></td>
<td><a th:href="@{/done/edit/project/{id}(id=${project.pk})}" th:title="${project.pk}">
<i class="fa fa-edit"></i>
</a></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3"><a class="nav-link btn btn-success btn-white-text" th:href="@{/done/add/project}">neues Projekt</a>
</td>
<td colspan="3"><a class="nav-link btn btn-success btn-white-text" th:href="@{/done/add/project}">neues Projekt</a></td>
</tr>
</tfoot>
</table>
@ -164,7 +190,9 @@
<tr th:each="module : ${moduleList}">
<td><span th:text="${module.name}"></span></td>
<td><span th:text="${module.percentUsage}"></span></td>
<td><a th:href="@{/done/edit/module/{id}(id=${module.pk})}" th:title="${module.pk}"><i class="fa fa-edit"></i></a></td>
<td><a th:href="@{/done/edit/module/{id}(id=${module.pk})}" th:title="${module.pk}">
<i class="fa fa-edit"></i>
</a></td>
</tr>
</tbody>
<tfoot>
@ -187,7 +215,9 @@
<tr th:each="job : ${jobList}">
<td><span th:text="${job.name}"></span></td>
<td><span th:text="${job.percentUsage}"></span></td>
<td><a th:href="@{/done/edit/job/{id}(id=${job.pk})}" th:title="${job.pk}"><i class="fa fa-edit"></i></a></td>
<td><a th:href="@{/done/edit/job/{id}(id=${job.pk})}" th:title="${job.pk}">
<i class="fa fa-edit"></i>
</a></td>
</tr>
</tbody>
<tfoot>
@ -242,9 +272,8 @@
</div>
<div id="div_slot" class="tab-pane fade tab-pane-table">
<div class="alert alert-info">
Zur Berechnung der täglichen Überstunden müssen Slots angelegt werden, die definieren, an welchen Tagen wieviele Stunden zu arbeiten ist.
Die Überstundenberechnung hängt von der Vollständigkeit der vorhandenen Slots ab; fehlen Slots, wird die Arbeitszeit jener Tage nicht eingerechnet.<br />
Hier werden nur die Slots für diesen Monat angezeigt.
Zur Berechnung der täglichen Überstunden müssen Slots angelegt werden, die definieren, an welchen Tagen wieviele Stunden zu arbeiten ist. Die Überstundenberechnung hängt von der
Vollständigkeit der vorhandenen Slots ab; fehlen Slots, wird die Arbeitszeit jener Tage nicht eingerechnet.<br /> Hier werden nur die Slots für diesen Monat angezeigt.
</div>
<div class="container">
<div class="row row-weekday">
@ -259,21 +288,24 @@
<div class="row row-weekday">
<div class="col slot_badge" th:each="o : ${slotOffset}"></div>
<div class="col slot_badge" th:each="s : ${slots}">
<span class="slot_badge_left" th:text="${#temporals.format(s.day, 'dd.MM.')}">
</span><a th:href="@{/done/slot/{id}(id=${s.id})}" class="slot_badge_middle" th:if="${s.id}">
<span class="slot_badge_left" th:text="${#temporals.format(s.day, 'dd.MM.')}"> </span>
<a th:href="@{/done/slot/{id}(id=${s.id})}" class="slot_badge_middle" th:if="${s.id}">
<i class="fas fa-pencil"></i>
</a><a th:href="@{/done/slot/add?day={d}(d=${s.day})}" class="slot_badge_middle" th:unless="${s.id}">
</a>
<a th:href="@{/done/slot/add?day={d}(d=${s.day})}" class="slot_badge_middle" th:unless="${s.id}">
<i class="fas fa-plus"></i>
</a>
<span class="slot_badge_middle slot_reason" th:if="${s.reason}" th:text="${s.reason}"></span><span th:class="${s.reason != null ? 'slot_badge_right' : 'slot_badge_right boldy'}" th:text="${s.printTime()}" th:if="${s.id}"></span><span
class="slot_badge_right" th:unless="${s.id}">&nbsp;--:--&nbsp;</span>
<span class="slot_badge_middle slot_reason" th:if="${s.reason}" th:text="${s.reason}"></span><span th:class="${s.reason != null ? 'slot_badge_right' : 'slot_badge_right boldy'}"
th:text="${s.printTime()}" th:if="${s.id}"></span><span class="slot_badge_right" th:unless="${s.id}">&nbsp;--:--&nbsp;</span>
</div>
</div>
<br />
<div class="row">
<div class="col">
<div class="col-2"><a th:href="@{/done/slot/back}" class="btn btn-outline-primary">&lt;- zurück</a></div>
<div class="col-8">
<a th:href="@{/done/slot/range}" class="btn btn-outline-primary">mehrere Slots auf einmal anlegen</a>
</div>
<div class="col-2"><a th:href="@{/done/slot/forward}" class="btn btn-outline-primary">weiter -&gt;</a></div>
</div>
<br />
<div class="row alert alert-info">
@ -281,69 +313,73 @@
<span style="text-decoration: underline">Legende</span>
</div>
<div class="col">
Üb: Überstunden, Mehrarbeit<br />
Ur: Urlaub, Sonderurlaub, Kur<br />
gF: gesetzlicher Feiertag<br />
Üb: Überstunden, Mehrarbeit<br /> Ur: Urlaub, Sonderurlaub, Kur<br /> gF: gesetzlicher Feiertag<br />
</div>
<div class="col">
Kr: Arbeits- und Dienstunfähigkeit<br />
Gl: Freistellung aus Gleitzeitguthaben<br />
Ar: Arbeits- und Dienstbefreiung<br />
Kr: Arbeits- und Dienstunfähigkeit<br /> Gl: Freistellung aus Gleitzeitguthaben<br /> Ar: Arbeits- und Dienstbefreiung<br />
</div>
<div class="col">
mK: "mit Kind krank"<br />
Di: Dienstreise, Dienstgänge<br />
mK: "mit Kind krank"<br /> Di: Dienstreise, Dienstgänge<br />
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
let width = parseInt($("#schedule").css("min-width"));
let height = parseInt($("#schedule").css("min-height"));
var schedule = new Schedule("#schedule", width, height);
var ctx = $("#scheduleCanvas")[0].getContext("2d");
var currentDayRecords = JSON.parse('[(${schedule})]');
var scheduleRecords = currentDayRecords.schedule;
for (var i = 0; i < scheduleRecords.length; i++) {
var r = scheduleRecords[i];
var cssClass = r.billing;
var color = "#ffffff";
if (cssClass == "WP5") {
color = "#aa0000";
} else if (cssClass == "WP4") {
color = "#0000aa";
} else if (cssClass == "WP2") {
color = "#aaaa00";
} else if (cssClass == "TA3") {
color = "#00aa00";
}
/* daySlot 7 = sunday, but this should be slot 0 */
schedule.drawSlot(ctx, r.daySlot > 6 ? 0 : r.daySlot, r.from, r.until, "black", color);
}
var localeUrl = '[[@{/js/dataTables/de.json}]]';
$("#project_table").DataTable({
"language" : {
"url" : localeUrl
}
});
$("#module_table").DataTable({
"language" : {
"url" : localeUrl
}
});
$("#job_table").DataTable({
"language" : {
"url" : localeUrl
}
});
$("#billing_table").DataTable({
"language" : {
"url" : localeUrl
}
});
});
$(document)
.ready(
function() {
let width = parseInt($("#schedule").css(
"min-width"));
let height = parseInt($("#schedule").css(
"min-height"));
var schedule = new Schedule("#schedule", width,
height);
var ctx = $("#scheduleCanvas")[0]
.getContext("2d");
var currentDayRecords = JSON
.parse('[(${schedule})]');
var scheduleRecords = currentDayRecords.schedule;
for (var i = 0; i < scheduleRecords.length; i++) {
var r = scheduleRecords[i];
var cssClass = r.billing;
var color = "#ffffff";
if (cssClass == "WP5") {
color = "#aa0000";
} else if (cssClass == "WP4") {
color = "#0000aa";
} else if (cssClass == "WP2") {
color = "#aaaa00";
} else if (cssClass == "TA3") {
color = "#00aa00";
}
/* daySlot 7 = sunday, but this should be slot 0 */
schedule.drawSlot(ctx, r.daySlot > 6 ? 0
: r.daySlot, r.from, r.until,
"black", color);
}
var localeUrl = '[[@{/js/dataTables/de.json}]]';
$("#project_table").DataTable({
"language" : {
"url" : localeUrl
}
});
$("#module_table").DataTable({
"language" : {
"url" : localeUrl
}
});
$("#job_table").DataTable({
"language" : {
"url" : localeUrl
}
});
$("#billing_table").DataTable({
"language" : {
"url" : localeUrl
}
});
});
</script>
</main>
</body>