mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-05 18:52:44 +01:00
Refactor for payments via client portal
This commit is contained in:
parent
f58ba0b502
commit
96750d5fdb
@ -71,18 +71,25 @@ class PaymentController extends Controller
|
||||
{
|
||||
$gateway = CompanyGateway::findOrFail(request()->input('company_gateway_id'));
|
||||
|
||||
/*find invoices*/
|
||||
/**
|
||||
* find invoices
|
||||
*
|
||||
* ['invoice_id' => xxx, 'amount' => 22.00]
|
||||
*
|
||||
*/
|
||||
|
||||
$payable_invoices = request()->payable_invoices;
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($payable_invoices, 'invoice_id')))->get();
|
||||
$payable_invoices = collect(request()->payable_invoices);
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys($payable_invoices->pluck('invoice_id')->toArray()))->get();
|
||||
|
||||
/* pop non payable invoice from the $payable_invoices array */
|
||||
$payable_invoices = $payable_invoices->filter(function ($payable_invoice) use ($invoices){
|
||||
|
||||
return $invoices->where('hashed_id', $payable_invoice['invoice_id'])->first()->isPayable();
|
||||
|
||||
/*filter only payable invoices*/
|
||||
$invoices = $invoices->filter(function ($invoice) {
|
||||
return $invoice->isPayable();
|
||||
});
|
||||
|
||||
/*return early if no invoices*/
|
||||
if ($invoices->count() == 0) {
|
||||
if ($payable_invoices->count() == 0) {
|
||||
return redirect()
|
||||
->route('client.invoices.index')
|
||||
->with(['warning' => 'No payable invoices selected.']);
|
||||
@ -91,10 +98,10 @@ class PaymentController extends Controller
|
||||
$settings = auth()->user()->client->getMergedSettings();
|
||||
|
||||
/*iterate through invoices and add gateway fees and other payment metadata*/
|
||||
foreach ($payable_invoices as $key => $payable_invoice) {
|
||||
$payable_invoices = $payable_invoices->map(function($payable_invoice) use($invoices, $settings){
|
||||
|
||||
$payable_invoices[$key]['amount'] = Number::parseFloat($payable_invoice['amount']);
|
||||
$payable_invoice['amount'] = $payable_invoices[$key]['amount'];
|
||||
|
||||
$payable_invoice['amount'] = Number::parseFloat($payable_invoice['amount']);
|
||||
|
||||
$invoice = $invoices->first(function ($inv) use ($payable_invoice) {
|
||||
return $payable_invoice['invoice_id'] == $inv->hashed_id;
|
||||
@ -135,8 +142,8 @@ class PaymentController extends Controller
|
||||
}
|
||||
} // Make sure 'amount' from form is not higher than 'amount' from invoice.
|
||||
|
||||
$payable_invoices[$key]['due_date'] = $this->formatDate($invoice->due_date, $invoice->client->date_format());
|
||||
$payable_invoices[$key]['invoice_number'] = $invoice->number;
|
||||
$payable_invoice['due_date'] = $this->formatDate($invoice->due_date, $invoice->client->date_format());
|
||||
$payable_invoice['invoice_number'] = $invoice->number;
|
||||
|
||||
if (isset($invoice->po_number)) {
|
||||
$additional_info = $invoice->po_number;
|
||||
@ -146,8 +153,13 @@ class PaymentController extends Controller
|
||||
$additional_info = $invoice->date;
|
||||
}
|
||||
|
||||
$payable_invoices[$key]['additional_info'] = $additional_info;
|
||||
}
|
||||
$payable_invoice['additional_info'] = $additional_info;
|
||||
|
||||
return $payable_invoice;
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
if ((bool) request()->signature) {
|
||||
$invoices->each(function ($invoice) {
|
||||
@ -157,7 +169,7 @@ class PaymentController extends Controller
|
||||
|
||||
$payment_method_id = request()->input('payment_method_id');
|
||||
|
||||
$invoice_totals = array_sum(array_column($payable_invoices, 'amount'));
|
||||
$invoice_totals = $payable_invoices->sum('amount');
|
||||
|
||||
$first_invoice = $invoices->first();
|
||||
|
||||
@ -209,24 +221,14 @@ class PaymentController extends Controller
|
||||
/*Payment Gateway*/
|
||||
$gateway = CompanyGateway::find($request->input('company_gateway_id'))->firstOrFail();
|
||||
|
||||
//REFACTOR - Entry point for the gateway response - we don't need to do anything at this point.
|
||||
//
|
||||
// - Inside each gateway driver, we should use have a generic code path (in BaseDriver.php)for successful/failed payment
|
||||
//
|
||||
// Success workflow
|
||||
//
|
||||
// - Rehydrate the hash and iterate through the invoices and update the balances
|
||||
// - Update the type_id of the gateway fee to type_id 4
|
||||
// - Link invoices to payment
|
||||
//
|
||||
// Failure workflow
|
||||
//
|
||||
// - Rehydrate hash, iterate through invoices and remove type_id 3's
|
||||
// - Recalcuate invoice totals
|
||||
|
||||
return $gateway
|
||||
->driver(auth()->user()->client)
|
||||
->setPaymentMethod($request->input('payment_method_id'))
|
||||
->processPaymentResponse($request);
|
||||
}
|
||||
|
||||
public function credit_response(Request $request)
|
||||
{
|
||||
$payment_hash = PaymentHash::find($request->input('payment_hash'));
|
||||
}
|
||||
}
|
||||
|
@ -517,7 +517,7 @@ class Client extends BaseModel implements HasLocalePreference
|
||||
$fee_label = $gateway->calcGatewayFeeLabel($amount, $this);
|
||||
|
||||
$payment_urls[] = [
|
||||
'label' => ctrans('texts.'.$gateway->getTypeAlias($gateway_type_id)).$fee_label,
|
||||
'label' => $gateway->getTypeAlias($gateway_type_id) . $fee_label,
|
||||
'company_gateway_id' => $gateway_id,
|
||||
'gateway_type_id' => $gateway_type_id,
|
||||
];
|
||||
|
@ -79,7 +79,7 @@ class CompanyGateway extends BaseModel
|
||||
|
||||
public function getTypeAlias($gateway_type_id)
|
||||
{
|
||||
return GatewayType::find($gateway_type_id)->alias;
|
||||
return GatewayType::getAlias($gateway_type_id);
|
||||
}
|
||||
|
||||
/* This is the public entry point into the payment superclass */
|
||||
|
@ -37,4 +37,41 @@ class GatewayType extends StaticModel
|
||||
{
|
||||
return $this->hasMany(PaymentType::class);
|
||||
}
|
||||
|
||||
public static function getAlias($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case self::CREDIT_CARD:
|
||||
return ctrans('texts.credit_card');
|
||||
break;
|
||||
case self::BANK_TRANSFER:
|
||||
return ctrans('texts.bank_transfer');
|
||||
break;
|
||||
case self::PAYPAL:
|
||||
return ctrans('texts.paypal');
|
||||
break;
|
||||
case self::CRYPTO:
|
||||
return ctrans('texts.crypto');
|
||||
break;
|
||||
case self::CUSTOM:
|
||||
return ctrans('texts.custom');
|
||||
break;
|
||||
case self::ALIPAY:
|
||||
return ctrans('texts.alipay');
|
||||
break;
|
||||
case self::SOFORT:
|
||||
return ctrans('texts.sofort');
|
||||
break;
|
||||
case self::APPLE_PAY:
|
||||
return ctrans('texts.apple_pay');
|
||||
break;
|
||||
case self::SEPA:
|
||||
return ctrans('texts.sepa');
|
||||
break;
|
||||
|
||||
default:
|
||||
return 'Undefined.';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,10 +104,8 @@ class AutoBillInvoice extends AbstractService
|
||||
*/
|
||||
private function finalizePaymentUsingCredits()
|
||||
{
|
||||
info("finalizing");
|
||||
info(print_r($this->used_credit,1));
|
||||
|
||||
$amount = array_sum(array_column($this->used_credit, 'amount'));
|
||||
info("amount {$amount}");
|
||||
|
||||
$payment = PaymentFactory::create($this->invoice->company_id, $this->invoice->user_id);
|
||||
$payment->amount = $amount;
|
||||
|
@ -77,7 +77,8 @@ class ExpenseTransformer extends EntityTransformer
|
||||
'public_notes' => (string) $expense->public_notes ?: '',
|
||||
'transaction_reference' => (string) $expense->transaction_reference ?: '',
|
||||
'transaction_id' => (string) $expense->transaction_id ?: '',
|
||||
'date' => $expense->date ?: '',
|
||||
//'date' => $expense->date ?: '',
|
||||
'expense_date' => $expense->date ?: '',
|
||||
'payment_date' => $expense->payment_date ?: '',
|
||||
'custom_value1' => $expense->custom_value1 ?: '',
|
||||
'custom_value2' => $expense->custom_value2 ?: '',
|
||||
|
@ -16,6 +16,10 @@
|
||||
<input type="hidden" name="company_gateway_id" value="{{ $gateway->getCompanyGatewayId() }}">
|
||||
<input type="hidden" name="payment_method_id" value="{{ $payment_method_id }}">
|
||||
</form>
|
||||
<form action="{{route('client.payments.credit_response')}}" method="post" id="credit-payment">
|
||||
@csrf
|
||||
<input type="hidden" name="payment_hash" value="{{$payment_hash}}">
|
||||
</form>
|
||||
<div class="container mx-auto">
|
||||
<div class="grid grid-cols-6 gap-4">
|
||||
<div class="col-span-6 md:col-start-2 md:col-span-4">
|
||||
@ -64,7 +68,9 @@
|
||||
</div>
|
||||
@if((int)$total['amount_with_fee'] == 0)
|
||||
<!-- finalize with credits only -->
|
||||
<button class="button button-primary bg-primary inline-flex items-center">Pay with credit</button>
|
||||
<div class="bg-white px-4 py-5 flex justify-end">
|
||||
<button form="credit-payment" class="button button-primary bg-primary inline-flex items-center">Pay with credit</button>
|
||||
</div>
|
||||
@elseif($token)
|
||||
<div class="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6 flex items-center">
|
||||
<dt class="text-sm leading-5 font-medium text-gray-500 mr-4">
|
||||
|
@ -35,6 +35,8 @@ Route::group(['middleware' => ['auth:contact', 'locale'], 'prefix' => 'client',
|
||||
Route::get('recurring_invoices/{recurring_invoice}/request_cancellation', 'ClientPortal\RecurringInvoiceController@requestCancellation')->name('recurring_invoices.request_cancellation');
|
||||
|
||||
Route::post('payments/process', 'ClientPortal\PaymentController@process')->name('payments.process');
|
||||
Route::post('payments/credit_response', 'ClientPortal\PaymentController@credit_response')->name('payments.credit_response');
|
||||
|
||||
Route::get('payments', 'ClientPortal\PaymentController@index')->name('payments.index')->middleware('portal_enabled');
|
||||
Route::get('payments/{payment}', 'ClientPortal\PaymentController@show')->name('payments.show');
|
||||
Route::post('payments/process/response', 'ClientPortal\PaymentController@response')->name('payments.response');
|
||||
|
@ -154,7 +154,7 @@ trait MockAccountData
|
||||
$cu->is_admin = true;
|
||||
$cu->save();
|
||||
|
||||
$this->token = \Illuminate\Support\Str::random(64);
|
||||
$this->token = 'TOKEN';
|
||||
|
||||
$company_token = new CompanyToken;
|
||||
$company_token->user_id = $this->user->id;
|
||||
|
Loading…
Reference in New Issue
Block a user