unit uEditorPresupuestoCliente;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  uEditorDBItem, DB, uDADataTable, JvAppStorage,
  JvAppRegistryStorage, JvComponent, JvFormPlacement, ImgList,
  PngImageList, StdActns, ActnList, ComCtrls, TBX, TB2Item, TB2Dock,
  TB2Toolbar, ExtCtrls, JvExControls, JvNavigationPane,
  uCustomView, uViewBase, JvComponentBase,
  StdCtrls, pngimage, AppEvnts, cxControls, cxContainer, cxEdit, cxTextEdit, cxMemo, cxDBEdit,
  uViewIncidencias,
  uPresupuestosClienteController,
  uViewDetallesBase, 
  dxLayoutLookAndFeels, JvExComCtrls, JvStatusBar, uViewTotales,
  uIEditorPresupuestoCliente, uBizPresupuestosCliente, uViewPresupuestoCliente,
  uViewDetallesDTO, uViewDetallesArticulos, uViewDetallesPresupuestoCliente,
  uDAInterfaces, cxRichEdit, cxDBRichEdit, JvGIF, uViewRichEditor, cxPC,
  uViewDetallesArticulosParaVenta, uViewDocumentos,
  uViewDocumentosPresupuestoCliente, uViewDatosYSeleccionClientePresupuesto,
  cxLabel, uViewTotalesPresupuesto;

type
  TfEditorPresupuestoCliente = class(TfEditorDBItem, IEditorPresupuestoCliente)
    pagContenido: TTabSheet;
    pagInicidencias: TTabSheet;
    frViewIncidenciasCli: TfrViewIncidencias;
    dxLayoutLookAndFeelList1: TdxLayoutLookAndFeelList;
    dxLayoutOfficeLookAndFeel1: TdxLayoutOfficeLookAndFeel;
    pagPortada: TTabSheet;
    pagMemoria: TTabSheet;
    Panel1: TPanel;
    Image2: TImage;
    Panel2: TPanel;
    Image3: TImage;
    frViewRichEditor1: TfrViewRichEditor;
    frViewRichEditor2: TfrViewRichEditor;
    frViewDetallesPresupuestoCliente1: TfrViewDetallesPresupuestoCliente;
    actGenerarCertificado: TAction;
    TBXSubmenuItem2: TTBXSubmenuItem;
    TBXItem7: TTBXItem;
    TBXSeparatorItem6: TTBXSeparatorItem;
    TBXItem33: TTBXItem;
    actEnviarPorEMail: TAction;
    TBXItem34: TTBXItem;
    TBXItem35: TTBXItem;
    pagDocumentos: TTabSheet;
    frViewDocumentosPresupuestoCliente1: TfrViewDocumentosPresupuestoCliente;
    frViewTotalesPresupuesto1: TfrViewTotalesPresupuesto;

    procedure FormShow(Sender: TObject);
    procedure CustomEditorClose(Sender: TObject; var Action: TCloseAction);
    procedure frViewTotales1ePortePropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
    procedure actGenerarCertificadoExecute(Sender: TObject);
    procedure actGenerarCertificadoUpdate(Sender: TObject);
    procedure pgPaginasChanging(Sender: TObject; var AllowChange: Boolean);
    procedure actEnviarPorEMailExecute(Sender: TObject);
    procedure actEnviarPorEMailUpdate(Sender: TObject);
    procedure actEliminarUpdate(Sender: TObject);
  private
    procedure RecalcularPortePorUnidad;

  protected
    FPresupuesto: IBizPresupuestoCliente;
    FViewPresupuesto: IViewPresupuestoCliente;
    FViewClientePresupuesto :IViewDatosYSeleccionClientePresupuesto;
    FController : IPresupuestosClienteController;

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

    function GetPresupuesto: IBizPresupuestoCliente;
    procedure SetPresupuesto(const Value: IBizPresupuestoCliente); virtual;

    function GetViewPresupuesto: IViewPresupuestoCliente;
    procedure SetViewPresupuesto(const Value: IViewPresupuestoCliente);

    procedure PrevisualizarInterno; override;
    procedure ImprimirInterno; override;
    procedure GuardarInterno; override;
    procedure EliminarInterno; override;

    property ViewPresupuesto: IViewPresupuestoCliente read GetViewPresupuesto write SetViewPresupuesto;

    procedure OnClienteChanged(Sender : TObject);

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

    procedure PonerTitulos(const ATitulo: string = ''); override;
    function GetModified: Boolean; override;
    procedure SetModified(const Value : Boolean); override;
    function PuedoImprimir: Boolean; override;
    function PuedoEnviar: Boolean; virtual;

  public
    property Controller : IPresupuestosClienteController read GetController write SetController;
    property Presupuesto: IBizPresupuestoCliente read GetPresupuesto write SetPresupuesto;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

uses
  uViewDatosYSeleccionCliente, uDataModuleUsuarios, uClientesController,
  uBizDireccionesContacto, uDialogUtils, uFactuGES_App, uDataTableUtils,
  uDialogOpcionesImpresionPresupuestosCliente;

{$R *.dfm}

{ TfEditorPresupuestoCliente }

{
**************************** TfEditorPresupuestoCliente ****************************
}
procedure TfEditorPresupuestoCliente.actEliminarUpdate(Sender: TObject);
begin
  inherited;
  if (Sender as TAction).Enabled then
     (Sender as TAction).Enabled := (FPresupuesto.SITUACION = SITUACION_PRESUPUESTO_PENDIENTE);
end;

procedure TfEditorPresupuestoCliente.actEnviarPorEMailExecute(Sender: TObject);
begin
  if actEnviarPorEMail.Enabled then
  begin
    if Modified then
    begin
      if (ShowConfirmMessage('Se han producido cambios', 'Se han producido cambios y no se puede enviar por email hasta que no se guarden.' + #10#13 +
        '¿Desea guardarlos ahora?') = IDYES) then
      begin
        GuardarInterno;
        FController.EnviarPresupuestoPorEMail(Presupuesto);
      end
      else
        ShowInfoMessage('Recuerde guardar los cambios si quiere enviar por email.');
    end
    else
      FController.EnviarPresupuestoPorEMail(Presupuesto);
  end;
end;

procedure TfEditorPresupuestoCliente.actEnviarPorEMailUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := HayDatos and PuedoEnviar;
end;

procedure TfEditorPresupuestoCliente.actGenerarCertificadoExecute(
  Sender: TObject);
begin
  if FController.GenerarCertificados(Presupuesto, False) then
    ShowInfoMessage('Generar certificado de trabajo', 'Se ha generado el certificado de trabajos.')  
end;


procedure TfEditorPresupuestoCliente.actGenerarCertificadoUpdate(
  Sender: TObject);
begin
  (Sender as TAction).Enabled := HayDatos and
                                (FPresupuesto.SITUACION = SITUACION_PRESUPUESTO_ACEPTADO);
end;

procedure TfEditorPresupuestoCliente.AsignarVista;
var
  AViewPresupuestoCliente: TfrViewPresupuestoCliente;

begin
  AViewPresupuestoCliente := TfrViewPresupuestoCliente.create(Self);
  with AViewPresupuestoCliente do
  begin
    Parent := pagGeneral;
    Align := alClient;
    dxLayoutControl1.LookAndFeel := dxLayoutOfficeLookAndFeel1;
  end;
  ViewPresupuesto := AViewPresupuestoCliente;
end;

constructor TfEditorPresupuestoCliente.Create(AOwner: TComponent);
begin
  inherited;
  pgPaginas.ActivePageIndex := 0;
  AsignarVista;
end;

procedure TfEditorPresupuestoCliente.CustomEditorClose(Sender: TObject;
  var Action: TCloseAction);
begin
  inherited;
  //GESTION_DOCUMENTOS
  //Este método eliminará el directorio temporal si se ha creado
  frViewDocumentosPresupuestoCliente1.actEliminarTodo.Execute;

  FViewPresupuesto := NIL;
  FViewClientePresupuesto := NIL;
  FPresupuesto := NIL;
end;

destructor TfEditorPresupuestoCliente.Destroy;
begin
  // Utilizar mejor OnClose;
  inherited;
end;

procedure TfEditorPresupuestoCliente.EliminarInterno;
begin
  if (ShowConfirmMessage('¿Desea borrar este presupuesto de cliente?', '') = IDYES) then
  begin
    FController.Eliminar(FPresupuesto);
    inherited
  end
end;

procedure TfEditorPresupuestoCliente.FormShow(Sender: TObject);
begin
  inherited;

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

  if not Assigned(Presupuesto) then
    raise Exception.Create('No hay ningún presupuesto asignado');

  pgPaginas.ActivePage := pagGeneral;
  Presupuesto.DataTable.Active := True;
end;

procedure TfEditorPresupuestoCliente.frViewTotales1ePortePropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
begin
  inherited;
{  if (not VarIsNull(DisplayValue)) and (Length(DisplayValue) > 0) then
    FPresupuesto.IMPORTE_PORTE := DisplayValue
  else
    FPresupuesto.IMPORTE_PORTE := 0;
}
//  RecalcularPortePorUnidad; En los documentos de cliente no se desglosa el porte por articulo
end;

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

function TfEditorPresupuestoCliente.GetModified: Boolean;
begin
  // inherited;  <- No llamar al padre porque queremos tratamiento especial.
  if ReadOnly then
     Result := False
  else begin
    Result := DataTableModified(dsDataTable.DataTable);

    if not Result then
      Result := frViewDocumentosPresupuestoCliente1.Modified;
  end;
end;

function TfEditorPresupuestoCliente.GetPresupuesto: IBizPresupuestoCliente;
begin
  Result := FPresupuesto;
end;

function TfEditorPresupuestoCliente.GetViewPresupuesto: IViewPresupuestoCliente;
begin
  Result := FViewPresupuesto;
end;

procedure TfEditorPresupuestoCliente.GuardarInterno;
var
  bEsNuevo : Boolean;
begin
  inherited;

  ShowHourglassCursor;
//  frViewDetallesPresupuestoCliente1.SaveGridStatus;
  frViewDetallesPresupuestoCliente1.BeginUpdate;
  try
    bEsNuevo := FPresupuesto.EsNuevo;
    //GESTION_DOCUMENTOS
    if FController.Guardar(FPresupuesto) then
       frViewDocumentosPresupuestoCliente1.actActualizarServidor.Execute;

  finally
    frViewDetallesPresupuestoCliente1.EndUpdate;
//    frViewDetallesPresupuestoCliente1.RestoreGridStatus;
    HideHourglassCursor;
  end;
  if bEsNuevo then
    ShowInfoMessage('El presupuesto se ha dado de alta con el código ' + FPresupuesto.REFERENCIA);

  Modified := False;
end;

procedure TfEditorPresupuestoCliente.ImprimirInterno;
var
  AVerSello: Integer;
  bPrevisualizar: Boolean;
begin
  inherited;
  bPrevisualizar := True;

  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(FPresupuesto) then
     if not Modified then
        FController.Print(FPresupuesto, False, AVerSello);
end;

procedure TfEditorPresupuestoCliente.OnClienteChanged(Sender: TObject);
begin
  if Assigned(FPresupuesto) then
  begin
  	FPresupuesto.Cliente := ViewPresupuesto.ViewClientePresupuesto.Cliente;

//Desactivado porque en presupuestos no utilizan el catálogo de clientes    
//    if (FPresupuesto.Detalles.RecordCount > 0) then
//      FController.DetallesController.ActualizarDetalles(FPresupuesto.Detalles, FPresupuesto.Cliente);
  end;
end;

procedure TfEditorPresupuestoCliente.pgPaginasChanging(Sender: TObject;
  var AllowChange: Boolean);
var
  ACadena : String;
begin
  inherited;
  if (not Assigned(FPresupuesto)) or (FPresupuesto.ID_CLIENTE = 0) then
  begin
    ACadena := 'Antes de introducir conceptos debe elegir un cliente para este presupuesto';
    ShowWarningMessage(ACadena);
    AllowChange := False;
  end
end;

procedure TfEditorPresupuestoCliente.PonerTitulos(const ATitulo: string);
var
  FTitulo : String;
begin
  FTitulo := ATitulo;
  if (FTitulo = '') and Assigned(FPresupuesto) then
  begin
    if FPresupuesto.EsNuevo then
      FTitulo := 'Nuevo presupuesto de cliente'
    else
      FTitulo := 'Presupuesto de cliente'  + ' - ' + FPresupuesto.Cliente.Nombre + ' - ' + FPresupuesto.SITUACION;
  end;

  inherited PonerTitulos(FTitulo);
  Self.Caption := FTitulo + ' (' + AppFactuGES.EmpresaActiva.NOMBRE + ')';
end;

procedure TfEditorPresupuestoCliente.PrevisualizarInterno;
var
  AVerSello: Integer;
  bPrevisualizar: Boolean;
begin
  inherited;
  bPrevisualizar := True;

  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(FPresupuesto) then
     if not Modified then
        FController.Preview(FPresupuesto, False, AVerSello);
end;

function TfEditorPresupuestoCliente.PuedoEnviar: Boolean;
begin
  Result := not Presupuesto.Cliente.IDIsNull;
end;

function TfEditorPresupuestoCliente.PuedoImprimir: Boolean;
begin
  Result := inherited PuedoImprimir and (not Presupuesto.Cliente.IDIsNull);
end;

procedure TfEditorPresupuestoCliente.RecalcularPortePorUnidad;
begin
  //Esta lógica se llamará en el editor porque es para facilitar el rellenado de información del documento
  //no puede ir en la clase de negocio porque no es una lógica que tenga sentido fuera del editor.
  if Assigned(Controller)
  and Assigned(Controller.DetallesController) then
      Controller.DetallesController.DesglosarPorteDetalles(FPresupuesto.IMPORTE_PORTE, FPresupuesto.Detalles)
end;

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

  if Assigned(FController) then
  begin
//    ViewPresupuesto.ViewClientePresupuesto.Controller := Controller.ClienteController;
    frViewDetallesPresupuestoCliente1.Controller := Controller.DetallesController;

    //GESTION_DOCUMENTOS
    frViewDocumentosPresupuestoCliente1.Controller := Controller;

    frViewTotalesPresupuesto1.Controller := FController;
  end;
end;

procedure TfEditorPresupuestoCliente.SetModified(const Value: Boolean);
begin
  inherited;
  frViewDocumentosPresupuestoCliente1.Modified := Value;
end;

procedure TfEditorPresupuestoCliente.SetPresupuesto(const Value: IBizPresupuestoCliente);
begin
  FPresupuesto := Value;

  if Assigned(FPresupuesto) then
  begin
    dsDataTable.DataTable := FPresupuesto.DataTable;
    frViewIncidenciasCli.DADataSource.DataTable := dsDataTable.DataTable;
    frViewTotalesPresupuesto1.DADataSource.DataTable := dsDataTable.DataTable;

    if Assigned(FViewPresupuesto) then
    begin
      ViewPresupuesto.ViewClientePresupuesto.OnClienteChanged := NIL;
      try
        FViewPresupuesto.Presupuesto := FPresupuesto;
        frViewDetallesPresupuestoCliente1.Detalles := FPresupuesto.Detalles;
        frViewDetallesPresupuestoCliente1.Presupuesto := FPresupuesto; //Para poder sacar los descuento del articulos segun el cliente seleccionado

        //GESTION_DOCUMENTOS
        frViewDocumentosPresupuestoCliente1.Presupuesto := FPresupuesto;

        frViewTotalesPresupuesto1.Presupuesto := FPresupuesto;

      finally
        ViewPresupuesto.ViewClientePresupuesto.OnClienteChanged := OnClienteChanged;
      end;
    end;
  end;
end;

procedure TfEditorPresupuestoCliente.SetViewPresupuesto(const Value: IViewPresupuestoCliente);
begin
  FViewPresupuesto := Value;

  if Assigned(FViewPresupuesto) then
  begin
    FViewClientePresupuesto := FViewPresupuesto.ViewClientePresupuesto;

    if Assigned(Presupuesto) then
      FViewPresupuesto.Presupuesto := Presupuesto;
  end;
end;

end.
