1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-13 06:32:40 +01:00

Merge pull request #7441 from turbo124/v5-develop

Set conditionals for recurring invoices that are being restarted
This commit is contained in:
David Bomba 2022-05-17 18:02:25 +10:00 committed by GitHub
commit 59fdc51ce0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 53 additions and 19 deletions

View File

@ -30,7 +30,8 @@ class CloneQuoteToInvoiceFactory
unset($quote_array['invitations']);
//preserve terms if they exist on Quotes
if(array_key_exists('terms', $quote_array) && strlen($quote_array['terms']) < 2)
//if(array_key_exists('terms', $quote_array) && strlen($quote_array['terms']) < 2)
if(!$quote->company->use_quote_terms_on_conversion)
unset($quote_array['terms']);
// unset($quote_array['public_notes']);
@ -38,7 +39,6 @@ class CloneQuoteToInvoiceFactory
unset($quote_array['design_id']);
unset($quote_array['user']);
foreach ($quote_array as $key => $value) {
$invoice->{$key} = $value;
}

View File

@ -32,7 +32,8 @@ class GenericReportRequest extends Request
'end_date' => 'string|date',
'date_key' => 'string',
'date_range' => 'string',
'report_keys' => 'present|array'
'report_keys' => 'present|array',
'send_email' => 'bool',
];
}
}

View File

@ -33,7 +33,8 @@ class ProfitLossRequest extends Request
'is_income_billed' => 'required|bail|bool',
'is_expense_billed' => 'required|bail|bool',
'include_tax' => 'required|bail|bool',
'date_range' => 'required|bail|string'
'date_range' => 'required|bail|string',
'send_email' => 'bool',
];
}
}

View File

@ -53,6 +53,7 @@ class AutoBillCron
$auto_bill_partial_invoices = Invoice::whereDate('partial_due_date', '<=', now())
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
->where('auto_bill_enabled', true)
->where('auto_bill_tries', '<', 3)
->where('balance', '>', 0)
->where('is_deleted', false)
->whereHas('company', function ($query) {
@ -70,6 +71,7 @@ class AutoBillCron
$auto_bill_invoices = Invoice::whereDate('due_date', '<=', now())
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
->where('auto_bill_enabled', true)
->where('auto_bill_tries', '<', 3)
->where('balance', '>', 0)
->where('is_deleted', false)
->whereHas('company', function ($query) {
@ -94,6 +96,7 @@ class AutoBillCron
$auto_bill_partial_invoices = Invoice::whereDate('partial_due_date', '<=', now())
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
->where('auto_bill_enabled', true)
->where('auto_bill_tries', '<', 3)
->where('balance', '>', 0)
->where('is_deleted', false)
->whereHas('company', function ($query) {
@ -111,6 +114,7 @@ class AutoBillCron
$auto_bill_invoices = Invoice::whereDate('due_date', '<=', now())
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
->where('auto_bill_enabled', true)
->where('auto_bill_tries', '<', 3)
->where('balance', '>', 0)
->where('is_deleted', false)
->whereHas('company', function ($query) {

View File

@ -67,11 +67,23 @@ class RecurringInvoicesCron
nlog("Trying to send {$recurring_invoice->number}");
/* Special check if we should generate another invoice is the previous one is yet to be paid */
if($recurring_invoice->company->stop_on_unpaid_recurring && $recurring_invoice->invoices()->whereIn('status_id', [2,3])->where('is_deleted', 0)->where('balance', '>', 0)->exists()) {
nlog("Existing invoice exists, skipping");
return;
}
try{
SendRecurring::dispatchNow($recurring_invoice, $recurring_invoice->company->db);
}
catch(\Exception $e){
nlog("Unable to sending recurring invoice {$recurring_invoice->id} ". $e->getMessage());
}
});
@ -103,6 +115,13 @@ class RecurringInvoicesCron
nlog("Trying to send {$recurring_invoice->number}");
if($recurring_invoice->company->stop_on_unpaid_recurring) {
if($recurring_invoice->invoices()->whereIn('status_id', [2,3])->where('is_deleted', 0)->where('balance', '>', 0)->exists())
return;
}
try{
SendRecurring::dispatchNow($recurring_invoice, $recurring_invoice->company->db);
}

View File

@ -100,6 +100,8 @@ class Company extends BaseModel
'client_registration_fields',
'convert_rate_to_client',
'markdown_email_enabled',
'stop_on_unpaid_recurring',
'use_quote_terms_on_conversion',
];
protected $hidden = [

View File

@ -90,8 +90,7 @@ class Invoice extends BaseModel
'subscription_id',
'auto_bill_enabled',
'uses_inclusive_taxes',
'vendor_id',
'auto_bill_tries'
'vendor_id'
];
protected $casts = [

View File

@ -227,12 +227,21 @@ class RecurringInvoice extends BaseModel
if (!$this->next_send_date) {
return null;
}
nlog("frequency = $this->frequency_id");
nlog("frequency = $this->next_send_date");
$offset = $this->client->timezone_offset();
/* If this setting is enabled, the recurring invoice may be set in the past */
if($this->company->stop_on_unpaid_recurring) {
/* Lets set the next send date to now so we increment from today, rather than in the past*/
if(Carbon::parse($this->next_send_date)->lt(now()->subDays(3)))
$this->next_send_date = now()->format('Y-m-d');
}
/*
As we are firing at UTC+0 if our offset is negative it is technically firing the day before so we always need
to add ON a day - a day = 86400 seconds

View File

@ -117,31 +117,26 @@ class AutoBillInvoice extends AbstractService
$payment = false;
$number_of_retries = $this->invoice->auto_bill_tries;
try {
$payment = $gateway_token->gateway
->driver($this->client)
->setPaymentHash($payment_hash)
->tokenBilling($gateway_token, $payment_hash);
} catch (\Exception $e) {
//increase the counter
$this->invoice->auto_bill_tries = $number_of_retries + 1;
$this->invoice->save();
//disable auto bill if limit of 3 is reached
if ($this->invoice->auto_bill_tries == 3) {
$this->invoice->auto_bill_enabled = false;
$this->invoice->auto_bill_tries = 0; //reset the counter here in case auto billing is turned on again in the future.
$this->invoice->save();
}
nlog("payment NOT captured for " . $this->invoice->number . " with error " . $e->getMessage());
// $this->invoice->service()->removeUnpaidGatewayFees();
}
if ($payment) {
info("Auto Bill payment captured for " . $this->invoice->number);
}
// return $this->invoice->fresh();
}
/**

View File

@ -168,6 +168,7 @@ class CompanyTransformer extends EntityTransformer
'client_registration_fields' => (array) $company->client_registration_fields,
'convert_rate_to_client' => (bool) $company->convert_rate_to_client,
'markdown_email_enabled' => (bool) $company->markdown_email_enabled,
'stop_on_unpaid_recurring' => (bool) $company->stop_on_unpaid_recurring,
];
}

View File

@ -16,6 +16,11 @@ class AddAutoBillTriesToInvoicesTable extends Migration
Schema::table('invoices', function (Blueprint $table) {
$table->smallInteger('auto_bill_tries')->default(0);
});
Schema::table('companies', function (Blueprint $table) {
$table->boolean('stop_on_unpaid_recurring')->default(0);
$table->boolean('use_quote_terms_on_conversion')->default(0);
});
}
/**
@ -25,8 +30,6 @@ class AddAutoBillTriesToInvoicesTable extends Migration
*/
public function down()
{
Schema::table('invoices', function (Blueprint $table) {
$table->dropColumn('auto_bill_tries');
});
}
}