Working on Sending Recurring invoices

This commit is contained in:
David Bomba 2019-05-23 15:08:31 +10:00
parent 364df6bfe2
commit 2549da4e6f
6 changed files with 254 additions and 1 deletions

View File

@ -13,6 +13,7 @@ namespace App\Console;
use Illuminate\Console\Scheduling\Schedule; use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel; use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Jobs\Cron\RecurringInvoicesCron;
class Kernel extends ConsoleKernel class Kernel extends ConsoleKernel
{ {
@ -35,6 +36,10 @@ class Kernel extends ConsoleKernel
{ {
// $schedule->command('inspire') // $schedule->command('inspire')
// ->hourly(); // ->hourly();
$schedule->job(new RecurringInvoicesCron)->hourly();
} }
/** /**

View 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;
}
}

View 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);
});
}
}

View 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();
}
}

View File

@ -9,7 +9,7 @@
* @license https://opensource.org/licenses/AAL * @license https://opensource.org/licenses/AAL
*/ */
namespace Jobs\Util; namespace App\Jobs\Util;
use App\Models\Document; use App\Models\Document;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;

View File

@ -83,4 +83,51 @@ class RecurringInvoice extends BaseModel
{ {
$this->morphMany(RecurringInvoiceInvitation::class); $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();
}
} }