baks-dev/products-promotion
Модуль акций на продукцию для PHP 8.4+/Laravel/Symfony: установка через Composer, команда baks:assets:install для ресурсов, миграции Doctrine для обновления БД, тесты PHPUnit (group=products-promotion).
Install the Package
composer require baks-dev/products-promotion
php artisan vendor:publish --provider="BaksDev\ProductsPromotion\ProductsPromotionServiceProvider" --tag="config"
php artisan migrate
promotions and promotion_rules tables exist in your database.Configure Basic Promotion
Edit config/promotions.php to set default values (e.g., currency, validation rules).
Example:
'default_currency' => 'USD',
'validation' => [
'min_quantity' => 1,
'max_quantity' => null,
],
Create a Simple Promotion Use the package’s facade or service to define a promotion:
use BaksDev\ProductsPromotion\Facades\Promotion;
// Create a 10% discount promotion
$promotion = Promotion::create([
'name' => 'Summer Sale',
'type' => 'percentage', // or 'fixed', 'bundle'
'value' => 10,
'start_date' => now()->addDays(1),
'end_date' => now()->addDays(7),
]);
// Add a rule (e.g., apply to product ID 123)
$promotion->addRule([
'type' => 'product',
'value' => 123,
]);
Apply Promotion to a Cart Integrate with your cart logic:
use BaksDev\ProductsPromotion\Services\PromotionApplier;
$applier = app(PromotionApplier::class);
$cart = $applier->applyPromotionsToCart($userCart);
Test in Development Run the provided test group:
php artisan test --group=products-promotion
// Load promotions from a YAML file (if supported)
$promotions = Promotion::loadFromYaml('promotions/summer.yml');
php artisan promotion:create --name="BlackFriday" --type="percentage" --value=20
Cart::itemAdded or Cart::updated to auto-apply promotions.
use BaksDev\ProductsPromotion\Events\PromotionApplied;
event(new PromotionApplied($promotion, $cart));
$order = $applier->applyPromotions($cart, $user);
// Example: Create a rule for users with loyalty points > 100
$promotion->addRule([
'type' => 'user_segment',
'value' => 'loyalty_points_gt_100',
]);
$promotion->addRule(['type' => 'product', 'value' => 123]);
$promotion->addRule(['type' => 'user', 'value' => 'premium']);
Route::get('/api/promotions', [PromotionController::class, 'index']);
@promotionBanner($promotion)
public function testPromotionAppliesToCart()
{
$cart = new Cart();
$cart->addItem(123, 2);
$this->assertEquals(80, $applier->applyPromotions($cart)->total);
}
Service Provider Binding
Override or extend the package’s service bindings in your AppServiceProvider:
public function register()
{
$this->app->bind(
PromotionApplier::class,
function ($app) {
return new CustomPromotionApplier(
$app->make(PromotionRepository::class)
);
}
);
}
Middleware for Promotion Checks Protect promotion-heavy routes:
Route::middleware(['promotion.eligible'])->group(function () {
Route::get('/sale', [SaleController::class, 'index']);
});
Event Listeners React to promotion events (e.g., log applied promotions, send notifications):
public function handle(PromotionApplied $event)
{
Log::info("Promotion applied: {$event->promotion->name}");
}
Command Bus for Complex Workflows Use Laravel’s command bus to handle promotion workflows (e.g., bulk creation):
$bus->dispatch(new CreatePromotionCommand($promotionData));
$rules = Cache::remember("promotion_rules_{$promotion->id}", now()->addHours(1), function () use ($promotion) {
return $promotion->rules()->get();
});
promotion_code, start_date, and end_date are indexed.Custom Promotion Types
Extend the base Promotion model or create a new type:
class TieredPromotion extends Promotion
{
protected $type = 'tiered';
public function calculateDiscount($quantity)
{
// Custom logic for tiered discounts
}
}
Third-Party Integrations
PaymentProcessed events to apply discounts.PromotionApplied events.Admin Panel Build a Laravel Nova or Filament resource for managing promotions:
Nova::resources([
\BaksDev\ProductsPromotion\Nova\Promotion::class,
]);
Migration Conflicts
database/migrations/) before running php artisan migrate. Use --pretend to dry-run:
php artisan migrate --pretend
Promotion Rule Conflicts
$applier->applyPromotions($cart, $user, ['priority' => 'high']);
Timezone Handling
start_date/end_date may not work correctly if timezones are misconfigured.$promotion->start_date->setTimezone($user->timezone);
Caching Stale Data
Cache::forget("promotion_rules_{$promotion->id}");
Dependency Version Locks
composer.json:
"require": {
"doctrine/dbal": "3.6.2",
"doctrine/orm": "2.14.3"
}
Missing Documentation
How can I help you explore Laravel packages today?