AutorÃa | Ultima modificación | Ver Log |
<?phpnamespace PhpOffice\PhpSpreadsheet\Calculation\Financial;use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;use PhpOffice\PhpSpreadsheet\Calculation\Exception;use PhpOffice\PhpSpreadsheet\Calculation\Financial\Constants as FinancialConstants;use PhpOffice\PhpSpreadsheet\Calculation\Functions;class Amortization{/*** AMORDEGRC.** Returns the depreciation for each accounting period.* This function is provided for the French accounting system. If an asset is purchased in* the middle of the accounting period, the prorated depreciation is taken into account.* The function is similar to AMORLINC, except that a depreciation coefficient is applied in* the calculation depending on the life of the assets.* This function will return the depreciation until the last period of the life of the assets* or until the cumulated value of depreciation is greater than the cost of the assets minus* the salvage value.** Excel Function:* AMORDEGRC(cost,purchased,firstPeriod,salvage,period,rate[,basis])** @param mixed $cost The float cost of the asset* @param mixed $purchased Date of the purchase of the asset* @param mixed $firstPeriod Date of the end of the first period* @param mixed $salvage The salvage value at the end of the life of the asset* @param mixed $period the period (float)* @param mixed $rate rate of depreciation (float)* @param mixed $basis The type of day count to use (int).* 0 or omitted US (NASD) 30/360* 1 Actual/actual* 2 Actual/360* 3 Actual/365* 4 European 30/360** @return float|string (string containing the error type if there is an error)*/public static function AMORDEGRC(mixed $cost,mixed $purchased,mixed $firstPeriod,mixed $salvage,mixed $period,mixed $rate,mixed $basis = FinancialConstants::BASIS_DAYS_PER_YEAR_NASD): string|float {$cost = Functions::flattenSingleValue($cost);$purchased = Functions::flattenSingleValue($purchased);$firstPeriod = Functions::flattenSingleValue($firstPeriod);$salvage = Functions::flattenSingleValue($salvage);$period = Functions::flattenSingleValue($period);$rate = Functions::flattenSingleValue($rate);$basis = ($basis === null)? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD: Functions::flattenSingleValue($basis);try {$cost = FinancialValidations::validateFloat($cost);$purchased = FinancialValidations::validateDate($purchased);$firstPeriod = FinancialValidations::validateDate($firstPeriod);$salvage = FinancialValidations::validateFloat($salvage);$period = FinancialValidations::validateInt($period);$rate = FinancialValidations::validateFloat($rate);$basis = FinancialValidations::validateBasis($basis);} catch (Exception $e) {return $e->getMessage();}$yearFracx = DateTimeExcel\YearFrac::fraction($purchased, $firstPeriod, $basis);if (is_string($yearFracx)) {return $yearFracx;}/** @var float $yearFrac */$yearFrac = $yearFracx;$amortiseCoeff = self::getAmortizationCoefficient($rate);$rate *= $amortiseCoeff;$rate = (float) (string) $rate; // ugly way to avoid rounding problem$fNRate = round($yearFrac * $rate * $cost, 0);$cost -= $fNRate;$fRest = $cost - $salvage;for ($n = 0; $n < $period; ++$n) {$fNRate = round($rate * $cost, 0);$fRest -= $fNRate;if ($fRest < 0.0) {return match ($period - $n) {1 => round($cost * 0.5, 0),default => 0.0,};}$cost -= $fNRate;}return $fNRate;}/*** AMORLINC.** Returns the depreciation for each accounting period.* This function is provided for the French accounting system. If an asset is purchased in* the middle of the accounting period, the prorated depreciation is taken into account.** Excel Function:* AMORLINC(cost,purchased,firstPeriod,salvage,period,rate[,basis])** @param mixed $cost The cost of the asset as a float* @param mixed $purchased Date of the purchase of the asset* @param mixed $firstPeriod Date of the end of the first period* @param mixed $salvage The salvage value at the end of the life of the asset* @param mixed $period The period as a float* @param mixed $rate Rate of depreciation as float* @param mixed $basis Integer indicating the type of day count to use.* 0 or omitted US (NASD) 30/360* 1 Actual/actual* 2 Actual/360* 3 Actual/365* 4 European 30/360** @return float|string (string containing the error type if there is an error)*/public static function AMORLINC(mixed $cost,mixed $purchased,mixed $firstPeriod,mixed $salvage,mixed $period,mixed $rate,mixed $basis = FinancialConstants::BASIS_DAYS_PER_YEAR_NASD): string|float {$cost = Functions::flattenSingleValue($cost);$purchased = Functions::flattenSingleValue($purchased);$firstPeriod = Functions::flattenSingleValue($firstPeriod);$salvage = Functions::flattenSingleValue($salvage);$period = Functions::flattenSingleValue($period);$rate = Functions::flattenSingleValue($rate);$basis = ($basis === null)? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD: Functions::flattenSingleValue($basis);try {$cost = FinancialValidations::validateFloat($cost);$purchased = FinancialValidations::validateDate($purchased);$firstPeriod = FinancialValidations::validateDate($firstPeriod);$salvage = FinancialValidations::validateFloat($salvage);$period = FinancialValidations::validateFloat($period);$rate = FinancialValidations::validateFloat($rate);$basis = FinancialValidations::validateBasis($basis);} catch (Exception $e) {return $e->getMessage();}$fOneRate = $cost * $rate;$fCostDelta = $cost - $salvage;// Note, quirky variation for leap years on the YEARFRAC for this function$purchasedYear = DateTimeExcel\DateParts::year($purchased);$yearFracx = DateTimeExcel\YearFrac::fraction($purchased, $firstPeriod, $basis);if (is_string($yearFracx)) {return $yearFracx;}/** @var float $yearFrac */$yearFrac = $yearFracx;if ($basis == FinancialConstants::BASIS_DAYS_PER_YEAR_ACTUAL&& $yearFrac < 1&& DateTimeExcel\Helpers::isLeapYear(Functions::scalar($purchasedYear))) {$yearFrac *= 365 / 366;}$f0Rate = $yearFrac * $rate * $cost;$nNumOfFullPeriods = (int) (($cost - $salvage - $f0Rate) / $fOneRate);if ($period == 0) {return $f0Rate;} elseif ($period <= $nNumOfFullPeriods) {return $fOneRate;} elseif ($period == ($nNumOfFullPeriods + 1)) {return $fCostDelta - $fOneRate * $nNumOfFullPeriods - $f0Rate;}return 0.0;}private static function getAmortizationCoefficient(float $rate): float{// The depreciation coefficients are:// Life of assets (1/rate) Depreciation coefficient// Less than 3 years 1// Between 3 and 4 years 1.5// Between 5 and 6 years 2// More than 6 years 2.5$fUsePer = 1.0 / $rate;if ($fUsePer < 3.0) {return 1.0;} elseif ($fUsePer < 4.0) {return 1.5;} elseif ($fUsePer <= 6.0) {return 2.0;}return 2.5;}}