unit ProjGatherDealPay;

interface

uses
  Classes, sdDB;

type
  TDealPayCalcData = class
  private
    FCurTotalPrice: Double;
    FPreTotalPrice: Double;
    FEndTotalPrice: Double;
    FAddTotalPrice: Double;

    FZoneTotalPrice: Double;
  public
    property CurTotalPrice: Double read FCurTotalPrice write FCurTotalPrice;
    property PreTotalPrice: Double read FPreTotalPrice write FPreTotalPrice;
    property EndTotalPrice: Double read FEndTotalPrice write FEndTotalPrice;
    property AddTotalPrice: Double read FAddTotalPrice write FAddTotalPrice;

    property ZoneTotalPrice: Double read FZoneTotalPrice write FZoneTotalPrice;
  end;

  TProjGatherDealPayNode = class
  private
    FID: Integer;
    FName: string;
    FCalcType: Integer;
    FIsMinus: Boolean;

    FSerialNo: Integer;
    FLinkSerialNo: Integer;

    FGatherCalc: TDealPayCalcData;
    FProjs: TList;
    FSpecialProjs: TList;
    function GetProj(AIndex: Integer): TDealPayCalcData;
    function GetProjCount: Integer;
    function GetSpecialProjCount: Integer;
    function GetSpecialProj(AIndex: Integer): TDealPayCalcData;
  public
    constructor Create(AID: Integer; AProjCount, ASpeicalProjCount: Integer);
    destructor Destroy; override;

    property ID: Integer read FID;
    property Name: string read FName;
    property CalcType: Integer read FCalcType;
    property IsMinus: Boolean read FIsMinus;

    property SerialNo: Integer read FSerialNo;
    property LinkSerialNo: Integer read FLinkSerialNo;

    property GatherCalc: TDealPayCalcData read FGatherCalc;

    property ProjCount: Integer read GetProjCount;
    property Proj[AIndex: Integer]: TDealPayCalcData read GetProj;

    property SpecialProjCount: Integer read GetSpecialProjCount;
    property SpecialProj[AIndex: Integer]: TDealPayCalcData read GetSpecialProj;
  end;

  TProjGatherDealPayList = class
  private
    FProjCount: Integer;
    FSpecialProjCount: Integer;

    FNewID: Integer;

    FList: TList;

    function FindDealPayNode(ARec: TsdDataRecord): TProjGatherDealPayNode;
    function CreateDealPayNode(ARec: TsdDataRecord): TProjGatherDealPayNode;

    function GetCount: Integer;
    function GetDealPay(AIndex: Integer): TProjGatherDealPayNode;
  public
    constructor Create(AProjCount, ASpeicalProjCount: Integer);
    destructor Destroy; override;

    function GetDealPayNode(ARec: TsdDataRecord): TProjGatherDealPayNode;

    procedure UpdateLinkSerialNo;

    property DealPay[AIndex: Integer]: TProjGatherDealPayNode read GetDealPay;
    property Count: Integer read GetCount;
  end;

implementation

uses
  ZhAPI, SysUtils;

{ TProjGatherDealPayNode }

constructor TProjGatherDealPayNode.Create(AID: Integer; AProjCount,
  ASpeicalProjCount: Integer);
var
  i: Integer;
  DealPayCalc: TDealPayCalcData;
begin
  FID := AID;

  FGatherCalc :=  TDealPayCalcData.Create;
  FProjs := TList.Create;
  for i := 0 to AProjCount - 1 do
  begin
    DealPayCalc := TDealPayCalcData.Create;
    FProjs.Add(DealPayCalc);
  end;
  FSpecialProjs := TList.Create;
  for i := 0 to ASpeicalProjCount - 1 do
  begin
    DealPayCalc := TDealPayCalcData.Create;
    FSpecialProjs.Add(DealPayCalc);
  end;
end;

destructor TProjGatherDealPayNode.Destroy;
begin
  FGatherCalc.Free;
  ClearObjects(FSpecialProjs);
  FSpecialProjs.Free;
  ClearObjects(FProjs);
  FProjs.Free;
  inherited;
end;

function TProjGatherDealPayNode.GetProj(AIndex: Integer): TDealPayCalcData;
begin
  Result := TDealPayCalcData(FProjs.Items[AIndex]);
end;

function TProjGatherDealPayNode.GetProjCount: Integer;
begin
  Result := FProjs.Count;
end;

function TProjGatherDealPayNode.GetSpecialProj(
  AIndex: Integer): TDealPayCalcData;
begin
  Result := TDealPayCalcData(FProjs.Items[AIndex]);
end;

function TProjGatherDealPayNode.GetSpecialProjCount: Integer;
begin
  Result := FSpecialProjs.Count;
end;

{ TProjGatherDealPayList }

constructor TProjGatherDealPayList.Create(AProjCount,
  ASpeicalProjCount: Integer);
begin
  FProjCount := AProjCount;
  FSpecialProjCount := ASpeicalProjCount;
  FList := TList.Create;
  FNewID := 1;
end;

function TProjGatherDealPayList.CreateDealPayNode(ARec: TsdDataRecord): TProjGatherDealPayNode;
begin
  Result := TProjGatherDealPayNode.Create(FNewID, FProjCount, FSpecialProjCount);
  Inc(FNewID);
  Result.FName := ARec.ValueByName('Name').AsString;
  Result.FCalcType := ARec.ValueByName('CalcType').AsInteger;
  Result.FIsMinus := ARec.ValueByName('IsMinus').AsBoolean;
  Result.FSerialNo := Result.ID;
  FList.Add(Result); 
end;

destructor TProjGatherDealPayList.Destroy;
begin
  ClearObjects(FList);
  FList.Free;
  inherited;
end;

function TProjGatherDealPayList.FindDealPayNode(ARec: TsdDataRecord): TProjGatherDealPayNode;
var
  iDeal: Integer;
  vDeal: TProjGatherDealPayNode;
begin
  Result := nil;
  for iDeal := 0 to FList.Count - 1 do
  begin
    vDeal := DealPay[iDeal];
    if ARec.ValueByName('CalcType').AsInteger in [0, 3] then
    begin
      if SameText(vDeal.Name, ARec.ValueByName('Name').AsString) and
         (vDeal.IsMinus = ARec.ValueByName('IsMinus').AsBoolean) and
         (vDeal.CalcType = ARec.ValueByName('CalcType').AsInteger) then
      begin
        Result := vDeal;
        Break;
      end;
    end
    else
    begin
      if vDeal.CalcType = ARec.ValueByName('CalcType').AsInteger then
      begin
        Result := vDeal;
        Break;
      end;
    end;
  end;
end;

function TProjGatherDealPayList.GetCount: Integer;
begin
  Result := FList.Count;
end;

function TProjGatherDealPayList.GetDealPay(AIndex: Integer): TProjGatherDealPayNode;
begin
  Result := TProjGatherDealPayNode(FList.Items[AIndex]);
end;

function TProjGatherDealPayList.GetDealPayNode(ARec: TsdDataRecord): TProjGatherDealPayNode;
begin
  Result := FindDealPayNode(ARec);
  if not Assigned(Result) then
    Result := CreateDealPayNode(ARec);
end;

procedure TProjGatherDealPayList.UpdateLinkSerialNo;
var
  iPay, iCut, iIndex: Integer;
  vDealPay: TProjGatherDealPayNode;
begin
  iPay := 1;
  iCut := 1;
  for iIndex := 0 to Count - 1 do
  begin
    vDealPay := DealPay[iIndex];
    if vDealPay.CalcType in [0, 3] then
    begin
      if vDealPay.IsMinus then
      begin
        vDealPay.FLinkSerialNo := iCut;
        Inc(iCut);
      end
      else
      begin
        vDealPay.FLinkSerialNo := iPay;
        Inc(iPay);
      end;
    end;
  end;
end;

end.
