diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/WorkingDayRepositoryApi.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/WorkingDayRepositoryApi.java index 7e0cd3d..ab7752d 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/WorkingDayRepositoryApi.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/api/WorkingDayRepositoryApi.java @@ -46,4 +46,5 @@ public interface WorkingDayRepositoryApi { } delete(Integer.parseInt(array[0]),Integer.parseInt(array[1]),Integer.parseInt(array[2])); } + int getTotalOvertimeForDayInMinutes(int year, int month, int day); } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/ActivityRepositorySQLiteImpl.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/ActivityRepositorySQLiteImpl.java index 7b98912..ee0992d 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/ActivityRepositorySQLiteImpl.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/ActivityRepositorySQLiteImpl.java @@ -32,7 +32,7 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi { sb .append("INSERT INTO ") .append(ActivityTable.TABLE_NAME) - .append(" VALUES (?,?,?,?, ?,?,?,?,?,?)"); + .append(" VALUES (?,?,?,?,?, ?,?,?,?,? ,?)"); String sql = sb.toString(); @@ -383,9 +383,9 @@ public class ActivityRepositorySQLiteImpl implements ActivityRepositoryApi { return null; } if(result.size() == 1) { - result.get(0); + return result.get(0); } - throw new TimeCalcException("Fatal error: More than one activity per one day with next activity id set to null: " + year + ", " + month + day); + throw new TimeCalcException("Fatal error: More (" + result.size() + ") than one activity per one day with next activity id set to null: " + year + ", " + month + ", " + day); } @Override diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/WorkingDayRepositorySQLiteImpl.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/WorkingDayRepositorySQLiteImpl.java index 6b49451..cbff163 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/WorkingDayRepositorySQLiteImpl.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/persistence/impl/sqlite/WorkingDayRepositorySQLiteImpl.java @@ -280,4 +280,49 @@ public class WorkingDayRepositorySQLiteImpl implements WorkingDayRepositoryApi { } } + @Override + public int getTotalOvertimeForDayInMinutes(int year, int month, int day) { + System.out.println("#"+year+month+day); + StringBuilder sb = new StringBuilder(); + sb + .append("SELECT (sum(OVERTIME_HOUR)*60 + sum(OVERTIME_MINUTE)) as total_overtime FROM ") + .append(WorkingDayTable.TABLE_NAME) + .append(" WHERE ") + .append(WorkingDayTable.YEAR).append(" * 10000 + ") + .append(WorkingDayTable.MONTH).append("* 100 + ") + .append(WorkingDayTable.DAY).append(" <= ? "); + + String sql = sb.toString(); + System.out.println(sql); + int i = 0; + ResultSet rs = null; + try ( + Connection connection = sqliteConnectionFactory.createConnection(); PreparedStatement stmt = connection.prepareStatement(sql);) { + + //System.err.println(stmt.toString()); + stmt.setInt(++i, year * 10000 + month * 100 + day); + rs = stmt.executeQuery(); + System.out.println(stmt); + while (rs.next()) { + return rs.getInt("total_overtime"); + } + } catch (SQLException e) { + System.out.println(e.getMessage()); + throw new RuntimeException(e); + } catch (ClassNotFoundException ex) { + System.out.println(ex.getMessage()); + throw new RuntimeException(ex); + } finally { + try { + if (rs != null) { + rs.close(); + } + } catch (SQLException ex) { + System.out.println(ex.getMessage()); + throw new RuntimeException(ex); + } + } + throw new IllegalStateException(); + } + } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivitiesWindow.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivitiesWindow.java index d0c67d1..29749f4 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivitiesWindow.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivitiesWindow.java @@ -5,6 +5,10 @@ import java.util.List; import java.util.Map; import javax.swing.JButton; import javax.swing.JOptionPane; +import javax.swing.JTabbedPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + import org.nanoboot.utils.timecalc.app.TimeCalcException; import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi; import org.nanoboot.utils.timecalc.swing.progress.Time; @@ -82,7 +86,20 @@ public class ActivitiesWindow extends TWindow { }); add(tp); - + ChangeListener changeListener = new ChangeListener() { + private boolean secondOrLaterChange = false; + public void stateChanged(ChangeEvent changeEvent) { + if(!secondOrLaterChange) { + secondOrLaterChange = true; + return; + } + JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent.getSource(); + int index = sourceTabbedPane.getSelectedIndex(); + + years.get(sourceTabbedPane.getTitleAt(index)).getMonthPanel("1").getDayPanel("1").load(); + } + }; + tp.addChangeListener(changeListener); getYearPanel(currentYearS).setSelectedMonth(currentMonthS); getYearPanel(currentYearS).getMonthPanel(currentMonthS).setSelectedDay(currentDayS); } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivityPanel.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivityPanel.java index caeb611..6aa60a7 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivityPanel.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/ActivityPanel.java @@ -4,10 +4,13 @@ import org.nanoboot.utils.timecalc.entity.Activity; import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi; import javax.swing.BorderFactory; +import javax.swing.JOptionPane; import javax.swing.JPanel; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; /** * @author Robert @@ -15,10 +18,7 @@ import java.awt.FlowLayout; */ public class ActivityPanel extends JPanel { private final ActivityRepositoryApi activityRepository; - private String id; - private int year; - private int month; - private int day; + private final Activity activity; private TTextField name = new TTextField(""); private TTextField comment = new TTextField(""); private TTextField ticket = new TTextField(""); @@ -28,20 +28,74 @@ public class ActivityPanel extends JPanel { private String nextActivityId; public ActivityPanel(ActivityRepositoryApi activityRepository, Activity activity) { - this.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0)); + this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); + this.activity = activity; add(name); add(comment); add(ticket); add(spentHours); add(spentMinutes); add(flags); - name.setPreferredSize(new Dimension(100, 40)); - comment.setPreferredSize(new Dimension(100, 40)); - ticket.setPreferredSize(new Dimension(100, 40)); - spentHours.setPreferredSize(new Dimension(100, 40)); - spentMinutes.setPreferredSize(new Dimension(100, 40)); + name.setPreferredSize(new Dimension(400, 40)); + comment.setPreferredSize(new Dimension(400, 40)); + ticket.setPreferredSize(new Dimension(80, 40)); + spentHours.setPreferredSize(new Dimension(25, 40)); + spentMinutes.setPreferredSize(new Dimension(25, 40)); flags.setPreferredSize(new Dimension(100, 40)); +this.setPreferredSize(new Dimension(getWidth(), 40)); + name.setEditable(false); + comment.setEditable(false); + ticket.setEditable(false); + spentHours.setEditable(false); + spentMinutes.setEditable(false); + flags.setEditable(false); + name.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + comment.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + ticket.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + spentHours.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + spentMinutes.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + flags.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); + + name.addMouseListener(new MouseListener() { + @Override + public void mouseClicked(MouseEvent e) { + String result = (String) JOptionPane.showInputDialog( + null, + "Select new name", + "New name", + JOptionPane.PLAIN_MESSAGE, + null, + null, + name.getText() + ); + if(result != null) { + activity.setName(result); + activityRepository.update(activity); + name.setText(result); + } + } + + @Override + public void mousePressed(MouseEvent e) { + + } + + @Override + public void mouseReleased(MouseEvent e) { + + } + + @Override + public void mouseEntered(MouseEvent e) { + + } + + @Override + public void mouseExited(MouseEvent e) { + + } + }); name.setText(activity.getName()); comment.setText(activity.getComment()); ticket.setText(activity.getTicket()); @@ -49,8 +103,7 @@ public class ActivityPanel extends JPanel { spentMinutes.setText(String.valueOf(activity.getSpentMinutes())); flags.setText(activity.getFlags()); this.activityRepository = activityRepository; - this.setBackground(Color.BLUE); - this.setBorder(BorderFactory.createLineBorder(Color.green)); +this.setBorder(BorderFactory.createLineBorder(Color.ORANGE, 1)); setAlignmentX(LEFT_ALIGNMENT); } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/DayPanel.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/DayPanel.java index 378160a..adf405b 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/DayPanel.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/DayPanel.java @@ -3,12 +3,16 @@ package org.nanoboot.utils.timecalc.swing.common; import org.nanoboot.utils.timecalc.entity.Activity; import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi; +import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JPanel; +import java.awt.Color; +import java.awt.Dimension; import java.awt.FlowLayout; import java.util.HashMap; import java.util.Map; +import java.util.UUID; /** * @author robertvokac @@ -37,15 +41,22 @@ public class DayPanel extends JPanel { this.loadButton = new JButton("Load"); this.loadButton.setBounds(10, 10, 200, 30); - this.loadButton.addActionListener(e -> load(activityRepository)); + this.loadButton.addActionListener(e -> load()); add(loadButton); } - private void load(ActivityRepositoryApi activityRepository) { + public void load() { + if(this.loadButton == null) { + //nothing to do + return; + } if (this.loadButton.isVisible()) { this.loadButton.setVisible(false); this.loadButton = null; + } else { + //already loaded + return; } BoxLayout boxLayout = new BoxLayout(this, BoxLayout.Y_AXIS); @@ -53,6 +64,7 @@ public class DayPanel extends JPanel { this.setLayout(boxLayout); JPanel buttons = new JPanel(); + buttons.setBorder(BorderFactory.createLineBorder(Color.BLUE, 1)); buttons.setLayout(new FlowLayout(FlowLayout.LEFT)); buttons.setAlignmentX(LEFT_ALIGNMENT); JButton newButton = new JButton("New"); @@ -60,11 +72,21 @@ public class DayPanel extends JPanel { buttons.add(newButton); buttons.add(pasteButton); add(buttons); - for (int i = 0; i < 10; i++) { - add(new ActivityPanel(activityRepository, - new Activity("aaa", 2000, 7, 7, "a", "b", "c", 2, 30, - "a b c", null))); - } + buttons.setMaximumSize(new Dimension(1000, 40)); + newButton.addActionListener(e-> { + Activity newActivity = new Activity(UUID.randomUUID().toString(), Integer.valueOf(year), Integer.valueOf(month), Integer.valueOf(day), "", "", "", 0, 0, "", null); + ActivityPanel comp = + new ActivityPanel(activityRepository, newActivity); + comp.setMaximumSize(new Dimension(1000, 40)); + add(comp); + activityRepository.create(newActivity); + repaint(); + }); +// for (int i = 0; i < 10; i++) { +// add(new ActivityPanel(activityRepository, +// new Activity("id", 2000, 7, 7, "name", "comment", "ticket", 2, 30, +// "a b c", null))); +// } } } diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/MonthPanel.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/MonthPanel.java index 5e21bea..bed59bc 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/MonthPanel.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/MonthPanel.java @@ -7,6 +7,8 @@ import java.util.HashMap; import java.util.Map; import javax.swing.JPanel; import javax.swing.JTabbedPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; /** * @@ -31,6 +33,22 @@ public class MonthPanel extends JPanel { this.tp = new TTabbedPane(); add(tp); tp.setBounds(0, 0, 1100, 650); + + ChangeListener changeListener = new ChangeListener() { + private boolean secondOrLaterChange = false; + public void stateChanged(ChangeEvent changeEvent) { + if(!secondOrLaterChange) { + secondOrLaterChange = true; + return; + } + JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent.getSource(); + int index = sourceTabbedPane.getSelectedIndex(); + + days.get(sourceTabbedPane.getTitleAt(index)).load(); + } + }; + tp.addChangeListener(changeListener); + Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, Integer.valueOf(year)); cal.set(Calendar.MONTH, Integer.valueOf(month) - 1); diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/WorkingDaysWindow.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/WorkingDaysWindow.java index 212e2cd..49d0d17 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/WorkingDaysWindow.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/WorkingDaysWindow.java @@ -358,6 +358,7 @@ public class WorkingDaysWindow extends TWindow { WorkingDayForStats.fillStatisticsColumns(wdfsList); List> listForArray = new ArrayList<>(); + int totalOvertime = workingDayRepository.getTotalOvertimeForDayInMinutes(year - 1, 12, 31); for (WorkingDayForStats wdfs : wdfsList) { ArrayList list2 = new ArrayList<>(); listForArray.add(list2); @@ -388,13 +389,15 @@ public class WorkingDaysWindow extends TWindow { .substring(0, overtime.isNegative() ? 6 : 5)); list2.add(TTime.ofMinutes(wdfs.getWorkingTimeInMinutes()) .toString().substring(0, 5)); + totalOvertime = totalOvertime + wdfs.getOvertimeHour() * 60 + wdfs.getOvertimeMinute(); list2.add( TTime.ofMinutes(wdfs.getPauseTimeInMinutes()).toString() .substring(0, 5)); } list2.add(wdfs.getNote()); list2.add(wdfs.isTimeOff() ? YES : NO); - list2.add(QUESTION_MARK); + TTime totalOvertimeTTime = TTime.ofMinutes(totalOvertime); + list2.add((totalOvertimeTTime.getHour() < 10 ? "0" : "") + totalOvertimeTTime.getHour() + ":" + (totalOvertimeTTime.getMinute() < 10 ? "0" : "") + totalOvertimeTTime.getMinute()); list2.add(TTime.ofMilliseconds( (int) (wdfs.getArrivalTimeMovingAverage7Days() * 60d * 60d * 1000d)).toString().substring(0, 8)); list2.add(TTime.ofMilliseconds( @@ -429,8 +432,6 @@ public class WorkingDaysWindow extends TWindow { public Class getColumnClass(int column) { return getValueAt(0, column).getClass(); } - - ; }; // class ColorRenderer extends JLabel // implements TableCellRenderer { diff --git a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/YearPanel.java b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/YearPanel.java index 0ed740a..68187b5 100644 --- a/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/YearPanel.java +++ b/modules/time-calc-app/src/main/java/org/nanoboot/utils/timecalc/swing/common/YearPanel.java @@ -5,6 +5,9 @@ import org.nanoboot.utils.timecalc.persistence.api.ActivityRepositoryApi; import java.util.HashMap; import java.util.Map; import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; /** * @@ -24,6 +27,22 @@ public class YearPanel extends JPanel { this.tp = new TTabbedPane(); add(tp); tp.setBounds(0, 0, 1150, 700); + + ChangeListener changeListener = new ChangeListener() { + private boolean secondOrLaterChange = false; + public void stateChanged(ChangeEvent changeEvent) { + if(!secondOrLaterChange) { + secondOrLaterChange = true; + return; + } + JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent.getSource(); + int index = sourceTabbedPane.getSelectedIndex(); + + months.get(sourceTabbedPane.getTitleAt(index)).getDayPanel("1").load(); + } + }; + tp.addChangeListener(changeListener); + for (int month = 1; month <= 12; month++) { final String monthS = String.valueOf(month); MonthPanel monthPanel = new MonthPanel(year, String.valueOf(month), activityRepository);