diff --git a/app/Database/factories/ExpenseFactory.php b/app/Database/factories/ExpenseFactory.php
index 99792729..e074e3a9 100644
--- a/app/Database/factories/ExpenseFactory.php
+++ b/app/Database/factories/ExpenseFactory.php
@@ -13,6 +13,8 @@ $factory->define(App\Models\Expense::class, function (Faker $faker) {
'amount' => $faker->randomFloat(2, 100, 1000),
'type' => ExpenseType::FLIGHT,
'multiplier' => false,
+ 'ref_class' => \App\Models\Expense::class,
+ 'ref_class_id' => null,
'active' => true,
];
});
diff --git a/app/Database/factories/SubfleetExpenseFactory.php b/app/Database/factories/SubfleetExpenseFactory.php
deleted file mode 100644
index 9ece1796..00000000
--- a/app/Database/factories/SubfleetExpenseFactory.php
+++ /dev/null
@@ -1,11 +0,0 @@
-define(App\Models\SubfleetExpense::class, function (Faker $faker) {
- return [
- 'subfleet_id' => null,
- 'name' => $faker->text(20),
- 'amount' => $faker->randomFloat(2, 100, 1000),
- ];
-});
diff --git a/app/Database/migrations/2017_06_23_011011_create_subfleet_tables.php b/app/Database/migrations/2017_06_23_011011_create_subfleet_tables.php
index f0bc297f..beff35f0 100644
--- a/app/Database/migrations/2017_06_23_011011_create_subfleet_tables.php
+++ b/app/Database/migrations/2017_06_23_011011_create_subfleet_tables.php
@@ -3,14 +3,11 @@
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
+/**
+ * Class CreateSubfleetTables
+ */
class CreateSubfleetTables extends Migration
{
-
- /**
- * Run the migrations.
- *
- * @return void
- */
public function up()
{
Schema::create('subfleets', function (Blueprint $table) {
@@ -26,17 +23,6 @@ class CreateSubfleetTables extends Migration
$table->timestamps();
});
- Schema::create('subfleet_expenses', function(Blueprint $table) {
- $table->increments('id');
- $table->unsignedBigInteger('subfleet_id');
- $table->string('name', 50);
- $table->unsignedTinyInteger('type'); # ExpenseType
- $table->unsignedDecimal('amount');
- $table->timestamps();
-
- $table->index('subfleet_id');
- });
-
Schema::create('subfleet_fare', function (Blueprint $table) {
$table->unsignedInteger('subfleet_id');
$table->unsignedInteger('fare_id');
@@ -76,7 +62,6 @@ class CreateSubfleetTables extends Migration
public function down()
{
Schema::dropIfExists('subfleets');
- Schema::dropIfExists('subfleet_expenses');
Schema::dropIfExists('subfleet_fare');
Schema::dropIfExists('subfleet_flight');
Schema::dropIfExists('subfleet_rank');
diff --git a/app/Database/migrations/2018_02_26_185121_create_expenses_table.php b/app/Database/migrations/2018_02_26_185121_create_expenses_table.php
index bf59172f..5098782a 100644
--- a/app/Database/migrations/2018_02_26_185121_create_expenses_table.php
+++ b/app/Database/migrations/2018_02_26_185121_create_expenses_table.php
@@ -16,15 +16,19 @@ class CreateExpensesTable extends Migration
Schema::create('expenses', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('airline_id')->nullable();
+
$table->string('name');
$table->unsignedInteger('amount');
$table->unsignedTinyInteger('type');
$table->boolean('multiplier')->nullable()->default(0);
$table->boolean('active')->nullable()->default(true);
- # Internal fields are expenses tied to some system object
+ # ref fields are expenses tied to some model object
# EG, the airports has an internal expense for gate costs
- $table->nullableMorphs('expensable');
+ $table->string('ref_class')->nullable();
+ $table->string('ref_class_id', 36)->nullable();
+ $table->index(['ref_class', 'ref_class_id']);
+
$table->timestamps();
});
}
diff --git a/app/Database/seeds/sample.yml b/app/Database/seeds/sample.yml
index 409b5ed4..86b46b60 100644
--- a/app/Database/seeds/sample.yml
+++ b/app/Database/seeds/sample.yml
@@ -184,25 +184,38 @@ expenses:
amount: 100
type: 0
active: 1
+ ref_class: App\Models\Expense
- name: Per-Flight (multiplier)
amount: 100
type: 0
multiplier: 1
active: 1
+ ref_class: App\Models\Expense
- name: Per-Flight (multiplier, on airline)
airline_id: 1
amount: 200
type: 0
multiplier: 1
active: 1
+ ref_class: App\Models\Expense
- name: A daily fee
amount: 800
type: 1
active: 1
+ ref_class: App\Models\Expense
- name: A monthly fee
amount: 5000
type: 2
active: 1
+ ref_class: App\Models\Expense
+ - name: Catering
+ amount: 1000
+ type: 0
+ active: 1
+ ref_class: App\Models\Subfleet
+ ref_class_id: 1
+ created_at: now
+ updated_at: now
fares:
- id: 1
@@ -238,13 +251,14 @@ subfleets:
type: 772-36ER-GE90-115B
ground_handling_multiplier: 150
-subfleet_expenses:
- - id: 1
- subfleet_id: 1
- name: Catering
- amount: 1000
- created_at: now
- updated_at: now
+#subfleet_expenses:
+# - id: 1
+# subfleet_id: 1
+# name: Catering
+# amount: 1000
+# type: 0
+# created_at: now
+# updated_at: now
# add a few mods to aircraft and fares
subfleet_fare:
diff --git a/app/Http/Controllers/Admin/ExpenseController.php b/app/Http/Controllers/Admin/ExpenseController.php
index bb9c2417..dc085b8e 100644
--- a/app/Http/Controllers/Admin/ExpenseController.php
+++ b/app/Http/Controllers/Admin/ExpenseController.php
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin;
use App\Http\Requests\CreateAirlineRequest;
use App\Http\Requests\UpdateAirlineRequest;
use App\Models\Enums\ExpenseType;
+use App\Models\Expense;
use App\Repositories\AirlineRepository;
use App\Repositories\ExpenseRepository;
use Flash;
@@ -39,7 +40,9 @@ class ExpenseController extends BaseController
public function index(Request $request)
{
$this->expenseRepo->pushCriteria(new RequestCriteria($request));
- $expenses = $this->expenseRepo->all();
+ $expenses = $this->expenseRepo->findWhere([
+ 'ref_class' => Expense::class
+ ]);
return view('admin.expenses.index', [
'expenses' => $expenses
@@ -66,6 +69,7 @@ class ExpenseController extends BaseController
public function store(Request $request)
{
$input = $request->all();
+ $input['ref_class'] = Expense::class;
$this->expenseRepo->create($input);
Flash::success('Expense saved successfully.');
diff --git a/app/Http/Controllers/Admin/SubfleetController.php b/app/Http/Controllers/Admin/SubfleetController.php
index f5d21ac1..45189400 100644
--- a/app/Http/Controllers/Admin/SubfleetController.php
+++ b/app/Http/Controllers/Admin/SubfleetController.php
@@ -6,8 +6,8 @@ use App\Http\Requests\CreateSubfleetRequest;
use App\Http\Requests\UpdateSubfleetRequest;
use App\Models\Airline;
use App\Models\Enums\FuelType;
+use App\Models\Expense;
use App\Models\Subfleet;
-use App\Models\SubfleetExpense;
use App\Repositories\AircraftRepository;
use App\Repositories\FareRepository;
use App\Repositories\RankRepository;
@@ -338,17 +338,18 @@ class SubfleetController extends BaseController
* update specific rank data
*/
if ($request->isMethod('post')) {
- $expense = new SubfleetExpense($request->post());
- $expense->subfleet_id = $subfleet->id;
+ $expense = new Expense($request->post());
+ $expense->ref_class = Subfleet::class;
+ $expense->ref_class_id = $subfleet->id;
$expense->save();
$subfleet->refresh();
} elseif ($request->isMethod('put')) {
- $expense = SubfleetExpense::findOrFail($request->input('expense_id'));
+ $expense = Expense::findOrFail($request->input('expense_id'));
$expense->{$request->name} = $request->value;
$expense->save();
} // dissassociate fare from teh aircraft
elseif ($request->isMethod('delete')) {
- $expense = SubfleetExpense::findOrFail($request->input('expense_id'));
+ $expense = Expense::findOrFail($request->input('expense_id'));
$expense->delete();
}
diff --git a/app/Models/Airport.php b/app/Models/Airport.php
index a257f995..38c356e1 100644
--- a/app/Models/Airport.php
+++ b/app/Models/Airport.php
@@ -2,7 +2,7 @@
namespace App\Models;
-use App\Models\Traits\ExpensableTrait;
+use App\Models\Traits\Expensable;
use Illuminate\Notifications\Notifiable;
/**
@@ -12,7 +12,7 @@ use Illuminate\Notifications\Notifiable;
*/
class Airport extends BaseModel
{
- use ExpensableTrait;
+ use Expensable;
use Notifiable;
public $table = 'airports';
diff --git a/app/Models/Expense.php b/app/Models/Expense.php
index c015efe7..27301a8b 100644
--- a/app/Models/Expense.php
+++ b/app/Models/Expense.php
@@ -18,6 +18,8 @@ class Expense extends BaseModel
'amount',
'type',
'multiplier',
+ 'ref_class',
+ 'ref_class_id',
'active',
];
diff --git a/app/Models/Subfleet.php b/app/Models/Subfleet.php
index ec45c282..94f765b7 100644
--- a/app/Models/Subfleet.php
+++ b/app/Models/Subfleet.php
@@ -3,6 +3,7 @@
namespace App\Models;
use App\Models\Enums\AircraftStatus;
+use App\Models\Traits\Expensable;
/**
* Class Subfleet
@@ -10,6 +11,8 @@ use App\Models\Enums\AircraftStatus;
*/
class Subfleet extends BaseModel
{
+ use Expensable;
+
public $table = 'subfleets';
public $fillable = [
@@ -88,14 +91,6 @@ class Subfleet extends BaseModel
return $this->belongsTo(Airline::class, 'airline_id');
}
- /**
- * @return \Illuminate\Database\Eloquent\Relations\HasMany
- */
- public function expenses()
- {
- return $this->hasMany(SubfleetExpense::class, 'subfleet_id');
- }
-
public function fares()
{
return $this->belongsToMany(Fare::class, 'subfleet_fare')
diff --git a/app/Models/SubfleetExpense.php b/app/Models/SubfleetExpense.php
deleted file mode 100644
index ab7f94c0..00000000
--- a/app/Models/SubfleetExpense.php
+++ /dev/null
@@ -1,47 +0,0 @@
- 'float',
- 'type' => 'integer',
- ];
-
- public static $rules = [
- 'name' => 'required',
- 'amount' => 'required|numeric',
- ];
-
- /**
- * Relationships
- */
-
- /**
- * Has a subfleet
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
- */
- public function subfleet()
- {
- return $this->belongsTo(Subfleet::class, 'subfleet_id');
- }
-}
diff --git a/app/Models/Traits/ExpensableTrait.php b/app/Models/Traits/Expensable.php
similarity index 68%
rename from app/Models/Traits/ExpensableTrait.php
rename to app/Models/Traits/Expensable.php
index 7aa479f9..51fc6f8e 100644
--- a/app/Models/Traits/ExpensableTrait.php
+++ b/app/Models/Traits/Expensable.php
@@ -4,13 +4,12 @@ namespace App\Models\Traits;
use App\Models\Expense;
-trait ExpensableTrait
+trait Expensable
{
-
/**
* Initialize a new journal when a new record is created
*/
- public static function bootExpensableTrait()
+ public static function bootExpensable()
{
/*static::created(function ($model) {
$model->initJournal(config('phpvms.currency'));
@@ -23,6 +22,7 @@ trait ExpensableTrait
*/
public function expenses()
{
- return $this->morphToMany(Expense::class, 'expensable');
+ return $this->hasMany(Expense::class, 'ref_class_id')
+ ->where('ref_class', __CLASS__);
}
}
diff --git a/app/Repositories/ExpenseRepository.php b/app/Repositories/ExpenseRepository.php
index 960c0f32..ad0b39da 100644
--- a/app/Repositories/ExpenseRepository.php
+++ b/app/Repositories/ExpenseRepository.php
@@ -24,20 +24,39 @@ class ExpenseRepository extends BaseRepository implements CacheableInterface
* Get all of the expenses for a given type, and also
* include expenses for a given airline ID
* @param $type
+ * @param null $airline_id
+ * @param null $ref_class
* @return Collection
*/
- public function getAllForType($type, $airline_id=null)
+ public function getAllForType($type, $airline_id=null, $ref_class=null)
{
- $expenses = $this->findWhere([
+ $where = [
'type' => $type,
['airline_id', '=', null]
- ]);
+ ];
+
+ if($ref_class) {
+ $where['ref_class'] = $ref_class;
+ } else {
+ $where[] = ['ref_class', '=', null];
+ }
+
+ $expenses = $this->findWhere($where);
if($airline_id) {
- $airline_expenses = $this->findWhere([
+
+ $where = [
'type' => $type,
'airline_id' => $airline_id
- ]);
+ ];
+
+ if ($ref_class) {
+ $where['ref_class'] = $ref_class;
+ } else {
+ $where[] = ['ref_class', '=', null];
+ }
+
+ $airline_expenses = $this->findWhere($where);
$expenses = $expenses->concat($airline_expenses);
}
diff --git a/app/Repositories/JournalRepository.php b/app/Repositories/JournalRepository.php
index 234fc3dc..a7d8fad1 100644
--- a/app/Repositories/JournalRepository.php
+++ b/app/Repositories/JournalRepository.php
@@ -61,6 +61,7 @@ class JournalRepository extends BaseRepository implements CacheableInterface
'currency' => config('phpvms.currency'),
'memo' => $memo,
'post_date' => $post_date ?? Carbon::now(),
+ 'transaction_group' => $transaction_group,
];
if($reference !== null) {
@@ -68,11 +69,6 @@ class JournalRepository extends BaseRepository implements CacheableInterface
$attrs['ref_class_id'] = $reference->id;
}
- if($transaction_group) {
- $transaction_group = str_replace(' ', '_', $transaction_group);
- $attrs['transaction_group'] = $transaction_group;
- }
-
try {
$transaction = $this->create($attrs);
} catch (ValidatorException $e) {
diff --git a/app/Services/FinanceService.php b/app/Services/FinanceService.php
index 3cea9525..3e359e89 100644
--- a/app/Services/FinanceService.php
+++ b/app/Services/FinanceService.php
@@ -7,7 +7,7 @@ use App\Models\Enums\ExpenseType;
use App\Models\Enums\PirepSource;
use App\Models\Expense;
use App\Models\Pirep;
-use App\Models\SubfleetExpense;
+use App\Models\Subfleet;
use App\Repositories\ExpenseRepository;
use App\Repositories\JournalRepository;
use App\Support\Math;
@@ -178,8 +178,9 @@ class FinanceService extends BaseService
public function paySubfleetExpenses(Pirep $pirep)
{
$subfleet = $pirep->aircraft->subfleet;
- $subfleet_expenses = SubfleetExpense::where([
- 'subfleet_id' => $subfleet->id,
+ $subfleet_expenses = Expense::where([
+ 'ref_class' => Subfleet::class,
+ 'ref_class_id' => $subfleet->id,
])->get();
if(!$subfleet_expenses) {
@@ -344,8 +345,11 @@ class FinanceService extends BaseService
{
$event_expenses = [];
- $expenses = $this->expenseRepo
- ->getAllForType(ExpenseType::FLIGHT, $pirep->airline_id);
+ $expenses = $this->expenseRepo->getAllForType(
+ ExpenseType::FLIGHT,
+ $pirep->airline_id,
+ Expense::class
+ );
/**
* Go through the expenses and apply a mulitplier if present
diff --git a/app/helpers.php b/app/helpers.php
index 3d28f4f5..d1014297 100644
--- a/app/helpers.php
+++ b/app/helpers.php
@@ -56,6 +56,31 @@ if(!function_exists('list_to_assoc')) {
}
}
+if(!function_exists('list_to_editable')) {
+ /**
+ * Convert a list (select box) into an editable list
+ * https://vitalets.github.io/x-editable/docs.html#select
+ * Takes a list of:
+ * [value => text, valueN => textN, ...]
+ * Return:
+ * [{value: 1, text: "text1"}, {value: 2, text: "text2"}, ...]
+ * @param array $list
+ * @return array
+ */
+ function list_to_editable(array $list)
+ {
+ $editable = [];
+ foreach($list as $value => $key) {
+ $editable[] = [
+ 'text' => $key,
+ 'value' => $value,
+ ];
+ }
+
+ return $editable;
+ }
+}
+
if (!function_exists('skin_view')) {
/**
* Render a skin
diff --git a/resources/views/admin/expenses/index.blade.php b/resources/views/admin/expenses/index.blade.php
index b595d02c..724289fe 100644
--- a/resources/views/admin/expenses/index.blade.php
+++ b/resources/views/admin/expenses/index.blade.php
@@ -14,7 +14,7 @@
@if(!filled($expenses))
- You must add a subfleet before you can add an aircraft!
+ There are no expenses
@else
@include('admin.expenses.table')
diff --git a/resources/views/admin/subfleets/expenses.blade.php b/resources/views/admin/subfleets/expenses.blade.php
index b8987072..e2e867b2 100644
--- a/resources/views/admin/subfleets/expenses.blade.php
+++ b/resources/views/admin/subfleets/expenses.blade.php
@@ -11,6 +11,7 @@
Name |
Cost {!! currency(config('phpvms.currency')) !!} |
+ Type |
|
@endif
@@ -19,16 +20,24 @@
|
- {!! $expense->name !!}
|
- {!! $expense->amount !!}
|
+
+
+ {!! \App\Models\Enums\ExpenseType::label($expense->type) !!}
+
+ |
{!! Form::open(['url' => url('/admin/subfleets/'.$subfleet->id.'/expenses'),
'method' => 'delete', 'class' => 'modify_expense form-inline']) !!}
@@ -49,8 +58,9 @@
{!! Form::open(['url' => url('/admin/subfleets/'.$subfleet->id.'/expenses'),
'method' => 'post', 'class' => 'modify_expense form-inline']) !!}
- {!! Form::input('text', 'name', null, ['class' => 'form-control input-sm']) !!}
- {!! Form::number('cost', null, ['class' => 'form-control input-sm']) !!}
+ {!! Form::input('text', 'name', null, ['class' => 'form-control input-sm', 'placeholder' => 'Name']) !!}
+ {!! Form::number('cost', null, ['class' => 'form-control input-sm', 'placeholder' => 'Amount']) !!}
+ {!! Form::select('type', \App\Models\Enums\ExpenseType::select(), null, ['class' => 'select2']) !!}
{!! Form::button(' Add', ['type' => 'submit',
'class' => 'btn btn-success btn-small']) !!}
{!! Form::close() !!}
diff --git a/resources/views/admin/subfleets/script.blade.php b/resources/views/admin/subfleets/script.blade.php
index 818586a6..925dfa87 100644
--- a/resources/views/admin/subfleets/script.blade.php
+++ b/resources/views/admin/subfleets/script.blade.php
@@ -33,9 +33,7 @@ function setEditable() {
}
});
- $('#subfleet-expenses a').editable({
- type: 'text',
- mode: 'inline',
+ $('#subfleet-expenses a.text').editable({
emptytext: '0',
url: '{!! url('/admin/subfleets/'.$subfleet->id.'/expenses') !!}',
title: 'Enter override value',
@@ -48,6 +46,23 @@ function setEditable() {
}
}
});
+
+ $('#subfleet-expenses a.dropdown').editable({
+ type: 'select',
+ emptytext: '0',
+ source: {!! json_encode(list_to_editable(\App\Models\Enums\ExpenseType::select())) !!},
+ url: '{!! url('/admin/subfleets/'.$subfleet->id.'/expenses') !!}',
+ title: 'Enter override value',
+ ajaxOptions: {'type': 'put'},
+ params: function (params) {
+ console.log(params);
+ return {
+ expense_id: params.pk,
+ name: params.name,
+ value: params.value
+ }
+ }
+ });
}
$(document).ready(function() {
diff --git a/tests/FinanceTest.php b/tests/FinanceTest.php
index ce352066..cd803c9d 100644
--- a/tests/FinanceTest.php
+++ b/tests/FinanceTest.php
@@ -98,8 +98,9 @@ class FinanceTest extends TestCase
]);
# Add a subfleet expense
- factory(App\Models\SubfleetExpense::class)->create([
- 'subfleet_id' => $subfleet['subfleet']->id,
+ factory(App\Models\Expense::class)->create([
+ 'ref_class' => \App\Models\Subfleet::class,
+ 'ref_class_id' => $subfleet['subfleet']->id,
'amount' => 200
]);
@@ -570,7 +571,7 @@ class FinanceTest extends TestCase
$airline = factory(App\Models\Airline::class)->create();
$airline2 = factory(App\Models\Airline::class)->create();
- factory(App\Models\Expense::class)->create([
+ $expense = factory(App\Models\Expense::class)->create([
'airline_id' => $airline->id
]);
@@ -582,8 +583,11 @@ class FinanceTest extends TestCase
'airline_id' => null
]);
- $expenses = $this->expenseRepo
- ->getAllForType(ExpenseType::FLIGHT, $airline->id);
+ $expenses = $this->expenseRepo->getAllForType(
+ ExpenseType::FLIGHT,
+ $airline->id,
+ \App\Models\Expense::class
+ );
$this->assertCount(2, $expenses);
@@ -632,11 +636,11 @@ class FinanceTest extends TestCase
# Check that all the different transaction types are there
$transaction_types = [
- 'expenses' => 1,
- 'fares' => 3,
- 'ground_handling' => 1,
- 'pilot_pay' => 2, # debit on the airline, credit to the pilot
- 'subfleet_expense' => 1,
+ 'Expenses' => 1,
+ 'Fares' => 3,
+ 'Ground Handling' => 1,
+ 'Pilot Pay' => 2, # debit on the airline, credit to the pilot
+ 'Subfleet Expense' => 1,
];
foreach($transaction_types as $type => $count) {
|