App\Ninja\Repositories\InvoiceRepository::createRecurringInvoice PHP Method

createRecurringInvoice() public method

public createRecurringInvoice ( Invoice $recurInvoice ) : mixed
$recurInvoice app\models\Invoice
return mixed
    public function createRecurringInvoice(Invoice $recurInvoice)
    {
        $recurInvoice->load('account.timezone', 'invoice_items', 'client', 'user');
        if ($recurInvoice->client->deleted_at) {
            return false;
        }
        if (!$recurInvoice->user->confirmed) {
            return false;
        }
        if (!$recurInvoice->shouldSendToday()) {
            return false;
        }
        $invoice = Invoice::createNew($recurInvoice);
        $invoice->invoice_type_id = INVOICE_TYPE_STANDARD;
        $invoice->client_id = $recurInvoice->client_id;
        $invoice->recurring_invoice_id = $recurInvoice->id;
        $invoice->invoice_number = $recurInvoice->account->getNextInvoiceNumber($invoice);
        $invoice->amount = $recurInvoice->amount;
        $invoice->balance = $recurInvoice->amount;
        $invoice->invoice_date = date_create()->format('Y-m-d');
        $invoice->discount = $recurInvoice->discount;
        $invoice->po_number = $recurInvoice->po_number;
        $invoice->public_notes = Utils::processVariables($recurInvoice->public_notes);
        $invoice->terms = Utils::processVariables($recurInvoice->terms);
        $invoice->invoice_footer = Utils::processVariables($recurInvoice->invoice_footer);
        $invoice->tax_name1 = $recurInvoice->tax_name1;
        $invoice->tax_rate1 = $recurInvoice->tax_rate1;
        $invoice->tax_name2 = $recurInvoice->tax_name2;
        $invoice->tax_rate2 = $recurInvoice->tax_rate2;
        $invoice->invoice_design_id = $recurInvoice->invoice_design_id;
        $invoice->custom_value1 = $recurInvoice->custom_value1 ?: 0;
        $invoice->custom_value2 = $recurInvoice->custom_value2 ?: 0;
        $invoice->custom_taxes1 = $recurInvoice->custom_taxes1 ?: 0;
        $invoice->custom_taxes2 = $recurInvoice->custom_taxes2 ?: 0;
        $invoice->custom_text_value1 = Utils::processVariables($recurInvoice->custom_text_value1);
        $invoice->custom_text_value2 = Utils::processVariables($recurInvoice->custom_text_value2);
        $invoice->is_amount_discount = $recurInvoice->is_amount_discount;
        $invoice->due_date = $recurInvoice->getDueDate();
        $invoice->save();
        foreach ($recurInvoice->invoice_items as $recurItem) {
            $item = InvoiceItem::createNew($recurItem);
            $item->product_id = $recurItem->product_id;
            $item->qty = $recurItem->qty;
            $item->cost = $recurItem->cost;
            $item->notes = Utils::processVariables($recurItem->notes);
            $item->product_key = Utils::processVariables($recurItem->product_key);
            $item->tax_name1 = $recurItem->tax_name1;
            $item->tax_rate1 = $recurItem->tax_rate1;
            $item->tax_name2 = $recurItem->tax_name2;
            $item->tax_rate2 = $recurItem->tax_rate2;
            $item->custom_value1 = Utils::processVariables($recurItem->custom_value1);
            $item->custom_value2 = Utils::processVariables($recurItem->custom_value2);
            $invoice->invoice_items()->save($item);
        }
        foreach ($recurInvoice->documents as $recurDocument) {
            $document = $recurDocument->cloneDocument();
            $invoice->documents()->save($document);
        }
        foreach ($recurInvoice->invitations as $recurInvitation) {
            $invitation = Invitation::createNew($recurInvitation);
            $invitation->contact_id = $recurInvitation->contact_id;
            $invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
            $invoice->invitations()->save($invitation);
        }
        $recurInvoice->last_sent_date = date('Y-m-d');
        $recurInvoice->save();
        if ($recurInvoice->getAutoBillEnabled() && !$recurInvoice->account->auto_bill_on_due_date) {
            // autoBillInvoice will check for ACH, so we're not checking here
            if ($this->paymentService->autoBillInvoice($invoice)) {
                // update the invoice reference to match its actual state
                // this is to ensure a 'payment received' email is sent
                $invoice->invoice_status_id = INVOICE_STATUS_PAID;
            }
        }
        return $invoice;
    }

Usage Example

 public function fire()
 {
     $this->info(date('Y-m-d') . ' Running SendRecurringInvoices...');
     $today = new DateTime();
     $invoices = Invoice::with('account.timezone', 'invoice_items', 'client', 'user')->whereRaw('is_deleted IS FALSE AND deleted_at IS NULL AND is_recurring IS TRUE AND frequency_id > 0 AND start_date <= ? AND (end_date IS NULL OR end_date >= ?)', [$today, $today])->orderBy('id', 'asc')->get();
     $this->info(count($invoices) . ' recurring invoice(s) found');
     foreach ($invoices as $recurInvoice) {
         $shouldSendToday = $recurInvoice->shouldSendToday();
         $this->info('Processing Invoice ' . $recurInvoice->id . ' - Should send ' . ($shouldSendToday ? 'YES' : 'NO'));
         if (!$shouldSendToday) {
             continue;
         }
         $recurInvoice->account->loadLocalizationSettings($recurInvoice->client);
         $invoice = $this->invoiceRepo->createRecurringInvoice($recurInvoice);
         if ($invoice && !$invoice->isPaid()) {
             $this->info('Sending Invoice');
             $this->mailer->sendInvoice($invoice);
         }
     }
     $delayedAutoBillInvoices = Invoice::with('account.timezone', 'recurring_invoice', 'invoice_items', 'client', 'user')->whereRaw('is_deleted IS FALSE AND deleted_at IS NULL AND is_recurring IS FALSE
         AND balance > 0 AND due_date = ? AND recurring_invoice_id IS NOT NULL', [$today->format('Y-m-d')])->orderBy('invoices.id', 'asc')->get();
     $this->info(count($delayedAutoBillInvoices) . ' due recurring invoice instance(s) found');
     /** @var Invoice $invoice */
     foreach ($delayedAutoBillInvoices as $invoice) {
         if ($invoice->isPaid()) {
             continue;
         }
         if ($invoice->getAutoBillEnabled() && $invoice->client->autoBillLater()) {
             $this->info('Processing Autobill-delayed Invoice ' . $invoice->id);
             $this->paymentService->autoBillInvoice($invoice);
         }
     }
     $this->info('Done');
 }