unit stgGatherGclCacheData;

interface

uses
  CacheTree, SysUtils, BillsTree, Classes, sdDB, mDataRecord;

type
  TstgGclStageData = class
  private
    FDealQuantity: Double;
    FDealTotalPrice: Double;
    FQcQuantity: Double;
    FQcTotalPrice: Double;
    FQcBGLCode: string;
    FQcBGLNum: string;

    procedure AddBGLCodeAndNum(ACode, ANum: string);
  public
    procedure ClearData;
    procedure AddStageData(AStageData: TstgGclStageData);
    procedure AssignedData(AStageRecord: TStageRecord);

    property DealQuantity: Double read FDealQuantity;
    property DealTotalPrice: Double read FDealTotalPrice;
    property QcQuantity: Double read FQcQuantity;
    property QcTotalPrice: Double read FQcTotalPrice;
    property QcBGLCode: string read FQcBGLCode;
    property QcBGLNum: string read FQcBGLNum;
  end;

  TstgGclSubTenderDetailData = class
  private
    FSerialNo: Integer;
    FLeafXmjCode: string;
    FDetailStage: TstgGclStageData;
  public
    constructor Create(ANode: TMeasureBillsIDTreeNode);
    destructor Destroy; override;

    property SerialNo: Integer read FSerialNo;
    property LeafXmjCode: string read FLeafXmjCode;
    property DetailStage: TstgGclStageData read FDetailStage;
  end;

  TstgGclSubTenderStageData = class
  private
    FSubTenderID: Integer;
    FGather: TstgGclStageData;
    FDetails: TList;
    function GetDetail(AIndex: Integer): TstgGclSubTenderDetailData;
    function GetDetailCount: Integer;
  public
    constructor Create(ASubTenderID: Integer);
    destructor Destroy; override;

    function AddDetail(ANode: TMeasureBillsIDTreeNode): TstgGclSubTenderDetailData;

    procedure CalculateGather;

    property SubTenderID: Integer read FSubTenderID;
    property Gather: TstgGclStageData read FGather;
    property DetailCount: Integer read GetDetailCount;
    property Detail[AIndex: Integer]: TstgGclSubTenderDetailData read GetDetail;
  end;

  TstgGatherGcl = class
  private
    FID: Integer;
    FIndexCode: string;
    FB_Code: string;
    FName: string;
    FUnits: string;
    FPrice: Double;

    FGather: TstgGclStageData;
    FSubTenders: TList;
    function GetIsGclBills: Boolean;
    function GetSubTender(AIndex: Integer): TstgGclSubTenderStageData;
    function GetSubTenderCount: Integer;
  public
    constructor Create(AID: Integer; ARec: TBillsRecord);
    destructor Destroy; override;

    function FindSubTender(ASubTenderID: Integer): TstgGclSubTenderStageData;
    function SafeSubTender(ASubTenderID: Integer): TstgGclSubTenderStageData;

    procedure CalculateGather;

    property ID: Integer read FID;
    property B_Code: string read FB_Code;
    property IndexCode: string read FIndexCode;
    property Name: string read FName;
    property Units: string read FUnits;
    property Price: Double read FPrice;

    property SubTenderCount: Integer read GetSubTenderCount;
    property SubTender[AIndex: Integer]: TstgGclSubTenderStageData read GetSubTender;

    property Gather: TstgGclStageData read FGather;
  end;

  TstgGatherGclSubTender = class
  private
    FID: Integer;
    FRec: TsdDataRecord;
  public
    constructor Create(ARec: TsdDataRecord);

    property ID: Integer read FID;
    property Rec: TsdDataRecord read FRec;
  end;

  TstgGatherGclCacheData = class
  private
    FGatherGcls: TList;
    FSubTenders: TList;

    function GetSubTenderCount: Integer;
    function GetSubTender(AIndex: Integer): TstgGatherGclSubTender;
    function GetGatherGcl(AIndex: Integer): TstgGatherGcl;
    function GetGatherGclCount: Integer;
  public
    constructor Create;
    destructor Destroy; override;

    function FindSubTender(AID: Integer): TstgGatherGclSubTender;
    function AddSubTender(ARec: TsdDataRecord): TstgGatherGclSubTender;

    function FindGatherGcl(ARec: TBillsRecord): TstgGatherGcl;
    function AddGatherGcl(ARec: TBillsRecord): TstgGatherGcl;

    procedure CalculateAll;

    property SubTenderCount: Integer read GetSubTenderCount;
    property SubTender[AIndex: Integer]: TstgGatherGclSubTender read GetSubTender;

    property GatherGclCount: Integer read GetGatherGclCount;
    property GatherGcl[AIndex: Integer]: TstgGatherGcl read GetGatherGcl;
  end;

implementation

uses
  ZhAPI, UtilMethods, Math;

{ TstgGatherGcl }

procedure TstgGatherGcl.CalculateGather;
var
  i: Integer;
  vSubTender: TstgGclSubTenderDetailData;
begin
  FGather.ClearData;
  for i := 0 to FSubTenders.Count - 1 do
  begin
    SubTender[i].CalculateGather;
    FGather.AddStageData(SubTender[i].Gather);
  end;
end;

constructor TstgGatherGcl.Create(AID: Integer; ARec: TBillsRecord);
begin
  FSubTenders := TList.Create;
  FGather := TstgGclStageData.Create;

  FID := AID;
  FB_Code := ARec.B_Code.AsString;
  FIndexCode := B_CodeToIndexCode(FB_Code);
  FName := ARec.Name.AsString;
  FUnits := ARec.Units.AsString;
  FPrice := ARec.Price.AsFloat;
end;

destructor TstgGatherGcl.Destroy;
begin
  FGather.Free;
  ClearObjects(FSubTenders);
  FSubTenders.Free;
  inherited;
end;

function TstgGatherGcl.FindSubTender(
  ASubTenderID: Integer): TstgGclSubTenderStageData;
var
  i: Integer;
begin
  Result := nil;
  for i := 0 to FSubTenders.Count - 1 do
  begin
    if ASubTenderID = SubTender[i].SubTenderID then
    begin
      Result := SubTender[i];
      Break;
    end;
  end;
end;

function TstgGatherGcl.GetIsGclBills: Boolean;
begin
  Result := FB_Code <> '';
end;

function TstgGatherGcl.GetSubTender(
  AIndex: Integer): TstgGclSubTenderStageData;
begin
  Result := TstgGclSubTenderStageData(FSubTenders.Items[AIndex]);
end;

function TstgGatherGcl.GetSubTenderCount: Integer;
begin
  Result := FSubTenders.Count;
end;

function TstgGatherGcl.SafeSubTender(
  ASubTenderID: Integer): TstgGclSubTenderStageData;
begin
  Result := FindSubTender(ASubTenderID);
  if not Assigned(Result) then
  begin
    Result := TstgGclSubTenderStageData.Create(ASubTenderID);
    FSubTenders.Add(Result);
  end;
end;

{ TstgGatherGclCacheData }

function TstgGatherGclCacheData.AddGatherGcl(
  ARec: TBillsRecord): TstgGatherGcl;
begin
  Result := FindGatherGcl(ARec);
  if not Assigned(Result) then
  begin
    Result := TstgGatherGcl.Create(GatherGclCount + 1, ARec);
    FGatherGcls.Add(Result);
  end;
end;

function TstgGatherGclCacheData.AddSubTender(
  ARec: TsdDataRecord): TstgGatherGclSubTender;
begin
  Result := FindSubTender(ARec.ValueByName('ID').AsInteger);
  if not Assigned(Result) then
  begin
    Result := TstgGatherGclSubTender.Create(ARec);
    FSubTenders.Add(Result);
  end;
end;

procedure TstgGatherGclCacheData.CalculateAll;
var
  i: Integer;
  vGcl: TstgGatherGcl;
begin
  for i := 0 to GatherGclCount - 1 do
  begin
    vGcl := GatherGcl[i];
    vGcl.CalculateGather;
  end;
end;

constructor TstgGatherGclCacheData.Create;
begin
  FGatherGcls := TList.Create;
  FSubTenders := TList.Create;
end;

destructor TstgGatherGclCacheData.Destroy;
begin
  ClearObjects(FSubTenders);
  FSubTenders.Free;
  ClearObjects(FGatherGcls);
  FGatherGcls.Free;
  inherited;
end;

function TstgGatherGclCacheData.FindGatherGcl(ARec: TBillsRecord): TstgGatherGcl;
var
  i: Integer;
  vGcl: TstgGatherGcl;
  bMatch: Boolean;
begin
  Result := nil;
  for i := 0 to FGatherGcls.Count - 1 do
  begin
    vGcl := TstgGatherGcl(FGatherGcls.Items[i]);
    bMatch := (vGcl.B_Code = ARec.B_Code.AsString) and (vGcl.Name = ARec.Name.AsString)
      and (vGcl.Units = ARec.Units.AsString);
      //and (CommonRoundTo(vGcl.Price - ARec.Price.AsFloat, -6) = 0);
    if bMatch then
    begin
      Result := vGcl;
      Break;
    end;
  end;
end;

function TstgGatherGclCacheData.FindSubTender(
  AID: Integer): TstgGatherGclSubTender;
var
  i: Integer;
begin
  Result := nil;
  for i := 0 to SubTenderCount - 1 do
  begin
    if SubTender[i].ID = AID then
    begin
      Result := SubTender[i];
      Break;
    end;
  end;
end;

function TstgGatherGclCacheData.GetGatherGcl(
  AIndex: Integer): TstgGatherGcl;
begin
  Result := TstgGatherGcl(FGatherGcls.Items[AIndex]);
end;

function TstgGatherGclCacheData.GetGatherGclCount: Integer;
begin
  Result := FGatherGcls.Count;
end;

function TstgGatherGclCacheData.GetSubTender(AIndex: Integer): TstgGatherGclSubTender;
begin
  Result := TstgGatherGclSubTender(FSubTenders.Items[AIndex]);
end;

function TstgGatherGclCacheData.GetSubTenderCount: Integer;
begin
  Result := FSubTenders.Count;
end;

{ TstgGatherGclSubTender }

constructor TstgGatherGclSubTender.Create(ARec: TsdDataRecord);
begin
  FID := ARec.ValueByName('ID').AsInteger;
  FRec := ARec;
end;

{ TstgGclStageData }

procedure TstgGclStageData.AddBGLCodeAndNum(ACode, ANum: string);
var
  sCode, sNum: string;
begin
  sCode := FQcBGLCode;
  sNum := FQcBGLNum;
  MergeRelaBGLAndNum(sCode, sNum, ACode, ANum);
  FQcBGLCode := sCode;
  FQcBGLNum := sNum;
end;

procedure TstgGclStageData.AddStageData(AStageData: TstgGclStageData);
begin
  FDealQuantity := FDealQuantity + AStageData.DealQuantity;
  FDealTotalPrice := FDealTotalPrice + AStageData.DealTotalPrice;
  FQcQuantity := FQcQuantity + AStageData.QcQuantity;
  FQcTotalPrice := FQcTotalPrice + AStageData.QcTotalPrice;
  AddBGLCodeAndNum(AStageData.QcBGLCode, AStageData.QcBGLNum);
end;

procedure TstgGclStageData.AssignedData(AStageRecord: TStageRecord);
begin
  FDealQuantity := AStageRecord.DealQuantity.AsFloat;
  FDealTotalPrice := AStageRecord.DealTotalPrice.AsFloat;
  FQcQuantity := AStageRecord.QcQuantity.AsFloat;
  FQcTotalPrice := AStageRecord.QcTotalPrice.AsFloat;
  FQcBGLCode := AStageRecord.QcBGLCode.AsString;
  FQcBGLNum := AStageRecord.QcBGLNum.AsString;
end;

procedure TstgGclStageData.ClearData;
begin
  FDealQuantity := 0;
  FDealTotalPrice := 0;
  FQcQuantity := 0;
  FQcTotalPrice := 0;
  FQcBGLCode := '';
  FQcBGLNum := '';
end;

{ TstgGclSubTenderStageData }

function TstgGclSubTenderStageData.AddDetail(
  ANode: TMeasureBillsIDTreeNode): TstgGclSubTenderDetailData;
begin
  Result := TstgGclSubTenderDetailData.Create(ANode);
  FDetails.Add(Result);
end;

procedure TstgGclSubTenderStageData.CalculateGather;
var
  i: Integer;
begin
  FGather.ClearData;
  for i := 0 to DetailCount - 1 do
    FGather.AddStageData(Detail[i].DetailStage);
end;

constructor TstgGclSubTenderStageData.Create(ASubTenderID: Integer);
begin
  FSubTenderID := ASubTenderID;
  FGather := TstgGclStageData.Create;
  FDetails := TList.Create;
end;

destructor TstgGclSubTenderStageData.Destroy;
begin
  ClearObjects(FDetails);
  FDetails.Free;
  FGather.Free;
  inherited;
end;

function TstgGclSubTenderStageData.GetDetail(
  AIndex: Integer): TstgGclSubTenderDetailData;
begin
  Result := TstgGclSubTenderDetailData(FDetails.Items[AIndex]);
end;

function TstgGclSubTenderStageData.GetDetailCount: Integer;
begin
  Result := FDetails.Count;
end;

{ TstgGclSubTenderDetailData }

constructor TstgGclSubTenderDetailData.Create(ANode: TMeasureBillsIDTreeNode);
begin
  FSerialNo := ANode.MajorIndex + 1;
  FDetailStage := TstgGclStageData.Create;
  if Assigned(ANode.StageRec) then
    FDetailStage.AssignedData(ANode.StageRec);
end;

destructor TstgGclSubTenderDetailData.Destroy;
begin
  FDetailStage.Free;
  inherited;
end;

end.
