unit uEditorFacturasCliente;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, DB, uDADataTable, JvAppStorage,
  JvAppRegistryStorage, JvComponent, JvFormPlacement, ImgList,
  PngImageList, StdActns, ActnList, ComCtrls, TB2ExtItems, TBXExtItems,
  TBX, TB2Item, TB2Dock, TB2Toolbar, ExtCtrls, JvExControls,
  JvNavigationPane, uViewGrid, pngimage, JvComponentBase,
  uEditorGridBase,
  uBizFacturasCliente, uIEditorFacturasCliente, uFacturasClienteController,
  uCustomView, uViewBase, uViewBarraSeleccion, uViewGridBase,
  uViewFacturasCliente, JvExComCtrls, JvStatusBar, JSDialog, uDAInterfaces,
  dxGDIPlusClasses;

type

  TfEditorFacturasCliente = class(TfEditorGridBase, IEditorFacturasCliente)
    frViewFacturasCliente1: TfrViewFacturasCliente;
    Cambiarlasituacin1: TMenuItem;
    N4: TMenuItem;
    JsNuevaFacturaDialog: TJSDialog;
    JsListaFacturasGeneradas: TJSDialog;
    JsPrevisualizarDialog: TJSDialog;
    JsImprimirDialog: TJSDialog;
    TBXSubmenuItem2: TTBXSubmenuItem;
    actNuevaFactura: TAction;
    TBXItem38: TTBXItem;
    TBXItem39: TTBXItem;
    actNuevoAbono: TAction;
    JsNuevoAbonoDialog: TJSDialog;
    JsListaFacturasNoEliminadas: TJSDialog;
    actInformes: TAction;
    JSInformesDialog: TJSDialog;
    TBXItem40: TTBXItem;
    actEnviarMail: TAction;
    TBXItem41: TTBXItem;
    actCambiarSituacion: TAction;
    TBXItem42: TTBXItem;
    TBXSeparatorItem17: TTBXSeparatorItem;
    JsListaFacturasNoModificadas: TJSDialog;
    actVerContrato: TAction;
    TBXItem43: TTBXItem;
    actLOPD: TAction;
    TBXItem44: TTBXItem;
    actGenerarPDF: TAction;
    TBXItem45: TTBXItem;
    procedure FormShow(Sender: TObject);
    procedure actEliminarUpdate(Sender: TObject);
    procedure actNuevaFacturaExecute(Sender: TObject);
    procedure actNuevoAbonoExecute(Sender: TObject);
    procedure actInformesExecute(Sender: TObject);
    procedure OnListaAnosChange(Sender: TObject; const Text: string);
    procedure actEnviarMailUpdate(Sender: TObject);
    procedure actEnviarMailExecute(Sender: TObject);
    procedure actCambiarSituacionExecute(Sender: TObject);
    procedure actVerContratoUpdate(Sender: TObject);
    procedure actLOPDExecute(Sender: TObject);
    procedure actLOPDUpdate(Sender: TObject);
    procedure actVerContratoExecute(Sender: TObject);
    procedure actGenerarPDFExecute(Sender: TObject);
    procedure actGenerarPDFUpdate(Sender: TObject);

  private
    FFacturas: IBizFacturaCliente;
    FController : IFacturasClienteController;
  protected
    function GetFacturas: IBizFacturaCliente;
    procedure SetFacturas(const Value: IBizFacturaCliente);

    function GetController : IFacturasClienteController; virtual;
    procedure SetController (const Value : IFacturasClienteController); virtual;

    procedure NuevoInterno; override;
    procedure EliminarInterno; override;
    procedure ModificarInterno; override;
    procedure DuplicarInterno; override;
    procedure ImprimirInterno; override;
    procedure PrevisualizarInterno; override;
    procedure RefrescarInterno; override;

  public
    procedure PonerTitulos(const ATitulo: string = ''); override;
    property Facturas: IBizFacturaCliente read GetFacturas write SetFacturas;
    property Controller : IFacturasClienteController read GetController write SetController;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;


implementation

uses
  uDataModuleFacturasCliente, uDataModuleUsuarios, uAlbaranesClienteController, uFactuGES_App,
  uBizejercicios, uGenerarFacturasCliAlbCliUtils, uEditorElegirSituacion,
  uBizAlbaranesCliente, uGestorInformesController, uGenerarFacturasCliUtils,
  uEditorBase,  uGridUtils, uDBSelectionListUtils;

{$R *.dfm}

{
*************************** TfEditorFacturasCliente ***************************
}
procedure TfEditorFacturasCliente.actCambiarSituacionExecute(Sender: TObject);
var
  ASituacion : String;
  AFacturas: IBizFacturaCliente;
  AllItems: Boolean;
  AListaCausas: TStringList;
  AEditor : tfEditorElegirSituacion;
  i: integer;

begin
  inherited;
  AFacturas := Nil;
  AllItems := False;
  ASituacion := CTE_PENDIENTE;
  AListaCausas := TStringList.Create;

  if MultiSelect and Assigned(ViewGrid) then
     AllItems :=  (ViewGrid.NumSeleccionados > 1);


  AEditor := TfEditorElegirSituacion.Create(Nil);
  if Assigned(AEditor) then
     with AEditor do
     begin
       try
         if IsPositiveResult(AEditor.ShowModal) then
         begin
           ASituacion := AEditor.edtSituacion.EditValue;

           if AllItems then
           begin
             SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Facturas as ISeleccionable).SelectedRecords);
             AFacturas := (Controller as IFacturasClienteController).ExtraerSeleccionados(Facturas) as IBizFacturaCliente;
           end
           else
             AFacturas := Facturas;

           if Assigned(AFacturas) then
              FController.CambiarSituacion(AFacturas, AllItems, Asituacion, AListaCausas);
         end;
       finally
         AEditor.Release;
         AEditor := NIL;
       end;
    end;

  if Assigned(AListaCausas) then
  begin
    JsListaFacturasNoModificadas.Content.Clear;
    for i := 0 to AListaCausas.Count - 1 do
    begin
      JsListaFacturasNoModificadas.Content.Add(AListaCausas.Strings[i]);
    end;
    if (AListaCausas.Count > 0) then
       JsListaFacturasNoModificadas.Execute;
  end;

  AListaCausas.Free;
  actRefrescar.Execute;
end;

procedure TfEditorFacturasCliente.actEliminarUpdate(Sender: TObject);
begin
  inherited;
  if (Sender as TAction).Enabled then
     (Sender as TAction).Enabled := (FFacturas.SITUACION = 'PENDIENTE')  and
                                    ((AppFactuGES.UsuarioActivo.ID_PERFIL = CTE_PERFIL_ADMINISTRADOR)
                                     or (AppFactuGES.UsuarioActivo.ID_PERFIL = CTE_PREFIL_GERENCIA))
end;

procedure TfEditorFacturasCliente.actEnviarMailExecute(Sender: TObject);
begin
  inherited;
  FController.EnviarFacturaPorEMail(FFacturas);
end;

procedure TfEditorFacturasCliente.actEnviarMailUpdate(Sender: TObject);
begin
  inherited;
  if HayDatos and Assigned(ViewGrid) then
    (Sender as TAction).Enabled := ViewGrid.EsSeleccionCeldaDatos
      and (ViewGrid.NumSeleccionados > 0)
  else
    (Sender as TAction).Enabled := False;
end;

procedure TfEditorFacturasCliente.actGenerarPDFExecute(Sender: TObject);
var
  ACadena : String;
  AFacturas: IBizFacturaCliente;
  AllItems: Boolean;
  AListaCausas: TStringList;
  AFirmar: Boolean;

begin
  inherited;
  AFacturas := Nil;
  AFirmar := False;
  AllItems := False;
  AListaCausas := TStringList.Create;

  if MultiSelect and Assigned(ViewGrid) then
     AllItems :=  (ViewGrid.NumSeleccionados > 1);

  if AllItems then
  begin
    SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Facturas as ISeleccionable).SelectedRecords);
    AFacturas := (Controller as IFacturasClienteController).ExtraerSeleccionados(Facturas) as IBizFacturaCliente;

    if (Application.MessageBox('¿Desea firmar digitalmente las facturas/abonos de cliente seleccionados?', 'Atención', MB_YESNO) = IDYES) then
       AFirmar := True;
  end
  else
  begin
    AFacturas := Facturas;

    if Facturas.TIPO = CTE_TIPO_FACTURA then
       ACadena := '¿Desea firmar digitalmente esta factura de cliente?'
    else
       ACadena := '¿Desea firmar digitalmente este abono a cliente?';

    if (Application.MessageBox(PChar(ACadena), 'Atención', MB_YESNO) = IDYES) then
       AFirmar := True;
  end;

  FController.GenerarPDF(AFacturas, AllItems, AFirmar);
end;

procedure TfEditorFacturasCliente.actGenerarPDFUpdate(Sender: TObject);
begin
  inherited;
  if HayDatos and Assigned(ViewGrid) then
    (Sender as TAction).Enabled := ViewGrid.EsSeleccionCeldaDatos
      and (ViewGrid.NumSeleccionados > 0)
  else
    (Sender as TAction).Enabled := False;
end;

procedure TfEditorFacturasCliente.actInformesExecute(Sender: TObject);
var
  Respuesta : Integer;
  AGestorInformesController : IGestorInformesController;

begin
  AGestorInformesController := TGestorInformesController.Create;
  try

    Respuesta := JsInformesDialog.Execute;

    if Respuesta <> IDCANCEL then
    begin
      case JsInformesDialog.CustomButtonResult of
        100 : begin   // Listado de facturas pendientes
                AGestorInformesController.VerInformeListadoFacturasCliPendientes;
              end;
        200 : begin   // Listado de IVA
                AGestorInformesController.VerInformeIVAClientes;
              end;
        300 : begin   // Listado de facturas de cliente
                AGestorInformesController.VerInformeListadoFacturasCli;
              end;
      end;
    end;

  finally
    AGestorInformesController := NIL;
  end;

end;

procedure TfEditorFacturasCliente.actLOPDExecute(Sender: TObject);
var
  AFacturas: IBizFacturaCliente;

begin
  inherited;
  ViewGrid.SaveGridStatus;
  try
    SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Facturas as ISeleccionable).SelectedRecords);
    AFacturas := (Controller as IFacturasClienteController).ExtraerSeleccionados(Facturas) as IBizFacturaCliente;
  finally
    ViewGrid.RestoreGridStatus;
  end;

  if (Controller as IFacturasClienteController).AsignarLOPD(AFacturas) then
     RefrescarInterno;
end;

procedure TfEditorFacturasCliente.actLOPDUpdate(Sender: TObject);
begin
  inherited;

  if HayDatos and Assigned(ViewGrid) then
    (Sender as TAction).Enabled := not (dsDataTable.DataTable.State in dsEditModes)
      and ViewGrid.esSeleccionCeldaDatos
      and (ViewGrid.NumSeleccionados > 0)
  else
    (Sender as TAction).Enabled := False;

end;

procedure TfEditorFacturasCliente.actNuevaFacturaExecute(Sender: TObject);
begin
  actNuevo.Execute;
end;

procedure TfEditorFacturasCliente.actNuevoAbonoExecute(Sender: TObject);
var
  Respuesta : Integer;
  Opcion : Integer;
begin
  inherited;
  //ABONOS
  if (Facturas.TIPO = CTE_TIPO_FACTURA) then
  begin
      Respuesta := JsNuevoAbonoDialog.Execute;
      //Nos salimos sin hace nada
      if Respuesta = IDCANCEL then
         Exit;
      Opcion := JsNuevoAbonoDialog.CustomButtonResult;
  end
  else
      Opcion := 100;

  case Opcion of
    200   : begin   // Utilizar factura seleccionada
                FController.Ver(FController.GenerarAbono(Facturas));
                actRefrescar.Execute;
                ViewGrid._FocusedView.DataController.GotoFirst;
    end;
    100    : begin   // Abono nuevo vacio
                if FController.AnadirAbono(Facturas) then
                   FController.Ver(Facturas);
              end;
  end;
end;

procedure TfEditorFacturasCliente.actVerContratoExecute(Sender: TObject);
begin
  inherited;
  VerContratoCliDeFactura(FFacturas);
end;

procedure TfEditorFacturasCliente.actVerContratoUpdate(Sender: TObject);
begin
  inherited;

  if HayDatos and Assigned(ViewGrid) then
    (Sender as TAction).Enabled := not (dsDataTable.DataTable.State in dsEditModes)
      and ViewGrid.esSeleccionCeldaDatos
      and (ViewGrid.NumSeleccionados = 1)
      and not FFacturas.ID_CONTRATOIsNull
  else
    (Sender as TAction).Enabled := False;

end;

constructor TfEditorFacturasCliente.Create(AOwner: TComponent);
begin
  inherited;
  ViewGrid := frViewFacturasCliente1; //  CreateView(TfrViewFacturasCliente) as IViewFacturasCliente;
end;

destructor TfEditorFacturasCliente.Destroy;
begin
  FFacturas := NIL;
  inherited;
end;

procedure TfEditorFacturasCliente.DuplicarInterno;
var
  AFactura : IBizFacturaCliente;
begin
  inherited;
  AFactura := FController.Duplicar(FFacturas);
  try
    FController.Ver(AFactura);
  finally
    actRefrescar.Execute;
  end;
end;

procedure TfEditorFacturasCliente.EliminarInterno;
var
  ACadena : String;
  AFacturas: IBizFacturaCliente;
  AllItems: Boolean;
  AListaCausas: TStringList;

begin
  AFacturas := Nil;
  AllItems := False;
  AListaCausas := TStringList.Create;

  if MultiSelect and Assigned(ViewGrid) then
     AllItems :=  (ViewGrid.NumSeleccionados > 1);

  if (Application.MessageBox('Atención, si elimina facturas/abonos de cliente podría producir huecos el la lista de facturas, ¿Desea continuar?', 'Atención', MB_YESNO) = IDYES) then
      if AllItems then
      begin
        if (Application.MessageBox('¿Desea borrar las facturas/abonos de cliente seleccionados?', 'Atención', MB_YESNO) = IDYES) then
        begin
          SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Facturas as ISeleccionable).SelectedRecords);
          AFacturas := (Controller as IFacturasClienteController).ExtraerSeleccionados(Facturas) as IBizFacturaCliente;
        end
      end
      else begin
         if Facturas.TIPO = CTE_TIPO_FACTURA then
            ACadena := '¿Desea borrar esta factura de cliente?'
         else
            ACadena := '¿Desea borrar este abono a cliente?';

         if (Application.MessageBox(PChar(ACadena), 'Atención', MB_YESNO) = IDYES) then
            AFacturas := Facturas;
      end;

  if Assigned(AFacturas) then
  begin
    if (not FController.Eliminar(AFacturas, AllItems, AListaCausas))
    //En el caso de querer borrar una factura pendiente cuyos recibos tienen devoluciones
    and (not AllItems) then
    begin
      JsListaFacturasNoEliminadas.Content.Clear;
      JsListaFacturasNoEliminadas.Content.Add('Ref. factura: ' + AFacturas.REFERENCIA + '  ' + AFacturas.NOMBRE);
      if Length(VarToStr(AListaCausas.Values[IntToStr(AFacturas.ID)])) > 0 then
         JsListaFacturasNoEliminadas.Content.Add(VarToStr(AListaCausas.Values[IntToStr(AFacturas.ID)]))
      else
         JsListaFacturasNoEliminadas.Content.Add('La factura puede tener algún recibo devuelto y no puede ser eliminada');
      JsListaFacturasNoEliminadas.Execute;
    end;


    if AllItems then
    begin
      if (AFacturas.DataTable.RecordCount > 0) then
      begin
        with  AFacturas.DataTable do
        begin
          JsListaFacturasNoEliminadas.Content.Clear;
          First;
          while not EOF do
          begin
            JsListaFacturasNoEliminadas.Content.Add('Ref. factura: ' + AFacturas.REFERENCIA + '  ' + AFacturas.NOMBRE);
            if Length(AListaCausas.Values[IntToStr(AFacturas.ID)]) > 0 then
               JsListaFacturasNoEliminadas.Content.Add(VarToStr(AListaCausas.Values[IntToStr(AFacturas.ID)]))
            else
               JsListaFacturasNoEliminadas.Content.Add('La factura puede tener algún recibo devuelto y no puede ser eliminada');
            JsListaFacturasNoEliminadas.Content.Add('');
            Next;
          end;
        end;
        JsListaFacturasNoEliminadas.Execute;
      end;
      actRefrescar.Execute;
    end
  end;

  AListaCausas.Free;
  ViewGrid.GotoFirst;
end;

procedure TfEditorFacturasCliente.FormShow(Sender: TObject);
begin
  cbxListaAnos.OnChange := OnListaAnosChange; //OJO SIEMPRE ANTES DEL INHERITED

  inherited;

  if not Assigned(ViewGrid) then
    raise Exception.Create('No hay ninguna vista asignada');

  if not Assigned(Facturas) then
    raise Exception.Create('No hay ninguna factura asignada');

  Facturas.DataTable.Active := True;
  ViewGrid.GotoFirst;  
end;

function TfEditorFacturasCliente.GetController: IFacturasClienteController;
begin
  Result := FController;
end;

function TfEditorFacturasCliente.GetFacturas: IBizFacturaCliente;
begin
  Result := FFacturas;
end;

procedure TfEditorFacturasCliente.ImprimirInterno;
var
  Respuesta : Integer;
  AFacturas: IBizFacturaCliente;
  AllItems: Boolean;
  AVerDatosCliente: Boolean;
begin
  AFacturas := Nil;
  AllItems := False;

  if MultiSelect and Assigned(ViewGrid) then
     AllItems :=  (ViewGrid.NumSeleccionados > 1);

  //Si esta agrupado solo podré imprimir la lista de elementos visibles
  if not ViewGrid.esSeleccionCeldaDatos then
     inherited
  else
  begin
    Respuesta := JsImprimirDialog.Execute;
    if Respuesta <> IDCANCEL then
    begin
      case JsImprimirDialog.CustomButtonResult of
        200   : begin   // Lista de elementos visibles
                  inherited;
                end;
        100   : begin   // Elemento Seleccionado
                  AVerDatosCliente := (Application.MessageBox('¿Desea imprimir los datos del cliente?', 'Atención', MB_YESNO) = IDYES);
                  
                  if AllItems then
                  begin
                    SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Facturas as ISeleccionable).SelectedRecords);
                    AFacturas := (Controller as IFacturasClienteController).ExtraerSeleccionados(Facturas) as IBizFacturaCliente;
                  end
                  else
                    AFacturas := Facturas;

                  if Assigned(AFacturas) then
                     FController.Print(AFacturas, AllItems, AVerDatosCliente);
                end;
      end;
    end;
  end;
end;

procedure TfEditorFacturasCliente.ModificarInterno;
begin
  inherited;
  FController.Ver(Facturas);
end;

procedure TfEditorFacturasCliente.NuevoInterno;
var
  Respuesta : Integer;
  //FPedidosClienteController : IPedidosClienteController;
  //APedido : IBizPedidoCliente;
  //FAlbaranesClienteController : IAlbaranesClienteController;
  //AAlbaranes : IBizAlbaranCliente;
  //AFacturasNuevas : IBizFacturaCliente;
  //i : integer;
begin
  inherited;

  if FController.Anadir(Facturas) then
    FController.Ver(Facturas);
{

  Respuesta := JsNuevaFacturaDialog.Execute;

  if Respuesta <> IDCANCEL then
  begin
    case JsNuevaFacturaDialog.CustomButtonResult of
      300   : begin   // Utilizar un pedido
                  ShowMessage('A COMPLETAR');
                  {FPedidosClienteController := TPedidosClienteController.Create;
                  try
                    APedido := FPedidosClienteController.ElegirPedidos(FPedidosClienteController.BuscarPendientes,
                        'Elija el pedido de cliente que desea utilizar para dar de alta la factura.'
                        + #10#13 + 'Tenga en cuenta que sólo se podrán utilizar pedidos que no tengan ningún albarán ya asociado.', False);
                    if Assigned(APedido) then
                    begin
                      if FController.Anadir(Facturas, APedido) then
                        FController.Ver(Facturas);
                    end;
                  finally
                    FPedidosClienteController := NIL;
                  end;}
{                end;
      200   : begin   // Utilizar albaranes
                  GenerarFacturaCli;
                  actRefrescar.Execute;
      end;
      100    : begin   // Factura nueva vacia
                  if FController.Anadir(Facturas) then
                    FController.Ver(Facturas);
                end;
    end;
  end;
}  
end;

procedure TfEditorFacturasCliente.OnListaAnosChange(Sender: TObject; const Text: string);
begin
  Controller.FiltrarAno(Facturas, DynWhereDataTable, Text);
  if Facturas.DataTable.Active then
     RefrescarInterno;
end;

procedure TfEditorFacturasCliente.PonerTitulos(const ATitulo: string);
var
  FTitulo : String;
begin
  FTitulo := 'Lista de facturas de cliente - ' + AppFactuGES.EmpresaActiva.NOMBRE;
  inherited PonerTitulos(FTitulo);
end;

procedure TfEditorFacturasCliente.PrevisualizarInterno;
var
  Respuesta : Integer;
  AFacturas: IBizFacturaCliente;
  AllItems: Boolean;
  AVerDatosCliente: Boolean;
begin
  AFacturas := Nil;
  AllItems := False;

  if MultiSelect and Assigned(ViewGrid) then
     AllItems :=  (ViewGrid.NumSeleccionados > 1);

  //Si esta agrupado solo podré imprimir la lista de elementos visibles
  if not ViewGrid.esSeleccionCeldaDatos then
     inherited
  else
  begin
    Respuesta := JsPrevisualizarDialog.Execute;
    if Respuesta <> IDCANCEL then
    begin
      case JsPrevisualizarDialog.CustomButtonResult of
        200   : begin   // Lista de elementos visibles
                  inherited;
                end;
        100   : begin   // Elemento Seleccionado
                  AVerDatosCliente := (Application.MessageBox('¿Desea previsualizar los datos del cliente?', 'Atención', MB_YESNO) = IDYES);

                  if AllItems then
                  begin
                    SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Facturas as ISeleccionable).SelectedRecords);
                    AFacturas := (Controller as IFacturasClienteController).ExtraerSeleccionados(Facturas) as IBizFacturaCliente;
                  end
                  else
                    AFacturas := Facturas;

                  if Assigned(AFacturas) then
                     FController.Preview(AFacturas, AllItems, AVerDatosCliente);
                end;
      end;
    end;
  end;
end;

procedure TfEditorFacturasCliente.RefrescarInterno;
begin
  //Volvemos a cargar los años de las facturas
  if Assigned(FController) then
     ListaAnos := FController.DarListaAnosFacturas;

  inherited;
end;

procedure TfEditorFacturasCliente.SetController(const Value: IFacturasClienteController);
begin
  FController := Value;

  if Assigned(FController) then
     ListaAnos := FController.DarListaAnosFacturas;
end;

procedure TfEditorFacturasCliente.SetFacturas(const Value: IBizFacturaCliente);
begin
  FFacturas := Value;

  if Assigned(FFacturas) then
  begin
    //Se guarda el where de la sentencia origen, por si el editor tiene filtros que
    //afecten a este where y en un futuro se desea volver al where origen (filtro de año))
    DynWhereDataTable := FFacturas.DataTable.DynamicWhere.Xml;

    dsDataTable.DataTable := FFacturas.DataTable;
    if Assigned(ViewGrid) then
      (ViewGrid as IViewFacturasCliente).Facturas := Facturas;
  end;
end;

end.
  