unit uBizDiario;

interface

uses
  uDAInterfaces, uDADataTable, schContabilidadClient_Intf, uBizApuntes;

const
  BIZ_CLIENT_Diario = 'Client.Diario';
  BIZ_CLIENT_EXTRACTOMOVIMIENTO = 'Client.ExtractoMovimiento';

type
  IBizDiario = interface(IDiario)
  ['{E2924908-0B5A-43DD-B03E-672F592FA19B}']
  end;

  IBizExtractoMovimiento = interface(IBizDiario)
  ['{3875CC17-B845-430F-B537-4733C26956D0}']
  end;

  TBizDiario = class(TDiarioDataTableRules, IBizDiario)
  end;

  TBizExtractoMovimiento = class(TBizDiario, IBizExtractoMovimiento)
  private
    FSumaAcumulada: Currency;
    procedure recalcular(const DesdeFinal: Boolean);
    procedure CalcularSaldo;

  protected
    procedure AfterDelete(Sender: TDADataTable); override;
    procedure AfterPost(Sender: TDADataTable); override;
    procedure AfterOpen(Sender: TDADataTable); override;

  public
    constructor Create(aDataTable: TDADataTable); override;

  end;

implementation
{ TBizDiario }


{ TBizExtractoMovimiento }

procedure TBizExtractoMovimiento.AfterDelete(Sender: TDADataTable);
begin
  recalcular(False);
end;

procedure TBizExtractoMovimiento.AfterOpen(Sender: TDADataTable);
begin
  recalcular(True);
end;

procedure TBizExtractoMovimiento.AfterPost(Sender: TDADataTable);
{var
  i, x: Integer;
}
begin
  //Comprobamos los cambios para solo recalcular en el caso de modificar el importe
  //y añadir un asiento nuevo
{  for i:=0 to DataTable.Delta.count-1 do
      if (DataTable.Delta.Changes[i].ChangeType = ctInsert) then
      begin
         //Este evento salta dos veces, cuando se hace el post en el cliente
         //y cuando se hace el applyupdates. En el primer caso todavía no se
         //ha asignado el codigo, de esta forma omitiremos el recalculo y
         //optimizamos el número de llamadas al mismo
         if CODIGO > 0 then recalcular(False);
      end
      else if (DataTable.Delta.Changes[i].ChangeType = ctUpdate) then
         if (DataTable.Delta.Changes[i].OldValueByName[fld_AsientosIMPORTE] <> DataTable.Delta.Changes[i].NewValueByName[fld_AsientosIMPORTE]) then
            recalcular(False);
}            
end;

procedure TBizExtractoMovimiento.CalcularSaldo;
var
  varImportePos: double;
  ABookmark: Pointer;

begin
  ABookmark := NIL;
  DataTable.DisableControls;
  DataTable.DisableEventHandlers;

  try
    ABookmark := DataTable.GetBookMark;
    DataTable.Next;
    //Comprobamos si calculamos desde el principio o desde un asiento intermedio
    if DataTable.EOF
    then
      varImportePos:=  FSumaAcumulada
    else
    begin
      varImportePos:= SALDO;
      DataTable.Prior;
    end;

    while not Self.DataTable.BOF do
    begin
      DataTable.edit;
      SALDO := varImportePos + DEBE - HABER;
      varImportePos := SALDO;
      DataTable.Post;
      DataTable.Prior;
    end;
  finally
    DataTable.GotoBookmark(Abookmark);
    DataTable.FreeBookmark(ABookmark);
    DataTable.EnableControls;
    DataTable.EnableEventHandlers;
  end;
end;

constructor TBizExtractoMovimiento.Create(aDataTable: TDADataTable);
begin
  inherited;
  FSumaAcumulada := 0;
end;

procedure TBizExtractoMovimiento.recalcular(const DesdeFinal: Boolean);
begin
  if DesdeFinal then
  begin
     FSumaAcumulada := 0; //Inicializamos la suma acumulada
     DataTable.Last;
  end
  else
  begin
{
     DataTable.Sort([fld_DiarioFECHA_ASIENTO, fld_DiarioORDEN_ASIENTO],[sdDescending, sdDescending]);

     //En el caso de ser un CIERRE NUEVO el asiento introducido punteamos "localmente"
     //todos los asientos anteriores al cierre y luego mandamos al servidor puntear en BD
     if TIPOASIENTO = CTE_CIERRE then
     begin
        puntearAsientos(CTE_PUNTEADO);
        dmAsientos.AsignarPunteado(Cuenta.CODIGO, FECHAASIENTO, Cuenta.PENULTIMOCIERRE, CTE_PUNTEADO);
     end;
}     
  end;

  CalcularSaldo;
end;

initialization
  RegisterDataTableRules(BIZ_CLIENT_Diario, TBizDiario);
  RegisterDataTableRules(BIZ_CLIENT_EXTRACTOMOVIMIENTO, TBizExtractoMovimiento);

finalization

end.


