unit BillsGatherDm;

interface

uses
  SysUtils, Classes, DB, DBClient, sdIDTree, sdDB, sdProvider,
  GclBillsGatherModel;

type
  TBillsGatherData = class(TDataModule)
    smpGclBills: TsdMemoryProvider;
    sddGclBills: TsdDataSet;
    sdvGclBills: TsdDataView;
    smpDetailGclBills: TsdMemoryProvider;
    sddDetailGclBills: TsdDataSet;
    sdvDetailGclBills: TsdDataView;
    smpDetailDealBills: TsdMemoryProvider;
    sddDetailDealBills: TsdDataSet;
    sdvDetailDealBills: TsdDataView;
    smpDetailBGLBills: TsdMemoryProvider;
    sddDetailBGLBills: TsdDataSet;
    sdvDetailBGLBills: TsdDataView;
    procedure sdvGclBillsCurrentChanged(ARecord: TsdDataRecord);
    procedure sdvDetailGclBillsFilterRecord(ARecord: TsdDataRecord;
      var Allow: Boolean);
    procedure sdvGclBillsGetText(var Text: String; ARecord: TsdDataRecord;
      AValue: TsdValue; AColumn: TsdViewColumn; DisplayText: Boolean);
  private
    FProjectData: TObject;

    procedure WriteGatherRecord(AGcls, AXmjs: TList);

    function GetMainBillsTree: TsdIDTree;
  public
    constructor Create(AProjectData: TObject);
    destructor Destroy; override;

    procedure RefreshBills;

    property ProjectData: TObject read FProjectData;
    property MainBillsTree: TsdIDTree read GetMainBillsTree;
  end;

implementation

uses
  ProjectData, PhaseData, StageDm, BillsDm, UtilMethods,
  ZhAPI, BillsCompileDm, DealBillsDm, BGLDm, BillsTree, BillsMeasureDm;

{$R *.dfm}

{ TBillsGatherData }

constructor TBillsGatherData.Create(AProjectData: TObject);
begin
  inherited Create(nil);
  FProjectData := AProjectData;

  sddGclBills.Open;
  if not Assigned(sddGclBills.FindIndex('idxIndexCode')) then
    sddGclBills.AddIndex('idxIndexCode', 'IndexCode');
  sdvGclBills.Open;
  sdvGclBills.IndexName := 'idxIndexCode';

  sddDetailGclBills.Open;
  if not Assigned(sddDetailGclBills.FindIndex('idxSerialNo')) then
    sddDetailGclBills.AddIndex('idxSerialNo', 'BillsID;TreeSerialNo');
  if not Assigned(sddDetailGclBills.FindIndex('idxRelaBills')) then
    sddDetailGclBills.AddIndex('idxRelaBills', 'RelaBillsID');
  sdvDetailGclBills.Open;
  sdvDetailGclBills.IndexName := 'idxSerialNo';

  sddDetailDealBills.Open;
  if not Assigned(sddDetailDealBills.FindIndex('idxDeal')) then
    sddDetailDealBills.AddIndex('idxDeal', 'DealID');
  sdvDetailDealBills.Open;
  sdvDetailDealBills.IndexName := 'idxDeal';

  sddDetailBGLBills.Open;
  if not Assigned(sddDetailBGLBills.FindIndex('idxBGL')) then
    sddDetailBGLBills.AddIndex('idxBGL', 'BGLID');
  sdvDetailBGLBills.Open;
  sdvDetailBGLBills.IndexName := 'idxBGL';
end;

destructor TBillsGatherData.Destroy;
begin
  inherited;
end;

function TBillsGatherData.GetMainBillsTree: TsdIDTree;
begin
  Result := TProjectData(FProjectData).BillsMeasureData.BillsMeasureTree;
end;

procedure TBillsGatherData.RefreshBills;
var
  vGather: TGclGatherModel;
begin
  vGather := TGclGatherModel.Create(FProjectData);
  try
    vGather.GatherDeal := True;
    vGather.GatherBGL := True;
    vGather.WriteGatherData := WriteGatherRecord;
    vGather.Execute;
  finally
    vGather.Free;
  end;
end;

procedure TBillsGatherData.WriteGatherRecord(AGcls, AXmjs: TList);
var
  sCurB_Code, sCurName, sCurUnits, sCurPrice: string;
  bHasCurrrent: Boolean;

  procedure DisableAndClearDataSet(ADataSet: TsdDataSet);
  begin
    ADataSet.DisableControls;
    ADataSet.BeginUpdate;
    ADataSet.DeleteAll;
  end;

  procedure EnableDataSet(ADataSet: TsdDataSet);
  begin
    ADataSet.EndUpdate;
    ADataSet.EnableControls;
  end;

  procedure BeforeWrite;
  begin
    bHasCurrrent := Assigned(sdvGclBills.Current);
    if Assigned(sdvGclBills.Current) then
    begin
      sCurB_Code := sdvGclBills.Current.ValueByName('B_Code').AsString;
      sCurName := sdvGclBills.Current.ValueByName('Name').AsString;
      sCurUnits := sdvGclBills.Current.ValueByName('Units').AsString;
      sCurPrice := sdvGclBills.Current.ValueByName('Price').AsString;
    end;

    sdvDetailGclBills.Filtered := False;
    sdvDetailDealBills.Filtered := False;
    sdvDetailBGLBills.Filtered := False;

    DisableAndClearDataSet(sddGclBills);
    DisableAndClearDataSet(sddDetailGclBills);
    DisableAndClearDataSet(sddDetailDealBills);
    DisableAndClearDataSet(sddDetailBGLBills);
  end;

  function FindCurrentRecord: TsdDataRecord;
  var
    i: Integer;
    Rec: TsdDataRecord;
  begin
    Result := nil;
    for i := 0 to sddGclBills.RecordCount - 1 do
    begin
      Rec := sddGclBills.Records[i];
      if SameText(sCurB_Code, Rec.ValueByName('B_Code').AsString) and
         SameText(sCurName, Rec.ValueByName('Name').AsString) and
         SameText(sCurUnits, Rec.ValueByName('Units').AsString) and
         SameText(sCurPrice, Rec.ValueByName('Price').AsString) then
      begin
        Result := Rec;
        Break;
      end;
    end;
  end;

  procedure AfterWrite;
  var
    Rec: TsdDataRecord;
  begin
    EnableDataSet(sddDetailBGLBills);
    EnableDataSet(sddDetailDealBills);
    EnableDataSet(sddDetailGclBills);
    EnableDataSet(sddGclBills);

    if bHasCurrrent then
      Rec := FindCurrentRecord;
    if not Assigned(Rec) and (sdvGclBills.RecordCount > 0) then
      Rec := sdvGclBills.Records[0];
    sdvGclBills.LocateInControl(Rec);
    
    sdvDetailGclBills.Filtered := True;
    sdvDetailDealBills.Filtered := True;
    sdvDetailBGLBills.Filtered := True;
  end;

  procedure WriteDetailDealNode(AGclNode: TGclNode);
  var
    iDeal: Integer;
    vDeal: TDetailDealNode;
    Rec: TsdDataRecord;
  begin
    for iDeal := 0 to AGclNode.DetailDealCount - 1 do
    begin
      vDeal := AGclNode.DetailDeal[iDeal];
      Rec := sddDetailDealBills.Add;
      Rec.ValueByName('ID').AsInteger := vDeal.ID;
      Rec.ValueByName('BillsID').AsInteger := AGclNode.ID;
      Rec.ValueByName('DealID').AsInteger := vDeal.DealID;

      Rec.ValueByName('B_Code').AsString := AGclNode.B_Code;
      Rec.ValueByName('Name').AsString := AGclNode.Name;
      Rec.ValueByName('Units').AsString := AGclNode.Units;
      Rec.ValueByName('Price').AsFloat := AGclNode.Price;

      Rec.ValueByName('Quantity').AsFloat := vDeal.Quantity;
      Rec.ValueByName('TotalPrice').AsFloat := vDeal.TotalPrice;
    end;
  end;

  procedure WriteDetailBGLNode(AGclNode: TGclNode);
  var
    iBGL: Integer;
    vBGL: TDetailBGLNode;
    Rec: TsdDataRecord;
  begin
    for iBGL := 0 to AGclNode.DetailBGLCount - 1 do
    begin
      vBGL := AGclNode.DetailBGL[iBGL];
      Rec := sddDetailBGLBills.Add;
      Rec.ValueByName('ID').AsInteger := vBGL.ID;
      Rec.ValueByName('BillsID').AsInteger := AGclNode.ID;
      Rec.ValueByName('BGBillsID').AsInteger := vBGL.BGBillsID;
      Rec.ValueByName('BGLID').AsInteger := vBGL.BGLID;

      Rec.ValueByName('BGLCode').AsString := vBGL.BGLCode;
      Rec.ValueByName('BGLName').AsString := vBGL.BGLName;
      Rec.ValueByName('BGLApprovalCode').AsString := vBGL.BGLApprovalCode;
      Rec.ValueByName('BGLDrawingCode').AsString := vBGL.BGLDrawingCode;

      Rec.ValueByName('Quantity').AsFloat := vBGL.Quantity;
      Rec.ValueByName('TotalPrice').AsFloat := vBGL.TotalPrice;
    end;
  end;

  procedure WriteDetailGclNode(AGclNode: TGclNode);
  var
    iDetailGcl: Integer;
    vDetailGcl: TDetailGclNode;
    Rec: TsdDataRecord;
  begin
    for iDetailGcl := 0 to AGclNode.DetailGclCount -1 do
    begin
      vDetailGcl := AGclNode.DetailGcl[iDetailGcl];
      Rec := sddDetailGclBills.Add;
      Rec.ValueByName('ID').AsInteger := vDetailGcl.ID;
      Rec.ValueByName('BillsID').AsInteger := AGclNode.ID;
      Rec.ValueByName('TreeSerialNo').AsInteger := vDetailGcl.TreeSerialNo;
      Rec.ValueByName('RelaBillsID').AsInteger := vDetailGcl.BillsID;

      if Assigned(vDetailGcl.LeafXmj) then
      begin
        Rec.ValueByName('LeafXmjID').AsInteger := vDetailGcl.LeafXmj.ID;
        Rec.ValueByName('XmjCode').AsString := vDetailGcl.LeafXmj.XmjCode;
        Rec.ValueByName('XmjName').AsString := vDetailGcl.LeafXmj.XmjName;
        Rec.ValueByName('XmjUnits').AsString := vDetailGcl.LeafXmj.XmjUnits;
        Rec.ValueByName('NameDanWei').AsString := vDetailGcl.LeafXmj.NameDanWei;
        Rec.ValueByName('NameFenXiang').AsString := vDetailGcl.LeafXmj.NameFenXiang;
        Rec.ValueByName('NameFenBu').AsString := vDetailGcl.LeafXmj.NameFenBu;
        Rec.ValueByName('NameUnit').AsString := vDetailGcl.LeafXmj.NameUnit;
        Rec.ValueByName('Peg').AsString := vDetailGcl.LeafXmj.Peg;
        Rec.ValueByName('Position').AsString := vDetailGcl.LeafXmj.Position;
        Rec.ValueByName('DrawingCode').AsString := vDetailGcl.LeafXmj.DrawingCode;
      end;

      Rec.ValueByName('Quantity').AsFloat := vDetailGcl.Quantity;
      Rec.ValueByName('TotalPrice').AsFloat := vDetailGcl.TotalPrice;

      Rec.ValueByName('CurDealQuantity').AsFloat := vDetailGcl.CurDealQuantity;
      Rec.ValueByName('CurDealTotalPrice').AsFloat := vDetailGcl.CurDealTotalPrice;
      Rec.ValueByName('CurQcQuantity').AsFloat := vDetailGcl.CurQcQuantity;
      Rec.ValueByName('CurQcTotalPrice').AsFloat := vDetailGcl.CurQcTotalPrice;
      Rec.ValueByName('CurGatherQuantity').AsFloat := vDetailGcl.CurGatherQuantity;
      Rec.ValueByName('CurGatherTotalPrice').AsFloat := vDetailGcl.CurGatherTotalPrice;

      Rec.ValueByName('PreDealQuantity').AsFloat := vDetailGcl.PreDealQuantity;
      Rec.ValueByName('PreDealTotalPrice').AsFloat := vDetailGcl.PreDealTotalPrice;
      Rec.ValueByName('PreQcQuantity').AsFloat := vDetailGcl.PreQcQuantity;
      Rec.ValueByName('PreQcTotalPrice').AsFloat := vDetailGcl.PreQcTotalPrice;
      Rec.ValueByName('PreGatherQuantity').AsFloat := vDetailGcl.PreGatherQuantity;
      Rec.ValueByName('PreGatherTotalPrice').AsFloat := vDetailGcl.PreGatherTotalPrice;

      Rec.ValueByName('EndDealQuantity').AsFloat := vDetailGcl.EndDealQuantity;
      Rec.ValueByName('EndDealTotalPrice').AsFloat := vDetailGcl.EndDealTotalPrice;
      Rec.ValueByName('EndQcQuantity').AsFloat := vDetailGcl.EndQcQuantity;
      Rec.ValueByName('EndQcTotalPrice').AsFloat := vDetailGcl.EndQcTotalPrice;
      Rec.ValueByName('EndGatherQuantity').AsFloat := vDetailGcl.EndGatherQuantity;
      Rec.ValueByName('EndGatherTotalPrice').AsFloat := vDetailGcl.EndGatherTotalPrice;

      Rec.ValueByName('Percent').AsFloat := vDetailGcl.Percent;

      Rec.ValueByName('AddDealQuantity').AsFloat := vDetailGcl.AddDealQuantity;
      Rec.ValueByName('AddDealTotalPrice').AsFloat := vDetailGcl.AddDealTotalPrice;
      Rec.ValueByName('AddQcQuantity').AsFloat := vDetailGcl.AddQcQuantity;
      Rec.ValueByName('AddQcTotalPrice').AsFloat := vDetailGcl.AddQcTotalPrice;
      Rec.ValueByName('AddGatherQuantity').AsFloat := vDetailGcl.AddGatherQuantity;
      Rec.ValueByName('AddGatherTotalPrice').AsFloat := vDetailGcl.AddGatherTotalPrice;
    end;
  end;

  procedure WriteGclNode(AGclNode: TGclNode);
  var
    Rec: TsdDataRecord;
  begin
    Rec := sddGclBills.Add;
    Rec.ValueByName('ID').AsInteger := AGclNode.ID;

    Rec.ValueByName('IndexCode').AsString := AGclNode.IndexCode;
    Rec.ValueByName('B_Code').AsString := AGclNode.B_Code;
    Rec.ValueByName('Name').AsString := AGclNode.Name;
    Rec.ValueByName('Units').AsString := AGclNode.Units;
    Rec.ValueByName('Price').AsFloat := AGclNode.Price;

    Rec.ValueByName('DealQuantity').AsFloat := AGclNode.DealQuantity;
    Rec.ValueByName('DealTotalPrice').AsFloat := AGclNode.DealTotalPrice;
    Rec.ValueByName('BGLQuantity').AsFloat := AGclNode.BGLQuantity;
    Rec.ValueByName('BGLTotalPrice').AsFloat := AGclNode.BGLTotalPrice;
    Rec.ValueByName('Quantity').AsFloat := AGclNode.Quantity;
    Rec.ValueByName('TotalPrice').AsFloat := AGclNode.TotalPrice;

    Rec.ValueByName('CurDealQuantity').AsFloat := AGclNode.CurDealQuantity;
    Rec.ValueByName('CurDealTotalPrice').AsFloat := AGclNode.CurDealTotalPrice;
    Rec.ValueByName('CurQcQuantity').AsFloat := AGclNode.CurQcQuantity;
    Rec.ValueByName('CurQcTotalPrice').AsFloat := AGclNode.CurQcTotalPrice;
    Rec.ValueByName('CurGatherQuantity').AsFloat := AGclNode.CurGatherQuantity;
    Rec.ValueByName('CurGatherTotalPrice').AsFloat := AGclNode.CurGatherTotalPrice;

    Rec.ValueByName('PreDealQuantity').AsFloat := AGclNode.PreDealQuantity;
    Rec.ValueByName('PreDealTotalPrice').AsFloat := AGclNode.PreDealTotalPrice;
    Rec.ValueByName('PreQcQuantity').AsFloat := AGclNode.PreQcQuantity;
    Rec.ValueByName('PreQcTotalPrice').AsFloat := AGclNode.PreQcTotalPrice;
    Rec.ValueByName('PreGatherQuantity').AsFloat := AGclNode.PreGatherQuantity;
    Rec.ValueByName('PreGatherTotalPrice').AsFloat := AGclNode.PreGatherTotalPrice;

    Rec.ValueByName('EndDealQuantity').AsFloat := AGclNode.EndDealQuantity;
    Rec.ValueByName('EndDealTotalPrice').AsFloat := AGclNode.EndDealTotalPrice;
    Rec.ValueByName('EndQcQuantity').AsFloat := AGclNode.EndQcQuantity;
    Rec.ValueByName('EndQcTotalPrice').AsFloat := AGclNode.EndQcTotalPrice;
    Rec.ValueByName('EndGatherQuantity').AsFloat := AGclNode.EndGatherQuantity;
    Rec.ValueByName('EndGatherTotalPrice').AsFloat := AGclNode.EndGatherTotalPrice;

    Rec.ValueByName('AddDealQuantity').AsFloat := AGclNode.AddDealQuantity;
    Rec.ValueByName('AddDealTotalPrice').AsFloat := AGclNode.AddDealTotalPrice;
    Rec.ValueByName('AddQcQuantity').AsFloat := AGclNode.AddQcQuantity;
    Rec.ValueByName('AddQcTotalPrice').AsFloat := AGclNode.AddQcTotalPrice;
    Rec.ValueByName('AddGatherQuantity').AsFloat := AGclNode.AddGatherQuantity;
    Rec.ValueByName('AddGatherTotalPrice').AsFloat := AGclNode.AddGatherTotalPrice;

    Rec.ValueByName('Deal_BGLQuantity').AsFloat := AGclNode.Deal_BGLQuantity;
    Rec.ValueByName('Deal_BGLTotalPrice').AsFloat := AGclNode.Deal_BGLTotalPrice;
    Rec.ValueByName('Deal_BGLPercent').AsFloat := AGclNode.Deal_BGLPercent;

    WriteDetailGclNode(AGclNode);
    WriteDetailDealNode(AGclNode);
    WriteDetailBGLNode(AGclNode);
  end;

var
  iGcl: Integer;
  vGclNode: TGclNode;
begin
  BeforeWrite;
  try
    for iGcl := 0 to AGcls.Count - 1 do
    begin
      vGclNode := TGclNode(AGcls.Items[iGcl]);
      WriteGclNode(vGclNode);
    end;
  finally
    AfterWrite;
  end;
end;

procedure TBillsGatherData.sdvGclBillsCurrentChanged(
  ARecord: TsdDataRecord);
begin
  sdvDetailGclBills.RefreshFilter;
  sdvDetailDealBills.RefreshFilter;
  sdvDetailBGLBills.RefreshFilter;
end;

procedure TBillsGatherData.sdvDetailGclBillsFilterRecord(
  ARecord: TsdDataRecord; var Allow: Boolean);
begin
  if Assigned(ARecord) and Assigned(sdvGclBills.Current) then
    Allow := ARecord.ValueByName('BillsID').AsInteger = sdvGclBills.Current.ValueByName('ID').AsInteger
  else
    Allow := False;
end;

procedure TBillsGatherData.sdvGclBillsGetText(var Text: String;
  ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
  DisplayText: Boolean);
begin
  if Assigned(AValue) and (AValue.Field.DataType = ftFloat) and (AValue.AsFloat = 0) then
    Text := '';
end;

end.
