Recurring invoice update / upgrade pricing

This commit is contained in:
David Bomba 2023-03-15 16:17:24 +11:00
parent a06fffe799
commit e809fa156d
5 changed files with 176 additions and 6 deletions

View File

@ -735,7 +735,9 @@ class RecurringInvoice extends BaseModel
}
/**
* Service entry points.
* service
*
* @return RecurringService
*/
public function service() :RecurringService
{

View File

@ -0,0 +1,49 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Services\Recurring;
use App\Models\Product;
use App\Models\RecurringInvoice;
use App\Services\AbstractService;
class IncreasePrices extends AbstractService
{
public function __construct(public array $ids, public float $percentage)
{
}
public function run()
{
RecurringInvoice::whereIn('id', $this->ids)
->cursor()
->each(function ($recurring_invoice) {
$line_items = $recurring_invoice->line_items;
foreach ($line_items as $key => $line_item) {
$line_items[$key]->cost = $line_item->cost * (1 + round(($this->percentage / 100), 2));
}
$recurring_invoice->line_items = $line_items;
$recurring_invoice->calc()->getInvoice()->save();
});
}
}

View File

@ -11,18 +11,22 @@
namespace App\Services\Recurring;
use App\Jobs\RecurringInvoice\SendRecurring;
use App\Jobs\Util\UnlinkFile;
use App\Models\RecurringInvoice;
use Illuminate\Support\Carbon;
use App\Models\RecurringExpense;
use App\Models\RecurringInvoice;
use App\Services\Recurring\ApplyNumber;
use App\Services\Recurring\UpdatePrices;
use App\Services\Recurring\GetInvoicePdf;
use App\Services\Recurring\IncreasePrices;
use App\Jobs\RecurringInvoice\SendRecurring;
use App\Services\Recurring\CreateRecurringInvitations;
class RecurringService
{
protected $recurring_entity;
public function __construct($recurring_entity)
public function __construct(public RecurringInvoice | RecurringExpense $recurring_entity)
{
$this->recurring_entity = $recurring_entity;
}
//set schedules - update next_send_dates
@ -135,6 +139,21 @@ class RecurringService
{
return $this;
}
public function increasePrices(array $ids, float $percentage)
{
(new IncreasePrices($ids, $percentage))->run();
return $ids;
}
public function updatePrices(array $ids)
{
(new UpdatePrices($ids))->run();
return $ids;
}
public function save()
{

View File

@ -0,0 +1,51 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Services\Recurring;
use App\Models\Product;
use App\Models\RecurringInvoice;
use App\Services\AbstractService;
class UpdatePrices extends AbstractService
{
public function __construct(public array $ids)
{
}
public function run()
{
RecurringInvoice::whereIn('id', $this->ids)
->cursor()
->each(function ($recurring_invoice){
$line_items = $recurring_invoice->line_items;
foreach($line_items as $key => $line_item)
{
$product = Product::where('company_id', $recurring_invoice->company_id)
->where('product_key', $line_item->product_key)
->where('is_deleted', 0)
->first();
if($product){
$line_items[$key]->cost = $product->cost;
}
}
$recurring_invoice->line_items = $line_items;
$recurring_invoice->calc()->getInvoice()->save();
});
}
}

View File

@ -13,12 +13,14 @@ namespace Tests\Feature;
use App\Factory\InvoiceItemFactory;
use App\Factory\InvoiceToRecurringInvoiceFactory;
use App\Factory\RecurringInvoiceFactory;
use App\Factory\RecurringInvoiceToInvoiceFactory;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\RecurringInvoice;
use App\Utils\Helpers;
use App\Utils\Traits\MakesHash;
use App\Models\Product;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Routing\Middleware\ThrottleRequests;
@ -53,6 +55,53 @@ class RecurringInvoiceTest extends TestCase
$this->makeTestData();
}
public function testBulkUpdatePrices()
{
$p = Product::factory()->create([
'company_id' => $this->company->id,
'user_id' => $this->user->id,
'cost' => 10,
'product_key' => 'pink',
]);
$recurring_invoice = RecurringInvoiceFactory::create($this->company->id, $this->user->id);
$recurring_invoice->client_id = $this->client->id;
$line_items[] = [
'product_key' => 'pink',
'notes' => 'test',
'cost' => 10,
'quantity' => 1,
'tax_name1' => '',
'tax_rate1' => 0,
'tax_name2' => '',
'tax_rate2' => 0,
'tax_name3' => '',
'tax_rate3' => 0,
];
$recurring_invoice->line_items = $line_items;
$recurring_invoice->calc()->getInvoice()->service()->start()->save()->fresh();
$this->assertEquals(10, $recurring_invoice->amount);
$p->cost = 20;
$p->save();
$recurring_invoice->service()->updatePrices([$recurring_invoice->id]);
$recurring_invoice->refresh();
$this->assertEquals(20, $recurring_invoice->amount);
$recurring_invoice->service()->increasePrices([$recurring_invoice->id], 10);
$recurring_invoice->refresh();
$this->assertEquals(22, $recurring_invoice->amount);
}
public function testRecurringGetStatus()
{
$response = $this->withHeaders([