Fixes for deletion of payments with unapplied amounts
This commit is contained in:
parent
866a5e0977
commit
22e1350a75
|
|
@ -139,10 +139,12 @@ class DeletePayment
|
|||
|
||||
// 2025-03-26 - If we are deleting a negative payment, then there is an edge case where the paid to date will be reduced further down.
|
||||
// for this scenario, we skip the update to the client paid to date at this point.
|
||||
|
||||
//2025-08-19 - if there is an unapplied amount, we need to subtract it from the paid to date.
|
||||
$this->payment
|
||||
->client
|
||||
->service()
|
||||
->updateBalanceAndPaidToDate($net_deletable, ($net_deletable * -1) > 0 ? 0 : ($net_deletable * -1)) // if negative, set to 0, the paid to date will be reduced further down.
|
||||
->updateBalanceAndPaidToDate($net_deletable, ($net_deletable * -1) > 0 ? 0 : ($net_deletable * -1 - ($this->payment->amount - $this->payment->applied))) // if negative, set to 0, the paid to date will be reduced further down.
|
||||
->save();
|
||||
|
||||
if (abs(floatval($paymentable_invoice->balance) - floatval($paymentable_invoice->amount)) < 0.005) {
|
||||
|
|
@ -172,6 +174,7 @@ class DeletePayment
|
|||
|
||||
$reduced_paid_to_date = $this->payment->amount < 0 ? $this->payment->amount * -1 : min(0, ($this->payment->amount - $this->payment->refunded - $this->_paid_to_date_deleted) * -1);
|
||||
|
||||
nlog("reduced paid to date: {$reduced_paid_to_date}");
|
||||
if($reduced_paid_to_date != 0) {
|
||||
$this->payment
|
||||
->client
|
||||
|
|
|
|||
|
|
@ -11,15 +11,17 @@
|
|||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\DataMapper\InvoiceItem;
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Credit;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use App\Models\ClientContact;
|
||||
use App\DataMapper\InvoiceItem;
|
||||
use Tests\MockAccountData;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Repositories\InvoiceRepository;
|
||||
use App\Repositories\CreditRepository;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
|
||||
class CreditTest extends TestCase
|
||||
|
|
@ -43,6 +45,125 @@ class CreditTest extends TestCase
|
|||
$this->makeTestData();
|
||||
}
|
||||
|
||||
|
||||
public function testPartialAmountWithPartialCreditAndPaymentDeletedBalance()
|
||||
{
|
||||
|
||||
|
||||
$c = Client::factory()->create([
|
||||
'company_id' => $this->company->id,
|
||||
'user_id' => $this->user->id,
|
||||
'balance' => 0,
|
||||
'paid_to_date' => 0,
|
||||
]);
|
||||
|
||||
$ii = new InvoiceItem();
|
||||
$ii->cost = 100;
|
||||
$ii->quantity = 1;
|
||||
$ii->product_key = 'xx';
|
||||
$ii->notes = 'yy';
|
||||
|
||||
$i = \App\Models\Invoice::factory()->create([
|
||||
'company_id' => $this->company->id,
|
||||
'user_id' => $this->user->id,
|
||||
'client_id' => $c->id,
|
||||
'tax_name1' => '',
|
||||
'tax_name2' => '',
|
||||
'tax_name3' => '',
|
||||
'tax_rate1' => 0,
|
||||
'tax_rate2' => 0,
|
||||
'tax_rate3' => 0,
|
||||
'discount' => 0,
|
||||
'line_items' => [
|
||||
$ii
|
||||
],
|
||||
'status_id' => 1,
|
||||
]);
|
||||
|
||||
$repo = new InvoiceRepository();
|
||||
$repo->save([], $i);
|
||||
|
||||
$i = $i->calc()->getInvoice();
|
||||
$i = $i->service()->markSent()->save();
|
||||
|
||||
$this->assertEquals(100, $i->balance);
|
||||
$this->assertEquals(100, $i->amount);
|
||||
|
||||
$cr = \App\Models\Credit::factory()->create([
|
||||
'company_id' => $this->company->id,
|
||||
'user_id' => $this->user->id,
|
||||
'client_id' => $c->id,
|
||||
'tax_name1' => '',
|
||||
'tax_name2' => '',
|
||||
'tax_name3' => '',
|
||||
'tax_rate1' => 0,
|
||||
'tax_rate2' => 0,
|
||||
'tax_rate3' => 0,
|
||||
'discount' => 0,
|
||||
'line_items' => [
|
||||
$ii
|
||||
],
|
||||
'status_id' => 1,
|
||||
]);
|
||||
|
||||
$repo = new CreditRepository();
|
||||
$repo->save([], $cr);
|
||||
|
||||
$cr = $cr->calc()->getInvoice();
|
||||
$cr = $cr->service()->markSent()->save();
|
||||
|
||||
$this->assertEquals(100, $cr->balance);
|
||||
$this->assertEquals(100, $cr->amount);
|
||||
|
||||
|
||||
$data = [
|
||||
'date' => '2020/12/12',
|
||||
'client_id' => $c->hashed_id,
|
||||
'amount' => 10,
|
||||
'invoices' => [
|
||||
[
|
||||
'invoice_id' => $i->hashed_id,
|
||||
'amount' => 10
|
||||
],
|
||||
],
|
||||
'credits' => [
|
||||
[
|
||||
'credit_id' => $cr->hashed_id,
|
||||
'amount' => 10
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson('/api/v1/payments', $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals(10, $arr['data']['amount']);
|
||||
|
||||
$this->assertEquals(20, $c->fresh()->paid_to_date);
|
||||
$this->assertEquals(90, $i->fresh()->balance);
|
||||
$this->assertEquals(90, $cr->fresh()->balance);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->deleteJson('/api/v1/payments/'.$arr['data']['id']);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertEquals(100, $i->fresh()->balance);
|
||||
$this->assertEquals(100, $cr->fresh()->balance);
|
||||
$this->assertEquals(100, $c->fresh()->balance);
|
||||
$this->assertEquals(0, $c->fresh()->paid_to_date);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testCreditReversalScenarioInvoicePartiallyPaid()
|
||||
{
|
||||
|
||||
|
|
@ -117,6 +238,8 @@ class CreditTest extends TestCase
|
|||
|
||||
$this->assertEquals(0, $c->balance);
|
||||
$this->assertEquals(6, $i->status_id);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue