@ -986,7 +986,9 @@ declare
_item_uuids uuid [ ] ;
_cart_uuid uuid ;
_item_uuid uuid ;
_item_count integer ;
_cart_item_count integer ;
_available_item_count integer ;
_item_availability_date timestamptz ;
_stockchange_uuid uuid ;
begin
-- Get cart uuid (and check completed)
@ -1009,31 +1011,65 @@ begin
-- Make stock-change record for each item
foreach _item_uuid in array _item_uuids loop
select cart_item_count into _item_count from sos . " cart_item "
-- Get cart and item info
select cart_item_count into _cart_item_count from sos . " cart_item "
where cart_item_cart_uuid = _cart_uuid
and cart_item_item_uuid = _item_uuid ;
insert into sos . " item_stockchange " (
stockchange_type ,
stockchange_item_uuid ,
stockchange_change ,
stockchange_direction
) values (
' purchase ' ,
_item_uuid ,
_item_count ,
' subtracted '
) returning stockchange_uuid into _stockchange_uuid ;
insert into sos . " item_stockchange_purchase " (
stockchange_uuid ,
stockchange_type ,
stockchange_transaction_uuid
) values (
_stockchange_uuid ,
' purchase ' ,
_transaction_uuid
) ;
select
item_number_in_stock , item_preorder_availability_date
into _available_item_count , _item_availability_date
from sos . v_item
where item_uuid = _item_uuid ;
-- Pre-order stockchange
if _cart_item_count > _available_item_count and _item_availability_date is not null then
insert into sos . " item_stockchange " (
stockchange_type ,
stockchange_item_uuid ,
stockchange_change ,
stockchange_direction
) values (
' preorder ' ,
_item_uuid ,
_cart_item_count ,
' subtracted '
) returning stockchange_uuid into _stockchange_uuid ;
insert into sos . " item_stockchange_preorder " (
stockchange_uuid ,
stockchange_type ,
stockchange_transaction_uuid ,
stockchange_preorder_estimated_fulfill_date
) values (
_stockchange_uuid ,
' preorder ' ,
_transaction_uuid ,
_item_availability_date
) ;
else -- Non-preorder stockchange
insert into sos . " item_stockchange " (
stockchange_type ,
stockchange_item_uuid ,
stockchange_change ,
stockchange_direction
) values (
' purchase ' ,
_item_uuid ,
_cart_item_count ,
' subtracted '
) returning stockchange_uuid into _stockchange_uuid ;
insert into sos . " item_stockchange_purchase " (
stockchange_uuid ,
stockchange_type ,
stockchange_transaction_uuid
) values (
_stockchange_uuid ,
' purchase ' ,
_transaction_uuid
) ;
end if ;
end loop ;
return query select * from sos . v_item where item_uuid = any ( _item_uuids ) ;
@ -1095,11 +1131,87 @@ begin
' shipment ' ,
_shipment_uuid
) ;
perform sos . mark_preorders_shippable ( _item_uuids [ i ] , _counts [ i ] ) ;
end loop ;
return query select * from sos . v_shipment where shipment_uuid = _shipment_uuid ;
end ; $ function $ ;
create or replace function sos . mark_preorders_shippable ( _item_uuid uuid , _count integer )
returns void
language plpgsql
as $ function $
declare
_preorder_uuids uuid [ ] ;
_num_marked integer : = 0 ;
_current_num integer ;
_current_direction sos . stock_change_dir_enum ;
_remaining_preorders integer ;
begin
-- Get unfulfilled pre-order stockchanges for this item, ordered by transaction completion time
select array_agg ( item_stockchange . stockchange_uuid order by transaction_completion_time ) into _preorder_uuids
from sos . item_stockchange
left join sos . item_stockchange_preorder on item_stockchange . stockchange_uuid = item_stockchange_preorder . stockchange_uuid
left join sos . transaction on stockchange_transaction_uuid = transaction_uuid
where stockchange_item_uuid = _item_uuid
and item_stockchange . stockchange_type = ' preorder '
and stockchange_preorder_ready_to_ship = false
group by stockchange_item_uuid ;
-- For all stockchanges
if _preorder_uuids is not null then
for i in array_lower ( _preorder_uuids , 1 ) . . array_upper ( _preorder_uuids , 1 ) loop
select
stockchange_direction ,
stockchange_change
into
_current_direction ,
_current_num
from sos . item_stockchange
where stockchange_uuid = _preorder_uuids [ i ] ;
-- Sanity check: Only fulfill ones that deducted stock
if _current_direction ! = ' subtracted ' then
continue ;
end if ;
-- Don't fulfill more than we have
if _num_marked + _current_num > _count then
exit ;
end if ;
update sos . item_stockchange_preorder set
stockchange_preorder_ready_to_ship = true
where stockchange_uuid = _preorder_uuids [ i ] ;
_num_marked : = _num_marked + _current_num ;
end loop ;
end if ;
-- Count remaining pre-orders
select count ( item_stockchange . stockchange_uuid ) into _remaining_preorders
from sos . item_stockchange
left join sos . item_stockchange_preorder on item_stockchange . stockchange_uuid = item_stockchange_preorder . stockchange_uuid
where stockchange_item_uuid = _item_uuid
and item_stockchange . stockchange_type = ' preorder '
and stockchange_preorder_ready_to_ship = false
group by stockchange_item_uuid ;
-- If we no longer have pre-orders clear item pre-order records
if _remaining_preorders < 1 then
update sos . item
set (
item_preorder_availability_date ,
item_preorder_maximum
) = (
null ,
null
)
where item_uuid = _item_uuid ;
end if ;
end ; $ function $ ;
create or replace function sos . set_delivery_tracking ( _order_uuid uuid , _tracking_number text , _date_shipped timestamptz , _price_cents integer )
returns setof sos . v_order
language plpgsql
@ -1336,4 +1448,44 @@ begin
) ;
return query select * from sos . v_config ;
end ; $ function $ ;
create or replace function sos . get_number_of_preorder_reservations ( _item_uuid uuid )
returns integer
language plpgsql
as $ function $
begin
return (
select
count ( * )
from sos . item_stockchange_preorder
left join sos . item_stockchange
on item_stockchange . stockchange_uuid = item_stockchange_preorder . stockchange_uuid
where stockchange_preorder_ready_to_ship = false
and stockchange_item_uuid = _item_uuid
) ;
end ; $ function $ ;
create or replace function sos . set_preorder ( _item_uuid uuid , _estimated_delivery timestamptz , _max_preorders integer )
returns setof sos . v_item
language plpgsql
as $ function $
declare
_num_reserved integer : = sos . get_number_of_preorder_reservations ( _item_uuid ) ;
begin
if _num_reserved > _max_preorders then
raise ' Cannot lower preorder limit past the number of reservations ' ;
end if ;
update sos . item
set (
item_preorder_availability_date ,
item_preorder_maximum
) = (
_estimated_delivery ,
_max_preorders
)
where item_uuid = _item_uuid ;
return query select * from sos . v_item where item_uuid = _item_uuid ;
end ; $ function $ ;