Skip to content

Commit 66aaf9c

Browse files
committed
#178: uncheck sync when already present. fix issue that present heimat time for mapped project without work at that day is not syncable
1 parent ed5eb29 commit 66aaf9c

File tree

3 files changed

+69
-27
lines changed

3 files changed

+69
-27
lines changed

src/main/java/de/doubleslash/keeptime/controller/HeimatController.java

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -129,33 +129,36 @@ public List<Mapping> getTableRows(final LocalDate currentReportDate, final List<
129129
pr.appendToWorkNotes(currentWorkNote);
130130
}
131131
final String keeptimeNotes = pr.getNotes();
132-
String canBeSynced;
132+
String canBeSyncedMessage;
133133
if (!isMappedInHeimat) {
134-
canBeSynced = "Not mapped to Heimat task.\nMap in settings dialog.";
134+
canBeSyncedMessage = "Not mapped to Heimat task.\nMap in settings dialog.";
135135
} else if (heimatTasks.stream().noneMatch(ht -> ht.id() == optHeimatMapping.get().getExternalTaskId())) {
136-
canBeSynced = "Heimat Task is not available (anymore).\nPlease check mappings in settings dialog.";
136+
canBeSyncedMessage = "Heimat Task is not available (anymore).\nPlease check mappings in settings dialog.";
137137
isMappedInHeimat = false;
138138
} else {
139139
final ExternalProjectMapping externalProjectMapping = optHeimatMapping.get();
140-
canBeSynced = "Sync to " + externalProjectMapping.getExternalTaskName() + "\n("
140+
canBeSyncedMessage = "Sync to " + externalProjectMapping.getExternalTaskName() + "\n("
141141
+ externalProjectMapping.getExternalProjectName() + ")";
142142
}
143143

144144
if (optionalExistingMapping.isPresent()) {
145145
final Mapping existingMapping = optionalExistingMapping.get();
146146
final ArrayList<Project> projects = new ArrayList<>(existingMapping.projects());
147147
projects.add(project);
148+
final long keepTimeSeconds = existingMapping.keeptimeSeconds() + projectWorkSeconds;
149+
final long heimatSeconds = existingMapping.heimatSeconds();
150+
final boolean shouldBeSynced = isMappedInHeimat && differenceGreater15Minutes(heimatSeconds, keepTimeSeconds);
148151
final Mapping mapping = new Mapping(isMappedInHeimat ? optHeimatMapping.get().getExternalTaskId() : -1,
149-
isMappedInHeimat, canBeSynced, existingMapping.existingTimes(), projects,
150-
existingMapping.heimatNotes(), existingMapping.keeptimeNotes() + ". " + keeptimeNotes,
151-
existingMapping.heimatSeconds(), existingMapping.keeptimeSeconds() + projectWorkSeconds);
152+
isMappedInHeimat, shouldBeSynced, canBeSyncedMessage, existingMapping.existingTimes(), projects,
153+
existingMapping.heimatNotes(), existingMapping.keeptimeNotes() + ". " + keeptimeNotes, heimatSeconds, keepTimeSeconds);
152154
list.remove(existingMapping);
153155
list.add(mapping);
154156
} else {
157+
final boolean shouldBeSynced = isMappedInHeimat && differenceGreater15Minutes(heimatTimeSeconds, projectWorkSeconds);
155158
final List<Project> projects = Collections.singletonList(project);
156159
final Mapping mapping = new Mapping(isMappedInHeimat ? optHeimatMapping.get().getExternalTaskId() : -1,
157-
isMappedInHeimat, canBeSynced, optionalAlreadyBookedTimes, projects, heimatNotes, keeptimeNotes,
158-
heimatTimeSeconds, projectWorkSeconds);
160+
isMappedInHeimat, shouldBeSynced, canBeSyncedMessage, optionalAlreadyBookedTimes, projects,
161+
heimatNotes, keeptimeNotes, heimatTimeSeconds, projectWorkSeconds);
159162
list.add(mapping);
160163
}
161164
}
@@ -175,7 +178,7 @@ public List<Mapping> getTableRows(final LocalDate currentReportDate, final List<
175178
.filter(t -> t.id() == times.get(0).taskId())
176179
.findAny()
177180
.orElseThrow();
178-
final Mapping mapping = new Mapping(id, false,
181+
final Mapping mapping = new Mapping(id, true, false,
179182
"Not mapped in KeepTime\n\n" + heimatTask.name() + "\n" + heimatTask.taskHolderName(), times,
180183
new ArrayList<>(0), heimatNotes, "", heimatTimeSeconds, 0);
181184
list.add(mapping);
@@ -199,7 +202,7 @@ public List<Mapping> getTableRows(final LocalDate currentReportDate, final List<
199202
String heimatNotes = addHeimatNotes(times);
200203
long heimatTimeSeconds = addHeimatTimes(times);
201204

202-
final Mapping mapping2 = new Mapping(id, true,
205+
final Mapping mapping2 = new Mapping(id, true, false,
203206
"Present in HEIMAT but not KeepTime\n\n" + externalProjectMapping.getExternalTaskName() + "\n"
204207
+ externalProjectMapping.getExternalProjectName(), times, mappedProjects.stream()
205208
.filter(
@@ -214,6 +217,10 @@ public List<Mapping> getTableRows(final LocalDate currentReportDate, final List<
214217
return list;
215218
}
216219

220+
private static boolean differenceGreater15Minutes(final long heimatTimeSeconds, final long projectWorkSeconds) {
221+
return heimatTimeSeconds == 0L || Math.abs(heimatTimeSeconds - projectWorkSeconds) > 15 * 60L;
222+
}
223+
217224
private static long addHeimatTimes(final List<HeimatTime> optionalAlreadyBookedTimes) {
218225
long heimatTimeSeconds;
219226
heimatTimeSeconds = optionalAlreadyBookedTimes.stream()
@@ -309,9 +316,9 @@ public void updateMappings(final List<ProjectMapping> newMappings) {
309316
ExternalSystem.Heimat,
310317
heimatTask.taskHolderName(),
311318
heimatTask.id(),
312-
heimatTask.name(), getAsJson(
313-
heimatTask)
314-
, projectMapping.getProject());
319+
heimatTask.name(),
320+
getAsJson(heimatTask),
321+
projectMapping.getProject());
315322
})
316323
.filter(Objects::nonNull)
317324
.toList();
@@ -338,7 +345,7 @@ public void updateMappings(final List<ProjectMapping> newMappings) {
338345
externalProjectsMappingsRepository.deleteAll(mappingsToRemove);
339346
}
340347

341-
private String getAsJson(final HeimatTask heimatTask){
348+
private String getAsJson(final HeimatTask heimatTask) {
342349
try {
343350
return objectMapper.writeValueAsString(heimatTask);
344351
} catch (JsonProcessingException e) {
@@ -394,9 +401,9 @@ public ExistingAndInvalidMappings getExistingProjectMappings(List<HeimatTask> ex
394401

395402
public record UserMapping(Mapping mapping, boolean shouldSync, String userNotes, int userMinutes) {}
396403

397-
public record Mapping(long heimatTaskId, boolean canBeSynced, String syncMessage, List<HeimatTime> existingTimes,
398-
List<Project> projects, String heimatNotes, String keeptimeNotes, long heimatSeconds,
399-
long keeptimeSeconds) {}
404+
public record Mapping(long heimatTaskId, boolean canBeSynced, boolean shouldBeSynced, String syncMessage,
405+
List<HeimatTime> existingTimes, List<Project> projects, String heimatNotes,
406+
String keeptimeNotes, long heimatSeconds, long keeptimeSeconds) {}
400407

401408
public record HeimatErrors(UserMapping mapping, String errorMessage) {}
402409

src/main/java/de/doubleslash/keeptime/view/ExternalProjectsSyncController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ public void initForDate(LocalDate currentReportDate, List<Work> currentWorkItems
173173
.bind(heimatTaskComboBox.getSelectionModel().selectedItemProperty().isNull());
174174
addHeimatTaskButton.setOnAction(ae -> {
175175
final HeimatTask task = heimatTaskComboBox.getValue();
176-
items.add(new TableRow(new HeimatController.Mapping(task.id(), true,
176+
items.add(new TableRow(new HeimatController.Mapping(task.id(), true, true,
177177
"Manually added\n\n" + task.name() + "\n(" + task.taskHolderName() + ")", List.of(), List.of(), "", "",
178178
0, 0), "", 0));
179179
heimatTaskComboBox.getSelectionModel().clearSelection();
@@ -427,6 +427,7 @@ protected List<HeimatController.HeimatErrors> call() {
427427
}
428428

429429
PauseTransition delay = new PauseTransition(Duration.seconds(2));
430+
// TODO maybe show countdown in UI with option to "Open day in HEIMAT"? could add 1 second again ;)
430431
delay.setOnFinished(event -> {
431432
showLoadingScreen(false);
432433
thisStage.close();
@@ -603,7 +604,7 @@ public static class TableRow {
603604

604605
public TableRow(HeimatController.Mapping mapping, String userNotes, final long userSeconds) {
605606
this.mapping = mapping;
606-
this.shouldSyncCheckBox = new SimpleBooleanProperty(mapping.canBeSynced());
607+
this.shouldSyncCheckBox = new SimpleBooleanProperty(mapping.shouldBeSynced());
607608
this.syncStatus = new SimpleStringProperty(mapping.syncMessage());
608609

609610
this.keeptimeNotes = new SimpleStringProperty(mapping.keeptimeNotes());

src/test/java/de/doubleslash/keeptime/controller/HeimatControllerTest.java

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,10 @@ void shouldMarkNonSyncableWhenNotMapped() {
203203
final List<HeimatController.Mapping> tableRows = heimatController.getTableRows(now.toLocalDate(), workItems);
204204

205205
// ASSERT
206-
assertFalse(tableRows.get(0).canBeSynced());
207-
assertThat(tableRows.get(0).heimatTaskId(), Matchers.is(-1L));
206+
final HeimatController.Mapping mapping = tableRows.get(0);
207+
assertFalse(mapping.canBeSynced());
208+
assertFalse(mapping.shouldBeSynced());
209+
assertThat(mapping.heimatTaskId(), Matchers.is(-1L));
208210
}
209211

210212
@Test
@@ -218,8 +220,10 @@ void shouldMarkNonSyncableWhenHeimatTaskNoLongerExists() {
218220
final List<HeimatController.Mapping> tableRows = heimatController.getTableRows(now.toLocalDate(), workItems);
219221

220222
// ASSERT
221-
assertFalse(tableRows.get(0).canBeSynced());
222-
assertThat(tableRows.get(0).syncMessage(), Matchers.containsString("is not available"));
223+
final HeimatController.Mapping mapping = tableRows.get(0);
224+
assertFalse(mapping.canBeSynced());
225+
assertFalse(mapping.shouldBeSynced());
226+
assertThat(mapping.syncMessage(), Matchers.containsString("is not available"));
223227
}
224228

225229
@Test
@@ -234,6 +238,7 @@ void shouldBeSyncableWhenMapped() {
234238

235239
// ASSERT
236240
assertTrue(mapping.canBeSynced());
241+
assertTrue(mapping.shouldBeSynced());
237242
assertThat(mapping.keeptimeSeconds(), Matchers.is(13 * 60L));
238243
assertThat(mapping.keeptimeNotes(), Matchers.is("Notes 1"));
239244
assertThat(mapping.syncMessage(), Matchers.containsString(project1To1Mapping.getExternalTaskName()));
@@ -258,6 +263,7 @@ void shouldAddHeimatDetailsWhenAlreadyPresent() {
258263

259264
// ASSERT
260265
assertAll(() -> assertTrue(mapping.canBeSynced()),
266+
() -> assertTrue(mapping.shouldBeSynced()),
261267
() -> assertThat(mapping.keeptimeSeconds(), Matchers.is(13 * 60L)),
262268
() -> assertThat(mapping.keeptimeNotes(), Matchers.is("Notes 1")),
263269
() -> assertThat(mapping.projects(), Matchers.containsInAnyOrder(workProject1)),
@@ -267,6 +273,32 @@ void shouldAddHeimatDetailsWhenAlreadyPresent() {
267273
//
268274
);
269275
}
276+
@Test
277+
void shouldDisableShouldBeSyncedWhenAlreadyPresentInHeimat() {
278+
// ARRANGE
279+
final Work work1 = new Work(now.minusMinutes(55), now, workProject1, "Notes 1");
280+
workItems.add(work1);
281+
externalMappings.add(project1To1Mapping);
282+
final HeimatTime existingTime1 = new HeimatTime(project1To1Mapping.getExternalTaskId(), now.toLocalDate(), null,
283+
null, 60, "Existing note 1", 12);
284+
when(mockedHeimatAPI.getMyTimes(now.toLocalDate())).thenReturn(Arrays.asList(existingTime1));
285+
286+
// ACT
287+
final List<HeimatController.Mapping> tableRows = heimatController.getTableRows(now.toLocalDate(), workItems);
288+
final HeimatController.Mapping mapping = tableRows.get(0);
289+
290+
// ASSERT
291+
assertAll(() -> assertTrue(mapping.canBeSynced()),
292+
() -> assertFalse(mapping.shouldBeSynced()),
293+
() -> assertThat(mapping.keeptimeSeconds(), Matchers.is(55 * 60L)),
294+
() -> assertThat(mapping.keeptimeNotes(), Matchers.is("Notes 1")),
295+
() -> assertThat(mapping.projects(), Matchers.containsInAnyOrder(workProject1)),
296+
() -> assertThat(mapping.heimatNotes(), Matchers.is("Existing note 1")),
297+
() -> assertThat(mapping.heimatSeconds(), Matchers.is((60) * 60L)),
298+
() -> assertThat(mapping.existingTimes(), Matchers.containsInAnyOrder(existingTime1))
299+
//
300+
);
301+
}
270302

271303
@Test
272304
void shouldCombineAllWorksAndProjectsWhenMultipleProjectsAreMappedToSame() {
@@ -284,13 +316,12 @@ void shouldCombineAllWorksAndProjectsWhenMultipleProjectsAreMappedToSame() {
284316

285317
// ASSERT
286318
assertAll(() -> assertTrue(mapping.canBeSynced()),
319+
() -> assertTrue(mapping.shouldBeSynced()),
287320
() -> assertThat(mapping.keeptimeSeconds(), Matchers.is(2 * 13 * 60L)),
288321
() -> assertThat(mapping.keeptimeNotes(), Matchers.is("Notes 1. Notes 2")),
289322
() -> assertThat(mapping.projects(), Matchers.containsInAnyOrder(workProject1, workProject2)));
290323
}
291324

292-
// shouldDisableShouldBeSyncedWhenAlreadyPresentInHeimat (nice 2 have)
293-
294325
@Test
295326
void shouldShowHeimatTimeWhenProjectIsNotMappedInKeeptime() {
296327
// ARRANGE
@@ -307,7 +338,8 @@ void shouldShowHeimatTimeWhenProjectIsNotMappedInKeeptime() {
307338
final HeimatController.Mapping mapping = tableRows.get(0);
308339

309340
// ASSERT
310-
assertAll(() -> assertFalse(mapping.canBeSynced()),
341+
assertAll(() -> assertTrue(mapping.canBeSynced()),
342+
() -> assertFalse(mapping.shouldBeSynced()),
311343
() -> assertThat(mapping.syncMessage(), Matchers.containsString("Not mapped in KeepTime")),
312344
() -> assertThat(mapping.syncMessage(), Matchers.containsString(project1To1Mapping.getExternalTaskName())),
313345
() -> assertThat(mapping.keeptimeSeconds(), Matchers.is(0L)),
@@ -338,6 +370,8 @@ void shouldShowHeimatTimeWhenProjectIsMappedInKeeptimeButNoWorkAtThatDay() {
338370

339371
// ASSERT
340372
assertAll(() -> assertThat(tableRows.size(), Matchers.is(1)), () -> assertTrue(mapping.canBeSynced()),
373+
() -> assertTrue(mapping.canBeSynced()),
374+
() -> assertFalse(mapping.shouldBeSynced()),
341375
() -> assertThat(mapping.syncMessage(), Matchers.containsString("Present in HEIMAT but not KeepTime")),
342376
() -> assertThat(mapping.syncMessage(), Matchers.containsString(project1To1Mapping.getExternalTaskName())),
343377
() -> assertThat(mapping.keeptimeSeconds(), Matchers.is(0L)),

0 commit comments

Comments
 (0)