unit BillsCommand;

interface

uses
  BillsMeasureDm, PhaseData, BillsTree,
  sdDB, Classes, SysUtils;

type
  TBillsCalculate = class
  private
    FBillsMeasureData: TBillsMeasureData;
    FPhaseData: TPhaseData;
    procedure ClearNodeCacheData(ANode: TBillsIDTreeNode);
    procedure ClearCacheData;

    procedure UpdateNodeCacheData(ABillsID: Integer; Rec: TsdDataRecord);
    procedure GatherPhaseData(APhaseData: TPhaseData);
    procedure GatherAllPhaseData;

    procedure WriteNodeGatherData(ANode: TBillsIDTreeNode);
    procedure WriteGatherData;
  public
    constructor Create(ABillsMeasureData: TBillsMeasureData);
    destructor Destroy; override;

    procedure Execute;
  end;

implementation

uses
  ProjectData, StageDm;

{ TBillsCalculate }

procedure TBillsCalculate.ClearCacheData;
begin
  ClearNodeCacheData(TBillsIDTreeNode(FBillsMeasureData.BillsMeasureTree.FirstNode));
end;

procedure TBillsCalculate.ClearNodeCacheData(ANode: TBillsIDTreeNode);
begin
  if not Assigned(ANode) then Exit;
  ANode.DealQuantity := 0;
  ANode.DealTotalPrice := 0;
  ANode.QcQuantity := 0;
  ANode.QcTotalPrice := 0;
  ANode.PcQuantity := 0;
  ANode.PcTotalPrice := 0;
  ANode.GatherQuantity := 0;
  ANode.GatherTotalPrice := 0;
  ClearNodeCacheData(TBillsIDTreeNode(ANode.FirstChild));
  ClearNodeCacheData(TBillsIDTreeNode(ANode.NextSibling));
end;

constructor TBillsCalculate.Create(ABillsMeasureData: TBillsMeasureData);
begin
  FBillsMeasureData := ABillsMeasureData;
end;

destructor TBillsCalculate.Destroy;
begin
  inherited;
end;

procedure TBillsCalculate.Execute;
begin
  ClearCacheData;
  GatherAllPhaseData;
  WriteGatherData;
end;

procedure TBillsCalculate.GatherAllPhaseData;
var
  iIndex: Integer;
begin
  with TProjectData(FBillsMeasureData.ProjectData) do
    for iIndex :=1 to ProjProperties.PhaseCount do
      if iIndex = PhaseIndex then
        GatherPhaseData(PhaseData)
      else
      begin
        FPhaseData := TPhaseData.Create(FBillsMeasureData.ProjectData);
        try
          FPhaseData.Open(Format('%sPhase%d.dat', [TempPath, iIndex]));
          GatherPhaseData(FPhaseData);
        finally
          FPhaseData.Free;
        end;
      end;
end;

procedure TBillsCalculate.GatherPhaseData(APhaseData: TPhaseData);
var
  iIndex: Integer;
  Rec: TsdDataRecord;
  StageData: TStageData;
  bIsNew: Boolean;
begin
  bIsNew := not APhaseData.IsLastStage;
  if bIsNew then
  begin
    StageData := TStageData.Create(APhaseData);
    StageData.TableName := APhaseData.StageTableName[APhaseData.AuditCount];
    StageData.Open(APhaseData.ADOConnection);
  end
  else
    StageData := APhaseData.StageData;

  try
    if not bIsNew and not APhaseData.PhaseProperty.FinalAudit then
      StageData.CalculateAll;

    for iIndex := 0 to StageData.sddStage.RecordCount - 1 do
    begin
      Rec := StageData.sddStage.Records[iIndex];
      UpdateNodeCacheData(Rec.ValueByName('BillsID').AsInteger, Rec);
    end;
  finally
    if bIsNew then
      StageData.Free;
  end;
end;

procedure TBillsCalculate.UpdateNodeCacheData(ABillsID: Integer; Rec: TsdDataRecord);
var
  vNode: TBillsIDTreeNode;
begin
  vNode := TBillsIDTreeNode(FBillsMeasureData.BillsMeasureTree.FindNode(ABillsID));
  if not Assigned(vNode) then Exit;
  if not vNode.HasChildren then
  begin
    vNode.DealQuantity := vNode.DealQuantity + Rec.ValueByName('DealQuantity').AsFloat;
    vNode.QcQuantity := vNode.QcQuantity + Rec.ValueByName('QcQuantity').AsFloat;
    vNode.PcQuantity := vNode.PcQuantity + Rec.ValueByName('PcQuantity').AsFloat;
  end;
  vNode.GatherQuantity := vNode.GatherQuantity + Rec.ValueByName('DealQuantity').AsFloat
                        + Rec.ValueByName('QcQuantity').AsFloat;
  vNode.DealTotalPrice := vNode.DealTotalPrice + Rec.ValueByName('DealTotalPrice').AsFloat;
  vNode.QcTotalPrice := vNode.QcTotalPrice + Rec.ValueByName('QcTotalPrice').AsFloat;
  vNode.PcTotalPrice := vNode.PcTotalPrice + Rec.ValueByName('PcTotalPrice').AsFloat;
  vNode.GatherTotalPrice := vNode.GatherTotalPrice + Rec.ValueByName('DealTotalPrice').AsFloat
                          + Rec.ValueByName('QcTotalPrice').AsFloat
                          + Rec.ValueByName('PcTotalPrice').AsFloat;
  //UpdateNodeCacheData(vNode.ParentID, Rec);
end;

procedure TBillsCalculate.WriteGatherData;
begin
  WriteNodeGatherData(TBillsIDTreeNode(FBillsMeasureData.BillsMeasureTree.FirstNode));
end;

procedure TBillsCalculate.WriteNodeGatherData(ANode: TBillsIDTreeNode);
begin
  if not Assigned(ANode) then Exit;
  ANode.Rec.ValueByName('AddDealQuantity').AsFloat := ANode.DealQuantity;
  ANode.Rec.ValueByName('AddDealTotalPrice').AsFloat := ANode.DealTotalPrice;
  ANode.Rec.ValueByName('AddQcQuantity').AsFloat := ANode.QcQuantity;
  ANode.Rec.ValueByName('AddQcTotalPrice').AsFloat := ANode.QcTotalPrice;
  ANode.Rec.ValueByName('AddPcQuantity').AsFloat := ANode.PcQuantity;
  ANode.Rec.ValueByName('AddPcTotalPrice').AsFloat := ANode.PcTotalPrice;
  ANode.Rec.ValueByName('AddGatherQuantity').AsFloat := ANode.GatherQuantity;
  ANode.Rec.ValueByName('AddGatherTotalPrice').AsFloat := ANode.GatherTotalPrice;
  WriteNodeGatherData(TBillsIDTreeNode(ANode.FirstChild));
  WriteNodeGatherData(TBillsIDTreeNode(ANode.NextSibling));
end;

end.
