NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Coupons for Laravel

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štruktorVý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 history

Obnovenie 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 collection

Seedery 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 kryptomien

Odoslaní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.