1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-06 03:02:34 +01:00

Fixes for partial credit payments"

This commit is contained in:
David Bomba 2021-01-06 16:54:04 +11:00
parent 3ee3f67c8c
commit 47f42b804d
4 changed files with 53 additions and 30 deletions

View File

@ -108,6 +108,8 @@ class PaymentController extends Controller
$settings = auth()->user()->client->getMergedSettings(); $settings = auth()->user()->client->getMergedSettings();
//nlog($settings);
/* This loop checks for under / over payments and returns the user if a check fails */ /* This loop checks for under / over payments and returns the user if a check fails */
foreach($payable_invoices as $payable_invoice) foreach($payable_invoices as $payable_invoice)
@ -220,7 +222,7 @@ class PaymentController extends Controller
$payment_hash = new PaymentHash; $payment_hash = new PaymentHash;
$payment_hash->hash = Str::random(128); $payment_hash->hash = Str::random(128);
$payment_hash->data = ['invoices' => $payable_invoices->toArray()]; $payment_hash->data = ['invoices' => $payable_invoices->toArray() , 'credits' => $credit_totals];
$payment_hash->fee_total = $fee_totals; $payment_hash->fee_total = $fee_totals;
$payment_hash->fee_invoice_id = $first_invoice->id; $payment_hash->fee_invoice_id = $first_invoice->id;
$payment_hash->save(); $payment_hash->save();
@ -255,6 +257,7 @@ class PaymentController extends Controller
public function response(PaymentResponseRequest $request) public function response(PaymentResponseRequest $request)
{ {
$gateway = CompanyGateway::findOrFail($request->input('company_gateway_id')); $gateway = CompanyGateway::findOrFail($request->input('company_gateway_id'));
$payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$request->payment_hash])->first(); $payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$request->payment_hash])->first();
@ -289,35 +292,7 @@ class PaymentController extends Controller
$payment_hash->save(); $payment_hash->save();
} }
/* Iterate through the invoices and apply credits to them */ $payment = $payment->service()->applyCredits($payment_hash)->save();
collect($payment_hash->invoices())->each(function ($payable_invoice) use ($payment, $payment_hash) {
$invoice = Invoice::find($this->decodePrimaryKey($payable_invoice->invoice_id));
$amount = $payable_invoice->amount;
$credits = $payment_hash->fee_invoice
->client
->service()
->getCredits();
foreach ($credits as $credit) {
//starting invoice balance
$invoice_balance = $invoice->balance;
//credit payment applied
$credit->service()->applyPayment($invoice, $amount, $payment);
//amount paid from invoice calculated
$remaining_balance = ($invoice_balance - $invoice->fresh()->balance);
//reduce the amount to be paid on the invoice from the NEXT credit
$amount -= $remaining_balance;
//break if the invoice is no longer PAYABLE OR there is no more amount to be applied
if (!$invoice->isPayable() || (int)$amount == 0) {
break;
}
}
});
return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]); return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]);
} }

View File

@ -27,6 +27,11 @@ class PaymentHash extends Model
return $this->data->invoices; return $this->data->invoices;
} }
public function credits_total()
{
return isset($this->data->credits) ? $this->data->credits : 0;
}
public function payment() public function payment()
{ {
return $this->belongsTo(Payment::class)->withTrashed(); return $this->belongsTo(Payment::class)->withTrashed();

View File

@ -213,6 +213,9 @@ class BaseDriver extends AbstractPaymentDriver
$this->attachInvoices($payment, $this->payment_hash); $this->attachInvoices($payment, $this->payment_hash);
if($this->payment_hash->credits_total() > 0)
$payment = $payment->service()->applyCredits($this->payment_hash)->save();
$payment->service()->updateInvoicePayment($this->payment_hash); $payment->service()->updateInvoicePayment($this->payment_hash);
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars())); event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));

View File

@ -15,9 +15,12 @@ use App\Factory\PaymentFactory;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Payment; use App\Models\Payment;
use App\Models\PaymentHash; use App\Models\PaymentHash;
use App\Utils\Traits\MakesHash;
class PaymentService class PaymentService
{ {
use MakesHash;
private $payment; private $payment;
public function __construct($payment) public function __construct($payment)
@ -97,6 +100,43 @@ class PaymentService
return $this; return $this;
} }
public function applyCredits($payment_hash)
{
/* Iterate through the invoices and apply credits to them */
collect($payment_hash->invoices())->each(function ($payable_invoice) use ($payment_hash) {
$invoice = Invoice::find($this->decodePrimaryKey($payable_invoice->invoice_id));
$amount = $payable_invoice->amount;
$credits = $payment_hash->fee_invoice
->client
->service()
->getCredits();
foreach ($credits as $credit) {
//starting invoice balance
$invoice_balance = $invoice->balance;
//credit payment applied
$credit->service()->applyPayment($invoice, $amount, $this->payment);
//amount paid from invoice calculated
$remaining_balance = ($invoice_balance - $invoice->fresh()->balance);
//reduce the amount to be paid on the invoice from the NEXT credit
$amount -= $remaining_balance;
//break if the invoice is no longer PAYABLE OR there is no more amount to be applied
if (!$invoice->isPayable() || (int)$amount == 0) {
break;
}
}
});
return $this;
}
public function save() public function save()
{ {
$this->payment->save(); $this->payment->save();