unit uActualizarPedidosUtils;

interface

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

function ActualizarPedidosTienda(ATiendaWeb : IBizTiendaWeb): Boolean;

implementation

uses
  uPedidosClienteController, uOscOrderProductsController, uDetallesPedidoClienteController,
  uOscOrdersController, uBizOscOrderProducts, uBizOscOrders, uClientesController,
  uPasswordUtils, schTiendaWebClient_Intf, uDADataTable, uBizPedidosCliente,
  uBizDetallesPedidoCliente, schPedidosClienteClient_Intf,
  JSDialogs, uDialogUtils, StrUtils, uIntegerListUtils,
  uBizContactos, uControllerDetallesBase;


function DarNumSituacionEquivalente(ASituacion : String) : Integer;
begin
  if ASituacion = SITUACION_PEDIDO_PENDIENTE then
    Result := 1
  else if ASituacion = SITUACION_PEDIDO_ENPROCESO then
    Result := 2
  else if ASituacion = SITUACION_PEDIDO_SERVIDO then
    Result := 3
  else
    Result := -1;
end;

function AnadirPedido(AOSCOrder : IBizOscOrder; APedido : IBizPedidoCliente): Boolean;
var
  APedidosController : IPedidosClienteController;
  ADetallesController : IDetallesPedidoClienteController;
  AClientesController : IClientesController;
  i : Integer;
  Resultado : Boolean;
begin
  Result := False;

  if not Assigned(AOSCOrder) then
    raise Exception.Create ('AOSCOrder no asignado (AnadirPedido)');

  if not Assigned(APedido) then
    raise Exception.Create ('Pedido no asignado (AnadirPedido)');

  AOSCOrder.DataTable.Active := True;
  APedido.DataTable.Active := True;

  APedidosController := TPedidosClienteController.Create;
  ADetallesController := TDetallesPedidoClienteController.Create;
  AClientesController := TClientesController.Create;

  try
    APedidosController.Anadir(APedido);
    with APedido do
    begin
      ID_CLIENTE := AOSCOrder.rdx_customers_id_local;
      _Cliente := (AClientesController.Buscar(AOSCOrder.rdx_customers_id_local) as IBizCliente);
      FECHA_PEDIDO := AOSCOrder.date_purchased;

      CALLE := AOSCOrder.delivery_street_address;
      CODIGO_POSTAL := AOSCOrder.delivery_postcode;
      POBLACION := AOSCOrder.delivery_city;
      PROVINCIA := AOSCOrder.delivery_state;
      PERSONA_CONTACTO := AOSCOrder.delivery_name;
      TELEFONO := AOSCOrder.delivery_telephone;
      REF_TIENDA_WEB := AOSCOrder.orders_id;
      FECHA_PREVISTA_ENVIO := AOSCOrder.rdx_ship_date;
      REFERENCIA_CLIENTE := AOSCOrder.rdx_referencia_cliente;

      DataTable.FieldByName(fld_PedidosClienteOBSERVACIONES).AsVariant := AOSCOrder.DataTable.FieldByName(fld_osc_Orderscomments).AsVariant;
      Post;
    end;

    AOSCOrder.OrderProducts.DataTable.First;
    for i := 0 to AOSCOrder.OrderProducts.DataTable.RecordCount - 1 do
    begin
      ADetallesController.Add(APedido.Detalles, TIPO_DETALLE_CONCEPTO);

      // ¡¡¡OJO!!! AnadirArticulo no añade una fila. Sólo rellena el concepto actual
      Resultado := ADetallesController.AnadirArticulo(APedido.Detalles, AOSCOrder.OrderProducts.rdx_products_id_local, AOSCOrder.rdx_customers_id_local);
      APedido.Detalles.Edit;
      APedido.Detalles.CANTIDAD := AOSCOrder.OrderProducts.products_quantity;
      APedido.Detalles.Post;      
      Result := Result AND Resultado;
      AOSCOrder.OrderProducts.DataTable.Next;
    end;

    // Guardo el pedido
    APedidosController.Guardar(APedido);

    AOSCOrder.Edit;
    AOSCOrder.rdx_orders_id_local := APedido.ID;
    AOSCOrder.Post;

    Result := True;
  finally
    APedidosController := NIL;
    ADetallesController := NIL;
    AClientesController := NIL;
  end;
end;

function ActualizarOSCOrder(AOSCOrders : IBizOscOrder; APedido : IBizPedidoCliente) : Boolean;
var
  AOSCOrderController : IOscOrdersController;
begin
  Result := True;

  if not Assigned(AOSCOrders) then
    raise Exception.Create ('OSCOrders no asignado (ActualizarOSCOrder)');

  if not Assigned(APedido) then
    raise Exception.Create ('Pedido no asignado (ActualizarOSCOrder)');

  APedido.DataTable.Active := True;

  AOSCOrderController := TOscOrdersController.Create;

  AOSCOrders.DataTable.Active := True;
  try
    if not AOSCOrderController.Localizar(AOSCOrders, APedido.ID) then
      raise Exception.CreateFmt('No se ha localizado el order con ID = %d', [APedido.ID]);

    with AOSCOrders do
    begin
      Edit;
      orders_status := DarNumSituacionEquivalente(APedido.SITUACION);
      if APedido.SITUACION = SITUACION_PEDIDO_SERVIDO then
        orders_date_finished := Now;
      Post;
    end;
    AOSCOrderController.Guardar(AOSCOrders);
    Result := True;
  finally
    AOSCOrderController := NIL;
  end;
end;

function HayCambiosPendientes(APedido : IBizPedidoCliente; AOSCOrder : IBizOscOrder;
  const UltimaSincro : TDateTime): Boolean;
var
  APedidoSituacion : Integer;
begin
  Result := False;
  
  if not Assigned(APedido) then
    raise Exception.Create ('Cliente no asignado (HayCambiosPendientes)');

  if not Assigned(AOSCOrder) then
    raise Exception.Create ('Customer no asignado (HayCambiosPendientes)');

  APedido.DataTable.Active := True;
  AOSCOrder.DataTable.Active := True;

  APedidoSituacion := DarNumSituacionEquivalente(APedido.SITUACION);
  if APedidoSituacion <> AOSCOrder.orders_status then
    Result := True;
end;

function ActualizarPedidosTienda(ATiendaWeb : IBizTiendaWeb): Boolean;
var
  APedidosClienteController : IPedidosClienteController;
  APedidos : IBizPedidoCliente;

  AOSCOrderController : IOscOrdersController;
  AOSCOrders : IBizOscOrder;

  i : Integer;
  j : Integer;

  Resultado : Boolean;
  s : String;

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

  try
    APedidosClienteController := TPedidosClienteController.Create;
    AOSCOrderController := TOscOrdersController.Create;

    AOSCOrders := AOSCOrderController.BuscarTodos;
    AOSCOrders.DataTable.Active := True;
    AOSCOrders.DataTable.First;

    // ATENCION!!! -> Aquí habría que pedir sólo los pedidos que vienen por web no?
    APedidos := (APedidosClienteController.BuscarTodos as IBizPedidoCliente);
    APedidos.DataTable.Active := True;
    APedidos.DataTable.First;

    for I := 0 to AOSCOrders.DataTable.RecordCount - 1 do
    begin
      Application.ProcessMessages;

      // Si el campo rdx_orders_id_local está vacio, el pedido es nuevo
      if (AOSCOrders.rdx_orders_id_local = 0) then
      begin
        // Hay que añadir el pedido
        AnadirPedido(AOSCOrders, APedidos);
        // Paso al siguiente
        AOSCOrders.DataTable.Next;
      end
      else begin
        // Busco el pedido. Si no lo encuentro, se ha borrado en local
        if not APedidosClienteController.Localizar(APedidos, AOSCOrders.rdx_orders_id_local) then
        begin
          // Borrar el pedido en OSC
          AOSCOrderController.Eliminar(AOSCOrders);
          // No paso al siguiente porque al eliminar se ha desplazado ya la posición.
        end
        else begin
          if HayCambiosPendientes(APedidos, AOSCOrders, ATiendaWeb.ULTIMA_ACTUALIZACION) then
          begin
            // Actualizar el estado del pedido en OSC
            ActualizarOSCOrder(AOSCOrders, APedidos);
          end;
          // Paso al siguiente
          AOSCOrders.DataTable.Next;
        end;
      end;
    end;

    Application.ProcessMessages;
    AOSCOrderController.Guardar(AOSCOrders);
    Result := True;
  finally
    APedidosClienteController := NIL;
    AOSCOrderController := NIL;
    AOSCOrders := NIL;
  end;
end;

end.
