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;
    actGenerarContrato: TAction;
    TBXSubmenuItem2: TTBXSubmenuItem;
    TBXSeparatorItem17: TTBXSeparatorItem;
    TBXItem38: TTBXItem;
    TBXItem39: TTBXItem;
    N4: TMenuItem;
    Generar2: TMenuItem;
    JsGenerarDialog: TJSDialog;
    JsPrevisualizarDialog: TJSDialog;
    JsImprimirDialog: TJSDialog;
    TBXItem40: TTBXItem;
    JsListaPresupuestosNoEliminados: TJSDialog;
    TBXItem41: 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;
    Aceptar1: TMenuItem;
    Anular1: TMenuItem;
    N3: TMenuItem;
    TBXSubmenuItem3: TTBXSubmenuItem;
    bVarios: TTBXItem;
    bElectrodomestico: TTBXItem;
    bBano: TTBXItem;
    bArmario: TTBXItem;
    bCocina: TTBXItem;
    bObra: TTBXItem;
    procedure FormShow(Sender: TObject);
    procedure actGenerarAlbaranCliExecute(Sender: TObject);
    procedure actEliminarUpdate(Sender: TObject);
    procedure actGenerarContratoUpdate(Sender: TObject);
    procedure actGenerarContratoExecute(Sender: TObject);
    procedure actGenerarExecute(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);
    procedure bCocinaClick(Sender: TObject);
    procedure bArmarioClick(Sender: TObject);
    procedure bBanoClick(Sender: TObject);
    procedure bElectrodomesticoClick(Sender: TObject);
    procedure bVariosClick(Sender: TObject);
    procedure bObraClick(Sender: TObject);

  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;

    procedure CambiarSituacion(const ASituacion : String);

    //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, uGridUtils,
  uGenerarContratosCliUtils,
  uGestorInformesController, uEditorFechaDecisionPresupuesto;


{$R *.dfm}

{
*************************** TfEditorPresupuestosCliente ***************************
}
procedure TfEditorPresupuestosCliente.actAceptarExecute(Sender: TObject);
begin
  CambiarSituacion(SITUACION_PRESUPUESTO_ACEPTADO);
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);
begin
  CambiarSituacion(SITUACION_PRESUPUESTO_ANULADO);
end;

procedure TfEditorPresupuestosCliente.actAnularUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := HayDatos
                                 and ViewGrid.esSeleccionCeldaDatos
                                 and (FPresupuestos.SITUACION <> SITUACION_PRESUPUESTO_ANULADO)
                                 and (FPresupuestos.REF_CONTRATO = '');
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);
begin
  inherited;
  FController.EnviarPresupuestoPorEMail(FPresupuestos);
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.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.actGenerarContratoExecute(Sender: TObject);
var
  APresupuestos: IBizPresupuestoCliente;
  AllItems: Boolean;
begin
  inherited;
  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;
  end
  else
    APresupuestos := Self.Presupuestos;

  if (Application.MessageBox('¿Está seguro que desea generar el/los contrato/s de los presupuesto/s seleccionado/s?', 'Atención', MB_YESNO) = IDYES) then
  begin
    if not AllItems then
      GenerarContratoCli(APresupuestos.ID)
    else
      with APresupuestos.DataTable do
      begin
        First;
        while not EOF do
        begin
          GenerarContratoCli(APresupuestos.ID, False);
          Next;
        end;
      end;

    actRefrescar.Execute;
    if AllItems then
       ShowInfoMessage('Se han generado los contratos');
  end
end;

procedure TfEditorPresupuestosCliente.actGenerarContratoUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := HayDatos
                                 and (ViewGrid.NumSeleccionados = 1)
                                 and (FPresupuestos.REF_CONTRATO = '')
                                 and ViewGrid.esSeleccionCeldaDatos
                                 and (FPresupuestos.SITUACION = SITUACION_PRESUPUESTO_ACEPTADO);
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;

procedure TfEditorPresupuestosCliente.bArmarioClick(Sender: TObject);
begin
  inherited;
  if FController.Anadir(Presupuestos, teArmario) then
     FController.Ver(Presupuestos);
end;

procedure TfEditorPresupuestosCliente.bBanoClick(Sender: TObject);
begin
  inherited;
  if FController.Anadir(Presupuestos, teBano) then
     FController.Ver(Presupuestos);
end;

procedure TfEditorPresupuestosCliente.bCocinaClick(Sender: TObject);
begin
  inherited;
  if FController.Anadir(Presupuestos, teCocina) then
     FController.Ver(Presupuestos);
end;

procedure TfEditorPresupuestosCliente.bElectrodomesticoClick(Sender: TObject);
begin
  inherited;
  if FController.Anadir(Presupuestos, teElectrodomestico) then
     FController.Ver(Presupuestos);
end;

procedure TfEditorPresupuestosCliente.bObraClick(Sender: TObject);
begin
  inherited;
  if FController.Anadir(Presupuestos, teObra) then
     FController.Ver(Presupuestos);
end;

procedure TfEditorPresupuestosCliente.bVariosClick(Sender: TObject);
begin
  inherited;
  if FController.Anadir(Presupuestos, teVarios) then
     FController.Ver(Presupuestos);
end;

procedure TfEditorPresupuestosCliente.CambiarSituacion(
  const ASituacion: String);
var
  APresupuestos: IBizPresupuestoCliente;
  AllItems: Boolean;
  AFecha: TDate;
  AMensaje : String;
  ATitulo : String;
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 := Now;
  if ElegirFechaDecisionPresupuesto(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;

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

      if ASituacion = SITUACION_PRESUPUESTO_ACEPTADO then
      begin
        // ¿Generar el contrato?
        if AllItems then
        begin
          AMensaje := 'Los presupuestos han sido aceptados';
          ATitulo := '¿Desea generar ahora los contratos?'
        end
        else begin
          AMensaje := 'El presupuesto ha sido aceptado';
          ATitulo := '¿Desea generar ahora el contrato?';
        end;

        if (ShowConfirmMessage(ATitulo, AMensaje) = IDYES) then
          actGenerarContrato.Execute;
      end;
    end;

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

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

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

procedure TfEditorPresupuestosCliente.NuevoInterno;
begin
  inherited;
  if FController.Anadir(Presupuestos, teCocina) 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
  if (ATitulo = '') then
     FTitulo := 'Lista de presupuestos de cliente - ' + AppFactuGES.EmpresaActiva.NOMBRE
  else
     FTitulo := ATitulo;

  inherited PonerTitulos(FTitulo);
end;

procedure TfEditorPresupuestosCliente.PrevisualizarInterno;
var
  Respuesta : Integer;
  APresupuestos: IBizPresupuestoCliente;
  AllItems: Boolean;
begin
  APresupuestos := 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, (Presupuestos as ISeleccionable).SelectedRecords);
                    APresupuestos := (Controller as IPresupuestosClienteController).ExtraerSeleccionados(Presupuestos) as IBizPresupuestoCliente;
                  end
                  else
                    APresupuestos := Presupuestos;

                  if Assigned(APresupuestos) then
                     FController.Preview(APresupuestos, AllItems);
                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.
