Skip to content

Commit

Permalink
add saving and investment types for category
Browse files Browse the repository at this point in the history
  • Loading branch information
saleem-hadad committed May 22, 2022
1 parent 1148e99 commit a8edc6d
Show file tree
Hide file tree
Showing 17 changed files with 176 additions and 23 deletions.
4 changes: 3 additions & 1 deletion app/GraphQL/Queries/TotalCash.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ public function __invoke($_, array $args)
{
$income = Transaction::income()->sum('amount');
$expenses = Transaction::expenses()->sum('amount');
$investment = Transaction::investment()->sum('amount');
$savings = Transaction::savings()->sum('amount');

return $income - $expenses;
return $income - ($expenses + $investment + $savings);
}
}
23 changes: 23 additions & 0 deletions app/GraphQL/Queries/TotalInvestment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\GraphQL\Queries;

use App\Models\Transaction;
use App\Domain\Metrics\ValueMetric;

class TotalInvestment extends ValueMetric
{
public function ranges()
{
return null;
}

/**
* @param null $_
* @param array<string, mixed> $args
*/
public function __invoke($_, array $args)
{
return Transaction::investment()->sum('amount');
}
}
23 changes: 23 additions & 0 deletions app/GraphQL/Queries/TotalSavings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\GraphQL\Queries;

use App\Models\Transaction;
use App\Domain\Metrics\ValueMetric;

class TotalSavings extends ValueMetric
{
public function ranges()
{
return null;
}

/**
* @param null $_
* @param array<string, mixed> $args
*/
public function __invoke($_, array $args)
{
return Transaction::savings()->sum('amount');
}
}
2 changes: 2 additions & 0 deletions app/Models/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class Category extends Model

const INCOME = "INCOME";
const EXPENSES = "EXPENSES";
const SAVINGS = "SAVINGS";
const INVESTMENT = "INVESTMENT";

protected $guarded = [];

Expand Down
14 changes: 14 additions & 0 deletions app/Models/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ public function scopeIncome($query)
});
}

public function scopeSavings($query)
{
return $query->whereHas('brand.category', function ($query) {
return $query->where('type', Category::SAVINGS);
});
}

public function scopeInvestment($query)
{
return $query->whereHas('brand.category', function ($query) {
return $query->where('type', Category::INVESTMENT);
});
}

public static function tryCreateFromSms($sms)
{
$brandFromSms = $sms->meta['data']['brand'] ?? null;
Expand Down
4 changes: 4 additions & 0 deletions config/finance.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

use App\GraphQL\Queries\TotalCash;
use App\GraphQL\Queries\TotalIncome;
use App\GraphQL\Queries\TotalSavings;
use App\GraphQL\Queries\TotalExpenses;
use App\GraphQL\Queries\TotalPerBrand;
use App\GraphQL\Queries\TotalInvestment;
use App\GraphQL\Queries\TotalIncomeTrend;
use App\GraphQL\Queries\IncomePerCategory;
use App\GraphQL\Queries\TotalExpensesTrend;
Expand All @@ -20,6 +22,8 @@
],
'reports' => [
new TotalCash,
new TotalSavings,
new TotalInvestment,
new TotalIncome,
new TotalExpenses,
new IncomePerCategory,
Expand Down
4 changes: 3 additions & 1 deletion graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ type Query {

sms: [Sms!]! @paginate(defaultCount: 100) @orderBy(column: transaction_id direction: ASC)

totalExpenses(range: String!): Json
totalIncome(range: String!): Json
totalExpenses(range: String!): Json
totalSavings: Json
totalInvestment: Json
totalCash: Json

expensesPerCategory(range: String!): Json
Expand Down
2 changes: 1 addition & 1 deletion public/js/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"/js/app.js": "/js/app.js?id=2f34dea68d844f1d7b06",
"/js/app.js": "/js/app.js?id=a851dd183cd50e896983",
"/css/app.css": "/css/app.css?id=58adc592c995babafb87"
}
2 changes: 2 additions & 0 deletions resources/js/Pages/Category/Create.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export default function Create({showCreate, onClose, onCreate}) {
>
<option value="EXPENSES">EXPENSES</option>
<option value="INCOME">INCOME</option>
<option value="SAVINGS">SAVINGS</option>
<option value="INVESTMENT">INVESTMENT</option>
</select>
</div>

Expand Down
2 changes: 2 additions & 0 deletions resources/js/Pages/Category/Edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export default function Edit({category, onClose, onUpdate}) {
>
<option value="EXPENSES">EXPENSES</option>
<option value="INCOME">INCOME</option>
<option value="SAVINGS">SAVINGS</option>
<option value="INVESTMENT">INVESTMENT</option>
</select>
</div>

Expand Down
11 changes: 3 additions & 8 deletions tests/Feature/TotalExpensesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,11 @@ class TotalExpensesTest extends TestCase
public function it_returns_correct_data()
{
$expensesCategory = Category::factory()->create(['type' => Category::EXPENSES]);
$incomeCategory = Category::factory()->create(['type' => Category::INCOME]);


$expensesBrand = Brand::factory()->create(['category_id' => $expensesCategory->id]);
$incomeBrand = Brand::factory()->create(['category_id' => $incomeCategory->id]);

// Expenses

Transaction::factory()->create(['brand_id' => $expensesBrand, 'amount' => 10001]);
// Income
Transaction::factory()->create(['brand_id' => $incomeBrand->id, 'amount' => 133]);


$this->graphQL(/** @lang GraphQL */ '
{
totalExpenses(range: "current-year")
Expand Down
5 changes: 0 additions & 5 deletions tests/Feature/TotalIncomeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,10 @@ class TotalIncomeTest extends TestCase
/** @test */
public function it_returns_correct_data()
{
$expensesCategory = Category::factory()->create(['type' => Category::EXPENSES]);
$incomeCategory = Category::factory()->create(['type' => Category::INCOME]);

$expensesBrand = Brand::factory()->create(['category_id' => $expensesCategory->id]);
$incomeBrand = Brand::factory()->create(['category_id' => $incomeCategory->id]);

// Expenses
Transaction::factory()->create(['brand_id' => $expensesBrand, 'amount' => 10001]);
// Income
Transaction::factory()->create(['brand_id' => $incomeBrand->id, 'amount' => 133]);

$this->graphQL(/** @lang GraphQL */ '
Expand Down
34 changes: 34 additions & 0 deletions tests/Feature/TotalInvestmentTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\Brand;
use App\Models\Category;
use App\Models\Transaction;
use Illuminate\Foundation\Testing\RefreshDatabase;

class TotalInvestmentTest extends TestCase
{
use RefreshDatabase;

/** @test */
public function it_returns_correct_data()
{
$investmentCategory = Category::factory()->create(['type' => Category::INVESTMENT]);

$investmentBrand = Brand::factory()->create(['category_id' => $investmentCategory->id]);

Transaction::factory()->create(['brand_id' => $investmentBrand->id, 'amount' => 133]);

$this->graphQL(/** @lang GraphQL */ '
{
totalInvestment
}
')->assertJson([
'data' => [
'totalInvestment' => '"133.0"'
],
]);
}
}
34 changes: 34 additions & 0 deletions tests/Feature/TotalSavingsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\Brand;
use App\Models\Category;
use App\Models\Transaction;
use Illuminate\Foundation\Testing\RefreshDatabase;

class TotalSavingsTest extends TestCase
{
use RefreshDatabase;

/** @test */
public function it_returns_correct_data()
{
$savingsCategory = Category::factory()->create(['type' => Category::SAVINGS]);

$savingsBrand = Brand::factory()->create(['category_id' => $savingsCategory->id]);

Transaction::factory()->create(['brand_id' => $savingsBrand->id, 'amount' => 133]);

$this->graphQL(/** @lang GraphQL */ '
{
totalSavings
}
')->assertJson([
'data' => [
'totalSavings' => '"133.0"'
],
]);
}
}
12 changes: 12 additions & 0 deletions tests/Unit/CategoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ public function class_has_income_constant()
{
$this->assertEquals(Category::INCOME, "INCOME");
}

/** @test */
public function class_has_investment_constant()
{
$this->assertEquals(Category::INVESTMENT, "INVESTMENT");
}

/** @test */
public function class_has_savings_constant()
{
$this->assertEquals(Category::SAVINGS, "SAVINGS");
}

/** @test */
public function it_has_name()
Expand Down
21 changes: 15 additions & 6 deletions tests/Unit/TotalCashTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,33 @@ class TotalCashTest extends TestCase
/** @test */
public function it_returns_correct_data()
{
$expensesCategory = Category::factory()->create(['type' => Category::EXPENSES]);
$incomeCategory = Category::factory()->create(['type' => Category::INCOME]);
$expensesCategory = Category::factory()->create(['type' => Category::EXPENSES]);
$investmentCategory = Category::factory()->create(['type' => Category::INVESTMENT]);
$savingsCategory = Category::factory()->create(['type' => Category::SAVINGS]);

$expensesBrand = Brand::factory()->create(['category_id' => $expensesCategory->id]);
$incomeBrand = Brand::factory()->create(['category_id' => $incomeCategory->id]);
$expensesBrand = Brand::factory()->create(['category_id' => $expensesCategory->id]);
$investmentBrand = Brand::factory()->create(['category_id' => $investmentCategory->id]);
$savingsBrand = Brand::factory()->create(['category_id' => $savingsCategory->id]);

// Expenses
Transaction::factory()->create(['brand_id' => $expensesBrand, 'amount' => 3444]);
// Income
Transaction::factory()->create(['brand_id' => $incomeBrand->id, 'amount' => 10001]);
Transaction::factory()->create(['brand_id' => $incomeBrand->id, 'amount' => 1000]);
// Expenses
Transaction::factory()->create(['brand_id' => $expensesBrand, 'amount' => 200]);
// Investment
Transaction::factory()->create(['brand_id' => $investmentBrand->id, 'amount' => 300]);
// Savings
Transaction::factory()->create(['brand_id' => $savingsBrand->id, 'amount' => 100]);


$this->graphQL(/** @lang GraphQL */ '
{
totalCash
}
')->assertJson([
'data' => [
'totalCash' => '6557'
'totalCash' => '400'
],
]);
}
Expand Down

0 comments on commit a8edc6d

Please sign in to comment.