unit uEditorAlbaranCliente;

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, uAlbaranesClienteController, uViewDetallesBase, uViewDetallesAlbaranCliente,
  dxLayoutLookAndFeels, JvExComCtrls, JvStatusBar, uViewTotales,
  uIEditorAlbaranCliente, uBizAlbaranesCliente, uViewAlbaranCliente,
  uViewDetallesDTO, uViewDetallesArticulos, uDAInterfaces,
  uViewDetallesArticulosParaVenta, cxLabel;

type
  TfEditorAlbaranCliente = class(TfEditorDBItem, IEditorAlbaranCliente)
    pagContenido: TTabSheet;
    pagInicidencias: TTabSheet;
    frViewIncidenciasCli: TfrViewIncidencias;
    dxLayoutLookAndFeelList1: TdxLayoutLookAndFeelList;
    dxLayoutOfficeLookAndFeel1: TdxLayoutOfficeLookAndFeel;
    frViewDetallesAlbaranCliente1: TfrViewDetallesAlbaranCliente;
    frViewTotales1: TfrViewTotales;
    actEnviarEMail: TAction;
    TBXSubmenuItem2: TTBXSubmenuItem;
    TBXItem7: TTBXItem;
    TBXItem33: TTBXItem;
    TBXSeparatorItem6: TTBXSeparatorItem;

    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 frViewTotales1edtDescuentoPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
    procedure frViewTotales1edtIVAPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
    procedure actEnviarEMailExecute(Sender: TObject);
    procedure actEnviarEMailUpdate(Sender: TObject);
  private
    procedure RecalcularPortePorUnidad;

  protected
    FAlbaran: IBizAlbaranCliente;
    FViewAlbaran: IViewAlbaranCliente;
    FController : IAlbaranesClienteController;

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

    function GetAlbaran: IBizAlbaranCliente;
    procedure SetAlbaran(const Value: IBizAlbaranCliente); virtual;

    function GetViewAlbaran: IViewAlbaranCliente;
    procedure SetViewAlbaran(const Value: IViewAlbaranCliente);

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

    property ViewAlbaran: IViewAlbaranCliente read GetViewAlbaran write SetViewAlbaran;

    procedure OnClienteChanged(Sender : TObject);

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

  public
    procedure PonerTitulos(const ATitulo: string = ''); override;
    property Controller : IAlbaranesClienteController read GetController write SetController;
    property Albaran: IBizAlbaranCliente read GetAlbaran write SetAlbaran;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

uses
  uViewDatosYSeleccionCliente, uDataModuleUsuarios, uClientesController,
  uBizDireccionesContacto, schAlbaranesClienteClient_Intf, uDialogUtils,
  uEditorDBBase, uDataTableUtils, uFactuGES_App, uDialogOpcionesImpresionAlbaranesCliente;

{$R *.dfm}

{ TfEditorAlbaranCliente }

{
**************************** TfEditorAlbaranCliente ****************************
}
procedure TfEditorAlbaranCliente.actEnviarEMailExecute(Sender: TObject);
begin
  inherited;
  FController.EnviarAlbaranPorEMail(FAlbaran);
end;

procedure TfEditorAlbaranCliente.actEnviarEMailUpdate(Sender: TObject);
begin
  inherited;
  (Sender as TAction).Enabled := HayDatos;
end;

procedure TfEditorAlbaranCliente.AsignarVista;
var
  AViewAlbaranCliente: TfrViewAlbaranCliente;
begin
  AViewAlbaranCliente := TfrViewAlbaranCliente.create(Self);
  with AViewAlbaranCliente do
  begin
    Parent := pagGeneral;
    Align := alClient;
    dxLayoutControl1.LookAndFeel := dxLayoutOfficeLookAndFeel1;
  end;
  ViewAlbaran := AViewAlbaranCliente;
end;

constructor TfEditorAlbaranCliente.Create(AOwner: TComponent);
begin
  inherited;
  pgPaginas.ActivePageIndex := 0;

  AsignarVista;
end;

procedure TfEditorAlbaranCliente.CustomEditorClose(Sender: TObject;
  var Action: TCloseAction);
begin
  inherited;
  FViewAlbaran := NIL;
  FAlbaran := NIL;
end;

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

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

procedure TfEditorAlbaranCliente.EliminarInterno;
begin
  if (ShowConfirmMessage('¿Desea borrar este albarán de cliente?', '') = IDYES) then
  begin
    FController.Eliminar(FAlbaran);
    inherited
  end
end;

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

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

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

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

procedure TfEditorAlbaranCliente.frViewTotales1edtDescuentoPropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
begin
  inherited;
  FAlbaran.DESCUENTO := DisplayValue;
end;

procedure TfEditorAlbaranCliente.frViewTotales1edtIVAPropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
begin
  inherited;
  FAlbaran.IVA := DisplayValue;
end;

procedure TfEditorAlbaranCliente.frViewTotales1ePortePropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
begin
  inherited;
  if (not VarIsNull(DisplayValue)) and (Length(DisplayValue) > 0) then
    FAlbaran.IMPORTE_PORTE := DisplayValue
  else
    FAlbaran.IMPORTE_PORTE := 0;

//  RecalcularPortePorUnidad; En los documentos de cliente no se desglosa el porte por articulo
end;

function TfEditorAlbaranCliente.GetController: IAlbaranesClienteController;
begin
  Result := FController;
end;

function TfEditorAlbaranCliente.GetAlbaran: IBizAlbaranCliente;
begin
  Result := FAlbaran;
end;

function TfEditorAlbaranCliente.GetViewAlbaran: IViewAlbaranCliente;
begin
  Result := FViewAlbaran;
end;

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

  ShowHourglassCursor;
//  frViewDetallesPedidoCliente1.SaveGridStatus;
  frViewDetallesAlbaranCliente1.BeginUpdate;
  try
    bEsNuevo := FAlbaran.EsNuevo;
    FController.Guardar(FAlbaran);
  finally
    frViewDetallesAlbaranCliente1.EndUpdate;
//    frViewDetallesPedidoCliente1.RestoreGridStatus;
    HideHourglassCursor;
  end;
  if bEsNuevo then
     if FAlbaran.TIPO = CTE_TIPO_ALBARAN then
        ShowInfoMessage('El albarán se ha dado de alta con el código ' + FAlbaran.REFERENCIA)
     else
        ShowInfoMessage('La orden de devolución se ha dado de alta con el código ' + FAlbaran.REFERENCIA);
  Modified := False;
end;

procedure TfEditorAlbaranCliente.ImprimirInterno;
var
  FImprimirPrecios : Boolean;
  FImprimirRefProveedor : Boolean;
  FImprimirObservaciones: Boolean;
  FImprimirIncidencias: Boolean;

begin
  inherited;
  FImprimirPrecios := True;
  FImprimirRefProveedor := True;
  FImprimirObservaciones := False;
  FImprimirIncidencias := False;

  if ElegirOpcionesImpresionAlbaranCliente(FImprimirPrecios, FImprimirRefProveedor, FImprimirObservaciones, FImprimirIncidencias) then
     FController.Print(Albaran, False, FImprimirPrecios, FImprimirRefProveedor, FImprimirObservaciones, FImprimirIncidencias);
end;

procedure TfEditorAlbaranCliente.OnClienteChanged(Sender: TObject);
var
  ADireccion : IBizDireccionesContacto;
begin
	if Assigned(FAlbaran) then
	begin
	  FAlbaran.Cliente := ViewAlbaran.ViewClienteAlbaran.Cliente;

    if FAlbaran.Cliente.Direcciones.RecordCount = 0 then
    begin
       MessageBox(0, '¡Atención! Este cliente no tiene ' + #10#13 + 'ninguna dirección de envío en su ficha', 'Atención', MB_ICONWARNING or MB_OK);
       FAlbaran.Edit;
       FAlbaran.IMPORTE_PORTE := 0;
    end;

    if not Controller.ClienteController.TieneDatosBancarios(FAlbaran.Cliente) then
       MessageBox(0, 'Este cliente no tiene datos bancarios en su ficha', 'Atención', MB_ICONWARNING or MB_OK);

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

procedure TfEditorAlbaranCliente.pgPaginasChanging(Sender: TObject; var AllowChange: Boolean);
begin
  inherited;
  if (not Assigned(FAlbaran)) or (FAlbaran.ID_CLIENTE = 0) then
  begin
    ShowWarningMessage('Antes de introducir conceptos debe elegir un cliente para este albarán');
    AllowChange := False;
  end;
end;

procedure TfEditorAlbaranCliente.PonerTitulos(const ATitulo: string);
var
  FTitulo : String;
begin
  FTitulo := ATitulo;
  if (FTitulo = '') and Assigned(FAlbaran) then
  begin
    if FAlbaran.EsNuevo then
      FTitulo := 'Nuevo albarán de cliente'
    else
      FTitulo := 'Albarán de cliente'  + ' - ' + FAlbaran.Cliente.Nombre + ' - ' + FAlbaran.SITUACION; 
  end;

  inherited PonerTitulos(FTitulo);

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

procedure TfEditorAlbaranCliente.PrevisualizarInterno;
var
  FImprimirPrecios : Boolean;
  FImprimirRefProveedor : Boolean;
  FImprimirObservaciones: Boolean;
  FImprimirIncidencias: Boolean;

begin
  inherited;
  FImprimirPrecios := True;
  FImprimirRefProveedor := True;
  FImprimirObservaciones := False;
  FImprimirIncidencias := False;

  if ElegirOpcionesImpresionAlbaranCliente(FImprimirPrecios, FImprimirRefProveedor, FImprimirObservaciones, FImprimirIncidencias) then
     FController.Preview(Albaran, False, FImprimirPrecios, FImprimirRefProveedor, FImprimirObservaciones, FImprimirIncidencias);
end;

procedure TfEditorAlbaranCliente.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(FAlbaran.IMPORTE_PORTE, FAlbaran.Detalles)
end;

procedure TfEditorAlbaranCliente.SetController(const Value: IAlbaranesClienteController);
begin
  FController := Value;

  if Assigned(FController) then
  begin
    ViewAlbaran.Controller := Controller;
    frViewDetallesAlbaranCliente1.Controller := Controller.DetallesController;
  end;
end;

procedure TfEditorAlbaranCliente.SetAlbaran(const Value: IBizAlbaranCliente);
begin
  FAlbaran := Value;

  if Assigned(FAlbaran) then
  begin
    dsDataTable.DataTable := FAlbaran.DataTable;
    frViewIncidenciasCli.DADataSource.DataTable := dsDataTable.DataTable;
    frViewTotales1.DADataSource.DataTable := dsDataTable.DataTable;

    if Assigned(FViewAlbaran) then
    begin
      ViewAlbaran.ViewClienteAlbaran.OnClienteChanged := NIL;
      try
        FViewAlbaran.Albaran := FAlbaran;
        frViewDetallesAlbaranCliente1.Detalles := FAlbaran.Detalles;
        frViewDetallesAlbaranCliente1.Albaran := FAlbaran; //Para poder sacar los descuento del articulos segun el cliente seleccionado
      finally
        ViewAlbaran.ViewClienteAlbaran.OnClienteChanged := OnClienteChanged;
      end;
    end;
  end
  else begin
    dsDataTable.DataTable := NIL;
    frViewIncidenciasCli.DADataSource.DataTable := NIL;
    frViewTotales1.DADataSource.DataTable := NIL;

    if Assigned(FViewAlbaran) then
    begin
      FViewAlbaran.Albaran := NIL;
      ViewAlbaran.ViewClienteAlbaran.OnClienteChanged := NIL;
      frViewDetallesAlbaranCliente1.Detalles := NIL;
      frViewDetallesAlbaranCliente1.Albaran := NIL;
    end;
  end;
end;

procedure TfEditorAlbaranCliente.SetViewAlbaran(const Value: IViewAlbaranCliente);
begin
  FViewAlbaran := Value;

  if Assigned(FViewAlbaran) and Assigned(Albaran) then
    FViewAlbaran.Albaran := Albaran;
end;

end.
