Merge branch 'master' of github.com:akaunting/akaunting

This commit is contained in:
Burak Çakırel 2020-09-30 15:49:52 +03:00
commit 89e7d934c3
No known key found for this signature in database
GPG Key ID: 48FFBB7771B99C7C
10 changed files with 385 additions and 209 deletions

View File

@ -2,21 +2,21 @@
namespace App\Console\Commands; namespace App\Console\Commands;
use App\Events\Banking\TransactionCreated;
use App\Events\Banking\TransactionRecurring;
use App\Events\Purchase\BillCreated; use App\Events\Purchase\BillCreated;
use App\Events\Purchase\BillRecurring; use App\Events\Purchase\BillRecurring;
use App\Events\Sale\InvoiceCreated; use App\Events\Sale\InvoiceCreated;
use App\Events\Sale\InvoiceRecurring; use App\Events\Sale\InvoiceRecurring;
use App\Models\Banking\Transaction;
use App\Models\Common\Company; use App\Models\Common\Company;
use App\Traits\Sales; use App\Models\Sale\Invoice;
use App\Utilities\Overrider; use App\Utilities\Overrider;
use Carbon\Carbon;
use Date; use Date;
use Illuminate\Console\Command; use Illuminate\Console\Command;
class RecurringCheck extends Command class RecurringCheck extends Command
{ {
use Sales;
/** /**
* The name and signature of the console command. * The name and signature of the console command.
* *
@ -34,7 +34,7 @@ class RecurringCheck extends Command
/** /**
* The current day. * The current day.
* *
* @var Carbon * @var \Carbon\Carbon
*/ */
protected $today; protected $today;
@ -64,8 +64,16 @@ class RecurringCheck extends Command
$this->today = Date::today(); $this->today = Date::today();
foreach ($company->recurring as $recurring) { foreach ($company->recurring as $recurring) {
foreach ($recurring->schedule() as $schedule) { if (!$model = $recurring->recurable) {
$this->recur($recurring, $schedule); continue;
}
foreach ($recurring->getRecurringSchedule() as $schedule) {
$schedule_date = Date::parse($schedule->getStart()->format('Y-m-d'));
\DB::transaction(function () use ($model, $recurring, $schedule_date) {
$this->recur($model, $recurring->recurable_type, $schedule_date);
});
} }
} }
} }
@ -75,97 +83,161 @@ class RecurringCheck extends Command
setting()->forgetAll(); setting()->forgetAll();
} }
protected function recur($recurring, $schedule) protected function recur($model, $type, $schedule_date)
{ {
$schedule_date = Date::parse($schedule->getStart()->format('Y-m-d')); // Don't recur the future
if ($schedule_date->greaterThan($this->today)) {
// Check if should recur today
if ($this->today->ne($schedule_date)) {
return; return;
} }
if (!$model = $recurring->recurable) { if (!$clone = $this->getClone($model, $schedule_date)) {
return; return;
} }
switch ($recurring->recurable_type) { switch ($type) {
case 'App\Models\Purchase\Bill': case 'App\Models\Purchase\Bill':
if (!$clone = $this->getDocumentClone($model, 'billed_at')) {
break;
}
event(new BillCreated($clone)); event(new BillCreated($clone));
event(new BillRecurring($clone)); event(new BillRecurring($clone));
break; break;
case 'App\Models\Sale\Invoice': case 'App\Models\Sale\Invoice':
if (!$clone = $this->getDocumentClone($model, 'invoiced_at')) {
break;
}
event(new InvoiceCreated($clone)); event(new InvoiceCreated($clone));
event(new InvoiceRecurring($clone)); event(new InvoiceRecurring($clone));
break; break;
case 'App\Models\Banking\Transaction': case 'App\Models\Banking\Transaction':
// Skip model created on the same day, but scheduler hasn't run yet event(new TransactionCreated($clone));
if ($this->today->eq(Date::parse($model->paid_at->format('Y-m-d')))) {
break;
}
$model->cloneable_relations = []; event(new TransactionRecurring($clone));
// Create new record
$clone = $model->duplicate();
$clone->parent_id = $model->id;
$clone->paid_at = $this->today->format('Y-m-d');
$clone->save();
break; break;
} }
} }
/**
* Clone the model and return it.
*
* @param $model
* @param $schedule_date
*
* @return boolean|object
*/
protected function getClone($model, $schedule_date)
{
if ($this->skipThisClone($model, $schedule_date)) {
return false;
}
$function = ($model instanceof Transaction) ? 'getTransactionClone' : 'getDocumentClone';
try {
return $this->$function($model, $schedule_date);
} catch (\Exception | \Throwable | \Swift_RfcComplianceException| \Swift_TransportException | \Illuminate\Database\QueryException $e) {
$this->error($e->getMessage());
logger('Recurring check:: ' . $e->getMessage());
return false;
}
}
/** /**
* Clone the document and return it. * Clone the document and return it.
* *
* @param $model * @param $model
* @param $date_field * @param $schedule_date
* *
* @return boolean|object * @return boolean|object
*/ */
protected function getDocumentClone($model, $date_field) protected function getDocumentClone($model, $schedule_date)
{ {
// Skip model created on the same day, but scheduler hasn't run yet
if ($this->today->eq(Date::parse($model->$date_field->format('Y-m-d')))) {
return false;
}
$model->cloneable_relations = ['items', 'totals']; $model->cloneable_relations = ['items', 'totals'];
try { $clone = $model->duplicate();
$clone = $model->duplicate();
} catch (\Exception | \Throwable | \Swift_RfcComplianceException | \Illuminate\Database\QueryException $e) {
$this->error($e->getMessage());
logger('Recurring check:: ' . $e->getMessage()); $date_field = $this->getDateField($model);
return false;
}
// Set original model id
$clone->parent_id = $model->id;
// Days between issued and due date // Days between issued and due date
$diff_days = Date::parse($clone->due_at)->diffInDays(Date::parse($clone->$date_field)); $diff_days = Date::parse($clone->due_at)->diffInDays(Date::parse($clone->$date_field));
// Update dates $clone->parent_id = $model->id;
$clone->$date_field = $this->today->format('Y-m-d'); $clone->$date_field = $schedule_date->format('Y-m-d');
$clone->due_at = $this->today->copy()->addDays($diff_days)->format('Y-m-d'); $clone->due_at = $schedule_date->copy()->addDays($diff_days)->format('Y-m-d');
$clone->save(); $clone->save();
return $clone; return $clone;
} }
}
/**
* Clone the transaction and return it.
*
* @param $model
* @param $schedule_date
*
* @return boolean|object
*/
protected function getTransactionClone($model, $schedule_date)
{
$model->cloneable_relations = [];
$clone = $model->duplicate();
$clone->parent_id = $model->id;
$clone->paid_at = $schedule_date->format('Y-m-d');
$clone->save();
return $clone;
}
protected function skipThisClone($model, $schedule_date)
{
$date_field = $this->getDateField($model);
// Skip model created on the same day, but scheduler hasn't run yet
if ($schedule_date->equalTo(Date::parse($model->$date_field->format('Y-m-d')))) {
return true;
}
$table = $this->getTable($model);
$already_cloned = \DB::table($table)
->where('parent_id', $model->id)
->whereDate($date_field, $schedule_date)
->value('id');
// Skip if already cloned
if ($already_cloned) {
return true;
}
return false;
}
protected function getDateField($model)
{
if ($model instanceof Transaction) {
return 'paid_at';
}
if ($model instanceof Invoice) {
return 'invoiced_at';
}
return 'billed_at';
}
protected function getTable($model)
{
if ($model instanceof Transaction) {
return 'transactions';
}
if ($model instanceof Invoice) {
return 'invoices';
}
return 'bills';
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Events\Banking;
use Illuminate\Queue\SerializesModels;
class TransactionRecurring
{
use SerializesModels;
public $transaction;
/**
* Create a new event instance.
*
* @param $transaction
*/
public function __construct($transaction)
{
$this->transaction = $transaction;
}
}

View File

@ -59,18 +59,71 @@ trait Recurring
]); ]);
} }
public function current() public function getRecurringSchedule()
{ {
if (!$schedule = $this->schedule()) { $config = new ArrayTransformerConfig();
$config->enableLastDayOfMonthFix();
$transformer = new ArrayTransformer();
$transformer->setConfig($config);
return $transformer->transform($this->getRecurringRule());
}
public function getRecurringRule()
{
$rule = (new Rule())
->setStartDate($this->getRecurringRuleStartDate())
->setTimezone($this->getRecurringRuleTimeZone())
->setFreq($this->getRecurringRuleFrequency())
->setInterval($this->getRecurringRuleInterval());
// 0 means infinite
if ($this->count != 0) {
$rule->setCount($this->getRecurringRuleCount());
}
return $rule;
}
public function getRecurringRuleStartDate()
{
return new \DateTime($this->started_at, new \DateTimeZone($this->getRecurringRuleTimeZone()));
}
public function getRecurringRuleTimeZone()
{
return setting('localisation.timezone');
}
public function getRecurringRuleCount()
{
// Fix for humans
return $this->count + 1;
}
public function getRecurringRuleFrequency()
{
return strtoupper($this->frequency);
}
public function getRecurringRuleInterval()
{
return $this->interval;
}
public function getCurrentRecurring()
{
if (!$schedule = $this->getRecurringSchedule()) {
return false; return false;
} }
return $schedule->current()->getStart(); return $schedule->current()->getStart();
} }
public function next() public function getNextRecurring()
{ {
if (!$schedule = $this->schedule()) { if (!$schedule = $this->getRecurringSchedule()) {
return false; return false;
} }
@ -81,69 +134,21 @@ trait Recurring
return $next->getStart(); return $next->getStart();
} }
public function first() public function getFirstRecurring()
{ {
if (!$schedule = $this->schedule()) { if (!$schedule = $this->getRecurringSchedule()) {
return false; return false;
} }
return $schedule->first()->getStart(); return $schedule->first()->getStart();
} }
public function last() public function getLastRecurring()
{ {
if (!$schedule = $this->schedule()) { if (!$schedule = $this->getRecurringSchedule()) {
return false; return false;
} }
return $schedule->last()->getStart(); return $schedule->last()->getStart();
} }
}
public function schedule()
{
$config = new ArrayTransformerConfig();
$config->enableLastDayOfMonthFix();
$transformer = new ArrayTransformer();
$transformer->setConfig($config);
return $transformer->transform($this->getRule());
}
public function getRule()
{
$rule = (new Rule())
->setStartDate($this->getRuleStartDate())
->setTimezone($this->getRuleTimeZone())
->setFreq($this->getRuleFrequency())
->setInterval($this->interval);
// 0 means infinite
if ($this->count != 0) {
$rule->setCount($this->getRuleCount());
}
return $rule;
}
public function getRuleStartDate()
{
return new \DateTime($this->started_at, new \DateTimeZone($this->getRuleTimeZone()));
}
public function getRuleTimeZone()
{
return setting('localisation.timezone');
}
public function getRuleCount()
{
// Fix for humans
return $this->count + 1;
}
public function getRuleFrequency()
{
return strtoupper($this->frequency);
}
}

View File

@ -16,9 +16,9 @@ class Recurring
continue; continue;
} }
foreach ($item->recurring->schedule() as $recurr) { foreach ($item->recurring->getRecurringSchedule() as $schedule) {
$issued = Date::parse($item->$issued_date_field); $issued = Date::parse($item->$issued_date_field);
$start = $recurr->getStart(); $start = $schedule->getStart();
if ($issued->format('Y') != $start->format('Y')) { if ($issued->format('Y') != $start->format('Y')) {
continue; continue;

View File

@ -76,7 +76,7 @@
"Modules\\": "modules/", "Modules\\": "modules/",
"Akaunting\\Module\\Commands\\": "overrides/akaunting/module/Commands/", "Akaunting\\Module\\Commands\\": "overrides/akaunting/module/Commands/",
"Illuminate\\Translation\\": "overrides/Illuminate/Translation/", "Illuminate\\Translation\\": "overrides/Illuminate/Translation/",
"Illuminate\\View\\": "overrides/Illuminate/View/", "Illuminate\\View\\Concerns\\": "overrides/Illuminate/View/Concerns/",
"Symfony\\Component\\Process\\": "overrides/symfony/process/" "Symfony\\Component\\Process\\": "overrides/symfony/process/"
}, },
"exclude-from-classmap": [ "exclude-from-classmap": [

255
composer.lock generated
View File

@ -1126,16 +1126,16 @@
}, },
{ {
"name": "composer/semver", "name": "composer/semver",
"version": "1.7.0", "version": "1.7.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/composer/semver.git", "url": "https://github.com/composer/semver.git",
"reference": "114f819054a2ea7db03287f5efb757e2af6e4079" "reference": "38276325bd896f90dfcfe30029aa5db40df387a7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/114f819054a2ea7db03287f5efb757e2af6e4079", "url": "https://api.github.com/repos/composer/semver/zipball/38276325bd896f90dfcfe30029aa5db40df387a7",
"reference": "114f819054a2ea7db03287f5efb757e2af6e4079", "reference": "38276325bd896f90dfcfe30029aa5db40df387a7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1197,7 +1197,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-09-09T09:34:06+00:00" "time": "2020-09-27T13:13:07+00:00"
}, },
{ {
"name": "composer/spdx-licenses", "name": "composer/spdx-licenses",
@ -2252,16 +2252,16 @@
}, },
{ {
"name": "egulias/email-validator", "name": "egulias/email-validator",
"version": "2.1.21", "version": "2.1.22",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/egulias/EmailValidator.git", "url": "https://github.com/egulias/EmailValidator.git",
"reference": "563d0cdde5d862235ffe24a158497f4d490191b5" "reference": "68e418ec08fbfc6f58f6fd2eea70ca8efc8cc7d5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/563d0cdde5d862235ffe24a158497f4d490191b5", "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/68e418ec08fbfc6f58f6fd2eea70ca8efc8cc7d5",
"reference": "563d0cdde5d862235ffe24a158497f4d490191b5", "reference": "68e418ec08fbfc6f58f6fd2eea70ca8efc8cc7d5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2306,7 +2306,7 @@
"validation", "validation",
"validator" "validator"
], ],
"time": "2020-09-19T14:37:56+00:00" "time": "2020-09-26T15:48:38+00:00"
}, },
{ {
"name": "fideloper/proxy", "name": "fideloper/proxy",
@ -5552,16 +5552,16 @@
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v4.10.0", "version": "v4.10.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nikic/PHP-Parser.git", "url": "https://github.com/nikic/PHP-Parser.git",
"reference": "1c13d05035deff45f1230ca68bd7d74d621762d9" "reference": "658f1be311a230e0907f5dfe0213742aff0596de"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1c13d05035deff45f1230ca68bd7d74d621762d9", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/658f1be311a230e0907f5dfe0213742aff0596de",
"reference": "1c13d05035deff45f1230ca68bd7d74d621762d9", "reference": "658f1be311a230e0907f5dfe0213742aff0596de",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5600,7 +5600,7 @@
"parser", "parser",
"php" "php"
], ],
"time": "2020-09-19T14:52:48+00:00" "time": "2020-09-26T10:30:38+00:00"
}, },
{ {
"name": "omnipay/common", "name": "omnipay/common",
@ -7829,16 +7829,16 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "186f395b256065ba9b890c0a4e48a91d598fa2cf" "reference": "04c3a31fe8ea94b42c9e2d1acc93d19782133b00"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/186f395b256065ba9b890c0a4e48a91d598fa2cf", "url": "https://api.github.com/repos/symfony/console/zipball/04c3a31fe8ea94b42c9e2d1acc93d19782133b00",
"reference": "186f395b256065ba9b890c0a4e48a91d598fa2cf", "reference": "04c3a31fe8ea94b42c9e2d1acc93d19782133b00",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -7918,11 +7918,11 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-09-02T07:07:40+00:00" "time": "2020-09-18T14:27:32+00:00"
}, },
{ {
"name": "symfony/css-selector", "name": "symfony/css-selector",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/css-selector.git", "url": "https://github.com/symfony/css-selector.git",
@ -7989,16 +7989,16 @@
}, },
{ {
"name": "symfony/debug", "name": "symfony/debug",
"version": "v4.4.13", "version": "v4.4.14",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/debug.git", "url": "https://github.com/symfony/debug.git",
"reference": "aeb73aca16a8f1fe958230fe44e6cf4c84cbb85e" "reference": "726b85e69342e767d60e3853b98559a68ff74183"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/aeb73aca16a8f1fe958230fe44e6cf4c84cbb85e", "url": "https://api.github.com/repos/symfony/debug/zipball/726b85e69342e767d60e3853b98559a68ff74183",
"reference": "aeb73aca16a8f1fe958230fe44e6cf4c84cbb85e", "reference": "726b85e69342e767d60e3853b98559a68ff74183",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8056,7 +8056,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-10T07:47:39+00:00" "time": "2020-09-09T05:20:36+00:00"
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",
@ -8124,16 +8124,16 @@
}, },
{ {
"name": "symfony/error-handler", "name": "symfony/error-handler",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/error-handler.git", "url": "https://github.com/symfony/error-handler.git",
"reference": "525636d4b84e06c6ca72d96b6856b5b169416e6a" "reference": "d2f1d4996d5499f1261164d10080e4120001f041"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/error-handler/zipball/525636d4b84e06c6ca72d96b6856b5b169416e6a", "url": "https://api.github.com/repos/symfony/error-handler/zipball/d2f1d4996d5499f1261164d10080e4120001f041",
"reference": "525636d4b84e06c6ca72d96b6856b5b169416e6a", "reference": "d2f1d4996d5499f1261164d10080e4120001f041",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8191,20 +8191,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-17T10:01:29+00:00" "time": "2020-09-27T03:44:28+00:00"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "94871fc0a69c3c5da57764187724cdce0755899c" "reference": "d5de97d6af175a9e8131c546db054ca32842dd0f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/94871fc0a69c3c5da57764187724cdce0755899c", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d5de97d6af175a9e8131c546db054ca32842dd0f",
"reference": "94871fc0a69c3c5da57764187724cdce0755899c", "reference": "d5de97d6af175a9e8131c546db054ca32842dd0f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8224,6 +8224,7 @@
"psr/log": "~1.0", "psr/log": "~1.0",
"symfony/config": "^4.4|^5.0", "symfony/config": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0", "symfony/dependency-injection": "^4.4|^5.0",
"symfony/error-handler": "^4.4|^5.0",
"symfony/expression-language": "^4.4|^5.0", "symfony/expression-language": "^4.4|^5.0",
"symfony/http-foundation": "^4.4|^5.0", "symfony/http-foundation": "^4.4|^5.0",
"symfony/service-contracts": "^1.1|^2", "symfony/service-contracts": "^1.1|^2",
@ -8277,7 +8278,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-13T14:19:42+00:00" "time": "2020-09-18T14:27:32+00:00"
}, },
{ {
"name": "symfony/event-dispatcher-contracts", "name": "symfony/event-dispatcher-contracts",
@ -8357,16 +8358,16 @@
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/filesystem.git", "url": "https://github.com/symfony/filesystem.git",
"reference": "f7b9ed6142a34252d219801d9767dedbd711da1a" "reference": "f3194303d3077829dbbc1d18f50288b2a01146f2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/f7b9ed6142a34252d219801d9767dedbd711da1a", "url": "https://api.github.com/repos/symfony/filesystem/zipball/f3194303d3077829dbbc1d18f50288b2a01146f2",
"reference": "f7b9ed6142a34252d219801d9767dedbd711da1a", "reference": "f3194303d3077829dbbc1d18f50288b2a01146f2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8417,20 +8418,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-21T17:19:47+00:00" "time": "2020-09-02T16:23:27+00:00"
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "2b765f0cf6612b3636e738c0689b29aa63088d5d" "reference": "2c3ba7ad6884e6c4451ce2340e2dc23f6fa3e0d8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/2b765f0cf6612b3636e738c0689b29aa63088d5d", "url": "https://api.github.com/repos/symfony/finder/zipball/2c3ba7ad6884e6c4451ce2340e2dc23f6fa3e0d8",
"reference": "2b765f0cf6612b3636e738c0689b29aa63088d5d", "reference": "2c3ba7ad6884e6c4451ce2340e2dc23f6fa3e0d8",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8480,20 +8481,95 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-17T10:01:29+00:00" "time": "2020-09-02T16:23:27+00:00"
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-client-contracts",
"version": "v5.1.5", "version": "v2.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-client-contracts.git",
"reference": "41a4647f12870e9d41d9a7d72ff0614a27208558" "reference": "3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/41a4647f12870e9d41d9a7d72ff0614a27208558", "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3",
"reference": "41a4647f12870e9d41d9a7d72ff0614a27208558", "reference": "3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3",
"shasum": ""
},
"require": {
"php": ">=7.2.5"
},
"suggest": {
"symfony/http-client-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
"Symfony\\Contracts\\HttpClient\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Generic abstractions related to HTTP clients",
"homepage": "https://symfony.com",
"keywords": [
"abstractions",
"contracts",
"decoupling",
"interfaces",
"interoperability",
"standards"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-09-07T11:33:47+00:00"
},
{
"name": "symfony/http-foundation",
"version": "v5.1.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "6cca6b2e4b69fc5bace160d14cf1ee5f71483db4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/6cca6b2e4b69fc5bace160d14cf1ee5f71483db4",
"reference": "6cca6b2e4b69fc5bace160d14cf1ee5f71483db4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8555,20 +8631,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-17T07:48:54+00:00" "time": "2020-09-13T05:01:27+00:00"
}, },
{ {
"name": "symfony/http-kernel", "name": "symfony/http-kernel",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-kernel.git", "url": "https://github.com/symfony/http-kernel.git",
"reference": "3e32676e6cb5d2081c91a56783471ff8a7f7110b" "reference": "17227644c3c66dcf32bdfeceff4364d090cd6756"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/3e32676e6cb5d2081c91a56783471ff8a7f7110b", "url": "https://api.github.com/repos/symfony/http-kernel/zipball/17227644c3c66dcf32bdfeceff4364d090cd6756",
"reference": "3e32676e6cb5d2081c91a56783471ff8a7f7110b", "reference": "17227644c3c66dcf32bdfeceff4364d090cd6756",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8577,6 +8653,7 @@
"symfony/deprecation-contracts": "^2.1", "symfony/deprecation-contracts": "^2.1",
"symfony/error-handler": "^4.4|^5.0", "symfony/error-handler": "^4.4|^5.0",
"symfony/event-dispatcher": "^5.0", "symfony/event-dispatcher": "^5.0",
"symfony/http-client-contracts": "^1.1|^2",
"symfony/http-foundation": "^4.4|^5.0", "symfony/http-foundation": "^4.4|^5.0",
"symfony/polyfill-ctype": "^1.8", "symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-php73": "^1.9", "symfony/polyfill-php73": "^1.9",
@ -8668,20 +8745,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-09-02T08:15:18+00:00" "time": "2020-09-27T04:33:19+00:00"
}, },
{ {
"name": "symfony/mime", "name": "symfony/mime",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mime.git", "url": "https://github.com/symfony/mime.git",
"reference": "89a2c9b4cb7b5aa516cf55f5194c384f444c81dc" "reference": "4404d6545125863561721514ad9388db2661eec5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/89a2c9b4cb7b5aa516cf55f5194c384f444c81dc", "url": "https://api.github.com/repos/symfony/mime/zipball/4404d6545125863561721514ad9388db2661eec5",
"reference": "89a2c9b4cb7b5aa516cf55f5194c384f444c81dc", "reference": "4404d6545125863561721514ad9388db2661eec5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8745,7 +8822,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-17T10:01:29+00:00" "time": "2020-09-02T16:23:27+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
@ -9529,16 +9606,16 @@
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/process.git", "url": "https://github.com/symfony/process.git",
"reference": "1864216226af21eb76d9477f691e7cbf198e0402" "reference": "d3a2e64866169586502f0cd9cab69135ad12cee9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/1864216226af21eb76d9477f691e7cbf198e0402", "url": "https://api.github.com/repos/symfony/process/zipball/d3a2e64866169586502f0cd9cab69135ad12cee9",
"reference": "1864216226af21eb76d9477f691e7cbf198e0402", "reference": "d3a2e64866169586502f0cd9cab69135ad12cee9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -9589,20 +9666,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-07-23T08:36:24+00:00" "time": "2020-09-02T16:23:27+00:00"
}, },
{ {
"name": "symfony/routing", "name": "symfony/routing",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/routing.git", "url": "https://github.com/symfony/routing.git",
"reference": "47b0218344cb6af25c93ca8ee1137fafbee5005d" "reference": "d36e06eb02a55522a8eed070c1cbc3dc3c389876"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/47b0218344cb6af25c93ca8ee1137fafbee5005d", "url": "https://api.github.com/repos/symfony/routing/zipball/d36e06eb02a55522a8eed070c1cbc3dc3c389876",
"reference": "47b0218344cb6af25c93ca8ee1137fafbee5005d", "reference": "d36e06eb02a55522a8eed070c1cbc3dc3c389876",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -9681,7 +9758,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-10T08:03:57+00:00" "time": "2020-09-02T16:23:27+00:00"
}, },
{ {
"name": "symfony/service-contracts", "name": "symfony/service-contracts",
@ -9761,16 +9838,16 @@
}, },
{ {
"name": "symfony/string", "name": "symfony/string",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/string.git", "url": "https://github.com/symfony/string.git",
"reference": "0de4cc1e18bb596226c06a82e2e7e9bc6001a63a" "reference": "4a9afe9d07bac506f75bcee8ed3ce76da5a9343e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/0de4cc1e18bb596226c06a82e2e7e9bc6001a63a", "url": "https://api.github.com/repos/symfony/string/zipball/4a9afe9d07bac506f75bcee8ed3ce76da5a9343e",
"reference": "0de4cc1e18bb596226c06a82e2e7e9bc6001a63a", "reference": "4a9afe9d07bac506f75bcee8ed3ce76da5a9343e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -9842,20 +9919,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-17T07:48:54+00:00" "time": "2020-09-15T12:23:47+00:00"
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "917b02cdc5f33e0309b8e9d33ee1480b20687413" "reference": "e3cdd5119b1b5bf0698c351b8ee20fb5a4ea248b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/917b02cdc5f33e0309b8e9d33ee1480b20687413", "url": "https://api.github.com/repos/symfony/translation/zipball/e3cdd5119b1b5bf0698c351b8ee20fb5a4ea248b",
"reference": "917b02cdc5f33e0309b8e9d33ee1480b20687413", "reference": "e3cdd5119b1b5bf0698c351b8ee20fb5a4ea248b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -9934,7 +10011,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-17T10:01:29+00:00" "time": "2020-09-27T03:44:28+00:00"
}, },
{ {
"name": "symfony/translation-contracts", "name": "symfony/translation-contracts",
@ -10013,16 +10090,16 @@
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v5.1.5", "version": "v5.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "b43a3905262bcf97b2510f0621f859ca4f5287be" "reference": "c976c115a0d788808f7e71834c8eb0844f678d02"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/b43a3905262bcf97b2510f0621f859ca4f5287be", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c976c115a0d788808f7e71834c8eb0844f678d02",
"reference": "b43a3905262bcf97b2510f0621f859ca4f5287be", "reference": "c976c115a0d788808f7e71834c8eb0844f678d02",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -10099,7 +10176,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2020-08-17T07:42:30+00:00" "time": "2020-09-18T14:27:32+00:00"
}, },
{ {
"name": "tijsverkoyen/css-to-inline-styles", "name": "tijsverkoyen/css-to-inline-styles",
@ -12278,4 +12355,4 @@
}, },
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "1.1.0" "plugin-api-version": "1.1.0"
} }

View File

@ -4,7 +4,7 @@
@section('content') @section('content')
@stack('recurring_message_start') @stack('recurring_message_start')
@if (($recurring = $bill->recurring) && ($next = $recurring->next())) @if (($recurring = $bill->recurring) && ($next = $recurring->getNextRecurring()))
<div class="row mb-3"> <div class="row mb-3">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="media"> <div class="media">

View File

@ -3,7 +3,7 @@
@section('title', trans('general.title.edit', ['type' => trans_choice('general.payments', 1)])) @section('title', trans('general.title.edit', ['type' => trans_choice('general.payments', 1)]))
@section('content') @section('content')
@if (($recurring = $payment->recurring) && ($next = $recurring->next())) @if (($recurring = $payment->recurring) && ($next = $recurring->getNextRecurring()))
<div class="media mb-3"> <div class="media mb-3">
<div class="media-body"> <div class="media-body">
<div class="media-comment-text"> <div class="media-comment-text">

View File

@ -4,7 +4,7 @@
@section('content') @section('content')
@stack('recurring_message_start') @stack('recurring_message_start')
@if (($recurring = $invoice->recurring) && ($next = $recurring->next())) @if (($recurring = $invoice->recurring) && ($next = $recurring->getNextRecurring()))
<div class="row mb-3"> <div class="row mb-3">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="media"> <div class="media">

View File

@ -3,7 +3,7 @@
@section('title', trans('general.title.edit', ['type' => trans_choice('general.revenues', 1)])) @section('title', trans('general.title.edit', ['type' => trans_choice('general.revenues', 1)]))
@section('content') @section('content')
@if (($recurring = $revenue->recurring) && ($next = $recurring->next())) @if (($recurring = $revenue->recurring) && ($next = $recurring->getNextRecurring()))
<div class="media mb-3"> <div class="media mb-3">
<div class="media-body"> <div class="media-body">
<div class="media-comment-text"> <div class="media-comment-text">