unit uEpigrafesController;

interface


uses
  Classes, SysUtils, uDADataTable, uControllerBase,
   uBizEpigrafes, uIDataModuleContabilidad;
type
  IEpigrafesController = interface(IControllerBase)
  ['{94E5F2B6-64C8-4331-B9CB-3ED730478529}']
    function BuscarTodos: IBizEpigrafe;
    function Buscar(ID: Integer): IBizEpigrafe;
    procedure VerTodos(AEpigrafes: IBizEpigrafe);
    procedure Ver(AEpigrafe: IBizEpigrafe);
    procedure Anadir(AEpigrafe : IBizEpigrafe);
    function Eliminar(AEpigrafe : IBizEpigrafe): Boolean;
    function Guardar(AEpigrafe : IBizEpigrafe): Boolean;
    procedure DescartarCambios(AEpigrafe : IBizEpigrafe);
    function Localizar(AEpigrafes: IBizEpigrafe; ADescripcion:String): Boolean;
    function DarListaEpigrafes: TStringList;

    function AsignarPadre(AEpigrafe, AEpigrafePadre: IBizEpigrafe) : IBizEpigrafe;
    function ExtraerSeleccionados(AEpigrafes: IBizEpigrafe) : IBizEpigrafe;
    function ElegirEpigrafe(AEpigrafes : IBizEpigrafe; AMensaje: String; AMultiSelect: Boolean): IBizEpigrafe;

  end;

  TEpigrafesController = class(TControllerBase, IEpigrafesController)
  protected
    FDataModule : IDataModuleContabilidad;

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

    function ValidarEpigrafe(AEpigrafe: IBizEpigrafe): Boolean;
    procedure AsignarDataModule;
    procedure FiltrarEjercicio(AEpigrafe: IBizEpigrafe);

  public
    constructor Create; override;
    destructor Destroy; override;

    function EsModificable(AEpigrafe : IBizEpigrafe): Boolean;
    function EsEliminable(AEpigrafe : IBizEpigrafe): Boolean;

    function Eliminar(AEpigrafe : IBizEpigrafe): Boolean;
    function Guardar(AEpigrafe : IBizEpigrafe): Boolean; virtual;
    procedure DescartarCambios(AEpigrafe : IBizEpigrafe); virtual;
    procedure Anadir(AEpigrafe : IBizEpigrafe);
    function BuscarTodos: IBizEpigrafe;
    function Buscar(ID: Integer): IBizEpigrafe;
    procedure VerTodos(AEpigrafes: IBizEpigrafe);
    procedure Ver(AEpigrafe: IBizEpigrafe);
    function Localizar(AEpigrafes: IBizEpigrafe; ADescripcion:String): Boolean;
    function DarListaEpigrafes: TStringList;

    function AsignarPadre(AEpigrafe, AEpigrafePadre: IBizEpigrafe) : IBizEpigrafe;
    function ExtraerSeleccionados(AEpigrafes: IBizEpigrafe) : IBizEpigrafe;
    function ElegirEpigrafe(AEpigrafes : IBizEpigrafe; AMensaje: String; AMultiSelect: Boolean): IBizEpigrafe;
  end;

implementation

uses
  cxControls, DB, uEditorRegistryUtils, schContabilidadClient_Intf, uBizEjercicios,
  uIEditorEpigrafes, uIEditorEpigrafe, uIEditorElegirEpigrafes, uDataModuleContabilidad,
  uDAInterfaces, uDataTableUtils, uDialogUtils, uFactuGES_App,
  uDateUtils, uROTypes, DateUtils, Controls, Windows;

{ TEpigrafesController }

procedure TEpigrafesController.Anadir(AEpigrafe: IBizEpigrafe);
begin
  AEpigrafe.Insert;
end;

procedure TEpigrafesController.AsignarDataModule;
begin
  FDataModule := TDataModuleContabilidad.Create(Nil);
end;

function TEpigrafesController.AsignarPadre(AEpigrafe, AEpigrafePadre: IBizEpigrafe): IBizEpigrafe;
begin
  if Assigned(AEpigrafePadre) then
  begin
    if Assigned(AEpigrafe) then
    begin
      if not AEpigrafe.DataTable.Editing then
         AEpigrafe.DataTable.Edit;

      AEpigrafe.ID_PADRE := AEpigrafePadre.ID;
      AEpigrafe.EPIGRAFE_PADRE := AEpigrafePadre.DESCRIPCION;
      AEpigrafe.Post;
    end;
  end;
end;

function TEpigrafesController.Buscar(ID: Integer): IBizEpigrafe;
var
  Condicion: TDAWhereExpression;
begin
  ShowHourglassCursor;
  try
    Result := BuscarTodos;

    with Result.DataTable.DynamicWhere do
    begin
      // (ID = :ID)
      Condicion := NewBinaryExpression(NewField('', fld_EpigrafesID), NewConstant(ID, datInteger), dboEqual);

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

  finally
    HideHourglassCursor;
  end;
end;

function TEpigrafesController.BuscarTodos: IBizEpigrafe;
begin
  Result := FDataModule.GetEpigrafeItems;
  FiltrarEjercicio(Result);
end;

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

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

function TEpigrafesController.DarListaEpigrafes: TStringList;
var
  AEpigrafes: IBizEpigrafe;
begin
  AEpigrafes := BuscarTodos;
  AEpigrafes.DataTable.Active := True;
  Result := TStringList.Create;
  try
    with Result do
    begin
      AEpigrafes.DataTable.First;
      while not AEpigrafes.DataTable.EOF do
      begin
        Add(AEpigrafes.DESCRIPCION);
        AEpigrafes.DataTable.Next;
      end;
    end;
  finally
    AEpigrafes := NIL;
  end;
end;

procedure TEpigrafesController.DescartarCambios(AEpigrafe: IBizEpigrafe);
begin
  if not Assigned(AEpigrafe) then
    raise Exception.Create ('Epigrafe no asignado');

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

    AEpigrafe.DataTable.CancelUpdates;
  finally
    HideHourglassCursor;
  end;
end;

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

function TEpigrafesController.ValidarEpigrafe(AEpigrafe: IBizEpigrafe): Boolean;
begin
  Result := False;
  
  if not Assigned(AEpigrafe) then
    raise Exception.Create ('Epigrafe no asignado');

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

  if Length(AEpigrafe.REF_EPIGRAFE) = 0 then
    raise Exception.Create('Debe indicar una referencia para este Epigrafe.');

  if Length(AEpigrafe.DESCRIPCION) = 0 then
    raise Exception.Create('Debe indicar una descripción para este Epigrafe.');

  Result := True;
end;

procedure TEpigrafesController.Ver(AEpigrafe: IBizEpigrafe);
var
  AEditor : IEditorEpigrafe;
begin
  AEditor := NIL;

  CreateEditor('EditorEpigrafe', IEditorEpigrafe, AEditor);
  if Assigned(AEditor) then
    try
      AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
      AEditor.Epigrafe := AEpigrafe;

      //MODO CONSULTAR
      if not EsModificable(AEpigrafe) then
      begin
         SetDataTableReadOnly(AEpigrafe.DataTable, True);
         AEditor.ReadOnly := True;
      end;

      AEditor.ShowModal;

      //MODO CONSULTAR (Se deja la tabla como estaba)
      if AEditor.ReadOnly then
         SetDataTableReadOnly(AEpigrafe.DataTable, False);

    finally
      AEditor.Release;
      AEditor := NIL;
    end;
end;

procedure TEpigrafesController.VerTodos(AEpigrafes: IBizEpigrafe);
var
  AEditor : IEditorEpigrafes;
begin
  AEditor := NIL;

  CreateEditor('EditorEpigrafes', IEditorEpigrafes, AEditor);
  if Assigned(AEditor) then
     with AEditor do
     begin
       Controller := Self; //OJO ORDEN MUY IMPORTANTE
       Epigrafes := AEpigrafes;
       ShowEmbedded;
     end;
end;

function TEpigrafesController.ElegirEpigrafe(AEpigrafes: IBizEpigrafe; AMensaje: String; AMultiSelect: Boolean): IBizEpigrafe;
var
  AEditor : IEditorElegirEpigrafes;
begin
  Result := NIL;

  CreateEditor('EditorElegirEpigrafes', IEditorElegirEpigrafes, AEditor);
  if Assigned(AEditor) then
    try
      AEditor.Epigrafes := AEpigrafes;
      AEditor.Controller := Self;
      AEditor.Mensaje := AMensaje;
      if IsPositiveResult(AEditor.ShowModal) then
        Result := AEditor.EpigrafesSeleccionados;
    finally
      AEditor.Release;
      AEditor := NIL;
    end;
end;

function TEpigrafesController.Eliminar(AEpigrafe: IBizEpigrafe): Boolean;
begin
  if not Assigned(AEpigrafe) then
    raise Exception.Create ('Epigrafe no asignado');

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

    //Siempre eliminaremos el seleccionado
    if EsEliminable(AEpigrafe) then
    begin
      AEpigrafe.Delete;
      AEpigrafe.DataTable.ApplyUpdates;
    end;

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

function TEpigrafesController.EsEliminable(AEpigrafe: IBizEpigrafe): Boolean;
begin
  if not Assigned(AEpigrafe) then
     raise Exception.Create ('Epigrafe no asignado: EsModificable');

  Result := (AEpigrafe.ESTADO = CTE_ABIERTO);
end;

function TEpigrafesController.EsModificable(AEpigrafe: IBizEpigrafe): Boolean;
begin
  if not Assigned(AEpigrafe) then
     raise Exception.Create ('Epigrafe no asignado: EsModificable');

  Result := (AEpigrafe.ESTADO = CTE_ABIERTO);
end;

function TEpigrafesController.ExtraerSeleccionados(AEpigrafes: IBizEpigrafe): IBizEpigrafe;
var
  ASeleccionados : IBizEpigrafe;
begin
  ASeleccionados := Self.Buscar(ID_NULO);
  CopyDataTableDA5(AEpigrafes.DataTable, ASeleccionados.DataTable, True);
  Result := ASeleccionados;
end;

procedure TEpigrafesController.FiltrarEjercicio(AEpigrafe: IBizEpigrafe);
var
  Condicion: TDAWhereExpression;
begin
  if AEpigrafe.DataTable.Active then
    AEpigrafe.DataTable.Active := False;

  if not Assigned(AppFactuGES.EjercicioActivo) then
    raise Exception.Create('No se ha definido ningún ejercicio activo');

  // Filtrar los epigrafes actuales por ejercicio activo
  with AEpigrafe.DataTable.DynamicWhere do
  begin
    // (ID_EJERCICIO = ID)
    Condicion := NewBinaryExpression(NewField('', fld_EpigrafesID_EJERCICIO), NewConstant(AppFactuGES.EjercicioActivo.ID, datInteger), dboEqual);

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

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

function TEpigrafesController.Guardar(AEpigrafe: IBizEpigrafe): Boolean;
begin
  Result := False;

  if ValidarEpigrafe(AEpigrafe) then
  begin
    ShowHourglassCursor;
    try
      AEpigrafe.DataTable.ApplyUpdates;
      Result := True;
    finally
      HideHourglassCursor;
    end;
  end;
end;

function TEpigrafesController.Localizar(AEpigrafes: IBizEpigrafe; ADescripcion: String): Boolean;
begin
  Result := True;
  ShowHourglassCursor;
  try
    with AEpigrafes.DataTable do
    begin
      DisableControls;
      First;
      if not Locate(fld_EpigrafesDESCRIPCION, ADescripcion, []) then
         Result := False;
      EnableControls;   
    end;
  finally
    HideHourglassCursor;
  end;
end;

end.
