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, 
  SpTBXItem, TB2Item, TB2Dock, TB2Toolbar, ExtCtrls, JvExControls,
  JvNavigationPane, uViewGrid, pngimage, JvComponentBase,
  uEditorGridBase,
  uBizFacturasCliente, uIEditorFacturasCliente, uFacturasClienteController,
  uCustomView, uViewBase, uViewBarraSeleccion, uViewGridBase,
  uViewFacturasCliente, JvExComCtrls, JvStatusBar, JSDialog, uDAInterfaces,
  cxStyles, cxCustomData,
  cxGraphics, cxFilter, cxData, cxDataStorage, cxEdit, cxDBData, cxGridLevel,
  cxClasses, cxControls, cxGridCustomView, cxGridCustomTableView,
  cxGridTableView, cxGridDBTableView, cxGrid, StdCtrls, cxContainer, cxTextEdit,
  cxMaskEdit, cxDropDownEdit, cxLookupEdit, cxDBLookupEdit, cxDBLookupComboBox,
  TntStdCtrls, SpTBXEditors;

type

  TfEditorFacturasCliente = class(TfEditorGridBase, IEditorFacturasCliente)
    frViewFacturasCliente1: TfrViewFacturasCliente;
    JsNuevaFacturaDialog: TJSDialog;
    JsListaFacturasGeneradas: TJSDialog;
    JsPrevisualizarDialog: TJSDialog;
    JsImprimirDialog: TJSDialog;
    TBXSubmenuItem2: TSpTBXSubmenuItem;
    actNuevaFactura: TAction;
    TBXItem38: TSpTBXItem;
    TBXItem39: TSpTBXItem;
    actNuevoAbono: TAction;
    JsNuevoAbonoDialog: TJSDialog;
    JsListaFacturasNoEliminadas: TJSDialog;
    actEnviarEMail: TAction;
    TBXItem40: TSpTBXItem;
    Enviarporemail1: TMenuItem;
    actInformes: TAction;
    TBXItem41: TSpTBXItem;
    JSInformesDialog: TJSDialog;
    procedure FormShow(Sender: TObject);
    procedure actEliminarUpdate(Sender: TObject);
    procedure actNuevaFacturaExecute(Sender: TObject);
    procedure actNuevoAbonoExecute(Sender: TObject);
    procedure actEnviarEMailUpdate(Sender: TObject);
    procedure actEnviarEMailExecute(Sender: TObject);
    procedure actInformesExecute(Sender: TObject);
    procedure OnListaAnosChange(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
    property Facturas: IBizFacturaCliente read GetFacturas write SetFacturas;
    property Controller : IFacturasClienteController read GetController write SetController;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure PonerTitulos(const ATitulo: string = ''); override;
  end;


implementation

uses
  uDataModuleFacturasCliente, uDataModuleUsuarios, uAlbaranesClienteController, uFactuGES_App,
  uGenerarFacturasCliAlbCliUtils, uGenerarFacturasCliPreCliUtils,
  uBizAlbaranesCliente, uGestorInformesController, uDialogOpcionesImpresionFacturasCliente,
  uEditorBase,  uGridStatusUtils, uDBSelectionListUtils, udialogUtils;

{$R *.dfm}

{
*************************** TfEditorFacturasCliente ***************************
}
procedure TfEditorFacturasCliente.actEliminarUpdate(Sender: TObject);
begin
  inherited;
  if (Sender as TAction).Enabled then
     (Sender as TAction).Enabled := (FFacturas.SITUACION = 'PENDIENTE');
end;

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

procedure TfEditorFacturasCliente.actEnviarEMailUpdate(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.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;

constructor TfEditorFacturasCliente.Create(AOwner: TComponent);
begin
  inherited;

  FHeaderText := 'Lista de facturas de cliente';
  FWindowCaption := FHeaderText;

  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;
begin
  AFacturas := Nil;
  AllItems := False;

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

  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))
    and (not AllItems) then //Es el caso de querer borrar una factura pendiente cuyos recibos tienen devoluciones
    begin
      JsListaFacturasNoEliminadas.Content.Clear;
      JsListaFacturasNoEliminadas.Content.Add('Ref. factura: ' + AFacturas.REFERENCIA + '  ' + AFacturas.NOMBRE);
      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);
            Next;
          end;
        end;
        JsListaFacturasNoEliminadas.Execute;
      end;
      actRefrescar.Execute;
    end
  end;

  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;
  AOriginal: Integer;
  ACopia: Integer;
  AContabilidad: Integer;

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
                  if AllItems then
                  begin
                    SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Facturas as ISeleccionable).SelectedRecords);
                    AFacturas := (Controller as IFacturasClienteController).ExtraerSeleccionados(Facturas) as IBizFacturaCliente;
                  end
                  else
                    AFacturas := Facturas;

                  //Preguntamos si desea que en las facturas se vea el Sello
                  if ElegirOpcionesImpresionFacturaCliente(AOriginal, ACopia, AContabilidad) then
                     if Assigned(AFacturas) then
                        FController.Print(AFacturas, AOriginal, ACopia, AContabilidad, AllItems);
                end;
      end;
    end;
  end;
end;

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

procedure TfEditorFacturasCliente.NuevoInterno;
var
  Respuesta : Integer;
begin
  inherited;

  Respuesta := JsNuevaFacturaDialog.Execute;

  if Respuesta <> IDCANCEL then
  begin
    case JsNuevaFacturaDialog.CustomButtonResult of
      200   : begin   // Utilizar presupuestos
                GenerarFacturaCliPre;
                actRefrescar.Execute;
              end;
      300   : begin   // Utilizar albaranes
                  GenerarFacturaCliAlb;
                  actRefrescar.Execute;
      end;
      100    : begin   // Albaran nuevo vacio
                  if FController.Anadir(Facturas) then
                    FController.Ver(Facturas);
                end;
    end;
  end;
end;

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

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

procedure TfEditorFacturasCliente.PrevisualizarInterno;
var
  Respuesta : Integer;
  AFacturas: IBizFacturaCliente;
  AllItems: Boolean;
  AOriginal: Integer;
  ACopia: Integer;
  AContabilidad: Integer;

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
                  if AllItems then
                  begin
                    SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Facturas as ISeleccionable).SelectedRecords);
                    AFacturas := (Controller as IFacturasClienteController).ExtraerSeleccionados(Facturas) as IBizFacturaCliente;
                  end
                  else
                    AFacturas := Facturas;

                  //Preguntamos si desea que en las facturas se vea el Sello
                  if ElegirOpcionesImpresionFacturaCliente(AOriginal, ACopia, AContabilidad) then
                     if Assigned(AFacturas) then
                        FController.Preview(AFacturas, AOriginal, ACopia, AContabilidad, AllItems);
                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.
