mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
Inventory Management Tests
This commit is contained in:
parent
e153a0a06a
commit
f92070e3be
@ -225,6 +225,7 @@ class InvoiceController extends BaseController
|
||||
$invoice = $invoice->service()
|
||||
->fillDefaults()
|
||||
->triggeredActions($request)
|
||||
->adjustInventory()
|
||||
->save();
|
||||
|
||||
event(new InvoiceWasCreated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
@ -414,9 +415,14 @@ class InvoiceController extends BaseController
|
||||
return response()->json(['message' => ctrans('texts.locked_invoice')], 403);
|
||||
}
|
||||
|
||||
$old_invoice = $invoice->line_items;
|
||||
|
||||
$invoice = $this->invoice_repo->save($request->all(), $invoice);
|
||||
|
||||
$invoice->service()->triggeredActions($request)->touchPdf();
|
||||
$invoice->service()
|
||||
->triggeredActions($request)
|
||||
->touchPdf()
|
||||
->adjustInventory($old_invoice);
|
||||
|
||||
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
|
@ -362,6 +362,7 @@ class BillingPortalPurchase extends Component
|
||||
->service()
|
||||
->markSent()
|
||||
->fillDefaults()
|
||||
->adjustInventory()
|
||||
->save();
|
||||
|
||||
Cache::put($this->hash, [
|
||||
|
@ -37,9 +37,8 @@ class AdjustProductInventory implements ShouldQueue
|
||||
|
||||
public array $old_invoice;
|
||||
|
||||
public function __construct(Company $company, Invoice $invoice, array $old_invoice = [])
|
||||
public function __construct(Company $company, Invoice $invoice, ?array $old_invoice = [])
|
||||
{
|
||||
|
||||
$this->company = $company;
|
||||
$this->invoice = $invoice;
|
||||
$this->old_invoice = $old_invoice;
|
||||
@ -55,8 +54,10 @@ class AdjustProductInventory implements ShouldQueue
|
||||
{
|
||||
MultiDB::setDb($this->company->db);
|
||||
|
||||
nlog("old invoice count = " . count($this->old_invoice));
|
||||
|
||||
if(count($this->old_invoice) > 0)
|
||||
return $this->existingInventoryAdjustment();
|
||||
$this->existingInventoryAdjustment();
|
||||
|
||||
return $this->newInventoryAdjustment();
|
||||
|
||||
@ -73,6 +74,8 @@ class AdjustProductInventory implements ShouldQueue
|
||||
|
||||
$line_items = $this->invoice->line_items;
|
||||
|
||||
nlog($line_items);
|
||||
|
||||
foreach($line_items as $item)
|
||||
{
|
||||
|
||||
@ -81,10 +84,14 @@ class AdjustProductInventory implements ShouldQueue
|
||||
if(!$p)
|
||||
continue;
|
||||
|
||||
$p->in_stock_quantity -= $item->quantity;
|
||||
$p->save();
|
||||
|
||||
//check thresholds and notify user
|
||||
nlog("subtracting back " . $item->quantity);
|
||||
|
||||
$p->in_stock_quantity -= $item->quantity;
|
||||
$p->saveQuietly();
|
||||
|
||||
nlog($p->toArray());
|
||||
|
||||
|
||||
if($p->stock_notification_threshold && $p->in_stock_quantity <= $p->stock_notification_threshold)
|
||||
$this->notifyStockLevels($p, 'product');
|
||||
@ -98,16 +105,18 @@ class AdjustProductInventory implements ShouldQueue
|
||||
private function existingInventoryAdjustment()
|
||||
{
|
||||
|
||||
foreach($this->old_invoice['line_items'] as $item)
|
||||
foreach($this->old_invoice as $item)
|
||||
{
|
||||
$p = Product::where('product_key', $item->product_key)->where('company_id', $this->company->id)->where('in_stock_quantity', '>', 0)->first();
|
||||
$p = Product::where('product_key', $item->product_key)->where('company_id', $this->company->id)->first();
|
||||
|
||||
if(!$p)
|
||||
continue;
|
||||
|
||||
$p->in_stock_quantity += $item->quantity;
|
||||
$p->save();
|
||||
nlog("adding back " . $item->quantity);
|
||||
|
||||
$p->in_stock_quantity += $item->quantity;
|
||||
$p->saveQuietly();
|
||||
nlog($p->toArray());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ class SendRecurring implements ShouldQueue
|
||||
->applyNumber()
|
||||
//->createInvitations() //need to only link invitations to those in the recurring invoice
|
||||
->fillDefaults()
|
||||
->adjustInventory()
|
||||
->save();
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class InventoryNotificationObject
|
||||
|
||||
public function __construct(Product $product, string $notification_level)
|
||||
{
|
||||
$this->payment = $product;
|
||||
$this->product = $product;
|
||||
$this->company = $product->company;
|
||||
$this->settings = $this->company->settings;
|
||||
}
|
||||
|
@ -565,10 +565,11 @@ class InvoiceService
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function adjustInventory()
|
||||
public function adjustInventory($old_invoice = [])
|
||||
{
|
||||
|
||||
if($this->invoice->company->track_inventory)
|
||||
AdjustProductInventory::dispatch($this->invoice->company, $this->invoice, null)->delay(rand(1,2));
|
||||
AdjustProductInventory::dispatchNow($this->invoice->company, $this->invoice, $old_invoice);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ class ConvertQuote
|
||||
|
||||
$invoice->service()
|
||||
->fillDefaults()
|
||||
->adjustInventory()
|
||||
->save();
|
||||
|
||||
$quote->invoice_id = $invoice->id;
|
||||
|
111
tests/Feature/Inventory/InventoryManagementTest.php
Normal file
111
tests/Feature/Inventory/InventoryManagementTest.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?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://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
namespace Tests\Feature\Inventory;
|
||||
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
use App\Models\Product;
|
||||
use App\Models\Invoice;
|
||||
use App\DataMapper\InvoiceItem;
|
||||
use Illuminate\Support\Str;
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
class InventoryManagementTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
use MockAccountData;
|
||||
|
||||
public function setUp() :void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->makeTestData();
|
||||
|
||||
$this->withoutMiddleware(
|
||||
ThrottleRequests::class
|
||||
);
|
||||
}
|
||||
|
||||
public function testInventoryMovements()
|
||||
{
|
||||
|
||||
$product = Product::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
'in_stock_quantity' => 100,
|
||||
'stock_notification' => true,
|
||||
'stock_notification_threshold' => 99
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
'client_id' => $this->client->id
|
||||
]);
|
||||
|
||||
$invoice->company->track_inventory = true;
|
||||
$invoice->push();
|
||||
|
||||
|
||||
$invoice_item = new InvoiceItem;
|
||||
$invoice_item->type_id = 1;
|
||||
$invoice_item->product_key = $product->product_key;
|
||||
$invoice_item->notes = $product->notes;
|
||||
$invoice_item->quantity = 10;
|
||||
$invoice_item->cost = 100;
|
||||
|
||||
$line_items[] = $invoice_item;
|
||||
$invoice->line_items = $line_items;
|
||||
$invoice->number = Str::random(16);
|
||||
|
||||
$invoice->client_id = $this->client->hashed_id;
|
||||
|
||||
$invoice_array = $invoice->toArray();
|
||||
$invoice_array['client_id'] = $this->client->hashed_id;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/invoices/', $invoice_array)
|
||||
->assertStatus(200);
|
||||
|
||||
$product = $product->refresh();
|
||||
|
||||
$this->assertEquals(90, $product->in_stock_quantity);
|
||||
|
||||
|
||||
$arr = $response->json();
|
||||
$invoice_hashed_id = $arr['data']['id'];
|
||||
|
||||
$invoice_item = new InvoiceItem;
|
||||
$invoice_item->type_id = 1;
|
||||
$invoice_item->product_key = $product->product_key;
|
||||
$invoice_item->notes = $product->notes;
|
||||
$invoice_item->quantity = 5;
|
||||
$invoice_item->cost = 100;
|
||||
|
||||
$line_items2[] = $invoice_item;
|
||||
$invoice->line_items = $line_items2;
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->put('/api/v1/invoices/'.$invoice_hashed_id, $invoice->toArray())
|
||||
->assertStatus(200);
|
||||
|
||||
$product = $product->refresh();
|
||||
|
||||
$this->assertEquals(95, $product->in_stock_quantity);
|
||||
}
|
||||
}
|
@ -217,6 +217,7 @@ trait MockAccountData
|
||||
$settings->timezone_id = '1';
|
||||
$settings->entity_send_time = 0;
|
||||
|
||||
$this->company->track_inventory = true;
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user