{
===============================================================================
  Copyright (©) 2001. 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: 11-08-2002
  Versión actual: 1.0.3
  Fecha versión actual: 12-10-2004
===============================================================================
  Modificaciones:

    Fecha         Comentarios
    ---------------------------------------------------------------------------
    16-11-2002    p250. Poner el número total de artículos dados de alta
                  en la inicialización del grid.

    14-04-2004    p272. Adaptación a multiempresa.

    12-10-2004    p290. Precio de coste de obra
===============================================================================
}

unit TablaArticulosObraHistorica;

interface

uses
  SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms,
  Dialogs, DBTables, DB, IBCustomDataSet, IBSQL, BaseDatos, IBDatabase,
  IBStoredProc, Mensajes, IB, cxGrid, Tipos,

  //TablaArticulos es usada por el Tipo TDatosArticulo, TDatosAlmacen, TDatosMovimiento
  TablaArticulos, TablaAlmacenes, TablaMovimientos;

type
  TDatosObraCerrada = class(TPersistent)
  public
    CodigoEmpresa : Integer;
    Codigo : Integer;
    FechaCierre : String;
    Nombre : String;
    Calle : String;
    Numero : String;
    Piso : String;
    CodigoPostal : String;
    Poblacion : String;
    Provincia : String;
    Telefono : String;
    PersonaContacto : String;
  end;

  TDatosMaterial = class(TPersistent)
  public
    CodigoObra : Integer;
    FechaCierre : String;
    CodigoArticulo : String;
    Familia : String;
    Descripcion : String;
    Unidadesmedida : String;
    Existencias : String;
    Observaciones : String;
  end;

  TdmTablaArticulosObraHistorica = class(TDataModule)
  private
    procedure IniciarSQL;
    function existeArticuloEnAlmacen(CodigoEmpresa: Integer; CodigoArticulo: String): Boolean;
  public
    sqlConsultar : TStrings;
    sqlEliminar : TStrings;
    sqlGrid : TStrings;
    sqlGridObrasCerradas : TStrings;

    constructor Create (AOwner : TComponent); override;
    destructor Destroy; override;

    function ValidarCodigo(Codigo : String) : Boolean;
    function FormatearCodigo(var Codigo : String) : String;
    function ExisteArticulo(CodigoEmpresa: Integer; Material : TDatosMaterial) : Boolean;
    function DarDatosObraCerrada(CodigoEmpresa: Integer; Codigo: Variant) : TDatosObraCerrada; overload;

    function DarDatosMaterial(CodigoEmpresa: Integer; var Datos: TDatosMaterial): Boolean;
    function ArticuloAlmacenTieneExistencias(CodigoEmpresa, CodigoAlmacen: Integer;
      CodigoArticulo: String): Boolean;

    function ExisteArticuloAlmacen(CodigoEmpresa, CodigoAlmacen: Integer;
      CodigoArticulo: String): Boolean;
    function DarDatosArticuloAlmacen(CodigoEmpresa: Integer; var Datos: TDatosArticulo): Boolean;
    function DarListaArticulos(Grid : TcxGrid; Tabla: TPTabla) : TStringList;

    function InsertarObraHistorica(CodigoEmpresa, CodigoAlmacen:Integer;
      Fecha: String): Boolean;
    function InsertarPresupuestosObraHistorica(CodigoEmpresa, CodigoAlmacen: Integer; Fecha: String): Boolean;
    function EliminarPresupuestosObra(CodigoEmpresa, CodigoAlmacen: Integer): Boolean;
    function InsertarArticulosObraHistorica(CodigoEmpresa, CodigoAlmacen: Integer; Fecha: String): Boolean;
    procedure InicializarTablaArticulosObraHistorica(Tabla : TPTabla);
    procedure InicializarGridArticulosObraHistorica(var Grid: TcxGrid);
    procedure InicializarGridObrasCerradas(var Grid: TcxGrid);

    function DarObras(CodigoEmpresa: Integer): TStringList;
    function DarArticuloMin(CodigoEmpresa: Integer; CodigoObra: Integer; FechaCierre: String): String;
    function DarArticuloMax(CodigoEmpresa: Integer; CodigoObra: Integer; FechaCierre: String): String;
  end;

var
  dmTablaArticulosObraHistorica: TdmTablaArticulosObraHistorica;

implementation
{$R *.DFM}

uses
  Excepciones, IBErrorCodes, RdxEmpresaActiva, Literales, DateFunc, StrFunc, Constantes,
  cxGridDBTableView, cxCustomData;

{ TdmTablaArticulosObraHistorica }

constructor TdmTablaArticulosObraHistorica.Create (AOwner : TComponent);
begin
  inherited;
  sqlConsultar := TStringList.Create;
  sqlEliminar := TStringList.Create;
  sqlGrid := TStringList.Create;
  sqlGridObrasCerradas := TStringList.Create;
  IniciarSQL;
end;

destructor TdmTablaArticulosObraHistorica.Destroy;
begin
  sqlConsultar.Free;
  sqlEliminar.Free;
  sqlGrid.Free;
  sqlGridObrasCerradas.Free;
  inherited;
end;

procedure TdmTablaArticulosObraHistorica.IniciarSQL;
begin
  with sqlConsultar do
  begin
    Add('select CODIGO, NOMBRE, OBRASHISTORICAS.FECHACIERRE, CODIGOARTICULO, ');
    Add('FAMILIA, DESCRIPCION, UNIDADESMEDIDA, OBSERVACIONES, EXISTENCIAS ');
    Add('from OBRASHISTORICAS, ESTADOOBRASHISTORICAS ');
    Add('where (OBRASHISTORICAS.CODIGO = :CODIGOOBRA) and ');
    Add('(OBRASHISTORICAS.FECHACIERRE = :FECHACIERRE) and ');
    Add('(OBRASHISTORICAS.CODIGOEMPRESA = :CODIGOEMPRESA) and ');
    Add('(ESTADOOBRASHISTORICAS.CODIGOOBRA = OBRASHISTORICAS.CODIGO) and ');
    Add('(ESTADOOBRASHISTORICAS.CODIGOEMPRESA = OBRASHISTORICAS.CODIGOEMPRESA) and ');
    Add('(ESTADOOBRASHISTORICAS.FECHACIERRE = OBRASHISTORICAS.FECHACIERRE) and ');
    Add('(ESTADOOBRASHISTORICAS.CODIGOARTICULO = :CODIGOARTICULO) ');
  end;

  with sqlEliminar do
  begin
    Add('delete from ESTADOOBRASHISTORICAS ');
    Add('where (CODIGOOBRA = :CODIGOOBRA) ');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    Add('and (FECHACIERRE = :FECHACIERRE) ');
    Add('and (CODIGOARTICULO = :CODIGOARTICULO) ');
  end;

  with sqlGrid do
  begin
    Add('select CODIGOOBRA, FECHACIERRE, CODIGOARTICULO, FAMILIA, DESCRIPCION, ');
    Add('UNIDADESMEDIDA, EXISTENCIAS, (PRECIORECEPCION * EXISTENCIAS) as TOTAL ');
    Add('from ESTADOOBRASHISTORICAS ');
    Add('where (CODIGOOBRA = :CODIGOOBRA) ');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    Add('and (FECHACIERRE = :FECHACIERRE) ');
    Add('order by DESCRIPCION');
  end;

  with sqlGridObrasCerradas do
  begin
    Add('select CODIGOEMPRESA, CODIGO as "ALMACENES.CODIGO", FECHACIERRE, NOMBRE as "ALMACENES.NOMBRE",');
    Add('TELEFONO, PERSONACONTACTO ');
    Add('from OBRASHISTORICAS ');
    Add('where (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    Add('order by NOMBRE');
  end;
end;

{ Tanto ExisteArticulosAlmacen como DarDatosArticuloAlmacen esta bien que
tengan su propia transaccion ya que se hace una consulta en un momento
determinado, sin dependencia de otras operaciones}

function TdmTablaArticulosObraHistorica.existeArticuloAlmacen(CodigoEmpresa,
  CodigoAlmacen: Integer; CodigoArticulo: String): Boolean;
{Comprueba si existe un articulo en un determinado almacen, pasandole por
 parametro el codigo de articulo y el del almacen, devuelve true o false
 dependiendo si existe o no}
var
  oSQL : TIBSQL;
  Codigo : String;
begin
  Result := False;
  if (Length(Trim(CodigoArticulo)) = 0) then
    Exit;

  oSQL := TIBSQL.Create(Self);

  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select CODIGOARTICULO ');
    SQL.Add('from ESTADOALMACEN ');
    SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) ');
    SQL.Add('and (CODIGOARTICULO = :CODIGOARTICULO) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGOALMACEN').AsInteger := CodigoAlmacen;
    ParamByName('CODIGOARTICULO').AsString := CodigoArticulo;
    try
      Prepare;
      ExecQuery;
      Codigo := FieldByName('CODIGOARTICULO').AsString;
      Result := (CodigoArticulo = Codigo);
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.existeArticuloEnAlmacen(CodigoEmpresa: Integer; CodigoArticulo: String): Boolean;
{Comprueba si existe un articulo en un determinado almacen, pasandole por
 parametro el codigo de articulo y el del almacen, devuelve true o false
 dependiendo si existe o no}
var
  oSQL : TIBSQL;
  Codigo : String;
begin
  Result := True;
  if (Length(Trim(CodigoArticulo)) = 0) then
    Exit;

  oSQL := TIBSQL.Create(Self);

  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select CODIGOARTICULO ');
    SQL.Add('from ESTADOALMACEN ');
    SQL.Add('where (CODIGOARTICULO = :CODIGOARTICULO) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGOARTICULO').AsString := CodigoArticulo;
    try
      Prepare;
      ExecQuery;

      if (RecordCount = 0) then
        Result := False;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.DarDatosArticuloAlmacen(CodigoEmpresa: Integer;
  var Datos: TDatosArticulo): Boolean;
{Devuelve los datos del articulo pasado por parametro si este existe en el
 almacen correspondiente, en caso de no existir devuelve false y rellena
 dichos datos con 0,0 y 1000 respectibamente}
var
  oSQL : TIBSQL;
begin
  Result := False;
  if (length(Datos.CodigoAlmacen)= 0) then
  begin
    //Para que cuando un articulo libre que no encuentra las existencias en
    //el almacen esten a cero
    Datos.Existencias := '0';
    Exit;
  end;

  oSQL := TIBSQL.Create(Self);

  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select * ');
    SQL.Add('from ESTADOALMACEN ');
    SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) ');
    SQL.Add('and (CODIGOARTICULO = :CODIGOARTICULO) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGOALMACEN').AsString := Datos.CodigoAlmacen;
    ParamByName('CODIGOARTICULO').AsString := Datos.Codigo;

    try
      Prepare;
      ExecQuery;

      if (RecordCount > 0) then
      begin
        Datos.Existencias := FieldByName('EXISTENCIAS').AsString;
        Datos.StockMin := FieldByName('STOCKMIN').AsString;
        Datos.StockMax := FieldByName('STOCKMAX').AsString;
        Result := True;
      end
      else
      begin
        Datos.Existencias := '0';
        Datos.StockMin := '0';
        Datos.StockMax := '1000';
      end;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

procedure TdmTablaArticulosObraHistorica.InicializarGridArticulosObraHistorica(var Grid: TcxGrid);
var
  Columna : TcxGridDBColumn;
begin
  with (Grid.ActiveView as TcxGridDBTableView) do
  begin
    ClearItems;
    OptionsView.Footer := True;
    {Columna CODIGOOBRA}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'CODIGOOBRA';
    Columna.Visible := false;
    {Columna CODIGOFECHACIERRE}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'FECHACIERRE';
    Columna.Visible := false;
    {Columna CODIGOARTICULO}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'CODIGOARTICULO';
    Columna.Caption := 'Código';
    Columna.Width := tamColCodigo;
    Columna.Summary.FooterKind := skCount;
    Columna.Summary.FooterFormat := 'Total: 0 artículos';
    {Columna FAMILIA}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'FAMILIA';
    Columna.Caption := 'Familia';
    Columna.Width := tamColFamilia;
    Columna.Visible := False;
    {Columna DESCRIPCION}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'DESCRIPCION';
    Columna.Caption := 'Descripción';
    Columna.Width := tamColDescripcion;
    {Columna UNIDADESMEDIDA}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'UNIDADESMEDIDA';
    Columna.Caption := 'Unidades de medida';
    Columna.Width := tamColNombreCorto;
    {Columna EXISTENCIAS}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'EXISTENCIAS';
    Columna.Caption := 'Existencias';
    Columna.Width := tamColCantidad;
    {Columna TOTAL}
{    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'TOTAL';
    Columna.Caption := 'Coste total';
    Columna.Width := tamColImporte;
    Columna.Summary.FooterKind := skSum;
    Columna.Summary.FooterFormat := 'Total: 0.00 €';
    {Columna PENDIENTESRECIBIR}
{    Columna := Add;
    Columna.Visible := True;
    Columna.DataBinding.FieldName := '';
    Columna.Title.Caption := 'U. pendientes recibir';}
  end;
end;

function TdmTablaArticulosObraHistorica.ArticuloAlmacenTieneExistencias(CodigoEmpresa,
  CodigoAlmacen: Integer; CodigoArticulo: String): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := True;
  if (length(CodigoArticulo)= 0) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select EXISTENCIAS ');
    SQL.Add('from ESTADOALMACEN ');
    SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) ');
    SQL.Add('and (CODIGOARTICULO = :CODIGOARTICULO) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGOALMACEN').AsInteger := CodigoAlmacen;
    ParamByName('CODIGOARTICULO').AsString := CodigoArticulo;

    try
      Prepare;
      ExecQuery;

      if (RecordCount > 0) and (FieldByName('EXISTENCIAS').AsString = '0') then
        Result := False;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.DarListaArticulos(Grid : TcxGrid; Tabla: TPTabla): TStringList;
var
  i: integer;
  ListaArticulos : TStringList;
begin
  ListaArticulos := Nil;

{  ¡¡¡ REVISAR !!!!!
  if Grid.SelectedCount = 0 then
  begin
    Result := ListaArticulos;
    exit
  end;

  ListaArticulos := TStringList.Create;
  Tabla^.DisableControls;
  for i:=0 to Grid.SelectedCount-1 do
  begin
    Tabla^.GotoBookmark(Pointer(Grid.SelectedRows[i]));
    ListaArticulos.Add(Tabla^.FieldByName('CODIGOARTICULO').AsString);
  end;
  Tabla^.EnableControls;}
  Result := ListaArticulos;
end;

function TdmTablaArticulosObraHistorica.DarObras(CodigoEmpresa: Integer) : TStringList;
var
  oSQL : TIBSQL;
  lcfCodigo : TTipoCodigoFecha;
  lsCadena : String;
  ListaAlmacenesCodigo : TStringList;

begin
  ListaAlmacenesCodigo := TStringList.Create;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select CODIGO, FECHACIERRE, NOMBRE from OBRASHISTORICAS');
    SQL.Add('where (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    SQL.Add('order by NOMBRE');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    try
      Prepare;
      ExecQuery;

      while not EOF do
      begin
        lcfCodigo := TTipoCodigoFecha.Create;
        lcfCodigo.Codigo := FieldByName('CODIGO').AsInteger;
        lcfCodigo.Fecha := FieldByName('FECHACIERRE').AsString;
        lcfCodigo.Nombre := FieldByName('NOMBRE').AsString;

        lsCadena := lcfCodigo.Nombre + ' ' + lcfCodigo.Fecha;
        ListaAlmacenesCodigo.AddObject(lsCadena, lcfCodigo);
        Next;
      end;
    finally
      Close;
      Transaction := NIL;
      Free;
      Result := ListaAlmacenesCodigo;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.InsertarObraHistorica(CodigoEmpresa,
  CodigoAlmacen: Integer; Fecha: String): Boolean;
var
  oSQL : TIBSQL;
  DatosAlmacen : TDatosAlmacen;
begin
  Result := False;

  DatosAlmacen := TDatosAlmacen.Create;
  DatosAlmacen.CodigoEmpresa := EmpresaActiva.Codigo;  
  DatosAlmacen.Codigo := CodigoAlmacen;
  if (dmTablaAlmacenes.DarDatosAlmacen(DatosAlmacen)) then
  begin
    oSQL := TIBSQL.Create(Self);
    with oSQL do
    begin
      Database := dmBaseDatos.BD;
      Transaction := dmBaseDatos.Transaccion;
      SQL.Add('insert into OBRASHISTORICAS (CODIGOEMPRESA, CODIGO, FECHACIERRE, NOMBRE, CALLE, ');
      SQL.Add('NUMERO, PISO, CODIGOPOSTAL, POBLACION, PROVINCIA, TELEFONO, PERSONACONTACTO) ');
      SQL.Add('values ');
      SQL.Add('(:CODIGOEMPRESA, :CODIGO, ');
      SQL.Add(':FECHACIERRE, ');
      SQL.Add(':NOMBRE, ');
      SQL.Add(':CALLE, ');
      SQL.Add(':NUMERO, ');
      SQL.Add(':PISO, ');
      SQL.Add(':CODIGOPOSTAL, ');
      SQL.Add(':POBLACION, ');
      SQL.Add(':PROVINCIA, ');
      SQL.Add(':TELEFONO, ');
      SQL.Add(':PERSONACONTACTO)');

    try
      ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
      ParamByName('CODIGO').AsInteger := DatosAlmacen.Codigo;
      ParamByName('FECHACIERRE').AsString := Fecha;
      ParamByName('NOMBRE').AsString := DatosAlmacen.Nombre;
      ParamByName('CALLE').AsString := DatosAlmacen.Calle;
      ParamByName('NUMERO').AsString := DatosAlmacen.Numero;
      ParamByName('PISO').AsString := DatosAlmacen.Piso;
      ParamByName('CODIGOPOSTAL').AsString := DatosAlmacen.CodigoPostal;
      ParamByName('POBLACION').AsString := DatosAlmacen.Poblacion;
      ParamByName('PROVINCIA').AsString := DatosAlmacen.Provincia;
      ParamByName('TELEFONO').AsString := DatosAlmacen.Telefono;
      ParamByName('PERSONACONTACTO').AsString := DatosAlmacen.PersonaContacto;
      Prepare;
      ExecQuery;
      Close;
      Transaction := NIL;
      Free;
      Result := True;
    except
      on E : EIBError do
      begin
        case E.IBErrorCode of
          isc_foreign_key : begin
                              VerMensaje(msgHisYaExisteObraHistorica);
                            end;
          else begin
            TratarExcepcion(E);
          end;
        end;
      end;
      on E : Exception do begin
        TratarExcepcion(E);
      end;
    end;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.InsertarArticulosObraHistorica(CodigoEmpresa,
  CodigoAlmacen: Integer; Fecha: String): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('insert into ESTADOOBRASHISTORICAS (CODIGOEMPRESA, CODIGOOBRA, FECHACIERRE, CODIGOARTICULO, ');
    SQL.Add('FAMILIA, DESCRIPCION, UNIDADESMEDIDA, EXISTENCIAS, FECHARECEPCION, PRECIORECEPCION) ');
    SQL.Add('select CODIGOEMPRESA, CODIGOALMACEN, ');
    // No se permite parametrizar antes del where
    SQL.Add('''' + DarFormatoInterbaseFecha(Fecha) + '''');
    SQL.Add(', CODIGOARTICULO, FAMILIA, DESCRIPCION, UNIDADESMEDIDA, EXISTENCIAS, FECHARECEPCION, PRECIORECEPCION ');
    SQL.Add('from ESTADOALMACEN, ARTICULOS ');
    SQL.Add('where (CODIGOALMACEN = :CODIGOALMACEN) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    SQL.Add('and (CODIGO = CODIGOARTICULO)');
    ParamByName('CODIGOALMACEN').AsInteger := CodigoAlmacen;
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;

    try
      Prepare;
      ExecQuery;
      Close;
      Transaction := NIL;
      Free;
      Result := True;
    except
      on E : EIBError do
      begin
        case E.IBErrorCode of
          isc_foreign_key : begin
                              VerMensaje(msgHisYaExisteObraHistorica);
                            end;
          else begin
            TratarExcepcion(E);
          end;
        end;
      end;
      on E : Exception do begin
        TratarExcepcion(E);
      end;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.DarDatosMaterial(CodigoEmpresa: Integer; var Datos: TDatosMaterial): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;

  if EsCadenaVacia(Datos.FechaCierre) and EsCadenaVacia(Datos.CodigoArticulo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select * from ESTADOOBRASHISTORICAS ');
    SQL.Add('where (CODIGOOBRA = :CODIGOOBRA) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    SQL.Add('and (FECHACIERRE = :FECHACIERRE) ');
    SQL.Add('and (CODIGOARTICULO = :CODIGOARTICULO)');
    ParamByName('CODIGOOBRA').AsInteger := Datos.CodigoObra;
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('FECHACIERRE').AsString := Datos.FechaCierre;
    ParamByName('CODIGOARTICULO').AsString := Datos.CodigoArticulo;

    try
      Prepare;
      ExecQuery;

      if (RecordCount > 0) then
      begin
        with Datos do
        begin
          Familia := FieldByName('FAMILIA').AsString;
          Descripcion := FieldByName('DESCRIPCION').AsString;
          Unidadesmedida := FieldByName('UNIDADESMEDIDA').AsString;
          Unidadesmedida := FieldByName('EXISTENCIAS').AsString;
          Observaciones := FieldByName('OBSERVACIONES').AsString;
          Result := True;
        end;
      end;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.ValidarCodigo(Codigo: String): Boolean;
begin
  Result := EsNumerico(Codigo);
end;

function TdmTablaArticulosObraHistorica.FormatearCodigo(var Codigo: String): String;
begin
  Codigo := StrPadLeft(Codigo, 10, '0');
  Result := Codigo;
end;

function TdmTablaArticulosObraHistorica.ExisteArticulo(CodigoEmpresa: Integer; Material: TDatosMaterial): Boolean;
var
  oSQL : TIBSQL;
  Codigo : String;
begin
  Result := False;

  if EsCadenaVacia(Material.CodigoObra)
  and EsCadenaVacia(Material.FechaCierre)
  and EsCadenaVacia(Material.CodigoArticulo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select CODIGOARTICULO ');
    SQL.Add('from ESTADOOBRASHISTORICAS ');
    SQL.Add('where CODIGOOBRA = :CODIGOOBRA ');
    SQL.Add('and FECHACIERRE = :FECHACIERRE ');
    SQL.Add('and CODIGOARTICULO = :CODIGOARTICULO ');
    SQL.Add('and CODIGOEMPRESA = :CODIGOEMPRESA ');

  try
    ParamByName('CODIGOOBRA').AsInteger := Material.CodigoObra;
    ParamByName('FECHACIERRE').AsString := Material.FechaCierre;
    ParamByName('CODIGOARTICULO').AsString := Material.CodigoArticulo;
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    Prepare;
    ExecQuery;

    Codigo := FieldByName('CODIGOARTICULO').AsString;
    Result := (Material.CodigoArticulo = Codigo);
  finally
    Close;
    Transaction := NIL;
    Free;
  end;
  end;
end;

function TdmTablaArticulosObraHistorica.DarArticuloMax(CodigoEmpresa: Integer; CodigoObra: Integer; FechaCierre: String): String;
var
  oSQL : TIBSQL;
begin
  Result := '';

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select max(DESCRIPCION) from ESTADOOBRASHISTORICAS ');
    SQL.Add('where CODIGOOBRA = :CODIGOOBRA ');
    SQL.Add('and FECHACIERRE = :FECHACIERRE ');
    SQL.Add('and CODIGOEMPRESA = :CODIGOEMPRESA ');

    try
      ParamByName('CODIGOOBRA').AsInteger := CodigoObra;
      ParamByName('FECHACIERRE').AsString := FechaCierre;
      ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
      Prepare;
      ExecQuery;
      Result := Fields[0].AsString;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.DarArticuloMin(CodigoEmpresa: Integer; CodigoObra: Integer; FechaCierre: String): String;
var
  oSQL : TIBSQL;
begin
  Result := '';

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select min(DESCRIPCION) from ESTADOOBRASHISTORICAS ');
    SQL.Add('where CODIGOOBRA = :CODIGOOBRA ');
    SQL.Add('and FECHACIERRE = :FECHACIERRE ');
    SQL.Add('and CODIGOEMPRESA = :CODIGOEMPRESA ');

    try
      ParamByName('CODIGOOBRA').AsInteger := CodigoObra;
      ParamByName('FECHACIERRE').AsString := FechaCierre;
      ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
      Prepare;
      ExecQuery;
      Result := Fields[0].AsString;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

procedure TdmTablaArticulosObraHistorica.InicializarTablaArticulosObraHistorica(
  Tabla: TPTabla);
begin
  with Tabla^.Fields do
  begin
    with (FieldByName('TOTAL') as TFloatField) do begin
      DisplayFormat := DISPLAY_EUROS2;
      EditFormat := EDIT_EUROS2;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.InsertarPresupuestosObraHistorica(
  CodigoEmpresa, CodigoAlmacen: Integer; Fecha: String): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('insert into OBRASHISTORICASPRESUPUESTOS (CODIGOEMPRESA, CODIGOALMACEN, FECHACIERRE, CODIGOPRESUPUESTO) ');
    SQL.Add('select CODIGOEMPRESA, CODIGOALMACEN, ');
    // No se permite parametrizar antes del where
    SQL.Add('''' + DarFormatoInterbaseFecha(Fecha) + '''');
    SQL.Add(', CODIGOPRESUPUESTO ');
    SQL.Add('from OBRASPRESUPUESTOS ');
    SQL.Add('where (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    SQL.Add('and (CODIGOALMACEN = :CODIGOALMACEN) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGOALMACEN').AsInteger := CodigoAlmacen;

    try
      Prepare;
      ExecQuery;
      Close;
      Transaction := NIL;
      Free;
      Result := True;
    except
      on E : EIBError do
      begin
        case E.IBErrorCode of
          isc_foreign_key : begin
                              VerMensaje(msgHisYaExisteObraHistorica);
                            end;
          else begin
            TratarExcepcion(E);
          end;
        end;
      end;
      on E : Exception do begin
        TratarExcepcion(E);
      end;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.EliminarPresupuestosObra(
  CodigoEmpresa, CodigoAlmacen: Integer): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('delete from OBRASPRESUPUESTOS ');
    SQL.Add('where (CODIGOEMPRESA = :CODIGOEMPRESA)');
    SQL.Add('and (CODIGOALMACEN = :CODIGOALMACEN) ');

    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGOALMACEN').AsInteger := CodigoAlmacen;

    try
      Prepare;
      ExecQuery;
      Close;
      Transaction := NIL;
      Free;
      Result := True;
    except
      on E : EIBError do
      begin
        case E.IBErrorCode of
          isc_foreign_key : begin
                              VerMensaje(msgHisYaExisteObraHistorica);
                            end;
          else begin
            TratarExcepcion(E);
          end;
        end;
      end;
      on E : Exception do begin
        TratarExcepcion(E);
      end;
    end;
  end;
end;

function TdmTablaArticulosObraHistorica.DarDatosObraCerrada(
  CodigoEmpresa: Integer; Codigo: Variant): TDatosObraCerrada;
var
  oSQL : TIBSQL;
  lDatos : TDatosObraCerrada;

begin
  Result := Nil;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select * ');
    SQL.Add('from OBRASHISTORICAS ');
    SQL.Add('where (CODIGO = :CODIGO) and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGO').AsInteger := Codigo;
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    try
      Prepare;
      ExecQuery;
      if (RecordCount > 0) then
      begin
        lDatos := TDatosObraCerrada.Create;
        lDatos.CodigoEmpresa := FieldByName('CODIGOEMPRESA').AsInteger;
        lDatos.Codigo := FieldByName('CODIGO').AsInteger;
        lDatos.FechaCierre := FieldByName('FECHACIERRE').AsString;
        lDatos.Nombre := FieldByName('NOMBRE').AsString;
        lDatos.Calle := FieldByName('CALLE').AsString;
        lDatos.Numero := FieldByName('NUMERO').AsString;
        lDatos.Piso := FieldByName('PISO').AsString;
        lDatos.CodigoPostal := FieldByName('CODIGOPOSTAL').AsString;
        lDatos.Poblacion := FieldByName('POBLACION').AsString;
        lDatos.Provincia := FieldByName('PROVINCIA').AsString;
        lDatos.Telefono := FieldByName('TELEFONO').AsString;
        lDatos.PersonaContacto := FieldByName('PERSONACONTACTO').AsString;
        Result := lDatos;
      end;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

procedure TdmTablaArticulosObraHistorica.InicializarGridObrasCerradas(
  var Grid: TcxGrid);
var
  Columna : TcxGridDBColumn;
begin
  with (Grid.ActiveView as TcxGridDBTableView) do
  begin
    ClearItems;
    OptionsView.Footer := True;
    GetColumnByFieldName('ALMACENES.PERSONACONTACTO').Visible := False;
    GetColumnByFieldName('CLIENTES.NOMBRE').Visible := False;

    {Columna CODIGOEMPRESA}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'CODIGOEMPRESA';
    Columna.Visible := False;
    {Columna CODIGOFECHACIERRE}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'FECHACIERRE';
    Columna.Visible := True;
  end;
end;

end.
