add and remove work times
This commit is contained in:
@ -32,6 +32,10 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
private TModuleRecord module;
|
||||
private TJobRecord activity;
|
||||
private TBillingRecord billing;
|
||||
private Integer fkProject;
|
||||
private Integer fkModule;
|
||||
private Integer fkJob;
|
||||
private Integer fkBilling;
|
||||
|
||||
public DoneBean() {
|
||||
}
|
||||
@ -45,8 +49,12 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
this.module = moduleMap.get(r.getFkModule());
|
||||
this.activity = jobMap.get(r.getFkJob());
|
||||
this.billing = billingMap.get(r.getFkBilling());
|
||||
this.fkProject = project.getPk();
|
||||
this.fkModule = module.getPk();
|
||||
this.fkJob = activity.getPk();
|
||||
this.fkBilling = billing.getPk();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
StringBuilder buf = new StringBuilder("DoneBean{");
|
||||
@ -105,6 +113,22 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
return String.format("%02d:%02d", diff.toHours(), diff.toMinutes() % 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* try to find out what date this entry is for; if not found, use the current
|
||||
* date
|
||||
*
|
||||
* @return a local date
|
||||
*/
|
||||
public LocalDate getLocalDate() {
|
||||
if (timeFrom != null) {
|
||||
return timeFrom.toLocalDate();
|
||||
} else if (timeUntil != null) {
|
||||
return timeUntil.toLocalDate();
|
||||
} else {
|
||||
return LocalDate.now();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get local date time from s
|
||||
*
|
||||
@ -146,15 +170,15 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
public String getJobName() {
|
||||
return activity == null ? "" : activity.getName();
|
||||
}
|
||||
|
||||
|
||||
public String getBillingName() {
|
||||
return billing == null ? "" : billing.getName();
|
||||
}
|
||||
|
||||
|
||||
public String getBillingShortcut() {
|
||||
return billing == null ? "" : billing.getShortcut();
|
||||
}
|
||||
|
||||
|
||||
public String getBillingCsskey() {
|
||||
return billing == null ? "" : billing.getCsskey();
|
||||
}
|
||||
@ -205,6 +229,7 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
|
||||
public void setProject(TProjectRecord project) {
|
||||
this.project = project;
|
||||
this.fkProject = project != null ? project.getPk() : null;
|
||||
}
|
||||
|
||||
public TModuleRecord getModule() {
|
||||
@ -213,6 +238,7 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
|
||||
public void setModule(TModuleRecord module) {
|
||||
this.module = module;
|
||||
this.fkModule = module != null ? module.getPk() : null;
|
||||
}
|
||||
|
||||
public TJobRecord getActivity() {
|
||||
@ -221,6 +247,7 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
|
||||
public void setActivity(TJobRecord activity) {
|
||||
this.activity = activity;
|
||||
this.fkJob = activity != null ? activity.getPk() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -235,5 +262,62 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
*/
|
||||
public void setBilling(TBillingRecord billing) {
|
||||
this.billing = billing;
|
||||
this.fkBilling = billing != null ? billing.getPk() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fkProject
|
||||
*/
|
||||
public Integer getFkProject() {
|
||||
return fkProject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fkProject the fkProject to set
|
||||
*/
|
||||
public void setFkProject(Integer fkProject) {
|
||||
this.fkProject = fkProject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fkModule
|
||||
*/
|
||||
public Integer getFkModule() {
|
||||
return fkModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fkModule the fkModule to set
|
||||
*/
|
||||
public void setFkModule(Integer fkModule) {
|
||||
this.fkModule = fkModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fkJob
|
||||
*/
|
||||
public Integer getFkJob() {
|
||||
return fkJob;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fkJob the fkJob to set
|
||||
*/
|
||||
public void setFkJob(Integer fkJob) {
|
||||
this.fkJob = fkJob;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the fkBilling
|
||||
*/
|
||||
public Integer getFkBilling() {
|
||||
return fkBilling;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fkBilling the fkBilling to set
|
||||
*/
|
||||
public void setFkBilling(Integer fkBilling) {
|
||||
this.fkBilling = fkBilling;
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,30 @@ public class DoneController {
|
||||
bean = new DoneBean(); // the add case
|
||||
}
|
||||
model.addAttribute("doneBean", bean);
|
||||
// model.addAttribute("types", Arrays.asList(EnumNotetype.values()));
|
||||
// model.addAttribute("categories", Arrays.asList(EnumCategory.values()));
|
||||
model.addAttribute("projectList", doneService.getProjects());
|
||||
model.addAttribute("moduleList", doneService.getModules());
|
||||
model.addAttribute("jobList", doneService.getJobs());
|
||||
model.addAttribute("billingList", doneService.getBillings());
|
||||
return "done/item";
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@RequestMapping(value = "/done/upsert", method = RequestMethod.POST)
|
||||
public String doUpsert(Model model, @ModelAttribute DoneBean bean) {
|
||||
String username = doneService.getCurrentUser(request);
|
||||
Integer amount = doneService.doUpsert(bean, username);
|
||||
DoneModel doneModel = new DoneModel();
|
||||
doneModel.setDay(bean.getLocalDate());
|
||||
return amount.equals(1) ? getList(doneModel, model) : toItem(bean.getPk(), model);
|
||||
}
|
||||
|
||||
@RolesAllowed("timetrack_user")
|
||||
@GetMapping(value = "/done/delete/{id}")
|
||||
public String doDelete(@PathVariable Integer id, Model model) {
|
||||
DoneBean bean = doneService.getBean(id);
|
||||
Integer amount = doneService.doDelete(id);
|
||||
DoneModel doneModel = new DoneModel();
|
||||
doneModel.setDay(bean.getLocalDate());
|
||||
return amount.equals(1) ? getList(doneModel, model) : toItem(id, model);
|
||||
}
|
||||
}
|
||||
|
@ -29,4 +29,8 @@ public interface IDoneService {
|
||||
public List<TJobRecord> getJobs();
|
||||
|
||||
public List<TBillingRecord> getBillings();
|
||||
|
||||
public Integer doUpsert(DoneBean bean, String username);
|
||||
|
||||
public Integer doDelete(Integer id);
|
||||
}
|
||||
|
@ -19,9 +19,11 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.DeleteConditionStep;
|
||||
import org.jooq.InsertValuesStep7;
|
||||
import org.jooq.Record7;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.SelectConditionStep;
|
||||
import org.jooq.UpdateConditionStep;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@ -51,7 +53,7 @@ public class DoneGateway {
|
||||
public DSLContext getJooq() {
|
||||
return this.jooq;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the user id of the user with username
|
||||
*
|
||||
@ -248,4 +250,82 @@ public class DoneGateway {
|
||||
LOGGER.debug("{}", sql.toString());
|
||||
return sql.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* get the done bean of the pk
|
||||
*
|
||||
* @param pk the ID of the data set
|
||||
* @return the bean if found; null otherwise
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
public DoneBean getBean(Integer pk) throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
SelectConditionStep<Record7<Integer, LocalDateTime, LocalDateTime, Integer, Integer, Integer, Integer>> sql = getJooq()
|
||||
// @formatter:off
|
||||
.select(T_DONE.PK,
|
||||
T_DONE.TIME_FROM,
|
||||
T_DONE.TIME_UNTIL,
|
||||
T_DONE.FK_PROJECT,
|
||||
T_DONE.FK_MODULE,
|
||||
T_DONE.FK_JOB,
|
||||
T_DONE.FK_BILLING)
|
||||
.from(T_DONE)
|
||||
.where(T_DONE.PK.eq(pk));
|
||||
// @formatter:on
|
||||
LOGGER.debug("{}", sql.toString());
|
||||
Map<Integer, TProjectRecord> projectMap = getProjectMap();
|
||||
Map<Integer, TModuleRecord> moduleMap = getModuleMap();
|
||||
Map<Integer, TJobRecord> jobMap = getJobMap();
|
||||
Map<Integer, TBillingRecord> billingMap = getBillingMap();
|
||||
for (Record7<Integer, LocalDateTime, LocalDateTime, Integer, Integer, Integer, Integer> r : sql.fetch()) {
|
||||
DoneBean bean = new DoneBean();
|
||||
bean.setPk(r.get(T_DONE.PK));
|
||||
bean.setTimeFrom(r.get(T_DONE.TIME_FROM));
|
||||
bean.setTimeUntil(r.get(T_DONE.TIME_UNTIL));
|
||||
bean.setProject(projectMap.get(r.get(T_DONE.FK_PROJECT)));
|
||||
bean.setModule(moduleMap.get(r.get(T_DONE.FK_MODULE)));
|
||||
bean.setActivity(jobMap.get(r.get(T_DONE.FK_JOB)));
|
||||
bean.setBilling(billingMap.get(r.get(T_DONE.FK_BILLING)));
|
||||
return (bean);
|
||||
}
|
||||
return (null);
|
||||
}
|
||||
|
||||
public Integer upsert(DoneBean bean, Integer userId) {
|
||||
return bean.getPk() != null ? update(bean) : insert(bean, userId);
|
||||
}
|
||||
|
||||
private Integer insert(DoneBean bean, Integer userId) {
|
||||
InsertValuesStep7<TDoneRecord, LocalDateTime, LocalDateTime, Integer, Integer, Integer, Integer, Integer> sql = getJooq()
|
||||
// @formatter:off
|
||||
.insertInto(T_DONE,
|
||||
T_DONE.TIME_FROM,
|
||||
T_DONE.TIME_UNTIL,
|
||||
T_DONE.FK_PROJECT,
|
||||
T_DONE.FK_MODULE,
|
||||
T_DONE.FK_JOB,
|
||||
T_DONE.FK_BILLING,
|
||||
T_DONE.FK_LOGIN)
|
||||
.values(bean.getTimeFrom(), bean.getTimeUntil(), bean.getFkProject(), bean.getFkModule(), bean.getFkJob(), bean.getFkBilling(), userId);
|
||||
// @formatter:on
|
||||
LOGGER.debug(sql.toString());
|
||||
return sql.execute();
|
||||
}
|
||||
|
||||
private Integer update(DoneBean bean) {
|
||||
UpdateConditionStep<TDoneRecord> sql = getJooq()
|
||||
// @formatter:off
|
||||
.update(T_DONE)
|
||||
.set(T_DONE.TIME_FROM, bean.getTimeFrom())
|
||||
.set(T_DONE.TIME_UNTIL, bean.getTimeUntil())
|
||||
.set(T_DONE.FK_PROJECT, bean.getFkProject())
|
||||
.set(T_DONE.FK_MODULE, bean.getFkModule())
|
||||
.set(T_DONE.FK_JOB, bean.getFkJob())
|
||||
.set(T_DONE.FK_BILLING, bean.getFkBilling())
|
||||
.where(T_DONE.PK.eq(bean.getPk()));
|
||||
// @formatter:on
|
||||
LOGGER.debug(sql.toString());
|
||||
return sql.execute();
|
||||
}
|
||||
}
|
||||
|
@ -59,12 +59,16 @@ public class DoneService implements IDoneService {
|
||||
|
||||
@Override
|
||||
public DoneBean getBean(Integer id) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
try {
|
||||
return new DoneGateway(dsl).getBean(id);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TProjectRecord> getProjects() {
|
||||
public List<TProjectRecord> getProjects() {
|
||||
try {
|
||||
return new DoneGateway(dsl).getAllProjects();
|
||||
} catch (Exception e) {
|
||||
@ -103,4 +107,26 @@ public class DoneService implements IDoneService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doUpsert(DoneBean bean, String username) {
|
||||
try {
|
||||
DoneGateway gw = new DoneGateway(dsl);
|
||||
Integer userId = gw.getUserId(username);
|
||||
return gw.upsert(bean, userId);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer doDelete(Integer id) {
|
||||
try {
|
||||
return new DoneGateway(dsl).delete(id);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
72
src/main/resources/templates/done/item.html
Normal file
72
src/main/resources/templates/done/item.html
Normal file
@ -0,0 +1,72 @@
|
||||
<!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}">
|
||||
<head>
|
||||
<title>Arbeitszeit aktualisieren</title>
|
||||
</head>
|
||||
<body>
|
||||
<ul layout:fragment="menu">
|
||||
</ul>
|
||||
<main layout:fragment="content">
|
||||
<div class="container formpane">
|
||||
<form th:action="@{/done/upsert}" th:object="${doneBean}" method="post">
|
||||
<div class="row mb-3">
|
||||
<label for="inputPk" class="col-sm-2 col-form-label">Inhalt von Eintrag</label>
|
||||
<div class="col-sm-10">
|
||||
<input id="inputPk" type="text" th:field="*{pk}" class="form-control" readonly="readonly" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="inputTimefrom" class="col-sm-2 col-form-label">von</label>
|
||||
<div class="col-sm-10">
|
||||
<input id="inputTimefrom" type="text" th:field="*{timeFromString}" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="inputTimeuntil" class="col-sm-2 col-form-label">bis</label>
|
||||
<div class="col-sm-10">
|
||||
<input id="inputTimeuntil" type="text" th:field="*{timeUntilString}" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="inputProject" class="col-sm-2 col-form-label">Projekt</label>
|
||||
<select id="inputProject" class="form-control select2-single" th:field="*{fkProject}">
|
||||
<option th:each="i : ${projectList}" th:value="${i.pk}" th:text="${i.name}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="inputModule" class="col-sm-2 col-form-label">Modul</label>
|
||||
<select id="inputModule" class="form-control select2-single" th:field="*{fkModule}">
|
||||
<option th:each="i : ${moduleList}" th:value="${i.pk}" th:text="${i.name}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="inputJob" class="col-sm-2 col-form-label">Aufgabe</label>
|
||||
<select id="inputJob" class="form-control select2-single" th:field="*{fkJob}">
|
||||
<option th:each="i : ${jobList}" th:value="${i.pk}" th:text="${i.name}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="inputBilling" class="col-sm-2 col-form-label">Abrechnung</label>
|
||||
<select id="inputBilling" class="form-control select2-single" th:field="*{fkBilling}">
|
||||
<option th:each="i : ${billingList}" th:value="${i.pk}" th:text="${i.name}"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-2">Änderung</div>
|
||||
<div class="col-sm-10">
|
||||
<button type="submit" class="btn btn-success">speichern</button>
|
||||
<button type="submit" class="btn btn-secondary" th:formaction="@{/done/list}">abbrechen</button>
|
||||
<div class="dropdown float-right" th:if="${doneBean.pk != null}" sec:authorize="hasRole('timetrack_user')">
|
||||
<button class="btn btn-danger dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Eintrag löschen</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" th:href="@{/done/delete/{id}(id=${doneBean.pk})}">endgültig löschen</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
@ -48,11 +48,11 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="done : ${doneList}">
|
||||
<td><span th:text="${#temporals.format(done.timeFrom, 'HH:mm')}"></span></td>
|
||||
<td><span th:text="${#temporals.format(done.timeUntil, 'HH:mm')}"></span></td>
|
||||
<td><span th:text="${done.project.name}"></span></td>
|
||||
<td><span th:text="${done.module.name}"></span></td>
|
||||
<td><span th:text="${done.activity.name}"></span></td>
|
||||
<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>
|
||||
</tr>
|
||||
|
Reference in New Issue
Block a user