schedule for weeks
This commit is contained in:
@ -0,0 +1,28 @@
|
||||
package de.jottyfan.timetrack.help;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author henkej
|
||||
*
|
||||
*/
|
||||
public class LocalDateHelper {
|
||||
|
||||
/**
|
||||
* find the day of the week in relation to day
|
||||
*
|
||||
* @param day the day to start the search from
|
||||
* @param dayOfWeek the day of the week that is wanted
|
||||
* @param backwards if true, search before day, if false, search after day
|
||||
* @return the found date
|
||||
*/
|
||||
public static final LocalDate seekDay(LocalDate day, DayOfWeek dayOfWeek, boolean backwards) {
|
||||
LocalDate found = day;
|
||||
while (!found.getDayOfWeek().equals(dayOfWeek)) {
|
||||
found = backwards ? found.minusDays(1) : found.plusDays(1);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
@ -76,7 +76,8 @@ public class DoneBean implements Serializable, Comparable<DoneBean> {
|
||||
|
||||
public final String toJson() {
|
||||
StringBuilder buf = new StringBuilder("{");
|
||||
buf.append("\"from\": ").append(nullable(timeFrom, "HH:mm"));
|
||||
buf.append("\"daySlot\": ").append(day == null ? "null" : day.getDayOfWeek().getValue());
|
||||
buf.append(", \"from\": ").append(nullable(timeFrom, "HH:mm"));
|
||||
buf.append(", \"until\": ").append(nullable(timeUntil, "HH:mm"));
|
||||
buf.append(", \"billing\": ").append(nullable(billing, null));
|
||||
buf.append("}");
|
||||
|
@ -45,11 +45,13 @@ public class DoneController {
|
||||
Duration maxWorkTime = Duration.ofHours(8); // TODO: to the configuration file
|
||||
LocalDate day = doneModel.getDay();
|
||||
List<DoneBean> list = doneService.getList(day, username);
|
||||
List<DoneBean> week = doneService.getWeek(day, username);
|
||||
SummaryBean bean = new SummaryBean(list, day, maxWorkTime);
|
||||
SummaryBean weekBean = new SummaryBean(week, day, maxWorkTime);
|
||||
model.addAttribute("doneList", list);
|
||||
model.addAttribute("doneModel", doneModel);
|
||||
model.addAttribute("sum", bean);
|
||||
model.addAttribute("schedule", bean.toJson()); // TODO: add the other days of that week
|
||||
model.addAttribute("schedule", weekBean.toJson());
|
||||
model.addAttribute("projectList", doneService.getProjects(false));
|
||||
model.addAttribute("moduleList", doneService.getModules(false));
|
||||
model.addAttribute("jobList", doneService.getJobs(false));
|
||||
|
@ -5,7 +5,6 @@ import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import de.jottyfan.timetrack.db.done.tables.records.TProjectRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.VBillingRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.VJobRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.VModuleRecord;
|
||||
@ -18,20 +17,13 @@ import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
|
||||
*/
|
||||
public interface IDoneService {
|
||||
public List<DoneBean> getList(LocalDate day, String username);
|
||||
|
||||
public List<DoneBean> getWeek(LocalDate day, String username);
|
||||
public DoneBean getBean(Integer id);
|
||||
|
||||
public String getCurrentUser(HttpServletRequest request);
|
||||
|
||||
public List<VProjectRecord> getProjects(boolean includeNull);
|
||||
|
||||
public List<VModuleRecord> getModules(boolean includeNull);
|
||||
|
||||
public List<VJobRecord> getJobs(boolean includeNull);
|
||||
|
||||
public List<VBillingRecord> getBillings(boolean includeNull);
|
||||
|
||||
public Integer doUpsert(DoneBean bean, String username);
|
||||
|
||||
public Integer doDelete(Integer id);
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import java.io.Serializable;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -19,17 +18,23 @@ public class SummaryBean implements Serializable {
|
||||
private final LocalDate day;
|
||||
private final List<DoneBean> list;
|
||||
|
||||
/**
|
||||
* @param list the list of beans
|
||||
* @param day the day that this selection refers to; might be the day
|
||||
* of the week for weekly sets
|
||||
* @param maxDayWorktime the maximum work time of a day
|
||||
*/
|
||||
public SummaryBean(List<DoneBean> list, LocalDate day, Duration maxDayWorktime) {
|
||||
this.list = list;
|
||||
this.day = day;
|
||||
this.maxDayWorktime = maxDayWorktime;
|
||||
}
|
||||
|
||||
|
||||
public String toJson() {
|
||||
StringBuilder buf = new StringBuilder("{");
|
||||
buf.append("\"maxDayWorktime\": \"").append(String.format("%02d:%02d", maxDayWorktime.toHoursPart(), maxDayWorktime.toMinutesPart()));
|
||||
buf.append("\", \"daySlot\": ").append(day == null ? "null" : day.getDayOfWeek().getValue());
|
||||
buf.append(", \"schedule\": [");
|
||||
buf.append("\"maxDayWorktime\": \"")
|
||||
.append(String.format("%02d:%02d", maxDayWorktime.toHoursPart(), maxDayWorktime.toMinutesPart()));
|
||||
buf.append("\", \"schedule\": [");
|
||||
boolean first = true;
|
||||
for (DoneBean bean : list) {
|
||||
if (!first) {
|
||||
@ -67,7 +72,7 @@ public class SummaryBean implements Serializable {
|
||||
int minutesPercent = Float.valueOf((5f / 3f) * minutes).intValue();
|
||||
return String.format("%d,%d h", duration.toHoursPart(), minutesPercent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the start
|
||||
*/
|
||||
|
@ -8,6 +8,7 @@ import static de.jottyfan.timetrack.db.done.Tables.V_PROJECT;
|
||||
import static de.jottyfan.timetrack.db.profile.Tables.T_LOGIN;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
@ -34,6 +35,7 @@ import de.jottyfan.timetrack.db.done.tables.records.VJobRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.VModuleRecord;
|
||||
import de.jottyfan.timetrack.db.done.tables.records.VProjectRecord;
|
||||
import de.jottyfan.timetrack.db.profile.tables.records.TLoginRecord;
|
||||
import de.jottyfan.timetrack.help.LocalDateHelper;
|
||||
import de.jottyfan.timetrack.spring.done.DoneBean;
|
||||
|
||||
/**
|
||||
@ -216,19 +218,19 @@ public class DoneGateway {
|
||||
}
|
||||
|
||||
/**
|
||||
* get list of entries of day
|
||||
* get list of entries of interval
|
||||
*
|
||||
* @param day the day
|
||||
* @param start the lower limit
|
||||
* @param end the upper limit
|
||||
* @param userId the id of the user
|
||||
*
|
||||
* @return a list (an empty one at least)
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
public List<DoneBean> getAllOfDay(LocalDate day, Integer userId)
|
||||
private List<DoneBean> getAllOfInterval(LocalDateTime start, LocalDateTime end, Integer userId)
|
||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
LocalDateTime dayStart = day.atStartOfDay();
|
||||
LocalDateTime dayEnd = day.atTime(23, 59, 59);
|
||||
SelectConditionStep<Record7<Integer, LocalDateTime, LocalDateTime, Integer, Integer, Integer, Integer>> sql = getJooq()
|
||||
// @formatter:off
|
||||
.select(T_DONE.PK,
|
||||
@ -239,8 +241,8 @@ public class DoneGateway {
|
||||
T_DONE.FK_JOB,
|
||||
T_DONE.FK_BILLING)
|
||||
.from(T_DONE)
|
||||
.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()))
|
||||
.where(T_DONE.TIME_FROM.between(start, end).or(T_DONE.TIME_FROM.isNull()))
|
||||
.and(T_DONE.TIME_UNTIL.between(start, end).or(T_DONE.TIME_UNTIL.isNull()))
|
||||
.and(T_DONE.FK_LOGIN.eq(userId == null ? -999999 : userId));
|
||||
// @formatter:on
|
||||
LOGGER.debug("{}", sql.toString());
|
||||
@ -265,6 +267,40 @@ public class DoneGateway {
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* get list of entries of day
|
||||
*
|
||||
* @param day the day
|
||||
*
|
||||
* @return a list (an empty one at least)
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
public List<DoneBean> getAllOfDay(LocalDate day, Integer userId)
|
||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
LocalDateTime dayStart = day.atStartOfDay();
|
||||
LocalDateTime dayEnd = day.atTime(23, 59, 59);
|
||||
return getAllOfInterval(dayStart, dayEnd, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all entries of the week where day belongs to
|
||||
*
|
||||
* @param day the day that the week refers to
|
||||
* @param userId the id of the user
|
||||
* @return a list of done beans; an empty one at least
|
||||
* @throws SQLException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws DataAccessException
|
||||
*/
|
||||
public List<DoneBean> getAllOfWeek(LocalDate day, Integer userId)
|
||||
throws DataAccessException, ClassNotFoundException, SQLException {
|
||||
LocalDate sunday = LocalDateHelper.seekDay(day, DayOfWeek.SUNDAY, true);
|
||||
LocalDate saturday = LocalDateHelper.seekDay(day, DayOfWeek.SATURDAY, false);
|
||||
return getAllOfInterval(sunday.atStartOfDay(), saturday.atTime(23, 59, 59), userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete an entry from the database
|
||||
*
|
||||
|
@ -57,6 +57,22 @@ public class DoneService implements IDoneService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DoneBean> getWeek(LocalDate day, String username) {
|
||||
try {
|
||||
DoneGateway gw = new DoneGateway(dsl);
|
||||
Integer userId = gw.getUserId(username);
|
||||
if (userId == null) {
|
||||
LOGGER.warn("userId of user {} is null", username);
|
||||
}
|
||||
return gw.getAllOfWeek(day, userId);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DoneBean getBean(Integer id) {
|
||||
try {
|
||||
|
@ -17,16 +17,32 @@ class Schedule {
|
||||
|
||||
drawBackgroundDay = function(ctx, width, height, offsetx) {
|
||||
var hourHeight = parseInt(height / 24);
|
||||
var fs = ["#eeeeee", "#bbbbbb", "#eeeeee", "#bbbbbb", "#eeeeee", "#bbbbbb",
|
||||
"#faf0fa", "#d9cbd9", "#faf0fa", "#9acbd9", "#cdf0fa", "#9acbd9",
|
||||
"#cdf0fa", "#9acbd9", "#cdf0fa", "#d9cbd9", "#faf0fa", "#d9cbd9",
|
||||
"#faf0fa", "#d9cbd9", "#eeeeee", "#bbbbbb", "#eeeeee", "#bbbbbb"];
|
||||
for (var i = 0; i < 24; i++) {
|
||||
var x = parseInt(offsetx);
|
||||
var y = parseInt(i * hourHeight);
|
||||
var w = parseInt(width);
|
||||
var h = parseInt(hourHeight);
|
||||
ctx.fillStyle = (i > 8 & i <= 17) ? (i % 2 ? "#cdf0fa" : "#9acbd9") : (i % 2 ? "#faf0fa" : "#d9cbd9");
|
||||
ctx.fillStyle = fs[i];
|
||||
ctx.fillRect(x, y, w, h);
|
||||
}
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeStyle = "white";
|
||||
ctx.strokeRect(offsetx, 0, width, height);
|
||||
ctx.strokeStyle = "black";
|
||||
ctx.lineWidth = 2;
|
||||
ctx.moveTo(parseInt(offsetx), parseInt(hourHeight * 6));
|
||||
ctx.lineTo(parseInt(offsetx + width), parseInt(hourHeight * 6));
|
||||
ctx.stroke();
|
||||
ctx.moveTo(parseInt(offsetx), parseInt(hourHeight * 12));
|
||||
ctx.lineTo(parseInt(offsetx + width), parseInt(hourHeight * 12));
|
||||
ctx.stroke();
|
||||
ctx.moveTo(parseInt(offsetx), parseInt(hourHeight * 18));
|
||||
ctx.lineTo(parseInt(offsetx + width), parseInt(hourHeight * 18));
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
drawBackgroundWeek = function(ctx, width, height) {
|
||||
|
@ -191,7 +191,6 @@
|
||||
var ctx = $("#scheduleCanvas")[0].getContext("2d");
|
||||
var currentDayRecords = JSON.parse('[(${schedule})]');
|
||||
var scheduleRecords = currentDayRecords.schedule;
|
||||
var daySlot = currentDayRecords.daySlot;
|
||||
for (var i = 0; i < scheduleRecords.length; i++) {
|
||||
var r = scheduleRecords[i];
|
||||
var cssClass = r.billing;
|
||||
@ -206,7 +205,7 @@
|
||||
color = "#00aa00";
|
||||
}
|
||||
/* daySlot 7 = sunday, but this should be slot 0 */
|
||||
schedule.drawSlot(ctx, daySlot > 6 ? 0 : daySlot, r.from, r.until, "black", color);
|
||||
schedule.drawSlot(ctx, r.daySlot > 6 ? 0 : r.daySlot, r.from, r.until, "black", color);
|
||||
}
|
||||
var localeUrl = '[[@{/js/dataTables/de.json}]]';
|
||||
$("#project_table").DataTable({
|
||||
|
Reference in New Issue
Block a user