Skip to content

Commit

Permalink
Implement casting to Decimal in DecimalObjectCast trait
Browse files Browse the repository at this point in the history
  • Loading branch information
AJenbo committed May 9, 2023
1 parent fbc4137 commit 18a8b69
Showing 1 changed file with 30 additions and 5 deletions.
35 changes: 30 additions & 5 deletions src/DecimalObjectCast.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
* "decimal" cast uses `number_format`, but we can utilize the `toFixed` method
* provided by Decimal\Decimal to prepare the value.
*
* This trait does not provide a cast from string to Decimal; this should be
* done manually using an accessor like `getPriceAttribute`, which should return
* a new Decimal\Decimal using the precision of the column in the database.
* This trait extends the default behavior by allowing the precision and scale
* of the decimal value to be specified via the attribute's casting definition.
* For example, `decimal:2:8` would cast the attribute to a Decimal with 2 digits
* of scale and 8 digits of precision.
*/
trait DecimalObjectCast
{
Expand All @@ -27,7 +28,31 @@ trait DecimalObjectCast
protected function asDecimal($value, $decimals)
{
assert($value instanceof Decimal);

return $value->toFixed($decimals, $commas = false, PHP_ROUND_HALF_UP);
$decimals = explode(':', $decimals)[0];

return $value->toFixed($decimals, false, PHP_ROUND_HALF_UP);
}

/**
* Set a given attribute on the model.
*
* @param string $key
* @param mixed $value
*
* @return mixed
*/
public function setAttribute($key, $value)
{
if (!is_null($value)) {
$casts = $this->getCasts();
if (array_key_exists($key, $casts) && $this->isDecimalCast($casts[$key])) {
$precision = explode(':', $this->casts[$key])[2] ?? Decimal::DEFAULT_PRECISION;
$this->attributes[$key] = new Decimal($value, $precision);

return $this;
}
}

return parent::setAttribute($key, $value);
}
}

0 comments on commit 18a8b69

Please sign in to comment.