mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Working on Sending Recurring invoices
This commit is contained in:
parent
364df6bfe2
commit
2549da4e6f
@ -13,6 +13,7 @@ namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
use App\Jobs\Cron\RecurringInvoicesCron;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
@ -35,6 +36,10 @@ class Kernel extends ConsoleKernel
|
||||
{
|
||||
// $schedule->command('inspire')
|
||||
// ->hourly();
|
||||
|
||||
$schedule->job(new RecurringInvoicesCron)->hourly();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
55
app/Factory/RecurringInvoiceToInvoiceFactory.php
Normal file
55
app/Factory/RecurringInvoiceToInvoiceFactory.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Factory;
|
||||
|
||||
use App\DataMapper\ClientSettings;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\RecurringInvoice;
|
||||
|
||||
class RecurringInvoiceToInvoiceFactory
|
||||
{
|
||||
|
||||
public static function create(RecurringInvoice $recurring_invoice) :Invoice
|
||||
{
|
||||
$invoice = new Invoice();
|
||||
$invoice->status_id = Invoice::STATUS_DRAFT;
|
||||
$invoice->discount = $recurring_invoice->discount;
|
||||
$invoice->is_amount_discount = $recurringinvoice->is_amount_discount;
|
||||
$invoice->po_number = $recurringinvoice->po_number;
|
||||
$invoice->footer = $recurringinvoice->footer;
|
||||
$invoice->terms = $recurringinvoice->terms;
|
||||
$invoice->public_notes = $recurringinvoice->public_notes;
|
||||
$invoice->private_notes = $recurringinvoice->private_notes;
|
||||
$invoice->invoice_date = date_create()->format('Y-m-d');
|
||||
$invoice->due_date = $recurringinvoice->due_date; //todo calculate based on terms
|
||||
$invoice->is_deleted = $recurringinvoice->is_deleted;
|
||||
$invoice->line_items = $recurringinvoice->line_items;
|
||||
$invoice->settings = $recurringinvoice->settings;
|
||||
$invoice->backup = json_encode([]);
|
||||
$invoice->tax_name1 = $recurringinvoice->tax_name1;
|
||||
$invoice->tax_rate1 = $recurringinvoice->tax_rate1;
|
||||
$invoice->tax_name2 = $recurringinvoice->tax_name2;
|
||||
$invoice->tax_rate2 = $recurringinvoice->tax_rate2;
|
||||
$invoice->custom_value1 = $recurringinvoice->custom_value1;
|
||||
$invoice->custom_value2 = $recurringinvoice->custom_value2;
|
||||
$invoice->custom_value3 = $recurringinvoice->custom_value3;
|
||||
$invoice->custom_value4 = $recurringinvoice->custom_value4;
|
||||
$invoice->amount = $recurringinvoice->amount;
|
||||
$invoice->balance = $recurringinvoice->balance;
|
||||
$invoice->user_id = $recurringinvoice->user_id;
|
||||
$invoice->company_id = $recurringinvoice->company_id;
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
}
|
60
app/Jobs/Cron/RecurringInvoicesCron.php
Normal file
60
app/Jobs/Cron/RecurringInvoicesCron.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\Cron;
|
||||
|
||||
use App\Jobs\RecurringInvoice\SendRecurring;
|
||||
use App\Models\RecurringInvoice;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class RecurringInvoicesCron
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle() : void
|
||||
{
|
||||
/* Get all invoices where the send date is less than NOW + 30 minutes() */
|
||||
|
||||
$recurring_invoices = RecurringInvoice::where('next_send_date', '<=' Carbon::now()->addMinutes(30))->get();
|
||||
|
||||
Log::info(Carbon::now()->addMinutes(30) . ' Sending Recurring Invoices. Count = '. $recurring_invoices->count() );
|
||||
|
||||
$recurring_invoices->each(function ($recurring_invoice, $key) {
|
||||
|
||||
SendRecurring::dispatch($recurring_invoice);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
86
app/Jobs/RecurringInvoice/SendRecurring.php
Normal file
86
app/Jobs/RecurringInvoice/SendRecurring.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com)
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\Jobs\RecurringInvoice;
|
||||
|
||||
use App\Factory\RecurringInvoiceToInvoiceFactory;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Utils\Traits\GeneratesNumberCounter;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class SendRecurring
|
||||
{
|
||||
|
||||
use GeneratesNumberCounter;
|
||||
|
||||
public $recurring_invoice;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function __construct(RecurringInvoice $recurring_invoice)
|
||||
{
|
||||
|
||||
$this->recurring_invoice = $recurring_invoice;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle() : void
|
||||
{
|
||||
|
||||
// Generate Standard Invoice
|
||||
$invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice);
|
||||
$invoice->invoice_number = $this->getNextNumber($invoice);
|
||||
$invoice->save();
|
||||
|
||||
// Queue: Emails for invoice
|
||||
|
||||
|
||||
// Calcuate next send date for recurring invoice
|
||||
|
||||
|
||||
// Decrement # of invoices remaining
|
||||
|
||||
|
||||
// Fire Payment if auto-bill is enabled
|
||||
|
||||
|
||||
// Clean up recurring invoice object
|
||||
|
||||
$this->recurring_invoice->remaining_cycles = $this->recurring_invoice->remainingCycles();
|
||||
$this->recurring_invoice->last_sent_date = date('Y-m-d');
|
||||
|
||||
if($this->recurring_invoice->remaining_cycles != 0)
|
||||
$this->recurring_invoice->next_send_date = $this->recurring_invoice->nextSendDate();
|
||||
else
|
||||
$this->recurring_invoice->setCompleted();
|
||||
|
||||
|
||||
$this->recurring_invoice->save();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace Jobs\Util;
|
||||
namespace App\Jobs\Util;
|
||||
|
||||
use App\Models\Document;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
@ -83,4 +83,51 @@ class RecurringInvoice extends BaseModel
|
||||
{
|
||||
$this->morphMany(RecurringInvoiceInvitation::class);
|
||||
}
|
||||
|
||||
public function nextSendDate()
|
||||
{
|
||||
|
||||
switch ($this->frequency_id) {
|
||||
case FREQUENCY_WEEKLY:
|
||||
return $this->next_send_date->addWeek();
|
||||
case FREQUENCY_TWO_WEEKS:
|
||||
return $this->next_send_date->addWeeks(2);
|
||||
case FREQUENCY_FOUR_WEEKS:
|
||||
return $this->next_send_date->addWeeks(4);
|
||||
case FREQUENCY_MONTHLY:
|
||||
return $this->next_send_date->addMonth();
|
||||
case FREQUENCY_TWO_MONTHS:
|
||||
return $this->next_send_date->addMonths(2);
|
||||
case FREQUENCY_THREE_MONTHS:
|
||||
return $this->next_send_date->addMonths(3);
|
||||
case FREQUENCY_FOUR_MONTHS:
|
||||
return $this->next_send_date->addMonths(4);
|
||||
case FREQUENCY_SIX_MONTHS:
|
||||
return $this->next_send_date->addMonths(6);
|
||||
case FREQUENCY_ANNUALLY:
|
||||
return $this->next_send_date->addYear();
|
||||
case FREQUENCY_TWO_YEARS:
|
||||
return $this->next_send_date->addYears(2);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
public function remainingCycles()
|
||||
{
|
||||
|
||||
if($this->remaining_cycles == 0)
|
||||
return 0;
|
||||
else
|
||||
return $this->remaining_cycles - 1;
|
||||
|
||||
}
|
||||
|
||||
public function setCompleted()
|
||||
{
|
||||
|
||||
$this->status_id = self::STATUS_COMPLETED;
|
||||
$this->next_send_date = null;
|
||||
$this->save();
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user