From 5ed1d7a77a9f53ff237d75cd948174d796561c85 Mon Sep 17 00:00:00 2001 From: smarcet Date: Fri, 14 Aug 2026 15:54:08 -0300 Subject: [PATCH] fix(promo-codes): persist quantity_available for generic SUMMIT_PROMO_CODE class SummitPromoCodeFactory::populate() applied quantity_available for every promo code class except the generic SummitRegistrationPromoCode, so the field was silently dropped on create and update. Codes meant to be limited (one-off, N uses) ended up stored with 0, which the platform treats as unlimited use. Adds the missing case to the per-class switch and a regression test. --- .../Factories/SummitPromoCodeFactory.php | 5 ++++ .../Services/SummitPromoCodeFactoryTest.php | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/app/Models/Foundation/Summit/Factories/SummitPromoCodeFactory.php b/app/Models/Foundation/Summit/Factories/SummitPromoCodeFactory.php index 8753b49a4..5ede8a15e 100644 --- a/app/Models/Foundation/Summit/Factories/SummitPromoCodeFactory.php +++ b/app/Models/Foundation/Summit/Factories/SummitPromoCodeFactory.php @@ -190,6 +190,11 @@ public static function populate(SummitRegistrationPromoCode $promo_code, Summit $promo_code->setAllowsToReassign(boolval($data['allows_to_reassign'])); switch ($data['class_name']){ + case SummitRegistrationPromoCode::ClassName:{ + if(isset($data['quantity_available'])) + $promo_code->setQuantityAvailable(intval($data['quantity_available'])); + } + break; case SummitRegistrationDiscountCode::ClassName: case PrePaidSummitRegistrationDiscountCode::ClassName:{ if(isset($data['amount'])) diff --git a/tests/Unit/Services/SummitPromoCodeFactoryTest.php b/tests/Unit/Services/SummitPromoCodeFactoryTest.php index df95b2625..63620aae6 100644 --- a/tests/Unit/Services/SummitPromoCodeFactoryTest.php +++ b/tests/Unit/Services/SummitPromoCodeFactoryTest.php @@ -14,6 +14,7 @@ use App\Models\Foundation\Summit\Factories\SummitPromoCodeFactory; use models\summit\Summit; +use models\summit\SummitRegistrationPromoCode; use models\summit\SummitRegistrationDiscountCode; use models\summit\SummitRegistrationDiscountCodeTicketTypeRule; use models\summit\SummitTicketType; @@ -93,4 +94,27 @@ public function testPopulateAppliesAmountAndRateWhenNoTicketTypesRulesInPayload( $this->assertEquals(25.0, $code->getRate(), 'flat rate must be applied when the payload carries no ticket_types_rules'); } + + /** + * Regression: populate()'s per-class switch had no case for the generic + * SUMMIT_PROMO_CODE class, so quantity_available was silently dropped on + * create and update - codes meant to be limited (one-off, N uses) ended up + * with 0 (= unlimited) in the DB. + */ + public function testPopulatePersistsQuantityAvailableForGenericSummitPromoCode(): void + { + $summit = $this->createMock(Summit::class); + + $code = new SummitRegistrationPromoCode(); + + $data = [ + 'class_name' => SummitRegistrationPromoCode::ClassName, + 'quantity_available' => 24, + ]; + + SummitPromoCodeFactory::populate($code, $summit, $data); + + $this->assertEquals(24, $code->getQuantityAvailable(), + 'quantity_available must be persisted for the generic SUMMIT_PROMO_CODE class'); + } }