unit PriceMarginClipboard;

interface

uses
  BaseClipboard, Classes, XmlDoc, XmlIntf, PriceMarginBillsDm, ZhAPI,
  Windows, ProjectGLDm, DetailGLDm, mDataRecord;

Type
  TProjectGLNode = class
  private
    FID: Integer;
    FCode: string;
    FName: string;
    FUnits: string;
    FSpecs: string;
    FBasePrice: Double;
    FRiskRange: Double;

    FInfoPrice: Double;
    FInfoDate: string;
  public
    procedure SaveToXmlNode(AXmlNode: IXMLNode);
    procedure LoadFromXmlNode(AXmlNode: IXMLNode);
  end;

  TDetailGLNode = class
  private
    FGLID: Integer;
    FCode: string;
    FQuantity: Double;
  public
    procedure SaveToXmlNode(AXmlNode: IXMLNode);
    procedure LoadFromXmlNode(AXmlNode: IXMLNode);
  end;

  TDetailGL_Clipboard = class(TBaseClipboard)
  private
    FProjectGLData: TProjectGLData;
    FDetailGLData: TDetailGLData;

    FProjectGLs: TList;
    FDetailGls: TList;

    procedure SaveProjectGLsToXml(AXmlNode: IXMLNode);
    procedure SaveDetailGLsToXml(AXmlNode: IXMLNode);

    procedure CopyProjectGL(ARec: TProjectGLRecord);
    procedure CopyDetailGL(ARec: TDetailGLRecord);
    procedure CopyData(ABillsID: Integer);

    procedure LoadProjectGLsFromXml(AXmlNode: IXMLNode);
    procedure LoadDetailGLsFromXml(AXmlNode: IXMLNode);

    procedure Clear;
  protected
    procedure SaveXmlData(AXmlDoc: IXmlDocument); override;
    procedure LoadXmlData(AXmlDoc: IXmlDocument); override;
  public
    constructor Create(AProjectData: TObject);
    destructor Destroy; override;

    procedure Copy(ABillsID: Integer);
    //procedure Paste
  end;

function HasDetailGLBlockFormat: Boolean;

implementation

uses
  ProjectData, sdDB;

var
  CF_DetailGLBlock: Word;

function HasDetailGLBlockFormat: Boolean;
begin
  Result := HasClipboardFormat(CF_DetailGLBlock);
end;

{ TDetailGLNode }

procedure TDetailGLNode.LoadFromXmlNode(AXmlNode: IXMLNode);
begin
  FGLID := AXmlNode.Attributes['GLID'];
  FCode := AXmlNode.Attributes['Code'];
  FQuantity := AXmlNode.Attributes['Quantity'];
end;

procedure TDetailGLNode.SaveToXmlNode(AXmlNode: IXMLNode);
begin
  AXmlNode.Attributes['GLID'] := FGLID;
  AXmlNode.Attributes['Code'] := FCode;
  AXmlNode.Attributes['Quantity'] := FQuantity;
end;

{ TProjectGLNode }

procedure TProjectGLNode.LoadFromXmlNode(AXmlNode: IXMLNode);
begin
  FID := AXmlNode.Attributes['ID'];
  FCode := AXmlNode.Attributes['Code'];
  FName := AXmlNode.Attributes['Name'];
  FUnits := AXmlNode.Attributes['Units'];
  FSpecs := AXmlNode.Attributes['Specs'];
  FBasePrice := AXmlNode.Attributes['BasePrice'];
  FRiskRange := AXmlNode.Attributes['RiskRange'];

  FInfoPrice := AXmlNode.Attributes['InfoPrice'];
  FInfoDate := AXmlNode.Attributes['InfoDate'];
end;

procedure TProjectGLNode.SaveToXmlNode(AXmlNode: IXMLNode);
begin
  AXmlNode.Attributes['ID'] := FID;
  AXmlNode.Attributes['Code'] := FCode;
  AXmlNode.Attributes['Name'] := FName;
  AXmlNode.Attributes['Units'] := FUnits;
  AXmlNode.Attributes['Specs'] := FSpecs;
  AXmlNode.Attributes['BasePrice'] := FBasePrice;
  AXmlNode.Attributes['RiskRange'] := FRiskRange;

  AXmlNode.Attributes['InfoPrice'] := FInfoPrice;
  AXmlNode.Attributes['InfoDate'] := FInfoDate;
end;

{ TDetailGL_Clipboard }

procedure TDetailGL_Clipboard.Clear;
begin
  ClearObjects(FDetailGls);
  ClearObjects(FProjectGLs);
end;

procedure TDetailGL_Clipboard.Copy(ABillsID: Integer);
begin
  Clear;
  CopyData(ABillsID);
  SaveToStream;
  SaveToClipboard(CF_DetailGLBlock);
end;

procedure TDetailGL_Clipboard.CopyData(ABillsID: Integer);
var
  vGLs: TList;
  iGL: Integer;
  Rec: TDetailGLRecord;
begin
  vGLs := TList.Create;
  try
    FDetailGLData.LoadDetailGLs(ABillsID, vGLs);
    for iGL := 0 to vGLs.Count - 1 do
    begin
      Rec := TDetailGLRecord(vGLs.Items[iGL]);
      CopyDetailGL(Rec);
    end;
  finally
    vGLs.Free;
  end;
end;

procedure TDetailGL_Clipboard.CopyDetailGL(ARec: TDetailGLRecord);
var
  DetailGL: TDetailGLNode;
begin
  DetailGL := TDetailGLNode.Create;
  FDetailGls.Add(DetailGL);
  DetailGL.FGLID := ARec.GLID.AsInteger;
  DetailGL.FCode := ARec.Code.AsString;
  DetailGL.FQuantity := ARec.Quantity.AsFloat;
  CopyProjectGL(ARec.RelaProjectGL);
end;

procedure TDetailGL_Clipboard.CopyProjectGL(ARec: TProjectGLRecord);
var
  ProjectGL: TProjectGLNode;
begin
  ProjectGL := TProjectGLNode.Create;
  FProjectGLs.Add(ProjectGL);
  ProjectGL.FID := ARec.ID.AsInteger;
  ProjectGL.FCode := ARec.Code.AsString;
  ProjectGL.FName := ARec.Name.AsString;
  ProjectGL.FUnits := ARec.Units.AsString;
  ProjectGL.FSpecs := ARec.Specs.AsString;
  ProjectGL.FBasePrice := ARec.BasePrice.AsFloat;
  ProjectGL.FRiskRange := ARec.RiskRange.AsFloat;
end;

constructor TDetailGL_Clipboard.Create(AProjectData: TObject);
begin
  inherited Create;
  FProjectGLs := TList.Create;
  FDetailGls := TList.Create;

  FProjectGLData := TProjectData(AProjectData).ProjectGLData;
  FDetailGLData := TProjectData(AProjectData).DetailGLData;
end;

destructor TDetailGL_Clipboard.Destroy;
begin
  ClearObjects(FDetailGls);
  FDetailGls.Free;
  ClearObjects(FProjectGLs);
  FProjectGLs.Free;
  inherited;
end;

procedure TDetailGL_Clipboard.LoadDetailGLsFromXml(AXmlNode: IXMLNode);
var
  Parent, Cur: IXMLNode;
  iGL: Integer;
  DetailGL: TDetailGLNode;
begin
  Parent := AXmlNode.ChildNodes.FindNode('DetailGLs');
  for iGL := 0 to AXmlNode.ChildNodes.Count - 1 do
  begin
    Cur := AXmlNode.ChildNodes.FindNode('DetailGL');
    DetailGL := TDetailGLNode.Create;
    FDetailGls.Add(DetailGL);
    DetailGL.LoadFromXmlNode(Cur);
  end;
end;

procedure TDetailGL_Clipboard.LoadProjectGLsFromXml(AXmlNode: IXMLNode);
var
  Parent, Cur: IXMLNode;
  iGL: Integer;
  ProjectGL: TProjectGLNode;
begin
  Parent := AXmlNode.ChildNodes.FindNode('ProjectGLs');
  for iGL := 0 to AXmlNode.ChildNodes.Count - 1 do
  begin
    Cur := AXmlNode.ChildNodes.FindNode('ProjectGL');
    ProjectGL := TProjectGLNode.Create;
    FProjectGLs.Add(ProjectGL);
    ProjectGL.LoadFromXmlNode(Cur);
  end;
end;

procedure TDetailGL_Clipboard.LoadXmlData(AXmlDoc: IXmlDocument);
begin
  inherited;
  LoadDetailGLsFromXml(AXmlDoc.DocumentElement);
  LoadProjectGLsFromXml(AXmlDoc.DocumentElement);
end;

procedure TDetailGL_Clipboard.SaveDetailGLsToXml(AXmlNode: IXMLNode);
var
  Parent, Cur: IXMLNode;
  i: Integer;
  DetailGL: TDetailGLNode;
begin
  Parent := AXmlNode.AddChild('DetailGLs');
  for i := 0 to FDetailGls.Count - 1 do
  begin
    DetailGL := TDetailGLNode(FDetailGls.Items[i]);
    Cur := Parent.AddChild('DetailGL');
    DetailGL.SaveToXmlNode(Cur);
  end;
end;

procedure TDetailGL_Clipboard.SaveProjectGLsToXml(AXmlNode: IXMLNode);
var
  Parent, Cur: IXMLNode;
  i: Integer;
  ProjectGL: TProjectGLNode;
begin
  Parent := AXmlNode.AddChild('ProjectGLs');
  for i := 0 to FProjectGLs.Count - 1 do
  begin
    ProjectGL := TProjectGLNode(FProjectGLs.Items[i]);
    Cur := Parent.AddChild('ProjectGL');
    ProjectGL.SaveToXmlNode(Cur);
  end;
end;

procedure TDetailGL_Clipboard.SaveXmlData(AXmlDoc: IXmlDocument);
begin
  inherited;
  SaveProjectGLsToXml(AXmlDoc.DocumentElement);
  SaveDetailGLsToXml(AXmlDoc.DocumentElement);
end;

initialization
  CF_DetailGLBlock := RegisterClipboardFormat('Zh.M.DetailGL');

end.
