TicketType Serializer update/ Promo code refactoring

* Missing default badge type
* Force to set default badge type automatically
* Remove Badge type Override using Promo code

Change-Id: I1b8f965bbb4309421b0d311968618a5b1565d491
Signed-off-by: smarcet <smarcet@gmail.com>
This commit is contained in:
smarcet 2021-07-16 10:16:36 -03:00
parent 0409f6fd0f
commit 81433f99fe
14 changed files with 71 additions and 137 deletions

View File

@ -52,7 +52,6 @@ final class PromoCodesValidationRulesFactory
'quantity_available' => 'sometimes|integer|min:0',
'valid_since_date' => 'nullable|date_format:U',
'valid_until_date' => 'nullable|required_with:valid_since_date|date_format:U|after:valid_since_date',
'badge_type_id' => 'nullable|integer',
'allowed_ticket_types' => 'sometimes|int_array',
'badge_features' => 'sometimes|int_array',
];

View File

@ -29,7 +29,7 @@ abstract class PromoCodeEmail extends AbstractEmailJob
public function __construct(SummitRegistrationPromoCode $promo_code){
if(!$promo_code instanceof IOwnablePromoCode)
throw new \InvalidArgumentException('promo code is not ownable.');
throw new \InvalidArgumentException('promo code is not ownerable.');
$summit = $promo_code->getSummit();
$payload = [];

View File

@ -25,7 +25,6 @@ class SummitRegistrationPromoCodeSerializer extends SilverStripeSerializer
'Source' => 'source:json_string',
'SummitId' => 'summit_id:json_int',
'CreatorId' => 'creator_id:json_int',
'BadgeTypeId' => 'badge_type_id:json_int',
'QuantityAvailable' => 'quantity_available:json_int',
'QuantityUsed' => 'quantity_used:json_int',
'ValidSinceDate' => 'valid_since_date:datetime_epoch',
@ -105,17 +104,7 @@ class SummitRegistrationPromoCodeSerializer extends SilverStripeSerializer
}
$values['allowed_ticket_types'] = $ticket_types;
}
break;
case 'badge_type': {
if($code->hasBadgeType()){
unset($values['badge_type_id']);
$values['badge_type'] = SerializerRegistry::getInstance()->getSerializer
(
$code->getBadgeType()
)->serialize($expand);
}
}
break;
break;
}
}
}

View File

@ -33,7 +33,12 @@ class SummitAdministratorPermissionGroup extends SilverstripeBaseModel
*/
private $title;
const ValidGroups = [IGroup::SummitAdministrators, IGroup::TrackChairsAdmins];
const ValidGroups = [
IGroup::SummitAdministrators,
IGroup::TrackChairsAdmins,
IGroup::TrackChairs,
IGroup::BadgePrinters,
];
public function __construct()
{
@ -79,11 +84,10 @@ class SummitAdministratorPermissionGroup extends SilverstripeBaseModel
}
public function canAddMember(Member $member):bool{
return
$member->isOnGroup(IGroup::SummitAdministrators, true) ||
$member->isOnGroup(IGroup::TrackChairs, true) ||
$member->isOnGroup(IGroup::TrackChairsAdmins, true) ||
$member->isOnGroup(IGroup::BadgePrinters, true);
foreach (self::ValidGroups as $slug){
if($member->isOnGroup($slug, true)) return true;
}
return false;
}
/**

View File

@ -84,9 +84,6 @@ final class SummitPromoCodeFactory
// common members
if(isset($params['badge_type']))
$promo_code->setBadgeType($params['badge_type']);
if(isset($params['allowed_ticket_types'])){
foreach ($params['allowed_ticket_types'] as $ticket_type){
$promo_code->addAllowedTicketType($ticket_type);

View File

@ -229,7 +229,6 @@ class SummitAttendeeBadge extends SilverstripeBaseModel implements IQREntity
* @return $this
*/
public function applyPromoCode(SummitRegistrationPromoCode $promo_code){
$this->setType($promo_code->getBadgeType());
foreach ($promo_code->getBadgeFeatures() as $feature)
$this->addFeature($feature);
return $this;

View File

@ -91,13 +91,6 @@ class SummitRegistrationPromoCode extends SilverstripeBaseModel
*/
protected $valid_until_date;
/**
* @ORM\ManyToOne(targetEntity="models\summit\SummitBadgeType",)
* @ORM\JoinColumn(name="BadgeTypeID", referencedColumnName="ID")
* @var SummitBadgeType
*/
protected $badge_type;
/**
* @ORM\ManyToOne(targetEntity="models\summit\Summit", inversedBy="promo_codes")
* @ORM\JoinColumn(name="SummitID", referencedColumnName="ID")
@ -132,7 +125,6 @@ class SummitRegistrationPromoCode extends SilverstripeBaseModel
*/
protected $allowed_ticket_types;
public function setSummit($summit){
$this->summit = $summit;
}
@ -350,28 +342,6 @@ class SummitRegistrationPromoCode extends SilverstripeBaseModel
return true;
}
/**
* @return int
*/
public function getBadgeTypeId(){
try {
return is_null($this->badge_type) ? 0: $this->badge_type->getId();
}
catch(\Exception $ex){
return 0;
}
}
/**
* @return bool
*/
public function hasBadgeType(){
return $this->getBadgeTypeId() > 0;
}
public function clearBadgeType(){
$this->badge_type = null;
}
public function setSourceAdmin(){
$this->source = 'ADMIN';
@ -415,7 +385,6 @@ class SummitRegistrationPromoCode extends SilverstripeBaseModel
'valid_until_date' => 'datetime',
'source' => ['CSV','ADMIN'],
'summit_id' => 'integer',
'badge_type_id' => 'integer',
'creator_id' => 'integer',
'allowed_ticket_types' => 'array',
];
@ -495,22 +464,6 @@ class SummitRegistrationPromoCode extends SilverstripeBaseModel
$this->valid_until_date = $valid_until_date;
}
/**
* @return SummitBadgeType
*/
public function getBadgeType(): ?SummitBadgeType
{
return $this->badge_type;
}
/**
* @param SummitBadgeType $badge_type
*/
public function setBadgeType(SummitBadgeType $badge_type): void
{
$this->badge_type = $badge_type;
}
/**
* @param SummitTicketType $ticket_type
*/
@ -546,12 +499,14 @@ class SummitRegistrationPromoCode extends SilverstripeBaseModel
/**
* @param SummitAttendeeTicket $ticket
* @return SummitAttendeeTicket
* @throws ValidationException
*/
public function applyTo(SummitAttendeeTicket $ticket){
if($this->hasBadgeType()){
$badge = $ticket->hasBadge() ? $ticket->getBadge() : new SummitAttendeeBadge();
$ticket->setBadge($badge->applyPromoCode($this));
}
public function applyTo(SummitAttendeeTicket $ticket):SummitAttendeeTicket{
$badge = $ticket->hasBadge() ? $ticket->getBadge() : null;
if(is_null($badge))
throw new ValidationException(sprintf("Ticket %s has not badge set.", $ticket->getId()));
// apply the promo code code to badge
$badge->applyPromoCode($this);
$ticket->setPromoCode($this);
return $ticket;
}

View File

@ -446,8 +446,9 @@ class SummitTicketType extends SilverstripeBaseModel
* @return int
*/
public function getBadgeTypeId(){
$res = $this->getBadgeType();
try {
return is_null($this->badge_type) ? 0: $this->badge_type->getId();
return is_null($res) ? 0: $res->getId();
}
catch(\Exception $ex){
return 0;
@ -459,20 +460,19 @@ class SummitTicketType extends SilverstripeBaseModel
*/
public function getBadgeType(): ?SummitBadgeType
{
return $this->badge_type;
$res = $this->badge_type;
if(is_null($res)){
$res = $this->summit->getDefaultBadgeType();
}
return $res;
}
/**
* @return bool
*/
public function hasBadgeType(){
public function hasBadgeType():bool{
return $this->getBadgeTypeId() > 0;
}
public function clearBadgeType(){
$this->badge_type = null;
}
/**
* @param SummitBadgeType $badge_type
*/

View File

@ -13,7 +13,6 @@
**/
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\main\EmailCreationRequest;
use models\main\Member;
use models\summit\Summit;
use models\summit\SummitRegistrationPromoCode;

View File

@ -29,6 +29,7 @@ use Exception;
use Illuminate\Support\Facades\Log;
use models\summit\SummitAttendeeBadge;
use models\summit\SummitAttendeeTicket;
use models\summit\SummitBadgeType;
use models\summit\SummitRegistrationDiscountCode;
use models\summit\ISummitAttendeeRepository;
use models\summit\SummitRegistrationPromoCode;
@ -232,6 +233,11 @@ final class RegistrationIngestionService
$ticket->setTicketType($ticket_type);
}
// default badge
if (!$ticket->hasBadge()) {
$ticket->setBadge(SummitBadgeType::buildBadgeFromType($default_badge_type));
}
if (count($external_promo_code)) {
// has promo code
$promo_code = $summit->getPromoCodeByCode($external_promo_code['code']);
@ -263,13 +269,6 @@ final class RegistrationIngestionService
$promo_code->applyTo($ticket);
}
// default badge
if (!$ticket->hasBadge()) {
$badge = new SummitAttendeeBadge();
$badge->setType($default_badge_type);
$ticket->setBadge($badge);
}
// assign attendee
// check if we have already an attendee on this summit
$attendee_email = trim($external_attendee_profile['email']);

View File

@ -39,22 +39,33 @@ final class SummitBadgeTypeService extends AbstractService
public function addBadgeType(Summit $summit, array $data): SummitBadgeType
{
return $this->tx_service->transaction(function () use ($summit, $data) {
$name = trim($data['name']);
$former_badge_type = $summit->getBadgeTypeByName($name);
if (!is_null($former_badge_type)) {
throw new ValidationException("badge type name already exists");
}
$is_default = boolval($data['is_default']);
if($is_default && $summit->hasDefaultBadgeType()){
throw new ValidationException("there is already a default badge type");
$formerDefault = $summit->getDefaultBadgeType();
if($is_default){
if(!is_null($formerDefault)){
$formerDefault->setIsDefault(false);
}
}
if(!$is_default && is_null($formerDefault)){
// force default
$data['is_default'] = true;
}
$badge_type = SummitBadgeTypeFactory::build($data);
// add default access levels
foreach($summit->getDefaultBadgeAccessLevelTypes() as $default_access_level){
$badge_type->addAccessLevel($default_access_level);
}
$summit->addBadgeType($badge_type);
return $badge_type;
});
@ -82,11 +93,20 @@ final class SummitBadgeTypeService extends AbstractService
throw new ValidationException("badge type name already exists");
}
}
if(isset($data['is_default'])) {
// default check
$formerDefault = $summit->getDefaultBadgeType();
if(isset($data['is_default'])) { // trying to set a default ( true or false)
$is_default = boolval($data['is_default']);
if ($is_default && $summit->hasDefaultBadgeType() && !$badge_type->isDefault()) {
throw new ValidationException("there is already a default badge type");
if ($is_default && !$badge_type->isDefault()) { // is we want to set it as default ...
if(!is_null($formerDefault)){
// remove former default
$formerDefault->setIsDefault(false);
}
}
// if we dont have a default
if(!$is_default && is_null($formerDefault)){
// force default
$data['is_default'] = true;
}
}

View File

@ -301,14 +301,14 @@ final class ReserveOrderTask extends AbstractTask
$ticket->setTicketType($ticket_type);
if (!$ticket->hasBadge()) {
$ticket->setBadge(SummitBadgeType::buildBadgeFromType($default_badge_type));
}
$promo_code = !empty($promo_code_value) ? $this->summit->getPromoCodeByCode($promo_code_value) : null;
if (!is_null($promo_code)) {
$promo_code->applyTo($ticket);
}
if (!$ticket->hasBadge()) {
$badge = SummitBadgeType::buildBadgeFromType($default_badge_type);
$ticket->setBadge($badge);
}
$ticket->applyTaxes($this->summit->getTaxTypes()->toArray());
@ -1877,6 +1877,10 @@ final class SummitOrderService
Log::debug(sprintf("SummitOrderService::createOrderSingleTicket ticket number %s", $ticket->getNumber()));
if (!$ticket->hasBadge()) {
$ticket->setBadge(SummitBadgeType::buildBadgeFromType($default_badge_type));
}
// promo code usage
$promo_code = isset($payload['promo_code']) ? $this->promo_code_repository->getByValueExclusiveLock($summit, trim($payload['promo_code'])) : null;
if (!is_null($promo_code)) {
@ -1884,11 +1888,6 @@ final class SummitOrderService
$promo_code->applyTo($ticket);
}
if (!$ticket->hasBadge()) {
$badge = SummitBadgeType::buildBadgeFromType($default_badge_type);
$ticket->setBadge($badge);
}
$ticket->applyTaxes($summit->getTaxTypes()->toArray());
$order->addTicket($ticket);
if (!is_null($owner)) {

View File

@ -23,7 +23,6 @@ use models\main\IMemberRepository;
use models\main\Member;
use models\summit\IOwnablePromoCode;
use models\summit\ISpeakerRepository;
use models\summit\ISummitRegistrationPromoCodeRepository;
use models\summit\Summit;
use models\summit\SummitRegistrationDiscountCode;
use models\summit\SummitRegistrationPromoCode;
@ -36,11 +35,6 @@ final class SummitPromoCodeService
extends AbstractService
implements ISummitPromoCodeService
{
/**
* @var ISummitRegistrationPromoCodeRepository
*/
private $promo_code_repository;
/**
* @var IMemberRepository
*/
@ -58,7 +52,6 @@ final class SummitPromoCodeService
/**
* SummitPromoCodeService constructor.
* @param ISummitRegistrationPromoCodeRepository $promo_code_repository
* @param IMemberRepository $member_repository
* @param ICompanyRepository $company_repository
* @param ISpeakerRepository $speaker_repository
@ -66,7 +59,6 @@ final class SummitPromoCodeService
*/
public function __construct
(
ISummitRegistrationPromoCodeRepository $promo_code_repository,
IMemberRepository $member_repository,
ICompanyRepository $company_repository,
ISpeakerRepository $speaker_repository,
@ -74,7 +66,6 @@ final class SummitPromoCodeService
)
{
parent::__construct($tx_service);
$this->promo_code_repository = $promo_code_repository;
$this->member_repository = $member_repository;
$this->company_repository = $company_repository;
$this->speaker_repository = $speaker_repository;
@ -134,13 +125,6 @@ final class SummitPromoCodeService
$params['sponsor'] = $sponsor;
}
if(isset($data['badge_type_id'])){
$badge_type = $summit->getBadgeTypeById(intval($data['badge_type_id']));
if(is_null($badge_type))
throw new EntityNotFoundException(sprintf("badge_type_id %s not found", $data['badge_type_id']));
$params['badge_type'] = $badge_type;
}
return $params;
}
/**

View File

@ -19,7 +19,6 @@ use Illuminate\Support\Facades\Event;
use libs\utils\ITransactionService;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\summit\ISummitTicketTypeRepository;
use models\summit\Summit;
use models\summit\SummitTicketType;
use services\apis\IEventbriteAPI;
@ -32,11 +31,6 @@ final class SummitTicketTypeService
implements ISummitTicketTypeService
{
/**
* @var ISummitTicketTypeRepository
*/
private $repository;
/**
* @var IEventbriteAPI
*/
@ -44,30 +38,26 @@ final class SummitTicketTypeService
/**
* SummitTicketTypeService constructor.
* @param ISummitTicketTypeRepository $repository
* @param IEventbriteAPI $eventbrite_api
* @param ITransactionService $tx_service
*/
public function __construct
(
ISummitTicketTypeRepository $repository,
IEventbriteAPI $eventbrite_api,
ITransactionService $tx_service
)
{
parent::__construct($tx_service);
$this->repository = $repository;
$this->eventbrite_api = $eventbrite_api;
}
/**
* @param Summit $summit
* @param array $data
* @return array
* @throws EntityNotFoundException
*/
static private function getPromoCodeParams(Summit $summit, array $data):array{
static private function getTicketTypeParams(Summit $summit, array $data):array{
if(isset($data['badge_type_id'])){
$badge_type = $summit->getBadgeTypeById(intval($data['badge_type_id']));
if(is_null($badge_type))
@ -120,7 +110,7 @@ final class SummitTicketTypeService
}
}
$ticket_type = SummitTicketTypeFactory::build($summit, self::getPromoCodeParams($summit, $data));
$ticket_type = SummitTicketTypeFactory::build($summit, self::getTicketTypeParams($summit, $data));
if($summit->hasTicketTypes()){
// before add check if we have the same currency
@ -215,7 +205,7 @@ final class SummitTicketTypeService
if(!empty($currency) && !empty($summit_currency) && $summit_currency != $currency)
throw new ValidationException(sprintf("ticket type should have same currency as summit (%s)", $summit_currency));
$ticket_type = SummitTicketTypeFactory::populate($ticket_type, self::getPromoCodeParams($summit, $data));
$ticket_type = SummitTicketTypeFactory::populate($ticket_type, self::getTicketTypeParams($summit, $data));
Event::fire
(