Skip to content

Currency field: Value stored in minor units #80

@vyuldashev

Description

@vyuldashev

There is a good practice to store money in minor units (for example, cents for dollars).

So here is the implementation for making this possible in Nova in Laravel\Nova\Fields\Currency field:

<?php

namespace Laravel\Nova\Fields;

use Laravel\Nova\Http\Requests\NovaRequest;

class Currency extends Number
{
    /**
     * The format the field will be displayed in.
     *
     * @var string
     */
    public $format;

    public $inMinorUnits = false;

    /**
     * Create a new field.
     *
     * @param  string  $name
     * @param  string|null  $attribute
     * @param  mixed|null  $resolveCallback
     * @return void
     */
    public function __construct($name, $attribute = null, $resolveCallback = null)
    {
        parent::__construct($name, $attribute, $resolveCallback);

        $this->step('0.01')
            ->resolveUsing(function ($value) {
                if(!$value) {
                    return $value;
                }

                if($this->inMinorUnits) {
                    $value /= 100;
                }

                return money_format($this->format ?? '%i', $value);
            })
            ->fillUsing(function (NovaRequest $request, $model, $attribute, $requestAttribute) {
                $value = $request[$requestAttribute];
                
                if($this->inMinorUnits) {
                    $value *= 100;
                }
                $model->{$attribute} = $value;
            });
    }

    /**
     * The monetary format the field will used be displayed in.
     *
     * @param  string  $format
     * @return $this
     */
    public function format($format)
    {
        $this->format = $format;

        return $this;
    }

    /**
     * The value in database is store in minor units (cents for dollars).
     */
    public function storedInMinorUnits()
    {
        $this->inMinorUnits = true;

        return $this;
    }
}

Usage:

public function fields(Request $request) {
    return [
        // ...
        Currency::make('Balance')->storedInMinorUnits(),
    ];
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions