Refactor payments

This commit is contained in:
David Bomba 2020-08-25 23:06:38 +10:00
parent 9f8b7c5d18
commit 979916adb5
6 changed files with 155 additions and 4 deletions

View File

@ -113,6 +113,8 @@ class InvoiceController extends Controller
'total' => $total,
];
//REFACTOR entry point for online payments starts here
return $this->render('invoices.payment', $data);
}

View File

@ -72,11 +72,29 @@ class PaymentController extends Controller
*/
public function process()
{
$invoices = Invoice::whereIn('id', $this->transformKeys(request()->invoices))
->where('company_id', auth('contact')->user()->company->id)
->get();
//REFACTOR - Here the request will contain an array of invoices and the amount to be charged for the invoice
//REFACTOR - At this point, we will also need to modify the invoice to include a line item for a gateway fee if applicable
// This is tagged with a type_id of 3 which is for a pending gateway fee.
//REFACTOR - In order to preserve state we should save the array of invoices and amounts and store it in db/cache and use a HASH
// to rehydrate these values in the payment response.
// [
// 'invoices' =>
// [
// 'invoice_id' => 'xx',
// 'amount' => 'yy',
// ]
// ]
//old
// $invoices = Invoice::whereIn('id', $this->transformKeys(request()->invoices))
// ->where('company_id', auth('contact')->user()->company->id)
// ->get();
$amount = $invoices->sum('balance');
$invoices = Invoice::whereIn('id', $this->transformKeys(array_column($request()->invoices, 'invoice_id')))->get();
//old
// $amount = $invoices->sum('balance');
$invoices = $invoices->filter(function ($invoice) {
return $invoice->isPayable();
@ -88,6 +106,14 @@ class PaymentController extends Controller
->with(['warning' => 'No payable invoices selected.']);
}
foreach(request()->invoices as $payable_invoice)
{
$invoice = Invoice::find($this->decodePrimaryKey($payable_invoice['invoice_id']));
$invoice->service()->addGatewayFee($payable_invoice['amount']);
}
$invoices->map(function ($invoice) {
$invoice->balance = Number::formatMoney($invoice->balance, $invoice->client);
$invoice->due_date = $this->formatDate($invoice->due_date, $invoice->client->date_format());
@ -127,6 +153,21 @@ class PaymentController extends Controller
{
$gateway = CompanyGateway::find($request->input('company_gateway_id'));
//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'))

View File

@ -0,0 +1,28 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class PaymentHash extends Model
{
protected $casts = [
'data' => 'object'
];
public function invoices()
{
return $this->data->invoices;
}
}

View File

@ -0,0 +1,67 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Services\Invoice;
use App\DataMapper\InvoiceItem;
use App\Events\Payment\PaymentWasCreated;
use App\Factory\PaymentFactory;
use App\Models\Client;
use App\Models\CompanyGateway;
use App\Models\Invoice;
use App\Models\Payment;
use App\Services\AbstractService;
use App\Services\Client\ClientService;
use App\Services\Payment\PaymentService;
use App\Utils\Traits\GeneratesCounter;
class AddGatewayFee extends AbstractService
{
private $company_gateway;
private $invoice;
private $amount;
public function __construct(CompanyGateway $company_gateway, Invoice $invoice, float $amount)
{
$this->company_gateway = $company_gateway;
$this->invoice = $invoice;
$this->amount = $amount;
}
public function run()
{
$gateway_fee = $this->company_gateway->calcGatewayFee($this->amount);
if($gateway_fee > 0)
return $this->processGatewayFee($gateway_fee);
return $this->processGatewayDiscount($gateway_fee);
}
private function processGatewayFee($gateway_fee)
{
$invoice_item = new InvoiceItem;
$invoice_item->type_id = 3;
$invoice_item->notes = ctrans('texts.Gateway Fee Surcharge');
}
private function processGatewayDiscount($gateway_fee)
{
}
}

View File

@ -11,6 +11,7 @@
namespace App\Services\Invoice;
use App\Models\CompanyGateway;
use App\Models\Invoice;
use App\Models\Payment;
use App\Services\Client\ClientService;
@ -76,6 +77,12 @@ class InvoiceService
return $this;
}
public function addGatewayFee(CompanyGateway $company_gateway, float $amount)
{
$this->invoice = (new AddGatewayFee($company_gateway, $this->invoice, $amoun))->run();
return $this;
}
/**
* Update an invoice balance
* @param float $balance_adjustment The amount to adjust the invoice by

View File

@ -35,6 +35,12 @@ class AddIsPublicToDocumentsTable extends Migration
$table->softDeletes('deleted_at', 6);
});
Schema::create('payment_hashes', function ($table) {
$table->increments('id');
$table->string('hash', 255);
$table->mediumText('data');
$table->timestamps(6);
});
}