unit uApuntesController;

interface


uses
  Classes, SysUtils, uDADataTable, uControllerBase,
   uBizApuntes, uBizSubCuentas, uIDataModuleContabilidad;
type
  IApuntesController = interface(IControllerBase)
  ['{94E5F2B6-64C8-4331-B9CB-3ED730478529}']
//    function BuscarTodos: IBizApunte;
//    function Buscar(const ID: Integer): IBizApunte;
//    procedure VerTodos(AApuntes: IBizApunte);
    procedure Anadir(AApunte : IBizApunte); overload;
    procedure Anadir(AApunte : IBizApunte; IdSubCuenta: Integer); overload;
    procedure AnadirCierre(AApunte : IBizApunte);
    procedure Ver(AApunte: IBizApunte);
//    function Anadir: IBizApunte;
    function Eliminar(AApunte : IBizApunte): Boolean;
    function Guardar(AApunte : IBizApunte): Boolean;
    procedure DescartarCambios(AApunte : IBizApunte);

    function ValidarApunte(AApunte: IBizApunte): Boolean;
    procedure ElegirSubCuenta(AApunte: IBizApunte);

    procedure AsignarDEBE(AApunte: IBizApunte);
    procedure AsignarHABER(AApunte: IBizApunte);
  end;

  TApuntesController = class(TControllerBase, IApuntesController)
  private
    procedure CopiarSubCuenta_Apunte(AApunte: IBizApunte; ASubCuenta : IBizSubCuenta);

  protected
    FDataModule : IDataModuleContabilidad;

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

    procedure AsignarDataModule;
    procedure FiltrarEjercicio(AApunte: IBizApunte);

  public
    constructor Create; override;
    destructor Destroy; override;

    function ValidarApunte(AApunte: IBizApunte): Boolean;

    function EsModificable(AApunte : IBizApunte): Boolean;
    function EsEliminable(AApunte : IBizApunte): Boolean;

    procedure Anadir(AApunte : IBizApunte); overload;
    procedure Anadir(AApunte : IBizApunte; IdSubCuenta: Integer); overload;
    procedure AnadirCierre(AApunte : IBizApunte);
    function Eliminar(AApunte : IBizApunte): Boolean;
    function Guardar(AApunte : IBizApunte): Boolean; virtual;
    procedure DescartarCambios(AApunte : IBizApunte); virtual;
//    function Anadir: IBizApunte;
//    function BuscarTodos: IBizApunte;
//    function Buscar(const ID: Integer): IBizApunte;
//    procedure VerTodos(AApuntes: IBizApunte);
    procedure Ver(AApunte: IBizApunte);
    procedure ElegirSubCuenta(AApunte: IBizApunte);

    procedure AsignarDEBE(AApunte: IBizApunte);
    procedure AsignarHABER(AApunte: IBizApunte);
  end;

implementation

uses
  cxControls, DB, uEditorRegistryUtils, schContabilidadClient_Intf,
  uSubCuentasController,
  uIEditorApunte, uDataModuleContabilidad,
  uDAInterfaces, uDataTableUtils, uDialogUtils, uFactuGES_App,
  uDateUtils, uROTypes, DateUtils, Controls, Windows;

{ TApuntesController }

{
function TApuntesController.Anadir: IBizApunte;
var
  AApunte : IBizApunte;
begin
  AApunte := FDataModule.GetApunteItem(ID_NULO);
  AApunte.DataTable.Active := True;
  AApunte.Insert;
  Result := AApunte;
end;
}

procedure TApuntesController.Anadir(AApunte: IBizApunte);
begin
//  AApunte.DataTable.DisableControls;
//  AApunte.Last;
  AApunte.Append;
//  AApunte.DataTable.EnableControls;
end;

procedure TApuntesController.Anadir(AApunte: IBizApunte; IdSubCuenta: Integer);
var
  ASubCuenta : IBizSubCuenta;
  AController : ISubCuentasController;

begin
  Anadir(AApunte);

  try
    AController := TSubCuentasController.Create;
    ASubCuenta := AController.Buscar(IdSubcuenta);
    CopiarSubCuenta_Apunte(AApunte, ASubCuenta);

  finally
    AController := Nil;
    ASubCuenta := Nil;
  end;
end;

procedure TApuntesController.AnadirCierre(AApunte: IBizApunte);
begin
  if not AApunte.DataTable.Editing then
     AApunte.DataTable.Edit;

  AApunte.CONCEPTO := 'CIERRE CAJA';
  AApunte.DEBE := 0;
  AApunte.Post;
end;

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

procedure TApuntesController.AsignarDEBE(AApunte: IBizApunte);
begin
  if Assigned(AApunte) then
  begin
    if not AApunte.DEBEIsNull then
    begin
      if not AApunte.DataTable.Editing then
         AApunte.DataTable.Edit;
      AApunte.HABERIsNull := True;
      AApunte.DataTable.Post;

//      RecalcularAsiento;
    end;
  end;
end;

procedure TApuntesController.AsignarHABER(AApunte: IBizApunte);
begin
  if Assigned(AApunte) then
  begin
    if not AApunte.HABERIsNull then
    begin
      if not AApunte.DataTable.Editing then
         AApunte.DataTable.Edit;
      AApunte.DEBEIsNull := True;
      AApunte.DataTable.Post;

//      RecalcularAsiento;
    end;
  end;
end;

{
function TApuntesController.Buscar(const ID: Integer): IBizApunte;
begin
  Result := FDataModule.GetApunteItem(ID);
end;
}

{
function TApuntesController.BuscarTodos: IBizApunte;
begin
  Result := FDataModule.GetApunteItems;
  FiltrarEjercicio(Result);
end;
}

procedure TApuntesController.CopiarSubCuenta_Apunte(AApunte: IBizApunte; ASubCuenta: IBizSubCuenta);
begin
  if Assigned(ASubCuenta) then
  begin
    if not ASubCuenta.DataTable.Active then
       ASubCuenta.DataTable.Active := True;

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

      AApunte.ID_SUBCUENTA := ASubCuenta.ID;
      AApunte.REF_SUBCUENTA := ASubCuenta.REF_SUBCUENTA;
      AApunte.SUBCUENTA := ASubCuenta.DESCRIPCION;
      AApunte.Post;
    end;
  end;
end;

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

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

procedure TApuntesController.DescartarCambios(AApunte: IBizApunte);
begin
  if not Assigned(AApunte) then
    raise Exception.Create ('Apunte no asignado');

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

    AApunte.DataTable.CancelUpdates;
  finally
    HideHourglassCursor;
  end;
end;

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

function TApuntesController.ValidarApunte(AApunte: IBizApunte): Boolean;
var
  Descuadre : Currency;
begin
  Result := False;
  
  if not Assigned(AApunte) then
    raise Exception.Create ('Apuntes no asignados');

  //Tambien hacemos post de sus tablas hija
  if (AApunte.DataTable.State in dsEditModes) then
      AApunte.DataTable.Post;

  if (AApunte.DataTable.RecordCount = 0) then
    raise Exception.Create('El asiento debe tener algún apunte');

  AApunte.DataTable.DisableControls;
  Descuadre := 0;
  AApunte.DataTable.First;
  while not AApunte.DataTable.EOF do
  begin
    if AApunte.ID_SUBCUENTAIsNull then
    begin
      AApunte.DataTable.EnableControls;
      raise Exception.Create('Todo apunte debe tener una subcuenta asociada');
    end;

    Descuadre := Descuadre + AApunte.DEBE;
    Descuadre := Descuadre - AApunte.HABER;
    AApunte.DataTable.Next;
  end;

  if (Descuadre <> 0) then
  begin
     AApunte.DataTable.EnableControls;
     raise Exception.Create('El asiento está descuadrado');
  end;

  Result := True;
end;

procedure TApuntesController.Ver(AApunte: IBizApunte);
var
  AEditor : IEditorApunte;
begin
  AEditor := NIL;

  CreateEditor('EditorApunte', IEditorApunte, AEditor);
  if Assigned(AEditor) then
    try
//         AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
      AEditor.Apunte := AApunte;
      AEditor.ShowModal;
    finally
      AEditor.Release;
      AEditor := NIL;
    end;
end;

{
procedure TApuntesController.VerTodos(AApuntes: IBizApunte);
var
  AEditor : IEditorApuntes;
begin
  AEditor := NIL;

  CreateEditor('EditorApuntes', IEditorApuntes, AEditor);
  if Assigned(AEditor) then
  begin
       AEditor.Controller := Self; //OJO ORDEN MUY IMPORTANTE
       AEditor.Apuntes := AApuntes;
       AEditor.ShowEmbedded;
  end;
end;
}

procedure TApuntesController.ElegirSubCuenta(AApunte: IBizApunte);
var
  ASubCuenta : IBizSubCuenta;
  AController : ISubCuentasController;
begin
  inherited;
  try
    AController := TSubCuentasController.Create;
    ASubCuenta := (AController.ElegirSubCuenta(AController.BuscarTodos, 'ddddddd', False) as IBizSubCuenta);
    CopiarSubCuenta_Apunte(AApunte, ASubCuenta);

  finally
    AController := Nil;
    ASubCuenta := Nil;
  end;
end;

function TApuntesController.Eliminar(AApunte: IBizApunte): Boolean;
begin
  if not Assigned(AApunte) then
    raise Exception.Create ('Apunte no asignado');

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

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

function TApuntesController.EsEliminable(AApunte: IBizApunte): Boolean;
begin
//  AApunte.
end;

function TApuntesController.EsModificable(AApunte: IBizApunte): Boolean;
begin
//
end;

procedure TApuntesController.FiltrarEjercicio(AApunte: IBizApunte);
var
  Condicion: TDAWhereExpression;
begin
  if AApunte.DataTable.Active then
    AApunte.DataTable.Active := False;

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

  // Filtrar los Apuntes por la empresa activa
  with AApunte.DataTable.DynamicWhere do
  begin
    // (ID_EJERCICIO = ID)
    Condicion := NewBinaryExpression(NewField('', fld_DiarioID_EJERCICIO), NewConstant(AppFactuGES.EjercicioActivo.ID, datInteger), dboEqual);

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

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

function TApuntesController.Guardar(AApunte: IBizApunte): Boolean;
begin
  Result := True;
{
  if ValidarApunte(AApunte) then
  begin
    ShowHourglassCursor;
    try
      AApunte.DataTable.ApplyUpdates;
      Result := True;
    finally
      HideHourglassCursor;
    end;
  end;
}
  if (AApunte.DataTable.State in dsEditModes) then
     AApunte.DataTable.Post;

end;

end.
