Add cash management schema and immediate variance alerts
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
-- =====================================================================
|
||||
-- Migration 0015 — Mid-Day Shift Cash Drops
|
||||
--
|
||||
-- Enables cashiers to "drop" large sums of accumulated cash (esp USD payout cash)
|
||||
-- into a safe midway through a shift, removing their liability without
|
||||
-- requiring them to close out and open a brand new shift.
|
||||
-- =====================================================================
|
||||
|
||||
create or replace function app.record_cash_drop(
|
||||
p_shift_id uuid,
|
||||
p_drop_usd numeric,
|
||||
p_drop_lbp numeric,
|
||||
p_notes text default null
|
||||
) returns void
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = app, public
|
||||
as $$
|
||||
declare
|
||||
v_shop uuid;
|
||||
v_till uuid;
|
||||
v_status text;
|
||||
v_user uuid;
|
||||
begin
|
||||
select shop_id, till_id, status, user_id
|
||||
into v_shop, v_till, v_status, v_user
|
||||
from app.shifts
|
||||
where id = p_shift_id;
|
||||
|
||||
if v_shop is null then
|
||||
raise exception 'Shift not found';
|
||||
end if;
|
||||
|
||||
if v_user <> auth.uid() and not app.has_role_in_shop(v_shop, 'manager') then
|
||||
raise exception 'Only the shift owner or a manager may record a drop';
|
||||
end if;
|
||||
|
||||
if v_status <> 'open' then
|
||||
raise exception 'Must have an open shift to record a soft drop';
|
||||
end if;
|
||||
|
||||
if p_drop_usd < 0 or p_drop_lbp < 0 then
|
||||
raise exception 'Drop amounts cannot be negative';
|
||||
end if;
|
||||
|
||||
if p_drop_usd = 0 and p_drop_lbp = 0 then
|
||||
raise exception 'Must drop > 0 in at least one currency';
|
||||
end if;
|
||||
|
||||
-- Create a matching cash_movements record reducing the drawer balance
|
||||
insert into app.cash_movements(
|
||||
shift_id, movement_type, currency, amount, external_ref
|
||||
)
|
||||
select
|
||||
p_shift_id,
|
||||
'safe_drop',
|
||||
case when d.idx = 1 then 'USD' else 'LBP' end,
|
||||
case when d.idx = 1 then p_drop_usd else p_drop_lbp end,
|
||||
p_notes
|
||||
from (values (1), (2)) as d(idx)
|
||||
where (d.idx = 1 and p_drop_usd > 0)
|
||||
or (d.idx = 2 and p_drop_lbp > 0);
|
||||
|
||||
perform app.log_auth_event('safe_drop_recorded', v_shop, null,
|
||||
jsonb_build_object('shift_id', p_shift_id, 'usd', p_drop_usd, 'lbp', p_drop_lbp));
|
||||
end;
|
||||
$$;
|
||||
|
||||
revoke all on function app.record_cash_drop(uuid, numeric, numeric, text) from public;
|
||||
grant execute on function app.record_cash_drop(uuid, numeric, numeric, text) to authenticated;
|
||||
Reference in New Issue
Block a user