unit uartikelpreis;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, fgl, LazLoggerBase, DBCtrls, dtm_basis;

type

  { TArtikelPreis }

  TArtikelPreis = class(TObject)
  private
    fIDSteuersatz: integer;
    fIsChanged: boolean;
    FCheckOK: boolean;
    fCheckMsg: string;
    fID: integer;
    fIDArtikel: integer;
    fIDPreisgruppe: integer;
    fStaffel: string;
    fIDMengeneinheit: integer;
    fZeit: real;
    fLohn: real;
    fService: real;
    fMaterial: real;
    fGeraet: real;
    fFremdleistung: real;
    fVKNetto: real;
    fVKBrutto: real;

    { Nur für Anzeige }
    fBezPreisgruppe: string;
    fBezMengeneinheit: string;
    fBezSteuersatz: string;
  public
    constructor Create;
    destructor Destroy;

    procedure SetIDArtikel(const aValue: integer);
    procedure SetIDPreisgruppe(const aValue: integer);
    procedure SetStaffel(const aValue: string);    // BV
    procedure SetIDMengeneinheit(const aValue: integer);
    procedure SetIDSteuersatz(const aValue: integer);
    procedure SetZeit(const aValue: real);
    procedure SetLohn(const aValue: real);
    procedure SetService(const aValue: real);
    procedure SetMaterial(const aValue: real);
    procedure SetGeraet(const aValue: real);
    procedure SetFremdleistung(const aValue: real);
    procedure SetVKNetto(const aValue: real);
    procedure SetVKBrutto(const aValue: real);

    procedure Init;
    procedure ReadByID(ID: integer);
    procedure WriteData;
    procedure ReadData(Query: string);

  published
    // idartikelpreis, fk_artikel, fk_preisgruppe, prs_staffel, fk_mengeneinheit, prs_zeit, prs_lohn, prs_service, prs_material, prs_geraet, prs_fremdleistung, prs_netto_vk, prs_brutto_vk
    property IsChanged: boolean read fIsChanged write fIsChanged default False;
    property CheckOK: boolean read fCheckOK write fCheckOK default True;
    property CheckMsg: string read fCheckMsg;
    property ID: integer read fID write fID default -1;
    property IDArtikel: integer read fIDArtikel write SetIDArtikel default -1;
    property IDPreisgruppe: integer read fIDPreisgruppe write SetIDPreisgruppe default -1;
    property Staffel: string read fStaffel write SetStaffel;
    property IDMengeneinheit: integer read fIDMengeneinheit write SetIDMengeneinheit default -1;
    property IDSteuersatz: integer read fIDSteuersatz write SetIDSteuersatz default -1;
    property Zeit: real read fZeit write SetZeit;
    property Lohn: real read fLohn write SetLohn;
    property Service: real read fService write SetService;
    property Material: real read fMaterial write SetMaterial;
    property Geraet: real read fGeraet write SetGeraet;
    property Fremdleistung: real read fFremdleistung write SetFremdleistung;
    property VKNetto: real read fVKNetto write SetVKNetto;
    property VKBrutto: real read fVKBrutto write SetVKBrutto;

    property BezPreisgruppe: string read fBezPreisgruppe;
    property BezMengeneinheit: string read fBezMengeneinheit;
    property BezSteuersatz: string read fBezSteuersatz;
  end;

  { TArtikelPreisListe }

  TArtikelPreisListe = class(specialize TFPGObjectList<TArtikelPreis>)
  private

  public
    function Add(Obj: TArtikelPreis): integer;// override;
    procedure ReadAllData;
    procedure ReadAllByArtikelID(IDArtikel: integer);
    procedure ReadListData(Query: string);
    {Suchfunktionen}
    function IndexOf(aID: integer): integer; overload;
    function IndexOf(const aBezPreisgruppe: string): integer; overload;
  published

  end;


implementation

{ TArtikelPreisListe }

function TArtikelPreisListe.Add(Obj: TArtikelPreis): integer;
begin
  inherited Add(Obj);
end;

procedure TArtikelPreisListe.ReadAllData;
var
  s: string;
begin
  s := 'SELECT idartikelpreis, fk_artikel, fk_preisgruppe, fk_mengeneinheit, fk_steuersatz, ';
  s := s + 'prs_staffel, prs_zeit, prs_lohn, prs_service, prs_material, prs_geraet, prs_fremdleistung, ';
  s := s + 'prs_netto_vk, prs_brutto_vk, preisgruppe as p, ME.beschreibung as m, SS.beschreibung as s ';
  s := s + 'FROM ArtikelPreise ';
  s := s + 'left join Preisgruppen on idpreisgruppe=fk_preisgruppe ';
  s := s + 'left join Mengeneinheiten ME on idmengeneinheit=fk_mengeneinheit ';
  s := s + 'left join Steuersaetze SS on idsteuersatz=fk_steuersatz ';
  s := s + 'order by preisgruppe';
  ReadListData(s);
end;

procedure TArtikelPreisListe.ReadAllByArtikelID(IDArtikel: integer);
var
  s: string;
begin
  s := 'SELECT idartikelpreis, fk_artikel, fk_preisgruppe, fk_mengeneinheit, fk_steuersatz, ';
  s := s + 'prs_staffel, prs_zeit, prs_lohn, prs_service, prs_material, prs_geraet, prs_fremdleistung, ';
  s := s + 'prs_netto_vk, prs_brutto_vk, preisgruppe as p, ME.beschreibung as m, SS.beschreibung as s ';
  s := s + 'FROM ArtikelPreise ';
  s := s + 'left join Preisgruppen on idpreisgruppe=fk_preisgruppe ';
  s := s + 'left join Mengeneinheiten ME on idmengeneinheit=fk_mengeneinheit ';
  s := s + 'left join Steuersaetze SS on idsteuersatz=fk_steuersatz ';
  s := s + 'where fk_artikel = ' + IntToStr(IDArtikel) + ' ';
  s := s + 'order by preisgruppe, ME.beschreibung';
  ReadListData(s);
end;

procedure TArtikelPreisListe.ReadListData(Query: string);
var
  TempObj: TArtikelPreis;
begin
  debugln('TArtikelPreisListe.ReadListData: ' + Query);
  with dtmBasis.qrySQL do
  begin
    try
      SQL.Text := Query;
      Open;
      debugln('  Gefunden: ' + IntToStr(RecordCount));
      if RecordCount > 0 then
      begin
        First;
        while not EOF do
        begin
          TempObj := TArtikelPreis.Create;

          TempObj.fID := FieldByName('idartikelpreis').AsInteger;
          TempObj.fIDArtikel := FieldByName('fk_artikel').AsInteger;
          TempObj.fIDPreisgruppe := FieldByName('fk_preisgruppe').AsInteger;
          TempObj.fStaffel := FieldByName('prs_staffel').AsString;
          TempObj.fIDMengeneinheit := FieldByName('fk_mengeneinheit').AsInteger;
          TempObj.fIDSteuersatz := FieldByName('fk_steuersatz').AsInteger;
          TempObj.fZeit := FieldByName('prs_zeit').AsFloat;
          TempObj.fLohn := FieldByName('prs_lohn').AsFloat;
          TempObj.fService := FieldByName('prs_service').AsFloat;
          TempObj.fMaterial := FieldByName('prs_material').AsFloat;
          TempObj.fGeraet := FieldByName('prs_geraet').AsFloat;
          TempObj.fFremdleistung := FieldByName('prs_fremdleistung').AsFloat;
          TempObj.fVKNetto := FieldByName('prs_netto_vk').AsFloat;
          TempObj.fVKBrutto := FieldByName('prs_brutto_vk').AsFloat;

          TempObj.fBezPreisgruppe := FieldByName('p').AsString;
          TempObj.fBezMengeneinheit := FieldByName('m').AsString;
          TempObj.fBezSteuersatz := FieldByName('s').AsString;

          Self.Add(TempObj);

          //TempObj.Free;
          Next;
        end;
      end;
      Close;
    except
      On E: Exception do
        debugln(' ' + E.Message)
    end;
  end;
end;

function TArtikelPreisListe.IndexOf(aID: integer): integer;
var
  i: integer;
begin
  Result := -1;
  for i := 0 to Count - 1 do
    if AId = TArtikelPreis(Items[i]).ID then  // der Typecast kann weggelassen werden, ist aber zur Codevervollständigung praktisch, siehe unten
      Exit(i);
end;

function TArtikelPreisListe.IndexOf(const aBezPreisgruppe: string): integer;
var
  i: integer;
begin
  Result := -1;
  for i := 0 to Count - 1 do
    if ABezPreisgruppe = Items[i].BezPreisgruppe then
      Exit(i);
end;

{ TArtikelPreis }

procedure TArtikelPreis.SetIDArtikel(const aValue: integer);
begin
  if fIDArtikel = aValue then
    exit;
  fIDArtikel := aValue;
  // IsChanged := True;    // Link setzt nicht auf aktualisiert !
end;

procedure TArtikelPreis.SetIDPreisgruppe(const aValue: integer);
begin
  if fIDPreisgruppe = aValue then
    exit;
  fIDPreisgruppe := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetStaffel(const aValue: string);
begin
  if fStaffel = aValue then
    exit;
  fStaffel := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetIDMengeneinheit(const aValue: integer);
begin
  if fIDMengeneinheit = aValue then
    exit;
  fIDMengeneinheit := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetIDSteuersatz(const aValue: integer);
begin
  if fIDSteuersatz = aValue then
    exit;
  fIDSteuersatz := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetZeit(const aValue: real);
begin
  if fZeit = aValue then
    exit;
  fZeit := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetLohn(const aValue: real);
begin
  if fLohn = aValue then
    exit;
  fLohn := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetService(const aValue: real);
begin
  if fService = aValue then
    exit;
  fService := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetMaterial(const aValue: real);
begin
  if fMaterial = aValue then
    exit;
  fMaterial := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetGeraet(const aValue: real);
begin
  if fGeraet = aValue then
    exit;
  fGeraet := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetFremdleistung(const aValue: real);
begin
  if fFremdleistung = aValue then
    exit;
  fFremdleistung := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetVKNetto(const aValue: real);
begin
  if fVKNetto = aValue then
    exit;
  fVKNetto := aValue;
  IsChanged := True;
end;

procedure TArtikelPreis.SetVKBrutto(const aValue: real);
begin
  if fVKBrutto = aValue then
    exit;
  fVKBrutto := aValue;
  IsChanged := True;
end;


constructor TArtikelPreis.Create;
begin
  inherited Create;
  Init;
end;

procedure TArtikelPreis.Init;
begin
  fIsChanged := False;
  fCheckOK := True;
  fID := -1;
  // fIDArtikel := -1;  // Link hat keine Vorgabe !
  fIDPreisgruppe := -1;
  fStaffel := '';
  fIDMengeneinheit := 1;
  fIDSteuersatz := 1;
  fZeit := 0;
  fLohn := 0;
  fService := 0;
  fMaterial := 0;
  fGeraet := 0;
  fFremdleistung := 0;
  fVKNetto := 0;
  fVKBrutto := 0;
end;

procedure TArtikelPreis.ReadByID(ID: integer);
var
  s: string;
begin
  s := 'SELECT idartikelpreis, fk_artikel, fk_preisgruppe, fk_mengeneinheit, fk_steuersatz, ';
  s := s + 'prs_staffel, prs_zeit, prs_lohn, prs_service, prs_material, prs_geraet, prs_fremdleistung, ';
  s := s + 'prs_netto_vk, prs_brutto_vk, preisgruppe as p, ME.beschreibung as m, SS.beschreibung as s ';
  s := s + 'FROM ArtikelPreise ';
  s := s + 'left join Preisgruppen on idpreisgruppe=fk_preisgruppe ';
  s := s + 'left join Mengeneinheiten ME on idmengeneinheit=fk_mengeneinheit ';
  s := s + 'left join Steuersaetze SS on idsteuersatz=fk_steuersatz ';
  s := s + 'where idartikelpreis = ' + IntToStr(ID);
  s := s + '';
  ReadData(s);
end;

procedure TArtikelPreis.WriteData;
begin
  debugln('TArtikelPreis.WriteData: ');
  if fIsChanged then
  begin
    fIsChanged := False;
    with dtmBasis.qrySQL do
    begin
      if fID < 0 then
      begin
        SQL.Clear;
        SQL.Add('Insert Into ArtikelPreise');
        SQL.Add('(fk_artikel, fk_preisgruppe, prs_staffel, fk_mengeneinheit, fk_steuersatz, prs_zeit, prs_lohn, prs_service, prs_material, prs_geraet, prs_fremdleistung, prs_netto_vk, prs_brutto_vk)');
        SQL.ADD('VALUES');
        SQL.ADD('(:fk_artikel, :fk_preisgruppe, :prs_staffel, :fk_mengeneinheit, :fk_steuersatz, :prs_zeit, :prs_lohn, :prs_service, :prs_material, :prs_geraet, :prs_fremdleistung, :prs_netto_vk, :prs_brutto_vk );');
        Prepare;
      end
      else
      begin  //Update
        DebugLn('  Datensatz ' + IntToStr(fid) + ' wird aktualisiert');
        SQL.Clear;
        SQL.ADD('UPDATE ArtikelPreise SET');
        SQL.ADD('fk_artikel = :fk_artikel,');
        SQL.ADD('fk_preisgruppe = :fk_preisgruppe,');
        SQL.ADD('prs_staffel = :prs_staffel,');
        SQL.ADD('fk_mengeneinheit = :fk_mengeneinheit,');
        SQL.ADD('fk_steuersatz = :fk_steuersatz,');
        SQL.ADD('prs_zeit = :prs_zeit,');
        SQL.ADD('prs_lohn =  :prs_lohn,');
        SQL.ADD('prs_service = :prs_service,');
        SQL.ADD('prs_material = :prs_material,');
        SQL.ADD('prs_geraet = :prs_geraet,');
        SQL.ADD('prs_fremdleistung = :prs_fremdleistung,');
        SQL.ADD('prs_netto_vk = :prs_netto_vk,');
        SQL.ADD('prs_brutto_vk = :prs_brutto_vk');
        SQL.ADD('WHERE idartikelpreis = :idartikelpreis;');
        Params.ParamByName('idartikelpreis').AsInteger := fID;
      end;
      Params.ParamByName('fk_artikel').AsInteger := fIDArtikel;
      Params.ParamByName('fk_preisgruppe').AsInteger := fIDPreisgruppe;
      Params.ParamByName('prs_staffel').AsString := fStaffel;
      Params.ParamByName('fk_mengeneinheit').AsInteger := fIDMengeneinheit;
      Params.ParamByName('fk_steuersatz').AsInteger := fIDSteuersatz;
      Params.ParamByName('prs_zeit').AsFloat := fZeit;
      Params.ParamByName('prs_lohn').AsFloat := fLohn;
      Params.ParamByName('prs_service').AsFloat := fService;
      Params.ParamByName('prs_material').AsFloat := fMaterial;
      Params.ParamByName('prs_geraet').AsFloat := fGeraet;
      Params.ParamByName('prs_fremdleistung').AsFloat := fFremdleistung;
      Params.ParamByName('prs_netto_vk').AsFloat := fVKNetto;
      Params.ParamByName('prs_brutto_vk').AsFloat := fVKBrutto;
      try
        ExecSQL;
        DebugLn('  Gespeichert!');
        if fID = -1 then
        begin
          SQL.Text := 'SELECT * FROM view_lastid';
          Open;
          fID := FieldByName('LastID').AsInteger;
          debugLn('  Neue ID ist: ' + IntToStr(fID));
          Close;
        end;
      except
        On E: Exception do
          debugln(' ' + E.Message);
      end;
    end;
  end
  else
    DebugLn('  Nicht gespeichert: Datensatz aktuell');
end;

procedure TArtikelPreis.ReadData(Query: string);
begin
  debugln('TArtikelPreis.ReadData: ' + Query);
  with dtmBasis.qrySQL do
  begin
    try
      SQL.Text := Query;
      Open;
      debugln('  Gefunden: ' + IntToStr(RecordCount));
      if RecordCount > 0 then
      begin
        fID := FieldByName('idartikelpreis').AsInteger;
        fIDArtikel := FieldByName('fk_artikel').AsInteger;
        fIDPreisgruppe := FieldByName('fk_preisgruppe').AsInteger;
        fStaffel := FieldByName('prs_staffel').AsString;
        fIDMengeneinheit := FieldByName('fk_mengeneinheit').AsInteger;
        fIDSteuersatz := FieldByName('fk_steuersatz').AsInteger;
        fZeit := FieldByName('prs_zeit').AsFloat;
        fLohn := FieldByName('prs_lohn').AsFloat;
        fService := FieldByName('prs_service').AsFloat;
        fMaterial := FieldByName('prs_material').AsFloat;
        fGeraet := FieldByName('prs_geraet').AsFloat;
        fFremdleistung := FieldByName('prs_fremdleistung').AsFloat;
        fVKNetto := FieldByName('prs_netto_vk').AsFloat;
        fVKBrutto := FieldByName('prs_brutto_vk').AsFloat;

        fBezPreisgruppe := FieldByName('p').AsString;
        fBezMengeneinheit := FieldByName('m').AsString;
        fBezSteuersatz := FieldByName('s').AsString;

      end
      else
        fID := -1;
      Close;
    except
      On E: Exception do
        debugln(' ' + E.Message)
    end;
  end;
end;



destructor TArtikelPreis.Destroy;
begin
  inherited;
end;



end.
