unit srvContabilidad_Impl;

{----------------------------------------------------------------------------}
{ This unit was automatically generated by the RemObjects SDK after reading  }
{ the RODL file associated with this project .                               }
{                                                                            }
{ This is where you are supposed to code the implementation of your objects. }
{----------------------------------------------------------------------------}

interface

uses
  {vcl:} Classes, SysUtils,
  {RemObjects:} uROClientIntf, uROTypes, uROServer, uROServerIntf, uROSessions,
  {Ancestor Implementation:} DataAbstractService_Impl,
  {Used RODLs:} DataAbstract4_Intf,
  {Generated:} FactuGES_Intf, uDADataTable, uDABINAdapter, uDAClasses,
  uDAScriptingProvider, uDABusinessProcessor, uDADataStreamer,
  uDABin2DataStreamer, uDAInterfaces;

const
  REFERENCIA_CLIENTES = 430;
  REFERENCIA_PROVEEDORES = 400;
  REFERENCIA_ACREEDORES = 410;  

type
  { TsrvContabilidad }
  TsrvContabilidad = class(TDataAbstractService, IsrvContabilidad)
    Diagrams: TDADiagrams;
    Bin2DataStreamer: TDABin2DataStreamer;
    bpEpigrafes: TDABusinessProcessor;
    bpCuentas: TDABusinessProcessor;
    bpSubCuentas: TDABusinessProcessor;
    bpApuntes: TDABusinessProcessor;
    bpAsientos: TDABusinessProcessor;
    schContabilidad: TDASchema;
    DataDictionary: TDADataDictionary;
    procedure DARemoteServiceCreate(Sender: TObject);
    procedure DataAbstractServiceBeforeAcquireConnection(aSender: TObject; var aConnectionName: string);
  private
    function DarEjercicioActivo(const ID_EMPRESA: Integer): Integer;

  public
    function TieneCuentaAsociada(const ID_CONTACTO: Integer; const ID_EMPRESA: Integer): Boolean;
    function AnadirSubCuentaCliente(const ID_CONTACTO: Integer; const ID_TIENDA: Integer; const ID_EMPRESA: Integer; const CLIENTE: String): Boolean;
    function AnadirSubCuentaProveedor(const ID_CONTACTO: Integer; const ES_ACREEDOR: Integer; const ID_EMPRESA: Integer; const PROVEEDOR: String): Boolean;
    function DarNumOrdenAsiento : Integer;
  end;

implementation

{$R *.dfm}
uses
  {Generated:} FactuGES_Invk, uROClasses, uDataModuleServer,
  uDatabaseUtils, srvEjercicios_Impl, Variants, uBizAsientosServer;

procedure Create_srvContabilidad(out anInstance : IUnknown);
begin
  anInstance := TsrvContabilidad.Create(NIL);
end;

{ srvContabilidad }
function TsrvContabilidad.AnadirSubCuentaCliente(const ID_CONTACTO, ID_TIENDA: Integer; const ID_EMPRESA: Integer; const CLIENTE: String): Boolean;
var
  AConn : IDAConnection;
  dsData: IDADataset;
  dsCommand: IDASQLCommand;

  RefSubCuenta: String;
  NumCuenta: Integer;
  RefTienda: String;
  NumTienda: Integer;
  IDCuenta: Integer;

begin
  Result := False;
  IDCuenta := 0;
  AConn := dmServer.ConnectionManager.NewConnection(dmServer.ConnectionManager.GetDefaultConnectionName);

  try
    try
      dsData := schContabilidad.NewDataset(AConn, 'DarCodigoContableTienda', ['ID_EMPRESA', 'ID_TIENDA'], [ID_EMPRESA, ID_TIENDA]);
      dsData.Active := True;

      if VarIsNull(dsData.FieldValues[0]) then
         NumTienda := 0
      else
         NumTienda := dsData.FieldValues[0];
      RefTienda :=  format('%.2d', [NumTienda]);

      dsData := NIL;
      dsData := schContabilidad.NewDataset(AConn, 'DarMaxRefSubCuentaCli', ['ID_EJERCICIO', 'REF_CUENTA', 'REF_TIENDA'], [darEjercicioActivo(ID_EMPRESA), REFERENCIA_CLIENTES, RefTienda]);
      dsData.Active := True;

      if VarIsNull(dsData.FieldValues[0]) then
         NumCuenta := 0
      else
         NumCuenta := dsData.FieldValues[0];

      Inc(NumCuenta);
      RefSubCuenta := format('%.5d', [NumCuenta]);
      RefSubCuenta := IntToStr(REFERENCIA_CLIENTES) + RefTienda + RefSubCuenta;

      dsData := NIL;
      dsData := schContabilidad.NewDataset(AConn, 'DarIDCuenta', ['ID_EJERCICIO', 'REFERENCIA'], [darEjercicioActivo(ID_EMPRESA), REFERENCIA_CLIENTES]);
      dsData.Active := True;

      if VarIsNull(dsData.FieldValues[0]) then
         IDCuenta := 0
      else
         IDCuenta := dsData.FieldValues[0];

      AConn.CommitTransaction;

    except
      RaiseError('Error al buscar nueva referencia para la subcuenta');
      AConn.RollbackTransaction;
    end;
  finally
    dsData := NIL;
  end;

  try
    try
      dsCommand := schContabilidad.NewCommand(AConn, 'AnadirSubCuenta');
      with dsCommand do
      begin
        ParamByName('REFERENCIA').AsString := RefSubCuenta;
        ParamByName('DESCRIPCION').AsString := 'Cuenta de cliente: ' + CLIENTE;
        ParamByName('ID_CUENTA').AsInteger := IDCuenta;
        ParamByName('ID_EJERCICIO').AsInteger := darEjercicioActivo(ID_EMPRESA);
        ParamByName('ID_CONTACTO').AsInteger := ID_CONTACTO;
      end;
      dsCommand.Execute;
      AConn.CommitTransaction;
      Result := True;
    except
      RaiseError('Error al crear la nueva subcuenta en tablas');
      AConn.RollbackTransaction;
    end;
  finally
    dsCommand := NIL;
  end;
end;

function TsrvContabilidad.AnadirSubCuentaProveedor(const ID_CONTACTO, ES_ACREEDOR: Integer; const ID_EMPRESA: Integer; const PROVEEDOR: String): Boolean;
var
  AConn : IDAConnection;
  dsData: IDADataset;
  dsCommand: IDASQLCommand;

  RefSubCuenta: String;
  NumCuenta: Integer;
  IDCuenta: Integer;

begin
  Result := False;
  IDCuenta := 0;
  AConn := dmServer.ConnectionManager.NewConnection(dmServer.ConnectionManager.GetDefaultConnectionName);

  try
    try
      dsData := NIL;
      if ES_ACREEDOR = 1 then
         dsData := schContabilidad.NewDataset(AConn, 'DarMaxRefSubCuentaProv', ['ID_EJERCICIO', 'REF_CUENTA'], [darEjercicioActivo(ID_EMPRESA), REFERENCIA_ACREEDORES])
      else
         dsData := schContabilidad.NewDataset(AConn, 'DarMaxRefSubCuentaProv', ['ID_EJERCICIO', 'REF_CUENTA'], [darEjercicioActivo(ID_EMPRESA), REFERENCIA_PROVEEDORES]);

      dsData.Active := True;

      if VarIsNull(dsData.FieldValues[0]) then
         NumCuenta := 0
      else
         NumCuenta := dsData.FieldValues[0];
      Inc(NumCuenta);
      RefSubCuenta := format('%.7d', [NumCuenta]);

      if ES_ACREEDOR = 1 then
         RefSubCuenta := IntToStr(REFERENCIA_ACREEDORES) + RefSubCuenta
      else
         RefSubCuenta := IntToStr(REFERENCIA_PROVEEDORES) + RefSubCuenta;

      dsData := NIL;

      if ES_ACREEDOR = 1 then
         dsData := schContabilidad.NewDataset(AConn, 'DarIDCuenta', ['ID_EJERCICIO', 'REFERENCIA'], [darEjercicioActivo(ID_EMPRESA), REFERENCIA_ACREEDORES])
      else
         dsData := schContabilidad.NewDataset(AConn, 'DarIDCuenta', ['ID_EJERCICIO', 'REFERENCIA'], [darEjercicioActivo(ID_EMPRESA), REFERENCIA_PROVEEDORES]);
      dsData.Active := True;

      if VarIsNull(dsData.FieldValues[0]) then
         IDCuenta := 0
      else
         IDCuenta := dsData.FieldValues[0];

      AConn.CommitTransaction;

    except
      RaiseError('Error al buscar nueva referencia para la subcuenta');
      AConn.RollbackTransaction;
    end;
  finally
    dsData := NIL;
  end;

  try
    try
      dsCommand := schContabilidad.NewCommand(AConn, 'AnadirSubCuenta');
      with dsCommand do
      begin
        ParamByName('REFERENCIA').AsString := RefSubCuenta;
        ParamByName('DESCRIPCION').AsString := 'Cuenta de proveedor ' + PROVEEDOR;
        ParamByName('ID_CUENTA').AsInteger := IDCuenta;
        ParamByName('ID_EJERCICIO').AsInteger := darEjercicioActivo(ID_EMPRESA);
        ParamByName('ID_CONTACTO').AsInteger := ID_CONTACTO;
      end;
      dsCommand.Execute;
      AConn.CommitTransaction;
      Result := True;
    except
      RaiseError('Error al crear la nueva subcuenta en tablas');
      AConn.RollbackTransaction;
    end;
  finally
    dsCommand := NIL;
  end;
end;

function TsrvContabilidad.DarEjercicioActivo(const ID_EMPRESA: Integer): Integer;
var
  AEjerciciosService : IsrvEjercicios;
  Intf : IInterface;
  AClientID : TGUID;
begin
  CreateGUID(AClientID);

  GetClassFactory('srvEjercicios').CreateInstance(AClientID, Intf);
  AEjerciciosService := Intf as IsrvEjercicios;
  Result := AEjerciciosService.darEjercicioActivo(ID_EMPRESA)
end;

procedure TsrvContabilidad.DARemoteServiceCreate(Sender: TObject);
begin
  SessionManager := dmServer.SessionManager;
  bpAsientos.BusinessRulesID := BIZ_SERVER_ASIENTOS;  
end;

function TsrvContabilidad.DarNumOrdenAsiento: Integer;
var
  AConn : IDAConnection;
  dsData: IDADataset;
begin
  AConn := dmServer.ConnectionManager.NewConnection(dmServer.ConnectionManager.GetDefaultConnectionName);

  try
    dsData := schContabilidad.NewDataset(AConn, 'DarNumOrdenAsiento');
    dsData.Active := True;
    Result := dsData.FieldValues[0];
  finally
    AConn.RollbackTransaction;
    dsData := NIL;
  end;
end;

procedure TsrvContabilidad.DataAbstractServiceBeforeAcquireConnection(
  aSender: TObject; var aConnectionName: string);
begin
  ConnectionName := dmServer.ConnectionName;
end;

function TsrvContabilidad.TieneCuentaAsociada(const ID_CONTACTO: Integer; const ID_EMPRESA: Integer): Boolean;
var
  AConn : IDAConnection;
  dsData: IDADataset;
  AWhere : TDAWhereExpression;

begin
  Result := False;

  AConn := dmServer.ConnectionManager.NewConnection(dmServer.ConnectionManager.GetDefaultConnectionName);
  { Construir la expresión del Where a partir de los parámetros
    que se han recibido.
  }
  with TDAWhereBuilder.Create do
    try
      AWhere := NewBinaryExpression(NewField('', 'ID_EJERCICIO'), NewConstant(darEjercicioActivo(ID_EMPRESA), datInteger), dboEqual);
    finally
      Free;
    end;

  try
    try
      dsData := schContabilidad.NewDataset(AConn, 'ExisteSubCuenta', ['ID_CONTACTO'], [ID_CONTACTO]);
      dsData.DynamicWhere.Expression := AWhere;

      dsData.Active := True;
      Result := (dsData.FieldValues[0] > 0);
      AConn.CommitTransaction;

    except
      RaiseError('Error al buscar subcuentas del contacto');
      AConn.RollbackTransaction;
    end;
  finally
    dsData := NIL;
  end;
end;

initialization
  TROClassFactory.Create('srvContabilidad', Create_srvContabilidad, TsrvContabilidad_Invoker);

finalization

end.
