Subversion Repositories SmartDukaan

Rev

Rev 37178 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 37178 Rev 37182
Line 357... Line 357...
357
			});
357
			});
358
		}
358
		}
359
 
359
 
360
		// Open agenda instances (AUTO + MANUAL) per party — the modal pre-selects
360
		// Open agenda instances (AUTO + MANUAL) per party — the modal pre-selects
361
		// these; AUTO ones are badged and close only when their metric normalizes.
361
		// these; AUTO ones are badged and close only when their metric normalizes.
-
 
362
		// Visibility rule: for a REVIVAL store only REVIVAL/CREDIT_DUES/MANUAL
-
 
363
		// agendas are populated (the rest keep their lifecycle but stay hidden).
362
		List<Integer> partyIds = new ArrayList<>();
364
		List<Integer> partyIds = new ArrayList<>();
363
		for (Map<String, Object> p : parties) partyIds.add((Integer) p.get("fofoStoreId"));
365
		for (Map<String, Object> p : parties) partyIds.add((Integer) p.get("fofoStoreId"));
364
		Map<Integer, List<Map<String, Object>>> openAgendasByFofo = new HashMap<>();
366
		Map<Integer, List<AgendaInstance>> openByFofo = new HashMap<>();
365
		for (AgendaInstance ai : agendaInstanceRepository.selectOpenByFofoIds(partyIds)) {
367
		for (AgendaInstance ai : agendaInstanceRepository.selectOpenByFofoIds(partyIds)) {
-
 
368
			openByFofo.computeIfAbsent(ai.getFofoId(), k -> new ArrayList<>()).add(ai);
-
 
369
		}
-
 
370
		Map<Integer, List<Map<String, Object>>> openAgendasByFofo = new HashMap<>();
-
 
371
		for (Map.Entry<Integer, List<AgendaInstance>> e : openByFofo.entrySet()) {
-
 
372
			List<Map<String, Object>> visible = new ArrayList<>();
-
 
373
			for (AgendaInstance ai : agendaInstanceService.filterVisibleForVisit(e.getValue())) {
366
			Map<String, Object> m = new HashMap<>();
374
				Map<String, Object> m = new HashMap<>();
367
			m.put("id", ai.getId());
375
				m.put("id", ai.getId());
368
			m.put("agendaType", ai.getAgendaType());
376
				m.put("agendaType", ai.getAgendaType());
369
			m.put("label", labelFor(ai.getAgendaType()));
377
				m.put("label", labelFor(ai.getAgendaType()));
370
			m.put("source", ai.getSource());
378
				m.put("source", ai.getSource());
371
			m.put("openedOn", ai.getOpenedOn() != null ? ai.getOpenedOn().toLocalDate().toString() : null);
379
				m.put("openedOn", ai.getOpenedOn() != null ? ai.getOpenedOn().toLocalDate().toString() : null);
-
 
380
				visible.add(m);
-
 
381
			}
372
			openAgendasByFofo.computeIfAbsent(ai.getFofoId(), k -> new ArrayList<>()).add(m);
382
			openAgendasByFofo.put(e.getKey(), visible);
373
		}
383
		}
374
		for (Map<String, Object> p : parties) {
384
		for (Map<String, Object> p : parties) {
375
			p.put("openAgendas", openAgendasByFofo.getOrDefault((Integer) p.get("fofoStoreId"), new ArrayList<>()));
385
			p.put("openAgendas", openAgendasByFofo.getOrDefault((Integer) p.get("fofoStoreId"), new ArrayList<>()));
376
		}
386
		}
377
 
387
 
378
		Map<String, Object> result = new HashMap<>();
388
		Map<String, Object> result = new HashMap<>();
379
		result.put("dtrUserId", dtrUserId);
389
		result.put("dtrUserId", dtrUserId);
380
		result.put("authUserId", authUserId);
390
		result.put("authUserId", authUserId);
381
		result.put("userName", au.getFirstName() + " " + au.getLastName());
391
		result.put("userName", au.getFirstName() + " " + au.getLastName());
382
		result.put("parties", parties);
392
		result.put("parties", parties);
-
 
393
		// Only non-auto agendas are manually assignable; auto ones surface via
-
 
394
		// openAgendas (chips) and are woven into task_name server-side on submit.
383
		result.put("agendaOptions", com.spice.profitmandi.dao.enumuration.dtr.VisitAgenda.labels());
395
		result.put("agendaOptions", AgendaType.manualAssignableLabels());
384
		return responseSender.ok(result);
396
		return responseSender.ok(result);
385
	}
397
	}
386
 
398
 
387
	// agenda_type holds the enum NAME (e.g. LOW_SALES); tolerate unknown values.
399
	// agenda_type holds the enum NAME (e.g. LOW_SALES); tolerate unknown values.
388
	private String labelFor(String agendaTypeName) {
400
	private String labelFor(String agendaTypeName) {
Line 480... Line 492...
480
			}
492
			}
481
			if (agendas.isEmpty()) {
493
			if (agendas.isEmpty()) {
482
				String single = (String) p.get("agenda");
494
				String single = (String) p.get("agenda");
483
				if (single != null && !single.trim().isEmpty()) agendas.add(single.trim());
495
				if (single != null && !single.trim().isEmpty()) agendas.add(single.trim());
484
			}
496
			}
485
			if (agendas.isEmpty()) agendas.add("Visit");
497
			// Compose the final agenda set: visible open instances first (auto
486
			String agendaJoined = String.join(", ", agendas);
498
			// agendas populate themselves — the planner never assigns them),
487
 
-
 
488
			// Lifecycle: any picked agenda without an open instance becomes a
499
			// then the picked manual-assignable agendas. Picked labels of
489
			// MANUAL instance. open() no-ops when one is already OPEN (AUTO or
500
			// auto-rule types are ignored (server-authoritative guard).
490
			// MANUAL), so pre-existing auto agendas are left untouched.
501
			LinkedHashSet<String> finalAgendas = new LinkedHashSet<>();
-
 
502
			for (AgendaInstance ai : agendaInstanceService.filterVisibleForVisit(
-
 
503
					agendaInstanceRepository.selectOpenByFofoId(fofoStoreId))) {
-
 
504
				finalAgendas.add(labelFor(ai.getAgendaType()));
-
 
505
			}
491
			for (String label : agendas) {
506
			for (String label : agendas) {
492
				AgendaType type = AgendaType.fromLabel(label);
507
				AgendaType type = AgendaType.fromLabel(label);
493
				if (type == null) continue; // "Visit" default — not lifecycle-tracked
508
				if (type == null) continue; // free text / legacy "Visit" — dropped
-
 
509
				if (!type.isManualAssignable()) continue; // auto agendas: cron-only
494
				agendaInstanceService.open(fofoStoreId, type.name(), AgendaSource.MANUAL, operatorAuthId, null);
510
				agendaInstanceService.open(fofoStoreId, type.name(), AgendaSource.MANUAL, operatorAuthId, null);
-
 
511
				finalAgendas.add(label);
495
			}
512
			}
-
 
513
			if (finalAgendas.isEmpty()) finalAgendas.add("Visit");
-
 
514
			String agendaJoined = String.join(", ", finalAgendas);
496
 
515
 
497
			String visitLocation = (lat != null && lng != null && !lat.isEmpty() && !lng.isEmpty())
516
			String visitLocation = (lat != null && lng != null && !lat.isEmpty() && !lng.isEmpty())
498
					? (lat + "," + lng) : "0.0000,0.0000";
517
					? (lat + "," + lng) : "0.0000,0.0000";
499
 
518
 
500
			String displayName = (outletName != null && !outletName.isEmpty()) ? outletName : ("Store #" + fofoStoreId);
519
			String displayName = (outletName != null && !outletName.isEmpty()) ? outletName : ("Store #" + fofoStoreId);