unit ProjGather;

interface

uses
  Classes, ProjGatherTree, GatherProjInfo, ProjectData, BillsTree, CalcData;

type
  TProjGather = class;
  TWriteGatherData = procedure (AGather: TProjGather) of Object;

  TProjGather = class
  private
    FWriter: TWriteGatherData;
    FXmjCompare: Integer;
    FGclCompare: Integer;

    FTree: TProjGatherTree;
    FProjs: TList;

    FProjectData: TProjectData;

    procedure OpenProjectData(AProj: TGatherProjInfo);
    procedure FreeProjectData;

    function FindBillsNode(ANode: TBillsIDTreeNode; AParent: TProjGatherTreeNode): TProjGatherTreeNode;
    function CreateBillsNode(ANode: TBillsIDTreeNode; AParent: TProjGatherTreeNode): TProjGatherTreeNode;
    procedure AddProjCalcData(AProjCalc: TProjCalc; ANode: TBillsIDTreeNode);
    function GatherBillsNode(ANode: TBillsIDTreeNode; AParent: TProjGatherTreeNode;
      AProjIndex: Integer): TProjGatherTreeNode;
    procedure GatherBills(ANode: TBillsIDTreeNode; AParent: TProjGatherTreeNode; AProjIndex: Integer);

    procedure GatherProj(AProj: TGatherProjInfo; AProjIndex: Integer);
  public
    constructor Create(AWriter: TWriteGatherData; AXmjCompare, AGclCompare: Integer);
    destructor Destroy; override;

    procedure Gather(AProjs: TList);

    property Projs: TList read FProjs;
    property Tree: TProjGatherTree read FTree;
  end;

implementation

uses
  Globals, UtilMethods, sdIDTree, sdDB, mDataRecord, BillsMeasureDm;

{ TProjGather }

procedure TProjGather.AddProjCalcData(AProjCalc: TProjCalc;
  ANode: TBillsIDTreeNode);
var
  StageRec: TStageRecord;
begin
  AProjCalc.Compile.Org.AddQuantity(ANode.Rec.OrgQuantity.AsFloat);
  AProjCalc.Compile.Org.AddTotalPrice(ANode.Rec.OrgTotalPrice.AsFloat);
  AProjCalc.Compile.Mis.AddQuantity(ANode.Rec.MisQuantity.AsFloat);
  AProjCalc.Compile.Mis.AddTotalPrice(ANode.Rec.MisTotalPrice.AsFloat);
  AProjCalc.Compile.Oth.AddQuantity(ANode.Rec.OthQuantity.AsFloat);
  AProjCalc.Compile.Oth.AddTotalPrice(ANode.Rec.OthTotalPrice.AsFloat);
  AProjCalc.Compile.SubTotal.AddQuantity(ANode.Rec.Quantity.AsFloat);
  AProjCalc.Compile.SubTotal.AddTotalPrice(ANode.Rec.TotalPrice.AsFloat);

  AProjCalc.AddMeasure.Deal.AddQuantity(ANode.Rec.AddDealQuantity.AsFloat);
  AProjCalc.AddMeasure.Deal.AddTotalPrice(ANode.Rec.AddDealTotalPrice.AsFloat);
  AProjCalc.AddMeasure.Qc.AddQuantity(ANode.Rec.AddQcQuantity.AsFloat);
  AProjCalc.AddMeasure.Qc.AddTotalPrice(ANode.Rec.AddQcTotalPrice.AsFloat);
  AProjCalc.AddMeasure.Gather.AddQuantity(ANode.Rec.AddGatherQuantity.AsFloat);
  AProjCalc.AddMeasure.Gather.AddTotalPrice(ANode.Rec.AddGatherTotalPrice.AsFloat);

  AProjCalc.DgnQuantity1 := AProjCalc.DgnQuantity1 + ANode.Rec.DgnQuantity1.AsFloat;
  AProjCalc.DgnQuantity2 := AProjCalc.DgnQuantity2 + ANode.Rec.DgnQuantity2.AsFloat;
  AProjCalc.DealDgnQuantity1 := AProjCalc.DealDgnQuantity1 + ANode.Rec.DealDgnQuantity1.AsFloat;
  AProjCalc.DealDgnQuantity2 := AProjCalc.DealDgnQuantity2 + ANode.Rec.DealDgnQuantity2.AsFloat;
  AProjCalc.CDgnQuantity1 := AProjCalc.CDgnQuantity1 + ANode.Rec.CDgnQuantity1.AsFloat;
  AProjCalc.CDgnQuantity2 := AProjCalc.CDgnQuantity2 + ANode.Rec.CDgnQuantity2.AsFloat;

  StageRec := ANode.StageRec;
  if Assigned(StageRec) then
  begin
    AProjCalc.CurMeasure.Deal.AddQuantity(StageRec.DealQuantity.AsFloat);
    AProjCalc.CurMeasure.Deal.AddTotalPrice(StageRec.DealTotalPrice.AsFloat);
    AProjCalc.CurMeasure.Qc.AddQuantity(StageRec.QcQuantity.AsFloat);
    AProjCalc.CurMeasure.Qc.AddTotalPrice(StageRec.QcTotalPrice.AsFloat);
    AProjCalc.CurMeasure.Gather.AddQuantity(StageRec.GatherQuantity.AsFloat);
    AProjCalc.CurMeasure.Gather.AddTotalPrice(StageRec.GatherTotalPrice.AsFloat);

    AProjCalc.PreMeasure.Deal.AddQuantity(StageRec.PreDealQuantity.AsFloat);
    AProjCalc.PreMeasure.Deal.AddTotalPrice(StageRec.PreDealTotalPrice.AsFloat);
    AProjCalc.PreMeasure.Qc.AddQuantity(StageRec.PreQcQuantity.AsFloat);
    AProjCalc.PreMeasure.Qc.AddTotalPrice(StageRec.PreQcTotalPrice.AsFloat);
    AProjCalc.PreMeasure.Gather.AddQuantity(StageRec.PreGatherQuantity.AsFloat);
    AProjCalc.PreMeasure.Gather.AddTotalPrice(StageRec.PreGatherTotalPrice.AsFloat);

    AProjCalc.EndMeasure.Deal.AddQuantity(StageRec.EndDealQuantity.AsFloat);
    AProjCalc.EndMeasure.Deal.AddTotalPrice(StageRec.EndDealTotalPrice.AsFloat);
    AProjCalc.EndMeasure.Qc.AddQuantity(StageRec.EndQcQuantity.AsFloat);
    AProjCalc.EndMeasure.Qc.AddTotalPrice(StageRec.EndQcTotalPrice.AsFloat);
    AProjCalc.EndMeasure.Gather.AddQuantity(StageRec.EndGatherQuantity.AsFloat);
    AProjCalc.EndMeasure.Gather.AddTotalPrice(StageRec.EndGatherTotalPrice.AsFloat);    
  end;
end;

constructor TProjGather.Create(AWriter: TWriteGatherData;
  AXmjCompare, AGclCompare: Integer);
begin
  FWriter := AWriter;
  FXmjCompare := AXmjCompare;
  FGclCompare := AGclCompare;
end;

function TProjGather.CreateBillsNode(ANode: TBillsIDTreeNode;
  AParent: TProjGatherTreeNode): TProjGatherTreeNode;
var
  vNextSibling: TProjGatherTreeNode;
begin
  vNextSibling := FTree.FindNextSibling(AParent, ANode.Rec.Code.AsString, ANode.Rec.B_Code.AsString);
  if ANode.ID < 100 then
    Result := FTree.AddNode(AParent, vNextSibling, ANode.ID)
  else
    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.XiangCode := ANode.Rec.XiangCode.AsString;
  Result.MuCode := ANode.Rec.MuCode.AsString;
  Result.JieCode := ANode.Rec.JieCode.AsString;
  Result.XiMuCode := ANode.Rec.XimuCode.AsString;
  Result.IndexCode := ANode.Rec.IndexCode.AsString;
end;

destructor TProjGather.Destroy;
begin

  inherited;
end;

function TProjGather.FindBillsNode(ANode: TBillsIDTreeNode;
  AParent: TProjGatherTreeNode): TProjGatherTreeNode;
var
  iCompareType: Integer;
begin
  if ANode.ID > 100 then
  begin
    if ANode.Rec.B_Code.AsString <> '' then
      iCompareType := FGclCompare
    else
      iCompareType := FXmjCompare;

    case iCompareType of
      // 按编号
      0: if (ANode.Rec.Code.AsString <> '') or (ANode.Rec.B_Code.asString <> '') then
           Result := FTree.FindNode(AParent, ANode.Rec.Code.AsString, ANode.Rec.B_Code.AsString, ANode.Rec.Price.AsFloat)
         else
           Result := FTree.FindNode(AParent, ANode.Rec.Name.AsString, ANode.Rec.Price.AsFloat);
      // 按名称
      1: Result := FTree.FindNode(AParent, ANode.Rec.Name.AsString, ANode.Rec.Price.AsFloat);
      // 按编号+名称
      2: Result := FTree.FindNode(AParent, ANode.Rec.Code.AsString, ANode.Rec.B_Code.AsString, ANode.Rec.Name.AsString, ANode.Rec.Price.AsFloat);
    end;
  end
  else
    Result := FTree.FindNode(ANode.ID);
end;

procedure TProjGather.FreeProjectData;
begin
  if not Assigned(OpenProjectManager.FindProjectData(FProjectData.ProjectID)) then
    FProjectData.Free;
end;

procedure TProjGather.Gather(AProjs: TList);
var
  i: Integer;
begin
  FProjs := AProjs;
  FTree := TProjGatherTree.Create(FProjs.Count);
  FTree.NewNodeID := 101;
  try
    for i := 0 to FProjs.Count - 1 do
      GatherProj(TGatherProjInfo(FProjs.Items[i]), i);
    FTree.CalculateAll;
    if Assigned(FWriter) then
      FWriter(Self);
  finally
    FTree.Free;
  end;
end;

procedure TProjGather.GatherBills(ANode: TBillsIDTreeNode;
  AParent: TProjGatherTreeNode; AProjIndex: Integer);
var
  vCur: TProjGatherTreeNode;
begin
  if not Assigned(ANode) then Exit;

  vCur := GatherBillsNode(ANode, AParent, AProjIndex);
  GatherBills(TBillsIDTreeNode(ANode.FirstChild), vCur, AProjIndex);
  GatherBills(TBillsIDTreeNode(ANode.NextSibling), AParent, AProjIndex );
end;

function TProjGather.GatherBillsNode(ANode: TBillsIDTreeNode;
  AParent: TProjGatherTreeNode; AProjIndex: Integer): TProjGatherTreeNode;
begin
  Result := FindBillsNode(ANode, AParent);
  if not Assigned(Result) then
    Result := CreateBillsNode(ANode, AParent);
  AddProjCalcData(Result.GatherCalc, ANode);
  AddProjCalcData(Result.Proj[AProjIndex], ANode);
end;

procedure TProjGather.GatherProj(AProj: TGatherProjInfo; AProjIndex: Integer);
begin
  OpenProjectData(AProj);
  try
    with FProjectData.BillsMeasureData do
      GatherBills(TMeasureBillsIDTreeNode(BillsMeasureTree.FirstNode), nil, AProjIndex);
  finally
    FreeProjectData;
  end;
end;

procedure TProjGather.OpenProjectData(AProj: TGatherProjInfo);
begin
  FProjectData := OpenProjectManager.FindProjectData(AProj.ProjectID);
  if not Assigned(FProjectData) then
  begin
    FProjectData := TProjectData.Create;
    FProjectData.OpenForReport3(GetMyProjectsFilePath + AProj.FileName);
  end;
end;

end.
