DatabaseProgramming: 01 Customer SIM activation.sql

File 01 Customer SIM activation.sql, 3.1 KB (added by 231139, 10 days ago)
Line 
1DROP PROCEDURE IF EXISTS public.proc_activate_subscription(bigint, bigint, bigint);
2DROP PROCEDURE IF EXISTS public.proc_activate_subscription(bigint, bigint, bigint, bigint, date);
3
4CREATE 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)
11LANGUAGE plpgsql
12AS $$
13DECLARE
14 v_subscription_id bigint;
15 v_subscription_number text;
16 v_activation_time timestamptz;
17BEGIN
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;
81END;
82$$;
83