{
===============================================================================
  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.0
  Fecha versión actual: 06-03-2004
===============================================================================
  Modificaciones:

    Fecha         Comentarios
    ---------------------------------------------------------------------------
    27-10-2001    Se ha eliminado el campo 'Notas' de la tabla de facturas
                  de cliente.

    30-10-2001    Añadir en el grid una columna que indique que código de
                  documento se factura (presupuesto/albarán). Si aparece
                  en blanco es una factura libre.

    30-10-2001    Se ha añadido cliente final en facturas de cliente.

    31-10-2001    Se han añadido los campos IMPORTEDESCUENTO e IMPORTEIVA.

    17-02-2002    Se ha cambiado la política de contadores de las facturas. Se
                  coje el valor más alta que existe en FACTURASCLIENTE.

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

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

    09-05-2002    P221. Cambio del funcionamiento de los contadores de facturas
                  de cliente. El código de factura se debe sacar a partir de la
                  tabla CONTADORES no a partir del máximo código que exista
                  en la tabla de facturas de cliente.

    11-08-2002    P236. Añadida la función 'DecrementarCodigo'.

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

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

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

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

    08-04-2003    P255. Agrupar por meses las facturas, ordenar las más recientes
                  arriba.

    21-04-2003    Arreglo en la funcion ModificarSituacionFactura,
                  para que no se borren todas las formas de pago de las
                  faturas que se cambien de una vez en 'Cambiar situacion'.

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

    01-03-2006    Se ha añadido el campo BaseImponible2 que nos aclara la base
                  imponible sobre la que se aplica el IVA
===============================================================================
}

unit TablaFacturasCliente;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  BaseDatos, dxDBGrid, Contadores;

type
  TDatosFacturaCliente = class(TPersistent)
  public
    CodigoEmpresa : Integer;
    Codigo : String;
    FechaAlta : String;
    FechaVencimiento : String;
    FormaPago : String;
    Situacion : String;
    Usuario  : String;
    Descripcion : 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;
    CodigoPresupuestoAlbaran : String;
    BaseImponible : Double;
    Descuento : Integer;
    Iva : Integer;
    ImporteTotal : Double;
    ImporteDescuento : Double;
    ImporteIva : Double;
    Banco : String;
    Notas : String;
    CodigoClienteFinal : String;
    NombreClienteFinal : String;
    ClaseFactura : String;
    CodigoCargo : String;
  end;

  TdmTablaFacturasCliente = class(TDataModule)
  private
    procedure IniciarSQLFactura;
    procedure IniciarSQLDetalles;
    procedure IniciarSQLGrids;
  public
    sqlInsertarFactura : TStrings;
    sqlModificarFactura : TStrings;
    sqlConsultarFactura : TStrings;
    sqlEliminarFactura : TStrings;
    sqlConsultarGridFacturas : TStrings;
    sqlConsultarGridFacturasCli : TStrings;
    sqlConsultarGridFacturasPreAlb : TStrings;
    sqlInsertarDetalles : TStrings;
    sqlModificarDetalles : TStrings;
    sqlConsultarDetalles : TStrings;
    sqlEliminarDetalles : TStrings;
    sqlConsultarGridDetalles : TStrings;

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

    function DarDatosFactura(Factura : TDatosFacturaCliente): Boolean;
    function DarClaseFactura(CodigoEmpresa: Integer; Codigo : String): String;
    function ExisteCodigo(CodigoEmpresa: Integer; Codigo : String) : Boolean;
    procedure InicializarGridDetalles(var Grid: TdxDBGrid);
    procedure InicializarGridFacturas(var Grid: TdxDBGrid);
    procedure InicializarTablaFacturas(Tabla: TPTabla);
    procedure InicializarTablaDetalles(Tabla: TPTabla);
    constructor Create (AOwner : TComponent); override;
    destructor Destroy; override;
    function DarSituaciones : TStrings;
    function DarSituacionFactura(CodigoEmpresa: Integer; Codigo: String): String;
    function DarListaFacturas(Grid : TdxDBGrid; Tabla: TPTabla): TStringList;
    function ModificarSituacionFactura(CodigoEmpresa: Integer; Codigo, Situacion, FormaPago : String): Boolean;
    function DarImporteTodosAbonos(CodigoEmpresa: Integer; Codigo: String): Double;
    function DarImporteOtrosAbonos(CodigoEmpresa: Integer; CodigoCargo: String; CodigoAbono : String): Double;
    function ExistenAbonos(CodigoEmpresa: Integer; CodigoCargo : String) : Boolean;
    function EsUltimaFactura(CodigoEmpresa: Integer; Codigo : String): Boolean;
    function DarListaAnos(CodigoEmpresa: Integer;const pTodos: Boolean): TStringList;
  end;

var
  dmTablaFacturasCliente: TdmTablaFacturasCliente;

implementation
{$R *.DFM}

uses
  IBSQL, Mensajes, StrFunc, IB, db, Excepciones,
  TablaUnidadesMedida, dxDBCtrl, dxDBTLCL, IBCustomDataSet, dxTL,
  Constantes, RdxGestorContadores;

{ TdmTablaFacturas }

constructor TdmTablaFacturasCliente.Create(AOwner: TComponent);
begin
  inherited;
  { Cabecera }
  sqlInsertarFactura := TStringList.Create;
  sqlModificarFactura := TStringList.Create;
  sqlConsultarFactura := TStringList.Create;
  sqlEliminarFactura := TStringList.Create;

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

  { Grids }
  sqlConsultarGridFacturas := TStringList.Create;
  sqlConsultarGridFacturasCli := TStringList.Create;
  sqlConsultarGridFacturasPreAlb := TStringList.Create;

  IniciarSQLFactura;
  IniciarSQLDetalles;
  IniciarSQLGrids;
end;

function TdmTablaFacturasCliente.DarNuevoCodigo: String;
begin
  Result := GestorContadores.DarNuevoCodigo(contFacturasCliente);
end;

function TdmTablaFacturasCliente.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 SITUFACTURAS');
    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 TdmTablaFacturasCliente.Destroy;
begin
  { Cabecera }
  sqlInsertarFactura.Free;
  sqlModificarFactura.Free;
  sqlConsultarFactura.Free;
  sqlEliminarFactura.Free;

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

  { Grids }
  sqlConsultarGridFacturas.Free;
  sqlConsultarGridFacturasCli.Free;
  sqlConsultarGridFacturasPreAlb.Free;
  inherited;
end;

function TdmTablaFacturasCliente.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 FACTURASCLIENTE ');
    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 TdmTablaFacturasCliente.FormatearCodigo(Codigo: String): String;
begin
  Result := GestorContadores.FormatearCodigo(contFacturasCliente, Codigo);
end;

function TdmTablaFacturasCliente.IncrementarCodigo: boolean;
begin
  Result := GestorContadores.IncrementarValor(contFacturasCliente);
end;

procedure TdmTablaFacturasCliente.InicializarGridDetalles(var Grid: TdxDBGrid);
var
  Columna : TdxDBTreeListColumn;
begin
  with Grid do begin
    DestroyColumns;
    {Columna CODIGOFACTURA}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.Visible := False;
    Columna.FieldName := 'CODIGOFACTURA';
    {Columna NUMCONCEPTO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.Visible := False;
    Columna.FieldName := 'NUMCONCEPTO';
    {Columna TIPO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.Visible := False;
    Columna.FieldName := 'TIPO';
    Columna.Width := tamColTipo;
    {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 TdmTablaFacturasCliente.InicializarGridFacturas(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ód. factura';
    Columna.Width := tamColCodigo;
    Columna.Sorted := csDown;
    Columna.SummaryFooterType := cstCount;
    Columna.SummaryFooterFormat := 'Total: 0 facturas';

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

//Para activar P255
    {Columna MES}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'MES';
    Columna.Caption := '';
    Columna.Width := tamColFecha;
    Columna.Visible := False;
//    TdxDBGridColumn(Grid.ColumnByFieldName('MES')).GroupIndex := 0;
//    tvOrders.DataController.Groups.FullExpand;
//    TdxDBGridColumn(Grid.ColumnByFieldName('MES')).ColumnGrouping := False;
//    Grid.OptionsCustomize.

    {Columna CLASEFACTURA}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'CLASEFACTURA';
    Columna.Caption := 'Clase';
    Columna.Width := tamClaseFactura;
    {Columna SITUACION}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'SITUACION';
    Columna.Caption := 'Situación';
    Columna.Width := tamColSituacion;
    {Columna CODIGOPRESUPUESTOALBARAN}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'CODIGOPRESUPUESTOALBARAN';
    Columna.Caption := 'Pres./Alb./Libre';
    Columna.Width := tamColCodigo;
    {Columna FECHAALTA}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'FECHAALTA';
    Columna.Caption := 'Fecha alta';
    Columna.Width := tamColFecha;
    {Columna FECHAVENCIMIENTO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'FECHAVENCIMIENTO';
    Columna.Caption := 'Vencimiento';
    Columna.Width := tamColFecha;
    {Columna CODIGOCLIENTE}
    Columna := CreateColumn(TdxDBTreeListColumn);
    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 total';
    Columna.Width := tamColPrecio;
    {Columna CODIGOCARGO}
    Columna := CreateColumn(TdxDBTreeListColumn);
    Columna.FieldName := 'CODIGOCARGO';
    Columna.Caption := 'Cargo';
    Columna.Width := tamColCodigo;
    Columna.Visible := False;
  end;
end;

procedure TdmTablaFacturasCliente.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('PRECIO') <> NIL then
      with (FieldByName('PRECIO') 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('TOTAL') <> NIL then
      with (FieldByName('TOTAL') as TFloatField) do begin
        DisplayFormat := DISPLAY_EUROS2;
        EditFormat := EDIT_EUROS2;
      end;
  end;
end;

procedure TdmTablaFacturasCliente.InicializarTablaFacturas(
  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('FECHAVENCIMIENTO') <> NIL then
      with (FieldByName('FECHAVENCIMIENTO') as TDateField) do begin
        EditMask := MASK_FECHA;
      end;

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

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

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

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

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

    if FindField('IMPORTEIVA') <> NIL then
      //with (FieldByName('IMPORTEIVA') as TFloatField) do begin
      with (FieldByName('IMPORTEIVA') as TIBBCDField) do begin
        DisplayFormat := DISPLAY_EUROS2;
        EditFormat := EDIT_EUROS2;
      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;
      end;
  end;
end;

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

  with sqlModificarDetalles do
  begin
    Add('update DETALLESFACTURASCLIENTE set ');
    Add('CODIGOFACTURA = :CODIGOFACTURA, ');
    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 (CODIGOFACTURA = :CODIGOFACTURA) ');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    Add('and (NUMCONCEPTO = :NUMCONCEPTO)');
  end;

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

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

procedure TdmTablaFacturasCliente.IniciarSQLGrids;
begin
  with sqlConsultarGridFacturas do
  begin
    Add('select CODIGO, CLASEFACTURA, SITUACION, FECHAALTA, CODIGOPRESUPUESTOALBARAN, ');
    Add('EXTRACT (YEAR FROM FECHAALTA) as ANO, ');
//Para activar P255
//    Add('EXTRACT (MONTH FROM FECHAALTA) || ''/'' || EXTRACT (YEAR FROM FECHAALTA) as MES, ');

    Add('FECHAVENCIMIENTO, CODIGOCLIENTE, NIFCIF, NOMBRE, ');
    Add('CODIGOCLIENTEFINAL, NOMBRECLIENTEFINAL, IMPORTETOTAL, CODIGOCARGO ');
    Add('from FACTURASCLIENTE ');
    Add('where (CODIGOEMPRESA = :CODIGOEMPRESA) ');     
    Add('order by CODIGO');
  end;

  with sqlConsultarGridFacturasCli do
  begin
    Add('select CODIGO, CLASEFACTURA, SITUACION, FECHAALTA, CODIGOPRESUPUESTOALBARAN, ');
    Add('EXTRACT (YEAR FROM FECHAALTA) as ANO, ');
    Add('FECHAVENCIMIENTO, CODIGOCLIENTE, NIFCIF, NOMBRE, ');
    Add('CODIGOCLIENTEFINAL, NOMBRECLIENTEFINAL, IMPORTETOTAL, CODIGOCARGO ');
    Add('from FACTURASCLIENTE ');
    Add('where (CODIGOCLIENTE = :CODIGOCLIENTE) ');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    Add('order by CODIGO');
  end;

  with sqlConsultarGridFacturasPreAlb do
  begin
    Add('select CODIGO, CLASEFACTURA, SITUACION, FECHAALTA, CODIGOPRESUPUESTOALBARAN, ');
    Add('EXTRACT (YEAR FROM FECHAALTA) as ANO, ');
    Add('FECHAVENCIMIENTO, CODIGOCLIENTE, NIFCIF, NOMBRE, ');
    Add('CODIGOCLIENTEFINAL, NOMBRECLIENTEFINAL, IMPORTETOTAL, CODIGOCARGO ');
    Add('from FACTURASCLIENTE ');
    Add('where (CODIGOPRESUPUESTOALBARAN = :CODIGOPRESUPUESTOALBARAN) ');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    Add('order by CODIGO');
  end;

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

procedure TdmTablaFacturasCliente.IniciarSQLFactura;
begin
  with sqlInsertarFactura do
  begin
    Add('insert into FACTURASCLIENTE ');
    Add('(CODIGOEMPRESA, CODIGO, FECHAALTA, FECHAVENCIMIENTO, FORMAPAGO, SITUACION, ');
    Add('USUARIO, DESCRIPCION, CODIGOCLIENTE, NIFCIF, NOMBRE, CALLE, ');
    Add('NUMERO, PISO, CODIGOPOSTAL, POBLACION, PROVINCIA, PERSONACONTACTO, ');
    Add('TELEFONO, FAX, CODIGOPRESUPUESTOALBARAN, BASEIMPONIBLE, DESCUENTO, ');
    Add('IVA, IMPORTETOTAL, BANCO, CODIGOCLIENTEFINAL, NOMBRECLIENTEFINAL, ');
    Add('IMPORTEDESCUENTO, IMPORTEIVA, CLASEFACTURA, CODIGOCARGO) ');
    Add('values (:CODIGOEMPRESA, :CODIGO, :FECHAALTA, :FECHAVENCIMIENTO, :FORMAPAGO, ');
    Add(':SITUACION, :USUARIO, :DESCRIPCION, :CODIGOCLIENTE, :NIFCIF, ');
    Add(':NOMBRE, :CALLE, :NUMERO, :PISO, :CODIGOPOSTAL, :POBLACION, ');
    Add(':PROVINCIA, :PERSONACONTACTO, :TELEFONO, :FAX, ');
    Add(':CODIGOPRESUPUESTOALBARAN, :BASEIMPONIBLE, :DESCUENTO, :IVA, ');
    Add(':IMPORTETOTAL, :BANCO, :CODIGOCLIENTEFINAL, :NOMBRECLIENTEFINAL, ');
    Add(':IMPORTEDESCUENTO, :IMPORTEIVA, :CLASEFACTURA, :CODIGOCARGO) ');

  end;

  with sqlModificarFactura do
  begin
    Add('update FACTURASCLIENTE set ');
    Add('FECHAALTA = :FECHAALTA, ');
    Add('FECHAVENCIMIENTO = :FECHAVENCIMIENTO, ');
    Add('FORMAPAGO = :FORMAPAGO, ');
    Add('SITUACION = :SITUACION, ');
    Add('USUARIO = :USUARIO, ');
    Add('DESCRIPCION = :DESCRIPCION, ');
    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('CODIGOPRESUPUESTOALBARAN = :CODIGOPRESUPUESTOALBARAN, ');
    Add('BASEIMPONIBLE = :BASEIMPONIBLE, ');
    Add('DESCUENTO = :DESCUENTO, ');
    Add('IMPORTEDESCUENTO = :IMPORTEDESCUENTO, ');
    Add('IVA = :IVA, ');
    Add('IMPORTEIVA = :IMPORTEIVA, ');
    Add('IMPORTETOTAL = :IMPORTETOTAL, ');
    Add('BANCO = :BANCO, ');
    Add('CODIGOCLIENTEFINAL = :CODIGOCLIENTEFINAL, ');
    Add('NOMBRECLIENTEFINAL = :NOMBRECLIENTEFINAL ');
    Add('where (CODIGO = :CODIGO)');
    Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');        
  end;

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

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

function TdmTablaFacturasCliente.InsertarContador: boolean;
begin
  Result := GestorContadores.InsertarContador(contFacturasCliente);
end;

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

function TdmTablaFacturasCliente.DarSituacionFactura(CodigoEmpresa: Integer; 
  Codigo: String): String;
var
  oSQL : TIBSQL;
begin
  Result := '-1';
  if EsCadenaVacia(Codigo) then
    Exit;

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

function TdmTablaFacturasCliente.ModificarSituacionFactura(CodigoEmpresa: Integer; 
	Codigo, Situacion, FormaPago: String): 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 FACTURASCLIENTE ');
    SQL.Add('set SITUACION = :SITUACION ');

    // Si recibimos la forma de pago a null o vacia, quiere decir que no se debe
    // cambiar ya que afectaria a todas las facturas seleccionadas
    if not esCadenaVacia(FormaPago) then
      SQL.Add(',FORMAPAGO = :FORMAPAGO ');

    SQL.Add('where (CODIGO = :CODIGO)');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGO').AsString := Codigo;
    ParamByName('SITUACION').AsString := Situacion;

    // Si recibimos la forma de pago a null o vacia, quiere decir que no se debe
    // cambiar ya que afectaria a todas las facturas seleccionadas
    if not esCadenaVacia(FormaPago) then
    ParamByName('FORMAPAGO').AsString := FormaPago;

    try
      Prepare;
      ExecQuery;
      Result := True;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaFacturasCliente.DarListaFacturas(Grid: TdxDBGrid;
  Tabla: TPTabla): TStringList;
var
  i: integer;
  ListaFacturas : TStringList;
begin
  ListaFacturas := Nil;

  if Grid.SelectedCount = 0 then
  begin
    Result := ListaFacturas;
    exit
  end;

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

function TdmTablaFacturasCliente.DecrementarCodigo: boolean;
begin
  Result := GestorContadores.DecrementarValor(contFacturasCliente);
end;

function TdmTablaFacturasCliente.DarImporteTodosAbonos(CodigoEmpresa: Integer; 
	Codigo: String): Double;
var
  oSQL : TIBSQL;
begin
  Result := 0.0;
  if EsCadenaVacia(Codigo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select sum(IMPORTETOTAL) ');
    SQL.Add('from FACTURASCLIENTE ');
    SQL.Add('where (CODIGOCARGO = :CODIGO) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGO').AsString := Codigo;
    try
      Prepare;
      ExecQuery;
      Result := Fields[0].AsFloat;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaFacturasCliente.DarDatosFactura(
  Factura: TDatosFacturaCliente): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;
  if EsCadenaVacia(Factura.Codigo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select * from FACTURASCLIENTE ');
    SQL.Add('where (CODIGO = :CODIGO)');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := Factura.CodigoEmpresa;
    ParamByName('CODIGO').AsString := Factura.Codigo;
    try
      Prepare;
      ExecQuery;
      //Compruebo que el codigo de albarán existe. Si no existe, devuelvo false
      if (RecordCount > 0) then
      begin
        with Factura do
        begin
          FechaAlta := FieldByName('FECHAALTA').AsString;
          FechaVencimiento := FieldByName('FECHAVENCIMIENTO').AsString;
          FormaPago := FieldByName('FORMAPAGO').AsString;
          Situacion := FieldByName('SITUACION').AsString;
          Usuario := FieldByName('USUARIO').AsString;
          Descripcion := FieldByName('DESCRIPCION').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;
          CodigoPresupuestoAlbaran := FieldByName('CODIGOPRESUPUESTOALBARAN').AsString;
          BaseImponible := FieldByName('BASEIMPONIBLE').AsFloat;
          Descuento := FieldByName('DESCUENTO').AsInteger;
          Iva := FieldByName('IVA').AsInteger;
          ImporteDescuento := FieldByName('IMPORTEDESCUENTO').AsFloat;
          ImporteIva := FieldByName('IMPORTEIVA').AsFloat;
          ImporteTotal := FieldByName('IMPORTETOTAL').AsFloat;
          Banco := FieldByName('BANCO').AsString;
          Notas := FieldByName('NOTAS').AsString;
          CodigoClienteFinal := FieldByName('CODIGOCLIENTEFINAL').AsString;
          NombreClienteFinal := FieldByName('NOMBRECLIENTEFINAL').AsString;
          ClaseFactura := FieldByName('CLASEFACTURA').AsString;
          CodigoCargo := FieldByName('CODIGOCARGO').AsString;
          Result := True;
        end;
      end;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;


function TdmTablaFacturasCliente.DarClaseFactura(CodigoEmpresa: Integer; 
	Codigo: String): String;
var
  oSQL : TIBSQL;
begin
  Result := 'C';
  if EsCadenaVacia(Codigo) then
    Exit;

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

function TdmTablaFacturasCliente.DarImporteOtrosAbonos(CodigoEmpresa: Integer; 
	CodigoCargo, CodigoAbono: String): Double;
var
  oSQL : TIBSQL;
begin
  Result := 0.0;
  if EsCadenaVacia(CodigoCargo) then
    Exit;

  if EsCadenaVacia(CodigoAbono) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select sum(IMPORTETOTAL) ');
    SQL.Add('from FACTURASCLIENTE ');
    SQL.Add('where (CODIGOCARGO = :CODIGOCARGO) ');
    SQL.Add('and (CODIGO <> :CODIGO)');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGOCARGO').AsString := CodigoCargo;
    ParamByName('CODIGO').AsString := CodigoAbono;
    try
      Prepare;
      ExecQuery;
      Result := Fields[0].AsFloat;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaFacturasCliente.EsUltimaFactura(CodigoEmpresa: Integer; Codigo: String): 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('select count(*) ');
    SQL.Add('from FACTURASCLIENTE ');
    SQL.Add('where (CODIGO > :CODIGO) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;
    ParamByName('CODIGO').AsString := Codigo;
    try
      Prepare;
      ExecQuery;
      if Fields[0].AsInteger = 0 then
        Result := True;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaFacturasCliente.ExistenAbonos(CodigoEmpresa: Integer; 
  CodigoCargo: String): Boolean;
var
  oSQL : TIBSQL;
begin
  Result := False;
  if EsCadenaVacia(CodigoCargo) then
    Exit;

  oSQL := TIBSQL.Create(Self);
  with oSQL do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select count(*) ');
    SQL.Add('from FACTURASCLIENTE ');
    SQL.Add('where (CODIGOCARGO = :CODIGOCARGO) ');
    SQL.Add('and (CODIGOEMPRESA = :CODIGOEMPRESA) ');
    ParamByName('CODIGOEMPRESA').AsInteger := CodigoEmpresa;    
    ParamByName('CODIGOCARGO').AsString := CodigoCargo;
    try
      Prepare;
      ExecQuery;
      if Fields[0].AsInteger > 0 then
        Result := True;
    finally
      Close;
      Transaction := NIL;
      Free;
    end;
  end;
end;

function TdmTablaFacturasCliente.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 FACTURASCLIENTE ');
    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;

end.
