diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 18d6f6529f91..8fcf06167227 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -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(); + + } /** diff --git a/app/Factory/RecurringInvoiceToInvoiceFactory.php b/app/Factory/RecurringInvoiceToInvoiceFactory.php new file mode 100644 index 000000000000..764fabddfeb0 --- /dev/null +++ b/app/Factory/RecurringInvoiceToInvoiceFactory.php @@ -0,0 +1,55 @@ +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; + } + +} diff --git a/app/Jobs/Cron/RecurringInvoicesCron.php b/app/Jobs/Cron/RecurringInvoicesCron.php new file mode 100644 index 000000000000..6f6c74a64e68 --- /dev/null +++ b/app/Jobs/Cron/RecurringInvoicesCron.php @@ -0,0 +1,60 @@ +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); + + }); + + } + + + + + + +} diff --git a/app/Jobs/RecurringInvoice/SendRecurring.php b/app/Jobs/RecurringInvoice/SendRecurring.php new file mode 100644 index 000000000000..00f4c8b2c1da --- /dev/null +++ b/app/Jobs/RecurringInvoice/SendRecurring.php @@ -0,0 +1,86 @@ +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(); + + } + + + + + + +} diff --git a/app/Jobs/Util/UploadFile.php b/app/Jobs/Util/UploadFile.php index 98cb3def2a65..6b2260ba01bc 100644 --- a/app/Jobs/Util/UploadFile.php +++ b/app/Jobs/Util/UploadFile.php @@ -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; diff --git a/app/Models/RecurringInvoice.php b/app/Models/RecurringInvoice.php index b4bc1f0b2888..0ba9dd163809 100644 --- a/app/Models/RecurringInvoice.php +++ b/app/Models/RecurringInvoice.php @@ -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(); + + } }