mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-03 22:07:33 -05: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