mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 17:04:45 -04:00
Working on gateway fees
This commit is contained in:
parent
ce3afdaf8d
commit
7d0ec404da
@ -9,7 +9,6 @@ use App\Http\Requests\SaveEmailSettings;
|
||||
use App\Http\Requests\UpdateAccountRequest;
|
||||
use App\Models\Account;
|
||||
use App\Models\AccountGateway;
|
||||
use App\Models\AccountGatewaySettings;
|
||||
use App\Models\Affiliate;
|
||||
use App\Models\Document;
|
||||
use App\Models\Gateway;
|
||||
@ -500,8 +499,8 @@ class AccountController extends BaseController
|
||||
'showAdd' => $count < count(Gateway::$alternate) + 1,
|
||||
'title' => trans('texts.online_payments'),
|
||||
'tokenBillingOptions' => $tokenBillingOptions,
|
||||
'currency' => Utils::getFromCache(Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY),
|
||||
'currencies'),
|
||||
'currency' => Utils::getFromCache(Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY), 'currencies'),
|
||||
'taxRates' => TaxRate::scope()->whereIsInclusive(false)->get(['id', 'name', 'rate']),
|
||||
'account' => $account,
|
||||
]);
|
||||
}
|
||||
@ -1198,35 +1197,6 @@ class AccountController extends BaseController
|
||||
return Redirect::to('settings/'.ACCOUNT_PAYMENTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function savePaymentGatewayLimits()
|
||||
{
|
||||
$gateway_type_id = intval(Input::get('gateway_type_id'));
|
||||
$gateway_settings = AccountGatewaySettings::scope()->where('gateway_type_id', '=', $gateway_type_id)->first();
|
||||
|
||||
if (! $gateway_settings) {
|
||||
$gateway_settings = AccountGatewaySettings::createNew();
|
||||
$gateway_settings->gateway_type_id = $gateway_type_id;
|
||||
}
|
||||
|
||||
$gateway_settings->min_limit = Input::get('limit_min_enable') ? intval(Input::get('limit_min')) : null;
|
||||
$gateway_settings->max_limit = Input::get('limit_max_enable') ? intval(Input::get('limit_max')) : null;
|
||||
|
||||
if ($gateway_settings->max_limit !== null && $gateway_settings->min_limit > $gateway_settings->max_limit) {
|
||||
$gateway_settings->max_limit = $gateway_settings->min_limit;
|
||||
}
|
||||
|
||||
$gateway_settings->save();
|
||||
|
||||
event(new UserSettingsChanged());
|
||||
|
||||
Session::flash('message', trans('texts.updated_settings'));
|
||||
|
||||
return Redirect::to('settings/' . ACCOUNT_PAYMENTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Account;
|
||||
use App\Models\AccountGatewaySettings;
|
||||
use App\Models\AccountGateway;
|
||||
use App\Models\Gateway;
|
||||
use App\Services\AccountGatewayService;
|
||||
@ -501,4 +502,33 @@ class AccountGatewayController extends BaseController
|
||||
|
||||
return Redirect::to("gateways/{$accountGateway->public_id}/edit");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function savePaymentGatewayLimits()
|
||||
{
|
||||
$gateway_type_id = intval(Input::get('gateway_type_id'));
|
||||
$gateway_settings = AccountGatewaySettings::scope()->where('gateway_type_id', '=', $gateway_type_id)->first();
|
||||
|
||||
if (! $gateway_settings) {
|
||||
$gateway_settings = AccountGatewaySettings::createNew();
|
||||
$gateway_settings->gateway_type_id = $gateway_type_id;
|
||||
}
|
||||
|
||||
$gateway_settings->min_limit = Input::get('limit_min_enable') ? intval(Input::get('limit_min')) : null;
|
||||
$gateway_settings->max_limit = Input::get('limit_max_enable') ? intval(Input::get('limit_max')) : null;
|
||||
|
||||
if ($gateway_settings->max_limit !== null && $gateway_settings->min_limit > $gateway_settings->max_limit) {
|
||||
$gateway_settings->max_limit = $gateway_settings->min_limit;
|
||||
}
|
||||
|
||||
$gateway_settings->fill(Input::all());
|
||||
$gateway_settings->save();
|
||||
|
||||
Session::flash('message', trans('texts.updated_settings'));
|
||||
|
||||
return Redirect::to('settings/' . ACCOUNT_PAYMENTS);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ Route::group(['middleware' => 'auth:user'], function () {
|
||||
|
||||
Route::get('settings/user_details', 'AccountController@showUserDetails');
|
||||
Route::post('settings/user_details', 'AccountController@saveUserDetails');
|
||||
Route::post('settings/payment_gateway_limits', 'AccountController@savePaymentGatewayLimits');
|
||||
Route::post('settings/payment_gateway_limits', 'AccountGatewayController@savePaymentGatewayLimits');
|
||||
Route::post('users/change_password', 'UserController@changePassword');
|
||||
|
||||
Route::resource('clients', 'ClientController');
|
||||
|
@ -12,6 +12,18 @@ class AccountGatewaySettings extends EntityModel
|
||||
*/
|
||||
protected $dates = ['updated_at'];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'fee_amount',
|
||||
'fee_percent',
|
||||
'fee_tax_name1',
|
||||
'fee_tax_rate1',
|
||||
'fee_tax_name2',
|
||||
'fee_tax_rate2',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
|
@ -103,6 +103,12 @@ class AccountGatewayDatatable extends EntityDatatable
|
||||
return $html;
|
||||
},
|
||||
],
|
||||
[
|
||||
'fees',
|
||||
function ($model) {
|
||||
return 'Fees description...';
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -160,7 +166,7 @@ class AccountGatewayDatatable extends EntityDatatable
|
||||
|
||||
foreach (Cache::get('gatewayTypes') as $gatewayType) {
|
||||
$actions[] = [
|
||||
trans('texts.set_limits', ['gateway_type' => $gatewayType->name]),
|
||||
trans('texts.set_limits_fees', ['gateway_type' => $gatewayType->name]),
|
||||
function () use ($gatewayType) {
|
||||
$accountGatewaySettings = AccountGatewaySettings::scope()
|
||||
->where('account_gateway_settings.gateway_type_id', '=', $gatewayType->id)
|
||||
@ -176,10 +182,7 @@ class AccountGatewayDatatable extends EntityDatatable
|
||||
return $gatewayType->id == GATEWAY_TYPE_CUSTOM;
|
||||
} else {
|
||||
$accountGateway = $this->getAccountGateway($model->id);
|
||||
$paymentDriver = $accountGateway->paymentDriver();
|
||||
$gatewayTypes = $paymentDriver->gatewayTypes();
|
||||
|
||||
return in_array($gatewayType->id, $gatewayTypes);
|
||||
return $accountGateway->paymentDriver()->supportsGatewayType($gatewayType->id);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
@ -888,6 +888,11 @@ class BasePaymentDriver
|
||||
return $links;
|
||||
}
|
||||
|
||||
public function supportsGatewayType($gatewayTypeId)
|
||||
{
|
||||
return in_array($gatewayTypeId, $this->gatewayTypes());
|
||||
}
|
||||
|
||||
protected function meetsGatewayTypeLimits($gatewayTypeId)
|
||||
{
|
||||
if (! $gatewayTypeId) {
|
||||
|
@ -18,6 +18,11 @@ class AccountGatewayRepository extends BaseRepository
|
||||
->where('account_gateways.account_id', '=', $accountId)
|
||||
->whereNull('account_gateways.deleted_at');
|
||||
|
||||
return $query->select('account_gateways.id', 'account_gateways.public_id', 'gateways.name', 'account_gateways.deleted_at', 'account_gateways.gateway_id');
|
||||
return $query->select(
|
||||
'account_gateways.id',
|
||||
'account_gateways.public_id',
|
||||
'gateways.name',
|
||||
'account_gateways.deleted_at',
|
||||
'account_gateways.gateway_id');
|
||||
}
|
||||
}
|
||||
|
@ -2398,6 +2398,14 @@ $LANG = array(
|
||||
'pro_plan_reports' => ':link to enable reports by joining the Pro Plan',
|
||||
'mark_ready' => 'Mark Ready',
|
||||
|
||||
'limits' => 'Limits',
|
||||
'fees' => 'Fees',
|
||||
'set_limits_fees' => 'Set :gateway_type Limits/Fees',
|
||||
'fee_amount' => 'Amount',
|
||||
'fee_percent' => 'Percent',
|
||||
'fees_tax_help' => 'Enable line item taxes to set fee tax rates.',
|
||||
'fees_sample' => 'For a :amount invoice the fees would be :total.',
|
||||
|
||||
);
|
||||
|
||||
return $LANG;
|
||||
|
@ -3,6 +3,7 @@
|
||||
@section('content')
|
||||
@parent
|
||||
@include('accounts.nav', ['selected' => ACCOUNT_PAYMENTS])
|
||||
@include('money_script')
|
||||
|
||||
{!! Former::open()->addClass('warn-on-exit') !!}
|
||||
{!! Former::populateField('token_billing_type_id', $account->token_billing_type_id) !!}
|
||||
@ -43,14 +44,15 @@
|
||||
{!! Datatable::table()
|
||||
->addColumn(
|
||||
trans('texts.name'),
|
||||
trans('texts.limit'),
|
||||
trans('texts.limits'),
|
||||
trans('texts.fees'),
|
||||
trans('texts.action'))
|
||||
->setUrl(url('api/gateways/'))
|
||||
->setOptions('sPaginationType', 'bootstrap')
|
||||
->setOptions('bFilter', false)
|
||||
->setOptions('bAutoWidth', false)
|
||||
->setOptions('aoColumns', [[ "sWidth"=> "50%" ], ["sWidth"=> "30%"], ["sWidth"=> "20%"]])
|
||||
->setOptions('aoColumnDefs', [['bSortable'=>false, 'aTargets'=>[1]]])
|
||||
->setOptions('aoColumns', [[ "sWidth"=> "30%" ], ["sWidth"=> "30%"], ["sWidth"=> "20%"], ["sWidth"=> "20%"]])
|
||||
->setOptions('aoColumnDefs', [['bSortable'=>false, 'aTargets'=>[1, 2, 3]]])
|
||||
->render('datatable') !!}
|
||||
|
||||
{!! Former::open( 'settings/payment_gateway_limits') !!}
|
||||
@ -64,42 +66,107 @@
|
||||
<h4 class="modal-title" id="paymentLimitsModalLabel"></h4>
|
||||
</div>
|
||||
|
||||
<div class="container" style="width: 100%; padding-bottom: 0px !important">
|
||||
<div class="container" style="width: 100%; padding-bottom: 2px !important">
|
||||
<div class="panel panel-default" style="margin-bottom: 0px">
|
||||
<div class="panel-body">
|
||||
<div class="row" style="text-align:center">
|
||||
<div class="col-xs-12">
|
||||
<div id="payment-limits-slider"></div>
|
||||
</div>
|
||||
</div><br/>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div id="payment-limit-min-container">
|
||||
<label for="payment-limit-min">{{ trans('texts.min') }}</label><br>
|
||||
<div class="input-group" style="padding-bottom:8px">
|
||||
<span class="input-group-addon">{{ $currency->symbol }}</span>
|
||||
<input type="number" class="form-control" min="0" id="payment-limit-min"
|
||||
name="limit_min">
|
||||
</div>
|
||||
<label><input type="checkbox" id="payment-limit-min-enable"
|
||||
name="limit_min_enable"> {{ trans('texts.enable_min') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div id="payment-limit-max-container">
|
||||
<label for="payment-limit-max">{{ trans('texts.max') }}</label><br>
|
||||
<div role="tabpanel">
|
||||
<ul class="nav nav-tabs" role="tablist" style="border: none">
|
||||
<li role="presentation" class="active">
|
||||
<a href="#limits" aria-controls="limits" role="tab" data-toggle="tab">{{ trans('texts.limits') }}</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#fees" aria-controls="fees" role="tab" data-toggle="tab">{{ trans('texts.fees') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="limits">
|
||||
<div class="panel-body"><br/>
|
||||
<div class="row" style="text-align:center">
|
||||
<div class="col-xs-12">
|
||||
<div id="payment-limits-slider"></div>
|
||||
</div>
|
||||
</div><br/>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div id="payment-limit-min-container">
|
||||
<label for="payment-limit-min">{{ trans('texts.min') }}</label><br>
|
||||
<div class="input-group" style="padding-bottom:8px">
|
||||
<span class="input-group-addon">{{ $currency->symbol }}</span>
|
||||
<input type="number" class="form-control" min="0" id="payment-limit-min"
|
||||
name="limit_min">
|
||||
</div>
|
||||
<label><input type="checkbox" id="payment-limit-min-enable"
|
||||
name="limit_min_enable"> {{ trans('texts.enable_min') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div id="payment-limit-max-container">
|
||||
<label for="payment-limit-max">{{ trans('texts.max') }}</label><br>
|
||||
|
||||
<div class="input-group" style="padding-bottom:8px">
|
||||
<span class="input-group-addon">{{ $currency->symbol }}</span>
|
||||
<input type="number" class="form-control" min="0" id="payment-limit-max"
|
||||
name="limit_max">
|
||||
</div>
|
||||
<label><input type="checkbox" id="payment-limit-max-enable"
|
||||
name="limit_max_enable"> {{ trans('texts.enable_max') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="gateway_type_id" id="payment-limit-gateway-type">
|
||||
<div class="input-group" style="padding-bottom:8px">
|
||||
<span class="input-group-addon">{{ $currency->symbol }}</span>
|
||||
<input type="number" class="form-control" min="0" id="payment-limit-max"
|
||||
name="limit_max">
|
||||
</div>
|
||||
<label><input type="checkbox" id="payment-limit-max-enable"
|
||||
name="limit_max_enable"> {{ trans('texts.enable_max') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane active" id="fees">
|
||||
<div class="panel-body">
|
||||
|
||||
{!! Former::text('fee_amount')
|
||||
->onchange('updateFeeSample()')
|
||||
->type('number')
|
||||
->min('0')
|
||||
->step('any') !!}
|
||||
|
||||
{!! Former::text('fee_percent')
|
||||
->onchange('updateFeeSample()')
|
||||
->type('number')
|
||||
->min('0')
|
||||
->step('any')
|
||||
->append('%') !!}
|
||||
|
||||
@if ($account->invoice_item_taxes)
|
||||
{!! Former::select('tax_rate1')
|
||||
->onchange('onTaxRateChange(1)')
|
||||
->addOption('', '')
|
||||
->label(trans('texts.tax_rate'))
|
||||
->fromQuery($taxRates, function($model) { return $model->name . ' ' . $model->rate . '%'; }, 'id') !!}
|
||||
|
||||
{!! Former::text('fee_tax_name1') !!}
|
||||
{!! Former::text('fee_tax_rate1') !!}
|
||||
|
||||
@if ($account->enable_second_tax_rate)
|
||||
{!! Former::select('tax_rate2')
|
||||
->onchange('onTaxRateChange(2)')
|
||||
->addOption('', '')
|
||||
->label(trans('texts.tax_rate'))
|
||||
->fromQuery($taxRates, function($model) { return $model->name . ' ' . $model->rate . '%'; }, 'id') !!}
|
||||
@endif
|
||||
|
||||
{!! Former::text('fee_tax_name2') !!}
|
||||
{!! Former::text('fee_tax_rate2') !!}
|
||||
|
||||
@endif
|
||||
|
||||
<br/><div id="feeSample" class="help-block"></div>
|
||||
|
||||
@if (!$account->invoice_item_taxes && $account->invoice_taxes && count($taxRates))
|
||||
<br/><div class="help-block">{{ trans('texts.fees_tax_help') }}</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="gateway_type_id" id="payment-limit-gateway-type">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -117,8 +184,10 @@
|
||||
<script>
|
||||
window.onDatatableReady = actionListHandler;
|
||||
|
||||
var taxRates = {!! $taxRates !!};
|
||||
|
||||
function showLimitsModal(gateway_type, gateway_type_id, min_limit, max_limit) {
|
||||
var modalLabel = {!! json_encode(trans('texts.set_limits')) !!};
|
||||
var modalLabel = {!! json_encode(trans('texts.set_limits_fees')) !!};
|
||||
$('#paymentLimitsModalLabel').text(modalLabel.replace(':gateway_type', gateway_type));
|
||||
|
||||
limitsSlider.noUiSlider.set([min_limit !== null ? min_limit : 0, max_limit !== null ? max_limit : 100000]);
|
||||
@ -197,6 +266,49 @@
|
||||
}
|
||||
});
|
||||
|
||||
function updateFeeSample() {
|
||||
var feeAmount = NINJA.parseFloat($('#fee_amount').val()) || 0;
|
||||
var feePercent = NINJA.parseFloat($('#fee_percent').val()) || 0;
|
||||
var total = feeAmount + feePercent
|
||||
var subtotal = total;
|
||||
|
||||
var taxRate1 = $('#tax_rate1').val();
|
||||
if (taxRate1) {
|
||||
taxRate1 = NINJA.parseFloat(taxRates[taxRate1-1].rate);
|
||||
total += subtotal * taxRate1 / 100;
|
||||
}
|
||||
|
||||
var taxRate2 = NINJA.parseFloat($('#tax_rate2').val());
|
||||
if (taxRate2) {
|
||||
taxRate2 = NINJA.parseFloat(taxRates[taxRate2-1].rate);
|
||||
total += subtotal * taxRate2 / 100;
|
||||
}
|
||||
|
||||
var str = "{{ trans('texts.fees_sample') }}";
|
||||
str = str.replace(':amount', formatMoney(100));
|
||||
str = str.replace(':total', formatMoney(total));
|
||||
$('#feeSample').text(str);
|
||||
}
|
||||
|
||||
function onTaxRateChange(instance) {
|
||||
var taxRate = $('#tax_rate' + instance).val();
|
||||
if (taxRate) {
|
||||
taxRate = taxRates[taxRate-1];
|
||||
}
|
||||
|
||||
$('#fee_tax_name' + instance).val(taxRate ? taxRate.name : '');
|
||||
$('#fee_tax_rate' + instance).val(taxRate ? taxRate.rate : '');
|
||||
|
||||
updateFeeSample();
|
||||
}
|
||||
|
||||
@if (Utils::isNinja())
|
||||
updateFeeSample();
|
||||
$(function() {
|
||||
javascript:showLimitsModal('Credit Card', 1, null, null);
|
||||
});
|
||||
@endif
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user