| Line 437... |
Line 437... |
| 437 |
if (days == null || days.isEmpty()) return responseSender.badRequest("No days provided");
|
437 |
if (days == null || days.isEmpty()) return responseSender.badRequest("No days provided");
|
| 438 |
|
438 |
|
| 439 |
// Update name if changed (and not colliding with another beat)
|
439 |
// Update name if changed (and not colliding with another beat)
|
| 440 |
String newName = plan.get("beatName") != null ? ((String) plan.get("beatName")).trim() : beat.getName();
|
440 |
String newName = plan.get("beatName") != null ? ((String) plan.get("beatName")).trim() : beat.getName();
|
| 441 |
if (newName != null && !newName.equalsIgnoreCase(beat.getName())) {
|
441 |
if (newName != null && !newName.equalsIgnoreCase(beat.getName())) {
|
| 442 |
// Make sure no other beat for this user already uses this name
|
442 |
// Make sure no other ACTIVE beat for this user already uses this name.
|
| - |
|
443 |
// Soft-deleted beats keep their name in the table; we don't want them
|
| - |
|
444 |
// to block a legitimate rename.
|
| 443 |
boolean collides = beatRepository.selectByAuthUserId(beat.getAuthUserId()).stream()
|
445 |
boolean collides = beatRepository.selectActiveByAuthUserId(beat.getAuthUserId()).stream()
|
| 444 |
.anyMatch(b -> b.getId() != beat.getId()
|
446 |
.anyMatch(b -> b.getId() != beat.getId()
|
| 445 |
&& b.getName() != null
|
447 |
&& b.getName() != null
|
| 446 |
&& newName.equalsIgnoreCase(b.getName().trim()));
|
448 |
&& newName.equalsIgnoreCase(b.getName().trim()));
|
| 447 |
if (collides) return responseSender.badRequest("Another beat with this name already exists");
|
449 |
if (collides) return responseSender.badRequest("Another beat with this name already exists");
|
| 448 |
beat.setName(newName);
|
450 |
beat.setName(newName);
|
| Line 1183... |
Line 1185... |
| 1183 |
List<Map<String, Object>> days = (List<Map<String, Object>>) plan.get("days");
|
1185 |
List<Map<String, Object>> days = (List<Map<String, Object>>) plan.get("days");
|
| 1184 |
List<String> dates = (List<String>) plan.get("dates");
|
1186 |
List<String> dates = (List<String>) plan.get("dates");
|
| 1185 |
|
1187 |
|
| 1186 |
String beatName = (plan.get("beatName") != null ? (String) plan.get("beatName") : "Beat").trim();
|
1188 |
String beatName = (plan.get("beatName") != null ? (String) plan.get("beatName") : "Beat").trim();
|
| 1187 |
|
1189 |
|
| 1188 |
// Duplicate check — same name + same authUserId = duplicate
|
1190 |
// Duplicate check — same name + same authUserId among ACTIVE beats only.
|
| - |
|
1191 |
// Soft-deleted beats keep the name in the table; we don't want them to
|
| - |
|
1192 |
// block the user from reusing a name they "deleted".
|
| 1189 |
List<Beat> existingBeats = beatRepository.selectByAuthUserId(authUserId);
|
1193 |
List<Beat> existingBeats = beatRepository.selectActiveByAuthUserId(authUserId);
|
| 1190 |
for (Beat existing : existingBeats) {
|
1194 |
for (Beat existing : existingBeats) {
|
| 1191 |
if (existing.getName() != null && beatName.equalsIgnoreCase(existing.getName().trim())) {
|
1195 |
if (existing.getName() != null && beatName.equalsIgnoreCase(existing.getName().trim())) {
|
| 1192 |
LOGGER.info("Duplicate beat blocked: name='{}' authUserId={} existingId={}", beatName, authUserId, existing.getId());
|
1196 |
LOGGER.info("Duplicate beat blocked: name='{}' authUserId={} existingId={}", beatName, authUserId, existing.getId());
|
| 1193 |
Map<String, Object> response = new HashMap<>();
|
1197 |
Map<String, Object> response = new HashMap<>();
|
| 1194 |
response.put("status", true);
|
1198 |
response.put("status", true);
|
| Line 1525... |
Line 1529... |
| 1525 |
scheduleDates.add(d);
|
1529 |
scheduleDates.add(d);
|
| 1526 |
d = d.plusDays(1);
|
1530 |
d = d.plusDays(1);
|
| 1527 |
}
|
1531 |
}
|
| 1528 |
}
|
1532 |
}
|
| 1529 |
|
1533 |
|
| 1530 |
// Duplicate check
|
1534 |
// Duplicate check — ACTIVE beats only (soft-deleted names are reusable)
|
| 1531 |
boolean isDuplicate = beatRepository.selectByAuthUserId(authUserId).stream()
|
1535 |
boolean isDuplicate = beatRepository.selectActiveByAuthUserId(authUserId).stream()
|
| 1532 |
.anyMatch(b -> b.getName() != null && beatName.equalsIgnoreCase(b.getName().trim()));
|
1536 |
.anyMatch(b -> b.getName() != null && beatName.equalsIgnoreCase(b.getName().trim()));
|
| 1533 |
if (isDuplicate) {
|
1537 |
if (isDuplicate) {
|
| 1534 |
errorMessages.add("Beat '" + beatName + "' already exists for user " + authUserId + ". Skipped.");
|
1538 |
errorMessages.add("Beat '" + beatName + "' already exists for user " + authUserId + ". Skipped.");
|
| 1535 |
errors++;
|
1539 |
errors++;
|
| 1536 |
continue;
|
1540 |
continue;
|
| Line 1641... |
Line 1645... |
| 1641 |
// ============ CALENDAR ============
|
1645 |
// ============ CALENDAR ============
|
| 1642 |
|
1646 |
|
| 1643 |
@PostMapping(value = "/beatPlan/delete")
|
1647 |
@PostMapping(value = "/beatPlan/delete")
|
| 1644 |
public ResponseEntity<?> deleteBeat(@RequestParam String planGroupId) {
|
1648 |
public ResponseEntity<?> deleteBeat(@RequestParam String planGroupId) {
|
| 1645 |
int beatId = Integer.parseInt(planGroupId);
|
1649 |
int beatId = Integer.parseInt(planGroupId);
|
| - |
|
1650 |
// Hard delete — wipe all child rows first, then the beat itself.
|
| - |
|
1651 |
// The name slot is freed naturally because the row is gone.
|
| 1646 |
beatRouteRepository.deleteByBeatId(beatId);
|
1652 |
beatRouteRepository.deleteByBeatId(beatId);
|
| 1647 |
beatScheduleRepository.deleteByBeatId(beatId);
|
1653 |
beatScheduleRepository.deleteByBeatId(beatId);
|
| - |
|
1654 |
leadRouteRepository.deleteByBeatId(beatId);
|
| 1648 |
Beat beat = beatRepository.selectById(beatId);
|
1655 |
Beat beat = beatRepository.selectById(beatId);
|
| 1649 |
if (beat != null) {
|
1656 |
if (beat != null) {
|
| 1650 |
beat.setActive(false);
|
1657 |
beatRepository.delete(beat);
|
| 1651 |
}
|
1658 |
}
|
| 1652 |
|
1659 |
|
| 1653 |
Map<String, Object> response = new HashMap<>();
|
1660 |
Map<String, Object> response = new HashMap<>();
|
| 1654 |
response.put("status", true);
|
1661 |
response.put("status", true);
|
| 1655 |
response.put("message", "Beat deleted");
|
1662 |
response.put("message", "Beat deleted");
|