Files
lazarus-ccr/applications/lazstats/source/forms/analysis/financial/dbldeclineunit.pas

221 lines
5.1 KiB
ObjectPascal
Raw Normal View History

unit DblDeclineUnit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
StdCtrls, ExtCtrls,
ContextHelpUnit;
type
{ TDblDeclineFrm }
TDblDeclineFrm = class(TForm)
Bevel1: TBevel;
Bevel2: TBevel;
HelpBtn: TButton;
Panel1: TPanel;
ResetBtn: TButton;
ComputeBtn: TButton;
CloseBtn: TButton;
CostEdit: TEdit;
LifeEdit: TEdit;
EndEdit: TEdit;
PeriodEdit: TEdit;
DeprecEdit: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
procedure ComputeBtnClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure HelpBtnClick(Sender: TObject);
procedure ResetBtnClick(Sender: TObject);
function DoubleDecliningBalance(Cost, Salvage: Extended; Life, Period: Integer): Extended;
private
{ private declarations }
function Validate(out AMsg: String; out AControl: TWinControl): Boolean;
public
{ public declarations }
end;
var
DblDeclineFrm: TDblDeclineFrm;
implementation
{ TDblDeclineFrm }
uses
Math;
procedure TDblDeclineFrm.ResetBtnClick(Sender: TObject);
begin
CostEdit.Text := '';
LifeEdit.Text := '';
EndEdit.Text := '';
PeriodEdit.Text := '';
DeprecEdit.Text := '';
end;
procedure TDblDeclineFrm.FormShow(Sender: TObject);
begin
ResetBtnClick(self);
end;
procedure TDblDeclineFrm.HelpBtnClick(Sender: TObject);
begin
if ContextHelpForm = nil then
Application.CreateForm(TContextHelpForm, ContextHelpForm);
ContextHelpForm.HelpMessage((Sender as TButton).tag);
end;
procedure TDblDeclineFrm.ComputeBtnClick(Sender: TObject);
VAR
Depreciation, Cost, Salvage: Extended;
Life, Period: integer;
msg: String;
C: TWinControl;
begin
if not Validate(msg, C) then
begin
C.SetFocus;
MessageDlg(msg, mtError, [mbOK], 0);
ModalResult := mrNone;
exit;
end;
Cost := StrToFloat(CostEdit.Text);
Salvage := StrToFloat(EndEdit.Text);
Life := StrToInt(LifeEdit.Text);
Period := StrToInt(PeriodEdit.Text);
Depreciation := DoubleDecliningBalance(Cost, Salvage, Life, Period);
DeprecEdit.Text := FormatFloat('0.00', Depreciation);
end;
function TDblDeclineFrm.DoubleDecliningBalance(Cost, Salvage: Extended; Life, Period: Integer): Extended;
{ dv := cost * (1 - 2/life)**(period - 1)
DDB = (2/life) * dv
if DDB > dv - salvage then DDB := dv - salvage
if DDB < 0 then DDB := 0
}
var
DepreciatedVal, Factor: Extended;
begin
Result := 0;
if (Period < 1) or (Life < Period) or (Life < 1) or (Cost <= Salvage) then
Exit;
{depreciate everything in period 1 if life is only one or two periods}
if ( Life <= 2 ) then
begin
if ( Period = 1 ) then
DoubleDecliningBalance:=Cost-Salvage
else
DoubleDecliningBalance:=0; {all depreciation occurred in first period}
exit;
end;
Factor := 2.0 / Life;
DepreciatedVal := Cost * IntPower((1.0 - Factor), Period - 1);
{DepreciatedVal is Cost-(sum of previous depreciation results)}
Result := Factor * DepreciatedVal;
{Nominal computed depreciation for this period. The rest of the
function applies limits to this nominal value. }
{Only depreciate until total depreciation equals cost-salvage.}
if Result > DepreciatedVal - Salvage then
Result := DepreciatedVal - Salvage;
{No more depreciation after salvage value is reached. This is mostly a nit.
If Result is negative at this point, it's very close to zero.}
if Result < 0.0 then
Result := 0.0;
end;
procedure TDblDeclineFrm.FormActivate(Sender: TObject);
var
w: Integer;
begin
w := MaxValue([HelpBtn.Width, ResetBtn.Width, ComputeBtn.Width, CloseBtn.Width]);
HelpBtn.Constraints.MinWidth := w;
ResetBtn.Constraints.MinWidth := w;
ComputeBtn.Constraints.MinWidth := w;
CloseBtn.Constraints.MinWidth := w;
end;
function TDblDeclineFrm.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
var
x: Double;
n: Integer;
begin
Result := false;
if (CostEdit.Text = '') then
begin
AControl := CostEdit;
AMsg := 'Initial cost not specified.';
exit;
end;
if not TryStrToFloat(CostEdit.Text, x) then
begin
AControl := CostEdit;
AMsg := 'No valid number for initial cost.';
exit;
end;
if (LifeEdit.Text = '') then
begin
AControl := LifeEdit;
AMsg := 'Life expectancy not specified.';
exit;
end;
if not TryStrToInt(LifeEdit.Text, n) or (n <= 0) then
begin
AControl := LifeEdit;
AMsg := 'Life expectancy can only be a positive number.';
exit;
end;
if (EndEdit.Text = '') then
begin
AControl := EndEdit;
AMsg := 'End value not specified.';
exit;
end;
if not TryStrToFloat(EndEdit.Text, x) then
begin
AControl := EndEdit;
AMsg := 'No valid number given for end value.';
exit;
end;
if (PeriodEdit.Text = '') then
begin
AControl := PeriodEdit;
AMsg := 'Depreciation period not specified.';
exit;
end;
if not TryStrToInt(PeriodEdit.Text, n) or (n <= 0) then
begin
AControl := PeriodEdit;
AMsg := 'Depreciation period can only be a positive number.';
exit;
end;
Result := true;
end;
initialization
{$I dbldeclineunit.lrs}
end.