mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-03 05:14:37 -04:00
List view for payment methods
This commit is contained in:
parent
905aaf7c98
commit
a331368383
25
app/DataMapper/PaymentMethodMeta.php
Normal file
25
app/DataMapper/PaymentMethodMeta.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\DataMapper;
|
||||||
|
|
||||||
|
class PaymentMethodMeta
|
||||||
|
{
|
||||||
|
$exp_month;
|
||||||
|
|
||||||
|
$exp_year;
|
||||||
|
|
||||||
|
$brand;
|
||||||
|
|
||||||
|
$last4;
|
||||||
|
|
||||||
|
$type;
|
||||||
|
}
|
@ -84,10 +84,10 @@ class PaymentController extends Controller
|
|||||||
* and invoice ids for reference.
|
* and invoice ids for reference.
|
||||||
*
|
*
|
||||||
* @param int $company_gateway_id The CompanyGateway ID
|
* @param int $company_gateway_id The CompanyGateway ID
|
||||||
* @param int $payment_method_id The PaymentMethod ID
|
* @param int $gateway_type_id The gateway_type_id ID
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function process($company_gateway_id, $payment_method_id)
|
public function process($company_gateway_id, $gateway_type_id)
|
||||||
{
|
{
|
||||||
|
|
||||||
$invoices = Invoice::whereIn('id', $this->transformKeys(request()->input('invoice_ids')))
|
$invoices = Invoice::whereIn('id', $this->transformKeys(request()->input('invoice_ids')))
|
||||||
@ -114,7 +114,7 @@ class PaymentController extends Controller
|
|||||||
'fee' => $gateway->calcGatewayFee($amount),
|
'fee' => $gateway->calcGatewayFee($amount),
|
||||||
'amount_with_fee' => ($amount + $gateway->calcGatewayFee($amount)),
|
'amount_with_fee' => ($amount + $gateway->calcGatewayFee($amount)),
|
||||||
'gateway' => $gateway,
|
'gateway' => $gateway,
|
||||||
'payment_method_id' => $payment_method_id,
|
'gateway_type_id' => $gateway_type_id,
|
||||||
'token' => auth()->user()->client->gateway_token($gateway->id),
|
'token' => auth()->user()->client->gateway_token($gateway->id),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -12,8 +12,10 @@
|
|||||||
namespace App\Http\Controllers\ClientPortal;
|
namespace App\Http\Controllers\ClientPortal;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\ClientGatewayToken;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Yajra\DataTables\Facades\DataTables;
|
||||||
|
|
||||||
class PaymentMethodController extends Controller
|
class PaymentMethodController extends Controller
|
||||||
{
|
{
|
||||||
@ -25,7 +27,32 @@ class PaymentMethodController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
echo 'list of payment methods here';
|
$payment_methods = ClientGatewayToken::whereClientId(auth()->user()->client->id);
|
||||||
|
|
||||||
|
if (request()->ajax()) {
|
||||||
|
|
||||||
|
return DataTables::of($payment_methods)->addColumn('action', function ($invoice) {
|
||||||
|
return '<a href="/client/payment_methods/'. $payment_methods->hashed_id .'" class="btn btn-xs btn-primary"><i class="glyphicon glyphicon-edit"></i>'.ctrans('texts.view').'</a>';
|
||||||
|
})
|
||||||
|
->editColumn('status_id', function ($invoice){
|
||||||
|
return Invoice::badgeForStatus($invoice->status);
|
||||||
|
})->editColumn('invoice_date', function ($invoice){
|
||||||
|
return $this->formatDate($invoice->invoice_date, $invoice->client->date_format());
|
||||||
|
})->editColumn('due_date', function ($invoice){
|
||||||
|
return $this->formatDate($invoice->due_date, $invoice->client->date_format());
|
||||||
|
})->editColumn('balance', function ($invoice) {
|
||||||
|
return Number::formatMoney($invoice->balance, $invoice->client);
|
||||||
|
})->editColumn('amount', function ($invoice) {
|
||||||
|
return Number::formatMoney($invoice->amount, $invoice->client);
|
||||||
|
})
|
||||||
|
->rawColumns(['action', 'status_id'])
|
||||||
|
->make(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['html'] = $builder;
|
||||||
|
|
||||||
|
return view('portal.default.payment_methods.index', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,11 +14,16 @@ namespace App\Models;
|
|||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\CompanyGateway;
|
use App\Models\CompanyGateway;
|
||||||
|
use App\Models\GatewayType;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
||||||
class ClientGatewayToken extends BaseModel
|
class ClientGatewayToken extends BaseModel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'meta' => 'object',
|
||||||
|
];
|
||||||
|
|
||||||
public function client()
|
public function client()
|
||||||
{
|
{
|
||||||
return $this->hasOne(Client::class);
|
return $this->hasOne(Client::class);
|
||||||
@ -29,6 +34,11 @@ class ClientGatewayToken extends BaseModel
|
|||||||
return $this->hasOne(CompanyGateway::class);
|
return $this->hasOne(CompanyGateway::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function gateway_type()
|
||||||
|
{
|
||||||
|
return $this->hasOne(GatewayType::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function company()
|
public function company()
|
||||||
{
|
{
|
||||||
return $this->hasOne(Company::class);
|
return $this->hasOne(Company::class);
|
||||||
|
@ -94,9 +94,9 @@ class StripePaymentDriver extends BasePaymentDriver
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function viewForType($payment_type)
|
public function viewForType($gateway_type_id)
|
||||||
{
|
{
|
||||||
switch ($payment_type) {
|
switch ($gateway_type_id) {
|
||||||
case GatewayType::CREDIT_CARD:
|
case GatewayType::CREDIT_CARD:
|
||||||
return 'portal.default.gateways.stripe.credit_card';
|
return 'portal.default.gateways.stripe.credit_card';
|
||||||
break;
|
break;
|
||||||
@ -142,25 +142,36 @@ class StripePaymentDriver extends BasePaymentDriver
|
|||||||
$server_response = json_decode($request->input('gateway_response'));
|
$server_response = json_decode($request->input('gateway_response'));
|
||||||
|
|
||||||
$gateway_id = $request->input('gateway_id');
|
$gateway_id = $request->input('gateway_id');
|
||||||
$gateway_type_id = $request->input('payment_method_id');
|
$gateway_type_id = $request->input('gateway_type_id');
|
||||||
$is_default = $request->input('is_default');
|
$is_default = $request->input('is_default');
|
||||||
|
|
||||||
$payment_method = $server_response->payment_method;
|
$payment_method = $server_response->payment_method;
|
||||||
|
|
||||||
$this->init();
|
|
||||||
|
|
||||||
$customer = $this->findOrCreateCustomer();
|
$customer = $this->findOrCreateCustomer();
|
||||||
|
|
||||||
|
$this->init();
|
||||||
$stripe_payment_method = \Stripe\PaymentMethod::retrieve($payment_method);
|
$stripe_payment_method = \Stripe\PaymentMethod::retrieve($payment_method);
|
||||||
|
$stripe_payment_method_obj = $stripe_payment_method->jsonSerialize();
|
||||||
$stripe_payment_method->attach(['customer' => $customer->id]);
|
$stripe_payment_method->attach(['customer' => $customer->id]);
|
||||||
|
|
||||||
|
$payment_meta = new \stdClass;
|
||||||
|
|
||||||
|
if($stripe_payment_method_obj['type'] == 'card') {
|
||||||
|
$payment_meta->exp_month = $stripe_payment_method_obj['card']['exp_month'];
|
||||||
|
$payment_meta->exp_year = $stripe_payment_method_obj['card']['exp_year'];
|
||||||
|
$payment_meta->brand = $stripe_payment_method_obj['card']['brand'];
|
||||||
|
$payment_meta->last4 = $stripe_payment_method_obj['card']['last4'];
|
||||||
|
$payment_meta->type = $stripe_payment_method_obj['type'];
|
||||||
|
}
|
||||||
|
|
||||||
$cgt = new ClientGatewayToken;
|
$cgt = new ClientGatewayToken;
|
||||||
$cgt->company_id = $this->client->company->id;
|
$cgt->company_id = $this->client->company->id;
|
||||||
$cgt->client_id = $this->client->id;
|
$cgt->client_id = $this->client->id;
|
||||||
$cgt->token = $payment_method;
|
$cgt->token = $payment_method;
|
||||||
$cgt->company_gateway_id = $this->company_gateway->id;
|
$cgt->company_gateway_id = $this->company_gateway->id;
|
||||||
$cgt->payment_method_id = $gateway_type_id;
|
$cgt->gateway_type_id = $gateway_type_id;
|
||||||
$cgt->gateway_customer_reference = $customer->id;
|
$cgt->gateway_customer_reference = $customer->id;
|
||||||
|
$cgt->meta = $payment_meta;
|
||||||
$cgt->save();
|
$cgt->save();
|
||||||
|
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ class CreateUsersTable extends Migration
|
|||||||
$table->unsignedInteger('company_id')->unique();
|
$table->unsignedInteger('company_id')->unique();
|
||||||
$table->unsignedInteger('user_id');
|
$table->unsignedInteger('user_id');
|
||||||
$table->unsignedInteger('gateway_id');
|
$table->unsignedInteger('gateway_id');
|
||||||
$table->unsignedInteger('gateway_type_id')->nullable();
|
$table->text('gateway_types')->default('');
|
||||||
$table->unsignedInteger('accepted_credit_cards');
|
$table->unsignedInteger('accepted_credit_cards');
|
||||||
$table->boolean('require_cvv')->default(true);
|
$table->boolean('require_cvv')->default(true);
|
||||||
$table->boolean('show_address')->default(true)->nullable();
|
$table->boolean('show_address')->default(true)->nullable();
|
||||||
@ -401,7 +401,7 @@ class CreateUsersTable extends Migration
|
|||||||
|
|
||||||
$t->text('line_items')->default('');
|
$t->text('line_items')->default('');
|
||||||
$t->text('settings')->default('');
|
$t->text('settings')->default('');
|
||||||
$t->text('backup')->default('');
|
$t->text('backup')->nullable();
|
||||||
|
|
||||||
$t->text('footer')->default('');
|
$t->text('footer')->default('');
|
||||||
$t->text('public_notes')->default('');
|
$t->text('public_notes')->default('');
|
||||||
@ -457,7 +457,7 @@ class CreateUsersTable extends Migration
|
|||||||
|
|
||||||
$t->text('line_items')->default('');
|
$t->text('line_items')->default('');
|
||||||
$t->text('settings')->default('');
|
$t->text('settings')->default('');
|
||||||
$t->text('backup')->default('');
|
$t->text('backup')->nullable();
|
||||||
|
|
||||||
$t->text('footer')->default('');
|
$t->text('footer')->default('');
|
||||||
$t->text('public_notes')->default('');
|
$t->text('public_notes')->default('');
|
||||||
@ -517,7 +517,7 @@ class CreateUsersTable extends Migration
|
|||||||
|
|
||||||
$t->text('line_items')->default('');
|
$t->text('line_items')->default('');
|
||||||
$t->text('settings')->default('');
|
$t->text('settings')->default('');
|
||||||
$t->text('backup')->default('');
|
$t->text('backup')->nullable();
|
||||||
|
|
||||||
$t->text('footer')->default('');
|
$t->text('footer')->default('');
|
||||||
$t->text('public_notes')->default('');
|
$t->text('public_notes')->default('');
|
||||||
@ -574,7 +574,7 @@ class CreateUsersTable extends Migration
|
|||||||
|
|
||||||
$t->text('line_items')->default('');
|
$t->text('line_items')->default('');
|
||||||
$t->text('settings')->default('');
|
$t->text('settings')->default('');
|
||||||
$t->text('backup')->default('');
|
$t->text('backup')->nullable();
|
||||||
|
|
||||||
$t->text('footer')->default('');
|
$t->text('footer')->default('');
|
||||||
$t->text('public_notes')->default('');
|
$t->text('public_notes')->default('');
|
||||||
@ -705,7 +705,7 @@ class CreateUsersTable extends Migration
|
|||||||
$t->decimal('amount', 13, 2)->default(0);
|
$t->decimal('amount', 13, 2)->default(0);
|
||||||
$t->datetime('payment_date')->nullable();
|
$t->datetime('payment_date')->nullable();
|
||||||
$t->string('transaction_reference')->nullable();
|
$t->string('transaction_reference')->nullable();
|
||||||
$t->string('payer_id')->default('');
|
$t->string('payer_id')->nullable();
|
||||||
$t->timestamps(6);
|
$t->timestamps(6);
|
||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
$t->boolean('is_deleted')->default(false);
|
$t->boolean('is_deleted')->default(false);
|
||||||
@ -867,7 +867,7 @@ class CreateUsersTable extends Migration
|
|||||||
Schema::create('backups', function ($table) {
|
Schema::create('backups', function ($table) {
|
||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
$table->unsignedInteger('activity_id');
|
$table->unsignedInteger('activity_id');
|
||||||
$table->text('json_backup')->default('');
|
$table->text('json_backup')->nullable();
|
||||||
$table->timestamps(6);
|
$table->timestamps(6);
|
||||||
|
|
||||||
$table->foreign('activity_id')->references('id')->on('activities')->onDelete('cascade');
|
$table->foreign('activity_id')->references('id')->on('activities')->onDelete('cascade');
|
||||||
@ -908,8 +908,9 @@ class CreateUsersTable extends Migration
|
|||||||
$table->text('token')->default('');
|
$table->text('token')->default('');
|
||||||
$table->unsignedInteger('company_gateway_id');
|
$table->unsignedInteger('company_gateway_id');
|
||||||
$table->string('gateway_customer_reference')->default('');
|
$table->string('gateway_customer_reference')->default('');
|
||||||
$table->unsignedInteger('payment_method_id');
|
$table->unsignedInteger('gateway_type_id');
|
||||||
$table->boolean('is_default')->default(0);
|
$table->boolean('is_default')->default(0);
|
||||||
|
$table->text('meta')->default('');
|
||||||
$table->softDeletes();
|
$table->softDeletes();
|
||||||
|
|
||||||
$table->timestamps(6);
|
$table->timestamps(6);
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@include($gateway->driver(auth()->user()->client)->viewForType($payment_method_id))
|
@include($gateway->driver(auth()->user()->client)->viewForType($gateway_type_id))
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
->method('POST'); !!}
|
->method('POST'); !!}
|
||||||
|
|
||||||
{!! Former::hidden('company_gateway_id')->value($gateway->gateway_id) !!}
|
{!! Former::hidden('company_gateway_id')->value($gateway->gateway_id) !!}
|
||||||
{!! Former::hidden('payment_method_id')->value($gateway->gateway_type_id) !!}
|
{!! Former::hidden('gateway_type_id')->value($gateway->gateway_type_id) !!}
|
||||||
{!! Former::hidden('gateway_response')->id('gateway_response') !!}
|
{!! Former::hidden('gateway_response')->id('gateway_response') !!}
|
||||||
{!! Former::hidden('is_default')->id('is_default') !!}
|
{!! Former::hidden('is_default')->id('is_default') !!}
|
||||||
|
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
@extends('portal.default.layouts.master')
|
||||||
|
@section('header')
|
||||||
|
@parent
|
||||||
|
<link href="//cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="/vendors/css/select2.min.css" rel="stylesheet">
|
||||||
|
@stop
|
||||||
|
@section('body')
|
||||||
|
<main class="main">
|
||||||
|
<div class="container-fluid">
|
||||||
|
|
||||||
|
{!! Former::framework('TwitterBootstrap4'); !!}
|
||||||
|
|
||||||
|
{!! Former::horizontal_open()
|
||||||
|
->id('payment_form')
|
||||||
|
->route('client.invoices.bulk')
|
||||||
|
->method('POST'); !!}
|
||||||
|
|
||||||
|
{!! Former::hidden('hashed_ids')->id('hashed_ids') !!}
|
||||||
|
{!! Former::hidden('action')->id('action') !!}
|
||||||
|
|
||||||
|
{!! Former::close() !!}
|
||||||
|
|
||||||
|
<div class="row" style="padding-top: 30px;">
|
||||||
|
|
||||||
|
<div class="col-lg-12" style="padding-bottom: 10px;">
|
||||||
|
|
||||||
|
<!-- Filters / Buttons in here.-->
|
||||||
|
<div id="top_right_buttons" class="pull-right">
|
||||||
|
<a href="{{ route('client.payment_methods.create ')}}" class="btn btn-success">{{ ctrans('texts.add_payment_method') }}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="animated fadeIn">
|
||||||
|
<div class="col-md-12 card">
|
||||||
|
|
||||||
|
{!! $html->table(['class' => 'table table-hover table-striped', 'id' => 'datatable'], true) !!}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
@endsection
|
||||||
|
@push('scripts')
|
||||||
|
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js" type="text/javascript"></script>
|
||||||
|
<script src="//cdn.datatables.net/1.10.18/js/dataTables.bootstrap4.min.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
/*global json payload*/
|
||||||
|
var data;
|
||||||
|
|
||||||
|
var data_table;
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
|
||||||
|
data_table = $('#datatable').DataTable({
|
||||||
|
processing: true,
|
||||||
|
serverSide: true,
|
||||||
|
searching: false,
|
||||||
|
bLengthChange: false,
|
||||||
|
language: {
|
||||||
|
processing: " {{ trans('texts.processing_request') }}",
|
||||||
|
search: "{{ trans('texts.search') }}:",
|
||||||
|
// info: "{{ trans('texts.info') }}",
|
||||||
|
infoPostFix: "",
|
||||||
|
loadingRecords: "{{ trans('texts.loading') }}",
|
||||||
|
zeroRecords: "{{ trans('texts.no_records_found') }}"
|
||||||
|
},
|
||||||
|
ajax: {
|
||||||
|
url: '{!! route('client.payment_methods.index') !!}',
|
||||||
|
data: function(data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
drawCallback: function(settings){
|
||||||
|
|
||||||
|
data = this.api().ajax.json().data;
|
||||||
|
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
|
||||||
|
{data: 'invoice_number', name: 'invoice_number', title: '{{ctrans('texts.invoice_number')}}', visible: true},
|
||||||
|
{data: 'invoice_date', name: 'invoice_date', title: '{{ctrans('texts.invoice_date')}}', visible: true},
|
||||||
|
{data: 'amount', name: 'amount', title: '{{ctrans('texts.total')}}', visible: true},
|
||||||
|
{data: 'balance', name: 'balance', title: '{{ctrans('texts.balance')}}', visible: true},
|
||||||
|
{data: 'due_date', name: 'due_date', title: '{{ctrans('texts.due_date')}}', visible: true},
|
||||||
|
{data: 'status_id', name: 'status_id', title: '{{ctrans('texts.status')}}', visible: true},
|
||||||
|
{data: 'action', name: 'action', title: '', searchable: false, orderable: false},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@endpush
|
||||||
|
|
@ -48,7 +48,7 @@ class RecurringInvoicesCronTest extends TestCase
|
|||||||
|
|
||||||
$recurring_invoices->each(function ($inv, $key) {
|
$recurring_invoices->each(function ($inv, $key) {
|
||||||
|
|
||||||
Log::error(Carbon::parse($inv->next_send_date)->format(config('ninja.date_time_format')));
|
// Log::error(Carbon::parse($inv->next_send_date)->format(config('ninja.date_time_format')));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user