unit uBizPedidosCliente;

interface

uses
  Classes, uDADataTable, uDAInterfaces, uROClasses,
  schPedidosClienteClient_Intf, uDBSelectionListUtils,
  uBizContactos, uBizDetallesPedidoCliente;

const
  BIZ_CLIENT_PEDIDO_CLIENTE = 'Client.PedidoCliente';
  BIZ_CLIENT_PEDIDO_CLIENTE_ARTICULOS_PENDIENTES_PEDIR_A_PROV = 'Client.PedidoClienteArticulosPendientesPedirAProv';

  SITUACION_PEDIDO_PENDIENTE = 'PENDIENTE';
  SITUACION_PEDIDO_ENPROCESO = 'EN PROCESO';
  SITUACION_PEDIDO_SERVIDO = 'SERVIDO';

type
  IBizPedidoCliente = interface(IPedidosCliente)
  ['{86A2FAD7-D125-47C2-B0BA-52A42FDFA6F6}']

    procedure SetCliente(AValue : IBizCliente);
    function GetCliente : IBizCliente;
    property Cliente : IBizCliente read GetCliente write SetCliente;

    // Esta propidad es para que el controlador pueda acceder directamente
    // a la propiedad Cliente
    procedure _SetCliente(AValue : IBizCliente);
    function _GetCliente : IBizCliente;
    property _Cliente : IBizCliente read _GetCliente write _SetCliente;

    function GetDetalles: IBizDetallesPedidoCliente;
    procedure SetDetalles(Value: IBizDetallesPedidoCliente);
    property Detalles: IBizDetallesPedidoCliente read GetDetalles write SetDetalles;

    procedure CalcularImporteTotal;

    function EsNuevo : Boolean;
    function DarListaSituaciones: TStringList;
  end;

  IBizPedidoClienteArticulosPendientesPedirAProv = interface(IPedidoCliente_ArticulosPendientesPedirAProv)
    ['{00537EF7-363E-4A50-BA03-1C0B79D17D31}']
  end;


  TBizPedidoCliente = class(TPedidosClienteDataTableRules, IBizPedidoCliente, ISeleccionable)
  private
    procedure CalcularBaseImponible;
    procedure CalcularIVA;
  protected
    FSeleccionableInterface : ISeleccionable;
    FCliente : IBizCliente;
    FDetalles : IBizDetallesPedidoCliente;
    FDetallesLink : TDADataSource;

    procedure SetCliente(AValue : IBizCliente);
    function GetCliente : IBizCliente;

    procedure _SetCliente(AValue : IBizCliente);
    function _GetCliente : IBizCliente;

    function GetDetalles: IBizDetallesPedidoCliente;
    procedure SetDetalles(Value: IBizDetallesPedidoCliente);

    procedure SetFECHA_PEDIDOValue(const aValue: TDateTime); override;
    procedure SetFECHA_PREVISTA_ENVIOValue(const aValue: DateTime); override;
    procedure SetINCIDENCIASValue(const aValue: IROStrings); override;
    procedure SetID_FORMA_PAGOValue(const aValue: Integer); override;

    procedure OnNewRecord(Sender: TDADataTable); override;
    procedure IniciarValoresPedidoNuevo;

    procedure IMPORTE_NETOOnChange(Sender: TDACustomField);
    procedure IMPORTE_PORTEOnChange(Sender: TDACustomField);
    procedure DESCUENTOOnChange(Sender: TDACustomField);
    procedure IVAOnChange(Sender: TDACustomField);
  public
    function DarListaSituaciones: TStringList;
    function EsNuevo : Boolean;
    procedure CalcularImporteTotal;
    property Cliente : IBizCliente read GetCliente write SetCliente;
    property _Cliente : IBizCliente read _GetCliente write _SetCliente;

    property Detalles: IBizDetallesPedidoCliente read GetDetalles write SetDetalles;

    property SeleccionableInterface : ISeleccionable read FSeleccionableInterface
        write FSeleccionableInterface implements ISeleccionable;

    constructor Create(aDataTable: TDADataTable); override;
    destructor Destroy; override;
  end;

  TBizPedidoClienteArticulosPendientesPedirAProv = class(TPedidoCliente_ArticulosPendientesPedirAProvDataTableRules, IBizPedidoClienteArticulosPendientesPedirAProv)
  end;


implementation

uses
  SysUtils, Variants, uDataModuleConfiguracion, uDataModuleUsuarios,
  uDataTableUtils, DateUtils, uDateUtils, DB;

{ TBizPedidoCliente }

procedure TBizPedidoCliente.CalcularBaseImponible;
begin
  if not Self.DataTable.Editing then
    Edit;
  IMPORTE_DESCUENTO := IMPORTE_NETO * (DESCUENTO/100);
  BASE_IMPONIBLE := IMPORTE_NETO - IMPORTE_DESCUENTO + IMPORTE_PORTE;
end;

procedure TBizPedidoCliente.CalcularImporteTotal;
begin
  DataTable.DisableControls;
  DataTable.Fields.FieldEventsDisabled := True;
  try
    CalcularBaseImponible;
    CalcularIVA;

    if not Self.DataTable.Editing then
      Edit;
    IMPORTE_TOTAL := BASE_IMPONIBLE + IMPORTE_IVA;
  finally
    DataTable.Fields.FieldEventsDisabled := False;
    DataTable.EnableControls;
  end;
end;

procedure TBizPedidoCliente.CalcularIVA;
begin
  if not Self.DataTable.Editing then
    Edit;
  IMPORTE_IVA := (IVA / 100) * (BASE_IMPONIBLE);
end;

constructor TBizPedidoCliente.Create(aDataTable: TDADataTable);
begin
  inherited;
  FCliente := Nil;

  with DataTable do
  begin
    FieldByName(fld_PedidosClienteIMPORTE_NETO).OnChange := IMPORTE_NETOOnChange;
    FieldByName(fld_PedidosClienteIMPORTE_PORTE).OnChange := IMPORTE_PORTEOnChange;
    FieldByName(fld_PedidosClienteDESCUENTO).OnChange := DESCUENTOOnChange;
    FieldByName(fld_PedidosClienteIVA).OnChange := IVAOnChange;
  end;

  FDetallesLink := TDADataSource.Create(NIL);
  FDetallesLink.DataTable := aDataTable;
  
  FSeleccionableInterface := TSeleccionable.Create(aDataTable);
end;

function TBizPedidoCliente.DarListaSituaciones: TStringList;
begin
  Result := TStringList.Create;
  with Result do
  begin
    Add(SITUACION_PEDIDO_PENDIENTE);
    Add(SITUACION_PEDIDO_ENPROCESO);
    Add(SITUACION_PEDIDO_SERVIDO);
  end;
end;

procedure TBizPedidoCliente.DESCUENTOOnChange(Sender: TDACustomField);
begin
  CalcularImporteTotal;
end;

destructor TBizPedidoCliente.Destroy;
begin
  FCliente := NIL;
  FDetalles := NIL;
  FDetallesLink.Free;
  
  FSeleccionableInterface := NIL;
  inherited;
end;

function TBizPedidoCliente.EsNuevo: Boolean;
begin
  Result := (ID < 0);
end;

function TBizPedidoCliente.GetCliente: IBizCliente;
begin
  Result := FCliente;
end;

procedure TBizPedidoCliente.IMPORTE_NETOOnChange(Sender: TDACustomField);
begin
  CalcularImporteTotal;
end;

procedure TBizPedidoCliente.IMPORTE_PORTEOnChange(Sender: TDACustomField);
begin
  CalcularImporteTotal;
end;

procedure TBizPedidoCliente.IniciarValoresPedidoNuevo;
begin
  ID_EMPRESA := dmUsuarios.IDEmpresaActual;
  USUARIO := dmUsuarios.LoginInfo.Usuario;
  FECHA_PEDIDO := DateOf(Date);
  FECHA_PREVISTA_ENVIO := 0;
  INCIDENCIAS_ACTIVAS := 0;
  INCIDENCIAS := NIL;  
  REFERENCIA := '';
  SetFieldNull(DataTable, fld_PedidosClienteREF_TIENDA_WEB);
  SITUACION := SITUACION_PEDIDO_PENDIENTE;
end;

procedure TBizPedidoCliente.IVAOnChange(Sender: TDACustomField);
begin
  CalcularImporteTotal;
end;

function TBizPedidoCliente.GetDetalles: IBizDetallesPedidoCliente;
begin
  Result := FDetalles;
end;

procedure TBizPedidoCliente.OnNewRecord(Sender: TDADataTable);
begin
  inherited;
  ID := GetRecNo; // -1, -2, -3...
  IniciarValoresPedidoNuevo;
end;

procedure TBizPedidoCliente.SetCliente(AValue: IBizCliente);
var
  bEnEdicion : Boolean;

begin
  FCliente := AValue;

  if Assigned(FCliente) then
  begin
    if not FCliente.DataTable.Active then
      FCliente.DataTable.Active := True;

    if ID_Cliente <> FCliente.ID then
    begin
      bEnEdicion := (DataTable.State in dsEditModes);
      if not bEnEdicion then
         DataTable.Edit;

      ID_CLIENTE := FCliente.ID;
      ID_FORMA_PAGO := FCliente.ID_FORMA_PAGO;

      DataTable.Post;  //Muy importante ya que es necesario hacer un post de la cabecera antes de aņadir detalles
                       //si se quita el id de la cabecera y los detalles se desincroniza
      if bEnEdicion then
         DataTable.Edit;
    end;
  end;
end;

procedure TBizPedidoCliente.SetDetalles(Value: IBizDetallesPedidoCliente);
begin
  FDetalles := Value;
  EnlazarMaestroDetalle(FDetallesLink, FDetalles);
end;

procedure TBizPedidoCliente.SetFECHA_PEDIDOValue(const aValue: TDateTime);
begin
  if EsFechaVacia(aValue) then
     SetFieldNull(DataTable, fld_PedidosClienteFECHA_PEDIDO)
  else
    inherited;
end;

procedure TBizPedidoCliente.SetFECHA_PREVISTA_ENVIOValue(
  const aValue: DateTime);
begin
  if EsFechaVacia(aValue) then
     SetFieldNull(DataTable, fld_PedidosClienteFECHA_PREVISTA_ENVIO)
  else
    inherited;
end;

procedure TBizPedidoCliente.SetID_FORMA_PAGOValue(const aValue: Integer);
begin
  if (aValue = 0) then
    SetFieldNull(DataTable, fld_PedidosClienteID_FORMA_PAGO)
  else
    inherited;
end;

procedure TBizPedidoCliente.SetINCIDENCIASValue(const aValue: IROStrings);
begin
  if not Assigned(aValue) then
    SetFieldNull(DataTable, fld_PedidosClienteINCIDENCIAS)
  else
    inherited;
end;

function TBizPedidoCliente._GetCliente: IBizCliente;
begin
  Result := FCliente;
end;

procedure TBizPedidoCliente._SetCliente(AValue: IBizCliente);
begin
  FCliente := AValue;
end;

initialization
  RegisterDataTableRules(BIZ_CLIENT_PEDIDO_CLIENTE, TBizPedidoCliente);
  RegisterDataTableRules(BIZ_CLIENT_PEDIDO_CLIENTE_ARTICULOS_PENDIENTES_PEDIR_A_PROV, TBizPedidoClienteArticulosPendientesPedirAProv);
  
finalization

end.

