Skip to content

Commit

Permalink
df38bde: Billing - price per period - settings for rounding
Browse files Browse the repository at this point in the history
  • Loading branch information
Mapiiik committed May 3, 2024
1 parent a93c229 commit c12c562
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 12 deletions.
3 changes: 3 additions & 0 deletions config/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export STRIP_PHONE_PREFIX_FOR_SUMMARY_TEXT="false"
#export OFFSET_OF_FIRST_AVAILABLE_IP_ADDRESS=1
#export MINIMUM_NUMBER_OF_DAYS_SINCE_LAST_USE_FOR_AVAILABLE_IP_ADDRESSES=365

#export BILLING_PERIOD_ROUNDING_PLACES=2
#export BILLING_PERIOD_ROUNDING_TYPE="HALF_UP" # (HALF_UP/CEIL/FLOOR)

#export REPORT_EMAILS="space separated"

#export APP_DEFAULT_CURRENCY="CZK"
Expand Down
46 changes: 34 additions & 12 deletions src/Model/Entity/Billing.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,26 @@ public static function calcVatBaseFromTotal(Decimal $total, float $vat_rate): De
);
}

/**
* Round for the billing period.
*
* @param \PhpCollective\DecimalObject\Decimal $price Unrounded price.
* @return \PhpCollective\DecimalObject\Decimal Rounded price.
* @throws \Exception When BILLING_PERIOD_ROUNDING_TYPE has an invalid value.
*/
public static function roundForBillingPeriod(Decimal $price): Decimal
{
return $price->round(
(int)env('BILLING_PERIOD_ROUNDING_PLACES', '2'),
match (env('BILLING_PERIOD_ROUNDING_TYPE', 'HALF_UP')) {
'HALF_UP' => Decimal::ROUND_HALF_UP,
'CEIL' => Decimal::ROUND_CEIL,
'FLOOR' => Decimal::ROUND_FLOOR,
default => throw new Exception('BILLING_PERIOD_ROUNDING_TYPE has an invalid value.'),
}
);
}

/**
* getter for VAT
*
Expand Down Expand Up @@ -252,30 +272,32 @@ public function periodTotal(Date $from, Date $until): Decimal
if (is_null($this->billing_until) || (!is_null($this->billing_until) && $this->billing_until >= $until)) { // billing_until is not limiting
// whole period
if ($this->billing_from <= $from) {
return $this->total_price
->round(0, Decimal::ROUND_CEIL);
return self::roundForBillingPeriod($this->total_price);
}
// later billing_from
if ($this->billing_from <= $until) {
return $this->total_price
->multiply($this->billing_from->diffInDays($until->addDays(1)))
->divide($period_days, 4)
->round(0, Decimal::ROUND_CEIL);
return self::roundForBillingPeriod(
$this->total_price
->multiply($this->billing_from->diffInDays($until->addDays(1)))
->divide($period_days, 4)
);
}
} else { // billing_until is limiting
// earlier billing_until
if ($this->billing_from <= $from) {
return $this->total_price
return self::roundForBillingPeriod(
$this->total_price
->multiply($from->diffInDays($this->billing_until->addDays(1)))
->divide($period_days, 4)
->round(0, Decimal::ROUND_CEIL);
);
}
// later billing_from and earlier billing_until
if ($this->billing_from <= $until) {
return $this->total_price
->multiply($this->billing_from->diffInDays($this->billing_until->addDays(1)))
->divide($period_days, 4)
->round(0, Decimal::ROUND_CEIL);
return self::roundForBillingPeriod(
$this->total_price
->multiply($this->billing_from->diffInDays($this->billing_until->addDays(1)))
->divide($period_days, 4)
);
}
}

Expand Down

0 comments on commit c12c562

Please sign in to comment.