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

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

unit Agenda;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, CalendarioPagos, RdxFrame, RdxTitulos, ExtCtrls, DB,
  IBCustomDataSet, IBQuery, Configuracion, StdCtrls, cxStyles,
  cxCustomData, cxGraphics, cxFilter, cxData, cxEdit, cxDBData,
  cxGridLevel, cxClasses, cxControls, cxGridCustomView,
  cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxGrid,
  cxContainer, cxTextEdit, cxMaskEdit, cxDropDownEdit,
  RdxBotones, RdxPaneles, RdxBarras, ActnList, cxGridCardView,
  cxGridDBCardView, RxMemDS, cxTimeEdit, cxMemo, cxLookupEdit,
  cxDBLookupEdit, cxDBLookupComboBox, Grids, DBGrids, Mask, DBCtrls,
  cxCalendar, cxDataStorage;

type
  TfrAgenda = class(TRdxFrame)
    frCalendario1: TfrCalendarioPagos;
    Panel1: TPanel;
    Splitter1: TSplitter;
    TablaCalendario: TIBQuery;
    eListaVisitas: TLabel;
    Panel2: TPanel;
    gridVisitas: TcxGrid;
    gridVisitasLevel1: TcxGridLevel;
    Panel3: TPanel;
    dsVisitas: TDataSource;
    pnlBarraGrid: TRdxPanel;
    bAnadir: TRdxBoton;
    bEliminar: TRdxBoton;
    bEliminarTodo: TRdxBoton;
    TablaCalVisitas: TIBQuery;
    pnlExtra: TRdxBarraSuperior;
    eUsuario: TPanel;
    Acciones: TActionList;
    actAnadir: TAction;
    gridVisitasDBCardView1: TcxGridDBCardView;
    gridVisitasDBTableView1: TcxGridDBTableView;
    actEliminar: TAction;
    actEliminarTodo: TAction;
    gridVisitasDBTableView1DBColumn1: TcxGridDBColumn;
    BarraAgenda: TRdxBarraSuperior;
    imgSombra: TImage;
    cbxUsuarios: TcxLookupComboBox;
    dsUsuarios: TDataSource;
    TablaUsuarios: TIBQuery;
    bRefrescar: TRdxBoton;
    actRefrescar: TAction;
    procedure RdxFrameShow(Sender: TObject);
    procedure actAnadirExecute(Sender: TObject);
    procedure actEliminarExecute(Sender: TObject);
    procedure actEliminarTodoExecute(Sender: TObject);
    procedure frCalendario1bHoyClick(Sender: TObject);
    procedure frCalendario1cbxMesPropertiesEditValueChanged(
      Sender: TObject);
    procedure frCalendario1seAnoPropertiesEditValueChanged(
      Sender: TObject);
    procedure cbxUsuariosPropertiesEditValueChanged(Sender: TObject);
    procedure gridVisitasResize(Sender: TObject);
    procedure actRefrescarExecute(Sender: TObject);
    procedure RdxFrameExit(Sender: TObject);
    procedure actEliminarUpdate(Sender: TObject);
  private
    FDia : TDateTime;
    FUsuario : Variant;
    FTablaVisitas : TIBDataSet;
    FTablaVisitasMem : TRxMemoryData;

    procedure FOnDrawDia(Sender : TObject; ADate : TDate; var ABackColor : TColor; var AFont : TFont; var Caption : TCaption; var Hint : String);
    procedure FOnClickDia(Sender : TObject; ADate : TDate);
    procedure RefrescarCalendario;
    procedure RefrescarVisitas;

    procedure CargarDatosVisitas;
    procedure GuardarDatos;
    procedure GuardarDatosVisitas;
    function SalvarDatosVisitas: Boolean;
    function BorrarDatosVisitasIB: Boolean;
    procedure SetDia(const Value: TDateTime);
    procedure SetUsuario(const Value: Variant);
    procedure HoraIniValidate(Sender: TField);
    procedure OnFilterVisitasMem(DataSet: TDataSet; var Accept: Boolean);
  protected
    property Dia : TDateTime read FDia write SetDia;
    property Usuario : Variant read FUsuario write SetUsuario;
    property TablaVisitas : TIBDataSet read FTablaVisitas write FTablaVisitas;
    property TablaVisitasMem : TRxMemoryData read FTablaVisitasMem write FTablaVisitasMem;
  public
    { Public declarations }
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  end;

var
  frAgenda: TfrAgenda;

implementation

uses
  BaseDatos, Constantes, TablaFacturasProveedor, TablaEmpresas, Entidades, 
  TablaAgenda, IB, IBErrorCodes, Excepciones, Mensajes, Literales, StrFunc, DateUtils;

{$R *.dfm}

{ TfrPagosPendientes }

constructor TfrAgenda.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Entidad := entAgenda;
  ConfigurarFrame(Self, Self.Entidad);

  with TablaCalendario do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SQL.Add('select fechaini, count(Fechaini) as numero ');
    SQL.Add('from agenda ');
    SQL.Add('where usuario = :usuario ');
    SQL.Add('and BORRADO <> ' + QuotedStr(CITA_BORRADA));
    SQL.Add('group by fechaini; ');
  end;

  with TablaCalVisitas do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
  end;

  with TablaUsuarios do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
  end;

  TablaVisitas := TIBDataSet.Create(Self);
  with TablaVisitas do
  begin
    Database := dmBaseDatos.BD;
    Transaction := dmBaseDatos.Transaccion;
    SelectSQL.Assign(dmTablaAgenda.sqlGrid);
    InsertSQL.Assign(dmTablaAgenda.sqlInsertar);
    ModifySQL.Assign(dmTablaAgenda.sqlModificar);
    DeleteSQL.Assign(dmTablaAgenda.sqlEliminar);
    RefreshSQL.Assign(dmTablaAgenda.sqlConsultar);
  end;

  TablaVisitasMem := TRxMemoryData.Create(Self);
  TablaVisitasMem.CopyStructure(TablaVisitas);
  TablaVisitasMem.OnFilterRecord := OnFilterVisitasMem;
  dsVisitas.DataSet := TablaVisitasMem;
  dmTablaAgenda.InicializarGridVisitas(gridVisitasDBCardView1);

  Dia := dmBaseDatos.DarFecha;
  Usuario := dmBaseDatos.Usuario;
end;

destructor TfrAgenda.Destroy;
begin
  TablaCalendario.Close;
  TablaCalVisitas.Close;
  TablaUsuarios.Close;
  TablaVisitas.Close;
  inherited;
end;

procedure TfrAgenda.FOnClickDia(Sender: TObject; ADate: TDate);
begin
  GuardarDatos;
  Dia := ADate;
end;

procedure TfrAgenda.FOnDrawDia(Sender: TObject; ADate: TDate;
  var ABackColor : TColor; var AFont : TFont; var Caption: TCaption; var Hint: String);
var
  Cadena1 : String;
  Cadena2 : String;
  CaptionCelda : TStringList;
  CaptionHint : TStringList;
begin
  CaptionCelda := TStringList.Create;
  CaptionHint := TStringList.Create;

  try
    with TablaCalendario do
    begin
      First;
      Caption := '';
      while not Eof do
      begin
        if (FieldByName('FECHAINI').AsString = DateToStr(ADate)) then
        begin
          CaptionCelda.Clear;
          CaptionHint.Clear;
          CaptionCelda.Append(FieldByName('NUMERO').AsString + ' visitas: ');
          CaptionHint.Append(FieldByName('NUMERO').AsString + ' visitas: ');
          CaptionCelda.Append(' ');
          CaptionHint.Append(' ');
          break;
        end;
        Next;
      end;
    end;

    with TablaCalVisitas do
    begin
      First;
      while not Eof do
      begin
        if FieldByName('FECHAINI').AsString = DateToStr(ADate) then
        begin
          Cadena1 := FormatDateTime('hh:mm', FieldByName('HORAINI').AsDateTime);
          Cadena1 := Cadena1 + ' - ';

          if CaptionCelda.Count < 4 then
          begin
             if length(FieldByName('DESCRIPCION').AsString) < 5
             then CaptionCelda.Append(Cadena1 + format('%.10s', [FieldByName('DESCRIPCION').AsString]))
             else CaptionCelda.Append(Cadena1 + format('%.10s...', [FieldByName('DESCRIPCION').AsString]))
          end
          else if CaptionCelda.Count < 5 then
             CaptionCelda.Append('>>');

          CaptionHint.Append(Cadena1 + FieldByName('DESCRIPCION').AsString);

          {if (MonthOf(FieldByName('FECHAINI').AsDateTime) = (frCalendario1.cbxMes.ItemIndex + 1)) then
          begin
            if (FieldByName('FECHAINI').AsString = DateToStr(Dia)) then
            begin
              ABackColor := $00C2F0FF;
              AFont.Style := [fsBold];
            end
            else
            begin
              ABackColor := $00C2FFFF;
            end;
          end;}
        end;
        Next;
      end;
    end;

    Caption := CaptionCelda.Text;
    Hint := CaptionHint.Text;

    if DateOf(ADate) = DateOf(Dia) then
    begin
      ABackColor := clHighlight;
      AFont.Color := clHighlightText;
    end;
  finally
    CaptionCelda.Free;
    CaptionHint.Free;
  end;
end;

procedure TfrAgenda.RdxFrameShow(Sender: TObject);
begin
  RefrescarCalendario;
end;

procedure TfrAgenda.RefrescarCalendario;
begin
  frCalendario1.OnDrawDay := NIL;
  frCalendario1.OnClickDay := NIL;

  with TablaCalendario do
  begin
    Close;
    ParamByName('USUARIO').AsString := Usuario;
    Prepare;
    Open;
  end;

  with TablaCalVisitas do
  begin
    Close;
    ParamByName('USUARIO').AsString := Usuario;
    OnFilterRecord := OnFilterVisitasMem;
    Filtered := True;
    Prepare;
    Open;
  end;

  with TablaUsuarios do
  begin
    Open;
    First;
    Locate('USUARIO', Usuario, []);
  end;

  frCalendario1.OnDrawDay := FOnDrawDia;
  frCalendario1.OnClickDay := FOnClickDia;
end;

procedure TfrAgenda.actAnadirExecute(Sender: TObject);
begin
  try
    GuardarDatosVisitas;

    gridVisitas.SetFocus;
    with TablaVisitasMem do
    begin
      Append;
      FieldByName('USUARIO').AsVariant := UpperCase(Usuario);
      FieldByName('FECHAINI').AsDateTime := Dia;
      FieldByName('FECHAFIN').AsDateTime := Dia;
      FieldByName('HORAINI').AsDateTime := dmBaseDatos.DarHora;
      Post;
      Edit;
      FieldByName('HORAINI').FocusControl;
    end;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrAgenda.CargarDatosVisitas;
var
  iContador : Integer;
begin
  with TablaVisitasMem do
  begin
    if TablaVisitas.IsEmpty then
      Exit;

    Filtered := False;

    TablaVisitas.Open;
    TablaVisitas.First;
    while not TablaVisitas.EOF do
    begin
      Append;
      for iContador := 0 to TablaVisitas.FieldCount-1 do
        Fields[iContador].Value := TablaVisitas.Fields[iContador].Value;
      Post;
      TablaVisitas.Next;
    end;
    Filtered := True;
    First;
  end;
end;

procedure TfrAgenda.actEliminarExecute(Sender: TObject);
begin
  if TablaVisitasMem.RecordCount = 0 then begin
    { Hacemos un cancel de la tabla por si el registro actual estuviera
      recien creado }
    TablaVisitasMem.Cancel;
    exit;
  end;
  try
    if (VerMensajePreguntaFmt(msgVisBorrarVisita, [TablaVisitasMem.FieldByName('HORAINI').AsString]) <> IDYES) then
      Exit;
    TablaVisitasMem.Edit;
    TablaVisitasMem.FieldByName('BORRADO').AsString := CITA_BORRADA;
    TablaVisitasMem.Post;
    GuardarDatos;
    actRefrescar.Execute;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrAgenda.actEliminarTodoExecute(Sender: TObject);
begin
  if (VerMensajePreguntaFmt(msgVisBorrarVisitas, [TablaVisitasMem.FieldByName('FECHAINI').AsString]) <> IDYES) then
    Exit;

  try
    with TablaVisitasMem do
    begin
      Cancel;
      DisableControls;
      First;
      while not EOF do begin
        Edit;
        FieldByName('BORRADO').AsString := CITA_BORRADA;
        Post;
        //Next;   // El filtro de la tabla lo hace avanzar hasta el siguiente.
      end;
      GuardarDatos;
      actRefrescar.Execute;
      EnableControls;
    end;
  except
    on E : EIBError do
      TratarExcepcion(E);
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrAgenda.GuardarDatosVisitas;
begin
  if (TablaVisitasMem.State in dsEditModes) then
      GuardarDatos;
end;

function TfrAgenda.BorrarDatosVisitasIB: Boolean;
begin
  Result := dmTablaAgenda.EliminarVisitas(Dia, Usuario);
end;

function TfrAgenda.SalvarDatosVisitas: Boolean;
var
  NumeroCampo : Integer;
  Valor : Variant;
begin
  Result := False;
  try
    with TablaVisitasMem do
    begin
      Filtered := False;
      if not IsEmpty then
      begin
        DisableControls;
        First;
        TablaVisitas.First;
        while not EOF do
        begin
          TablaVisitas.Insert;

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

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

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

            if (TablaVisitas.Fields[NumeroCampo].FieldName = 'DESCRIPCION') and
               (EsCadenaVacia(Valor)) then
              Valor := 'Sin asunto';

            //Comprobamos si ya tiene codigo asignado
            if (TablaVisitas.Fields[NumeroCampo].FieldName = 'CODIGO') and
               (EsCadenaVacia(FieldByName('CODIGO').AsString)) then
            begin
               Valor := dmTablaAgenda.DarNuevoCodigo;
               //Asignamos el valor a la tabla de memoria;
               Edit;
               TablaVisitasMem.Fields[NumeroCampo].AsVariant := Valor;
               Post;

           end;

            TablaVisitas.Fields[NumeroCampo].AsVariant := Valor;
          end;
          TablaVisitas.Post;
          Next;
        end;
      end;
      Result := True;
      Filtered := True;
      EnableControls;
    end;
  except
    on E : EIBError do
    begin
      if E.IBErrorCode = isc_unique_key_violation then
      begin
        VerMensajeFmt(msgCliCodCliRepetido, ['dddddd']);
        //TablaClientes.Edit;
      end
      else
        TratarExcepcion(E);
    end;
    on E : Exception do
      TratarExcepcion(E);
  end;
end;

procedure TfrAgenda.GuardarDatos;
begin
  if (TablaVisitasMem.State in dsEditModes) then
    TablaVisitasMem.Post;
  if BorrarDatosVisitasIB and SalvarDatosVisitas then
    dmBaseDatos.Commit
  else
    dmBaseDatos.Rollback;
  RefrescarCalendario;
end;

procedure TfrAgenda.SetDia(const Value: TDateTime);
begin
  if FDia <> Value then
     GuardarDatosVisitas;

  FDia := Value;
  RefrescarCalendario;
  RefrescarVisitas;
end;

procedure TfrAgenda.frCalendario1bHoyClick(Sender: TObject);
begin
  inherited;
  frCalendario1.bHoyClick(Sender);
end;

procedure TfrAgenda.RefrescarVisitas;
begin
  eListaVisitas.Caption := 'Citas pendientes del ' + DateToStr(Dia);

  with TablaVisitas do
  begin
    try
      Close;
      ParamByName('USUARIO').AsString := UpperCase(Usuario);
      ParamByName('FECHAINI').AsDate := Dia;
      Prepare;
      Open;
    finally
    end;
  end;

  with TablaVisitasMem do
  begin
    try
      DisableControls;
      Close;
      Open;
      CargarDatosVisitas;
      FieldByName('HORAINI').
      OnValidate := HoraIniValidate;
      dmTablaAgenda.InicializarTablaVisitas(@TablaVisitasMem);
    finally
      EnableControls;
    end;
  end;
end;

procedure TfrAgenda.SetUsuario(const Value: Variant);
begin
  if FUsuario <> Value then
     GuardarDatosVisitas;

  FUsuario := UpperCase(Value);
  if EsCadenaVacia(cbxUsuarios.Text) then
  begin
     TablaUsuarios.Locate('USUARIO', FUsuario,[]);
     cbxUsuarios.Text := TablaUsuarios.FieldByName('NOMBRE').AsString;
  end;
     
  RefrescarCalendario;
  RefrescarVisitas;
end;

procedure TfrAgenda.frCalendario1cbxMesPropertiesEditValueChanged(
  Sender: TObject);
  var i: integer;
begin
  inherited;
  Dia := StrToDateTime('01/' + IntToStr(frCalendario1.cbxMes.ItemIndex + 1) + '/' + IntToStr(frCalendario1.seAno.Value));
  Usuario := TablaUsuarios.FieldByName('USUARIO').AsString;
end;

procedure TfrAgenda.frCalendario1seAnoPropertiesEditValueChanged(
  Sender: TObject);
begin
  inherited;
  Dia := StrToDateTime('01/' + IntToStr(frCalendario1.cbxMes.ItemIndex + 1) + '/' + IntToStr(frCalendario1.seAno.Value));
  Usuario := TablaUsuarios.FieldByName('USUARIO').AsString;
end;

procedure TfrAgenda.HoraIniValidate(Sender: TField);
begin
  if EsCadenaVacia(Sender.Text) then
    Sender.AsDateTime := dmBaseDatos.DarHora;

  TablaVisitasMem.FieldByName('HORAFIN').AsDateTime := IncMinute(Sender.AsDateTime,30);
end;

procedure TfrAgenda.cbxUsuariosPropertiesEditValueChanged(Sender: TObject);
begin
  inherited;
  Usuario := TablaUsuarios.FieldByName('USUARIO').AsString;
end;

procedure TfrAgenda.gridVisitasResize(Sender: TObject);
begin
  inherited;
  gridVisitasDBCardView1.OptionsView.CardWidth := gridVisitas.Width - 40; 
end;

procedure TfrAgenda.actRefrescarExecute(Sender: TObject);
begin
  RefrescarCalendario;
  RefrescarVisitas;  
end;

procedure TfrAgenda.OnFilterVisitasMem(DataSet: TDataSet;
  var Accept: Boolean);
begin
  Accept := (DataSet.FieldByName('BORRADO').AsString <> CITA_BORRADA);
end;

procedure TfrAgenda.RdxFrameExit(Sender: TObject);
begin
  GuardarDatos;
end;

procedure TfrAgenda.actEliminarUpdate(Sender: TObject);
begin
  (Sender as TAction).Enabled := not (gridVisitasDBCardView1.ViewData.RecordCount = 0)
end;

end.
