Allow recurrings to be earning as well
MODIFY
app/Http/Controllers/RecurringController.php
app/Http/Controllers/RecurringController.php
@@ -33,6 +33,7 @@ class RecurringController extends Controller {
public function store(Request $request) {
$request->validate([
+ 'type' => 'required|in:earning,spending',
'day' => ['required',
'regex:/\b(0?[1-9]|[12][0-9]|3[01])\b/',
],
@@ -47,6 +48,7 @@ class RecurringController extends Controller {
$recurring = new Recurring;
$recurring->space_id = session('space')->id;
+ $recurring->type = $request->type;
$recurring->interval = 'monthly';
$recurring->day = ltrim($request->input('day'), '0');
$recurring->starts_on = date('Y-m-d');

MODIFY
app/Jobs/ProcessRecurrings.php
app/Jobs/ProcessRecurrings.php
namespace App\Jobs;
+use App\Models\Earning;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
@@ -9,6 +10,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Models\Recurring;
use App\Models\Spending;
+use Exception;
class ProcessRecurrings implements ShouldQueue {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
@@ -41,6 +43,21 @@ class ProcessRecurrings implements ShouldQueue {
})->get();
foreach ($recurrings as $recurring) {
+ if ($recurring->type !== 'earning' && $recurring->type !== 'spending') {
+ throw new Exception('Unknown type "' . $recurring->type . '" for recurring');
+ }
+
+ if ($recurring->type === 'earning') {
+ $earning = new Earning;
+ $earning->space_id = $recurring->space_id;
+ $earning->recurring_id = $recurring->id;
+ $earning->happened_on = date('Y-m-d');
+ $earning->description = $recurring->description;
+ $earning->amount = $recurring->amount;
+ $earning->save();
+ }
+
+ if ($recurring->type === 'spending') {
$spending = new Spending;
$spending->space_id = $recurring->space_id;
$spending->recurring_id = $recurring->id;
@@ -49,6 +66,7 @@ class ProcessRecurrings implements ShouldQueue {
$spending->description = $recurring->description;
$spending->amount = $recurring->amount;
$spending->save();
+ }
$recurring->last_used_on = date('Y-m-d');
$recurring->save();

MODIFY
app/Models/Recurring.php
app/Models/Recurring.php
@@ -12,6 +12,10 @@ class Recurring extends Model {
protected $dates = ['deleted_at'];
+ protected $fillable = [
+ 'type'
+ ];
+
protected $dispatchesEvents = [
'created' => RecurringCreated::class,
'deleted' => RecurringDeleted::class

ADD
database/migrations/2020_06_05_160648_add_type_column_to_recurrings_table.php
+<?php
+
+use App\Models\Recurring;
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddTypeColumnToRecurringsTable extends Migration
+{
+ public function up(): void
+ {
+ Schema::table('recurrings', function (Blueprint $table) {
+ $table->string('type')->after('space_id');
+ });
+
+ // Set newly introduced column to "spending" everywhere
+ foreach (Recurring::all() as $recurring) {
+ $recurring->update([
+ 'type' => 'spending'
+ ]);
+ }
+ }
+
+ public function down(): void
+ {
+ Schema::table('recurrings', function (Blueprint $table) {
+ $table->dropColumn('type');
+ });
+ }
+}

MODIFY
resources/assets/js/components/TransactionWizard.vue
resources/assets/js/components/TransactionWizard.vue
<input type="text" v-model="amount" />
<validation-error v-if="errors.amount" :message="errors.amount"></validation-error>
</div>
- <div v-if="type == 'spending'">
+ <div>
<div class="input row">
<div class="row__column row__column--compact mr-1">
<input type="checkbox" id="test" v-model="isRecurring" />
</div>
<div class="row__column">
- <label for="test">This is a recurring spending&mdash;create it for me in the future</label>
+ <label for="test">This is a recurring transaction&mdash;create it for me in the future</label>
</div>
</div>
<div v-if="isRecurring">
<input id="noEnd" type="radio" v-model="recurringEnd" value="forever" />
</div>
<div class="row__column">
- <label for="noEnd">Forever :(</label>
+ <label for="noEnd">Forever</label>
</div>
</div>
<div class="row">
if (!this.loading) {
this.loading = true
- if (this.type == 'spending' && this.isRecurring) { // It's a recurring
+ if (this.isRecurring) { // It's a recurring
let body = {
_token: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
+ type: this.type,
day: this.date.slice(-2),
description: this.description,
amount: this.amount

Allow recurrings to be earning as well