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,   
    
    
   uViewDocumentos, uViewDocumentosPresupuestoCliente;

type
  TfEditorPresupuestoCliente = class(TfEditorDBItem, IEditorPresupuestoCliente)
    pagContenido: TTabSheet;
    pagInicidencias: TTabSheet;
    frViewIncidenciasCli: TfrViewIncidencias;
    dxLayoutLookAndFeelList1: TdxLayoutLookAndFeelList;
    dxLayoutOfficeLookAndFeel1: TdxLayoutOfficeLookAndFeel;
    frViewTotales1: TfrViewTotales;
    frViewDetallesPresupuestoCliente1: TfrViewDetallesPresupuestoCliente;
    pagPortada: TTabSheet;
    pagMemoria: TTabSheet;
    cxDBMemo1: TcxDBMemo;
    edtPortada: TcxDBRichEdit;
    actEnviarEMail: TAction;
    frViewDocumentosPresupuestoCliente1: TfrViewDocumentosPresupuestoCliente;
    TBXItem7: TTBXItem;
    TBXSeparatorItem6: TTBXSeparatorItem;
    TBXItem33: TTBXItem;
    TBXSubmenuItem2: TTBXSubmenuItem;
    pagDocumentos: TTabSheet;
    procedure FormShow(Sender: TObject);
    procedure CustomEditorClose(Sender: TObject; var Action: TCloseAction);
    procedure pgPaginasChanging(Sender: TObject; var AllowChange: Boolean);
    procedure frViewTotales1ePortePropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
    procedure actEnviarEMailExecute(Sender: TObject);
    procedure actEnviarEMailUpdate(Sender: TObject);
  private
    procedure RecalcularPortePorUnidad;

  protected
    FPresupuesto: IBizPresupuestoCliente;
    FViewPresupuesto: IViewPresupuestoCliente;
    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;
  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;

{$R *.dfm}

{ TfEditorPresupuestoCliente }

{
**************************** TfEditorPresupuestoCliente ****************************
}
procedure TfEditorPresupuestoCliente.actEnviarEMailExecute(Sender: TObject);
begin
  inherited;
  FController.EnviarPresupuestoPorEMail(Presupuesto);
end;

procedure TfEditorPresupuestoCliente.actEnviarEMailUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := HayDatos; 
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;
  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');

  Presupuesto.DataTable.Active := True;
  pgPaginas.ActivePage := pagGeneral;
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; No se desglosa el porte por articulo en los documentos de cliente
end;

function TfEditorPresupuestoCliente.GetController: IPresupuestosClienteController;
begin
  Result := FController;
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;
  bEsNuevo := False;

  ShowHourglassCursor;
  frViewDetallesPresupuestoCliente1.BeginUpdate;
  try
    bEsNuevo := FPresupuesto.EsNuevo;

    //GESTION_DOCUMENTOS
    if FController.Guardar(FPresupuesto) then
       frViewDocumentosPresupuestoCliente1.actActualizarServidor.Execute;

    FController.Guardar(FPresupuesto);
  finally
    frViewDetallesPresupuestoCliente1.EndUpdate;
    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;
begin
  AppFactuGES.ShowCapado;
{
  inherited;
  if not Modified then
    FController.Print(FPresupuesto);
}
end;

procedure TfEditorPresupuestoCliente.OnClienteChanged(Sender: TObject);
var
  AClientesController : IClientesController;
  ADireccion : IBizDireccionesContacto;
begin
  if Assigned(FPresupuesto) then
  begin
    FPresupuesto.Cliente := ViewPresupuesto.ViewClientePresupuesto.Cliente;

    AClientesController := TClientesController.Create;
    try
      // No avisar si el cliente no tiene datos bancarios
      {if not AClientesController.TieneDatosBancarios(FPresupuesto.Cliente) then
        MessageBox(0, 'Este cliente no tiene datos bancarios en su ficha', 'Atención', MB_ICONWARNING or MB_OK);}

        // Si el Presupuesto tiene detalles hay que mirar si los descuentos y otros campos
        // para los artículos hay que cambiarlos.
        if (FPresupuesto.Detalles.RecordCount > 0) then
           FController.DetallesController.ActualizarDetalles(FPresupuesto.Detalles, FPresupuesto.Cliente);

    finally
      AClientesController := NIL;
    end;
  end;
end;

procedure TfEditorPresupuestoCliente.pgPaginasChanging(Sender: TObject; var AllowChange: Boolean);
begin
  inherited;
  if (not Assigned(FPresupuesto)) or (FPresupuesto.ID_CLIENTE = 0) then
  begin
    ShowWarningMessage('Antes de introducir conceptos debe elegir un cliente para este presupuesto');
    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;
begin
AppFactuGES.ShowCapado;
{
  inherited;
  if not Modified then
    FController.Preview(FPresupuesto);
}    
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.Controller := Controller;
    ViewPresupuesto.ViewClientePresupuesto.Controller := Controller.ClienteController;
    frViewDetallesPresupuestoCliente1.Controller := Controller.DetallesController;

    //GESTION_DOCUMENTOS
    frViewDocumentosPresupuestoCliente1.Controller := Controller;
  end;
end;

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

  if Assigned(FPresupuesto) then
  begin
    dsDataTable.DataTable := FPresupuesto.DataTable;
    frViewIncidenciasCli.DADataSource.DataTable := dsDataTable.DataTable;
    frViewTotales1.DADataSource.DataTable := dsDataTable.DataTable;
    if Assigned(FViewPresupuesto) then
    begin
      FViewPresupuesto.Presupuesto := FPresupuesto;
      ViewPresupuesto.ViewClientePresupuesto.Cliente := FPresupuesto.Cliente;
      ViewPresupuesto.ViewClientePresupuesto.OnClienteChanged := OnClienteChanged;
      frViewDetallesPresupuestoCliente1.Detalles := FPresupuesto.Detalles;
      frViewDetallesPresupuestoCliente1.Presupuesto := FPresupuesto; //Para poder sacar los descuento del articulos segun el cliente seleccionado

      //GESTION_DOCUMENTOS
      frViewDocumentosPresupuestoCliente1.Presupuesto := FPresupuesto;
    end;
  end;
end;

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

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

end.
