{ =============================================================================== Copyright (©) 2005. Rodax Software. =============================================================================== Los contenidos de este fichero son propiedad de Rodax Software titular del copyright. Este fichero sólo podrá ser copiado, distribuido y utilizado, en su totalidad o en parte, con el permiso escrito de Rodax Software, o de acuerdo con los términos y condiciones establecidas en el acuerdo/contrato bajo el que se suministra. ----------------------------------------------------------------------------- Web: www.rodax-software.com =============================================================================== Fecha primera versión: 01-02-2005 Versión actual: 1.0.1 Fecha versión actual: 03-03-2005 =============================================================================== Modificaciones: Fecha Comentarios --------------------------------------------------------------------------- 03-03-2005 Se ha quitado en FormCreate la validación de tener instalado el activeSync de microsoft. =============================================================================== } unit Sincronizacion; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, RdxBotones, RdxBarras, ExtCtrls, RdxPaneles, OleServer, DB, IBCustomDataSet, StdCtrls, TablaProveedores, TablaClientes, Outlook2000; type tContactos = (tcProveedores, tcClientes); TfSincronizacion = class(TForm) BarraContadores: TRdxBarraSuperior; imgSombra: TImage; brInferior: TRdxBarraInferior; bCerrar: TRdxBoton; Label1: TLabel; eProgress1: TLabel; eFechaUltimaSinc: TLabel; Label2: TLabel; eProgress2: TLabel; Image1: TImage; Image2: TImage; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormActivate(Sender: TObject); private olOutlook: _Application; olContactsFolder: MAPIFolder; olNmSpace: _NameSpace; FTablaContactos : TIBDataSet; FUltimaSincronizacion : TDateTime; function DarUltimaSincronizacion : TDateTime; procedure ActualizarFechaSincronizacion; procedure SincronizarContactos (TipoContacto : tContactos); procedure AnadirClientesNuevos; procedure AnadirProveedoresNuevos; procedure EliminarClientesSobrantes; procedure EliminarProveedoresSobrantes; procedure InsertarProveedorBD (Contacto : ContactItem; Proveedor : TDatosProveedor); procedure InsertarClienteBD (Contacto : ContactItem; Cliente : TDatosCliente); procedure ActualizarProveedorOutlook (Contacto : ContactItem; Proveedor : TDatosProveedor); procedure ActualizarProveedorBD (Contacto : ContactItem; Proveedor : TDatosProveedor); procedure ActualizarClienteOutlook (Contacto : ContactItem; Cliente : TDatosCliente); procedure ActualizarClienteBD (Contacto : ContactItem; Cliente : TDatosCliente); end; var fSincronizacion: TfSincronizacion; implementation {$R *.dfm} uses IBSQL, Framework, BaseDatos, Mensajes, StrFunc, RdxEmpresaActiva, IBQuery; const CATEGORIA_CLIENTES = 'Clientes FactuGES'; CATEGORIA_PROVEEDORES = 'Proveedores FactuGES'; procedure TfSincronizacion.ActualizarClienteBD(Contacto: ContactItem; Cliente: TDatosCliente); var Cadena : String; begin with Contacto, Cliente do begin if FullName <> Nombre then Nombre := FullName; if not EsCadenaVacia(Calle) then begin Cadena := Calle; if not EsCadenaVacia(Numero) then Cadena := Cadena + ', ' + Numero; if not EsCadenaVacia(Piso) then Cadena := Cadena + ' ' + Piso; end; if Cadena <> BusinessAddressStreet then begin Calle := BusinessAddressStreet; Piso := ''; Numero := ''; end; if BusinessAddressPostalCode <> CodigoPostal then CodigoPostal := BusinessAddressPostalCode; if BusinessAddressCity <> Poblacion then Poblacion := BusinessAddressCity; if BusinessAddressState <> Provincia then Provincia := BusinessAddressState; if Email1Address <> Correo then Correo := Email1Address; if BusinessTelephoneNumber <> Telefono1 then Telefono1 := BusinessTelephoneNumber; if Business2TelephoneNumber <> Telefono2 then Telefono2 := Business2TelephoneNumber; if BusinessFaxNumber <> Fax then Fax := BusinessFaxNumber; if Body <> Observaciones then Observaciones := Body; SalvarDatos; end; end; procedure TfSincronizacion.ActualizarClienteOutlook(Contacto: ContactItem; Cliente: TDatosCliente); begin with Contacto, Cliente do begin CustomerID := Codigo; FullName := Nombre; FileAs := FullName; if not EsCadenaVacia(Calle) then begin BusinessAddressStreet := Calle; if not EsCadenaVacia(Numero) then BusinessAddressStreet := BusinessAddressStreet + ', ' + Numero; if not EsCadenaVacia(Piso) then BusinessAddressStreet := BusinessAddressStreet + ' ' + Piso; end; BusinessAddressPostalCode := CodigoPostal; BusinessAddressCity := Poblacion; BusinessAddressState := Provincia; Email1Address := Correo; BusinessTelephoneNumber := Telefono1; Business2TelephoneNumber := Telefono2; BusinessFaxNumber := Fax; Body := Observaciones; Categories := CATEGORIA_CLIENTES; Save; end; end; procedure TfSincronizacion.ActualizarProveedorBD(Contacto: ContactItem; Proveedor: TDatosProveedor); var Cadena : String; begin with Contacto, Proveedor do begin if FullName <> Nombre then Nombre := FullName; if not EsCadenaVacia(Calle) then begin Cadena := Calle; if not EsCadenaVacia(Numero) then Cadena := Cadena + ', ' + Numero; if not EsCadenaVacia(Piso) then Cadena := Cadena + ' ' + Piso; end; if Cadena <> BusinessAddressStreet then begin Calle := BusinessAddressStreet; Piso := ''; Numero := ''; end; if BusinessAddressPostalCode <> CodigoPostal then CodigoPostal := BusinessAddressPostalCode; if BusinessAddressCity <> Poblacion then Poblacion := BusinessAddressCity; if BusinessAddressState <> Provincia then Provincia := BusinessAddressState; if Email1Address <> Correo then Correo := Email1Address; if BusinessTelephoneNumber <> Telefono1 then Telefono1 := BusinessTelephoneNumber; if Business2TelephoneNumber <> Telefono2 then Telefono2 := Business2TelephoneNumber; if BusinessFaxNumber <> Fax then Fax := BusinessFaxNumber; if Body <> Observaciones then Observaciones := Body; SalvarDatos; end; end; procedure TfSincronizacion.ActualizarProveedorOutlook(Contacto: ContactItem; Proveedor : TDatosProveedor); begin with Contacto, Proveedor do begin CustomerID := Codigo; FullName := Nombre; FileAs := FullName; if not EsCadenaVacia(Calle) then begin BusinessAddressStreet := Calle; if not EsCadenaVacia(Numero) then BusinessAddressStreet := BusinessAddressStreet + ', ' + Numero; if not EsCadenaVacia(Piso) then BusinessAddressStreet := BusinessAddressStreet + ' ' + Piso; end; BusinessAddressPostalCode := CodigoPostal; BusinessAddressCity := Poblacion; BusinessAddressState := Provincia; Email1Address := Correo; BusinessTelephoneNumber := Telefono1; Business2TelephoneNumber := Telefono2; BusinessFaxNumber := Fax; Body := Observaciones; Categories := CATEGORIA_PROVEEDORES; Save; end; end; procedure TfSincronizacion.FormCreate(Sender: TObject); var DLLHandle: THandle; begin FTablaContactos := NIL; olOutlook := CoOutlookApplication.Create; olNmSpace := olOutlook.GetNamespace('MAPI'); olContactsFolder := olNmSpace.GetDefaultFolder(olFolderContacts); FTablaContactos := TIBDataSet.Create(Self); with FTablaContactos do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; end; FUltimaSincronizacion := DarUltimaSincronizacion; end; procedure TfSincronizacion.FormDestroy(Sender: TObject); begin dmBaseDatos.Rollback; if Assigned (FTablaContactos) then begin FTablaContactos.Close; FTablaContactos.Free; end; FTablaContactos := NIL; end; procedure TfSincronizacion.FormShow(Sender: TObject); begin eFechaUltimaSinc.Caption := 'Ultima sincronización: ' + VarToStr(FUltimaSincronizacion); end; procedure TfSincronizacion.EliminarClientesSobrantes; var Contacto : ContactItem; Filter: Widestring; Id: IDispatch; Total : Integer; Contador : Integer; DatosContacto : TObjeto; Clientes : Items; begin Clientes := olContactsFolder.Items.Restrict('[Categorías] = ' + CATEGORIA_CLIENTES); FTablaContactos.Open; FTablaContactos.Last; try Total := Clientes.Count - FTablaContactos.RecordCount; Id := Clientes.GetLast; if Total > 0 then begin Contador := 0; while (Contador < Total) and Assigned(Id) and (Sysutils.Supports(Id, ContactItem, Contacto)) do begin FTablaContactos.First; if not FTablaContactos.Locate('CODIGO', Contacto.CustomerID, []) then begin Contacto.Delete; Contador := Contador + 1; end; Id := Clientes.GetPrevious; end; end; finally FTablaContactos.Close; end; end; procedure TfSincronizacion.SincronizarContactos(TipoContacto : tContactos); var Contacto : ContactItem; Filter: Widestring; Id: IDispatch; Contador : Integer; DatosContacto : TObjeto; Contactos : Items; begin Contador := 0; FTablaContactos.Open; with FTablaContactos do begin Last; First; while not EOF do begin if TipoContacto = tcProveedores then eProgress1.Caption := IntToStr(Contador) + ' proveedores de ' + IntToStr(RecordCount) + ' sincronizados.' else eProgress2.Caption := IntToStr(Contador) + ' clientes de ' + IntToStr(RecordCount) + ' sincronizados.'; Self.Refresh; Application.ProcessMessages; Filter :='[CustomerID] = "' + FieldByName('CODIGO').AsString + '"'; if TipoContacto = tcProveedores then Contactos := olContactsFolder.Items.Restrict('[Categorías] = ' + CATEGORIA_PROVEEDORES) else Contactos := olContactsFolder.Items.Restrict('[Categorías] = ' + CATEGORIA_CLIENTES); Id := Contactos.Find(Filter); if (Id = nil) then begin Id := ContactItem(Contactos.Add(olContactItem)); if Sysutils.Supports(Id, ContactItem, Contacto) then begin // El contacto no existe try if TipoContacto = tcProveedores then begin DatosContacto := TDatosProveedor.Create(FieldByName('CODIGO').AsString); ActualizarProveedorOutlook(Contacto, DatosContacto as TDatosProveedor); end else begin DatosContacto := TDatosCliente.Create(FieldByName('CODIGO').AsString); ActualizarClienteOutlook(Contacto, DatosContacto as TDatosCliente); end; finally DatosContacto.Free; end; end; end else begin if Sysutils.Supports(Id, ContactItem, Contacto) then begin if (Contacto.LastModificationTime > FUltimaSincronizacion) or (FTablaContactos.FieldByName('ULTIMOCAMBIO').AsDateTime > FUltimaSincronizacion) then begin Contador := Contador + 1; if TipoContacto = tcProveedores then begin DatosContacto := TDatosProveedor.Create(FieldByName('CODIGO').AsString); if (Contacto.LastModificationTime > FieldByName('ULTIMOCAMBIO').AsDateTime) then ActualizarProveedorBD(Contacto, DatosContacto as TDatosProveedor) else ActualizarProveedorOutlook(Contacto, DatosContacto as TDatosProveedor); end else begin DatosContacto := TDatosCliente.Create(FieldByName('CODIGO').AsString); if (Contacto.LastModificationTime > FieldByName('ULTIMOCAMBIO').AsDateTime) then ActualizarClienteBD(Contacto, DatosContacto as TDatosCliente) else ActualizarClienteOutlook(Contacto, DatosContacto as TDatosCliente); end; DatosContacto.Free; end; end; end; Contador := Contador + 1; Next; end; end; if TipoContacto = tcProveedores then eProgress1.Caption := IntToStr(Contador) + ' proveedores sincronizados.' else eProgress2.Caption := IntToStr(Contador) + ' clientes sincronizados.'; FTablaContactos.Close; end; procedure TfSincronizacion.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; procedure TfSincronizacion.FormActivate(Sender: TObject); begin OnActivate := NIL; Screen.Cursor := crHourGlass; Self.Refresh; Application.ProcessMessages; // Sincronizar los contactos AnadirProveedoresNuevos; AnadirClientesNuevos; with FTablaContactos do begin Close; SelectSQL.Clear; SelectSQL.Add('select * from PROVEEDORES order by CODIGO desc'); Prepare; end; SincronizarContactos(tcProveedores); EliminarProveedoresSobrantes; Image1.Visible := True; Self.Refresh; Application.ProcessMessages; with FTablaContactos do begin Close; Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SelectSQL.Clear; SelectSQL.Add('select * from CLIENTES order by CODIGO desc'); Prepare; end; SincronizarContactos(tcClientes); EliminarClientesSobrantes; Image2.Visible := True; // Fin ActualizarFechaSincronizacion; FUltimaSincronizacion := DarUltimaSincronizacion; dmBaseDatos.Commit; bCerrar.Enabled := True; Self.Refresh; Application.ProcessMessages; Screen.Cursor := crDefault; end; procedure TfSincronizacion.AnadirClientesNuevos; var Contacto : ContactItem; Id: IDispatch; DatosContacto : TObjeto; Clientes : Items; DatosCliente : TDatosCliente; begin Clientes := olContactsFolder.Items.Restrict('[Categorías] = ' + CATEGORIA_CLIENTES); Id := Clientes.GetFirst; while Assigned(Id) and (Sysutils.Supports(Id, ContactItem, Contacto)) do begin if EsCadenaVacia(Contacto.CustomerID) then begin DatosCliente := TDatosCliente.Create; try InsertarClienteBD(Contacto, DatosCliente); ActualizarClienteOutlook(Contacto, DatosCliente); finally DatosCliente.Free; end; end; Id := Clientes.GetNext; end; end; procedure TfSincronizacion.InsertarClienteBD(Contacto: ContactItem; Cliente: TDatosCliente); begin with Contacto, Cliente do begin Nombre := FullName; Calle := BusinessAddressStreet; Piso := ''; Numero := ''; CodigoPostal := BusinessAddressPostalCode; Poblacion := BusinessAddressCity; Provincia := BusinessAddressState; Correo := Email1Address; Telefono1 := BusinessTelephoneNumber; Telefono2 := Business2TelephoneNumber; Fax := BusinessFaxNumber; Observaciones := Body; SalvarDatos; end; end; procedure TfSincronizacion.InsertarProveedorBD(Contacto: ContactItem; Proveedor: TDatosProveedor); begin with Contacto, Proveedor do begin Nombre := FullName; Calle := BusinessAddressStreet; Piso := ''; Numero := ''; CodigoPostal := BusinessAddressPostalCode; Poblacion := BusinessAddressCity; Provincia := BusinessAddressState; Correo := Email1Address; Telefono1 := BusinessTelephoneNumber; Telefono2 := Business2TelephoneNumber; Fax := BusinessFaxNumber; Observaciones := Body; SalvarDatos; end; end; procedure TfSincronizacion.AnadirProveedoresNuevos; var Contacto : ContactItem; Id: IDispatch; DatosContacto : TObjeto; Proveedores : Items; DatosProveedor : TDatosProveedor; begin Proveedores := olContactsFolder.Items.Restrict('[Categorías] = ' + CATEGORIA_PROVEEDORES); Id := Proveedores.GetFirst; while Assigned(Id) and (Sysutils.Supports(Id, ContactItem, Contacto)) do begin if EsCadenaVacia(Contacto.CustomerID) then begin DatosProveedor := TDatosProveedor.Create; try InsertarProveedorBD(Contacto, DatosProveedor); ActualizarProveedorOutlook(Contacto, DatosProveedor); finally DatosProveedor.Free; end; end; Id := Proveedores.GetNext; end; end; procedure TfSincronizacion.EliminarProveedoresSobrantes; var Contacto : ContactItem; Filter: Widestring; Id: IDispatch; Total : Integer; Contador : Integer; DatosContacto : TObjeto; Proveedores : Items; begin Proveedores := olContactsFolder.Items.Restrict('[Categorías] = ' + CATEGORIA_PROVEEDORES); FTablaContactos.Open; FTablaContactos.Last; try Total := Proveedores.Count - FTablaContactos.RecordCount; Id := Proveedores.GetLast; if Total > 0 then begin Contador := 0; while (Contador < Total) and Assigned(Id) and (Sysutils.Supports(Id, ContactItem, Contacto)) do begin FTablaContactos.First; if not FTablaContactos.Locate('CODIGO', Contacto.CustomerID, []) then begin Contacto.Delete; Contador := Contador + 1; end; Id := Proveedores.GetPrevious; end; end; finally FTablaContactos.Close; end; end; function TfSincronizacion.DarUltimaSincronizacion: TDateTime; var oSQL : TIBQuery; begin oSQL := TIBQuery.Create(Self); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('select ULTIMASINCRONIZACION '); SQL.Add('from USUARIOS '); SQL.Add('where UPPER(USUARIO) = UPPER(:USUARIO)'); ParamByName('USUARIO').AsString := dmBaseDatos.Usuario; try Prepare; Open; Result := FieldByName('ULTIMASINCRONIZACION').AsDateTime; finally Close; Transaction := NIL; Free; end; end; end; procedure TfSincronizacion.ActualizarFechaSincronizacion; var oSQL : TIBSQL; bInsertar : Boolean; begin bInsertar := False; oSQL := TIBSQL.Create(nil); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('update USUARIOS set '); SQL.Add('ULTIMASINCRONIZACION = CURRENT_TIME '); SQL.Add('where UPPER(USUARIO) = UPPER(:USUARIO)'); ParamByName('USUARIO').AsString := dmBaseDatos.Usuario; try Prepare; ExecQuery; if RowsAffected = 0 then bInsertar := True; finally Close; Transaction := NIL; Free; end; end; if bInsertar then begin oSQL := TIBSQL.Create(nil); with oSQL do begin Database := dmBaseDatos.BD; Transaction := dmBaseDatos.Transaccion; SQL.Add('insert into USUARIOS '); SQL.Add('(USUARIO, ULTIMASINCRONIZACION) values '); SQL.Add('(:USUARIO, CURRENT_TIME) '); ParamByName('USUARIO').AsString := dmBaseDatos.Usuario; try Prepare; ExecQuery; finally Close; Transaction := NIL; Free; end; end; end; end; end.