Advertising sustains the DA. Ads are hidden for members. Join today

Computed Field

Calculating depreciation and valuation

Last updated on
30 April 2025

Here are a couple of snippets designed to calculate the straight-line depreciation and the estimated current value of a given node.

the user input CCK fields are two dates (requires the date module) and two (currency) values:
1. purchase_date (iso date format)
2. expire_date (iso date format)
3. purchase_value (decimal format)
4. expire_value (decimal format) - this is the 'scrap value' of the item when it reaches the end of it's useful life.

The first function calculates the annual rate of depreciation:

<?php
if (!$node->nid) node_save($node); 
$start_date = date_make_date($node->field_purchase_date[0]['value']);
$start = $start_date->db->parts;
$end_date = date_make_date($node->field_expire_date[0]['value']);
$end = $end_date->db->parts;

$start_decimal = $start['year'] + ($start['mon'] / 12);    // this gives the annual depreciation
$end_decimal = $end['year'] + ($end['mon'] / 12);
// $start_decimal = ($start['year'] * 12) + $start['mon'];  // this would give the monthly depreciation
// $end_decimal = ($end['year'] * 12) + $end['mon'];

  $useful_life = $end_decimal - $start_decimal;

$start_value = ($node->field_purchase_value[0]['value']);
$end_value = ($node->field_expire_value[0]['value']);
  $useful_value =  ($start_value - $end_value);

   $node_field[0]['value'] = ($useful_value / $useful_life);
?>

The result should be stored in the database as a float type with data length 10,2 and NULL values should be allowed. It will update only when one of the node-editable fields is changed (and the node re-submitted).

The second function is a derivative of the first (but not dependant on it). It calculates a current value based on the same linear depreciation calculation.

<?php
if (!$node->nid) node_save($node); 

// get the dates and format them as decimals
$today = time();                                        // gets the current time, we could use $node->updated instead ... see note below
$start_date = date_make_date($node->field_purchase_date[0]['value']);
$start = $start_date->db->parts;
$end_date = date_make_date($node->field_expire_date[0]['value']);
$end = $end_date->db->parts;
$today_decimal = ($today / 31556952) + 1970.083;        // convert unix time to decimal (pretty rough, but good enough for an estimate ;)
$start_decimal = $start['year'] + ($start['mon'] / 12);    // convert iso date format to decimal
$end_decimal = $end['year'] + ($end['mon'] / 12);

  $useful_life = $end_decimal - $start_decimal;
  $used_life = $today_decimal - $start_decimal;

// get the purchase and scrap values and work out the depreciable value
$start_value = ($node->field_purchase_value[0]['value']);
$end_value = ($node->field_expire_value[0]['value']);
  $useful_value =  ($start_value - $end_value);

// calculate the estimated current value and round-off to nearest integer
$est_value = round(($useful_value / $useful_life) * $used_life);            

 // make sure the estimated value never falls below the scrap value.
if ($today_decimal > $end_decimal) {            
  $node_field[0]['value'] = ($end_value . ' (expired)');
  }
else {
  $node_field[0]['value'] = ($est_value . ' (estimated)');
  }

?>

If this is stored in the database, it will only update (ie recalculate to the current date) each time the node is submitted from the node edit tab - ie it's only current at the time of the node's (re)submission. I'm trying to think of a way round this so that the current value could be recalculated in a View ...

Now enjoy playing with your assets ;)

Help improve this page

Page status: Not set

You can: