unit PhaseData;

interface

uses
  StageDm, PhasePayDm, ZJJLDm, ADODB, StageCompareDm,
  Connections, UpdateDataBase, UtilMethods, ZhAPI, PhaseProperty,
  Classes, SysUtils, sdDB;

const
  ReferIndex = 0; // 原报序号

type
  TPhaseData = class
  private
    FConnection: TEncryptConnection;
    FUpdator: TUpdatePhaseDB;

    FStageData: TStageData;
    FAuditList: TList;
    FPhaseProperty: TPhaseProperties;
    //FCurStageIndex: Integer;
    FStageIndex: Integer;
    FProjectData: TObject;
    FPhasePayData: TPhasePayData;
    FZJJLData: TZJJLData;

    FStageCompareData: TStageCompareData;

    procedure UpdatePhaseDataBase;

    procedure CopyPreStageData;

    procedure CheckAuditCount;

    function GetFileName: string;
    function GetPhaseIndex: Integer;
    function GetActive: Boolean;
    function GetStageDataReadOnly: Boolean;
    function GetAllowInsert: Boolean;
    function GetmdbFileName: string;
    function GetADOConnection: TADOConnection;
    procedure SetStageIndex(const Value: Integer);
    function GetStageTableName(AIndex: Integer): string;
    function GetAuditCount: Integer;
    function GetStageCount: Integer;
    function GetIsLastStage: Boolean;
  public
    constructor Create(AProjectData: TObject);
    destructor Destroy; override;

    procedure Open(const AProjectName: string);
    procedure Save;
    procedure SaveDebugFile(const AFileName: string);
    {仅打开项目属性}
    procedure SimpleOpen(const AProjectName: string);
    procedure SimpleSave;
    procedure SimpleOpen2(const AProjectName: string);

    procedure CreateNewAuditData;
    procedure CopyPreData;

    property StageIndex: Integer read FStageIndex write SetStageIndex;
    property StageData: TStageData read FStageData;
    property IsLastStage: Boolean read GetIsLastStage;

    // Other
    property PhaseProperty: TPhaseProperties read FPhaseProperty;
    property PhasePayData: TPhasePayData read FPhasePayData;
    property ZJJLData: TZJJLData read FZJJLData;

    property StageCompareData: TStageCompareData read FStageCompareData;

    property StageDataReadOnly: Boolean read GetStageDataReadOnly;
    property AllowInsert: Boolean read GetAllowInsert;

    property PhaseIndex: Integer read GetPhaseIndex;
    property FileName: string read GetFileName;
    property mdbFileName: string read GetmdbFileName;
    property ProjectData: TObject read FProjectData;
    property Active: Boolean read GetActive;
    property ADOConnection: TADOConnection read GetADOConnection;

    property StageTableName[AIndex: Integer]: string read GetStageTableName;
    property AuditCount: Integer read GetAuditCount;
    property StageCount: Integer read GetStageCount;
  end;

implementation

uses
  ProjectData, Globals;

{ TPhaseData }

constructor TPhaseData.Create(AProjectData: TObject);
begin
  FProjectData := AProjectData;
  FConnection := TEncryptConnection.Create;
  FUpdator := TUpdatePhaseDB.Create;
  FStageData := TStageData.Create(Self);
  FPhaseProperty := TPhaseProperties.Create(FConnection.Connection);
  FPhasePayData := TPhasePayData.Create(Self);
  FZJJLData := TZJJLData.Create(Self);

  FStageCompareData := TStageCompareData.Create(Self);
end;

procedure TPhaseData.CreateNewAuditData;
var
  iAuditCount: Integer;
begin
  try
    iAuditCount := FPhaseProperty.AuditCount;
    FPhaseProperty.AuditCount := iAuditCount + 1;
    CopyPreStageData;
    StageIndex := FPhaseProperty.AuditCount;
    PhasePayData.UpdateDataForNewAudit;
  except
    FPhaseProperty.AuditCount := iAuditCount;
  end;
end;

destructor TPhaseData.Destroy;
begin
  FStageCompareData.Free;
  FPhasePayData.Free;
  FPhaseProperty.Free;
  FStageData.Free;
  FUpdator.Free;
  FConnection.Free;
  inherited;
end;

function TPhaseData.GetActive: Boolean;
begin
  Result := FConnection.Connection.Connected;
end;

function TPhaseData.GetAllowInsert: Boolean;
begin
  Result := not PhaseProperty.FinalAudit;
end;

function TPhaseData.GetStageDataReadOnly: Boolean;
begin
  Result := not IsLastStage or PhaseProperty.FinalAudit;
end;

function TPhaseData.GetFileName: string;
begin
  Result := FConnection.OrgFile;
end;

function TPhaseData.GetPhaseIndex: Integer;
begin
  Result := TProjectData(FProjectData).PhaseIndex;
end;

procedure TPhaseData.Open(const AProjectName: string);
begin
  UpdateSysProgress(35, '正在打开文件');
  FConnection.Open(AProjectName);
  UpdateSysProgress(40, '正在升级文件');
  UpdatePhaseDataBase;

  UpdateSysProgress(50, '正在读取数据');
  FPhaseProperty.Open;
  CheckAuditCount;
  FStageIndex := FPhaseProperty.AuditCount;
  UpdateSysProgress(140, '正在读取数据');
  FStageData.TableName := StageTableName[FStageIndex];
  FStageData.Open(FConnection.Connection);
  UpdateSysProgress(160, '正在读取数据');
  FPhasePayData.Open(FConnection.Connection);
  UpdateSysProgress(180, '正在读取数据');
  FZJJLData.Open(FConnection.Connection);
  UpdateSysProgress(200, '就绪');
end;

procedure TPhaseData.Save;
begin
  TProjectData(FProjectData).AppendProjectLog('Save Phase Data');

  UpdateSysProgress(30, '正在保存数据');
  FPhaseProperty.Save;
  UpdateSysProgress(80, '正在保存数据');
  FStageData.Save;
  UpdateSysProgress(150, '正在保存数据');
  FPhasePayData.Save;
  UpdateSysProgress(170, '正在保存数据');
  FZJJLData.Save;
  UpdateSysProgress(180, '正在保存数据');
  FConnection.Save;
  UpdateSysProgress(200, '就绪');

  TProjectData(FProjectData).AppendProjectLog('Save Phase Data --> End');
end;

procedure TPhaseData.SimpleOpen(const AProjectName: string);
begin
  FConnection.Open(AProjectName);
  UpdatePhaseDataBase;
  FPhaseProperty.Open;
  CheckAuditCount;
  FPhasePayData.Open(FConnection.Connection);
end;

procedure TPhaseData.SimpleSave;
begin
  FPhasePayData.Save;
  FPhaseProperty.Save;
  FConnection.Save;
end;

procedure TPhaseData.UpdatePhaseDataBase;
begin
  FUpdator.Update(FConnection);
end;

function TPhaseData.GetmdbFileName: string;
begin
  Result := FConnection.FileName;
end;

procedure TPhaseData.CopyPreData;
begin
  StageData.CopyPrePhaseData;
  PhasePayData.CopyPrePhasePayData;
end;

function TPhaseData.GetADOConnection: TADOConnection;
begin
  Result := FConnection.Connection;
end;

procedure TPhaseData.SetStageIndex(const Value: Integer);

  procedure ReCreateStageData;
  begin
    if StageData.Active then
      StageData.Save;
    StageData.Free;
    FStageData := TStageData.Create(Self);
    FStageData.TableName := StageTableName[fStageIndex];
    FStageData.Open(ADOConnection);
  end;

begin
  TProjectData(FProjectData).SaveLastestPhaseMainData;
  FStageIndex := Value;
  ReCreateStageData;
  TProjectData(FProjectData).ResetPhaseDataLink;
end;

function TPhaseData.GetStageTableName(AIndex: Integer): string;
begin
  if AIndex > 0 then
    Result := 'Audit' + IntToStr(AIndex)
  else
    Result := 'Refer';
end;

function TPhaseData.GetAuditCount: Integer;
begin
  Result := PhaseProperty.AuditCount;
end;

function TPhaseData.GetStageCount: Integer;
begin
  Result := PhaseProperty.AuditCount + 1;
end;

procedure TPhaseData.CheckAuditCount;

  function GetRealAuditCount: Integer;
  var
    Tables: TStrings;
  begin
    Tables := TStringList.Create;
    try
      FConnection.Connection.GetTableNames(Tables);
      Result := 0;
      while Tables.IndexOf('Audit' + IntToStr(Result + 1)) > -1 do
        Inc(Result);
    finally
      Tables.Free;
    end;
  end;

var
  iAuditCount: Integer;
begin
  // 改为强制检验
  //if FPhaseProperty.AuditCount = 0 then
  //begin
    iAuditCount := GetRealAuditCount;
    if iAuditCount <> FPhaseProperty.AuditCount then
      FPhaseProperty.AuditCount := iAuditCount;
  //end;
end;

function TPhaseData.GetIsLastStage: Boolean;
begin
  Result := FStageIndex = FPhaseProperty.AuditCount;
end;

procedure TPhaseData.CopyPreStageData;
const
  sCopySql = 'Insert Into %s Select * From %s';
var
  sPre, sCur, sSql: string;
begin
  FUpdator.AddAuditData(FConnection.Connection, FPhaseProperty.AuditCount);
  sPre := StageTableName[FPhaseProperty.AuditCount-1];
  sCur := StageTableName[FPhaseProperty.AuditCount];
  sSql := Format(sCopySql, [sCur, sPre]);
  ExecuteSql(FConnection.Connection, sSql);
end;

procedure TPhaseData.SimpleOpen2(const AProjectName: string);
begin
  FConnection.Open(AProjectName);
  UpdatePhaseDataBase;
  FPhaseProperty.Open;
  CheckAuditCount;
  FStageIndex := FPhaseProperty.AuditCount;
  FStageData.TableName := StageTableName[FStageIndex];
  FStageData.Open(FConnection.Connection);
  FPhasePayData.Open(FConnection.Connection);
  FZJJLData.Open(FConnection.Connection);
end;

procedure TPhaseData.SaveDebugFile(const AFileName: string);
begin
  TProjectData(FProjectData).AppendProjectLog('Save Phase Data');
  FPhaseProperty.Save;
  FStageData.Save;
  FPhasePayData.Save;
  FZJJLData.Save;
  FConnection.SaveDebugFile(AFileName);
  TProjectData(FProjectData).AppendProjectLog('Save Phase Data --> End');
end;

end.
