unit uActualizarClientesUtils; interface uses Forms, Classes, Windows, SysUtils, uBizTiendaWeb, JSDialog, ExtCtrls; function ActualizarClientesTienda(ATiendaWeb : IBizTiendaWeb): Boolean; implementation uses uClientesController, uOscAddressBookController, uDireccionesContactoController, uOscCustomersController, uBizOscAddressBook, uBizOscCustomers, uPasswordUtils, schTiendaWebClient_Intf, uDADataTable, uBizContactos, uBizDireccionesContacto, schContactosClient_Intf, JSDialogs, uDialogUtils, StrUtils, uIntegerListUtils; const OSC_CUSTOMER_GENDER = 'm'; OSC_CUSTOMER_COUNTRY_ID = 195; // España OSC_CUSTOMER_ZONE_ID = 161; // Madrid function AnadirOSCAddressBook(AOSCAddressBook : IBizOscAddressBook; ACliente : IBizCliente; ADireccionContacto : IBizDireccionesContacto) : Boolean; begin Result := False; if not Assigned(AOSCAddressBook) then raise Exception.Create ('OSCAddressBook no asignado (AnadirOSCAddressBook)'); if not Assigned(ACliente) then raise Exception.Create ('Cliente no asignado (AnadirOSCAddressBook)'); if not Assigned(ADireccionContacto) then raise Exception.Create ('Dirección no asignada (AnadirOSCAddressBook)'); ACliente.DataTable.Active := True; ADireccionContacto.DataTable.Active := True; AOSCAddressBook.DataTable.Active := True; with AOSCAddressBook do begin Insert; rdx_address_book_id_local := ADireccionContacto.ID; entry_company := ACliente.NOMBRE_COMERCIAL; entry_gender := OSC_CUSTOMER_GENDER; // No puede ser nulo entry_firstname := ACliente.NOMBRE; entry_lastname := ''; // No puede ser nulo entry_street_address := ADireccionContacto.CALLE; entry_postcode := ADireccionContacto.CODIGO_POSTAL; entry_city := ADireccionContacto.POBLACION; entry_state := ADireccionContacto.PROVINCIA; entry_telephone := ADireccionContacto.TELEFONO; entry_country_id := OSC_CUSTOMER_COUNTRY_ID; // No puede ser nulo entry_zone_id := OSC_CUSTOMER_ZONE_ID; // No puede ser nulo Post; end; Result := True; end; function ActualizarOSCAddressBook(AOSCAddressBook : IBizOscAddressBook; ACliente : IBizCliente; ADireccionContacto : IBizDireccionesContacto): Boolean; begin Result := False; if not Assigned(AOSCAddressBook) then raise Exception.Create ('OSCAddressBook no asignado (ActualizarOSCAddressBook)'); if not Assigned(ACliente) then raise Exception.Create ('Cliente no asignado (ActualizarOSCAddressBook)'); if not Assigned(ADireccionContacto) then raise Exception.Create ('Dirección no asignada (ActualizarOSCAddressBook)'); ACliente.DataTable.Active := True; ADireccionContacto.DataTable.Active := True; AOSCAddressBook.DataTable.Active := True; with AOSCAddressBook do begin Edit; entry_company := ACliente.NOMBRE_COMERCIAL; entry_gender := OSC_CUSTOMER_GENDER; // No puede ser nulo entry_firstname := ACliente.NOMBRE; entry_lastname := ''; // No puede ser nulo entry_street_address := ADireccionContacto.CALLE; entry_postcode := ADireccionContacto.CODIGO_POSTAL; entry_city := ADireccionContacto.POBLACION; entry_state := ADireccionContacto.PROVINCIA; entry_telephone := ADireccionContacto.TELEFONO; entry_country_id := OSC_CUSTOMER_COUNTRY_ID; // No puede ser nulo entry_zone_id := OSC_CUSTOMER_ZONE_ID; // No puede ser nulo Post; end; Result := True; end; function AnadirOSCCustomer(AOSCCustomers : IBizOscCustomer; ACliente : IBizCliente): Boolean; var AOSCCustomerController : IOscCustomersController; i : Integer; Resultado : Boolean; s : string; begin { CUIDADITO CON EL MYSQL Y LOS CAMPOS AUTOINC Orden para insertar los datos: 1º -> Guardar la ficha del cliente 2º -> Guardar todas las direcciones 3ª -> Actualizar la ficha del cliente con la dirección de entrega por defecto. } Result := True; if not Assigned(AOSCCustomers) then raise Exception.Create ('OSCCustomers no asignado (AnadirOSCCustomer)'); if not Assigned(ACliente) then raise Exception.Create ('Cliente no asignado (AnadirOSCCustomer)'); ACliente.DataTable.Active := True; AOSCCustomerController := TOscCustomersController.Create; AOSCCustomers.DataTable.Active := True; try AOSCCustomerController.Anadir(AOSCCustomers); with AOSCCustomers do begin customers_firstname := ACliente.NOMBRE; customers_lastname := ''; // No puede ser nulo customers_email_address := ACliente.EMAIL_1; customers_telephone := ACliente.TELEFONO_1; customers_fax := ACliente.FAX; customers_password := EncriptarPasswordOSC(ACliente.NIF_CIF); rdx_customers_id_local := ACliente.ID; Post; end; // Guardo el customer AOSCCustomerController.Guardar(AOSCCustomers); ACliente.Direcciones.DataTable.First; for i := 0 to ACliente.Direcciones.DataTable.RecordCount - 1 do begin Resultado := AnadirOSCAddressBook(AOSCCustomers.AddressBook, ACliente, ACliente.Direcciones); Result := Result AND Resultado; ACliente.Direcciones.DataTable.Next; end; // Guardo todas sus direcciones AOSCCustomerController.Guardar(AOSCCustomers); AOSCCustomers.AddressBook.DataTable.First; with AOSCCustomers do begin Edit; customers_default_address_id := AOSCCustomers.AddressBook.address_book_id; Post; end; // Guardo la dirección de entrega por defecto en la ficha del customer AOSCCustomerController.Guardar(AOSCCustomers); {s := AOSCCustomers.customers_firstname + #10#13 + 'AOSCCustomers.customers_id -> ' + IntToStr(AOSCCustomers.customers_id) + #10#13 + #10#13 + 'AOSCCustomers.AddressBook:' + #10#13; AOSCCustomers.AddressBook.DataTable.First; for i := 0 to AOSCCustomers.AddressBook.DataTable.RecordCount - 1 do begin s := s + Format(' [%d] -> %d', [i, AOSCCustomers.AddressBook.address_book_id]) + #10#13; AOSCCustomers.AddressBook.DataTable.Next; end; ShowMessage(s);} finally AOSCCustomerController := NIL; end; end; function ActualizarOSCCustomer(AOSCCustomers : IBizOscCustomer; ACliente : IBizCliente) : Boolean; var AOSCCustomerController : IOscCustomersController; AOSCAddressController : IOscAddressBookController; ADireccionesController : IDireccionesContactoController; i : Integer; Resultado : Boolean; begin Result := True; if not Assigned(AOSCCustomers) then raise Exception.Create ('OSCCustomers no asignado (ActualizarOSCCustomer)'); if not Assigned(ACliente) then raise Exception.Create ('Cliente no asignado (ActualizarOSCCustomer)'); ACliente.DataTable.Active := True; AOSCCustomerController := TOscCustomersController.Create; AOSCAddressController := TOscAddressBookController.Create; ADireccionesController := TDireccionesContactoController.Create; AOSCCustomers.DataTable.Active := True; try if not AOSCCustomerController.Localizar(AOSCCustomers, ACliente.ID) then raise Exception.CreateFmt('No se ha localizado el customer con ID = %d', [ACliente.ID]); with AOSCCustomers do begin Edit; customers_firstname := ACliente.NOMBRE; customers_lastname := ''; // No puede ser nulo customers_email_address := ACliente.EMAIL_1; customers_telephone := ACliente.TELEFONO_1; customers_fax := ACliente.FAX; Post; end; AOSCCustomerController.Guardar(AOSCCustomers); // Comprobar si hay que borrar algún address AOSCCustomers.AddressBook.Last; for i := 0 to AOSCCustomers.AddressBook.RecordCount - 1 do begin if (AOSCCustomers.AddressBook.rdx_address_book_id_local > 0) and not ADireccionesController.Localizar(ACliente.Direcciones, AOSCCustomers.AddressBook.rdx_address_book_id_local) then AOSCCustomers.AddressBook.Delete else AOSCCustomers.AddressBook.Prior; end; ACliente.Direcciones.DataTable.First; for i := 0 to ACliente.Direcciones.DataTable.RecordCount - 1 do begin if not AOSCAddressController.Localizar(AOSCCustomers.AddressBook, ACliente.Direcciones.ID) then Resultado := AnadirOSCAddressBook(AOSCCustomers.AddressBook, ACliente, ACliente.Direcciones) else Resultado := ActualizarOSCAddressBook(AOSCCustomers.AddressBook, ACliente, ACliente.Direcciones); Result := Result AND Resultado; ACliente.Direcciones.DataTable.Next; end; AOSCCustomerController.Guardar(AOSCCustomers); //ShowMessage(AOSCCustomers.customers_firstname + #10#13 + 'AOSCCustomers.customers_id -> ' + IntToStr(AOSCCustomers.customers_id)); AOSCCustomers.AddressBook.DataTable.First; with AOSCCustomers do begin Edit; customers_default_address_id := AOSCCustomers.AddressBook.address_book_id; Post; end; // Guardo la dirección de entrega por defecto en la ficha del customer AOSCCustomerController.Guardar(AOSCCustomers); finally AOSCCustomerController := NIL; AOSCAddressController := NIL; ADireccionesController := NIL; end; end; function HayCambiosPendientes(ACliente : IBizCliente; AOSCCustomer : IBizOscCustomer; const UltimaSincro : TDateTime): Boolean; var i : integer; Cambiado : Boolean; ANumAddr : Integer; begin { Casos: 1 -> El cliente ha cambiado en FactuGES 2 -> Se ha dado de alta una dirección 3 -> Se han cambiado los datos de una dirección 4 -> Se ha eliminado una dirección } if not Assigned(ACliente) then raise Exception.Create ('Cliente no asignado (HayCambiosPendientes)'); if not Assigned(AOSCCustomer) then raise Exception.Create ('Customer no asignado (HayCambiosPendientes)'); ACliente.DataTable.Active := True; AOSCCustomer.DataTable.Active := True; // 1 -> ¿El cliente ha cambiado en FactuGES? Cambiado := (ACliente.FECHA_MODIFICACION > UltimaSincro); if not Cambiado then begin ACliente.Direcciones.First; { 2 -> ¿Se ha dado de alta una dirección? 4 -> ¿Se ha eliminado una dirección? } ANumAddr := 0; AOSCCustomer.AddressBook.First; for i := 0 to AOSCCustomer.AddressBook.RecordCount - 1 do begin // Saber el número de address que tienen relleno el campo rdx_address_book_id_local. // Si lo tienen relleno quiere decir que provienen de FactuGES y no // que el cliente las ha dado de alta desde OSC. Esas se ignoran. if (AOSCCustomer.AddressBook.rdx_address_book_id_local > 0) then begin Inc(ANumAddr); end; AOSCCustomer.AddressBook.Next; end; // Si no coincide el número de calles es que algo ha cambiado Cambiado := ACliente.Direcciones.RecordCount <> ANumAddr; { 3 -> ¿Se han cambiado los datos de una dirección? } if not Cambiado then begin for i := 0 to ACliente.Direcciones.RecordCount - 1 do begin Cambiado := ((ACliente.Direcciones.FECHA_MODIFICACION > UltimaSincro) or (ACliente.Direcciones.FECHA_ALTA > UltimaSincro)); if Cambiado then Break else ACliente.Direcciones.Next; end; end; end; Result := Cambiado; end; function ActualizarClientesTienda(ATiendaWeb : IBizTiendaWeb): Boolean; var AClientesController : IClientesController; AClientes : IBizCliente; AOSCCustomerController : IOscCustomersController; AOSCCustomers : IBizOscCustomer; i : Integer; j : Integer; //ADlg : TJSDialog; Resultado : Boolean; s : String; ACustomerList : TIntegerList; AIndex : Integer; begin Result := False; if not Assigned(ATiendaWeb) then raise Exception.Create ('TiendaWeb no asignada'); try AClientesController := TClientesController.Create; AOSCCustomerController := TOscCustomersController.Create; ACustomerList := TIntegerList.Create; {ADlg := TJSDialog.Create(Application); with ADlg do begin Title := 'Actualización de clientes'; DialogOptions := [doProgressBar, doTopMost]; ButtonBar.Buttons := []; Instruction.Text := 'Actualizando clientes...'; Content.Text := Format('Progreso: %d%%', [0]); Expando.Visible := True; Expando.MoreHeight := 200; Expando.ShowInFooter := True; Expando.ShowText := 'Ver más detalles...'; Expando.HideText := 'Ocultar detalles...'; Progress.Max := 100; end;} AClientes := (AClientesController.BuscarTodosTiendaWeb as IBizCliente); AClientes.DataTable.Active := True; AClientes.DataTable.First; AOSCCustomers := AOSCCustomerController.BuscarTodos; AOSCCustomers.DataTable.Active := True; AOSCCustomers.DataTable.First; {if AClientes.DataTable.RecordCount > 0 then ADlg.Progress.Max := AClientes.DataTable.RecordCount; ADlg.Execute; } {s := ''; AOSCCustomers.DataTable.First; for I := 0 to AOSCCustomers.DataTable.RecordCount - 1 do begin s := s + AOSCCustomers.customers_firstname + ' -> ' + IntToStr(AOSCCustomers.rdx_customers_id_local) + #10#13; AOSCCustomers.DataTable.Next; end; ShowMessage(s);} for I := 0 to AClientes.DataTable.RecordCount - 1 do begin Application.ProcessMessages; {with ADlg do begin Content.Text := Format('Progreso: %d%%', [Progress.Position*100 div ADlg.Progress.Max]); UpdateProgress; Application.ProcessMessages; end;} if not AOSCCustomerController.Localizar(AOSCCustomers, AClientes.ID) then begin s := Format('Añadiendo %s... ', [AClientes.NOMBRE]); Resultado := AnadirOSCCustomer(AOSCCustomers, AClientes); if Resultado then s := s + 'OK' else s := s + 'Fallo'; end else begin if HayCambiosPendientes(AClientes, AOSCCustomers, ATiendaWeb.ULTIMA_ACTUALIZACION) then begin s := Format('Actualizando %s... ', [AClientes.NOMBRE]); Resultado := ActualizarOSCCustomer(AOSCCustomers, AClientes); if Resultado then s := s + 'OK' else s := s + 'Fallo'; end else s := Format('%s sin cambios', [AClientes.NOMBRE]); end; //ADlg.Expando.Lines.Add(s); ACustomerList.Add(AClientes.ID); AClientes.DataTable.Next; end; // Ahora hay que eliminar de OSC los clientes que sobran AOSCCustomers.Last; for I := (AOSCCustomers.DataTable.RecordCount - 1) downto 0 do begin Application.ProcessMessages; if not ACustomerList.Find(AOSCCustomers.rdx_customers_id_local, AIndex) then begin s := Format('Eliminado %s... ', [AOSCCustomers.customers_firstname]); //ADlg.Expando.Lines.Add(s); AOSCCustomers.Delete; end; AOSCCustomers.Prior; end; AOSCCustomerController.Guardar(AOSCCustomers); Application.ProcessMessages; Result := True; finally {ADlg.Close; FreeAndNIL(ADlg);} FreeAndNIL(ACustomerList); AClientesController := NIL; AOSCCustomerController := NIL; AOSCCustomers := NIL; end; end; end.