mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-03 23:57:33 -05:00 
			
		
		
		
	Working on recurring
This commit is contained in:
		
							parent
							
								
									c389ff49f2
								
							
						
					
					
						commit
						f5eecf0eb6
					
				@ -55,6 +55,8 @@ class Kernel extends ConsoleKernel
 | 
			
		||||
 | 
			
		||||
        $schedule->job(new UpdateExchangeRates)->daily();
 | 
			
		||||
 | 
			
		||||
        $schedule->job(new RecurringInvoicesCron)->hourly();
 | 
			
		||||
 | 
			
		||||
        /* Run hosted specific jobs */
 | 
			
		||||
        if (Ninja::isHosted()) {
 | 
			
		||||
            $schedule->job(new AdjustEmailQuota())->daily();
 | 
			
		||||
 | 
			
		||||
@ -37,21 +37,24 @@ class RecurringInvoicesCron
 | 
			
		||||
    public function handle() : void
 | 
			
		||||
    {
 | 
			
		||||
        /* Get all invoices where the send date is less than NOW + 30 minutes() */
 | 
			
		||||
        info("Sending recurring invoices {now()}");
 | 
			
		||||
 | 
			
		||||
        if (! config('ninja.db.multi_db_enabled')) {
 | 
			
		||||
            $recurring_invoices = RecurringInvoice::where('next_send_date', '<=', Carbon::now()->addMinutes(30))->get();
 | 
			
		||||
 | 
			
		||||
            $recurring_invoices = RecurringInvoice::where('next_send_date', '<=', Carbon::now()->addMinutes(30))->cursor();
 | 
			
		||||
 | 
			
		||||
            Log::info(Carbon::now()->addMinutes(30).' Sending Recurring Invoices. Count = '.$recurring_invoices->count());
 | 
			
		||||
 | 
			
		||||
            $recurring_invoices->each(function ($recurring_invoice, $key) {
 | 
			
		||||
                SendRecurring::dispatch($recurring_invoice, $recurring_invoice->company->db);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            //multiDB environment, need to
 | 
			
		||||
            foreach (MultiDB::$dbs as $db) {
 | 
			
		||||
                MultiDB::setDB($db);
 | 
			
		||||
 | 
			
		||||
                $recurring_invoices = RecurringInvoice::where('next_send_date', '<=', Carbon::now()->addMinutes(30))->get();
 | 
			
		||||
                $recurring_invoices = RecurringInvoice::where('next_send_date', '<=', Carbon::now()->addMinutes(30))->cursor();
 | 
			
		||||
 | 
			
		||||
                Log::info(Carbon::now()->addMinutes(30).' Sending Recurring Invoices. Count = '.$recurring_invoices->count().'On Database # '.$db);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,10 @@
 | 
			
		||||
 | 
			
		||||
namespace App\Jobs\RecurringInvoice;
 | 
			
		||||
 | 
			
		||||
use App\Events\Invoice\InvoiceWasEmailed;
 | 
			
		||||
use App\Factory\RecurringInvoiceToInvoiceFactory;
 | 
			
		||||
use App\Helpers\Email\InvoiceEmail;
 | 
			
		||||
use App\Jobs\Invoice\EmailInvoice;
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use App\Models\RecurringInvoice;
 | 
			
		||||
use App\Utils\Traits\GeneratesCounter;
 | 
			
		||||
@ -53,29 +56,40 @@ class SendRecurring implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        // Generate Standard Invoice
 | 
			
		||||
        $invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice, $this->recurring_invoice->client);
 | 
			
		||||
        $invoice->number = $this->getNextRecurringInvoiceNumber($this->recurring_invoice->client);
 | 
			
		||||
        $invoice->status_id = Invoice::STATUS_SENT;
 | 
			
		||||
        $invoice->save();
 | 
			
		||||
        $invoice = $invoice->service()
 | 
			
		||||
                           ->markSent()
 | 
			
		||||
                           ->applyRecurringNumber()
 | 
			
		||||
                           ->createInvitations()
 | 
			
		||||
                           ->save();
 | 
			
		||||
 | 
			
		||||
        // Queue: Emails for invoice
 | 
			
		||||
        // foreach invoice->invitations
 | 
			
		||||
       $invoice->invitations->each(function ($invitation) use ($invoice) {
 | 
			
		||||
 | 
			
		||||
        // Fire Payment if auto-bill is enabled
 | 
			
		||||
        if ($this->recurring_invoice->settings->auto_bill) {
 | 
			
		||||
            //PAYMENT ACTION HERE TODO
 | 
			
		||||
            $email_builder = (new InvoiceEmail())->build($invitation);
 | 
			
		||||
 | 
			
		||||
            // Clean up recurring invoice object
 | 
			
		||||
            EmailInvoice::dispatch($email_builder, $invitation, $invoice->company);
 | 
			
		||||
 | 
			
		||||
            info("Firing email for invoice {$invoice->number}");
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        /* Set next date here to prevent a recurring loop forming */
 | 
			
		||||
        $this->recurring_invoice->next_send_date = $this->recurring_invoice->nextSendDate()->format('Y-m-d');
 | 
			
		||||
        $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()->format('Y-m-d');
 | 
			
		||||
        } else {
 | 
			
		||||
        /* Set completed if we don't have any more cycles remaining*/
 | 
			
		||||
        if ($this->recurring_invoice->remaining_cycles == 0) 
 | 
			
		||||
            $this->recurring_invoice->setCompleted();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->recurring_invoice->save();
 | 
			
		||||
 | 
			
		||||
        if ($invoice->invitations->count() > 0) 
 | 
			
		||||
            event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars()));
 | 
			
		||||
 | 
			
		||||
        // Fire Payment if auto-bill is enabled
 | 
			
		||||
        if ($this->recurring_invoice->auto_bill) 
 | 
			
		||||
            $invoice->service()->autoBill()->save();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -56,14 +56,16 @@ class ReminderJob implements ShouldQueue
 | 
			
		||||
                $this->processReminders($db);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function processReminders($db = null)
 | 
			
		||||
    {
 | 
			
		||||
        $invoices = Invoice::where('next_send_date', Carbon::today()->format('Y-m-d'))->get();
 | 
			
		||||
 | 
			
		||||
        $invoices->each(function ($invoice) {
 | 
			
		||||
        Invoice::where('next_send_date', Carbon::today()->format('Y-m-d'))->with('invitations')->cursor()->each(function ($invoice) {
 | 
			
		||||
        
 | 
			
		||||
            if ($invoice->isPayable()) {
 | 
			
		||||
 | 
			
		||||
                $invoice->invitations->each(function ($invitation) use ($invoice) {
 | 
			
		||||
                    $email_builder = (new InvoiceEmail())->build($invitation);
 | 
			
		||||
 | 
			
		||||
@ -72,13 +74,18 @@ class ReminderJob implements ShouldQueue
 | 
			
		||||
                    info("Firing email for invoice {$invoice->number}");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                if ($invoice->invitations->count() > 0) {
 | 
			
		||||
                if ($invoice->invitations->count() > 0) 
 | 
			
		||||
                    event(new InvoiceWasEmailed($invoice->invitations->first(), $invoice->company, Ninja::eventVars()));
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
                $invoice->next_send_date = null;
 | 
			
		||||
                $invoice->save();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								app/Services/Invoice/ApplyRecurringNumber.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								app/Services/Invoice/ApplyRecurringNumber.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
<?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\Payment\PaymentWasCreated;
 | 
			
		||||
use App\Factory\PaymentFactory;
 | 
			
		||||
use App\Models\Client;
 | 
			
		||||
use App\Models\Invoice;
 | 
			
		||||
use App\Models\Payment;
 | 
			
		||||
use App\Services\AbstractService;
 | 
			
		||||
use App\Services\Client\ClientService;
 | 
			
		||||
use App\Services\Payment\PaymentService;
 | 
			
		||||
use App\Utils\Traits\GeneratesCounter;
 | 
			
		||||
 | 
			
		||||
class ApplyRecurringNumber extends AbstractService
 | 
			
		||||
{
 | 
			
		||||
    use GeneratesCounter;
 | 
			
		||||
 | 
			
		||||
    private $client;
 | 
			
		||||
 | 
			
		||||
    private $invoice;
 | 
			
		||||
 | 
			
		||||
    public function __construct(Client $client, Invoice $invoice)
 | 
			
		||||
    {
 | 
			
		||||
        $this->client = $client;
 | 
			
		||||
 | 
			
		||||
        $this->invoice = $invoice;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function run()
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->invoice->number != '') {
 | 
			
		||||
            return $this->invoice;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch ($this->client->getSetting('counter_number_applied')) {
 | 
			
		||||
            case 'when_saved':
 | 
			
		||||
                $this->invoice->number = $this->getNextRecurringInvoiceNumber($this->client);;
 | 
			
		||||
                break;
 | 
			
		||||
            case 'when_sent':
 | 
			
		||||
                if ($this->invoice->status_id == Invoice::STATUS_SENT) {
 | 
			
		||||
                $this->invoice->number = $this->getNextRecurringInvoiceNumber($this->client);;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                // code...
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $this->invoice;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -74,22 +74,6 @@ class AutoBillInvoice extends AbstractService
 | 
			
		||||
 | 
			
		||||
        $payment = $gateway_token->gateway->driver($this->client)->tokenBilling($gateway_token, $payment_hash);
 | 
			
		||||
 | 
			
		||||
        //this is redundant - taken care of much further down.
 | 
			
		||||
        // if($payment){
 | 
			
		||||
 | 
			
		||||
        //     if($this->invoice->partial > 0)
 | 
			
		||||
        //         $amount = $this->invoice->partial;
 | 
			
		||||
        //     else
 | 
			
		||||
        //         $amount = $this->invoice->balance;
 | 
			
		||||
 | 
			
		||||
        //     $this->invoice = $this->invoice->service()->addGatewayFee($gateway_token->gateway, $amount)->save();
 | 
			
		||||
 | 
			
		||||
        // }
 | 
			
		||||
        // else
 | 
			
		||||
        // {
 | 
			
		||||
        //     //TODO autobill failed
 | 
			
		||||
        // }
 | 
			
		||||
 | 
			
		||||
        return $this->invoice;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ use App\Models\Payment;
 | 
			
		||||
use App\Services\Client\ClientService;
 | 
			
		||||
use App\Services\Invoice\ApplyNumber;
 | 
			
		||||
use App\Services\Invoice\ApplyPayment;
 | 
			
		||||
use App\Services\Invoice\ApplyRecurringNumber;
 | 
			
		||||
use App\Services\Invoice\AutoBillInvoice;
 | 
			
		||||
use App\Services\Invoice\CreateInvitations;
 | 
			
		||||
use App\Services\Invoice\GetInvoicePdf;
 | 
			
		||||
@ -64,6 +65,18 @@ class InvoiceService
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Applies the recurring invoice number.
 | 
			
		||||
     * @return $this InvoiceService object
 | 
			
		||||
     */
 | 
			
		||||
    public function applyRecurringNumber()
 | 
			
		||||
    {
 | 
			
		||||
        $this->invoice = (new ApplyRecurringNumber($this->invoice->client, $this->invoice))->run();
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Apply a payment amount to an invoice.
 | 
			
		||||
     * @param  Payment $payment        The Payment
 | 
			
		||||
 | 
			
		||||
@ -44,13 +44,9 @@ class AddIsPublicToDocumentsTable extends Migration
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Schema::table('recurring_invoices', function ($table) {
 | 
			
		||||
            $table->string('auto_bill');
 | 
			
		||||
            $table->boolean('auto_bill')->default(0);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Schema::table('recurring_expenses', function ($table) {
 | 
			
		||||
        //     $table->string('auto_bill');
 | 
			
		||||
        // });
 | 
			
		||||
 | 
			
		||||
        Schema::table('companies', function ($table) {
 | 
			
		||||
            $table->enum('default_auto_bill', ['off', 'always', 'optin', 'optout'])->default('off');
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user