Merge pull request #6310 from devansh-webkul/cancel-inventory-fix
This commit is contained in:
commit
2c7cf3a220
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Webkul\Product\Models\Product;
|
||||
use Webkul\Product\Models\ProductOrderedInventory;
|
||||
|
||||
class ProductOrderedInventoryFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = ProductOrderedInventory::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'qty' => $this->faker->numberBetween(100, 200),
|
||||
'product_id' => Product::factory(),
|
||||
'channel_id' => 1,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -2,15 +2,29 @@
|
|||
|
||||
namespace Webkul\Product\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Inventory\Models\InventorySourceProxy;
|
||||
use Webkul\Core\Models\ChannelProxy;
|
||||
use Webkul\Product\Contracts\ProductOrderedInventory as ProductOrderedInventoryContract;
|
||||
use Webkul\Product\Database\Factories\ProductOrderedInventoryFactory;
|
||||
|
||||
class ProductOrderedInventory extends Model implements ProductOrderedInventoryContract
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* Timestamps.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* Fillables.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'qty',
|
||||
'product_id',
|
||||
|
|
@ -19,6 +33,8 @@ class ProductOrderedInventory extends Model implements ProductOrderedInventoryCo
|
|||
|
||||
/**
|
||||
* Get the channel owns the inventory.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function channel()
|
||||
{
|
||||
|
|
@ -27,9 +43,21 @@ class ProductOrderedInventory extends Model implements ProductOrderedInventoryCo
|
|||
|
||||
/**
|
||||
* Get the product that owns the product inventory.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(ProductProxy::modelClass());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new factory instance for the model.
|
||||
*
|
||||
* @return Factory
|
||||
*/
|
||||
protected static function newFactory(): Factory
|
||||
{
|
||||
return ProductOrderedInventoryFactory::new ();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Webkul\Sales\Repositories;
|
||||
|
||||
use Illuminate\Container\Container as App;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
use Webkul\Sales\Contracts\OrderItem;
|
||||
|
|
@ -11,16 +9,18 @@ use Webkul\Sales\Contracts\OrderItem;
|
|||
class OrderItemRepository extends Repository
|
||||
{
|
||||
/**
|
||||
* Specify Model class name
|
||||
* Specify model class name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function model()
|
||||
public function model()
|
||||
{
|
||||
return OrderItem::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Webkul\Sales\Contracts\OrderItem
|
||||
*/
|
||||
|
|
@ -37,6 +37,8 @@ class OrderItemRepository extends Repository
|
|||
}
|
||||
|
||||
/**
|
||||
* Collect totals.
|
||||
*
|
||||
* @param \Webkul\Sales\Contracts\OrderItem $orderItem
|
||||
* @return \Webkul\Sales\Contracts\OrderItem
|
||||
*/
|
||||
|
|
@ -96,6 +98,8 @@ class OrderItemRepository extends Repository
|
|||
}
|
||||
|
||||
/**
|
||||
* Manage inventory.
|
||||
*
|
||||
* @param \Webkul\Sales\Contracts\OrderItem $orderItem
|
||||
* @return void
|
||||
*/
|
||||
|
|
@ -125,14 +129,14 @@ class OrderItemRepository extends Repository
|
|||
if (isset($item->qty_ordered)) {
|
||||
$qty = $item->qty_ordered;
|
||||
} else {
|
||||
Log::info('OrderItem has no qty_ordered', ['orderItem' => $item, 'product' => $item->product]);
|
||||
Log::info('OrderItem has no `qty_ordered`.', ['orderItem' => $item, 'product' => $item->product]);
|
||||
if (isset($item->parent->qty_ordered)) {
|
||||
$qty = $item->parent->qty_ordered;
|
||||
} else {
|
||||
Log::info('OrderItem has no parent with qty_ordered', [
|
||||
Log::info('OrderItem has no parent with `qty_ordered`', [
|
||||
'orderItem' => $item,
|
||||
'parent' => $item->parent,
|
||||
'product' => $item->product
|
||||
'parent' => $item->parent,
|
||||
'product' => $item->product,
|
||||
]);
|
||||
$qty = 1;
|
||||
}
|
||||
|
|
@ -154,26 +158,14 @@ class OrderItemRepository extends Repository
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns qty to product inventory after order cancelation
|
||||
* Returns qty to product inventory after order cancellation.
|
||||
*
|
||||
* @param \Webkul\Sales\Contracts\OrderItem $orderItem
|
||||
* @return void
|
||||
*/
|
||||
public function returnQtyToProductInventory($orderItem)
|
||||
{
|
||||
$orderedInventory = $orderItem->product->ordered_inventories()
|
||||
->where('channel_id', $orderItem->order->channel->id)
|
||||
->first();
|
||||
|
||||
if (! $orderedInventory) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (($qty = $orderedInventory->qty - ($orderItem->qty_ordered ? $orderItem->qty_to_cancel : $orderItem->parent->qty_ordered)) < 0) {
|
||||
$qty = 0;
|
||||
}
|
||||
|
||||
$orderedInventory->update(['qty' => $qty]);
|
||||
$this->updateProductOrderedInventories($orderItem);
|
||||
|
||||
if ($orderItem->getTypeInstance()->isStockable()) {
|
||||
$shipmentItems = $orderItem->parent ? $orderItem->parent->shipment_items : $orderItem->shipment_items;
|
||||
|
|
@ -182,20 +174,55 @@ class OrderItemRepository extends Repository
|
|||
foreach ($shipmentItems as $shipmentItem) {
|
||||
if ($orderItem->parent) {
|
||||
$shippedQty = $orderItem->qty_ordered
|
||||
? ($orderItem->qty_ordered / $orderItem->parent->qty_ordered) * $shipmentItem->qty
|
||||
: $orderItem->parent->qty_ordered;
|
||||
? ($orderItem->qty_ordered / $orderItem->parent->qty_ordered) * $shipmentItem->qty
|
||||
: $orderItem->parent->qty_ordered;
|
||||
} else {
|
||||
$shippedQty = $shipmentItem->qty;
|
||||
}
|
||||
|
||||
|
||||
$inventory = $orderItem->product->inventories()
|
||||
// ->where('vendor_id', $data['vendor_id'])
|
||||
->where('inventory_source_id', $shipmentItem->shipment->inventory_source_id)
|
||||
->first();
|
||||
|
||||
$inventory->update(['qty' => $inventory->qty + $shippedQty]);
|
||||
->where('inventory_source_id', $shipmentItem->shipment->inventory_source_id)
|
||||
->first();
|
||||
|
||||
$inventory->update(['qty' => $inventory->qty + $shippedQty]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update product ordered quantity.
|
||||
*
|
||||
* @param \Webkul\Sales\Contracts\OrderItem $orderItem
|
||||
* @return void
|
||||
*/
|
||||
public function updateProductOrderedInventories($orderItem)
|
||||
{
|
||||
$orderedInventory = $orderItem->product->ordered_inventories()
|
||||
->where('channel_id', $orderItem->order->channel->id)
|
||||
->first();
|
||||
|
||||
if (! $orderedInventory) {
|
||||
return;
|
||||
}
|
||||
|
||||
$qty = (
|
||||
$orderedInventory->qty +
|
||||
(
|
||||
isset($orderItem->qty_shipped)
|
||||
? $orderItem->qty_shipped
|
||||
: $orderItem->parent->qty_shipped
|
||||
)
|
||||
) - (
|
||||
isset($orderItem->qty_ordered)
|
||||
? $orderItem->qty_ordered
|
||||
: $orderItem->parent->qty_ordered
|
||||
);
|
||||
|
||||
if ($qty < 0) {
|
||||
$qty = 0;
|
||||
}
|
||||
|
||||
$orderedInventory->update(['qty' => $qty]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Sales\Order;
|
||||
|
||||
use Helper\Bagisto;
|
||||
use UnitTester;
|
||||
use Webkul\Product\Models\ProductOrderedInventory;
|
||||
use Webkul\Sales\Models\OrderItem;
|
||||
use Webkul\Sales\Repositories\OrderItemRepository;
|
||||
|
||||
class OrderItemRepositoryCest
|
||||
{
|
||||
/**
|
||||
* Order item repository.
|
||||
*
|
||||
* @var Webkul\Sales\Repositories\OrderItemRepository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
public function _before()
|
||||
{
|
||||
$reflection = new \ReflectionClass(OrderItemRepository::class);
|
||||
|
||||
$property = $reflection->getProperty('model');
|
||||
$property->setAccessible(true);
|
||||
|
||||
$this->repository = $reflection->newInstanceWithoutConstructor();
|
||||
}
|
||||
|
||||
public function testUpdateProductOrderedInventories(UnitTester $I)
|
||||
{
|
||||
/**
|
||||
* Having 10 quantity in inventory.
|
||||
*/
|
||||
$product = $I->haveProduct(Bagisto::SIMPLE_PRODUCT, [
|
||||
'productInventory' => ['qty' => 10],
|
||||
]);
|
||||
|
||||
/**
|
||||
* 2 quantities are on hold.
|
||||
*/
|
||||
$productOrderedInventory = $I->have(ProductOrderedInventory::class, [
|
||||
'product_id' => $product->id,
|
||||
'qty' => 2,
|
||||
]);
|
||||
|
||||
/**
|
||||
* 5 quantities are shipped.
|
||||
*/
|
||||
$orderItem1 = $I->have(OrderItem::class, [
|
||||
'product_id' => $product->id,
|
||||
'qty_ordered' => 5,
|
||||
'qty_shipped' => 5,
|
||||
]);
|
||||
|
||||
/**
|
||||
* 2 quantities are in queue.
|
||||
*/
|
||||
$orderItem2 = $I->have(OrderItem::class, [
|
||||
'product_id' => $product->id,
|
||||
'qty_ordered' => 2,
|
||||
'qty_shipped' => 0,
|
||||
]);
|
||||
|
||||
/**
|
||||
* Now testing the repository method with shipped one cancelled.
|
||||
*/
|
||||
$this->repository->updateProductOrderedInventories($orderItem1);
|
||||
$productOrderedInventory->refresh();
|
||||
$I->assertNotEquals(0, $productOrderedInventory->qty);
|
||||
$I->assertEquals(2, $productOrderedInventory->qty);
|
||||
|
||||
/**
|
||||
* Now testing the repository method with pending one cancelled.
|
||||
*/
|
||||
$this->repository->updateProductOrderedInventories($orderItem2);
|
||||
$productOrderedInventory->refresh();
|
||||
$I->assertEquals(0, $productOrderedInventory->qty);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue