diff --git a/app/Helpers/Invoice/InvoiceItemSum.php b/app/Helpers/Invoice/InvoiceItemSum.php index 74625c98416c..b1f7fa9e6471 100644 --- a/app/Helpers/Invoice/InvoiceItemSum.php +++ b/app/Helpers/Invoice/InvoiceItemSum.php @@ -144,7 +144,7 @@ class InvoiceItemSum public function process(): self { - if (!$this->invoice->line_items || !is_array($this->invoice->line_items)) { + if (!$this->invoice->line_items || !is_iterable($this->invoice->line_items)) { $this->items = []; return $this; } diff --git a/app/Helpers/Invoice/InvoiceItemSumInclusive.php b/app/Helpers/Invoice/InvoiceItemSumInclusive.php index ad1a92600a08..7198abbfe8d1 100644 --- a/app/Helpers/Invoice/InvoiceItemSumInclusive.php +++ b/app/Helpers/Invoice/InvoiceItemSumInclusive.php @@ -131,8 +131,7 @@ class InvoiceItemSumInclusive public function process() { - if (! $this->invoice->line_items || ! is_array($this->invoice->line_items) || count($this->invoice->line_items) == 0) { - + if (!$this->invoice->line_items || ! is_iterable($this->invoice->line_items) || count($this->invoice->line_items) == 0) { return $this; } diff --git a/app/Http/Controllers/ClientPortal/InvoiceController.php b/app/Http/Controllers/ClientPortal/InvoiceController.php index 3804ab890e94..bbed2ee5bbbf 100644 --- a/app/Http/Controllers/ClientPortal/InvoiceController.php +++ b/app/Http/Controllers/ClientPortal/InvoiceController.php @@ -195,7 +195,7 @@ class InvoiceController extends Controller //format data $invoices->map(function ($invoice) { - $invoice->service()->removeUnpaidGatewayFees(); + // $invoice->service()->removeUnpaidGatewayFees(); $invoice->balance = $invoice->balance > 0 ? Number::formatValue($invoice->balance, $invoice->client->currency()) : 0; $invoice->partial = $invoice->partial > 0 ? Number::formatValue($invoice->partial, $invoice->client->currency()) : 0; diff --git a/app/Services/Invoice/AddGatewayFee.php b/app/Services/Invoice/AddGatewayFee.php index 5729a13195ec..08666ad1f4a5 100644 --- a/app/Services/Invoice/AddGatewayFee.php +++ b/app/Services/Invoice/AddGatewayFee.php @@ -29,7 +29,7 @@ class AddGatewayFee extends AbstractService { $gateway_fee = round($this->company_gateway->calcGatewayFee($this->amount, $this->gateway_type_id, $this->invoice->uses_inclusive_taxes), $this->invoice->client->currency()->precision); - if (! $gateway_fee) { + if (! $gateway_fee || $gateway_fee == 0) { return $this->invoice; } @@ -52,6 +52,7 @@ class AddGatewayFee extends AbstractService $invoice_items = collect($invoice_items)->filter(function ($item) { return $item->type_id != '3'; }); + // })->toArray(); $this->invoice->line_items = $invoice_items; @@ -150,7 +151,7 @@ class AddGatewayFee extends AbstractService $this->invoice ->ledger() - ->updateInvoiceBalance($adjustment * -1, 'Adjustment for adding gateway fee'); + ->updateInvoiceBalance($adjustment * -1, 'Adjustment for adding gateway DISCOUNT'); } return $this->invoice; diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index e7d8eb2f6869..7aad51649f2b 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -402,17 +402,19 @@ class InvoiceService $balance = $this->invoice->balance; //return early if type three does not exist. - if (! collect($this->invoice->line_items)->contains('type_id', '3')) { + if (! collect($this->invoice->line_items)->contains('type_id', 3)) { return $this; } $pre_count = count($this->invoice->line_items); - $this->invoice->line_items = collect($this->invoice->line_items) + $items = collect($this->invoice->line_items) ->reject(function ($item) { return $item->type_id == '3'; })->toArray(); + $this->invoice->line_items = array_values($items); + $this->invoice = $this->invoice->calc()->getInvoice(); // $this->deletePdf(); $this->deleteEInvoice(); diff --git a/tests/Unit/LateFeeTest.php b/tests/Unit/LateFeeTest.php index 5721f79e0727..74c708d0cacd 100644 --- a/tests/Unit/LateFeeTest.php +++ b/tests/Unit/LateFeeTest.php @@ -95,6 +95,159 @@ class LateFeeTest extends TestCase return $client; } + public function testModelBehaviourInsideMap() + { + $i = Invoice::factory()->count(5) + ->create([ + 'client_id' => $this->client->id, + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'tax_name1' => '', + 'tax_rate1' => 0, + 'tax_name2' => '', + 'tax_rate2' => 0, + 'tax_name3' => '', + 'tax_rate3' => 0, + 'discount' => 0, + ]); + + $i->each(function($invoice){ + $this->assertGreaterThan(1, count($invoice->line_items)); + }); + + $this->assertCount(5, $i); + + $invoices = $i->map(function ($invoice) { + $invoice->service()->removeUnpaidGatewayFees(); + return $invoice; + }); + + $invoices->each(function ($invoice) { + $this->assertGreaterThan(1, count($invoice->line_items)); + }); + + $ids = $invoices->pluck('id'); + + $invoices = $i->map(function ($invoice) { + + $line_items = $invoice->line_items; + + $item = new InvoiceItem; + $item->type_id = '3'; + $item->product_key = trans('texts.fee'); + $item->quantity = 1; + $item->cost = 10; + + $line_items[] = $item; + + $item = new InvoiceItem; + $item->type_id = '5'; + $item->product_key = trans('texts.fee'); + $item->quantity = 1; + $item->cost = 10; + + $line_items[] = $item; + $invoice->line_items = $line_items; + $invoice->saveQuietly(); + + return $invoice; + }); + + $invoices = Invoice::whereIn('id', $ids)->cursor()->map(function ($invoice){ + nlog("line item count = ".count($invoice->line_items)); + $this->assertGreaterThan(0, count($invoice->line_items)); + + $invoice->service()->removeUnpaidGatewayFees(); + $invoice = $invoice->fresh(); + $this->assertGreaterThan(0, count($invoice->line_items)); + + return $invoice; + }); + + $invoices->each(function ($invoice) { + nlog($invoice->line_items); + $this->assertGreaterThan(0, count($invoice->line_items)); + }); + + } + + public function testCollectionPassesIsArray() + { + $line_items = collect($this->invoice->line_items); + $this->assertTrue(is_array($this->invoice->line_items)); + $this->assertTrue(is_iterable($line_items)); + $this->assertFalse(is_array($line_items)); + } + + public function testLineItemResiliency() + { + $line_count = count($this->invoice->line_items); + $this->assertGreaterThan(0, $line_count); + + $this->invoice->service()->removeUnpaidGatewayFees(); + + $this->invoice = $this->invoice->fresh(); + + $this->assertCount($line_count, $this->invoice->line_items); + } + + public function testCollectionAsLineItemArray() + { + + $i = Invoice::factory()->create([ + 'client_id' => $this->client->id, + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'tax_name1' => '', + 'tax_rate1' => 0, + 'tax_name2' => '', + 'tax_rate2' => 0, + 'tax_name3' => '', + 'tax_rate3' => 0, + 'discount' => 0, + ]); + + $line_items = []; + + $item = InvoiceItemFactory::create(); + $item->quantity = 1; + $item->cost = 10; + $item->type_id = '1'; + + $line_items[] = $item; + + $item = new InvoiceItem; + $item->type_id = '5'; + $item->product_key = trans('texts.fee'); + $item->quantity = 1; + $item->cost = 10; + + $line_items[] = $item; + + $item = InvoiceItemFactory::create(); + $item->quantity = 1; + $item->cost = 1; + $item->type_id = '3'; + + $line_items[] = $item; + + $i->line_items = $line_items; + + $this->assertEquals(3, count($line_items)); + + $i = $i->calc()->getInvoice(); + + $this->assertEquals(3, count($i->line_items)); + $this->assertEquals(21, $i->amount); + + // $invoice_items = collect($invoice_items)->filter(function ($item) { + // return $item->type_id != '3'; + // }); + + // $this->invoice->line_items = $invoice_items; + + } + public function testLateFeeRemovals() { @@ -133,6 +286,20 @@ class LateFeeTest extends TestCase $cgt->company_gateway_id = $cg->id; $cgt->save(); + + $i = Invoice::factory()->create([ + 'client_id' => $this->client->id, + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'tax_name1' => '', + 'tax_rate1' => 0, + 'tax_name2' => '', + 'tax_rate2' => 0, + 'tax_name3' => '', + 'tax_rate3' => 0, + 'discount' => 0, + ]); + $line_items = []; $item = InvoiceItemFactory::create(); @@ -142,11 +309,11 @@ class LateFeeTest extends TestCase $line_items[] = $item; - $invoice_item = new InvoiceItem; - $invoice_item->type_id = '5'; - $invoice_item->product_key = trans('texts.fee'); - $invoice_item->quantity = 1; - $invoice_item->cost = 10; + $item = new InvoiceItem; + $item->type_id = '5'; + $item->product_key = trans('texts.fee'); + $item->quantity = 1; + $item->cost = 10; $line_items[] = $item; @@ -157,20 +324,12 @@ class LateFeeTest extends TestCase $line_items[] = $item; - $this->assertTrue(collect($line_items)->contains('type_id', '3')); - $this->assertTrue(collect($line_items)->contains('type_id', 3)); - - $i = Invoice::factory()->create([ - - 'client_id' => $this->client->id, - 'company_id' => $this->company->id, - 'user_id' => $this->user->id, - 'line_items' => $line_items, - ]); + $i->line_items = $line_items; $i = $i->calc()->getInvoice(); $this->assertEquals(3, count($i->line_items)); + $this->assertEquals(21, $i->amount); $invoice_items = (array) $i->line_items; @@ -180,6 +339,10 @@ class LateFeeTest extends TestCase $i->line_items = $invoice_items; + $i = $i->calc()->getInvoice(); + + $this->assertEquals(20, $i->amount); + $i->line_items = collect($i->line_items) ->reject(function ($item) { return $item->type_id == '3'; @@ -192,21 +355,28 @@ class LateFeeTest extends TestCase $i = $i->fresh(); $this->assertCount(2, $i->line_items); + $this->assertEquals(20, $i->amount); $line_items = $i->line_items; - $invoice_item = new InvoiceItem; - $invoice_item->type_id = '5'; - $invoice_item->product_key = trans('texts.fee'); - $invoice_item->quantity = 1; - $invoice_item->cost = 10; + $item = new InvoiceItem; + $item->type_id = '5'; + $item->product_key = trans('texts.fee'); + $item->quantity = 1; + $item->cost = 10; $line_items[] = $item; $i->line_items = $line_items; $i = $i->calc()->getInvoice(); + $this->assertEquals(30, $i->amount); + $this->assertCount(3, $i->line_items); + $i->service()->autoBill(); + $i = $i->fresh(); + + $this->assertEquals(30, $i->amount); $this->assertCount(3, $i->line_items); }