unit U_ReportForm;

interface

uses
  Windows, U_LNG, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, U_BaseCommon, U_BaseConstants, U_Common, U_SCSComponent, U_SCSLists, Math, ExtCtrls, RzPanel, RzButton,
  cxStyles, cxCustomData, cxGraphics, cxFilter, cxData, cxDataStorage,
  cxEdit, DB, cxDBData, cxGridLevel, cxClasses, cxControls,
  cxGridCustomView, cxGridCustomTableView, cxGridTableView,
  cxGridDBTableView, cxGrid, kbmMemTable, StdCtrls, Mask, RzEdit,
  cxCurrencyEdit, cxCheckBox, cxColorComboBox, cxSpinEdit, cxDropDownEdit,
  cxDBLookupComboBox, cxTextEdit, ActnList, ActnMan, Menus, ComCtrls,
  ToolWin, XPMenu, siComp, siLngLnk, cxMemo, cxImageComboBox, Buttons,
  cxLookAndFeels, cxLookAndFeelPainters, cxNavigator,
  PlatformDefaultStyleActnCtrls, {Tolik} cxGridDBDataDefinitions, cxGridRows,
  RzRadChk;

//const
  //Colmn Indexes
  //ciTransToUOM = 10;

type
  TF_ReportForm = class(TForm)
    RzGroupBox1: TRzGroupBox;
    gbOkCancel: TRzGroupBox;
    btOK: TRzBitBtn;
    btCancel: TRzBitBtn;
    RzPanel1: TRzPanel;
    GT_Resources: TcxGridDBTableView;
    GL_Resources: TcxGridLevel;
    gridResources: TcxGrid;
    mtResources: TkbmMemTable;
    dsrcResources: TDataSource;
    lbTotalCost: TLabel;
    neTotalCost: TRzNumericEdit;
    GT_ResourcesName: TcxGridDBColumn;
    GT_ResourcesArticulProducer: TcxGridDBColumn;
    GT_ResourcesArticulDistributor: TcxGridDBColumn;
    GT_ResourcesProducerName: TcxGridDBColumn;
    GT_ResourcesIzm: TcxGridDBColumn;
    GT_ResourcesKolvo: TcxGridDBColumn;
    GT_ResourcesPrice: TcxGridDBColumn;
    GT_ResourcesCost: TcxGridDBColumn;
    mtProducers: TkbmMemTable;
    dsrcProducers: TDataSource;
    Timer_DefineTotalCost: TTimer;
    Timer_PostResources: TTimer;
    ActionManager: TActionManager;
    Act_ReplaceComponent: TAction;
    PopupMenu: TPopupMenu;
    N1: TMenuItem;
    Act_DelComponent: TAction;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    N2: TMenuItem;
    XPMenu1: TXPMenu;
    GT_ResourcesNpp: TcxGridDBColumn;
    btApply: TRzBitBtn;
    lng_Forms: TsiLangLinked;
    GT_ResourcesTransformToUOM: TcxGridDBColumn;
    GT_ResourcesIsResource: TcxGridDBColumn;
    GT_ResourcesGUIDNBCompon: TcxGridDBColumn;
    GT_ResourcesIcon: TcxGridDBColumn;
    GT_ResourcesPriceNB: TcxGridDBColumn;
    Act_LoadPricesFromNB: TAction;
    N3: TMenuItem;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    GT_ResourcesID: TcxGridDBColumn;
    GT_ResourcesAdress: TcxGridDBColumn;
    cbShowConnectForm: TRzCheckBox;
    N4: TMenuItem;
    Action1: TAction;
    DStatus: TEdit;
    tbExportToCSV: TToolButton;
    SaveDialog1: TSaveDialog;
    ToolButton5: TToolButton;
    procedure gbOkCancelResize(Sender: TObject);
    procedure mtResourcesBeforeEdit(DataSet: TDataSet);
    procedure mtResourcesAfterEdit(DataSet: TDataSet);
    procedure FormCreate(Sender: TObject);
    procedure GT_ResourcesPricePropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure GT_ResourcesCostPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure neTotalCostChange(Sender: TObject);
    procedure GT_ResourcesEditing(Sender: TcxCustomGridTableView;
      AItem: TcxCustomGridTableItem; var AAllow: Boolean);
    procedure GT_ResourcesEditValueChanged(Sender: TcxCustomGridTableView;
      AItem: TcxCustomGridTableItem);
    procedure Timer_DefineTotalCostTimer(Sender: TObject);
    procedure Timer_PostResourcesTimer(Sender: TObject);
    procedure Act_ReplaceComponentExecute(Sender: TObject);
    procedure Act_DelComponentExecute(Sender: TObject);
    procedure GT_ResourcesNppGetDisplayText(Sender: TcxCustomGridTableItem;
      ARecord: TcxCustomGridRecord; var AText: String);
    procedure btApplyClick(Sender: TObject);
    procedure GT_ResourcesIzmGetDisplayText(Sender: TcxCustomGridTableItem;
      ARecord: TcxCustomGridRecord; var AText: String);
    procedure GT_ResourcesPriceGetDisplayText(
      Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
      var AText: String);
    procedure GT_ResourcesInitEdit(Sender: TcxCustomGridTableView;
      AItem: TcxCustomGridTableItem; AEdit: TcxCustomEdit);
    procedure GT_ResourcesKolvoGetDisplayText(
      Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
      var AText: String);
    procedure GT_ResourcesFocusedRecordChanged(
      Sender: TcxCustomGridTableView; APrevFocusedRecord,
      AFocusedRecord: TcxCustomGridRecord;
      ANewItemRecordFocusingChanged: Boolean);
    procedure GT_ResourcesCustomDrawCell(Sender: TcxCustomGridTableView;
      ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo;
      var ADone: Boolean);
    procedure Act_LoadPricesFromNBExecute(Sender: TObject);
    procedure GT_ResourcesPriceNBPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure neTotalCostKeyPress(Sender: TObject; var Key: Char);
    procedure neTotalCostExit(Sender: TObject);

    procedure btOKClick(Sender: TObject);
    procedure btCancelClick(Sender: TObject);

    procedure GT_ResourcesDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure GT_ResourcesDragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure gridResourcesDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    //procedure FormShow(Sender: TObject);
    Procedure CheckAddCableToList(var aList: TSCSComponents; aCompon: TSCSComponent);
    procedure FormShow(Sender: TObject);
    procedure Action1Execute(Sender: TObject);
    procedure GT_ResourcesIconPropertiesChange(Sender: TObject);
    procedure GT_ResourcesNamePropertiesChange(Sender: TObject);
    procedure GT_ResourcesArticulProducerPropertiesChange(Sender: TObject);
    procedure GT_ResourcesArticulDistributorPropertiesChange(Sender: TObject);
    procedure GT_ResourcesProducerNamePropertiesChange(Sender: TObject);
    procedure GT_ResourcesIzmPropertiesChange(Sender: TObject);
    procedure GT_ResourcesPricePropertiesChange(Sender: TObject);
    procedure GT_ResourcesCostPropertiesChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure gridResourcesMouseLeave(Sender: TObject);
    procedure gridResourcesEndDrag(Sender, Target: TObject; X, Y: Integer);
    procedure FormMouseLeave(Sender: TObject);
    procedure tbExportToCSVClick(Sender: TObject);
    procedure ToolButton5Click(Sender: TObject);
  private
    GForm: TForm;
    FCanHaveActiveComponents: Boolean;
    FCanHaveDismountAccount: Boolean;
    FComponsWithZeroPrice: Boolean;
    FFormMode: TResourceReportFormMode;
    FFolder: TSCSCatalog;
    FLastTotalCost: Double;
    FNormResources: TSCSNormsResources;
    FReportName: String;

    Edit: TcxCustomEdit;
    //Colmn Indexes
    FTransToUOMIdx: Integer;
    FExecuteResult: Boolean; // Tolik 15/04/2021 --
    FisDropComponent: Boolean;
    FIsEdited: Boolean; // Tolik 06/05/2021 -- флаг редактирования

    procedure DefineTotalCost;
    procedure PrepareForm;
    function OnPriceValidate(const aFieldName: String; var aDisplayValue: Variant): Double;
    procedure OnTotalCostChange;
    procedure SendPriceAndCostToCurrRecord(APrice, ACost: Double);
    procedure SendStringToCurrRecord(AFieldName, AValue: String);
    procedure SendFromMTToObjects;
    procedure SendProducersToMT;
    procedure SendResourcesToMT;
    procedure SetActions;
  public
    constructor Create(AOwner: TComponent; AForm: TForm); overload;
    destructor Destroy; override;

    function Execute(AFolder: TSCSCatalog; const AReportName: String;
              AFormMode: TResourceReportFormMode; ACanHaveActiveComponents, ACanHaveDismountAccount, AComponsWithZeroPrice: Boolean): Boolean;
    property ExecuteResult: Boolean read FExecuteResult write FExecuteResult; // Tolik 15/04/2021 --; // Tolik 15/04/2021 --; // Tolik 15/04/2021 --
    property isDropComponent: Boolean read FisDropComponent write FisDropComponent;
    // Tolik 29/04/2021 --
    Property CanHaveActiveComponents: Boolean read FCanHaveActiveComponents;
    Property CanHaveDismountAccount: Boolean read FCanHaveDismountAccount;
    Property ComponsWithZeroPrice: Boolean read FComponsWithZeroPrice;
    Property FormMode: TResourceReportFormMode read FFormMode;
    Property Folder: TSCSCatalog read FFolder;
    Property ReportName: String read FReportName;
    Property IsEdited: Boolean read FIsEdited write FIsEdited;
  end;

//var
  //F_ReportForm: TF_ReportForm;

implementation
Uses U_Main, Unit_DM_SCS, U_DMCommon, U_Constants, USCS_Main, U_ResourceReport;
{$R *.dfm}

{ TF_ReportForm }

constructor TF_ReportForm.Create(AOwner: TComponent; AForm: TForm);
begin
  GForm := AForm;
  inherited Create(AOwner);
  isDropComponent := false;
  IsEdited := False; // Tolik 06/05/2021 --
end;

destructor TF_ReportForm.Destroy;
begin
  inherited;
end;

Procedure TF_ReportForm.CheckAddCableToList(var aList: TSCSComponents; aCompon: TSCSComponent);
var i: integer;
   CanAddCable: Boolean;
begin
  CanAddCable := True;
  for i := 0 to aList.Count - 1 do
  begin
    if aList[i].Whole_ID = aCompon.Whole_ID  then
    begin
      CanAddCable := False;
      break;
    end;
  end;
  if CanAddCable then
    aList.Add(aCompon);
end;

function TF_ReportForm.Execute(AFolder: TSCSCatalog; const AReportName: String;
  AFormMode: TResourceReportFormMode; ACanHaveActiveComponents, ACanHaveDismountAccount, AComponsWithZeroPrice: Boolean): Boolean;
begin
  Result := false;
  isDropComponent := False;
  IsEdited := False; // Tolik 06/05/2021 --
  if AFolder <> nil then
  begin
    FFolder := AFolder;
    FFormMode := AFormMode;
    FCanHaveActiveComponents := ACanHaveActiveComponents;
    FCanHaveDismountAccount := ACanHaveDismountAccount;
    FComponsWithZeroPrice := AComponsWithZeroPrice;
    FReportName := AReportName;
    FLastTotalCost := -1;
    FNormResources := nil;

    mtProducers.Active := False;
    mtProducers.Active := True;

    mtResources.Active := False;
    mtResources.Active := True;

    PrepareForm;
    SendProducersToMT;
    SendResourcesToMT;
    // Если с отчетов пришли - закрыть форму отчетов, а то из-за модального режима формы отчетов не сможем драг дропать на форму из нормативки
    if Assigned(GForm) then
      if Assigned(TF_Main(GForm).F_ResourceReport) then
        if TF_Main(GForm).F_ResourceReport.Visible then
          TF_Main(GForm).F_ResourceReport.Close;

    if not Self.Showing then
      show;
    {try
      if ShowModal = mrOk then
      begin
        Result := true;
        SendFromMTToObjects;
      end;
    finally
      if FNormResources <> nil then
        FreeAndNil(FNormResources);
    end;
    }
  end;
end;



procedure TF_ReportForm.gbOkCancelResize(Sender: TObject);
begin
  SetMiddleControlChilds(TControl(Sender), TControl(Self));
end;

procedure TF_ReportForm.gridResourcesDragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
var i, j: integer;
    Dataset: TDataset;
    HitTest: TcxCustomGridHitTest;
    NamePath: String;
    RecordIndex: integer;
    GRec: TcxGridDatarow;
    ComponGuid: String;
    SCSCompon: TSCSComponent;
    ComponList: TSCscomponents;
    GroupResource: TSCSResourceGroup;
    BookMark: TbookMark;
begin
  //
//  Accept := True;
 //TcxGridSite(Sender).BeginDrag(False);
end;

procedure TF_ReportForm.gridResourcesEndDrag(Sender, Target: TObject; X,
  Y: Integer);
begin
  DStatus.text := '';
end;

procedure TF_ReportForm.gridResourcesMouseLeave(Sender: TObject);
begin
  DStatus.text := '';
end;

procedure TF_ReportForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if IsEdited then
  begin
    if MessageBox(Self.Handle, PChar(cQuastSaveChanging), PChar(cResourceReport_Msg1_6), MB_YESNO) = ID_Yes then
    begin
      ExecuteResult := True;
      SendFromMTToObjects;
    end;
  end;
end;

procedure TF_ReportForm.FormCreate(Sender: TObject);
var
  i: Integer;
  Action: TAction;
  ImgCbProps: TcxImageComboBoxProperties;

  procedure AddItemToImgCbProps(AImageIndex: Integer);
  var
    ImgCbItem: TcxImageComboBoxItem; //}TCollectionItem;
  begin
    ImgCbItem := TcxImageComboBoxItem(ImgCbProps.Items.Add);
    ImgCbItem.Value := AImageIndex;
    ImgCbItem.ImageIndex := AImageIndex;
  end;

begin
  ExecuteResult := False; // Tolik 15/04/2021 --
  for i := 0 to ActionManager.ActionCount - 1 do
  begin
    Action := TAction(ActionManager.Actions[i]);
    Action.Hint := Action.Caption;
  end;

  mtResources.FieldDefs.Add(fnID, ftAutoInc);
  mtResources.FieldDefs.Add(fnGuid, ftString, 40);
  mtResources.FieldDefs.Add(fnIsResource, ftBoolean);
  mtResources.FieldDefs.Add(fnIsModified, ftBoolean);
  mtResources.FieldDefs.Add(fnObjectAddress, ftInteger);
  mtResources.FieldDefs.Add(fnTransToUOM, ftBoolean);
  mtResources.FieldDefs.Add(fnGuidNBComponent, ftString, 40);
  mtResources.FieldDefs.Add(fnIconType, ftInteger);

  mtResources.FieldDefs.Add(fnName, ftString, 255);
  mtResources.FieldDefs.Add(fnArticulProducer, ftString, 255);
  mtResources.FieldDefs.Add(fnArticulDistributor, ftString, 255);
  mtResources.FieldDefs.Add(fnGuidProducer, ftString, 255);
  mtResources.FieldDefs.Add(fnIzm, ftString, 50);
  mtResources.FieldDefs.Add(fnFirstKolvo, ftFloat);
  mtResources.FieldDefs.Add(fnFirstPrice, ftFloat);
  mtResources.FieldDefs.Add(fnKolvo, ftFloat);
  mtResources.FieldDefs.Add(fnPrice, ftFloat);
  mtResources.FieldDefs.Add(fnCost, ftFloat);
  mtResources.FieldDefs.Add(fnPriceNB, ftFloat);

  mtProducers.FieldDefs.Add(fnID, ftInteger);
  mtProducers.FieldDefs.Add(fnGuid, ftString, 40);
  mtProducers.FieldDefs.Add(fnName, ftString, 255);

  ImgCbProps := TcxImageComboBoxProperties(GT_ResourcesIcon.Properties);
  ImgCbProps.Images := TF_Main(GForm).DM.ImageList_Dir;
  ImgCbProps.LargeImages := TF_Main(GForm).DM.ImageList_Dir;
  AddItemToImgCbProps(tciiComponLine);
  AddItemToImgCbProps(tciiComponCon);
  AddItemToImgCbProps(tciiTemplateLine);
  AddItemToImgCbProps(tciiTemplateCon);

  if GReadOnlyMode then
  begin
    btOk.Enabled := False;
    btApply.Enabled := False;
    ToolBar1.Enabled := False;
  end;
end;

procedure TF_ReportForm.FormMouseLeave(Sender: TObject);
begin
  DStatus.Text := '';
end;

procedure TF_ReportForm.FormShow(Sender: TObject);
begin
  isDropComponent := false;
  tbExportToCSV.Enabled := (mtResources.RecordCount > 0);
  lbTotalCost.Left :=  neTotalCost.Left - 20 - lbTotalCost.Width;
end;

procedure TF_ReportForm.PrepareForm;
var
  CurrencyName: String;
begin
  gbOkCancelResize(gbOkCancel);
  Caption := FReportName + ' - ' + FFolder.GetNameForVisible;

  CurrencyName := TF_Main(GForm).GCurrencyM.NameBrief;
  if CurrencyName <> '' then
    CurrencyName := ', ' + CurrencyName;

  FTransToUOMIdx := GT_ResourcesTransformToUOM.Index;
  SetCxCurrencyEditProperties(GT_ResourcesPrice.Properties); //29.08.2012 TcxCurrencyEditProperties(GT_ResourcesPrice.Properties).DisplayFormat := GetDisplayFormatForFloat;
  SetCxCurrencyEditProperties(GT_ResourcesCost.Properties); //29.08.2012 TcxCurrencyEditProperties(GT_ResourcesCost.Properties).DisplayFormat := GetDisplayFormatForFloat;
  SetCxCurrencyEditProperties(GT_ResourcesPriceNB.Properties); //29.08.2012 TcxCurrencyEditProperties(GT_ResourcesPriceNB.Properties).DisplayFormat := GetDisplayFormatForFloat;

  neTotalCost.DisplayFormat := GetDisplayFormatForFloat; //GetDisplayFormat(TF_Main(GForm).GCurrencyM.NameBrief);
  neTotalCost.IntegersOnly := false;

  GT_ResourcesPrice.Caption := cReportForm_Msg1 + CurrencyName;
  GT_ResourcesCost.Caption := cReportForm_Msg2 + CurrencyName;
  GT_ResourcesPriceNB.Caption := cReportForm_Msg1_2 + CurrencyName;
  lbTotalCost.Caption := cReportForm_Msg3 + CurrencyName;
end;

function TF_ReportForm.OnPriceValidate(const aFieldName: String; var aDisplayValue: Variant): Double;
var
  OldPrice: Double;
  NewPrice: Double;
begin
  OldPrice := mtResources.FieldByName(aFieldName).AsFloat;
  if aDisplayValue = '' then
  begin
    aDisplayValue := FloatToStr(OldPrice);
    Exit; ///// EXIT /////
  end;
  NewPrice := StrToFloat_My(aDisplayValue);
  // Преобразуем цену из TF_Main(GForm).FUOM на метр
  if mtResources.FieldByName(fnTransToUOM).AsBoolean then
  begin
    NewPrice := FloatInUOM(NewPrice, umMetr, TF_Main(GForm).FUOM);
    if NewPrice <> OldPrice then
    begin
      mtResources.Edit;
      mtResources.FieldByName(aFieldName).AsFloat := NewPrice;
      mtResources.Post;
    end;
  end;
  Result := NewPrice;
  if OldPrice = NewPrice then
    Exit; ///// EXIT /////

end;

procedure TF_ReportForm.OnTotalCostChange;
var
  NewValue: Double;
  PercentFromLast: Double;

  RecordCost: Double;
  RecordPrice: Double;

  RecNo: Integer;
  i: Integer;
begin
  NewValue := neTotalCost.Value;
  if NewValue = 0 then
  begin
    neTotalCost.OnChange := nil;
    try
      neTotalCost.Value := FLastTotalCost;
    finally
      neTotalCost.OnChange := neTotalCostChange;
    end;
    Exit; ///// EXIT /////
  end;
  if mtResources.Active then // Tolik 09/02/2022 --
  begin
    // Tolik 28/12/2019 --
    if mtResources.RecordCount > 0 then
    begin
      PercentFromLast := RoundX((NewValue * 100) / FLastTotalCost, 20);
      RecNo := mtResources.RecNo;
      mtResources.DisableControls;
      try
        for i := 0 to mtResources.RecordCount - 1 do
        begin
          mtResources.RecNo := i+1;

          RecordCost := mtResources.FieldByName(fnCost).AsFloat;
          RecordCost := RecordCost * (PercentFromLast / 100);
          RecordPrice := RoundCP(RecordCost / mtResources.FieldByName(fnKolvo).AsFloat);

          SendPriceAndCostToCurrRecord(RecordPrice, RecordCost);
        end;
        mtResources.RecNo := RecNo;
      finally
        mtResources.EnableControls;
      end;
    end;
    FLastTotalCost := NewValue;
  end;
end;

procedure TF_ReportForm.mtResourcesBeforeEdit(DataSet: TDataSet);
begin
  //beep;
end;

procedure TF_ReportForm.mtResourcesAfterEdit(DataSet: TDataSet);
begin
  if DataSet.State <> dsBrowse then
    DataSet.FieldByName(fnIsModified).AsBoolean := true;
end;

procedure TF_ReportForm.SendStringToCurrRecord(AFieldName, AValue: String);
begin
  mtResources.Edit;
  mtResources.FieldByName(AFieldName).AsString := AValue;
  mtResources.Post;
end;

procedure TF_ReportForm.SendFromMTToObjects;
var
  ResourceGroup: TSCSResourceGroup;
  SCSComponent: TSCSComponent;
  PartComponent: TSCSComponent;

  ResourceRel: TSCSResourceRel;

  ChangedComponents: TSCSComponents;
  RecNo: Integer;
  i, j, k: Integer;
  IsRecalcTotal: Boolean;
begin
  ChangedComponents := TSCSComponents.Create(false);

  if mtResources.RecordCount > 0 then // Tolik 28/12/2019 --
  begin
    RecNo := mtResources.RecNo;
    mtResources.DisableControls;
    try
      IsRecalcTotal := false;
      for i := 0 to mtResources.RecordCount - 1 do
      begin
        mtResources.RecNo := i+1;
        if GT_ResourcesPriceNB.Visible then
          if mtResources.FieldByName(fnPriceNB).Value <> null then
          begin
            mtResources.Edit;
            mtResources.FieldByName(fnPrice).AsFloat := mtResources.FieldByName(fnPriceNB).AsFloat;
            mtResources.FieldByName(fnCost).AsFloat := mtResources.FieldByName(fnPrice).AsFloat * mtResources.FieldByName(fnKolvo).AsFloat;
            mtResources.FieldByName(fnIsModified).AsBoolean := true;
            mtResources.Post;
            IsRecalcTotal := true;
          end;

        if mtResources.FieldByName(fnIsModified).AsBoolean then
        begin
          ResourceGroup := TSCSResourceGroup(mtResources.FieldByName(fnObjectAddress).AsInteger);
          if Assigned(ResourceGroup) then
            for j := 0 to ResourceGroup.ObjectList.Count - 1 do
            begin
              case ResourceGroup.ServIsResource of
                False:
                  begin
                    SCSComponent := TSCSComponent(ResourceGroup.ObjectList[j]);

                    SCSComponent.Name := mtResources.FieldByName(fnName).AsString;
                    SCSComponent.ArticulDistributor := mtResources.FieldByName(fnArticulDistributor).AsString;
                    SCSComponent.ArticulProducer := mtResources.FieldByName(fnArticulProducer).AsString;
                    SCSComponent.Izm := mtResources.FieldByName(fnIzm).AsString;
                    SCSComponent.Price := mtResources.FieldByName(fnPrice).AsFloat;
                    SCSComponent.GUIDProducer := mtResources.FieldByName(fnGuidProducer).AsString;
                    if SCSComponent.GUIDProducer <> '' then
                      SCSComponent.ID_Producer := TF_Main(GForm).FNormBase.DM.GetIntFromTableByGUID(tnProducers, fnID, SCSComponent.GUIDProducer, qmPhisical)
                    else
                      SCSComponent.ID_Producer := 0;

                    ChangedComponents.Add(SCSComponent);

                    if SCSComponent.IsLine = biTrue then
                    begin
                      SCSComponent.LoadWholeComponent(false);
                      for k := 0 to SCSComponent.WholeComponent.Count - 1 do
                      begin
                        PartComponent := TF_Main(GForm).GSCSBase.CurrProject.GetComponentFromReferences(SCSComponent.WholeComponent[k]);

                        if PartComponent <> SCSComponent then
                        begin
                          PartComponent.Name := SCSComponent.Name;
                          PartComponent.ArticulDistributor := SCSComponent.ArticulDistributor;
                          PartComponent.ArticulProducer := SCSComponent.ArticulProducer;
                          PartComponent.Izm := SCSComponent.Izm;
                          PartComponent.Price := SCSComponent.Price;
                          PartComponent.GUIDProducer := SCSComponent.GUIDProducer;
                          PartComponent.ID_Producer := SCSComponent.ID_Producer;

                          ChangedComponents.Add(PartComponent);
                        end;
                      end;
                    end;
                  end;
                True:
                  begin
                    ResourceRel := TSCSResourceRel(ResourceGroup.ObjectList[j]);

                    ResourceRel.Name := mtResources.FieldByName(fnName).AsString;
                    ResourceRel.Izm := mtResources.FieldByName(fnIzm).AsString;
                    ResourceRel.Price := mtResources.FieldByName(fnPrice).AsFloat;
                    ResourceRel.CalcCost;
                  end;
              end;
            end;
          mtResources.Edit;
          mtResources.FieldByName(fnIsModified).AsBoolean := False;
          mtResources.FieldByName(fnPriceNB).Value := null;
          mtResources.Post;
        end;
      end;

      for i := 0 to ChangedComponents.Count - 1 do
      begin
        SCSComponent := ChangedComponents[i];
        TF_Main(GForm).CalcPriceForParents(SCSComponent.ID);
      end;

      if IsRecalcTotal then
        Timer_DefineTotalCost.Enabled := true;
    finally
      mtResources.RecNo := RecNo;
      mtResources.EnableControls;
      FreeAndNil(ChangedComponents);
      //GT_ResourcesPriceNB.Visible := false;
    end;
  end;
end;

procedure TF_ReportForm.SendProducersToMT;
var
  //AllProducers: TList;
  //ptrProducer: PProducer;
  Spravochnik: TSpravochnik;
  SprProducer: TNBProducer;
  i: Integer;
begin
  //AllProducers := TF_Main(GForm).FNormBase.DM.GetAllProducers;
  try
    mtProducers.Active := false;
    mtProducers.Active := true;
    mtProducers.DisableControls;

    {mtProducers.Append;
    mtProducers.FieldByName(fnID).AsInteger := 0;
    mtProducers.FieldByName(fnGUID).AsString := '';
    mtProducers.FieldByName(fnName).AsString := '';
    mtProducers.Post;}

    Spravochnik := TF_Main(GForm).GSCSBase.CurrProject.Spravochnik;

    for i := 0 to Spravochnik.Producers.Count - 1 do
    begin
      SprProducer := TNBProducer(Spravochnik.Producers[i]);

      mtProducers.Append;
      mtProducers.FieldByName(fnID).AsInteger := SprProducer.ID;
      mtProducers.FieldByName(fnGUID).AsString := SprProducer.GUID;
      mtProducers.FieldByName(fnName).AsString := SprProducer.Name;
      mtProducers.Post;
    end;
  finally
    mtProducers.EnableControls;
    mtProducers.SortOn(fnName, []);
  end;
end;

procedure TF_ReportForm.SendResourcesToMT;
var
  ResourceRel: TSCSResourceGroup;
  ResourceCompon: TSCSComponent;
  ComponImageIndex: Integer;
  i: Integer;
begin
  BeginProgress(pcPreparingReport);
  try

    FNormResources := FFolder.GetAllNormsResources([nrResources, nrAccessories, nrComponents],
                          false, FCanHaveActiveComponents, FCanHaveDismountAccount, FComponsWithZeroPrice);
    //mtResources.AfterPost := nil;
    mtResources.DisableControls;
    try
      mtResources.Active := false;
      mtResources.Active := true;

      for i := 0 to FNormResources.Resources.Count - 1 do
      begin
        ResourceRel := TSCSResourceGroup(FNormResources.Resources[i]);
        ComponImageIndex := -1;

        mtResources.Append;
        mtResources.FieldByName(fnGuid).AsString := ResourceRel.GuidNB;
        mtResources.FieldByName(fnIsResource).AsBoolean := ResourceRel.ServIsResource;
        mtResources.FieldByName(fnIsModified).AsBoolean := false;
        mtResources.FieldByName(fnObjectAddress).AsInteger := Integer(ResourceRel);
        if ResourceRel.ServIsResource then
          mtResources.FieldByName(fnTransToUOM).AsBoolean := false
        else
        if ResourceRel.ObjectList.Count > 0 then
        begin
          ResourceCompon := TSCSComponent(ResourceRel.ObjectList[0]);
          if CheckPriceTransformToUOMByCompType(@ResourceCompon.ComponentType) then//26.05.2009 if CheckPriceTransformToUOMByCompType(@TSCSComponent(ResourceRel.ObjectList[0]).ComponentType) then
            mtResources.FieldByName(fnTransToUOM).AsBoolean := true;

          // Иконка компонента
          case ResourceCompon.IsLine of
            biTrue:
              if ResourceCompon.IsTemplate = biTrue then
                ComponImageIndex := tciiTemplateLine
              else
                ComponImageIndex := tciiComponLine;
            biFalse:
              if ResourceCompon.IsTemplate = biTrue then
                ComponImageIndex := tciiTemplateCon
              else
                ComponImageIndex := tciiComponCon;
          end;
        end;
        mtResources.FieldByName(fnGuidNBComponent).AsString := ResourceRel.GUIDNBComponent;
        if Not ResourceRel.ServIsResource then
          mtResources.FieldByName(fnGuidNBComponent).AsString := ResourceRel.GuidNB;
        mtResources.FieldByName(fnIconType).AsInteger := ComponImageIndex;

        mtResources.FieldByName(fnName).AsString := ResourceRel.Name;
        mtResources.FieldByName(fnArticulProducer).AsString := ResourceRel.ArtProducer;
        mtResources.FieldByName(fnArticulDistributor).AsString := ResourceRel.ArtDistributor;
        mtResources.FieldByName(fnGuidProducer).AsString := ResourceRel.GUIDProducer; //}TF_Main(GForm).FNormBase.DM.GetStringFromTableByGUID(tnProducers, fnName, ResourceRel.GUIDProducer, qmPhisical);
        mtResources.FieldByName(fnIzm).AsString := ResourceRel.Izm;
        mtResources.FieldByName(fnFirstKolvo).AsFloat := Round3(ResourceRel.Kolvo);
        mtResources.FieldByName(fnFirstPrice).AsFloat := Round3(ResourceRel.Price);
        mtResources.FieldByName(fnKolvo).AsFloat := Round3(ResourceRel.Kolvo);
        mtResources.FieldByName(fnPrice).AsFloat := Round3(ResourceRel.Price);
        mtResources.FieldByName(fnCost).AsFloat := Round3(ResourceRel.Cost);
        mtResources.Post;

        //TotalCost := TotalCost + ResourceRel.Cost;
      end;
      mtResources.SortOn(fnName, []);
    finally
      mtResources.EnableControls;
      //mtResources.AfterPost := mtResourcesAfterPost;
      if mtResources.RecordCount > 0 then
        mtResources.First;
    end;
  finally
    EndProgress;
  end;
  DefineTotalCost;
  SetActions;
end;

procedure TF_ReportForm.SetActions;
begin
  Act_ReplaceComponent.Enabled := mtResources.RecordCount > 0;
  Act_DelComponent.Enabled := mtResources.RecordCount > 0;
end;
//Tolik 07/02/2022 --
procedure TF_ReportForm.tbExportToCSVClick(Sender: TObject);
var fName, s: string;
    BookMark: TBookmark;
    i: integer;
    f: TextFile;
    CanSave: Boolean;
begin
  Try
    if SaveDialog1.Execute(TF_Main(F_ProjMan).F_ReportForm.Handle) then
    begin
      fName := SaveDialog1.FileName;
      canSave := True;
      if FileExists(fName) then
        CanSave := (MessageQuastYN(fName+' '+cMain_Mes131) = IDYES);

      //if not FileExists(fName) then
      if CanSave then
      begin
        AssignFile(f, fName);
        Rewrite(f);
        s := GT_ResourcesNpp.Caption + ';' + GT_ResourcesName.Caption + ';' + GT_ResourcesArticulProducer.Caption + ';' +
             GT_ResourcesArticulDistributor.Caption + ';' + GT_ResourcesProducerName.Caption + ';' +
             GT_ResourcesKolvo.Caption + ';' + GT_ResourcesIzm.Caption + ';' + GT_ResourcesPrice.Caption + ';' +
             GT_ResourcesCost.Caption + ';' + GT_ResourcesPriceNB.Caption;
        writeln(f,s);

      end;

      try
        BookMark := mtResources.GetBookmark;
        mtResources.First;
        i := 1;
        while not mtResources.Eof do
        begin
          s := inttostr(i) + ';' +
          mtResources.FieldByName(fnName).AsString  + ';' +
          mtResources.FieldByName(fnArticulProducer).AsString + ';' +
          mtResources.FieldByName(fnArticulDistributor).AsString + ';' +
          mtResources.FieldByName(fnGuidProducer).AsString + ';' +
          mtResources.FieldByName(fnKolvo).AsString + ';' +
          mtResources.FieldByName(fnIzm).AsString + ';' +
          mtResources.FieldByName(fnPrice).AsString + ';' +
          mtResources.FieldByName(fnCost).AsString + ';' +
          mtResources.FieldByName(fnPriceNB).AsString;

          writeln(f,s);
          mtResources.Next;
          inc(i);
        end;
      finally
        mtResources.GOTOBookmark(BookMark);
        mtResources.FreeBookmark(BookMark);
        CloseFile(f);
      end;
    end;
  Except
    on e: Exception do;
  End;
end;
//

procedure TF_ReportForm.DefineTotalCost;
var
  RecNo: Integer;
  i: Integer;
  CurrCost: Double;

  SavedOnChange: TNotifyevent;
begin
  CurrCost := 0;

  if mtResources.RecordCount > 0 then
  begin
    RecNo := mtResources.RecNo;
    mtResources.DisableControls;
    try
      for i := 0 to mtResources.RecordCount - 1 do
      begin
        mtResources.RecNo := i+1;
        CurrCost := CurrCost + mtResources.FieldByName(fnCost).AsFloat;
      end;
    finally
      mtResources.EnableControls;
      mtResources.RecNo := RecNo;
    end;
  end;
  FLastTotalCost := CurrCost;

  SavedOnChange := neTotalCost.OnChange;
  neTotalCost.OnChange := nil;
  try
    neTotalCost.Value := CurrCost;
  finally
    neTotalCost.OnChange := SavedOnChange;
  end;
end;

procedure TF_ReportForm.GT_ResourcesPricePropertiesChange(Sender: TObject);
begin
  IsEdited := True;
end;

procedure TF_ReportForm.GT_ResourcesPricePropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
var
  //OldPrice: Double;
  NewPrice: Double;
  NewCost: Double;
begin
  TcxCurrencyEditProperties(GT_ResourcesPrice.Properties).OnValidate := nil;
  try
    {//28.08.2012
    OldPrice := mtResources.FieldByName(fnPrice).AsFloat;
    if DisplayValue = '' then
    begin
      DisplayValue := FloatToStr(OldPrice);
      Exit; ///// EXIT /////
    end;
    NewPrice := StrToFloat_My(DisplayValue);
    // Преобразуем цену из TF_Main(GForm).FUOM на метр
    if mtResources.FieldByName(fnTransToUOM).AsBoolean then
    begin
      NewPrice := FloatInUOM(NewPrice, umMetr, TF_Main(GForm).FUOM);
      if NewPrice <> OldPrice then
      begin
        mtResources.Edit;
        mtResources.FieldByName(fnPrice).AsFloat := NewPrice;
        mtResources.Post;
      end;
    end;
    if OldPrice = NewPrice then
      Exit; ///// EXIT /////}
    NewPrice := OnPriceValidate(fnPrice, DisplayValue);

    NewCost := NewPrice * mtResources.FieldByName(fnKolvo).AsFloat;
    SendPriceAndCostToCurrRecord(NewPrice, NewCost);
    Timer_DefineTotalCost.Enabled := true;
  finally
    TcxCurrencyEditProperties(GT_ResourcesPrice.Properties).OnValidate := GT_ResourcesPricePropertiesValidate;
  end;
end;

procedure TF_ReportForm.GT_ResourcesProducerNamePropertiesChange(
  Sender: TObject);
begin
   IsEdited := True;
end;

procedure TF_ReportForm.GT_ResourcesPriceNBPropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
begin
  TcxCurrencyEditProperties(GT_ResourcesPriceNB.Properties).OnValidate := nil;
  try
    OnPriceValidate(fnPriceNB, DisplayValue);
  finally
    TcxCurrencyEditProperties(GT_ResourcesPriceNB.Properties).OnValidate := GT_ResourcesPricePropertiesValidate;
  end;
end;


procedure TF_ReportForm.GT_ResourcesArticulDistributorPropertiesChange(
  Sender: TObject);
begin
   IsEdited := True;
end;

procedure TF_ReportForm.GT_ResourcesArticulProducerPropertiesChange(
  Sender: TObject);
begin
   IsEdited := True;
end;

procedure TF_ReportForm.GT_ResourcesCostPropertiesChange(Sender: TObject);
begin
  IsEdited := True;
end;

procedure TF_ReportForm.GT_ResourcesCostPropertiesValidate(Sender: TObject;
  var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
var
  OldCost: Double;
  NewPrice: Double;
  NewCost: Double;
begin
  TcxCurrencyEditProperties(GT_ResourcesCost.Properties).OnValidate := nil;
  try
    OldCost := mtResources.FieldByName(fnCost).AsFloat;
    if DisplayValue = '' then
    begin
      DisplayValue := FloatToStr(OldCost);
      Exit; ///// EXIT /////
    end;
    NewCost := StrToFloat_My(DisplayValue);
    if OldCost = NewCost then
      Exit; ///// EXIT /////

    NewPrice := RoundCP(NewCost / mtResources.FieldByName(fnKolvo).AsFloat);
    SendPriceAndCostToCurrRecord(NewPrice, NewCost);
    Timer_DefineTotalCost.Enabled := true;
  finally
    TcxCurrencyEditProperties(GT_ResourcesCost.Properties).OnValidate := GT_ResourcesCostPropertiesValidate;
  end;
end;

procedure TF_ReportForm.SendPriceAndCostToCurrRecord(APrice,
  ACost: Double);
begin
  mtResources.Edit;
  mtResources.FieldByName(fnPrice).AsFloat := APrice;
  mtResources.FieldByName(fnCost).AsFloat := ACost;
  mtResources.FieldByName(fnIsModified).AsBoolean := true;
  mtResources.Post;
end;

procedure TF_ReportForm.neTotalCostChange(Sender: TObject);
begin
  IsEdited := true;
  OnTotalCostChange;
end;

procedure TF_ReportForm.GT_ResourcesEditing(Sender: TcxCustomGridTableView;
  AItem: TcxCustomGridTableItem; var AAllow: Boolean);
begin
  //mtResources.Edit;
  //mtResources.FieldByName(fnIsModified).AsBoolean := true;
  //mtResources.Post;
end;

procedure TF_ReportForm.GT_ResourcesEditValueChanged(
  Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem);
begin
  if (Sender.DataController.IsEditing) and (mtResources.State <> dsBrowse) then
  begin
    Timer_PostResources.Enabled := true;
  end;
end;

procedure TF_ReportForm.Timer_DefineTotalCostTimer(Sender: TObject);
begin
  TTimer(Sender).Enabled := false;
  DefineTotalCost;
end;

procedure TF_ReportForm.Timer_PostResourcesTimer(Sender: TObject);
begin
  TTimer(Sender).Enabled := false;
  if mtResources.State <> dsBrowse then
  begin
    GT_Resources.DataController.Post;
  end;
end;

procedure TF_ReportForm.ToolButton5Click(Sender: TObject);
begin
  ShowInvoice;
end;

procedure TF_ReportForm.Act_ReplaceComponentExecute(Sender: TObject);
var
  GroupResource: TSCSResourceGroup;
  ComponentList: TSCSComponents;
  SCSComponent: TSCSComponent;

  NBComponent: TSCSComponent;
  ReplacedComponent: TSCSComponent;
  FirstReplacedComponent: TSCSComponent;
  ComponentIndex: Integer;

  CanReplaceIndexes: TIntList;
  CanReplaceCount: Integer;

  strText: String;
  strWarning: String;

  SelectedRecord: Boolean;

  i: Integer;
  CmpDelta: Double;

begin
  try
    TF_Main(GForm).CreateFConnectComplWith;

    CmpDelta := 1 / Power(10, FloatPrecision);
    GroupResource := nil;
    GroupResource := TSCSResourceGroup(mtResources.FieldByName(fnObjectAddress).AsInteger);
    if GroupResource <> nil then
    begin
      if Not GroupResource.ServIsResource then
      begin
        if GroupResource.ObjectList.Count > 0 then
        begin
          ComponentList := TSCSComponents.Create(false);
          CanReplaceIndexes := TIntList.Create;
          CanReplaceCount := 0;

          try
            for i := 0 to GroupResource.ObjectList.Count - 1 do
            // Tolik 19/04/2021 -- кабель заменяется по всей длине сразу за одно действие, поэтому нужно отобрать
            //                     цельные куски по Whole_ID, иначе будет бить АВ по удаленным в списке
            //ComponentList.Add(TSCSComponent(GroupResource.ObjectList[i]));
            begin
              SCSComponent := TSCSComponent(GroupResource.ObjectList[i]);
              if isCableComponent(SCSComponent) then
                CheckAddCableToList(ComponentList, SCSComponent)
              else
                ComponentList.Add(SCSComponent);
            end;

           { if cbShowConnectForm.checked then
              NBComponent := GDropComponent
            else}
            NBComponent := TF_Main(GForm).CreateFConnectComplWith.DefineReplaceComponent(ComponentList, ComponentIndex, true);

            if NBComponent <> nil then
            begin
              //*** Анализ всех на подкл.
              BeginProgress;
              try
                for i := 0 to ComponentList.Count - 1 do
                begin
                  SCSComponent := ComponentList[i];
                  CanReplaceIndexes.Add(biNone);

                  if (SCSComponent.IsLine = biTrue) or
                     (SCSComponent.Parent is TSCSCatalog) or
                     (TF_Main(GForm).CreateFConnectComplWith.cbApplyForComplects.Checked) then
                  begin
                    if SCSComponent.CanReplaceWithNBCompon(NBComponent, TF_Main(GForm).CreateFConnectComplWith.cbLeaveComplectsInTarget.Checked) = [crcrSuccessful] then
                    begin
                      Inc(CanReplaceCount);
                      CanReplaceIndexes[i] := biTrue;
                    end
                    else
                      CanReplaceIndexes[i] := biFalse;
                  end;
                end;
              finally
                EndProgress;
              end;

              strText := '';
              strWarning := cReportForm_Msg4;
              if CanReplaceIndexes.Count <> CanReplaceCount then
              begin
                strText := cReportForm_Msg5+#13+#10+#13+#10+ strWarning;
              end
              else
                strText := strText + strWarning + #13+#10+ cReportForm_Msg6;


              if MessageModal(strText, ApplicationName, MB_ICONQUESTION or MB_YESNO) = IDYES then
              begin
                ProcessMessagesEx;
                BeginProgress;
                try
                  mtResources.DisableControls;
                  try
                    //if FFolder is TSCSList then
                    //  OpenNoExistsListInCAD(FFolder);

                    FirstReplacedComponent := nil;
                    //*** Заменить компоненты
                    for i := 0 to CanReplaceIndexes.Count - 1 do
                      if CanReplaceIndexes[i] = biTrue then
                      begin
                        SCSComponent := ComponentList[i];
                        //ReplacedComponent := SCSComponent.ReplaceWithNBCompon(NBComponent, TF_Main(GForm).F_ConnectComplWith.cbLeaveComplectsInTarget.Checked);
                        ReplacePMComponResFromNB(SCSComponent, NBComponent, false);
                        ReplacedComponent := ReplacePMComponFromNB(SCSComponent, NBComponent, TF_Main(GForm).CreateFConnectComplWith.cbLeaveComplectsInTarget.Checked);
                        if (FirstReplacedComponent = nil) and (ReplacedComponent <> nil) then
                          FirstReplacedComponent := ReplacedComponent;
                      end;

                    //*** Обновить ведомость ресурсов
                    if FNormResources <> nil then
                      FreeAndNil(FNormResources);
                    SendResourcesToMT;

                    //*** Выделить позицию с замененной компонентой
                    SelectedRecord := false;
                    if FirstReplacedComponent <> nil then
                      for i := 0 to mtResources.RecordCount - 1 do
                      begin
                        mtResources.RecNo := i+1;
                        if (mtResources.FieldByName(fnIsResource).AsBoolean = false) and
                           (mtResources.FieldByName(fnGuid).AsString = FirstReplacedComponent.GuidNB) and
                           (mtResources.FieldByName(fnName).AsString = FirstReplacedComponent.Name) and
                           (mtResources.FieldByName(fnArticulProducer).AsString = FirstReplacedComponent.ArticulProducer) and
                           (mtResources.FieldByName(fnArticulDistributor).AsString = FirstReplacedComponent.ArticulDistributor) and
                           (mtResources.FieldByName(fnGuidProducer).AsString = FirstReplacedComponent.GUIDProducer) and
                           (mtResources.FieldByName(fnIzm).AsString = FirstReplacedComponent.Izm) and
                           (Abs(mtResources.FieldByName(fnPrice).AsFloat - Round3(FirstReplacedComponent.Price)) < CmpDelta) then
                        begin
                          SelectedRecord := true;
                          Break; //// BREAK ////
                        end;
                      end;
                    if Not SelectedRecord then
                      if mtResources.RecordCount > 0 then
                        mtResources.First;
                  finally
                    mtResources.EnableControls;
                  end;
                finally
                  EndProgress;
                end;
              end;
            end;
          finally
            FreeAndNil(ComponentList);
            FreeAndNil(CanReplaceIndexes);
          end;
        end;
      end
      else
        MessageModal(cReportForm_Msg7,
          ApplicationName, MB_ICONINFORMATION or MB_OK);
    end;
  except
    on E: Exception do AddExceptionToLog('TF_ReportForm.Act_ReplaceComponentExecute: '+E.Message);
  end;
end;

procedure TF_ReportForm.Action1Execute(Sender: TObject); // Tolik 06/05/2021 --
var
  CanMessage: Boolean;
  GroupResource: TSCSResourceGroup;
  SCSComponent: TSCSComponent;
begin
  GSelNodeColor := clRed;
  Try
    CanMessage := false;
    GroupResource := nil;
    GroupResource := TSCSResourceGroup(mtResources.FieldByName(fnObjectAddress).AsInteger);
    if GroupResource <> nil then
    begin
      if (Not GroupResource.ServIsResource) and (GroupResource.ObjectList.Count > 0) then
      begin
        SCSComponent := TSCSComponent(GroupResource.ObjectList[0]);
        if SCSComponent <> nil then
        begin
          if F_NormBase.SelectComponInPCObjectsByGUID(SCSComponent.GuidNB) <> nil then
          begin
            if SCSComponent.IsTemplate = biFalse then
              if F_NormBase.FindComponentByGUIDWithBlink(SCSComponent.GuidNB) = nil then
                CanMessage := true;
          end
          else
            CanMessage := true;
        end
        else
          CanMessage := true;
      end
      else
        CanMessage := true;
    end
    else
      CanMessage := true;

    if CanMessage then
      MessageModal(cMain_Msg108, ApplicationName, MB_ICONINFORMATION or MB_OK);
  Except
    on E: Exception do;
  End;
  GSelNodeColor := -1;
end;

procedure TF_ReportForm.Act_DelComponentExecute(Sender: TObject);
var
  GroupResource: TSCSResourceGroup;
  SCSComponent: TSCSComponent;
  WholeComponent: TSCSComponents;
  PartComponent: TSCSComponent;

  CanDeleteComponents: TSCSComponents;
  CanDelete: Boolean;
  strText: String;
  msgStyle: Integer;
  msgResult: Integer;

  i: Integer;
  RecNo: Integer;
begin
  try
    GroupResource := nil;
    GroupResource := TSCSResourceGroup(mtResources.FieldByName(fnObjectAddress).AsInteger);
    if GroupResource <> nil then
    begin
      if (Not GroupResource.ServIsResource) and (GroupResource.ObjectList.Count > 0) then
      begin
        CanDeleteComponents := TSCSComponents.Create(false);
        try
          //*** Анализ на удаление не подключенных компонент
          for i := 0 to GroupResource.ObjectList.Count - 1 do
          begin
            SCSComponent := TSCSComponent(GroupResource.ObjectList[i]);

            case SCSComponent.IsLine of
              biFalse:
                if Not CheckJoinedComponToIsLine(SCSComponent, biTrue, true) or
                  (SCSComponent.ComponentType.SysName = ctsnCableChannelElement) then
                  CanDeleteComponents.Add(SCSComponent);
              biTrue:
                if ((SCSComponent.FirstIDConnectedConnCompon = 0) and (SCSComponent.LastIDConnectedConnCompon = 0)) or
                   (SCSComponent.ComponentType.SysName = ctsnCableChannel) then
                  CanDeleteComponents.Add(SCSComponent);
            end;
          end;

          strText := '';
          msgStyle := MB_ICONQUESTION or MB_YESNO;

          CanDelete := true;
          if (CanDeleteComponents.Count <> GroupResource.ObjectList.Count) then
          begin
            if CanDeleteComponents.Count = 0 then
            begin
              strText := cReportForm_Msg9;
              msgStyle := MB_ICONINFORMATION or MB_OK;
              CanDelete := false;
            end
            else
              strText := cReportForm_Msg10;
          end
          else
            strText := cReportForm_Msg8; //strText := strText + strWarning + #13+#10+ cReportForm_Msg11;
          msgResult := MessageModal(strText, ApplicationName, msgStyle);

          if CanDelete and (msgResult = IDYES) then
          begin
            //if FFolder is TSCSList then
            //  OpenNoExistsListInCAD(FFolder);

            TF_Main(GForm).DelComponentsFromList(TSCSList(FFolder), CanDeleteComponents, true);

            BeginProgress;
            try
              RecNo := mtResources.RecNo;

              {
              //*** Удаление компонент
              while CanDeleteComponents.Count > 0 do
              begin
                SCSComponent := CanDeleteComponents[0];
                CanDeleteComponents.Delete(0);

                if SCSComponent.IsLine = biTrue then
                begin
                  if SCSComponent.ChildComplects.Count > 0 then
                  begin
                    SCSComponent.TreeViewNode := TF_Main(GForm).FindComponOrDirInTree(SCSComponent.ID, true);
                    TF_Main(GForm).MoveComponComplectsToUp(SCSComponent.TreeViewNode);
                  end;
                  WholeComponent := FFolder.GetComponentsByWholeID(SCSComponent.Whole_ID);
                  for i := 0 to WholeComponent.Count - 1 do
                  begin
                    PartComponent := WholeComponent[i];
                    //PartComponent.DisConnectFromParent;
                    TF_Main(GForm).DelCompon(PartComponent, PartComponent.TreeViewNode, true, true, true, false);
                  end;
                end
                else
                begin
                  //SCSComponent.DisConnectFromParent;
                  TF_Main(GForm).DelCompon(SCSComponent, SCSComponent.TreeViewNode, true, true, true, false);
                end;
              end;
              }

              //*** Обновить ведомость ресурсов
              if FNormResources <> nil then
                FreeAndNil(FNormResources);
              SendResourcesToMT;

              //*** Стать на позицию перед удаляемой
              if mtResources.RecordCount > 0 then
              begin
                if RecNo > mtResources.RecordCount + 1 then
                  RecNo := mtResources.RecordCount + 1;
                if RecNo > -1 then // Tolik 28/12/2019 --
                  mtResources.RecNo := RecNo;
              end;
            finally
              EndProgress;
            end;
            //IsEdited := True;
          end;
        finally
          FreeAndNil(CanDeleteComponents);
        end;
      end
      else
        MessageModal(cReportForm_Msg12,
          ApplicationName, MB_ICONINFORMATION or MB_OK);
    end;
    SetActions;
  except
    on E: Exception do AddExceptionToLog('TF_ReportForm.Act_DelComponentExecute: '+E.Message);
  end;
end;

procedure TF_ReportForm.GT_ResourcesNamePropertiesChange(Sender: TObject); // Tolik 06/05/2021 --
begin
  IsEdited := True;
end;

procedure TF_ReportForm.GT_ResourcesNppGetDisplayText(
  Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
  var AText: String);
begin
  AText := IntToStr(ARecord.Index + 1);
end;

procedure TF_ReportForm.btApplyClick(Sender: TObject);
begin
  IsEdited := False;
  SendFromMTToObjects;
end;

// Tolik 15/04/2021 --
procedure TF_ReportForm.btCancelClick(Sender: TObject);
begin
  IsEdited := False;
  ExecuteResult := False;
  if FNormResources <> nil then
        FreeAndNil(FNormResources);
  Close;
end;

procedure TF_ReportForm.btOKClick(Sender: TObject);
begin
  IsEdited := False;
  ExecuteResult := True;
  SendFromMTToObjects;
  Close;
end;
//

procedure TF_ReportForm.GT_ResourcesIzmGetDisplayText(
  Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
  var AText: String);
begin
  try
    if ARecord.Values[FTransToUOMIdx] <> null then
      if ARecord.Values[FTransToUOMIdx] = true then
        AText := GetNameUOM(TF_Main(GForm).FUOM, true);
  except
  end;
end;

procedure TF_ReportForm.GT_ResourcesIzmPropertiesChange(Sender: TObject);
begin
  IsEdited := True;
end;

procedure TF_ReportForm.GT_ResourcesKolvoGetDisplayText(
  Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
  var AText: String);
var
  ValueFloat: Double;
begin
  try
    if ARecord.Values[FTransToUOMIdx] <> null then
      if ARecord.Values[FTransToUOMIdx] = true then
      begin
        ValueFloat := StrToFloat_My(AText);
        ValueFloat := FloatInUOM(ValueFloat, umMetr, TF_Main(GForm).FUOM);
        AText := FloatToStr(RoundCP(ValueFloat));
      end;
  except
  end;
end;

procedure TF_ReportForm.GT_ResourcesPriceGetDisplayText(
  Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
  var AText: String);
begin
  try
    if ARecord.Values[FTransToUOMIdx] <> null then
      if ARecord.Values[FTransToUOMIdx] = true then
        AText := GetDisplayTextToNORMExpenseForLength(AText, TF_Main(GForm).FUOM);
    // Tolik 06/05/2021 --
    if aText <> '' then
      aText := FloatToStr(RoundCP(StrToFloat_My(aText)));
  except
  end;
end;

procedure TF_ReportForm.GT_ResourcesIconPropertiesChange(Sender: TObject); // Tolik 06/05/2021 --
begin
  IsEdited := True;
end;

procedure TF_ReportForm.GT_ResourcesInitEdit(
  Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem;
  AEdit: TcxCustomEdit);
begin
  if (AItem = GT_ResourcesPrice) or (AItem = GT_ResourcesPriceNB) then
    if mtResources.Active then
      if mtResources.FieldByName(fnTransToUOM).AsBoolean then
        AEdit.EditValue := GetDisplayTextToNORMExpenseForLength(AEdit.EditValue, TF_Main(GForm).FUOM);
  Edit := AEdit;
end;

procedure TF_ReportForm.GT_ResourcesFocusedRecordChanged(
  Sender: TcxCustomGridTableView; APrevFocusedRecord,
  AFocusedRecord: TcxCustomGridRecord;
  ANewItemRecordFocusingChanged: Boolean);
var
  CanEditIzm: Boolean;
begin
  CanEditIzm := true;
  if mtResources.Active then
    if mtResources.FieldByName(fnTransToUOM).AsBoolean then
      CanEditIzm := false;
  GT_ResourcesIzm.Options.Editing := CanEditIzm;
end;

procedure TF_ReportForm.GT_ResourcesCustomDrawCell(
  Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
  AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
  OnNormsResourcesCustomDrawCell(ACanvas, AViewInfo, GT_ResourcesIsResource.Index, GT_ResourcesGUIDNBCompon.Index, -1, false);
end;

// Tolik -- 15/04/2021 --
procedure TF_ReportForm.GT_ResourcesDragDrop(Sender, Source: TObject; X,
  Y: Integer);
var i: integer;
    Dataset: TDataset;
    HitTest: TcxCustomGridHitTest;
    RecordIndex: integer;
    GRec: TcxGridDatarow;
    SCSCompon, FirstReplacedComponent, ReplacedComponent: TSCSComponent;
    GroupResource: TSCSResourceGroup;
    ComponentList: TSCSComponents;
    SelectedRecord: Boolean;
    CmpDelta: Double;
    CurrRec, RecordID: integer;
    strText, Capt: String;
begin
  ComponentList := nil;
  isDropComponent := true;

  HitTest := TcxGridSite(Sender).ViewInfo.GetHitTest(X, Y);
  if (HitTest.HitTestCode() in [htCell, htRecord])  then
  begin
    if HitTest.ViewInfo is TcxGridDataCellViewInfo then
    begin
      GRec := TcxGridDataCellViewInfo(HitTest.ViewInfo).RecordViewInfo.GridRecord;
      RecordIndex := GRec.RecordIndex;
      RecordID := TcxGridDBDataController(TcxGridSite(Sender).GridView.DataController).Values[RecordIndex, GT_ResourcesID.Index];
      DataSet := TcxGridDBDataController(TcxGridSite(Sender).GridView.DataController).DataSet;

      if Dataset <> nil then
      begin
        if not cbShowConnectForm.Checked then
        begin
          strText := cReportForm_Msg4 + #13#10 + cReportForm_Msg4_1 + #13#10 + cReportForm_Msg6;
          //if MessageModal(strText, ApplicationName, MB_ICONQUESTION or MB_YESNO) = IDYES then
          Capt := cConnectComplWith_Msg8_1;
          if MessageBox(Self.Handle, PChar(strText), PChar(Capt), MB_YESNO) = ID_Yes then
          begin
            try
              BeginProgress;
              IsEdited := false;
              CurrRec := Dataset.RecNo;
              Dataset.DisableControls;
              Dataset.First;
              while (Dataset.FieldByName('ID').AsInteger <> RecordID) do
              begin
                Dataset.Next;
                if Dataset.Eof then
                  break;
              end;

              GroupResource := TSCSResourceGroup(Dataset.FieldByName(fnObjectAddress).AsInteger);
              if GroupResource <> nil then
              begin
                if GroupResource.ObjectList.Count > 0 then
                begin
                  SCSCompon := TSCSComponent(GroupResource.ObjectList[0]);
                  //if SCSCompon.CanReplaceWithNBCompon(GDropComponent, true) = [crcrSuccessful] then
                  if SCSCompon.isLine = GDropComponent.isLine then
                  Begin
                    if (SCSCompon.ComponentType.SysName <>  GDropComponent.ComponentType.SysName) then
                      exit
                    else
                    begin
                      ComponentList := TSCSComponents.Create(false);

                      for I := 0 to GroupResource.ObjectList.Count - 1 do
                      begin
                        SCSCompon := TSCSComponent(GroupResource.ObjectList[i]);
                        if isCableComponent(SCSCompon) then
                          CheckAddCableToList(ComponentList, SCSCompon)
                        else
                          ComponentList.Add(SCSCompon);
                      end;
                      CmpDelta := 1 / Power(10, FloatPrecision);
                      BeginProgress;
                      try
                        mtResources.DisableControls;
                        try
                          //if FFolder is TSCSList then
                          //  OpenNoExistsListInCAD(FFolder);

                          FirstReplacedComponent := nil;
                          //*** Заменить компоненты
                          BaseBeginUpdate;
                          for i := 0 to  ComponentList.Count - 1 do
                          begin
                            SCSCompon := ComponentList[i];
                            if SCSCompon.ComponentType.SysName = GDropComponent.ComponentType.SysName then
                            begin
                              ReplacedComponent := SCSCompon;
                              //ReplacedComponent := SCSComponent.ReplaceWithNBCompon(NBComponent, TF_Main(GForm).F_ConnectComplWith.cbLeaveComplectsInTarget.Checked);
                              ReplacePMComponResFromNB(SCSCompon, GDropComponent, false);
                             // ReplacedComponent := ReplacePMComponFromNB(SCSCompon, GDropComponent, True);
                              if (FirstReplacedComponent = nil) and (ReplacedComponent <> nil) then
                                FirstReplacedComponent := ReplacedComponent;
                            end;
                          end;

                          //*** Обновить ведомость ресурсов
                          if FNormResources <> nil then
                            FreeAndNil(FNormResources);
                          SendResourcesToMT;

                          //*** Выделить позицию с замененной компонентой
                          SelectedRecord := false;
                          if FirstReplacedComponent <> nil then
                            for i := 0 to mtResources.RecordCount - 1 do
                            begin
                              mtResources.RecNo := i+1;
                              if (mtResources.FieldByName(fnIsResource).AsBoolean = false) and
                                 (mtResources.FieldByName(fnGuid).AsString = FirstReplacedComponent.GuidNB) and
                                 (mtResources.FieldByName(fnName).AsString = FirstReplacedComponent.Name) and
                                 (mtResources.FieldByName(fnArticulProducer).AsString = FirstReplacedComponent.ArticulProducer) and
                                 (mtResources.FieldByName(fnArticulDistributor).AsString = FirstReplacedComponent.ArticulDistributor) and
                                 (mtResources.FieldByName(fnGuidProducer).AsString = FirstReplacedComponent.GUIDProducer) and
                                 (mtResources.FieldByName(fnIzm).AsString = FirstReplacedComponent.Izm) and
                                 (Abs(mtResources.FieldByName(fnPrice).AsFloat - Round3(FirstReplacedComponent.Price)) < CmpDelta) then
                              begin
                                SelectedRecord := true;
                                Break; //// BREAK ////
                              end;
                            end;
                          if Not SelectedRecord then
                            if mtResources.RecordCount > 0 then
                              mtResources.First;
                        finally
                          mtResources.EnableControls;
                          BaseEndUpdate;
                        end;
                      finally
                        EndProgress;
                        if ComponentList <> nil then
                          ComponentList.free;
                      end;
                    end;
                  End;
                end;
              end;
            finally
              EndProgress;
            end;
          end;
          Dataset.EnableControls;
        end
        else
        begin
          CurrRec := Dataset.RecNo;
          Dataset.DisableControls;
          Dataset.First;
          while (Dataset.FieldByName('ID').AsInteger <> RecordID) do
          begin
            Dataset.Next;
            if Dataset.Eof then
              break;
          end;
          //with TF_Main(GForm).CreateFConnectComplWith do
          //  TF_Main(FNormBase).SelectComponInPCObjectsByGUID(GDropComponent.GuidNB);
          formStyle := fsNormal;
          Act_ReplaceComponent.Execute;
          Dataset.EnableControls;
          formStyle := fsStayOnTop;
          isDropComponent := False;
        end;
      end;
    end;
  end;

  isDropComponent := false;
end;

procedure TF_ReportForm.GT_ResourcesDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
var i, j: integer;
    Dataset: TDataset;
    HitTest: TcxCustomGridHitTest;
    RecordIndex: integer;
    GRec: TcxGridDatarow;
    SCSCompon: TSCSComponent;
    GroupResource: TSCSResourceGroup;
    currRec, RecordID: Integer;
    GroupResAddr: Integer;
    imgList: TDragImageList;
begin
  //Tolik 19/11/2021 -- сбросить редактирование поля таблицы ресурсов, если идет драг объекта над формой, иначе
  //                    над редактируемым полем дроп будет запрещен ....
  if GT_ResourcesName.Editing or //then
  //GT_ResourcesName.Editing := False;
  GT_ResourcesArticulProducer.Editing or //then
  GT_ResourcesArticulDistributor.Editing or //then
  GT_ResourcesPrice.Editing or //then
  GT_ResourcesCost.Editing or
  GT_ResourcesProducerName.Editing then
  begin
    GT_Resources.Controller.EditingController.Edit.Deactivate;
    GT_Resources.Controller.EditingController.HideEdit(true);
    GT_Resources.Controller.ClearSelection;
     //if GT_Resources.Controller.SelectedRowCount > 0 then
    begin
      GT_Resources.Controller.FocusedColumnIndex := 1;
    end;
    GridResources.Refresh;
  end;
  if Edit <> nil then
  begin
    Edit.Deactivate;
    Edit := nil;
  end;
  IsEdited := False;
  GT_Resources.Controller.FocusedItemIndex := -1;
  GridResources.SetFocus;
  //
  Accept := False;
  DStatus.Text := '';
  if Source is TTreeView then
  begin
    imgList := TTreeView(Source).GetDragImages;
    if ImgList <> nil then
    begin
      ImgList.HideDragImage;
      TcxGridSite(Sender).Refresh;
      ImgList.ShowDragImage;
    end;
  end;
  RecordIndex := 0;
  if GDropComponent <> nil then
  begin
    HitTest := TcxGridSite(Sender).ViewInfo.GetHitTest(X, Y);
    if (HitTest.HitTestCode() in [htCell, htRecord])  then
    begin
      if HitTest.ViewInfo is TcxGridDataCellViewInfo then
      begin
        GRec := TcxGridDataCellViewInfo(HitTest.ViewInfo).RecordViewInfo.GridRecord;
        RecordIndex := GRec.RecordIndex;
        DataSet := TcxGridDBDataController(TcxGridSite(Sender).GridView.DataController).DataSet;
        if Dataset <> nil then
        begin
          //RecordID := TcxGridDBDataController(TcxGridSite(Sender).GridView.DataController).Values[RecordIndex, GT_ResourcesID.Index];
         {
          currRec := Dataset.RecNo;
          Dataset.DisableControls;

          Dataset.First;
          while Dataset.FieldByName('ID').AsInteger <> RecordID do
          begin
            Dataset.next;
            if Dataset.Eof then
              break;
          end;
          }
          //GroupResource := TSCSResourceGroup(Dataset.FieldByName(fnObjectAddress).AsInteger);

          GroupResAddr := TcxGridDBDataController(TcxGridSite(Sender).GridView.DataController).Values[RecordIndex, GT_ResourcesAdress.Index];
          GroupResource := TSCSResourceGroup(GroupResAddr);
          if GroupResource <> nil then
          begin
            if GroupResource.ObjectList.Count > 0 then
            begin
              SCSCompon := TSCSComponent(GroupResource.ObjectList[0]);
              //if SCSCompon.CanReplaceWithNBCompon(GDropComponent, true) = [crcrSuccessful] then
              Begin
                // 04/02/2022 -- Tolik -- здесь закомментим по просьбе Ромы - чтобы пользователь мог иенять что угодно
                //          кроме линейного на точечный
                //if (SCSCompon.ComponentType.SysName = GDropComponent.ComponentType.SysName) then
                begin
                  if SCSCompon.isLine = GDropComponent.IsLine then
                  begin
                    Accept := True;
                    DStatus.Text := '';
                    //Tolik 04/02/2022 -- но пользователю все же покажем, что типы компонент не совместимы
                    if (SCSCompon.ComponentType.SysName <> GDropComponent.ComponentType.SysName) then
                      DStatus.Text := 'Incompatible Component Type';
                    exit;
                  end
                  else
                    DStatus.Text := 'Not a Line Component';
                end;
              End;
            end;
          end;
         { Dataset.First;
          while Dataset.RecNo <> currRec do
          begin
            Dataset.Next;
            if Dataset.EOf then
              break;
          end;
          Dataset.EnableControls;}
        end;
      end;
      //TcxGridSite(Sender).Refresh;
    end;
  end;
end;
//

procedure TF_ReportForm.Act_LoadPricesFromNBExecute(Sender: TObject);
var
  i: Integer;
  GUIDCompon: String;
  IDCompon: Integer;
  NBPrice: Double;
  Compon: TSCSComponent;
  //BookMark: String;
  BookMark: TBookMark;
begin
  GT_ResourcesPriceNB.Visible := true;

  //BookMark := mtResources.Bookmark;
  BookMark := mtResources.GetBookmark;
  try
    Compon := TSCSComponent.Create(F_NormBase);
    for i := 0 to GT_Resources.Controller.SelectedRecordCount - 1 do
    begin
      //GT_Resources.Controller.SelectedRows[i].
      GUIDCompon := GT_Resources.Controller.SelectedRecords[i].Values[GT_ResourcesGUIDNBCompon.Index];
      IDCompon := F_NormBase.DM.GetIntFromTableByGUID(tnComponent, fnID, GUIDCompon, qmPhisical);
      if IDCompon <> 0 then
      begin
        Compon.Clear;
        Compon.LoadComponentByID(IDCompon, false);
        DefineComponPriceOnCopyToOtherBase(Compon, nil, F_ProjMan.GSCSBase.CurrProject, F_NormBase, F_ProjMan);
        //GT_Resources.Controller.SelectedRecords[i].Values[GT_ResourcesPriceNB.Index] := Compon.Price;
        //GT_Resources.DataController.Values[GT_Resources.Controller.SelectedRecords[i].Index, GT_ResourcesPriceNB.Index] := Compon.Price;
        if mtResources.Locate(fnGuidNBComponent, GUIDCompon, []) then
        begin
          mtResources.Edit;
          mtResources.FieldByName(fnPriceNB).AsFloat := RoundCP(Compon.Price);
          mtResources.Post;
        end;
      end;
    end;
    Compon.Free;
  finally
    //mtResources.Bookmark := BookMark;
    mtResources.GOTOBookmark(BookMark);
    mtResources.FreeBookmark(BookMark);

  end;
end;


procedure TF_ReportForm.neTotalCostKeyPress(Sender: TObject;
  var Key: Char);
begin
  CorrectMaskKeyPress(Key);
  //if Key = #13 then
  //  OnTotalCostChange;
end;

procedure TF_ReportForm.neTotalCostExit(Sender: TObject);
begin
  //OnTotalCostChange;
end;

end.
