unit uActualizarArticulosUtils;

interface

uses
  Forms, Classes, Windows, SysUtils,
  uBizTiendaWeb, JSDialog, ExtCtrls;

function ActualizarArticulosTienda(ATiendaWeb : IBizTiendaWeb): Boolean;

implementation

uses
  uArticulosController, uBizArticulos,
  uOscProductsController, uProveedoresController, uOscManufacturersController,
  uBizOscManufacturers, uBizOscProducts,
  uPasswordUtils, schTiendaWebClient_Intf, uDADataTable,
  uBizContactos, uBizDireccionesContacto,
  schContactosClient_Intf, JSDialogs, uDialogUtils, StrUtils, uIntegerListUtils,
  schArticulosClient_Intf;


function AnadirOSCProduct(AOSCProducts : IBizOscProduct; AArticulo : IBizArticulo): Boolean;
var
  AOSCProductController : IOscProductsController;
  AOSCManufacturersController : TOscManufacturersController;
  AOSCManufacturer : IBizOscManufacturer;
  Resultado : Boolean;
begin
  Result := True;

  if not Assigned(AOSCProducts) then
    raise Exception.Create ('OSCProducts no asignado (AnadirOSCProduct)');

  if not Assigned(AArticulo) then
    raise Exception.Create ('Articulo no asignado (AnadirOSCProduct)');

  AArticulo.DataTable.Active := True;

  AOSCProductController := TOscProductsController.Create;
  AOSCProducts.DataTable.Active := True;

  AOSCManufacturersController := TOscManufacturersController.Create;
  AOSCManufacturer := AOSCManufacturersController.Buscar(AArticulo.ID_PROVEEDOR);
  AOSCManufacturer.DataTable.Active := True;
  if (AOSCManufacturer.DataTable.RecordCount = 0) then
    raise Exception.CreateFmt('No se ha encontrado el proveedor %d en la tienda web (AnadirOSCProduct)', [AArticulo.ID_PROVEEDOR]);

  try
    AOSCProductController.Anadir(AOSCProducts);
    with AOSCProducts do
    begin
      products_name := AArticulo.DESCRIPCION;
      products_model := AArticulo.REFERENCIA_PROV;
      products_date_added := Now;
      manufacturers_id := AOSCManufacturer.manufacturers_id;
      rdx_products_id_local := AArticulo.ID;
      products_status := 1;
      Post;
    end;
    AOSCProductController.Guardar(AOSCProducts);
    
  finally
    AOSCProductController := NIL;
    AOSCManufacturer := NIL;
    AOSCManufacturersController := NIL;
  end;
end;


function ActualizarOSCProduct(AOSCProducts : IBizOscProduct; AArticulo : IBizArticulo) : Boolean;
var
  AOSCProductController : IOscProductsController;
  AOSCManufacturersController : TOscManufacturersController;
  AOSCManufacturer : IBizOscManufacturer;
  Resultado : Boolean;  
begin
  Result := True;

  if not Assigned(AOSCProducts) then
    raise Exception.Create ('OSCProducts no asignado (ActualizarOSCProduct)');

  if not Assigned(AArticulo) then
    raise Exception.Create ('Artículo no asignado (ActualizarOSCProduct)');

  AArticulo.DataTable.Active := True;

  AOSCProductController := TOscProductsController.Create;
  AOSCProducts.DataTable.Active := True;

  AOSCManufacturersController := TOscManufacturersController.Create;
  AOSCManufacturer := AOSCManufacturersController.Buscar(AArticulo.ID_PROVEEDOR);
  AOSCManufacturer.DataTable.Active := True;
  if (AOSCManufacturer.DataTable.RecordCount = 0) then
    raise Exception.CreateFmt('No se ha encontrado el proveedor %d en la tienda web (ActualizarOSCProduct)', [AArticulo.ID_PROVEEDOR]);
  
  try
    if not AOSCProductController.Localizar(AOSCProducts, AArticulo.ID) then
      raise Exception.CreateFmt('No se ha localizado el producto con ID = %d', [AArticulo.ID]);

    with AOSCProducts do
    begin
      Edit;
      products_name := AArticulo.DESCRIPCION;
      products_model := AArticulo.REFERENCIA_PROV;
      products_last_modified := Now;
      manufacturers_id := AOSCManufacturer.manufacturers_id;
      products_status := 1;      
      Post;
    end;
    AOSCProductController.Guardar(AOSCProducts);
    
  finally
    AOSCProductController := NIL;
    AOSCManufacturer := NIL;
    AOSCManufacturersController := NIL;
  end;
end;

function HayCambiosPendientes(AArticulo : IBizArticulo; const UltimaSincro : TDateTime): Boolean;
begin
  if not Assigned(AArticulo) then
    raise Exception.Create ('Artículo no asignado (HayCambiosPendientes)');

  AArticulo.DataTable.Active := True;

  Result := (AArticulo.FECHA_MODIFICACION > UltimaSincro);
end;

function ActualizarArticulosTienda(ATiendaWeb : IBizTiendaWeb): Boolean;
var
  AProveedoresController : IProveedoresController;
  AProveedores : IBizProveedor;

  AOSCProductController : IOscProductsController;
  AOSCProducts : IBizOscProduct;

  AArticulosController : IArticulosController;
  AArticulos : IBizArticulo;

  i : Integer;

  //ADlg : TJSDialog;
  Resultado : Boolean;
  s : String;

  AProductList : TIntegerList;
  AIndex : Integer;
  AContadorProv: Integer;
  AContadorArt : Integer;
begin
  Result := False;
  if not Assigned(ATiendaWeb) then
    raise Exception.Create ('TiendaWeb no asignada');

  try
    AProveedoresController := TProveedoresController.Create;
    AArticulosController := TArticulosController.Create;
    AOSCProductController := TOscProductsController.Create;

    AProductList := TIntegerList.Create;

    {ADlg := TJSDialog.Create(nil);
    with ADlg do
    begin
      Title := 'Actualización de artículos';
      DialogOptions := [doProgressBar, doTopMost];
      ButtonBar.Buttons := [];
      Instruction.Text := 'Actualizando artículos...';
      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;}

    // Recupero todos los proveedores que hay en la tienda
    AProveedores := (AProveedoresController.BuscarTodosTiendaWeb as IBizProveedor);
    AProveedores.DataTable.Active := True;
    AProveedores.DataTable.First;

    AOSCProducts := AOSCProductController.BuscarTodos;
    AOSCProducts.DataTable.Active := True;
    AOSCProducts.DataTable.First;

    {if AProveedores.DataTable.RecordCount > 0 then
      ADlg.Progress.Max := AProveedores.DataTable.RecordCount;}

    for AContadorProv := 0 to AProveedores.DataTable.RecordCount - 1 do
    begin
      // Por cada uno de los proveedores:
      //  - Recupero todos los artículos que sirve
      //  - Actualizo la tienda

      AArticulos := AArticulosController.BuscarTodos(AProveedores);
      AArticulos.DataTable.Active := True;
      AArticulos.DataTable.First;

      for AContadorArt := 0 to AArticulos.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 AOSCProductController.Localizar(AOSCProducts, AArticulos.ID) then
        begin
          s := Format('Añadiendo %15s... ', [AArticulos.DESCRIPCION]);
          Resultado := AnadirOSCProduct(AOSCProducts, AArticulos);
          if Resultado then
            s := s + 'OK'
          else
            s := s + 'Fallo';
        end
        else begin
          if HayCambiosPendientes(AArticulos, ATiendaWeb.ULTIMA_ACTUALIZACION) then
          begin
            s := Format('Actualizando %15s... ', [AArticulos.DESCRIPCION]);
            Resultado := ActualizarOSCProduct(AOSCProducts, AArticulos);
            if Resultado then
              s := s + 'OK'
            else
              s := s + 'Fallo';
          end
          else
            s := Format('%15s... sin cambios', [AArticulos.DESCRIPCION]);
        end;

        //ADlg.Expando.Lines.Add(s);
        AProductList.Add(AArticulos.ID);
        AArticulos.DataTable.Next;
      end;

      // Avanzo al siguiente proveedor
      AProveedores.DataTable.Next;
    end;

    // Ahora hay que eliminar de OSC los artículos que sobran
    AOSCProducts.Last;
    for I := (AOSCProducts.DataTable.RecordCount - 1) downto 0 do
    begin
      Application.ProcessMessages;
      if not AProductList.Find(AOSCProducts.rdx_products_id_local, AIndex) then
      begin
        s := Format('Eliminado %15s... ', [AOSCProducts.products_name]);
        //ADlg.Expando.Lines.Add(s);
        AOSCProducts.Delete;
      end;
      AOSCProducts.Prior;
    end;
    AOSCProductController.Guardar(AOSCProducts);

    Application.ProcessMessages;
    Result := True;
  finally
    {ADlg.Close;
    FreeAndNIL(ADlg);}
    
    FreeAndNIL(AProductList);

    AProveedoresController := NIL;
    AArticulosController := NIL;
    AOSCProductController := NIL;
    AOSCProducts := NIL;
    AProveedores := NIL;
    AArticulos := NIL;
  end;
end;


end.
