0

I have a model where I get total of order like this:

public function total()
{
    $total = $this->subtotal();
    foreach ($this->lineItems as $l) {
        $total += $l->amount;
    }
    return $total;
}

I want to add method formated() which will format subtotal and total method returns with function number_format($numberHere, 2).

I want it to be dynamic not like: totalFormated or subtotalFormated. I want to output formated value like this: $order->total()->formated();.

Is there any chance I can get that to work?

Buglinjo
  • 2,067
  • 1
  • 15
  • 26
  • Nothing is impossible but I would recommend against it. You'll need to bloat your Model with a lot of additional logic for these methods that have nothing to do with database. Maybe look at [accessors](https://laravel.com/docs/5.3/eloquent-mutators#defining-an-accessor) for these types of "computed attributes". However if you really want to make it chainable [here's a good start](http://stackoverflow.com/questions/3724112/php-method-chaining) – DevK Jan 17 '17 at 20:28
  • I don't want to add `number_format($numberHere, 2)` every line I want to output total or subtotal or discount or tax amounts. That's why I want to implement that here. Or if you suggest any other(better) solution? – Buglinjo Jan 17 '17 at 20:38

2 Answers2

2

Create total as an instance variance

protected $total;

then change your function to this

public function total()
{
    $this->total = $this->subtotal();
    foreach ($this->lineItems as $l) {
      $this->total += $l->amount;
    }

    return $this;
}

then create the formated function

public function formated()
{
  return number_format($this->total, 2)
}

now you can chain the function like

$order->total()->formated()

** Updated **

you can return both total and subtotal in formated function

public function formated()
{
  return [
      "total" => number_format($this->total, 2), 
      "subtotal" => number_format($this->subtotal, 2)
   ];
}

** or **

you can use one instance variable for both total and or subtotal. let name this varibles myTotals

protected $myTotals;

public function total()
{
    $this->myTotals = $this->subtotal();
    foreach ($this->lineItems as $l) {
      $this->myTotals += $l->amount;
    }

    return $this;
}


public function subTotal()
{
    $this->myTotals = $this->subtotal();
    foreach ($this->lineItems as $l) {
      $this->myTotals += $l->amount;
    }

    return $this;
}

public function formated()
{
    return number_format($this->myTotals, 2)
}

so in this case you can call

$order->total()->formated() // and this will return the total
$order->subTotal()->formated() // and this will return the subtotal
oseintow
  • 7,221
  • 3
  • 26
  • 31
0

You just need to save your $total as a property ($this->total += $l->amount) and at the end of your total() method return the current instance of your class = $this, basically:

public function total()
{
    $this->total = $this->subtotal();
    foreach ($this->lineItems as $l) {
        $this->total += $l->amount;
    }

    return $this;
}

Now your method returns the instance of the Class itself so you can call the other method (or anything else within that class):

public function format()
{
    return number_format($this->total, 2);
}

And with this you should be able to "chain" your methods. The key is to return the instance.

$order->total()->formated()

Mihailo
  • 4,736
  • 4
  • 22
  • 30