unit SincronizarCalendario;

interface

uses
  Classes, IBCustomDataSet, CETools, DB;
  
type
  TSincCalendario = class(TComponent)
  private
    FCalendarioBD : TIBDataSet;
    FCEApp : TCEAppointments;
    FUltimaSincronizacion: TDateTime;
    FListaID : TStringList;
    function InsertarCitaBD: boolean;
    function InsertarCitaPPC: boolean;
    function ActualizarCitaBD: boolean;
    function ActualizarCitaPPC: boolean;
    procedure OnFilterIDNulo(DataSet: TDataSet; var Accept: Boolean);
    procedure OnFilterIDNoNulo(DataSet: TDataSet; var Accept: Boolean);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Sincronizar;
  published
    property CalendarioBD : TIBDataSet read FCalendarioBD write FCalendarioBD;
    property UltimaSincronizacion : TDateTime read FUltimaSincronizacion write FUltimaSincronizacion;
  end;


implementation

uses
  SysUtils, BaseDatos, TablaAgenda, DateUtils, Variants;

{ TSincCalendario }

function TSincCalendario.ActualizarCitaBD: boolean;
var
  Visita: TDatosVisita;
begin
  Result := False;
  Visita := TDatosVisita.Create(FCalendarioBD.FieldByName('CODIGO').AsInteger);
  try
    Visita.Descripcion := FCEApp.Appointment.SUBJECT;
    Visita.FechaIni := DateOf(FCEApp.Appointment.DATE);
    Visita.HoraIni := TimeOf(FCEApp.Appointment.DATE);
    Visita.FechaFin := IncMinute(FCEApp.Appointment.DATE, FCEApp.Appointment.LEN);
    Visita.HoraFin := TimeOf(Visita.FechaFin);
    Visita.FechaFin := DateOf(Visita.FechaFin);
    Visita.EntryID := FCEApp.RecordID;
    Visita.SalvarDatos;
  finally
    Visita.Free;
    Visita := NIL;
  end;
end;

function TSincCalendario.ActualizarCitaPPC: boolean;
var
  Visita: TDatosVisita;
  CEApp: TCEAppointmentRecord;
  FechaAux : TDateTime;
begin
  Result := False;
  Visita := TDatosVisita.Create(FCalendarioBD.FieldByName('CODIGO').AsInteger);
  FillChar(CEApp, SizeOf(TCEAppointmentRecord), 0);
  try
    CEApp := FCEApp.Appointment;
    CEApp.SUBJECT := Visita.Descripcion;
    CEApp.DATE := Visita.FechaIni;
    ReplaceTime(CEApp.DATE, Visita.HoraIni);
    FechaAux := Visita.FechaFin;
    ReplaceTime(FechaAux, Visita.HoraFin);
    CEApp.LEN := MinutesBetween(CEApp.DATE, FechaAux);
    FCEApp.Appointment := CEApp;
    FCEApp.Write;
  finally
    Visita.Free;
    Visita := NIL;
  end;
end;

constructor TSincCalendario.Create(AOwner: TComponent);
begin
  inherited;
  FCalendarioBD := NIL;
  FUltimaSincronizacion := dmBaseDatos.DarFecha;
  FCEApp := TCEAppointments.Create(Self);
  FListaID := TStringList.Create;
end;

destructor TSincCalendario.Destroy;
begin
  FCEApp.Free;
  FCEApp := NIL;

  FListaID.Free;
  FListaID := NIL;

  FCalendarioBD := NIL;
  inherited;
end;

function TSincCalendario.InsertarCitaBD: boolean;
var
  Visita: TDatosVisita;
begin
  Result := False;
  Visita := TDatosVisita.Create;
  try
    Visita.Usuario := dmBaseDatos.Usuario;
    Visita.Descripcion := FCEApp.Appointment.SUBJECT;
    Visita.FechaIni := DateOf(FCEApp.Appointment.DATE);
    Visita.HoraIni := TimeOf(FCEApp.Appointment.DATE);
    Visita.FechaFin := IncMinute(FCEApp.Appointment.DATE, FCEApp.Appointment.LEN);
    Visita.HoraFin := TimeOf(Visita.FechaFin);
    Visita.FechaFin := DateOf(Visita.FechaFin);
    Visita.EntryID := FCEApp.RecordID;
    Visita.SalvarDatos;
  finally
    Visita.Free;
    Visita := NIL;
  end;
end;

function TSincCalendario.InsertarCitaPPC: boolean;
var
  Visita: TDatosVisita;
  CEApp: TCEAppointmentRecord;
  FechaAux : TDateTime;
begin
  Result := False;
  Visita := TDatosVisita.Create(FCalendarioBD.FieldByName('CODIGO').AsInteger);
  FillChar(CEApp, SizeOf(TCEAppointmentRecord), 0);
  try
    CEApp.SUBJECT := Visita.Descripcion;
    CEApp.DATE := Visita.FechaIni;
    ReplaceTime(CEApp.DATE, Visita.HoraIni);
    FechaAux := Visita.FechaFin;
    ReplaceTime(FechaAux, Visita.HoraFin);
    CEApp.LEN := MinutesBetween(CEApp.DATE, FechaAux);
    CEApp.STATUS := APPSTATUS_BUSY;

    FCEApp.Append;
    FCEApp.Appointment := CEApp;
    FCEApp.Write;

    Visita.EntryID := FCEApp.RecordID;
    Visita.SalvarDatos;
  finally
    Visita.Free;
    Visita := NIL;
  end;
end;

procedure TSincCalendario.OnFilterIDNoNulo(DataSet: TDataSet;
  var Accept: Boolean);
begin
  Accept := not VarIsNull(DataSet.FieldByName('ENTRYID').AsVariant);
end;

procedure TSincCalendario.OnFilterIDNulo(DataSet: TDataSet; var Accept: Boolean);
begin
  Accept := VarIsNull(DataSet.FieldByName('ENTRYID').AsVariant);
end;

procedure TSincCalendario.Sincronizar;
var
  Continuar : Boolean;
begin
  if not Assigned(FCalendarioBD) then
    raise Exception.Create('Falta indicar la tabla de BD');

  try
    FCalendarioBD.Open;
    FCalendarioBD.First;

    FCEApp.Open;
    FCEApp.First;

    Continuar := (FCEApp.NumRecords > 0);
    while Continuar do
    begin
      FCEApp.Read;
      if not FCalendarioBD.Locate('ENTRYID', FCEApp.RecordID, []) then
        InsertarCitaBD
      else begin
        if (FCalendarioBD.FieldByName('BORRADO').AsString = CITA_BORRADA) then
        begin
          FCalendarioBD.Delete;
          FCEApp.Delete;
        end
        else begin
          if (FCEApp.LastModified > FUltimaSincronizacion) or
             (FCalendarioBD.FieldByName('ULTIMOCAMBIO').AsDateTime > FUltimaSincronizacion) then
          begin
            if (FCEApp.LastModified > FCalendarioBD.FieldByName('ULTIMOCAMBIO').AsDateTime) then
              ActualizarCitaBD
            else
              ActualizarCitaPPC;
          end;
        end;
      end;
      FListaID.Add(IntToStr(FCEApp.RecordID));
      Continuar := FCEApp.Next;
    end;

    // Borrar de la BD las citas que se han borrado en el PPC
    FCalendarioBD.Filtered := False;
    FCalendarioBD.OnFilterRecord := OnFilterIDNoNulo;
    FCalendarioBD.Filtered := True;
    FCalendarioBD.First;
    while not FCalendarioBD.EOF do
    begin
      if FListaID.IndexOf(FCalendarioBD.FieldByName('ENTRYID').AsString) = -1 then
        FCalendarioBD.Delete
      else
        FCalendarioBD.Next;
    end;


    // Insertar en el PPC las citas nuevas
    FCalendarioBD.Filtered := False;
    FCalendarioBD.OnFilterRecord := OnFilterIDNulo;
    FCalendarioBD.Filtered := True;
    FCalendarioBD.First;
    while not FCalendarioBD.EOF do
    begin
      if (FCalendarioBD.FieldByName('BORRADO').AsString = CITA_BORRADA) then
        FCalendarioBD.Delete
      else begin
        InsertarCitaPPC;
        FCalendarioBD.Next;
      end;
    end;

    FCalendarioBD.Filtered := False;
    FCalendarioBD.Filter := '';
  finally
    FCalendarioBD.Close;
    FCalendarioBD.OnFilterRecord := NIL;
    FCEApp.Close;
  end;
end;

end.
