unit uClientesController;

interface

uses
  uCustomEditor, Classes,
  uContactosController, uBizContactos, uBizDireccionesContacto,
  uIEditorClientes, uIEditorCliente, uIDataModuleContactos, uIDataModuleClientes,
  uDireccionesContactoController, uBizContactosPersonal;

type
  IClientesController = interface(IContactosController)
  ['{AAC3C51A-37F7-4961-B39F-FBC6B6A2B0F1}']
    function BuscarTodosTiendaWeb: IBizCliente;
    function TieneDatosBancarios(ACliente: IBizCliente) : Boolean;
    function ElegirDireccionEntrega(ACliente: IBizCliente; AMensaje: String): IBizDireccionesContacto;
    function EsEliminable(ACliente: IBizContacto): Boolean;
    function Eliminar(ACliente: IBizContacto; AllItems: Boolean = false): Boolean; overload;
    procedure Preview(ACliente : IBizCliente; AllItems: Boolean = false);
    procedure Print(ACliente : IBizCliente; AllItems: Boolean = false);
    procedure VerPresupuestosDeCliente(ACliente : IBizCliente);
    procedure VerAlbaranesDeCliente(ACliente : IBizCliente);
    procedure VerFacturasDeCliente(ACliente : IBizCliente);
    procedure VerRecibosDeCliente(ACliente : IBizCliente);
    function DarListaCuentasBancarias(const IdCliente: Integer): TStringList;
  end;

  TClientesController = class(TContactosController, IClientesController)
  protected
    FDireccionesController : IDireccionesContactoController;
    function ValidarContacto(AContacto: IBizContacto): Boolean; override;
  public
    constructor Create; override;
    destructor Destroy; override;

    function Duplicar(AContacto: IBizContacto): IBizContacto; override;

    function Buscar(const ID: Integer): IBizContacto; override;
    function BuscarTodos: IBizContacto; override;
    function BuscarTodosTiendaWeb: IBizCliente;
    function Nuevo : IBizContacto; override;
    procedure Ver(AContacto : IBizContacto); override;
    procedure VerTodos(AContactos: IBizContacto); override;
    function ElegirContacto(AContactos : IBizContacto;
      AMensaje: String; AMultiSelect: Boolean): IBizContacto; override;
    function TieneDatosBancarios(ACliente: IBizCliente) : Boolean;
    function ElegirDireccionEntrega(ACliente: IBizCliente;
      AMensaje: String): IBizDireccionesContacto;
    function EsEliminable(ACliente: IBizContacto): Boolean;
    function Eliminar(ACliente: IBizContacto; AllItems: Boolean = false): Boolean; overload;
    procedure Preview(ACliente : IBizCliente; AllItems: Boolean = false);
    procedure Print(ACliente : IBizCliente; AllItems: Boolean = false);
    procedure VerPresupuestosDeCliente(ACliente : IBizCliente);
    procedure VerAlbaranesDeCliente(ACliente : IBizCliente);
    procedure VerFacturasDeCliente(ACliente : IBizCliente);
    procedure VerRecibosDeCliente(ACliente : IBizCliente);
    function DarListaCuentasBancarias(const IdCliente: Integer): TStringList;
  end;

implementation

uses
  Forms, Windows, SysUtils, Controls, cxControls, uDialogUtils, uDataModuleClientes, uEditorRegistryUtils,
  uDataTableUtils, uDADataTable, DB, schContactosClient_Intf, uEtiquetasContactosReportController,
  uIEditorElegirClientes, uIEditorElegirDireccionEntrega, uEditorGridBase, uModuleController,
  Dialogs, uIntegerListUtils, uFactuGES_App,
  uPlugins_Intf;

{ TClientesController }

function TClientesController.Buscar(const ID: Integer): IBizContacto;
begin
  Result := (FDataModule as IDataModuleClientes).GetItem(ID);
  FiltrarEmpresa(Result);
end;

function TClientesController.BuscarTodos: IBizContacto;
begin
  Result := (FDataModule as IDataModuleClientes).GetItems;
  FiltrarEmpresa(Result);
end;

function TClientesController.BuscarTodosTiendaWeb: IBizCliente;
begin
  Result := (FDataModule as IDataModuleClientes).GetItemsTiendaWeb;
  FiltrarEmpresa(Result);
end;

constructor TClientesController.Create;
begin
  inherited;
  FDataModule := TDataModuleClientes.Create(Nil);
  FDireccionesController := TDireccionesContactoController.Create;
end;

function TClientesController.DarListaCuentasBancarias(const IdCliente: Integer): TStringList;
var
  ACliente: IBizCliente;
  Aux : String;

begin
  ACliente := (Buscar(IdCliente) as IBizCliente);
  ACliente.DataTable.Active := True;

  Result := TStringList.Create;
  ShowHourglassCursor;
  try
    with Result do
    begin
      ACliente.DatosBancarios.DataTable.First;
      while not ACliente.DatosBancarios.DataTable.EOF do
      begin
        Aux := Format('Nº de cuenta: %s %s %s %s  - Titular: %s ', [ACliente.DatosBancarios.ENTIDAD,
          ACliente.DatosBancarios.SUCURSAL, ACliente.DatosBancarios.DC, ACliente.DatosBancarios.CUENTA, ACliente.DatosBancarios.TITULAR]);
        Add(Format('%s=%d', [Aux, ACliente.DatosBancarios.ID]));
        ACliente.DatosBancarios.DataTable.Next;
      end;
    end;
  finally
    ACliente := NIL;
    HideHourglassCursor;
  end;
end;

destructor TClientesController.Destroy;
begin
  FDireccionesController := NIL;
  inherited;
end;

function TClientesController.Duplicar(AContacto: IBizContacto): IBizContacto;
begin
  Result := inherited Duplicar(AContacto);

  if Assigned((Result as IBizCliente).Descuentos) then
     DuplicarRegistros((AContacto as IBizCliente).Descuentos.DataTable, (Result as IBizCliente).Descuentos.DataTable, mdrTodos);
end;

function TClientesController.ElegirContacto(AContactos : IBizContacto;
  AMensaje: String; AMultiSelect: Boolean): IBizContacto;
var
  AEditor : IEditorElegirClientes;
begin
  Result := NIL;

  CreateEditor('EditorElegirClientes', IEditorElegirClientes, AEditor);
  if Assigned(AEditor) then
  begin
    try
      AEditor.Contactos := AContactos;
      AEditor.Controller := Self;
      AEditor.MultiSelect := AMultiSelect;
      AEditor.Mensaje := AMensaje;
      if IsPositiveResult(AEditor.ShowModal) then
        Result := AEditor.ContactosSeleccionados;
    finally
      AEditor.Release;
      AEditor := NIL;
      Application.ProcessMessages;
    end;
  end;
end;

function TClientesController.ElegirDireccionEntrega(ACliente: IBizCliente;
  AMensaje: String): IBizDireccionesContacto;
var
  AEditor : IEditorElegirDireccionEntrega;
begin
  Result := NIL;

  CreateEditor('EditorElegirDireccionEntrega', IEditorElegirDireccionEntrega, AEditor);
  if Assigned(AEditor) then
  begin
    try
      AEditor.Contacto := ACliente;
      AEditor.Mensaje := AMensaje;
      if IsPositiveResult(AEditor.ShowModal) then
        Result := AEditor.DireccionSeleccionada;
    finally
      AEditor.Release;
      AEditor := NIL;
      Application.ProcessMessages;
    end;
  end;
end;

function TClientesController.Eliminar(ACliente: IBizContacto; AllItems: Boolean): Boolean;
//En el caso de eliminar almenos un elemento del conjunto se devuelve true
var
  bEliminado: Boolean;
begin
  bEliminado := False;

  if not Assigned(ACliente) then
    raise Exception.Create ('Contacto no asignado');

  ShowHourglassCursor;
  try
    if not ACliente.DataTable.Active then
      ACliente.DataTable.Active := True;

    if (ACliente.State in dsEditModes) then
      ACliente.Cancel;

    //Siempre eliminaremos el seleccionado
    if EsEliminable(ACliente) then
    begin
      ACliente.Delete;
      bEliminado := True;
    end;

    //En el caso de querer eliminar todos los items del objeto ACliente
    if AllItems then
    begin
       with ACliente.DataTable do
       begin
         First;
         while not EOF do
         begin
           if EsEliminable(ACliente) then
           begin
              ACliente.Delete;
              bEliminado := True
           end
           else Next;
         end;
       end;
    end;

    if bEliminado then
    begin
       ACliente.DataTable.ApplyUpdates;
       Result := True;
    end
    else
       Result := False;

  finally
    HideHourglassCursor;
  end;
end;

function TClientesController.EsEliminable(ACliente: IBizContacto): Boolean;
begin
  if not Assigned(ACliente) then
     raise Exception.Create ('Contacto no asignado: EsEliminable');

  Result := True;
end;

function TClientesController.Nuevo: IBizContacto;
var
  AContacto : IBizCliente;
begin
  AContacto := (FDataModule as IDataModuleClientes).NewItem;
  FiltrarEmpresa(AContacto);
  AContacto.DataTable.Active := True;
  AContacto.Insert;
  Result := AContacto;
end;

procedure TClientesController.Preview(ACliente: IBizCliente; AllItems: Boolean);
var
  AReportController : IEtiquetasContactosReportController;
  ListaID: TIntegerList;
begin
  AReportController := TEtiquetasContactosReportController.Create;
  ListaID := TIntegerList.Create;

  try
   //Si deseamos previsualizar todos los items del objeto albaran
   if AllItems then
   begin
     with ACliente.DataTable do
     begin
       First;
       while not EOF do
       begin
         ListaID.Add(ACliente.ID);
         Next;
       end;
     end;
   end
   //Solo previsualizamos el item seleccionado
   else
     ListaID.Add(ACliente.ID);

    AReportController.Preview(ListaID);
  finally
    AReportController := NIL;
    FreeANDNIL(ListaID);
  end;
end;

procedure TClientesController.Print(ACliente: IBizCliente; AllItems: Boolean);
var
  AReportController : IEtiquetasContactosReportController;
  ListaID: TIntegerList;

begin
  AReportController := TEtiquetasContactosReportController.Create;
  ListaID := TIntegerList.Create;

  try
   //Si deseamos previsualizar todos los items del objeto albaran
   if AllItems then
   begin
     with ACliente.DataTable do
     begin
       First;
       while not EOF do
       begin
         ListaID.Add(ACliente.ID);
         Next;
       end;
     end;
   end
   //Solo previsualizamos el item seleccionado
   else
     ListaID.Add(ACliente.ID);

    AReportController.Print(ListaID);

  finally
    AReportController := NIL;
    FreeANDNil(ListaID);
  end;
end;

function TClientesController.TieneDatosBancarios(
  ACliente: IBizCliente): Boolean;
begin
  if not Assigned(ACliente) then
    raise Exception.Create ('Cliente no asignado (TieneDatosBancarios)');

  if ACliente.DataTable.Active then
    ACliente.DataTable.Active := True;

  with ACliente.DatosBancarios do
  begin
    Result := (DataTable.RecordCount > 0) and
    (
      (Length(ENTIDAD) > 0) and
      (Length(SUCURSAL) > 0) and
      (Length(DC) > 0) and
      (Length(CUENTA) > 0)
    );
  end;
end;

function TClientesController.ValidarContacto(AContacto: IBizContacto): Boolean;
begin
  Result := inherited ValidarContacto(AContacto);
  if Result then
  begin
    with (AContacto as IBizCliente) do
    begin
      if (BLOQUEADO = 0) then
      begin
        Edit;
        MOTIVO_BLOQUEO := '';
        Post;
      end;

      if (TIENDA_WEB = 1) and (Length(EMAIL_1) = 0) then
      begin
        {ShowWarningMessage('Acceso a la tienda web',
          'Para que el cliente pueda tener acceso a la tienda web es necesario indicar una dirección de e-mail en el campo ''Correo de trabajo''' +
           #10#13 + #10#13 +
          'Por favor, indique una dirección o desactive el acceso a la tienda.');
         Result := False;}
        raise Exception.Create('Para que el cliente pueda tener acceso a la tienda web es necesario indicar una dirección de e-mail en el campo ''Correo de trabajo''' +
           #10#13 + #10#13 +
          'Por favor, indique una dirección o desactive el acceso a la tienda.');
      end;
    end;

    {
    // Por ahora no existe el concepto de direcciones de entrega asi que esto está desactivado
    if Result and (AContacto.Direcciones.RecordCount = 0) then
      if (ShowConfirmMessage('El cliente no tiene direcciones asociadas',
        AContacto.NOMBRE + ' no tiene ninguna dirección de envío dada de alta, ' + #10#13 +
        '¿Desea utilizar el domicilio fiscal para dar de alta una dirección de entrega?') = IDYES) then
      begin
        FDireccionesController.CopiarDireccionFiscal(AContacto, AContacto.Direcciones);
        FDireccionesController.Ver(AContacto.Direcciones);
      end;}
  end;
end;

procedure TClientesController.Ver(AContacto: IBizContacto);
var
  AEditor : IEditorCliente;
begin
  AEditor := NIL;

  CreateEditor('EditorCliente', IEditorCliente, AEditor);
  if Assigned(AEditor) then
    try
      AEditor.Contacto := AContacto;
      AEditor.Controller := Self;
      AEditor.ShowModal;
    finally
      AEditor.Release;
      AEditor := NIL;
    end;
end;

procedure TClientesController.VerAlbaranesDeCliente(ACliente: IBizCliente);
var
  AModule : TModuleController;
  APlugin : IMCAlbaranesCliente;
begin
  if not Assigned(ACliente) then
    raise Exception.Create ('Cliente no asignado (VerAlbaranesDeCliente)');

  if ACliente.DataTable.Active then
    ACliente.DataTable.Active := True;

  AModule := AppFactuGES.GetModule(MODULENAME_ALBARANES_CLIENTE);
  if Assigned(AModule) then
    try
      if Supports(AModule, IMCAlbaranesCliente, APlugin) then
        APlugin.VerAlbaranes(ACliente.ID, ACliente.NOMBRE);
    finally
      APlugin := NIL;
    end;
end;

procedure TClientesController.VerFacturasDeCliente(ACliente: IBizCliente);
var
  AModule : TModuleController;
  APlugin : IMCFacturasCliente;
begin
  if not Assigned(ACliente) then
    raise Exception.Create ('Cliente no asignado (VerFacturasDeCliente)');

  if ACliente.DataTable.Active then
    ACliente.DataTable.Active := True;

  AModule := AppFactuGES.GetModule(MODULENAME_FACTURAS_CLIENTE);
  if Assigned(AModule) then
    try
      if Supports(AModule, IMCFacturasCliente, APlugin) then
        APlugin.VerFacturas(ACliente.ID, ACliente.NOMBRE);
    finally
      APlugin := NIL;
    end;
end;

procedure TClientesController.VerPresupuestosDeCliente(ACliente : IBizCliente);
var
  AModule : TModuleController;
  APlugin : IMCPresupuestosCliente;
begin
  if not Assigned(ACliente) then
    raise Exception.Create ('Cliente no asignado (VerPresupuestosDeCliente)');

  if ACliente.DataTable.Active then
    ACliente.DataTable.Active := True;

  AModule := AppFactuGES.GetModule(MODULENAME_PRESUPUESTOS_CLIENTE);
  if Assigned(AModule) then
    try
      if Supports(AModule, IMCPresupuestosCliente, APlugin) then
        APlugin.VerPresupuestos(ACliente.ID, ACliente.NOMBRE);
    finally
      APlugin := NIL;
    end;
end;

procedure TClientesController.VerRecibosDeCliente(ACliente: IBizCliente);
var
  AModule : TModuleController;
  APlugin : IMCRecibosCliente;
begin
  if not Assigned(ACliente) then
    raise Exception.Create ('Cliente no asignado (VerFacturasDeCliente)');

  if ACliente.DataTable.Active then
    ACliente.DataTable.Active := True;

  AModule := AppFactuGES.GetModule(MODULENAME_RECIBOS_CLIENTE);
  if Assigned(AModule) then
    try
      if Supports(AModule, IMCRecibosCliente, APlugin) then
        APlugin.VerRecibos(ACliente.ID, ACliente.NOMBRE);
    finally
      APlugin := NIL;
    end;
end;

procedure TClientesController.VerTodos(AContactos: IBizContacto);
var
  AEditor : IEditorClientes;
begin
  AEditor := NIL;

  CreateEditor('EditorClientes', IEditorClientes, AEditor);
  if Assigned(AEditor) then
     with AEditor do
     begin
        Contactos := AContactos;
        Controller := Self;
        MultiSelect := True;
        ShowEmbedded;
     end;
end;

end.
