unit uBizFacturasProveedor;

interface

uses
  uDAInterfaces, uDADataTable, schFacturasProveedorClient_Intf,
  uBizContactos, uBizDetallesFacturaProveedor, uBizPedidosFacturaProveedor,
  uDBSelectionListUtils, Classes;

const
  BIZ_CLIENT_FACTURA_PROVEEDOR = 'Client.FacturaProveedor';

  CTE_TIPO_ABONO = 'A';
  CTE_TIPO_FACTURA = 'F';

  CTE_PENDIENTE = 'PENDIENTE';
  CTE_PARCIAMENTE_PAGADA = 'PARCIALMENTE PAGADA';
  CTE_PAGADA = 'PAGADA';

type
  IBizFacturaProveedor = interface(IFacturasProveedor)
  ['{4BC473E5-3B82-4C1A-8E52-2A227490F94E}']

    procedure SetProveedor(AValue : IBizProveedor);
    function GetProveedor : IBizProveedor;
    property Proveedor : IBizProveedor read GetProveedor write SetProveedor;

    // Esta propidad es para que el controlador pueda acceder directamente
    // a la propiedad Proveedor
    procedure _SetProveedor(AValue : IBizProveedor);
    function _GetProveedor : IBizProveedor;
    property _Proveedor : IBizProveedor read _GetProveedor write _SetProveedor;

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

    function GetPedidos: IBizPedidosFacturaProveedor;
    procedure SetPedidos(Value: IBizPedidosFacturaProveedor);
    property Pedidos: IBizPedidosFacturaProveedor read GetPedidos write SetPedidos;

		function EsNuevo : Boolean;
    procedure CalcularImporteTotal;
  end;

  TBizFacturaProveedor = class(TFacturasProveedorDataTableRules, IBizFacturaProveedor, ISeleccionable)
  private
    FSeleccionableInterface : ISeleccionable;
    procedure CalcularDescuento;
    procedure CalcularIVA;
    procedure CalcularRE;
    procedure CalcularBaseImponible;
    procedure AsignarTipoIVA (IDTipoIVA : Integer);
  protected
    FProveedor : IBizProveedor;
    FDetalles : IBizDetallesFacturaProveedor;
    FDetallesLink : TDADataSource;
    FPedidos: IBizPedidosFacturaProveedor;
    FPedidosLink : TDADataSource;

    procedure SetProveedor(AValue : IBizProveedor);
    function GetProveedor : IBizProveedor;

    procedure _SetProveedor(AValue : IBizProveedor);
    function _GetProveedor : IBizProveedor;

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

    function GetPedidos: IBizPedidosFacturaProveedor;
    procedure SetPedidos(Value: IBizPedidosFacturaProveedor);

    procedure RECARGO_EQUIVALENCIAOnChange(Sender: TDACustomField);
    procedure ID_TIPO_IVAOnChange(Sender: TDACustomField);

    procedure IMPORTE_NETOOnChange(Sender: TDACustomField);
    procedure IMPORTE_PORTEOnChange(Sender: TDACustomField);
    procedure DESCUENTOOnChange(Sender: TDACustomField);
    procedure IVAOnChange(Sender: TDACustomField);
    procedure REOnChange(Sender: TDACustomField);

    procedure OnNewRecord(Sender: TDADataTable); override;

  public
		function EsNuevo : Boolean;
    procedure IniciarValoresFacturaNueva;
    procedure CalcularImporteTotal;

    property Proveedor : IBizProveedor read GetProveedor write SetProveedor;
    property _Proveedor : IBizProveedor read _GetProveedor write _SetProveedor;
    property Detalles: IBizDetallesFacturaProveedor read GetDetalles write SetDetalles;
    property Pedidos: IBizPedidosFacturaProveedor read GetPedidos write SetPedidos;

    property SeleccionableInterface : ISeleccionable read FSeleccionableInterface
        write FSeleccionableInterface implements ISeleccionable;

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

implementation

uses
  SysUtils, uDataTableUtils, DB, uDateUtils, DateUtils, uDataModuleUsuarios,
  Variants, cxDateUtils, uTiposIVAController, uBizTiposIVA, uFactuGES_App;

{ TBizFacturaProveedor }

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

procedure TBizFacturaProveedor.AsignarTipoIVA(IDTipoIVA: Integer);
var
  ATiposIVAController : ITiposIVAController;
  ATipoIVA : IBizTipoIVA;
begin
  inherited;

  ATiposIVAController := TTiposIVAController.Create;
  try
    ATipoIVA := ATiposIVAController.Buscar(IDTipoIVA);
    ATipoIVA.DataTable.Active := True;
    if Assigned(ATipoIVA) then
    begin
      Edit;
      IVA := ATipoIVA.IVA;
      if (RECARGO_EQUIVALENCIA = 1) then
        RE := ATipoIVA.RE
      else
        RE := 0;
    end;
  finally
    ATiposIVAController := NIL;
  end;
end;

procedure TBizFacturaProveedor.CalcularBaseImponible;
begin
  if not Self.DataTable.Editing then
    Edit;
  IMPORTE_DESCUENTO := IMPORTE_NETO * (DESCUENTO/100);
  BASE_IMPONIBLE := IMPORTE_NETO - IMPORTE_DESCUENTO; // + IMPORTE_PORTE; ya no se tiene en cuenta porque se desglosa por artículo
end;

procedure TBizFacturaProveedor.CalcularDescuento;
begin
  if not Self.DataTable.Editing then
    Edit;
  IMPORTE_DESCUENTO := (DESCUENTO / 100) * BASE_IMPONIBLE;
end;

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

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

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

procedure TBizFacturaProveedor.CalcularRE;
begin
  if not Self.DataTable.Editing then
    Edit;
  IMPORTE_RE := (RE / 100) * (BASE_IMPONIBLE - IMPORTE_DESCUENTO);
end;

constructor TBizFacturaProveedor.Create(aDataTable: TDADataTable);
begin
  inherited;
  FProveedor := Nil;

  with DataTable do
  begin
    FieldByName(fld_FacturasProveedorID_TIPO_IVA).OnChange := ID_TIPO_IVAOnChange;
    FieldByName(fld_FacturasProveedorRECARGO_EQUIVALENCIA).OnChange := RECARGO_EQUIVALENCIAOnChange;

    FieldByName(fld_FacturasProveedorIMPORTE_NETO).OnChange := IMPORTE_NETOOnChange;
    FieldByName(fld_FacturasProveedorIMPORTE_PORTE).OnChange := IMPORTE_PORTEOnChange;
    FieldByName(fld_FacturasProveedorDESCUENTO).OnChange := DESCUENTOOnChange;
    FieldByName(fld_FacturasProveedorIVA).OnChange := IVAOnChange;
    FieldByName(fld_FacturasProveedorRE).OnChange := REOnChange;
  end;

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

  FPedidosLink := TDADataSource.Create(NIL);
  FPedidosLink.DataTable := aDataTable;

  FSeleccionableInterface := TSeleccionable.Create(aDataTable);
end;

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

destructor TBizFacturaProveedor.Destroy;
begin
  FProveedor := NIL;
  FDetalles := NIL;
  FDetallesLink.Free;
  FPedidos := NIL;
  FPedidosLink.Free;

  FSeleccionableInterface := NIL;
  inherited;
end;

function TBizFacturaProveedor.GetPedidos: IBizPedidosFacturaProveedor;
begin
  Result := FPedidos;
end;

function TBizFacturaProveedor.GetProveedor: IBizProveedor;
begin
  Result := FProveedor;
end;

function TBizFacturaProveedor.GetDetalles: IBizDetallesFacturaProveedor;
begin
  Result := FDetalles;
end;

procedure TBizFacturaProveedor.ID_TIPO_IVAOnChange(Sender: TDACustomField);
begin
  AsignarTipoIVA(ID_TIPO_IVA);
end;

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

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

procedure TBizFacturaProveedor.IniciarValoresFacturaNueva;
begin
  ID_EMPRESA := AppFactuGES.EmpresaActiva.ID;
  USUARIO := AppFactuGES.UsuarioActivo.UserName;
  FECHA_FACTURA := DateOf(Now);
  FECHA_VENCIMIENTO := DateOf(Now);
  ID_PROVEEDOR := ID_NULO;
  TIPO := CTE_TIPO_FACTURA;  
  ID_FORMA_PAGO := AppFactuGES.EmpresaActiva.ID_FORMA_PAGO;
  ID_TIPO_IVA := AppFactuGES.EmpresaActiva.ID_TIPO_IVA;
  RE := 0;
  SITUACION := CTE_PENDIENTE;  
end;

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

procedure TBizFacturaProveedor.OnNewRecord(Sender: TDADataTable);
begin
  inherited;
  IniciarValoresFacturaNueva;
end;

procedure TBizFacturaProveedor.RECARGO_EQUIVALENCIAOnChange(
  Sender: TDACustomField);
begin
  AsignarTipoIVA(ID_TIPO_IVA);
end;

procedure TBizFacturaProveedor.REOnChange(Sender: TDACustomField);
begin
  CalcularImporteTotal;
end;

procedure TBizFacturaProveedor.SetPedidos(Value: IBizPedidosFacturaProveedor);
begin
  FPedidos := Value;
  EnlazarMaestroDetalle(FPedidosLink, FPedidos);
end;

procedure TBizFacturaProveedor.SetProveedor(AValue: IBizProveedor);
var
  bEnEdicion : Boolean;
begin
  FProveedor := AValue;

  bEnEdicion := (DataTable.State in dsEditModes);
  if not bEnEdicion then
    Edit;

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

    ID_Proveedor := FProveedor.ID;
    NOMBRE := FProveedor.NOMBRE;
    NIF_CIF := FProveedor.NIF_CIF;
    CALLE := FProveedor.CALLE;
    CODIGO_POSTAL := FProveedor.CODIGO_POSTAL;
    PROVINCIA := FProveedor.PROVINCIA;
    POBLACION := FProveedor.POBLACION;
    if FProveedor.ID_FORMA_PAGO > 0 then
       ID_FORMA_PAGO := FProveedor.ID_FORMA_PAGO;
    if FProveedor.ID_TIPO_IVA > 0 then
       ID_TIPO_IVA := FProveedor.ID_TIPO_IVA;
//    RECARGO_EQUIVALENCIA := FProveedor.RECARGO_EQUIVALENCIA;
    Post;

    if bEnEdicion then
      Edit;
  end
end;

procedure TBizFacturaProveedor.SetDetalles(Value: IBizDetallesFacturaProveedor);
begin
  FDetalles := Value;
  EnlazarMaestroDetalle(FDetallesLink, FDetalles);
end;

function TBizFacturaProveedor._GetProveedor: IBizProveedor;
begin
  Result := FProveedor;
end;

procedure TBizFacturaProveedor._SetProveedor(AValue: IBizProveedor);
begin
  FProveedor := AValue;
end;

initialization
  RegisterDataTableRules(BIZ_CLIENT_FACTURA_PROVEEDOR, TBizFacturaProveedor);

finalization

end.
