| 1 | DROP PROCEDURE IF EXISTS public.proc_activate_subscription(bigint, bigint, bigint);
|
|---|
| 2 | DROP PROCEDURE IF EXISTS public.proc_activate_subscription(bigint, bigint, bigint, bigint, date);
|
|---|
| 3 |
|
|---|
| 4 | CREATE PROCEDURE public.proc_activate_subscription(
|
|---|
| 5 | p_account_id bigint,
|
|---|
| 6 | p_plan_id bigint,
|
|---|
| 7 | p_contract_id bigint,
|
|---|
| 8 | p_sim_id bigint,
|
|---|
| 9 | p_activation_date date DEFAULT CURRENT_DATE
|
|---|
| 10 | )
|
|---|
| 11 | LANGUAGE plpgsql
|
|---|
| 12 | AS $$
|
|---|
| 13 | DECLARE
|
|---|
| 14 | v_subscription_id bigint;
|
|---|
| 15 | v_subscription_number text;
|
|---|
| 16 | v_activation_time timestamptz;
|
|---|
| 17 | BEGIN
|
|---|
| 18 | IF p_activation_date > CURRENT_DATE THEN
|
|---|
| 19 | RAISE EXCEPTION 'Activation date % cannot be in the future.', p_activation_date;
|
|---|
| 20 | END IF;
|
|---|
| 21 |
|
|---|
| 22 | PERFORM 1 FROM public.accounts
|
|---|
| 23 | WHERE account_id = p_account_id AND account_status = 'active'
|
|---|
| 24 | FOR UPDATE;
|
|---|
| 25 | IF NOT FOUND THEN
|
|---|
| 26 | RAISE EXCEPTION 'Account % does not exist or is not active.', p_account_id;
|
|---|
| 27 | END IF;
|
|---|
| 28 |
|
|---|
| 29 | PERFORM 1 FROM public.plans
|
|---|
| 30 | WHERE plan_id = p_plan_id AND status = 'active';
|
|---|
| 31 | IF NOT FOUND THEN
|
|---|
| 32 | RAISE EXCEPTION 'Plan % does not exist or is not active.', p_plan_id;
|
|---|
| 33 | END IF;
|
|---|
| 34 |
|
|---|
| 35 | PERFORM 1 FROM public.contracts
|
|---|
| 36 | WHERE contract_id = p_contract_id
|
|---|
| 37 | AND account_id = p_account_id
|
|---|
| 38 | AND status = 'active'
|
|---|
| 39 | AND start_date <= p_activation_date
|
|---|
| 40 | AND (end_date IS NULL OR end_date >= p_activation_date);
|
|---|
| 41 | IF NOT FOUND THEN
|
|---|
| 42 | RAISE EXCEPTION 'Contract % is not active for account % on %.', p_contract_id, p_account_id, p_activation_date;
|
|---|
| 43 | END IF;
|
|---|
| 44 |
|
|---|
| 45 | PERFORM 1 FROM public.sim_cards
|
|---|
| 46 | WHERE sim_id = p_sim_id AND status = 'available'
|
|---|
| 47 | FOR UPDATE;
|
|---|
| 48 | IF NOT FOUND OR EXISTS (
|
|---|
| 49 | SELECT 1 FROM public.sim_card_subscription_history
|
|---|
| 50 | WHERE sim_id = p_sim_id AND end_date IS NULL
|
|---|
| 51 | ) THEN
|
|---|
| 52 | RAISE EXCEPTION 'SIM % does not exist, is unavailable, or is already assigned.', p_sim_id;
|
|---|
| 53 | END IF;
|
|---|
| 54 |
|
|---|
| 55 | v_subscription_id := nextval(pg_get_serial_sequence('public.subscriptions', 'subscription_id'));
|
|---|
| 56 | v_subscription_number := 'SUB-' || lpad(v_subscription_id::text, 10, '0');
|
|---|
| 57 | v_activation_time := (p_activation_date + time '09:00') AT TIME ZONE 'Europe/Skopje';
|
|---|
| 58 |
|
|---|
| 59 | INSERT INTO public.subscriptions (
|
|---|
| 60 | subscription_id, account_id, plan_id, contract_id, subscription_number,
|
|---|
| 61 | activation_date, status, billing_start_date
|
|---|
| 62 | ) VALUES (
|
|---|
| 63 | v_subscription_id, p_account_id, p_plan_id, p_contract_id, v_subscription_number,
|
|---|
| 64 | p_activation_date, 'active', p_activation_date
|
|---|
| 65 | );
|
|---|
| 66 |
|
|---|
| 67 | INSERT INTO public.subscription_status_history (
|
|---|
| 68 | subscription_id, old_status, new_status, changed_at, reason
|
|---|
| 69 | ) VALUES (
|
|---|
| 70 | v_subscription_id, NULL, 'active', v_activation_time, 'Subscription activated through proc_activate_subscription'
|
|---|
| 71 | );
|
|---|
| 72 |
|
|---|
| 73 | INSERT INTO public.sim_card_subscription_history (sim_id, subscription_id, start_date)
|
|---|
| 74 | VALUES (p_sim_id, v_subscription_id, v_activation_time);
|
|---|
| 75 |
|
|---|
| 76 | UPDATE public.sim_cards
|
|---|
| 77 | SET status = 'active', issued_at = COALESCE(issued_at, v_activation_time)
|
|---|
| 78 | WHERE sim_id = p_sim_id;
|
|---|
| 79 |
|
|---|
| 80 | RAISE NOTICE 'Subscription % activated successfully with SIM %.', v_subscription_number, p_sim_id;
|
|---|
| 81 | END;
|
|---|
| 82 | $$;
|
|---|
| 83 |
|
|---|