2026-05-13 07:21:33 +02:00
|
|
|
/** Effektives Ablaufprofil für Kombination im Coach/in der Planung */
|
|
|
|
|
|
2026-05-13 14:42:01 +02:00
|
|
|
/**
|
|
|
|
|
* Vereinigt slot_profiles_v1 aus Katalog und Planungs-Overlay (je slot_index).
|
|
|
|
|
* @param {unknown} catArr
|
|
|
|
|
* @param {unknown} planArr
|
|
|
|
|
*/
|
|
|
|
|
function mergeSlotProfilesV1(catArr, planArr) {
|
|
|
|
|
const c = Array.isArray(catArr) ? catArr : []
|
|
|
|
|
const p = Array.isArray(planArr) ? planArr : []
|
|
|
|
|
const byIx = new Map()
|
|
|
|
|
for (const r of c) {
|
|
|
|
|
if (!r || typeof r !== 'object') continue
|
|
|
|
|
const ix = Number(r.slot_index)
|
|
|
|
|
if (!Number.isFinite(ix)) continue
|
|
|
|
|
byIx.set(ix, { ...r })
|
|
|
|
|
}
|
|
|
|
|
for (const r of p) {
|
|
|
|
|
if (!r || typeof r !== 'object') continue
|
|
|
|
|
const ix = Number(r.slot_index)
|
|
|
|
|
if (!Number.isFinite(ix)) continue
|
|
|
|
|
const prev = byIx.get(ix) || {}
|
|
|
|
|
byIx.set(ix, { ...prev, ...r })
|
|
|
|
|
}
|
|
|
|
|
return [...byIx.entries()].sort((a, b) => a[0] - b[0]).map(([, row]) => row)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Katalog-Basis + optionaler Planungs-Snapshot.
|
|
|
|
|
* Wichtig: `planning_method_profile` darf nur **Überschreibungen** sein — nie den Katalog komplett ersetzen
|
|
|
|
|
* (sonst verschwinden Zeiten/Runden bei leerem Objekt oder Teil-Payload).
|
|
|
|
|
*/
|
2026-05-13 07:21:33 +02:00
|
|
|
export function effectiveComboMethodProfile(catalogDict, planningSnapshot) {
|
|
|
|
|
const cat =
|
2026-05-13 14:42:01 +02:00
|
|
|
catalogDict && typeof catalogDict === 'object' && !Array.isArray(catalogDict) ? { ...catalogDict } : {}
|
|
|
|
|
|
2026-05-13 07:21:33 +02:00
|
|
|
if (
|
2026-05-13 14:42:01 +02:00
|
|
|
planningSnapshot === null ||
|
|
|
|
|
planningSnapshot === undefined ||
|
|
|
|
|
typeof planningSnapshot !== 'object' ||
|
|
|
|
|
Array.isArray(planningSnapshot)
|
2026-05-13 07:21:33 +02:00
|
|
|
) {
|
2026-05-13 14:42:01 +02:00
|
|
|
return { ...cat }
|
2026-05-13 07:21:33 +02:00
|
|
|
}
|
2026-05-13 14:42:01 +02:00
|
|
|
|
|
|
|
|
const plan = planningSnapshot
|
|
|
|
|
const merged = { ...cat, ...plan }
|
|
|
|
|
|
|
|
|
|
if (Object.prototype.hasOwnProperty.call(plan, 'slot_profiles_v1')) {
|
|
|
|
|
merged.slot_profiles_v1 = mergeSlotProfilesV1(cat.slot_profiles_v1, plan.slot_profiles_v1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return merged
|
2026-05-13 07:21:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function comboPlanningProfileJsonForEditor(catalogDict, planningSnapshot) {
|
|
|
|
|
const o = effectiveComboMethodProfile(catalogDict, planningSnapshot)
|
|
|
|
|
try {
|
|
|
|
|
return JSON.stringify(Object.keys(o).length ? o : {})
|
|
|
|
|
} catch {
|
|
|
|
|
return '{}'
|
|
|
|
|
}
|
|
|
|
|
}
|