mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge pull request #4705 from turbo124/v5-develop
Autobill improvements
This commit is contained in:
commit
2e49776d75
@ -432,10 +432,11 @@ class ClientController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function destroy(DestroyClientRequest $request, Client $client)
|
public function destroy(DestroyClientRequest $request, Client $client)
|
||||||
{
|
{
|
||||||
//may not need these destroy routes as we are using actions to 'archive/delete'
|
|
||||||
$client->delete();
|
|
||||||
|
|
||||||
return response()->json([], 200);
|
$this->client_repo->delete($client);
|
||||||
|
|
||||||
|
return $this->itemResponse($client->fresh());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -421,7 +421,7 @@ class CompanyGatewayController extends BaseController
|
|||||||
{
|
{
|
||||||
$company_gateway->delete();
|
$company_gateway->delete();
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($company_gateway->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -420,9 +420,9 @@ class CreditController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function destroy(DestroyCreditRequest $request, Credit $credit)
|
public function destroy(DestroyCreditRequest $request, Credit $credit)
|
||||||
{
|
{
|
||||||
$credit->delete();
|
$this->credit_repository->delete($credit);
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($credit->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -415,7 +415,7 @@ class DesignController extends BaseController
|
|||||||
$design->delete();
|
$design->delete();
|
||||||
$design->save();
|
$design->save();
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($design->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -414,7 +414,7 @@ class GroupSettingController extends BaseController
|
|||||||
{
|
{
|
||||||
$group_setting->delete();
|
$group_setting->delete();
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($group_setting->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -451,9 +451,9 @@ class InvoiceController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function destroy(DestroyInvoiceRequest $request, Invoice $invoice)
|
public function destroy(DestroyInvoiceRequest $request, Invoice $invoice)
|
||||||
{
|
{
|
||||||
$invoice->delete();
|
$this->invoice_repo->delete($invoice);
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($invoice->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -397,7 +397,7 @@ class PaymentTermController extends BaseController
|
|||||||
{
|
{
|
||||||
$payment_term->delete();
|
$payment_term->delete();
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($payment_term->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -429,7 +429,7 @@ class ProjectController extends BaseController
|
|||||||
$project->delete();
|
$project->delete();
|
||||||
$project->save();
|
$project->save();
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($project->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -441,9 +441,9 @@ class QuoteController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function destroy(DestroyQuoteRequest $request, Quote $quote)
|
public function destroy(DestroyQuoteRequest $request, Quote $quote)
|
||||||
{
|
{
|
||||||
$quote->delete();
|
$this->quote_repo->delete($quote);
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($quote->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -426,9 +426,9 @@ class RecurringInvoiceController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function destroy(DestroyRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice)
|
public function destroy(DestroyRecurringInvoiceRequest $request, RecurringInvoice $recurring_invoice)
|
||||||
{
|
{
|
||||||
$recurring_invoice->delete();
|
$this->recurring_invoice_repo->delete($recurring_invoice);
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($recurring_invoice->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -428,9 +428,9 @@ class RecurringQuoteController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function destroy(DestroyRecurringQuoteRequest $request, RecurringQuote $recurring_quote)
|
public function destroy(DestroyRecurringQuoteRequest $request, RecurringQuote $recurring_quote)
|
||||||
{
|
{
|
||||||
$recurring_quote->delete();
|
$this->recurring_quote_repo->delete($recurring_quote);
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($recurring_quote->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -425,9 +425,9 @@ class TaskController extends BaseController
|
|||||||
public function destroy(DestroyTaskRequest $request, Task $task)
|
public function destroy(DestroyTaskRequest $request, Task $task)
|
||||||
{
|
{
|
||||||
//may not need these destroy routes as we are using actions to 'archive/delete'
|
//may not need these destroy routes as we are using actions to 'archive/delete'
|
||||||
$task->delete();
|
$this->task_repo->delete($task);
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($task->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -400,7 +400,7 @@ class TaskStatusController extends BaseController
|
|||||||
{
|
{
|
||||||
$task_status->delete();
|
$task_status->delete();
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($task_status->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -432,7 +432,7 @@ class VendorController extends BaseController
|
|||||||
//may not need these destroy routes as we are using actions to 'archive/delete'
|
//may not need these destroy routes as we are using actions to 'archive/delete'
|
||||||
$vendor->delete();
|
$vendor->delete();
|
||||||
|
|
||||||
return response()->json([], 200);
|
return $this->itemResponse($vendor->fresh());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +60,7 @@ class BaseTransformer
|
|||||||
if ($code) {
|
if ($code) {
|
||||||
$currency = $this->maps['currencies']->where('code', $code)->first();
|
$currency = $this->maps['currencies']->where('code', $code)->first();
|
||||||
|
|
||||||
if ($currency_id) {
|
if ($currency) {
|
||||||
return $currency->id;
|
return $currency->id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,11 @@ class SendRecurring implements ShouldQueue
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Admin notification for recurring invoice sent.
|
||||||
|
if ($invoice->invitations->count() >= 1) {
|
||||||
|
$invoice->entityEmailEvent($invoice->invitations->first(), 'invoice', 'email_template_invoice');
|
||||||
|
}
|
||||||
|
|
||||||
if ($invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $this->recurring_invoice->auto_bill_enabled) {
|
if ($invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $this->recurring_invoice->auto_bill_enabled) {
|
||||||
$invoice->service()->autoBill()->save();
|
$invoice->service()->autoBill()->save();
|
||||||
}
|
}
|
||||||
|
@ -108,13 +108,27 @@ class WebhookHandler implements ShouldQueue
|
|||||||
|
|
||||||
$client = new Client(['headers' => array_merge($base_headers, $headers)]);
|
$client = new Client(['headers' => array_merge($base_headers, $headers)]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
$response = $client->post($subscription->target_url, [
|
$response = $client->post($subscription->target_url, [
|
||||||
RequestOptions::JSON => $data, // or 'json' => [...]
|
RequestOptions::JSON => $data, // or 'json' => [...]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($response->getStatusCode() == 410 || $response->getStatusCode() == 200) {
|
if ($response->getStatusCode() == 410 || $response->getStatusCode() == 200)
|
||||||
$subscription->delete();
|
$subscription->delete();
|
||||||
|
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
$response,
|
||||||
|
SystemLog::CATEGORY_WEBHOOK,
|
||||||
|
SystemLog::EVENT_WEBHOOK_RESPONSE,
|
||||||
|
SystemLog::TYPE_WEBHOOK_RESPONSE,
|
||||||
|
$this->company->clients->first(),
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
catch(\Exception $e){
|
||||||
|
|
||||||
|
// nlog($e->getMessage());
|
||||||
|
|
||||||
SystemLogger::dispatch(
|
SystemLogger::dispatch(
|
||||||
$e->getMessage(),
|
$e->getMessage(),
|
||||||
@ -126,6 +140,10 @@ class WebhookHandler implements ShouldQueue
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function failed($exception)
|
public function failed($exception)
|
||||||
{
|
{
|
||||||
nlog(print_r($exception->getMessage(), 1));
|
nlog(print_r($exception->getMessage(), 1));
|
||||||
|
@ -43,16 +43,17 @@ class AddGatewayFee extends AbstractService
|
|||||||
{
|
{
|
||||||
$gateway_fee = round($this->company_gateway->calcGatewayFee($this->amount, $this->gateway_type_id, $this->invoice->uses_inclusive_taxes), $this->invoice->client->currency()->precision);
|
$gateway_fee = round($this->company_gateway->calcGatewayFee($this->amount, $this->gateway_type_id, $this->invoice->uses_inclusive_taxes), $this->invoice->client->currency()->precision);
|
||||||
|
|
||||||
if ((int)$gateway_fee == 0) {
|
if ((int)$gateway_fee == 0)
|
||||||
return $this->invoice;
|
return $this->invoice;
|
||||||
}
|
|
||||||
|
|
||||||
|
// Removes existing stale gateway fees
|
||||||
$this->cleanPendingGatewayFees();
|
$this->cleanPendingGatewayFees();
|
||||||
|
|
||||||
if ($gateway_fee > 0) {
|
// If a gateway fee is > 0 insert the line item
|
||||||
|
if ($gateway_fee > 0)
|
||||||
return $this->processGatewayFee($gateway_fee);
|
return $this->processGatewayFee($gateway_fee);
|
||||||
}
|
|
||||||
|
|
||||||
|
// If we have reached this far, then we are apply a gateway discount
|
||||||
return $this->processGatewayDiscount($gateway_fee);
|
return $this->processGatewayDiscount($gateway_fee);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ class AutoBillInvoice extends AbstractService
|
|||||||
/* Build payment hash */
|
/* Build payment hash */
|
||||||
$payment_hash = PaymentHash::create([
|
$payment_hash = PaymentHash::create([
|
||||||
'hash' => Str::random(128),
|
'hash' => Str::random(128),
|
||||||
'data' => [['invoice_id' => $this->invoice->hashed_id, 'amount' => $amount]],
|
'data' => ['invoices' => [['invoice_id' => $this->invoice->hashed_id, 'amount' => $amount]]],
|
||||||
'fee_total' => $fee,
|
'fee_total' => $fee,
|
||||||
'fee_invoice_id' => $this->invoice->id,
|
'fee_invoice_id' => $this->invoice->id,
|
||||||
]);
|
]);
|
||||||
@ -252,17 +252,51 @@ class AutoBillInvoice extends AbstractService
|
|||||||
* @param float $amount The amount to charge
|
* @param float $amount The amount to charge
|
||||||
* @return ClientGatewayToken The client gateway token
|
* @return ClientGatewayToken The client gateway token
|
||||||
*/
|
*/
|
||||||
private function getGateway($amount)
|
// private function
|
||||||
{
|
// {
|
||||||
$gateway_tokens = $this->client->gateway_tokens()->orderBy('is_default', 'DESC')->get();
|
// $gateway_tokens = $this->client->gateway_tokens()->orderBy('is_default', 'DESC')->get();
|
||||||
|
|
||||||
|
// foreach ($gateway_tokens as $gateway_token) {
|
||||||
|
// if ($this->validGatewayLimits($gateway_token, $amount)) {
|
||||||
|
// return $gateway_token;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
public function getGateway($amount)
|
||||||
|
{
|
||||||
|
|
||||||
|
//get all client gateway tokens and set the is_default one to the first record
|
||||||
|
//$gateway_tokens = $this->client->gateway_tokens()->orderBy('is_default', 'DESC');
|
||||||
|
$gateway_tokens = $this->client->gateway_tokens;
|
||||||
|
|
||||||
|
$filtered_gateways = $gateway_tokens->filter(function ($gateway_token) use($amount) {
|
||||||
|
|
||||||
|
$company_gateway = $gateway_token->gateway;
|
||||||
|
|
||||||
|
//check if fees and limits are set
|
||||||
|
if (isset($company_gateway->fees_and_limits) && property_exists($company_gateway->fees_and_limits, $gateway_token->gateway_type_id))
|
||||||
|
{
|
||||||
|
//if valid we keep this gateway_token
|
||||||
|
if ($this->invoice->client->validGatewayForAmount($company_gateway->fees_and_limits->{$gateway_token->gateway_type_id}, $amount))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
foreach ($gateway_tokens as $gateway_token) {
|
|
||||||
if ($this->validGatewayLimits($gateway_token, $amount)) {
|
|
||||||
return $gateway_token;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return true; //if no fees_and_limits set then we automatically must add this gateway
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if($filtered_gateways->count() >= 1)
|
||||||
|
return $filtered_gateways->first();
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a gateway fee to the invoice.
|
* Adds a gateway fee to the invoice.
|
||||||
*
|
*
|
||||||
@ -332,33 +366,33 @@ class AutoBillInvoice extends AbstractService
|
|||||||
// return $this;
|
// return $this;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Checks whether a given gateway token is able
|
// * Checks whether a given gateway token is able
|
||||||
* to process the payment after passing through the
|
// * to process the payment after passing through the
|
||||||
* fees and limits check.
|
// * fees and limits check.
|
||||||
*
|
// *
|
||||||
* @param CompanyGateway $cg The CompanyGateway instance
|
// * @param CompanyGateway $cg The CompanyGateway instance
|
||||||
* @param float $amount The amount to be paid
|
// * @param float $amount The amount to be paid
|
||||||
* @return bool
|
// * @return bool
|
||||||
*/
|
// */
|
||||||
public function validGatewayLimits($cg, $amount) : bool
|
// public function validGatewayLimits($cg, $amount) : bool
|
||||||
{
|
// {
|
||||||
if (isset($cg->fees_and_limits)) {
|
// if (isset($cg->fees_and_limits)) {
|
||||||
$fees_and_limits = $cg->fees_and_limits->{'1'};
|
// $fees_and_limits = $cg->fees_and_limits->{'1'};
|
||||||
} else {
|
// } else {
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if ((property_exists($fees_and_limits, 'min_limit')) && $fees_and_limits->min_limit !== null && $amount < $fees_and_limits->min_limit) {
|
// if ((property_exists($fees_and_limits, 'min_limit')) && $fees_and_limits->min_limit !== null && $amount < $fees_and_limits->min_limit) {
|
||||||
info("amount {$amount} less than ".$fees_and_limits->min_limit);
|
// info("amount {$amount} less than ".$fees_and_limits->min_limit);
|
||||||
$passes = false;
|
// $passes = false;
|
||||||
} elseif ((property_exists($fees_and_limits, 'max_limit')) && $fees_and_limits->max_limit !== null && $amount > $fees_and_limits->max_limit) {
|
// } elseif ((property_exists($fees_and_limits, 'max_limit')) && $fees_and_limits->max_limit !== null && $amount > $fees_and_limits->max_limit) {
|
||||||
info("amount {$amount} greater than ".$fees_and_limits->max_limit);
|
// info("amount {$amount} greater than ".$fees_and_limits->max_limit);
|
||||||
$passes = false;
|
// $passes = false;
|
||||||
} else {
|
// } else {
|
||||||
$passes = true;
|
// $passes = true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return $passes;
|
// return $passes;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@ -376,6 +376,10 @@ class InvoiceService
|
|||||||
$this->invoice->terms = $settings->invoice_terms;
|
$this->invoice->terms = $settings->invoice_terms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!isset($this->invoice->public_notes)) {
|
||||||
|
$this->invoice->public_notes = $settings->public_notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class ChangeCustomSurchargeColumnType extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('invoices', function (Blueprint $table) {
|
||||||
|
$table->decimal('custom_surcharge1', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge2', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge3', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge4', 20,6)->change();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('recurring_invoices', function (Blueprint $table) {
|
||||||
|
$table->decimal('custom_surcharge1', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge2', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge3', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge4', 20,6)->change();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Schema::table('quotes', function (Blueprint $table) {
|
||||||
|
$table->decimal('custom_surcharge1', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge2', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge3', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge4', 20,6)->change();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Schema::table('credits', function (Blueprint $table) {
|
||||||
|
$table->decimal('custom_surcharge1', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge2', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge3', 20,6)->change();
|
||||||
|
$table->decimal('custom_surcharge4', 20,6)->change();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user