Implement events for cron expenses; add processing of daily/monthly expenses #136

This commit is contained in:
Nabeel Shahzad
2018-03-16 20:12:56 -05:00
parent d34de098e5
commit 067fb0f9f0
24 changed files with 623 additions and 118 deletions

View File

@@ -3,13 +3,30 @@
namespace App\Console;
use Illuminate\Console\Command;
use Monolog\Handler\StreamHandler;
use Symfony\Component\Process\Process;
class BaseCommand extends Command
{
/**
* Splice the logger and replace the handler to direct
* everything to stdout as well as the log
*/
public function redirectLoggingToStdout()
{
$logger = app(\Illuminate\Log\Logger::class);
$handlers = $logger->getHandlers();
try {
$handlers[] = new StreamHandler('php://stdout');
$logger->setHandlers($handlers);
} catch (\Exception $e) {
$this->error('Couldn\'t splice the logger');
}
}
/**
* Streaming file read
* Streaming file reader
* @param $filename
* @return \Generator
*/
@@ -33,6 +50,8 @@ class BaseCommand extends Command
* @param $cmd
* @param bool $return
* @return string
* @throws \Symfony\Component\Process\Exception\RuntimeException
* @throws \Symfony\Component\Process\Exception\LogicException
*/
public function runCommand($cmd, $return=false, $verbose=true)
{
@@ -46,18 +65,12 @@ class BaseCommand extends Command
$val = '';
$process = new Process($cmd);
$process->run(function ($type, $buffer) use ($return, $val) {
$process->run(function ($type, $buffer) use ($return, &$val) {
if ($return) {
$val .= $buffer;
} else {
echo $buffer;
}
/*if (Process::ERR === $type) {
echo $buffer;
} else {
echo $buffer;
}*/
});
return $val;

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Console\Cron;
use App\Console\BaseCommand;
use App\Events\CronMonthly;
/**
* This just calls the CronMonthly event, so all of the
* listeners, etc can just be called to run those tasks
* @package App\Console\Cron
*/
class Monthly extends BaseCommand
{
protected $signature = 'cron:monthly';
protected $description = 'Run the monthly cron tasks';
protected $schedule;
public function handle(): void
{
$this->redirectLoggingToStdout();
event(new CronMonthly());
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Console\Cron;
use App\Console\BaseCommand;
use App\Events\CronNightly;
/**
* This just calls the CronNightly event, so all of the
* listeners, etc can just be called to run those tasks
* @package App\Console\Cron
*/
class Nightly extends BaseCommand
{
protected $signature = 'cron:nightly';
protected $description = 'Run the nightly cron tasks';
protected $schedule;
public function handle(): void
{
$this->redirectLoggingToStdout();
event(new CronNightly());
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Console\Cron;
use App\Console\BaseCommand;
use App\Events\CronMonthly;
/**
* This just calls the CronWeekly event, so all of the
* listeners, etc can just be called to run those tasks
* @package App\Console\Cron
*/
class Weekly extends BaseCommand
{
protected $signature = 'cron:monthly';
protected $description = 'Run the monthly cron tasks';
protected $schedule;
public function handle(): void
{
$this->redirectLoggingToStdout();
event(new CronMonthly());
}
}

View File

@@ -2,6 +2,9 @@
namespace App\Console;
use App\Console\Cron\Monthly;
use App\Console\Cron\Nightly;
use App\Console\Cron\Weekly;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@@ -25,24 +28,24 @@ class Kernel extends ConsoleKernel
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
protected function schedule(Schedule $schedule): void
{
// $schedule->command('inspire')
// ->hourly();
$schedule->command(Nightly::class)->dailyAt('01:00');
$schedule->command(Weekly::class)->weeklyOn(0);
$schedule->command(Monthly::class)->monthlyOn(1);
}
/**
* Register the Closure based commands for the application.
*
* @return void
*/
protected function commands()
protected function commands(): void
{
require app_path('Routes/console.php');
$this->load(__DIR__ . '/Commands');
$this->load(__DIR__ . '/Cron');
}
}

23
app/Console/Logger.php Normal file
View File

@@ -0,0 +1,23 @@
<?php
namespace App\Console;
use Monolog\Handler\StreamHandler;
/**
* Just a simple custom logger that dumps to the console
* @package App\Console
*/
class Logger
{
public function __invoke(array $config)
{
$logger = new \Monolog\Logger('console');
try {
$logger->pushHandler(new StreamHandler('php://stdout'));
} catch (\Exception $e) {
}
return $logger;
}
}

View File

@@ -25,7 +25,7 @@ class CreateJournalTransactionsTable extends Migration
$table->string('ref_class', 50)->nullable();
$table->string('ref_class_id', 36)->nullable();
$table->timestamps();
$table->dateTime('post_date');
$table->date('post_date');
$table->primary('id');
$table->index('journal_id');

View File

@@ -216,6 +216,22 @@ expenses:
ref_class_id: 1
created_at: now
updated_at: now
- name: Catering Staff
amount: 1000
type: 1
active: 1
ref_class: App\Models\Subfleet
ref_class_id: 1
created_at: now
updated_at: now
- name: Maintenance
amount: 1000
type: 1
active: 1
ref_class: App\Models\Aircraft
ref_class_id: 1
created_at: now
updated_at: now
fares:
- id: 1
@@ -448,7 +464,7 @@ journals:
id: 1
ledger_id: null
type: 0
balance: 23710000
balance: 7870000
currency: USD
morphed_type: App\Models\Airline
morphed_id: 1
@@ -458,7 +474,7 @@ journals:
id: 2
ledger_id: null
type: 1
balance: 45000
balance: 15000
currency: USD
morphed_type: App\Models\User
morphed_id: 1

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
/**
* This event is dispatched when the monthly cron is run
* It happens after all of the default nightly tasks
* @package App\Events
*/
class CronMonthly
{
use Dispatchable, SerializesModels;
public function __construct()
{
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
/**
* This event is dispatched when the daily cron is run
* It happens after all of the default nightly tasks
* @package App\Events
*/
class CronNightly
{
use Dispatchable, SerializesModels;
public function __construct()
{
}
}

21
app/Events/CronWeekly.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
/**
* This event is dispatched when the weekly cron is run
* It happens after all of the default nightly tasks
* @package App\Events
*/
class CronWeekly
{
use Dispatchable, SerializesModels;
public function __construct()
{
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Listeners\Cron\Monthly;
use App\Events\CronMonthly;
use App\Models\Enums\ExpenseType;
use App\Services\Finance\RecurringFinanceService;
/**
* Go through and apply any finances that are daily
* @package App\Listeners\Cron\Nightly
*/
class ApplyExpenses
{
private $dfSvc;
public function __construct(RecurringFinanceService $dfSvc)
{
$this->dfSvc = $dfSvc;
}
/**
* Apply all of the expenses for a month
* @param CronMonthly $event
* @throws \UnexpectedValueException
* @throws \InvalidArgumentException
* @throws \Prettus\Validator\Exceptions\ValidatorException
*/
public function handle(CronMonthly $event)
{
$this->dfSvc->processExpenses(ExpenseType::MONTHLY);
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Listeners\Cron\Nightly;
use App\Events\CronNightly;
use App\Models\Enums\ExpenseType;
use App\Services\Finance\RecurringFinanceService;
/**
* Go through and apply any finances that are daily
* @package App\Listeners\Cron\Nightly
*/
class ApplyExpenses
{
private $dfSvc;
public function __construct(RecurringFinanceService $dfSvc)
{
$this->dfSvc = $dfSvc;
}
/**
* Apply all of the expenses for a day
* @param CronNightly $event
* @throws \UnexpectedValueException
* @throws \InvalidArgumentException
* @throws \Prettus\Validator\Exceptions\ValidatorException
*/
public function handle(CronNightly $event): void
{
$this->dfSvc->processExpenses(ExpenseType::DAILY);
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace App\Listeners\Cron\Nightly;
use App\Events\CronNightly;
use App\Models\Journal;
use App\Models\JournalTransaction;
use App\Repositories\JournalRepository;
use App\Support\Money;
use Log;
/**
* This recalculates the balances on all of the journals
* @package App\Listeners\Cron
*/
class RecalculateBalances
{
private $journalRepo;
/**
* Nightly constructor.
* @param JournalRepository $journalRepo
*/
public function __construct(JournalRepository $journalRepo)
{
$this->journalRepo = $journalRepo;
}
/**
* Recalculate all the balances for the different ledgers
* @param CronNightly $event
* @throws \UnexpectedValueException
* @throws \InvalidArgumentException
*/
public function handle(CronNightly $event): void
{
Log::info('Recalculating balances');
$journals = Journal::all();
foreach ($journals as $journal) {
$where = ['journal_id' => $journal->id];
$credits = Money::create(JournalTransaction::where($where)->sum('credit') ?: 0);
$debits = Money::create(JournalTransaction::where($where)->sum('debit') ?: 0);
$balance = $credits->subtract($debits);
Log::info('Adjusting balance on ' .
$journal->morphed_type . ':' . $journal->morphed_id
. ' from ' . $journal->balance . ' to ' . $balance);
$journal->balance = $balance->getAmount();
$journal->save();
}
Log::info('Done calculating balances');
}
}

View File

@@ -4,8 +4,11 @@ namespace App\Models;
/**
* Class Expense
* @property int airline_id
* @property float amount
* @property string name
* @property string ref_class
* @property string ref_class_id
* @package App\Models
*/
class Expense extends BaseModel
@@ -33,6 +36,27 @@ class Expense extends BaseModel
'charge_to_user' => 'bool',
];
/**
* Get the referring object
*/
public function getReference()
{
if (!$this->ref_class || !$this->ref_class_id) {
return null;
}
if($this->ref_class === __CLASS__) {
return $this;
}
try {
$klass = new $this->ref_class;
return $klass->find($this->ref_class_id);
} catch (\Exception $e) {
return null;
}
}
/**
* Foreign Keys
*/

View File

@@ -11,7 +11,7 @@ use Carbon\Carbon;
/**
* Class Journal
* @package Scottlaurent\Accounting
* @property mixed id
* @property Money $balance
* @property string $currency
* @property Carbon $updated_at

View File

@@ -41,6 +41,13 @@ class JournalTransaction extends BaseModel
'tags' => 'array',
];
protected $dateFormat = 'Y-m-d';
protected $dates = [
'created_at',
'updated_at',
'post_date',
];
/**
* Callbacks
* @throws \UnexpectedValueException

View File

@@ -2,11 +2,15 @@
namespace App\Providers;
use App\Events\CronMonthly;
use App\Events\CronNightly;
use App\Events\CronWeekly;
use App\Events\Expenses;
use App\Listeners\Cron\Nightly\RecalculateBalances;
use App\Listeners\ExpenseListener;
use App\Listeners\FinanceEvents;
use App\Listeners\NotificationEvents;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use App\Listeners\ExpenseListener;
use App\Events\Expenses;
class EventServiceProvider extends ServiceProvider
@@ -20,6 +24,19 @@ class EventServiceProvider extends ServiceProvider
Expenses::class => [
ExpenseListener::class
],
# Cron hooks
CronNightly::class => [
\App\Listeners\Cron\Nightly\ApplyExpenses::class,
RecalculateBalances::class,
],
CronWeekly::class => [
],
CronMonthly::class => [
\App\Listeners\Cron\Monthly\ApplyExpenses::class
],
];
protected $subscribe = [

View File

@@ -27,6 +27,20 @@ class JournalRepository extends BaseRepository implements CacheableInterface
return JournalTransaction::class;
}
/**
* Return a Y-m-d string for the post date
* @param Carbon $date
* @return string
*/
public function formatPostDate(Carbon $date=null)
{
if(!$date) {
return null;
}
return $date->setTimezone('UTC')->toDateString();
}
/**
* Post a new transaction to a journal, and also adjust the balance
* on the transaction itself. A cron will run to reconcile the journal
@@ -55,22 +69,26 @@ class JournalRepository extends BaseRepository implements CacheableInterface
) {
# tags can be passed in a list
if($tags && \is_array($tags)) {
if ($tags && \is_array($tags)) {
$tags = implode(',', $tags);
}
if(!$post_date) {
$post_date = Carbon::now('UTC');
}
$attrs = [
'journal_id' => $journal->id,
'credit' => $credit ? $credit->getAmount():null,
'debit' => $debit ? $debit->getAmount():null,
'currency' => config('phpvms.currency'),
'memo' => $memo,
'post_date' => $post_date ?? Carbon::now(),
'journal_id' => $journal->id,
'credit' => $credit ? $credit->getAmount() : null,
'debit' => $debit ? $debit->getAmount() : null,
'currency' => config('phpvms.currency'),
'memo' => $memo,
'post_date' => $post_date,
'transaction_group' => $transaction_group,
'tags' => $tags
'tags' => $tags
];
if($reference !== null) {
if ($reference !== null) {
$attrs['ref_class'] = \get_class($reference);
$attrs['ref_class_id'] = $reference->id;
}
@@ -112,6 +130,8 @@ class JournalRepository extends BaseRepository implements CacheableInterface
* @param Carbon|null $start_date
* @param null $transaction_group
* @return Money
* @throws \UnexpectedValueException
* @throws \InvalidArgumentException
*/
public function getCreditBalanceBetween(
Carbon $date,
@@ -124,7 +144,7 @@ class JournalRepository extends BaseRepository implements CacheableInterface
['post_date', '<=', $date]
];
if($journal) {
if ($journal) {
$where['journal_id'] = $journal->id;
}
@@ -152,10 +172,13 @@ class JournalRepository extends BaseRepository implements CacheableInterface
*/
public function getDebitBalanceBetween(
Carbon $date,
Journal $journal=null,
Carbon $start_date=null,
$transaction_group=null
): Money {
Journal $journal = null,
Carbon $start_date = null,
$transaction_group = null
): Money
{
$date = $this->formatPostDate($date);
$where = [
['post_date', '<=', $date]
@@ -165,11 +188,12 @@ class JournalRepository extends BaseRepository implements CacheableInterface
$where['journal_id'] = $journal->id;
}
if($start_date) {
if ($start_date) {
$start_date = $this->formatPostDate($start_date);
$where[] = ['post_date', '>=', $start_date];
}
if($transaction_group) {
if ($transaction_group) {
$where['transaction_group'] = $transaction_group;
}
@@ -184,25 +208,31 @@ class JournalRepository extends BaseRepository implements CacheableInterface
* Return all transactions for a given object
* @param $object
* @param null $journal
* @param Carbon|null $date
* @return array
* @throws \UnexpectedValueException
* @throws \InvalidArgumentException
*/
public function getAllForObject($object, $journal=null)
public function getAllForObject($object, $journal = null, Carbon $date = null)
{
$where = [
'ref_class' => \get_class($object),
'ref_class_id' => $object->id,
];
if($journal) {
if ($journal) {
$where['journal_id'] = $journal->id;
}
if ($date) {
$date = $this->formatPostDate($date);
$where[] = ['post_date', '=', $date];
}
$transactions = $this->whereOrder($where, [
'credit' => 'desc',
'debit' => 'desc'
])->get();
'credit' => 'desc',
'debit' => 'desc'
])->get();
return [
'credits' => new Money($transactions->sum('credit')),

View File

@@ -1,20 +0,0 @@
<?php
namespace App\Services\Finance;
use App\Services\BaseService;
/**
* Class DailyFinanceService
* @package App\Services\Finance
*/
class DailyFinanceService extends BaseService
{
/**
* Run all of the daily expense/financials
*/
public function processFinances()
{
}
}

View File

@@ -1,20 +0,0 @@
<?php
namespace App\Services\Finance;
use App\Services\BaseService;
/**
* Class MonthlyFinanceService
* @package App\Services\Finance
*/
class MonthlyFinanceService extends BaseService
{
/**
* Run all of the daily expense/financials
*/
public function processFinances()
{
}
}

View File

@@ -0,0 +1,141 @@
<?php
namespace App\Services\Finance;
use App\Models\Airline;
use App\Models\Enums\ExpenseType;
use App\Models\Expense;
use App\Models\JournalTransaction;
use App\Repositories\JournalRepository;
use App\Services\BaseService;
use App\Support\Money;
use Log;
/**
* Process all of the daily expenses and charge them
* @package App\Services\Finance
*/
class RecurringFinanceService extends BaseService
{
private $journalRepo;
public function __construct(JournalRepository $journalRepo)
{
$this->journalRepo = $journalRepo;
}
/**
* Determine the journal to charge to, otherwise, it's charged
* to every airline journal
* @param Expense $expense
* @return \Generator
*/
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;
}
}
}
/**
* Get the name of the transaction group from the expense
* @param Expense $expense
* @return array
*/
protected function getMemoAndGroup(Expense $expense): array
{
$klass = 'Expense';
if ($expense->ref_class) {
$ref = explode('\\', $expense->ref_class);
$klass = end($ref);
$obj = $expense->getReference();
}
if ($klass === 'Airport') {
$memo = "Airport Expense: {$expense->name} ({$expense->ref_class_id})";
$transaction_group = "Airport: {$expense->ref_class_id}";
} elseif ($klass === 'Subfleet') {
$memo = "Subfleet Expense: {$expense->name}";
$transaction_group = "Subfleet: {$expense->name}";
} elseif ($klass === 'Aircraft') {
$memo = "Aircraft Expense: {$expense->name} ({$obj->name})";
$transaction_group = "Aircraft: {$expense->name} ({$obj->name}-{$obj->registration})";
} else {
$memo = "Expense: {$expense->name}";
$transaction_group = "Expense: {$expense->name}";
}
return [$memo, $transaction_group];
}
/**
* Run all of the daily expense/financials
* @param int $type
* @throws \UnexpectedValueException
* @throws \InvalidArgumentException
* @throws \Prettus\Validator\Exceptions\ValidatorException
*/
public function processExpenses($type=ExpenseType::DAILY): void
{
$expenses = Expense::where(['type' => $type])->get();
$tag = 'expense_recurring';
if($type === ExpenseType::DAILY) {
$tag = 'expenses_daily';
} elseif ($type === ExpenseType::MONTHLY) {
$tag === 'expenses_monthly';
}
/**
* @var $expenses Expense[]
*/
foreach ($expenses as $expense) {
# Apply the expenses to the appropriate journals
$journals = $this->findJournals($expense);
foreach($journals as $journal) {
$amount = $expense->amount;
# Has this expense already been charged? Check
# against this specific journal, on today
$w = [
'journal_id' => $journal->id,
'ref_class' => Expense::class,
'ref_class_id' => $expense->id,
'post_date' => \Carbon::now('UTC')->format('Y-m-d'),
];
$found = JournalTransaction::where($w)->count(['id']);
if($found > 0) {
Log::info('Expense "'.$expense->name.'" already charged for today, skipping');
continue;
}
[$memo, $ta_group] = $this->getMemoAndGroup($expense);
$this->journalRepo->post(
$journal,
null,
Money::createFromAmount($amount),
$expense,
$memo,
null,
$ta_group,
$tag
);
Log::info('Expense memo: "'.$memo.'"; group: "'. $ta_group. '" charged!');
}
}
}
}

72
composer.lock generated
View File

@@ -876,16 +876,16 @@
},
{
"name": "google/apiclient-services",
"version": "v0.49",
"version": "v0.50",
"source": {
"type": "git",
"url": "https://github.com/google/google-api-php-client-services.git",
"reference": "7552d7d1bb92e933fc93088014c8c2555c0feab6"
"reference": "3e792254734e4444dd8a594e927926f28de2e609"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/google/google-api-php-client-services/zipball/7552d7d1bb92e933fc93088014c8c2555c0feab6",
"reference": "7552d7d1bb92e933fc93088014c8c2555c0feab6",
"url": "https://api.github.com/repos/google/google-api-php-client-services/zipball/3e792254734e4444dd8a594e927926f28de2e609",
"reference": "3e792254734e4444dd8a594e927926f28de2e609",
"shasum": ""
},
"require": {
@@ -909,7 +909,7 @@
"keywords": [
"google"
],
"time": "2018-03-04T00:24:05+00:00"
"time": "2018-03-10T00:23:06+00:00"
},
{
"name": "google/auth",
@@ -1567,16 +1567,16 @@
},
{
"name": "laravel/framework",
"version": "v5.6.11",
"version": "v5.6.12",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "195ba6a67bdad2a23105c7ab410cd43e0f20bb73"
"reference": "82d8165d1ea86bdd81ddfa1db9343fa19e7d1450"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/195ba6a67bdad2a23105c7ab410cd43e0f20bb73",
"reference": "195ba6a67bdad2a23105c7ab410cd43e0f20bb73",
"url": "https://api.github.com/repos/laravel/framework/zipball/82d8165d1ea86bdd81ddfa1db9343fa19e7d1450",
"reference": "82d8165d1ea86bdd81ddfa1db9343fa19e7d1450",
"shasum": ""
},
"require": {
@@ -1585,7 +1585,7 @@
"erusev/parsedown": "~1.7",
"ext-mbstring": "*",
"ext-openssl": "*",
"league/flysystem": "~1.0",
"league/flysystem": "^1.0.8",
"monolog/monolog": "~1.12",
"nesbot/carbon": "^1.24.1",
"php": "^7.1.3",
@@ -1701,7 +1701,7 @@
"framework",
"laravel"
],
"time": "2018-03-09T16:53:27+00:00"
"time": "2018-03-14T17:29:38+00:00"
},
{
"name": "laravelcollective/html",
@@ -2162,16 +2162,16 @@
},
{
"name": "nesbot/carbon",
"version": "1.24.1",
"version": "1.24.2",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
"reference": "ef12cbd8ba5ce624f0a6a95e0850c4cc13e71e41"
"reference": "bba6c6e410c6b4317e37a9474aeaa753808c3875"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/ef12cbd8ba5ce624f0a6a95e0850c4cc13e71e41",
"reference": "ef12cbd8ba5ce624f0a6a95e0850c4cc13e71e41",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bba6c6e410c6b4317e37a9474aeaa753808c3875",
"reference": "bba6c6e410c6b4317e37a9474aeaa753808c3875",
"shasum": ""
},
"require": {
@@ -2211,7 +2211,7 @@
"datetime",
"time"
],
"time": "2018-03-09T15:49:34+00:00"
"time": "2018-03-10T10:10:14+00:00"
},
{
"name": "nikic/php-parser",
@@ -2362,7 +2362,7 @@
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"MIT"
],
@@ -2588,16 +2588,16 @@
},
{
"name": "pragmarx/version",
"version": "v0.2.5",
"version": "v0.2.6",
"source": {
"type": "git",
"url": "https://github.com/antonioribeiro/version.git",
"reference": "ed34e37904067bdb15857d3f2bcc11683f37eb84"
"reference": "73439723bf8f32534e0a79a07a914971b729ec1e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/antonioribeiro/version/zipball/ed34e37904067bdb15857d3f2bcc11683f37eb84",
"reference": "ed34e37904067bdb15857d3f2bcc11683f37eb84",
"url": "https://api.github.com/repos/antonioribeiro/version/zipball/73439723bf8f32534e0a79a07a914971b729ec1e",
"reference": "73439723bf8f32534e0a79a07a914971b729ec1e",
"shasum": ""
},
"require": {
@@ -2645,7 +2645,7 @@
"version",
"versioning"
],
"time": "2018-02-10T17:40:28+00:00"
"time": "2018-03-13T00:04:06+00:00"
},
{
"name": "pragmarx/yaml",
@@ -2795,7 +2795,7 @@
"Prettus\\Validator\\": "src/Prettus/Validator/"
}
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"authors": [
{
"name": "Anderson Andrade",
@@ -2884,7 +2884,7 @@
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"MIT"
],
@@ -3439,7 +3439,7 @@
"lib/swift_required.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"MIT"
],
@@ -5387,7 +5387,7 @@
"Faker\\": "src/Faker/"
}
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"MIT"
],
@@ -5739,7 +5739,7 @@
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
@@ -5786,7 +5786,7 @@
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
@@ -5843,7 +5843,7 @@
]
}
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"MIT"
],
@@ -6606,7 +6606,7 @@
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
@@ -6658,7 +6658,7 @@
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
@@ -6726,7 +6726,7 @@
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
@@ -6776,7 +6776,7 @@
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
@@ -6821,7 +6821,7 @@
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
@@ -6866,7 +6866,7 @@
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
@@ -7055,7 +7055,7 @@
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"notification-url": "http://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],

View File

@@ -28,7 +28,16 @@ return [
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
'channels' => [
'daily',
# PHP_SAPI === 'cli' ? 'console' : 'daily',
],
],
'console' => [
'driver' => 'stack',
'channels' => [
'stdout',
],
],
'single' => [
'driver' => 'single',
@@ -48,6 +57,10 @@ return [
'emoji' => ':boom:',
'level' => 'critical',
],
'stdout' => [
'driver' => 'custom',
'via' => \App\Console\Logger::class,
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',