refactor(stock): implement expiration for stock reservations and add configuration
This commit is contained in:
@@ -8,6 +8,7 @@ PURCHASE_CHECKOUT_EXPIRATION_MINUTES=30
|
|||||||
PURCHASE_QR_EXPIRATION_MINUTES=15
|
PURCHASE_QR_EXPIRATION_MINUTES=15
|
||||||
PURCHASE_TELEPAGOS_EXPIRATION_MINUTES=30
|
PURCHASE_TELEPAGOS_EXPIRATION_MINUTES=30
|
||||||
PURCHASE_TRANSFER_EXPIRATION_MINUTES=1440
|
PURCHASE_TRANSFER_EXPIRATION_MINUTES=1440
|
||||||
|
STOCK_RESERVATION_EXPIRATION_MINUTES=30
|
||||||
FRONTEND_URLS=http://localhost:4200
|
FRONTEND_URLS=http://localhost:4200
|
||||||
|
|
||||||
APP_LOCALE=es
|
APP_LOCALE=es
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use App\Domains\Catalog\Models\CatalogItem;
|
|||||||
use App\Domains\Catalog\Models\StockReservation;
|
use App\Domains\Catalog\Models\StockReservation;
|
||||||
use App\Domains\Catalog\Models\Variant;
|
use App\Domains\Catalog\Models\Variant;
|
||||||
use App\Domains\Purchase\Models\Purchase;
|
use App\Domains\Purchase\Models\Purchase;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class StockReservationService
|
class StockReservationService
|
||||||
@@ -71,6 +72,7 @@ class StockReservationService
|
|||||||
'cart_item_id' => $cartItem->getKey(),
|
'cart_item_id' => $cartItem->getKey(),
|
||||||
'quantity' => $quantity,
|
'quantity' => $quantity,
|
||||||
'status' => StockReservation::STATUS_ACTIVE,
|
'status' => StockReservation::STATUS_ACTIVE,
|
||||||
|
'expires_at' => $this->expiration(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@@ -82,6 +84,7 @@ class StockReservationService
|
|||||||
'status' => StockReservation::STATUS_ACTIVE,
|
'status' => StockReservation::STATUS_ACTIVE,
|
||||||
'committed_at' => null,
|
'committed_at' => null,
|
||||||
'released_at' => null,
|
'released_at' => null,
|
||||||
|
'expires_at' => $this->expiration(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,7 +114,7 @@ class StockReservationService
|
|||||||
->where('status', StockReservation::STATUS_ACTIVE)
|
->where('status', StockReservation::STATUS_ACTIVE)
|
||||||
->update([
|
->update([
|
||||||
'purchase_id' => null,
|
'purchase_id' => null,
|
||||||
'expires_at' => null,
|
'expires_at' => $this->expiration(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +147,7 @@ class StockReservationService
|
|||||||
'cart_item_id' => $target->getKey(),
|
'cart_item_id' => $target->getKey(),
|
||||||
'purchase_id' => null,
|
'purchase_id' => null,
|
||||||
'quantity' => $perItemQuantity * $targetItemQuantity,
|
'quantity' => $perItemQuantity * $targetItemQuantity,
|
||||||
'expires_at' => null,
|
'expires_at' => $this->expiration(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@@ -153,6 +156,7 @@ class StockReservationService
|
|||||||
$targetReservation->update([
|
$targetReservation->update([
|
||||||
'quantity' => $targetReservation->quantity + $sourceReservation->quantity,
|
'quantity' => $targetReservation->quantity + $sourceReservation->quantity,
|
||||||
'status' => StockReservation::STATUS_ACTIVE,
|
'status' => StockReservation::STATUS_ACTIVE,
|
||||||
|
'expires_at' => $this->expiration(),
|
||||||
]);
|
]);
|
||||||
$sourceReservation->delete();
|
$sourceReservation->delete();
|
||||||
}
|
}
|
||||||
@@ -170,6 +174,7 @@ class StockReservationService
|
|||||||
'cart_item_id' => $cartItem->getKey(),
|
'cart_item_id' => $cartItem->getKey(),
|
||||||
'quantity' => $requiredQuantity,
|
'quantity' => $requiredQuantity,
|
||||||
'status' => StockReservation::STATUS_ACTIVE,
|
'status' => StockReservation::STATUS_ACTIVE,
|
||||||
|
'expires_at' => $this->expiration(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@@ -180,6 +185,7 @@ class StockReservationService
|
|||||||
'status' => StockReservation::STATUS_ACTIVE,
|
'status' => StockReservation::STATUS_ACTIVE,
|
||||||
'committed_at' => null,
|
'committed_at' => null,
|
||||||
'released_at' => null,
|
'released_at' => null,
|
||||||
|
'expires_at' => $this->expiration(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,4 +220,11 @@ class StockReservationService
|
|||||||
->lockForUpdate()
|
->lockForUpdate()
|
||||||
->first();
|
->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function expiration(): Carbon
|
||||||
|
{
|
||||||
|
return now()->addMinutes(
|
||||||
|
max(1, (int) config('catalog.stock_reservation_expiration_minutes', 30)),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
config/catalog.php
Normal file
5
config/catalog.php
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'stock_reservation_expiration_minutes' => (int) env('STOCK_RESERVATION_EXPIRATION_MINUTES', 30),
|
||||||
|
];
|
||||||
@@ -80,6 +80,30 @@ class CartControllerTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_it_sets_the_configured_expiration_when_creating_a_stock_reservation(): void
|
||||||
|
{
|
||||||
|
config()->set('catalog.stock_reservation_expiration_minutes', 45);
|
||||||
|
$now = now()->startOfSecond();
|
||||||
|
$this->travelTo($now);
|
||||||
|
|
||||||
|
$tenant = $this->createTenant('acme');
|
||||||
|
$item = $this->createDirectItem($tenant, 10, '49.90');
|
||||||
|
|
||||||
|
$this->postJson('/api/tenants/acme/cart/items', [
|
||||||
|
'catalog_item_id' => $item->id,
|
||||||
|
'cantidad' => 2,
|
||||||
|
])->assertOk();
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('stock_reservations', [
|
||||||
|
'inventory_id' => $item->inventory_id,
|
||||||
|
'quantity' => 2,
|
||||||
|
'status' => 'active',
|
||||||
|
'expires_at' => $now->copy()->addMinutes(45)->toDateTimeString(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->travelBack();
|
||||||
|
}
|
||||||
|
|
||||||
public function test_it_filters_item_images_when_the_tenant_disables_them(): void
|
public function test_it_filters_item_images_when_the_tenant_disables_them(): void
|
||||||
{
|
{
|
||||||
$tenant = $this->createTenant('acme');
|
$tenant = $this->createTenant('acme');
|
||||||
|
|||||||
Reference in New Issue
Block a user