unit uBizPresupuestos;

interface

uses
  uDAInterfaces, uDADataTable, schPresupuestosClient_Intf,
  uBizContactos, uBizDetallesPresupuesto, Classes, uDBSelectionListUtils;

const
  BIZ_CLIENT_PRESUPUESTO = 'Client.Presupuesto';

  SITUACION_PENDIENTE = 'Pendiente';
  SITUACION_ACEPTADO = 'Aceptado';
  SITUACION_RECHAZADO = 'Rechazado';

  DIAS_VIGENCIA = 30;

type
  IBizPresupuesto = interface(IPresupuestos)
  ['{7AD0B8F3-AD33-4311-9451-FC4500430D0C}']

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

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

    function GetFECHA_VIGENCIAValue: DateTime;
    property FECHA_VIGENCIA: DateTime read GetFECHA_VIGENCIAValue;

    function EsNuevo : Boolean;
    procedure CalcularImporteTotal;
    procedure IniciarValoresPresupuestoNuevo;

    function GetSelectedRecords: ISelectedRecords;
    property SelectedRecords : ISelectedRecords read GetSelectedRecords;

    function DarListaSituaciones: TStringList;
  end;

  TBizPresupuesto = class(TPresupuestosDataTableRules, IBizPresupuesto, ISelectedRecords)
  private
    function GetSelected: Boolean;
    procedure SetSelected(const Value: Boolean);

  protected
    FCliente : IBizCliente;
    FSelectedRecords : TSelectedRecords;

    FDetalles : IBizDetallesPresupuesto;
    FDetallesLink : TDADataSource;

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

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

    procedure OnNewRecord(Sender: TDADataTable); override;

    function GetFECHA_VIGENCIAValue: DateTime;
    procedure SetFECHA_DECISIONValue(const aValue: TDateTime); override;
    procedure SetFECHA_PRESUPUESTOValue(const aValue: TDateTime); override;
    procedure SetBASE_IMPONIBLEValue(const aValue: Double); override;
    procedure SetIVAValue(const aValue: Double); override;
    procedure SetDESCUENTOValue(const aValue: Double); override;
    procedure OnCalcFields(Sender: TDADataTable); override;
    procedure CalcularDescuento;
    procedure CalcularIVA;

  public
    function DarListaSituaciones: TStringList;
    procedure CalcularImporteTotal;
    procedure IniciarValoresPresupuestoNuevo;
    function EsNuevo : Boolean;
    function GetSelectedRecords: ISelectedRecords;
    property SelectedRecords : ISelectedRecords read GetSelectedRecords implements ISelectedRecords;
    property Selected : Boolean read GetSelected write SetSelected;
    property Cliente : IBizCliente read GetCliente write SetCliente;
    property Detalles: IBizDetallesPresupuesto read GetDetalles write SetDetalles;
    property FECHA_VIGENCIA: DateTime read GetFECHA_VIGENCIAValue;
    constructor Create(aDataTable: TDADataTable); override;
    destructor Destroy; override;
  end;

implementation

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

{ TBizPresupuesto }

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

procedure TBizPresupuesto.CalcularImporteTotal;
begin
  CalcularDescuento; //Importante orden
  CalcularIVA;

  if not DataTable.Editing then
    DataTable.Edit;
  IMPORTE_TOTAL := BASE_IMPONIBLE - IMPORTE_DESCUENTO + IMPORTE_IVA;
end;

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

constructor TBizPresupuesto.Create(aDataTable: TDADataTable);
begin
  inherited;
  FCliente := Nil;
  FSelectedRecords := TSelectedRecords.Create(aDataTable);

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

function TBizPresupuesto.DarListaSituaciones: TStringList;
begin
  Result := TStringList.Create;
  with Result do
  begin
    Add(SITUACION_PENDIENTE);
    Add(SITUACION_ACEPTADO);
    Add(SITUACION_RECHAZADO);
  end;
end;

destructor TBizPresupuesto.Destroy;
begin
  FCliente := NIL;
  FreeAndNIL(FSelectedRecords);

  FDetalles := NIL;
  FDetallesLink.Free;
  inherited;
end;

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

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

function TBizPresupuesto.GetDetalles: IBizDetallesPresupuesto;
begin
  Result := FDetalles;
end;

function TBizPresupuesto.GetFECHA_VIGENCIAValue: DateTime;
begin
  Result := DateUtils.IncDay(FECHA_PRESUPUESTO, VIGENCIA);
end;

function TBizPresupuesto.GetSelected: Boolean;
begin
  Result := FSelectedRecords.CurrentRowSelected;
end;

function TBizPresupuesto.GetSelectedRecords: ISelectedRecords;
begin
  Result := FSelectedRecords;
end;

procedure TBizPresupuesto.IniciarValoresPresupuestoNuevo;
begin
  ID_EMPRESA := dmUsuarios.IDEmpresaActual;
  ID_CLIENTE := ID_NULO;
//  ID_VENDEDOR := ID_NULO;
  USUARIO := dmUsuarios.LoginInfo.Usuario;
  FECHA_PRESUPUESTO := DateOf(Now);
  VIGENCIA := DIAS_VIGENCIA;
  SITUACION := SITUACION_PENDIENTE;
  FECHA_DECISION := 0;
end;

procedure TBizPresupuesto.OnCalcFields(Sender: TDADataTable);
begin
  inherited;
  FECHA_VALIDEZ := IncDay(FECHA_PRESUPUESTO, VIGENCIA);
end;

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

procedure TBizPresupuesto.SetBASE_IMPONIBLEValue(const aValue: Double);
begin
  inherited;
  CalcularImporteTotal;
end;

procedure TBizPresupuesto.SetCliente(AValue: IBizCliente);
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
      DataTable.Edit;
      ID_CLIENTE := FCliente.ID;
    end;
  end;
end;

procedure TBizPresupuesto.SetDESCUENTOValue(const aValue: Double);
begin
  inherited;
  CalcularImporteTotal;
end;

procedure TBizPresupuesto.SetDetalles(Value: IBizDetallesPresupuesto);
begin
  FDetalles := Value;
  EnlazarMaestroDetalle(FDetallesLink, FDetalles);
end;

procedure TBizPresupuesto.SetFECHA_DECISIONValue(const aValue: TDateTime);
begin
  if EsFechaVacia(aValue) then
    DataTable.Fields[idx_PresupuestosFECHA_DECISION].AsVariant := NULL
  else
    inherited;
end;

procedure TBizPresupuesto.SetFECHA_PRESUPUESTOValue(const aValue: TDateTime);
begin
  if EsFechaVacia(aValue) then
    DataTable.Fields[idx_PresupuestosFECHA_PRESUPUESTO].AsVariant := NULL
  else
    inherited;
end;

procedure TBizPresupuesto.SetIVAValue(const aValue: Double);
begin
  inherited;
  CalcularImporteTotal;
end;

procedure TBizPresupuesto.SetSelected(const Value: Boolean);
begin
  FSelectedRecords.CurrentRowSelected := True;
end;

initialization
  RegisterDataTableRules(BIZ_CLIENT_PRESUPUESTO, TBizPresupuesto);

finalization

end.

