mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
commit
dedf43e562
@ -80,4 +80,5 @@ class ContactLoginController extends Controller
|
||||
|
||||
return redirect('/client/login');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\ClientPortal;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ContactHashLoginController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Logs a user into the client portal using their contact_key
|
||||
* @param string $contact_key The contact key
|
||||
* @return Auth|Redirect
|
||||
*/
|
||||
public function login(string $contact_key)
|
||||
{
|
||||
|
||||
return redirect('/client/login');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -496,7 +496,7 @@ class RecurringInvoiceController extends BaseController
|
||||
|
||||
$recurring_invoices->each(function ($recurring_invoice, $key) use ($action) {
|
||||
if (auth()->user()->can('edit', $recurring_invoice)) {
|
||||
$this->recurring_invoice_repo->{$action}($recurring_invoice);
|
||||
$this->performAction($recurring_invoice, $action, true);
|
||||
}
|
||||
});
|
||||
|
||||
@ -572,38 +572,56 @@ class RecurringInvoiceController extends BaseController
|
||||
* )
|
||||
*/
|
||||
public function action(ActionRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice, $action)
|
||||
{
|
||||
return $this->performAction($recurring_invoice, $action);
|
||||
}
|
||||
|
||||
private function performAction(RecurringInvoice $recurring_invoice, string $action, $bulk = false)
|
||||
{
|
||||
switch ($action) {
|
||||
case 'clone_to_RecurringInvoice':
|
||||
// $recurring_invoice = CloneRecurringInvoiceFactory::create($recurring_invoice, auth()->user()->id);
|
||||
// return $this->itemResponse($recurring_invoice);
|
||||
break;
|
||||
case 'clone_to_quote':
|
||||
// $recurring_invoice = CloneRecurringInvoiceToQuoteFactory::create($recurring_invoice, auth()->user()->id);
|
||||
// todo build the quote transformer and return response here
|
||||
break;
|
||||
case 'history':
|
||||
// code...
|
||||
break;
|
||||
case 'delivery_note':
|
||||
// code...
|
||||
break;
|
||||
case 'mark_paid':
|
||||
// code...
|
||||
break;
|
||||
case 'archive':
|
||||
// code...
|
||||
$this->recurring_invoice_repo->archive($recurring_invoice);
|
||||
|
||||
if (! $bulk) {
|
||||
return $this->listResponse($recurring_invoice);
|
||||
}
|
||||
break;
|
||||
case 'restore':
|
||||
$this->recurring_invoice_repo->restore($recurring_invoice);
|
||||
|
||||
if (! $bulk) {
|
||||
return $this->listResponse($recurring_invoice);
|
||||
}
|
||||
break;
|
||||
case 'delete':
|
||||
// code...
|
||||
$this->recurring_invoice_repo->delete($recurring_invoice);
|
||||
|
||||
if (! $bulk) {
|
||||
return $this->listResponse($recurring_invoice);
|
||||
}
|
||||
break;
|
||||
case 'email':
|
||||
//dispatch email to queue
|
||||
break;
|
||||
case 'start':
|
||||
$recurring_invoice = $recurring_invoice->service()->start()->save();
|
||||
|
||||
if (! $bulk) {
|
||||
$this->itemResponse($recurring_invoice);
|
||||
}
|
||||
break;
|
||||
case 'stop':
|
||||
$recurring_invoice = $recurring_invoice->service()->stop()->save();
|
||||
|
||||
if (! $bulk) {
|
||||
$this->itemResponse($recurring_invoice);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
// code...
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +82,6 @@ class SelfUpdateController extends BaseController
|
||||
|
||||
Artisan::call('ninja:post-update');
|
||||
|
||||
return response()->json(['message'=>$res], 200);
|
||||
return response()->json(['message' => ''], 200);
|
||||
}
|
||||
}
|
||||
|
@ -117,5 +117,6 @@ class Kernel extends HttpKernel
|
||||
'contact.register' => \App\Http\Middleware\ContactRegister::class,
|
||||
'shop_token_auth' => \App\Http\Middleware\Shop\ShopTokenAuth::class,
|
||||
'phantom_secret' => \App\Http\Middleware\PhantomSecret::class,
|
||||
'contact_key_login' => \App\Http\Middleware\ContactKeyLogin::class,
|
||||
];
|
||||
}
|
||||
|
54
app/Http/Middleware/ContactKeyLogin.php
Normal file
54
app/Http/Middleware/ContactKeyLogin.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\CompanyToken;
|
||||
use Closure;
|
||||
use Auth;
|
||||
|
||||
class ContactKeyLogin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
|
||||
if ($request->segment(3) && config('ninja.db.multi_db_enabled')) {
|
||||
|
||||
if (MultiDB::findAndSetDbByContactKey($request->segment(3))) {
|
||||
|
||||
$client_contact = ClientContact::where('contact_key', $request->segment(3))->first();
|
||||
Auth::guard('contact')->login($client_contact, true);
|
||||
return redirect()->to('client/dashboard');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if ($request->has('contact_key')) {
|
||||
|
||||
if($client_contact = ClientContact::where('contact_key', $request->segment(3))->first()){
|
||||
Auth::guard('contact')->login($client_contact, true);
|
||||
return redirect()->to('client/dashboard');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -95,9 +95,24 @@ class StoreRecurringInvoiceRequest extends Request
|
||||
}
|
||||
|
||||
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
|
||||
//$input['line_items'] = json_encode($input['line_items']);
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
if(isset($input['auto_bill']))
|
||||
$input['auto_bill_enabled'] = $this->setAutoBillFlag($input['auto_bill']);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
private function setAutoBillFlag($auto_bill)
|
||||
{
|
||||
if($auto_bill == 'always')
|
||||
return true;
|
||||
|
||||
if($auto_bill == 'off')
|
||||
return false;
|
||||
|
||||
//todo do we need to handle optin / optout here?
|
||||
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
|
@ -85,6 +85,22 @@ class UpdateRecurringInvoiceRequest extends Request
|
||||
|
||||
$input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : [];
|
||||
|
||||
if(isset($input['auto_bill']))
|
||||
$input['auto_bill_enabled'] = $this->setAutoBillFlag($input['auto_bill']);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
private function setAutoBillFlag($auto_bill)
|
||||
{
|
||||
if($auto_bill == 'always')
|
||||
return true;
|
||||
|
||||
if($auto_bill == 'off')
|
||||
return false;
|
||||
|
||||
//todo do we need to handle optin / optout here?
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ use App\Helpers\Email\InvoiceEmail;
|
||||
use App\Jobs\Invoice\EmailInvoice;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\GeneratesCounter;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
|
@ -195,6 +195,20 @@ class MultiDB
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function findAndSetDbByContactKey($contact_key) :bool
|
||||
{
|
||||
foreach (self::$dbs as $db) {
|
||||
if ($client_contact = ClientContact::on($db)->where('contact_key', $contact_key)->first()) {
|
||||
self::setDb($client_contact->company->db);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static function findAndSetDbByDomain($subdomain) :bool
|
||||
{
|
||||
foreach (self::$dbs as $db) {
|
||||
|
@ -15,6 +15,7 @@ use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Helpers\Invoice\InvoiceSumInclusive;
|
||||
use App\Models\Filterable;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Services\Recurring\RecurringService;
|
||||
use App\Utils\Traits\MakesDates;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\Recurring\HasRecurrence;
|
||||
@ -103,6 +104,7 @@ class RecurringInvoice extends BaseModel
|
||||
'next_send_date',
|
||||
'remaining_cycles',
|
||||
'auto_bill',
|
||||
'auto_bill_enabled',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
@ -190,7 +192,7 @@ class RecurringInvoice extends BaseModel
|
||||
|
||||
public function getStatusAttribute()
|
||||
{
|
||||
if ($this->status_id == self::STATUS_ACTIVE && $this->next_send_date > Carbon::now())
|
||||
if ($this->status_id == self::STATUS_ACTIVE && Carbon::parse($this->next_send_date)->isFuture())
|
||||
return self::STATUS_PENDING;
|
||||
else
|
||||
return $this->status_id;
|
||||
@ -200,27 +202,27 @@ class RecurringInvoice extends BaseModel
|
||||
{
|
||||
switch ($this->frequency_id) {
|
||||
case self::FREQUENCY_WEEKLY:
|
||||
return Carbon::parse($this->next_send_date->addWeek());
|
||||
return Carbon::parse($this->next_send_date)->addWeek();
|
||||
case self::FREQUENCY_TWO_WEEKS:
|
||||
return Carbon::parse($this->next_send_date->addWeeks(2));
|
||||
return Carbon::parse($this->next_send_date)->addWeeks(2);
|
||||
case self::FREQUENCY_FOUR_WEEKS:
|
||||
return Carbon::parse($this->next_send_date->addWeeks(4));
|
||||
return Carbon::parse($this->next_send_date)->addWeeks(4);
|
||||
case self::FREQUENCY_MONTHLY:
|
||||
return Carbon::parse($this->next_send_date->addMonthNoOverflow());
|
||||
return Carbon::parse($this->next_send_date)->addMonthNoOverflow();
|
||||
case self::FREQUENCY_TWO_MONTHS:
|
||||
return Carbon::parse($this->next_send_date->addMonthsNoOverflow(2));
|
||||
return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(2);
|
||||
case self::FREQUENCY_THREE_MONTHS:
|
||||
return Carbon::parse($this->next_send_date->addMonthsNoOverflow(3));
|
||||
return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(3);
|
||||
case self::FREQUENCY_FOUR_MONTHS:
|
||||
return Carbon::parse($this->next_send_date->addMonthsNoOverflow(4));
|
||||
return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(4);
|
||||
case self::FREQUENCY_SIX_MONTHS:
|
||||
return Carbon::parse($this->next_send_date->addMonthsNoOverflow(6));
|
||||
return Carbon::parse($this->next_send_date)->addMonthsNoOverflow(6);
|
||||
case self::FREQUENCY_ANNUALLY:
|
||||
return Carbon::parse($this->next_send_date->addYear());
|
||||
return Carbon::parse($this->next_send_date)->addYear();
|
||||
case self::FREQUENCY_TWO_YEARS:
|
||||
return Carbon::parse($this->next_send_date->addYears(2));
|
||||
return Carbon::parse($this->next_send_date)->addYears(2);
|
||||
case self::FREQUENCY_THREE_YEARS:
|
||||
return Carbon::parse($this->next_send_date->addYears(3));
|
||||
return Carbon::parse($this->next_send_date)->addYears(3);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@ -231,27 +233,27 @@ class RecurringInvoice extends BaseModel
|
||||
|
||||
switch ($this->frequency_id) {
|
||||
case self::FREQUENCY_WEEKLY:
|
||||
return Carbon::parse($date->addWeek());
|
||||
return Carbon::parse($date)->addWeek();
|
||||
case self::FREQUENCY_TWO_WEEKS:
|
||||
return Carbon::parse($date->addWeeks(2));
|
||||
return Carbon::parse($date)->addWeeks(2);
|
||||
case self::FREQUENCY_FOUR_WEEKS:
|
||||
return Carbon::parse($date->addWeeks(4));
|
||||
return Carbon::parse($date)->addWeeks(4);
|
||||
case self::FREQUENCY_MONTHLY:
|
||||
return Carbon::parse($date->addMonthNoOverflow());
|
||||
return Carbon::parse($date)->addMonthNoOverflow();
|
||||
case self::FREQUENCY_TWO_MONTHS:
|
||||
return Carbon::parse($date->addMonthsNoOverflow(2));
|
||||
return Carbon::parse($date)->addMonthsNoOverflow(2);
|
||||
case self::FREQUENCY_THREE_MONTHS:
|
||||
return Carbon::parse($date->addMonthsNoOverflow(3));
|
||||
return Carbon::parse($date)->addMonthsNoOverflow(3);
|
||||
case self::FREQUENCY_FOUR_MONTHS:
|
||||
return Carbon::parse($date->addMonthsNoOverflow(4));
|
||||
return Carbon::parse($date)->addMonthsNoOverflow(4);
|
||||
case self::FREQUENCY_SIX_MONTHS:
|
||||
return Carbon::parse($date->addMonthsNoOverflow(6));
|
||||
return Carbon::parse($date)->addMonthsNoOverflow(6);
|
||||
case self::FREQUENCY_ANNUALLY:
|
||||
return Carbon::parse($date->addYear());
|
||||
return Carbon::parse($date)->addYear();
|
||||
case self::FREQUENCY_TWO_YEARS:
|
||||
return Carbon::parse($date->addYears(2));
|
||||
return Carbon::parse($date)->addYears(2);
|
||||
case self::FREQUENCY_THREE_YEARS:
|
||||
return Carbon::parse($date->addYears(3));
|
||||
return Carbon::parse($date)->addYears(3);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@ -379,24 +381,24 @@ class RecurringInvoice extends BaseModel
|
||||
if($this->remaining_cycles == -1)
|
||||
$iterations = 10;
|
||||
|
||||
$data = [];
|
||||
|
||||
$next_send_date = Carbon::parse($this->next_send_date)->copy();
|
||||
|
||||
$data = [];
|
||||
|
||||
for($x=0; $x<$iterations; $x++)
|
||||
{
|
||||
|
||||
$next_due_date = $next_send_date->copy()->addDays($this->due_date_days);
|
||||
// we don't add the days... we calc the day of the month!!
|
||||
$next_due_date = $this->calculateDueDate($next_send_date->copy()->format('Y-m-d'));
|
||||
|
||||
$next_send_date = Carbon::parse($next_send_date);
|
||||
$next_due_date = Carbon::parse($next_due_date);
|
||||
|
||||
$data[] = [
|
||||
'next_send_date' => $next_send_date->format('Y-m-d'),
|
||||
'send_date' => $next_send_date->format('Y-m-d'),
|
||||
'due_date' => $next_due_date->format('Y-m-d'),
|
||||
];
|
||||
|
||||
$next_send_date = $this->calculateDueDate($next_send_date);
|
||||
$next_send_date = $this->nextDateByFrequency($next_send_date->format('Y-m-d'));
|
||||
|
||||
}
|
||||
|
||||
@ -434,14 +436,22 @@ class RecurringInvoice extends BaseModel
|
||||
*/
|
||||
public function calculateDateFromTerms($date)
|
||||
{
|
||||
$new_date = Carbon::parse($date);
|
||||
|
||||
$client_payment_terms = $this->client->getSetting('payment_terms');
|
||||
|
||||
if($client_payment_terms == '')//no due date! return null;
|
||||
return null;
|
||||
|
||||
return $date->copy()->addDays($client_payment_terms); //add the number of days in the payment terms to the date
|
||||
return $new_date->addDays($client_payment_terms); //add the number of days in the payment terms to the date
|
||||
}
|
||||
|
||||
/**
|
||||
* Service entry points.
|
||||
*/
|
||||
public function service() :RecurringService
|
||||
{
|
||||
return new RecurringService($this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -83,7 +83,9 @@ class InvoiceRepository extends BaseRepository
|
||||
return;
|
||||
}
|
||||
|
||||
$invoice->service()->handleCancellation()->save();
|
||||
$invoice->service()->markDeleted()->handleCancellation()->save();
|
||||
|
||||
|
||||
|
||||
$invoice = parent::delete($invoice);
|
||||
|
||||
|
@ -24,6 +24,7 @@ use App\Services\Invoice\CreateInvitations;
|
||||
use App\Services\Invoice\GetInvoicePdf;
|
||||
use App\Services\Invoice\HandleCancellation;
|
||||
use App\Services\Invoice\HandleReversal;
|
||||
use App\Services\Invoice\MarkInvoiceDeleted;
|
||||
use App\Services\Invoice\MarkInvoicePaid;
|
||||
use App\Services\Invoice\MarkSent;
|
||||
use App\Services\Invoice\TriggeredActions;
|
||||
@ -154,6 +155,13 @@ class InvoiceService
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function markDeleted()
|
||||
{
|
||||
$this->invoice = (new MarkInvoiceDeleted($this->invoice))->run();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function reverseCancellation()
|
||||
{
|
||||
$this->invoice = (new HandleCancellation($this->invoice))->reverse();
|
||||
|
71
app/Services/Invoice/MarkInvoiceDeleted.php
Normal file
71
app/Services/Invoice/MarkInvoiceDeleted.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Services\Invoice;
|
||||
|
||||
use App\Events\Invoice\InvoiceWasCancelled;
|
||||
use App\Events\Payment\PaymentWasCreated;
|
||||
use App\Factory\CreditFactory;
|
||||
use App\Factory\InvoiceItemFactory;
|
||||
use App\Factory\PaymentFactory;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Models\Client;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Paymentable;
|
||||
use App\Services\AbstractService;
|
||||
use App\Services\Client\ClientService;
|
||||
use App\Services\Payment\PaymentService;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\GeneratesCounter;
|
||||
|
||||
class MarkInvoiceDeleted extends AbstractService
|
||||
{
|
||||
use GeneratesCounter;
|
||||
|
||||
private $invoice;
|
||||
|
||||
public function __construct(Invoice $invoice)
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$check = false;
|
||||
$x=0;
|
||||
|
||||
do {
|
||||
|
||||
$number = $this->calcNumber($x);
|
||||
$check = $this->checkNumberAvailable(Invoice::class, $this->invoice, $number);
|
||||
$x++;
|
||||
|
||||
} while (!$check);
|
||||
|
||||
$this->invoice->number = $number;
|
||||
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
|
||||
private function calcNumber($x)
|
||||
{
|
||||
if($x==0)
|
||||
$number = $this->invoice->number . '_' . ctrans('texts.deleted');
|
||||
else
|
||||
$number = $this->invoice->number . '_' . ctrans('texts.deleted') . '_'. $x;
|
||||
|
||||
return $number;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -72,8 +72,10 @@ class RefundPayment
|
||||
{
|
||||
if ($this->refund_data['gateway_refund'] !== false && $this->total_refund > 0) {
|
||||
if ($this->payment->company_gateway) {
|
||||
|
||||
$response = $this->payment->company_gateway->driver($this->payment->client)->refund($this->payment, $this->total_refund);
|
||||
|
||||
|
||||
if ($response['success'] == false) {
|
||||
throw new PaymentRefundFailed();
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Services\Recurring;
|
||||
|
||||
use App\Models\RecurringInvoice;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class RecurringService
|
||||
{
|
||||
@ -23,4 +24,35 @@ class RecurringService
|
||||
}
|
||||
|
||||
//set schedules - update next_send_dates
|
||||
|
||||
/**
|
||||
* Stops a recurring invoice
|
||||
*
|
||||
* @return $this RecurringService object
|
||||
*/
|
||||
public function stop()
|
||||
{
|
||||
$this->status_id = RecurringInvoice::STATUS_PAUSED;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function start()
|
||||
{
|
||||
//make sure next_send_date is either now or in the future else return.
|
||||
if(Carbon::parse($this->recurring_entity->next_send_date)->lt(now()))
|
||||
return $this;
|
||||
|
||||
$this->recurring_entity->status_id = RecurringInvoice::STATUS_ACTIVE;
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->recurring_entity->save();
|
||||
|
||||
return $this->recurring_entity;
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ class SystemHealth
|
||||
'php_version' => [
|
||||
'minimum_php_version' => (string) self::$php_version,
|
||||
'current_php_version' => phpversion(),
|
||||
'current_php_cli_version' => (string) self::checkPhpCli(),
|
||||
'is_okay' => version_compare(phpversion(), self::$php_version, '>='),
|
||||
],
|
||||
'env_writable' => self::checkEnvWritable(),
|
||||
@ -116,6 +117,21 @@ class SystemHealth
|
||||
return $result;
|
||||
}
|
||||
|
||||
private static function checkPhpCli()
|
||||
{
|
||||
|
||||
try {
|
||||
exec('php -v', $foo, $exitCode);
|
||||
|
||||
if ($exitCode === 0) {
|
||||
return empty($foo[0]) ? 'Found php cli, but no version information' : $foo[0];
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static function extensions() :array
|
||||
{
|
||||
$loaded_extensions = [];
|
||||
|
@ -306,6 +306,16 @@ trait GeneratesCounter
|
||||
return $number;
|
||||
}
|
||||
|
||||
|
||||
/*Check if a number is available for use. */
|
||||
public function checkNumberAvailable($class, $entity, $number) :bool
|
||||
{
|
||||
if($entity = $class::whereCompanyId($entity->company_id)->whereNumber($number)->withTrashed()->first())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves counters at both the company and client level.
|
||||
*
|
||||
|
@ -53,12 +53,13 @@ trait HasRecurrence
|
||||
*/
|
||||
public function setDayOfMonth($date, $day_of_month)
|
||||
{
|
||||
|
||||
$set_date = $date->copy()->setUnitNoOverflow('day', $day_of_month, 'month');
|
||||
$carbon_date = Carbon::parse($date);
|
||||
|
||||
$set_date = $carbon_date->copy()->setUnitNoOverflow('day', $day_of_month, 'month');
|
||||
|
||||
//If the set date is less than the original date we need to add a month.
|
||||
//If we are overflowing dates, then we need to diff the dates and ensure it doesn't equal 0
|
||||
if($set_date->lte($date) || $set_date->diffInDays($date) == 0)
|
||||
if($set_date->lte($date) || $set_date->diffInDays($carbon_date) == 0)
|
||||
$set_date->addMonthNoOverflow();
|
||||
|
||||
if($day_of_month == '31')
|
||||
|
149
composer.lock
generated
149
composer.lock
generated
@ -108,16 +108,16 @@
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.154.6",
|
||||
"version": "3.155.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "83a1382930359e4d4f4c9187239f059d5b282520"
|
||||
"reference": "575430a46c329a2a3723cdcb2d30df390f434ba1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/83a1382930359e4d4f4c9187239f059d5b282520",
|
||||
"reference": "83a1382930359e4d4f4c9187239f059d5b282520",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/575430a46c329a2a3723cdcb2d30df390f434ba1",
|
||||
"reference": "575430a46c329a2a3723cdcb2d30df390f434ba1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -189,7 +189,7 @@
|
||||
"s3",
|
||||
"sdk"
|
||||
],
|
||||
"time": "2020-09-18T18:16:42+00:00"
|
||||
"time": "2020-09-23T18:11:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
@ -1084,30 +1084,30 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "2.10.4",
|
||||
"version": "2.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "47433196b6390d14409a33885ee42b6208160643"
|
||||
"reference": "0d4e1a8b29dd987704842f0465aded378f441dca"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/47433196b6390d14409a33885ee42b6208160643",
|
||||
"reference": "47433196b6390d14409a33885ee42b6208160643",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/0d4e1a8b29dd987704842f0465aded378f441dca",
|
||||
"reference": "0d4e1a8b29dd987704842f0465aded378f441dca",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/cache": "^1.0",
|
||||
"doctrine/event-manager": "^1.0",
|
||||
"ext-pdo": "*",
|
||||
"php": "^7.2"
|
||||
"php": "^7.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^8.1",
|
||||
"jetbrains/phpstorm-stubs": "^2019.1",
|
||||
"nikic/php-parser": "^4.4",
|
||||
"phpstan/phpstan": "^0.12.40",
|
||||
"phpunit/phpunit": "^8.5.5",
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"psalm/plugin-phpunit": "^0.10.0",
|
||||
"symfony/console": "^2.0.5|^3.0|^4.0|^5.0",
|
||||
"vimeo/psalm": "^3.14.2"
|
||||
@ -1121,8 +1121,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.10.x-dev",
|
||||
"dev-develop": "3.0.x-dev"
|
||||
"dev-master": "4.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -1189,7 +1188,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-09-12T21:20:41+00:00"
|
||||
"time": "2020-09-20T23:24:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/event-manager",
|
||||
@ -1504,16 +1503,16 @@
|
||||
},
|
||||
{
|
||||
"name": "egulias/email-validator",
|
||||
"version": "2.1.20",
|
||||
"version": "2.1.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/egulias/EmailValidator.git",
|
||||
"reference": "f46887bc48db66c7f38f668eb7d6ae54583617ff"
|
||||
"reference": "563d0cdde5d862235ffe24a158497f4d490191b5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/f46887bc48db66c7f38f668eb7d6ae54583617ff",
|
||||
"reference": "f46887bc48db66c7f38f668eb7d6ae54583617ff",
|
||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/563d0cdde5d862235ffe24a158497f4d490191b5",
|
||||
"reference": "563d0cdde5d862235ffe24a158497f4d490191b5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1558,7 +1557,7 @@
|
||||
"validation",
|
||||
"validator"
|
||||
],
|
||||
"time": "2020-09-06T13:44:32+00:00"
|
||||
"time": "2020-09-19T14:37:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fedeisas/laravel-mail-css-inliner",
|
||||
@ -1834,16 +1833,16 @@
|
||||
},
|
||||
{
|
||||
"name": "google/apiclient-services",
|
||||
"version": "v0.146",
|
||||
"version": "v0.147",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/googleapis/google-api-php-client-services.git",
|
||||
"reference": "029e20e81508cee6dc652529514eeeb1cf56ce54"
|
||||
"reference": "8624bd004cfccb33b760ae7650d0b750168cd7f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/029e20e81508cee6dc652529514eeeb1cf56ce54",
|
||||
"reference": "029e20e81508cee6dc652529514eeeb1cf56ce54",
|
||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/8624bd004cfccb33b760ae7650d0b750168cd7f7",
|
||||
"reference": "8624bd004cfccb33b760ae7650d0b750168cd7f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1867,7 +1866,7 @@
|
||||
"keywords": [
|
||||
"google"
|
||||
],
|
||||
"time": "2020-09-12T00:24:59+00:00"
|
||||
"time": "2020-09-20T00:24:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "google/auth",
|
||||
@ -2805,16 +2804,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/ui",
|
||||
"version": "v2.4.0",
|
||||
"version": "v2.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/ui.git",
|
||||
"reference": "f5398544a9cd4804a42d09ce51735e37cd51ea2d"
|
||||
"reference": "1c69ae3e8b52fe6c9eaf83b43c6dd8ef5c3f9e2c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/ui/zipball/f5398544a9cd4804a42d09ce51735e37cd51ea2d",
|
||||
"reference": "f5398544a9cd4804a42d09ce51735e37cd51ea2d",
|
||||
"url": "https://api.github.com/repos/laravel/ui/zipball/1c69ae3e8b52fe6c9eaf83b43c6dd8ef5c3f9e2c",
|
||||
"reference": "1c69ae3e8b52fe6c9eaf83b43c6dd8ef5c3f9e2c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2856,7 +2855,7 @@
|
||||
"laravel",
|
||||
"ui"
|
||||
],
|
||||
"time": "2020-09-11T15:31:52+00:00"
|
||||
"time": "2020-09-22T16:51:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
@ -3265,16 +3264,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/mime-type-detection",
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/mime-type-detection.git",
|
||||
"reference": "fda190b62b962d96a069fcc414d781db66d65b69"
|
||||
"reference": "ea2fbfc988bade315acd5967e6d02274086d0f28"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/fda190b62b962d96a069fcc414d781db66d65b69",
|
||||
"reference": "fda190b62b962d96a069fcc414d781db66d65b69",
|
||||
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ea2fbfc988bade315acd5967e6d02274086d0f28",
|
||||
"reference": "ea2fbfc988bade315acd5967e6d02274086d0f28",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3312,7 +3311,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-08-09T10:34:01+00:00"
|
||||
"time": "2020-09-21T18:10:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/oauth1-client",
|
||||
@ -3839,16 +3838,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "2.40.0",
|
||||
"version": "2.40.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "6c7646154181013ecd55e80c201b9fd873c6ee5d"
|
||||
"reference": "d9a76d8b7eb0f97cf3a82529393245212f40ba3b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/6c7646154181013ecd55e80c201b9fd873c6ee5d",
|
||||
"reference": "6c7646154181013ecd55e80c201b9fd873c6ee5d",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d9a76d8b7eb0f97cf3a82529393245212f40ba3b",
|
||||
"reference": "d9a76d8b7eb0f97cf3a82529393245212f40ba3b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3924,20 +3923,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-09-11T19:00:58+00:00"
|
||||
"time": "2020-09-23T08:17:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v4.9.1",
|
||||
"version": "v4.10.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "88e519766fc58bd46b8265561fb79b54e2e00b28"
|
||||
"reference": "1b479e7592812411c20c34d9ed33db3957bde66e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/88e519766fc58bd46b8265561fb79b54e2e00b28",
|
||||
"reference": "88e519766fc58bd46b8265561fb79b54e2e00b28",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1b479e7592812411c20c34d9ed33db3957bde66e",
|
||||
"reference": "1b479e7592812411c20c34d9ed33db3957bde66e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3976,7 +3975,7 @@
|
||||
"parser",
|
||||
"php"
|
||||
],
|
||||
"time": "2020-08-30T16:15:20+00:00"
|
||||
"time": "2020-09-23T18:23:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nwidart/laravel-modules",
|
||||
@ -4429,16 +4428,16 @@
|
||||
},
|
||||
{
|
||||
"name": "php-http/discovery",
|
||||
"version": "1.10.0",
|
||||
"version": "1.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-http/discovery.git",
|
||||
"reference": "88ff14cad4a0db68b343260fa7ac3f1599703660"
|
||||
"reference": "4366bf1bc39b663aa87459bd725501d2f1988b6c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-http/discovery/zipball/88ff14cad4a0db68b343260fa7ac3f1599703660",
|
||||
"reference": "88ff14cad4a0db68b343260fa7ac3f1599703660",
|
||||
"url": "https://api.github.com/repos/php-http/discovery/zipball/4366bf1bc39b663aa87459bd725501d2f1988b6c",
|
||||
"reference": "4366bf1bc39b663aa87459bd725501d2f1988b6c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4490,7 +4489,7 @@
|
||||
"message",
|
||||
"psr7"
|
||||
],
|
||||
"time": "2020-09-04T08:41:23+00:00"
|
||||
"time": "2020-09-22T13:31:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-http/guzzle6-adapter",
|
||||
@ -6137,16 +6136,16 @@
|
||||
},
|
||||
{
|
||||
"name": "spatie/browsershot",
|
||||
"version": "3.37.2",
|
||||
"version": "3.38.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/browsershot.git",
|
||||
"reference": "32d2984079ed8fe690f4dc5b7b6c205ae0a7b0fd"
|
||||
"reference": "97ebb1dc0750f9c543162cb1e44d5b4916b17a7c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/browsershot/zipball/32d2984079ed8fe690f4dc5b7b6c205ae0a7b0fd",
|
||||
"reference": "32d2984079ed8fe690f4dc5b7b6c205ae0a7b0fd",
|
||||
"url": "https://api.github.com/repos/spatie/browsershot/zipball/97ebb1dc0750f9c543162cb1e44d5b4916b17a7c",
|
||||
"reference": "97ebb1dc0750f9c543162cb1e44d5b4916b17a7c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6195,7 +6194,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2020-07-21T22:40:58+00:00"
|
||||
"time": "2020-09-22T06:26:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/image",
|
||||
@ -6392,16 +6391,16 @@
|
||||
},
|
||||
{
|
||||
"name": "stripe/stripe-php",
|
||||
"version": "v7.52.0",
|
||||
"version": "v7.54.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/stripe/stripe-php.git",
|
||||
"reference": "51e95c514aff45616dff09791ca5b2f10cf5c4e8"
|
||||
"reference": "3a5cff6ce6f5f2f0fc75164d3677bd5dc3e96fe3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/51e95c514aff45616dff09791ca5b2f10cf5c4e8",
|
||||
"reference": "51e95c514aff45616dff09791ca5b2f10cf5c4e8",
|
||||
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/3a5cff6ce6f5f2f0fc75164d3677bd5dc3e96fe3",
|
||||
"reference": "3a5cff6ce6f5f2f0fc75164d3677bd5dc3e96fe3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6445,7 +6444,7 @@
|
||||
"payment processing",
|
||||
"stripe"
|
||||
],
|
||||
"time": "2020-09-08T19:29:20+00:00"
|
||||
"time": "2020-09-23T21:48:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
@ -9339,33 +9338,33 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "anahkiasen/former",
|
||||
"version": "4.4.0",
|
||||
"version": "4.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/formers/former.git",
|
||||
"reference": "2fcc1f68ca04af39a01e370ed0e2eef132ed5072"
|
||||
"reference": "625e1dbcf3a7c9a60b21ce96a7736a17b0f2ebf8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/formers/former/zipball/2fcc1f68ca04af39a01e370ed0e2eef132ed5072",
|
||||
"reference": "2fcc1f68ca04af39a01e370ed0e2eef132ed5072",
|
||||
"url": "https://api.github.com/repos/formers/former/zipball/625e1dbcf3a7c9a60b21ce96a7736a17b0f2ebf8",
|
||||
"reference": "625e1dbcf3a7c9a60b21ce96a7736a17b0f2ebf8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"anahkiasen/html-object": "~1.4",
|
||||
"illuminate/config": "~5.0|^6.0|^7.0",
|
||||
"illuminate/container": "~5.0|^6.0|^7.0",
|
||||
"illuminate/http": "~5.0|^6.0|^7.0",
|
||||
"illuminate/routing": "~5.0|^6.0|^7.0",
|
||||
"illuminate/session": "~5.0|^6.0|^7.0",
|
||||
"illuminate/support": "~5.0|^6.0|^7.0",
|
||||
"illuminate/translation": "~5.0|^6.0|^7.0",
|
||||
"php": ">=5.4.0"
|
||||
"illuminate/config": "~5.0|^6.0|^7.0|^8.0",
|
||||
"illuminate/container": "~5.0|^6.0|^7.0|^8.0",
|
||||
"illuminate/http": "~5.0|^6.0|^7.0|^8.0",
|
||||
"illuminate/routing": "~5.0|^6.0|^7.0|^8.0",
|
||||
"illuminate/session": "~5.0|^6.0|^7.0|^8.0",
|
||||
"illuminate/support": "~5.0|^6.0|^7.0|^8.0",
|
||||
"illuminate/translation": "~5.0|^6.0|^7.0|^8.0",
|
||||
"php": ">=7.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/database": "~5.0|^6.0|^7.0",
|
||||
"mockery/mockery": "~0.9.1",
|
||||
"phpunit/phpunit": "~4"
|
||||
"illuminate/database": "~5.0|^6.0|^7.0|^8.0",
|
||||
"mockery/mockery": "^1.3",
|
||||
"phpunit/phpunit": "^8.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
@ -9408,7 +9407,7 @@
|
||||
"foundation",
|
||||
"laravel"
|
||||
],
|
||||
"time": "2020-03-04T08:38:36+00:00"
|
||||
"time": "2020-09-23T18:18:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "anahkiasen/html-object",
|
||||
|
@ -19,6 +19,8 @@ Route::get('view/{entity_type}/{invitation_key}', 'ClientPortal\EntityViewContro
|
||||
Route::get('view/{entity_type}/{invitation_key}/password', 'ClientPortal\EntityViewController@password')->name('client.entity_view.password');
|
||||
Route::post('view/{entity_type}/{invitation_key}/password', 'ClientPortal\EntityViewController@handlePassword');
|
||||
|
||||
Route::get('client/key_login/{contact_key}', 'ClientPortal\ContactHashLoginController@login')->name('client.contact_login')->middleware(['contact_key_login']);
|
||||
|
||||
//todo implement domain DB
|
||||
Route::group(['middleware' => ['auth:contact', 'locale'], 'prefix' => 'client', 'as' => 'client.'], function () {
|
||||
Route::get('dashboard', 'ClientPortal\DashboardController@index')->name('dashboard'); // name = (dashboard. index / create / show / update / destroy / edit
|
||||
|
@ -20,9 +20,11 @@ use App\Models\RecurringInvoice;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @covers \App\Models\RecurringInvoice
|
||||
*/
|
||||
class RecurringDatesTest extends TestCase
|
||||
{
|
||||
@ -92,4 +94,13 @@ class RecurringDatesTest extends TestCase
|
||||
$this->assertEquals(5, count($recurring_invoice->recurringDates()));
|
||||
|
||||
}
|
||||
|
||||
public function testCompareDatesLogic()
|
||||
{
|
||||
$date = now()->startOfDay()->format('Y-m-d');
|
||||
|
||||
$this->assertTrue(Carbon::parse($date)->lte(now()->startOfDay()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user