unit uEditorPedidoCliente;

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,
  uPedidosClienteController,
  uViewDetallesBase, uViewDetallesPedidoCliente,
  dxLayoutLookAndFeels, JvExComCtrls, JvStatusBar, uViewTotales,
  uIEditorPedidoCliente, uBizPedidosCliente, uViewPedidoCliente,
  uViewDetallesDTO, uViewDetallesArticulos;

type
  TfEditorPedidoCliente = class(TfEditorDBItem, IEditorPedidoCliente)
    pagContenido: TTabSheet;
    pagInicidencias: TTabSheet;
    frViewIncidenciasCli: TfrViewIncidencias;
    dxLayoutLookAndFeelList1: TdxLayoutLookAndFeelList;
    dxLayoutOfficeLookAndFeel1: TdxLayoutOfficeLookAndFeel;
    frViewDetallesPedidoCliente1: TfrViewDetallesPedidoCliente;
    frViewTotales1: TfrViewTotales;

    procedure FormShow(Sender: TObject); override;
    procedure CustomEditorClose(Sender: TObject; var Action: TCloseAction);
    procedure pgPaginasChanging(Sender: TObject; var AllowChange: Boolean);

  protected
    FPedido: IBizPedidoCliente;
    FViewPedido: IViewPedidoCliente;
    FController : IPedidosClienteController;

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

    function GetPedido: IBizPedidoCliente;
    procedure SetPedido(const Value: IBizPedidoCliente); virtual;

    function GetViewPedido: IViewPedidoCliente;
    procedure SetViewPedido(const Value: IViewPedidoCliente);

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

    property ViewPedido: IViewPedidoCliente read GetViewPedido write SetViewPedido;

    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 : IPedidosClienteController read GetController write SetController;
    property Pedido: IBizPedidoCliente read GetPedido write SetPedido;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

implementation

uses
  uViewDatosYSeleccionCliente, uDataModuleUsuarios, uClientesController,
  uBizDireccionesContacto, uDialogUtils;

{$R *.dfm}

{ TfEditorPedidoCliente }

{
**************************** TfEditorPedidoCliente ****************************
}
procedure TfEditorPedidoCliente.AsignarVista;
var
  AViewPedidoCliente: TfrViewPedidoCliente;

begin
  AViewPedidoCliente := TfrViewPedidoCliente.create(Self);
  with AViewPedidoCliente do
  begin
    Parent := pagGeneral;
    Align := alClient;
    dxLayoutControl1.LookAndFeel := dxLayoutOfficeLookAndFeel1;
  end;
  ViewPedido := AViewPedidoCliente;
end;

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

  AsignarVista;
end;

procedure TfEditorPedidoCliente.CustomEditorClose(Sender: TObject;
  var Action: TCloseAction);
begin
  inherited;
  FViewPedido := NIL;
  FPedido := NIL;
end;

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

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

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

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

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

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

function TfEditorPedidoCliente.GetController: IPedidosClienteController;
begin
  Result := FController;
end;

function TfEditorPedidoCliente.GetPedido: IBizPedidoCliente;
begin
  Result := FPedido;
end;

function TfEditorPedidoCliente.GetViewPedido: IViewPedidoCliente;
begin
  Result := FViewPedido;
end;

procedure TfEditorPedidoCliente.GuardarInterno;
var
  bEsNuevo : Boolean;
begin
  inherited;
  bEsNuevo := False;

  ShowHourglassCursor;
//  frViewDetallesPedidoCliente1.SaveGridStatus;
  frViewDetallesPedidoCliente1.BeginUpdate;
  try
    bEsNuevo := FPedido.EsNuevo;
    FController.Guardar(FPedido);
  finally
    frViewDetallesPedidoCliente1.EndUpdate;
//    frViewDetallesPedidoCliente1.RestoreGridStatus;
    HideHourglassCursor;
  end;
  if bEsNuevo then
    ShowInfoMessage('El pedido se ha dado de alta con el código ' + FPedido.REFERENCIA);

  Modified := False;
end;

procedure TfEditorPedidoCliente.ImprimirInterno;
begin
  inherited;
  if not Modified then
    FController.Print(FPedido);
end;

procedure TfEditorPedidoCliente.OnClienteChanged(Sender: TObject);
var
  AClientesController : IClientesController;
  ADireccion : IBizDireccionesContacto;
begin
  if Assigned(FPedido) then
  begin
    FPedido.Cliente := ViewPedido.ViewClientePedido.Cliente;

    AClientesController := TClientesController.Create;
    try
      if not AClientesController.TieneDatosBancarios(FPedido.Cliente) then
        MessageBox(0, 'Este cliente no tiene datos bancarios en su ficha', 'Atención', MB_ICONWARNING or MB_OK);

        case FPedido.Cliente.Direcciones.RecordCount of
          0   : begin
                  FController.QuitarDireccionEnvio(FPedido);
                  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);
                  FPedido.Edit;
                  FPedido.IMPORTE_PORTE := 0;
                end;
          1   : begin
                  FController.CopiarDireccionEnvio(FPedido.Cliente.Direcciones, FPedido);
                  FPedido.Edit;
                  FPedido.IMPORTE_PORTE := FPedido.Cliente.Direcciones.PORTE;
                end
          else begin
            ADireccion := AClientesController.ElegirDireccionEntrega(FPedido.Cliente.Direcciones, '');
            try
              if Assigned(ADireccion) then
              begin
                FController.CopiarDireccionEnvio(ADireccion, FPedido);
                FPedido.Edit;
                FPedido.IMPORTE_PORTE := ADireccion.PORTE;
              end;
            finally
              ADireccion := NIL;
            end;
          end;
        end;

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

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

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

procedure TfEditorPedidoCliente.PonerTitulos(const ATitulo: string);
var
  FTitulo : String;
begin
  FTitulo := ATitulo;
  if (FTitulo = '') and Assigned(FPedido) then
  begin
    if FPedido.EsNuevo then
      FTitulo := 'Nuevo pedido de cliente'
    else
      FTitulo := 'Pedido de cliente'  + ' - ' + FPedido.Cliente.Nombre + ' - ' + FPedido.SITUACION;
  end;

  inherited PonerTitulos(FTitulo);

  Self.Caption := FTitulo + ' (' + dmUsuarios.EmpresaActual.NOMBRE + ')';
end;

procedure TfEditorPedidoCliente.PrevisualizarInterno;
begin
  inherited;
  if not Modified then
    FController.Preview(FPedido);
end;

procedure TfEditorPedidoCliente.SetController(const Value: IPedidosClienteController);
begin
  FController := Value;

  if Assigned(FController) then
  begin
    ViewPedido.ViewClientePedido.Controller := Controller.ClienteController;
    frViewDetallesPedidoCliente1.Controller := Controller.DetallesController;
  end;
end;

procedure TfEditorPedidoCliente.SetPedido(const Value: IBizPedidoCliente);
begin
  FPedido := Value;

  if Assigned(FPedido) then
  begin
    dsDataTable.DataTable := FPedido.DataTable;
    frViewIncidenciasCli.DADataSource.DataTable := dsDataTable.DataTable;
    frViewTotales1.DADataSource.DataTable := dsDataTable.DataTable;
    if Assigned(FViewPedido) then
    begin
      FViewPedido.Pedido := FPedido;
      ViewPedido.ViewClientePedido.Cliente := FPedido.Cliente;
      ViewPedido.ViewClientePedido.OnClienteChanged := OnClienteChanged;
      frViewDetallesPedidoCliente1.Detalles := FPedido.Detalles;
      frViewDetallesPedidoCliente1.Pedido := FPedido; //Para poder sacar los descuento del articulos segun el cliente seleccionado
    end;
  end;
end;

procedure TfEditorPedidoCliente.SetViewPedido(const Value: IViewPedidoCliente);
begin
  FViewPedido := Value;

  if Assigned(FViewPedido) and Assigned(Pedido) then
    FViewPedido.Pedido := Pedido;
end;

end.
