{
===============================================================================
  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 uRecibosProveedorController;

interface

uses
  Classes, SysUtils, uDADataTable, uControllerBase,
	uPagosProveedorController, uProveedoresController,
  uBizRecibosProveedor, uIDataModuleRecibosProveedor;

type
  IRecibosProveedorController = interface(IObservador)
  ['{763DF610-3540-42BE-A09A-35AABFAF2DA1}']

    function GetPagosController: IPagosProveedorController;
    procedure SetPagosController(const Value: IPagosProveedorController);
    property PagosController: IPagosProveedorController read GetPagosController write SetPagosController;

    procedure Anadir(ARecibosProveedor : IBizRecibosProveedor);
    function AnadirPago(ARecibosProveedor : IBizRecibosProveedor; FechaPago: String =''): Boolean;
    procedure ModificarPago(ARecibosProveedor : IBizRecibosProveedor);
    function Eliminar(ARecibosProveedor : IBizRecibosProveedor): Boolean;
    function EliminarPago(ARecibosProveedor : IBizRecibosProveedor): Boolean;
    function EliminarTodo(ARecibosProveedor : IBizRecibosProveedor): Boolean;
    function Guardar(ARecibosProveedor : IBizRecibosProveedor): Boolean;
    procedure DescartarCambios(ARecibosProveedor : IBizRecibosProveedor);
		function Duplicar(ARecibosProveedor: IBizRecibosProveedor): IBizRecibosProveedor;
    function Nuevo : IBizRecibosProveedor;
    procedure RecuperarCliente(AReciboProveedor : IBizRecibosProveedor);
    function Buscar(const ID: Integer): IBizRecibosProveedor;
  	function BuscarTodos: IBizRecibosProveedor;

    function BuscarRecibosRemesa(const ID_REMESA: Integer): IBizRecibosProveedor;
  	function BuscarRecibosFactura(const ID_FACTURA: Integer): IBizRecibosProveedor;
    function BuscarRecibosACompensar(const Recibo: IBizRecibosProveedor): IBizRecibosProveedor;
  	function BuscarRecibosARemesar: IBizRecibosProveedor;

    procedure VerTodos(ARecibosProveedor: IBizRecibosProveedor);
    procedure Ver(ARecibosProveedor: IBizRecibosProveedor);
    function ExtraerSeleccionados(ARecibosProveedor: IBizRecibosProveedor) : IBizRecibosProveedor;

    procedure AsignarRemesa(ARecibos : IBizRecibosProveedor; ID_REMESA: Integer);
    procedure QuitarRemesa(ARecibos : IBizRecibosProveedor);
    procedure SetSituacionCobrados(ARecibos : IBizRecibosProveedor; WithDeltas: Boolean=False);
    function ElegirRecibos(ARecibos : IBizRecibosProveedor; AMensaje: String; AMultiSelect: Boolean): IBizRecibosProveedor;

    function ElegirRecibosCompensados(ARecibo : IBizRecibosProveedor): Boolean;
    procedure QuitarReciboCompensado(ARecibo : IBizRecibosProveedor);

    procedure Preview(ARecibosProveedor : IBizRecibosProveedor);
    procedure Print(ARecibosProveedor : IBizRecibosProveedor);
  end;

  TRecibosProveedorController = class(TObservador, IRecibosProveedorController)
  private
    function ImporteTotalModificado(ARecibosProveedor: IBizRecibosProveedor;
      var ImporteRestante: Currency): Boolean;
  protected
    FDataModule : IDataModuleRecibosProveedor;
    FPagosController : IPagosProveedorController;
    FClienteController : IProveedoresController;

    function GetPagosController: IPagosProveedorController;
    procedure SetPagosController(const Value: IPagosProveedorController);

  	function _Vacio : IBizRecibosProveedor;

    function ValidarReciboProveedor(ARecibosProveedor: IBizRecibosProveedor): Boolean;
    procedure AsignarDataModule;
    procedure AsignarID(ARecibosProveedor: IBizRecibosProveedor; const IDNuevo: Integer);
    function DarNuevaReferencia(ID_FACTURA : Integer; REFERENCIA: String): String;

  public
    property PagosController: IPagosProveedorController read GetPagosController write SetPagosController;
    constructor Create; virtual;
    destructor Destroy; override;

    procedure RecuperarCliente(AReciboProveedor : IBizRecibosProveedor);
    procedure Anadir(ARecibosProveedor : IBizRecibosProveedor);
    function AnadirPago(ARecibosProveedor : IBizRecibosProveedor; FechaPago: String =''): Boolean;
    procedure ModificarPago(ARecibosProveedor : IBizRecibosProveedor);
    function Eliminar(ARecibosProveedor : IBizRecibosProveedor): Boolean;
    function EliminarPago(ARecibosProveedor : IBizRecibosProveedor): Boolean;
    function EliminarTodo(ARecibosProveedor : IBizRecibosProveedor): Boolean;
    function Guardar(ARecibosProveedor : IBizRecibosProveedor): Boolean;
    procedure DescartarCambios(ARecibosProveedor : IBizRecibosProveedor);
    function Duplicar(ARecibosProveedor: IBizRecibosProveedor): IBizRecibosProveedor;
    function Nuevo : IBizRecibosProveedor;

  	function Buscar(const ID: Integer): IBizRecibosProveedor;
    function BuscarTodos: IBizRecibosProveedor;

    function BuscarRecibosRemesa(const ID_REMESA: Integer): IBizRecibosProveedor;
  	function BuscarRecibosFactura(const ID_FACTURA: Integer): IBizRecibosProveedor;
    function BuscarRecibosACompensar(const Recibo: IBizRecibosProveedor): IBizRecibosProveedor;
  	function BuscarRecibosARemesar: IBizRecibosProveedor;

    procedure VerTodos(ARecibosProveedor: IBizRecibosProveedor);
    procedure Ver(ARecibosProveedor: IBizRecibosProveedor);

    function ExtraerSeleccionados(ARecibosProveedor: IBizRecibosProveedor) : IBizRecibosProveedor;
    function ElegirRecibos(ARecibos : IBizRecibosProveedor; AMensaje: String; AMultiSelect: Boolean): IBizRecibosProveedor;
    function ElegirRecibosCompensados(ARecibo : IBizRecibosProveedor): Boolean;

    procedure AsignarRemesa(ARecibos : IBizRecibosProveedor; ID_REMESA: Integer);
    procedure QuitarRemesa(ARecibos : IBizRecibosProveedor);
    procedure QuitarReciboCompensado(ARecibo : IBizRecibosProveedor);

    procedure SetSituacionCobrados(ARecibos : IBizRecibosProveedor; WithDeltas: Boolean=False);

    procedure Preview(ARecibosProveedor : IBizRecibosProveedor);
    procedure Print(ARecibosProveedor : IBizRecibosProveedor);
  end;

implementation

uses
  Forms, uNumUtils, cxControls, DB, uEditorRegistryUtils, Dialogs,
  uDAInterfaces, uDataTableUtils, uDataModuleUsuarios,
  uDateUtils, uROTypes, DateUtils, Controls, Windows, Variants,
  uRecibosProveedorReportController, uBizContactos,
  schRecibosProveedorClient_Intf, uIEditorRecibosProveedor, uIEditorReciboProveedor,
  uDataModuleRecibosProveedor, uIEditorFechaPagoProveedor, uIEditorElegirRecibosProveedor;

{ TRecibosProveedorController }

procedure TRecibosProveedorController.Anadir(ARecibosProveedor: IBizRecibosProveedor);
begin
  ARecibosProveedor.Insert;
end;

function TRecibosProveedorController.AnadirPago(ARecibosProveedor: IBizRecibosProveedor; FechaPago: String =''): Boolean;
var
  AEditor : IEditorFechaPagoProveedor;
begin
  Result := False;

  //Pedimos la fecha del pago
  if (Length(FechaPago) = 0) then
  begin
    CreateEditor('EditorFechaPagoProveedor', IEditorFechaPagoProveedor, AEditor);
    if Assigned(AEditor) then
      try
        if (AEditor.ShowModal = mrOk) then
           FechaPago := DateToStr(AEditor.FechaPago);
        AEditor.Release;
      finally
        AEditor := NIL;
      end;
  end;

  // Se cancela la operación
  if Length(FechaPago) = 0 then
     Exit;

  //Finalmente añadimos el pago (pago o devolucion)
  if PagosController.Anadir(ARecibosProveedor.Pagos, FechaPago) then
  begin
    ARecibosProveedor.Edit;
    ARecibosProveedor.SITUACION := CTE_PAGADO;
    Result := True;
  end
  //Podremos modificar si anulamos el pago mediante una devolución
  else
  begin
    ARecibosProveedor.Edit;
    ARecibosProveedor.SITUACION := CTE_DEVUELTO;
    Result := False;
  end;
end;

procedure TRecibosProveedorController.AsignarDataModule;
begin
  FDataModule := TDataModuleRecibosProveedor.Create(Nil);
end;

procedure TRecibosProveedorController.AsignarID(ARecibosProveedor: IBizRecibosProveedor;
  const IDNuevo: Integer);
var
  AContador : Integer;
begin
  if not Assigned(ARecibosProveedor) then
    raise Exception.Create ('IBizRecibosProveedor no asignado');

  if not Assigned(ARecibosProveedor.Pagos) then
    raise Exception.Create ('Pagos del recibo no asignados');

  if not Assigned(FPagosController) then
    raise Exception.Create ('Controller pagos no asignado');

  { Los detalles hay que comprobarlos siempre
     tanto en inserción como en modificación. }
  if Assigned(ARecibosProveedor.Pagos) then
     FPagosController.AsignarID(ARecibosProveedor.Pagos, IDNuevo, ARecibosProveedor.EsNuevo);

//Lo haremos siempre para actualizar siempre la referencia del recibo
//  if ARecibosProveedor.EsNuevo then
//  begin
    ARecibosProveedor.Edit;
    ARecibosProveedor.ID := IDNuevo;
    ARecibosProveedor.DESCRIPCION := 'RECIBO ' + ARecibosProveedor.REFERENCIA + ' - ' + CifraToLetras((ARecibosProveedor.IMPORTE + ARecibosProveedor.OTROS_GASTOS));
    ARecibosProveedor.Post;
//  end;
end;

procedure TRecibosProveedorController.AsignarRemesa(ARecibos: IBizRecibosProveedor; ID_REMESA: Integer);
begin
  if Assigned(ARecibos) then
  begin
    With ARecibos.DataTable do
    begin
      First;
      While not EOF do
      begin
        if (ARecibos.ID_REMESA <> ID_REMESA) then
        begin
          ARecibos.Edit;
          //Añadimos el cobro automatico por la remesa y volvemos a asignar ID
          //para que asigne un ID nuevo para el pago, porque aqui si hay maestro-detalle
          AnadirPago(ARecibos, DateToStr(Date)); //->Ojo el orden es importante
          ARecibos.ID_REMESA := ID_REMESA;
          AsignarID(ARecibos, ARecibos.ID);
        end;
        Next;
      end;
    end;
  end;
end;

function TRecibosProveedorController.BuscarTodos: IBizRecibosProveedor;
begin
  Result := FDataModule.GetItems;
end;

constructor TRecibosProveedorController.Create;
begin
  inherited;
  AsignarDataModule;
  FPagosController := TPagosProveedorController.Create;
  FClienteController := TProveedoresController.Create;
//  FPagosController.addObservador(Self);   //PETA NO SE PORQUE
end;

function TRecibosProveedorController.Buscar(const ID: Integer): IBizRecibosProveedor;
begin
  Result := (FDataModule as IDataModuleRecibosProveedor).GetItem(ID);
end;

function TRecibosProveedorController.BuscarRecibosFactura(const ID_FACTURA: Integer): IBizRecibosProveedor;
begin
  ShowHourglassCursor;
  try
    Result := BuscarTodos;
    with Result.DataTable.Where do
    begin
      if NotEmpty then
         AddOperator(opAND);
      OpenBraket;
      AddText(fld_RecibosProveedorID_FACTURA + ' = ' + IntToStr(ID_FACTURA));
      CloseBraket;
    end;
  finally
    HideHourglassCursor;
  end;
end;

function TRecibosProveedorController.BuscarRecibosACompensar(const Recibo: IBizRecibosProveedor): IBizRecibosProveedor;
begin
  if not Assigned(Recibo) then
     raise Exception.Create ('IBizReciboProveedor no asignado (BuscarRecibosACompensar)');

  ShowHourglassCursor;
  try
    Result := BuscarTodos;
    with Result.DataTable.Where do
    begin
      if NotEmpty then
         AddOperator(opAND);

      //No podrá compensarse un recibo a si mismo
      OpenBraket;
      AddText(fld_RecibosProveedorID + ' <> ' + IntToStr(Recibo.ID));
      CloseBraket;

      AddOperator(opAND);

      //Solo podrá compensar recibos del mismo proveedor
      OpenBraket;
      AddText(fld_RecibosProveedorID_PROVEEDOR + ' = ' + IntToStr(Recibo.ID_PROVEEDOR));
      CloseBraket;

      AddOperator(opAND);

      //Omitimos los recibos compensados
      OpenBraket;
      AddText(fld_RecibosProveedorID_RECIBO_COMPENSADO + ' IS NULL ');
      CloseBraket;

      AddOperator(opAND);

      //Solo dejaremos remesar aquellos recibos que no esten cobrados (Pendientes/Devueltos)
      OpenBraket;
      AddText(fld_RecibosProveedorSITUACION + ' <> ''' + CTE_PAGADO + '''');
      CloseBraket;
    end;
  finally
    HideHourglassCursor;
  end;
end;

function TRecibosProveedorController.BuscarRecibosARemesar: IBizRecibosProveedor;
begin
  ShowHourglassCursor;
  try
    Result := BuscarTodos;
    with Result.DataTable.Where do
    begin
      if NotEmpty then
         AddOperator(opAND);
      //Omitimos los recibos compensados
      OpenBraket;
      AddText(fld_RecibosProveedorID_RECIBO_COMPENSADO + ' IS NULL ');
      CloseBraket;
      AddOperator(opAND);
      //Solo dejaremos remesar aquellos recibos que no esten pagados (Pendientes/Devueltos)
      OpenBraket;
      AddText(fld_RecibosProveedorSITUACION + ' <> ''' + CTE_PAGADO + '''');
      CloseBraket;
    end;
  finally
    HideHourglassCursor;
  end;
end;

function TRecibosProveedorController.BuscarRecibosRemesa(const ID_REMESA: Integer): IBizRecibosProveedor;
begin
  ShowHourglassCursor;
  try
    Result := BuscarTodos;
    with Result.DataTable.Where do
    begin
      if NotEmpty then
         AddOperator(opAND);
      OpenBraket;
      AddText(fld_RecibosProveedorID_REMESA + ' = ' + IntToStr(ID_REMESA));
      CloseBraket;
    end;
  finally
    HideHourglassCursor;
  end;
end;

function TRecibosProveedorController._Vacio: IBizRecibosProveedor;
begin
  Result := Buscar(ID_NULO);
end;

function TRecibosProveedorController.DarNuevaReferencia(ID_FACTURA: Integer; REFERENCIA: String): String;
var
  ARecibosProveedor: IBizRecibosProveedor;
  NumReferencia : Integer;
  Cadena : String;
begin
  try
    ARecibosProveedor := BuscarRecibosFactura(ID_FACTURA);
    ARecibosProveedor.DataTable.Active := True;
    NumReferencia := ARecibosProveedor.DataTable.RecordCount;
    Cadena := Copy(REFERENCIA, 0, Pos('-', REFERENCIA));
    Result := Cadena + ' ' + IntToStr((NumReferencia + 1));
  finally
    ARecibosProveedor := Nil;
  end;
end;

procedure TRecibosProveedorController.DescartarCambios(ARecibosProveedor: IBizRecibosProveedor);
begin
  if not Assigned(ARecibosProveedor) then
    raise Exception.Create ('IBizRecibosProveedor no asignado');

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

    ARecibosProveedor.DataTable.CancelUpdates;
  finally
    HideHourglassCursor;
  end;
end;

destructor TRecibosProveedorController.Destroy;
begin
  FDataModule := NIL;
  FPagosController := NIL;
  FClienteController := NIL;
  inherited;
end;


function TRecibosProveedorController.Duplicar(ARecibosProveedor: IBizRecibosProveedor): IBizRecibosProveedor;
begin
  Result := Self._Vacio;
  ShowHourglassCursor;
  try
    DuplicarRegistros(ARecibosProveedor.DataTable, Result.DataTable, mdrActual);

    // Descomentar esto si hay detalles
    // (EN ESTE CASO NO NOS INTERESA COPIAR LOS PAGOS DEL RECIBO DUPLIACDO)
    // DuplicarRegistros(ARecibosProveedor.Detalles.DataTable, Result.Detalles.DataTable, mdrTodos);

    // ¡CUIDADO! Hay que dejar algunos campos como si fuera todo nuevo
    Result.Edit;
    with Result do
    begin
    	// Ejemplos
      // ID_EMPRESA := dmUsuarios.IDEmpresaActual;
      // USUARIO := dmUsuarios.LoginInfo.Usuario;
      // REFERENCIA := ''; //Para que se asigne una nueva
      // FECHA_FACTURA := DateOf(Now);
      // SITUACION := SITUACION_PENDIENTE;
    end;

    Result.Post;
  finally
    HideHourglassCursor;
  end;
end;


function TRecibosProveedorController.ValidarReciboProveedor(ARecibosProveedor: IBizRecibosProveedor): Boolean;
var
  ImporteRestante: Double;

begin
  Result := False;

  if not Assigned(ARecibosProveedor) then
    raise Exception.Create ('IBizRecibosProveedor no asignado');

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

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

  if ARecibosProveedor.DataTable.FieldByName(fld_RecibosProveedorFECHA_EMISION).IsNull then
     raise Exception.Create('Debe indicar la fecha de emisión del recibo.');

  if ARecibosProveedor.DataTable.FieldByName(fld_RecibosProveedorFECHA_VENCIMIENTO).IsNull then
     raise Exception.Create('Debe indicar la fecha de vencimiento del recibo.');


  { Asegurarse de valores en campos "automáticos" tanto
    en MODIFICACIÓN como en INSERCIÓN. }
  ARecibosProveedor.Edit;
  try
    ARecibosProveedor.USUARIO := dmUsuarios.LoginInfo.Usuario;
    Result := True;
  finally
    ARecibosProveedor.Post;
  end;

  Result := True;
end;

procedure TRecibosProveedorController.Ver(ARecibosProveedor: IBizRecibosProveedor);
var
  AEditor : IEditorReciboProveedor;
begin
  AEditor := NIL;
  ShowHourglassCursor;
  try
    RecuperarCliente(ARecibosProveedor);
    CreateEditor('EditorReciboProveedor', IEditorReciboProveedor, AEditor);
    with AEditor do
    begin
      Controller := Self; //OJO ORDEN MUY IMPORTANTE
      Recibo := ARecibosProveedor;
    end;
  finally
    HideHourglassCursor;
  end;

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

procedure TRecibosProveedorController.VerTodos(ARecibosProveedor: IBizRecibosProveedor);
var
  AEditor : IEditorRecibosProveedor;
begin
  AEditor := NIL;
  ShowHourglassCursor;
  try
    CreateEditor('EditorRecibosProveedor', IEditorRecibosProveedor, AEditor);
    with AEditor do
      RecibosProveedor := ARecibosProveedor;
  finally
    HideHourglassCursor;
  end;

  if Assigned(AEditor) then
    try
      AEditor.ShowEmbedded;
    finally
      AEditor := NIL;
    end;
end;

function TRecibosProveedorController.ElegirRecibos(ARecibos: IBizRecibosProveedor; AMensaje: String;
  AMultiSelect: Boolean): IBizRecibosProveedor;
var
  AEditor : IEditorElegirRecibosProveedor;
begin
  Result := NIL;
  CreateEditor('EditorElegirRecibosProveedor', IEditorElegirRecibosProveedor, AEditor);
  try
    with AEditor do
    begin
      Controller := Self;
      RecibosProveedor := ARecibos;
      MultiSelect := AMultiSelect;
      Mensaje := AMensaje;
      if IsPositiveResult(ShowModal) then
        Result := RecibosProveedorSeleccionados;
	  Release;
    end;
  finally
    AEditor := NIL;
  end;
end;

function TRecibosProveedorController.ElegirRecibosCompensados(ARecibo: IBizRecibosProveedor): Boolean;
var
  ARecibosACompensar: IBizRecibosProveedor;
begin
  ARecibosACompensar := Self.ElegirRecibos(BuscarRecibosACompensar(ARecibo), 'Elija los recibos que desea compensar', True);

  if Assigned(ARecibosACompensar) then
  begin
     ShowHourglassCursor;
     try
      DuplicarRegistros(ARecibosACompensar.DataTable, ARecibo.RecibosCompensados.DataTable, mdrTodos, True, True, False);
      Result := True;
     finally
       HideHourglassCursor;
       ARecibosACompensar := Nil;
     end;
  end;
end;

function TRecibosProveedorController.Eliminar(ARecibosProveedor: IBizRecibosProveedor): Boolean;
begin
  Result := False;

  if not Assigned(ARecibosProveedor) then
    raise Exception.Create ('IBizRecibosProveedor no asignado');

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

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

function TRecibosProveedorController.EliminarPago(ARecibosProveedor: IBizRecibosProveedor): Boolean;
begin
  Result := PagosController.Eliminar(ARecibosProveedor.Pagos);
end;

function TRecibosProveedorController.EliminarTodo(ARecibosProveedor: IBizRecibosProveedor): Boolean;
begin
  if Assigned(ARecibosProveedor) then
  begin
    if not ARecibosProveedor.DataTable.Active then
       ARecibosProveedor.DataTable.Active := True;
    ARecibosProveedor.DataTable.ClearRows;
    ARecibosProveedor.DataTable.ApplyUpdates;
  end;
end;

procedure TRecibosProveedorController.RecuperarCliente(
  AReciboProveedor: IBizRecibosProveedor);
begin
  AReciboProveedor._Proveedor := (FClienteController.Buscar(AReciboProveedor.ID_PROVEEDOR) as IBizProveedor);
end;

function TRecibosProveedorController.GetPagosController: IPagosProveedorController;
begin
  Result := FPagosController;
end;

procedure TRecibosProveedorController.SetPagosController(const Value: IPagosProveedorController);
begin
  FPagosController := Value;
end;

procedure TRecibosProveedorController.SetSituacionCobrados(ARecibos: IBizRecibosProveedor; WithDeltas: Boolean);
begin
  if Assigned(ARecibos) then
  begin
    ARecibos.DataTable.DisableControls;
    try
      DesconectarTabla(ARecibos.DataTable);
      with ARecibos.DataTable do
      begin
        First;
        while not Eof do
        begin
          if not Editing then Edit;
          ARecibos.SITUACION := CTE_PAGADO;
          Post;
          Next;
        end;
        First;
      end;
    finally
      ConectarTabla(ARecibos.DataTable);
      ARecibos.DataTable.EnableControls;
    end;
  end;
end;

function TRecibosProveedorController.ImporteTotalModificado(ARecibosProveedor : IBizRecibosProveedor; var ImporteRestante: Currency) : Boolean;
var
  HayCambio: TDADeltaChange;
begin
  Result := False;
  ImporteRestante := 0;
  HayCambio := ARecibosProveedor.DataTable.Delta.FindChange(ARecibosProveedor.RecNo);
  if  (Assigned(HayCambio)) and
    (HayCambio.OldValueByName[fld_RecibosProveedorIMPORTE] <> 0) then
  begin
    ImporteRestante := HayCambio.OldValueByName[fld_RecibosProveedorIMPORTE] - ARecibosProveedor.IMPORTE;
    if ImporteRestante <> 0 then
      Result := True;
  end;
end;

function TRecibosProveedorController.Guardar(ARecibosProveedor: IBizRecibosProveedor): Boolean;
var
  NuevoID : Integer;
  ANuevoReciboProveedor : IBizRecibosProveedor;
  ImporteRestante : Currency;
begin
  Result := False;

  ANuevoReciboProveedor := NIL;
  ImporteRestante := 0;

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

      //Si el importe ha cambiado se debe hacer un recibo nuevo con el importe restante
      if ImporteTotalModificado(ARecibosProveedor, ImporteRestante) then
      begin
        ANuevoReciboProveedor := Duplicar(ARecibosProveedor);
        ANuevoReciboProveedor.Edit;
        ANuevoReciboProveedor.REFERENCIA := DarNuevaReferencia(ARecibosProveedor.ID_FACTURA, ARecibosProveedor.REFERENCIA);
        ANuevoReciboProveedor.ID := FDataModule.GetNextID(ARecibosProveedor.DataTable.LogicalName);
        ANuevoReciboProveedor.IMPORTE := ImporteRestante;
        ANuevoReciboProveedor.DESCRIPCION := 'RECIBO ' + ANuevoReciboProveedor.REFERENCIA + ' - ' + CifraToLetras(ImporteRestante);
        ANuevoReciboProveedor.Post;
      end;

      //Primero debemos hacer el ApplyUpdates del recibo inicial por si fallase
      //Así no se haría el nuevo
      AsignarID(ARecibosProveedor, NuevoID);
      ARecibosProveedor.DataTable.ApplyUpdates;

      if Assigned(ANuevoReciboProveedor) then
         ANuevoReciboProveedor.DataTable.ApplyUpdates;

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

procedure TRecibosProveedorController.ModificarPago(ARecibosProveedor: IBizRecibosProveedor);
var
  AEditor : IEditorFechaPagoProveedor;
  FechaPago: String;
begin
  //Pedimos la fecha del pago
  CreateEditor('EditorFechaPagoProveedor', IEditorFechaPagoProveedor, AEditor);
  if Assigned(AEditor) then
    try
      FechaPago:= '';
      if (AEditor.ShowModal = mrOk) then
         FechaPago := DateToStr(AEditor.FechaPago);
      AEditor.Release;
    finally
      AEditor := NIL;
    end;

  if Length(FechaPago) > 0 then
     PagosController.Modificar(ARecibosProveedor.Pagos, FechaPago);
end;

function TRecibosProveedorController.Nuevo: IBizRecibosProveedor;
var
  ARecibo : IBizRecibosProveedor;
begin
  ARecibo := Buscar(ID_NULO);
  ARecibo.DataTable.Active := True;
  Anadir(ARecibo);
  Result := ARecibo;
end;

function TRecibosProveedorController.ExtraerSeleccionados(ARecibosProveedor: IBizRecibosProveedor): IBizRecibosProveedor;
var
  ASeleccionados : IBizRecibosProveedor;
begin
  ASeleccionados := (Self.Buscar(ID_NULO) as IBizRecibosProveedor);
  CopyDataTable(ARecibosProveedor.DataTable, ASeleccionados.DataTable, True);
  Result := ASeleccionados;
end;

procedure TRecibosProveedorController.Preview(ARecibosProveedor: IBizRecibosProveedor);
var
  AReportController : IRecibosProveedorReportController;
begin
  AReportController := TRecibosProveedorReportController.Create;
  try
    AReportController.Preview(ARecibosProveedor.ID);
  finally
    AReportController := NIL;
  end;
end;

procedure TRecibosProveedorController.Print(ARecibosProveedor: IBizRecibosProveedor);
var
  AReportController : IRecibosProveedorReportController;
begin
  AReportController := TRecibosProveedorReportController.Create;
  try
    AReportController.Print(ARecibosProveedor.ID);
  finally
    AReportController := NIL;
  end;
end;

procedure TRecibosProveedorController.QuitarReciboCompensado(ARecibo: IBizRecibosProveedor);
var
  IdRecibo: Variant;
begin
  IdRecibo := ARecibo.RecibosCompensados.ID;

  ARecibo.RecibosCompensados.DataTable.First;
  while ARecibo.RecibosCompensados.DataTable.Locate('ID', IdRecibo,[]) do
  begin
    ARecibo.RecibosCompensados.DataTable.Delete;
    ARecibo.RecibosCompensados.DataTable.First;
  end;
end;

procedure TRecibosProveedorController.QuitarRemesa(ARecibos: IBizRecibosProveedor);
begin
  if Assigned(ARecibos) then
  begin
    if ARecibos.Pagos.DataTable.RecordCount = 0 then
       Exit;

    //Eliminamos el cobro generado por la remesa y quitamos el ID_REMESA del recibo
    ARecibos.Pagos.DataTable.Last;
    ARecibos.Pagos.Delete;

    ARecibos.DataTable.Edit;
    ARecibos.ID_REMESA := 0;
    ARecibos.DataTable.Post;
  end;
end;

end.
