package Ada_Store.Trading.Transaction.Sale

with Ada_Store.Support.List;
with Ada_Store.Trading.Item;
with Ada_Store.Trading.Department;
with Ada_Store.Trading.Tender;

package Ada_Store.Trading.Transaction.Sale is

   type Instance is new Transaction.Instance with private;

   procedure Add_Item
     (Sale     : in out Instance;
      New_Item : in     Item.Instance;
      Quantity : in     Positive := 1);

   procedure Add_Item
     (Sale     : in out Instance;
      New_Item : in     Department.Instance;
      Amount   : in     Currency);

   procedure Add_Payment
     (Sale	 : in out Instance;
      New_Tender : in     Tender.Instance;
      Amount	 : in     Currency;
      Change	 :    out Currency);

   procedure Complete
     (Sale : in out Instance);

   procedure Void
     (Sale : in out Instance);

   function Total_Items
     (Sale	 : in Instance)
     return Natural;

   function Total_Value
     (Sale	 : in Instance)
     return Currency;

   function Total_Tendered
     (Sale	 : in Instance)
     return Currency;

   Invalid_Item   : exception;
   Invalid_Tender : exception;

private
   type Sale_Line_Type  is ( Item_Line, Department_Line, Tender_Line );

   type Transaction_Line(Line_Type : Sale_Line_Type := Item_Line) is
      record
	 case Line_Type is
	    when Item_Line =>
	       The_Item     : Item.Instance;
	       The_Quantity : Quantity;
	    when Department_Line =>
	       The_Dept     : Department.Instance;
	       Dept_Amount  : Currency;
	    when Tender_Line =>
	       Tender_Type  : Tender.Instance;
	       The_Amount   : Currency;
	 end case;
      end record;

   package Line_List    is new Support.List(Transaction_Line);

   type Instance 	is new Transaction.Instance with 
      record
	 Total_Items    : Natural      := 0;
	 Total_Value    : Currency     := 0.0;
	 Total_Tendered : Currency     := 0.0;
	 Lines		: Line_List.Instance;
      end record;

end Ada_Store.Trading.Transaction.Sale;

with Ada_Store.Trading.Item;

package body Ada_Store.Trading.Transaction.Sale is

   procedure Add_Item
     (Sale     : in out Instance;
      New_Item : in     Item.Instance;
      Quantity : in     Positive      := 1) is
   begin
      Sale.Total_Items := Sale.Total_Items + 1;
      Sale.Total_Value := Sale.Total_Value + Item.Price(New_Item);
   end Add_Item;
   
   procedure Add_Item
     (Sale     : in out Instance;
      New_Item : in     Department.Instance;
      Amount   : in     Currency) is
   begin
      Sale.Total_Items := Sale.Total_Items + 1;
      Sale.Total_Value := Sale.Total_Value + Amount;
   end Add_Item;

   procedure Add_Payment
     (Sale	 : in out Instance;
      New_Tender : in     Tender.Instance;
      Amount	 : in     Currency;
      Change	 :    out Currency) is
   begin
      if Sale.Total_Tendered >= Sale.Total_Value then
	 raise Invalid_Tender;
      end if;
      
      Sale.Total_Tendered := Sale.Total_Tendered + Amount;
      
      Change := Sale.Total_Tendered - Sale.Total_Value;
      -- may be negative.
   end Add_Payment;

   procedure Complete
     (Sale : in out Instance) is
   begin
      if Sale.Total_Tendered >= Sale.Total_Value then
	 Sale.Current_State := Complete;
	 Ada_Store.Log.Put(Sale);
      else
	 raise Unable_To_Complete;
      end if;
   end Complete;

   procedure Void
     (Sale : in out Instance) is
   begin
      Sale.Current_State := Void;
      
      Ada_Store.Log.Put(Sale);
   end Void;

   function Total_Items
     (Sale	 : in Instance)
     return Natural is
   begin
      return Sale.Total_Items;
   end Total_Items;

   function Total_Value
     (Sale	 : in Instance)
     return Currency is
   begin
      return Sale.Total_Value;
   end Total_Value;

   function Total_Tendered
     (Sale	 : in Instance)
     return Currency is
   begin
      return Sale.Total_Tendered;
   end Total_Tendered;

end Ada_Store.Trading.Transaction.Sale;

Contents Page

Copyright © 1996 Simon Johnston &
Addison Wesley Longman