<?php
namespace App\EventSubscriber;
use App\Model\SelectOptionsProvider\QuestionnaireType\QuestionnaireTypeSelectOptionsProvider;
use App\Repository\BPCQuestionnaireRepository;
use App\Services\Asset\SharepointAssetsManager;
use App\Services\BPCScoreCalculationService;
use App\Services\Workflow\BPCQuestionnaire\BPCQuestionnaireWorkflow\BPCQuestionnaireWorkflowService;
use App\Services\Workflow\BPCZone\BPCZoneWorkflow\BPCZoneWorkflowService;
use App\Services\Workflow\BPCZone\BPCZoneWorkflow\Transitions\ToValidatedTransition;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Pimcore\Event\DataObjectEvents;
use Pimcore\Event\Model\DataObjectEvent;
use Pimcore\Model\DataObject\BPCQuestionnaire;
use Pimcore\Model\DataObject\BPCZone;
use Pimcore\Model\DataObject\Service;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class BPCQuestionnaireSubscriber implements EventSubscriberInterface
{
public function __construct(
protected SharepointAssetsManager $sharepointAssetsManager,
protected BPCZoneWorkflowService $bpcZoneWorkflowService,
protected BPCScoreCalculationService $scoreCalculationService,
)
{
}
public static function getSubscribedEvents(): array
{
return [
DataObjectEvents::PRE_ADD => ['onPreAdd', 10],
DataObjectEvents::POST_ADD => ['onPostAdd', 10],
DataObjectEvents::PRE_UPDATE => ['onPreUpdate', 10],
DataObjectEvents::POST_UPDATE => ['onPostUpdate', 10],
];
}
/**
* @throws Exception
*/
public function onPreUpdate(DataObjectEvent $event): void
{
$bpcQuestionnaire = $event->getObject();
if (!($bpcQuestionnaire instanceof BPCQuestionnaire)) {
return;
}
$bpcCertification = $bpcQuestionnaire->getBPCQ_Certification();
$questionnaireTemplate = $bpcQuestionnaire->getBPCQ_QuestionnaireTemplate();
if (!$bpcCertification || !$questionnaireTemplate) {
return;
}
$questionnaireType = $questionnaireTemplate->getBPCQT_QuestionnaireType();
if (!empty($questionnaireType)) {
$bpcQuestionnaire->setParent(Service::createFolderByPath($bpcCertification->getRealFullPath() .
DIRECTORY_SEPARATOR .
BPCQuestionnaireRepository::DEFAULT_FOLDER_ARRAY[$questionnaireType]
));
$this->setQuestionnaireYearNumberCycle($bpcQuestionnaire);
}
// Check if center properties changed (affects useCriteria() logic)
// If they did, recalculate scores as criteria inclusion may have changed
if ($this->hasPropertyChanges($bpcQuestionnaire)) {
$this->scoreCalculationService->recalculateAllScores($bpcQuestionnaire);
}
}
/**
* Check if center properties that affect criteria inclusion have changed
*
* @param BPCQuestionnaire $q
* @return bool
*/
private function hasPropertyChanges(BPCQuestionnaire $q): bool
{
// These properties affect useCriteria() logic in repository
return $q->isFieldDirty('BPCQ_CenterProperties')
|| $q->isFieldDirty('BPCQ_CenterPropertiesHSE')
|| $q->isFieldDirty('BPCQ_CenterPropertiesQuality')
|| $q->isFieldDirty('BPCQ_CenterPropertiesSecurity');
}
/**
* @throws Exception
* @throws GuzzleException
*/
public function onPostUpdate(DataObjectEvent $event): void
{
$bpcQuestionnaire = $event->getObject();
if (!($bpcQuestionnaire instanceof BPCQuestionnaire)) {
return;
}
$bpcq_AuditReports = $bpcQuestionnaire->getBPCQ_AuditReports();
foreach ($bpcq_AuditReports as $BPCQ_AuditReport) {
$report = $BPCQ_AuditReport->getElement();
if ($report) {
$this->sharepointAssetsManager->applySharepointInfos($report, $bpcQuestionnaire, 'audit_report', true);
}
}
$questionnaireType = $bpcQuestionnaire->getBPCQ_QuestionnaireTemplate()?->getBPCQT_QuestionnaireType();
if ($questionnaireType === QuestionnaireTypeSelectOptionsProvider::QUESTIONNAIRE_TYPE_CUSTOMER_JOURNEY
&& $bpcQuestionnaire->getBPCQ_WorkflowStatus() === BPCQuestionnaireWorkflowService::BPC_QUESTIONNAIRE_WORKFLOW_STATUS_VALIDATED
) {
$listing = new BPCZone\Listing();
$listing->setCondition('BPCZ_Questionnaire__id = ?', $bpcQuestionnaire->getId());
foreach ($listing as $bpcZone) {
if ($bpcZone->getBPCZ_WorkflowStatus() !== BPCZoneWorkflowService::BPC_ZONE_WORKFLOW_STATUS_VALIDATED) {
$this->bpcZoneWorkflowService->applyTransition(
object: $bpcZone,
transitionClassName: ToValidatedTransition::class
);
}
}
}
}
/**
* @throws Exception
*/
public function onPreAdd(DataObjectEvent $event): void
{
$bpcQuestionnaire = $event->getObject();
if ($bpcQuestionnaire instanceof BPCQuestionnaire) {
$this->setQuestionnaireYearNumberCycle($bpcQuestionnaire);
}
}
/**
* @throws Exception
*/
public function onPostAdd(DataObjectEvent $event): void
{
$bpcQuestionnaire = $event->getObject();
if ($bpcQuestionnaire instanceof BPCQuestionnaire) {
Service::createFolderByPath($bpcQuestionnaire . DIRECTORY_SEPARATOR . 'Report');
}
}
private function setQuestionnaireYearNumberCycle(BPCQuestionnaire $bpcQuestionnaire): void
{
$previousQuestionnaire = $bpcQuestionnaire->getBPCQ_PreviousQuestionnaire();
/* If the BPCQ_YearNumberCycle field has already been computed, then skip */
if (!empty($previousQuestionnaire) && $bpcQuestionnaire->getBPCQ_YearNumberCycle() > 1) {
return;
}
if (!empty($previousQuestionnaire)) {
$yearNumberCycle = $previousQuestionnaire->getBPCQ_YearNumberCycle() + 1;
$yearNumberCycle = $yearNumberCycle > 3 ? 1 : $yearNumberCycle;
$bpcQuestionnaire->setBPCQ_YearNumberCycle($yearNumberCycle);
} else {
$bpcQuestionnaire->setBPCQ_YearNumberCycle(1);
}
}
}