baks-dev/products-stocks
Модуль складского учета продукции для PHP 8.4+. Установка через Composer, установка конфигурации и ресурсов командой baks:assets:install, миграции Doctrine для обновления схемы БД, тесты PHPUnit (group=products-stocks).
Installation:
composer require baks-dev/products-stocks
php artisan baks:assets:install # Installs config, views, and assets
php artisan doctrine:migrations:diff # Review schema changes
php artisan doctrine:migrations:migrate # Apply migrations
First Use Case:
use BaksDev\ProductsStocks\Services\StockService;
$stockService = app(StockService::class);
$stock = $stockService->getStockByProductAndWarehouse(
productId: 1,
warehouseId: 1
);
$stockService->adjustStock(
productId: 1,
quantity: -5, // Negative for deductions
warehouseId: 1,
reason: 'Order #12345'
);
Where to Look First:
config/baks-products-stocks.php (override defaults).app/Models/BaksDev/ProductsStocks/ (extend if needed).app/Services/BaksDev/ProductsStocks/ (business logic).database/migrations/ (check for custom tables).$stockService->createStock(
productId: $product->id,
warehouseId: $warehouse->id,
quantity: 100,
attributes: ['batch' => 'BATCH-2023']
);
$stockService->transferStock(
productId: 1,
fromWarehouseId: 1,
toWarehouseId: 2,
quantity: 20,
reference: 'TRANSFER-001'
);
// Example: Low stock alert
event(new \BaksDev\ProductsStocks\Events\StockLow(
productId: 1,
currentStock: 5,
threshold: 10
));
class CustomStockEvent extends Event
{
public function __construct(public int $productId, public string $action) {}
}
$warehouseRepo = app(\BaksDev\ProductsStocks\Repositories\WarehouseRepository::class);
$warehouses = $warehouseRepo->getAllWithStock();
// routes/api.php
Route::get('/stock/{product}', [StockController::class, 'show']);
public function show(StockService $stockService, $productId)
{
return new StockResource($stockService->getStockByProduct($productId));
}
StockService for CRUD operations (e.g., after order fulfillment).stock_movements table for historical tracking:
$movements = \BaksDev\ProductsStocks\Models\StockMovement::where('product_id', 1)
->orderBy('created_at', 'desc')
->take(10)
->get();
// app/Console/Commands/CheckStock.php
public function handle()
{
$lowStock = $stockService->getLowStockProducts(threshold: 10);
// Send notifications...
}
$stockService->adjustStock(
productId: $orderItem->product_id,
quantity: -$orderItem->quantity,
warehouseId: $warehouseId,
reason: 'Order #' . $order->id
);
$stockService->adjustStock(
productId: $product->id,
quantity: $delivery->quantity,
warehouseId: $warehouse->id,
reason: 'Supplier Delivery #' . $delivery->id
);
php artisan test --group=products-stocks
public function testStockAdjustment()
{
$this->actingAs($adminUser);
$initialStock = $stockService->getStockByProductAndWarehouse(1, 1);
$stockService->adjustStock(1, -5, 1, 'Test');
$this->assertEquals($initialStock - 5, $stockService->getStockByProductAndWarehouse(1, 1));
}
Product or Warehouse:
// app/Models/Product.php
use BaksDev\ProductsStocks\Models\Product as BaseProduct;
class Product extends BaseProduct
{
protected $casts = [
'is_perishable' => 'boolean',
'expiry_days' => 'integer',
];
}
// app/Providers/AppServiceProvider.php
use BaksDev\ProductsStocks\Services\StockService;
public function boot(StockService $stockService)
{
$stockService->setValidator(function ($productId, $quantity, $warehouseId) {
$currentStock = $stockService->getStockByProductAndWarehouse($productId, $warehouseId);
if ($currentStock + $quantity < 0) {
throw new \Exception("Insufficient stock for product {$productId}");
}
});
}
$warehouseStock = $stockService->getStockByProductAndWarehouse(
productId: 1,
warehouseId: $warehouseId
);
$stock = Cache::remember(
"stock_{$productId}_{$warehouseId}",
now()->addHours(1),
fn() => $stockService->getStockByProductAndWarehouse($productId, $warehouseId)
);
// resources/lang/en/stock.php
return [
'low_stock_alert' => 'Product {product} is running low (only {stock} left)!',
];
php artisan doctrine:migrations:diff --dry-run
// config/database.php
'default' => 'doctrine',
'connections' => [
'doctrine' => [
'driver' => 'doctrine',
'host' => env('DB_HOST', '127.0.0.1'),
// ...
],
],
\BaksDev\ProductsStocks\Models\StockMovement::created(function ($movement) {
// Trigger custom logic (e.g., notifications)
});
baks:assets:install may conflict with existing commands.php artisan baks:assets:install --name=custom-install
FROM php:8.4-cli
How can I help you explore Laravel packages today?