List view for payment methods

This commit is contained in:
David Bomba 2019-09-18 12:39:53 +10:00
parent 905aaf7c98
commit a331368383
10 changed files with 194 additions and 21 deletions

View 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;
}

View File

@ -84,10 +84,10 @@ class PaymentController extends Controller
* and invoice ids for reference.
*
* @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
*/
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')))
@ -114,7 +114,7 @@ class PaymentController extends Controller
'fee' => $gateway->calcGatewayFee($amount),
'amount_with_fee' => ($amount + $gateway->calcGatewayFee($amount)),
'gateway' => $gateway,
'payment_method_id' => $payment_method_id,
'gateway_type_id' => $gateway_type_id,
'token' => auth()->user()->client->gateway_token($gateway->id),
];

View File

@ -12,8 +12,10 @@
namespace App\Http\Controllers\ClientPortal;
use App\Http\Controllers\Controller;
use App\Models\ClientGatewayToken;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Yajra\DataTables\Facades\DataTables;
class PaymentMethodController extends Controller
{
@ -25,7 +27,32 @@ class PaymentMethodController extends Controller
*/
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);
}
/**

View File

@ -14,11 +14,16 @@ namespace App\Models;
use App\Models\Client;
use App\Models\Company;
use App\Models\CompanyGateway;
use App\Models\GatewayType;
use App\Models\User;
class ClientGatewayToken extends BaseModel
{
protected $casts = [
'meta' => 'object',
];
public function client()
{
return $this->hasOne(Client::class);
@ -29,6 +34,11 @@ class ClientGatewayToken extends BaseModel
return $this->hasOne(CompanyGateway::class);
}
public function gateway_type()
{
return $this->hasOne(GatewayType::class);
}
public function company()
{
return $this->hasOne(Company::class);

View File

@ -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:
return 'portal.default.gateways.stripe.credit_card';
break;
@ -142,25 +142,36 @@ class StripePaymentDriver extends BasePaymentDriver
$server_response = json_decode($request->input('gateway_response'));
$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');
$payment_method = $server_response->payment_method;
$this->init();
$customer = $this->findOrCreateCustomer();
$this->init();
$stripe_payment_method = \Stripe\PaymentMethod::retrieve($payment_method);
$stripe_payment_method_obj = $stripe_payment_method->jsonSerialize();
$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->company_id = $this->client->company->id;
$cgt->client_id = $this->client->id;
$cgt->token = $payment_method;
$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->meta = $payment_meta;
$cgt->save();

View File

@ -349,7 +349,7 @@ class CreateUsersTable extends Migration
$table->unsignedInteger('company_id')->unique();
$table->unsignedInteger('user_id');
$table->unsignedInteger('gateway_id');
$table->unsignedInteger('gateway_type_id')->nullable();
$table->text('gateway_types')->default('');
$table->unsignedInteger('accepted_credit_cards');
$table->boolean('require_cvv')->default(true);
$table->boolean('show_address')->default(true)->nullable();
@ -401,7 +401,7 @@ class CreateUsersTable extends Migration
$t->text('line_items')->default('');
$t->text('settings')->default('');
$t->text('backup')->default('');
$t->text('backup')->nullable();
$t->text('footer')->default('');
$t->text('public_notes')->default('');
@ -457,7 +457,7 @@ class CreateUsersTable extends Migration
$t->text('line_items')->default('');
$t->text('settings')->default('');
$t->text('backup')->default('');
$t->text('backup')->nullable();
$t->text('footer')->default('');
$t->text('public_notes')->default('');
@ -517,7 +517,7 @@ class CreateUsersTable extends Migration
$t->text('line_items')->default('');
$t->text('settings')->default('');
$t->text('backup')->default('');
$t->text('backup')->nullable();
$t->text('footer')->default('');
$t->text('public_notes')->default('');
@ -574,7 +574,7 @@ class CreateUsersTable extends Migration
$t->text('line_items')->default('');
$t->text('settings')->default('');
$t->text('backup')->default('');
$t->text('backup')->nullable();
$t->text('footer')->default('');
$t->text('public_notes')->default('');
@ -705,7 +705,7 @@ class CreateUsersTable extends Migration
$t->decimal('amount', 13, 2)->default(0);
$t->datetime('payment_date')->nullable();
$t->string('transaction_reference')->nullable();
$t->string('payer_id')->default('');
$t->string('payer_id')->nullable();
$t->timestamps(6);
$t->softDeletes();
$t->boolean('is_deleted')->default(false);
@ -867,7 +867,7 @@ class CreateUsersTable extends Migration
Schema::create('backups', function ($table) {
$table->increments('id');
$table->unsignedInteger('activity_id');
$table->text('json_backup')->default('');
$table->text('json_backup')->nullable();
$table->timestamps(6);
$table->foreign('activity_id')->references('id')->on('activities')->onDelete('cascade');
@ -908,8 +908,9 @@ class CreateUsersTable extends Migration
$table->text('token')->default('');
$table->unsignedInteger('company_gateway_id');
$table->string('gateway_customer_reference')->default('');
$table->unsignedInteger('payment_method_id');
$table->unsignedInteger('gateway_type_id');
$table->boolean('is_default')->default(0);
$table->text('meta')->default('');
$table->softDeletes();
$table->timestamps(6);

View File

@ -49,7 +49,7 @@
</ul>
</div>
@include($gateway->driver(auth()->user()->client)->viewForType($payment_method_id))
@include($gateway->driver(auth()->user()->client)->viewForType($gateway_type_id))
</div>
</div>

View File

@ -10,7 +10,7 @@
->method('POST'); !!}
{!! 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('is_default')->id('is_default') !!}

View File

@ -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

View File

@ -48,7 +48,7 @@ class RecurringInvoicesCronTest extends TestCase
$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')));
});