{
===============================================================================
  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: 26-12-2002
  Versión actual: 1.0.7
  Fecha versión actual: 17-11-2004
===============================================================================
  Modificaciones:

    Fecha         Comentarios
    ---------------------------------------------------------------------------
    25-03-2003    Añadido el recargo de equivalencia.

    10-05-2003    Error con el código de factura al escribirlo manualmente.

    25-08-2003    Al dar de alta una factura, el cliente debe estar también
                  dado de alta.

    02-02-2004    Se ha eliminado el atributo SERIE (P8 MULTIEMPRESA)
                  Se ha adaptado a los nuevos contadores

    17-05-2004    Codigo de presupuesto no se puede modificar porque hay dos tablas
                  que dependen de el y seria muy costoso mantener la politica de codigos
                  de la aplicacion en este apartado.

    19-07-2004    p13. En los menus contextuales deben aparecer las opciones
                  de cortar, copiar y pegar.

    06-10-2004    p26. Se ha eliminado la tabla DETALLESFACTURASCLIPROPIEDADES.

    17-11-2004    Cuando ha mejorado la inserción de una factura cuando el código
                  ya ha sido utilizado por otro usuario.
===============================================================================
}

unit FacturaCliente;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Grids, DBGrids, RdxBotones, RdxTitulos, StdCtrls,
  RdxMemo, RdxCampos, ExtCtrls, RdxComboBox, RdxPaneles, RdxBarras, ComCtrls,
  RdxRichEdit, RXDBCtrl, RdxFrame,
  RdxPageControl, RdxFrameFacturasCliente, Db, TablaArticulos,
  RdxRadioButton, RxMemDS, IBCustomDataSet, TablaPresupuestos, 
  cxStyles, cxCustomData, cxGraphics,
  cxFilter, cxData, cxEdit, cxDBData, cxGridLevel, cxClasses, cxControls,
  cxGridCustomView, cxGridCustomTableView, cxGridTableView,
  cxGridDBTableView, cxGrid, Configuracion, cxContainer, cxTextEdit,
  cxMaskEdit, cxDropDownEdit, cxCalendar, cxDBEdit,
  cxButtonEdit, cxMemo, cxSpinEdit, AdvPanel, ActnList, Menus,
  am2000menuitem, am2000popupmenu, am2000, RdxCheckBox, cxCheckBox, cxCalc,
  cxCurrencyEdit, cxLookupEdit, cxDBLookupEdit, cxDBLookupComboBox, IBQuery,

  TablaTrimestres,
  
  RdxEmpresaActiva, am2000utils, cxDataStorage;

type
  TfrFacturaCliente = class(TRdxFrameFacturasCliente)
    brSalir: TRdxBarraInferior;
    bSalir: TRdxBoton;
    brGuardar: TRdxBarraInferior;
    bGuardar: TRdxBoton;
    bCancelar: TRdxBoton;
    Titulo: TRdxPanelTituloOperacion;
    dsFactura: TDataSource;
    dsDetallesFacturas: TDataSource;
    pnlCuerpo: TPanel;
    pnlDatosFactura: TAdvPanel;
    eCodigo: TLabel;
    eEstadoFactura: TLabel;
    eFormaPago: TLabel;
    Label1: TLabel;
    Codigo: TcxDBButtonEdit;
    FechaFactura: TcxDBDateEdit;
    pnlGrid: TAdvPanel;
    Paginas: TRdxPagesControl;
    pagCliente: TTabSheet;
    pagContenido: TTabSheet;
    pnlGridArticulos: TPanel;
    pagObservaciones: TTabSheet;
    RdxPanel4: TPanel;
    Label3: TLabel;
    RdxPanel5: TPanel;
    Observaciones: TcxDBMemo;
    Label2: TLabel;
    CodCliente: TcxDBButtonEdit;
    eNIFCIF: TLabel;
    NIFCIF: TcxDBTextEdit;
    eNombre: TLabel;
    Nombre: TcxDBTextEdit;
    eDireccion: TLabel;
    Calle: TcxDBTextEdit;
    eProvincia: TLabel;
    Provincia: TcxDBButtonEdit;
    ePoblacion: TLabel;
    Poblacion: TcxDBButtonEdit;
    eTelefono1: TLabel;
    Telefono1: TcxDBTextEdit;
    eTelefono2: TLabel;
    Telefono2: TcxDBTextEdit;
    eNumero: TLabel;
    Numero: TcxDBTextEdit;
    ePiso: TLabel;
    Piso: TcxDBTextEdit;
    eCodigoPostal: TLabel;
    CodigoPostal: TcxDBTextEdit;
    eFax: TLabel;
    Fax: TcxDBTextEdit;
    eMovil2: TLabel;
    Movil2: TcxDBTextEdit;
    eMovil1: TLabel;
    Movil1: TcxDBTextEdit;
    ePersona: TLabel;
    PersonaContacto: TcxDBTextEdit;
    cbxSituacion: TcxDBComboBox;
    cbxFormaPago: TcxDBComboBox;
    pnlImportes: TAdvPanel;
    Label7: TLabel;
    Label8: TLabel;
    Panel1: TPanel;
    Label5: TLabel;
    Label9: TLabel;
    BaseImponible: TcxDBTextEdit;
    ImporteTotal: TcxDBTextEdit;
    ImporteDescuento: TcxDBTextEdit;
    ImporteIVA: TcxDBTextEdit;
    RdxPanel1: TRdxPanel;
    Label10: TLabel;
    Label11: TLabel;
    Shape2: TShape;
    Panel2: TPanel;
    cbRecargoEquivalencia: TcxCheckBox;
    Descuento: TcxDBTextEdit;
    IVA: TcxDBTextEdit;
    RecargoEquivalencia: TcxDBTextEdit;
    cbxDocumento: TcxDBLookupComboBox;
    eDocumento: TLabel;
    TablaDocumentos: TIBQuery;
    dsDocumentos: TDataSource;
    pnlBarraGrid: TRdxPanel;
    bAnadirCon: TRdxBoton;
    bEliminar: TRdxBoton;
    bEliminarTodo: TRdxBoton;
    bEditarPropiedades: TRdxBoton;
    ActionList1: TActionList;
    actAnadirConcepto: TAction;
    actEliminar: TAction;
    actEliminarTodo: TAction;
    actEditarPropiedades: TAction;
    gridDetalles: TcxGrid;
    VistaDetalles: TcxGridDBTableView;
    VistaPropiedades2: TcxGridDBTableView;
    gridDetallesLevel1: TcxGridLevel;
    eTrimestre: TLabel;
    cbxTrimestres: TcxComboBox;
    eTrimestreCerrado: TLabel;
    cbComisiones: TcxDBCheckBox;
    procedure bCancelarClick(Sender: TObject);
    procedure bSalirClick(Sender: TObject);
    procedure bGuardarClick(Sender: TObject);
    procedure CodClienteExit(Sender: TObject);
    procedure CodigoPropertiesButtonClick(Sender: TObject;
      AButtonIndex: Integer);
    procedure CodClientePropertiesButtonClick(Sender: TObject;
      AButtonIndex: Integer);
    procedure ProvinciaPropertiesButtonClick(Sender: TObject;
      AButtonIndex: Integer);
    procedure PoblacionPropertiesButtonClick(Sender: TObject;
      AButtonIndex: Integer);
    procedure actAnadirConceptoExecute(Sender: TObject);
    procedure actEliminarExecute(Sender: TObject);
    procedure actEliminarTodoExecute(Sender: TObject);
    procedure cbRecargoEquivalenciaPropertiesChange(Sender: TObject);
    procedure actEliminarUpdate(Sender: TObject);
    procedure actEliminarTodoUpdate(Sender: TObject);
    procedure VistaDetallesEditing(Sender: TcxCustomGridTableView;
      AItem: TcxCustomGridTableItem; var AAllow: Boolean);
    procedure cbxDocumentoPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption;
      var Error: Boolean);
  private
    FListaTrimestres: TListaTrimestres;
    FCodigoProvincia : Variant;
    FCodigoPoblacion : Variant;
    FCodigoCliente : Variant;
    FCodigoArticulo : Variant;
    FTablaDetallesMem : TRxMemoryData;
    FTablaPropiedadesMem : TRxMemoryData;
    procedure CalcularTotalDetalle;
    procedure CalcularTotalFactura;
    procedure ActivarEventosCampos;
    procedure DesactivarEventosCampos;
    procedure CargarDatosDocumento(CodigoDocumento : String);
    procedure CodCliSetText(Sender: TField; const Text: String);
    procedure IVASetText(Sender: TField; const Text: String);
    procedure DtoSetText(Sender: TField; const Text: String);
    procedure RESetText(Sender: TField; const Text: String);
    procedure InsertarReferenciaAPresupuesto (DatosPre : TDatosPresupuesto);
    procedure BorrarDetalles;
    procedure SalvarDetalles;
    procedure CargarDetalles;
    procedure BorrarDetallesIB;
    procedure ReordenarDetallesMem;
    procedure IntercambiarDetallesMem(PosCon1, PosCon2 : Integer);
    procedure AsignarNumConceptoDetalles;
    procedure DetalleAfterDelete (DataSet: TDataSet);
    procedure GridBotonCodigoArticuloClick(Sender: TObject; AButtonIndex: Integer);
    procedure CodigoArticuloDetalleSetText(Sender: TField; const Text: String);
    procedure CantidadDetalleSetText(Sender: TField; const Text: String);
    procedure PrecioDetalleSetText(Sender: TField; const Text: String);
    procedure ProvinciaSetText(Sender: TField; const Text: String);
    procedure DetallesAfterInsert(DataSet: TDataSet);
    function GetCodigoCliente: Variant;
  protected
    procedure ActivarModoAnadir; override;
    procedure ActivarModoModificar; override;
    procedure ActivarModoConsultar; override;
    procedure ActivarModoEliminar; override;
    function AnadirDatos : Boolean; override;
    function ModificarDatos : Boolean; override;
    function EliminarDatos : Boolean; override;
    function CancelarAnadir : Boolean; override;
    function CancelarModificar : Boolean; override;
    function CancelarEliminar : Boolean; override;
    function ComprobarDatos : Boolean; override;
    procedure VerModal; override;
    procedure SetCodigoProvincia (Value : Variant); virtual;
    procedure SetCodigoPoblacion (Value : Variant); virtual;
    procedure SetCodigoCliente (Value : Variant);
    procedure SetCodigoArticulo (Value : Variant);
    procedure FreeContenido; override;
    procedure BuscarFactura; override;
    property TablaDetallesMem : TRxMemoryData read FTablaDetallesMem write FTablaDetallesMem;
  public
    property CodigoProvincia : Variant read FCodigoProvincia write SetCodigoProvincia;
    property CodigoPoblacion : Variant read FCodigoPoblacion write SetCodigoPoblacion;
    property CodigoCliente : Variant read GetCodigoCliente write SetCodigoCliente;
    property CodigoArticulo : Variant read FCodigoArticulo write SetCodigoArticulo;
    constructor Create (AOwner : TComponent); override;
    destructor Destroy; override;
  published
    property TablaFacturas;
    property TablaDetallesFacturas;
    property CodigoFactura;
  end;

var
  frFacturaCliente: TfrFacturaCliente;

implementation

{$R *.DFM}

uses
  cxGridDBDataDefinitions, Variants, Entidades, FacturasClientes, BaseDatos,
  Mensajes, Clientes, RdxFrameProvincias, RdxFramePoblaciones,
  TablaProvincias, Provincias, Poblaciones, TablaClientes, RdxFrameClientes,
  IB, Articulos, RdxFrameArticulos, Constantes, IBDatabase, TablaDocumentos,
  StrFunc, TablaPoblaciones, TablaFormasPago, NumFunc, TablaFamilias,
  IBSQL, Excepciones, IBErrorCodes, Literales, ElegirDireccionCliente,
  TablaFacturasCliente, TablaEmpresas;

procedure TfrFacturaCliente.bCancelarClick(Sender: TObject);
begin
  if (TratarCambios = IDOK) then
    CloseFrame;
end;

procedure TfrFacturaCliente.bSalirClick(Sender: TObject);
begin
  try
    Rollback;
    CloseFrame;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrFacturaCliente.bGuardarClick(Sender: TObject);
begin
  if (RealizarOperacion) then
    CloseFrame;
end;

procedure TfrFacturaCliente.ActivarModoAnadir;
var
  CodNuevo : Variant;
begin
  if Entidad in dsFacturaCliente then
    pnlDatosFactura.Caption.Text := 'Datos de la ' + CaptionsEntidades[Entidad]
  else
    if Entidad in dsAbonoCliente then
      pnlDatosFactura.Caption.Text := 'Datos del ' + CaptionsEntidades[Entidad];

  dsFactura.AutoEdit := True;
  dsDetallesFacturas.AutoEdit := True;
  pnlBarraGrid.Visible := True;

  Codigo.Properties.Buttons[0].Visible := False;
  Codigo.Properties.ReadOnly := False;
  CodCliente.Properties.Buttons[0].Visible := True;
  Poblacion.Properties.Buttons[0].Visible := True;
  Provincia.Properties.Buttons[0].Visible := True;
  cbRecargoEquivalencia.Checked := False;
  RecargoEquivalencia.Enabled := False;
  cbxTrimestres.Enabled  := True;
  cbxTrimestres.Properties.ReadOnly := False;

  try
    CodNuevo := dmTablaFacturasCliente.DarNuevoCodigo;

    with TablaFacturas do
    begin
      Close;
      Prepare;
      Open;
      FieldByName('PROVINCIA').OnSetText := ProvinciaSetText;
      Insert;
      Codigo.DataBinding.Field.AsString := CodNuevo;
      Codigo.Properties.ReadOnly := True;
      FieldByName('CODIGOEMPRESA').AsInteger := EmpresaActiva.Codigo;
      FieldByName('FECHAALTA').AsDateTime := dmBaseDatos.DarFecha;
      FieldByName('CLASEFACTURA').AsString := CTE_CF_FACTURA;
      FieldByName('USUARIO').AsString := dmBaseDatos.Usuario;
      FieldByName('IVA').AsString := EmpresaActiva.IvaDefecto;
      FieldByName('COMISION').AsInteger := 1;
      FechaFactura.DataBinding.Field.AsDateTime := dmBaseDatos.DarFecha;
      cbxSituacion.DataBinding.Field.AsString := cbxSituacion.Properties.Items[0];
    end;

    with TablaDetallesFacturas do
    begin
      Close;
      Params.ByName('CODIGOEMPRESA').AsInteger := EmpresaActiva.Codigo;
      Params.ByName('CODIGOFACTURA').AsString := CodNuevo;
      Prepare;
      Open;
    end;

    with TablaDetallesMem do
    begin
      Close;
      Open;
    end;

    dmTablaFacturasCliente.InicializarTablaFacturas(@TablaFacturas);
    dmTablaFacturasCliente.InicializarTablaDetalles(@TablaDetallesMem);
    cbRecargoEquivalencia.Properties.ReadOnly := False;
    ActivarEdicionGridDetalles(VistaDetalles);
    cbxDocumento.DataBinding.Field.AsString := dmTablaDocumentos.DarCodigoDocumento(Entidad);
    CargarDatosDocumento(cbxDocumento.DataBinding.Field.AsString);

    ActivarEventosCampos;
    Visible := True;
    FechaFactura.SetFocus;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrFacturaCliente.ActivarModoConsultar;
var
  liResultado: Integer;

begin
  dsFactura.AutoEdit := False;
  dsDetallesFacturas.AutoEdit := False;
  pnlBarraGrid.Visible := False;

  Codigo.Properties.Buttons[0].Visible := True;
  CodCliente.Properties.Buttons[0].Visible := False;
  Poblacion.Properties.Buttons[0].Visible := False;
  Provincia.Properties.Buttons[0].Visible := False;

  try
    with TablaFacturas do
    begin
      Prepare;
      Open;

      liResultado := FListaTrimestres.getNumItem(FieldByName('CODIGOTRIMESTRE').AsString);
      if (liResultado = -1) then
      begin
        cbxTrimestres.EditText := dmTablaTrimestres.darDescripcionCompletaTrimestre(FieldByName('CODIGOTRIMESTRE').AsString);
        cbxTrimestres.Enabled  := False;
        cbxTrimestres.Properties.ReadOnly := True;
        eTrimestreCerrado.Visible := True;
      end
      else begin
        cbxTrimestres.ItemIndex := liResultado;
        cbxTrimestres.Enabled  := True;
        cbxTrimestres.Properties.ReadOnly := True;
        eTrimestreCerrado.Visible := False;
      end;

      if RecordCount = 0 then
      begin
        VerMensajeFmt(msgCliNoExisteFac, [CodigoFactura]);
        CloseFrame;
        Exit;
      end;
      Cancel;
    end;

    {with TablaDetallesFacturas do
    begin
      Close;
      Params.ByName('CODIGOFACTURA').AsString := CodigoFactura;
      Prepare;
      Open;
      Cancel;
    end;

    with TablaDetallesMem do
    begin
      Close;
      Open;
      Cancel;
      CargarDetalles;
    end;}

    dmTablaFacturasCliente.InicializarTablaFacturas(@TablaFacturas);
    dmTablaFacturasCliente.InicializarTablaDetalles(@TablaDetallesMem);

    if Entidad in dsFacturaCliente then
      Entidad := dmTablaDocumentos.darEntidadDocumento(entFacturaCliente, TablaFacturas.FieldByName('CODIGODOCUMENTO').AsString)
    else
      if Entidad in dsAbonoCliente then
        Entidad := dmTablaDocumentos.darEntidadDocumento(entAbonoCliente, TablaFacturas.FieldByName('CODIGODOCUMENTO').AsString);

    DesactivarEventosCampos;
    DesactivarEdicionGridDetalles(gridDetalles);
    cbRecargoEquivalencia.Checked := TablaFacturas.FieldByName('RE').AsFloat > 0;
    RecargoEquivalencia.Enabled := TablaFacturas.FieldByName('RE').AsFloat > 0;
    cbRecargoEquivalencia.Properties.ReadOnly := True;
    Visible := True;
    FechaFactura.SetFocus;    
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrFacturaCliente.ActivarModoEliminar;
var
  liResultado: Integer;
begin
  dsFactura.AutoEdit := False;
  dsDetallesFacturas.AutoEdit := False;
  pnlBarraGrid.Visible := False;

  Codigo.Properties.Buttons[0].Visible := True;
  CodCliente.Properties.Buttons[0].Visible := False;
  Poblacion.Properties.Buttons[0].Visible := False;
  Provincia.Properties.Buttons[0].Visible := False;

  try
    with TablaFacturas do
    begin

      liResultado := FListaTrimestres.getNumItem(FieldByName('CODIGOTRIMESTRE').AsString);
      if (liResultado = -1) then
      begin
        cbxTrimestres.EditText := dmTablaTrimestres.darDescripcionCompletaTrimestre(FieldByName('CODIGOTRIMESTRE').AsString);
        cbxTrimestres.Enabled  := False;
        cbxTrimestres.Properties.ReadOnly := True;
        eTrimestreCerrado.Visible := True;
      end
      else begin
        cbxTrimestres.ItemIndex := liResultado;
        cbxTrimestres.Enabled  := True;
        cbxTrimestres.Properties.ReadOnly := True;
        eTrimestreCerrado.Visible := False;
      end;

      if RecordCount = 0 then
      begin
        VerMensajeFmt(msgCliNoExisteFac, [CodigoFactura]);
        CancelarEliminar;
        CloseFrame;
        Exit;
      end;
      Cancel;
    end;

    dmTablaFacturasCliente.InicializarTablaFacturas(@TablaFacturas);
    dmTablaFacturasCliente.InicializarTablaDetalles(@TablaDetallesMem);

    if Entidad in dsFacturaCliente then
      Entidad := dmTablaDocumentos.darEntidadDocumento(entFacturaCliente, TablaFacturas.FieldByName('CODIGODOCUMENTO').AsString)
    else
      if Entidad in dsAbonoCliente then
        Entidad := dmTablaDocumentos.darEntidadDocumento(entAbonoCliente, TablaFacturas.FieldByName('CODIGODOCUMENTO').AsString);

    DesactivarEdicionGridDetalles(gridDetalles);
    cbRecargoEquivalencia.Checked := TablaFacturas.FieldByName('RE').AsFloat > 0;
    RecargoEquivalencia.Enabled := TablaFacturas.FieldByName('RE').AsFloat > 0;    
    cbRecargoEquivalencia.Properties.ReadOnly := True;
    Visible := True;
    FechaFactura.SetFocus;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrFacturaCliente.ActivarModoModificar;
var
  CodPreAlb : String;
  CodCargo : string;
  liResultado: Integer;
begin
  dsFactura.AutoEdit := True;
  dsDetallesFacturas.AutoEdit := True;
  pnlBarraGrid.Visible := True;

  Codigo.Properties.Buttons[0].Visible := True;
  Codigo.Properties.ReadOnly := True;
  CodCliente.Properties.Buttons[0].Visible := True;
  Poblacion.Properties.Buttons[0].Visible := True;
  Provincia.Properties.Buttons[0].Visible := True;

  try
    with TablaFacturas do
    begin
      liResultado := FListaTrimestres.getNumItem(FieldByName('CODIGOTRIMESTRE').AsString);
      if (liResultado = -1) then
      begin
        cbxTrimestres.EditText := dmTablaTrimestres.darDescripcionCompletaTrimestre(FieldByName('CODIGOTRIMESTRE').AsString);
        cbxTrimestres.Enabled  := False;
        cbxTrimestres.Properties.ReadOnly := True;
        eTrimestreCerrado.Visible := True;
      end
      else begin
        cbxTrimestres.ItemIndex := liResultado;
        cbxTrimestres.Enabled  := True;
        cbxTrimestres.Properties.ReadOnly := False;
        eTrimestreCerrado.Visible := False;        
      end;

      FieldByName('PROVINCIA').OnSetText := ProvinciaSetText;
      if RecordCount = 0 then
      begin
        VerMensajeFmt(msgCliNoExisteFac, [CodigoFactura]);
        CancelarModificar;
        CloseFrame;
        Exit;
      end;

      Edit;
      Post;
      Edit;
    end;

    dmTablaFacturasCliente.InicializarTablaFacturas(@TablaFacturas);
    dmTablaFacturasCliente.InicializarTablaDetalles(@TablaDetallesMem);
    CalcularTotalFactura;
    ActivarEdicionGridDetalles(gridDetalles);
    FCodigoProvincia := dmTablaProvincias.DarCodigoProvincia(Provincia.Text);

    if Entidad in dsFacturaCliente then
      Entidad := dmTablaDocumentos.darEntidadDocumento(entFacturaCliente, cbxDocumento.DataBinding.Field.AsString)
    else
      if Entidad in dsAbonoCliente then
        Entidad := dmTablaDocumentos.darEntidadDocumento(entAbonoCliente, cbxDocumento.DataBinding.Field.AsString);

    cbRecargoEquivalencia.Checked := TablaFacturas.FieldByName('RE').AsFloat > 0;
    RecargoEquivalencia.Enabled := TablaFacturas.FieldByName('RE').AsFloat > 0;
    cbRecargoEquivalencia.Properties.ReadOnly := False;
    ActivarEventosCampos;
    Visible := True;
    FechaFactura.SetFocus;
  except
    on E : EIBError do
    begin
      case E.IBErrorCode of
        isc_lock_conflict : begin
                              VerMensajeFmt(msgCliFacBloqueado, [CodigoFactura]);
                              CancelarModificar;
                              CloseFrame;
                              Exit;
                            end
        else
          TratarExcepcion(E);
      end;
    end;
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrFacturaCliente.AnadirDatos: Boolean;
var
  CodAux : String;
begin
  try
    TablaFacturas.Edit;
    CalcularTotalFactura;
    if Entidad in dsFacturaCliente then
        TablaFacturas.FieldByName('CLASEFACTURA').AsString := CTE_CF_FACTURA
    else
      if Entidad in dsAbonoCliente then
        TablaFacturas.FieldByName('CLASEFACTURA').AsString := CTE_CF_ABONO;

    TablaFacturas.FieldByName('TIPOFACTURA').AsInteger := CTE_TIPFAC_VENTA;
    TablaFacturas.FieldByName('CODIGOTRIMESTRE').AsString := dmTablaTrimestres.darCodigoTrimestre(TablaFacturas.FieldByName('FECHAFACTURA').AsDateTime); //FListaTrimestres.getCodItem(cbxTrimestres.ItemIndex);
    TablaFacturas.Post;

    BorrarDetallesIB;
    SalvarDetalles;

    dmTablaFacturasCliente.IncrementarCodigo;

    Commit;
    FCodigoFactura := TablaFacturas.FieldByName('CODIGO').AsString;
    Result := True;
  except
    on E : EIBError do begin
      if E.IBErrorCode = isc_unique_key_violation then
      begin
        // El código ya se ha utilizado
        TablaFacturas.Edit;
        CodAux := dmTablaFacturasCliente.DarNuevoCodigo;
        VerMensajeFmt(msgCliCodFacRepetido, [Codigo.DataBinding.Field.AsString, CodAux]);
        Codigo.DataBinding.Field.AsString := CodAux;
      end
      else
        TratarExcepcion(E);
    end;
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrFacturaCliente.BuscarFactura;
begin
  if Transaccion = NIL then
    exit;

  try
    TablaFacturas.DisableControls;
    TablaDetallesFacturas.DisableControls;
    TablaDetallesMem.DisableControls;

    DesactivarEventosCampos;

    TablaFacturas.Close;
    TablaDetallesFacturas.Close;
    TablaDetallesMem.Close;

    // Buscar la fila a tratar si es necesario
    if not EsCadenaVacia(FCodigoFactura) then
    begin
      TablaFacturas.ParamByName('CODIGOEMPRESA').AsInteger := EmpresaActiva.Codigo;
      TablaFacturas.ParamByName('CODIGO').AsString := FCodigoFactura;
      TablaDetallesFacturas.ParamByName('CODIGOEMPRESA').AsInteger := EmpresaActiva.Codigo;
      TablaDetallesFacturas.ParamByName('CODIGOFACTURA').AsString := FCodigoFactura;
    end;
    TablaFacturas.Prepare;
    TablaFacturas.Open;

    TablaDetallesFacturas.Prepare;
    TablaDetallesFacturas.Open;

    TablaDetallesMem.Open;
    CargarDetalles;

    if not TablaDocumentos.Active then
      TablaDocumentos.Open;

    dmTablaFacturasCliente.InicializarTablaFacturas(@TablaFacturas);
    dmTablaFacturasCliente.InicializarTablaDetalles(@TablaDetallesMem);

    if not EsCadenaVacia(FCodigoFactura) then
    begin
      if (UpperCase(TablaFacturas.FieldByName('CLASEFACTURA').AsString) = CTE_CF_FACTURA) then
      begin
        pnlDatosFactura.Caption.Text := 'Datos de la ' + CaptionsEntidades[entFacturaCliente];
        Entidad := entFacturaCliente;
      end
      else begin
        pnlDatosFactura.Caption.Text := 'Datos del ' + CaptionsEntidades[entAbonoCliente];
        Entidad := entAbonoCliente;
      end;
    end;

    ActivarEventosCampos;

    TablaFacturas.EnableControls;
    TablaDetallesFacturas.EnableControls;
    TablaDetallesMem.EnableControls;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrFacturaCliente.CalcularTotalDetalle;
var
  auxCantidad,
  auxPrecio,
  auxTotal : double;
begin
  with TablaDetallesMem do
  begin
    auxCantidad := FieldByName('CANTIDAD').AsFloat;
    auxPrecio := FieldByName('IMPORTEUNIDAD').AsFloat;
    auxTotal := (auxCantidad * auxPrecio);
    FieldByName('IMPORTETOTAL').AsFloat := auxTotal;
  end;
  CalcularTotalFactura;
end;

procedure TfrFacturaCliente.CalcularTotalFactura;
var
  BaseImponible,
  ImporteRE,
  ImporteIVA,
  ImporteDto,
  ImporteTotal : Double;
  FDetallesBookmark : string;
begin
  BaseImponible := 0;
  ImporteTotal := 0;
  with TablaDetallesMem do
  begin
    DisableControls;
    FDetallesBookmark := Bookmark;
    try
      First;
      while not EOF do begin
        BaseImponible := BaseImponible + FieldByName('IMPORTETOTAL').AsFloat;
        Next;
      end;

      ImporteRE := BaseImponible * (TablaFacturas.FieldByName('RE').AsFloat/100);
      ImporteDto := BaseImponible * (TablaFacturas.FieldByName('DESCUENTO').AsFloat/100);
      ImporteTotal := BaseImponible - ImporteDto;
      ImporteIVA := ImporteTotal * (TablaFacturas.FieldByName('IVA').AsFloat/100);
      ImporteTotal := ImporteTotal + ImporteIVA + ImporteRE;

      TablaFacturas.FieldByName('BASEIMPONIBLE').AsFloat := BaseImponible;
      TablaFacturas.FieldByName('IMPORTEDESCUENTO').AsFloat := ImporteDto;
      TablaFacturas.FieldByName('IMPORTERE').AsFloat := ImporteRE;
      TablaFacturas.FieldByName('IMPORTEIVA').AsFloat := ImporteIVA;
      TablaFacturas.FieldByName('IMPORTETOTAL').AsFloat := ImporteTotal;
    finally
      Bookmark := FDetallesBookmark;
      EnableControls;
    end;
  end;
end;

function TfrFacturaCliente.CancelarAnadir: Boolean;
begin
  Result := False;
  try
    TablaFacturas.Cancel;
    TablaDetallesMem.Cancel;
    RollBack;
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrFacturaCliente.CancelarEliminar: Boolean;
begin
  Result := False;
  try
    RollBack;
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrFacturaCliente.CancelarModificar: Boolean;
begin
  Result := False;
  try
    TablaFacturas.Cancel;
    TablaDetallesMem.Cancel;
    RollBack;
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrFacturaCliente.ComprobarDatos: Boolean;
begin
  Result := False;

  if EsCadenaVacia(FechaFactura.DataBinding.Field.AsString) then
  begin
    VerMensaje(msgCliFaltaFechaAlta);
    FechaFactura.SetFocus;
    Exit;
  end;

  if Modo = Anadir then
  begin
    if EsCadenaVacia(CodCliente.DataBinding.Field.AsString) then
    begin
      VerMensaje(msgCliFaltaCodCli);
      Paginas.ActivePageIndex := 0;
      CodCliente.SetFocus;
      Exit;
    end
  end
  else
  begin
    if EsCadenaVacia(Nombre.DataBinding.Field.AsString) then
    begin
      VerMensaje(msgCliFaltaNombreCli);
      Paginas.ActivePageIndex := 0;
      Nombre.SetFocus;
      Exit;
    end
  end;

  if TablaDetallesMem.IsEmpty then
  begin
    VerMensaje(msgCliFaltaArticulos);
    Paginas.ActivePage := pagContenido;
    gridDetalles.SetFocus;
    Exit;
  end;

  Result := True;
end;

constructor TfrFacturaCliente.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Entidad := entFacturaCliente;

  FCodigoProvincia := NULL;
  FCodigoPoblacion := NULL;
  FCodigoCliente := NULL;
  FCodigoArticulo := NULL;

  BaseDatos := dmBaseDatos.BD;
  Transaccion := dmBaseDatos.Transaccion;

  TablaFacturas := TIBDataSet.Create(Self);
  TablaDetallesFacturas := TIBDataSet.Create(Self);
  TablaDetallesMem := TRxMemoryData.Create(Self);

  dsFactura.DataSet := TablaFacturas;
  dsDetallesFacturas.DataSet := TablaDetallesMem;

  with TablaDocumentos do
  begin
    Database := BaseDatos;
    Transaction := Transaccion;
    SQL.Assign(dmTablaDocumentos.sqlDatosDocumento);
  end;

  with TablaFacturas do
  begin
    Database := BaseDatos;
    Transaction := Transaccion;
    SelectSQL.Assign(dmTablaFacturasCliente.sqlConsultarFactura);
    InsertSQL.Assign(dmTablaFacturasCliente.sqlInsertarFactura);
    ModifySQL.Assign(dmTablaFacturasCliente.sqlModificarFactura);
    DeleteSQL.Assign(dmTablaFacturasCliente.sqlEliminarFactura);
  end;

  with TablaDetallesFacturas do
  begin
    Database := BaseDatos;
    Transaction := Transaccion;
    SelectSQL.Assign(dmTablaFacturasCliente.sqlConsultarGridDetalles);
    InsertSQL.Assign(dmTablaFacturasCliente.sqlInsertarDetalles);
    ModifySQL.Assign(dmTablaFacturasCliente.sqlModificarDetalles);
    DeleteSQL.Assign(dmTablaFacturasCliente.sqlEliminarDetalles);
  end;

  with TablaDetallesMem do
  begin
    CopyStructure(TablaDetallesFacturas);
  end;

  FListaTrimestres := TListaTrimestres.Create(tlcTriAbiertos);
  cbxTrimestres.ItemIndex := FListaTrimestres.cargarLista(cbxTrimestres.Properties.Items);

  dmTablaFacturasCliente.InicializarGridDetalles(VistaDetalles);
  cbxSituacion.Properties.Items := dmTablaFacturasCliente.DarSituaciones;
  dmTablaArticulos.ArtModelo := entArticulo;
  cbxFormaPago.Properties.Items := dmTablaFormasPago.DarFormasPago;
  Paginas.ActivePage := pagCliente;
end;

destructor TfrFacturaCliente.Destroy;
begin
  TablaDocumentos.Close;

  TablaDetallesMem.Close;
  TablaDetallesMem.Free;

  TablaFacturas.Close;
  TablaFacturas.UnPrepare;
  TablaFacturas.Free;

  TablaDetallesFacturas.Close;
  TablaDetallesFacturas.Unprepare;
  TablaDetallesFacturas.Free;

  FListaTrimestres.Free;
  FListaTrimestres := Nil;
  inherited;
end;

function TfrFacturaCliente.EliminarDatos: Boolean;
begin
  Result := False;

  try
    if dmTablaFacturasCliente.EsUltimaFactura(Codigo.DataBinding.Field.AsString) then
       dmTablaFacturasCliente.DecrementarCodigo;

    TablaFacturas.Delete;
    BorrarDetalles;
    Commit;
    Result := True;
  except
    on E : EIBError do
    begin
      case E.IBErrorCode of
        isc_lock_conflict : VerMensajeFmt(msgCliFacBloqueado, [Codigo.DataBinding.Field.AsString]);
        else
          TratarExcepcion(E);
      end;
    end;
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrFacturaCliente.FreeContenido;
var
  Contador : integer;
  ListaCodigos : TStringList;
begin
  if (ContenidoModal is TRdxFrameFacturasCliente) then begin
    CodigoFactura := (ContenidoModal as TRdxFrameFacturasCliente).CodigoFactura;
    ActivarModo;
  end;
  if (ContenidoModal is TfrArticulos) then
    CodigoArticulo := (ContenidoModal as TRdxFrameArticulos).CodigoArticulo;
  if (ContenidoModal is TRdxFrameClientes) then
    CodigoCliente := (ContenidoModal as TRdxFrameClientes).CodigoCliente;
  if (ContenidoModal is TRdxFrameProvincias) then
    CodigoProvincia := (ContenidoModal as TRdxFrameProvincias).CodigoProvincia;
  if (ContenidoModal is TRdxFramePoblaciones) then begin
    CodigoProvincia := (ContenidoModal as TRdxFramePoblaciones).CodigoProvincia;
    CodigoPoblacion := (ContenidoModal as TRdxFramePoblaciones).CodigoPoblacion;
  end;
  inherited FreeContenido;
end;

function TfrFacturaCliente.ModificarDatos: Boolean;
begin
  Result := False;
  try
//    if (cbxTrimestres.Enabled) then
//      TablaFacturas.FieldByName('CODIGOTRIMESTRE').AsString := FListaTrimestres.getCodItem(cbxTrimestres.ItemIndex);
    TablaFacturas.FieldByName('CODIGOTRIMESTRE').AsString := dmTablaTrimestres.darCodigoTrimestre(TablaFacturas.FieldByName('FECHAFACTURA').AsDateTime);

    CalcularTotalFactura;
    TablaFacturas.Post;

    BorrarDetallesIB;
    SalvarDetalles;

    Commit;
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrFacturaCliente.SetCodigoArticulo(Value: Variant);
var
  CodigoAux : String;
  DatosArticulo : TDatosArticulo;
begin
  if (EsCadenaVacia(Value)) then
  begin
    FCodigoArticulo := CodigoAux;
    Exit;
  end;

  CodigoAux := Trim(Value);
  if (dmTablaArticulos.ValidarCodigo(CodigoAux)) then
  begin
    CodigoAux := dmTablaArticulos.FormatearCodigo(CodigoAux);
    if (dmTablaArticulos.ExisteCodigo(CodigoAux)) then
      FCodigoArticulo := CodigoAux
    else begin
      raise Exception.CreateFmt(msgDatosCodArtNoExiste, [CodigoAux]);
    end;
  end
  else begin
    raise Exception.CreateFmt(msgDatosCodArtIncorrecto, [CodigoAux]);
    Exit;
  end;

  DatosArticulo := TDatosArticulo.Create(CodigoAux);
  try
    with TablaDetallesMem do
    begin
      Edit;
      FieldByName('CODIGOFACTURA').AsString := Codigo.DataBinding.Field.AsString;
      FieldByName('NUMCONCEPTO').AsString := dmTablaPresupuestos.FormatearNumConcepto(IntToStr(RecNo));
      FieldByName('CODIGOARTICULO').AsString := DatosArticulo.Codigo;
      FieldByName('DESCRIPCION').AsString := DatosArticulo.Descripcion;
      FieldByName('IMPORTEUNIDAD').AsString := DatosArticulo.Precio;
      FieldByName('CANTIDAD').AsString := '1';
      Post;
      Edit;
      CalcularTotalDetalle;
      gridDetalles.Refresh;
    end;
    FCodigoArticulo := Value;
  finally
    DatosArticulo.Free;
  end;
end;

procedure TfrFacturaCliente.SetCodigoCliente(Value: Variant);
var
  DatosCliente : TDatosCliente;
  CodAux : Variant;
  DireccionElegida : TDireccionElegida;
  NumSucursal : Integer;
begin
  if EsCadenaVacia(Value) then
    exit;

  CodAux := Trim(Value);
  if (dmTablaClientes.ValidarCodigo(CodAux)) then begin
    CodAux := dmTablaClientes.FormatearCodigo(CodAux);
    if (dmTablaClientes.ExisteCodigo(CodAux)) then
      FCodigoCliente := CodAux
    else begin
      raise Exception.CreateFmt(msgCliCodCliNoExiste, [CodAux]);
    end;
  end
  else begin
    raise Exception.CreateFmt(msgCliCodCliIncorrecto, [CodAux]);
  end;

  DatosCliente := TDatosCliente.Create(FCodigoCliente);
  try
    CodCliente.DataBinding.Field.AsString := DatosCliente.Codigo;
    if DatosCliente.Sucursales.Count > 0 then
    begin
      frElegirDireccionCliente := TfrElegirDireccionCliente.Create(Self);
      try
        frElegirDireccionCliente.Cliente := DatosCliente;
        frElegirDireccionCliente.ShowModal;
        DireccionElegida := frElegirDireccionCliente.DireccionSeleccionada;
        NumSucursal := frElegirDireccionCliente.NumSucursal;
      finally
        frElegirDireccionCliente.Free;
      end;
    end
    else
      DireccionElegida := dePrincipal;

    if DireccionElegida = dePrincipal then
    begin
      NIFCIF.DataBinding.Field.AsString := DatosCliente.Nifcif;
      Nombre.DataBinding.Field.AsString := DatosCliente.Nombre;
      Calle.DataBinding.Field.AsString := DatosCliente.Calle;
      Numero.DataBinding.Field.AsString := DatosCliente.Numero;
      Piso.DataBinding.Field.AsString := DatosCliente.Piso;
      Provincia.DataBinding.Field.AsString := DatosCliente.Provincia;
      FCodigoProvincia := dmTablaProvincias.DarCodigoProvincia(DatosCliente.Provincia);
      Poblacion.DataBinding.Field.AsString := DatosCliente.Poblacion;
      CodigoPostal.DataBinding.Field.AsString := DatosCliente.CodigoPostal;
      Telefono1.DataBinding.Field.AsString := DatosCliente.Telefono1;
      Telefono2.DataBinding.Field.AsString := DatosCliente.Telefono2;
      Movil1.DataBinding.Field.AsString := DatosCliente.Movil1;
      Movil2.DataBinding.Field.AsString := DatosCliente.Movil2;
      Fax.DataBinding.Field.AsString := DatosCliente.Fax;
      PersonaContacto.DataBinding.Field.AsString := DatosCliente.PersonaContacto;
    end
    else begin
      with DatosCliente.Sucursales do
      begin
        NIFCIF.DataBinding.Field.AsString := Sucursal[NumSucursal].Nifcif;
        Nombre.DataBinding.Field.AsString := Sucursal[NumSucursal].Nombre;
        Calle.DataBinding.Field.AsString := Sucursal[NumSucursal].Calle;
        Numero.DataBinding.Field.AsString := Sucursal[NumSucursal].Numero;
        Piso.DataBinding.Field.AsString := Sucursal[NumSucursal].Piso;
        Provincia.DataBinding.Field.AsString := Sucursal[NumSucursal].Provincia;
        FCodigoProvincia := dmTablaProvincias.DarCodigoProvincia(Sucursal[NumSucursal].Provincia);
        Poblacion.DataBinding.Field.AsString := Sucursal[NumSucursal].Poblacion;
        CodigoPostal.DataBinding.Field.AsString := Sucursal[NumSucursal].CodigoPostal;
        Telefono1.DataBinding.Field.AsString := Sucursal[NumSucursal].Telefono1;
        Telefono2.DataBinding.Field.AsString := Sucursal[NumSucursal].Telefono2;
        Movil1.DataBinding.Field.AsString := Sucursal[NumSucursal].Movil1;
        Movil2.DataBinding.Field.AsString := Sucursal[NumSucursal].Movil2;
        Fax.DataBinding.Field.AsString := Sucursal[NumSucursal].Fax;
        PersonaContacto.DataBinding.Field.AsString := Sucursal[NumSucursal].PersonaContacto;
      end;
    end;
  finally
    DatosCliente.Free;
  end;
end;

procedure TfrFacturaCliente.SetCodigoPoblacion(Value: Variant);
begin
  if (not EsCadenaVacia(Value)) then
  begin
    FCodigoPoblacion := Value;
    Poblacion.DataBinding.Field.AsString := dmTablaPoblaciones.darNombrePoblacion(FCodigoProvincia, FCodigoPoblacion);
  end;
end;

procedure TfrFacturaCliente.SetCodigoProvincia(Value: Variant);
begin
  if (not EsCadenaVacia(Value)) then
  begin
    FCodigoProvincia := Value;
    Provincia.DataBinding.Field.AsString := dmTablaProvincias.DarNombreProvincia(FCodigoProvincia);
  end;
end;

procedure TfrFacturaCliente.VerModal;
begin
  if (ContenidoModal is TRdxFramePoblaciones) then
    (ContenidoModal as TRdxFramePoblaciones).CodigoProvincia := CodigoProvincia;

  if (ContenidoModal is TRdxFrameClientes) then
    (ContenidoModal as TRdxFrameClientes).CodigoCliente := CodigoCliente;

  if (ContenidoModal is TfrArticulos) then
  begin
    FCodigoArticulo := TablaDetallesMem.FieldByName('CODIGOARTICULO').AsString;
    if EsCadenaVacia(FCodigoArticulo) then
    begin
      if (not EsCadenaVacia(TablaDocumentos.FieldByName('DESCFAMILIA').AsString)) then
         (ContenidoModal as TfrArticulos).Familia := TablaDocumentos.FieldByName('DESCFAMILIA').AsString;
    end
    else begin
      (ContenidoModal as TfrArticulos).Familia := TablaDocumentos.FieldByName('DESCFAMILIA').AsString;
      (ContenidoModal as TfrArticulos).CodigoArticulo := FCodigoArticulo;
    end;
  end;
    
  inherited;
end;

procedure TfrFacturaCliente.CantidadDetalleSetText(Sender: TField;
  const Text: String);
begin
  Sender.AsString := Text;
  CalcularTotalDetalle;
end;

procedure TfrFacturaCliente.CodigoArticuloDetalleSetText(Sender: TField;
  const Text: String);
var
  Codigo : String;
begin
  Sender.AsString := Text;
  CodigoArticulo := Text;
end;

procedure TfrFacturaCliente.GridBotonCodigoArticuloClick(Sender: TObject; AButtonIndex: Integer);
begin
  TablaDetallesMem.Edit;
  ContenidoModal := TfrArticulos.Create(Self);
  gridDetalles.SetFocus;
end;

procedure TfrFacturaCliente.PrecioDetalleSetText(Sender: TField;
  const Text: String);
begin
  {if EsCadenaVacia(Text) then begin
    Sender.AsString := '0';
    exit;
  end;}
  Sender.AsString := Text;

  if Entidad in dsAbonoCliente then
  begin
    try
      if StrToFloat(Text) > 0
      then begin
        Sender.AsFloat := (-1) * StrToFloat(Text)
      end
      else Sender.AsString := Text;
    except
      on E : EConvertError do begin
        Sender.AsString := '0'
      end;
    end;
  end
  else
    Sender.AsString := Text;
  CalcularTotalDetalle;
end;

procedure TfrFacturaCliente.CodClienteExit(Sender: TObject);
begin
  if not (Modo in [Anadir, Modificar]) then
    Exit;
end;

procedure TfrFacturaCliente.DtoSetText(Sender: TField; const Text: String);
begin
  if EsCadenaVacia(Text) then
    Sender.AsString := '0'
  else begin
    ValidarDto(Text);
    Sender.AsString := Text;
  end;
  CalcularTotalFactura;
end;

procedure TfrFacturaCliente.IVASetText(Sender: TField; const Text: String);
begin
  if EsCadenaVacia(Text) then
    Sender.AsString := '0'
  else begin
    ValidarIVA(Text);
    Sender.AsString := Text;
  end;
  CalcularTotalFactura;
end;

procedure TfrFacturaCliente.InsertarReferenciaAPresupuesto (DatosPre : TDatosPresupuesto);
var
  FechaAux : String;
begin
{  FechaAux := FormatDateTime('d "de" mmmm "de" yyyy', StrToDate(DatosPre.FechaAlta));
  TablaFacturas.FieldByName('DESCRIPCION').AsString := Format(msgDescripcionFacturaPre, [DatosPre.Codigo, FechaAux]);

  // Añadir un concepto con el importe del presupuesto
  try
    with TablaDetallesMem do
    begin
      DisableControls;
      Append;
      FieldByName('CODIGOFACTURA').AsString := Codigo.DataBinding.Field.AsString;
      FieldByName('NUMCONCEPTO').AsString := '0000000000';
      FieldByName('TIPO').AsString := 'CON';
      FieldByName('DESCRIPCION').AsString := 'Presupuesto ' + DatosPre.Codigo;
      FieldByName('CANTIDAD').AsString := '1';
      FieldByName('IMPORTEUNIDAD').AsString := DatosPre.ImporteTotal;
      FieldByName('PRECIO').AsString := DatosPre.ImporteTotal;
      FieldByName('IMPORTETOTAL').AsString := DatosPre.ImporteTotal;
      Post;
      EnableControls;
    end;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;}
end;

procedure TfrFacturaCliente.BorrarDetalles;
begin
  with TablaDetallesMem do
  begin
    DisableControls;
    EmptyTable;
    EnableControls;
  end;
end;

procedure TfrFacturaCliente.BorrarDetallesIB;
begin
  with TablaDetallesFacturas do
  begin
    if IsEmpty then
      Exit;
    DisableControls;
    Last;
    while not BOF do
    begin
      Delete;
      Prior;
    end;
    if not IsEmpty then
      Delete;
    EnableControls;
  end;
end;

procedure TfrFacturaCliente.CargarDetalles;
var
  NumeroCampo : Integer;
begin
  with TablaDetallesMem do
  begin
    if TablaDetallesFacturas.IsEmpty then
      Exit;
    DisableControls;
    TablaDetallesFacturas.First;
    while not TablaDetallesFacturas.EOF do
    begin
      Append;
      for NumeroCampo := 0 to TablaDetallesFacturas.FieldCount-1 do
        Fields[NumeroCampo].AsString := TablaDetallesFacturas.Fields[NumeroCampo].AsString;
      Post;
      TablaDetallesFacturas.Next;
    end;
    First;
    EnableControls;
  end;
end;

procedure TfrFacturaCliente.SalvarDetalles;
var
  NumeroCampo : Integer;
begin
  try
    with TablaDetallesMem do
    begin
      if IsEmpty then
        Exit;
      DisableControls;
      First;
      while not EOF do
      begin
        TablaDetallesFacturas.Append;
        for NumeroCampo := 0 to FieldCount-1 do
        begin
          if Fields[NumeroCampo].FieldName = 'CODIGOEMPRESA' then
            TablaDetallesFacturas.Fields[NumeroCampo].AsInteger := EmpresaActiva.Codigo
          else if Fields[NumeroCampo].FieldName = 'CODIGOFACTURA' then
            TablaDetallesFacturas.Fields[NumeroCampo].AsString := Codigo.DataBinding.Field.AsString
          else
            if Fields[NumeroCampo].FieldName = 'NUMCONCEPTO' then
              TablaDetallesFacturas.Fields[NumeroCampo].AsString := dmTablaPresupuestos.FormatearNumConcepto(IntToStr(RecNo))
            else
              TablaDetallesFacturas.Fields[NumeroCampo].AsVariant := Fields[NumeroCampo].AsVariant;
        end;
        TablaDetallesFacturas.Post;
        Next;
      end;
      EnableControls;
    end
  except
    on E : EIBError do begin
      if E.IBErrorCode = isc_unique_key_violation then
      begin
        TablaDetallesFacturas.Delete;
        TablaDetallesMem.EnableControls;
      end;
      raise EIBError.Create(E.SQLCode, E.IBErrorCode, E.Message);
    end;
  end;
end;

procedure TfrFacturaCliente.DetalleAfterDelete(DataSet: TDataSet);
begin
  AsignarNumConceptoDetalles;
  CalcularTotalFactura;
end;

procedure TfrFacturaCliente.ProvinciaSetText(Sender: TField;
  const Text: String);
begin
  FCodigoProvincia := dmTablaProvincias.DarCodigoProvincia(Text);
  Sender.AsString := Text;
end;

procedure TfrFacturaCliente.CodigoPropertiesButtonClick(Sender: TObject;
  AButtonIndex: Integer);
begin
  if (TratarCambios = IDCANCEL) then
    Exit;
  { Esto es porque en modo 'Modificar' hacemos un cambio y pulsamos
    este botón se cierra la tabla y si en el frame hijo (el del grid) damos
    a cancelar, FCodigoFactura es NULL y da error al activar modo porque
    no se inicializa los parámetros de la sql. Lo hace BuscarFactura. }
  if not TablaFacturas.Active then
    BuscarFactura;
  ContenidoModal := TfrFacturasClientes.Create(Self);
end;

procedure TfrFacturaCliente.CodClientePropertiesButtonClick(
  Sender: TObject; AButtonIndex: Integer);
begin
  ContenidoModal := TfrClientes.Create(Self);
end;

procedure TfrFacturaCliente.ProvinciaPropertiesButtonClick(Sender: TObject;
  AButtonIndex: Integer);
begin
  CaptionModal := msgListaProvincias;
  WidthModal := 280;
  HeightModal := 460;
  ContenidoModal := TfrProvincias.Create(Self);
end;

procedure TfrFacturaCliente.PoblacionPropertiesButtonClick(Sender: TObject;
  AButtonIndex: Integer);
begin
  if EsCadenaVacia(CodigoProvincia) then
  begin
    VerMensaje(msgSinProvincia);
    Paginas.ActivePageIndex := 0;
    Provincia.SetFocus;
    Exit;
  end;
  CaptionModal := Format(msgListaPoblaciones, [dmTablaProvincias.darNombreProvincia(CodigoProvincia)]);
  WidthModal := 280;
  HeightModal := 460;
  ContenidoModal := TfrPoblaciones.Create(Self);
end;

procedure TfrFacturaCliente.ActivarEventosCampos;
begin
  cbRecargoEquivalencia.Properties.OnChange := cbRecargoEquivalenciaPropertiesChange;

  with TablaFacturas do
  begin
    FieldByName('CODIGOCLIENTE').OnSetText := CodCliSetText;
    FieldByName('IVA').OnSetText := IVASetText;
    FieldByName('DESCUENTO').OnSetText := DtoSetText;
    FieldByName('RE').OnSetText := RESetText;
  end;

  with TablaDetallesMem do
  begin
    FieldByName('CODIGOARTICULO').OnSetText := CodigoArticuloDetalleSetText;
    FieldByName('CANTIDAD').OnSetText := CantidadDetalleSetText;
    FieldByName('IMPORTEUNIDAD').OnSetText := PrecioDetalleSetText;
    AfterDelete := DetalleAfterDelete;
    AfterInsert := DetallesAfterInsert;
  end;

  with VistaDetalles do
  begin
    TcxButtonEditProperties(GetColumnByFieldName('CODIGOARTICULO').Properties).OnButtonClick := GridBotonCodigoArticuloClick;
  end;
end;

procedure TfrFacturaCliente.DetallesAfterInsert(DataSet: TDataSet);
var
  DatosDocumento : TDocumento;
begin
  with DataSet do
  begin
    DatosDocumento := TDocumento.Create(TablaFacturas.FieldByName('CODIGODOCUMENTO').AsString);
    try
      Edit;
      FieldByName('CODIGOFACTURA').AsString := Codigo.DataBinding.Field.AsString;
      FieldByName('NUMCONCEPTO').AsString := dmTablaFacturasCliente.FormatearNumConcepto(IntToStr(RecNo));
      FieldByName('DESCRIPCION').AsString := #13+#13+#13;
      {if EsCadenaVacia(FieldByName('CANTIDAD').AsString) then
        FieldByName('CANTIDAD').AsString := '1';}
      Post;
      AsignarNumConceptoDetalles;
      Edit;
    finally
      DatosDocumento.Free;
    end;
  end;
end;

procedure TfrFacturaCliente.actAnadirConceptoExecute(Sender: TObject);
begin
  try
    with TablaDetallesMem do
    begin
      //DisableControls;
      Next;
      if EOF then
        Append
      else begin
        Prior;
        Insert;
      end;
      //EnableControls;
    end;
    Paginas.ActivePage := pagContenido;
    gridDetalles.SetFocus;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrFacturaCliente.actEliminarExecute(Sender: TObject);
begin
  if (VerMensajePregunta(msgDeseaBorrar) <> IDYES) then
    Exit;
  if TablaDetallesMem.RecordCount = 0 then begin
    { Hacemos un cancel de la tabla por si el registro actual estuviera
      recien creado }
    TablaDetallesMem.Cancel;
    Exit
  end;
  try
    TablaDetallesMem.Delete;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
  CalcularTotalFactura;
end;

procedure TfrFacturaCliente.actEliminarTodoExecute(Sender: TObject);
begin
  if (VerMensajePregunta(msgDeseaBorrarTodo) <> IDYES) then
    Exit;
  BorrarDetalles;
  CalcularTotalFactura;
end;

procedure TfrFacturaCliente.ReordenarDetallesMem;
var
  NumConcepto : Integer;
  CurBookmark: string;
begin
  try
    with TablaDetallesMem do
    begin
      if IsEmpty then
        Exit;
      NumConcepto := RecordCount;
      DisableControls;
      CurBookmark := Bookmark;
      Last;
      while not BOF do
      begin
        Edit;
        FieldByName('NUMCONCEPTO').AsString := dmTablaFacturasCliente.FormatearNumConcepto(IntToStr(NumConcepto));
        Post;
        Dec(NumConcepto);
        Prior;
      end;
      Bookmark := CurBookmark;
      EnableControls;
    end
  except
    on E : EIBError do begin
      if E.IBErrorCode = isc_unique_key_violation then
        TablaDetallesMem.EnableControls;
      raise EIBError.Create(E.SQLCode, E.IBErrorCode, E.Message);
    end;
  end;
end;

procedure TfrFacturaCliente.IntercambiarDetallesMem(PosCon1,
  PosCon2: Integer);
var
  NumCon1,
  NumCon2 : Variant;
begin
  try
    with TablaDetallesMem do
    begin
      DisableControls;
      RecNo := PosCon1;
      NumCon1 := FieldByName('NUMCONCEPTO').AsString;
      RecNo := PosCon2;
      NumCon2 := FieldByName('NUMCONCEPTO').AsString;

      // Intercambio los concepto
      Edit;
      FieldByName('NUMCONCEPTO').AsString := NumCon1;
      Post;
      RecNo := PosCon1;
      Edit;
      FieldByName('NUMCONCEPTO').AsString := NumCon2;
      Post;
      EnableControls;
      ReordenarDetallesMem;
    end;
  except
    TablaDetallesMem.EnableControls;
  end;
end;

function TfrFacturaCliente.GetCodigoCliente: Variant;
begin
  if TablaFacturas.Active then
    Result := TablaFacturas.FieldByName('CODIGOCLIENTE').AsVariant
  else
    Result := NULL;
end;

procedure TfrFacturaCliente.cbRecargoEquivalenciaPropertiesChange(
  Sender: TObject);
begin
  RecargoEquivalencia.Enabled := cbRecargoEquivalencia.Checked;
  if not cbRecargoEquivalencia.Checked then
  begin
    RecargoEquivalencia.DataBinding.Field.Value := Null;
    CalcularTotalFactura;
  end;
end;

procedure TfrFacturaCliente.RESetText(Sender: TField; const Text: String);
begin
  if EsCadenaVacia(Text) then
    Sender.AsString := '0'
  else begin
    ValidarDto(Text);
    Sender.AsString := Text;
  end;
  CalcularTotalFactura;
end;

procedure TfrFacturaCliente.DesactivarEventosCampos;
begin
  cbRecargoEquivalencia.Properties.OnChange := NIL;

  with TablaFacturas do
  begin
    if FindField('CODIGOCLIENTE') <> NIL then
      FieldByName('CODIGOCLIENTE').OnSetText := NIL;
    if FindField('IVA') <> NIL then
      FieldByName('IVA').OnSetText := NIL;
    if FindField('DESCUENTO') <> NIL then
      FieldByName('DESCUENTO').OnSetText := NIL;
    if FindField('RE') <> NIL then
      FieldByName('RE').OnSetText := NIL;
  end;

  with TablaDetallesMem do
  begin
    if FindField('CODIGOARTICULO') <> NIL then
      FieldByName('CODIGOARTICULO').OnSetText := NIL;
    if FindField('CANTIDAD') <> NIL then
      FieldByName('CANTIDAD').OnSetText := NIL;
    if FindField('IMPORTEUNIDAD') <> NIL then
      FieldByName('IMPORTEUNIDAD').OnSetText := NIL;
    AfterDelete := NIL;
    AfterInsert := NIL;
  end;

  with VistaDetalles do
  begin
    if GetColumnByFieldName('CODIGOARTICULO') <> NIL then
      TcxButtonEditProperties(GetColumnByFieldName('CODIGOARTICULO').Properties).OnButtonClick := NIL;
  end;
 
end;

procedure TfrFacturaCliente.CodCliSetText(Sender: TField;
  const Text: String);
begin
  Sender.AsString := Text; 
  CodigoCliente := Text;
end;

procedure TfrFacturaCliente.actEliminarUpdate(Sender: TObject);
begin
  if not (Modo in [Anadir, Modificar]) then
    (Sender as TAction).Enabled := False
  else
    (Sender as TAction).Enabled := not (TablaDetallesMem.RecordCount = 0);
end;

procedure TfrFacturaCliente.actEliminarTodoUpdate(Sender: TObject);
begin
  if not (Modo in [Anadir, Modificar]) then
    (Sender as TAction).Enabled := False
  else
    (Sender as TAction).Enabled := not (TablaDetallesMem.RecordCount = 0);
end;

procedure TfrFacturaCliente.VistaDetallesEditing(
  Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem;
  var AAllow: Boolean);
begin
{  AAllow := True;
  if (AItem.DataBinding as TcxGridItemDBDataBinding).FieldName = 'DESCRIPCION' then
  begin
    if ArticuloConPropiedades(TablaDetallesMem.FieldByName('NUMCONCEPTO').AsString) then
    begin
      AAllow := False;
      actEditarPropiedades.Execute;
    end;
  end;}
end;

procedure TfrFacturaCliente.AsignarNumConceptoDetalles;
var
  FDetallesBookmark : string;
  NumConAnt,
  NumConNue : String;
begin
  with TablaDetallesMem do
  begin
    DisableControls;
    FDetallesBookmark := Bookmark;
    try
      Last;
      while not BOF do
      begin
        Edit;
        NumConAnt := FieldByName('NUMCONCEPTO').AsString;
        NumConNue := dmTablaFacturasCliente.FormatearNumConcepto(IntToStr(RecNo));
        FieldByName('NUMCONCEPTO').AsString := NumConNue;
        Post;
        Prior;
      end;
    finally
      EnableControls;
      Bookmark := FDetallesBookmark;
    end;
  end;
end;

procedure TfrFacturaCliente.cbxDocumentoPropertiesValidate(Sender: TObject;
  var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
begin
  if VerMensajePreguntaFmt(msgCliCambiarTipoPre, [cbxDocumento.Text]) = mrYES then
    CargarDatosDocumento(TablaDocumentos.FieldByName('CODIGO').AsString)
  else begin
    ErrorText := '';
    Error := True;
    cbxDocumento.Undo;  // Restaurar el valor anterior
  end;
end;

procedure TfrFacturaCliente.CargarDatosDocumento(CodigoDocumento: String);
var
  DocAux : TDocumento;
begin
  DocAux := TDocumento.Create(CodigoDocumento);
  if Entidad in dsFacturaCliente then
    Entidad := dmTablaDocumentos.DarEntidadDocumento(entFacturaCliente, DocAux.Codigo)
  else
    if Entidad in dsAbonoCliente then
      Entidad := dmTablaDocumentos.DarEntidadDocumento(entAbonoCliente, DocAux.Codigo);
end;

end.
