unit uUsuariosController;

interface


uses
  Classes, SysUtils, Forms, uDADataTable, uControllerBase,
  uIDataModuleUsuarios, uDataModuleUsuarios, UCBase, uBizUsuarios;

type
  TUCCriptografia = (ucStandard, ucMD5);

  IUsuariosController = interface(IControllerBase)
  ['{DD963EEC-5880-4DE7-AF55-B5080B538D84}']

    procedure Logoff;
    function StartLogin : Boolean;
    procedure VerUsuarios;
    procedure VerPerfiles;
    procedure VerUsuario(const AIDUser: Integer); overload;
    procedure VerUsuario(AUser : IBizUsuario); overload;

    procedure VerPerfil(const AIDPerfil: Integer); overload;
    procedure VerPerfil(APerfil : IBizPerfilUsuario); overload;
        
    procedure _ShowUserManager;
    procedure _ShowProfileManager;
    procedure _ShowLogManager;
    procedure _ShowChangePassword;
    function ComprobarUsuario(const User : String; const Password: String): Boolean;
    function CambiarPassword(const AIDUser: Integer): Boolean;

    function GetMaxIntentosLogin: Integer;
    procedure SetMaxIntentosLogin(const Value: Integer);
    property MaxIntentosLogin : Integer read GetMaxIntentosLogin write SetMaxIntentosLogin;

    function GetCurrentUser: IBizUsuario;
    property CurrentUser: IBizUsuario read GetCurrentUser;

    function GuardarPerfil(APerfil : IBizPerfilUsuario): Boolean;
    function GuardarUsuario(AUser : IBizUsuario): Boolean;

    function EliminarUsuario(const AIDUser : integer): Boolean; overload;
    function EliminarUsuario(AUser : IBizUsuario): Boolean; overload;

    function EliminarPerfil(APerfil : IBizPerfilUsuario): Boolean; overload;
    function EliminarPerfil(const AIDPerfil : integer): Boolean; overload;

    function HayUsuarioConPerfil(const AIDPerfil : integer): Boolean;

    function BuscarUsuario(const AIDUser: Integer): IBizUsuario;
    function BuscarTodosUsuarios: IBizUsuario;

    function DarListaPerfilesUsuario: TStringList;
    function DarListaUsuarios: TStringList;

    function ValidarPassword(const APassword : string; const ALogin : String;
      const ANombre: String; out AMsg : String): boolean;

    function NuevoUsuario : IBizUsuario;
    function NuevoPerfil : IBizPerfilUsuario;

    function GetCriptografia : TUCCriptografia;
    property Criptografia: TUCCriptografia read GetCriptografia;

    function GetUsarPasswordsSeguras: Boolean;
    procedure SetUsarPasswordsSeguras(const Value: Boolean);
    property UsarPasswordsSeguras : Boolean read GetUsarPasswordsSeguras write SetUsarPasswordsSeguras;

{
    procedure ChangePassword(IDUser: Integer; NewPassword: String);
    procedure AddRight(idUser: Integer; ItemRight: TObject; FullPath: Boolean = True); overload;
    procedure AddRight(idUser: Integer; ItemRight: String); overload;
    procedure AddRightEX(idUser: Integer; Module, FormName, ObjName: String);
    function VerificaLogin(User, Password: String): Boolean;
    function GetLocalUserName: String;
    function GetLocalComputerName: String;
    function AddUser(Login, Password, Name, Mail: String; Profile , UserExpired , DaysExpired : Integer; PrivUser: Boolean): Integer;
    function ExisteUsuario(Login: String): Boolean;
    property CurrentUser: TUCCurrentUser read FCurrentUser write FCurrentUser;
    property CurrentEmpresa : TEmpresaDef read FEmpresaAtual write FEmpresaAtual;
    property UserSettings: TUCUserSettings read FUserSettings write SetUserSettings;}

  end;

  TUsuariosController = class(TControllerBase, IUsuariosController)
  private
    procedure FiltrarEmpresa(AUsuario: IBizUsuario);
  protected
    FDataModule : IDataModuleUsuarios;
    FUserControl: TUserControl;
    FCurrentUser : IBizUsuario;
    FUsarPasswordsSeguras : Boolean;

    function GetMaxIntentosLogin: Integer;
    procedure SetMaxIntentosLogin(const Value: Integer);

    procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override;
    function CreateEditor(const AName : String; const IID: TGUID; out Intf): Boolean;

    procedure AsignarDataModule;
    procedure InicializarUserControl;
    function GetCurrentUser: IBizUsuario;

    function AnadirUsuario(AUser : IBizUsuario): Boolean;
    function ModificarUsuario(AUser : IBizUsuario): Boolean;

    function AnadirPerfil(APerfil : IBizPerfilUsuario): Boolean;
    function ModificarPerfil(APerfil : IBizPerfilUsuario): Boolean;

    function ValidarUsuario(AUser: IBizUsuario): Boolean;
    function ValidarPerfil(APerfil: IBizPerfilUsuario): Boolean;

    function GetCriptografia : TUCCriptografia;
    function CambiarPassword(const AIDUser: Integer; const ANewPassword: String): Boolean; overload;

    function GetUsarPasswordsSeguras: Boolean;
    procedure SetUsarPasswordsSeguras(const Value: Boolean);
  public
    constructor Create; override;
    destructor Destroy; override;

    procedure Logoff;
    function StartLogin : Boolean;
    procedure VerUsuarios;
    procedure VerPerfiles;

    procedure VerUsuario(const AIDUser: Integer); overload;
    procedure VerUsuario(AUser : IBizUsuario); overload;

    procedure VerPerfil(const AIDPerfil: Integer); overload;
    procedure VerPerfil(APerfil : IBizPerfilUsuario); overload;

    procedure _ShowUserManager;
    procedure _ShowProfileManager;
    procedure _ShowLogManager;
    procedure _ShowChangePassword;
    function ComprobarUsuario(const User : String; const Password: String): Boolean;
    function CambiarPassword(const AIDUser: Integer): Boolean; overload;

    function EliminarUsuario(const AIDUser : integer): Boolean; overload;
    function EliminarUsuario(AUser : IBizUsuario): Boolean; overload;

    function EliminarPerfil(APerfil : IBizPerfilUsuario): Boolean; overload;
    function EliminarPerfil(const AIDPerfil : integer): Boolean; overload;

    function NuevoUsuario : IBizUsuario;
    function NuevoPerfil : IBizPerfilUsuario;

    function GuardarPerfil(APerfil : IBizPerfilUsuario): Boolean;
    function GuardarUsuario(AUser : IBizUsuario): Boolean;

    function BuscarUsuario(const AIDUser: Integer): IBizUsuario;
    function BuscarTodosUsuarios: IBizUsuario;

    function DarListaPerfilesUsuario: TStringList;
    function DarListaUsuarios: TStringList;

    function HayUsuarioConPerfil(const AIDPerfil : integer): Boolean;
    function ValidarPassword(const APassword : string; const ALogin : String;
      const ANombre: String; out AMsg : String): boolean;

    property UsarPasswordsSeguras : Boolean read GetUsarPasswordsSeguras write SetUsarPasswordsSeguras;
    property UserControl : TUserControl read FUserControl;
    property MaxIntentosLogin : Integer read GetMaxIntentosLogin write SetMaxIntentosLogin;
    property CurrentUser: IBizUsuario read GetCurrentUser;
    property Criptografia: TUCCriptografia read GetCriptografia;
  end;

implementation

uses
  cxControls, DB, uEditorRegistryUtils, schUsuariosClient_Intf,
  uDAInterfaces, uDataTableUtils, uDialogUtils, uFactuGES_App, Dialogs,
  uDateUtils, uROTypes, DateUtils, Controls, Windows, uIEditorLogin,
  uIEditorUsuarios, uIEditorUsuario, uIEditorPerfilesUsuario,
  uIEditorPerfilUsuario, uEditorCambiarPassword, uDataModuleConexion;

{ TUsuariosController }

function TUsuariosController.AnadirPerfil(APerfil: IBizPerfilUsuario): Boolean;

  function GetNewIdUser: Integer;
  var
    TempDs: TDataset;
  begin
    with FUserControl do
      TempDS := DataConnector.UCGetSQLDataSet('SELECT ' + TableUsers.FieldUserID + ' as MaxUserID from ' + TableUsers.TableName +
        ' ORDER BY ' + TableUsers.FieldUserID + ' DESC');
    Result := TempDs.FieldByName('MaxUserID').AsInteger + 1;
    TempDS.Close;
    FreeAndNil(TempDS);
  end;

var
  ANuevoID : Integer;
begin
  Result := False;

  if not Assigned(APerfil) then
    raise Exception.Create('No hay perfil asignado (AnadirPerfil)');

  if ValidarPerfil(APerfil) then
  begin
    ShowHourglassCursor;
    try
      ANuevoID := GetNewIdUser;
      with FUserControl do
      begin
        DataConnector.UCExecSQL(Format('INSERT INTO %s(%s, %s, %s) Values(%d,%s,%s)',
          [TableUsers.TableName,
          TableUsers.FieldUserID,
          TableUsers.FieldUserName,
          TableUsers.FieldTypeRec,
          ANuevoID,
          QuotedStr(APerfil.USERNAME),
          QuotedStr('P')]));
      end;

      Result := (ANuevoID > 0);

      if Result then
      begin
        APerfil.Edit;
        APerfil.ID := ANuevoID;
        APerfil.Post;
      end;
    finally
      HideHourglassCursor;
    end;
  end;
end;

function TUsuariosController.AnadirUsuario(AUser: IBizUsuario): Boolean;
var
  ANuevoID : Integer;
begin
  Result := False;

  if not Assigned(AUser) then
    raise Exception.Create('No hay usuario asignado (AnadirUsuario)');

  if FUserControl.ExisteUsuario(AUser.LOGIN) then
  begin
    MessageDlg(Format(FUserControl.UserSettings.CommonMessages.UsuarioExiste, [AUser.LOGIN]), mtWarning, [mbOK], 0);
    Exit;
  end;

  if ValidarUsuario(AUser) then
  begin
    ShowHourglassCursor;
    try
      ANuevoID := FUserControl.AddUser(AUser.LOGIN, AUser.PASS, AUser.USERNAME, AUser.EMAIL,
        AUser.ID_PERFIL, AUser.BLOQUEADO, AUser.USERDAYSSUN, (AUser.PRIVILEGED = 1));

      Result := (ANuevoID > 0);

      if Result then
      begin
        AUser.Edit;
        AUser.ID := ANuevoID;
        AUser.Post;
      end;

      { TODO -oLuiz -cUpgrade : Consertar a Senha para poder avisar MD5 }
      {if (Assigned(MailUserControl)) and (MailUserControl.AdicionaUsuario.Ativo) then
        try
          MailUserControl.EnviaEmailAdicionaUsuario(vNome, vLogin, Encrypt(vNovaSenha, EncryptKey), vEmail, IntToStr(vPerfil), EncryptKey);
        except
          on E: Exception do
            Log(E.Message, llMedio);
        end;}
    finally
      HideHourglassCursor;
    end;
  end;
end;

procedure TUsuariosController.AsignarDataModule;
begin
  FDataModule := TDataModuleUsuarios.Create(Nil);
end;

function TUsuariosController.BuscarTodosUsuarios: IBizUsuario;
begin
  Result := FDataModule.GetUsuarios;
  FiltrarEmpresa(Result);
end;

function TUsuariosController.BuscarUsuario(const AIDUser: Integer): IBizUsuario;
begin
  Result := FDataModule.GetUsuario(AIDUser);
  FiltrarEmpresa(Result);
end;

function TUsuariosController.CambiarPassword(const AIDUser: Integer;
  const ANewPassword: String): Boolean;
begin
  FUserControl.ChangePassword(AIDUser, ANewPassword);
  Result := True;
end;

function TUsuariosController.CambiarPassword(const AIDUser: Integer) : Boolean;
var
  AUser : IBizUsuario;
  AEditor : TfEditorCambiarPassword;
begin
  Result := False;
  AUser := FDataModule.GetUsuario(AIDUser);
  if Assigned(AUser) then
  begin
    AUser.Active := True;
    
    AEditor := TfEditorCambiarPassword.Create(NIL);
    try
      AEditor.Controller := Self;
      AEditor.Usuario := AUser;
      AEditor.CambioObligatorio := False;
      if (Length(Trim(AUser.PASS)) = 0) then
        AEditor.EditAtu.Enabled := False;
      if (AEditor.ShowModal = mrOk) then
        Result := CambiarPassword(AIDUser, AEditor.EditNova.Text);
    finally
      AEditor.Release;
      AUser.Active := False;
      AUser := NIL;
    end;
  end;
end;

function TUsuariosController.ComprobarUsuario(const User,
  Password: String): Boolean;
begin
	Result := FUserControl.VerificaLogin(User, Password);
	if not Result then 
 	begin
    if User = 'admin' then
    begin
      if not FUserControl.ExisteUsuario('admin') then
      begin
        FUserControl.AddUser('admin', '1', 'Administrador', 'admin@correo.net', 0, 0 , 30, True);
 	 	    Result := ComprobarUsuario(User, Password);
      end;
    end;
 	end;
end;

constructor TUsuariosController.Create;
begin
  inherited;
  AsignarDataModule;
  FCurrentUser := NIL;
  FUserControl := TUserControl.Create(nil);
  FUsarPasswordsSeguras := False;
  InicializarUserControl;
end;

function TUsuariosController.CreateEditor(const AName: String; const IID: TGUID; out Intf): Boolean;
begin
  Result := Supports(EditorRegistry.CreateEditor(AName), IID, Intf);
end;

function TUsuariosController.DarListaPerfilesUsuario: TStringList;
var
  APerfilesUsuario: IBizPerfilUsuario;
begin
  APerfilesUsuario := FDataModule.GetPerfiles;
  APerfilesUsuario.DataTable.Active := True;

  Result := TStringList.Create;
  try
    with Result do
    begin
      APerfilesUsuario.DataTable.First;
      while not APerfilesUsuario.DataTable.EOF do
      begin
        Add(Format('%s=%d', [APerfilesUsuario.USERNAME, APerfilesUsuario.ID]));
        APerfilesUsuario.DataTable.Next;
      end;
    end;
  finally
    APerfilesUsuario := NIL;
  end;
end;

function TUsuariosController.DarListaUsuarios: TStringList;
var
  AUsuarios: IBizUsuario;
begin
  AUsuarios := FDataModule.GetUsuarios;
  AUsuarios.DataTable.Active := True;

  Result := TStringList.Create;
  try
    with Result do
    begin
      AUsuarios.DataTable.First;
      while not AUsuarios.DataTable.EOF do
      begin
        Add(Format('%s=%d', [AUsuarios.USERNAME, AUsuarios.ID]));
        AUsuarios.DataTable.Next;
      end;
    end;
  finally
    AUsuarios := NIL;
  end;
end;

destructor TUsuariosController.Destroy;
begin
  FreeAndNIL(FUserControl);
  FDataModule := NIL;
  FCurrentUser := NIL;

  inherited;
end;

function TUsuariosController.EliminarPerfil(
  APerfil: IBizPerfilUsuario): Boolean;
var
  CanDelete: Boolean;
  ErrorMsg:  String;
begin
  Result := False;

  if not Assigned(APerfil) then
    raise Exception.Create('No hay perfil asignado (EliminarPerfil)');

  if not APerfil.Active then
    APerfil.Active := True;

  if APerfil.DataTable.RecordCount = 0 then
    Exit;

  if HayUsuarioConPerfil(APerfil.ID) then
  begin
    //changed by fduenas: PromptDelete_WindowCaption
    if MessageBox(Application.Handle, PChar(Format(FUserControl.UserSettings.UsersProfile.PromptDelete, [APerfil.USERNAME])),
      PChar(FUserControl.UserSettings.UsersProfile.PromptDelete_WindowCaption), MB_ICONQUESTION or MB_YESNO or MB_DEFBUTTON2) <> idYes then
      Exit;
  end;

  CanDelete := True;
  if Assigned(FUserControl.onDeleteProfile) then
    FUserControl.onDeleteProfile(NIL, APerfil.ID, CanDelete, ErrorMsg);
  if not CanDelete then
  begin
    MessageDlg(ErrorMSG, mtWarning, [mbOK], 0);
    Exit;
  end;

  with FUserControl do
  begin
    DataConnector.UCExecSQL('Delete from ' + TableUsers.TableName + ' where ' + TableUsers.FieldUserID + ' = ' + IntToStr(APerfil.ID));
    DataConnector.UCExecSQL('Delete from ' + TableRights.TableName + ' where ' + TableRights.FieldUserID + ' = ' + IntToStr(APerfil.ID));
    DataConnector.UCExecSQL('Delete from ' + TableRights.TableName + 'EX where ' + TableRights.FieldUserID + ' = ' + IntToStr(APerfil.ID));
    DataConnector.UCExecSQL('Update ' + TableUsers.TableName +
      ' Set ' + TableUsers.FieldProfile + ' = null where ' + TableUsers.FieldUserID + ' = ' + IntToStr(APerfil.ID));
  end;
  Result := True;
end;

function TUsuariosController.EliminarPerfil(const AIDPerfil: integer): Boolean;
begin
  Result := EliminarPerfil(FDataModule.GetPerfil(AIDPerfil));
end;

function TUsuariosController.EliminarUsuario(AUser: IBizUsuario): Boolean;
begin
  Result := False;
  
  if not Assigned(AUser) then
    raise Exception.Create('No hay usuario asignado (EliminarUsuario)');

  if not AUser.Active then
    AUser.Active := True;

  if AUser.DataTable.RecordCount > 0 then
    Result := EliminarUsuario(AUser.ID);
end;

function TUsuariosController.EliminarUsuario(const AIDUser: integer): Boolean;
begin
  FUserControl.DataConnector.UCExecSQL('Delete from ' + FUserControl.TableRights.TableName + ' where ' + FUserControl.TableRights.FieldUserID + ' = ' + IntToStr(AIDUser));
  FUserControl.DataConnector.UCExecSQL('Delete from ' + FUserControl.TableUsers.TableName + ' where ' + FUserControl.TableUsers.FieldUserID + ' = ' + IntToStr(AIDUser));
  Result := True;
end;

function TUsuariosController.GetCriptografia: TUCCriptografia;
begin
  case FUserControl.Criptografia of
    cPadrao: Result := ucStandard;
    cMD5: Result := ucMD5;
    else
      Result := ucStandard;
  end;
end;

function TUsuariosController.GetCurrentUser: IBizUsuario;
begin
  if FUserControl.CurrentUser.UserID = 0 then // todavía no hemos hecho login
  begin
    Result := NIL;
    exit;
  end;

  if not Assigned(FCurrentUser) or
    (Assigned(FUserControl.CurrentUser) and (FCurrentUser.ID <> FUserControl.CurrentUser.UserID)) then
    FCurrentUser := BuscarUsuario(FUserControl.CurrentUser.UserID);

  if not FCurrentUser.Active then
    FCurrentUser.Active := True;

  Result := FCurrentUser;
end;

function TUsuariosController.GetMaxIntentosLogin: Integer;
begin
  Result := FUserControl.Login.MaxLoginAttempts;
end;

function TUsuariosController.GetUsarPasswordsSeguras: Boolean;
begin
  Result := FUsarPasswordsSeguras;
end;

function TUsuariosController.GuardarPerfil(APerfil: IBizPerfilUsuario): Boolean;
begin
  if not Assigned(APerfil) then
    raise Exception.Create('No hay perfil asignado (GuardarPerfil)');

  if APerfil.EsNuevo then
    Result := AnadirPerfil(APerfil)
  else
    Result := ModificarPerfil(APerfil);
end;

function TUsuariosController.GuardarUsuario(AUser: IBizUsuario): Boolean;
begin
  if not Assigned(AUser) then
    raise Exception.Create('No hay usuario asignado (GuardarUsuario)');

  if AUser.EsNuevo then
    Result := AnadirUsuario(AUser)
  else
    Result := ModificarUsuario(AUser);
end;

function TUsuariosController.HayUsuarioConPerfil(
  const AIDPerfil: integer): Boolean;
var
  TempDS:    TDataset;
begin
  try
    TempDS := FUserControl.DataConnector.UCGetSQLDataset('Select ' + FUserControl.TableUsers.FieldUserID + ' as IdUser from ' +
      FUserControl.TableUsers.TableName +
      ' Where ' + FUserControl.TableUsers.FieldTypeRec + ' = ' + QuotedStr('U') +
      ' AND ' + FUserControl.TableUsers.FieldProfile + ' = ' + IntToStr(AIDPerfil));

    Result := (TempDS.FieldByName('IdUser').AsInteger > 0);
    TempDS.Close;
  finally
    FreeAndNil(TempDS);
  end;
end;

procedure TUsuariosController.InicializarUserControl;
begin
  with FUserControl do
  begin
    ApplicationID := AppFactuGES.AppName;
    AutoStart := False;
    Criptografia := cMD5;
    CheckValidationKey := True;
    Login.MaxLoginAttempts := 3;
    UserPasswordChange.ForcePassword := True;
    UserPasswordChange.MinPasswordLength := 3;
  end;
  FDataModule.InicializarUserControl(FUserControl);
end;

procedure TUsuariosController.Logoff;
begin
  try
    if dmConexion.HayConexion then
      FUserControl.Logoff;
  finally
    FUserControl.UsersLogged.Active := False;
  end;
end;

function TUsuariosController.ModificarPerfil(
  APerfil: IBizPerfilUsuario): Boolean;
begin
  Result := False;

  if not Assigned(APerfil) then
    raise Exception.Create('No hay perfil asignado (ModificarPerfil)');

  if ValidarPerfil(APerfil) then
  begin
    ShowHourglassCursor;
    try
      with FUserControl do
      begin
        DataConnector.UCExecSQL(Format('UPDATE %s SET %s = %s WHERE %s = %d',
          [TableUsers.TableName,
          TableUsers.FieldUserName,
          QuotedStr(APerfil.USERNAME),
          TableUsers.FieldUserID,
          APerfil.ID]));
      end;

      Result := True;
    finally
      HideHourglassCursor;
    end;
  end;
end;

function TUsuariosController.ModificarUsuario(AUser: IBizUsuario): Boolean;
begin
  Result := False;

  if not Assigned(AUser) then
    raise Exception.Create('No hay usuario asignado (ModificarUsuario)');

  if ValidarUsuario(AUser) then
  begin
    ShowHourglassCursor;
    try
      FUserControl.ChangeUser(AUser.ID, AUser.LOGIN, AUser.USERNAME, AUser.EMAIL,
        AUser.ID_PERFIL, AUser.BLOQUEADO , AUser.USERDAYSSUN, (AUser.PRIVILEGED = 1));

      Result := True;

      { TODO -oLuiz -cUpgrade : Consertar a Senha para poder avisar MD5 }
      {if (Assigned(MailUserControl)) and (MailUserControl.AlteraUsuario.Ativo) then
        try
          MailUserControl.EnviaEmailAlteraUsuario(vNome,
            vLogin,
            TfrmCadastrarUsuario(Self.Owner).FDataSetCadastroUsuario.FieldByName('SENHA').AsString,
            vEmail,
            IntToStr(vPerfil),
            EncryptKey);
        except
          on E: Exception do
            Log(E.Message, 2);
        end;}
    finally
      HideHourglassCursor;
    end;
  end;
end;

function TUsuariosController.NuevoPerfil: IBizPerfilUsuario;
var
  APerfil : IBizPerfilUsuario;
begin
  APerfil := FDataModule.NuevoPerfil;
  APerfil.DataTable.Active := True;
  APerfil.Insert;
  Result := APerfil;
end;

function TUsuariosController.NuevoUsuario: IBizUsuario;
var
  AUsuario : IBizUsuario;
begin
  AUsuario := FDataModule.NuevoUsuario;
  AUsuario.DataTable.Active := True;
  AUsuario.Insert;
  Result := AUsuario;
end;

procedure TUsuariosController.RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable);
begin
  inherited;
//
end;

procedure TUsuariosController.SetMaxIntentosLogin(const Value: Integer);
begin
  FUserControl.Login.MaxLoginAttempts := Value;
end;

procedure TUsuariosController.SetUsarPasswordsSeguras(const Value: Boolean);
begin
  FUsarPasswordsSeguras := Value;
end;

procedure TUsuariosController._ShowChangePassword;
begin
  FUserControl.ShowChangePassword;
end;

procedure TUsuariosController._ShowLogManager;
begin
  FUserControl.ShowLogManager;
end;

procedure TUsuariosController._ShowProfileManager;
begin
  FUserControl.ShowProfileManager;
end;

function TUsuariosController.ValidarPassword(const APassword : string;
  const ALogin : String; const ANombre: String; out AMsg : String): boolean;
begin
  Result := False;
  AMsg := '';
  if (FUserControl.UserPasswordChange.ForcePassword) and (Length(Trim(APassword)) = 0) then
    AMsg := FUserControl.UserSettings.CommonMessages.ChangePasswordError.PasswordRequired
  else
    if (Length(Trim(APassword)) < FUserControl.UserPasswordChange.MinPasswordLength) then
      AMsg := Format(FUserControl.UserSettings.CommonMessages.ChangePasswordError.MinPasswordLength, [FUserControl.UserPasswordChange.MinPasswordLength])
    else
      if FUsarPasswordsSeguras and (Pos(LowerCase(APassword), 'abcdeasdfqwerzxcv1234567890321654987test' + LowerCase(ALogin) + LowerCase(AMsg)) > 0) then
        AMsg := FUserControl.UserSettings.CommonMessages.ChangePasswordError.InvalidNewPassword
      else
        Result := true;
end;

function TUsuariosController.ValidarPerfil(APerfil: IBizPerfilUsuario): Boolean;
begin
  if not Assigned(APerfil) then
    raise Exception.Create ('Perfil no asignado (ValidarPerfil)');

  if (APerfil.DataTable.State in dsEditModes) then
    APerfil.DataTable.Post;

  if Length(APerfil.USERNAME) = 0 then
    raise Exception.Create('Debe indicar el nombre del perfil.');

  Result := True;
end;

function TUsuariosController.ValidarUsuario(AUser: IBizUsuario): Boolean;
begin
  if not Assigned(AUser) then
    raise Exception.Create ('Usuario no asignado (ValidarUsuario)');

  if (AUser.DataTable.State in dsEditModes) then
    AUser.DataTable.Post;

  if Length(AUser.USERNAME) = 0 then
    raise Exception.Create('Debe indicar el nombre completo del usuario.');

  if Length(AUser.LOGIN) = 0 then
    raise Exception.Create('Debe indicar un login para el usuario.');

  Result := True;
end;


procedure TUsuariosController.VerPerfil(const AIDPerfil: Integer);
var
  FPerfil : IBizPerfilUsuario;
begin
  FPerfil := FDataModule.GetPerfil(AIDPerfil);
  VerPerfil(FPerfil);
end;

procedure TUsuariosController.VerPerfil(APerfil: IBizPerfilUsuario);
var
  AEditor : IEditorPerfilUsuario;
begin
  if not Assigned(APerfil) then
    raise Exception.Create('Perfil no asignado (VerPerfil)');

  APerfil.Active := True;
  CreateEditor('EditorPerfilUsuario', IEditorPerfilUsuario, AEditor);
  if Assigned(AEditor) then
  begin
    try
      AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
      AEditor.PerfilUsuario := APerfil;
      AEditor.ShowModal;
    finally
      AEditor.Release;
      AEditor := NIL;
    end;
  end;
end;

procedure TUsuariosController.VerPerfiles;
var
  AEditor : IEditorPerfilesUsuario;
  APerfilesUsuario: IBizPerfilUsuario;
begin
  APerfilesUsuario := FDataModule.GetPerfiles;
  if Assigned(APerfilesUsuario) then
  begin
    try
      APerfilesUsuario.Active := True;
      CreateEditor('EditorPerfilesUsuario', IEditorPerfilesUsuario, AEditor);
      if Assigned(AEditor) then
        try
          AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
          AEditor.PerfilesUsuario := APerfilesUsuario;
          AEditor.ShowModal;
        finally
          AEditor.Release;
          AEditor := NIL;
        end;
    finally
      APerfilesUsuario := NIL;
    end;
  end;
end;

procedure TUsuariosController.VerUsuario(const AIDUser: Integer);
var
  FUsuario : IBizUsuario;
begin
  FUsuario := FDataModule.GetUsuario(AIDUser);
  VerUsuario(FUsuario);
end;

procedure TUsuariosController.VerUsuario(AUser: IBizUsuario);
var
  AEditor : IEditorUsuario;
begin
  if not Assigned(AUser) then
    raise Exception.Create('Usuario no asignado (VerUsuario)');

  AUser.Active := True;
  CreateEditor('EditorUsuario', IEditorUsuario, AEditor);
  if Assigned(AEditor) then
    try
      AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
      AEditor.Usuario := AUser;
      AEditor.ShowModal;
    finally
      AEditor.Release;
      AEditor := NIL;
    end;
end;

procedure TUsuariosController.VerUsuarios;
var
  AEditor : IEditorUsuarios;
  FUsuarios : IBizUsuario;
begin
  FUsuarios := FDataModule.GetUsuarios;
  if Assigned(FUsuarios) then
  begin
    FUsuarios.Active := True;
    try
      CreateEditor('EditorUsuarios', IEditorUsuarios, AEditor);
      if Assigned(AEditor) then
        try
          AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
          AEditor.Usuarios := FUsuarios;
          AEditor.ShowModal;
        finally
          AEditor.Release;
          AEditor := NIL;
        end;
    finally
      FUsuarios := NIL;
    end;
  end;
end;

procedure TUsuariosController._ShowUserManager;
begin
  FUserControl.ShowUserManager;
end;

function TUsuariosController.StartLogin : Boolean;
var
  AEditor : IEditorLogin;
begin
  Result := False;
  AEditor := NIL;

  CreateEditor('EditorLogin', IEditorLogin, AEditor);
  if Assigned(AEditor) then
    try
      AEditor.Controller := Self;
      Result := (AEditor.ShowModal = mrOk);
    finally
      AEditor.Release;
      AEditor := NIL;
    end;
end;

procedure TUsuariosController.FiltrarEmpresa(AUsuario: IBizUsuario);
{var
  Condicion: TDAWhereExpression;}
begin

  // AQUI HAY QUE TENER EN CUENTA QUE UN USUARIO PUEDE QUE NO TENGA ACCESO
  // EN UNA DETERMINADA EMPRESA


{  if AUsuario.DataTable.Active then
    AUsuario.DataTable.Active := False;

  // Filtrar los contactos actuales por empresa
  with AUsuario.DataTable.DynamicWhere do
  begin
    Condicion := NewBinaryExpression(NewField('', fld_U
    ContactosID_EMPRESA), NewConstant(AppFactuGES.EmpresaActiva.ID, datInteger), dboEqual);

    if IsEmpty then
       Expression := Condicion
    else
       Expression := NewBinaryExpression(Expression, Condicion, dboAnd);
  end;}
end;


end.
