mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-09-21 08:51:34 +02:00
Merge pull request #5501 from turbo124/v5-develop
Fixes for deleting refunded payments.
This commit is contained in:
commit
b72e6de980
@ -1 +1 @@
|
||||
5.1.49
|
||||
5.1.50
|
@ -88,9 +88,9 @@ class OneTimeTokenController extends BaseController
|
||||
|
||||
MultiDB::findAndSetDbByCompanyKey($data['company_key']);
|
||||
|
||||
$user = User::findOrFail($data['user_id']);
|
||||
// $user = User::findOrFail($data['user_id']);
|
||||
|
||||
Auth::login($user, true);
|
||||
// Auth::login($user, true);
|
||||
|
||||
// Cache::forget($request->input('hash'));
|
||||
|
||||
|
@ -245,21 +245,30 @@ class Invoice extends BaseModel
|
||||
|
||||
public function getStatusAttribute()
|
||||
{
|
||||
if ($this->status_id == self::STATUS_SENT && $this->due_date > Carbon::now()) {
|
||||
$due_date = $this->due_date ? Carbon::parse($this->due_date) : false;
|
||||
$partial_due_date = $this->partial_due_Date ? Carbon::parse($this->partial_due_date) : false;
|
||||
|
||||
if ($this->status_id == self::STATUS_SENT && $due_date && $due_date->gt(now())) {
|
||||
nlog("1 unpaid");
|
||||
return self::STATUS_UNPAID;
|
||||
} elseif ($this->status_id == self::STATUS_PARTIAL && $this->partial_due_date > Carbon::now()) {
|
||||
return self::STATUS_UNPAID;
|
||||
} elseif ($this->status_id == self::STATUS_SENT && $this->due_date < Carbon::now()) {
|
||||
} elseif ($this->status_id == self::STATUS_PARTIAL && $partial_due_date && $partial_due_date->gt(now())) {
|
||||
nlog("2 partial");
|
||||
return self::STATUS_PARTIAL;
|
||||
} elseif ($this->status_id == self::STATUS_SENT && $due_date && $due_date->lt(now())) {
|
||||
nlog("3 overdue");
|
||||
return self::STATUS_OVERDUE;
|
||||
} elseif ($this->status_id == self::STATUS_PARTIAL && $this->partial_due_date < Carbon::now()) {
|
||||
} elseif ($this->status_id == self::STATUS_PARTIAL && $partial_due_date && $partial_due_date->lt(now())) {
|
||||
nlog("4 overdue");
|
||||
return self::STATUS_OVERDUE;
|
||||
} else {
|
||||
nlog("status id ");
|
||||
return $this->status_id;
|
||||
}
|
||||
}
|
||||
|
||||
public function isPayable(): bool
|
||||
{
|
||||
|
||||
if ($this->status_id == self::STATUS_DRAFT && $this->is_deleted == false) {
|
||||
return true;
|
||||
} elseif ($this->status_id == self::STATUS_SENT && $this->is_deleted == false) {
|
||||
|
@ -80,19 +80,21 @@ class DeletePayment
|
||||
|
||||
$this->payment->invoices()->each(function ($paymentable_invoice) {
|
||||
|
||||
$net_deletable = $paymentable_invoice->pivot->amount - $paymentable_invoice->pivot->refunded;
|
||||
|
||||
$paymentable_invoice->service()
|
||||
->updateBalance($paymentable_invoice->pivot->amount)
|
||||
->updatePaidToDate($paymentable_invoice->pivot->amount * -1)
|
||||
->updateBalance($net_deletable)
|
||||
->updatePaidToDate($net_deletable * -1)
|
||||
->save();
|
||||
|
||||
$paymentable_invoice->ledger()
|
||||
->updateInvoiceBalance($paymentable_invoice->pivot->amount, "Adjusting invoice {$paymentable_invoice->number} due to deletion of Payment {$this->payment->number}")
|
||||
->updateInvoiceBalance($net_deletable, "Adjusting invoice {$paymentable_invoice->number} due to deletion of Payment {$this->payment->number}")
|
||||
->save();
|
||||
|
||||
$paymentable_invoice->client
|
||||
->service()
|
||||
->updateBalance($paymentable_invoice->pivot->amount)
|
||||
->updatePaidToDate($paymentable_invoice->pivot->amount * -1)
|
||||
->updateBalance($net_deletable)
|
||||
->updatePaidToDate($net_deletable * -1)
|
||||
->save();
|
||||
|
||||
if ($paymentable_invoice->balance == $paymentable_invoice->amount) {
|
||||
|
@ -14,6 +14,7 @@ use App\DataMapper\ClientSettings;
|
||||
use App\Factory\ClientFactory;
|
||||
use App\Factory\CreditFactory;
|
||||
use App\Factory\InvoiceFactory;
|
||||
use App\Factory\InvoiceItemFactory;
|
||||
use App\Factory\PaymentFactory;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Models\Client;
|
||||
@ -1385,4 +1386,99 @@ class PaymentTest extends TestCase
|
||||
|
||||
$this->assertEquals(1, $arr['data'][0]['is_deleted']);
|
||||
}
|
||||
|
||||
|
||||
public function testDeleteRefundedPayment()
|
||||
{
|
||||
|
||||
$this->invoice = null;
|
||||
|
||||
$client = ClientFactory::create($this->company->id, $this->user->id);
|
||||
$client->save();
|
||||
|
||||
$this->invoice = InvoiceFactory::create($this->company->id, $this->user->id); //stub the company and user_id
|
||||
$this->invoice->client_id = $client->id;
|
||||
|
||||
|
||||
$item = InvoiceItemFactory::create();
|
||||
$item->quantity = 1;
|
||||
$item->cost = 10;
|
||||
$item->product_key = 'test';
|
||||
$item->notes = 'test';
|
||||
$item->custom_value1 = '';
|
||||
$item->custom_value2 = '';
|
||||
$item->custom_value3 = '';
|
||||
$item->custom_value4 = '';
|
||||
|
||||
$line_items[] = $item;
|
||||
|
||||
$this->invoice->line_items = $line_items;
|
||||
$this->invoice->uses_inclusive_taxes = false;
|
||||
|
||||
$this->invoice->save();
|
||||
|
||||
$this->invoice_calc = new InvoiceSum($this->invoice);
|
||||
$this->invoice_calc->build();
|
||||
|
||||
$this->invoice = $this->invoice_calc->getInvoice();
|
||||
$this->invoice->save();
|
||||
$this->invoice->service()->markSent()->save();
|
||||
|
||||
|
||||
$this->assertEquals(10, $this->invoice->balance);
|
||||
$this->assertEquals(10, $this->invoice->client->balance);
|
||||
|
||||
$this->invoice->service()->markPaid()->save();
|
||||
|
||||
$this->assertEquals(0, $this->invoice->balance);
|
||||
$this->assertEquals(0, $this->invoice->client->balance);
|
||||
|
||||
$this->assertTrue($this->invoice->payments()->exists());
|
||||
|
||||
$payment = $this->invoice->payments()->first();
|
||||
|
||||
$data = [
|
||||
'id' => $this->encodePrimaryKey($payment->id),
|
||||
'amount' => 10,
|
||||
'date' => '2021/12/12',
|
||||
'invoices' => [
|
||||
[
|
||||
'invoice_id' => $this->invoice->hashed_id,
|
||||
'amount' => 10,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$response = false;
|
||||
|
||||
try {
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/payments/refund', $data);
|
||||
} catch (ValidationException $e) {
|
||||
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||
nlog($message);
|
||||
}
|
||||
|
||||
$arr = $response->json();
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertEquals(10, $this->invoice->fresh()->balance);
|
||||
$this->assertEquals(10, $this->invoice->fresh()->balance);
|
||||
|
||||
$data = [
|
||||
'ids' => [$this->encodePrimaryKey($payment->id)],
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/payments/bulk?action=delete', $data);
|
||||
|
||||
$this->assertEquals(10, $this->invoice->fresh()->balance);
|
||||
$this->assertEquals(10, $this->invoice->fresh()->balance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ use App\Models\Company;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\Timezone;
|
||||
use App\Utils\Traits\GeneratesCounter;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@ -48,6 +49,42 @@ class GeneratesCounterTest extends TestCase
|
||||
$this->makeTestData();
|
||||
}
|
||||
|
||||
public function testResetCounter()
|
||||
{
|
||||
$timezone = Timezone::find(1);
|
||||
|
||||
$date_formatted = now($timezone->name)->format('Ymd');
|
||||
|
||||
$settings = $this->company->settings;
|
||||
$settings->invoice_number_pattern = '{$date:Ymd}-{$counter}';
|
||||
$settings->timezone_id = 1;
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$this->client->settings = $settings;
|
||||
$this->client->save();
|
||||
|
||||
$invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh());
|
||||
$this->assertEquals($date_formatted."-0001", $invoice_number);
|
||||
$invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh());
|
||||
$this->assertEquals($date_formatted."-0002", $invoice_number);
|
||||
|
||||
$settings->reset_counter_date = now($timezone->name)->format('Y-m-d');
|
||||
$settings->reset_counter_frequency_id = RecurringInvoice::FREQUENCY_DAILY;
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$this->client->settings = $settings;
|
||||
$this->client->save();
|
||||
|
||||
$this->travel(5)->days();
|
||||
$date_formatted = now($timezone->name)->format('Ymd');
|
||||
|
||||
$invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh());
|
||||
$this->assertEquals($date_formatted."-0001", $invoice_number);
|
||||
|
||||
}
|
||||
|
||||
public function testHasSharedCounter()
|
||||
{
|
||||
$this->assertFalse($this->hasSharedCounter($this->client));
|
||||
@ -348,6 +385,7 @@ class GeneratesCounterTest extends TestCase
|
||||
$this->assertEquals($vendor_number, date('Y').'-'.str_pad($vendor->user_id, 2, '0', STR_PAD_LEFT).'-0002');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
public function testClientNextNumber()
|
||||
|
58
tests/Unit/InvoiceStatusTest.php
Normal file
58
tests/Unit/InvoiceStatusTest.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Factory\InvoiceItemFactory;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Models\Invoice;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @covers App\Helpers\Invoice\InvoiceSum
|
||||
*/
|
||||
class InvoiceStatusTest extends TestCase
|
||||
{
|
||||
use MockAccountData;
|
||||
use DatabaseTransactions;
|
||||
|
||||
public $invoice;
|
||||
|
||||
public $invoice_calc;
|
||||
|
||||
public $settings;
|
||||
|
||||
public function setUp() :void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->makeTestData();
|
||||
|
||||
}
|
||||
|
||||
public function testSentStatus()
|
||||
{
|
||||
$this->invoice->due_date = now()->addMonth();
|
||||
$this->invoice->status_id = Invoice::STATUS_SENT;
|
||||
|
||||
$this->assertEquals(Invoice::STATUS_UNPAID, $this->invoice->getStatusAttribute());
|
||||
}
|
||||
|
||||
public function testPartialStatus()
|
||||
{
|
||||
$this->invoice->partial_due_date = now()->addMonth();
|
||||
$this->invoice->status_id = Invoice::STATUS_SENT;
|
||||
|
||||
$this->assertEquals(Invoice::STATUS_SENT, $this->invoice->getStatusAttribute());
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ namespace Tests\Unit;
|
||||
|
||||
use App\Factory\InvoiceItemFactory;
|
||||
use App\Helpers\Invoice\InvoiceSum;
|
||||
use App\Models\Invoice;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
@ -220,4 +221,6 @@ class InvoiceTest extends TestCase
|
||||
//$this->assertEquals($this->invoice_calc->getTotalTaxes(), 4);
|
||||
//$this->assertEquals(count($this->invoice_calc->getTaxMap()), 1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user