Skip to content

Commit

Permalink
Start work on breaking down some of the Financial Excel functions
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkBaker committed Mar 19, 2021
1 parent 4e8a926 commit 5ad1675
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 36 deletions.
4 changes: 2 additions & 2 deletions src/PhpSpreadsheet/Calculation/Calculation.php
Original file line number Diff line number Diff line change
Expand Up @@ -875,12 +875,12 @@ class Calculation
],
'DOLLARDE' => [
'category' => Category::CATEGORY_FINANCIAL,
'functionCall' => [Financial::class, 'DOLLARDE'],
'functionCall' => [Financial\Dollar::class, 'decimal'],
'argumentCount' => '2',
],
'DOLLARFR' => [
'category' => Category::CATEGORY_FINANCIAL,
'functionCall' => [Financial::class, 'DOLLARFR'],
'functionCall' => [Financial\Dollar::class, 'fractional'],
'argumentCount' => '2',
],
'DPRODUCT' => [
Expand Down
44 changes: 10 additions & 34 deletions src/PhpSpreadsheet/Calculation/Financial.php
Original file line number Diff line number Diff line change
Expand Up @@ -997,30 +997,18 @@ public static function DISC($settlement, $maturity, $price, $redemption, $basis
* Excel Function:
* DOLLARDE(fractional_dollar,fraction)
*
* @Deprecated 1.18.0
*
* @see Use the decimal() method in the Financial\Dollar class instead
*
* @param float $fractional_dollar Fractional Dollar
* @param int $fraction Fraction
*
* @return float|string
*/
public static function DOLLARDE($fractional_dollar = null, $fraction = 0)
{
$fractional_dollar = Functions::flattenSingleValue($fractional_dollar);
$fraction = (int) Functions::flattenSingleValue($fraction);

// Validate parameters
if ($fractional_dollar === null || $fraction < 0) {
return Functions::NAN();
}
if ($fraction == 0) {
return Functions::DIV0();
}

$dollars = floor($fractional_dollar);
$cents = fmod($fractional_dollar, 1);
$cents /= $fraction;
$cents *= 10 ** ceil(log10($fraction));

return $dollars + $cents;
return Financial\Dollar::decimal($fractional_dollar, $fraction);
}

/**
Expand All @@ -1033,30 +1021,18 @@ public static function DOLLARDE($fractional_dollar = null, $fraction = 0)
* Excel Function:
* DOLLARFR(decimal_dollar,fraction)
*
* @Deprecated 1.18.0
*
* @see Use the fractional() method in the Financial\Dollar class instead
*
* @param float $decimal_dollar Decimal Dollar
* @param int $fraction Fraction
*
* @return float|string
*/
public static function DOLLARFR($decimal_dollar = null, $fraction = 0)
{
$decimal_dollar = Functions::flattenSingleValue($decimal_dollar);
$fraction = (int) Functions::flattenSingleValue($fraction);

// Validate parameters
if ($decimal_dollar === null || $fraction < 0) {
return Functions::NAN();
}
if ($fraction == 0) {
return Functions::DIV0();
}

$dollars = floor($decimal_dollar);
$cents = fmod($decimal_dollar, 1);
$cents *= $fraction;
$cents *= 10 ** (-ceil(log10($fraction)));

return $dollars + $cents;
return Financial\Dollar::fractional($decimal_dollar, $fraction);
}

/**
Expand Down
80 changes: 80 additions & 0 deletions src/PhpSpreadsheet/Calculation/Financial/Dollar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace PhpOffice\PhpSpreadsheet\Calculation\Financial;

use PhpOffice\PhpSpreadsheet\Calculation\Functions;

class Dollar
{
/**
* DOLLARDE.
*
* Converts a dollar price expressed as an integer part and a fraction
* part into a dollar price expressed as a decimal number.
* Fractional dollar numbers are sometimes used for security prices.
*
* Excel Function:
* DOLLARDE(fractional_dollar,fraction)
*
* @param float $fractionalDollar Fractional Dollar
* @param int $fraction Fraction
*
* @return float|string
*/
public static function decimal($fractionalDollar = null, $fraction = 0)
{
$fractionalDollar = Functions::flattenSingleValue($fractionalDollar);
$fraction = (int) Functions::flattenSingleValue($fraction);

// Validate parameters
if ($fractionalDollar === null || $fraction < 0) {
return Functions::NAN();
}
if ($fraction == 0) {
return Functions::DIV0();
}

$dollars = floor($fractionalDollar);
$cents = fmod($fractionalDollar, 1);
$cents /= $fraction;
$cents *= 10 ** ceil(log10($fraction));

return $dollars + $cents;
}

/**
* DOLLARFR.
*
* Converts a dollar price expressed as a decimal number into a dollar price
* expressed as a fraction.
* Fractional dollar numbers are sometimes used for security prices.
*
* Excel Function:
* DOLLARFR(decimal_dollar,fraction)
*
* @param float $decimalDollar Decimal Dollar
* @param int $fraction Fraction
*
* @return float|string
*/
public static function fractional($decimalDollar = null, $fraction = 0)
{
$decimalDollar = Functions::flattenSingleValue($decimalDollar);
$fraction = (int) Functions::flattenSingleValue($fraction);

// Validate parameters
if ($decimalDollar === null || $fraction < 0) {
return Functions::NAN();
}
if ($fraction == 0) {
return Functions::DIV0();
}

$dollars = floor($decimalDollar);
$cents = fmod($decimalDollar, 1);
$cents *= $fraction;
$cents *= 10 ** (-ceil(log10($fraction)));

return $dollars + $cents;
}
}

0 comments on commit 5ad1675

Please sign in to comment.