Subversion Repositories SmartDukaan

Rev

Rev 36650 | Rev 36655 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 36650 Rev 36651
Line 91... Line 91...
91
		return "beat-plan-window";
91
		return "beat-plan-window";
92
	}
92
	}
93
 
93
 
94
	@Autowired
94
	@Autowired
95
	private com.spice.profitmandi.dao.repository.dtr.LeadLiveLocationRepository leadLiveLocationRepositoryAuto;
95
	private com.spice.profitmandi.dao.repository.dtr.LeadLiveLocationRepository leadLiveLocationRepositoryAuto;
-
 
96
	@Autowired
-
 
97
	private com.spice.profitmandi.dao.repository.dtr.LeadActivityRepository leadActivityRepositoryAuto;
-
 
98
 
-
 
99
	// ====================== EDIT BEAT ======================
-
 
100
	// Update an existing beat — name + partner stops (routes).
-
 
101
	// Schedules are NOT touched here; manage them via calendar drag-drop.
-
 
102
	@PostMapping(value = "/beatPlan/updateBeat")
-
 
103
	public ResponseEntity<?> updateBeat(
-
 
104
			HttpServletRequest request,
-
 
105
			@RequestParam int beatId,
-
 
106
			@RequestParam String planData) throws Exception {
-
 
107
 
-
 
108
		Beat beat = beatRepository.selectById(beatId);
-
 
109
		if (beat == null) return responseSender.badRequest("Beat not found");
-
 
110
 
-
 
111
		Gson gson = new Gson();
-
 
112
		Type type = new TypeToken<Map<String, Object>>() {
-
 
113
		}.getType();
-
 
114
		Map<String, Object> plan = gson.fromJson(planData, type);
-
 
115
 
-
 
116
		List<Map<String, Object>> days = (List<Map<String, Object>>) plan.get("days");
-
 
117
		if (days == null || days.isEmpty()) return responseSender.badRequest("No days provided");
-
 
118
 
-
 
119
		// Update name if changed (and not colliding with another beat)
-
 
120
		String newName = plan.get("beatName") != null ? ((String) plan.get("beatName")).trim() : beat.getName();
-
 
121
		if (newName != null && !newName.equalsIgnoreCase(beat.getName())) {
-
 
122
			// Make sure no other beat for this user already uses this name
-
 
123
			boolean collides = beatRepository.selectByAuthUserId(beat.getAuthUserId()).stream()
-
 
124
					.anyMatch(b -> b.getId() != beat.getId()
-
 
125
							&& b.getName() != null
-
 
126
							&& newName.equalsIgnoreCase(b.getName().trim()));
-
 
127
			if (collides) return responseSender.badRequest("Another beat with this name already exists");
-
 
128
			beat.setName(newName);
-
 
129
		}
-
 
130
 
-
 
131
		// Update start location from first day if present
-
 
132
		Map<String, Object> firstDay = days.get(0);
-
 
133
		if (firstDay.get("startLocationName") != null)
-
 
134
			beat.setStartLocationName((String) firstDay.get("startLocationName"));
-
 
135
		if (firstDay.get("startLatitude") != null) beat.setStartLatitude((String) firstDay.get("startLatitude"));
-
 
136
		if (firstDay.get("startLongitude") != null) beat.setStartLongitude((String) firstDay.get("startLongitude"));
-
 
137
		beat.setTotalDays(days.size());
-
 
138
 
-
 
139
		// Replace routes (partner stops). Schedules stay intact.
-
 
140
		beatRouteRepository.deleteByBeatId(beatId);
-
 
141
		// Collect lead IDs the user kept on the plan (for date-aware edit below)
-
 
142
		Set<Integer> keptLeadIds = new HashSet<>();
-
 
143
		for (int d = 0; d < days.size(); d++) {
-
 
144
			Map<String, Object> day = days.get(d);
-
 
145
			int dayNumber = d + 1;
-
 
146
			List<Map<String, Object>> visits = (List<Map<String, Object>>) day.get("visits");
-
 
147
			if (visits == null) continue;
-
 
148
			int partnerSeq = 0;
-
 
149
			for (int i = 0; i < visits.size(); i++) {
-
 
150
				Map<String, Object> v = visits.get(i);
-
 
151
				if ("lead".equals(v.get("type"))) {
-
 
152
					keptLeadIds.add(((Number) v.get("id")).intValue());
-
 
153
					continue; // leads live in lead_route, handled below
-
 
154
				}
-
 
155
				BeatRoute route = new BeatRoute();
-
 
156
				route.setBeatId(beatId);
-
 
157
				route.setFofoId(((Number) v.get("id")).intValue());
-
 
158
				route.setSequenceOrder(partnerSeq++);
-
 
159
				route.setDayNumber(dayNumber);
-
 
160
				route.setActive(true);
-
 
161
				beatRouteRepository.persist(route);
-
 
162
			}
-
 
163
		}
-
 
164
 
-
 
165
		// Date-aware lead handling: if planDate is provided, remove lead_route rows
-
 
166
		// for that (beat, date) that the user removed in the editor.
-
 
167
		String planDateStr = (String) plan.get("planDate");
-
 
168
		if (planDateStr != null && !planDateStr.isEmpty()) {
-
 
169
			try {
-
 
170
				LocalDate planDate = LocalDate.parse(planDateStr);
-
 
171
				List<LeadRoute> existing = leadRouteRepository.selectByBeatId(beatId);
-
 
172
				for (LeadRoute lr : existing) {
-
 
173
					if (!"APPROVED".equals(lr.getStatus())) continue;
-
 
174
					if (lr.getScheduleDate() == null || !lr.getScheduleDate().equals(planDate)) continue;
-
 
175
					if (keptLeadIds.contains(lr.getLeadId())) continue;
-
 
176
					// User removed this lead from the date — mark cancelled
-
 
177
					lr.setStatus("CANCELLED");
-
 
178
					lr.setUpdatedTimestamp(LocalDateTime.now());
-
 
179
					// activity log
-
 
180
					LeadActivity a = new LeadActivity();
-
 
181
					a.setLeadId(lr.getLeadId());
-
 
182
					a.setRemark("Removed from beat '" + beat.getName() + "' on " + planDate);
-
 
183
					a.setAuthId(0);
-
 
184
					a.setCreatedTimestamp(LocalDateTime.now());
-
 
185
					leadActivityRepositoryAuto.persist(a);
-
 
186
				}
-
 
187
			} catch (Exception e) {
-
 
188
				LOGGER.warn("Could not parse planDate '{}' — leads not adjusted", planDateStr);
-
 
189
			}
-
 
190
		}
-
 
191
 
-
 
192
		Map<String, Object> response = new HashMap<>();
-
 
193
		response.put("status", true);
-
 
194
		response.put("planGroupId", String.valueOf(beat.getId()));
-
 
195
		response.put("message", "Beat updated successfully");
-
 
196
		return responseSender.ok(response);
-
 
197
	}
96
 
198
 
97
	// ====================== DAY VIEW ======================
199
	// ====================== DAY VIEW ======================
98
	// Inline page (loaded into dashboard #main-content): tabular list of all beats
200
	// Inline page (loaded into dashboard #main-content): tabular list of all beats
99
	// scheduled in a date range across all users. Each row has a View button that
201
	// scheduled in a date range across all users. Each row has a View button that
100
	// opens that user's calendar in a modal.
202
	// opens that user's calendar in a modal.