-- Die Teilzeitvariante übersteht auch eine geplante Rückkehr. -- -- record_karenz_return legt für ein Rückkehrdatum in der Zukunft eine Zeile -- in pending_org_changes an; der Tageslauf wendet sie an. Diese Zeile trug -- bisher nur Beschäftigungsausmaß und Stunden — die Variante wäre am Stichtag -- verlorengegangen, und jemand käme in Elternteilzeit zurück, ohne dass es -- irgendwo stünde ausser im Beschreibungstext der Historie. -- -- Aufgefallen beim Proben: die Probe hatte ein Rückkehrdatum in der Zukunft -- gewählt und lief deshalb in genau diesen Zweig. CREATE OR REPLACE FUNCTION public.apply_due_pending_changes() RETURNS integer LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'public', 'pg_temp' AS $function$ declare v_rec record; v_count int := 0; begin for v_rec in select * from pending_org_changes where status = 'pending' and effective_date <= current_date order by effective_date, created_at loop if v_rec.change_type = 'transfer' then update position_assignments set valid_to = v_rec.effective_date where employee_id = v_rec.employee_id and valid_to is null; insert into position_assignments (position_id, employee_id, valid_from) values ((v_rec.payload->>'target_position_id')::uuid, v_rec.employee_id, v_rec.effective_date); update employees set job_title = ( select j.title from om_positions p join jobs j on j.id = p.job_id where p.id = (v_rec.payload->>'target_position_id')::uuid ) where id = v_rec.employee_id; elsif v_rec.change_type = 'promotion' then update employees set job_title = coalesce(v_rec.payload->>'new_title', job_title), paygrade = coalesce((v_rec.payload->>'new_paygrade')::paygrade_type, paygrade) where id = v_rec.employee_id; elsif v_rec.change_type = 'karenz_start' then update employees set status = 'Karenz', karenz_return_date = (v_rec.payload->>'planned_return_date')::date, absence_type = coalesce(nullif(v_rec.payload->>'absence_type', ''), absence_type) where id = v_rec.employee_id; elsif v_rec.change_type = 'karenz_return' then update employees set status = 'Aktiv', karenz_return_date = null, karenz_start_date = null, absence_type = null, employment_type = coalesce((v_rec.payload->>'employment_type')::employment_type, employment_type), weekly_hours = coalesce((v_rec.payload->>'weekly_hours')::numeric, weekly_hours), -- Auch bei einer *geplanten* Rückkehr: sonst käme jemand am -- Stichtag mit reduzierten Stunden zurück, und der Grund dafür -- wäre verschwunden. Der Nachweis stünde nur in der Historie, -- auswerten liesse sich nichts. teilzeit_art = case when v_rec.payload ? 'teilzeit_art' then nullif(v_rec.payload->>'teilzeit_art', '') else teilzeit_art end, teilzeit_bis = case when v_rec.payload ? 'teilzeit_art' then nullif(v_rec.payload->>'teilzeit_bis', '')::date else teilzeit_bis end where id = v_rec.employee_id; elsif v_rec.change_type = 'contract_change' then update employees set first_name = coalesce(v_rec.payload->'person'->>'first_name', first_name), last_name = coalesce(v_rec.payload->'person'->>'last_name', last_name), gender = coalesce((v_rec.payload->'person'->>'gender')::gender_type, gender), birth_date = coalesce((v_rec.payload->'person'->>'birth_date')::date, birth_date), sv_nummer = coalesce(v_rec.payload->'person'->>'sv_nummer', sv_nummer), nationality = coalesce(v_rec.payload->'person'->>'nationality', nationality), address = coalesce(v_rec.payload->'person'->>'address', address), postal_code = coalesce(v_rec.payload->'person'->>'postal_code', postal_code), city = coalesce(v_rec.payload->'person'->>'city', city), address_country = coalesce(v_rec.payload->'person'->>'address_country', address_country), email = coalesce(v_rec.payload->'person'->>'email', email), phone = coalesce(v_rec.payload->'person'->>'phone', phone), employment_type = coalesce((v_rec.payload->'contract'->>'employment_type')::employment_type, employment_type), weekly_hours = coalesce((v_rec.payload->'contract'->>'weekly_hours')::numeric, weekly_hours), contract_type = coalesce((v_rec.payload->'contract'->>'contract_type')::contract_type, contract_type) where id = v_rec.employee_id; elsif v_rec.change_type = 'dependent_add' then insert into employee_dependents (employee_id, first_name, last_name, relationship, sv_nummer, birth_date) values (v_rec.employee_id, v_rec.payload->>'first_name', v_rec.payload->>'last_name', (v_rec.payload->>'relationship')::text, nullif(v_rec.payload->>'sv_nummer', ''), (v_rec.payload->>'birth_date')::date); elsif v_rec.change_type = 'dependent_remove' then delete from employee_dependents where id = (v_rec.payload->>'dependent_id')::uuid; end if; update pending_org_changes set status = 'applied', applied_at = now() where id = v_rec.id; v_count := v_count + 1; end loop; return v_count; end; $function$; -- Selbstprüfung. do $$ declare v_apply text := pg_get_functiondef('public.apply_due_pending_changes()'::regprocedure); v_ret text := pg_get_functiondef('public.record_karenz_return(jsonb)'::regprocedure); begin if v_apply not like '%teilzeit_art%' then raise exception 'Der Tageslauf überträgt die Teilzeitvariante nicht'; end if; if v_ret not like '%teilzeit_art%' then raise exception 'record_karenz_return legt die Variante nicht in den Vorgang'; end if; end $$;