unit U_NormsComplete;

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,
  cxCalendar, cxLookAndFeels, cxLookAndFeelPainters, cxNavigator,
  PlatformDefaultStyleActnCtrls;

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

type
  TF_NormsComplete = 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_DefineTotals: TTimer;
    Timer_Post: TTimer;
    ActionManager: TActionManager;
    PopupMenu: TPopupMenu;
    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;
    GT_NormsWorkersAmount: TcxGridDBColumn;
    GT_NormsStartDate: TcxGridDBColumn;
    GT_NormsEndDate: TcxGridDBColumn;
    GT_NormsTotalLaborTime: TcxGridDBColumn;
    GT_NormsTotalCost: TcxGridDBColumn;
    GT_NormsCompletePct: TcxGridDBColumn;
    GT_NormsDone: TcxGridDBColumn;
    GT_NormsID: TcxGridDBColumn;
    Label1: TLabel;
    Label2: TLabel;
    edTotalTime: TRzEdit;
    edRemainingTime: TRzEdit;
    procedure gbOkCancelResize(Sender: TObject);
    procedure mtNormsBeforeEdit(DataSet: TDataSet);
    procedure mtNormsAfterEdit(DataSet: TDataSet);
    procedure FormCreate(Sender: TObject);
    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_DefineTotalsTimer(Sender: TObject);
    procedure Timer_PostTimer(Sender: TObject);
    procedure GT_NormsNppGetDisplayText(Sender: TcxCustomGridTableItem;
      ARecord: TcxCustomGridRecord; var AText: String);
    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 GT_NormsWorkersAmountPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure GT_NormsStartDatePropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
    procedure GT_NormsTotalLaborTimeGetDisplayText(
      Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord;
      var AText: String);
    procedure GT_NormsTotalLaborTimeCustomDrawCell(
      Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
      AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
    procedure GT_NormsEndDateCustomDrawCell(Sender: TcxCustomGridTableView;
      ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo;
      var ADone: Boolean);
    procedure FormDestroy(Sender: TObject);
    procedure GT_NormsCompletePctPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
  private
    GForm: TForm;
    FCanHaveActiveComponents: Boolean;
    FCanHaveDismountAccount: Boolean;
    FComponsWithZeroPrice: Boolean;
    FFolder: TSCSCatalog;
    FLastTotalCost: Double;
    FNormResources: TSCSNormsResources;
    //FReportName: String;

    Edit: TcxCustomEdit;
    //Colmn Indexes
    //FTransToUOMIdx: Integer;
    FIdsChangedTotalLaborTime: TIntList;

    procedure CalcEndDate;
    //procedure DefineTotalCost;
    procedure DefineTotals;
    procedure PrepareForm;
    procedure OnDrawCellAsChanged(ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo);
    function OnPriceValidate(const aFieldName: String; var aDisplayValue: Variant): Double;
    procedure OnTotalCostChange;
    procedure SendPriceAndCostToCurrRecord(APrice, ACost: Double);
    procedure SendStringToCurrRecord(AFieldName, AValue: String);
    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_NormsComplete: TF_NormsComplete;

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

{ TF_NormsComplete }

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

destructor TF_NormsComplete.Destroy;
begin

  inherited;
end;

function TF_NormsComplete.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;
    dsrcNorms.DataSet := TF_Main(GForm).GSCSBase.CurrProject.MTNormsComplete; //TF_Main(GForm).DM.tSQL_NormsComplete;
    dsrcNorms.DataSet.DisableControls;
    try
      PrepareForm;
      SendToMT;
    finally
      dsrcNorms.DataSet.EnableControls;
    end;

    dsrcNorms.DataSet.EnableControls;
    try
      if ShowModal = mrOk then
      begin
        Result := true;
      end;
    finally
      dsrcNorms.DataSet.DisableControls;
      dsrcNorms.DataSet := nil;
      if FNormResources <> nil then
        FreeAndNil(FNormResources);
    end;
  end;
end;

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

procedure TF_NormsComplete.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);

  FIdsChangedTotalLaborTime := TIntList.Create;
end;


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

  GT_NormsTotalLaborTime.Caption := TF_Main(GForm).GT_NormsResourcesLaborTime.Caption;
  GT_NormsPricePerTime.Caption := TF_Main(GForm).GT_NormsResourcesPricePerTime.Caption;

  //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;
  SetCxCurrencyEditProperties(GT_NormsTotalCost.Properties);

  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;

procedure TF_NormsComplete.OnDrawCellAsChanged(ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo);
var
  RecID, CellColor: Integer;
begin
  RecID := AViewInfo.GridRecord.Values[GT_NormsID.Index];
  if FIdsChangedTotalLaborTime.IndexOf(RecID) <> -1 then
  begin
    CellColor := clBlue;
    if dsrcNorms.DataSet.RecNo > 0 then
      if RecID = dsrcNorms.DataSet.FieldByName(fnID).AsInteger then
        CellColor := clYellow;
    ACanvas.Font.Color := CellColor;
  end;
end;

function TF_NormsComplete.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_My(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_NormsComplete.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);

  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;
  FLastTotalCost := NewValue;
end;

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

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

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


procedure TF_NormsComplete.SendToMT;
var
  Norm: TSCSNormGroup;
  i: Integer;
  MTPositions: TStringList;
  NormKey: String;
  NormKeyIdx: Integer;
  OldTotalLaborTime: Integer;

  function GetNormKey(const aGUID, aCypher, aName: String; aPrice, aPricePerTime: Double; aLaborTime: Integer): String;
  begin
    Result := aGUID+'_'+aCypher+'_'+aName+'_'+FloatToStr(aPrice)+'_'+FloatToStr(aPricePerTime)+'_'+IntToStr(aLaborTime);
  end;

begin
  BeginProgress(pcPreparingReport);

  MTPositions := CreateStringListSorted;
  try
    FNormResources := FFolder.GetAllNormsResources([nrNorms], false, FCanHaveActiveComponents, FCanHaveDismountAccount, FComponsWithZeroPrice, false, true, false, true, true);
    //FNormResources := FFolder.GetAllNormsResources([nrNorms], false, true, false, true, true, false);

    dsrcNorms.DataSet.DisableControls;
    try
      //dsrcNorms.DataSet.Active := false;
      //dsrcNorms.DataSet.Active := true;
      FIdsChangedTotalLaborTime.Clear;
      for i := 1 to dsrcNorms.DataSet.RecordCount do
      begin
        dsrcNorms.DataSet.RecNo := i;
        MTPositions.AddObject(GetNormKey(
          dsrcNorms.DataSet.FieldByName(fnGuid).AsString,
          dsrcNorms.DataSet.FieldByName(fnCypher).AsString,
          dsrcNorms.DataSet.FieldByName(fnName).AsString,
          dsrcNorms.DataSet.FieldByName(fnCost).AsFloat,
          dsrcNorms.DataSet.FieldByName(fnPricePerTime).AsFloat,
          dsrcNorms.DataSet.FieldByName(fnLaborTime).AsInteger
        ), TObject(i));
      end;

      for i := 0 to FNormResources.Norms.Count - 1 do
      begin
        Norm := TSCSNormGroup(FNormResources.Norms[i]);
        NormKey := GetNormKey(Norm.GuidNB, Norm.Cypher, Norm.Name, RoundCP(Norm.Price), RoundCP(Norm.PricePerTime), Norm.LaborTime);
        NormKeyIdx := MTPositions.IndexOf(NormKey);
        if NormKeyIdx = -1 then
        begin
          dsrcNorms.DataSet.Append;
          dsrcNorms.DataSet.FieldByName(fnGuid).AsString := Norm.GuidNB;
          dsrcNorms.DataSet.FieldByName(fnCypher).AsString := Norm.Cypher;

          dsrcNorms.DataSet.FieldByName(fnName).AsString := Norm.Name;
          dsrcNorms.DataSet.FieldByName(fnIzm).AsString := Norm.Izm_;
          dsrcNorms.DataSet.FieldByName(fnLaborTime).AsInteger := Norm.LaborTime;
          dsrcNorms.DataSet.FieldByName(fnPricePerTime).AsFloat := RoundCP(Norm.PricePerTime);
          //dsrcNorms.DataSet.FieldByName(fnKolvo).AsFloat := RoundX(Norm.GrpKolvo, PrecisionNormKolvo);
          //dsrcNorms.DataSet.FieldByName(fnPrice).AsFloat := Round3(Norm.Price);
          dsrcNorms.DataSet.FieldByName(fnCost).AsFloat := RoundCP(Norm.Price);
          dsrcNorms.DataSet.FieldByName(fnTotalCost).AsFloat := RoundX(Norm.TotalCost, PrecisionNormKolvo);
          dsrcNorms.DataSet.FieldByName(fnTotalLaborTime).AsInteger := Round(Norm.LaborTime*Norm.Kolvo);
          dsrcNorms.DataSet.FieldByName(fnDone).AsInteger := biFalse;
          dsrcNorms.DataSet.Post;
        end
        else
        begin
          dsrcNorms.DataSet.RecNo := Integer(MTPositions.Objects[NormKeyIdx]);
          OldTotalLaborTime := dsrcNorms.DataSet.FieldByName(fnTotalLaborTime).AsInteger;

          dsrcNorms.DataSet.Edit;
          dsrcNorms.DataSet.FieldByName(fnTotalLaborTime).AsInteger := Round(Norm.LaborTime*Norm.Kolvo);
          CalcEndDate;
          dsrcNorms.DataSet.Post;
          if OldTotalLaborTime <> dsrcNorms.DataSet.FieldByName(fnTotalLaborTime).AsInteger then
            FIdsChangedTotalLaborTime.Add(dsrcNorms.DataSet.FieldByName(fnID).AsInteger);
        end;
      end;
      //dsrcNorms.DataSet.SortOn(fnName, []);

      DefineTotals;
    finally
      dsrcNorms.DataSet.EnableControls;
      //mtNorms.AfterPost := mtResourcesAfterPost;
      if dsrcNorms.DataSet.RecordCount > 0 then
        dsrcNorms.DataSet.First;
    end;
  finally
    FreeAndNil(MTPositions);
    EndProgress;
  end;
  //DefineTotalCost;
  SetActions;
end;

procedure TF_NormsComplete.SetActions;
begin

end;

procedure TF_NormsComplete.CalcEndDate;
var
  IsBrowse: Boolean;
begin
  if (dsrcNorms.DataSet.FieldByName(fnStartDate).AsFloat <> 0) and (dsrcNorms.DataSet.FieldByName(fnWorkersAmount).AsFloat <> 0) then
  begin
    IsBrowse := dsrcNorms.DataSet.State = dsBrowse;
    if IsBrowse then
      dsrcNorms.DataSet.Edit;
    if dsrcNorms.DataSet.FieldByName(fnTotalLaborTime).AsInteger > 0 then
      dsrcNorms.DataSet.FieldByName(fnEndDate).AsDateTime := dsrcNorms.DataSet.FieldByName(fnStartDate).AsDateTime +
        RoundUp(
          (dsrcNorms.DataSet.FieldByName(fnTotalLaborTime).AsInteger/(cntWorkDayHours*60)) / dsrcNorms.DataSet.FieldByName(fnWorkersAmount).AsInteger
        ) - 1
    else
      dsrcNorms.DataSet.FieldByName(fnEndDate).AsDateTime := dsrcNorms.DataSet.FieldByName(fnStartDate).AsDateTime;
    if IsBrowse then
      dsrcNorms.DataSet.Post;
  end;
end;

{
procedure TF_NormsComplete.DefineTotalCost;
var
  RecNo: Integer;
  i: Integer;
  CurrCost: Double;

  SavedOnChange: TNotifyevent;
begin
  CurrCost := 0;

  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;
  FLastTotalCost := CurrCost;

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

procedure TF_NormsComplete.DefineTotals;
var
  RecNo: Integer;
  i: Integer;
  TotalTime: Integer;
  RemainingTime: Double;
begin
  TotalTime := 0;
  RemainingTime := 0;
  if dsrcNorms.DataSet.RecordCount > 0 then // Tolik 27/12/2019 --
  begin
    RecNo := dsrcNorms.DataSet.RecNo;
    dsrcNorms.DataSet.DisableControls;
    try
      for i := 0 to dsrcNorms.DataSet.RecordCount - 1 do
      begin
        dsrcNorms.DataSet.RecNo := i+1;
        TotalTime := TotalTime + dsrcNorms.DataSet.FieldByName(fnTotalLaborTime).AsInteger;
        RemainingTime := RemainingTime + dsrcNorms.DataSet.FieldByName(fnTotalLaborTime).AsInteger * (dsrcNorms.DataSet.FieldByName(fnCompletePct).AsFloat/100);
      end;
    finally
      dsrcNorms.DataSet.EnableControls;
      dsrcNorms.DataSet.RecNo := RecNo;
    end;
  end;

  edTotalTime.Text := GetDisplayTextToNORMLaborTime(IntToStr(TotalTime), true);
  edRemainingTime.Text := GetDisplayTextToNORMLaborTime(IntToStr(TotalTime - Round(RemainingTime)), true);
end;

procedure TF_NormsComplete.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_My(DisplayValue);

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

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

procedure TF_NormsComplete.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_NormsComplete.neTotalCostChange(Sender: TObject);
begin
  OnTotalCostChange;
end;

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

procedure TF_NormsComplete.GT_NormsEditValueChanged(
  Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem);
begin
  if (Sender.DataController.IsEditing) and (mtNorms.State <> dsBrowse) then
  begin
    Timer_Post.Enabled := true;
  end;
   if not GProjectChanged then // Tolik 28/08/2019 --
    SetProjectChanged(true);
end;

procedure TF_NormsComplete.Timer_DefineTotalsTimer(Sender: TObject);
begin
  TTimer(Sender).Enabled := false;
  DefineTotals;
end;

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


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

procedure TF_NormsComplete.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_NormsComplete.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_My(AText);
  //      ValueFloat := FloatInUOM(ValueFloat, umMetr, TF_Main(GForm).FUOM);
  //      AText := FloatToStr(RoundCP(ValueFloat));
  //    end;
  //except
  //end;
end;

procedure TF_NormsComplete.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_NormsComplete.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_NormsComplete.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_NormsComplete.GT_NormsCustomDrawCell(
  Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
  AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
  //OnNormsResourcesCustomDrawCell(ACanvas, AViewInfo, GT_NormsIsResource.Index, GT_NormsGUIDNBCompon.Index, -1, false);
  if AViewInfo.GridRecord.Values[GT_NormsDone.Index] = biTrue then
    ACanvas.Font.Style := ACanvas.Font.Style + [fsStrikeOut];
end;

procedure TF_NormsComplete.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_NormsComplete.neTotalCostKeyPress(Sender: TObject;
  var Key: Char);
begin
  CorrectMaskKeyPress(Key);
  //if Key = #13 then
  //  OnTotalCostChange;
end;

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

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

procedure TF_NormsComplete.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_My(DisplayValue);

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

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

procedure TF_NormsComplete.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_My(DisplayValue);

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

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

procedure TF_NormsComplete.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_My(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_NormsComplete.GT_NormsWorkersAmountPropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
var
  ValueInt: Integer;
begin
  //TcxSpinEditProperties(GT_NormsWorkersAmount.Properties).OnValidate := nil;
  TcxDateEdit(Sender).Properties.OnValidate := nil;
  try
    if DisplayValue = '' then
    begin
      DisplayValue := FloatToStr(mtNorms.FieldByName(fnWorkersAmount).AsInteger);
      Exit; ///// EXIT /////
    end;
    ValueInt := StrToInt(DisplayValue);

    dsrcNorms.DataSet.Edit;
    dsrcNorms.DataSet.FieldByName(fnWorkersAmount).AsInteger := ValueInt;
    dsrcNorms.DataSet.Post;

    CalcEndDate;
  finally
    //TcxSpinEditProperties(GT_NormsWorkersAmount.Properties).OnValidate := GT_NormsWorkersAmountPropertiesValidate;
    TcxDateEdit(Sender).Properties.OnValidate := GT_NormsWorkersAmountPropertiesValidate;
  end;
end;

procedure TF_NormsComplete.GT_NormsStartDatePropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
var
  ValueDate: TDate;
begin
  //TcxDateEditProperties(GT_NormsStartDate.Properties).OnValidate := nil;
  TcxDateEdit(Sender).Properties.OnValidate := nil;
  try
    if DisplayValue = '' then
    begin
      DisplayValue := FloatToStr(mtNorms.FieldByName(fnStartDate).AsFloat);
      Exit; ///// EXIT /////
    end;
    ValueDate := StrToDate(DisplayValue);

    dsrcNorms.DataSet.Edit;
    dsrcNorms.DataSet.FieldByName(fnStartDate).AsFloat := ValueDate;
    dsrcNorms.DataSet.Post;

    CalcEndDate;
  finally
    //TcxDateEditProperties(GT_NormsStartDate.Properties).OnValidate := GT_NormsStartDatePropertiesValidate;
    TcxDateEdit(Sender).Properties.OnValidate := GT_NormsStartDatePropertiesValidate;
  end;
end;

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

procedure TF_NormsComplete.GT_NormsTotalLaborTimeCustomDrawCell(
  Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
  AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
  OnDrawCellAsChanged(ACanvas, AViewInfo);
end;

procedure TF_NormsComplete.GT_NormsEndDateCustomDrawCell(
  Sender: TcxCustomGridTableView; ACanvas: TcxCanvas;
  AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean);
begin
  OnDrawCellAsChanged(ACanvas, AViewInfo);
end;

procedure TF_NormsComplete.FormDestroy(Sender: TObject);
begin
  FreeAndNil(FIdsChangedTotalLaborTime);
end;

procedure TF_NormsComplete.GT_NormsCompletePctPropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
begin
  Timer_DefineTotals.Enabled := true;
end;

end.
