unit BatchInsertBillsFrm;

interface

uses
  BillsCompileDm,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ZJGrid, sdIDTree, dxBar, sdGridDBA, ComCtrls,
  ActnList;

type
  TInsertType = (itChild, itNextSibling);

  TBatchInsertBillsForm = class(TForm)
    pnlButton: TPanel;
    btnOK: TButton;
    btnCancel: TButton;
    dxpmInsertBills: TdxBarPopupMenu;
    pnlAllGrid: TPanel;
    pnlPositon_Bills: TPanel;
    pnlPosition: TPanel;
    lblPostion: TLabel;
    zgPosition: TZJGrid;
    pnlPositionSpr: TPanel;
    pnlBills: TPanel;
    lblBills: TLabel;
    zgBills: TZJGrid;
    pnlBillsSpr: TPanel;
    pnlDealBills: TPanel;
    pnlOther: TPanel;
    leBeginCode: TLabeledEdit;
    leDrawingCode: TLabeledEdit;
    zgDealBills: TZJGrid;
    pnlDealBillsSpr: TPanel;
    lblDealBills: TLabel;
    lblHint: TLabel;
    sgdDealBills: TsdGridDBA;
    udBeginCode: TUpDown;
    alBatchInsertBills: TActionList;
    actnInsertCol: TAction;
    procedure zgPositionCustomPaste(Sender: TObject; ABounds: TRect;
      ASourSheet: TZjSheet);
    procedure zgBillsCustomPaste(Sender: TObject; ABounds: TRect;
      ASourSheet: TZjSheet);
    procedure btnOKClick(Sender: TObject);
    procedure zgPositionMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure zgBillsCellTextChanged(Sender: TObject; Col, Row: Integer);
    procedure zgDealBillsMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure leBeginCodeKeyPress(Sender: TObject; var Key: Char);
    procedure zgPositionCellTextChanged(Sender: TObject; Col,
      Row: Integer);
    procedure dxpmInsertBillsPopup(Sender: TObject);
    procedure actnInsertColExecute(Sender: TObject);
    procedure zgBillsMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure actnInsertColUpdate(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
    FInsertType: TInsertType;
    FBillsCompileData: TBillsCompileData;
    FParentCode: string;

    procedure ResetPositionGridHead;
    procedure ResetBillsGridHead;
    procedure PasteData(AGrid: TZJGrid; ABounds: TRect; ASourSheet: TZjSheet);
    procedure SetRowAndColumnCount(AGrid: TZJGrid; ASourSheet: TZjSheet);
    procedure LoadParentCode;

    function ReplaceLastNum(const ACode: string; ARow: Integer): string;
    function GetXmjCode(ARow: Integer): string;
    procedure AddXmjNode(ARow, AParentID, ANextSiblingID: Integer);
    procedure AddBillsNode(AQtyRow, ARow: Integer; AParent: TsdIDTreeNode);
    procedure AddBillsNodes(AQtyRow: Integer; AParent: TsdIDTreeNode);
    procedure BatchAddBillsNodes(AParentID, ANextSiblingID: Integer);
  public
    procedure Init(ABillsCompileData: TBillsCompileData; AInsertType: TInsertType);
    procedure Execute;
  end;

procedure AddLeafBills(ABillsCompileData: TBillsCompileData; AInsertType: TInsertType);

implementation

uses
  sdDB, UtilMethods, ProjectData, MainFrm, Globals;

{$R *.dfm}

const
  iBwNameCol = 1;
  iBwDrawingCodeCol = 2;
  iBwBillsQtyCol = 3;

  iGclCodeCol = 1;
  iGclNameCol = 2;
  iGclUnitsCol = 3;
  iGclPriceCol = 4;
  iGclDrawingCodeCol = 5;

procedure AddLeafBills(ABillsCompileData: TBillsCompileData; AInsertType: TInsertType);
var
  InsertBillsForm: TBatchInsertBillsForm;
begin
  InsertBillsForm := TBatchInsertBillsForm.Create(nil);
  try
    InsertBillsForm.Init(ABillsCompileData, AInsertType);
    if InsertBillsForm.ShowModal = mrOK then
      InsertBillsForm.Execute;
  finally
    InsertBillsForm.Free;
  end;
end;

{ TAddLeafBillsForm }

procedure TBatchInsertBillsForm.AddXmjNode(ARow, AParentID, ANextSiblingID: Integer);
var
  stnNode: TsdIDTreeNode;
begin
  if zgPosition.Cells[1, ARow].Text = '' then Exit;

  stnNode := FBillsCompileData.BillsCompileTree.Add(AParentID, ANextSiblingID);
  with stnNode.Rec do
  begin
    ValueByName('Code').AsString := GetXmjCode(ARow);{ReplaceLastNum(leBeginCode.Text, ARow);}
    ValueByName('Name').AsString := zgPosition.Cells[iBwNameCol, ARow].Text;
    ValueByName('DrawingCode').AsString := zgPosition.Cells[iBwDrawingCodeCol, ARow].Text;
  end;

  AddBillsNodes(ARow, stnNode);
end;

procedure TBatchInsertBillsForm.BatchAddBillsNodes(AParentID, ANextSiblingID: Integer);
var
  iRow: Integer;
begin
  for iRow := 1 to zgPosition.RowCount - 1 do
    AddXmjNode(iRow, AParentID, ANextSiblingID);
end;

procedure TBatchInsertBillsForm.Execute;
begin
  with FBillsCompileData.BillsCompileTree do
  begin
    if FInsertType = itChild then
    begin
      if not Assigned(Selected) then Exit;
      BatchAddBillsNodes(Selected.ID, -1);
      FBillsCompileData.Calculate(Selected.ID);
    end
    else if FInsertType = itNextSibling then
    begin
      if not Assigned(Selected.Parent) then Exit;
        BatchAddBillsNodes(Selected.ParentID, Selected.NextSiblingID);
        FBillsCompileData.Calculate(Selected.ParentID);
    end;
  end;
end;

procedure TBatchInsertBillsForm.Init(ABillsCompileData: TBillsCompileData;
  AInsertType: TInsertType);
begin
  ClientHeight := SupportManager.ConfigInfo.BatchInsertFrmHeight;
  ClientWidth := SupportManager.ConfigInfo.BatchInsertFrmWidth;
  pnlBills.Height := Trunc((pnlPositon_Bills.Height - pnlOther.Height)/22*9);

  OnResize := FormResize;

  FBillsCompileData := ABillsCompileData;
  sgdDealBills.DataView := TProjectData(ABillsCompileData.ProjectData).DealBillsData.sdvDealBills;
  FInsertType := AInsertType;
  if FInsertType = itChild then
    Caption := '批量插入子项'
  else if FInsertType = itNextSibling then
    Caption := '批量插入后项';
  ResetPositionGridHead;
  ResetBillsGridHead;
  LoadParentCode;
end;

procedure TBatchInsertBillsForm.PasteData(AGrid: TZJGrid; ABounds: TRect;
  ASourSheet: TZjSheet);
var
  iCol, iRow: Integer;
begin
  for iRow := 0 to ASourSheet.RowCount - 1 do
    for iCol := 0 to ASourSheet.ColCount - 1 do
    begin
      with AGrid.Cells[iCol + ABounds.Left , iRow + ABounds.Top] do
        if CanEdit then Text := ASourSheet.Values[iCol, iRow];
    end;
end;

function TBatchInsertBillsForm.ReplaceLastNum(const ACode: string;
  ARow: Integer): string;
var
  sgs: TStringList;
begin
  sgs := TStringList.Create;
  try
    sgs.Delimiter := '-';
    sgs.DelimitedText := ACode;
    sgs[sgs.Count - 1] := IntToStr(StrToInt(sgs[sgs.Count - 1]) + ARow - 1);
    Result := sgs.DelimitedText;
  finally
    sgs.Free;
  end;
end;

procedure TBatchInsertBillsForm.ResetPositionGridHead;
var
  iCol, iColDiff: Integer;
begin
  zgPosition.Cells[iBwNameCol, 0].Text := '部位';
  zgPosition.ColWidths[iBwNameCol] := 100;
  zgPosition.Cells[iBwDrawingCodeCol, 0].Text := '图(册)号';
  zgPosition.ColWidths[iBwDrawingCodeCol] := 100;
  iColDiff := iBwBillsQtyCol - 1;
  for iCol := iBwBillsQtyCol to zgPosition.ColCount - 1 do
  begin
    zgPosition.Cells[iCol, 0].Text := '清单' + IntToStr(iCol - iColDiff);
    zgPosition.ColWidths[iCol] := 50;
  end;
end;

procedure TBatchInsertBillsForm.SetRowAndColumnCount(AGrid: TZJGrid;
  ASourSheet: TZjSheet);
begin
  if AGrid.ColCount < ASourSheet.ColCount + AGrid.CurCol + 1 then
    AGrid.ColCount := ASourSheet.ColCount + AGrid.CurCol + 1;
  if AGrid.RowCount < ASourSheet.RowCount + AGrid.CurRow + 1 then
    AGrid.RowCount := ASourSheet.RowCount + AGrid.CurRow + 1;
end;

procedure TBatchInsertBillsForm.zgPositionCustomPaste(Sender: TObject;
  ABounds: TRect; ASourSheet: TZjSheet);
begin
  SetRowAndColumnCount(TZJGrid(Sender), ASourSheet);
  ResetPositionGridHead;
  PasteData(TZJGrid(Sender), ABounds, ASourSheet);
  zgBills.RowCount := zgPosition.ColCount - 1;
  ResetBillsGridHead;
end;

procedure TBatchInsertBillsForm.zgBillsCustomPaste(Sender: TObject;
  ABounds: TRect; ASourSheet: TZjSheet);
begin
  SetRowAndColumnCount(TZJGrid(Sender), ASourSheet);
  PasteData(TZJGrid(Sender), ABounds, ASourSheet);
end;

procedure TBatchInsertBillsForm.AddBillsNodes(AQtyRow: Integer;
  AParent: TsdIDTreeNode);
var
  iRow: Integer;
begin
  for iRow := 1 to zgBills.RowCount - 1 do
    AddBillsNode(AQtyRow, iRow, AParent);
end;

procedure TBatchInsertBillsForm.AddBillsNode(AQtyRow, ARow: Integer;
  AParent: TsdIDTreeNode);
var
  stnNode: TsdIDTreeNode;
  fQuantity: Double;
begin
  if (zgBills.Cells[1, ARow].Text = '') or
     (zgPosition.Cells[ARow + iBwBillsQtyCol - 1, AQtyRow].Text = '') or
     not TryStrToFloat(zgPosition.Cells[ARow + iBwBillsQtyCol - 1, AQtyRow].Text, fQuantity) then Exit;

  stnNode := FBillsCompileData.BillsCompileTree.Add(AParent.ID, -1);
  with stnNode.Rec do
  begin
    ValueByName('B_Code').AsString := zgBills.Cells[iGclCodeCol, ARow].Text;
    ValueByName('Name').AsString := zgBills.Cells[iGclNameCol, ARow].Text;
    ValueByName('Units').AsString := zgBills.Cells[iGclUnitsCol, ARow].Text;
    ValueByName('Price').AsFloat := StrToFloatDef(zgBills.Cells[iGclPriceCol, ARow].Text, 0);
    ValueByName('OrgQuantity').AsFloat := StrToFloatDef(zgPosition.Cells[ARow + iBwBillsQtyCol - 1, AQtyRow].Text, 0);
    ValueByName('DrawingCode').AsString := zgBills.Cells[iGclDrawingCodeCol, ARow].Text;
  end;
end;

procedure TBatchInsertBillsForm.ResetBillsGridHead;
var
  iRow: Integer;
begin
  zgBills.Cells[iGclCodeCol, 0].Text := '编号';
  zgBills.ColWidths[1] := 80;
  zgBills.Cells[iGclNameCol, 0].Text := '名称';
  zgBills.ColWidths[2] := 120;
  zgBills.Cells[iGclUnitsCol, 0].Text := '单位';
  zgBills.ColWidths[3] := 60;
  zgBills.Cells[iGclPriceCol, 0].Text := '单价';
  zgBills.ColWidths[4] := 60;
  zgBills.Cells[iGclDrawingCodeCol, 0].Text := '图(册)号';
  zgBills.ColWidths[5] := 60;
  for iRow := 1 to zgBills.RowCount - 1 do
    zgBills.Cells[0, iRow].Text := '清单' + IntToStr(iRow);
end;

procedure TBatchInsertBillsForm.btnOKClick(Sender: TObject);

  function CheckGridHasData(AGrid: TZJGrid): Boolean;
  var
    iRow: Integer;
  begin
    Result := False;
    for iRow := 1 to AGrid.RowCount - 1 do
      if AGrid.Cells[1, iRow].Text <> '' then
      begin
        Result := True;
        Break;
      end;
  end;

  function CheckBeginCodeAvailable(const ACode: string): Boolean;
  var
    sgsCode: TStrings;
    iCode: Integer;
  begin
    sgsCode := TStringList.Create;
    try
      sgsCode.Delimiter := '-';
      sgsCode.DelimitedText := ACode;

      Result := TryStrToInt(sgsCode[sgsCode.Count - 1], iCode);
    finally
      sgsCode.Free;
    end;
  end;

begin
  if not CheckGridHasData(zgPosition) then
    ErrorMessage('请输入部位数量复核数据！')
  else if not CheckGridHasData(zgBills) then
    ErrorMessage('请输入清单编号等数据！')
  else if leBeginCode.Text = '' then
    ErrorMessage('请输入起始编号！')
  else if not CheckBeginCodeAvailable(leBeginCode.Text) then
    ErrorMessage('请输入规范的起始部位编号，如1或1-1等。')
  else
    ModalResult := mrOK;
end;

procedure TBatchInsertBillsForm.zgPositionMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbRight then
  begin
    dxpmInsertBills.Tag := 0;
    dxpmInsertBills.PopupFromCursorPos;
  end;
end;

procedure TBatchInsertBillsForm.zgBillsCellTextChanged(Sender: TObject;
  Col, Row: Integer);
var
  sB_Code: string;
  Rec: TsdDataRecord;
begin
  if (Col = 1) and (Row > 0) then
  begin
    zgBills.Cells[Col, Row].Align := gaCenterLeft;
    sB_Code := zgBills.Cells[Col, Row].Text;
    if sB_Code = '' then Exit;
    with FBillsCompileData.BillsData do
      Rec := sddBills.Locate('B_Code', sB_Code);
    if Assigned(Rec) then
    begin
      zgBills.Cells[iGclNameCol, Row].Text := Rec.ValueByName('Name').AsString;
      zgBills.Cells[iGclNameCol, Row].Align := gaCenterLeft;
      zgBills.Cells[iGclUnitsCol, Row].Text := Rec.ValueByName('Units').AsString;
      zgBills.Cells[iGclUnitsCol, Row].Align := gaCenterCenter;
      zgBills.Cells[iGclPriceCol, Row].Font.Name := 'smartSimSun';
      zgBills.Cells[iGclPriceCol, Row].Text := Rec.ValueByName('Price').AsString;
      zgBills.Cells[iGclPriceCol, Row].Align := gaCenterRight;
      zgBills.Cells[iGclDrawingCodeCol, Row].Align := gaCenterLeft;
    end;
  end
  else if (Col = iGclNameCol) and (Row > 0) then
    zgBills.Cells[iGclNameCol, Row].Align := gaCenterLeft
  else if (Col = iGclPriceCol) and (Row > 0) then
  begin
    zgBills.Cells[Col, Row].Value := PriceRoundTo(
        StrToFloatDef(zgBills.Cells[Col, Row].Text, 0));
    zgBills.Cells[Col, Row].Align := gaCenterRight;
  end
  else if (Col = iGclDrawingCodeCol) and (Row > 0) then
    zgBills.Cells[Col, Row].Align := gaCenterLeft;
end;

procedure TBatchInsertBillsForm.zgDealBillsMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  i: Integer;
begin
  if (Button = mbLeft) and (ssDouble in Shift) then
    for i := 1 to 4 do
      zgBills.Cells[i, zgBills.CurRow].Text := zgDealBills.Cells[i, zgDealBills.CurRow].Text;
end;

procedure TBatchInsertBillsForm.LoadParentCode;
var
  Parent: TsdIDTreeNode;
begin
  if FInsertType = itChild then
    Parent := FBillsCompileData.BillsCompileTree.Selected
  else if FInsertType = itNextSibling then
    Parent := FBillsCompileData.BillsCompileTree.Selected.Parent;
  FParentCode := Parent.Rec.ValueByName('Code').AsString;
end;

function TBatchInsertBillsForm.GetXmjCode(ARow: Integer): string;
var
  iBeginCode: Integer;
begin
  iBeginCode := StrToIntDef(leBeginCode.Text, 1);
  Result := Format('%s-%d', [FParentCode, iBeginCode + ARow - 1]);
end;

procedure TBatchInsertBillsForm.leBeginCodeKeyPress(Sender: TObject;
  var Key: Char);
begin
  ValidInteger(Key);
end;

procedure TBatchInsertBillsForm.zgPositionCellTextChanged(Sender: TObject;
  Col, Row: Integer);
var
  value: Double;
begin
  if (Row > 0) then
  begin
    if (Col >= iBwBillsQtyCol) then
    begin
      if (TryStrToFloat(zgPosition.Cells[Col, Row].Text, value)) then
      begin
        zgPosition.Cells[Col, Row].Value := QuantityRoundTo(Value);
        zgPosition.Cells[Col, Row].Align := gaCenterRight;
      end
      else
        zgPosition.Cells[Col, Row].Value := '';
    end
    else if (Col > zgPosition.FixedColCount) then
      zgPosition.Cells[Col, Row].Align := gaCenterLeft;
  end;
end;

procedure TBatchInsertBillsForm.dxpmInsertBillsPopup(Sender: TObject);
begin
  SetDxBtnAction(actnInsertCol, MainForm.dxbtnInsertCol);
end;

procedure TBatchInsertBillsForm.actnInsertColExecute(Sender: TObject);
begin
  zgPosition.ColCount := zgPosition.ColCount + 1;
  zgPosition.Cells[zgPosition.ColCount-1, 0].Text := '清单' + IntToStr(zgPosition.ColCount - iBwBillsQtyCol);
  zgPosition.ColWidths[zgPosition.ColCount-1] := 50;

  zgBills.RowCount := zgPosition.ColCount - (iBwBillsQtyCol - 1);
  zgBills.Cells[0, zgBills.RowCount-1].Text := '清单' + IntToStr(zgBills.RowCount-1);
end;

procedure TBatchInsertBillsForm.zgBillsMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbRight then
  begin
    dxpmInsertBills.Tag := 1;
    dxpmInsertBills.PopupFromCursorPos;
  end;
end;

procedure TBatchInsertBillsForm.actnInsertColUpdate(Sender: TObject);
begin
  if dxpmInsertBills.Tag = 0 then
    TAction(Sender).Caption := '插入一列'
  else
    TAction(Sender).Caption := '插入一行';
end;

procedure TBatchInsertBillsForm.FormResize(Sender: TObject);
begin
  SupportManager.ConfigInfo.BatchInsertFrmHeight := ClientHeight;
  SupportManager.ConfigInfo.BatchInsertFrmWidth := ClientWidth;
  pnlBills.Height := Trunc((pnlPositon_Bills.Height - pnlOther.Height)/22*9);
end;

end.
