Repository: nabeelio/phpvms (php)

Issue:
Subfleet and Aircraft Expenses Being Applied to Wrong Airline
Subfleet and Aircraft based expenses are being applied to all airlines, even to airlines without subfleets/aircraft.

**Version**
7.0.0-dev+231215.655f15

**To Reproduce**
Steps to reproduce the behavior:
1. Go to Admin > Fleets, pick one subfleet and click edit
2. Add some daily expenses to the subfleet
3. Either wait for daily cron to run at midnight or force run it
4. Check your cron log, you will see that the expense is applied to other airlines and subfleets too (!)
5. Also check your finances, or better transactions, you will see that the expense is applied at all assets (!)

**Expected behavior**
Daily / Monthly expenses should be applied to *relevant* subfleets / aircraft, not to all.

**Additional context**
Looks like there are logical problems while picking up proper objects.

![image](https://github.com/nabeelio/phpvms/assets/74361521/33454925-9078-4cac-b20a-7f48e33598b2)

![image](https://github.com/nabeelio/phpvms/assets/74361521/3bd69341-6110-4eb7-a422-9f174e3aa5eb)

![image](https://github.com/nabeelio/phpvms/assets/74361521/9e94cd07-bc42-47ab-89b4-13416428bb38)

```
[2023-12-16 16:02:49] production.INFO: Nightly: Applying daily expenses  
[2023-12-16 16:02:49] production.INFO: Charging to DSH  
[2023-12-16 16:02:49] production.INFO: Charging to DSC  
[2023-12-16 16:02:49] production.INFO: Charging to DSH  
[2023-12-16 16:02:49] production.INFO: Expense memo: "Subfleet Expense: Daily Check"; group: "Subfleet: Daily Check" charged!  
[2023-12-16 16:02:49] production.INFO: Charging to DSC  
[2023-12-16 16:02:49] production.INFO: Expense memo: "Subfleet Expense: Daily Check"; group: "Subfleet: Daily Check" charged!  
[2023-12-16 16:02:49] production.INFO: Nightly: Recalculating balances  
```
```
[2023-12-16 16:02:59] production.INFO: Monthly: Applying monthly expenses  
[2023-12-16 16:02:59] production.INFO: Charging to DSH  
[2023-12-16 16:02:59] production.INFO: Charging to DSC  
[2023-12-16 16:02:59] production.INFO: Charging to DSH  
[2023-12-16 16:02:59] production.INFO: Expense memo: "Subfleet Expense: Leasing Payments"; group: "Subfleet: Leasing Payments" charged!  
[2023-12-16 16:02:59] production.INFO: Charging to DSC  
[2023-12-16 16:02:59] production.INFO: Expense memo: "Subfleet Expense: Leasing Payments"; group: "Subfleet: Leasing Payments" charged!  
[2023-12-16 16:02:59] production.INFO: Charging to DSH  
[2023-12-16 16:02:59] production.INFO: Expense memo: "Aircraft Expense: Aircraft Leasing Expenses (TC-DSP)"; group: "Aircraft: Aircraft Leasing Expenses (TC-DSP-TC-DSP)" charged!  
[2023-12-16 16:02:59] production.INFO: Charging to DSC  
[2023-12-16 16:02:59] production.INFO: Expense memo: "Aircraft Expense: Aircraft Leasing Expenses (TC-DSP)"; group: "Aircraft: Aircraft Leasing Expenses (TC-DSP-TC-DSP)" charged!  
```

![image](https://github.com/nabeelio/phpvms/assets/74361521/a4435af1-a2ed-4273-b4b0-e2149d86604d)


Pull request description:
Make sure airline IDs are added to the expense
Closes #1723 

Patch:
diff --git a/app/Database/migrations_data/2023_12_19_174436_correct_expenses.php b/app/Database/migrations_data/2023_12_19_174436_correct_expenses.php
new file mode 100644
index 00000000..7c9aee64
--- /dev/null
+++ b/app/Database/migrations_data/2023_12_19_174436_correct_expenses.php
@@ -0,0 +1,49 @@
+<?php
+
+use App\Contracts\Migration;
+use App\Models\Expense;
+
+/**
+ * Update the expenses to add the airline ID
+ */
+return new class() extends Migration {
+    public function up(): void
+    {
+        /** @var Expense[] $all_expenses */
+        $all_expenses = Expense::all();
+        foreach ($all_expenses as $expense) {
+            $this->getAirlineId($expense);
+        }
+    }
+
+    /**
+     * Figure out the airline ID
+     *
+     * @param Expense $expense
+     *
+     * @return void
+     */
+    public function getAirlineId(Expense $expense): void
+    {
+        $klass = 'Expense';
+        if ($expense->ref_model) {
+            $ref = explode('\\', $expense->ref_model);
+            $klass = end($ref);
+            $obj = $expense->getReferencedObject();
+        }
+
+        if (empty($obj)) {
+            return;
+        }
+
+        if ($klass === 'Airport') {
+            // TODO: Get an airline ID?
+        } elseif ($klass === 'Subfleet') {
+            $expense->airline_id = $obj->airline_id;
+        } elseif ($klass === 'Aircraft') {
+            $expense->airline_id = $obj->airline->id;
+        }
+
+        $expense->save();
+    }
+};
diff --git a/app/Http/Controllers/Admin/AircraftController.php b/app/Http/Controllers/Admin/AircraftController.php
index 79f66bc9..5cb8208a 100644
--- a/app/Http/Controllers/Admin/AircraftController.php
+++ b/app/Http/Controllers/Admin/AircraftController.php
@@ -15,6 +15,7 @@ use App\Repositories\AircraftRepository;
 use App\Repositories\AirportRepository;
 use App\Services\ExportService;
 use App\Services\FileService;
+use App\Services\FinanceService;
 use App\Services\ImportService;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
@@ -26,19 +27,12 @@ class AircraftController extends Controller
 {
     use Importable;
 
-    /**
-     * AircraftController constructor.
-     *
-     * @param AirportRepository  $airportRepo
-     * @param AircraftRepository $aircraftRepo
-     * @param FileService        $fileSvc
-     * @param ImportService      $importSvc
-     */
     public function __construct(
         private readonly AirportRepository $airportRepo,
         private readonly AircraftRepository $aircraftRepo,
         private readonly FileService $fileSvc,
         private readonly ImportService $importSvc,
+        private readonly FinanceService $financeSvc,
     ) {
     }
 
@@ -317,7 +311,8 @@ class AircraftController extends Controller
      */
     public function expenses(int $id, Request $request): View
     {
-        $aircraft = $this->aircraftRepo->findWithoutFail($id);
+        /** @var Aircraft $aircraft */
+        $aircraft = $this->aircraftRepo->with('airline')->findWithoutFail($id);
         if (empty($aircraft)) {
             return $this->return_expenses_view($aircraft);
         }
@@ -327,10 +322,11 @@ class AircraftController extends Controller
         }
 
         if ($request->isMethod('post')) {
-            $expense = new Expense($request->post());
-            $expense->ref_model = Aircraft::class;
-            $expense->ref_model_id = $aircraft->id;
-            $expense->save();
+            $this->financeSvc->addExpense(
+                $request->post(),
+                $aircraft,
+                $aircraft->airline->id
+            );
         } elseif ($request->isMethod('put')) {
             $expense = Expense::findOrFail($request->input('expense_id'));
             $expense->{$request->name} = $request->value;
diff --git a/app/Http/Controllers/Admin/AirportController.php b/app/Http/Controllers/Admin/AirportController.php
index 81645d66..680f2c37 100644
--- a/app/Http/Controllers/Admin/AirportController.php
+++ b/app/Http/Controllers/Admin/AirportController.php
@@ -13,6 +13,7 @@ use App\Repositories\AirportRepository;
 use App\Repositories\Criteria\WhereCriteria;
 use App\Services\ExportService;
 use App\Services\FileService;
+use App\Services\FinanceService;
 use App\Services\ImportService;
 use App\Support\Timezonelist;
 use Illuminate\Http\RedirectResponse;
@@ -25,15 +26,11 @@ class AirportController extends Controller
 {
     use Importable;
 
-    /**
-     * @param AirportRepository $airportRepo
-     * @param FileService       $fileSvc
-     * @param ImportService     $importSvc
-     */
     public function __construct(
         private readonly AirportRepository $airportRepo,
         private readonly FileService $fileSvc,
         private readonly ImportService $importSvc,
+        private readonly FinanceService $financeSvc,
     ) {
     }
 
@@ -270,10 +267,10 @@ class AirportController extends Controller
         }
 
         if ($request->isMethod('post')) {
-            $expense = new Expense($request->post());
-            $expense->ref_model = Airport::class;
-            $expense->ref_model_id = $airport->id;
-            $expense->save();
+            $this->financeSvc->addExpense(
+                $request->post(),
+                $airport,
+            );
         } elseif ($request->isMethod('put')) {
             $expense = Expense::findOrFail($request->input('expense_id'));
             $expense->{$request->name} = $request->value;
diff --git a/app/Http/Controllers/Admin/ExpenseController.php b/app/Http/Controllers/Admin/ExpenseController.php
index 1c0f864e..f3247495 100644
--- a/app/Http/Controllers/Admin/ExpenseController.php
+++ b/app/Http/Controllers/Admin/ExpenseController.php
@@ -11,6 +11,7 @@ use App\Models\Expense;
 use App\Repositories\AirlineRepository;
 use App\Repositories\ExpenseRepository;
 use App\Services\ExportService;
+use App\Services\FinanceService;
 use App\Services\ImportService;
 use Illuminate\Http\RedirectResponse;
 use Illuminate\Http\Request;
@@ -23,17 +24,11 @@ class ExpenseController extends Controller
 {
     use Importable;
 
-    /**
-     * expensesController constructor.
-     *
-     * @param AirlineRepository $airlineRepo
-     * @param ExpenseRepository $expenseRepo
-     * @param ImportService     $importSvc
-     */
     public function __construct(
         private readonly AirlineRepository $airlineRepo,
         private readonly ExpenseRepository $expenseRepo,
-        private readonly ImportService $importSvc
+        private readonly ImportService $importSvc,
+        private readonly FinanceService $financeSvc,
     ) {
     }
 
@@ -81,9 +76,7 @@ class ExpenseController extends Controller
      */
     public function store(Request $request): RedirectResponse
     {
-        $input = $request->all();
-        $input['ref_model'] = Expense::class;
-        $this->expenseRepo->create($input);
+        $this->financeSvc->addExpense($request->all(), null, null);
 
         Flash::success('Expense saved successfully.');
 
diff --git a/app/Http/Controllers/Admin/SubfleetController.php b/app/Http/Controllers/Admin/SubfleetController.php
index 680f6ce9..c52dbc7e 100644
--- a/app/Http/Controllers/Admin/SubfleetController.php
+++ b/app/Http/Controllers/Admin/SubfleetController.php
@@ -21,6 +21,7 @@ use App\Repositories\TypeRatingRepository;
 use App\Services\ExportService;
 use App\Services\FareService;
 use App\Services\FileService;
+use App\Services\FinanceService;
 use App\Services\FleetService;
 use App\Services\ImportService;
 use Illuminate\Http\RedirectResponse;
@@ -34,19 +35,6 @@ class SubfleetController extends Controller
 {
     use Importable;
 
-    /**
-     * SubfleetController constructor.
-     *
-     * @param AircraftRepository   $aircraftRepo
-     * @param FareRepository       $fareRepo
-     * @param FareService          $fareSvc
-     * @param FileService          $fileSvc
-     * @param FleetService         $fleetSvc
-     * @param ImportService        $importSvc
-     * @param RankRepository       $rankRepo
-     * @param SubfleetRepository   $subfleetRepo
-     * @param TypeRatingRepository $typeratingRepo
-     */
     public function __construct(
         private readonly AircraftRepository $aircraftRepo,
         private readonly FareRepository $fareRepo,
@@ -56,7 +44,8 @@ class SubfleetController extends Controller
         private readonly ImportService $importSvc,
         private readonly RankRepository $rankRepo,
         private readonly SubfleetRepository $subfleetRepo,
-        private readonly TypeRatingRepository $typeratingRepo
+        private readonly TypeRatingRepository $typeratingRepo,
+        private readonly FinanceService $financeSvc,
     ) {
     }
 
@@ -445,6 +434,7 @@ class SubfleetController extends Controller
      */
     public function expenses(int $id, Request $request): View
     {
+        /** @var Subfleet $subfleet */
         $subfleet = $this->subfleetRepo->findWithoutFail($id);
         if (empty($subfleet)) {
             return $this->return_expenses_view($subfleet);
@@ -458,10 +448,11 @@ class SubfleetController extends Controller
          * update specific rank data
          */
         if ($request->isMethod('post')) {
-            $expense = new Expense($request->post());
-            $expense->ref_model = Subfleet::class;
-            $expense->ref_model_id = $subfleet->id;
-            $expense->save();
+            $this->financeSvc->addExpense(
+                $request->post(),
+                $subfleet,
+                $subfleet->airline_id
+            );
         } elseif ($request->isMethod('put')) {
             $expense = Expense::findOrFail($request->input('expense_id'));
             $expense->{$request->name} = $request->value;
diff --git a/app/Models/Aircraft.php b/app/Models/Aircraft.php
index 0f285505..7a132186 100644
--- a/app/Models/Aircraft.php
+++ b/app/Models/Aircraft.php
@@ -40,6 +40,7 @@ use Znck\Eloquent\Traits\BelongsToThrough;
  * @property Airport  airport
  * @property Airport  hub
  * @property Airport  home
+ * @property Airline  airline
  * @property Subfleet subfleet
  * @property int      status
  * @property int      state
diff --git a/app/Models/Traits/JournalTrait.php b/app/Models/Traits/JournalTrait.php
index 9198360a..22d18215 100644
--- a/app/Models/Traits/JournalTrait.php
+++ b/app/Models/Traits/JournalTrait.php
@@ -3,13 +3,14 @@
 namespace App\Models\Traits;
 
 use App\Models\Journal;
+use Illuminate\Database\Eloquent\Relations\MorphOne;
 
 trait JournalTrait
 {
     /**
      * Initialize a new journal when a new record is created
      */
-    public static function bootJournalTrait()
+    public static function bootJournalTrait(): void
     {
         static::created(function ($model) {
             $model->initJournal(setting('units.currency'));
@@ -21,7 +22,7 @@ trait JournalTrait
      *
      * @return mixed
      */
-    public function journal()
+    public function journal(): MorphOne
     {
         return $this->morphOne(Journal::class, 'morphed');
     }
@@ -35,7 +36,7 @@ trait JournalTrait
      *
      * @return Journal
      */
-    public function initJournal($currency_code = 'USD')
+    public function initJournal(string $currency_code = 'USD')
     {
         if (!$this->journal) {
             $journal = new Journal();
diff --git a/app/Services/Finance/RecurringFinanceService.php b/app/Services/Finance/RecurringFinanceService.php
index b84f6f32..0f17221f 100644
--- a/app/Services/Finance/RecurringFinanceService.php
+++ b/app/Services/Finance/RecurringFinanceService.php
@@ -6,6 +6,7 @@ use App\Contracts\Service;
 use App\Models\Airline;
 use App\Models\Enums\ExpenseType;
 use App\Models\Expense;
+use App\Models\Journal;
 use App\Models\JournalTransaction;
 use App\Services\FinanceService;
 use App\Support\Money;
@@ -28,21 +29,23 @@ class RecurringFinanceService extends Service
      *
      * @param Expense $expense
      *
-     * @return \Generator
+     * @return Journal[]
      */
     protected function findJournals(Expense $expense)
     {
         if ($expense->airline_id) {
-            $airline = Airline::find($expense->airline_id)->first(['id', 'icao']);
-            Log::info('Charging to '.$airline->icao);
-            yield $airline->journal;
-        } else {
-            $airlines = Airline::all(['id', 'icao']);
-            foreach ($airlines as $airline) {
-                Log::info('Charging to '.$airline->icao);
-                yield $airline->journal;
-            }
+            return Journal::where([
+                'morphed_type' => Airline::class,
+                'morphed_id'   => $expense->airline_id,
+            ])
+                ->get();
         }
+
+        $airline_ids = Airline::get(['id'])->pluck('id')->all();
+
+        return Journal::where(['morphed_type' => Airline::class])
+            ->whereIn('morphed_id', $airline_ids)
+            ->get();
     }
 
     /**
@@ -89,7 +92,7 @@ class RecurringFinanceService extends Service
      *
      * @throws \Prettus\Validator\Exceptions\ValidatorException
      */
-    public function processExpenses($type = ExpenseType::DAILY): void
+    public function processExpenses(string $type = ExpenseType::DAILY): void
     {
         $expenses = Expense::where(['type' => $type])->get();
 
@@ -117,6 +120,9 @@ class RecurringFinanceService extends Service
                     'ref_model_id' => $expense->id,
                 ];
 
+                $ref = explode('\\', $expense->ref_model);
+                $type = end($ref);
+
                 $found = JournalTransaction::where($w)
                     ->whereDate('post_date', '=', Carbon::now('UTC')->toDateString())
                     ->count(['id']);
@@ -131,6 +137,17 @@ class RecurringFinanceService extends Service
                     continue;
                 }
 
+                // Determine if this object actually belongs to this airline or not
+                if ($type === 'Subfleet' || $type === 'Aircraft') {
+                    $ref_model = $expense->ref_model()->with('airline')->first();
+                    if ($ref_model?->airline?->id !== $journal->morphed_id) {
+                        Log::info(
+                            $type.' id '.$expense->ref_model_id.' does not belong to airline id '.$expense->airline_id.', skipping expense "'.$expense->name.'"'
+                        );
+                        continue;
+                    }
+                }
+
                 $this->financeSvc->debitFromJournal(
                     $journal,
                     Money::createFromAmount($amount),
diff --git a/app/Services/FinanceService.php b/app/Services/FinanceService.php
index 3a2723f5..8a2d3727 100644
--- a/app/Services/FinanceService.php
+++ b/app/Services/FinanceService.php
@@ -2,8 +2,10 @@
 
 namespace App\Services;
 
+use App\Contracts\Model;
 use App\Contracts\Service;
 use App\Models\Airline;
+use App\Models\Expense;
 use App\Models\Journal;
 use App\Models\JournalTransaction;
 use App\Repositories\AirlineRepository;
@@ -19,6 +21,40 @@ class FinanceService extends Service
     ) {
     }
 
+    /**
+     * Add an expense, and properly tie it to a model, and know which
+     * airline this needs to be charged to
+     *
+     * @param array      $attrs      Array of attributes
+     * @param Model|null $model      The model this expense is tied to
+     * @param int|null   $airline_id The airline this expense should get charged to
+     *
+     * @return Expense
+     */
+    public function addExpense(array $attrs, Model $model = null, int $airline_id = null): Expense
+    {
+        $expense = new Expense($attrs);
+
+        if (!empty($model)) {
+            $expense->ref_model = get_class($model);
+
+            // In case it's a generic expense not tied to a specific instance
+            if (!empty($model->id)) {
+                $expense->ref_model_id = $model->id;
+            }
+        } else {
+            $expense->ref_model = Expense::class;
+        }
+
+        if (!empty($airline_id)) {
+            $expense->airline_id = $airline_id;
+        }
+
+        $expense->save();
+
+        return $expense;
+    }
+
     /**
      * Credit some amount to a given journal
      * E.g, some amount for expenses or ground handling fees, etc. Example, to pay a user a dollar
@@ -137,10 +173,12 @@ class FinanceService extends Service
     {
         // Return all the transactions, grouped by the transaction group
         $transactions = JournalTransaction::groupBy('transaction_group', 'currency')
-            ->selectRaw('transaction_group, 
+            ->selectRaw(
+                'transaction_group, 
                          currency, 
                          SUM(credit) as sum_credits, 
-                         SUM(debit) as sum_debits')
+                         SUM(debit) as sum_debits'
+            )
             ->where(['journal_id' => $airline->journal->id])
             ->whereBetween('created_at', [$start_date, $end_date], 'AND')
             ->orderBy('sum_credits', 'desc')


Test patch:
diff --git a/tests/FinanceTest.php b/tests/FinanceTest.php
index c57d7e4b..bd8a8649 100644
--- a/tests/FinanceTest.php
+++ b/tests/FinanceTest.php
@@ -21,6 +21,8 @@ use App\Repositories\JournalRepository;
 use App\Services\BidService;
 use App\Services\FareService;
 use App\Services\Finance\PirepFinanceService;
+use App\Services\Finance\RecurringFinanceService;
+use App\Services\FinanceService;
 use App\Services\FleetService;
 use App\Services\PirepService;
 use App\Support\Math;
@@ -68,7 +70,7 @@ final class FinanceTest extends TestCase
      *
      * @return array
      */
-    public function createFullPirep(): array
+    public function createFullPirep(Airline $airline = null): array
     {
         /**
          * Setup tests
@@ -96,9 +98,16 @@ final class FinanceTest extends TestCase
         ]);
 
         /** @var User $user */
-        $user = User::factory()->create([
+        $u = [
             'rank_id' => $rank->id,
-        ]);
+        ];
+
+        if (!empty($airline)) {
+            $u['airline_id'] = $airline->id;
+        }
+
+        $user = User::factory()->create($u);
+        $user->airline->initJournal('USD');
 
         /** @var Flight $flight */
         $flight = Flight::factory()->create([
@@ -378,7 +387,8 @@ final class FinanceTest extends TestCase
         // set an override now
         //
         $this->fareSvc->setForSubfleet($subfleet, $fare, [
-            'price' => 50, 'capacity' => 400,
+            'price'    => 50,
+            'capacity' => 400,
         ]);
 
         // look for them again
@@ -399,7 +409,8 @@ final class FinanceTest extends TestCase
         $fare = Fare::factory()->create();
 
         $this->fareSvc->setForSubfleet($subfleet, $fare, [
-            'price' => 50, 'capacity' => 400,
+            'price'    => 50,
+            'capacity' => 400,
         ]);
 
         $ac_fares = $this->fareSvc->getForSubfleet($subfleet);
@@ -413,7 +424,8 @@ final class FinanceTest extends TestCase
         //
 
         $this->fareSvc->setForSubfleet($subfleet, $fare, [
-            'price' => 150, 'capacity' => 50,
+            'price'    => 150,
+            'capacity' => 50,
         ]);
 
         $ac_fares = $this->fareSvc->getForSubfleet($subfleet);
@@ -558,8 +570,6 @@ final class FinanceTest extends TestCase
 
     /**
      * Get the pilot pay, derived from the rank
-     *
-     * @throws Exception
      */
     public function testGetPilotPayNoOverride(): void
     {
@@ -583,8 +593,6 @@ final class FinanceTest extends TestCase
 
     /**
      * Get the pilot pay, but include different overrides
-     *
-     * @throws Exception
      */
     public function testGetPilotPayWithOverride(): void
     {
@@ -636,8 +644,6 @@ final class FinanceTest extends TestCase
 
     /**
      * Get the payment for a pilot
-     *
-     * @throws Exception
      */
     public function testGetPirepPilotPay(): void
     {
@@ -995,7 +1001,7 @@ final class FinanceTest extends TestCase
 
         $transactions = $journalRepo->getAllForObject($pirep);
 
-//        $this->assertCount(9, $transactions['transactions']);
+        //        $this->assertCount(9, $transactions['transactions']);
         $this->assertEquals(3020, $transactions['credits']->getValue());
         $this->assertEquals(2050.4, $transactions['debits']->getValue());
 
@@ -1092,6 +1098,7 @@ final class FinanceTest extends TestCase
         /** @var Airline $airline */
         $airline = Airline::factory()->create();
 
+        /** @var JournalRepository $journalRepo */
         $journalRepo = app(JournalRepository::class);
 
         // Add an expense that's only for a cargo flight
@@ -1175,4 +1182,71 @@ final class FinanceTest extends TestCase
         $this->assertEquals(3020, $transactions['credits']->getValue());
         $this->assertEquals(2050.4, $transactions['debits']->getValue());
     }
+
+    /**
+     * Test that all expenses are pulled properly
+     */
+    public function testPirepExpensesNightly()
+    {
+        /** @var JournalRepository $journalRepo */
+        $journalRepo = app(JournalRepository::class);
+
+        /** @var Airline $airline */
+        $airline = Airline::factory()->create();
+
+        /** @var Airline $airline2 */
+        $airline2 = Airline::factory()->create();
+
+        Expense::factory()->create([
+            'airline_id' => null,
+            'type'       => ExpenseType::DAILY,
+        ]);
+
+        Expense::factory()->create([
+            'airline_id' => $airline->id,
+            'type'       => ExpenseType::DAILY,
+        ]);
+
+        Expense::factory()->create([
+            'airline_id' => $airline2->id,
+            'type'       => ExpenseType::DAILY,
+        ]);
+
+        Expense::factory()->create([
+            'airline_id' => null,
+            'type'       => ExpenseType::DAILY,
+        ]);
+
+        /*
+         * Test the subfleet class
+         */
+
+        $subfleet = Subfleet::factory()->create();
+        $subfleet2 = Subfleet::factory()->create();
+
+        /** @var FinanceService $financeSvc */
+        $financeSvc = app(FinanceService::class);
+
+        $exp = Expense::factory()->make([
+            'airline_id' => null,
+            'type'       => ExpenseType::DAILY,
+        ]);
+
+        $financeSvc->addExpense($exp->toArray(), $subfleet);
+
+        [$user, $pirep, $fares] = $this->createFullPirep();
+        $pirep = $this->pirepSvc->accept($pirep);
+
+        // $transactions = $journalRepo->getAllForObject($pirep);
+        $txn_airline1 = $journalRepo->getAllForObject($airline);
+        $txn_airline2 = $journalRepo->getAllForObject($airline2);
+
+        /** @var RecurringFinanceService $recurringFService */
+        $recurringFService = app(RecurringFinanceService::class);
+        $recurringFService->processExpenses(ExpenseType::DAILY);
+
+        $txn_airline1 = $journalRepo->getAllForObject($airline);
+        $txn_airline2 = $journalRepo->getAllForObject($airline2);
+        // dd($txn_airline1);
+    }
 }