unit uEditorPresupuestosCliente;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  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,
  uBizPresupuestosCliente, uIEditorPresupuestosCliente, uPresupuestosClienteController,
  uCustomView, uViewBase, uViewBarraSeleccion, uViewGridBase,
  uViewPresupuestosCliente, JvExComCtrls, JvStatusBar, JSDialog, StdCtrls,
  uDAInterfaces;

type
  TfEditorPresupuestosCliente = class(TfEditorGridBase, IEditorPresupuestosCliente)
    actGenerarAlbaranCli: TAction;
    actGenerarFactura: TAction;
    TBXSubmenuItem2: TTBXSubmenuItem;
    TBXSeparatorItem17: TTBXSeparatorItem;
    TBXItem38: TTBXItem;
    TBXItem39: TTBXItem;
    N4: TMenuItem;
    Generar2: TMenuItem;
    JsGenerarDialog: TJSDialog;
    JsPrevisualizarDialog: TJSDialog;
    JsImprimirDialog: TJSDialog;
    TBXItem40: TTBXItem;
    JsListaPresupuestosNoEliminados: TJSDialog;
    actGenerarCertificado: TAction;
    TBXItem41: TTBXItem;
    TBXItem42: TTBXItem;
    Generarcertificado1: TMenuItem;
    actAceptar: TAction;
    actAnular: TAction;
    TBXItem43: TTBXItem;
    TBXItem44: TTBXItem;
    TBXSeparatorItem18: TTBXSeparatorItem;
    actEnviarEMail: TAction;
    TBXItem45: TTBXItem;
    Enviarporemail1: TMenuItem;
    actInformes: TAction;
    TBXItem46: TTBXItem;
    JSInformesDialog: TJSDialog;
    TBXItem47: TTBXItem;
    procedure FormShow(Sender: TObject);
    procedure actGenerarAlbaranCliExecute(Sender: TObject);
    procedure actEliminarUpdate(Sender: TObject);
    procedure actGenerarFacturaUpdate(Sender: TObject);
    procedure actGenerarFacturaExecute(Sender: TObject);
    procedure actGenerarPresupuestoProvExecute(Sender: TObject);
    procedure actGenerarExecute(Sender: TObject);
    procedure actGenerarCertificadoUpdate(Sender: TObject);
    procedure actGenerarCertificadoExecute(Sender: TObject);
    procedure actAceptarExecute(Sender: TObject);
    procedure actAceptarUpdate(Sender: TObject);
    procedure actAnularExecute(Sender: TObject);
    procedure actAnularUpdate(Sender: TObject);
    procedure actEnviarEMailExecute(Sender: TObject);
    procedure actEnviarEMailUpdate(Sender: TObject);
    procedure actInformesExecute(Sender: TObject);
    procedure OnListaAnosChange(Sender: TObject; const Text: string);

  protected
    FPresupuestos: IBizPresupuestoCliente;
    FController : IPresupuestosClienteController;

    function GetPresupuestos: IBizPresupuestoCliente;
    procedure SetPresupuestos(const Value: IBizPresupuestoCliente);

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

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

    //Si queremos crear otra vista para el editor heredado solo tendriamos que
    //sobreescribir este metodo
    procedure AsignarVista; virtual;

  public
    procedure PonerTitulos(const ATitulo: string = ''); override;
    property Presupuestos: IBizPresupuestoCliente read GetPresupuestos write SetPresupuestos;
    property Controller : IPresupuestosClienteController read GetController write SetController;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

uses
  uDataModulePresupuestosCliente, uDataModuleUsuarios, uFactuGES_App,
  uEditorBase, uEditorDBBase, uDialogUtils, Dialogs,
  uDBSelectionListUtils, uGridStatusUtils, uDialogOpcionesImpresionPresupuestosCliente,
  uGenerarFacturasCliPreCliUtils, uEditorFechaDecision,
//  uBizAlbaranesCliente, uAlbaranesClienteController,
//  uFacturasClienteController, uBizFacturasCliente,
  uGenerarAlbaranesCliUtils, uGestorInformesController;


{$R *.dfm}

{
*************************** TfEditorPresupuestosCliente ***************************
}
procedure TfEditorPresupuestosCliente.actAceptarExecute(Sender: TObject);
var
  APresupuestos: IBizPresupuestoCliente;
  AllItems: Boolean;
  AFecha: Variant;
begin
  APresupuestos := Nil;
  AllItems := False;

  //Pedimos fecha de decision y realizamos todo el proceso de asignacion, en el caso de no darla no se hace nada
  AFecha := Null;
  with TfEditorFechaDecision.Create(nil) do
  try
    if ShowModal = mrOk then
       AFecha := edtFechaDecision.Date;
  finally
    Free;
  end;

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

    if AllItems then
    begin
      SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Presupuestos as ISeleccionable).SelectedRecords);
      APresupuestos := (Controller as IPresupuestosClienteController).ExtraerSeleccionados(Presupuestos) as IBizPresupuestoCliente;
    end
    else begin
      APresupuestos := Presupuestos;
    end;

    ViewGrid._Grid.BeginUpdate;
    if Assigned(APresupuestos) then
    begin
      FController.CambiarSituacion(APresupuestos, SITUACION_PRESUPUESTO_ACEPTADO, AFecha, AllItems);
      actRefrescar.Execute;
    end;
    ViewGrid._Grid.EndUpdate;
  end;
end;

procedure TfEditorPresupuestosCliente.actAceptarUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := HayDatos
                                 and ViewGrid.esSeleccionCeldaDatos
                                 and (FPresupuestos.SITUACION <> SITUACION_PRESUPUESTO_ACEPTADO);
end;

procedure TfEditorPresupuestosCliente.actAnularExecute(Sender: TObject);
var
  APresupuestos: IBizPresupuestoCliente;
  AllItems: Boolean;
  AFecha: Variant;
begin
  APresupuestos := Nil;
  AllItems := False;

  //Pedimos fecha de decision y realizamos todo el proceso de asignacion, en el caso de no darla no se hace nada
  AFecha := Null;
  with TfEditorFechaDecision.Create(nil) do
  try
    if ShowModal = mrOk then
       AFecha := edtFechaDecision.Date;
  finally
    Free;
  end;

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

    if AllItems then
    begin
      SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Presupuestos as ISeleccionable).SelectedRecords);
      APresupuestos := (Controller as IPresupuestosClienteController).ExtraerSeleccionados(Presupuestos) as IBizPresupuestoCliente;
    end
    else begin
      APresupuestos := Presupuestos;
    end;

    ViewGrid._Grid.BeginUpdate;
    if Assigned(APresupuestos) then
    begin
      FController.CambiarSituacion(APresupuestos, SITUACION_PRESUPUESTO_ANULADO, AFecha, AllItems);
      actRefrescar.Execute;
    end;
    ViewGrid._Grid.EndUpdate;
  end;
end;

procedure TfEditorPresupuestosCliente.actAnularUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := HayDatos
                                 and ViewGrid.esSeleccionCeldaDatos
                                 and (FPresupuestos.SITUACION <> SITUACION_PRESUPUESTO_ANULADO);
end;

procedure TfEditorPresupuestosCliente.actEliminarUpdate(Sender: TObject);
begin
  inherited;
  if (Sender as TAction).Enabled then
     (Sender as TAction).Enabled := (FPresupuestos.SITUACION = SITUACION_PRESUPUESTO_PENDIENTE);
end;

procedure TfEditorPresupuestosCliente.actEnviarEMailExecute(Sender: TObject);
var
  APresupuestos : IBizPresupuestoCliente;

begin
  inherited;

  if ViewGrid.NumSeleccionados = 1 then
    FController.EnviarPresupuestoPorEMail(FPresupuestos)
  else begin
//    ShowHourglassCursor;
    try
      SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Presupuestos as ISeleccionable).SelectedRecords);
      APresupuestos := (Controller as IPresupuestosClienteController).ExtraerSeleccionados(Presupuestos) as IBizPresupuestoCliente;

      if Assigned(APresupuestos) then
         FController.EnviarEmailPresupuestos(APresupuestos);
//            RefrescarInterno;
    finally
      APresupuestos := NIL;
//      HideHourglassCursor;
    end;
  end;
end;

procedure TfEditorPresupuestosCliente.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 TfEditorPresupuestosCliente.actGenerarAlbaranCliExecute(Sender: TObject);
begin
  inherited;
  GenerarAlbaranCli(FPresupuestos.ID);
end;

procedure TfEditorPresupuestosCliente.actGenerarCertificadoExecute(
  Sender: TObject);
var
  APresupuestos: IBizPresupuestoCliente;
  AllItems: Boolean;
  ATexto : String;
begin
  APresupuestos := Nil;
  AllItems := False;

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

  if AllItems then
  begin
    SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Presupuestos as ISeleccionable).SelectedRecords);
    APresupuestos := (Controller as IPresupuestosClienteController).ExtraerSeleccionados(Presupuestos) as IBizPresupuestoCliente;
    ATexto := 'Se han generado los certificados de trabajos.';
  end
  else begin
    APresupuestos := Presupuestos;
    ATexto := 'Se ha generado el certificado de trabajos.';
  end;


  if Assigned(APresupuestos) then
     if FController.GenerarCertificados(APresupuestos, AllItems) then
       ShowInfoMessage('Generar certificado de trabajo', ATexto)
end;

procedure TfEditorPresupuestosCliente.actGenerarCertificadoUpdate(
  Sender: TObject);
begin
  (Sender as TAction).Enabled := HayDatos
                                 and ViewGrid.EsSeleccionCeldaDatos
                                 and (FPresupuestos.SITUACION = SITUACION_PRESUPUESTO_ACEPTADO);
end;

procedure TfEditorPresupuestosCliente.actGenerarExecute(Sender: TObject);
//var
//  Respuesta : Integer;
begin
  inherited;
{
  Respuesta := JsGenerarDialog.Execute;

  if Respuesta <> IDCANCEL then
  begin
    case JsGenerarDialog.CustomButtonResult of
      200   : begin   // Generar factura de cliente
                actGenerarFactura.Execute;
              end;
      100   : begin  // Generar albaran de cliente
//                actGenerarAlbaranCli.Execute;
              end;
    end;
    actRefrescar.Execute;
  end;
}
end;

procedure TfEditorPresupuestosCliente.actGenerarFacturaExecute(Sender: TObject);
begin
  inherited;

  if (ShowConfirmMessage('Generar factura', Format('¿Desea copiar todos los conceptos del presupuesto %s a la factura?', [Presupuestos.REFERENCIA])) = IDYES) then
    GenerarFacturaCliPre(Presupuestos.ID)
  else
    GenerarFacturaCliPre(Presupuestos.ID, False);

  actRefrescar.Execute;
end;

procedure TfEditorPresupuestosCliente.actGenerarFacturaUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := HayDatos
                                 and not (ViewGrid.NumSeleccionados > 1)
                                 and (FPresupuestos.FACTURA = '')
                                 and ViewGrid.esSeleccionCeldaDatos
                                 and (FPresupuestos.SITUACION = SITUACION_PRESUPUESTO_ACEPTADO);
end;

procedure TfEditorPresupuestosCliente.actGenerarPresupuestoProvExecute(Sender: TObject);
begin
  inherited;
//  GenerarPresupuestosProv(FPresupuestos);
end;

procedure TfEditorPresupuestosCliente.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.VerInformeListadoPresupuestos;
              end;
      end;
    end;

  finally
    AGestorInformesController := NIL;
  end;
end;

procedure TfEditorPresupuestosCliente.AsignarVista;
begin
  ViewGrid := CreateView(TfrViewPresupuestosCliente) as IViewPresupuestosCliente;
end;

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

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

  AsignarVista;
end;

destructor TfEditorPresupuestosCliente.Destroy;
begin
  FPresupuestos := NIL;
  FController := NIL;
  inherited;
end;

procedure TfEditorPresupuestosCliente.DuplicarInterno;
var
  APresupuesto : IBizPresupuestoCliente;
begin
  inherited;
  APresupuesto := FController.Duplicar(Presupuestos);
  try
    FController.Ver(APresupuesto);
  finally
    actRefrescar.Execute;
  end;
end;

procedure TfEditorPresupuestosCliente.EliminarInterno;
var
  APresupuestos: IBizPresupuestoCliente;
  AllItems: Boolean;
begin
  APresupuestos := Nil;
  AllItems := False;

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

  if AllItems then
  begin
    if (Application.MessageBox('¿Desea borrar los presupuestos seleccionados?', 'Atención', MB_YESNO) = IDYES) then
    begin
      SeleccionarFilasDesdeGrid(ViewGrid._FocusedView, (Presupuestos as ISeleccionable).SelectedRecords);
      APresupuestos := (Controller as IPresupuestosClienteController).ExtraerSeleccionados(Presupuestos) as IBizPresupuestoCliente;
    end
  end
  else begin
    if (Application.MessageBox('¿Desea borrar el presupuesto seleccionado?', 'Atención', MB_YESNO) = IDYES) then
        APresupuestos := Presupuestos;
  end;

  if Assigned(APresupuestos) then
  begin
    FController.Eliminar(APresupuestos, AllItems);
    if AllItems then
    begin
      if (APresupuestos.DataTable.RecordCount > 0) then
      begin
        with  APresupuestos.DataTable do
        begin
          First;
          while not EOF do
          begin
            JsListaPresupuestosNoEliminados.Content.Add('Ref. Presupuesto: ' + APresupuestos.REFERENCIA + '  ' + APresupuestos.NOMBRE);
            Next;
          end;
        end;
        JsListaPresupuestosNoEliminados.Execute;
      end;
      actRefrescar.Execute;
    end;
  end;

  ViewGrid.GotoFirst;
end;

procedure TfEditorPresupuestosCliente.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(Presupuestos) then
    raise Exception.Create('No hay ningún Presupuesto asignado');

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

function TfEditorPresupuestosCliente.GetController: IPresupuestosClienteController;
begin
  Result := FController;
end;

function TfEditorPresupuestosCliente.GetPresupuestos: IBizPresupuestoCliente;
begin
  Result := FPresupuestos;
end;

procedure TfEditorPresupuestosCliente.ImprimirInterno;
var
  Respuesta : Integer;
  APresupuestos: IBizPresupuestoCliente;
  AllItems: Boolean;
  AVerSello: Integer;
  bPrevisualizar: Boolean;  
begin
  APresupuestos := Nil;
  AllItems := False;
  bPrevisualizar := True;

  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, (Presupuestos as ISeleccionable).SelectedRecords);
                    APresupuestos := (Controller as IPresupuestosClienteController).ExtraerSeleccionados(Presupuestos) as IBizPresupuestoCliente;
                  end
                  else
                    APresupuestos := Presupuestos;

                    if (AppFactuGES.EmpresaActiva.ID = 1) then
                       //Preguntamos si desea que en los presupuestos se vea el Sello de Paco u Oscar,
                       //solo para empresa Tecsitel
                       bPrevisualizar := ElegirOpcionesImpresionPresupuestoCliente(AVerSello);

                    if bPrevisualizar and Assigned(APresupuestos) then
                       FController.Print(APresupuestos, AllItems, AVerSello);
                end;
      end;
    end;
  end;
end;

procedure TfEditorPresupuestosCliente.ModificarInterno;
begin
  inherited;
  FController.Ver(Presupuestos);
end;

procedure TfEditorPresupuestosCliente.NuevoInterno;
begin
  inherited;
  if FController.Anadir(Presupuestos) then
     FController.Ver(Presupuestos);
end;

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

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

procedure TfEditorPresupuestosCliente.PrevisualizarInterno;
var
  Respuesta : Integer;
  APresupuestos: IBizPresupuestoCliente;
  AllItems: Boolean;
  AVerSello: Integer;
  bPrevisualizar: Boolean;
begin
  APresupuestos := Nil;
  AllItems := False;
  bPrevisualizar := True;

  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, (Presupuestos as ISeleccionable).SelectedRecords);
                    APresupuestos := (Controller as IPresupuestosClienteController).ExtraerSeleccionados(Presupuestos) as IBizPresupuestoCliente;
                  end
                  else
                    APresupuestos := Presupuestos;

                    if (AppFactuGES.EmpresaActiva.ID = 1) then
                       //Preguntamos si desea que en los presupuestos se vea el Sello de Paco u Oscar,
                       //solo para empresa Tecsitel
                       bPrevisualizar := ElegirOpcionesImpresionPresupuestoCliente(AVerSello);

                    if bPrevisualizar and Assigned(APresupuestos) then
                       FController.Preview(APresupuestos, AllItems, AVerSello);
                end;
      end;
    end;
  end;
  APresupuestos := Nil;
end;

procedure TfEditorPresupuestosCliente.RefrescarInterno;
begin
  //Volvemos a cargar los años de los presupuestos
  if Assigned(FController) then
     ListaAnos := FController.DarListaAnosPresupuestos;

  inherited;
end;

procedure TfEditorPresupuestosCliente.SetController(const Value: IPresupuestosClienteController);
begin
  FController := Value;

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

procedure TfEditorPresupuestosCliente.SetPresupuestos(const Value: IBizPresupuestoCliente);
begin
  FPresupuestos := Value;

  if Assigned(FPresupuestos) 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 := FPresupuestos.DataTable.DynamicWhere.Xml;

    dsDataTable.DataTable := FPresupuestos.DataTable;
    if Assigned(ViewGrid) then
      (ViewGrid as IViewPresupuestosCliente).Presupuestos := Presupuestos;
  end;
end;

end.
