{
===============================================================================
  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: 01-10-2001
  Versión actual: 1.1.2
  Fecha versión actual: 18-03-2005
===============================================================================
  Modificaciones:

    Fecha         Comentarios
    ---------------------------------------------------------------------------
    18-10-2001    Añadidos los campos 'CODIGOCLIENTEFINAL' y 'NOMBRECLIENTEFINAL'

    01-11-2001    Nueva función 'BloquearRegistro'.

    01-11-2001    Se ha eliminado la columna FACTURADO por CODIGOFACTURA.

    27-11-2001    Se ha añadido la columna 'Unid. medida'.

    07-04-2002    Adaptar todas las funciones a la transacción única.

    06-05-2002    Adaptación al grid 'TdxDBGrid'.

    22-08-2002    La columna 'TIPO' de los detalles se ha puesto como no
                  requerida.

    27-05-2002    Cambio a un objeto contador (TContadorPresupuestoCliente)

    16-11-2002    p250. Poner el número total de presupuestos dados de alta
                  en la inicialización del grid.

    08-04-2003    P263. Agrupar por años los presupuestos, nueva función
                  DarListaAnos.

    21-04-2003    P266. Añadimos el metodo, ModificarSituacionPresupuesto

    06-03-2004    P272. Adaptación a multiempresa.

    02-08-2004    P285. Modificada la función 'NoFacturarAlbaran'.

    18-03-2005    p587. Adaptación a Bonificaciones
===============================================================================
}

unit TablaPresupuestos;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  BaseDatos, Ibdatabase, dxDBGrid, Contadores, IBCustomDataSet,
  cxGridDBTableView, cxCustomData;

type
  TDatosPresupuesto = class(TPersistent)
  public
  	CodigoEmpresa : integer;
	Codigo : string;
    FechaAlta : string;
    FechaDecision : string;
    Situacion : string;
    CodigoPedidoCliente : string;
    Usuario : string;
    CodigoCliente : string;
    NIFCIF : string;
    Nombre : string;
    Calle : string;
    Numero : string;
    Piso : string;
    CodigoPostal : string;
    Poblacion : string;
    Provincia : string;
    PersonaContacto : string;
    Telefono : string;
    Fax : string;
    ImporteTotal : string;
    Portada : string;
    Descripcion : string;
    Notas : string;
    CodigoFactura : string;
    CodigoClienteFinal : string;
    NombreClienteFinal : string;
    DesBonificacion : string;
    ImpBonificacion : Double;
  end;

  TdmTablaPresupuestos = class(TDataModule)
  private
    procedure IniciarSQLPresupuesto;
    procedure IniciarSQLDetalles;
    procedure IniciarSQLGrids;
  public
    sqlInsertarPresupuesto : TStrings;
    sqlModificarPresupuesto : TStrings;
    sqlConsultarPresupuesto : TStrings;
    sqlEliminarPresupuesto : TStrings;
    sqlConsultarGridPresupuestos : TStrings;
    sqlConsultarGridPresupuestosCli : TStrings;
    sqlConsultarGridPresupuestosFacturar : TStrings;
    sqlInsertarDetalles : TStrings;
    sqlModificarDetalles : TStrings;
    sqlConsultarDetalles : TStrings;
    sqlEliminarDetalles : TStrings;
    sqlConsultarGridDetalles : TStrings;

    //Metodos que llamaran a contador
    function DarNuevoCodigo : String;
    function InsertarContador : boolean;
    function IncrementarCodigo : boolean;
    function ValidarCodigo(Codigo : String) : Boolean;
    function FormatearCodigo(Codigo : String) : String;

    function DarDatosPresupuesto(Presupuesto : TDatosPresupuesto): Boolean;
    function ExisteCodigo(CodigoEmpresa: Integer; Codigo : String) : Boolean;
    function AceptarPresupuesto(CodigoEmpresa: Integer; Codigo: String; FechaAceptacion: TDateTime): Boolean;
    function AnularPresupuesto(CodigoEmpresa: Integer; Codigo: String; FechaAnulacion: TDateTime): Boolean;
    function FacturarPresupuesto(CodigoEmpresa: Integer; Codigo, CodigoFactura: String): boolean;
    function NoFacturarPresupuesto(CodigoEmpresa: Integer; Codigo: String) : boolean;
    function PresupuestoFacturado (CodigoEmpresa: Integer; Codigo: String): boolean;
    function DarSituacionPresupuesto(CodigoEmpresa: Integer; Codigo: String) : String;
    procedure InicializarGridPresupuestos(var Grid: TdxDBGrid);
    procedure InicializarTablaPresupuestos(Tabla: TPTabla);
    procedure InicializarTablaDetalles(Tabla: TPTabla);
    constructor Create (AOwner : TComponent); override;
    destructor Destroy; override;
    function DarSituaciones : TStrings;
    function DarListaAnos(CodigoEmpresa: Integer;const pTodos: Boolean): TStringList;
    function ModificarSituacionPresupuesto(CodigoEmpresa: Integer; Codigo, Situacion: String; FechaDecision: TDateTime): Boolean;

    procedure InicializarGridDetalles(var Grid: TdxDBGrid); overload;
    procedure InicializarGridDetalles(var vGrid: TcxGridDBTableView); overload;
  end;

var
  dmTablaPresupuestos: TdmTablaPresupuestos;

implementation

{$R *.DFM}

uses
  IBSQL, Mensajes, StrFunc, IB, db, dbgrids, Excepciones,
  TablaUnidadesMedida, dxDBCtrl, dxDBTLCL, dxTL, Constantes, Literales,
  RdxGestorContadores, cxButtonEdit, cxEdit, cxDropDownEdit,
  cxCalc;

{ TdmTablaPresupuestos }

function TdmTablaPresupuestos.AceptarPresupuesto(CodigoEmpresa: Integer;
	Codigo: String; FechaAceptacion: TDateTime): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;
  if EsCadenaVacia(Codigo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('update PRESUPUESTOSCLIENTE set ');
    SQL.Add('SITUACION = :SITUACION, ');
    SQL.Add('FECHADECISION = :FECHADECISION ');
    SQL.Add('where (CODIGO = :CODIGO) and (CODIGOEMPRESA = :CODIGOEMPRESA)');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGO').AsString := Codigo;
    ParamByName('FECHADECISION').AsDate := FechaAceptacion;
    ParamByName('SITUACION').AsString := CTE_ACEPTADO;
    try
      Prepare;
      ExecQuery;
      Result := True;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaPresupuestos.AnularPresupuesto(CodigoEmpresa: Integer;
	Codigo: String; FechaAnulacion: TDateTime): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;
  if EsCadenaVacia(Codigo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('update PRESUPUESTOSCLIENTE set ');
    SQL.Add('SITUACION = :SITUACION,');
    SQL.Add('FECHADECISION = :FECHADECISION ');
    SQL.Add('where (CODIGO = :CODIGO) and (CODIGOEMPRESA = :CODIGOEMPRESA)');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGO').AsString := Codigo;
    ParamByName('FECHADECISION').AsDate := FechaAnulacion;
    ParamByName('SITUACION').AsString := CTE_ANULADO;
    try
      Prepare;
      ExecQuery;
      Result := True;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

constructor TdmTablaPresupuestos.Create(AOwner: TComponent);
begin
  inherited;
  { Cabecera }
  sqlInsertarPresupuesto := TStringList.Create;
  sqlModificarPresupuesto := TStringList.Create;
  sqlConsultarPresupuesto := TStringList.Create;
  sqlEliminarPresupuesto := TStringList.Create;

  { Detalles }
  sqlInsertarDetalles := TStringList.Create;
  sqlModificarDetalles := TStringList.Create;
  sqlConsultarDetalles := TStringList.Create;
  sqlEliminarDetalles := TStringList.Create;
  sqlConsultarGridDetalles := TStringList.Create;

  { Grids }
  sqlConsultarGridPresupuestos := TStringList.Create;
  sqlConsultarGridPresupuestosCli := TStringList.Create;
  sqlConsultarGridPresupuestosFacturar := TStringList.Create;

  IniciarSQLPresupuesto;
  IniciarSQLDetalles;
  IniciarSQLGrids;
end;

function TdmTablaPresupuestos.DarDatosPresupuesto(Presupuesto: TDatosPresupuesto): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;
  if EsCadenaVacia(Presupuesto.Codigo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select * from PRESUPUESTOSCLIENTE ');
    SQL.Add('where (CODIGO = :CODIGO) and (CODIGOEMPRESA = :CODIGOEMPRESA)');
    ParamByName('CODIGOEMPRESA').AsInteger := Presupuesto.CodigoEmpresa;
    ParamByName('CODIGO').AsString := Presupuesto.Codigo;
    try
      Prepare;
      ExecQuery;

      //Compruebo que el codigo de presupuesto existe. Si no existe, devuelvo false
      if (RecordCount > 0) then
      begin
        with Presupuesto do
        begin
          FechaAlta := FieldByName('FECHAALTA').AsString;
          FechaDecision := FieldByName('FECHADECISION').AsString;
          Situacion := FieldByName('SITUACION').AsString;
          CodigoPedidoCliente := FieldByName('CODIGOPEDIDOCLIENTE').AsString;
          Usuario:= FieldByName('USUARIO').AsString;
          CodigoCliente := FieldByName('CODIGOCLIENTE').AsString;
          NifCif := FieldByName('NIFCIF').AsString;
          Nombre := FieldByName('NOMBRE').AsString;
          Calle := FieldByName('CALLE').AsString;
          Numero := FieldByName('NUMERO').AsString;
          Piso := FieldByName('PISO').AsString;
          CodigoPostal := FieldByName('CODIGOPOSTAL').AsString;
          Poblacion := FieldByName('POBLACION').AsString;
          Provincia := FieldByName('PROVINCIA').AsString;
          PersonaContacto := FieldByName('PERSONACONTACTO').AsString;
          Telefono := FieldByName('TELEFONO').AsString;
          Fax := FieldByName('FAX').AsString;
          ImporteTotal := FieldByName('IMPORTETOTAL').AsString;
          Portada := FieldByName('PORTADA').AsString;
          Descripcion := FieldByName('DESCRIPCION').AsString;
          Notas := FieldByName('NOTAS').AsString;
          CodigoFactura := FieldByName('CODIGOFACTURA').AsString;
          CodigoClienteFinal := FieldByName('CODIGOCLIENTEFINAL').AsString;
          NombreClienteFinal := FieldByName('NOMBRECLIENTEFINAL').AsString;
          DesBonificacion := FieldByName('DESBONIFICACION').AsString;
          ImpBonificacion := FieldByName('IMPBONIFICACION').AsFloat;
          Result := True;
        end;
      end;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaPresupuestos.DarNuevoCodigo: String;
begin
  Result := GestorContadores.DarNuevoCodigo(contPresupuestosCliente);
end;

function TdmTablaPresupuestos.DarSituaciones: TStrings;
var
  oSQL : TIBSQL;
  Lista : TStringList;
begin
  Result := NIL;
  oSQL := TIBSQL.Create(Self);
  Lista := TStringList.Create;
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select DESCRIPCION from SITUPRESUPUESTOS');
    try
      Prepare;
      ExecQuery;
      while not EOF do begin
        Lista.Append(Fields[0].AsString);
        Next;
      end;
      Result := Lista;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

destructor TdmTablaPresupuestos.Destroy;
begin
  { Cabecera }
  sqlInsertarPresupuesto.Free;
  sqlModificarPresupuesto.Free;
  sqlConsultarPresupuesto.Free;
  sqlEliminarPresupuesto.Free;

  { Detalles }
  sqlInsertarDetalles.Free;
  sqlModificarDetalles.Free;
  sqlConsultarDetalles.Free;
  sqlEliminarDetalles.Free;
  sqlConsultarGridDetalles.Free;

  { Grids }
  sqlConsultarGridPresupuestos.Free;
  sqlConsultarGridPresupuestosCli.Free;
  sqlConsultarGridPresupuestosFacturar.Free;

  inherited;
end;

function TdmTablaPresupuestos.ExisteCodigo(CodigoEmpresa: Integer; Codigo: String): Boolean;
var
  oSQL : TIBSQL;
  Contador : String;
begin
  Result := False;
  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select CODIGO ');
    SQL.Add('from PRESUPUESTOSCLIENTE ');
    SQL.Add('where (CODIGO = :CODIGO) and (CODIGOEMPRESA = :CODIGOEMPRESA)');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGO').AsString := Codigo;
    try
      Prepare;
      ExecQuery;
      Contador := Fields[0].AsString;
      Result := (Codigo = Contador);
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaPresupuestos.FormatearCodigo(Codigo: String): String;
begin
  Result := GestorContadores.FormatearCodigo(contPresupuestosCliente, Codigo);
end;

function TdmTablaPresupuestos.IncrementarCodigo: boolean;
begin
  Result := GestorContadores.IncrementarValor(contPresupuestosCliente);
end;

procedure TdmTablaPresupuestos.InicializarGridDetalles(var Grid: TdxDBGrid);
var
  Columna : TdxDBTreeListColumn;
begin
  with Grid do begin
    DestroyColumns;
    {Columna CODIGOPRESUPUESTO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.Visible := False;
    Columna.FieldName := 'CODIGOPRESUPUESTO';
    {Columna NUMCONCEPTO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.Visible := False;
    Columna.FieldName := 'NUMCONCEPTO';
    {Columna TIPO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.Visible := False;
    Columna.FieldName := 'TIPO';
    {Columna CODIGOARTICULO}
    Columna := CreateColumn(TdxDBTreeListButtonColumn);
    Columna.FieldName := 'CODIGOARTICULO';
    Columna.Caption := 'Cód. material';
    Columna.Width := tamColCodigo;
    {Columna DESCRIPCION}
    Columna := CreateColumn(TdxDBTreeListButtonColumn);
    Columna.FieldName := 'DESCRIPCION';
    Columna.Caption := 'Descripción servicio/material';
    Columna.Width := tamColDescripcion;
    {Columna CANTIDAD}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'CANTIDAD';
    Columna.Caption := 'Cantidad';
    Columna.Width := tamColCantidad;
    {Columna UNIDADESMEDIDA}
    Columna := CreateColumn(TdxDBTreeListPickColumn);
    Columna.FieldName := 'UNIDADESMEDIDA';
    Columna.Caption := 'Unid. medida';
    Columna.Width := tamColUnidadesMedida;
    (Columna as TdxDBTreeListPickColumn).Items := dmTablaUnidadesMedida.DarUnidadesMedida;
    {Columna PRECIOUNIDAD}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'PRECIOUNIDAD';
    Columna.Caption := 'Precio unidad';
    Columna.Width := tamColPrecio;
    {Columna MINUTOS}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'MINUTOS';
    Columna.Caption := 'Num. minutos';
    Columna.Width := tamColCantidad;
    {Columna PRECIOMINUTO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'PRECIOMINUTO';
    Columna.Caption := 'Precio minuto';
    Columna.Width := tamColPrecio;
    {Columna PLUS}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'PLUS';
    Columna.Caption := 'Plus (%)';
    Columna.Width := tamColPorcentaje;
    {Columna TOTAL}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'TOTAL';
    Columna.ReadOnly := True;
    Columna.Caption := 'Precio total';
    Columna.Width := tamColPrecio;
  end;
end;

procedure TdmTablaPresupuestos.InicializarGridPresupuestos(var Grid: TdxDBGrid);
var
  Columna : TdxDBTreeListColumn;
begin
  with Grid do begin
    DestroyColumns;
    ShowSummaryFooter := True;
    {Columna CODIGO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'CODIGO';
    Columna.Caption := 'Código';
    Columna.Width := tamColCodigo;
    Columna.Sorted := csDown;
    Columna.SummaryFooterType := cstCount;
    Columna.SummaryFooterFormat := 'Total: 0 presupuestos';

    {Columna ANO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'ANO';
    Columna.Caption := 'Año';
    Columna.Width := tamColFecha;
    Columna.Visible := False;

    {Columna SITUACION}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'SITUACION';
    Columna.Caption := 'Situación';
    Columna.Width := tamColSituacion;
    {Columna FECHAALTA}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'FECHAALTA';
    Columna.Caption := 'Fecha alta';
    Columna.Width := tamColFecha;
    {Columna CODIGOCLIENTE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.Visible := False;
    Columna.FieldName := 'CODIGOCLIENTE';
    Columna.Caption := 'Cód. cliente';
    Columna.Width := tamColCodigo;
    {Columna NIFCIF}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'NIFCIF';
    Columna.Caption := 'NIF/CIF';
    Columna.Width := tamColNIFCIF;
    {Columna NOMBRE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'NOMBRE';
    Columna.Caption := 'Nombre';
    Columna.Width := tamColNombre;
    {Columna NOMBRECLIENTEFINAL}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'NOMBRECLIENTEFINAL';
    Columna.Caption := 'Cliente final';
    Columna.Width := tamColNombre;
    {Columna IMPORTETOTAL}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'IMPORTETOTAL';
    Columna.Caption := 'Importe';
    Columna.Width := tamColPrecio;
    {Columna CODIGOFACTURA}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'CODIGOFACTURA';
    Columna.Caption := 'Cód. factura';
    Columna.Width := tamColCodigo;
  end;
end;

procedure TdmTablaPresupuestos.InicializarTablaDetalles(Tabla: TPTabla);
begin
  with Tabla^.Fields do
  begin
    if FindField('TIPO') <> NIL then
      with (FieldByName('TIPO') as TField) do begin
        Required := False;
      end;

    if FindField('PRECIOUNIDAD') <> NIL then
      with (FieldByName('PRECIOUNIDAD') as TFloatField) do begin
        DisplayFormat := DISPLAY_EUROS2;
        EditFormat := EDIT_EUROS2;
      end;

    if FindField('PRECIOMINUTO') <> NIL then
      with (FieldByName('PRECIOMINUTO') as TFloatField) do begin
        DisplayFormat := DISPLAY_EUROS2;
        EditFormat := EDIT_EUROS2;
      end;

    if FindField('PLUS') <> NIL then
      with (FieldByName('PLUS') as TFloatField) do begin
        DisplayFormat := DISPLAY_DTO;
        EditFormat := EDIT_DTO;
      end;

    if FindField('PRECIO') <> NIL then
      with (FieldByName('PRECIO') as TFloatField) do begin
        DisplayFormat := DISPLAY_EUROS2;
        EditFormat := EDIT_EUROS2;
      end;

    if FindField('TOTAL') <> NIL then
      with (FieldByName('TOTAL') as TFloatField) do begin
        DisplayFormat := DISPLAY_EUROS2;
        EditFormat := EDIT_EUROS2;
      end;
  end;
end;

procedure TdmTablaPresupuestos.InicializarTablaPresupuestos(
  Tabla: TPTabla);
begin
  with Tabla^.Fields do
  begin
    if FindField('FECHAALTA') <> NIL then
      with (FieldByName('FECHAALTA') as TDateField) do begin
        EditMask := MASK_FECHA;
      end;

    if FindField('FECHADECISION') <> NIL then
      with (FieldByName('FECHADECISION') as TDateField) do begin
        EditMask := MASK_FECHA;
      end;

    if FindField('IMPORTETOTAL') <> NIL then
      //with (FieldByName('IMPORTETOTAL') as TFloatField) do begin
      with (FieldByName('IMPORTETOTAL') as TIBBCDField) do begin
        DisplayFormat := DISPLAY_EUROS2;
        EditFormat := EDIT_EUROS2;
        DisplayLabel := 'Importe total';
      end;

    if FindField('IMPBONIFICACION') <> NIL then
      with (FieldByName('IMPBONIFICACION') as TIBBCDField) do begin
        DisplayFormat := DISPLAY_EUROS2;
        EditFormat := EDIT_EUROS2;
        DisplayLabel := 'Importe bonificación';
      end;
  end;
end;

procedure TdmTablaPresupuestos.IniciarSQLDetalles;
begin
  with sqlInsertarDetalles do
  begin
    Add('insert into DETALLESPRESUPUESTOSCLIENTE ');
    Add('(CODIGOEMPRESA, CODIGOPRESUPUESTO, NUMCONCEPTO, TIPO, CODIGOARTICULO, DESCRIPCION, ');
    Add('CANTIDAD, UNIDADESMEDIDA, PRECIOUNIDAD, MINUTOS, PRECIOMINUTO, PLUS, ');
    Add('PRECIO, TOTAL) ');
    Add('values (:CODIGOEMPRESA, :CODIGOPRESUPUESTO, :NUMCONCEPTO, :TIPO, :CODIGOARTICULO, ');
    Add(':DESCRIPCION, :CANTIDAD, :UNIDADESMEDIDA, :PRECIOUNIDAD, :MINUTOS, ');
    Add(':PRECIOMINUTO, :PLUS, :PRECIO, :TOTAL)');
  end;

  with sqlModificarDetalles do
  begin
    Add('update DETALLESPRESUPUESTOSCLIENTE set ');
    Add('CODIGOPRESUPUESTO = :CODIGOPRESUPUESTO, ');
    Add('NUMCONCEPTO = :NUMCONCEPTO, ');
    Add('CODIGOARTICULO = :CODIGOARTICULO, ');
    Add('TIPO = :TIPO, ');
    Add('DESCRIPCION = :DESCRIPCION, ');
    Add('CANTIDAD = :CANTIDAD, ');
    Add('UNIDADESMEDIDA = :UNIDADESMEDIDA, ');
    Add('PRECIOUNIDAD = :PRECIOUNIDAD, ');
    Add('MINUTOS = :MINUTOS, ');
    Add('PRECIOMINUTO = :PRECIOMINUTO, ');
    Add('PLUS = :PLUS, ');
    Add('PRECIO = :PRECIO, ');
    Add('TOTAL = :TOTAL ');
    Add('where (CODIGOPRESUPUESTO = :CODIGOPRESUPUESTO) and ');
    Add('(CODIGOEMPRESA = :CODIGOEMPRESA) and ');
    Add('(NUMCONCEPTO = :NUMCONCEPTO)');
  end;

  with sqlEliminarDetalles do
  begin
    Add('delete from DETALLESPRESUPUESTOSCLIENTE ');
    Add('where (CODIGOPRESUPUESTO = :CODIGOPRESUPUESTO) and ');
    Add('(CODIGOEMPRESA = :CODIGOEMPRESA) and ');    
    Add('(NUMCONCEPTO = :NUMCONCEPTO)');
  end;

  with sqlConsultarDetalles do
  begin
    Add('select CODIGOEMPRESA, CODIGOPRESUPUESTO, NUMCONCEPTO, TIPO, ');
    Add('CODIGOARTICULO, DESCRIPCION, CANTIDAD, UNIDADESMEDIDA, PRECIOUNIDAD, ');
    Add('MINUTOS, PRECIOMINUTO, PLUS, PRECIO, TOTAL ');
    Add('from DETALLESPRESUPUESTOSCLIENTE ');
    Add('where (CODIGOPRESUPUESTO = :CODIGOPRESUPUESTO) and ');
    Add('(CODIGOEMPRESA = :CODIGOEMPRESA) and ');    
    Add('(NUMCONCEPTO = :NUMCONCEPTO)');
  end;
end;

procedure TdmTablaPresupuestos.IniciarSQLGrids;
begin
  with sqlConsultarGridPresupuestos do
  begin
    Add('select CODIGO, SITUACION, FECHAALTA, FECHADECISION, CODIGOCLIENTE, ');
    Add('EXTRACT (YEAR FROM FECHAALTA) as ANO, ');
    Add('NIFCIF, NOMBRE, CODIGOCLIENTEFINAL, NOMBRECLIENTEFINAL, ');
    Add('IMPORTETOTAL, CODIGOFACTURA ');
    Add('from PRESUPUESTOSCLIENTE ');
    Add('where (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    Add('order by CODIGO');
  end;

  with sqlConsultarGridPresupuestosCli do
  begin
    Add('select CODIGO, SITUACION, FECHAALTA, FECHADECISION, CODIGOCLIENTE, ');
    Add('EXTRACT (YEAR FROM FECHAALTA) as ANO, ');
    Add('NIFCIF, NOMBRE, CODIGOCLIENTEFINAL, NOMBRECLIENTEFINAL, ');
    Add('IMPORTETOTAL, CODIGOFACTURA ');
    Add('from PRESUPUESTOSCLIENTE ');
    Add('where (CODIGOCLIENTE = :CODIGOCLIENTE) ');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    Add('order by CODIGO');
  end;

  with sqlConsultarGridPresupuestosFacturar do
  begin
    Add('select CODIGO, SITUACION, FECHAALTA, FECHADECISION, CODIGOCLIENTE, ');
    Add('EXTRACT (YEAR FROM FECHAALTA) as ANO, ');
    Add('NIFCIF, NOMBRE, CODIGOCLIENTEFINAL, NOMBRECLIENTEFINAL, ');
    Add('IMPORTETOTAL, CODIGOFACTURA ');
    Add('from PRESUPUESTOSCLIENTE ');
    Add('where (CODIGOFACTURA IS NULL) and ');
    Add(('(UPPER(SITUACION) = ''' + CTE_ACEPTADO + ''') '));
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    Add('order by CODIGO');
  end;

  with sqlConsultarGridDetalles do
  begin
    Add('select CODIGOEMPRESA, CODIGOPRESUPUESTO, NUMCONCEPTO, CODIGOARTICULO, TIPO, ');
    Add('DESCRIPCION, CANTIDAD, UNIDADESMEDIDA, PRECIOUNIDAD, MINUTOS, ');
    Add('PRECIOMINUTO, PLUS, PRECIO, TOTAL ');
    Add('from DETALLESPRESUPUESTOSCLIENTE ');
    Add('where (CODIGOPRESUPUESTO = :CODIGOPRESUPUESTO) ');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    Add('order by CODIGOPRESUPUESTO, NUMCONCEPTO');
  end;
end;

procedure TdmTablaPresupuestos.IniciarSQLPresupuesto;
begin
  with sqlInsertarPresupuesto do
  begin
    Add('insert into PRESUPUESTOSCLIENTE ');
    Add('(CODIGOEMPRESA, CODIGO, FECHAALTA, FECHADECISION, SITUACION, CODIGOPEDIDOCLIENTE, ');
    Add('USUARIO, CODIGOCLIENTE, NIFCIF, ');
    Add('NOMBRE, CALLE, NUMERO, PISO, CODIGOPOSTAL, POBLACION, PROVINCIA, ');
    Add('PERSONACONTACTO, TELEFONO, FAX, IMPORTETOTAL, PORTADA, DESCRIPCION, ');
    Add('NOTAS, CODIGOCLIENTEFINAL, NOMBRECLIENTEFINAL, DESBONIFICACION, IMPBONIFICACION) ');
    Add('values (:CODIGOEMPRESA, :CODIGO, :FECHAALTA, :FECHADECISION, :SITUACION, ');
    Add(':CODIGOPEDIDOCLIENTE, :USUARIO, ');
    Add(':CODIGOCLIENTE, :NIFCIF, :NOMBRE, :CALLE, :NUMERO, :PISO, ');
    Add(':CODIGOPOSTAL, :POBLACION, :PROVINCIA, :PERSONACONTACTO, :TELEFONO, ');
    Add(':FAX, :IMPORTETOTAL, :PORTADA, :DESCRIPCION, :NOTAS, ');
    Add(':CODIGOCLIENTEFINAL, :NOMBRECLIENTEFINAL, :DESBONIFICACION, :IMPBONIFICACION)');
  end;

  with sqlModificarPresupuesto do
  begin
    Add('update PRESUPUESTOSCLIENTE set ');
    Add('FECHAALTA = :FECHAALTA, ');
    Add('FECHADECISION = :FECHADECISION, ');
    Add('SITUACION = :SITUACION, ');
    Add('CODIGOPEDIDOCLIENTE = :CODIGOPEDIDOCLIENTE, ');
    Add('USUARIO = :USUARIO, ');
    Add('CODIGOCLIENTE = :CODIGOCLIENTE, ');
    Add('NIFCIF = :NIFCIF, ');
    Add('NOMBRE = :NOMBRE, ');
    Add('CALLE = :CALLE, ');
    Add('NUMERO = :NUMERO, ');
    Add('PISO = :PISO, ');
    Add('CODIGOPOSTAL = :CODIGOPOSTAL, ');
    Add('POBLACION = :POBLACION, ');
    Add('PROVINCIA = :PROVINCIA, ');
    Add('PERSONACONTACTO = :PERSONACONTACTO, ');
    Add('TELEFONO = :TELEFONO, ');
    Add('FAX = :FAX, ');
    Add('IMPORTETOTAL = :IMPORTETOTAL, ');
    Add('PORTADA = :PORTADA, ');
    Add('DESCRIPCION = :DESCRIPCION, ');
    Add('NOTAS = :NOTAS, ');
    Add('CODIGOCLIENTEFINAL = :CODIGOCLIENTEFINAL, ');
    Add('NOMBRECLIENTEFINAL = :NOMBRECLIENTEFINAL, ');
    Add('DESBONIFICACION = :DESBONIFICACION, ');
    Add('IMPBONIFICACION = :IMPBONIFICACION ');
    Add('where (CODIGO = :CODIGO) ');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');            
  end;

  with sqlEliminarPresupuesto do
  begin
    Add('delete from PRESUPUESTOSCLIENTE ');
    Add('where (CODIGO = :CODIGO) ');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
  end;

  with sqlConsultarPresupuesto do
  begin
    Add('SELECT * FROM PRESUPUESTOSCLIENTE ');
    Add('where (CODIGO = :CODIGO) ');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
  end;
end;

function TdmTablaPresupuestos.InsertarContador: boolean;
begin
  Result := GestorContadores.InsertarContador(contPresupuestosCliente);
end;

function TdmTablaPresupuestos.FacturarPresupuesto(CodigoEmpresa: Integer; 
	Codigo, CodigoFactura: String): boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;
  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('update PRESUPUESTOSCLIENTE set ');
    SQL.Add('CODIGOFACTURA = :CODIGOFACTURA');
    SQL.Add('where (CODIGO = :CODIGO) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    SQL.Add('and (CODIGOFACTURA is NULL) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGO').AsString := Codigo;
    ParamByName('CODIGOFACTURA').AsString := CodigoFactura;
    try
      Prepare;
      ExecQuery;
      if RowsAffected = 0 then
        raise Exception.CreateFmt(msgPreYaFacturado, [Codigo]);
      Result := True;
    finally;
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaPresupuestos.ValidarCodigo(Codigo: String): Boolean;
begin
  Result := GestorContadores.ValidarCodigo(contPresupuestosCliente, Codigo);
end;

function TdmTablaPresupuestos.NoFacturarPresupuesto(CodigoEmpresa: Integer; 
  Codigo: String): boolean;
var
  oSQL : TIBSQL;
begin
  { Con la adaptación a multiempresa, esto hay que hacerlo por código
    por que si se hace por integridad referencial, la BD pone NULL en
    CODIGOFACTURA y en CODIGOEMPRESA (eso está mal) }
  Result := False;
  if (Length(Trim(Codigo)) = 0) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('update PRESUPUESTOSCLIENTE set ');
    SQL.Add('CODIGOFACTURA = NULL');
    SQL.Add('where (CODIGOEMPRESA = :CODIGOEMPRESA) and (CODIGO = :CODIGO) ');
    ParamByName('CODIGO').AsString := Codigo;
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    try
      Prepare;
      ExecQuery;
      Result := True;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaPresupuestos.DarSituacionPresupuesto(CodigoEmpresa: Integer; 
  Codigo: String): String;
var
  oSQL : TIBSQL;
begin
  Result := '';

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select SITUACION ');
    SQL.Add('from PRESUPUESTOSCLIENTE ');
    SQL.Add('where (CODIGO = :CODIGO) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;    
    ParamByName('CODIGO').AsString := Codigo;
    try
      Prepare;
      ExecQuery;
      Result := UpperCase(FieldByName('SITUACION').AsString);
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaPresupuestos.PresupuestoFacturado(CodigoEmpresa: Integer; 
	Codigo: String): boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;
  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select CODIGOFACTURA ');
    SQL.Add('from PRESUPUESTOSCLIENTE ');
    SQL.Add('where (CODIGO = :CODIGO) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGO').AsString := Codigo;
    try
      Prepare;
      ExecQuery;
      Result := not EsCadenaVacia(FieldByName('CODIGOFACTURA').AsString);
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaPresupuestos.DarListaAnos(CodigoEmpresa: Integer;const pTodos: Boolean): TStringList;
var
  oSQL : TIBSQL;
  Lista : TStringList;
begin
  Lista := TStringList.Create;
  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select distinct (EXTRACT (YEAR FROM FECHAALTA)) ANO ');
    SQL.Add('from PRESUPUESTOSCLIENTE ');
    SQL.Add('where (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    SQL.Add('order by FECHAALTA desc');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;

  try
    Prepare;
    ExecQuery;
    if pTodos then
       Lista.Add(CTE_TODOS);
    while not EOF do begin
      Lista.Add(Fields[0].AsString);
      Next;
    end;
    result := Lista;
  finally
    Close;
    Transaction := NIL;
    Free;
  end;
  end;
end;

function TdmTablaPresupuestos.ModificarSituacionPresupuesto(CodigoEmpresa: Integer;
	Codigo, Situacion: String; FechaDecision: TDateTime): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;
  if EsCadenaVacia(Codigo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('update PRESUPUESTOSCLIENTE ');
    SQL.Add('set SITUACION = :SITUACION, ');
    SQL.Add('FECHADECISION = :FECHADECISION ');
    SQL.Add('where (CODIGO = :CODIGO)');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGO').AsString := Codigo;
    ParamByName('SITUACION').AsString := Situacion;
    ParamByName('FECHADECISION').AsDate := FechaDecision;
    try
      Prepare;
      ExecQuery;
      Result := True;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

procedure TdmTablaPresupuestos.InicializarGridDetalles(
  var vGrid: TcxGridDBTableView);
var
  Columna : TcxGridDBColumn;
begin
  with vGrid do begin
    OptionsView.Footer := True;

    {Columna CODIGOPRESUPUESTO}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'CODIGOPRESUPUESTO';
    Columna.Caption := 'Código presupuesto';
    Columna.Options.Filtering := False;
    Columna.Visible := False;

    {Columna NUMCONCEPTO}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'NUMCONCEPTO';
    Columna.Caption := 'Numconcepto';
    Columna.Options.Filtering := False;
    Columna.Visible := False;

    {Columna TIPO}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'TIPO';
    Columna.Caption := 'Tipo';
    Columna.Options.Filtering := False;
    Columna.Visible := False;

    {Columna CODIGOARTICULO}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'CODIGOARTICULO';
    Columna.Caption := 'Cód. material';
    Columna.Options.Filtering := False;
    Columna.Width := tamColCodigo;
    Columna.Visible := True;
    Columna.PropertiesClassName := 'TcxButtonEditProperties';
    with TcxButtonEditProperties(Columna.Properties) do
    begin
      Buttons[0].Kind := bkEllipsis;
    end;

    {Columna DESCRIPCION}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'DESCRIPCION';
    Columna.Caption := 'Descripción servicio/material';
    Columna.Options.Filtering := False;
    Columna.Width := tamColDescripcion;
    Columna.Visible := True;

    {Columna CANTIDAD}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'CANTIDAD';
    Columna.Caption := 'Cantidad';
    Columna.Options.Filtering := False;
    Columna.Width := tamColCantidad;
    Columna.Visible := True;
    Columna.HeaderAlignmentHorz := taRightJustify;
//    Columna.PropertiesClassName := 'TcxCalcEditProperties';
    Columna.PropertiesClassName := 'TcxMaskEditProperties';

    {Columna UNIDADESMEDIDA}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'UNIDADESMEDIDA';
    Columna.Caption := 'Unid. medida';
    Columna.Options.Filtering := False;
    Columna.Width := tamColUnidadesMedida;
    Columna.Visible := True;
    Columna.PropertiesClassName := 'TcxComboBoxProperties';
    with TcxComboBoxProperties(Columna.Properties) do
    begin
      Items.Clear;
      Items := dmTablaUnidadesMedida.DarUnidadesMedida;
    end;
    {Columna PRECIOUNIDAD}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'PRECIOUNIDAD';
    Columna.Caption := 'Precio unidad';
    Columna.Options.Filtering := False;
    Columna.Width := tamColPrecio;
    Columna.Visible := True;
    Columna.HeaderAlignmentHorz := taRightJustify;

    {Columna MINUTOS}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'MINUTOS';
    Columna.Caption := 'Num. minutos';
    Columna.Options.Filtering := False;
    Columna.Width := tamColCantidad;
    Columna.Visible := True;
    Columna.HeaderAlignmentHorz := taRightJustify;

    {Columna PRECIOMINUTO}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'PRECIOMINUTO';
    Columna.Caption := 'Precio minuto';
    Columna.Options.Filtering := False;
    Columna.Width := tamColPrecio;
    Columna.Visible := True;
    Columna.HeaderAlignmentHorz := taRightJustify;

    {Columna PLUS}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'PLUS';
    Columna.Caption := 'Plus (%)';
    Columna.Options.Filtering := False;
    Columna.Width := tamColPorcentaje;
    Columna.Visible := True;
    Columna.HeaderAlignmentHorz := taRightJustify;

    {Columna TOTAL}
    Columna := CreateColumn;
    Columna.DataBinding.FieldName := 'TOTAL';
    Columna.Caption := 'Precio total';
    Columna.Options.Filtering := False;
    Columna.Width := tamColPrecio;
    Columna.Visible := True;
    Columna.HeaderAlignmentHorz := taRightJustify;

     { with Grid do begin
    DestroyColumns;
    Columna := CreateColumn(TdxDBTreeListPickColumn);
    Columna.FieldName := 'UNIDADESMEDIDA';
    Columna.Caption := 'Unid. medida';
    Columna.Width := tamColUnidadesMedida;
    (Columna as TdxDBTreeListPickColumn).Items := dmTablaUnidadesMedida.DarUnidadesMedida;
    }
  end;
end;

end.
