unit uCuentasController;

interface


uses
  Classes, SysUtils, uDADataTable, uControllerBase,
   uBizCuentas, uIDataModuleContabilidad;
type
  ICuentasController = interface(IControllerBase)
  ['{94E5F2B6-64C8-4331-B9CB-3ED730478529}']
    function BuscarTodos: IBizCuenta;
    function Buscar(ID: Integer): IBizCuenta;
    procedure VerTodos(ACuentas: IBizCuenta);
    procedure Ver(ACuenta: IBizCuenta);
    procedure Anadir(ACuenta : IBizCuenta);
    function Eliminar(ACuenta : IBizCuenta): Boolean; 
    function Guardar(ACuenta : IBizCuenta): Boolean;
    procedure DescartarCambios(ACuenta : IBizCuenta);
    function Localizar(ACuentas: IBizCuenta; ADescripcion:String): Boolean;
    function DarListaCuentas: TStringList;

    function ExtraerSeleccionados(ACuentas: IBizCuenta) : IBizCuenta;
    function ElegirCuenta(ACuentas : IBizCuenta; AMensaje: String; AMultiSelect: Boolean): IBizCuenta;

    procedure ElegirEpigrafe(ACuenta: IBizCuenta);
    procedure ElegirBalance(ACuenta: IBizCuenta);
    procedure ElegirCuentaEspecial(ACuenta: IBizCuenta);
  end;

  TCuentasController = class(TControllerBase, ICuentasController)
  protected
    FDataModule : IDataModuleContabilidad;

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

    function ValidarCuenta(ACuenta: IBizCuenta): Boolean;
    procedure AsignarDataModule;
    procedure FiltrarEjercicio(ACuenta: IBizCuenta);

  public
    constructor Create; override;
    destructor Destroy; override;

    function Eliminar(ACuenta : IBizCuenta): Boolean;
    function Guardar(ACuenta : IBizCuenta): Boolean; virtual;
    procedure DescartarCambios(ACuenta : IBizCuenta); virtual;
    procedure Anadir(ACuenta : IBizCuenta);
    function BuscarTodos: IBizCuenta;
    function Buscar(ID: Integer): IBizCuenta;
    procedure VerTodos(ACuentas: IBizCuenta);
    procedure Ver(ACuenta: IBizCuenta);
    function Localizar(ACuentas: IBizCuenta; ADescripcion:String): Boolean;
    function DarListaCuentas: TStringList;

    function ExtraerSeleccionados(ACuentas: IBizCuenta) : IBizCuenta;
    function ElegirCuenta(ACuentas : IBizCuenta; AMensaje: String; AMultiSelect: Boolean): IBizCuenta;

    procedure ElegirEpigrafe(ACuenta: IBizCuenta);
    procedure ElegirBalance(ACuenta: IBizCuenta);
    procedure ElegirCuentaEspecial(ACuenta: IBizCuenta);
  end;

implementation

uses
  cxControls, DB, uEditorRegistryUtils, schContabilidadClient_Intf,
  uIEditorCuentas, uIEditorCuenta, uIEditorElegirCuentas, uDataModuleContabilidad,
  uDAInterfaces, uDataTableUtils, uDialogUtils, uFactuGES_App,
  uDateUtils, uROTypes, DateUtils, Controls, Windows,
  uBizEpigrafes, uEpigrafesController,
  uBizBalances, uBalancesController,
  uBizCuentasEspeciales, uCuentasEspecialesController;

{ TCuentasController }

procedure TCuentasController.Anadir(ACuenta: IBizCuenta);
begin
  ACuenta.Insert;
end;

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

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

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

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

  finally
    HideHourglassCursor;
  end;
end;

function TCuentasController.BuscarTodos: IBizCuenta;
begin
  Result := FDataModule.GetCuentaItems;
  FiltrarEjercicio(Result);
end;

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

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

function TCuentasController.DarListaCuentas: TStringList;
var
  ACuentas: IBizCuenta;
begin
  ACuentas := BuscarTodos;
  ACuentas.DataTable.Active := True;
  Result := TStringList.Create;
  try
    with Result do
    begin
      ACuentas.DataTable.First;
      while not ACuentas.DataTable.EOF do
      begin
        Add(ACuentas.DESCRIPCION);
        ACuentas.DataTable.Next;
      end;
    end;
  finally
    ACuentas := NIL;
  end;
end;

procedure TCuentasController.DescartarCambios(ACuenta: IBizCuenta);
begin
  if not Assigned(ACuenta) then
    raise Exception.Create ('Cuenta no asignado');

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

    ACuenta.DataTable.CancelUpdates;
  finally
    HideHourglassCursor;
  end;
end;

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

function TCuentasController.ValidarCuenta(ACuenta: IBizCuenta): Boolean;
begin
  Result := False;

  if not Assigned(ACuenta) then
    raise Exception.Create ('Cuenta no asignado');

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

  if Length(ACuenta.REF_CUENTA) = 0 then
    raise Exception.Create('Debe indicar una referencia para esta cuenta.');

  if Length(ACuenta.DESCRIPCION) = 0 then
    raise Exception.Create('Debe indicar una descripción para esta cuenta.');

  Result := True;
end;

procedure TCuentasController.Ver(ACuenta: IBizCuenta);
var
  AEditor : IEditorCuenta;
begin
  AEditor := NIL;

  CreateEditor('EditorCuenta', IEditorCuenta, AEditor);
  if Assigned(AEditor) then
    try
      AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
      AEditor.Cuenta := ACuenta;
      AEditor.ShowModal;
    finally
      AEditor.Release;
      AEditor := NIL;
    end;
end;

procedure TCuentasController.VerTodos(ACuentas: IBizCuenta);
var
  AEditor : IEditorCuentas;
begin
  AEditor := NIL;

  CreateEditor('EditorCuentas', IEditorCuentas, AEditor);
  if Assigned(AEditor) then
     with AEditor do
     begin
       Controller := Self; //OJO ORDEN MUY IMPORTANTE
       Cuentas := ACuentas;
       ShowEmbedded;
     end;
end;

procedure TCuentasController.ElegirBalance(ACuenta: IBizCuenta);
var
  ABalance : IBizBalance;
  AController : IBalancesController;
begin
  inherited;
  try
    AController := TBalancesController.Create;
    ABalance := (AController.ElegirBalance(AController.BuscarTodos, 'Elija el balance al que pertenece la cuenta', False) as IBizBalance);

    if Assigned(ABalance) then
    begin
      if Assigned(ACuenta) then
      begin
        if not ACuenta.DataTable.Editing then
           ACuenta.DataTable.Edit;

        ACuenta.ID_BALANCE := ABalance.ID;
        ACuenta.BALANCE := ABalance.REF_BALANCE;
        ACuenta.Post;
      end;
    end;
  finally
    AController := Nil;
    ABalance := Nil;
  end;
end;

function TCuentasController.ElegirCuenta(ACuentas: IBizCuenta;
  AMensaje: String; AMultiSelect: Boolean): IBizCuenta;
var
  AEditor : IEditorElegirCuentas;
begin
  Result := NIL;

  CreateEditor('EditorElegirCuentas', IEditorElegirCuentas, AEditor);
  if Assigned(AEditor) then
    try
      AEditor.Cuentas := ACuentas;
      AEditor.Controller := Self;
      AEditor.Mensaje := AMensaje;
      if IsPositiveResult(AEditor.ShowModal) then
        Result := AEditor.CuentasSeleccionados;
    finally
      AEditor.Release;
      AEditor := NIL;
    end;
end;

procedure TCuentasController.ElegirCuentaEspecial(ACuenta: IBizCuenta);
var
  ACuentaEspecial : IBizCuentaEspecial;
  AController : ICuentasEspecialesController;
begin
  inherited;
  try
    AController := TCuentasEspecialesController.Create;
    ACuentaEspecial := (AController.ElegirCuentaEspecial(AController.BuscarTodos, 'Elija la cuenta especial a la que pertenece la cuenta', False) as IBizCuentaEspecial);

    if Assigned(ACuentaEspecial) then
    begin
      if Assigned(ACuenta) then
      begin
        if not ACuenta.DataTable.Editing then
           ACuenta.DataTable.Edit;

        ACuenta.ID_CUENTA_ESPECIAL := ACuentaEspecial.ID;
        ACuenta.CUENTA_ESPECIAL := ACuentaEspecial.REFERENCIA;
        ACuenta.Post;
      end;
    end;
  finally
    AController := Nil;
    ACuentaEspecial := Nil;
  end;
end;

procedure TCuentasController.ElegirEpigrafe(ACuenta: IBizCuenta);
var
  AEpigrafe : IBizEpigrafe;
  AController : IEpigrafesController;
begin
  inherited;
  try
    AController := TEpigrafesController.Create;
    AEpigrafe := (AController.ElegirEpigrafe(AController.BuscarTodos, 'Elija el epigrafe al que pertenece la cuenta', False) as IBizEpigrafe);

    if Assigned(AEpigrafe) then
    begin
      if Assigned(ACuenta) then
      begin
        if not ACuenta.DataTable.Editing then
           ACuenta.DataTable.Edit;

        ACuenta.ID_EPIGRAFE := AEpigrafe.ID;
        ACuenta.EPIGRAFE := AEpigrafe.DESCRIPCION;
        ACuenta.Post;
      end;
    end;
  finally
    AController := Nil;
    AEpigrafe := Nil;
  end;
end;

function TCuentasController.Eliminar(ACuenta: IBizCuenta): Boolean;
begin
  if not Assigned(ACuenta) then
    raise Exception.Create ('Cuenta no asignado');

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

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

function TCuentasController.ExtraerSeleccionados(ACuentas: IBizCuenta): IBizCuenta;
var
  ASeleccionados : IBizCuenta;
begin
  ASeleccionados := Self.Buscar(ID_NULO);
  CopyDataTableDA5(ACuentas.DataTable, ASeleccionados.DataTable, True);
  Result := ASeleccionados;
end;

procedure TCuentasController.FiltrarEjercicio(ACuenta: IBizCuenta);
var
  Condicion: TDAWhereExpression;
begin
  if ACuenta.DataTable.Active then
    ACuenta.DataTable.Active := False;

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

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

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

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

function TCuentasController.Guardar(ACuenta: IBizCuenta): Boolean;
begin
  Result := False;

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

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

end.
