unit uAlmacenesController;

interface


uses
  Classes, SysUtils, uDADataTable, uControllerBase, uEditorDBItem,
  uIDataModuleAlmacenes, uBizAlmacenes;

type
  IAlmacenesController = interface(IControllerBase)
  ['{1F5E5845-5B29-4C08-87F0-D753E5454068}']
    function Buscar(const ID: Integer): IBizAlmacen;
    function BuscarTodos: IBizAlmacen;
    procedure Ver(AAlmacen : IBizAlmacen);
    procedure VerTodos(AAlmacenes: IBizAlmacen);
    function VerLista(AAlmacenes: IBizAlmacen): IBizAlmacen;
    function Nuevo : IBizAlmacen; overload;
    procedure Anadir(AAlmacen : IBizAlmacen);
    function Eliminar(const ID : Integer): Boolean; overload;
    function Eliminar(AAlmacen : IBizAlmacen): Boolean; overload;
    function Guardar(AAlmacen : IBizAlmacen): Boolean;
    procedure DescartarCambios(AAlmacen : IBizAlmacen);
    function Existe(const ID: Integer) : Boolean;
    function Duplicar(AAlmacen: IBizAlmacen): IBizAlmacen;
    procedure Preview(AAlmacen : IBizAlmacen);
    procedure Print(AAlmacen : IBizAlmacen);
    function DarListaAlmacenes : TStringList;
  end;

  TAlmacenesController = class(TControllerBase, IAlmacenesController)
  protected
    FDataModule : IDataModuleAlmacenes;

    procedure RecibirAviso(ASujeto: ISujeto; ADataTable: IDAStronglyTypedDataTable); override;
//    procedure AssignarID(AAlmacen: IBizAlmacen; ADataModule : IDataModuleAlmacenes); virtual;
    function CreateEditor(const AName : String; const IID: TGUID; out Intf): Boolean;
    function _Vacio : IBizAlmacen;

    procedure FiltrarEmpresa(AAlmacen: IBizAlmacen);
    function ValidarAlmacen(AAlmacen: IBizAlmacen): Boolean;

    //Estos son los tres métodos a sobre escribir si se desea heredar toda la logica de
    //este controller
    procedure AsignarDataModule; virtual;
    procedure RecuperarObjetos(AAlmacen: IBizAlmacen); virtual;

    procedure ValidarObjetos; virtual;
//    procedure AsignarCodigo(AAlmacen: IBizAlmacen); virtual;

  public
    constructor Create; override;
    destructor Destroy; override;

    function Eliminar(const ID : Integer): Boolean; overload;
    function Eliminar(AAlmacen : IBizAlmacen): Boolean; overload;
    function Guardar(AAlmacen : IBizAlmacen): Boolean;
    procedure DescartarCambios(AAlmacen : IBizAlmacen); virtual;
    function Existe(const ID: Integer) : Boolean; virtual;
    procedure Anadir(AAlmacen : IBizAlmacen);
    function Buscar(const ID: Integer): IBizAlmacen;
    function BuscarTodos: IBizAlmacen;
    function Nuevo : IBizAlmacen; overload;
    procedure Ver(AAlmacen : IBizAlmacen);
    procedure VerTodos(AAlmacenes: IBizAlmacen);
    function VerLista(AAlmacenes: IBizAlmacen): IBizAlmacen;
    function Duplicar(AAlmacen: IBizAlmacen): IBizAlmacen;
    procedure Preview(AAlmacen : IBizAlmacen);
    procedure Print(AAlmacen : IBizAlmacen);
    function DarListaAlmacenes : TStringList;
  end;

implementation

uses
  cxControls, DB, uEditorRegistryUtils, schAlmacenesClient_Intf,
  uIEditorAlmacenes, uIEditorAlmacen, uDataModuleAlmacenes,
  uDataModuleUsuarios, uDAInterfaces, uDataTableUtils, uFactuGES_App,
  uDateUtils, uROTypes, DateUtils, Controls, Windows, uIEditorListaAlmacenes;

{ TAlmacenesController }

procedure TAlmacenesController.Anadir(AAlmacen: IBizAlmacen);
begin
  AAlmacen.Insert;
end;

{procedure TAlmacenesController.AsignarCodigo(AAlmacen: IBizAlmacen);
begin
  if (AAlmacen.EsNuevo) then
     AssignarID(AAlmacen, (FDataModule as IDataModuleAlmacenes));
end;}

procedure TAlmacenesController.AsignarDataModule;
begin
  FDataModule := TDataModuleAlmacenes.Create(Nil);
end;

{procedure TAlmacenesController.AssignarID(AAlmacen: IBizAlmacen; ADataModule : IDataModuleAlmacenes);
var
  NuevoIDCabecera : Integer;
begin
  if not Assigned(AAlmacen) then
    raise Exception.Create ('Almacen no asignada');

  NuevoIDCabecera := ADataModule.GetNextID(AAlmacen.DataTable.LogicalName);

  AAlmacen.Edit;
  AAlmacen.ID := NuevoIDCabecera;
  AAlmacen.Post;
end;}

function TAlmacenesController.Buscar(const ID: Integer): IBizAlmacen;
begin
  Result := (FDataModule as IDataModuleAlmacenes).GetItem(ID);
//Los almacenes serán comunes para todas las empresas.
//  FiltrarEmpresa(Result);
end;

function TAlmacenesController.BuscarTodos: IBizAlmacen;
begin
  Result := FDataModule.GetItems;
//Los almacenes serán comunes para todas las empresas.
  FiltrarEmpresa(Result);
end;

constructor TAlmacenesController.Create;
begin
  inherited;
  AsignarDataModule;
end;

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

function TAlmacenesController.DarListaAlmacenes: TStringList;
begin
  ShowHourglassCursor;
  try
    Result := FDataModule.DarListaAlmacenes(AppFactuGES.EmpresaActiva.ID);
  finally
    HideHourglassCursor;
  end;
end;

procedure TAlmacenesController.DescartarCambios(AAlmacen: IBizAlmacen);
begin
  if not Assigned(AAlmacen) then
    raise Exception.Create ('Almacen no asignado');

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

    AAlmacen.DataTable.CancelUpdates;
  finally
    HideHourglassCursor;
  end;
end;

destructor TAlmacenesController.Destroy;
begin
  FDataModule := Nil;
  inherited;
end;

function TAlmacenesController.Duplicar(AAlmacen: IBizAlmacen): IBizAlmacen;
begin
  Result := Self._Vacio;
  ShowHourglassCursor;
  try
    DuplicarRegistros(AAlmacen.DataTable, Result.DataTable, mdrActual);

    // Hay que dejar algunos campos como si fuera un almacen nuevo
    Result.Edit;
    with Result do
    begin
      ID_EMPRESA := AppFactuGES.EmpresaActiva.ID;
      USUARIO := AppFactuGES.UsuarioActivo.UserName;
    end;

    Result.Post;
  finally
    HideHourglassCursor;
  end;
end;

function TAlmacenesController.ValidarAlmacen(AAlmacen: IBizAlmacen): Boolean;
begin
  if (AAlmacen.DataTable.State in dsEditModes) then
    AAlmacen.DataTable.Post;

  if Length(AAlmacen.NOMBRE) = 0 then
    raise Exception.Create('Debe indicar al menos el nombre de este almacén.');

  // Asegurarse de valores en campos "automáticos"
  AAlmacen.Edit;
  try
    AAlmacen.USUARIO := AppFactuGES.UsuarioActivo.UserName;

    Result := True;
  finally
    AAlmacen.Post;
  end;
end;

procedure TAlmacenesController.ValidarObjetos;
begin
//
end;

procedure TAlmacenesController.Ver(AAlmacen: IBizAlmacen);
var
  AEditor : IEditorAlmacen;
begin
  AEditor := NIL;
  RecuperarObjetos(AAlmacen);
  CreateEditor('EditorAlmacen', IEditorAlmacen, AEditor);
  if Assigned(AEditor) then
    try
       AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
       AEditor.Almacen := AAlmacen;
       AEditor.ShowModal;
    finally
       AEditor.Release;
       AEditor := NIL;
    end;
end;

function TAlmacenesController.VerLista(AAlmacenes: IBizAlmacen): IBizAlmacen;
var
  AEditor : IEditorListaAlmacenes;
begin
  AEditor := NIL;
  Result := NIL;

  CreateEditor('EditorListaAlmacenes', IEditorListaAlmacenes, AEditor);
  if Assigned(AEditor) then
    try
       AEditor.Almacenes := AAlmacenes;
       if IsPositiveResult(AEditor.ShowModal) then
          Result := AEditor.AlmacenSeleccionado;
    finally
      AEditor.Release;
      AEditor := NIL;
    end;
end;

procedure TAlmacenesController.VerTodos(AAlmacenes: IBizAlmacen);
var
  AEditor : IEditorAlmacenes;
begin
  AEditor := NIL;

  CreateEditor('EditorAlmacenes', IEditorAlmacenes, AEditor);
  if Assigned(AEditor) then
    with AEditor do
    begin
      Controller := Self; //OJO ORDEN MUY IMPORTANTE
      Almacenes := AAlmacenes;
      ShowEmbedded;
    end;
end;

function TAlmacenesController._Vacio: IBizAlmacen;
begin
  Result := Buscar(ID_NULO);
end;

function TAlmacenesController.Eliminar(const ID: Integer): Boolean;
var
  AAlmacen : IBizAlmacen;
begin
  AAlmacen := Buscar(ID);

  if not Assigned(AAlmacen) then
    raise Exception.Create(Format('No se ha encontrado el almacen con ID = %d', [ID]));

  Result := Eliminar(AAlmacen);
  AAlmacen := NIL;
end;

function TAlmacenesController.Eliminar(AAlmacen: IBizAlmacen): Boolean;
begin
  Result := False;

  if not Assigned(AAlmacen) then
    raise Exception.Create ('Almacen no asignada');

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

    AAlmacen.Delete;
    AAlmacen.DataTable.ApplyUpdates;
    HideHourglassCursor;
    Result := True;
  except
    on E: Exception do
    begin
      AAlmacen.DataTable.CancelUpdates;
      HideHourglassCursor;
      if (Pos('FOREIGN KEY', E.Message) > 0) then
         MessageBox(0, 'No se puede borrar este almacen porque tiene artículos', 'Atención', MB_ICONWARNING or MB_OK);
    end;
  end;
end;

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

procedure TAlmacenesController.RecuperarObjetos(AAlmacen: IBizAlmacen);
begin
//
end;

function TAlmacenesController.Existe(const ID: Integer): Boolean;
var
  AAlmacen : IBizAlmacen;
begin
  try
    AAlmacen := Buscar(ID);
    Result := Assigned(AAlmacen) and (AAlmacen.ID = ID);
  finally
    AAlmacen := NIL;
  end;
end;

procedure TAlmacenesController.FiltrarEmpresa(AAlmacen: IBizAlmacen);
var
  Condicion: TDAWhereExpression;
begin
  if AAlmacen.DataTable.Active then
    AAlmacen.DataTable.Active := False;

  // Filtrar los Almacenes actuales por empresa
  with AAlmacen.DataTable.DynamicWhere do
  begin
    // (ID_EMPRESA >= ID)
    Condicion := NewBinaryExpression(NewField('', fld_AlmacenesID_EMPRESA), NewConstant(AppFactuGES.EmpresaActiva.ID, datInteger), dboEqual);

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

function TAlmacenesController.Guardar(AAlmacen: IBizAlmacen): Boolean;
begin
  Result := False;

  if not Assigned(AAlmacen) then
    raise Exception.Create ('Almacen no asignada');

  ValidarObjetos;

  if ValidarAlmacen(AAlmacen) then
  begin
    ShowHourglassCursor;
    try
      if (AAlmacen.DataTable.State in dsEditModes) then
          AAlmacen.DataTable.Post;

//      AsignarCodigo(AAlmacen);
      AAlmacen.DataTable.ApplyUpdates;

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

function TAlmacenesController.Nuevo: IBizAlmacen;
var
  AAlmacen : IBizAlmacen;
begin
  AAlmacen := FDataModule.NewItem;
//Los almacenes serán comunes para todas las empresas.  
//  FiltrarEmpresa(AAlmacen);
  AAlmacen.DataTable.Active := True;
  AAlmacen.Insert;
  Result := AAlmacen;
end;

procedure TAlmacenesController.Preview(AAlmacen: IBizAlmacen);
//var
//  AReportController : IAlmacenesReportController;
begin
{  AReportController := TAlmacenesReportController.Create;
  try
    AReportController.Preview(AAlmacen.ID);
  finally
    AReportController := NIL;
  end;
}
end;

procedure TAlmacenesController.Print(AAlmacen: IBizAlmacen);
//var
//  AReportController : IAlmacenesReportController;
begin
{  AReportController := TAlmacenesReportController.Create;
  try
    AReportController.Print(AAlmacen.ID);
  finally
    AReportController := NIL;
  end;
}
end;

end.
