further processing
This commit is contained in:
@ -1,2 +1,13 @@
|
||||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=false
|
||||
show.console.view=false
|
||||
show.executions.view=false
|
||||
|
@ -106,6 +106,24 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
return o == null || timeFrom == null || o.getTimeFrom() == null ? 0 : timeFrom.compareTo(o.getTimeFrom());
|
||||
}
|
||||
|
||||
public String getTimeNote() {
|
||||
LocalDateTime earlier = timeFrom != null ? timeFrom : LocalDateTime.now();
|
||||
LocalDateTime later = timeUntil != null ? timeUntil : LocalDateTime.now();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (timeFrom == null) {
|
||||
buf.append(" ");
|
||||
} else {
|
||||
buf.append(String.format("%02d:%02d", earlier.getHour(), earlier.getMinute() % 60));
|
||||
}
|
||||
buf.append(" - ");
|
||||
if (timeUntil == null) {
|
||||
buf.append(" ");
|
||||
} else {
|
||||
buf.append(String.format("%02d:%02d", later.getHour(), later.getMinute() % 60));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String getTimeDiff() {
|
||||
LocalDateTime earlier = timeFrom != null ? timeFrom : LocalDateTime.now();
|
||||
LocalDateTime later = timeUntil != null ? timeUntil : LocalDateTime.now();
|
||||
|
@ -42,6 +42,7 @@ public class DoneController {
|
||||
List<DoneBean> list = doneService.getList(doneModel.getDay(), username);
|
||||
model.addAttribute("doneList", list);
|
||||
model.addAttribute("doneModel", doneModel);
|
||||
model.addAttribute("sum", new SummaryBean(list));
|
||||
model.addAttribute("projectList", doneService.getProjects());
|
||||
model.addAttribute("moduleList", doneService.getModules());
|
||||
model.addAttribute("jobList", doneService.getJobs());
|
||||
|
@ -0,0 +1,69 @@
|
||||
package de.jottyfan.timetrack.spring.done;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
*
|
||||
*/
|
||||
public class SummaryBean implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final List<DoneBean> list;
|
||||
|
||||
public SummaryBean(List<DoneBean> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the start
|
||||
*/
|
||||
public String getStart() {
|
||||
LocalDateTime found = LocalDateTime.now();
|
||||
for (DoneBean bean : list) {
|
||||
LocalDateTime ldt = bean.getTimeFrom();
|
||||
if (ldt != null && ldt.isBefore(found)) {
|
||||
found = ldt;
|
||||
}
|
||||
}
|
||||
return String.format("%02d:%02d", found.getHour(), found.getMinute() % 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the end
|
||||
*/
|
||||
public String getEnd() {
|
||||
LocalDateTime found = LocalDateTime.now();
|
||||
for (DoneBean bean : list) {
|
||||
LocalDateTime ldt = bean.getTimeUntil();
|
||||
if (ldt != null && found.isBefore(ldt)) {
|
||||
found = ldt;
|
||||
}
|
||||
}
|
||||
return String.format("%02d:%02d", found.getHour(), found.getMinute() % 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the total
|
||||
*/
|
||||
public String getTotal() {
|
||||
return "TODO";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pause
|
||||
*/
|
||||
public String getPause() {
|
||||
return "TODO";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the overdue
|
||||
*/
|
||||
public String getOverdue() {
|
||||
return "TODO";
|
||||
}
|
||||
}
|
@ -68,53 +68,81 @@ public class DoneGateway {
|
||||
/**
|
||||
* get all projects from the database
|
||||
*
|
||||
* @param includeNull if true, add a null value at the beginning of the result
|
||||
*
|
||||
* @return a list of found projects
|
||||
*
|
||||
* @throws DataAccessException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
public List<TProjectRecord> getAllProjects() throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
return getJooq().selectFrom(T_PROJECT).orderBy(T_PROJECT.NAME).fetchInto(TProjectRecord.class);
|
||||
public List<TProjectRecord> getAllProjects(boolean includeNull) throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
List<TProjectRecord> list = new ArrayList<>();
|
||||
if (includeNull) {
|
||||
list.add(new TProjectRecord(null, null, "---"));
|
||||
}
|
||||
list.addAll(getJooq().selectFrom(T_PROJECT).orderBy(T_PROJECT.NAME).fetchInto(TProjectRecord.class));
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all modules from the database
|
||||
*
|
||||
* @param includeNull if true, add a null value at the beginning of the result
|
||||
*
|
||||
* @return a list of found modules
|
||||
*
|
||||
* @throws DataAccessException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
public List<TModuleRecord> getAllModules() throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
return getJooq().selectFrom(T_MODULE).orderBy(T_MODULE.NAME).fetchInto(TModuleRecord.class);
|
||||
public List<TModuleRecord> getAllModules(boolean includeNull) throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
List<TModuleRecord> list = new ArrayList<>();
|
||||
if (includeNull) {
|
||||
list.add(new TModuleRecord(null, null, "---"));
|
||||
}
|
||||
list.addAll(getJooq().selectFrom(T_MODULE).orderBy(T_MODULE.NAME).fetchInto(TModuleRecord.class));
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all jobs from the database
|
||||
*
|
||||
* @param includeNull if true, add a null value at the beginning of the result
|
||||
*
|
||||
* @return a list of found jobs
|
||||
*
|
||||
* @throws DataAccessException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
public List<TJobRecord> getAllJobs() throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
return getJooq().selectFrom(T_JOB).orderBy(T_JOB.NAME).fetchInto(TJobRecord.class);
|
||||
public List<TJobRecord> getAllJobs(boolean includeNull) throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
List<TJobRecord> list = new ArrayList<>();
|
||||
if (includeNull) {
|
||||
list.add(new TJobRecord(null, null, "---"));
|
||||
}
|
||||
list.addAll(getJooq().selectFrom(T_JOB).orderBy(T_JOB.NAME).fetchInto(TJobRecord.class));
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* get all billings from the database
|
||||
*
|
||||
* @param includeNull if true, add a null value at the beginning of the result
|
||||
*
|
||||
* @return a list of found billings
|
||||
*
|
||||
* @throws DataAccessException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SQLException
|
||||
*/
|
||||
public List<TBillingRecord> getAllBillings() throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
return getJooq().selectFrom(T_BILLING).orderBy(T_BILLING.NAME).fetchInto(TBillingRecord.class);
|
||||
public List<TBillingRecord> getAllBillings(boolean includeNull) throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
List<TBillingRecord> list = new ArrayList<>();
|
||||
if (includeNull) {
|
||||
list.add(new TBillingRecord(null, null, "---", null, null));
|
||||
}
|
||||
list.addAll(getJooq().selectFrom(T_BILLING).orderBy(T_BILLING.NAME).fetchInto(TBillingRecord.class));
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,7 +156,7 @@ public class DoneGateway {
|
||||
private Map<Integer, TProjectRecord> getProjectMap()
|
||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
Map<Integer, TProjectRecord> map = new HashMap<>();
|
||||
for (TProjectRecord r : getAllProjects()) {
|
||||
for (TProjectRecord r : getAllProjects(false)) {
|
||||
map.put(r.getPk(), r);
|
||||
}
|
||||
return map;
|
||||
@ -144,7 +172,7 @@ public class DoneGateway {
|
||||
*/
|
||||
private Map<Integer, TModuleRecord> getModuleMap() throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
Map<Integer, TModuleRecord> map = new HashMap<>();
|
||||
for (TModuleRecord r : getAllModules()) {
|
||||
for (TModuleRecord r : getAllModules(false)) {
|
||||
map.put(r.getPk(), r);
|
||||
}
|
||||
return map;
|
||||
@ -160,7 +188,7 @@ public class DoneGateway {
|
||||
*/
|
||||
private Map<Integer, TJobRecord> getJobMap() throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
Map<Integer, TJobRecord> map = new HashMap<>();
|
||||
for (TJobRecord r : getAllJobs()) {
|
||||
for (TJobRecord r : getAllJobs(false)) {
|
||||
map.put(r.getPk(), r);
|
||||
}
|
||||
return map;
|
||||
@ -177,7 +205,7 @@ public class DoneGateway {
|
||||
private Map<Integer, TBillingRecord> getBillingMap()
|
||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
Map<Integer, TBillingRecord> map = new HashMap<>();
|
||||
for (TBillingRecord r : getAllBillings()) {
|
||||
for (TBillingRecord r : getAllBillings(false)) {
|
||||
map.put(r.getPk(), r);
|
||||
}
|
||||
return map;
|
||||
@ -207,8 +235,8 @@ public class DoneGateway {
|
||||
T_DONE.FK_JOB,
|
||||
T_DONE.FK_BILLING)
|
||||
.from(T_DONE)
|
||||
.where(T_DONE.TIME_FROM.between(dayStart, dayEnd))
|
||||
.and(T_DONE.TIME_UNTIL.between(dayStart, dayEnd))
|
||||
.where(T_DONE.TIME_FROM.between(dayStart, dayEnd).or(T_DONE.TIME_FROM.isNull()))
|
||||
.and(T_DONE.TIME_UNTIL.between(dayStart, dayEnd).or(T_DONE.TIME_UNTIL.isNull()))
|
||||
.and(T_DONE.FK_LOGIN.eq(userId == null ? -999999 : userId));
|
||||
// @formatter:on
|
||||
LOGGER.debug("{}", sql.toString());
|
||||
|
@ -70,7 +70,7 @@ public class DoneService implements IDoneService {
|
||||
@Override
|
||||
public List<TProjectRecord> getProjects() {
|
||||
try {
|
||||
return new DoneGateway(dsl).getAllProjects();
|
||||
return new DoneGateway(dsl).getAllProjects(true);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return new ArrayList<>();
|
||||
@ -80,7 +80,7 @@ public class DoneService implements IDoneService {
|
||||
@Override
|
||||
public List<TModuleRecord> getModules() {
|
||||
try {
|
||||
return new DoneGateway(dsl).getAllModules();
|
||||
return new DoneGateway(dsl).getAllModules(true);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return new ArrayList<>();
|
||||
@ -90,7 +90,7 @@ public class DoneService implements IDoneService {
|
||||
@Override
|
||||
public List<TJobRecord> getJobs() {
|
||||
try {
|
||||
return new DoneGateway(dsl).getAllJobs();
|
||||
return new DoneGateway(dsl).getAllJobs(true);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return new ArrayList<>();
|
||||
@ -100,7 +100,7 @@ public class DoneService implements IDoneService {
|
||||
@Override
|
||||
public List<TBillingRecord> getBillings() {
|
||||
try {
|
||||
return new DoneGateway(dsl).getAllBillings();
|
||||
return new DoneGateway(dsl).getAllBillings(true);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return new ArrayList<>();
|
||||
|
@ -163,3 +163,57 @@ body {
|
||||
.fc-content {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn-white-text {
|
||||
color: white !important;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.hoverlink {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.hoverlink:hover {
|
||||
color: #1a5f64;
|
||||
}
|
||||
|
||||
.boldtext {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.emphgreen {
|
||||
font-weight: bolder;
|
||||
color: #136600;
|
||||
border: 1px solid gray;
|
||||
border-radius: 8px;
|
||||
background-image: linear-gradient(to left, #e6e6e6, white);
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.emphblue {
|
||||
font-weight: bolder;
|
||||
color: #1a5fb4;
|
||||
border: 1px solid gray;
|
||||
border-radius: 8px;
|
||||
background-image: linear-gradient(to left, #e6e6e6, white);
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.emphorange {
|
||||
font-weight: bolder;
|
||||
color: #c64600;
|
||||
border: 1px solid gray;
|
||||
border-radius: 8px;
|
||||
background-image: linear-gradient(to left, #e6e6e6, white);
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.emphred {
|
||||
font-weight: bolder;
|
||||
color: #a51d2d;
|
||||
border: 1px solid gray;
|
||||
border-radius: 8px;
|
||||
background-image: linear-gradient(to left, #e6e6e6, white);
|
||||
padding: 4px;
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
<body>
|
||||
<font layout:fragment="title">Kontakte</font>
|
||||
<ul layout:fragment="menu">
|
||||
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/contact/add}">Neuen
|
||||
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link btn btn-success btn-white-text" th:href="@{/contact/add}">Neuen
|
||||
Kontakt anlegen</a></li>
|
||||
</ul>
|
||||
<main layout:fragment="content">
|
||||
|
@ -9,7 +9,7 @@
|
||||
<ul layout:fragment="menuitem">
|
||||
<li class="nav-item" sec:authorize="hasRole('timetrack_user')">
|
||||
<form th:action="@{/done/list}" th:object="${doneModel}" method="post">
|
||||
<div class="nav-link" style="padding-top: 0px !important">
|
||||
<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}" />
|
||||
<button type="submit" class="btn btn-primary btn-sm">Ok</button>
|
||||
@ -19,7 +19,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
<ul layout:fragment="menu">
|
||||
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/done/add}">Neuer
|
||||
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link btn btn-success btn-white-text" th:href="@{/done/add}">Neuer
|
||||
Eintrag</a></li>
|
||||
</ul>
|
||||
<main layout:fragment="content">
|
||||
@ -38,25 +38,36 @@
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Von</th>
|
||||
<th>Bis</th>
|
||||
<th>Zeit</th>
|
||||
<th>Projekt</th>
|
||||
<th>Modul</th>
|
||||
<th>Aufgabe</th>
|
||||
<th>Abrechnung</th>
|
||||
<th>Dauer</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="done : ${doneList}">
|
||||
<td><a th:href="@{/done/edit/{id}(id=${done.pk})}"><span th:text="${#temporals.format(done.timeFrom, 'HH:mm')}"></span></a></td>
|
||||
<td><a th:href="@{/done/edit/{id}(id=${done.pk})}"><span th:text="${#temporals.format(done.timeUntil, 'HH:mm')}"></span></a></td>
|
||||
<td><a th:href="@{/done/edit/{id}(id=${done.pk})}"><span th:text="${done.project.name}"></span></a></td>
|
||||
<td><a th:href="@{/done/edit/{id}(id=${done.pk})}"><span th:text="${done.module.name}"></span></a></td>
|
||||
<td><a th:href="@{/done/edit/{id}(id=${done.pk})}"><span 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="hoverlink" th:href="@{/done/edit/{id}(id=${done.pk})}"><span th:text="${done.timeNote}"></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><span th:text="${done.timeDiff}"></span></td>
|
||||
<td><a th:href="@{/done/edit/{id}(id=${done.pk})}" th:title="${done.pk}"><i class="fa fa-edit"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>Zusammenfassung</td>
|
||||
<td>Start: <span class="emphgreen" th:text="${sum.start}"></span></td>
|
||||
<td>Ende: <span class="emphgreen" th:text="${sum.end}"></span></td>
|
||||
<td>Arbeitszeit total: <span class="emphblue" th:text="${sum.total}"></span></td>
|
||||
<td>Pausezeit total: <span class="emphorange" th:text="${sum.pause}"></span></td>
|
||||
<td>Überstunden: <span class="emphred" th:text="${sum.overdue}"></span></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div id="div_summary" class="tab-pane fade">Zusammenfassung</div>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<body>
|
||||
<font layout:fragment="title">Notizen</font>
|
||||
<ul layout:fragment="menu">
|
||||
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link" th:href="@{/note/add}">Neue Notiz
|
||||
<li class="nav-item" sec:authorize="hasRole('timetrack_user')"><a class="nav-link btn btn-success btn-white-text" th:href="@{/note/add}">Neue Notiz
|
||||
anlegen</a></li>
|
||||
</ul>
|
||||
<main layout:fragment="content">
|
||||
|
Reference in New Issue
Block a user