Skip to content

Commit 88da4e1

Browse files
author
Mark Baker
authored
Merge pull request #2579 from PHPOffice/Issue-2578_Negative-dollar-values-for-DOLLARDE()-and-DOLLARFR()-Functions
Fix for DOLLARDE() and DOLLARFR() with negative dollar values
2 parents 5ab3cbc + f577dde commit 88da4e1

File tree

5 files changed

+54
-25
lines changed

5 files changed

+54
-25
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
4949

5050
### Fixed
5151

52+
- Fix bug with `DOLLARDE()` and `DOLLARFR()` functions when the dollar value is negative [Issue #2578](https://github.com/PHPOffice/PhpSpreadsheet/issues/2578) [PR #2579](https://github.com/PHPOffice/PhpSpreadsheet/pull/2579)
5253
- Fix partial function name matching when translating formulae from Russian to English [Issue #2533](https://github.com/PHPOffice/PhpSpreadsheet/issues/2533) [PR #2534](https://github.com/PHPOffice/PhpSpreadsheet/pull/2534)
5354
- Various bugs related to Conditional Formatting Rules, and errors in the Xlsx Writer for Conditional Formatting [PR #2491](https://github.com/PHPOffice/PhpSpreadsheet/pull/2491)
5455
- Xlsx Reader merge range fixes.

phpstan-baseline.neon

-15
Original file line numberDiff line numberDiff line change
@@ -960,21 +960,6 @@ parameters:
960960
count: 1
961961
path: src/PhpSpreadsheet/Calculation/Financial/Depreciation.php
962962

963-
-
964-
message: "#^Cannot cast mixed to int\\.$#"
965-
count: 2
966-
path: src/PhpSpreadsheet/Calculation/Financial/Dollar.php
967-
968-
-
969-
message: "#^Parameter \\#1 \\$number of function floor expects float, mixed given\\.$#"
970-
count: 2
971-
path: src/PhpSpreadsheet/Calculation/Financial/Dollar.php
972-
973-
-
974-
message: "#^Parameter \\#1 \\$x of function fmod expects float, mixed given\\.$#"
975-
count: 2
976-
path: src/PhpSpreadsheet/Calculation/Financial/Dollar.php
977-
978963
-
979964
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Securities\\\\AccruedInterest\\:\\:atMaturity\\(\\) should return float\\|string but returns array\\|string\\.$#"
980965
count: 1

src/PhpSpreadsheet/Calculation/Financial/Dollar.php

+23-10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Calculation\Financial;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
56
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
67
use PhpOffice\PhpSpreadsheet\Calculation\TextData\Format;
78

@@ -40,18 +41,24 @@ public static function format($number, $precision = 2): string
4041
*/
4142
public static function decimal($fractionalDollar = null, $fraction = 0)
4243
{
43-
$fractionalDollar = Functions::flattenSingleValue($fractionalDollar);
44-
$fraction = (int) Functions::flattenSingleValue($fraction);
44+
try {
45+
$fractionalDollar = FinancialValidations::validateFloat(
46+
Functions::flattenSingleValue($fractionalDollar) ?? 0.0
47+
);
48+
$fraction = FinancialValidations::validateInt(Functions::flattenSingleValue($fraction));
49+
} catch (Exception $e) {
50+
return $e->getMessage();
51+
}
4552

46-
// Validate parameters
47-
if ($fractionalDollar === null || $fraction < 0) {
53+
// Additional parameter validations
54+
if ($fraction < 0) {
4855
return Functions::NAN();
4956
}
5057
if ($fraction == 0) {
5158
return Functions::DIV0();
5259
}
5360

54-
$dollars = floor($fractionalDollar);
61+
$dollars = ($fractionalDollar < 0.0) ? ceil($fractionalDollar) : floor($fractionalDollar);
5562
$cents = fmod($fractionalDollar, 1);
5663
$cents /= $fraction;
5764
$cents *= 10 ** ceil(log10($fraction));
@@ -76,18 +83,24 @@ public static function decimal($fractionalDollar = null, $fraction = 0)
7683
*/
7784
public static function fractional($decimalDollar = null, $fraction = 0)
7885
{
79-
$decimalDollar = Functions::flattenSingleValue($decimalDollar);
80-
$fraction = (int) Functions::flattenSingleValue($fraction);
86+
try {
87+
$decimalDollar = FinancialValidations::validateFloat(
88+
Functions::flattenSingleValue($decimalDollar) ?? 0.0
89+
);
90+
$fraction = FinancialValidations::validateInt(Functions::flattenSingleValue($fraction));
91+
} catch (Exception $e) {
92+
return $e->getMessage();
93+
}
8194

82-
// Validate parameters
83-
if ($decimalDollar === null || $fraction < 0) {
95+
// Additional parameter validations
96+
if ($fraction < 0) {
8497
return Functions::NAN();
8598
}
8699
if ($fraction == 0) {
87100
return Functions::DIV0();
88101
}
89102

90-
$dollars = floor($decimalDollar);
103+
$dollars = ($decimalDollar < 0.0) ? ceil($decimalDollar) : floor($decimalDollar);
91104
$cents = fmod($decimalDollar, 1);
92105
$cents *= $fraction;
93106
$cents *= 10 ** (-ceil(log10($fraction)));

tests/data/Calculation/Financial/DOLLARDE.php

+15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
// fractional_dollar, fraction, result
44

55
return [
6+
[
7+
2.5,
8+
1.6,
9+
4,
10+
],
11+
[
12+
-2.5,
13+
-1.6,
14+
4,
15+
],
616
[
717
1.125,
818
1.02,
@@ -38,6 +48,11 @@
3848
1.1200000000000001,
3949
32,
4050
],
51+
[
52+
'#VALUE!',
53+
'Not A Number',
54+
0,
55+
],
4156
[
4257
'#DIV/0!',
4358
1.2344999999999999,

tests/data/Calculation/Financial/DOLLARFR.php

+15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
// decimal_dollar, fraction, result
44

55
return [
6+
[
7+
1.24,
8+
1.6,
9+
4,
10+
],
11+
[
12+
-1.24,
13+
-1.6,
14+
4,
15+
],
616
[
717
1.02,
818
1.125,
@@ -38,6 +48,11 @@
3848
1.375,
3949
32,
4050
],
51+
[
52+
'#VALUE!',
53+
'Not A Number',
54+
0,
55+
],
4156
[
4257
'#DIV/0!',
4358
1.2344999999999999,

0 commit comments

Comments
 (0)