unit CheckAndClearFrm;

interface

uses
  BillsCompileDm, ZhAPI, sdIDTree, sdDB,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ZJGrid, StdCtrls, ExtCtrls, ZJCells;

type
  TNodeData = class
  private
    FID: Integer;
    FB_Code: string;
    FName: string;
    FUnits: string;
    FPrice: Double;
    FQuantity: Double;
  end;

  TCheckAndClearForm = class(TForm)
    pnlSearch: TPanel;
    cbUnits: TCheckBox;
    cbPrice: TCheckBox;
    cbQuantity: TCheckBox;
    btnSearch: TButton;
    pnlResult: TPanel;
    zgSearchResult: TZJGrid;
    pnlClear: TPanel;
    cbSelectAll: TCheckBox;
    btnDelete: TButton;
    procedure btnSearchClick(Sender: TObject);
    procedure zgSearchResultMouseDown(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure zgSearchResultCellCanEdit(Sender: TObject;
      const ACoord: TPoint; var Allow: Boolean);
    procedure btnDeleteClick(Sender: TObject);
    procedure cbSelectAllClick(Sender: TObject);
  private
    FBillsCompileData: TBillsCompileData;
    FResults: TList;

    procedure InitResultGrid;

    procedure FilterResult(ANode: TsdIDTreeNode);
    procedure FilterResults(ANode: TsdIDTreeNode);
    procedure SearchResults;
    procedure DisplayResults;

    procedure SelectAllorNot(ASelect: Boolean);

    procedure DeleteAllResults;
    procedure DeleteSelectResults;
  public
    constructor Create(ABillsCompileData: TBillsCompileData);
    destructor Destroy; override;
  end;

procedure ShowCheckAndClearForm(ABillsCompileData: TBillsCompileData);

implementation

{$R *.dfm}

procedure ShowCheckAndClearForm(ABillsCompileData: TBillsCompileData);
var
  CheckClearForm: TCheckAndClearForm;
begin
  CheckClearForm := TCheckAndClearForm.Create(ABillsCompileData);
  try
    CheckClearForm.ShowModal; 
  finally
    CheckClearForm.Free;
  end;
end;

{ TForm1 }

constructor TCheckAndClearForm.Create(ABillsCompileData: TBillsCompileData);
begin
  inherited Create(nil);
  FBillsCompileData := ABillsCompileData;
  FResults := TList.Create;
  InitResultGrid;
end;

destructor TCheckAndClearForm.Destroy;
begin
  ClearObjects(FResults);
  FResults.Free;
  inherited;
end;

procedure TCheckAndClearForm.DisplayResults;
var
  i: Integer;
  ResultNode: TNodeData;
begin
  zgSearchResult.RowCount := FResults.Count + 1;
  for i := 0 to FResults.Count - 1 do
  begin
    ResultNode := TNodeData(FResults.Items[i]);
    zgSearchResult.Cells[1, i+1].Text := 'False';
    zgSearchResult.Cells[2, i+1].Text := ResultNode.FB_Code;
    zgSearchResult.Cells[2, i+1].Align := gaCenterLeft;
    zgSearchResult.Cells[3, i+1].Text := ResultNode.FName;
    zgSearchResult.Cells[3, i+1].Align := gaCenterLeft;
    zgSearchResult.Cells[4, i+1].Text := ResultNode.FUnits;
    zgSearchResult.Cells[4, i+1].Align := gaCenterCenter;
    zgSearchResult.Cells[5, i+1].Text := FloatToStr(ResultNode.FPrice);
    zgSearchResult.Cells[5, i+1].Align := gaCenterRight;
    zgSearchResult.Cells[6, i+1].Text := FloatToStr(ResultNode.FQuantity);
    zgSearchResult.Cells[6, i+1].Align := gaCenterRight;
    zgSearchResult.Rows[i+1].Data := ResultNode;
  end;
end;

procedure TCheckAndClearForm.FilterResults(ANode: TsdIDTreeNode);
begin
  if not Assigned(ANode) then Exit;
  if ANode.HasChildren then
    FilterResults(ANode.FirstChild)
  else
    FilterResult(ANode);
  FilterResults(ANode.NextSibling);
end;

procedure TCheckAndClearForm.InitResultGrid;
begin
  zgSearchResult.ColCount := 7;
  zgSearchResult.Cells[1, 0].Text := '选择';
  zgSearchResult.Cells[1, 0].Align := gaCenterCenter;
  zgSearchResult.ColWidths[1] := 35;
  zgSearchResult.CellClass.Cols[1] := TZjCheckBoxCell;
  zgSearchResult.Cells[2, 0].Text := '清单编号';
  zgSearchResult.Cells[2, 0].Align := gaCenterCenter;
  zgSearchResult.ColWidths[2] := 80;
  zgSearchResult.Cells[3, 0].Text := '名称';
  zgSearchResult.Cells[3, 0].Align := gaCenterCenter;
  zgSearchResult.ColWidths[3] := 120;
  zgSearchResult.Cells[4, 0].Text := '单位';
  zgSearchResult.Cells[4, 0].Align := gaCenterCenter;
  zgSearchResult.ColWidths[4] := 40;
  zgSearchResult.Cells[5, 0].Text := '单价';
  zgSearchResult.Cells[5, 0].Align := gaCenterCenter;
  zgSearchResult.ColWidths[5] := 60;
  zgSearchResult.Cells[6, 0].Text := '数量';
  zgSearchResult.Cells[6, 0].Align := gaCenterCenter;
  zgSearchResult.ColWidths[6] := 60;
end;

procedure TCheckAndClearForm.SearchResults;
begin
  if cbUnits.Checked or cbPrice.Checked or cbQuantity.Checked then
  begin
    ClearObjects(FResults);
    FilterResults(FBillsCompileData.BillsCompileTree.FirstNode);
    DisplayResults;
  end;
end;

procedure TCheckAndClearForm.btnSearchClick(Sender: TObject);
begin
  SearchResults;
  cbSelectAll.Checked := False;
end;

procedure TCheckAndClearForm.FilterResult(ANode: TsdIDTreeNode);

  function CheckCondition(ARec: TsdDataRecord): Boolean;
  begin
    Result := (not cbUnits.Checked or (ARec.ValueByName('Units').AsString = ''))
          and (not cbPrice.Checked or (ARec.ValueByName('Price').AsFloat = 0))
          and (not cbQuantity.Checked or (ARec.ValueByName('Quantity').AsFloat = 0));
  end;

var
  ResultNode: TNodeData;
begin
  if CheckCondition(ANode.Rec) and FBillsCompileData.BillsCompileTree.CanDelete(ANode) then
  begin
    ResultNode := TNodeData.Create;
    ResultNode.FID := ANode.ID;
    ResultNode.FB_Code := ANode.Rec.ValueByName('B_Code').AsString;
    ResultNode.FName := ANode.Rec.ValueByName('Name').AsString;
    ResultNode.FUnits := ANode.Rec.ValueByName('Units').AsString;
    ResultNode.FPrice := ANode.Rec.ValueByName('Price').AsFloat;
    ResultNode.FQuantity := ANode.Rec.ValueByName('Quantity').AsFloat;
    FResults.Add(ResultNode);
  end;
end;

procedure TCheckAndClearForm.zgSearchResultMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  ResultNode: TNodeData;
  BillsNode: TsdIDTreeNode;
begin
  if (ssDouble in Shift) and (zgSearchResult.CurRow > 0) and (zgSearchResult.CurCol > 1) then
  begin
    ResultNode := TNodeData(zgSearchResult.Rows[zgSearchResult.CurRow].Data);
    BillsNode := FBillsCompileData.BillsCompileTree.FindNode(ResultNode.FID);
    FBillsCompileData.sdvBillsCompile.LocateInControl(BillsNode.Rec);
  end;
end;

procedure TCheckAndClearForm.zgSearchResultCellCanEdit(Sender: TObject;
  const ACoord: TPoint; var Allow: Boolean);
begin
  if (ACoord.X = 1) and (ACoord.Y > 0) then
    Allow := True
  else
    Allow := False;
end;

procedure TCheckAndClearForm.btnDeleteClick(Sender: TObject);
begin
  DeleteSelectResults;
  DisplayResults;
end;

procedure TCheckAndClearForm.DeleteAllResults;
var
  i: Integer;
  ResultNode: TNodeData;
  BillsNode: TsdIDTreeNode;
begin
  for i := 0 to FResults.Count - 1 do
  begin
    ResultNode := TNodeData(FResults.Items[i]);
    BillsNode := FBillsCompileData.BillsCompileTree.FindNode(ResultNode.FID);
    if FBillsCompileData.BillsCompileTree.CanDelete(BillsNode) then
      FBillsCompileData.BillsCompileTree.DeleteNode(BillsNode);
  end;
  ClearObjects(FResults);
end;

procedure TCheckAndClearForm.cbSelectAllClick(Sender: TObject);
begin
  SelectAllorNot(TCheckBox(Sender).Checked);
end;

procedure TCheckAndClearForm.SelectAllorNot(ASelect: Boolean);
var
  iRow: Integer;
begin
  for iRow := 1 to zgSearchResult.RowCount - 1 do
  begin
    if ASelect then
      zgSearchResult.Cells[1, iRow].Text := 'True'
    else
      zgSearchResult.Cells[1, iRow].Text := 'False';
  end;
end;

procedure TCheckAndClearForm.DeleteSelectResults;
var
  iRow: Integer;
  ResultNode: TNodeData;
  BillsNode: TsdIDTreeNode;
begin
  for iRow := 1 to zgSearchResult.RowCount - 1 do
  begin
    if SameText(zgSearchResult.Cells[1, iRow].Text, 'True') then
    begin
      ResultNode := TNodeData(zgSearchResult.Rows[iRow].Data);
      BillsNode := FBillsCompileData.BillsCompileTree.FindNode(ResultNode.FID);
      if FBillsCompileData.BillsCompileTree.CanDelete(BillsNode) then
        FBillsCompileData.BillsCompileTree.DeleteNode(BillsNode);
      FResults.Remove(ResultNode);
      ResultNode.Free;
    end;
  end;
end;

end.
