{
===============================================================================
  Copyright (©) 2002. 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: 01-12-2002
  Versión actual: 1.0.1
  Fecha versión actual: 02-02-2004
===============================================================================
  Modificaciones:

    Fecha         Comentarios
    ---------------------------------------------------------------------------
    02-02-2004    Se ha adaptado a los nuevos contadores
===============================================================================
}

unit TablaArticulos;

interface

uses
  //Generales
  SysUtils, Classes, Controls, IBSQL, cxGridDBTableView, cxCustomData, DB, IBCustomDataSet,
  //Particulares
  TablaPropiedadesArticulo, TablaPropiedades,

  //Aplicacion
  Framework, StrFunc, Entidades, Constantes, BaseDatos,

  // Contador
  Contadores, RdxGestorContadores;

type
  TDatosArticuloModelo = class(TObjeto)
  private
    FListaPropiedades : TListaPropiedades;
  protected
    procedure ObtenerDatos; override;
    procedure AssignTo(Dest: TPersistent); override;
  public
    Codigo : String;
    Familia : Variant;
    Descripcion : String;
    constructor Create(Familia : Integer); overload;
    constructor Create(Codigo : String); overload; virtual;
    constructor Create; overload; override;
    destructor Destroy; override;
    property ListaPropiedades : TListaPropiedades read FListaPropiedades;
  end;

  TDatosArticulo = class(TDatosArticuloModelo)
  protected
    procedure ObtenerDatos; override;
  public
    Referencia : String;
    Precio : double;
    constructor Create(Codigo : String); overload; override;
  end;

/////////////////////////////////////////////////////////////////////////////////

type
  TdmTablaArticulos = class(TDataModule)
  private
    FArtModelo : TRdxEntidad;
    procedure IniciarSQL;
  public
    sqlInsertar : TStrings;
    sqlModificar : TStrings;
    sqlConsultar : TStrings;
    sqlEliminar : TStrings;
    sqlGrid : TStrings;

    sqlInsertarArtModelo : TStrings;
    sqlModificarArtModelo : TStrings;
    sqlConsultarArtModelo : TStrings;
    sqlEliminarArtModelo : TStrings;
    sqlGridArtModelo : TStrings;

    //Metodos que llamaran a contador de articulo y articulo modelo dependiendo de
    //la propiedad FArtModelo
    function DarNuevoCodigo : String;
    function InsertarContador : boolean;
    function IncrementarCodigo : boolean;
    function ValidarCodigo(Codigo : String) : Boolean;
    function FormatearCodigo(Codigo : String) : String;

    function ExisteCodigo(CodigoArticulo : String) : Boolean;
    function ExisteCodigoArt(CodigoArticulo : String) : Boolean;
    function ExisteCodigoArtModelo(CodigoArticulo : String) : Boolean;

    function ExisteReferencia(ReferenciaArticulo : String) : Boolean;
    function DarCodigoArt(ReferenciaArticulo : String; var CodigoArticulo : String) : Boolean;

    function DarDatosArticulo(var Datos: TDatosArticulo): Boolean;
    function DarDatosArticuloArt(var Datos: TDatosArticulo): Boolean;
    function DarDatosArticuloArtModelo(var Datos: TDatosArticulo): Boolean;

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

    procedure InicializarGridArticulos(var vGrid: TcxGridDBTableView);
    procedure InicializarTablaArticulos(Tabla: TPTabla);

    property ArtModelo : TRdxEntidad read FArtModelo write FArtModelo;
  end;

var
  dmTablaArticulos: TdmTablaArticulos;

implementation
{$R *.DFM}

uses
  Mensajes, Literales, cxGridCustomTableView, cxCalc;

constructor TdmTablaArticulos.Create (AOwner : TComponent);
begin
  inherited;
  sqlInsertar := TStringList.Create;
  sqlModificar := TStringList.Create;
  sqlConsultar := TStringList.Create;
  sqlEliminar := TStringList.Create;
  sqlGrid := TStringList.Create;
  sqlInsertarArtModelo  := TStringList.Create;
  sqlModificarArtModelo  := TStringList.Create;
  sqlConsultarArtModelo  := TStringList.Create;
  sqlEliminarArtModelo  := TStringList.Create;
  sqlGridArtModelo  := TStringList.Create;
  IniciarSQL;

  FArtModelo := entArticuloModelo;
end;

destructor TdmTablaArticulos.Destroy;
begin
  sqlInsertar.Free;
  sqlModificar.Free;
  sqlConsultar.Free;
  sqlEliminar.Free;
  sqlGrid.Free;

  sqlInsertarArtModelo.Free;
  sqlModificarArtModelo.Free;
  sqlConsultarArtModelo.Free;
  sqlEliminarArtModelo.Free;
  sqlGridArtModelo.Free;
  inherited;
end;

procedure TdmTablaArticulos.IniciarSQL;
begin
  //Articulos
  with sqlInsertar do
  begin
    Add('insert into ARTICULOS (');
    Add('CODIGO, FECHAALTA, USUARIO, FAMILIA, DESCRIPCION, PRECIO, REFERENCIA) ');
    Add('values (:CODIGO, :FECHAALTA, :USUARIO, :FAMILIA, :DESCRIPCION, :PRECIO, :REFERENCIA)');
  end;

  with sqlModificar do
  begin
    Add('update ARTICULOS set ');
    Add('FAMILIA = :FAMILIA, ');
    Add('DESCRIPCION = :DESCRIPCION, ');
    Add('REFERENCIA = :REFERENCIA, ');
    Add('PRECIO = :PRECIO ');
    Add('where (CODIGO = :CODIGO)');
  end;

  with sqlEliminar do
  begin
    Add('delete from ARTICULOS ');
    Add('where CODIGO = :CODIGO');
  end;

  with sqlConsultar do
  begin
    Add('select * from ARTICULOS ');
    Add('where CODIGO = :CODIGO');
  end;

  with sqlGrid do
  begin
    Add('select ARTICULOS.CODIGO, FAMILIAS.DESCRIPCION as FAMILIA, ARTICULOS.DESCRIPCION, ARTICULOS.PRECIO, ARTICULOS.REFERENCIA ');
    Add('from ARTICULOS, FAMILIAS ');
    Add('where FAMILIAS.CODIGO = ARTICULOS.FAMILIA ');
    Add('order by ARTICULOS.DESCRIPCION');
  end;

  //Articulos Modelo
  with sqlInsertarArtModelo do
  begin
    Add('insert into ARTICULOSMODELO (');
    Add('CODIGO, FECHAALTA, USUARIO, FAMILIA, DESCRIPCION) ');
    Add('values (:CODIGO, :FECHAALTA, :USUARIO, :FAMILIA, :DESCRIPCION)');
  end;

  with sqlModificarArtModelo do
  begin
    Add('update ARTICULOSMODELO set ');
    Add('FAMILIA = :FAMILIA, ');
    Add('DESCRIPCION = :DESCRIPCION ');
    Add('where (CODIGO = :CODIGO)');
  end;

  with sqlEliminarArtModelo do
  begin
    Add('delete from ARTICULOSMODELO ');
    Add('where CODIGO = :CODIGO');
  end;

  with sqlConsultarArtModelo do
  begin
    Add('select * from ARTICULOSMODELO ');
    Add('where CODIGO = :CODIGO');
  end;

  with sqlGridArtModelo do
  begin
    Add('select CODIGO, FAMILIA, DESCRIPCION ');
    Add('from ARTICULOSMODELO ');
    Add('order by DESCRIPCION');
  end;
end;

function TdmTablaArticulos.darNuevoCodigo : String;
begin
  case FArtModelo of
    entArticulo: Result := GestorContadores.darNuevoCodigo(contArticulos);
    entArticuloModelo: Result := GestorContadores.darNuevoCodigo(contArticulosModelo);
    else Result := GestorContadores.darNuevoCodigo(contArticulos);
  end;
end;

function TdmTablaArticulos.IncrementarCodigo: boolean;
begin
  case FArtModelo of
    entArticulo: Result := GestorContadores.IncrementarValor(contArticulos);
    entArticuloModelo: Result := GestorContadores.IncrementarValor(contArticulosModelo);
    else Result := GestorContadores.IncrementarValor(contArticulos);
  end;
end;

function TdmTablaArticulos.validarCodigo(Codigo : String) : Boolean;
begin
  case FArtModelo of
    entArticulo: Result := GestorContadores.ValidarCodigo(contArticulos, Codigo);
    entArticuloModelo: Result := GestorContadores.ValidarCodigo(contArticulosModelo, Codigo);
    else Result := GestorContadores.ValidarCodigo(contArticulos, Codigo);
  end;
end;

function TdmTablaArticulos.formatearCodigo(Codigo : String) : String;
begin
  case FArtModelo of
    entArticulo: Result := GestorContadores.formatearCodigo(contArticulos, Codigo);
    entArticuloModelo: Result := GestorContadores.formatearCodigo(contArticulosModelo, Codigo);
    else Result := GestorContadores.formatearCodigo(contArticulos, Codigo);
  end;
end;

function TdmTablaArticulos.insertarContador: boolean;
begin
  case FArtModelo of
    entArticulo: Result := GestorContadores.InsertarContador(contArticulos);
    entArticuloModelo: Result := GestorContadores.InsertarContador(contArticulosModelo);
    else Result := GestorContadores.InsertarContador(contArticulos);
  end;
end;

function TdmTablaArticulos.ExisteCodigoArt(CodigoArticulo: String): Boolean;
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 CODIGO ');
    SQL.Add('from ARTICULOS ');
    SQL.Add('where CODIGO = :CODIGO ');

    try
      ParamByName('CODIGO').AsString := CodigoArticulo;
      Prepare;
      ExecQuery;

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

function TdmTablaArticulos.DarDatosArticuloArt(var Datos: TDatosArticulo): Boolean;
var
  oSQL : TIBSQL;

begin
  Result := False;

  if EsCadenaVacia(Datos.Codigo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select * from ARTICULOS ');
    SQL.Add('where CODIGO = :CODIGO');

    try
      ParamByName('CODIGO').AsString := Datos.Codigo;
      Prepare;
      ExecQuery;

      if (RecordCount > 0) then
      begin
        with Datos do
        begin
          Familia := FieldByName('FAMILIA').AsVariant;
          Descripcion := FieldByName('DESCRIPCION').AsString;

          SQL.Clear;
          SQL.Add('select * from PROPIEDADESARTICULOS ');
          SQL.Add('where CODIGOARTICULO = :CODIGO');

          ParamByName('CODIGO').AsString := Datos.Codigo;
          Prepare;
          ExecQuery;
          if (RecordCount = 0) then
          begin
            verMensaje('No tiene propiedades');
          end
          else
          begin
            verMensaje('Tiene propiedades');
          end;

          Result := True;
        end;
      end;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

procedure TdmTablaArticulos.InicializarGridArticulos(var vGrid: TcxGridDBTableView);
var
  Columna : TcxGridDBColumn;
begin
  with vGrid do begin
    ClearItems;

    OptionsView.Footer := True;

    {Columna CODIGO}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'CODIGO';
    Columna.Caption := 'Código';
    Columna.Width := tamColCodigo;
    Columna.Options.Filtering := False;

    with TcxGridDBTableSummaryItem(DataController.Summary.FooterSummaryItems.Add) do
    try
      try
        BeginUpdate;
        Column := Columna;
        FieldName := Columna.DataBinding.FieldName;
        Format := 'Total: 0 artículos';
        Kind := skCount;
      finally
        EndUpdate;
      end;
    except
      DataController.Summary.FooterSummaryItems.Delete(DataController.Summary.FooterSummaryItems.Count-1);
    end;

    {Columna REFERENCIA}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'REFERENCIA';
    Columna.Caption := 'Referencia';
    Columna.Width := tamColReferencia;
    Columna.Options.Filtering := False;
    
    {Columna FAMILIA}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'FAMILIA';
    Columna.Caption := 'Familia';
    Columna.Width := tamColFamilia;
    Columna.Options.Filtering := False;
    {Columna DESCRIPCION}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'DESCRIPCION';
    Columna.Caption := 'Descripción';
    Columna.Width := tamColNombre;
    Columna.Options.Filtering := False;
    Columna.SortOrder := soAscending;
    {Columna PRECIO}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'PRECIO';
    Columna.Caption := 'Precio';
    Columna.Width := tamColImporte;
    Columna.Options.Filtering := False;
    Columna.PropertiesClassName := 'TcxCalcEditProperties';
    with TcxCalcEditProperties(Columna.Properties) do
      DisplayFormat := DISPLAY_EUROS2;
      
    Columna.HeaderAlignmentHorz := taRightJustify;
  end;
end;

{ TDatosArticuloModelo }

constructor TDatosArticuloModelo.Create(Codigo: String);
begin
  inherited Create;
  Self.Codigo := Codigo;
  // Recuperar los datos del artículo
  ObtenerDatos;
  // Recuperar la lista de propiedades del artículo
  FListaPropiedades := TListaPropiedadesArtModelo.Create(Codigo);
end;

constructor TDatosArticuloModelo.Create(Familia : Integer);
begin
  inherited Create;
  Self.Familia := Familia;
  // Recuperar los datos del artículo
  ObtenerDatos;
  // Recuperar la lista de propiedades del artículo
  FListaPropiedades := TListaPropiedadesArtModelo.Create(Codigo);
end;

procedure TDatosArticuloModelo.AssignTo(Dest: TPersistent);
begin
  if not (Dest is TDatosArticulo) then
    AssignError(Dest);
  (Dest as TDatosArticulo).Codigo := Codigo;
  (Dest as TDatosArticulo).Descripcion := Descripcion;
  (Dest as TDatosArticulo).Familia := Familia;
  (Dest as TDatosArticulo).ListaPropiedades.Assign(ListaPropiedades);
end;

constructor TDatosArticuloModelo.Create;
begin
  inherited Create;
  Codigo := '';
  FListaPropiedades := TListaPropiedadesArtModelo.Create;
end;

destructor TDatosArticuloModelo.Destroy;
begin
  FListaPropiedades.Free;
  FListaPropiedades := NIL;
  inherited;
end;

procedure TDatosArticuloModelo.ObtenerDatos;
var
  oSQL : TIBSQL;
begin
  if EsCadenaVacia(Codigo) and EsCadenaVacia(Familia) then
    raise Exception.Create(msgDatosCodArtNoExiste);

  oSQL := TIBSQL.Create(nil);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select * from ARTICULOSMODELO ');
    if not EsCadenaVacia(Codigo) then begin
      SQL.Add('where CODIGO = :CODIGO');
      ParamByName('CODIGO').AsString := Codigo;
    end
    else begin
      SQL.Add('where FAMILIA = :FAMILIA');
      ParamByName('FAMILIA').AsInteger := Familia;
    end;

    try
      Prepare;
      ExecQuery;

      if (RecordCount > 0) then
      begin
        Codigo := FieldByName('CODIGO').AsString;
        Familia := FieldByName('FAMILIA').AsVariant;
        Descripcion := FieldByName('DESCRIPCION').AsString;
      end
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

{ TDatosArticulo }

constructor TDatosArticulo.Create(Codigo: String);
begin
  inherited Create;
  Self.Codigo := Codigo;
  // Recuperar los datos del artículo
  ObtenerDatos;
  // Recuperar la lista de propiedades del artículo
  FListaPropiedades := TListaPropiedadesArticulo.Create(Codigo);
end;

procedure TDatosArticulo.ObtenerDatos;
var
  oSQL : TIBSQL;
begin
  if EsCadenaVacia(Codigo) then
    raise Exception.Create(msgDatosCodArtNoExiste);

  oSQL := TIBSQL.Create(nil);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select * from ARTICULOS ');
    SQL.Add('where CODIGO = :CODIGO');

    try
      ParamByName('CODIGO').AsString := Codigo;
      Prepare;
      ExecQuery;

      if (RecordCount > 0) then
      begin
        Referencia := FieldByName('REFERENCIA').AsString;
        Familia := FieldByName('FAMILIA').AsVariant;
        Descripcion := FieldByName('DESCRIPCION').AsString;
        Precio := FieldByName('PRECIO').AsDouble;
      end
      else begin
        raise Exception.CreateFmt(msgDatosNoExisteArt, [Codigo]);
      end;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaArticulos.DarDatosArticuloArtModelo(var Datos: TDatosArticulo): Boolean;
var
  oSQL : TIBSQL;

begin
  Result := False;

  if EsCadenaVacia(Datos.Codigo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select * from ARTICULOSMODELO ');
    SQL.Add('where CODIGO = :CODIGO');

    try
      ParamByName('CODIGO').AsString := Datos.Codigo;
      Prepare;
      ExecQuery;

      if (RecordCount > 0) then
      begin
        with Datos do
        begin
          Familia := FieldByName('FAMILIA').AsVariant;
          Descripcion := FieldByName('DESCRIPCION').AsString;

          SQL.Clear;
          SQL.Add('select * from PROPIEDADESARTICULOSMODELO ');
          SQL.Add('where CODIGOARTICULO = :CODIGO');

          ParamByName('CODIGO').AsString := Datos.Codigo;
          Prepare;
          ExecQuery;
          if (RecordCount = 0) then
          begin
            verMensaje('No tiene propiedades');
          end
          else
          begin
            verMensaje('Tiene propiedades');
          end;

          Result := True;
        end;
      end;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaArticulos.ExisteCodigoArtModelo(CodigoArticulo: String): Boolean;
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 CODIGO ');
    SQL.Add('from ARTICULOSMODELO ');
    SQL.Add('where CODIGO = :CODIGO ');

  try
    ParamByName('CODIGO').AsString := CodigoArticulo;
    Prepare;
    ExecQuery;

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

function TdmTablaArticulos.ExisteCodigo(CodigoArticulo: String): Boolean;
begin
  case FArtModelo of
    entArticulo: Result := ExisteCodigoArt(CodigoArticulo);
    entArticuloModelo: Result := ExisteCodigoArtModelo(CodigoArticulo);
  end;
end;

function TdmTablaArticulos.DarDatosArticulo(var Datos: TDatosArticulo): Boolean;
begin
  case FArtModelo of
    entArticulo: Result := DarDatosArticuloArt(Datos);
    entArticuloModelo: Result := DarDatosArticuloArtModelo(Datos);
  end;
end;


procedure TdmTablaArticulos.InicializarTablaArticulos(Tabla: TPTabla);
begin
  with Tabla^.Fields do
  begin
    if FindField('PRECIO') <> NIL then
      with (FieldByName('PRECIO') as TIBBCDField) do begin
        DisplayFormat := DISPLAY_EUROS2;
        EditFormat := EDIT_EUROS2;
      end;
  end;
end;

function TdmTablaArticulos.ExisteReferencia(
  ReferenciaArticulo: String): Boolean;
var
  oSQL : TIBSQL;
  Referencia : String;
begin
  Result := False;

  if Length(Trim(ReferenciaArticulo)) = 0 then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select CODIGO ');
    SQL.Add('from ARTICULOS ');
    SQL.Add('where REFERENCIA = :REFERENCIA ');

    try
      ParamByName('REFERENCIA').AsString := ReferenciaArticulo;
      Prepare;
      ExecQuery;

      Referencia := FieldByName('REFERENCIA').AsString;
      Result := (ReferenciaArticulo = Referencia);
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaArticulos.DarCodigoArt(ReferenciaArticulo: String;
  var CodigoArticulo: String): Boolean;
var
  oSQL : TIBSQL;

begin
  Result := False;

  if EsCadenaVacia(ReferenciaArticulo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select CODIGO from ARTICULOS ');
    SQL.Add('where REFERENCIA = :REFERENCIA ');

    try
      ParamByName('REFERENCIA').AsString := ReferenciaArticulo;
      Prepare;
      ExecQuery;

      if (RecordCount > 0) then
      begin
        CodigoArticulo := FieldByName('CODIGO').AsString;
        Result := True;
      end;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

end.
