unit tpBaseGatherData;

interface

uses
  Classes, tpGatherTree, tpPeg, BillsTree, tpSelectTenderNode,
  ProjectData, tpNoPegDm;

type
  TtpBaseGatherData = class
  private
    FTree: TtpGatherTree;
    FPegs: TtpPegList;

    FNoPegTree: TtpGatherTree;
    FNoPegData: TtpNoPegData;

    function AddBillsNode(ANode: TBillsIDTreeNode; AParent: TtpGatherTreeNode): TtpGatherTreeNode;
    procedure CheckPeg(ANode: TtpGatherTreeNode);
    procedure AddBills(ANode: TBillsIDTreeNode; AParent: TtpGatherTreeNode);
    procedure GatherTender(ATender: TtpSelectTenderNode);

    function AddNoPegTreeNode(AOrgNode, AParent: TtpGatherTreeNode): TtpGatherTreeNode;
    procedure FilterNoPegTreeNode(AOrgNode, AParent: TtpGatherTreeNode);
    procedure FilterNoPegTree;
  public
    constructor Create;
    destructor Destroy; override;

    procedure GatherTenders(ATenders: TList);

    property Tree: TtpGatherTree read FTree;
    property Pegs: TtpPegList read FPegs;
    property NoPegData: TtpNoPegData read FNoPegData;
  end;

implementation

uses
  ProgressHintFrm, mPegFilter, Globals, UtilMethods, Forms, Controls;

{ TtpBaseGatherData }

procedure TtpBaseGatherData.AddBills(ANode: TBillsIDTreeNode;
  AParent: TtpGatherTreeNode);
var
  ACur: TtpGatherTreeNode;
begin
  if not Assigned(ANode) then Exit;

  ACur := AddBillsNode(ANode, AParent);
  CheckPeg(ACur);
  AddBills(TBillsIDTreeNode(ANode.FirstChild), ACur);
  AddBills(TBillsIDTreeNode(ANode.NextSibling), AParent);
end;

function TtpBaseGatherData.AddBillsNode(ANode: TBillsIDTreeNode;
  AParent: TtpGatherTreeNode): TtpGatherTreeNode;
var
  vNextSibling: TtpGatherTreeNode;
  vPeg: TtpPegNode;
begin
  Result := FTree.FindNode(AParent, ANode.Rec);
  if not Assigned(Result) then
  begin
    vNextSibling := FTree.FindNextSibling(AParent, ANode.Rec);
    Result := FTree.AddNode(AParent, vNextSibling);
    Result.Code := ANode.Rec.Code.AsString;
    Result.B_Code := ANode.Rec.B_Code.AsString;
    Result.Name := ANode.Rec.Name.AsString;
    Result.Units := ANode.Rec.Units.AsString;
    Result.Price := ANode.Rec.Price.AsFloat;
    Result.DrawingCode := ANode.Rec.DrawingCode.AsString;
  end;

  Result.Quantity := Result.Quantity + ANode.Rec.Quantity.AsFloat;
  Result.TotalPrice := Result.TotalPrice + ANode.Rec.TotalPrice.AsFloat;
end;

procedure TtpBaseGatherData.CheckPeg(ANode: TtpGatherTreeNode);
var
  vPegNode: TtpPegNode;
begin
  if not Assigned(ANode) then Exit;

  if PegFilter.Filter(ANode.Name) then
  begin
    vPegNode := TtpPegNode.Create(ANode, PegFilter);
    FPegs.AddPegs(vPegNode);
  end;
end;

constructor TtpBaseGatherData.Create;
begin
  FTree := TtpGatherTree.Create;
  FPegs := TtpPegList.Create;
  FNoPegTree := TtpGatherTree.Create;
  FNoPegData := TtpNoPegData.Create;
end;

destructor TtpBaseGatherData.Destroy;
begin
  FNoPegData.Free;
  FNoPegTree.Free;
  FPegs.Free;
  FTree.Free;
  inherited;
end;

procedure TtpBaseGatherData.GatherTenders(ATenders: TList);
var
  iTender: Integer;
  vTender: TtpSelectTenderNode;
begin
  Screen.Cursor := crHourGlass;
  ShowProgressHint('正在汇总项目', ATenders.Count*2);
  try
    FTree.ClearTreeNodes;
    FPegs.Clear;
    for iTender := 0 to ATenders.Count - 1 do
    begin
      vTender := TtpSelectTenderNode(ATenders.Items[iTender]);
      GatherTender(vTender);
    end;
    FPegs.LoadRelaGclNodes;
    FPegs.SortPegs;
    FilterNoPegTree;
  finally
    CloseProgressHint;
    Screen.Cursor := crDefault;
  end;
end;

procedure TtpBaseGatherData.GatherTender(ATender: TtpSelectTenderNode);
var
  vProjectData: TProjectData;

  procedure OpenProject;
  begin
    vProjectData := OpenProjectManager.FindProjectData(ATender.ID);
    if not Assigned(vProjectData) then
    begin
      vProjectData := TProjectData.Create;
      vProjectData.OpenForReport(GetMyProjectsFilePath + ATender.FileName);
    end;
    ATender.NodeCount := vProjectData.BillsCompileData.BillsCompileTree.Count;
  end;

  procedure FreeProject;
  begin
    if not Assigned(OpenProjectManager.FindProjectData(ATender.ID)) then
      vProjectData.Free;
  end;

begin
  try
    UpdateProgressHint('正在打开项目： ' + ATender.Name);
    OpenProject;
    UpdateProgressPosition;

    UpdateProgressHint('正在汇总项目： ' + ATender.Name);
    with vProjectData.BillsCompileData do
      AddBills(TBillsIDTreeNode(BillsCompileTree.FirstNode), nil);
    UpdateProgressPosition;
  finally
    FreeProject;
  end;
end;

procedure TtpBaseGatherData.FilterNoPegTreeNode(
  AOrgNode, AParent: TtpGatherTreeNode);
var
  vCur: TtpGatherTreeNode;
begin
  if not Assigned(AOrgNode) then Exit;

  if not AOrgNode.RelaPeg then
  begin
    vCur := AddNoPegTreeNode(AOrgNode, AParent);
    FilterNoPegTreeNode(TtpGatherTreeNode(AOrgNode.FirstChild), vCur);
  end;
  FilterNoPegTreeNode(TtpGatherTreeNode(AOrgNode.NextSibling), AParent);
end;

function TtpBaseGatherData.AddNoPegTreeNode(AOrgNode,
  AParent: TtpGatherTreeNode): TtpGatherTreeNode;
begin
  Result := FNoPegTree.AddNode(AParent);
  Result.Code := AOrgNode.Code;
  Result.B_Code := AOrgNode.B_Code;
  Result.Name := AOrgNode.Name;
  Result.Units := AOrgNode.Units;
  Result.Price := AOrgNode.Price;
  Result.Quantity := AOrgNode.Quantity;
  Result.TotalPrice := AOrgNode.TotalPrice;
  Result.DgnQuantity1 := AOrgNode.DgnQuantity1;
  Result.DgnQuantity2 := AOrgNode.DgnQuantity2;
  Result.DrawingCode := AOrgNode.DrawingCode;
end;

procedure TtpBaseGatherData.FilterNoPegTree;
begin
  FTree.CheckRelaPeg;
  FilterNoPegTreeNode(TtpGatherTreeNode(FTree.Root.FirstChild), nil);
  FNoPegTree.CalculateAllParent;
  FNoPegData.LoadData(FNoPegTree);
end;

end.
