Vytváranie kupónov
Kupóny vytvárate cez fasádu — Coupons::create() s DTO CreateCouponData alebo skratkou Coupons::generate(). Obe spúšťajú CreateCouponAction. Ak kód nezadáte, vygeneruje sa unikátny, a spustí sa udalosť CouponCreated.
Pomenované konštruktory
Pomenované konštruktory za vás zvolia jednotku aj uzamknutie meny:
use RoundlyConsulting\Coupons\DataTransferObjects\CreateCouponData;
use RoundlyConsulting\Coupons\Facades\Coupons;
use RoundlyConsulting\Money\Money;
// 5.00 EUR off, first 500 uses, basket must reach 20.00 EUR
Coupons::create(CreateCouponData::fixed(
Money::ofMinor(500, 'EUR'), code: 'FIVE', maxUsage: 500, minimumSpend: Money::ofMinor(2000, 'EUR'),
));
// 12.5 % off, capped at 50.00 EUR (locks the coupon to EUR)
Coupons::create(CreateCouponData::percentage('12.5', code: 'SPRING', maxDiscount: Money::ofMinor(5000, 'EUR')));
// Free shipping over 40.00 EUR
Coupons::create(CreateCouponData::freeShipping('SHIPFREE', minimumSpend: Money::ofMinor(4000, 'EUR')));| Konštruktor | Výsledok |
|---|---|
CreateCouponData::fixed(Money $amount, ?string $code = null, int $maxUsage = 0, ?Money $minimumSpend = null) | Pevná zľava: value = najmenšie jednotky sumy, uzamknutá na jej menu. Nad rozsah int64 vyhodí AmountOverflow z money. |
CreateCouponData::percentage(Percentage|int|string $percent, ?string $code = null, ?Money $maxDiscount = null, int $maxUsage = 0, ?Money $minimumSpend = null) | Percentuálna zľava z 25, '12.5' alebo Percentage, uložená v celých bázických bodoch — '12.345' vyhodí RoundingNecessary z money. Ak zadáte strop alebo minimum, uzamkne sa na menu stropu, inak minima. |
CreateCouponData::freeShipping(?string $code = null, int $maxUsage = 0, ?Money $minimumSpend = null) | Doprava zadarmo; pri zadanom minime sa uzamkne na jeho menu. |
Celé DTO
Pre plnú kontrolu zostavte CreateCouponData sami a odovzdajte ho Coupons::create():
use RoundlyConsulting\Coupons\DataTransferObjects\CreateCouponData;
use RoundlyConsulting\Coupons\Enums\DiscountType;
use RoundlyConsulting\Coupons\Facades\Coupons;
use RoundlyConsulting\Money\Currency;
use RoundlyConsulting\Money\Money;
$coupon = Coupons::create(new CreateCouponData(
type: DiscountType::Percentage,
value: 2000, // basis points: 20 % off
currency: Currency::of('EUR'), // optional lock (required for Fixed / min spend / cap)
code: 'SAVE20', // optional — auto-generated when omitted
maxUsage: 100, // optional — 0 means unlimited
minimumSpend: Money::ofMinor(5000, 'EUR'),
maxDiscount: Money::ofMinor(1000, 'EUR'),
));lockedCurrency() vráti menu, na ktorú sa kupón uzamkne: explicitne zadanú menu, inak menu minima, inak menu stropu, inak null.
Validácia
- Prázdny explicitný kód ('' alebo len medzery) — InvalidCouponDefinition.
- Kupón Fixed bez meny — InvalidCouponDefinition.
- Záporná pevná hodnota — InvalidCouponDefinition.
- Percento mimo 0..10 000 bázických bodov — InvalidCouponDefinition.
- Percento jemnejšie ako celé bázické body, napr. CreateCouponData::percentage('12.345') — RoundingNecessary z money.
- Minimum alebo strop v inej mene, než na ktorú je kupón uzamknutý — CurrencyMismatch z money.
- CreateCouponData::fixed() so sumou nad rozsah int64 najmenších jednotiek — AmountOverflow z money (value je stĺpec bigint).
- Explicitný kód, ktorý už má nezmazaný kupón, v akejkoľvek veľkosti písmen — CouponCodeTaken.
- Kód, ktorý sa má vygenerovať, no nedá sa — InvalidCouponConfiguration (pozrite si Generované kódy).
Unikátne kódy a ich opätovné použitie
Každý kód sa ukladá orezaný a veľkými písmenami a je unikátny medzi kupónmi, ktoré nie sú soft-deleted. Explicitný kód, ktorý už má nezmazaný kupón, v akejkoľvek veľkosti písmen, vyhodí CouponCodeTaken, čo je CouponException — aj keď ho súbežná požiadavka obsadí medzi kontrolou a zápisom. Kód, ktorý majú len soft-deleted kupóny, je voľný: keď Coupons::prune() zmaže minuloročný XMAS, ďalšie generate(code: 'XMAS') vytvorí nový kupón a starý riadok si ponechá svoj kód aj históriu uplatnení:
use RoundlyConsulting\Coupons\Enums\DiscountType;
use RoundlyConsulting\Coupons\Exceptions\CouponCodeTaken;
use RoundlyConsulting\Coupons\Facades\Coupons;
Coupons::generate(DiscountType::Percentage, 1000, code: 'SUMMER');
try {
Coupons::generate(DiscountType::Percentage, 1000, code: ' summer ');
} catch (CouponCodeTaken $e) {
$e->getMessage(); // "Coupon code [SUMMER] is already taken."
}
// After Coupons::prune() soft-deletes last season's XMAS, its code is free again:
Coupons::generate(DiscountType::Percentage, 1000, code: 'XMAS'); // a fresh coupon; the old row keeps its historyObnovenie zmazaného kupónu, ktorého kód medzitým získal nezmazaný kupón, zlyhá na chybe unikátneho obmedzenia databázy. Unikátnosť vynucuje databáza — unikátny index nad generovaným stĺpcom, ktorý drží kód len dovtedy, kým riadok nie je zmazaný —, a preto vyžaduje MySQL/MariaDB, PostgreSQL alebo SQLite.
Aktivácia, platnosť a limity
CreateCouponData nesie typ, hodnotu, menu, kód, celkový limit, minimum a strop zľavy. Aktiváciu, koniec platnosti, limit na zákazníka a voľné meta nastavíte na modeli dodatočne. Fluentné metódy neukladajú — zavolajte save():
$coupon->activate()->save(); // redeemable from now
$coupon->activate(now()->addDay())->expire(now()->addMonth())->save(); // a scheduled window
$coupon->setMaxUsageTo(1000)->save(); // global cap (0 = unlimited)
$coupon->update(['max_usage_per_redeemer' => 1]); // one per customer
$coupon->update(['meta' => ['campaign' => 'spring']]); // free-form, cast to a collectionSeedery a fixtures
createQuietly() — alebo execute($data, quiet: true) na akcii — uloží kupón bez udalosti CouponCreated:
use RoundlyConsulting\Coupons\Actions\CreateCouponAction;
use RoundlyConsulting\Coupons\DataTransferObjects\CreateCouponData;
use RoundlyConsulting\Coupons\Facades\Coupons;
// Seeders: no CouponCreated event
Coupons::createQuietly(CreateCouponData::percentage(10, 'SEED10'));
// The same through the action
app(CreateCouponAction::class)->execute($data, quiet: true);Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.