Calculating depreciation and valuation
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
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion