unit U_NormsGroups;

interface

uses
  Windows, U_LNG, Messages, SysUtils, Variants, Classes, Graphics, Controls, Contnrs, 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;

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

type
  TF_NormsGroups = class(TForm)
    RzGroupBox1: TRzGroupBox;
    gbOkCancel: TRzGroupBox;
    btOK: TRzBitBtn;
    btCancel: TRzBitBtn;
    RzPanel1: TRzPanel;
    GT_Norms: TcxGridDBTableView;
    GL_Norms: TcxGridLevel;
    gridNorms: TcxGrid;
    mtNorms: TkbmMemTable;
    dsrcNorms: TDataSource;
    lbTotalCost: TLabel;
    neTotalCost: TRzNumericEdit;
    GT_NormsName: TcxGridDBColumn;
    GT_NormsIzm: TcxGridDBColumn;
    GT_NormsKolvo: TcxGridDBColumn;
    GT_NormsPrice: TcxGridDBColumn;
    GT_NormsCost: TcxGridDBColumn;
    Timer_DefineTotalCost: TTimer;
    Timer_Post: TTimer;
    ActionManager: TActionManager;
    PopupMenu: TPopupMenu;
    Act_DelNorm: TAction;
    ToolBar1: TToolBar;
    ToolButton2: TToolButton;
    N2: TMenuItem;
    XPMenu1: TXPMenu;
    GT_NormsNpp: TcxGridDBColumn;
    btApply: TRzBitBtn;
    lng_Forms: TsiLangLinked;
    GT_NormsTransformToUOM: TcxGridDBColumn;
    GT_NormsGUIDNBCompon: TcxGridDBColumn;
    GT_NormsIcon: TcxGridDBColumn;
    GT_NormsLaborTime: TcxGridDBColumn;
    GT_NormsPricePerTime: TcxGridDBColumn;
    procedure gbOkCancelResize(Sender: TObject);
    procedure mtNormsBeforeEdit(DataSet: TDataSet);
    procedure mtNormsAfterEdit(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_NormsEditing(Sender: TcxCustomGridTableView;
      AItem: TcxCustomGridTableItem; var AAllow: Boolean);
    procedure GT_NormsEditValueChanged(Sender: TcxCustomGridTableView;
      AItem: TcxCustomGridTableItem);
    procedure Timer_DefineTotalCostTimer(Sender: TObject);
    procedure Timer_PostTimer(Sender: TObject);
    procedure Act_DelNormExecute(Sender: TObject);
    procedure GT_NormsNppGetDisplayText(Sender: TcxCustomGridTableItem;
      ARecord: TcxCustomGridRecord; var AText: String);
    procedure btApplyClick(Sender: TObject);
    procedure GT_NormsIzmGetDisplayText(Sender: TcxCustomGridTableItem;
      ARecord: TcxCustomGridRecord; var AText: String);
    procedure GT_NormsPriceGetDisplayText(
      Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
      var AText: String);
    procedure GT_NormsInitEdit(Sender: TcxCustomGridTableView;
      AItem: TcxCustomGridTableItem; AEdit: TcxCustomEdit);
    procedure GT_NormsKolvoGetDisplayText(
      Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
      var AText: String);
    procedure GT_NormsFocusedRecordChanged(
      Sender: TcxCustomGridTableView; APrevFocusedRecord,
      AFocusedRecord: TcxCustomGridRecord;
      ANewItemRecordFocusingChanged: Boolean);
    procedure GT_NormsCustomDrawCell(Sender: TcxCustomGridTableView;
      ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo;
      var ADone: Boolean);
    procedure Act_LoadPricesFromNBExecute(Sender: TObject);
    procedure neTotalCostKeyPress(Sender: TObject; var Key: Char);
    procedure neTotalCostExit(Sender: TObject);
    procedure GT_NormsLaborTimeGetDisplayText(
      Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
      var AText: String);
    procedure GT_NormsLaborTimePropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure GT_NormsPricePerTimePropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure GT_NormsKolvoPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure FormDestroy(Sender: TObject);
  private
    GForm: TForm;
    FCanHaveActiveComponents: Boolean;
    FCanHaveDismountAccount: Boolean;
    FComponsWithZeroPrice: Boolean;
    FFolder: TSCSCatalog;
    FLastTotalCost: Double;
    FNormResources: TSCSNormsResources;
    //FReportName: String;

    Edit: TcxCustomEdit;
    //Colmn Indexes
    FTransToUOMIdx: Integer;
    FDeletedGroups: TObjectList;

    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 SendToMT;
    procedure SetActions;
  public
    constructor Create(AOwner: TComponent; AForm: TForm); overload;
    destructor Destroy; override;

    function Execute(AFolder: TSCSCatalog;
              ACanHaveActiveComponents, ACanHaveDismountAccount, AComponsWithZeroPrice: Boolean): Boolean;
  end;

//var
  //F_NormsGroups: TF_NormsGroups;

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

{ TF_NormsGroups }

constructor TF_NormsGroups.Create(AOwner: TComponent; AForm: TForm);
begin
  GForm := AForm;
  inherited Create(AOwner);
end;

destructor TF_NormsGroups.Destroy;
begin

  inherited;
end;

function TF_NormsGroups.Execute(AFolder: TSCSCatalog;
  ACanHaveActiveComponents, ACanHaveDismountAccount, AComponsWithZeroPrice: Boolean): Boolean;
begin
  Result := false;
  if AFolder <> nil then
  begin
    FFolder := AFolder;
    FCanHaveActiveComponents := ACanHaveActiveComponents;
    FCanHaveDismountAccount := ACanHaveDismountAccount;
    FComponsWithZeroPrice := AComponsWithZeroPrice;
    //FReportName := AReportName;
    FLastTotalCost := -1;
    FNormResources := nil;

    mtNorms.Active := False;
    mtNorms.Active := True;

    FDeletedGroups.Clear;

    PrepareForm;
    SendToMT;

    try
      if ShowModal = mrOk then
      begin
        Result := true;
        SendFromMTToObjects;
      end;
    finally
      if FNormResources <> nil then
        FreeAndNil(FNormResources);
    end;
  end;
end;

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

procedure TF_NormsGroups.FormCreate(Sender: TObject);
var
  i: Integer;
  Action: TAction;

begin
  for i := 0 to ActionManager.ActionCount - 1 do
  begin
    Action := TAction(ActionManager.Actions[i]);
    Action.Hint := Action.Caption;
  end;

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

  mtNorms.FieldDefs.Add(fnName, ftString, 255);
  mtNorms.FieldDefs.Add(fnArticulProducer, ftString, 255);
  mtNorms.FieldDefs.Add(fnArticulDistributor, ftString, 255);
  mtNorms.FieldDefs.Add(fnGuidProducer, ftString, 255);
  mtNorms.FieldDefs.Add(fnIzm, ftString, 50);
  mtNorms.FieldDefs.Add(fnLaborTime, ftInteger);
  mtNorms.FieldDefs.Add(fnPricePerTime, ftFloat);
  mtNorms.FieldDefs.Add(fnKolvo, ftFloat);
  mtNorms.FieldDefs.Add(fnPrice, ftFloat);
  mtNorms.FieldDefs.Add(fnCost, ftFloat);
  mtNorms.FieldDefs.Add(fnPriceNB, ftFloat);

  FDeletedGroups := TObjectList.Create(false);

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

end;


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

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

  //30.12.2013
  DisplayFormatM := GetDisplayFormat(TF_Main(GForm).GCurrencyM.NameBrief);
  GT_NormsLaborTime.Caption := TF_Main(GForm).GT_NormsResourcesLaborTime.Caption;
  GT_NormsPricePerTime.Caption := TF_Main(GForm).GT_NormsResourcesPricePerTime.Caption;
  TcxCurrencyEditProperties(GT_NormsPricePerTime.Properties).DisplayFormat := DisplayFormatM; //GetDisplayFormatForFloat;
  TcxCurrencyEditProperties(GT_NormsPricePerTime.Properties).DecimalPlaces := FloatPrecision;

  FTransToUOMIdx := GT_NormsTransformToUOM.Index;
  SetCxCurrencyEditProperties(GT_NormsPrice.Properties); //29.08.2012 TcxCurrencyEditProperties(GT_NormsPrice.Properties).DisplayFormat := GetDisplayFormatForFloat;
  SetCxCurrencyEditProperties(GT_NormsCost.Properties); //29.08.2012 TcxCurrencyEditProperties(GT_NormsCost.Properties).DisplayFormat := GetDisplayFormatForFloat;
  //SetCxCurrencyEditProperties(GT_NormsPriceNB.Properties); //29.08.2012 TcxCurrencyEditProperties(GT_NormsPriceNB.Properties).DisplayFormat := GetDisplayFormatForFloat;

  GT_NormsKolvo.Caption := TF_Main(GForm).GT_NormsResourcesKolvo.Caption;
  TcxCurrencyEditProperties(GT_NormsKolvo.Properties).DisplayFormat := GetDisplayFormatForFloatByPrecision(PrecisionNormKolvo);
  TcxCurrencyEditProperties(GT_NormsKolvo.Properties).DecimalPlaces := PrecisionNormKolvo;
  GT_NormsCost.Caption := TF_Main(GForm).GT_NormsResourcesCost.Caption;

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

  //GT_NormsPrice.Caption := cReportForm_Msg1 + CurrencyName;
  //GT_NormsCost.Caption := cReportForm_Msg2 + CurrencyName;
  //GT_NormsPriceNB.Caption := cReportForm_Msg1_2 + CurrencyName;
  lbTotalCost.Caption := cReportForm_Msg3 + CurrencyName;
end;

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

end;

procedure TF_NormsGroups.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;

  PercentFromLast := RoundX((NewValue * 100) / FLastTotalCost, 20);

  if mtNorms.RecordCount > 0 then
  begin
    RecNo := mtNorms.RecNo;
    mtNorms.DisableControls;
    try
      for i := 0 to mtNorms.RecordCount - 1 do
      begin
        mtNorms.RecNo := i+1;

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

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

procedure TF_NormsGroups.mtNormsBeforeEdit(DataSet: TDataSet);
begin
  //beep;
end;

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

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

procedure TF_NormsGroups.SendFromMTToObjects;
var
  NormGrp: TSCSNormGroup;
  Norm: TSCSNorm;
  NormOwner: TSCSComponCatalogClass;
  //SCSComponent: TSCSComponent;
  //PartComponent: TSCSComponent;

  //ResourceRel: TSCSResourceRel;
  NormIdx: Integer;

  RecNo: Integer;
  i, j, k: Integer;
  IsRecalcTotal: Boolean;
begin
  RecNo := mtNorms.RecNo;
  mtNorms.DisableControls;
  try
    IsRecalcTotal := false;
    for i := 0 to mtNorms.RecordCount - 1 do
    begin
      mtNorms.RecNo := i+1;
      if mtNorms.FieldByName(fnIsModified).AsBoolean then
      begin
        NormGrp := TSCSNormGroup(mtNorms.FieldByName(fnObjectAddress).AsInteger);
        if Assigned(NormGrp) then
          for j := 0 to NormGrp.ObjectList.Count - 1 do
          begin
            Norm := TSCSNorm(NormGrp.ObjectList[j]);

            Norm.Name := mtNorms.FieldByName(fnName).AsString;
            Norm.Izm_ := mtNorms.FieldByName(fnIzm).AsString;
            Norm.LaborTime := mtNorms.FieldByName(fnLaborTime).AsInteger;
            Norm.PricePerTime := RoundX(mtNorms.FieldByName(fnPricePerTime).AsFloat, PrecisionNormKolvo);
            Norm.Kolvo := RoundX(mtNorms.FieldByName(fnKolvo).AsFloat, PrecisionNormKolvo);
            Norm.Price := RoundX(mtNorms.FieldByName(fnCost).AsFloat, PrecisionNormKolvo);

            //Norm.CalcCost;
          end;
        mtNorms.Edit;
        mtNorms.FieldByName(fnIsModified).AsBoolean := False;
        mtNorms.FieldByName(fnPriceNB).Value := null;
        mtNorms.Post;
      end;
    end;

    //Применение удаления
    for i := 0 to FDeletedGroups.Count - 1 do
    begin
      NormGrp := TSCSNormGroup(FDeletedGroups[i]);
      if Assigned(NormGrp) then
      begin
        for j := 0 to NormGrp.ObjectList.Count - 1 do
        begin
          Norm := TSCSNorm(NormGrp.ObjectList[j]);
          NormOwner := nil;
          case Norm.MasterTableKind Of
            ctkComponent:
              NormOwner := FFolder.GetComponentFromReferences(Norm.IDMaster);
            ctkCatalog:
              begin
                if FFolder.Id = Norm.IDMaster then
                  NormOwner := FFolder
                else
                  NormOwner := FFolder.GetCatalogFromReferences(Norm.IDMaster)
              end;
          end;
          if NormOwner <> nil then
          begin
            NormIdx := NormOwner.NormsResources.Norms.IndexOf(Norm);
            if NormIdx <> -1 then
            begin
              NormOwner.NormsResources.Norms.Delete(NormIdx);
              FreeAndNil(Norm);
              NormGrp.ObjectList[j] := nil;
            end;
          end;
        end;
        NormGrp.ObjectList.Pack;
      end;
    end;
    FDeletedGroups.Clear;

    if IsRecalcTotal then
      Timer_DefineTotalCost.Enabled := true;

    TF_Main(GForm).RefreshNode(false);
  finally
    if RecNo > -1 then // Tolik 28/12/2019 --
      mtNorms.RecNo := RecNo;
    mtNorms.EnableControls;
  end;
end;


procedure TF_NormsGroups.SendToMT;
var
  Norm: TSCSNormGroup;
  i: Integer;
begin
  BeginProgress(pcPreparingReport);
  try
    FNormResources := FFolder.GetAllNormsResources([nrNorms], false, FCanHaveActiveComponents, FCanHaveDismountAccount, FComponsWithZeroPrice, false, true, false, true, true);
    //FNormResources := FFolder.GetAllNormsResources([nrNorms], false, true, false, true, true, false);

    //mtNorms.AfterPost := nil;
    mtNorms.DisableControls;
    try
      mtNorms.Active := false;
      mtNorms.Active := true;

      for i := 0 to FNormResources.Norms.Count - 1 do
      begin
        Norm := TSCSNormGroup(FNormResources.Norms[i]);

        mtNorms.Append;
        mtNorms.FieldByName(fnGuid).AsString := Norm.GuidNB;
        mtNorms.FieldByName(fnIsModified).AsBoolean := false;
        mtNorms.FieldByName(fnObjectAddress).AsInteger := Integer(Norm);

        mtNorms.FieldByName(fnName).AsString := Norm.Name;
        mtNorms.FieldByName(fnIzm).AsString := Norm.Izm_;
        mtNorms.FieldByName(fnLaborTime).AsInteger := Norm.LaborTime;
        mtNorms.FieldByName(fnPricePerTime).AsFloat := RoundCP(Norm.PricePerTime);
        mtNorms.FieldByName(fnKolvo).AsFloat := RoundX(Norm.GrpKolvo, PrecisionNormKolvo);
        //mtNorms.FieldByName(fnPrice).AsFloat := Round3(Norm.Price);
        mtNorms.FieldByName(fnCost).AsFloat := RoundCP(Norm.Price);
        mtNorms.Post;
      end;
      mtNorms.SortOn(fnName, []);
    finally
      mtNorms.EnableControls;
      //mtNorms.AfterPost := mtResourcesAfterPost;
      if mtNorms.RecordCount > 0 then
        mtNorms.First;
    end;
  finally
    EndProgress;
  end;
  DefineTotalCost;
  SetActions;
end;

procedure TF_NormsGroups.SetActions;
begin
  //Act_ReplaceComponent.Enabled := mtNorms.RecordCount > 0;
  Act_DelNorm.Enabled := mtNorms.RecordCount > 0;
end;

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

  SavedOnChange: TNotifyevent;
begin
  CurrCost := 0;

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

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

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

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

procedure TF_NormsGroups.GT_ResourcesCostPropertiesValidate(Sender: TObject;
  var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
var
  ValueFloat: Double;
  IsCalcNormTotal: Boolean;
begin
  try
    if DisplayValue = '' then
    begin
      DisplayValue := FloatToStr(mtNorms.FieldByName(fnCost).AsFloat);
      Exit; ///// EXIT /////
    end;
    ValueFloat := StrToFloat(DisplayValue);

    mtNorms.Edit;
    mtNorms.FieldByName(fnCost).AsFloat := ValueFloat;
    mtNorms.Post;

    TF_Main(GForm).DM.CalcNormCostTime(mtNorms, fnCost, IsCalcNormTotal);
  except
  end;
end;

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

procedure TF_NormsGroups.neTotalCostChange(Sender: TObject);
begin
  OnTotalCostChange;
end;

procedure TF_NormsGroups.GT_NormsEditing(Sender: TcxCustomGridTableView;
  AItem: TcxCustomGridTableItem; var AAllow: Boolean);
begin
  //mtNorms.Edit;
  //mtNorms.FieldByName(fnIsModified).AsBoolean := true;
  //mtNorms.Post;
end;

procedure TF_NormsGroups.GT_NormsEditValueChanged(
  Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem);
begin
  if (Sender.DataController.IsEditing) and (mtNorms.State <> dsBrowse) then
  begin
    Timer_Post.Enabled := true;
  end;
end;

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

procedure TF_NormsGroups.Timer_PostTimer(Sender: TObject);
begin
  TTimer(Sender).Enabled := false;
  if mtNorms.State <> dsBrowse then
  begin
    GT_Norms.DataController.Post;
  end;
end;


procedure TF_NormsGroups.Act_DelNormExecute(Sender: TObject);
begin
  try
    FDeletedGroups.Add(TObject(mtNorms.FieldByName(fnObjectAddress).AsInteger));
    mtNorms.Delete;
  except
    on E: Exception do AddExceptionToLog('TF_NormsGroups.Act_DelNormsExecute: '+E.Message);
  end;
end;

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

procedure TF_NormsGroups.btApplyClick(Sender: TObject);
begin
  SendFromMTToObjects;
end;

procedure TF_NormsGroups.GT_NormsIzmGetDisplayText(
  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_NormsGroups.GT_NormsKolvoGetDisplayText(
  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(AText);
        ValueFloat := FloatInUOM(ValueFloat, umMetr, TF_Main(GForm).FUOM);
        AText := FloatToStr(RoundCP(ValueFloat));
      end;
  except
  end;
end;

procedure TF_NormsGroups.GT_NormsPriceGetDisplayText(
  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);
  except
  end;
end;

procedure TF_NormsGroups.GT_NormsInitEdit(
  Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem;
  AEdit: TcxCustomEdit);
begin
  if (AItem = GT_NormsPrice) {or (AItem = GT_NormsPriceNB)} then
    AEdit.EditValue := GetDisplayTextToNORMExpenseForLength(AEdit.EditValue, TF_Main(GForm).FUOM);
  Edit := AEdit;
end;

procedure TF_NormsGroups.GT_NormsFocusedRecordChanged(
  Sender: TcxCustomGridTableView; APrevFocusedRecord,
  AFocusedRecord: TcxCustomGridRecord;
  ANewItemRecordFocusingChanged: Boolean);
var
  CanEditIzm: Boolean;
begin
  CanEditIzm := true;
  if mtNorms.Active then
    if mtNorms.FieldByName(fnTransToUOM).AsBoolean then
      CanEditIzm := false;
  GT_NormsIzm.Options.Editing := CanEditIzm;
end;

procedure TF_NormsGroups.GT_NormsCustomDrawCell(
  Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
  AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
  //OnNormsResourcesCustomDrawCell(ACanvas, AViewInfo, GT_NormsIsResource.Index, GT_NormsGUIDNBCompon.Index, -1, false);
end;

procedure TF_NormsGroups.Act_LoadPricesFromNBExecute(Sender: TObject);
var
  i: Integer;
  GUIDCompon: String;
  IDCompon: Integer;
  NBPrice: Double;
  Compon: TSCSComponent;
  BookMark: String;
begin
  {GT_NormsPriceNB.Visible := true;

  BookMark := mtNorms.Bookmark;
  try
    Compon := TSCSComponent.Create(F_NormBase);
    for i := 0 to GT_Norms.Controller.SelectedRecordCount - 1 do
    begin
      //GT_Norms.Controller.SelectedRows[i].
      GUIDCompon := GT_Norms.Controller.SelectedRecords[i].Values[GT_NormsGUIDNBCompon.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_Norms.Controller.SelectedRecords[i].Values[GT_NormsPriceNB.Index] := Compon.Price;
        //GT_Norms.DataController.Values[GT_Norms.Controller.SelectedRecords[i].Index, GT_NormsPriceNB.Index] := Compon.Price;
        if mtNorms.Locate(fnGuidNBComponent, GUIDCompon, []) then
        begin
          mtNorms.Edit;
          mtNorms.FieldByName(fnPriceNB).AsFloat := RoundCP(Compon.Price);
          mtNorms.Post;
        end;
      end;
    end;
    Compon.Free;
  finally
    mtNorms.Bookmark := BookMark;
  end;}
end;


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

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

procedure TF_NormsGroups.GT_NormsLaborTimeGetDisplayText(
  Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
  var AText: String);
begin
  AText := GetDisplayTextToNORMLaborTime(AText);
end;

procedure TF_NormsGroups.GT_NormsLaborTimePropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
var
  ValueFloat: Double;
  IsCalcNormTotal: Boolean;
begin
  try
    if DisplayValue = '' then
    begin
      DisplayValue := FloatToStr(mtNorms.FieldByName(fnLaborTime).AsInteger);
      Exit; ///// EXIT /////
    end;
    ValueFloat := StrToFloat(DisplayValue);

    mtNorms.Edit;
    mtNorms.FieldByName(fnLaborTime).AsFloat := ValueFloat;
    mtNorms.Post;

    TF_Main(GForm).DM.CalcNormCostTime(mtNorms, fnLaborTime, IsCalcNormTotal);
  except
  end;
end;

procedure TF_NormsGroups.GT_NormsPricePerTimePropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
var
  ValueFloat: Double;
  IsCalcNormTotal: Boolean;
begin
  try
    if DisplayValue = '' then
    begin
      DisplayValue := FloatToStr(mtNorms.FieldByName(fnPricePerTime).AsFloat);
      Exit; ///// EXIT /////
    end;
    ValueFloat := StrToFloat(DisplayValue);

    mtNorms.Edit;
    mtNorms.FieldByName(fnPricePerTime).AsFloat := ValueFloat;
    mtNorms.Post;

    TF_Main(GForm).DM.CalcNormCostTime(mtNorms, fnPricePerTime, IsCalcNormTotal);
  except
  end;
end;

procedure TF_NormsGroups.GT_NormsKolvoPropertiesValidate(Sender: TObject;
  var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
var
  ValueFloat: Double;
begin
  try
    if DisplayValue = '' then
    begin
      DisplayValue := FloatToStr(mtNorms.FieldByName(fnKolvo).AsFloat);
      Exit; ///// EXIT /////
    end;
    ValueFloat := StrToFloat(DisplayValue);

    mtNorms.Edit;
    mtNorms.FieldByName(fnKolvo).AsFloat := ValueFloat;
    //mtNorms.FieldByName(fnExpenseForLength).AsFloat := 0;
    //mtNorms.FieldByName(fnCountForPoint).AsFloat := 0;
    //mtNorms.FieldByName(fnStepOfPoint).AsFloat := 0;
    mtNorms.Post;
  except
  end;
end;

procedure TF_NormsGroups.FormDestroy(Sender: TObject);
begin
  FreeAndNil(FDeletedGroups);
end;

end.
