1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-05 18:52:44 +01:00

Merge pull request #4141 from turbo124/v2

Fixes for tests
This commit is contained in:
David Bomba 2020-10-09 07:14:23 +11:00 committed by GitHub
commit 7f31d076b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 159 additions and 50 deletions

View File

@ -203,10 +203,8 @@ class BaseRepository
$resource = explode('\\', $class->name)[2]; /** This will extract 'Invoice' from App\Models\Invoice */
$lcfirst_resource_id = lcfirst($resource).'_id';
if ($class->name == Invoice::class || $class->name == Quote::class) {
$state['starting_amount'] = $model->amount;
}
$state['starting_amount'] = $model->amount;
if (! $model->id) {
$company_defaults = $client->setCompanyDefaults($data, lcfirst($resource));
$model->uses_inclusive_taxes = $client->getSetting('inclusive_taxes');
@ -320,7 +318,10 @@ class BaseRepository
}
if ($class->name == Credit::class) {
$model = $model->calc()->getCredit();
$model->ledger()->updateCreditBalance(($state['finished_amount'] - $state['starting_amount']));
if (! $model->design_id) {
$model->design_id = $this->decodePrimaryKey($client->getSetting('credit_design_id'));

View File

@ -45,6 +45,7 @@ class MarkSent
->applyNumber()
->save();
return $this->credit;
}
}

View File

@ -21,6 +21,7 @@ use App\Models\PaymentHash;
use App\Services\AbstractService;
use App\Services\Client\ClientService;
use App\Services\Payment\PaymentService;
use App\Utils\Ninja;
use App\Utils\Traits\GeneratesCounter;
use Illuminate\Support\Str;
@ -30,7 +31,7 @@ class AutoBillInvoice extends AbstractService
private $client;
private $payment;
private $used_credit = [];
public function __construct(Invoice $invoice)
{
@ -52,15 +53,15 @@ class AutoBillInvoice extends AbstractService
if ((int)$this->invoice->balance == 0)
return $this->invoice->service()->markPaid()->save();
$this->applyCreditPayment();
$this->applyCreditPayment(); //if the credits cover the payments, we stop here, build the payment with credits and exit early
/* Determine $amount */
if ($this->invoice->partial > 0)
$amount = $this->invoice->partial;
elseif($this->invoice->balance >0)
elseif($this->invoice->balance > 0)
$amount = $this->invoice->balance;
else
return $this->invoice;
return $this->finalizePaymentUsingCredits();
$gateway_token = $this->getGateway($amount);
@ -86,6 +87,56 @@ class AutoBillInvoice extends AbstractService
return $this->invoice;
}
/**
* If the credits on file cover the invoice amount
* the we create a matching payment using credits only
*
* @return Invoice $invoice
*/
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;
$payment->client_id = $this->invoice->client_id;
$payment->currency_id = $this->invoice->client->getSetting('currency_id');
$payment->date = now();
$payment->status_id = Payment::STATUS_COMPLETED;
$payment->service()->applyNumber()->save();
$payment->invoices()->attach($this->invoice->id, ['amount' => $amount]);
$this->invoice->service()->setStatus(Invoice::STATUS_PAID)->save();
foreach($this->used_credit as $credit)
{
$payment->credits()->attach($credit['credit_id'], ['amount' => $credit['amount']]);
}
$payment->ledger()
->updatePaymentBalance($amount * -1)
->save();
$this->invoice->client->service()
->updateBalance($amount * -1)
->updatePaidToDate($amount)
->adjustCreditBalance($amount * -1)
->save();
$this->invoice->ledger()
->updateInvoiceBalance($amount * -1, 'Invoice payment using Credit')
->updateCreditBalance($amount * -1, 'Credits used to pay down Invoice ' . $this->invoice->number)
->save();
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
return $this->invoice->service()->setStatus(Invoice::STATUS_PAID)->save();
}
/**
* Applies credits to a payment prior to push
* to the payment gateway
@ -112,48 +163,50 @@ class AutoBillInvoice extends AbstractService
$is_partial_amount = true;
}
$this->payment = PaymentFactory::create($this->client->company_id, $this->client->user_id);
$this->payment->save();
$this->used_credit = [];
$available_credits->each(function($credit) use($is_partial_amount){
foreach($available_credits as $key => $credit) {
//todo need to iterate until the partial or balance is completely consumed
//by the credit, any remaining balance is then dealt with by
//the gateway
//each time a credit is applied SAVE the invoice
if($is_partial_amount) {
//more credit than needed
if($credit->balance >= $this->invoice->partial) {
$this->used_credit[$key]['credit_id'] = $credit->id;
$this->used_credit[$key]['amount'] = $this->invoice->partial;
$this->invoice->balance -= $this->invoice->partial;
$this->invoice->partial = 0;
break;
}
else {
$this->used_credit[$key]['credit_id'] = $credit->id;
$this->used_credit[$key]['amount'] = $credit->balance;
$this->invoice->partial -= $credit->balance;
$this->invoice->balance -= $credit->balance;
}
}
else {
//more credit than needed
if($credit->balance >= $this->invoice->balance) {
$this->used_credit[$key]['credit_id'] = $credit->id;
$this->used_credit[$key]['amount'] = $this->invoice->balance;
$this->invoice->balance = 0;
break;
}
else {
$this->used_credit[$key]['credit_id'] = $credit->id;
$this->used_credit[$key]['amount'] = $credit->balance;
$this->invoice->balance -= $credit->balance;
}
}
}
// if($credit->balance >= $amount){
// //current credit covers the total amount
// }
//return false to exit each loop
});
return $this;
}
private function buildPayment($credit, $is_partial_amount)
{
if($is_partial_amount) {
if($this->invoice->partial >= $credit->balance) {
$amount = $this->invoice->partial - $credit->balance;
$this->invoice->partial -= $amount;
$this->payment->credits()->attach([
$credit->id => ['amount' => $amount]
]);
$this->payment->invoice()->attach([
$this->invoice->id => ['amount' => $amount]
]);
$this->applyPaymentToCredit($credit, $amount);
}
}
}
private function applyPaymentToCredit($credit, $amount)
@ -173,7 +226,6 @@ class AutoBillInvoice extends AbstractService
$credit = $credit->calc()->getCredit();
}
/**

View File

@ -66,6 +66,8 @@ class LedgerService
$company_ledger->save();
$this->entity->company_ledger()->save($company_ledger);
return $this;
}
public function updateCreditBalance($adjustment, $notes = '')

View File

@ -227,12 +227,6 @@ trait MockAccountData
$this->invoice = InvoiceFactory::create($this->company->id, $this->user->id); //stub the company and user_id
$this->invoice->client_id = $this->client->id;
// $this->invoice = Invoice::factory()->create([
// 'user_id' => $this->user->id,
// 'client_id' => $this->client->id,
// 'company_id' => $this->company->id,
// ]);
$this->invoice->line_items = $this->buildLineItems();
$this->invoice->uses_inclusive_taxes = false;
@ -316,7 +310,6 @@ trait MockAccountData
$this->credit->uses_inclusive_taxes = false;
$this->credit->save();
$this->credit->service()->createInvitations()->markSent();
$this->credit_calc = new InvoiceSum($this->credit);
@ -325,6 +318,9 @@ trait MockAccountData
$this->credit = $this->credit_calc->getCredit();
$this->credit->service()->markSent();
$this->client->service()->adjustCreditBalance($this->credit->balance)->save();
$this->credit->ledger()->updateCreditBalance($this->credit->balance)->save();
$contacts = $this->invoice->client->contacts;
$contacts->each(function ($contact) {

View File

@ -0,0 +1,57 @@
<?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 Tests\Unit;
use App\Models\Invoice;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\MockAccountData;
use Tests\TestCase;
/**
* @test
* @covers App\Services\Invoice\AutoBillInvoice
*/
class AutoBillInvoiceTest extends TestCase
{
use MockAccountData;
use DatabaseTransactions;
public function setUp() :void
{
parent::setUp();
$this->makeTestData();
}
public function testAutoBillFunctionality()
{
// info("client balance = {$this->client->balance}");
// info("invoice balance = {$this->invoice->balance}");
$this->assertEquals($this->client->balance, 10);
$this->assertEquals($this->client->paid_to_date, 0);
$this->assertEquals($this->client->credit_balance, 10);
$this->invoice->service()->markSent()->autoBill()->save();
// info(print_r($this->invoice->payments()->first()->toArray(),1));
$this->assertNotNull($this->invoice->payments());
$this->assertEquals(10, $this->invoice->payments()->sum('payments.amount'));
//info(print_r($this->invoice->payments()->get(),1));
$this->assertEquals($this->client->balance, 0);
$this->assertEquals($this->client->paid_to_date, 10);
$this->assertEquals($this->client->credit_balance, 0);
}
}