Post fares/expenses on PIREP to Airline journal #130
This commit is contained in:
@@ -4,6 +4,8 @@ namespace App\Services;
|
||||
|
||||
use App\Models\Fare;
|
||||
use App\Models\Flight;
|
||||
use App\Models\Pirep;
|
||||
use App\Models\PirepFare;
|
||||
use App\Models\Subfleet;
|
||||
use App\Support\Math;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -184,4 +186,47 @@ class FareService extends BaseService
|
||||
$subfleet->refresh();
|
||||
return $subfleet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fares for a PIREP, this just returns the PirepFare
|
||||
* model which includes the counts for that particular fare
|
||||
* @param Pirep $pirep
|
||||
* @return Collection
|
||||
*/
|
||||
public function getForPirep(Pirep $pirep)
|
||||
{
|
||||
$fares = [];
|
||||
$found_fares = PirepFare::where('pirep_id', $pirep->id)->get();
|
||||
return $found_fares;
|
||||
/*foreach($found_fares as $fare) {
|
||||
$fares[] = $fare->toArray();
|
||||
}
|
||||
|
||||
return collect($fares);*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the list of fares
|
||||
* @param Pirep $pirep
|
||||
* @param array $fares ['fare_id', 'count']
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function saveForPirep(Pirep $pirep, array $fares)
|
||||
{
|
||||
if (!$fares) {
|
||||
return;
|
||||
}
|
||||
|
||||
# Remove all the previous fares
|
||||
PirepFare::where('pirep_id', $pirep->id)->delete();
|
||||
|
||||
# Add them in
|
||||
foreach ($fares as $fare) {
|
||||
$fare['pirep_id'] = $pirep->id;
|
||||
# other fields: ['fare_id', 'count']
|
||||
|
||||
$field = new PirepFare($fare);
|
||||
$field->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +1,266 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Events\Expenses as ExpensesEvent;
|
||||
use App\Models\Enums\ExpenseType;
|
||||
use App\Models\Enums\PirepSource;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Pirep;
|
||||
use App\Repositories\ExpenseRepository;
|
||||
use App\Repositories\JournalRepository;
|
||||
use App\Support\Math;
|
||||
use App\Support\Money;
|
||||
|
||||
/**
|
||||
* Class FinanceService
|
||||
* @package App\Services
|
||||
*
|
||||
*/
|
||||
class FinanceService extends BaseService
|
||||
{
|
||||
private $fareSvc,
|
||||
$flightSvc;
|
||||
private $expenseRepo,
|
||||
$fareSvc,
|
||||
$journalRepo,
|
||||
$pirepSvc;
|
||||
|
||||
/**
|
||||
* FinanceService constructor.
|
||||
* @param ExpenseRepository $expenseRepo
|
||||
* @param FareService $fareSvc
|
||||
* @param FlightService $flightSvc
|
||||
* @param JournalRepository $journalRepo
|
||||
* @param PIREPService $pirepSvc
|
||||
*/
|
||||
public function __construct(
|
||||
ExpenseRepository $expenseRepo,
|
||||
FareService $fareSvc,
|
||||
FlightService $flightSvc
|
||||
JournalRepository $journalRepo,
|
||||
PIREPService $pirepSvc
|
||||
) {
|
||||
$this->expenseRepo = $expenseRepo;
|
||||
$this->fareSvc = $fareSvc;
|
||||
$this->flightSvc = $flightSvc;
|
||||
$this->journalRepo = $journalRepo;
|
||||
$this->pirepSvc = $pirepSvc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine from the base rate, if we want to return the overridden rate
|
||||
* or if the overridden rate is a percentage, then return that amount
|
||||
* @param $base_rate
|
||||
* @param $override_rate
|
||||
* @return float|null
|
||||
*/
|
||||
public function applyAmountOrPercent($base_rate, $override_rate=null): ?float
|
||||
{
|
||||
if (!$override_rate) {
|
||||
return $base_rate;
|
||||
}
|
||||
|
||||
# Not a percentage override
|
||||
if (substr_count($override_rate, '%') === 0) {
|
||||
return $override_rate;
|
||||
}
|
||||
|
||||
return Math::addPercent($base_rate, $override_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process all of the finances for a pilot report. This is called
|
||||
* from a listener (FinanceEvents)
|
||||
* @param Pirep $pirep
|
||||
* @return mixed
|
||||
* @throws \UnexpectedValueException
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \Prettus\Validator\Exceptions\ValidatorException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function processFinancesForPirep(Pirep $pirep)
|
||||
{
|
||||
$journal = $pirep->airline->journal;
|
||||
if(!$journal) {
|
||||
$journal = $pirep->airline->initJournal(config('phpvms.currency'));
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect all of the fares and then post each fare class's profit and
|
||||
* the costs for each seat and post it to the journal
|
||||
*/
|
||||
|
||||
$fares = $this->getReconciledFaresForPirep($pirep);
|
||||
foreach($fares as $fare) {
|
||||
|
||||
$credit = Money::createFromAmount($fare->count * $fare->price);
|
||||
$debit = Money::createFromAmount($fare->count * $fare->cost);
|
||||
|
||||
$this->journalRepo->post(
|
||||
$journal,
|
||||
$credit,
|
||||
$debit,
|
||||
$pirep,
|
||||
'Fares '. $fare->code.$fare->count
|
||||
. '; price:'.$fare->price .', cost: '. $fare->cost,
|
||||
null,
|
||||
'fares'
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect all of the expenses and apply those to the journal
|
||||
*/
|
||||
$expenses = $this->getExpenses($pirep);
|
||||
foreach($expenses as $expense) {
|
||||
$debit = Money::createFromAmount($expense->amount);
|
||||
$this->journalRepo->post(
|
||||
$journal,
|
||||
null,
|
||||
$debit,
|
||||
$pirep,
|
||||
'Expense: ' . $expense->name,
|
||||
null,
|
||||
'expenses'
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect and apply the ground handling cost
|
||||
*/
|
||||
$ground_handling_cost = $this->getGroundHandlingCost($pirep);
|
||||
$this->journalRepo->post(
|
||||
$journal,
|
||||
null,
|
||||
Money::createFromAmount($ground_handling_cost),
|
||||
$pirep,
|
||||
'Ground handling',
|
||||
null,
|
||||
'ground_handling'
|
||||
);
|
||||
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all of the fares for the PIREP. Reconcile the list;
|
||||
* Get the fares that have been filled out for the PIREP, and
|
||||
* then get the fares for the flight and subfleet. Then merge
|
||||
* them together, and return the final list of:
|
||||
* count = number of pax
|
||||
* price = how much each pax unit paid
|
||||
* capacity = max number of pax units
|
||||
*
|
||||
* If count > capacity, count will be adjusted to capacity
|
||||
* @param $pirep
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function getReconciledFaresForPirep($pirep)
|
||||
{
|
||||
$flight = $this->pirepSvc->findFlight($pirep);
|
||||
|
||||
# Collect all of the fares and prices
|
||||
$flight_fares = $this->fareSvc->getForPirep($pirep);
|
||||
$all_fares = $this->fareSvc->getAllFares($flight, $pirep->aircraft->subfleet);
|
||||
|
||||
$fares = $all_fares->map(function($fare, $i) use ($flight_fares) {
|
||||
|
||||
$fare_count = $flight_fares->whereStrict('id', $fare->id)->first();
|
||||
|
||||
if($fare_count) {
|
||||
# If the count is greater than capacity, then just set it
|
||||
# to the maximum amount
|
||||
if($fare_count->count > $fare->capacity) {
|
||||
$fare->count = $fare->capacity;
|
||||
} else {
|
||||
$fare->count = $fare_count->count;
|
||||
}
|
||||
}
|
||||
|
||||
return $fare;
|
||||
});
|
||||
|
||||
return $fares;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the costs for the ground handling, with the multiplier
|
||||
* being applied from the subfleet
|
||||
* @param Pirep $pirep
|
||||
* @return float|null
|
||||
*/
|
||||
public function getGroundHandlingCost(Pirep $pirep)
|
||||
{
|
||||
if(filled($pirep->aircraft->subfleet->ground_handling_multiplier)) {
|
||||
// force into percent mode
|
||||
$multiplier = $pirep->aircraft->subfleet->ground_handling_multiplier.'%';
|
||||
return $this->applyAmountOrPercent(
|
||||
$pirep->arr_airport->ground_handling_cost,
|
||||
$multiplier
|
||||
);
|
||||
}
|
||||
|
||||
return $pirep->arr_airport->ground_handling_cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send out an event called ExpensesEvent, which picks up any
|
||||
* event listeners and check if they return a list of additional
|
||||
* Expense model objects.
|
||||
* @param Pirep $pirep
|
||||
* @return mixed
|
||||
*/
|
||||
public function getExpenses(Pirep $pirep)
|
||||
{
|
||||
$event_expenses = [];
|
||||
|
||||
$expenses = $this->expenseRepo
|
||||
->getAllForType(ExpenseType::FLIGHT, $pirep->airline_id);
|
||||
|
||||
/**
|
||||
* Go through the expenses and apply a mulitplier if present
|
||||
*/
|
||||
$expenses = $expenses->map(function($expense, $i) use ($pirep) {
|
||||
if(!$expense->multiplier) {
|
||||
return $expense;
|
||||
}
|
||||
|
||||
// TODO Apply the multiplier from the subfleet
|
||||
});
|
||||
|
||||
$gathered_expenses = event(new ExpensesEvent($pirep));
|
||||
if (!\is_array($gathered_expenses)) {
|
||||
return $expenses;
|
||||
}
|
||||
|
||||
foreach ($gathered_expenses as $event_expense) {
|
||||
if (!\is_array($event_expense)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach($event_expense as $expense) {
|
||||
# Make sure it's of type expense Model
|
||||
if(!($expense instanceof Expense)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
# If an airline_id is filled, then see if it matches
|
||||
if($expense->airline_id !== $pirep->airline_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$event_expenses[] = $expense;
|
||||
}
|
||||
}
|
||||
|
||||
$expenses = $expenses->concat($event_expenses);
|
||||
|
||||
return $expenses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the pilot's hourly pay for the given PIREP
|
||||
* @param Pirep $pirep
|
||||
* @return float
|
||||
* @throws \Money\Exception\UnknownCurrencyException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function getPayRateForPirep(Pirep $pirep)
|
||||
public function getPilotPayRateForPirep(Pirep $pirep)
|
||||
{
|
||||
# Get the base rate for the rank
|
||||
$rank = $pirep->user->rank;
|
||||
@@ -55,16 +280,10 @@ class FinanceService extends BaseService
|
||||
$override_rate = $override_rate->manual_pay;
|
||||
}
|
||||
|
||||
if(!$override_rate) {
|
||||
return $base_rate;
|
||||
}
|
||||
|
||||
# Not a percentage override
|
||||
if(substr_count($override_rate, '%') === 0) {
|
||||
return $override_rate;
|
||||
}
|
||||
|
||||
return Math::addPercent($base_rate, $override_rate);
|
||||
return $this->applyAmountOrPercent(
|
||||
$base_rate,
|
||||
$override_rate
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,11 +292,10 @@ class FinanceService extends BaseService
|
||||
* @return Money
|
||||
* @throws \UnexpectedValueException
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \Money\Exception\UnknownCurrencyException
|
||||
*/
|
||||
public function getPilotPilotPay(Pirep $pirep)
|
||||
{
|
||||
$pilot_rate = $this->getPayRateForPirep($pirep) / 60;
|
||||
$pilot_rate = $this->getPilotPayRateForPirep($pirep) / 60;
|
||||
$payment = round($pirep->flight_time * $pilot_rate, 2);
|
||||
|
||||
return Money::createFromAmount($payment);
|
||||
|
||||
@@ -16,6 +16,7 @@ use App\Models\PirepFare;
|
||||
use App\Models\PirepFieldValues;
|
||||
use App\Models\User;
|
||||
use App\Repositories\AcarsRepository;
|
||||
use App\Repositories\FlightRepository;
|
||||
use App\Repositories\NavdataRepository;
|
||||
use App\Repositories\PirepRepository;
|
||||
use Carbon\Carbon;
|
||||
@@ -24,11 +25,12 @@ use Log;
|
||||
|
||||
class PIREPService extends BaseService
|
||||
{
|
||||
protected $acarsRepo,
|
||||
$geoSvc,
|
||||
$navRepo,
|
||||
$pilotSvc,
|
||||
$pirepRepo;
|
||||
private $acarsRepo,
|
||||
$flightRepo,
|
||||
$geoSvc,
|
||||
$navRepo,
|
||||
$pilotSvc,
|
||||
$pirepRepo;
|
||||
|
||||
/**
|
||||
* PIREPService constructor.
|
||||
@@ -40,6 +42,7 @@ class PIREPService extends BaseService
|
||||
*/
|
||||
public function __construct(
|
||||
AcarsRepository $acarsRepo,
|
||||
FlightRepository $flightRepo,
|
||||
GeoService $geoSvc,
|
||||
NavdataRepository $navRepo,
|
||||
PirepRepository $pirepRepo,
|
||||
@@ -47,6 +50,7 @@ class PIREPService extends BaseService
|
||||
)
|
||||
{
|
||||
$this->acarsRepo = $acarsRepo;
|
||||
$this->flightRepo = $flightRepo;
|
||||
$this->geoSvc = $geoSvc;
|
||||
$this->pilotSvc = $pilotSvc;
|
||||
$this->navRepo = $navRepo;
|
||||
@@ -54,6 +58,21 @@ class PIREPService extends BaseService
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the flight that a PIREP is based on
|
||||
* @param Pirep $pirep
|
||||
* @return mixed
|
||||
*/
|
||||
public function findFlight(Pirep $pirep)
|
||||
{
|
||||
return $this->flightRepo->findFlight(
|
||||
$pirep->airline_id,
|
||||
$pirep->flight_number,
|
||||
$pirep->route_code,
|
||||
$pirep->route_leg
|
||||
)->first();
|
||||
}
|
||||
|
||||
/**π
|
||||
* Find if there are duplicates to a given PIREP. Ideally, the passed
|
||||
* in PIREP hasn't been saved or gone through the create() method
|
||||
* @param Pirep $pirep
|
||||
@@ -211,29 +230,6 @@ class PIREPService extends BaseService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the list of fares
|
||||
* @param $pirep_id
|
||||
* @param array $fares ['field_id', 'count']
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function saveFares($pirep_id, array $fares)
|
||||
{
|
||||
if(!$fares) { return; }
|
||||
|
||||
# Remove all the previous fares
|
||||
PirepFare::where('pirep_id', $pirep_id)->delete();
|
||||
|
||||
# Add them in
|
||||
foreach($fares as $fare) {
|
||||
$fare['pirep_id'] = $pirep_id;
|
||||
# other fields: ['fare_id', 'count']
|
||||
|
||||
$field = new PirepFare($fare);
|
||||
$field->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Pirep $pirep
|
||||
* @param int $new_state
|
||||
|
||||
@@ -36,9 +36,10 @@ class UserService extends BaseService
|
||||
/**
|
||||
* Register a pilot. Also attaches the initial roles
|
||||
* required, and then triggers the UserRegistered event
|
||||
* @param User $user User model
|
||||
* @param array $groups Additional groups to assign
|
||||
* @param User $user User model
|
||||
* @param array $groups Additional groups to assign
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function createPilot(User $user, array $groups=null)
|
||||
{
|
||||
@@ -64,6 +65,7 @@ class UserService extends BaseService
|
||||
|
||||
# Let's check their rank and where they should start
|
||||
$this->calculatePilotRank($user);
|
||||
$user->initJournal(config('phpvms.currency'));
|
||||
|
||||
$user->refresh();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user