unit uBizContratosCliente;

interface

uses
  Classes, uDADataTable, uDAInterfaces, uROClasses,
  schContratosClienteClient_Intf, uDBSelectionListUtils,
  uBizContactos, uBizDetallesContratoCliente;

const
  BIZ_CLIENT_CONTRATO_CLIENTE = 'Client.ContratoCliente';
  BIZ_CLIENT_CONTRATOS_CLIENTE_BENEFICIOS = 'Client.ContratosClienteBeneficios';

  SITUACION_CONTRATO_PENDIENTE = 'PENDIENTE';
  SITUACION_CONTRATO_ACEPTADO = 'ACEPTADO';
  SITUACION_CONTRATO_RECHAZADO = 'RECHAZADO';

  CTE_TamLetraIni = 8;
  CTE_TamLetraMin = 5;
  CTE_TamLetraMax = 16;
  CTE_Aumento = 1;


type

  IBizContratoCliente = interface(IContratosCliente)
  ['{3C12014E-6AD6-45BC-A87B-D818EDAB14C8}']

    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: IBizDetallesContratoCliente;
    procedure SetDetalles(Value: IBizDetallesContratoCliente);
    property Detalles: IBizDetallesContratoCliente read GetDetalles write SetDetalles;

    procedure CalcularImporteTotal;
    procedure AsignarVendedor;

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

  IBizContratosClienteBeneficios = interface(IContratosClienteBeneficios)
  ['{ABB58720-9FD2-4E85-AEAA-4E7DAA1E6223}']
  end;

  TBizContratoCliente = class(TContratosClienteDataTableRules, IBizContratoCliente, ISeleccionable)
  private
    procedure CalcularBaseImponible;
    procedure CalcularIVA;
    procedure CalcularRE;
    procedure AsignarTipoIVA (IDTipoIVA : Integer);

  protected
    FSeleccionableInterface : ISeleccionable;
    FCliente : IBizCliente;
    FDetalles : IBizDetallesContratoCliente;
    FDetallesLink : TDADataSource;

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

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

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

    function GetSITUACIONValue: String; override;
    procedure SetFECHA_CONTRATOValue(const aValue: TDateTime); override;
    procedure SetID_FORMA_PAGOValue(const aValue: Integer); override;

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

    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 SetID_TIPO_IVAValue(const aValue: Integer); override;

  public
    function DarListaSituaciones: TStringList;
    function EsNuevo : Boolean;
    procedure CalcularImporteTotal;
    procedure AsignarVendedor;
    property Cliente : IBizCliente read GetCliente write SetCliente;
    property _Cliente : IBizCliente read _GetCliente write _SetCliente;

    property Detalles: IBizDetallesContratoCliente read GetDetalles write SetDetalles;

    property SeleccionableInterface : ISeleccionable read FSeleccionableInterface
        write FSeleccionableInterface implements ISeleccionable;

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

  TBizContratosClienteBeneficios = class(TContratosClienteBeneficiosDataTableRules, IBizContratosClienteBeneficios)
  end;


implementation

uses
  SysUtils, Variants, uDataModuleConfiguracion, uDataModuleUsuarios, Dialogs,
  uDataTableUtils, DateUtils, uDateUtils, DB, uFactuGES_App, uTiposIVAController,
  uBizTiposIVA, uVendedoresController;

{ TBizContratoCliente }

procedure TBizContratoCliente.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 TBizContratoCliente.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 TBizContratoCliente.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 TBizContratoCliente.CalcularIVA;
begin
  if not Self.DataTable.Editing then
    Edit;
  IMPORTE_IVA := (IVA / 100) * (BASE_IMPONIBLE);
end;

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

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

  with DataTable do
  begin
    FieldByName(fld_ContratosClienteID_TIPO_IVA).OnChange := ID_TIPO_IVAOnChange;
    FieldByName(fld_ContratosClienteRECARGO_EQUIVALENCIA).OnChange := RECARGO_EQUIVALENCIAOnChange;

    FieldByName(fld_ContratosClienteIMPORTE_NETO).OnChange := IMPORTE_NETOOnChange;
    FieldByName(fld_ContratosClienteIMPORTE_PORTE).OnChange := IMPORTE_PORTEOnChange;
    FieldByName(fld_ContratosClienteDESCUENTO).OnChange := DESCUENTOOnChange;
    FieldByName(fld_ContratosClienteIVA).OnChange := IVAOnChange;
    FieldByName(fld_ContratosClienteRE).OnChange := REOnChange;
  end;

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

function TBizContratoCliente.DarListaSituaciones: TStringList;
begin
  Result := TStringList.Create;
  with Result do
  begin
    Add(SITUACION_CONTRATO_PENDIENTE);
    Add(SITUACION_CONTRATO_ACEPTADO);
    Add(SITUACION_CONTRATO_RECHAZADO);
  end;
end;

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

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

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

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

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

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

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

procedure TBizContratoCliente.IniciarValoresContratoNuevo;
begin
  ID_EMPRESA := AppFactuGES.EmpresaActiva.ID;
  USUARIO := AppFactuGES.UsuarioActivo.UserName;
  ID_FORMA_PAGO := AppFactuGES.EmpresaActiva.ID_FORMA_PAGO;
  ID_TIPO_IVA := AppFactuGES.EmpresaActiva.ID_TIPO_IVA;

  FECHA_CONTRATO := DateOf(Date);
  FECHA_ULT_PRESENTACION_CLIENTE := DateOf(Date);  

  INCIDENCIAS_ACTIVAS := 0;
  RE := 0;
  REFERENCIA := '';
  SITUACION := SITUACION_CONTRATO_PENDIENTE;

  ID_TIENDA := AppFactuGES.TiendaActiva.ID;
  TIENDA := AppFactuGES.TiendaActiva.NOMBRE;

//  Self.DataTable.FieldByName(fld_ContratosClienteFORMA_PAGO).AsString := AppFactuGES.FormaPagoDocumentos;
  Self.DataTable.FieldByName(fld_ContratosClienteOBSERVACIONES).AsString := AppFactuGES.ObservacionesDocumentos;
  Self.DataTable.FieldByName(fld_ContratosClienteCONDICIONES).AsString := AppFactuGES.CondicionesDocumentos;

  AsignarVendedor;  
end;

procedure TBizContratoCliente.AsignarVendedor;
var
  AVendedoresController: IVendedoresController;
begin
  AVendedoresController := TVendedoresController.Create;
  try
    ID_VENDEDOR := AVendedoresController.DarIDVendedorDeUsuario(AppFactuGES.UsuarioActivo.ID);
  finally
    AVendedoresController := nil;
  end;
end;


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

function TBizContratoCliente.GetDetalles: IBizDetallesContratoCliente;
begin
  Result := FDetalles;
end;

function TBizContratoCliente.GetSITUACIONValue: String;
begin
  result := Trim(DataTable.Fields[idx_ContratosClienteSITUACION].AsString);
end;

procedure TBizContratoCliente.OnNewRecord(Sender: TDADataTable);
begin
  inherited;
  IniciarValoresContratoNuevo;
end;

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

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

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

begin
  FCliente := AValue;

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

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

    ID_CLIENTE := FCliente.ID;
    NOMBRE := FCliente.NOMBRE;
    NIF_CIF := FCliente.NIF_CIF;
    CALLE := FCliente.CALLE;
    CODIGO_POSTAL := FCliente.CODIGO_POSTAL;
    PROVINCIA := FCliente.PROVINCIA;
    POBLACION := FCliente.POBLACION;
    TELEFONO := FCliente.TELEFONO_1;
    MOVIL := FCliente.MOVIL_1;

//En alonso y sal no se coge la forma de pago ni el iva del contacto sino de la empresa
//    if FCliente.ID_FORMA_PAGO > 0 then
//       ID_FORMA_PAGO := FCliente.ID_FORMA_PAGO;
//    if FCliente.ID_TIPO_IVA > 0 then
//       ID_TIPO_IVA := FCliente.ID_TIPO_IVA;
//    RECARGO_EQUIVALENCIA := FCliente.RECARGO_EQUIVALENCIA;

// En acana la ficha de cliente no tiene descuento aplicado por defecto
//      DESCUENTO := FCliente.DESCUENTO;

    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;

procedure TBizContratoCliente.SetDetalles(Value: IBizDetallesContratoCliente);
begin
  FDetalles := Value;
  EnlazarMaestroDetalle(FDetallesLink, FDetalles);
end;

procedure TBizContratoCliente.SetFECHA_CONTRATOValue(const aValue: TDateTime);
begin
  if EsFechaVacia(aValue) then
     SetFieldNull(DataTable, fld_ContratosClienteFECHA_CONTRATO)
  else
    inherited;
end;

procedure TBizContratoCliente.SetID_FORMA_PAGOValue(const aValue: Integer);
begin
  if (aValue = 0) then
    SetFieldNull(DataTable, fld_ContratosClienteID_FORMA_PAGO)
  else
    inherited;
end;
procedure TBizContratoCliente.SetID_TIPO_IVAValue(const aValue: Integer);
begin
  if (aValue = 0) then
    SetFieldNull(DataTable, fld_ContratosClienteID_TIPO_IVA)
  else
    inherited;
end;

{
procedure TBizContratoCliente.SetINCIDENCIASValue(const aValue: IROStrings);
begin
  if not Assigned(aValue) then
    SetFieldNull(DataTable, fld_ContratosClienteINCIDENCIAS)
  else
    inherited;
end;
}
function TBizContratoCliente._GetCliente: IBizCliente;
begin
  Result := FCliente;
end;

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

initialization
  RegisterDataTableRules(BIZ_CLIENT_CONTRATO_CLIENTE, TBizContratoCliente);
  RegisterDataTableRules(BIZ_CLIENT_CONTRATOS_CLIENTE_BENEFICIOS, TBizContratosClienteBeneficios);

finalization

end.

