{
===============================================================================
  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: 03-11-2002
  Versión actual: 1.0.0
  Fecha versión actual: 03-11-2002
===============================================================================
  Modificaciones:

    Fecha         Comentarios
    ---------------------------------------------------------------------------
===============================================================================
}

unit Cliente;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  RdxBotones, StdCtrls, RdxMemo, RdxComboBox, RdxCampos, ExtCtrls,
  RdxTitulos, ComCtrls, RdxCheckBox, Grids, DBGrids, RdxPaneles,
  RdxBarras, Db, RdxFrame, RdxDBFrame, RdxFrameClientes, RXDBCtrl,
  RdxPageControl, IB, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData,
  cxEdit, cxDBData, cxGridLevel, cxClasses, cxControls, cxGridCustomView,
  cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxGrid,
  cxGridCardView, cxGridDBCardView, RxMemDS, Configuracion, cxMemo,
  cxDBEdit, cxContainer, cxTextEdit, cxMaskEdit, cxButtonEdit, AdvPanel,
  cxDataStorage, cxDropDownEdit, cxLookupEdit, cxDBLookupEdit,
  cxDBLookupComboBox, IBCustomDataSet;

type
  TfrCliente = class(TRdxFrameClientes)
    pnlCuerpo: TPanel;
    brDoble: TRdxBarraInferior;
    bGuardar: TRdxBoton;
    bCancelar: TRdxBoton;
    brSimple: TRdxBarraInferior;
    bSalir: TRdxBoton;
    pnlTitulo: TRdxPanelTituloOperacion;
    PanelDirecciones: TRdxPanel;
    Paginas: TRdxPagesControl;
    pagDireccion: TTabSheet;
    pagSucursales: TTabSheet;
    pnlGridArticulos: TPanel;
    pnlBarraGrid: TRdxPanel;
    bAnadir: TRdxBoton;
    bEliminar: TRdxBoton;
    bEliminarTodo: TRdxBoton;
    dsSucursales: TDataSource;
    dsCliente: TDataSource;
    gridSucursales: TcxGrid;
    gridSucursalesLevel: TcxGridLevel;
    gridSucursalesDBCardView: TcxGridDBCardView;
    dsDireccion: TDataSource;
    pnlProveedor: TAdvPanel;
    eCodigo: TLabel;
    eNombre: TLabel;
    eProcedencia: TLabel;
    eVendedor: TLabel;
    eNIFCIF: TLabel;
    eObservaciones: TLabel;
    Codigo: TcxDBButtonEdit;
    Nombre: TcxDBTextEdit;
    Vendedor: TcxDBButtonEdit;
    Observaciones: TcxDBMemo;
    NIF: TcxDBTextEdit;
    eDireccion: TLabel;
    Calle: TcxDBTextEdit;
    eProvincia: TLabel;
    Provincia: TcxDBButtonEdit;
    ePoblacion: TLabel;
    Poblacion: TcxDBButtonEdit;
    eTelefono1: TLabel;
    Telefono1: TcxDBTextEdit;
    Label2: TLabel;
    Movil1: TcxDBTextEdit;
    eCorreo: TLabel;
    PersonaContacto: TcxDBTextEdit;
    eTelefono2: TLabel;
    Telefono2: TcxDBTextEdit;
    Label3: TLabel;
    Movil2: TcxDBTextEdit;
    eFax: TLabel;
    Fax: TcxDBTextEdit;
    eCodigoPostal: TLabel;
    CodigoPostal: TcxDBTextEdit;
    eNumero: TLabel;
    Numero: TcxDBTextEdit;
    ePiso: TLabel;
    Piso: TcxDBTextEdit;
    Label1: TLabel;
    Correo: TcxDBTextEdit;
    cbxProcedencia: TcxDBLookupComboBox;
    dsProcedencias: TDataSource;
    procedure bSalirClick(Sender: TObject);
    procedure bAceptarClick(Sender: TObject);
    procedure CodigoExit(Sender: TObject);
    procedure bCancelarClick(Sender: TObject);
    procedure bAnadirClick(Sender: TObject);
    procedure bEliminarClick(Sender: TObject);
    procedure bEliminarTodoClick(Sender: TObject);
    procedure gridSucursalesResize(Sender: TObject);
    procedure pagSucursalesShow(Sender: TObject);
    procedure gridSucursalesDBCardViewKeyDown(Sender: TObject;
      var Key: Word; Shift: TShiftState);
    procedure dsSucursalesStateChange(Sender: TObject);
    procedure VendedorPropertiesButtonClick(Sender: TObject;
      AButtonIndex: Integer);
    procedure CodigoPropertiesButtonClick(Sender: TObject;
      AButtonIndex: Integer);
    procedure ProvinciaPropertiesButtonClick(Sender: TObject;
      AButtonIndex: Integer);
    procedure PoblacionPropertiesButtonClick(Sender: TObject;
      AButtonIndex: Integer);
  private
    FTablaProcedencias : TIBDataSet;
    FCodigoProvincia : Variant;
    FCodigoPoblacion : Variant;
    FCodigoProvinciaDireccion : Variant;
    FCodigoPoblacionDireccion : Variant;
    FCodigoProvinciaSucursal : Variant;
    FCodigoPoblacionSucursal : Variant;
    FCodigoVendedor : Variant;
    FTablaDireccionMem : TRxMemoryData;
    FTablaSucursalesMem : TRxMemoryData;
    procedure CargarDatosDireccion;
    procedure CargarDatosSucursales;
    procedure SalvarDatosDireccion;
    procedure SalvarDatosSucursales;
    procedure BorrarDatosSucursalesIB;
    procedure SucursalesMemAfterInsert(DataSet: TDataSet);
    procedure GridBotonPoblacionClick(Sender: TObject; AButtonIndex: Integer);
    procedure GridBotonProvinciaClick(Sender: TObject; AButtonIndex: Integer);
    procedure ProvinciaSetText(Sender: TField; const Text: String);
    procedure ProvinciaSucursalSetText(Sender: TField; const Text: String);
  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 SetCodigoVendedor (Value : Variant); virtual;
    procedure SetCodigoProvinciaDireccion (Value : Variant); virtual;
    procedure SetCodigoPoblacionDireccion (Value : Variant); virtual;
    procedure SetCodigoProvinciaSucursal (Value : Variant); virtual;
    procedure SetCodigoPoblacionSucursal (Value : Variant); virtual;
    procedure FreeContenido; override;
    procedure BuscarCliente; override;
  public
    property CodigoProvincia : Variant read FCodigoProvincia write SetCodigoProvincia;
    property CodigoPoblacion : Variant read FCodigoPoblacion write SetCodigoPoblacion;
    property CodigoProvinciaDireccion : Variant read FCodigoProvinciaDireccion write SetCodigoProvinciaDireccion;
    property CodigoPoblacionDireccion : Variant read FCodigoPoblacionDireccion write SetCodigoPoblacionDireccion;
    property CodigoProvinciaSucursal : Variant read FCodigoProvinciaSucursal write SetCodigoProvinciaSucursal;
    property CodigoPoblacionSucursal : Variant read FCodigoPoblacionSucursal write SetCodigoPoblacionSucursal;
    property CodigoVendedor : Variant read FCodigoVendedor write SetCodigoVendedor;
    constructor Create (AOwner : TComponent); override;
    destructor Destroy; override;
  published
    property TablaClientes;
    property TablaSucursales;
    property TablaDireccionMem : TRxMemoryData read FTablaDireccionMem write FTablaDireccionMem;
    property TablaSucursalesMem : TRxMemoryData read FTablaSucursalesMem write FTablaSucursalesMem;
    property CodigoCliente;
  end;

var
  frCliente: TfrCliente;

implementation
{$R *.DFM}

uses
  RdxFrameVendedores, TablaClientes, Mensajes, Provincias, Entidades,
  Poblaciones, Clientes, Variants, Vendedores, BaseDatos, RdxFrameProvincias,
  RdxFramePoblaciones, TablaProvincias, StrFunc, TablaPoblaciones, Excepciones,
  IBErrorCodes, TablaSucursalesCliente, TablaVendedores, Literales, TablaProcedencias;

constructor TfrCliente.Create (AOwner : TComponent);
begin
  inherited Create(AOwner);
  Entidad := entCliente;

  FCodigoProvincia := NULL;
  FCodigoPoblacion := NULL;
  FCodigoVendedor := NULL;
  FCodigoProvinciaDireccion := NULL;
  FCodigoPoblacionDireccion := NULL;
  FCodigoProvinciaSucursal := NULL;
  FCodigoPoblacionSucursal := NULL;

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

  TablaClientes := TIBDataSet.Create(Self);
  TablaSucursales := TIBDataSet.Create(Self);
  TablaSucursalesMem := TRxMemoryData.Create(Self);
  TablaDireccionMem := TRxMemoryData.Create(Self);

  dsCliente.DataSet := TablaClientes;
  dsSucursales.DataSet := TablaSucursalesMem;
  dsSucursales.OnStateChange := dsSucursalesStateChange;
  dsDireccion.DataSet := TablaDireccionMem;

  with TablaClientes do
  begin
    Database := BaseDatos;
    Transaction := Transaccion;
    SelectSQL.Assign(dmTablaClientes.sqlConsultar);
    InsertSQL.Assign(dmTablaClientes.sqlInsertar);
    ModifySQL.Assign(dmTablaClientes.sqlModificar);
    DeleteSQL.Assign(dmTablaClientes.sqlEliminar);
    RefreshSQL.Assign(dmTablaClientes.sqlConsultar);
  end;

  FTablaProcedencias := TIBDataSet.Create(Self);
  dsProcedencias.DataSet := FTablaProcedencias;
  with FTablaProcedencias do
  begin
    Database := BaseDatos;
    Transaction := Transaccion;
    SelectSQL.Assign(dmTablaProcedencias.sqlConsultar);
    prepare;
    open;
  end;

  with TablaSucursales do
  begin
    Database := BaseDatos;
    Transaction := Transaccion;
    SelectSQL.Assign(dmTablaSucursalesCliente.sqlGrid);
    InsertSQL.Assign(dmTablaSucursalesCliente.sqlInsertar);
    ModifySQL.Assign(dmTablaSucursalesCliente.sqlModificar);
    DeleteSQL.Assign(dmTablaSucursalesCliente.sqlEliminar);
    RefreshSQL.Assign(dmTablaSucursalesCliente.sqlConsultar);
  end;

  TablaDireccionMem.CopyStructure(TablaSucursales);
  TablaSucursalesMem.CopyStructure(TablaSucursales);
  dmTablaSucursalesCliente.InicializarGridSucursales(gridSucursalesDBCardView);
  Paginas.ActivePageIndex := 0;

  bCancelar.Cancel := True;
  bSalir.Cancel := True;
end;

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

procedure TfrCliente.bAceptarClick(Sender: TObject);
begin
  if (RealizarOperacion) then
    CloseFrame;
end;

function TfrCliente.AnadirDatos : boolean;
begin
  Result := False;
  try
    TablaClientes.Post;

    BorrarDatosSucursalesIB;
    SalvarDatosDireccion;
    SalvarDatosSucursales;

    CodigoCliente := TablaClientes.FieldByName('CODIGO').AsString;
    dmTablaClientes.IncrementarCodigo;
    Commit;

    TablaClientes.Close;
    TablaSucursales.Close;
    TablaDireccionMem.Close;
    TablaSucursalesMem.Close;

    Result := True;
  except
    on E : EIBError do begin
      if E.IBErrorCode = isc_unique_key_violation then
      begin
        VerMensajeFmt(msgCliCodCliRepetido, [Codigo.DataBinding.Field.AsString]);
        TablaClientes.Edit;
      end
      else
        TratarExcepcion(E);
    end;
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrCliente.ModificarDatos : boolean;
begin
  Result := False;
  try
    TablaClientes.Post;
    BorrarDatosSucursalesIB;
    SalvarDatosDireccion;
    SalvarDatosSucursales;

    Commit;

    TablaClientes.Close;
    TablaDireccionMem.Close;
    TablaSucursalesMem.Close;
    TablaSucursales.Close;
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrCliente.EliminarDatos : boolean;
begin
  Result := False;
  try
    TablaClientes.Delete;
    Commit;
    TablaClientes.Close;
    TablaSucursales.Close;
    Result := True;
  except
    on E : EIBError do
    begin
      case E.IBErrorCode of
        isc_lock_conflict : VerMensajeFmt(msgCliCliBloqueado, [Codigo.DataBinding.Field.AsString]);
        isc_foreign_key : VerMensajeFmt(msgCliCliNoElim, [Codigo.DataBinding.Field.AsString]);
        else
          TratarExcepcion(E);
      end;
    end;
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrCliente.ActivarModoAnadir;
var
  CodNuevo : Variant;
begin
  dsCliente.AutoEdit := True;
  dsSucursales.AutoEdit := True;
  dsDireccion.AutoEdit := True;
  pnlBarraGrid.Visible := True;

  ActivarEdicionGridDetalles(gridSucursales);
  with gridSucursalesDBCardView do
  begin
    TcxButtonEditProperties(GetRowByFieldName('PROVINCIA').Properties).OnButtonClick := GridBotonProvinciaClick;
    TcxButtonEditProperties(GetRowByFieldName('POBLACION').Properties).OnButtonClick := GridBotonPoblacionClick;
  end;

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

  try
    CodNuevo := dmTablaClientes.DarNuevoCodigo;

    with TablaClientes do
    begin
      Close;
      Prepare;
      Open;
      Insert;
      FieldByName('CODIGO').AsString := CodNuevo;
      FieldByName('FECHAALTA').AsDateTime := dmBaseDatos.DarFecha;
      FieldByName('USUARIO').AsString := dmBaseDatos.Usuario;
    end;

    with TablaSucursales do
    begin
      Close;
      Prepare;
      Params.ByName('CODIGOCLIENTE').AsString := CodNuevo;
      Open;
      FieldByName('PROVINCIA').OnSetText := ProvinciaSucursalSetText;
    end;

    with TablaDireccionMem do
    begin
      Close;
      Open;
      FieldByName('PROVINCIA').OnSetText := ProvinciaSetText;
      Insert;
    end;

    with TablaSucursalesMem do
    begin
      Close;
      AfterInsert := SucursalesMemAfterInsert;
      Open;
    end;

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

procedure TfrCliente.ActivarModoModificar;
begin
  dsCliente.AutoEdit := True;
  dsSucursales.AutoEdit := True;
  dsDireccion.AutoEdit := True;
  pnlBarraGrid.Visible := True;

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

  ActivarEdicionGridDetalles(gridSucursales);
  with gridSucursalesDBCardView do
  begin
    TcxButtonEditProperties(GetRowByFieldName('PROVINCIA').Properties).OnButtonClick := GridBotonProvinciaClick;
    TcxButtonEditProperties(GetRowByFieldName('POBLACION').Properties).OnButtonClick := GridBotonPoblacionClick;
  end;

  try
    with TablaClientes do
    begin
      Prepare;
      Open;
      if RecordCount = 0 then
      begin
        VerMensajeFmt(msgCliNoExisteCli, [CodigoCliente]);
        CancelarModificar;
        CloseFrame;
        Exit;
      end;
      // Bloquear el cliente
      Edit;
      Post;
      Edit;
    end;

    with TablaSucursales do
    begin
      Close;
      Params.ByName('CODIGOCLIENTE').AsString := Codigo.DataBinding.Field.AsString;
      Prepare;
      Open;
    end;

    with TablaDireccionMem do
    begin
      Close;
      Open;
      CargarDatosDireccion;
      FieldByName('PROVINCIA').OnSetText := ProvinciaSetText;
      if not IsEmpty then
        Edit;
    end;

    with TablaSucursalesMem do
    begin
      Close;
      Open;
      CargarDatosSucursales;
      AfterInsert := SucursalesMemAfterInsert;
      if not IsEmpty then
        Edit;
    end;

    // Bloquear las sucursales
    with TablaSucursales do
    begin
      if RecordCount > 0 then
      begin
        Edit;
        Post;
        Edit;
      end;
    end;

    FCodigoProvinciaDireccion := dmTablaProvincias.DarCodigoProvincia(Provincia.Text);
    Visible := True;
    NIF.SetFocus;    
  except
    on E : EIBError do
    begin
      case E.IBErrorCode of
        isc_lock_conflict : begin
                              VerMensajeFmt(msgCliCliBloqueado, [CodigoCliente]);
                              CancelarModificar;
                              CloseFrame;
                              Exit;
                            end
        else
          TratarExcepcion(E);
      end;
    end;
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrCliente.ActivarModoConsultar;
begin
  dsCliente.AutoEdit := False;
  dsSucursales.AutoEdit := False;
  dsDireccion.AutoEdit := False;
  pnlBarraGrid.Visible := False;

  DesactivarEdicionGridDetalles(gridSucursales);

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

  try
    with TablaClientes do
    begin
      Prepare;
      Open;
      if RecordCount = 0 then
      begin
        VerMensajeFmt(msgCliNoExisteCli, [CodigoCliente]);
        CancelarModificar;
        CloseFrame;
        Exit;
      end;
    end;

    with TablaSucursales do
    begin
      Close;
      Params.ByName('CODIGOCLIENTE').AsString := Codigo.DataBinding.Field.AsString;
      Prepare;
      Open;
    end;

    with TablaDireccionMem do
    begin
      Close;
      Open;
      CargarDatosDireccion;
    end;

    with TablaSucursalesMem do
    begin
      Close;
      Open;
      CargarDatosSucursales;
    end;

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

procedure TfrCliente.ActivarModoEliminar;
begin
  dsCliente.AutoEdit := False;
  dsSucursales.AutoEdit := False;
  dsDireccion.AutoEdit := False;
  pnlBarraGrid.Visible := False;

  DesactivarEdicionGridDetalles(gridSucursales);

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

  try
    with TablaClientes do
    begin
      Prepare;
      Open;
      if RecordCount = 0 then
      begin
        VerMensajeFmt(msgCliNoExisteCli, [CodigoCliente]);
        CancelarModificar;
        CloseFrame;
        Exit;
      end;
    end;

    with TablaSucursales do
    begin
      Close;
      Params.ByName('CODIGOCLIENTE').AsString := Codigo.DataBinding.Field.AsString;
      Prepare;
      Open;
    end;

    with TablaDireccionMem do
    begin
      Close;
      Open;
      CargarDatosDireccion;
    end;

    with TablaSucursalesMem do
    begin
      Close;
      Open;
      CargarDatosSucursales;
    end;
    Visible := True;
    NIF.SetFocus;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrCliente.CodigoExit(Sender: TObject);
begin
  inherited;
  if (Modo <> Anadir) or (Visible = false) then
    exit;

  if not esCadenaVacia(Codigo.Text) then
  begin
    if (dmTablaClientes.validarCodigo(Codigo.Text)) then
    begin
      Codigo.DataBinding.Field.AsString := dmTablaClientes.formatearCodigo(Codigo.Text);
      if (dmTablaClientes.existeCodigo(Codigo.Text)) then begin
        VerMensajeFmt(msgCliCodCliRepetido, [Codigo.Text]);
        Codigo.SetFocus;
      end;
    end
    else begin
      VerMensajeFmt(msgCliCodCliIncorrecto, [Codigo.Text]);
      Codigo.SetFocus;
    end;
  end
  else
    Codigo.DataBinding.Field.AsString := dmTablaClientes.darNuevoCodigo;
end;

procedure TfrCliente.BuscarCliente;
begin
  if Transaccion = NIL then
    exit;
  try
    TablaClientes.Close;

    // Buscar la fila a tratar si es necesario
    if not esCadenaVacia(CodigoCliente) then
    begin
        TablaClientes.Params.ByName('CODIGO').AsString := CodigoCliente;
        TablaSucursales.Params.ByName('CODIGOCLIENTE').AsString := CodigoCliente;
    end;
    TablaClientes.Prepare;
    TablaSucursales.Prepare;
    TablaClientes.Open;
    TablaSucursales.Open;    
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrCliente.CancelarAnadir: Boolean;
begin
  Result := False;
  try
    RollBack;

    TablaClientes.Close;
    TablaSucursales.Close;
    TablaDireccionMem.Close;
    TablaSucursalesMem.Close;
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrCliente.CancelarEliminar: Boolean;
begin
  Result := False;
  try
    RollBack;
    TablaClientes.Close;
    TablaDireccionMem.Close;
    TablaSucursalesMem.Close;
    TablaSucursales.Close;
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

function TfrCliente.CancelarModificar: Boolean;
begin
  Result := False;
  try
    RollBack;
    TablaClientes.Close;
    TablaDireccionMem.Close;
    TablaSucursalesMem.Close;
    TablaSucursales.Close;
    Result := True;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

destructor TfrCliente.Destroy;
begin
  gridSucursalesDBCardView.DataController.DataSource := NIL;

  TablaDireccionMem.Close;
  TablaDireccionMem.Free;

  TablaSucursalesMem.Close;
  TablaSucursalesMem.Free;

  FTablaProcedencias.Close;
  FTablaProcedencias.UnPrepare;
  FTablaProcedencias.Free;

  TablaSucursales.Close;
  TablaSucursales.UnPrepare;
  TablaSucursales.Free;

  TablaClientes.Close;
  TablaClientes.UnPrepare;
  TablaClientes.Free;

  inherited;
end;

procedure TfrCliente.FreeContenido;
begin
  if (ContenidoModal is TRdxFrameClientes) then begin
    CodigoCliente := (ContenidoModal as TRdxFrameClientes).CodigoCliente;
    ActivarModo;
  end;
  if (ContenidoModal is TRdxFrameVendedores) then
    CodigoVendedor := (ContenidoModal as TRdxFrameVendedores).CodigoVendedor;
  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;

procedure TfrCliente.SetCodigoPoblacion(Value: Variant);
begin
  if FCodigoPoblacion <> Value then
    FCodigoPoblacion := Value;
end;

procedure TfrCliente.SetCodigoProvincia(Value: Variant);
begin
  if FCodigoProvincia <> Value then
    FCodigoProvincia := Value;
end;

procedure TfrCliente.VerModal;
begin
  if (ContenidoModal is TRdxFrameClientes) then
    (ContenidoModal as TRdxFrameClientes).CodigoCliente := CodigoCliente;

  if (ContenidoModal is TRdxFramePoblaciones) then
    (ContenidoModal as TRdxFramePoblaciones).CodigoProvincia := CodigoProvincia;

  inherited;
end;

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

procedure TfrCliente.bAnadirClick(Sender: TObject);
begin
  try
    Paginas.ActivePageIndex := 1;
    gridSucursales.SetFocus;
    with TablaSucursalesMem do
    begin
      Append;
      Post;
      Edit;
      FieldByName('CALLE').FocusControl;
    end;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

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

procedure TfrCliente.GridBotonPoblacionClick(Sender: TObject; AButtonIndex: Integer);
begin
  FCodigoProvinciaSucursal := dmTablaProvincias.darCodigoProvincia(TablaSucursalesMem.FieldByName('PROVINCIA').AsString);
  if (esCadenaVacia(CodigoProvinciaSucursal)) then begin
    VerMensaje(msgSinProvincia);
    Exit;
  end;
  TablaSucursalesMem.Edit;
  CodigoProvincia := CodigoProvinciaSucursal;
  CaptionModal := Format(msgListaPoblaciones, [dmTablaProvincias.darNombreProvincia(CodigoProvincia)]);
  WidthModal := 280;
  HeightModal := 460;
  ContenidoModal := TfrPoblaciones.Create(Self);
  CodigoPoblacionSucursal := CodigoPoblacion;
end;

procedure TfrCliente.SetCodigoPoblacionDireccion(Value: Variant);
begin
  if (not esCadenaVacia(FCodigoPoblacionDireccion)) and (FCodigoPoblacionDireccion = Value) then
    exit;

  if (not esCadenaVacia(Value)) then
  begin
    FCodigoPoblacionDireccion := Value;
    Poblacion.DataBinding.Field.AsString := dmTablaPoblaciones.darNombrePoblacion(FCodigoProvinciaDireccion, FCodigoPoblacionDireccion);
  end;
end;

procedure TfrCliente.SetCodigoPoblacionSucursal(Value: Variant);
begin
  if (not esCadenaVacia(FCodigoPoblacionSucursal)) and (FCodigoPoblacionSucursal = Value) then
    exit;

  if (not esCadenaVacia(Value)) then
  begin
    FCodigoPoblacionSucursal := Value;
    TablaSucursalesMem.FieldByName('POBLACION').AsString := dmTablaPoblaciones.DarNombrePoblacion(FCodigoProvinciaSucursal, FCodigoPoblacionSucursal);
  end;
end;

procedure TfrCliente.SetCodigoProvinciaDireccion(Value: Variant);
begin
  if (not esCadenaVacia(FCodigoProvinciaDireccion)) and (FCodigoProvinciaDireccion = Value) then
    exit;

  if (not esCadenaVacia(Value)) then
  begin
    FCodigoProvinciaDireccion := Value;
    Provincia.DataBinding.Field.AsString := dmTablaProvincias.darNombreProvincia(FCodigoProvinciaDireccion);
  end;
end;

procedure TfrCliente.SetCodigoProvinciaSucursal(Value: Variant);
begin
  if (not esCadenaVacia(FCodigoProvinciaSucursal)) and (FCodigoProvinciaSucursal = Value) then
    exit;

  if (not esCadenaVacia(Value)) then
  begin
    FCodigoProvinciaSucursal := Value;
    TablaSucursalesMem.FieldByName('PROVINCIA').AsString := dmTablaProvincias.darNombreProvincia(FCodigoProvinciaSucursal);
  end;
end;

procedure TfrCliente.SucursalesMemAfterInsert(DataSet: TDataSet);
begin
  with DataSet do
  begin
    FieldByName('CODIGOCLIENTE').AsString := Codigo.DataBinding.Field.AsString;
    FieldByName('CODIGO').AsString := '-';
    FieldByName('NIFCIF').AsString := NIF.DataBinding.Field.AsString;
    FieldByName('NOMBRE').AsString := Nombre.DataBinding.Field.AsString;
  end;
end;

procedure TfrCliente.bEliminarTodoClick(Sender: TObject);
begin
  if (VerMensajePregunta(msgCliBorrarSucursales) <> IDYES) then
    Exit;

  try
    with TablaSucursalesMem do
    begin
      DisableControls;
      Last;
      while RecordCount > 0 do begin
        Delete;
        Prior;
      end;
      EnableControls;
    end;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

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

  if EsCadenaVacia(Nombre.Text) then
  begin
    VerMensaje(msgCliFaltaNombreCli);
    Nombre.SetFocus;
    Exit;
  end;
  Result := True;
end;

procedure TfrCliente.ProvinciaSucursalSetText(Sender: TField;
  const Text: String);
var
  CampoProvincia : String;
begin
  CampoProvincia := AnsiUpperCase(Text);
  FCodigoProvinciaSucursal := dmTablaProvincias.darCodigoProvincia(CampoProvincia);
  Sender.AsString := CampoProvincia;
end;

procedure TfrCliente.GridBotonProvinciaClick(Sender: TObject; AButtonIndex: Integer);
begin
  TablaSucursalesMem.Edit;
  CaptionModal := msgListaProvincias;
  WidthModal := 280;
  HeightModal := 460;
  ContenidoModal := TfrProvincias.Create(Self);
  CodigoProvinciaSucursal := CodigoProvincia;
end;

procedure TfrCliente.CargarDatosDireccion;
var
  iContador : Integer;
begin
  with TablaDireccionMem do
  begin
    if TablaSucursales.IsEmpty then
    begin
      Insert;
      FieldByName('FECHAALTA').AsDateTime := dmBaseDatos.DarFecha;
      FieldByName('USUARIO').AsString := dmBaseDatos.Usuario;
      FieldByName('CODIGO').AsString := '1';
      FieldByName('TIPO').AsString := 'P';
      Exit;
    end;

    // Localizar la fila donde está la dirección principal
    TablaSucursales.First;
    if not TablaSucursales.Locate('TIPO', 'P', []) then
      exit; // No hay direccion principal

    DisableControls;
    Append;
    for iContador := 0 to TablaSucursales.FieldCount-1 do
      Fields[iContador].Value := TablaSucursales.Fields[iContador].Value;
    Post;
    First;
    EnableControls;
  end;
end;

procedure TfrCliente.SalvarDatosDireccion;
var
  NumeroCampo : Integer;
  Valor : Variant;
begin
  try
    with TablaDireccionMem do
    begin
      if IsEmpty then
        Exit;
      DisableControls;
      First;

      // Localizar la dirección principal si la hubiera
      TablaSucursales.First;
      if TablaSucursales.Locate('TIPO', 'P', []) then
        TablaSucursales.Edit    // Hay direccion principal
      else
        TablaSucursales.Insert; // No hay direccion principal

      for NumeroCampo := 0 to FieldCount-1 do
      begin
        Valor := Fields[NumeroCampo].AsVariant;

        if (TablaSucursales.Fields[NumeroCampo].FieldName = 'FECHAALTA') and
           (EsCadenaVacia(Valor)) then
          Valor := dmBaseDatos.DarFecha;

        if (TablaSucursales.Fields[NumeroCampo].FieldName = 'USUARIO') and
           (EsCadenaVacia(Valor)) then
          Valor := dmBaseDatos.Usuario;

        if TablaSucursales.Fields[NumeroCampo].FieldName = 'CODIGOCLIENTE' then
          Valor := Codigo.DataBinding.Field.AsString;

        if TablaSucursales.Fields[NumeroCampo].FieldName = 'CODIGO' then
          Valor := '1';

        if TablaSucursales.Fields[NumeroCampo].FieldName = 'TIPO' then
          Valor := 'P';

        TablaSucursales.Fields[NumeroCampo].AsVariant := Valor;
      end;
      TablaSucursales.Post;
      EnableControls;
    end;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrCliente.BorrarDatosSucursalesIB;
begin
  with TablaSucursales do
  begin
    if IsEmpty then
      Exit;
    Last;
    while not BOF do
    begin
      Delete;
      Prior;
    end;
    if not IsEmpty then
      Delete;
  end;
end;

procedure TfrCliente.gridSucursalesResize(Sender: TObject);
begin
  gridSucursalesDBCardView.OptionsView.CardWidth := (gridSucursales.Width - 30) div 2;
end;

procedure TfrCliente.CargarDatosSucursales;
var
  iContador : Integer;
begin
  with TablaSucursalesMem do
  begin
    if TablaSucursales.IsEmpty then
      exit;

    // Localizar la fila donde está la dirección principal
    DisableControls;
    TablaSucursales.First;
    while not TablaSucursales.EOF do
    begin
      if TablaSucursales.FieldByName('TIPO').AsString = 'S' then
      begin
        Append;
        for iContador := 0 to TablaSucursales.FieldCount-1 do
          Fields[iContador].Value := TablaSucursales.Fields[iContador].Value;
        Post;
      end;
      TablaSucursales.Next;
    end;
    First;
    EnableControls;
  end;
end;

procedure TfrCliente.SalvarDatosSucursales;
var
  NumeroCampo : Integer;
  NumeroSucursal : Integer;
  Valor : Variant;
begin
  NumeroSucursal := 2;
  try
    with TablaSucursalesMem do
    begin
      if IsEmpty then
        Exit;
      DisableControls;
      First;
      TablaSucursales.First;

      while not EOF do
      begin
        TablaSucursales.Insert;

        for NumeroCampo := 0 to FieldCount-1 do
        begin
          Valor := Fields[NumeroCampo].AsVariant;

          if (TablaSucursales.Fields[NumeroCampo].FieldName = 'FECHAALTA') and
             (EsCadenaVacia(Valor)) then
            Valor := dmBaseDatos.DarFecha;

          if (TablaSucursales.Fields[NumeroCampo].FieldName = 'USUARIO') and
             (EsCadenaVacia(Valor)) then
            Valor := dmBaseDatos.Usuario;

          if TablaSucursales.Fields[NumeroCampo].FieldName = 'CODIGOCLIENTE' then
            Valor := Codigo.DataBinding.Field.AsString;

          if TablaSucursales.Fields[NumeroCampo].FieldName = 'CODIGO' then
            Valor := NumeroSucursal;

          if TablaSucursales.Fields[NumeroCampo].FieldName = 'TIPO' then
            Valor := 'S';

          TablaSucursales.Fields[NumeroCampo].AsVariant := Valor;
        end;
        TablaSucursales.Post;
        Inc(NumeroSucursal);
        Next;
      end;
      EnableControls;
    end;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;


procedure TfrCliente.pagSucursalesShow(Sender: TObject);
begin
  gridSucursales.SetFocus;
end;

procedure TfrCliente.gridSucursalesDBCardViewKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if (ssCtrl in Shift) and (Key = VK_DELETE) and
     (Modo in [Anadir, Modificar]) then
    bEliminar.Click;
end;

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

  bEliminar.Enabled := not (TablaSucursalesMem.RecordCount = 0);
  bEliminarTodo.Enabled := not (TablaSucursalesMem.RecordCount = 0);
end;

procedure TfrCliente.SetCodigoVendedor(Value: Variant);
var
  DatosVendedor : TDatosVendedor;
begin
  if EsCadenaVacia(Value) then
    exit;
  DatosVendedor := TDatosVendedor.Create;
  DatosVendedor.Codigo := Value;
  try
    if dmTablaVendedores.DarDatosVendedor(DatosVendedor) then
    begin
      with TablaClientes do
      begin
        Edit;
        FieldByName('VENDEDOR').AsString := DatosVendedor.Nombre;
      end;
      FCodigoVendedor := Value;
    end
    else
      raise Exception.CreateFmt(msgDatosCodVendNoExiste, [Value]);
  finally
    DatosVendedor.Free;
  end;
end;

procedure TfrCliente.ProvinciaSetText(Sender: TField; const Text: String);
begin
  FCodigoProvinciaDireccion := dmTablaProvincias.darCodigoProvincia(Text);
  Sender.AsString := Text;
end;

procedure TfrCliente.VendedorPropertiesButtonClick(Sender: TObject;
  AButtonIndex: Integer);
begin
  CaptionModal := 'Lista de vendedores';
  ContenidoModal := TfrVendedores.Create(Self);
end;

procedure TfrCliente.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, FCodigoCliente es NULL y da error al activar modo porque
    no se inicializa los parámetros de la sql. Lo hace BuscarCliente. }
  if not TablaClientes.Active then
    BuscarCliente;
  ContenidoModal := TfrClientes.Create(Self);
end;

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

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

end.
