//----------------------------------------------------------------------------//
//- CaoController.pas --------------------------------------------------------//
//----------------------------------------------------------------------------//

//- Beschreibung -------------------------------------------------------------//
// Diese Klasse steuert Abläufe im Kassensystem, so z.B. das Drucken von      //
// Preisschildern, das Verkaufen von Artikeln etc.                            //
//----------------------------------------------------------------------------//

unit CaoController;

//------------------------------------------------------------------------------

interface

//------------------------------------------------------------------------------

uses
  CaoArtikelListe, CaoBoersenInfo, CaoPersonenListe, CaoDatenBank, CaoRegistry;

//------------------------------------------------------------------------------

type
  TCaoController = class (TObject)
  private
    m_obPersonenListe: TCaoPersonenListe;
    m_obVerkauf      : TCaoArtikelListe;
    m_obArtikelListe : TCaoArtikelListe;
    m_obBoersenInfo  : TCaoBoersenInfo;
    m_obDatenBank    : TCaoDatenBank;
    m_fVerkaufActive : Boolean;
    m_obRegistry     : TCaoRegistry;

  //----------------------------------------------------------------------------

  public
    property    obVerkauf      : TCaoArtikelListe  read m_obVerkauf;
    property    obPersonenListe: TCaoPersonenListe
                  read m_obPersonenListe write m_obPersonenListe;
    property    obArtikelListe : TCaoArtikelListe
                  read m_obArtikelListe  write m_obArtikelListe;
    property    obBoersenInfo  : TCaoBoersenInfo
                  read m_obBoersenInfo   write m_obBoersenInfo;
    property    fVerkaufActive : Boolean
                  read m_fVerkaufActive;

    //--------------------------------------------------------------------------

    constructor Create;  reintroduce;
    destructor  Destroy; reintroduce;
    procedure   EtikettenDrucken(obArtikelListe: TCaoArtikelListe);
    procedure   ArtikelVerkaufen(cKey: Char);
    procedure   VerkaufAbschliessen;
    procedure   BoerseStarten;
    procedure   BoerseBeenden;
    procedure   QuittungDrucken;
    function    ProgrammBeenden: Boolean;
    procedure   PrintAbschlussDaten;
    procedure   PreviewAbschlussDaten;
    procedure   SetStatusZeilen;
    procedure   ArtikelverkaufRueckgaengig;

  //----------------------------------------------------------------------------

  end; // TCaoController

//------------------------------------------------------------------------------

var
  g_obController: TCaoController;

//------------------------------------------------------------------------------

implementation

//------------------------------------------------------------------------------

uses
  CadEtikettenDrucken, Dialogs, CamConst, Controls, CapEtikettenReport,
  CadAnzahlEtiketten, CadArtikelCodeAnzeige, SysUtils, CawMain,
  CadAdministratorLogin, CadBoersenStart, CadSchlussabrechnung,
  CapQuittung, Forms, CapAbschlussdaten;

//------------------------------------------------------------------------------

procedure TCaoController.EtikettenDrucken(obArtikelListe: TCaoArtikelListe);
(*
  Prozedur zum Durcken von Strichcode-Etiketten
*)
var
  iDialogResult,
  iAnzahlFehlendeEtiketten: Integer;
begin
  iDialogResult := CaDlgEtikettenDrucken.ShowModal;
  case iDialogResult of
    c_iDialogResultNeuerBogen:
    begin
      CapQrEtikettenReport.Print(obArtikelListe, 0);
      m_obRegistry.WriteAnzFehlendeEtiketten(obArtikelListe.Count mod
                                             c_iAnzahlBogenEtiketten);
    end; // case c_iDialogResultNeuerBogen
    c_iDialogResultBogenFortfahren:
    begin
      iAnzahlFehlendeEtiketten := m_obRegistry.ReadAnzFehlendeEtiketten;
      CapQrEtikettenReport.Print(obArtikelListe, iAnzahlFehlendeEtiketten);
      m_obRegistry.WriteAnzFehlendeEtiketten((obArtikelListe.Count +
      iAnzahlFehlendeEtiketten) mod c_iAnzahlBogenEtiketten);
    end; // case c_iDialogResultBogenFortfahren
    c_iDailogResultAnzahlEingeben:
    begin
      if CaDlgAnzahlEtiketten.ShowModal = mrOk then begin
        iAnzahlFehlendeEtiketten := CaDlgAnzahlEtiketten.iAnzahlFehlendeEtiketten;
        CapQrEtikettenReport.Print(obArtikelListe, iAnzahlFehlendeEtiketten);
        m_obRegistry.WriteAnzFehlendeEtiketten((obArtikelListe.Count +
        iAnzahlFehlendeEtiketten) mod c_iAnzahlBogenEtiketten);
      end; // if
    end; // case c_iDailogResultAnzahlEingeben
  end; // case
end; // TCaoController.EtikettenDrucken

//------------------------------------------------------------------------------

procedure TCaoController.ArtikelVerkaufen(cKey: Char);
(*
  Ablauf beim Verkauf eines Artikels
*)
var
  obTempArtikel       : TCaoArtikel;
begin
  // Wurde eine Zahl im Hauptformular eingegeben, so wird der Verkauf gestartet
  // oder fortgesetzt
  if cKey in c_stCharZahlen then begin
    // Ist eine Börse aktiv, wird die Artikelnummeranzeige gestartet
    if m_obBoersenInfo.fBoerseActive then begin
      // Mittels der Artikelcodeanzeige den ArtikelCode ermitteln
      CaDlgArtikelCodeAnzeige.ShowModal(StrToInt(cKey));
      // Den Artikelcode in der Artikelliste mit allen Artikeln suchen
      obTempArtikel := m_obArtikelListe.Locate(CaDlgArtikelCodeAnzeige.ArtikelNummer);
      // Überprüfen, ob der Artikel gefunden wurde
      if obTempArtikel <> nil then begin
        // Überprüfen, ob der Artikel nicht schon verkauft wurde
        if obTempArtikel.fVerkauft = False then begin
           // Prüfen, ob der Verkauf noch nicht gestartet wurde. In diesem Fall
           // ein neues Verkaufsobjekt anlegen
          if not m_fVerkaufActive then begin
            m_obVerkauf := m_obBoersenInfo.VerkaufsListe.CreateArtikelListe;
            m_fVerkaufActive := True;
            CaWinMain.SetBoersenStatus(c_iStatusVerkauf);
          end; // if
          // Artikel dem Verkaufsobjekt hinzufügen
          m_obVerkauf.AddArtikel(obTempArtikel);
          obTempArtikel.fVerkauft := True;
          obTempArtikel.iStatus   := c_iModusEdit;
          // Die Listview mit den Artikeldaten aktualisieren
          CaWinMain.InitArtikelList(False);
        end // if
        else begin
          // Meldung, wenn der Artikel bereits verkauft wurde
          MessageDlg(c_sMeldungArtikelVerkauft, mtError, [mbOk], 0);
        end; // else
      end // if
      // Wurde der Artikel nicht gefunden, -> Meldung ausgeben
      else begin
        MessageDlg(c_sMeldungArtikelUnbekannt, mtError, [mbOk], 0);
      end; // else
    end // if
    else begin
      MessageDlg(c_sMeldungBoerseNichtAktiv, mtError, [mbOk], 0);
    end; // else
  end; // if
end; // TCaWinMain.ArtikelVerkaufen

//------------------------------------------------------------------------------

constructor TCaoController.Create;
begin
  m_obRegistry               := TCaoRegistry.Create;
  m_obBoersenInfo            := TCaoBoersenInfo.Create;
  // m_fBoerseActive gibt an, ob in der Datenbank eine bereits gesatartete
  // Börse gefunden wurde
  m_obBoersenInfo.LoadFromDb; 
  if m_obBoersenInfo.fBoerseActive then begin
    MessageDlg(Format(c_sMeldungBoerseGeladen,
      [m_obBoersenInfo.sTitel, DateToStr(m_obBoersenInfo.dtBoersenDatum)]),
      mtInformation, [mbOk], 0);
  end; // if
  m_fVerkaufActive           := False;
  // Kreiren der Liste, die Alle Artikel enthält
  m_obArtikelListe := TCaoArtikelListe.Create;
  // Kreiren der Liste, die alle Anbieter beinhaltet
  m_obPersonenListe := TCaoPersonenListe.Create;
  // Abfüllen der ArtikelListe mit den Daten aus der Datenbank
  m_obArtikelListe.LoadFromDb(m_obBoersenInfo.iBoersenNummer);
  // Abfüllen der Personenliste mit den Daten aus der Datenbank
  m_obPersonenListe.LoadFromDb;

  // Artikel den Anbietern zuordnen
  m_obDatenBank.LoadAnbieterData(m_obArtikelListe, m_obPersonenListe);
end; // TCaoController.Create

//------------------------------------------------------------------------------

procedure TCaoController.VerkaufAbschliessen;
(*
  Abschliessen des Verkaufs durch drücken von Enter
*)
begin
  // Überprüfen, ob überhaupt ein Verkauf gestartet wurde
  if m_fVerkaufActive then begin
    m_fVerkaufActive := False;
    CaWinMain.SetBoersenStatus(c_iStatusBereit);
    CaWinMain.InitArtikelList(True);
    m_obArtikelListe.SaveToDb;
  end // if
  else begin
    // Überprüfen, ob eine Börse aktiv ist, wenn nicht wird eine Fehlermeldung
    // ausgegeben
    if not m_obBoersenInfo.fBoerseActive then begin
      MessageDlg(c_sMeldungBoerseNichtAktiv, mtError, [mbOk], 0);
    end; // if
  end; // else
end; // TCaoController.VerkaufAbschliessen

//------------------------------------------------------------------------------ 

destructor TCaoController.Destroy;
begin
  m_obBoersenInfo.Free;
  m_obArtikelListe.Free(True);
  m_obPersonenListe.Free(True);
  m_obRegistry.Free;
end; // TCaoController.Destroy

//------------------------------------------------------------------------------

procedure TCaoController.BoerseStarten;
(*
  Starten der Börse
*)
begin
  if CaDlgAdministratorLogin.ShowModal = mrOk then begin
    // Prüfen, ob nicht schon eine Börse gestartet wurde
    if not m_obBoersenInfo.fBoerseActive then begin
      if CaDlgBoersenStart.ShowModal(m_obBoersenInfo) = mrOk then begin
        // Anbieterliste aus der Datenbank laden
        m_obPersonenListe.LoadFromDb;
        // Den Börsenstatus auf aktiv setzen
        m_obBoersenInfo.fBoerseActive := True;
        CaWinMain.SetBoersenStatus(c_iStatusBereit);
        m_obBoersenInfo.iStatus := c_iModusNeu;
        // Die Börsendaten in die Datenbank schreiben
        m_obBoersenInfo.SaveToDb;
        // Die ArtikelListe aus der Datenbank lesen
        m_obArtikelListe.LoadFromDb(m_obBoersenInfo.iBoersenNummer);
      end; // if
    end // if
    else begin
      // Wurde bereits eine Börse gestartet, wird eine Fehlermeldung ausgegeben
      MessageDlg(c_sMeldungBoerseAktiv, mtError, [mbOk], 0);
    end; // else
  end; // if
end; // TCaoController.BoerseStarten

//------------------------------------------------------------------------------

procedure TCaoController.BoerseBeenden;
(*
  Beenden der Börse
*)
var
  iTempMsgResult: Integer;
begin
 // Der Administrator muss sich einloggen
  if CaDlgAdministratorLogin.ShowModal = mrOk then begin
    if m_obBoersenInfo.fBoerseActive then begin
      if CaDlgSchlussabrechnung.ShowModal(m_obBoersenInfo,
                                          m_obArtikelListe) = mrOk then begin
         // Abfragen, ob die Börse wirklich abgeschlossen werden soll
        if MessageDlg(c_sMeldungBoerseBeenden, mtConfirmation, [mbYes, mbNO], 0)
          = mrYes then begin
          // Das Abschlussdatum setzen
          m_obBoersenInfo.dtAbschlussDatum := Now;
          m_obBoersenInfo.fBoerseActive    := False;
          CaWinMain.SetBoersenStatus(c_iStatusKeineBoerse);
          iTempMsgResult :=  MessageDlg(c_sMeldungAbschlussDrucken, mtConfirmation,
                        [mbYes, mbNO, mbCancel], 0);
          // Wurde der Dialog mit "Cancel" verlassen, wird die Börse nicht
          // abgeschlossen
          if iTempMsgResult = mrCancel then begin
            m_obBoersenInfo.fBoerseActive := True;
            MessageDlg(c_sMeldungKeinAbschluss, mtInformation, [mbOk], 0);
            g_obController.SetStatusZeilen;
          end // if
          else if iTempMsgResult = mrYes then begin
            g_obController.PrintAbschlussDaten;
          end; // else
          m_obBoersenInfo.iStatus := c_iModusEdit;
          m_obBoersenInfo.SaveToDb;
        end; // if
      end; // if
    end // if
    else begin
      MessageDlg(c_sMeldungBoerseNichtAktiv, mtError, [mbOk], 0);
    end; // else
  end; // if
end; // TCaoController.BoerseBeenden

//------------------------------------------------------------------------------

procedure TCaoController.QuittungDrucken;
(*
  Prozedur zum Drucken der Quittung
*)
begin
  if m_obBoersenInfo.fBoerseActive then begin
    // Prüfen, ob überhaupt ein Verkauf gestartet wurde
    if not m_fVerkaufActive then begin
      // Prüfen, ob das Verkaufsobjekt initialisiert ist, andernfalls wird eine
      // Fehlermeldung ausgegeben
      if Assigned(m_obVerkauf) then begin
        // Nur wenn mindestens ein Artikel erfasst wurde, kann eine Quittung
        // gedruckt werden
        if m_obVerkauf.Count > 0 then begin
          // Drucken der Quittung
          CaQrpQuittung.Print(m_obBoersenInfo, m_obVerkauf);
        end // if
        else begin
          // Fehldermeldung, wenn noch kein Artikel erfasst wurde
          MessageDlg(c_sMeldungKeineArtikelErfasst, mtError, [mbOk], 0);
        end; // else
      end // if
      else begin
        // Fehlermeldung, wenn das Verkaufsobjekt nicht initialisiert ist
        MessageDlg(c_sMeldungKeineArtikelErfasst, mtError, [mbOk], 0);
      end; // else
    end // if
    else begin
      // Fehlermeldung, wenn noch keine Artikel erfasst wurden
      MessageDlg(c_sMeldungVerkaufNichtAbgeschl, mtError, [mbOk], 0);
    end; // else
  end // if
  // Fehlermeldung, wenn keine Börse akriv ist
  else begin
    MessageDlg(c_sMeldungBoerseNichtAktiv, mtError, [mbOk], 0);
  end; // else
end; // TCaoController.QuittungDrucken

//------------------------------------------------------------------------------

function TCaoController.ProgrammBeenden: Boolean;
(*
  Beenden des Programms
*)
begin
  Result := False;
  // Wenn ein Verkauf nicht abgeschlossen wurde, darf das Programm nicht
  // beendet werden
  if m_fVerkaufActive then begin
    MessageDlg(c_sMeldungProgrammNichtBeenden, mtError, [mbOk], 0);  
  end // if
  else begin
    Result := True;
  end; // else
end; // TCaoController.ProgrammBeenden

//------------------------------------------------------------------------------

procedure TCaoController.PrintAbschlussDaten;
(*
  Drucken der Abschlussdaten
*)
begin
  CaQrpAbschlussdaten.Print(m_obBoersenInfo, m_obArtikelListe);
end; // TCaoController.PrintAbschlussDaten

//------------------------------------------------------------------------------

procedure TCaoController.PreviewAbschlussDaten;
(*
  Anzeigen Abschlussdaten
*)
begin
  CaQrpAbschlussdaten.Preview(m_obBoersenInfo, m_obArtikelListe);
end; // TCaoController.PrintAbschlussDaten

//------------------------------------------------------------------------------

procedure TCaoController.SetStatusZeilen;
begin
  if not m_obBoersenInfo.fBoerseActive then begin
    m_obBoersenInfo.iStatus  := c_iModusNeu;
    CaWinMain.SetBoersenStatus(c_iStatusKeineBoerse);
  end // if
  else begin
    m_obBoersenInfo.iStatus  := c_iModusEdit;
    CaWinMain.SetBoersenStatus(c_iStatusBereit);
  end; // else
end; // TCaoController.SetStatusZeilen

//------------------------------------------------------------------------------

procedure TCaoController.ArtikelverkaufRueckgaengig;
(*
  Macht den Verkauf eines Artikels rückgängig
*)
begin
  if m_fVerkaufActive then begin
    m_obVerkauf.Items[m_obVerkauf.Count-1].iStatus   := c_iModusEdit;
    m_obVerkauf.Items[m_obVerkauf.Count-1].fVerkauft := False;
    m_obVerkauf.RemoveArtikel(m_obVerkauf.Count-1);   
    m_obArtikelListe.SaveToDb;
    CaWinMain.InitArtikelList(m_obVerkauf.Count = 0);
    if m_obVerkauf.Count < 1 then begin
      m_fVerkaufActive := False;
      CaWinMain.SetBoersenStatus(c_iStatusBereit);
      CaWinMain.m_LivArtikelliste.Clear;
      CaWinMain.m_LivTotal.Clear;
    end; // if
  end; // if
end; // TCaoController.ArtikelverkaufRueckgaengig

//------------------------------------------------------------------------------

end. // CaoController
