unit uEditorFacturaCliente;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uEditorDBItem, DB, uDADataTable, JvAppStorage,
  JvAppRegistryStorage, JvComponent, JvFormPlacement, ImgList,
  PngImageList, StdActns, ActnList, ComCtrls, TBX, TB2Item, TB2Dock,
  TB2Toolbar, ExtCtrls, JvExControls, JvNavigationPane, 
  uViewFacturaCliente, uCustomView, uViewBase, uViewTotales,
  StdCtrls, pngimage, AppEvnts, JvComponentBase,
  uBizFacturasCliente,


  uIEditorFacturaCliente, uFacturasClienteController, uViewDetallesBase,
  uViewDetallesFacturaCliente, dxLayoutLookAndFeels, JvExComCtrls, JvStatusBar,
  uViewDetallesDTO, uViewDetallesArticulos, uTiposIVAController;


type
  TfEditorFacturaCliente = class(TfEditorDBItem, IEditorFacturaCliente)
    frViewDetallesFacturaCliente1: TfrViewDetallesFacturaCliente;
    frViewFacturaCliente1: TfrViewFacturaCliente;
    frViewTotales1: TfrViewTotales;
    procedure FormShow(Sender: TObject);
    procedure frViewClienteFactura1edtlNombrePropertiesEditValueChanged(
      Sender: TObject);
    procedure dsDataTableDataChange(Sender: TObject; Field: TField);
    procedure CustomEditorClose(Sender: TObject; var Action: TCloseAction);
    procedure frViewClienteFacturaedtlNombrePropertiesChange(Sender: TObject);
    procedure pgPaginasChanging(Sender: TObject; var AllowChange: Boolean);
    procedure frViewTotales1edtDescuentoPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
    procedure frViewTotales1bTiposIVAClick(Sender: TObject);
    procedure frViewTotales1eIVAPropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
    procedure frViewTotales1cbRecargoEquivalenciaPropertiesEditValueChanged(
      Sender: TObject);
    procedure frViewTotales1ePortePropertiesValidate(Sender: TObject;
      var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);

  protected
    FController : IFacturasClienteController;
    FFactura: IBizFacturaCliente;
    FViewFactura: IViewFacturaCliente;
    FTiposIVAController : ITiposIVAController;
    function GetController : IFacturasClienteController;
    procedure SetController (const Value : IFacturasClienteController);
    function GetFactura: IBizFacturaCliente;
    procedure SetFactura(const Value: IBizFacturaCliente);

    function GetViewFactura: IViewFacturaCliente;
    procedure SetViewFactura(const Value: IViewFacturaCliente);

    property ViewFacturaCliente: IViewFacturaCliente read GetViewFactura write SetViewFactura;

    procedure OnClienteChanged(Sender: TObject);

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

    procedure PonerTitulos(const ATitulo: string = ''); override;
  public
    destructor Destroy; override;
    property Controller : IFacturasClienteController read GetController write SetController;
    property Factura: IBizFacturaCliente read GetFactura write SetFactura;
    constructor Create(AOwner: TComponent); override;
  end;

implementation
{$R *.dfm}

uses
  cxDBEdit, uBizContactos, uDataModuleUsuarios, cxControls, uBizTiposIVA,
  uDetallesFacturaClienteController, uDialogUtils, uDataTableUtils,
  uGenerarAlbaranesCliFacCliUtils;


{ TfEditorFacturaCliente }

{
**************************** TfEditorFacturaCliente ****************************
}
constructor TfEditorFacturaCliente.Create(AOwner: TComponent);
begin
  inherited;
  pgPaginas.ActivePageIndex := 0;
  ViewFacturaCliente := frViewFacturaCliente1;
  FTiposIVAController := TTiposIVAController.Create;    
end;

procedure TfEditorFacturaCliente.CustomEditorClose(Sender: TObject;
  var Action: TCloseAction);
begin
  inherited;
  dsDataTable.DataTable := NIL;
  frViewTotales1.DADataSource.DataTable := NIL;

  FViewFactura := NIL;
  FFactura := NIL;
end;

destructor TfEditorFacturaCliente.Destroy;
begin
  FTiposIVAController := NIL;
  inherited;
end;

procedure TfEditorFacturaCliente.dsDataTableDataChange(Sender: TObject;
  Field: TField);
begin
  inherited;
  if Assigned(FFactura) and (not (FFactura.DataTable.Fetching) or
    not (FFactura.DataTable.Opening) or not (FFactura.DataTable.Closing)) then
    PonerTitulos;
end;

procedure TfEditorFacturaCliente.EliminarInterno;
var
  ACadena : String;
begin
   if Factura.TIPO = CTE_TIPO_FACTURA then
      ACadena := '¿Desea borrar esta factura de cliente?'
   else
      ACadena := '¿Desea borrar este abono a cliente?';

  if (Application.MessageBox(PChar(ACadena), 'Atención', MB_YESNO) = IDYES) then
  begin
    FController.Eliminar(Factura);
    inherited;
  end;
end;

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

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

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

  Factura.DataTable.Active := True;
end;

procedure TfEditorFacturaCliente.frViewClienteFactura1edtlNombrePropertiesEditValueChanged(Sender: TObject);
begin
  inherited;
  with (Sender as TcxDBTextEdit) do
    Enabled := (FFactura.ID <> 0)
end;

procedure TfEditorFacturaCliente.frViewClienteFacturaedtlNombrePropertiesChange(
  Sender: TObject);
begin
  inherited;
  PonerTitulos;
end;

procedure TfEditorFacturaCliente.frViewTotales1bTiposIVAClick(Sender: TObject);
begin
  inherited;
  FTiposIVAController.VerTodos((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA);
end;

procedure TfEditorFacturaCliente.frViewTotales1cbRecargoEquivalenciaPropertiesEditValueChanged(
  Sender: TObject);
begin
  inherited;
{  if frViewTotales1.cbRecargoEquivalencia.Checked then
    Factura.RECARGO_EQUIVALENCIA := 1
  else
    Factura.RECARGO_EQUIVALENCIA := 0;}
end;

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

procedure TfEditorFacturaCliente.frViewTotales1eIVAPropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
begin
  inherited;
  Factura.Edit;
  Factura.ID_TIPO_IVA := ((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).ID;
end;

procedure TfEditorFacturaCliente.frViewTotales1ePortePropertiesValidate(
  Sender: TObject; var DisplayValue: Variant; var ErrorText: TCaption;
  var Error: Boolean);
begin
  inherited;
  Factura.IMPORTE_PORTE := DisplayValue;
end;

function TfEditorFacturaCliente.GetController: IFacturasClienteController;
begin
  Result := FController;
end;

function TfEditorFacturaCliente.GetFactura: IBizFacturaCliente;
begin
  Result := FFactura;
end;

function TfEditorFacturaCliente.GetViewFactura: IViewFacturaCliente;
begin
  Result := FViewFactura;
end;

procedure TfEditorFacturaCliente.GuardarInterno;
var
  bEsNuevo : Boolean;
begin
  inherited;
  
  ShowHourglassCursor;
  //frViewDetallesFacturaCliente1.SaveGridStatus; // Para guardar estado del grid
  frViewDetallesFacturaCliente1.BeginUpdate;  // Para que no se mueva el foco
  try
    bEsNuevo := FFactura.EsNuevo;
    FController.Guardar(FFactura);
  finally
    frViewDetallesFacturaCliente1.EndUpdate;
    //frViewDetallesFacturaCliente1.RestoreGridStatus;
    HideHourglassCursor;
  end;

  if bEsNuevo then
  begin
    if FFactura.TIPO = CTE_TIPO_FACTURA then
      ShowInfoMessage('La factura se ha dado de alta con el código ' + FFactura.REFERENCIA)
    else
    begin
      ShowInfoMessage('El abono se ha dado de alta con el código ' + FFactura.REFERENCIA);
      //Preguntamos is desea hacer una orden de devolución asociada
      if (Application.MessageBox('¿Desea crear una orden de devolución para el abono?', 'Atención', MB_YESNO) = IDYES) then
         GenerarAlbaranCli(FFactura);
    end;
  end;

  Modified := False;
end;

procedure TfEditorFacturaCliente.ImprimirInterno;
begin
  inherited;
  FController.Print(FFactura);
end;

procedure TfEditorFacturaCliente.OnClienteChanged(Sender: TObject);
var
  FDetallesController : IDetallesFacturaClienteController;
begin
  FFactura.Cliente := frViewFacturaCliente1.frViewClienteFactura.Cliente;

  // Actualizar IVA y RE a partir del tipo de IVA del cliente.
  Factura.IVA := ((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).IVA;
  if FFactura.Cliente.RECARGO_EQUIVALENCIA = 1 then
    Factura.RE := ((frViewTotales1.dsTiposIVA.DataTable) as IBizTipoIVA).RE
  else
    Factura.RE := 0;

  // Si la factura tiene detalles hay que mirar si los descuentos y otros campos
  // para los artículos hay que cambiarlos.
  if (FFactura.Detalles.RecordCount > 0) then
  begin
    FDetallesController := TDetallesFacturaClienteController.Create;
    try
      FDetallesController.ActualizarDetalles(FFactura.Detalles, FFactura.Cliente);
    finally
      FDetallesController := NIL;
    end;
  end;
end;

procedure TfEditorFacturaCliente.pgPaginasChanging(Sender: TObject;
  var AllowChange: Boolean);
var
  ACadena : String;
begin
  inherited;
  if (not Assigned(FFactura)) or (FFactura.ID_CLIENTE = ID_NULO) then
  begin
    if FFactura.TIPO = CTE_TIPO_FACTURA then
      ACadena := 'Antes debe elegir un cliente para esta factura'
    else
      ACadena := 'Antes debe elegir un cliente para este abono';
    ShowWarningMessage(ACadena);
    AllowChange := False;
  end;
end;

procedure TfEditorFacturaCliente.PonerTitulos(const ATitulo: string);
var
  FTitulo : String;
begin
  FTitulo := ATitulo;
  if (FTitulo = '') and Assigned(Factura) then
  begin
    if Factura.EsNuevo then
       if Factura.TIPO = CTE_TIPO_FACTURA then
          FTitulo := 'Nueva factura de cliente'
       else
          FTitulo := 'Nuevo abono a cliente'
    else
       if Factura.TIPO = CTE_TIPO_FACTURA then
          FTitulo := 'Factura de cliente'  + ' - ' + FFactura.Cliente.Nombre
       else
          FTitulo := 'Abono a cliente'  + ' - ' + FFactura.Cliente.Nombre       
  end;

  inherited PonerTitulos(FTitulo);

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

procedure TfEditorFacturaCliente.PrevisualizarInterno;
begin
  inherited;
  FController.Preview(FFactura);
end;

procedure TfEditorFacturaCliente.SetController(const Value: IFacturasClienteController);
begin
  FController := Value;

  if Assigned(FController) then
  begin
     frViewFacturaCliente1.frViewClienteFactura.Controller := Controller.ClienteController;
     frViewDetallesFacturaCliente1.Controller := Controller.DetallesController;
  end;
end;

procedure TfEditorFacturaCliente.SetFactura(const Value: IBizFacturaCliente);
begin
  FFactura := Value;

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

    frViewTotales1.dsTiposIVA.DataTable := FTiposIVAController.BuscarTodos.DataTable;
    frViewTotales1.dsTiposIVA.DataTable.Active := True;

    if Assigned(FViewFactura) then
    begin
      frViewFacturaCliente1.frViewClienteFactura.Cliente := FFactura.Cliente;
      frViewFacturaCliente1.frViewClienteFactura.OnClienteChanged := OnClienteChanged;

      FViewFactura.Factura := FFactura;
      frViewDetallesFacturaCliente1.Detalles := FFactura.Detalles;
      frViewDetallesFacturaCliente1.Factura := FFactura; //Para poder sacar los descuento del articulos segun el cliente seleccionado
    end;
  end
  else begin
    frViewFacturaCliente1.frViewClienteFactura.OnClienteChanged := NIL;
    frViewFacturaCliente1.frViewClienteFactura.Cliente := NIL;
    dsDataTable.DataTable := NIL;
    frViewTotales1.DADataSource.DataTable := NIL;
    frViewTotales1.dsTiposIVA.DataTable := NIL;
  end
end;

procedure TfEditorFacturaCliente.SetViewFactura(const Value: IViewFacturaCliente);
begin
  FViewFactura := Value;

  if Assigned(FViewFactura) and Assigned(Factura) then
    FViewFactura.Factura := Factura;
end;

end.
