canadianlover's avatar

Creating a subtotal() function

I have the following Model Factory


/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| Here you may define all of your model factories. Model factories give
| you a convenient way to create models for testing and seeding your
| database. Just tell the factory how a default model should look.
|
*/

$factory->define(App\User::class, function (Faker\Generator $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->safeEmail,
        'password' => bcrypt(str_random(10)),
        'remember_token' => str_random(10),
    ];
});

$factory->define(App\Cart::class, function (Faker\Generator $faker) {
    return [

        'name' => $faker->sentence,
        'items' => ['item_id' => 1, 'name' => 'WTC', 'filename' => 'filename.pdf', 'price' => 1]

    ];
});```

I am trying to create a model function that calculates the subtotal in my e-commerce application. I have this as my model
```<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class cart extends Model
{
    
}

Any idea on how I can find the subtotal of each individual order?

0 likes
6 replies
tykus's avatar

@canadianlover how are you storing items in the cart? Are they being stored in the cart table as JSON; or do you have an items table?

willvincent's avatar
Level 54

This might be useful.. I've got this helper function that I use to get a sum of array items with a particular key:

// Sum of a specified array key
if (!function_exists('sumOfKey')) {
    function sumOfKey($key, $arr)
    {
        return array_sum(
            array_map(function ($element) use ($key) {
                return isset($element[$key]) ? $element[$key] : 0;
            }, $arr
            )
        );
    }
}

Might get you heading in the right direction anyway.

With that, if I had an array like this:

$data = [
  ['foo' => 10, 'bar' => 20],
  ['foo' => 15, 'bar' => 5],
  ['foo' => 25, 'bar' => 2],
];

I can do the following and get the expected results:

$sum_of_foo = sumOfKey('foo', $data); // this will be 50
$sum_of_bar = sumOfKey('bar', $data); // this will be 27
jlrdw's avatar

@willvincent yet another code snippet for me to hold onto you come up with some real good ones. Can tell you programmed real-world applications.

1 like
willvincent's avatar

@jlrdw Thanks. Basically it's an improvement on a custom filter I wrote for Angular some time ago, as I'm in the process of rebuilding that site with a laravel backend (instead of node), and a vue/blade frontend.

As it existed before for angular:

angular.module('MainModule')
.filter('sumOfKey', function() {
  return function (data, key) {
    if (typeof (data) === 'undefined' || typeof (key) === 'undefined') {
      return 0;
    }
    var sum = 0;
    for (var i = 0; i < data.length; i++) {
      sum = sum + data[i][key];
    }
    return sum;
  };
});

Please or to participate in this conversation.