unit rptmasterdetaildataset;


{$mode objfpc}{$H+}
{$I demos.inc}

interface

uses
  Classes,
  SysUtils,
  fpreport,
  fpreportdb,
  db,
  sqldb,
  IBConnection,
  udapp;

type

  { TMasterDetailDatasetDemo }

  TMasterDetailDatasetDemo = class(TReportDemoApp)
  private
    IBConnection1: TIBConnection;
    SQLTransaction1: TSQLTransaction;
    ProjectDS: TDataSource;
    qryProject: TSQLQuery;
    qryEmployee: TSQLQuery;
    qryProjBudget: TSQLQuery;
    ReportMasterData: TFPReportDatasetData;
    ReportDetailData: TFPReportDatasetData;
    ReportBudgetData: TFPReportDatasetData;
  Protected
    procedure   CreateReportDesign; override;
    procedure   InitialiseData; override;
  public
    constructor Create(AOwner : TComponent); override;
    destructor  Destroy; override;
    Class function Description : string; override;
  end;


implementation

uses
  fpTTF;

const
  // use alias, it is pre-defined in Firebird installations
  cDatabase = 'localhost:employee';
//  cDatabase = 'localhost:/usr/share/doc/firebird2.5-common-doc/examples/empbuild/employee.fdb';
//  cDatabase = '/opt/firebird/examples/empbuild/employee.fdb';

{ TMasterDetailDatasetDemo }

procedure TMasterDetailDatasetDemo.CreateReportDesign;
var
  p: TFPReportPage;
  TitleBand: TFPReportTitleBand;
  MasterDataBand: TFPReportDataBand;
  DetailDataBand: TFPReportDataBand;
  ProjBudgetBand: TFPReportDataBand;
  Memo: TFPReportMemo;
  DataHeader: TFPReportDataHeaderBand;
  BudgetDataHeader: TFPReportDataHeaderBand;
begin
  Inherited;
  rpt.Author := 'Graeme Geldenhuys';
  rpt.Title := 'FPReport Demo 11 - Master/Detail using datasets';
  p := TFPReportPage.Create(rpt);
  p.Orientation := poPortrait;
  p.PageSize.PaperName := 'A4';
  { page margins }
  p.Margins.Left := 30;
  p.Margins.Top := 20;
  p.Margins.Right := 30;
  p.Margins.Bottom := 20;
  p.Data := ReportMasterData;
  p.Font.Name := 'LiberationSans';

  // ======== ReportTitle band ===========
  TitleBand := TFPReportTitleBand.Create(p);
  TitleBand.Layout.Height := 20;
  {$ifdef ColorBands}
  TitleBand.Frame.Shape := fsRectangle;
  TitleBand.Frame.BackgroundColor := clReportTitleSummary;
  {$endif}

  Memo := TFPReportMemo.Create(TitleBand);
  Memo.Layout.Left := 0;
  Memo.Layout.Top := 0;
  Memo.Layout.Width := TitleBand.Layout.Width;
  Memo.Layout.Height := 15;
  Memo.UseParentFont := False;
  Memo.Font.Name := 'LiberationSans-Bold';
  Memo.Font.Size := 18;
  Memo.Text := 'FPReport Demo 11' + LineEnding + 'Master/Detail using datasets';
  Memo.TextAlignment.Vertical := tlCenter;
  Memo.TextAlignment.Horizontal := taCentered;

  // ======== MasterData band ===========
  MasterDataBand := TFPReportDataBand.Create(p);
  MasterDataBand.Layout.Height := 8;
  {$ifdef ColorBands}
  MasterDataBand.Frame.Shape := fsRectangle;
  MasterDataBand.Frame.BackgroundColor := clDataBand;
  {$endif}
  MasterDataBand.Data:=ReportMasterData;

  Memo := TFPReportMemo.Create(MasterDataBand);
  Memo.Layout.Left := 5;
  Memo.Layout.Top := 2;
  Memo.Layout.Width := 50;
  Memo.Layout.Height := 5;
  Memo.Text := '[reportmasterdata.proj_id] - [reportmasterdata.proj_name]';
  Memo.TextAlignment.Vertical := tlCenter;
  Memo.Frame.Shape := fsRectangle;
  Memo.Frame.BackgroundColor := clLtGray;

  // ======== DataHeader band for DetailData ===========
  DataHeader := TFPReportDataHeaderBand.Create(p);
  DataHeader.Layout.Height := 8;
  {$ifdef ColorBands}
  DataHeader.Frame.Shape := fsRectangle;
  DataHeader.Frame.BackgroundColor := clDataHeaderFooter;
  {$endif}
  DataHeader.Data:=ReportDetailData;

  Memo := TFPReportMemo.Create(DataHeader);
  Memo.Layout.Left := 15;
  Memo.Layout.Top := 3;
  Memo.Layout.Width := 15;
  Memo.Layout.Height := 5;
  Memo.Text := 'Emp No.';
  Memo.TextAlignment.Vertical := tlCenter;
  Memo.Options := [moDisableWordWrap];
  Memo.Frame.Shape := fsRectangle;
  Memo.Frame.Color := clBlack;
  Memo.Frame.BackgroundColor := clLtGray;

  Memo := TFPReportMemo.Create(DataHeader);
  Memo.Layout.Left := 30;
  Memo.Layout.Top := 3;
  Memo.Layout.Width := 50;
  Memo.Layout.Height := 5;
  Memo.Text := 'Employee Name';
  Memo.TextAlignment.Vertical := tlCenter;
  Memo.TextAlignment.Horizontal := taCentered;
  Memo.Frame.Shape := fsRectangle;
  Memo.Frame.Color := clBlack;
  Memo.Frame.BackgroundColor := clLtGray;

  // ======== DetailData band ===========
  DetailDataBand := TFPReportDataBand.Create(p);
  DetailDataBand.Layout.Height := 5;
  DetailDataBand.Data := ReportDetailData;
  { associate this band with the MasterData band }
  DetailDataBand.MasterBand := MasterDataBand;
  { associate DataHeader band }
  DetailDataBand.DisplayPosition := 0;
  {$ifdef ColorBands}
  DetailDataBand.Frame.Shape := fsRectangle;
  DetailDataBand.Frame.BackgroundColor := clChildBand;
  {$endif}

  Memo := TFPReportMemo.Create(DetailDataBand);
  Memo.Layout.Left := 15;
  Memo.Layout.Top := 0;
  Memo.Layout.Width := 15;
  Memo.Layout.Height := 5;
  Memo.Text := '[reportdetaildata.emp_no]';
  Memo.TextAlignment.Vertical := tlCenter;
  Memo.Frame.Shape := fsRectangle;
  Memo.Frame.Color := clBlack;

  Memo := TFPReportMemo.Create(DetailDataBand);
  Memo.Layout.Left := 30;
  Memo.Layout.Top := 0;
  Memo.Layout.Width := 50;
  Memo.Layout.Height := 5;
  Memo.Text := '[reportdetaildata.first_name] [reportdetaildata.last_name]';
  Memo.TextAlignment.Vertical := tlCenter;
  Memo.Frame.Shape := fsRectangle;
  Memo.Frame.Color := clBlack;


  // ======== DataHeader band for DetailData ===========
  BudgetDataHeader := TFPReportDataHeaderBand.Create(p);
  BudgetDataHeader.Layout.Height := 8;
  {$ifdef ColorBands}
  BudgetDataHeader.Frame.Shape := fsRectangle;
  BudgetDataHeader.Frame.BackgroundColor := clDataHeaderFooter;
  {$endif}
  BudgetDataHeader.Data:=ReportBudgetData;
   
  Memo := TFPReportMemo.Create(BudgetDataHeader);
  Memo.Layout.Left := 15;
  Memo.Layout.Top := 3;
  Memo.Layout.Width := 15;
  Memo.Layout.Height := 5;
  Memo.Text := 'Year';
  Memo.TextAlignment.Vertical := tlCenter;
  Memo.TextAlignment.Horizontal := taCentered;
  Memo.Frame.Shape := fsRectangle;
  Memo.Frame.Color := clBlack;
  Memo.Frame.BackgroundColor := clLtGray;

  Memo := TFPReportMemo.Create(BudgetDataHeader);
  Memo.Layout.Left := 30;
  Memo.Layout.Top := 3;
  Memo.Layout.Width := 50;
  Memo.Layout.Height := 5;
  Memo.Text := 'Budget';
  Memo.TextAlignment.Vertical := tlCenter;
  Memo.TextAlignment.Horizontal := taCentered;
  Memo.Frame.Shape := fsRectangle;
  Memo.Frame.Color := clBlack;
  Memo.Frame.BackgroundColor := clLtGray;


  // ======== Project Budget band ===========
  ProjBudgetBand := TFPReportDataBand.Create(p);
  ProjBudgetBand.Layout.Height := 5;
  ProjBudgetBand.Data := ReportBudgetData;
  { associate this band with the MasterData band }
  ProjBudgetBand.MasterBand := MasterDataBand;
  ProjBudgetBand.DisplayPosition := 1;
  {$ifdef ColorBands}
  ProjBudgetBand.Frame.Shape := fsRectangle;
  ProjBudgetBand.Frame.BackgroundColor := clChildBand;
  {$endif}

  Memo := TFPReportMemo.Create(ProjBudgetBand);
  Memo.Layout.Left := 15;
  Memo.Layout.Top := 0;
  Memo.Layout.Width := 15;
  Memo.Layout.Height := 5;
  Memo.Text := '[ReportBudgetData.FISCAL_YEAR]';
  Memo.TextAlignment.Vertical := tlCenter;
  Memo.TextAlignment.Horizontal := taCentered;
  Memo.Frame.Shape := fsRectangle;
  Memo.Frame.Color := clBlack;

  Memo := TFPReportMemo.Create(ProjBudgetBand);
  Memo.Layout.Left := 30;
  Memo.Layout.Top := 0;
  Memo.Layout.Width := 50;
  Memo.Layout.Height := 5;
  Memo.Text := '[formatfloat(''#,##0'', ReportBudgetData.PROJECTED_BUDGET)]';
  Memo.TextAlignment.Vertical := tlCenter;
  Memo.TextAlignment.Horizontal := taRightJustified;
  Memo.Frame.Shape := fsRectangle;
  Memo.Frame.Color := clBlack;
end;

procedure TMasterDetailDatasetDemo.InitialiseData;
begin
  SQLTransaction1 := TSQLTransaction.Create(Self);

  IBConnection1 := TIBConnection.Create(Self);
  with IBConnection1 do
  begin
    LoginPrompt := False;
    DatabaseName := cDatabase;
    KeepConnection := False;
    Password := 'masterkey';
    Transaction := SQLTransaction1;
    UserName := 'sysdba';
    Connected := True;
  end;

  qryProject := TSQLQuery.Create(Self);
  with qryProject do
  begin
    Database := IBConnection1;
    Transaction := SQLTransaction1;
    ReadOnly := True;
    SQL.Text := 'select * from PROJECT order by PROJ_NAME';
    Active := True
  end;

  ProjectDS := TDataSource.Create(Self);
  ProjectDS.DataSet := qryProject;

  qryEmployee := TSQLQuery.Create(Self);
  with qryEmployee do
  begin
    Database := IBConnection1;
    Transaction := SQLTransaction1;
    ReadOnly := True;
    SQL.Text :=
          'SELECT ' +
          '  e.* ' +
          'FROM EMPLOYEE e ' +
          '  INNER JOIN EMPLOYEE_PROJECT ep on e.EMP_NO = ep.EMP_NO ' +
          'where ep.proj_id = :proj_id ' +
          'order by e.EMP_NO';
    DataSource := ProjectDS;
    Active := True
  end;

  qryProjBudget := TSQLQuery.Create(Self);
  with qryProjBudget do
  begin
    Database := IBConnection1;
    Transaction := SQLTransaction1;
    ReadOnly := True;
    SQL.Text :=
          'SELECT ' +
          '  b.FISCAL_YEAR, b.PROJECTED_BUDGET ' +
          'FROM PROJ_DEPT_BUDGET b ' +
          'where b.proj_id = :proj_id ' +
          'order by b.FISCAL_YEAR';
    DataSource := ProjectDS;
    Active := True
  end;

  ReportMasterData.DataSet:= qryProject;
  ReportDetailData.DataSet:= qryEmployee;
  ReportBudgetData.DataSet:= qryProjBudget;
  rpt.ReportData.AddReportData(ReportMasterData);
  rpt.ReportData.AddReportData(ReportDetailData);
  rpt.ReportData.AddReportData(ReportBudgetData);
end;

constructor TMasterDetailDatasetDemo.Create(AOwner: TComponent);
begin
  Inherited;
  ReportMasterData := TFPReportDatasetData.Create(Self);
  ReportMasterData.Name := 'ReportMasterData';
  ReportDetailData := TFPReportDatasetData.Create(Self);
  ReportDetailData.Name := 'ReportDetailData';
  ReportBudgetData := TFPReportDatasetData.Create(Self);
  ReportBudgetData.Name := 'ReportBudgetData';
end;

destructor TMasterDetailDatasetDemo.Destroy;
begin
  IBConnection1.Close();
  FreeAndNil(qryEmployee);
  FreeAndNil(qryProject);
  FreeAndNil(ReportMasterData);
  FreeAndNil(ReportDetailData);
  FreeAndNil(ReportBudgetData);
  FreeAndNil(ProjectDS);
  FreeAndNil(SQLTransaction1);
  FreeAndNil(IBConnection1);
  inherited Destroy;
end;

class function TMasterDetailDatasetDemo.Description: string;
begin
  Result:='Demo for support of master-detail relations with datasets';
end;



end.

