unit U_Norms;

interface

uses
  Windows, U_LNG, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData, cxEdit,
  DB, cxDBData, cxGridLevel, cxClasses, cxControls, cxGridCustomView,
  cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxGrid,
  ComCtrls, ToolWin, ExtCtrls, cxLookAndFeelPainters, Menus, ActnList,
  ActnMan, StdCtrls, cxButtons, cxContainer, cxTextEdit, cxCurrencyEdit,

  U_SCSComponent, U_BaseCommon, cxEditRepositoryItems, cxDataStorage,
  cxCheckBox, cxSpinEdit, cxColorComboBox, kbmMemTable, RzPanel, XPMenu,
  siComp, siLngLnk, cxMemo, cxDBLookupComboBox;

const
  // Fields indexes
  fiNormIsOn = 1;
  fiNormTotalCost = 8;
  fiResourceIsOn = 1;
  fiResourcePrice = 5;
  fiResourceAdditionalPrice = 6;
  fiResourceKolvo = 7;
  fiResourceCost = 8;

type
  TF_Norms = class(TForm)
    Splitter1: TSplitter;
    ToolBar_Norms: TToolBar;
    ToolBar_Resources: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    GT_NORMS: TcxGridDBTableView;
    GL_NORMS: TcxGridLevel;
    Grid_NORMS: TcxGrid;
    GT_Resources: TcxGridDBTableView;
    GL_Resources: TcxGridLevel;
    Grid_Resources: TcxGrid;
    ActionManager1: TActionManager;
    PopupMenu_NormsResources: TPopupMenu;
    GT_NORMSNPP: TcxGridDBColumn;
    GT_NORMSIsOn: TcxGridDBColumn;
    GT_NORMSCypher: TcxGridDBColumn;
    GT_NORMSName: TcxGridDBColumn;
    GT_NORMSWork_Kind: TcxGridDBColumn;
    GT_NORMSIZM: TcxGridDBColumn;
    GT_NORMSZarplat: TcxGridDBColumn;
    Act_AddNorm: TAction;
    Act_EditNorm: TAction;
    Act_RemoveNorm: TAction;
    GT_ResourcesIsOn: TcxGridDBColumn;
    GT_ResourcesCypher: TcxGridDBColumn;
    GT_ResourcesName: TcxGridDBColumn;
    GT_ResourcesIzm: TcxGridDBColumn;
    GT_ResourcesRType: TcxGridDBColumn;
    GT_ResourcesPrice: TcxGridDBColumn;
    GT_ResourcesKolvo: TcxGridDBColumn;
    Act_AddResource: TAction;
    Act_EditResource: TAction;
    Act_DelResource: TAction;
    GT_ResourcesCost: TcxGridDBColumn;
    GT_NORMSKolvo: TcxGridDBColumn;
    Panel_TotalCost: TPanel;
    Label1: TLabel;
    CurrencyEdit_ResourcesCost: TcxCurrencyEdit;
    GT_NORMSCost: TcxGridDBColumn;
    GT_NORMSTotalCost: TcxGridDBColumn;
    EditRepository_Norm: TcxEditRepository;
    EditRepository_NormCurrency_NormCost: TcxEditRepositoryCurrencyItem;
    EditRepository_NormCurrency_NormTotalCost: TcxEditRepositoryCurrencyItem;
    EditRepository_NormCurrency_ResourcePrice: TcxEditRepositoryCurrencyItem;
    EditRepository_NormCurrency_ResourceCost: TcxEditRepositoryCurrencyItem;
    Act_AddResourceToMTNorm: TAction;
    GT_ResourcesNPP: TcxGridDBColumn;
    ToolButton7: TToolButton;
    Panel_OKCancel: TRzPanel;
    Button_OK: TcxButton;
    Button_Cancel: TcxButton;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    PopupMenu_Resources: TPopupMenu;
    N5: TMenuItem;
    N6: TMenuItem;
    N7: TMenuItem;
    XPMenu1: TXPMenu;
    GroupBox_Norms: TRzGroupBox;
    GroupBox_ResourcesRel: TRzGroupBox;
    GT_ResourcesAdditionalPrice: TcxGridDBColumn;
    lng_Forms: TsiLangLinked;
    procedure FormShow(Sender: TObject);
    procedure FormHide(Sender: TObject);
    procedure Act_AddNormExecute(Sender: TObject);
    procedure Act_EditNormExecute(Sender: TObject);
    procedure Act_RemoveNormExecute(Sender: TObject);
    procedure Button_OKClick(Sender: TObject);
    procedure GT_NORMSFocusedRecordChanged(Sender: TcxCustomGridTableView;
      APrevFocusedRecord, AFocusedRecord: TcxCustomGridRecord;
      ANewItemRecordFocusingChanged: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure Act_AddResourceExecute(Sender: TObject);
    procedure Act_EditResourceExecute(Sender: TObject);
    procedure Act_DelResourceExecute(Sender: TObject);
    procedure GT_ResourcesKolvoPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure GT_ResourcesPricePropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure GT_ResourcesEditing(Sender: TcxCustomGridTableView;
      AItem: TcxCustomGridTableItem; var AAllow: Boolean);
    procedure GT_NORMSEditing(Sender: TcxCustomGridTableView;
      AItem: TcxCustomGridTableItem; var AAllow: Boolean);
    procedure GT_ResourcesCellClick(Sender: TcxCustomGridTableView;
      ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton;
      AShift: TShiftState; var AHandled: Boolean);
    procedure GT_NORMSKolvoPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure GT_NORMSCostPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure GT_NORMSCellClick(Sender: TcxCustomGridTableView;
      ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton;
      AShift: TShiftState; var AHandled: Boolean);
    procedure Act_AddResourceToMTNormExecute(Sender: TObject);
    procedure Panel_OKCancelResize(Sender: TObject);
    procedure GT_ResourcesAdditionalPricePropertiesValidate(
      Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
  private
    FItemType: TItemType;
    FIDMaster: Integer; //*** ID компоненты
    FOutNormsResources: TSCSNormsResources;

    FCurrencyRatio: Double;
    FNBCurrencyRatio: Double;

    GDeletedNormID: TStringList;
    GDeletedResourceID: TStringList;
  public
    GForm: TForm;
    GMasterTableKind: Integer;

    GLength: Double;
    GComponPrice: Double;

    GTableName: string;
    GMasterField: string;

    procedure EnableEditDelNorm;
    procedure EnableEditDelResource;
    function Execute(AItemType, AIDMaster: Integer; AOutNormsResources: TSCSNormsResources): Boolean;
    procedure AddEditNorm(AMakeEdit: TMakeEdit);
    procedure AddEditResource(AMakeEdit: TMakeEdit; AMemoryTableKind: TTableKind);
    function GetNewNPP(AMemTable: TkbmMemTable): Integer;
    procedure SdvigNPP(ANPPAfter: Integer; AMemTable: TkbmMemTable);

    procedure LoadFromResourceToMT(AResource: TSCSResourceRel; AMakeEdit: TMakeEdit; AMemoryTableKind: TTableKind);
    procedure LoadFromNormToMT(ASCSNorm: TSCSNorm; AMakeEdit: TMakeEdit; AKolvo: Double);

    procedure LoadFromMTToResource(AMemoryTableKind: TTableKind; AResourceRel: TSCSResourceRel);
    procedure LoadFromMTToNorm(ASCSNorm: TSCSNorm);

    procedure CalcNormCost;
    procedure CalcWorkCost;

    procedure DelResourcesFromCurrNorm;

    constructor Create(AOwner: TComponent; AForm: TForm);
    destructor Destroy; override;
  end;

  //var
    //F_Norms: TF_Norms;

implementation
uses Unit_DM_SCS, U_Main, FIBQuery;
{$R *.dfm}

{ TF_Norms }

// ##### Создает форму #####

constructor TF_Norms.Create(AOwner: TComponent; AForm: TForm);
begin
  GForm := AForm;
  GDeletedNormID := TStringList.Create;
  GDeletedResourceID := TStringList.Create;

  inherited Create(AOwner);
end;

// ##### Удаляет форму #####

destructor TF_Norms.Destroy;
begin
  GDeletedNormID.Free;
  GDeletedResourceID.Free;
  inherited;
end;

// ##### Разрешить/ запретить Редактирование/Удаление #####

procedure TF_Norms.EnableEditDelNorm;
begin
  Act_AddNorm.Enabled := true;
  { if (TF_Main(GForm).DM.MemTable_NormsEd.RecNo = 1) and (GTableKind = ctkComponent) then
     begin
         Act_EditNorm.Enabled := false;
         Act_RemoveNorm.Enabled := false;
     end
   else
     begin
         if TF_Main(GForm).DM.MemTable_NormsEd.RecordCount = 0 then
           begin
               Act_EditNorm.Enabled := false;
               Act_RemoveNorm.Enabled := false;
           end
         else
           begin
               Act_EditNorm.Enabled := true;
               Act_RemoveNorm.Enabled := true;
           end;
     end;     }

  if TF_Main(GForm).DM.MemTable_NormsEd.RecordCount = 0 then
  begin
    Act_EditNorm.Enabled := false;
    Act_RemoveNorm.Enabled := false;
  end
  else
  begin
    Act_EditNorm.Enabled := true;
    Act_RemoveNorm.Enabled := true;
  end;
  EnableEditDelResource;
end;

procedure TF_Norms.EnableEditDelResource;
begin
  if TF_Main(GForm).DM.MemTable_NormsEd.RecordCount = 0 then
  begin
    Act_AddResource.Enabled := false;
    Act_EditResource.Enabled := false;
    Act_DelResource.Enabled := false;
  end
  else
  begin
    if TF_Main(GForm).DM.MemTable_NormsEd.FieldByName('isResource').AsBoolean = true {TF_Main(GForm).DM.MemTable_Norms.RecNo = 1} {FieldByName('npp').AsInteger = 1} then
      Act_AddResource.Enabled := false
    else
      Act_AddResource.Enabled := true;

    if TF_Main(GForm).DM.MemTable_ResourcesRelEd.RecordCount = 0 then
    begin
      Act_EditResource.Enabled := false;
      Act_DelResource.Enabled := false;
    end
    else
    begin
      Act_EditResource.Enabled := true;
      Act_DelResource.Enabled := true;
    end;
  end;
end;

function TF_Norms.Execute(AItemType, AIDMaster: Integer; AOutNormsResources: TSCSNormsResources): Boolean;
var //qSQL: String;
  NormsResources: TSCSNormsResources;
  ObjectLength: Double;

  i, j: Integer;
  SCSNorm: TSCSNorm;
  ResourceRel: TSCSResourceRel;
  RecCount: Integer;
  NppFinded: Boolean;
begin
  Result := false;
  FIDMaster := AIDMaster;
  FItemType := AItemType;

  if not (FItemType in [itSCSConnector, itSCSLine, itComponCon, itComponLine]) then
    Exit; ///// EXIT //////

  FCurrencyRatio := TF_Main(GForm).GCurrencyM.Ratio;
  FNBCurrencyRatio := TF_Main(GForm).FNormBase.GCurrencyM.Ratio;

  GT_NORMS.OnFocusedRecordChanged := nil;
  with TF_Main(GForm).DM do
  begin
    //*** Загрузить форматы валют
    //GT_NORMSCost.Properties.

    Caption := 'Ведомость работ/ресурсов компонента';
    case FItemType of
      itComponCon, itComponLine:
        begin
          GMasterTableKind := ctkComponent;
          Caption := 'Ведомость работ/ресурсов компонента';
        end;
      itSCSConnector, itSCSLine:
        begin
          GMasterTableKind := ctkCatalog;
          Caption := 'Ведомость работ/ресурсов объекта';
        end;
    end;

    GLength := 0;
    ObjectLength := 0;

    case FItemType of
      itComponLine, itSCSLine:
        begin
          //GT_NORMSKolvo.Options.Editing := false;
          case FItemType of
            itComponLine:
              ObjectLength := TF_Main(GForm).DM.GetPropertyValueAsFloat(tkComponent, FIDMaster, pnLength, qmUndef, -1);
            itSCSLine:
              ObjectLength := TF_Main(GForm).DM.GetPropertyValueAsFloat(tkCatalog, FIDMaster, pnLength, qmUndef, -1);
          end;
        end;
      itComponCon, itSCSConnector:
        begin
          //GT_NORMSKolvo.Options.Editing := true;
          ObjectLength := 0;
        end;
    end;

    //*** Отобрать нормы
    NormsResources := nil;
    FOutNormsResources := AOutNormsResources;
    if not Assigned(AOutNormsResources) then
    begin
      NormsResources := TSCSNormsResources.Create(GForm, GMasterTableKind);
      NormsResources.LoadNorms(true, true);
      NormsResources.LoadResources(True);
    end
    else
      NormsResources := AOutNormsResources;

    if Assigned(NormsResources) then
    begin
      NormsResources.IDMaster := FIDMaster;
      NormsResources.Length := ObjectLength;

      NormsResources.CalcResourcesCost(true, true);

      MemTable_NormsEd.Active := false;
      MemTable_NormsEd.Active := true;
      MemTable_ResourcesRelEd.Active := false;
      MemTable_ResourcesRelEd.Active := true;

      RecCount := NormsResources.Norms.Count + NormsResources.Resources.Count;
      for i := 0 to RecCount - 1 do
      begin
        NppFinded := false;
        for j := 0 to NormsResources.Norms.Count - 1 do
        begin
          SCSNorm := NormsResources.Norms.Items[j];
          if SCSNorm.NPP = i + 1 then
          begin
            Self.LoadFromNormToMT(SCSNorm, meNone, -1);
            NppFinded := true;
            Break;
          end;
        end;

        if not NppFinded then
          for j := 0 to NormsResources.Resources.Count - 1 do
          begin
            ResourceRel := NormsResources.Resources.Items[j];
            if ResourceRel.NPP = i + 1 then
            begin
              Self.LoadFromResourceToMT(ResourceRel, meNone, tkNormEd);
              Break;
            end;
          end;
      end;

      {for i := 0 to NormsResources.Norms.Count - 1 do
        begin
            SCSNorm := NormsResources.Norms.Items[i];
            LoadFromNormToMT(SCSNorm, meNone, -1);
        end;

      for i := 0 to NormsResources.Resources.Count - 1 do
        begin
            ResourceRel := NormsResources.Resources.Items[i];
            LoadFromResourceToMT(ResourceRel, meNone, tkNormEd);
        end; }

      //*** Запомнить цену компоненты
      GComponPrice := 0;
      if NormsResources.Resources.Count > 0 then
        GComponPrice := TSCSResourceRel(NormsResources.Resources[0]).Price;

      MemTable_NormsEd.First;
      if not Assigned(AOutNormsResources) then
        NormsResources.Free;
    end;
    CalcWorkCost;
  end;
  GT_NORMS.OnFocusedRecordChanged := GT_NORMSFocusedRecordChanged;

  EnableEditDelNorm;
  GDeletedNormID.Clear;
  GDeletedResourceID.Clear;

  if ShowModal = mrOk then
  begin
    Result := true;
  end;
end;

// ##### Вернет новую позицию #####

function TF_Norms.GetNewNPP(AMemTable: TkbmMemTable): Integer;
var
  RecordNo: Integer;
  MaxNPP: Integer;
begin
  Result := 1;
  with AMemTable do
  begin
    RecordNo := RecNo;
    First;
    MaxNPP := FieldByName('NPP').AsInteger;
    while not Eof do
    begin
      if FieldByName('NPP').AsInteger > MaxNPP then
        MaxNPP := FieldByName('NPP').AsInteger;
      Next;
    end;
    RecNo := RecordNo;
  end;
  Result := MaxNPP + 1;
end;

// ##### Здвигает порядковые номера после ANPPAfter на -1 #####

procedure TF_Norms.SdvigNPP(ANPPAfter: Integer; AMemTable: TkbmMemTable);
var
  RecordNo: Integer;
  NewNPP: Integer;
begin
  try
    if (AMemTable = nil) or (AMemTable.Active = false) then
      Exit; ///// EXIT /////

    with AMemTable do
    begin
      RecordNo := RecNo;
      first;
      while not Eof do
      begin
        if FieldByName('NPP').AsInteger > ANPPAfter then
        begin
          NewNPP := FieldByName('NPP').AsInteger - 1;
          Edit;
          FieldByName('NPP').AsInteger := NewNPP;
          FieldByName('isModified').AsBoolean := true;
          Post;
        end;
        Next;
      end;
      RecNo := RecordNo;
    end;
  except
    on E: Exception do
      AddExceptionToLog('TF_Norms.SdvigNPP: ' + E.Message);
  end;
end;

// ##### Подгружает ресурсы #####

procedure TF_Norms.LoadFromResourceToMT(AResource: TSCSResourceRel; AMakeEdit: TMakeEdit; AMemoryTableKind: TTableKind);
var
  TrgMemTable: TkbmMemTable;
  NewNpp: Integer;
begin
  try
    TrgMemTable := nil;
    with TF_Main(GForm).DM do
      case AMemoryTableKind of
        tkResourceRelEd:
          TrgMemTable := MemTable_ResourcesRelEd;
        tkNormEd:
          TrgMemTable := MemTable_NormsEd;
      end;
    if TrgMemTable = nil then
      Exit; //// EXIT ////

    case AMakeEdit of
      meMake:
        begin
          NewNpp := GetNewNPP(TrgMemTable);
          TrgMemTable.Append;
          TrgMemTable.FieldByName('Npp').AsInteger := NewNpp;
          if AMemoryTableKind = tkNormEd then
            TrgMemTable.FieldByName('isResource').AsBoolean := true;
        end;
      meEdit: TrgMemTable.Edit;
      meNone:
        begin
          TrgMemTable.Append;
          TrgMemTable.FieldByName('id').AsInteger := AResource.ID;
          TrgMemTable.FieldByName('id_master').AsInteger := AResource.IDMaster;
          TrgMemTable.FieldByName('Npp').AsInteger := AResource.Npp;
          if AMemoryTableKind = tkNormEd then
            TrgMemTable.FieldByName('isResource').AsBoolean := true;
        end;
    end;
    TrgMemTable.FieldByName('Table_Kind').AsInteger := AResource.MasterTableKind;

    TrgMemTable.FieldByName('id_resource').AsInteger := AResource.IDResource;
    //TrgMemTable.FieldByName('id_nb').AsInteger := AResource.IDNB;
    TrgMemTable.FieldByName(fnGuidNB).AsString := AResource.GuidNB;
    TrgMemTable.FieldByName('table_kind_nb').AsInteger := AResource.TableKindNB;

    TrgMemTable.FieldByName('kolvo').AsFloat := AResource.Kolvo;
    TrgMemTable.FieldByName('ison').AsInteger := AResource.IsOn;

    TrgMemTable.FieldByName('Cypher').AsString := AResource.Cypher;
    TrgMemTable.FieldByName('Name').AsString := AResource.Name;
    TrgMemTable.FieldByName('Izm').AsString := AResource.Izm;
    case AMemoryTableKind of
      tkResourceRelEd:
        begin
          TrgMemTable.FieldByName('Price').AsFloat := AResource.Price;
          TrgMemTable.FieldByName(fnAdditionalPrice).AsFloat := AResource.AdditionalPrice;
          TrgMemTable.FieldByName('Cost').AsFloat := AResource.Cost;
        end;
      tkNormEd:
        begin
          TrgMemTable.FieldByName('Cost').AsFloat := AResource.Price;
          TrgMemTable.FieldByName('Total_Cost').AsFloat := AResource.Cost;
        end;
    end;

    TrgMemTable.FieldByName('RType').AsInteger := AResource.RType;
    case AMakeEdit of
      meNone:
        begin
          TrgMemTable.FieldByName('isModified').AsBoolean := false;
          TrgMemTable.FieldByName('isNew').AsBoolean := false;
        end;
      meMake:
        TrgMemTable.FieldByName('isNew').AsBoolean := true;
      meEdit:
        TrgMemTable.FieldByName('isModified').AsBoolean := true;
    end;
    TrgMemTable.Post;

    {with TF_Main(GForm).DM do
      begin
          case AMakeEdit of
            meMake : MemTable_ResourcesRelEd.Append;
            meEdit: MemTable_ResourcesRelEd.Edit;
            meNone:
                begin
                    MemTable_ResourcesRelEd.Append;
                    MemTable_ResourcesRelEd.FieldByName('id').AsInteger := AResource.ID;
                    MemTable_ResourcesRelEd.FieldByName('id_master').AsInteger := AResource.IDMaster;
                end;
          end;
          MemTable_ResourcesRelEd.FieldByName('id_resource').AsInteger := AResource.IDResource;
          MemTable_ResourcesRelEd.FieldByName('kolvo').AsFloat := AResource.Kolvo;
          MemTable_ResourcesRelEd.FieldByName('ison').AsInteger := AResource.IsOn;

          MemTable_ResourcesRelEd.FieldByName('Cypher').AsString := AResource.Cypher;
          MemTable_ResourcesRelEd.FieldByName('Name').AsString := AResource.Name;
          MemTable_ResourcesRelEd.FieldByName('Izm').AsString := AResource.Izm;
          MemTable_ResourcesRelEd.FieldByName('Price').AsFloat := AResource.Price;
          MemTable_ResourcesRelEd.FieldByName('Cost').AsFloat := AResource.Cost;
          MemTable_ResourcesRelEd.FieldByName('RType').AsInteger := AResource.RType;
          case AMakeEdit of
            meNone:
                begin
                    MemTable_ResourcesRelEd.FieldByName('isModified').AsBoolean := false;
                    MemTable_ResourcesRelEd.FieldByName('isNew').AsBoolean := false;
                end;
            meMake:
                MemTable_ResourcesRelEd.FieldByName('isNew').AsBoolean := true;
            meEdit:
                MemTable_ResourcesRelEd.FieldByName('isModified').AsBoolean := true;
          end;
          MemTable_ResourcesRelEd.Post;
      end; }
  except
    on E: Exception do
      AddExceptionToLog('TF_Norms.LoadResourceToMT: ' + E.Message);
  end;
end;

procedure TF_Norms.LoadFromNormToMT(ASCSNorm: TSCSNorm; AMakeEdit: TMakeEdit; AKolvo: Double);
var
  i: Integer;
  ResourceRel: TSCSResourceRel;
  NewNpp: Integer;
begin
  with TF_Main(GForm).DM do
  begin
    NewNpp := 0;
    case AMakeEdit of
      meMake:
        begin
          NewNpp := GetNewNPP(MemTable_NormsEd);
          MemTable_NormsEd.Append;
        end;
      meEdit:
        MemTable_NormsEd.Edit;
      meNone:
        MemTable_NormsEd.Append;
    end;
    MemTable_NormsEd.FieldByName('ID_Master').AsInteger := FIDMaster;
    //MemTable_NormsEd.FieldByName(fnIDNB).AsInteger := ASCSNorm.IDNB;
    MemTable_NormsEd.FieldByName(fnGuidNB).AsString := ASCSNorm.GuidNB;
    MemTable_NormsEd.FieldByName('TABLE_KIND').AsInteger := GMasterTableKind;
    MemTable_NormsEd.FieldByName('Cypher').AsString := ASCSNorm.Cypher;
    MemTable_NormsEd.FieldByName('Name').AsString := ASCSNorm.Name;
    MemTable_NormsEd.FieldByName('Work_Kind').AsString := ASCSNorm.WorkKind;
    MemTable_NormsEd.FieldByName('Izm').AsString := ASCSNorm.Izm_;
    MemTable_NormsEd.FieldByName('Cost').AsFloat := ASCSNorm.Cost;
    MemTable_NormsEd.FieldByName('Total_Cost').AsFloat := ASCSNorm.TotalCost; //ASCSNorm.Cost * ASCSNorm.Kolvo;
    //MemTable_NormRel.FieldByName('Zarplat').AsFloat := F_NormBase.DM.Query.FN('Zarplat').AsFloat;

    case AMakeEdit of
      meNone:
        begin
          MemTable_NormsEd.FieldByName('ID').AsInteger := ASCSNorm.ID;
          MemTable_NormsEd.FieldByName('NPP').AsInteger := ASCSNorm.NPP;
          MemTable_NormsEd.FieldByName('ISON').AsInteger := ASCSNorm.IsOn;
          MemTable_NormsEd.FieldByName('Kolvo').AsFloat := ASCSNorm.Kolvo;

          MemTable_NormsEd.FieldByName('isResource').AsBoolean := false;
          MemTable_NormsEd.FieldByName('isModified').AsBoolean := false;
          MemTable_NormsEd.FieldByName('isNew').AsBoolean := false;
        end;
      meMake:
        begin
          MemTable_NormsEd.FieldByName('NPP').AsInteger := NewNpp;
          MemTable_NormsEd.FieldByName('ISON').AsInteger := 1;
          MemTable_NormsEd.FieldByName('Kolvo').AsFloat := AKolvo;
          MemTable_NormsEd.FieldByName('isResource').AsBoolean := false;
          MemTable_NormsEd.FieldByName('isNew').AsBoolean := true;
        end;
      meEdit:
        begin
          MemTable_NormsEd.FieldByName('Kolvo').AsFloat := AKolvo;
          MemTable_NormsEd.FieldByName('isModified').AsBoolean := true;
        end;
    end;
    MemTable_NormsEd.Post;
  end;

  for i := 0 to ASCSNorm.Resources.Count - 1 do
  begin
    ResourceRel := ASCSNorm.Resources.Items[i];
    LoadFromResourceToMT(ResourceRel, AMakeEdit, tkResourceRelEd);
  end;
end;

procedure TF_Norms.LoadFromMTToResource(AMemoryTableKind: TTableKind; AResourceRel: TSCSResourceRel);
var
  TrgMemTable: TkbmMemTable;
begin
  try
    if AResourceRel = nil then
      Exit; /// EXIT ///

    TrgMemTable := nil;
    with TF_Main(GForm).DM do
      case AMemoryTableKind of
        tkResourceRelEd:
          TrgMemTable := MemTable_ResourcesRelEd;
        tkNormEd:
          TrgMemTable := MemTable_NormsEd;
      end;
    if TrgMemTable = nil then
      Exit; //// EXIT ////

    AResourceRel.ID := TrgMemTable.FieldByName('id').AsInteger;
    AResourceRel.IDMaster := TrgMemTable.FieldByName('id_master').AsInteger;
    AResourceRel.MasterTableKind := TrgMemTable.FieldByName('Table_Kind').AsInteger;
    AResourceRel.Npp := TrgMemTable.FieldByName('Npp').AsInteger;
    AResourceRel.IsOn := TrgMemTable.FieldByName('ison').AsInteger;

    AResourceRel.IDResource := TrgMemTable.FieldByName('id_resource').AsInteger;
    //AResourceRel.IDNB := TrgMemTable.FieldByName('id_nb').AsInteger;
    AResourceRel.GuidNB := TrgMemTable.FieldByName(fnGuidNB).AsString;
    AResourceRel.TableKindNB := TrgMemTable.FieldByName('table_kind_nb').AsInteger;

    AResourceRel.Kolvo := TrgMemTable.FieldByName('kolvo').AsFloat;

    AResourceRel.Cypher := TrgMemTable.FieldByName('Cypher').AsString;
    AResourceRel.Name := TrgMemTable.FieldByName('Name').AsString;
    AResourceRel.Izm := TrgMemTable.FieldByName('Izm').AsString;
    case AMemoryTableKind of
      tkResourceRelEd:
        begin
          AResourceRel.Price := TrgMemTable.FieldByName('Price').AsFloat;
          AResourceRel.AdditionalPrice := TrgMemTable.FieldByName(fnAdditionalPrice).AsFloat;
          AResourceRel.Cost := TrgMemTable.FieldByName('Cost').AsFloat;
        end;
      tkNormEd:
        begin
          AResourceRel.Price := TrgMemTable.FieldByName('Cost').AsFloat;
          AResourceRel.Cost := TrgMemTable.FieldByName('Total_Cost').AsFloat;
        end;
    end;

    AResourceRel.RType := TrgMemTable.FieldByName('RType').AsInteger;
    AResourceRel.IsModified := TrgMemTable.FieldByName('isModified').AsBoolean;
    AResourceRel.IsNew := TrgMemTable.FieldByName('isNew').AsBoolean;
  except
    on E: Exception do
      AddExceptionToLog('TF_Norms.LoadFromMTToResource: ' + E.Message);
  end;
end;

procedure TF_Norms.LoadFromMTToNorm(ASCSNorm: TSCSNorm);
begin
  with TF_Main(GForm).DM do
  begin
    ASCSNorm.ID := MemTable_NormsEd.FieldByName('ID').AsInteger;
    ASCSNorm.IDMaster := MemTable_NormsEd.FieldByName('ID_Master').AsInteger;
    //ASCSNorm.IDNB := MemTable_NormsEd.FieldByName(fnIDNB).AsInteger;
    ASCSNorm.GuidNB := MemTable_NormsEd.FieldByName(fnGuidNB).AsString;
    ASCSNorm.MasterTableKind := MemTable_NormsEd.FieldByName('TABLE_KIND').AsInteger;

    ASCSNorm.NPP := MemTable_NormsEd.FieldByName('NPP').AsInteger;
    ASCSNorm.IsOn := MemTable_NormsEd.FieldByName('ISON').AsInteger;
    ASCSNorm.Kolvo := MemTable_NormsEd.FieldByName('Kolvo').AsFloat;

    ASCSNorm.Cypher := MemTable_NormsEd.FieldByName('Cypher').AsString;
    ASCSNorm.Name := MemTable_NormsEd.FieldByName('Name').AsString;
    ASCSNorm.WorkKind := MemTable_NormsEd.FieldByName('Work_Kind').AsString;
    ASCSNorm.Izm_ := MemTable_NormsEd.FieldByName('Izm').AsString;
    ASCSNorm.Cost := MemTable_NormsEd.FieldByName('Cost').AsFloat;
    ASCSNorm.TotalCost := MemTable_NormsEd.FieldByName('Total_Cost').AsFloat;
    //MemTable_NormRel.FieldByName('Zarplat').AsFloat := F_NormBase.DM.Query.FN('Zarplat').AsFloat;

    ASCSNorm.IsModified := MemTable_NormsEd.FieldByName('isModified').AsBoolean;
    ASCSNorm.IsNew := MemTable_NormsEd.FieldByName('isNew').AsBoolean;
  end;
end;

// ##### Вычисляет единичную и общую стоимость текущей нормы #####

procedure TF_Norms.CalcNormCost;
var
  SCSNorm: TSCSNorm;
  ResourceRel: TSCSResourceRel;
  RecNoResource: Integer;
  i: Integer;
begin
  with TF_Main(GForm).DM do
  begin
    SCSNorm := TSCSNorm.Create(GForm, ntProj);
    RecNoResource := MemTable_ResourcesRelEd.RecNo;
    try
      try
        //GT_Resources.DataController.BeginUpdate;
        SCSNorm.Kolvo := MemTable_NormsEd.FieldByName('Kolvo').AsFloat;

        {MemTable_ResourcesRelEd.First;
        while Not MemTable_ResourcesRelEd.Eof do
          begin
              if MemTable_ResourcesRelEd.FieldByName('IsOn').AsInteger = biTrue then
                begin
                    New(ptrResource);
                    ptrResource.IsOn := MemTable_ResourcesRelEd.FieldByName('IsOn').AsInteger;
                    ptrResource.Cost := MemTable_ResourcesRelEd.FieldByName('Cost').AsFloat;
                    SCSNorm.Resources.Add(ptrResource);
                end;
              MemTable_ResourcesRelEd.Next;
          end; }
        for i := 0 to GT_Resources.DataController.RecordCount - 1 do
          if GT_Resources.DataController.Values[i, fiResourceIsOn] = biTrue then
          begin
            ResourceRel := TSCSResourceRel.Create(GForm, ntProj);
            ResourceRel.IsOn := GT_Resources.DataController.Values[i, fiResourceIsOn];
            ResourceRel.Price := GT_Resources.DataController.Values[i, fiResourcePrice];
            ResourceRel.AdditionalPrice := GT_Resources.DataController.Values[i, fiResourceAdditionalPrice];
            ResourceRel.Kolvo := GT_Resources.DataController.Values[i, fiResourceKolvo];
            ResourceRel.Cost := GT_Resources.DataController.Values[i, fiResourceCost];
            SCSNorm.Resources.Add(ResourceRel);
          end;
        SCSNorm.CalcTotalCost(true);
        MemTable_NormsEd.Edit;
        MemTable_NormsEd.FieldByName('cost').AsFloat := SCSNorm.Cost;
        MemTable_NormsEd.FieldByName('total_cost').AsFloat := SCSNorm.TotalCost;
        MemTable_NormsEd.FieldByName('isModified').AsBoolean := true;
        MemTable_NormsEd.Post;
        CalcWorkCost;
      except
        on E: Exception do
          AddExceptionToLog('TF_Norms.CalcNormCost: ' + E.Message);
      end;
    finally
      SCSNorm.Free;
      MemTable_ResourcesRelEd.RecNo := RecNoResource;
      //GT_Resources.DataController.EndUpdate;
    end;
  end;
end;

// ##### Вычисляет стоимость работ #####

procedure TF_Norms.CalcWorkCost;
var
  SCSNorms: TSCSNormsResources;
  SCSNorm: TSCSNorm;
  i: Integer;
begin
  SCSNorms := TSCSNormsResources.Create(GForm, GMasterTableKind);
  try
    try
      SCSNorms.IDMaster := FIDMaster;
      for i := 0 to GT_NORMS.DataController.RecordCount - 1 do
        if GT_NORMS.DataController.Values[i, 1] = biTrue then //*** поле "Включен"
        begin
          SCSNorm := TSCSNorm.Create(GForm, ntProj);
          SCSNorm.IsOn := GT_NORMS.DataController.Values[i, fiNormIsOn];
          SCSNorm.TotalCost := GT_NORMS.DataController.Values[i, fiNormTotalCost];
          SCSNorms.Norms.Add(SCSNorm);
        end;
      SCSNorms.CalcResourcesCost(false, false);
      CurrencyEdit_ResourcesCost.Value := SCSNorms.TotalCost;
    except
      on E: Exception do
        AddExceptionToLog('TF_Norms.CalcWorkCost: ' + E.Message);
    end;
  finally
    SCSNorms.Free;
  end;
end;

procedure TF_Norms.DelResourcesFromCurrNorm;
var
  IDResource: Integer;
begin
  with TF_Main(GForm).DM do
  begin
    MemTable_ResourcesRelEd.Last;
    while not MemTable_ResourcesRelEd.Bof do
    begin
      IDResource := MemTable_ResourcesRelEd.FieldByName('id').AsInteger;
      if MemTable_ResourcesRelEd.FieldByName('isNew').AsBoolean = false then
        GDeletedResourceID.Add(IntToStr(IDResource));
      MemTable_ResourcesRelEd.Delete;
    end;
  end;
end;

// ##### Добавить / Изменить норму #####

procedure TF_Norms.AddEditNorm(AMakeEdit: TMakeEdit);
var
  ID_Norm: Integer;
  ID_ResourceRel: Integer;
  //ModRes: TModalResult;
  NewNpp: Integer;
  SCSNorm: TSCSNorm;
  FormMode: TFormMode;
begin
  FormMode := fmNone;
  case AMakeEdit of
    meMake:
      begin
        FormMode := fmMake;
        F_NormBase.F_CaseForm.SpinEdit_Kolvo.Value := 1;
      end;
    meEdit:
      begin
        FormMode := fmEdit;
        if GLength = 0 then
          F_NormBase.F_CaseForm.SpinEdit_Kolvo.Value := TF_Main(GForm).DM.MemTable_NormsEd.FieldByName('Kolvo').AsFloat
      end;
  end;
  if GLength > 0 then
  begin
    F_NormBase.F_CaseForm.SpinEdit_Kolvo.Value := GLength;
    F_NormBase.F_CaseForm.SpinEdit_Kolvo.Properties.ReadOnly := true;
    //F_NormBase.F_CaseForm.Label_CaptLength.Visible := true;
  end
  else
  begin
    F_NormBase.F_CaseForm.SpinEdit_Kolvo.Properties.ReadOnly := false;
    //F_NormBase.F_CaseForm.Label_CaptLength.Visible := false;
  end;

  //F_NormBase.F_CaseForm.GViewKind := vkNorm;
  //ModRes := F_NormBase.F_CaseForm.ShowModal;

  with TF_Main(GForm) do
  begin
    //if ModRes = mrOk then
    if F_NormBase.F_CaseForm.Execute(vkNorm, FormMode) then
    begin
      //*** Занести ресурсы в список удаленных
      if AMakeEdit = meEdit then
        DelResourcesFromCurrNorm;

      ID_Norm := F_NormBase.DM.DataSet_NB_NORMS.FN('ID').AsInteger;
      SCSNorm := TSCSNorm.Create(TF_Main(GForm).FNormBase, ntNB);
      SCSNorm.LoadNorm(ID_Norm, true);
      SCSNorm.IDMaster := FIDMaster;

      //*** Преобразование валют
      //SCSNorm.RefreshPricesAfterChangeRatio(FNBCurrencyRatio, FCurrencyRatio, false);

      LoadFromNormToMT(SCSNorm, AMakeEdit, F_NormBase.F_CaseForm.SpinEdit_Kolvo.Value);
      SCSNorm.Free;
      CalcNormCost;
    end;
  end;
end;

procedure TF_Norms.AddEditResource(AMakeEdit: TMakeEdit; AMemoryTableKind: TTableKind);
var
  ID_ResourceRel: Integer;
  //ModRes: TModalResult;
  ResourceRel: TSCSResourceRel;
  FormMode: TFormMode;
begin
  FormMode := fmNone;
  case AMakeEdit of
    meMake: FormMode := fmMake;
    meEdit:
      begin
        FormMode := fmEdit;
        F_NormBase.F_CaseForm.SpinEdit_Kolvo.Value := RoundX(TF_Main(GForm).DM.MemTable_ResourcesRelEd.FieldByName('Kolvo').AsFloat, 10);
      end;
  end;
  if GLength > 0 then
  begin
    F_NormBase.F_CaseForm.SpinEdit_Kolvo.Value := GLength;
    F_NormBase.F_CaseForm.SpinEdit_Kolvo.Properties.ReadOnly := true;
    //F_NormBase.F_CaseForm.Label_CaptLength.Visible := true;
  end
  else
  begin
    F_NormBase.F_CaseForm.SpinEdit_Kolvo.Properties.ReadOnly := false;
    //F_NormBase.F_CaseForm.Label_CaptLength.Visible := false;
  end;

  //F_NormBase.F_CaseForm.GViewKind := vkResource;
  //ModRes := F_NormBase.F_CaseForm.ShowModal;

  with TF_Main(GForm) do
  begin
    //if ModRes = mrOk then
    if F_NormBase.F_CaseForm.Execute(vkResource, FormMode) then
    begin
      ResourceRel := TSCSResourceRel.Create(GForm, ntNB);
      //Resource.ID := F_NormBase.DM.DataSet_NB_RESOURCES.FN('ID').AsInteger;

      //*** Определить таблицу владельца ресурса
      case AMemoryTableKind of
        tkNormEd:
          ResourceRel.MasterTableKind := GMasterTableKind;
        tkResourceRelEd:
          ResourceRel.MasterTableKind := ctkNorm;
      end;

      ResourceRel.IDMaster := DM.MemTable_NormsEd.FieldByName('Id').AsInteger;

      ResourceRel.IDResource := F_NormBase.DM.DataSet_NB_RESOURCES.FN('ID').AsInteger;
      //ResourceRel.IDNB := F_NormBase.DM.DataSet_NB_RESOURCES.FN('ID').AsInteger;
      ResourceRel.TableKindNB := ctkNBResources;

      ResourceRel.Cypher := F_NormBase.DM.DataSet_NB_RESOURCES.FN('Cypher').AsString;
      ResourceRel.Name := F_NormBase.DM.DataSet_NB_RESOURCES.FN('Name').AsString;
      ResourceRel.Izm := F_NormBase.DM.DataSet_NB_RESOURCES.FN('Izm').AsString;
      ResourceRel.Price := F_NormBase.DM.DataSet_NB_RESOURCES.FN('Price').AsFloat;
      ResourceRel.AdditionalPrice := F_NormBase.DM.DataSet_NB_RESOURCES.FN(fnAdditionalPrice).AsFloat;
      ResourceRel.RType := F_NormBase.DM.DataSet_NB_RESOURCES.FN('RType').AsInteger;

      ResourceRel.Kolvo := F_NormBase.F_CaseForm.SpinEdit_Kolvo.Value;
      ResourceRel.Cost := ResourceRel.Price * ResourceRel.Kolvo; //F_NormBase.DM.DataSet_NB_RESOURCES.FN('Cost').AsFloat;
      ResourceRel.IsOn := 1;

      //ResourceRel.RefreshPricesAfterChangeRatio(FNBCurrencyRatio, FCurrencyRatio, false);

      LoadFromResourceToMT(ResourceRel, AMakeEdit, AMemoryTableKind);
      ResourceRel.Free;

      if AMemoryTableKind = tkResourceRelEd then
        CalcNormCost
      else
        CalcWorkCost;
    end;
  end;
end;

// #############################################################################
// #############################################################################
//
// ##### Создаст форму #####

procedure TF_Norms.FormCreate(Sender: TObject);
begin
  {    with TF_Main(GForm).DM do
        begin
            GT_Norms.DataController.DataSource := DataSource_MT_Norms;
            GT_Resources.DataController.DataSource := DataSource_MT_ResourcesRel;
        end;}
end;

// ##### Показать форму #####

procedure TF_Norms.FormShow(Sender: TObject);
//var //qSQL: String;
    {
    NormsResources: TSCSNormsResources;
    ObjectLength: Double;

    i, j: Integer;
    SCSNorm: TSCSNorm;
    ResourceRel: TSCSResourceRel;
    RecCount: Integer;
    NppFinded: Boolean; }
begin
  (*
  if Not(GItemType in [itSCSConnector, itSCSLine,  itComponCon, itComponLine]) then
    Exit; ///// EXIT //////
  GT_NORMS.OnFocusedRecordChanged := nil;
  with TF_Main(GForm).DM do
    begin
        //*** Загрузить форматы валют
        //GT_NORMSCost.Properties.

        Caption := 'Ведомость работ/ресурсов компоненты';
        case GItemType of
          itComponCon, itComponLine:
              begin
                  GMasterTableKind := ctkComponent;
                  Caption := 'Ведомость работ/ресурсов компоненты';
              end;
          itSCSConnector, itSCSLine:
              begin
                  GMasterTableKind := ctkCatalog;
                  Caption := 'Ведомость работ/ресурсов объекта';
              end;
        end;

        GLength := 0;
        ObjectLength := 0;

        case GItemType of
          itComponLine, itSCSLine:
              begin
                  //GT_NORMSKolvo.Options.Editing := false;
                  case GItemType of
                    itComponLine:
                        ObjectLength := TF_Main(GForm).DM.GetPropertyValueAsFloat(tkComponent, GIDMaster, pnLength, qmUndef, -1);
                    itSCSLine:
                        ObjectLength := TF_Main(GForm).DM.GetPropertyValueAsFloat(tkCatalog, GIDMaster, pnLength, qmUndef, -1);
                  end;
              end;
          itComponCon, itSCSConnector:
              begin
                  //GT_NORMSKolvo.Options.Editing := true;
                  ObjectLength := 0;
              end;
        end;

        //*** Отобрать нормы
        NormsResources := TSCSNormsResources.Create(GForm, GMasterTableKind);
        NormsResources.IDMaster := GIDMaster;
        NormsResources.Length := ObjectLength;
        NormsResources.LoadNorms(true, true);
        NormsResources.LoadResources(True);

        NormsResources.CalcResourcesCost(true, true);

        MemTable_NormsEd.Active := false;
        MemTable_NormsEd.Active := true;
        MemTable_ResourcesRelEd.Active := false;
        MemTable_ResourcesRelEd.Active := true;

        RecCount := NormsResources.Norms.Count + NormsResources.Resources.Count;
        for i := 0 to RecCount - 1 do
          begin
              NppFinded := false;
              for j := 0 to NormsResources.Norms.Count - 1 do
                begin
                    SCSNorm := NormsResources.Norms.Items[j];
                    if SCSNorm.NPP = i + 1 then
                      begin
                          LoadFromNormToMT(SCSNorm, meNone, -1);
                          NppFinded := true;
                          Break;
                      end;
                end;

              if Not NppFinded then
                for j := 0 to NormsResources.Resources.Count - 1 do
                  begin
                      ResourceRel := NormsResources.Resources.Items[j];
                      if ResourceRel.NPP = i + 1 then
                        begin
                            LoadFromResourceToMT(ResourceRel, meNone, tkNormEd);
                            Break;
                        end;
                  end;
          end;

        {for i := 0 to NormsResources.Norms.Count - 1 do
          begin
              SCSNorm := NormsResources.Norms.Items[i];
              LoadFromNormToMT(SCSNorm, meNone, -1);
          end;

        for i := 0 to NormsResources.Resources.Count - 1 do
          begin
              ResourceRel := NormsResources.Resources.Items[i];
              LoadFromResourceToMT(ResourceRel, meNone, tkNormEd);
          end; }

        //*** Запомнить цену компоненты
        GComponPrice := 0;
        if NormsResources.Resources.Count > 0 then
          GComponPrice := TSCSResourceRel(NormsResources.Resources[0]).Price;

        MemTable_NormsEd.First;
        NormsResources.Free;
        CalcWorkCost;
    end;
  GT_NORMS.OnFocusedRecordChanged := GT_NORMSFocusedRecordChanged;

  EnableEditDelNorm;
  GDeletedNormID.Clear;
  GDeletedResourceID.Clear; *)
end;

// ##### Скрыть форму #####

procedure TF_Norms.FormHide(Sender: TObject);
begin
  {with TF_Main(GForm).DM do
    begin
        if MemTable_ResourcesRelEd.Active = true then
          MemTable_ResourcesRelEd.Close;
        if MemTable_NormsEd.State <> dsInactive then
          MemTable_NormsEd.Close;
    end;       }
end;

// ##### Добавить норму #####

procedure TF_Norms.Act_AddNormExecute(Sender: TObject);
begin
  AddEditNorm(meMake);
  EnableEditDelNorm;
end;

// ##### Добавляет Ресурс в таблицу Норм #####

procedure TF_Norms.Act_AddResourceToMTNormExecute(Sender: TObject);
begin
  try
    AddEditResource(meMake, tkNormEd);
    EnableEditDelNorm;
  except
    on E: Exception do
      AddExceptionToLog('TF_Norms.Act_AddResourceToMTNormExecute: ' + E.Message);
  end;
end;

// ##### Изменить норму #####

procedure TF_Norms.Act_EditNormExecute(Sender: TObject);
begin
  try
    case TF_Main(GForm).DM.MemTable_NormsEd.FieldByName(fnIsResource).AsBoolean of
      true:
        AddEditResource(meEdit, tkNormEd);
      false:
        AddEditNorm(meEdit);
    end;
  except
    on E: Exception do
      AddExceptionToLog('TF_Norms.Act_EditNormExecute: ' + E.Message);
  end;
end;

// ##### Убрать норму #####

procedure TF_Norms.Act_RemoveNormExecute(Sender: TObject);
var
  DelName: string;
  IDDel: Integer;
  CurrNPP: Integer;
  CanDel: Boolean;
begin
  try
    CanDel := false;
    DelName := TF_Main(GForm).DM.MemTable_NormsEd.FieldByName('Name').AsString;
    case TF_Main(GForm).DM.MemTable_NormsEd.FieldByName('isResource').AsBoolean of
      true:
        if MessageModal('Удалить ресурс "' + DelName + '"?',
          'Удаление ресурса.', MB_ICONQUESTION or MB_YESNO) = IDYES then
          CanDel := true;
      false:
        if MessageModal('Удалить норму "' + DelName + '"?',
          'Удаление нормы.', MB_ICONQUESTION or MB_YESNO) = IDYES then
          CanDel := true;
    end;

    if CanDel then
    begin
      IDDel := TF_Main(GForm).DM.MemTable_NormsEd.FieldByName('ID').AsInteger;
      if TF_Main(GForm).DM.MemTable_NormsEd.FieldByName('isNew').AsBoolean = false then
        case TF_Main(GForm).DM.MemTable_NormsEd.FieldByName('isResource').AsBoolean of
          true:
            GDeletedResourceID.Add(IntToStr(IDDel));
          false:
            begin
              DelResourcesFromCurrNorm;
              GDeletedNormID.Add(IntToStr(IDDel));
            end;
        end;
      CurrNPP := TF_Main(GForm).DM.MemTable_NormsEd.FieldByName('NPP').AsInteger;
      TF_Main(GForm).DM.MemTable_NormsEd.Delete;
      SdvigNPP(CurrNPP, TF_Main(GForm).DM.MemTable_NormsEd);
      CalcWorkCost;
      EnableEditDelNorm;
    end;
  except
    on E: Exception do
      AddExceptionToLog('TF_Norms.Act_RemoveNormExecute: ' + E.Message);
  end;
end;

// ###### Добавить ресурс ######

procedure TF_Norms.Act_AddResourceExecute(Sender: TObject);
begin
  AddEditResource(meMake, tkResourceRelEd);
  EnableEditDelResource;
end;

// ###### Изменить ресурс ######

procedure TF_Norms.Act_EditResourceExecute(Sender: TObject);
begin
  AddEditResource(meEdit, tkResourceRelEd);
end;

// ###### Удалить ресурс ######

procedure TF_Norms.Act_DelResourceExecute(Sender: TObject);
var
  DelName: string;
  IDDel: Integer;
  CurrNPP: Integer;
begin
  try
    DelName := TF_Main(GForm).DM.MemTable_ResourcesRelEd.FieldByName('Name').AsString;
    if MessageModal('Убрать ресурс "' + DelName + '"?',
      'Удаление ресурса.', MB_ICONQUESTION or MB_YESNO) = IDYES then
    begin
      if TF_Main(GForm).DM.MemTable_ResourcesRelEd.FieldByName('isNew').AsBoolean = false then
      begin
        IDDel := TF_Main(GForm).DM.MemTable_ResourcesRelEd.FieldByName('ID').AsInteger;
        GDeletedResourceID.Add(IntToStr(IDDel));
      end;
      CurrNPP := TF_Main(GForm).DM.MemTable_ResourcesRelEd.FieldByName('NPP').AsInteger;
      TF_Main(GForm).DM.MemTable_ResourcesRelEd.Delete;
      SdvigNPP(CurrNPP, TF_Main(GForm).DM.MemTable_ResourcesRelEd);

      CalcNormCost;
      EnableEditDelResource;
    end;
  except
    on E: Exception do
      AddExceptionToLog('TF_Norms.Act_DelResourceExecute: ' + E.Message);
  end;
end;

// ##### Нажат ОК - Сохранить изменения #####

procedure TF_Norms.Button_OKClick(Sender: TObject);
var
  i: Integer;
  qSQL: string;
  MakeEdit: TMakeEdit;
  NormsFields: TStringList;
  ResourcesFields: TStringList;
  NormResourceRelFields: TStringList;

  CurrIDNorm: Integer;
  CurrIDResource: Integer;

  NormResources: TSCSNormsResources;
  SCSNorm: TSCSNorm;
  ResourceRel: TSCSResourceRel;
  SCSComponent: TSCSComponent;
begin
  try
    with TF_Main(GForm).DM do
    begin
      {//*** Удалить удаленные ресурсы
      scsQOperat.Close;
      scsQOperat.SQL.Clear;
      scsQOperat.SQL.Add(' delete from resources '+
                           ' where id in (select id_resource from norm_resource_rel '+
                                        ' where id = :id  ) ');
      for i := 0 to GDeletedResourceID.Count - 1 do
        begin
            scsQOperat.Close;
            scsQOperat.ParamByName('id').AsInteger := StrToInt(GDeletedResourceID.Strings[i]);
            scsQOperat.ExecQuery;
        end;   }

      //*** Удалить удаленные связей с удаленными ресурсами
      for i := 0 to GDeletedResourceID.Count - 1 do
      begin
        DelResourceRelByID(StrToInt(GDeletedResourceID.Strings[i]));
        if Assigned(FOutNormsResources) then
        begin
          ResourceRel := FOutNormsResources.Resources.GetResourceByID(StrToInt(GDeletedResourceID.Strings[i]));
          if Assigned(ResourceRel) then
          begin
            FOutNormsResources.Resources.Remove(ResourceRel);
            FreeAndNil(ResourceRel);
          end;
        end;
      end;

      //*** Удалить удаленные нормы
      for i := 0 to GDeletedNormID.Count - 1 do
      begin
        DelNormByID(StrToInt(GDeletedNormID.Strings[i]));
        if Assigned(FOutNormsResources) then
        begin
          SCSNorm := FOutNormsResources.Norms.GetNormByID(StrToInt(GDeletedNormID.Strings[i]));
          if Assigned(SCSNorm) then
          begin
            FOutNormsResources.Norms.Remove(SCSNorm);
            FreeAndNil(SCSNorm);
          end;
        end;
      end;

      {ChangeSQLQuery(scsQOperat, ' delete from norm_resource_rel '+
                                   ' where id = :id ');
      for i := 0 to GDeletedResourceID.Count - 1 do
        begin
            scsQOperat.Close;
            scsQOperat.SetParamAsInteger('id', StrToInt(GDeletedResourceID.Strings[i]) );
            scsQOperat.ExecQuery;
        end;      }

      {//*** Удалить удаленные нормы
      ChangeSQLQuery(scsQOperat, ' delete from norms where id = :id ');
      for i := 0 to GDeletedNormID.Count - 1 do
        begin
            scsQOperat.Close;
            scsQOperat.SetParamAsInteger('id', StrToInt(GDeletedNormID.Strings[i]) );
            scsQOperat.ExecQuery;
        end;
      scsQOperat.Close; }

      //*** Перемещение данных в объект
      NormResources := nil;
      if not Assigned(FOutNormsResources) then
        NormResources := TSCSNormsResources.Create(GForm, GMasterTableKind)
      else
      begin
        NormResources := FOutNormsResources;
        NormResources.Norms.Clear;
        NormResources.Resources.Clear;
      end;
      if Assigned(NormResources) then
      begin
        MemTable_NormsEd.First;
        while not MemTable_NormsEd.Eof do
        begin
          case TF_Main(GForm).DM.MemTable_NormsEd.FieldByName('isResource').AsBoolean of
            true: // Внести ресурс
              begin
                ResourceRel := TSCSResourceRel.Create(GForm, ntProj);
                Self.LoadFromMTToResource(tkNormEd, ResourceRel);
                NormResources.Resources.Add(ResourceRel);
              end;
            false: // Внести Норму
              begin
                SCSNorm := TSCSNorm.Create(GForm, ntProj);
                Self.LoadFromMTToNorm(SCSNorm);
                NormResources.Norms.Add(SCSNorm);

                // Внести в норму ее ресурсы
                MemTable_ResourcesRelEd.First;
                while not MemTable_ResourcesRelEd.Eof do
                begin
                  ResourceRel := TSCSResourceRel.Create(GForm, ntProj);
                  Self.LoadFromMTToResource(tkResourceRelEd, ResourceRel);
                  SCSNorm.Resources.Add(ResourceRel);
                  MemTable_ResourcesRelEd.Next;
                end;
              end;
          end;
          MemTable_NormsEd.Next;
        end;
        NormResources.SaveByServiceFields(FIDMaster);
        if not Assigned(FOutNormsResources) then
          NormResources.Free;
      end;

      {NormsFields := TStringList.Create;
      NormsFields.Add('ID');
      NormsFields.Add('ID_MASTER');
      NormsFields.Add('TABLE_KIND');
      NormsFields.Add('NPP');
      NormsFields.Add('ISON');
      NormsFields.Add('KOLVO');
      NormsFields.Add('TOTAL_COST');
      NormsFields.Add('CYPHER');
      NormsFields.Add('NAME');
      NormsFields.Add('WORK_KIND');
      NormsFields.Add('IZM');
      NormsFields.Add('COST');

      ResourcesFields := TStringList.Create;
      ResourcesFields.Add('ID');
      ResourcesFields.Add('CYPHER');
      ResourcesFields.Add('NAME');
      ResourcesFields.Add('IZM');
      ResourcesFields.Add('PRICE');
      ResourcesFields.Add('RTYPE');

      NormResourceRelFields := TStringList.Create;
      NormResourceRelFields.Add('ID');
      NormResourceRelFields.Add('ID_MASTER');
      NormResourceRelFields.Add('TABLE_KIND');
      NormResourceRelFields.Add('ID_RESOURCE');
      NormResourceRelFields.Add('KOLVO');
      NormResourceRelFields.Add('ISON');
      NormResourceRelFields.Add('COST');
      NormResourceRelFields.Add('RVALUE');

      //*** Сохранить Нормы
      MemTable_NormsEd.First;
      while Not MemTable_NormsEd.Eof do
        begin
            MakeEdit := meNone;
            CurrIDNorm := MemTable_NormsEd.FieldByName('id').AsInteger;
            if MemTable_NormsEd.FieldByName('isNew').AsBoolean = true then
              begin
                  MakeEdit := meMake;
                  SQLBuilder(scsQOperat, qtInsert, 'norms', '', NormsFields, false);
              end
            else
              if MemTable_NormsEd.FieldByName('isModified').AsBoolean = true then
                begin
                    MakeEdit := meEdit;
                    SQLBuilder(scsQOperat, qtUpdate, 'norms', 'id = :id', NormsFields, false);
                    scsQOperat.ParamByName('id').AsInteger := MemTable_NormsEd.FieldByName('id').AsInteger;
                    CurrIDNorm := MemTable_NormsEd.FieldByName('id').AsInteger;
                end;
            if MakeEdit <> meNone then
              begin
                  scsQOperat.ParamByName('ID_MASTER').AsInteger := GIDMaster;
                  scsQOperat.ParamByName('TABLE_KIND').AsInteger := GTableKind;
                  scsQOperat.ParamByName('NPP').AsInteger := MemTable_NormsEd.FieldByName('NPP').AsInteger;
                  scsQOperat.ParamByName('ISON').AsInteger := MemTable_NormsEd.FieldByName('ISOn').AsInteger;
                  scsQOperat.ParamByName('KOLVO').AsFloat := MemTable_NormsEd.FieldByName('Kolvo').AsFloat;
                  scsQOperat.ParamByName('TOTAL_COST').AsFloat := MemTable_Norms.FieldByName('TOTAL_COST').AsFloat;
                  scsQOperat.ParamByName('CYPHER').AsString := MemTable_NormsEd.FieldByName('Cypher').AsString;
                  scsQOperat.ParamByName('NAME').AsString := MemTable_NormsEd.FieldByName('NAME').AsString;
                  scsQOperat.ParamByName('WORK_KIND').AsString := MemTable_NormsEd.FieldByName('WORK_KIND').AsString;
                  scsQOperat.ParamByName('IZM').AsString := MemTable_NormsEd.FieldByName('IZM').AsString;
                  scsQOperat.ParamByName('COST').AsFloat := MemTable_NormsEd.FieldByName('COST').AsFloat;
                  scsQOperat.ExecQuery;
                  scsQOperat.Close;
                  if MemTable_NormsEd.FieldByName('isNew').AsBoolean = true then
                    begin
                        SetSQLToQuery(scsQSelect, ' select MAX(ID) from norms ');
                        CurrIDNorm := scsQSelect.FN('MAX').AsInteger;
                    end;
              end;

            //*** Сохранить ресурс
            MemTable_ResourcesRelEd.First;
            while Not MemTable_ResourcesRelEd.Eof do
              begin
                  MakeEdit := meNone;
                  if MemTable_ResourcesRelEd.FieldByName('isNew').AsBoolean = true then
                    begin
                        MakeEdit := meMake;
                        SQLBuilder(scsQOperat, qtInsert, 'resources', '', ResourcesFields, false);
                    end
                  else
                    if MemTable_ResourcesRelEd.FieldByName('isModified').AsBoolean = true then
                      begin
                          MakeEdit := meEdit;
                          SQLBuilder(scsQOperat, qtUpdate, 'resources', 'id = :id', ResourcesFields, false);
                          scsQOperat.ParamByName('id').AsInteger := MemTable_ResourcesRelEd.FieldByName('id_resource').AsInteger;
                          CurrIDResource := MemTable_ResourcesRelEd.FieldByName('id_resource').AsInteger;
                      end;
                  if MakeEdit <> meNone then
                    begin
                        scsQOperat.ParamByName('CYPHER').AsString := MemTable_ResourcesRelEd.FieldByName('Cypher').AsString;
                        scsQOperat.ParamByName('NAME').AsString := MemTable_ResourcesRelEd.FieldByName('Name').AsString;
                        scsQOperat.ParamByName('IZM').AsString := MemTable_ResourcesRelEd.FieldByName('Izm').AsString;
                        scsQOperat.ParamByName('PRICE').AsFloat := MemTable_ResourcesRelEd.FieldByName('Price').AsFloat;
                        scsQOperat.ParamByName('RTYPE').AsInteger := MemTable_ResourcesRelEd.FieldByName('Rtype').AsInteger;
                        scsQOperat.ExecQuery;
                        scsQOperat.Close;
                        if MemTable_ResourcesRelEd.FieldByName('isNew').AsBoolean = true then
                          begin
                              SetSQLToQuery(scsQSelect, ' select MAX(ID) from resources ');
                              CurrIDResource := scsQSelect.FN('MAX').AsInteger;
                          end;

                        //*** Занести изменения в таблицу связей
                        if MakeEdit = meMake then
                          SQLBuilder(scsQOperat, qtInsert, 'norm_resource_rel', '', NormResourceRelFields, false)
                        else
                          if MakeEdit = meEdit then
                            begin
                                SQLBuilder(scsQOperat, qtUpdate, 'norm_resource_rel', 'id = :id', NormResourceRelFields, false);
                                scsQOperat.ParamByName('id').AsInteger := MemTable_ResourcesRelEd.FieldByName('id').AsInteger;
                            end;
                        scsQOperat.ParamByName('ID_MASTER').AsInteger := CurrIDNorm;
                        scsQOperat.ParamByName('TABLE_KIND').AsInteger := ctkNorm;
                        scsQOperat.ParamByName('ID_RESOURCE').AsInteger := CurrIDResource;
                        scsQOperat.ParamByName('KOLVO').AsFloat := MemTable_ResourcesRelEd.FieldByName('Kolvo').AsFloat;
                        scsQOperat.ParamByName('COST').AsFloat := MemTable_ResourcesRelEd.FieldByName('Cost').AsFloat;
                        scsQOperat.ParamByName('ISON').AsInteger := MemTable_ResourcesRelEd.FieldByName('IsON').AsInteger;
                        scsQOperat.ExecQuery;
                        scsQOperat.Close;
                    end;
                  MemTable_ResourcesRelEd.Next;
              end;
            MemTable_NormsEd.Next;
        end;

      NormsFields.Free;
      ResourcesFields.Free;
      NormResourceRelFields.Free; }
    end;
  except
    on E: Exception do
      AddExceptionToLog('TF_Norms.Button_OKClick: ' + E.Message);
  end;
end;

procedure TF_Norms.GT_NORMSFocusedRecordChanged(
  Sender: TcxCustomGridTableView; APrevFocusedRecord,
  AFocusedRecord: TcxCustomGridRecord;
  ANewItemRecordFocusingChanged: Boolean);
var
  i: Integer;
begin
  {
 if (AFocusedRecord.Index = 0) and (GTableKind = ctkComponent) then
   begin
       //Act_AddResource.Enabled := false;
       GT_NORMS.OptionsSelection.CellSelect := false;
   end
 else
   begin
       //Act_AddResource.Enabled := true;
       GT_NORMS.OptionsSelection.CellSelect := true;
   end;}

  if TF_Main(GForm).DM.MemTable_NormsEd.FieldByName('isResource').AsBoolean = true then
    GroupBox_ResourcesRel.Enabled := false
  else
    GroupBox_ResourcesRel.Enabled := true;

  EnableEditDelNorm;
end;

// ##### Обработка процесса редактирования любой ячейки Грида Норм #####

procedure TF_Norms.GT_NORMSEditing(Sender: TcxCustomGridTableView;
  AItem: TcxCustomGridTableItem; var AAllow: Boolean);
begin
  with TF_Main(GForm).DM do
  begin
    MemTable_NormsEd.Edit;
    MemTable_NormsEd.FieldByName(fnIsModified).AsBoolean := true;
    MemTable_NormsEd.Post;
  end;
end;

// ##### Обработка щелчка левой клавиши по полю Грида Норм #####

procedure TF_Norms.GT_NORMSCellClick(Sender: TcxCustomGridTableView; ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton;
  AShift: TShiftState; var AHandled: Boolean);
begin
  //if TF_Main(GForm).DM.MemTable_NormsEd.RecNo > 1 then
  if ACellViewInfo.Item.Index = 1 then //*** Поле "Включен"
    with TF_Main(GForm).DM do
    begin
      MemTable_NormsEd.Edit;
      MemTable_NormsEd.FieldByName('IsOn').AsInteger := 1 - MemTable_NormsEd.FieldByName('IsOn').AsInteger;
      MemTable_NormsEd.FieldByName('IsModified').AsBoolean := true;
      MemTable_NormsEd.Post;
      CalcWorkCost;
      AHandled := true;
    end;
end;

// ##### Изменение количества Норм #####

procedure TF_Norms.GT_NORMSKolvoPropertiesValidate(Sender: TObject;
  var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
var
  Cost, Kolvo, TotalCost: Double;
begin
  Error := false;
  with TF_Main(GForm).DM do
  begin
    Cost := MemTable_NormsEd.FieldByName('Cost').AsFloat;
    Kolvo := DisplayValue;
    TotalCost := Cost * Kolvo;
    MemTable_NormsEd.Edit;
    MemTable_NormsEd.FieldByName('Total_Cost').AsFloat := TotalCost;
    MemTable_NormsEd.FieldByName('kolvo').AsFloat := kolvo;
    MemTable_NormsEd.Post;
  end;
  CalcWorkCost;
end;

// ##### Изменение ед-й стоимости Нормы #####

procedure TF_Norms.GT_NORMSCostPropertiesValidate(Sender: TObject;
  var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
var
  Cost, Kolvo, TotalCost: Double;
begin
  Error := false;
  with TF_Main(GForm).DM do
  begin
    Cost := DisplayValue;
    Kolvo := MemTable_NormsEd.FieldByName('Kolvo').AsFloat;
    TotalCost := Cost * Kolvo;
    MemTable_NormsEd.Edit;
    MemTable_NormsEd.FieldByName('Total_Cost').AsFloat := TotalCost;
    MemTable_NormsEd.FieldByName('Cost').AsFloat := Cost;
    MemTable_NormsEd.Post;
  end;
  CalcWorkCost;
end;

// ##### Обработка процесса редактирования любой ячейки Грида Ресурсов #####

procedure TF_Norms.GT_ResourcesEditing(Sender: TcxCustomGridTableView;
  AItem: TcxCustomGridTableItem; var AAllow: Boolean);
begin
  with TF_Main(GForm).DM do
  begin
    MemTable_ResourcesRelEd.Edit;
    MemTable_ResourcesRelEd.FieldByName('isModified').AsBoolean := true;
    MemTable_ResourcesRelEd.Post;
  end;
end;

// ##### Обработка щелчка левой клавиши по полю Грида Ресурсов #####

procedure TF_Norms.GT_ResourcesCellClick(Sender: TcxCustomGridTableView;
  ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton;
  AShift: TShiftState; var AHandled: Boolean);
//var RecordNo: Integer;
begin
  with TF_Main(GForm).DM do
    try
      try
        if ACellViewInfo.Item.Index = 1 then //*** Поле "Включен"
        begin
          //RecordNo := MemTable_ResourcesRelEd.RecNo;
          MemTable_ResourcesRelEd.Edit;
          MemTable_ResourcesRelEd.FieldByName('IsOn').AsInteger := 1 - MemTable_ResourcesRelEd.FieldByName('IsOn').AsInteger;
          MemTable_ResourcesRelEd.FieldByName('IsModified').AsBoolean := true;
          MemTable_ResourcesRelEd.Post;
          CalcNormCost;
          AHandled := true;
        end;
      except
        on E: Exception do
          AddExceptionToLog('TF_Norms.GT_ResourcesCellClick: ' + E.Message);
      end;
    finally
      //MemTable_ResourcesRelEd.RecNo := RecordNo;
    end;
end;

// ##### Изменение количества ресурсов #####

procedure TF_Norms.GT_ResourcesKolvoPropertiesValidate(Sender: TObject;
  var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
var
  cost, price, AdditionalPrice, kolvo: Double;
begin
  Error := false;
  with TF_Main(GForm).DM do
  begin
    price := MemTable_ResourcesRelEd.FieldByName('Price').AsFloat;
    AdditionalPrice := MemTable_ResourcesRelEd.FieldByName(fnAdditionalPrice).AsFloat;
    kolvo := DisplayValue; //MemTable_ResourcesRelEd.FieldByName('kolvo').AsInteger;
    cost := (price + AdditionalPrice) * kolvo;
    MemTable_ResourcesRelEd.Edit;
    MemTable_ResourcesRelEd.FieldByName('Cost').AsFloat := cost; //MemTable_ResourcesRelEd.FieldByName('Price').AsFloat * MemTable_ResourcesRelEd.FieldByName('kolvo').AsInteger;
    MemTable_ResourcesRelEd.FieldByName('kolvo').AsFloat := kolvo;
    MemTable_ResourcesRelEd.Post;
  end;
  CalcNormCost;
end;

// ##### Изменение цены ресурса #####

procedure TF_Norms.GT_ResourcesPricePropertiesValidate(Sender: TObject;
  var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
var
  cost, price, AdditionalPrice, kolvo: Double;
begin
  Error := false;
  with TF_Main(GForm).DM do
  begin
    price := DisplayValue;
    AdditionalPrice := MemTable_ResourcesRelEd.FieldByName(fnAdditionalPrice).AsFloat;
    kolvo := MemTable_ResourcesRelEd.FieldByName('kolvo').AsFloat;
    cost := (price + AdditionalPrice) * kolvo;
    MemTable_ResourcesRelEd.Edit;
    MemTable_ResourcesRelEd.FieldByName('Cost').AsFloat := cost; //MemTable_ResourcesRelEd.FieldByName('Price').AsFloat * MemTable_ResourcesRelEd.FieldByName('kolvo').AsInteger;
    MemTable_ResourcesRelEd.FieldByName('price').AsFloat := price;
    MemTable_ResourcesRelEd.Post;
  end;
  CalcNormCost;
end;

procedure TF_Norms.GT_ResourcesAdditionalPricePropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
var
  cost, price, AdditionalPrice, kolvo: Double;
begin
  Error := false;
  with TF_Main(GForm).DM do
  begin
    price := MemTable_ResourcesRelEd.FieldByName(fnPrice).AsFloat;
    AdditionalPrice := DisplayValue;
    kolvo := MemTable_ResourcesRelEd.FieldByName('kolvo').AsInteger;
    cost := (price + AdditionalPrice) * kolvo;
    MemTable_ResourcesRelEd.Edit;
    MemTable_ResourcesRelEd.FieldByName('Cost').AsFloat := cost; //MemTable_ResourcesRelEd.FieldByName('Price').AsFloat * MemTable_ResourcesRelEd.FieldByName('kolvo').AsInteger;
    MemTable_ResourcesRelEd.FieldByName(fnAdditionalPrice).AsFloat := AdditionalPrice;
    MemTable_ResourcesRelEd.Post;
  end;
  CalcNormCost;
end;

procedure TF_Norms.Panel_OKCancelResize(Sender: TObject);
begin
  SetMiddleControlChilds(TControl(Sender), TControl(Self));
end;

end.

