-----------------------------------------------------------------
-- PL/SQL: Package  (Example 4.4.7)                             -
-- Chapter 4; Oracle Programming -- A Primer                    -
--            by R. Sunderraman                                 -
-----------------------------------------------------------------

-- PACKAGE PROCESS_ERRORS SPECS ---

create or replace package process_orders as
  procedure add_order_details
    (onum      IN odetails.ono%type,
     pnum      IN odetails.pno%type,
     quantity  IN odetails.qty%type);
  procedure add_order
    (onum IN orders.ono%type,
     cnum IN orders.cno%type,
     enum IN orders.eno%type,
     receive IN date);
  procedure ship_order
    (onum IN orders.ono%type,
     ship IN date);
end;
/
show errors

-- PACKAGE PROCESS_ERRORS BODY ---

create or replace package body process_orders as

  procedure add_order_details
    (onum      IN odetails.ono%type,
     pnum      IN odetails.pno%type,
     quantity  IN odetails.qty%type) is
  cur_q parts.qoh%type;
  lev parts.olevel%type;
  begin
    select qoh,olevel into cur_q,lev from parts where pno = pnum;
    if (cur_q > quantity) then
      update parts set qoh = qoh - quantity where pno = pnum;
      if (cur_q - quantity) < lev then
        insert into restock values (sysdate,pnum);
      end if;
      insert into odetails values (onum,pnum,quantity);
    else
      insert into odetails_errors
        values(sysdate,onum,pnum,'Do not have enough to sell'); 
    end if; 
  exception
    when others then
      rollback work; 
      insert into odetails_errors
        values(sysdate,onum,pnum,'error inserting order detail'); 
  end;

  procedure add_order
    (onum IN orders.ono%type,
     cnum IN orders.cno%type,
     enum IN orders.eno%type,
     receive IN date) is
  begin
    if (receive is null) then
      insert into orders
        values (onum,cnum,enum,sysdate,null);
    else
      insert into orders
        values (onum,cnum,enum,receive,null);
    end if;
  exception
    when others then
      rollback work;
      insert into orders_errors
        values(sysdate,onum,'error inserting order'); 
    
  end;

  procedure ship_order
    (onum IN orders.ono%type,
     ship IN date) is
  begin
    if (ship is null) then
      update orders
      set    shipped = sysdate
      where  ono = onum;
    else
      update orders
      set    shipped = ship
      where  ono = onum;
    end if;
  exception
    when others then
      rollback work;
      insert into orders_errors
        values(sysdate,onum,'error updating shipped date'); 
  end;

end;
/
show errors
