Skip to content

Commit 6a5d1ca

Browse files
authored
Merge pull request #654 from bettercodepaul/swt2#2238
#2238: Satzeingabe brach mit 'inkonsistente Schuetzen' ab - Gemeldet-…
2 parents 0d22dc0 + 45d2bc0 commit 6a5d1ca

4 files changed

Lines changed: 61 additions & 27 deletions

File tree

bogenliga/bogenliga-business-logic/src/main/java/de/bogenliga/application/business/schusszettel/impl/business/domain/states/Satzeingabe.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,12 @@ private void validateSingleArrowValue(StateContext context, Integer arrowValue,
342342
private void validateShooterRegistration(StateContext context, long shooterId) {
343343
try {
344344
long currentMatchId = context.getCurrentMatchId();
345-
long currentMatchNr = context.getMatchComponent().findById(currentMatchId).getNr();
346-
345+
347346
MannschaftsmitgliedDO member = context.getMannschaftsmitgliedComponent()
348347
.findByMemberAndTeamId(context.getTeamId(), shooterId);
349-
350-
if (member.getDsbMitgliedEingesetzt() < currentMatchNr) {
348+
349+
if (member.getDsbMitgliedEingesetzt() == null
350+
|| member.getDsbMitgliedEingesetzt() != Math.toIntExact(currentMatchId)) {
351351
throw new BusinessException(ErrorCode.INVALID_ARGUMENT_ERROR,
352352
"Shooter " + shooterId + " was not registered in Schützenmeldung for this match");
353353
}
@@ -363,15 +363,16 @@ private void validateShooterRegistration(StateContext context, long shooterId) {
363363

364364
/**
365365
* Gets shooters registered for the current match.
366+
* Gemeldet-Marker ist die eindeutige Match-ID, nicht die Match-Nr
367+
* (Kollision mit dem Kader-Flag eingesetzt=1, siehe Schuetzenmeldung#markShootersAsDeployed).
366368
*/
367369
private List<Long> getRegisteredShootersForCurrentMatch(StateContext context) {
368370
try {
369371
long currentMatchId = context.getCurrentMatchId();
370-
long currentMatchNr = context.getMatchComponent().findById(currentMatchId).getNr();
371-
372+
372373
return context.getMannschaftsmitgliedComponent().findByTeamId(context.getTeamId()).stream()
373374
.filter(mm -> mm.getDsbMitgliedEingesetzt() != null &&
374-
mm.getDsbMitgliedEingesetzt().equals(Math.toIntExact(currentMatchNr)))
375+
mm.getDsbMitgliedEingesetzt().equals(Math.toIntExact(currentMatchId)))
375376
.map(MannschaftsmitgliedDO::getDsbMitgliedId)
376377
.distinct() // Remove duplicates
377378
.collect(Collectors.toList());

bogenliga/bogenliga-business-logic/src/main/java/de/bogenliga/application/business/schusszettel/impl/business/domain/states/Schuetzenmeldung.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,19 +198,23 @@ private void validateSchuetzenmeldungTeamRoster(StateContext context, List<Long>
198198
}
199199

200200
/**
201-
* Marks shooters as deployed for current match using match number.
201+
* Marks shooters as deployed for current match using the unique match id.
202+
*
203+
* <p>Die Match-Nr (1..7) darf hier nicht verwendet werden: sie kollidiert mit dem
204+
* Kader-Flag {@code eingesetzt = 1} ("in der Schuetzenmeldung waehlbar"). Bei
205+
* Mannschaften mit mehr als 3 Kadermitgliedern galten dadurch in Match Nr. 1
206+
* alle Mitglieder als "gemeldet" und die Satzeingabe brach mit
207+
* "inkonsistente Schuetzen" ab.</p>
202208
*/
203209
private void markShootersAsDeployed(StateContext context, List<Long> shooterIds) {
204210
try {
205-
// Get current match number from session
206211
long currentMatchId = context.getCurrentMatchId();
207-
long currentMatchNr = context.getMatchComponent().findById(currentMatchId).getNr();
208-
212+
209213
for (Long shooterId : shooterIds) {
210214
try {
211215
MannschaftsmitgliedDO member = context.getMannschaftsmitgliedComponent()
212216
.findByMemberAndTeamId(context.getTeamId(), shooterId);
213-
member.setDsbMitgliedEingesetzt(Math.toIntExact(currentMatchNr));
217+
member.setDsbMitgliedEingesetzt(Math.toIntExact(currentMatchId));
214218
context.getMannschaftsmitgliedComponent().update(member, 0L);
215219

216220
} catch (Exception e) {
@@ -231,11 +235,10 @@ private void markShootersAsDeployed(StateContext context, List<Long> shooterIds)
231235
private List<MannschaftsmitgliedDO> getDeployedMembersForCurrentMatch(StateContext context) {
232236
try {
233237
long currentMatchId = context.getCurrentMatchId();
234-
long currentMatchNr = context.getMatchComponent().findById(currentMatchId).getNr();
235-
238+
236239
return context.getMannschaftsmitgliedComponent().findByTeamId(context.getTeamId()).stream()
237240
.filter(mm -> mm.getDsbMitgliedEingesetzt() != null &&
238-
mm.getDsbMitgliedEingesetzt().equals(Math.toIntExact(currentMatchNr)))
241+
mm.getDsbMitgliedEingesetzt().equals(Math.toIntExact(currentMatchId)))
239242
.collect(Collectors.toList());
240243
} catch (Exception e) {
241244
LOGGER.error("Error getting deployed members for current match: {}", e.getMessage());

bogenliga/bogenliga-business-logic/src/test/java/de/bogenliga/application/business/schusszettel/impl/business/domain/states/SatzeingabeTest.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,11 @@ private void setupTestData() {
6464
testMatch.setSatzpunkte(2L);
6565
testMatch.setMatchpunkte(0L);
6666

67+
// gemeldet = eingesetzt traegt die eindeutige Match-ID (300), nicht die Match-Nr
6768
testTeamMembers = Arrays.asList(
68-
createTeamMember(1L, 101L, 1),
69-
createTeamMember(2L, 102L, 1),
70-
createTeamMember(3L, 103L, 1)
69+
createTeamMember(1L, 101L, 300),
70+
createTeamMember(2L, 102L, 300),
71+
createTeamMember(3L, 103L, 300)
7172
);
7273

7374
testMembers = Arrays.asList(
@@ -379,6 +380,22 @@ public void getRegisteredShootersForCurrentMatch_validMatch_returnsShooters() {
379380
assertThat(stammdaten).hasSize(3);
380381
}
381382

383+
@Test
384+
public void prepareResponseData_kaderFlagMemberNotCountedAsRegistered() {
385+
// Regression zum Ticket "inkonsistente Schuetzen": ein 4. Kadermitglied mit
386+
// blossem Waehlbar-Flag (eingesetzt=1) kollidierte frueher mit Match Nr. 1
387+
// und liess die Satzeingabe mit >3 Schuetzen abbrechen
388+
List<MannschaftsmitgliedDO> membersWithExtra = new ArrayList<>(testTeamMembers);
389+
membersWithExtra.add(createTeamMember(4L, 104L, 1));
390+
when(mockMannschaftsmitgliedComponent.findByTeamId(100L)).thenReturn(membersWithExtra);
391+
392+
Map<String, Object> result = state.prepareResponseData(mockContext);
393+
394+
@SuppressWarnings("unchecked")
395+
List<SchuetzeStammdatenDO> stammdaten = (List<SchuetzeStammdatenDO>) result.get("schuetzeStammDaten");
396+
assertThat(stammdaten).hasSize(3);
397+
}
398+
382399
@Test
383400
public void getRegisteredShootersForCurrentMatch_exceptionInQuery_returnsEmpty() {
384401
when(mockMannschaftsmitgliedComponent.findByTeamId(100L))

bogenliga/bogenliga-business-logic/src/test/java/de/bogenliga/application/business/schusszettel/impl/business/domain/states/SchuetzenmeldungTest.java

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,13 @@ public void canTransitionTo_otherState_returnsFalse() {
122122

123123
@Test
124124
public void isDatabaseReadyForTransition_threeShootersDeployed_returnsTrue() {
125-
when(mockMmComponent.findByTeamId(100L)).thenReturn(
126-
testTeamMembers.stream()
127-
.filter(tm -> tm.getDsbMitgliedEingesetzt().equals(1))
128-
.toList()
129-
);
130-
125+
// gemeldet = eingesetzt traegt die Match-ID (200), nicht die Match-Nr
126+
when(mockMmComponent.findByTeamId(100L)).thenReturn(Arrays.asList(
127+
createTeamMember(1L, 101L, 200),
128+
createTeamMember(2L, 102L, 200),
129+
createTeamMember(3L, 103L, 200)
130+
));
131+
131132
boolean result = state.isDatabaseReadyForTransition(mockContext, State.STATUS_SATZEINGABE);
132133
assertThat(result).isTrue();
133134
}
@@ -250,9 +251,14 @@ public void handlePostOperation_validRegistration_succeeds() {
250251

251252
boolean result = state.handlePostOperation(mockContext, "submitSchuetzen", shooterIds);
252253
assertThat(result).isTrue();
253-
254+
254255
verify(mockContext).updateSessionStatus(State.STATUS_SATZEINGABE);
255256
verify(mockMmComponent, times(3)).update(any(MannschaftsmitgliedDO.class), eq(0L));
257+
258+
// eingesetzt muss die eindeutige Match-ID tragen, nicht die Match-Nr
259+
assertThat(testTeamMembers.get(0).getDsbMitgliedEingesetzt()).isEqualTo(200);
260+
assertThat(testTeamMembers.get(1).getDsbMitgliedEingesetzt()).isEqualTo(200);
261+
assertThat(testTeamMembers.get(2).getDsbMitgliedEingesetzt()).isEqualTo(200);
256262
}
257263

258264
@Test
@@ -300,8 +306,15 @@ public void markShootersAsDeployed_exceptionInDeployment_throwsException() {
300306

301307
@Test
302308
public void getDeployedMembersForCurrentMatch_validMatch_returnsFilteredMembers() {
303-
when(mockMmComponent.findByTeamId(100L)).thenReturn(testTeamMembers);
304-
309+
// Regression zum Ticket "inkonsistente Schuetzen": Kadermitglieder mit
310+
// blossem Waehlbar-Flag (eingesetzt=1) duerfen nicht als gemeldet zaehlen
311+
when(mockMmComponent.findByTeamId(100L)).thenReturn(Arrays.asList(
312+
createTeamMember(1L, 101L, 200),
313+
createTeamMember(2L, 102L, 200),
314+
createTeamMember(3L, 103L, 200),
315+
createTeamMember(4L, 104L, 1)
316+
));
317+
305318
boolean result = state.isDatabaseReadyForTransition(mockContext, State.STATUS_SATZEINGABE);
306319
assertThat(result).isTrue();
307320
}

0 commit comments

Comments
 (0)