From acdb626c9f390b66fcab0cb6c992cbaba3438b0e Mon Sep 17 00:00:00 2001 From: romanetar Date: Wed, 4 Mar 2026 10:12:57 +0100 Subject: [PATCH 1/2] feat: sponsor service statistics crud endpoints Signed-off-by: romanetar --- ...rvicesStatisticsValidationRulesFactory.php | 35 ++++++ .../OAuth2SummitSponsorApiController.php | 80 ++++++++++++ app/ModelSerializers/SerializerRegistry.php | 6 +- .../Summit/SponsorBaseSerializer.php | 9 +- .../Summit/SponsorSerializer.php | 19 ++- .../Summit/SponsorSerializerV2.php | 5 +- .../Summit/SponsorStatisticsSerializer.php | 29 +++++ .../SponsorServicesStatisticsFactory.php | 58 +++++++++ app/Models/Foundation/Summit/Sponsor.php | 58 ++++++++- .../Foundation/Summit/SponsorStatistics.php | 114 ++++++++++++++++++ app/Services/Model/ISummitSponsorService.php | 12 +- .../Model/Imp/SummitSponsorService.php | 28 ++++- app/Swagger/SponsorSchemas.php | 12 ++ .../model/Version20260302173010.php | 56 +++++++++ database/seeders/ApiEndpointsSeeder.php | 13 ++ routes/api_v1.php | 5 + tests/InsertSummitTestData.php | 8 ++ tests/OAuth2SummitSponsorApiTest.php | 71 ++++++++++- 18 files changed, 604 insertions(+), 14 deletions(-) create mode 100644 app/Http/Controllers/Apis/Protected/Summit/Factories/SponsorServicesStatisticsValidationRulesFactory.php create mode 100644 app/ModelSerializers/Summit/SponsorStatisticsSerializer.php create mode 100644 app/Models/Foundation/Summit/Factories/SponsorServicesStatisticsFactory.php create mode 100644 app/Models/Foundation/Summit/SponsorStatistics.php create mode 100644 database/migrations/model/Version20260302173010.php diff --git a/app/Http/Controllers/Apis/Protected/Summit/Factories/SponsorServicesStatisticsValidationRulesFactory.php b/app/Http/Controllers/Apis/Protected/Summit/Factories/SponsorServicesStatisticsValidationRulesFactory.php new file mode 100644 index 0000000000..6e193563e4 --- /dev/null +++ b/app/Http/Controllers/Apis/Protected/Summit/Factories/SponsorServicesStatisticsValidationRulesFactory.php @@ -0,0 +1,35 @@ + 'sometimes|integer', + 'purchases_qty' => 'sometimes|integer', + 'pages_qty' => 'sometimes|integer', + 'documents_qty' => 'sometimes|integer', + ]; + } + + public static function buildForUpdate(array $payload = []): array + { + return self::buildForAdd(); + } +} diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSponsorApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSponsorApiController.php index 0ecdf7ffe0..e99e12ba5f 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSponsorApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitSponsorApiController.php @@ -4288,4 +4288,84 @@ public function updateLeadReportSettings($summit_id, $sponsor_id) { ); }); } + + #[OA\Put( + path: "/api/v1/summits/{id}/sponsors/{sponsor_id}/sponsorservices-statistics", + description: "required-groups " . IGroup::SuperAdmins . ", " . IGroup::Administrators . ", " . IGroup::SummitAdministrators, + summary: 'Upsert Sponsor Services Statistics', + operationId: 'updateSponsorServicesStatistics', + tags: ['Sponsors'], + x: [ + 'required-groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], + security: [ + [ + 'summit_sponsor_oauth2' => [ + SummitScopes::WriteSummitData, + ] + ] + ], + parameters: [ + new OA\Parameter( + name: 'id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The summit id' + ), + new OA\Parameter( + name: 'sponsor_id', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer'), + description: 'The sponsor id' + ), + ], + requestBody: new OA\RequestBody( + required: true, + content: new OA\JsonContent(ref: "#/components/schemas/SponsorServicesStatisticsUpsertRequest") + ), + responses: [ + new OA\Response( + response: Response::HTTP_CREATED, + description: 'Sponsor Services Statistics created/updated successfully' + ), + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error") + ] + )] + /** + * @param $summit_id + * @param $sponsor_id + * @return mixed + */ + public function updateSponsorServicesStatistics($summit_id, $sponsor_id) { + return $this->processRequest(function () use ($summit_id, $sponsor_id) { + + $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); + if (is_null($summit)) return $this->error404(); + + $sponsor = $summit->getSummitSponsorById(intval($sponsor_id)); + if (is_null($sponsor)) return $this->error404(); + + $payload = $this->getJsonPayload(SponsorServicesStatisticsValidationRulesFactory::buildForUpdate(), true); + + $statistics = $this->service->updateSponsorServicesStatistics($summit, $sponsor->getId(), $payload); + + return $this->updated(SerializerRegistry::getInstance() + ->getSerializer($statistics) + ->serialize( + SerializerUtils::getExpand(), + SerializerUtils::getFields(), + SerializerUtils::getRelations() + ) + ); + }); + } } diff --git a/app/ModelSerializers/SerializerRegistry.php b/app/ModelSerializers/SerializerRegistry.php index 0a9c7807de..08559d9f40 100644 --- a/app/ModelSerializers/SerializerRegistry.php +++ b/app/ModelSerializers/SerializerRegistry.php @@ -108,6 +108,7 @@ use App\ModelSerializers\Summit\SponsorMaterialSerializer; use App\ModelSerializers\Summit\SponsorSerializerV2; use App\ModelSerializers\Summit\SponsorSocialNetworkSerializer; +use App\ModelSerializers\Summit\SponsorStatisticsSerializer; use App\ModelSerializers\Summit\SponsorUserInfoGrantSerializer; use App\ModelSerializers\Summit\StripePaymentProfileSerializer; use App\ModelSerializers\Summit\SummitAttendeeBadgeSerializer; @@ -268,7 +269,7 @@ private function __construct() $this->registry['SummitSelectionPlanExtraQuestionType'] = SummitSelectionPlanExtraQuestionTypeSerializer::class; $this->registry['AssignedSelectionPlanExtraQuestionType'] = AssignedSelectionPlanExtraQuestionTypeSerializer::class; $this->registry['SelectionPlanAllowedMember'] = SelectionPlanAllowedMemberSerializer::class; - + $this->registry['SummitWIFIConnection'] = SummitWIFIConnectionSerializer::class; $this->registry['SummitType'] = SummitTypeSerializer::class; $this->registry['SummitEventType'] = SummitEventTypeSerializer::class; @@ -602,6 +603,7 @@ private function __construct() $this->registry['SponsorAd'] = SponsorAdSerializer::class; $this->registry['SponsorMaterial'] = SponsorMaterialSerializer::class; $this->registry['SponsorSocialNetwork'] = SponsorSocialNetworkSerializer::class; + $this->registry['SponsorStatistics'] = SponsorStatisticsSerializer::class; // locations @@ -804,4 +806,4 @@ public function serialize($expand = null, array $fields = [], array $relations = return $res; } -} \ No newline at end of file +} diff --git a/app/ModelSerializers/Summit/SponsorBaseSerializer.php b/app/ModelSerializers/Summit/SponsorBaseSerializer.php index 2cc5bd5213..710e8a39ed 100644 --- a/app/ModelSerializers/Summit/SponsorBaseSerializer.php +++ b/app/ModelSerializers/Summit/SponsorBaseSerializer.php @@ -50,6 +50,7 @@ abstract class SponsorBaseSerializer extends SilverStripeSerializer 'CarouselAdvertiseImageAltText' => 'carousel_advertise_image_alt_text:json_string', 'ShowLogoInEventPage' => 'show_logo_in_event_page:json_boolean', 'LeadReportSettingId' => 'lead_report_setting_id:json_int', + 'SponsorServicesStatisticsId' => 'sponsorservices_statistics_id:json_int', ]; @@ -193,5 +194,11 @@ public function serialize($expand = null, array $fields = [], array $relations = 'getter' => 'getLeadReportSetting', 'has' => 'hasLeadReportSetting' ], + 'sponsorservices_statistics' => [ + 'type' => One2ManyExpandSerializer::class, + 'original_attribute' => 'sponsorservices_statistics_id', + 'getter' => 'getSponsorServicesStatistics', + 'has' => 'hasSponsorServicesStatistics' + ], ]; -} \ No newline at end of file +} diff --git a/app/ModelSerializers/Summit/SponsorSerializer.php b/app/ModelSerializers/Summit/SponsorSerializer.php index 1f41e1e5d8..6e8ecdd678 100644 --- a/app/ModelSerializers/Summit/SponsorSerializer.php +++ b/app/ModelSerializers/Summit/SponsorSerializer.php @@ -14,8 +14,6 @@ use App\ModelSerializers\Summit\SponsorBaseSerializer; use Libs\ModelSerializers\AbstractSerializer; -use Libs\ModelSerializers\Many2OneExpandSerializer; -use Libs\ModelSerializers\One2ManyExpandSerializer; use models\summit\Sponsor; /** @@ -63,6 +61,21 @@ public function serialize($expand = null, array $fields = [], array $relations = } } break; + case 'sponsorservices_statistics': + { + if ($sponsor->hasStatistics()) { + unset($values['sponsorservices_statistics_id']); + $statistics = $sponsor->getStatistics(); + $values['sponsorservices_statistics'] = SerializerRegistry::getInstance()->getSerializer($statistics)->serialize + ( + AbstractSerializer::filterExpandByPrefix($expand, $relation), + AbstractSerializer::filterFieldsByPrefix($fields, $relation), + AbstractSerializer::filterFieldsByPrefix($relations, $relation), + $params + ); + } + } + break; } } } @@ -70,4 +83,4 @@ public function serialize($expand = null, array $fields = [], array $relations = return $values; } -} \ No newline at end of file +} diff --git a/app/ModelSerializers/Summit/SponsorSerializerV2.php b/app/ModelSerializers/Summit/SponsorSerializerV2.php index 8d4c0d3e13..ec33bf2908 100644 --- a/app/ModelSerializers/Summit/SponsorSerializerV2.php +++ b/app/ModelSerializers/Summit/SponsorSerializerV2.php @@ -23,6 +23,7 @@ final class SponsorSerializerV2 extends SponsorBaseSerializer { protected static $allowed_relations = [ 'sponsorships', + 'statistics', ]; /** @@ -53,6 +54,6 @@ public function serialize($expand = null, array $fields = [], array $relations = 'sponsorships' => [ 'type' => Many2OneExpandSerializer::class, 'getter' => 'getSponsorships', - ], + ] ]; -} \ No newline at end of file +} diff --git a/app/ModelSerializers/Summit/SponsorStatisticsSerializer.php b/app/ModelSerializers/Summit/SponsorStatisticsSerializer.php new file mode 100644 index 0000000000..ec698f427d --- /dev/null +++ b/app/ModelSerializers/Summit/SponsorStatisticsSerializer.php @@ -0,0 +1,29 @@ + 'forms_qty:json_int', + 'PurchasesQty' => 'purchases_qty:json_int', + 'PagesQty' => 'pages_qty:json_int', + 'DocumentsQty' => 'documents_qty:json_int', + ]; +} diff --git a/app/Models/Foundation/Summit/Factories/SponsorServicesStatisticsFactory.php b/app/Models/Foundation/Summit/Factories/SponsorServicesStatisticsFactory.php new file mode 100644 index 0000000000..7d00e3558d --- /dev/null +++ b/app/Models/Foundation/Summit/Factories/SponsorServicesStatisticsFactory.php @@ -0,0 +1,58 @@ +setFormsQty($data['forms_qty']); + } + if(isset($data['purchases_qty'])) { + $statistics->setPurchasesQty($data['purchases_qty']); + } + if(isset($data['pages_qty'])) { + $statistics->setPagesQty($data['pages_qty']); + } + if(isset($data['documents_qty'])) { + $statistics->setDocumentsQty($data['documents_qty']); + } + return $statistics; + } + + protected static function getNewEntity(): SponsorStatistics + { + return new SponsorStatistics; + } +} diff --git a/app/Models/Foundation/Summit/Sponsor.php b/app/Models/Foundation/Summit/Sponsor.php index 3584119525..1cdad43ca9 100644 --- a/app/Models/Foundation/Summit/Sponsor.php +++ b/app/Models/Foundation/Summit/Sponsor.php @@ -18,6 +18,7 @@ use App\Models\Foundation\Main\IOrderable; use App\Models\Foundation\Main\OrderableChilds; use App\Models\Foundation\Summit\ExtraQuestions\SummitSponsorExtraQuestionType; +use App\Models\Foundation\Summit\SponsorStatistics; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\Mapping as ORM; @@ -53,6 +54,7 @@ class Sponsor extends SilverstripeBaseModel implements IOrderable 'getFeaturedEventId' => 'featured_event', 'getCompanyId' => 'company', 'getLeadReportSettingId' => 'lead_report_setting', + 'getSponsorServicesStatisticsId' => 'sponsorservices_statistics', ]; protected $hasPropertyMappings = [ @@ -63,6 +65,7 @@ class Sponsor extends SilverstripeBaseModel implements IOrderable 'hasFeaturedEvent' => 'featured_event', 'hasCompany' => 'company', 'hasLeadReportSetting' => 'lead_report_setting', + 'hasSponsorServicesStatistics' => 'sponsorservices_statistics', ]; /** @@ -230,6 +233,12 @@ class Sponsor extends SilverstripeBaseModel implements IOrderable #[ORM\OneToMany(targetEntity: \models\summit\SummitSponsorship::class, mappedBy: 'sponsor', cascade: ['persist', 'remove'], orphanRemoval: true, fetch: 'EXTRA_LAZY')] private $sponsorships; + /** + * @var SponsorStatistics + */ + #[ORM\OneToOne(targetEntity: SponsorStatistics::class, mappedBy: 'sponsor', cascade: ['persist', 'remove'], orphanRemoval: true, fetch: 'EXTRA_LAZY')] + private $sponsorservices_statistics; + /** * Sponsor constructor. */ @@ -1081,4 +1090,51 @@ public function getSponsorshipId():int{ if(!$this->hasSponsorships()) return 0; return $this->sponsorships->first()->getType()->getId(); } -} \ No newline at end of file + + /** + * @return SponsorStatistics + */ + public function getSponsorServicesStatistics() + { + return $this->sponsorservices_statistics; + } + + /** + * @param SponsorStatistics $statistics + */ + public function setSponsorServicesStatistics(SponsorStatistics $statistics): void + { + $statistics->setSponsor($this); + $this->sponsorservices_statistics = $statistics; + } + + /** + * @return int + */ + public function getSponsorServicesStatisticsId(): int + { + try { + return is_null($this->sponsorservices_statistics) ? 0 : $this->sponsorservices_statistics->getId(); + } catch (\Exception $ex) { + return 0; + } + } + + /** + * @return void + */ + public function clearSponsorServicesStatistics() + { + if (is_null($this->sponsorservices_statistics)) return; + $this->sponsorservices_statistics->clearSponsor(); + $this->sponsorservices_statistics = null; + } + + /** + * @return bool + */ + public function hasSponsorServicesStatistics(): bool + { + return $this->getSponsorServicesStatisticsId() > 0; + } +} diff --git a/app/Models/Foundation/Summit/SponsorStatistics.php b/app/Models/Foundation/Summit/SponsorStatistics.php new file mode 100644 index 0000000000..a9f809c57a --- /dev/null +++ b/app/Models/Foundation/Summit/SponsorStatistics.php @@ -0,0 +1,114 @@ +sponsor; + } + + public function setSponsor(Sponsor $sponsor): void + { + $this->sponsor = $sponsor; + } + + public function clearSponsor(): void + { + $this->sponsor = null; + } + + public function getFormsQty(): int + { + return $this->formsQty; + } + + public function setFormsQty(int $formsQty): void + { + $this->formsQty = $formsQty; + } + + public function getPurchasesQty(): int + { + return $this->purchasesQty; + } + + public function setPurchasesQty(int $purchasesQty): void + { + $this->purchasesQty = $purchasesQty; + } + + public function getPagesQty(): int + { + return $this->pagesQty; + } + + public function setPagesQty(int $pagesQty): void + { + $this->pagesQty = $pagesQty; + } + + public function getDocumentsQty(): int + { + return $this->documentsQty; + } + + public function setDocumentsQty(int $documentsQty): void + { + $this->documentsQty = $documentsQty; + } +} diff --git a/app/Services/Model/ISummitSponsorService.php b/app/Services/Model/ISummitSponsorService.php index c22f85ec4f..1e78e344ec 100644 --- a/app/Services/Model/ISummitSponsorService.php +++ b/app/Services/Model/ISummitSponsorService.php @@ -15,6 +15,7 @@ use App\Models\Foundation\ExtraQuestions\ExtraQuestionTypeValue; use App\Models\Foundation\Main\IFileConstants; use App\Models\Foundation\Summit\ExtraQuestions\SummitSponsorExtraQuestionType; +use App\Models\Foundation\Summit\SponsorStatistics; use Illuminate\Http\UploadedFile; use models\exceptions\EntityNotFoundException; use models\exceptions\ValidationException; @@ -326,4 +327,13 @@ public function addLeadReportSettings(Summit $summit, int $sponsor_id, array $pa * @throws \Exception */ public function updateLeadReportSettings(Summit $summit, int $sponsor_id, array $payload): SummitLeadReportSetting; -} \ No newline at end of file + + /** + * @param Summit $summit + * @param int $sponsor_id + * @param array $payload + * @return SponsorStatistics + * @throws \Exception + */ + public function updateSponsorServicesStatistics(Summit $summit, int $sponsor_id, array $payload): SponsorStatistics; +} diff --git a/app/Services/Model/Imp/SummitSponsorService.php b/app/Services/Model/Imp/SummitSponsorService.php index 0d023b8302..b320481e56 100644 --- a/app/Services/Model/Imp/SummitSponsorService.php +++ b/app/Services/Model/Imp/SummitSponsorService.php @@ -25,9 +25,11 @@ use App\Models\Foundation\Summit\Factories\SponsorExtraQuestionFactory; use App\Models\Foundation\Summit\Factories\SponsorFactory; use App\Models\Foundation\Summit\Factories\SponsorMaterialFactory; +use App\Models\Foundation\Summit\Factories\SponsorServicesStatisticsFactory; use App\Models\Foundation\Summit\Factories\SponsorSocialNetworkFactory; use App\Models\Foundation\Summit\Repositories\ISponsorExtraQuestionTypeRepository; use App\Models\Foundation\Summit\Repositories\ISummitSponsorshipRepository; +use App\Models\Foundation\Summit\SponsorStatistics; use App\Services\Model\Imp\ExtraQuestionTypeService; use Doctrine\Common\Collections\ArrayCollection; use Illuminate\Http\UploadedFile; @@ -1164,4 +1166,28 @@ public function updateLeadReportSettings(Summit $summit, int $sponsor_id, array return $lead_report_settings; }); } -} \ No newline at end of file + + /** + * @param Summit $summit + * @param int $sponsor_id + * @param array $payload + * @return SponsorStatistics + * @throws \Exception + */ + public function updateSponsorServicesStatistics(Summit $summit, int $sponsor_id, array $payload): SponsorStatistics + { + return $this->tx_service->transaction(function () use ($summit, $sponsor_id, $payload) { + + $summit_sponsor = $summit->getSummitSponsorById($sponsor_id); + if (is_null($summit_sponsor)) + throw new EntityNotFoundException("Sponsor not found."); + + $statistics = $summit_sponsor->getSponsorServicesStatistics(); + if (!$statistics) { + $statistics = new SponsorStatistics(); + $statistics->setSponsor($summit_sponsor); + } + return SponsorServicesStatisticsFactory::populate($statistics, $payload); + }); + } +} diff --git a/app/Swagger/SponsorSchemas.php b/app/Swagger/SponsorSchemas.php index 2162a5bd9e..dcad408308 100644 --- a/app/Swagger/SponsorSchemas.php +++ b/app/Swagger/SponsorSchemas.php @@ -258,3 +258,15 @@ class PaginatedSponsorResponseSchema {} ] )] class PaginatedSponsorV2ResponseSchema {} + +#[OA\Schema( + schema: 'SponsorServicesStatisticsUpsertRequest', + type: 'object', + properties: [ + new OA\Property(property: 'forms_qty', type: 'integer', example: 1, nullable: true), + new OA\Property(property: 'purchases_qty', type: 'integer', example: 1, nullable: true), + new OA\Property(property: 'pages_qty', type: 'integer', example: 1, nullable: true), + new OA\Property(property: 'documents_qty', type: 'integer', example: 1, nullable: true) + ] +)] +class SponsorServicesStatisticsUpsertRequestSchema {} diff --git a/database/migrations/model/Version20260302173010.php b/database/migrations/model/Version20260302173010.php new file mode 100644 index 0000000000..264707c5de --- /dev/null +++ b/database/migrations/model/Version20260302173010.php @@ -0,0 +1,56 @@ +integer('FormsQty')->setNotnull(true)->setDefault(0); + $table->integer('PurchasesQty')->setNotnull(true)->setDefault(0); + $table->integer('PagesQty')->setNotnull(true)->setDefault(0); + $table->integer('DocumentsQty')->setNotnull(true)->setDefault(0); + + // FK + $table->integer("SponsorID", false, false)->setNotnull(false)->setDefault('NULL'); + $table->index("SponsorID", "SponsorID"); + $table->foreign("Sponsor", "SponsorID", "ID", ["onDelete" => "CASCADE"], 'FK_Sponsor_SponsorStatistic'); + }); + } + + /** + * @param Schema $schema + * @throws SchemaException + */ + public function down(Schema $schema): void + { + $schema->dropTable(self::TableName); + } +} diff --git a/database/seeders/ApiEndpointsSeeder.php b/database/seeders/ApiEndpointsSeeder.php index ef2db1d9bb..161f4de02f 100644 --- a/database/seeders/ApiEndpointsSeeder.php +++ b/database/seeders/ApiEndpointsSeeder.php @@ -2803,6 +2803,19 @@ private function seedSummitEndpoints() IGroup::SummitAdministrators, ] ], + [ + 'name' => 'update-sponsor-services-statistics', + 'route' => '/api/v1/summits/{id}/sponsors/{sponsor_id}/sponsorservices-statistics', + 'http_method' => 'PUT', + 'scopes' => [ + sprintf(SummitScopes::WriteSummitData, $current_realm), + ], + 'authz_groups' => [ + IGroup::SuperAdmins, + IGroup::Administrators, + IGroup::SummitAdministrators, + ] + ], // Add-On types [ 'name' => 'get-add-ons-metadata', diff --git a/routes/api_v1.php b/routes/api_v1.php index 4839320f95..333eefa0df 100644 --- a/routes/api_v1.php +++ b/routes/api_v1.php @@ -1343,6 +1343,11 @@ }); }); }); + + // sponsor services statistics + Route::group(['prefix' => 'sponsorservices-statistics'], function(){ + Route::put('', ['uses' => 'OAuth2SummitSponsorApiController@updateSponsorServicesStatistics']); + }); }); }); diff --git a/tests/InsertSummitTestData.php b/tests/InsertSummitTestData.php index 0345e79681..15d2edd7d7 100644 --- a/tests/InsertSummitTestData.php +++ b/tests/InsertSummitTestData.php @@ -20,6 +20,7 @@ use App\Models\Foundation\Summit\ExtraQuestions\SummitSelectionPlanExtraQuestionType; use App\Models\Foundation\Summit\ExtraQuestions\SummitSponsorExtraQuestionType; use App\Models\Foundation\Summit\SelectionPlan; +use App\Models\Foundation\Summit\SponsorStatistics; use App\Models\Foundation\Summit\TrackTagGroup; use DateInterval; use DateTime; @@ -912,6 +913,13 @@ protected static function insertSummitTestData(){ } } + $statistics = new SponsorStatistics(); + $statistics->setFormsQty(random_int(1, 30)); + $statistics->setPurchasesQty(random_int(1, 30)); + $statistics->setPagesQty(random_int(1, 30)); + $statistics->setDocumentsQty(random_int(1, 30)); + $s->setSponsorServicesStatistics($statistics); + self::$em->persist($s); self::$summit->addSummitSponsor($s); self::$sponsors[] = $s; diff --git a/tests/OAuth2SummitSponsorApiTest.php b/tests/OAuth2SummitSponsorApiTest.php index 2e90694b1e..cce73bf941 100644 --- a/tests/OAuth2SummitSponsorApiTest.php +++ b/tests/OAuth2SummitSponsorApiTest.php @@ -60,7 +60,7 @@ public function testGetAllSponsorsBySummit(){ $params = [ 'id' => self::$summit->getId(), 'filter'=> 'company_name=@'.substr(self::$companies[0]->getName(),0,3), - 'expand' => 'summit,company,extra_questions,featured_event,lead_report_setting', + 'expand' => 'summit,company,extra_questions,featured_event,lead_report_setting,sponsorservices_statistics', 'order' => '-sponsorship_name' ]; @@ -89,7 +89,7 @@ public function testGetAllSponsorsBySummitV2(){ $params = [ 'id' => self::$summit->getId(), 'filter'=> 'company_name=@'.substr(self::$companies[0]->getName(),0,3), - 'expand' => 'summit,company,sponsorships,sponsorships.type,sponsorships.add_ons,extra_questions,featured_event,lead_report_setting', + 'expand' => 'summit,company,sponsorships,sponsorships.type,sponsorships.add_ons,extra_questions,featured_event,lead_report_setting,sponsorservices_statistics', 'order' => '-sponsorship_name' ]; @@ -115,6 +115,7 @@ public function testGetAllSponsorsBySummitV2(){ $this->assertNotNull($sponsor->sponsorships[0]->add_ons[0]->name); $this->assertNotNull($sponsor->sponsorships[0]->type); $this->assertNotNull($sponsor->sponsorships[0]->type->type_id); + $this->assertNotNull($sponsor->sponsorservices_statistics); return $page; } @@ -813,4 +814,68 @@ public function testGetLeadReportSettingsMetadata(){ $metadata = json_decode($content); $this->assertNotNull($metadata); } -} \ No newline at end of file + + public function testUpdateSponsorServicesStatistics(){ + $params = [ + 'id' => self::$summit->getId(), + 'sponsor_id' => self::$sponsors[0]->getId(), + ]; + + $new_forms_qty = 10; + + $data = [ + 'forms_qty' => $new_forms_qty, + 'purchases_qty' => 8, + 'pages_qty' => 7, + 'documents_qty' => 6 + ]; + + $response = $this->action( + "PUT", + "OAuth2SummitSponsorApiController@updateSponsorServicesStatistics", + $params, + [], + [], + [], + $this->getAuthHeaders(), + json_encode($data) + ); + + $content = $response->getContent(); + $this->assertResponseStatus(201); + $statistics = json_decode($content); + $this->assertEquals($new_forms_qty, $statistics->forms_qty); + } + + public function testUpdatePartiallySponsorServicesStatistics(){ + $params = [ + 'id' => self::$summit->getId(), + 'sponsor_id' => self::$sponsors[0]->getId(), + ]; + + + $new_forms_qty = 10; + $pages_qty = self::$sponsors[0]->getSponsorServicesStatistics()->getPagesQty(); + + $data = [ + 'forms_qty' => $new_forms_qty + ]; + + $response = $this->action( + "PUT", + "OAuth2SummitSponsorApiController@updateSponsorServicesStatistics", + $params, + [], + [], + [], + $this->getAuthHeaders(), + json_encode($data) + ); + + $content = $response->getContent(); + $this->assertResponseStatus(201); + $statistics = json_decode($content); + $this->assertEquals($new_forms_qty, $statistics->forms_qty); + $this->assertEquals($pages_qty, $statistics->pages_qty); + } +} From 289457f45f2c183362071a155ef8f45f2aa36d8d Mon Sep 17 00:00:00 2001 From: romanetar Date: Thu, 5 Mar 2026 19:07:28 +0100 Subject: [PATCH 2/2] fix: review feedback Signed-off-by: romanetar --- .../Summit/Factories/SponsorServicesStatisticsFactory.php | 8 ++++---- database/migrations/model/Version20260302173010.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Models/Foundation/Summit/Factories/SponsorServicesStatisticsFactory.php b/app/Models/Foundation/Summit/Factories/SponsorServicesStatisticsFactory.php index 7d00e3558d..2f13dcb830 100644 --- a/app/Models/Foundation/Summit/Factories/SponsorServicesStatisticsFactory.php +++ b/app/Models/Foundation/Summit/Factories/SponsorServicesStatisticsFactory.php @@ -37,16 +37,16 @@ public static function build(array $data): SponsorStatistics public static function populate(SponsorStatistics $statistics, array $data): SponsorStatistics { if(isset($data['forms_qty'])) { - $statistics->setFormsQty($data['forms_qty']); + $statistics->setFormsQty(intval($data['forms_qty'])); } if(isset($data['purchases_qty'])) { - $statistics->setPurchasesQty($data['purchases_qty']); + $statistics->setPurchasesQty(intval($data['purchases_qty'])); } if(isset($data['pages_qty'])) { - $statistics->setPagesQty($data['pages_qty']); + $statistics->setPagesQty(intval($data['pages_qty'])); } if(isset($data['documents_qty'])) { - $statistics->setDocumentsQty($data['documents_qty']); + $statistics->setDocumentsQty(intval($data['documents_qty'])); } return $statistics; } diff --git a/database/migrations/model/Version20260302173010.php b/database/migrations/model/Version20260302173010.php index 264707c5de..e45807e753 100644 --- a/database/migrations/model/Version20260302173010.php +++ b/database/migrations/model/Version20260302173010.php @@ -39,7 +39,7 @@ public function up(Schema $schema):void $table->integer('DocumentsQty')->setNotnull(true)->setDefault(0); // FK - $table->integer("SponsorID", false, false)->setNotnull(false)->setDefault('NULL'); + $table->integer("SponsorID", false, false)->setNotnull(false)->setDefault(null); $table->index("SponsorID", "SponsorID"); $table->foreign("Sponsor", "SponsorID", "ID", ["onDelete" => "CASCADE"], 'FK_Sponsor_SponsorStatistic'); });