Merge branch 'develop' into MED-102

This commit is contained in:
Danel Kungla
2025-09-30 18:08:04 +03:00
104 changed files with 5607 additions and 1104 deletions

View File

@@ -0,0 +1,14 @@
select
cron.schedule(
'sync-connected-online-every-night', -- Unique job name
'0 1 * * *', -- Cron schedule: every night at 04:00 (GMT +3)
$$
select
net.http_post(
url := 'https://test.medreport.ee/api/job/sync-connected-online',
headers := jsonb_build_object(
'x-jobs-api-key', 'fd26ec26-70ed-11f0-9e95-431ac3b15a84'
)
) as request_id;
$$
);

View File

@@ -0,0 +1,59 @@
alter table medreport.account_balance_entries add column "is_analysis_order" boolean;
alter table medreport.account_balance_entries add column "is_analysis_package_order" boolean;
drop function if exists medreport.consume_account_balance(uuid, numeric, text, text);
-- Create function to consume balance (for purchases)
create or replace function medreport.consume_account_balance(
p_account_id uuid,
p_amount numeric,
p_description text,
p_reference_id text default null,
p_is_analysis_order boolean default false,
p_is_analysis_package_order boolean default false
)
returns boolean
language plpgsql
security definer
as $$
declare
current_balance numeric;
remaining_amount numeric := p_amount;
entry_record record;
consumed_amount numeric;
begin
-- Get current balance
current_balance := medreport.get_account_balance(p_account_id);
-- Check if sufficient balance
if current_balance < p_amount then
return false;
end if;
-- Record the consumption
insert into medreport.account_balance_entries (
account_id,
amount,
entry_type,
description,
reference_id,
created_by,
is_analysis_order,
is_analysis_package_order
) values (
p_account_id,
-p_amount,
'purchase',
p_description,
p_reference_id,
auth.uid(),
p_is_analysis_order,
p_is_analysis_package_order
);
return true;
end;
$$;
-- Grant execute permission
grant execute on function medreport.consume_account_balance(uuid, numeric, text, text, boolean, boolean) to authenticated, service_role;

View File

@@ -0,0 +1,219 @@
ALTER TABLE medreport.account_balance_entries ADD COLUMN benefit_distribution_schedule_id uuid;
-- Also setting `benefit_distribution_schedule_id` value now
drop function if exists medreport.distribute_health_benefits(uuid, numeric, text);
create or replace function medreport.distribute_health_benefits(
p_benefit_distribution_schedule_id uuid
)
returns void
language plpgsql
security definer
as $$
declare
member_record record;
expires_date timestamp with time zone;
v_company_id uuid;
v_benefit_amount numeric;
begin
-- Expires on first day of next year.
expires_date := date_trunc('year', now() + interval '1 year');
-- Get company_id and benefit_amount from benefit_distribution_schedule
select company_id, benefit_amount into v_company_id, v_benefit_amount
from medreport.benefit_distribution_schedule
where id = p_benefit_distribution_schedule_id;
-- Get all personal accounts that are members of this company
for member_record in
select distinct a.id as personal_account_id
from medreport.accounts a
join medreport.accounts_memberships am on a.id = am.user_id
where am.account_id = v_company_id
and a.is_personal_account = true
loop
-- Check if there is already a balance entry for this personal account from the same company in same month
if exists (
select 1
from medreport.account_balance_entries
where entry_type = 'benefit'
and account_id = member_record.personal_account_id
and source_company_id = v_company_id
and date_trunc('month', created_at) = date_trunc('month', now())
) then
continue;
end if;
-- Insert balance entry for each personal account
insert into medreport.account_balance_entries (
account_id,
amount,
entry_type,
description,
source_company_id,
created_by,
expires_at,
benefit_distribution_schedule_id
) values (
member_record.personal_account_id,
v_benefit_amount,
'benefit',
'Health benefit from company',
v_company_id,
auth.uid(),
expires_date,
p_benefit_distribution_schedule_id
);
end loop;
end;
$$;
grant execute on function medreport.distribute_health_benefits(uuid) to authenticated, service_role;
create or replace function medreport.process_periodic_benefit_distributions()
returns void
language plpgsql
as $$
declare
schedule_record record;
next_distribution_date timestamp with time zone;
begin
-- Get all active schedules that are due for distribution
for schedule_record in
select *
from medreport.benefit_distribution_schedule
where is_active = true
and next_distribution_at <= now()
loop
-- Distribute benefits
perform medreport.distribute_health_benefits(
schedule_record.id
);
-- Calculate next distribution date
next_distribution_date := medreport.calculate_next_distribution_date(
schedule_record.benefit_occurrence,
now()
);
-- Update the schedule
update medreport.benefit_distribution_schedule
set
last_distributed_at = now(),
next_distribution_at = next_distribution_date,
updated_at = now()
where id = schedule_record.id;
end loop;
end;
$$;
DROP FUNCTION IF EXISTS medreport.upsert_benefit_distribution_schedule(uuid,numeric,text);
create or replace function medreport.upsert_benefit_distribution_schedule(
p_company_id uuid,
p_benefit_amount numeric,
p_benefit_occurrence text
)
-- Return schedule row id
returns uuid
language plpgsql
as $$
declare
next_distribution_date timestamp with time zone;
record_id uuid;
begin
-- Calculate next distribution date
next_distribution_date := medreport.calculate_next_distribution_date(p_benefit_occurrence);
-- Check if there's an existing record for this company
select id into record_id
from medreport.benefit_distribution_schedule
where company_id = p_company_id
limit 1;
if record_id is not null then
-- Update existing record
update medreport.benefit_distribution_schedule
set
benefit_amount = p_benefit_amount,
benefit_occurrence = p_benefit_occurrence,
next_distribution_at = next_distribution_date,
is_active = true,
updated_at = now()
where id = record_id;
else
record_id := gen_random_uuid();
-- Insert new record
insert into medreport.benefit_distribution_schedule (
id,
company_id,
benefit_amount,
benefit_occurrence,
next_distribution_at
) values (
record_id,
p_company_id,
p_benefit_amount,
p_benefit_occurrence,
next_distribution_date
);
end if;
return record_id;
end;
$$;
grant execute on function medreport.upsert_benefit_distribution_schedule(uuid, numeric, text) to authenticated, service_role;
create or replace function medreport.trigger_distribute_benefits()
returns trigger
language plpgsql
security definer
as $$
declare
v_benefit_distribution_schedule_id uuid;
begin
-- Only distribute if benefit_amount is set and greater than 0
if new.benefit_amount is not null and new.benefit_amount > 0 then
-- Create or update the distribution schedule for future distributions
v_benefit_distribution_schedule_id := medreport.upsert_benefit_distribution_schedule(
new.account_id,
new.benefit_amount,
coalesce(new.benefit_occurance, 'yearly')
);
-- Distribute benefits to all company members immediately
perform medreport.distribute_health_benefits(
v_benefit_distribution_schedule_id
);
else
-- If benefit_amount is 0 or null, deactivate the schedule
update medreport.benefit_distribution_schedule
set is_active = false, updated_at = now()
where company_id = new.account_id;
end if;
return new;
end;
$$;
CREATE OR REPLACE FUNCTION medreport.get_benefits_usages_for_company_members(p_account_id uuid)
returns table (
personal_account_id uuid,
benefit_amount numeric
)
language plpgsql
as $$
begin
return query
select
abe.account_id as personal_account_id,
sum(abe.amount) as benefit_amount
from medreport.account_balance_entries abe
where abe.source_company_id = p_account_id
and abe.entry_type = 'benefit'
group by abe.account_id;
end;
$$;
grant execute on function medreport.get_benefits_usages_for_company_members(uuid) to authenticated, service_role;

View File

@@ -0,0 +1,11 @@
create trigger tto_order_confirmation_email
after update on medreport.connected_online_reservation
for each row
when (old.status is distinct from new.status and new.status = 'CONFIRMED')
execute function supabase_functions.http_request(
'http://host.docker.internal:3000/api/db/webhook',
'POST',
'{"Content-Type":"application/json", "X-Supabase-Event-Signature":"WEBHOOKSECRET"}',
'{}',
'1000'
);