{
===============================================================================
  Copyright (©) 2007. Rodax Software.
===============================================================================
  Los contenidos de este fichero son propiedad de Rodax Software titular del
  copyright. Este fichero sólo podrá ser copiado, distribuido y utilizado,
  en su totalidad o en parte, con el permiso escrito de Rodax Software, o de
  acuerdo con los términos y condiciones establecidas en el acuerdo/contrato
  bajo el que se suministra.
  -----------------------------------------------------------------------------
  Web:  www.rodax-software.com
===============================================================================
  Fecha primera versión: 
  Versión actual: 1.0.0
  Fecha versión actual: 
===============================================================================
  Modificaciones:

    Fecha         Comentarios
    ---------------------------------------------------------------------------
===============================================================================
}

unit uTiendaWebController;

interface

uses
  Classes, SysUtils, uDADataTable, uControllerBase,
  uBizTiendaWeb, uIDataModuleTiendaWeb,
  uBizContactos, uBizDireccionesContacto;

type

  ITiendaWebController = interface(IObservador)
  ['{559E2D92-0C7F-46C6-96C4-1C3794B79A57}']
    function Guardar(ATiendaWeb : IBizTiendaWeb): Boolean;
    procedure DescartarCambios(ATiendaWeb : IBizTiendaWeb);
    function Buscar(const ID_Empresa: Integer): IBizTiendaWeb;
    function Ver(ATiendaWeb: IBizTiendaWeb) : Integer;

    function HayConexionConTienda(ATiendaWeb : IBizTiendaWeb): Boolean; overload;
    function HayConexionConTienda(const ABDServer : String;
        const ABDName : String; const ABDUser : String;
        const ABDPass : String): Boolean; overload; 

    function ActualizarTienda(ATiendaWeb : IBizTiendaWeb): Boolean;
    function DescargarPedidos(ATiendaWeb : IBizTiendaWeb): Boolean;    
  end;

  TTiendaWebController = class(TObservador, ITiendaWebController)
  protected
    FDataModule : IDataModuleTiendaWeb;

    procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override;
	  function _Vacio : IBizTiendaWeb;

    function ValidarTiendaWeb(ATiendaWeb: IBizTiendaWeb): Boolean;
    procedure AsignarDataModule;
    procedure AsignarID(ATiendaWeb: IBizTiendaWeb; const IDNuevo: Integer);

  public
    constructor Create; virtual;
    destructor Destroy; override;

    procedure Anadir(ATiendaWeb : IBizTiendaWeb);
    function Eliminar(ATiendaWeb : IBizTiendaWeb): Boolean; overload;
    function Guardar(ATiendaWeb : IBizTiendaWeb): Boolean;
    procedure DescartarCambios(ATiendaWeb : IBizTiendaWeb);

	  function Buscar(const ID_Empresa: Integer): IBizTiendaWeb;
    function Ver(ATiendaWeb: IBizTiendaWeb) : Integer;

    function HayConexionConTienda(ATiendaWeb : IBizTiendaWeb): Boolean; overload;
    function HayConexionConTienda(const ABDServer : String; 
        const ABDName : String; const ABDUser : String;
        const ABDPass : String): Boolean; overload;

    function ActualizarTienda(ATiendaWeb : IBizTiendaWeb): Boolean;
    function DescargarPedidos(ATiendaWeb : IBizTiendaWeb): Boolean;
  end;

implementation

uses
  cxControls, DB, uEditorRegistryUtils, uDAInterfaces, uDataTableUtils,
  uDateUtils, uROTypes, DateUtils, Controls, Windows, schTiendaWebClient_Intf,
  uIEditorTiendaWeb, uDataModuleTiendaWeb, uDialogUtils, SqlExpr, JSDialog,

  uClientesController, uProveedoresController, uActualizarClientesUtils,
  uOscCustomersController, uOscAddressBookController,
  uBizOscCustomers, uBizOscAddressBook, uIEditorActualizarTiendaWeb,
  uActualizarProveedoresUtils, uActualizarArticulosUtils, Dialogs, Forms,
  uActualizarPedidosUtils;

{ TTiendaWebController }

function TTiendaWebController.ActualizarTienda(
  ATiendaWeb: IBizTiendaWeb): Boolean;
var
  AEditor : IEditorActualizarTiendaWeb;
  Respuesta : Integer;
  AContenidosAct : TContenidosActualizables;
  ADlg : TJSDialog;  
begin
  Result := False;

  if not Assigned(ATiendaWeb) then
    raise Exception.Create('TiendaWeb no asignada');

  ATiendaWeb.DataTable.Active := True;
  if (ATiendaWeb.TIENDA_ACTIVA <> 1) then
  begin
    if (ShowConfirmMessage('La tienda no está activada', 'No se ha activado o configurado el acceso a la tienda.' +
      #13 + '¿Desea hacerlo ahora?') = IDYES) then
    begin
      if IsPositiveResult(Self.Ver(ATiendaWeb)) then
        Self.ActualizarTienda(ATiendaWeb);
    end;
    Exit;
  end;

  if not Self.HayConexionConTienda(ATiendaWeb) then
  begin
    ShowErrorMessage('No hay conexión con la tienda web', 'Se ha producido un error al intentar realizar la conexión con la tienda web.' +
          #10#13 + 'Inténtelo de nuevo pasados unos minutos o revise los datos de conexión a la tienda.');
    Exit;
  end;

  AContenidosAct := [caClientes, caProveedores];

  AEditor := NIL;
  ShowHourglassCursor;
  try
    CreateEditor('EditorActualizarTiendaWeb', IEditorActualizarTiendaWeb, AEditor);
    with AEditor do
      ContenidosActualizables := AContenidosAct;
  finally
    HideHourglassCursor;
  end;

  Respuesta := mrNone;
  AContenidosAct := [];
  if Assigned(AEditor) then
    try
      Respuesta := AEditor.ShowModal;
      AContenidosAct := AEditor.ContenidosActualizables;
      AEditor.Release;
    finally
      AEditor := NIL;
    end;

  if IsPositiveResult(Respuesta) then
  begin
    try
      ADlg := TJSDialog.Create(nil);
      ShowHourglassCursor;
      try
        with ADlg do
        begin
          Title := 'Actualización de la tienda web';
          DialogOptions := [doProgressBarMarquee, doTopMost];
          ButtonBar.Buttons := [];
        end;

        if (caClientes in AContenidosAct) then
        begin
          ADlg.Instruction.Text := 'Actualizando clientes...';
          ADlg.Execute;
          Application.ProcessMessages;

          Result := uActualizarClientesUtils.ActualizarClientesTienda(ATiendaWeb);
          if not Result then
            Exit;
        end;

        if (caProveedores in AContenidosAct) then
        begin
          ADlg.Close;
          ADlg.Instruction.Text := 'Actualizando proveedores...';
          ADlg.Execute;
          Application.ProcessMessages;

          Result := uActualizarProveedoresUtils.ActualizarProveedoresTienda(ATiendaWeb);

          // Actualizar los artículos de los proveedores
          if Result then
          begin
            ADlg.Close;
            ADlg.Instruction.Text := 'Actualizando artículos...';
            ADlg.Execute;
            Application.ProcessMessages;

            Result := uActualizarArticulosUtils.ActualizarArticulosTienda(ATiendaWeb);
          end;

          if not Result then
            Exit;
        end;
        Application.ProcessMessages;

        ATiendaWeb.Edit;
        ATiendaWeb.ULTIMA_ACTUALIZACION := Now;
        Self.Guardar(ATiendaWeb);

        ADlg.Close;

        if Result then
          ShowInfoMessage('Actualización de tienda web realizada', 'Se ha actualizado correctamente la información de la tienda web.');
      finally
        HideHourglassCursor;
        ADlg.Close;
        ADlg.Free;
        ADlg := NIL;
        Application.ProcessMessages;
      end;
    except
      on E: Exception do
      begin
        // Cannot connect to mySQL server on localhost (10061)
        if (Pos('(10061)', E.Message) > 0) then
        begin
          ShowErrorMessage('No hay conexión con la tienda web', 'Se ha producido un error al intentar realizar la conexión con la tienda web.' +
            #10#13 + 'Inténtelo de nuevo pasados unos minutos o revise los datos de conexión a la tienda.', E);
        end
        else
          ShowErrorMessage('Error durante la actualización de la tienda web', 'Se ha producido un error al intentar actualizar los contenidos de la tienda web con los datos de FactuGES.', E);
      end;
    end; // try ... except
  end; // if
end;

procedure TTiendaWebController.Anadir(ATiendaWeb: IBizTiendaWeb);
begin
  ATiendaWeb.Insert;
end;

procedure TTiendaWebController.AsignarDataModule;
begin
  FDataModule := TDataModuleTiendaWeb.Create(Nil);
end;

procedure TTiendaWebController.AsignarID(ATiendaWeb: IBizTiendaWeb;
  const IDNuevo: Integer);
begin
  if not Assigned(ATiendaWeb) then
    raise Exception.Create ('TiendaWeb no asignada');

  if ATiendaWeb.EsNuevo then
  begin
    ATiendaWeb.Edit;
    ATiendaWeb.ID := IDNuevo;
    ATiendaWeb.Post;
  end;
end;

constructor TTiendaWebController.Create;
begin
  AsignarDataModule;
end;

function TTiendaWebController.Buscar(const ID_Empresa: Integer): IBizTiendaWeb;
var
  ATienda : IBizTiendaWeb;
begin
  ATienda := (FDataModule as IDataModuleTiendaWeb).GetItem(ID_Empresa);

  ATienda.DataTable.Active := True;
  if ATienda.DataTable.RecordCount = 0 then
    Anadir(ATienda);
  Result := ATienda;
end;

function TTiendaWebController._Vacio: IBizTiendaWeb;
begin
  Result := Buscar(ID_NULO);
end;

function TTiendaWebController.DescargarPedidos(
  ATiendaWeb: IBizTiendaWeb): Boolean;
var
  Respuesta : Integer;
  ADlg : TJSDialog;
begin
  Result := False;

  if not Assigned(ATiendaWeb) then
    raise Exception.Create('TiendaWeb no asignada');

  ATiendaWeb.DataTable.Active := True;
  if (ATiendaWeb.TIENDA_ACTIVA <> 1) then
  begin
    if (ShowConfirmMessage('La tienda no está activada', 'No se ha activado o configurado el acceso a la tienda.' +
      #13 + '¿Desea hacerlo ahora?') = IDYES) then
    begin
      if IsPositiveResult(Self.Ver(ATiendaWeb)) then
        Self.ActualizarTienda(ATiendaWeb);
    end;
    Exit;
  end;

  if not Self.HayConexionConTienda(ATiendaWeb) then
  begin
    ShowErrorMessage('No hay conexión con la tienda web', 'Se ha producido un error al intentar realizar la conexión con la tienda web.' +
          #10#13 + 'Inténtelo de nuevo pasados unos minutos o revise los datos de conexión a la tienda.');
    Exit;
  end;

  try
    ADlg := TJSDialog.Create(nil);
    ShowHourglassCursor;
    try
      with ADlg do
      begin
        Title := 'Descarga de pedidos desde la tienda web';
        DialogOptions := [doProgressBarMarquee, doTopMost];
        ButtonBar.Buttons := [];
      end;

      ADlg.Instruction.Text := 'Descargando pedidos...';
      ADlg.Execute;
      Application.ProcessMessages;

      Result := uActualizarPedidosUtils.ActualizarPedidosTienda(ATiendaWeb);
      Application.ProcessMessages;

      ADlg.Close;

      if Result then
        ShowInfoMessage('Descarga de pedidos realizada', 'Se han descagado correctamente los pedidos nuevos desde la tienda web.');
    finally
      HideHourglassCursor;
      ADlg.Close;
      ADlg.Free;
      ADlg := NIL;
      Application.ProcessMessages;
    end;
  except
    on E: Exception do
    begin
      // Cannot connect to mySQL server on localhost (10061)
      if (Pos('(10061)', E.Message) > 0) then
      begin
        ShowErrorMessage('No hay conexión con la tienda web', 'Se ha producido un error al intentar realizar la conexión con la tienda web.' +
          #10#13 + 'Inténtelo de nuevo pasados unos minutos o revise los datos de conexión a la tienda.', E);
      end
      else
        ShowErrorMessage('Error durante la descarga de pedido', 'Se ha producido un error al intentar descargar los pedidos nuevos desde la tienda web.', E);
    end;
  end; // try ... except
end;

procedure TTiendaWebController.DescartarCambios(ATiendaWeb: IBizTiendaWeb);
begin
  if not Assigned(ATiendaWeb) then
    raise Exception.Create ('IBizTiendaWeb no asignado');

  ShowHourglassCursor;
  try
    if (ATiendaWeb.State in dsEditModes) then
      ATiendaWeb.Cancel;

    ATiendaWeb.DataTable.CancelUpdates;
  finally
    HideHourglassCursor;
  end;
end;

destructor TTiendaWebController.Destroy;
begin
  FDataModule := NIL;
 
  inherited;
end;


function TTiendaWebController.ValidarTiendaWeb(ATiendaWeb: IBizTiendaWeb): Boolean;
begin
  Result := False;

  if not Assigned(ATiendaWeb) then
    raise Exception.Create ('IBizTiendaWeb no asignado');

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

  Result := True;
end;

function TTiendaWebController.Ver(ATiendaWeb: IBizTiendaWeb) : Integer;
var
  AEditor : IEditorTiendaWeb;
begin
  Result := mrNone;
  AEditor := NIL;
  ShowHourglassCursor;
  try
    CreateEditor('EditorTiendaWeb', IEditorTiendaWeb, AEditor);
    with AEditor do
      TiendaWeb := ATiendaWeb;
  finally
    HideHourglassCursor;
  end;

  if Assigned(AEditor) then
    try
      Result := AEditor.ShowModal;
      AEditor.Release;
    finally
      AEditor := NIL;
    end;
end;

function TTiendaWebController.Eliminar(ATiendaWeb: IBizTiendaWeb): Boolean;
begin
  Result := False;

  if not Assigned(ATiendaWeb) then
    raise Exception.Create ('TiendaWeb no asignado');

  ShowHourglassCursor;
  try
    if (ATiendaWeb.State in dsEditModes) then
      ATiendaWeb.Cancel;

    ATiendaWeb.Delete;
    ATiendaWeb.DataTable.ApplyUpdates;
    Result := True;
  finally
    HideHourglassCursor;
  end;
end;

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

function TTiendaWebController.Guardar(ATiendaWeb: IBizTiendaWeb): Boolean;
var
  NuevoID : Integer;
begin
  Result := False;

  if ValidarTiendaWeb(ATiendaWeb) then
  begin
    ShowHourglassCursor;
    try
      if ATiendaWeb.EsNuevo then
        NuevoID := FDataModule.GetNextID(ATiendaWeb.DataTable.LogicalName)
      else
        NuevoID := ATiendaWeb.ID;

      AsignarID(ATiendaWeb, NuevoID);
      ATiendaWeb.DataTable.ApplyUpdates;
      
      Result := True;
    finally
      HideHourglassCursor;
    end;
  end;
end;


function TTiendaWebController.HayConexionConTienda(
  ATiendaWeb: IBizTiendaWeb): Boolean;
begin
  if not Assigned(ATiendaWeb) then
    raise Exception.Create ('TiendaWeb no asignada');

  with ATiendaWeb do
  begin
    DataTable.Active := True;
    Result := Self.HayConexionConTienda(BDSERVER, BDNAME, BDUSER, BDPASS);
  end;
end;

function TTiendaWebController.HayConexionConTienda(
  const ABDServer : String; const ABDName : String;
  const ABDUser : String; const ABDPass : String): Boolean;
var
  SQLConnection1: TSQLConnection;
begin
  SQLConnection1 := TSQLConnection.Create(nil);
  try
    with SQLConnection1 do
    begin
      Name := 'SQLConnection1';
      ConnectionName := 'MySQLConnection';
      DriverName := 'MySQL';
      GetDriverFunc := 'getSQLDriverMYSQL';
      LibraryName := 'dbxmys30.dll';
      LoginPrompt := False;
      with Params do
      begin
        Clear;
        Add('BlobSize=-1');
        Add('DriverName=MySQL');
        Add('ErrorResourceFile=');
        Add('LocaleCode=0000');
        Add('Compressed=True');
        Add('Encrypted=True');
        Add('Database=' + ABDName);
        Add('HostName=' + ABDServer);
        Add('User_Name=' + ABDUser);
        Add('Password=' + ABDPass);
      end;
      VendorLib := 'LIBMYSQL.dll';

      try
        Connected := True;
        Result := True;
        Connected := False;
      except
        Result := False;
      end;
    end;
  finally
    FreeAndNIL(SQLConnection1);
  end;
end;

end.
