77
88namespace Monarc \FrontOffice \Service ;
99
10+ use DateTime ;
1011use Dom \Entity as DomEntity ;
1112use Monarc \Core \Exception \Exception ;
1213use Monarc \Core \Entity as CoreEntity ;
@@ -127,6 +128,12 @@ public function getInstanceRisks(Entity\Anr $anr, ?int $instanceId, array $param
127128 'comment ' => $ instanceRisk ->getComment (),
128129 'scope ' => $ object ->getScope (),
129130 'kindOfMeasure ' => $ instanceRisk ->getKindOfMeasure (),
131+ 'lastReviewDate ' => $ instanceRisk ->getLastReviewDate ()?->format('Y-m-d ' ),
132+ 'reviewFrequency ' => $ instanceRisk ->getReviewFrequency (),
133+ 'reviewFrequencyLabel ' => $ this ->getReviewFrequencyLabel (
134+ $ instanceRisk ->getReviewFrequency (),
135+ $ languageIndex
136+ ),
130137 't ' => $ instanceRisk ->isTreated (),
131138 'tid ' => $ threat ->getUuid (),
132139 'vid ' => $ vulnerability ->getUuid (),
@@ -232,6 +239,15 @@ public function createInstanceRisks(
232239 );
233240 $ instanceRisk ->setInstanceRiskOwner ($ instanceRiskOwner );
234241 }
242+ if (array_key_exists ('lastReviewDate ' , $ instanceRiskData )) {
243+ $ instanceRisk ->setLastReviewDate (
244+ $ this ->createLastReviewDateFromString ($ instanceRiskData ['lastReviewDate ' ])
245+ );
246+ }
247+ if (array_key_exists ('reviewFrequency ' , $ instanceRiskData )) {
248+ $ reviewFrequency = trim ((string )$ instanceRiskData ['reviewFrequency ' ]);
249+ $ instanceRisk ->setReviewFrequency ($ reviewFrequency === '' ? null : $ reviewFrequency );
250+ }
235251 }
236252 }
237253
@@ -380,6 +396,8 @@ public function getInstanceRisksInCsv(Entity\Anr $anr, int $instanceId = null, a
380396 $ this ->translateService ->translate ('Residual risk ' , $ languageIndex ),
381397 $ this ->translateService ->translate ('Risk owner ' , $ languageIndex ),
382398 $ this ->translateService ->translate ('Risk context ' , $ languageIndex ),
399+ $ this ->translateService ->translate ('Last review date ' , $ languageIndex ),
400+ $ this ->translateService ->translate ('Review frequency ' , $ languageIndex ),
383401 $ this ->translateService ->translate ('Recommendations ' , $ languageIndex ),
384402 $ this ->translateService ->translate ('Security referentials ' , $ languageIndex ),
385403 ]) . "\n" ;
@@ -450,6 +468,8 @@ public function getInstanceRisksInCsv(Entity\Anr $anr, int $instanceId = null, a
450468 $ instanceRisk ->getCacheTargetedRisk () === -1 ? null : $ instanceRisk ->getCacheTargetedRisk (),
451469 $ instanceRisk ->getInstanceRiskOwner () ? $ instanceRisk ->getInstanceRiskOwner ()->getName () : '' ,
452470 $ instanceRisk ->getContext (),
471+ $ instanceRisk ->getLastReviewDate ()?->format('Y-m-d ' ),
472+ $ this ->getReviewFrequencyLabel ($ instanceRisk ->getReviewFrequency (), $ languageIndex ),
453473 implode ("\n" , $ recommendationData ),
454474 implode ("\n" , $ measuresData ),
455475 ];
@@ -471,6 +491,13 @@ private function updateInstanceRiskData(Entity\InstanceRisk $instanceRisk, array
471491 $ riskSourceId = empty ($ data ['riskSourceId ' ]) ? null : $ data ['riskSourceId ' ];
472492 $ instanceRisk ->setRiskSource ($ this ->riskSourceTable ->findById ((int )$ riskSourceId ));
473493 }
494+ if (array_key_exists ('lastReviewDate ' , $ data )) {
495+ $ instanceRisk ->setLastReviewDate ($ this ->prepareLastReviewDate ($ instanceRisk , $ data ['lastReviewDate ' ]));
496+ }
497+ if (array_key_exists ('reviewFrequency ' , $ data )) {
498+ $ reviewFrequency = trim ((string )$ data ['reviewFrequency ' ]);
499+ $ instanceRisk ->setReviewFrequency ($ reviewFrequency === '' ? null : $ reviewFrequency );
500+ }
474501 if (isset ($ data ['owner ' ])) {
475502 $ this ->instanceRiskOwnerService ->processRiskOwnerNameAndAssign ((string )$ data ['owner ' ], $ instanceRisk );
476503 }
@@ -518,6 +545,57 @@ private function getOrCreateRiskSourceByLabel(Entity\Anr $anr, string $label): E
518545 return $ riskSource ;
519546 }
520547
548+ private function prepareLastReviewDate (Entity \InstanceRisk $ instanceRisk , mixed $ lastReviewDate ): ?DateTime
549+ {
550+ $ normalizedDate = $ this ->createLastReviewDateFromString ($ lastReviewDate );
551+ $ currentLastReviewDate = $ instanceRisk ->getLastReviewDate ();
552+ if (
553+ $ normalizedDate !== null
554+ && $ currentLastReviewDate !== null
555+ && $ normalizedDate ->format ('Y-m-d ' ) !== $ currentLastReviewDate ->format ('Y-m-d ' )
556+ && $ normalizedDate <= $ currentLastReviewDate
557+ ) {
558+ throw new Exception ('Last review date must be later than the existing last review date. ' , 412 );
559+ }
560+
561+ return $ normalizedDate ;
562+ }
563+
564+ private function createLastReviewDateFromString (mixed $ lastReviewDate ): ?DateTime
565+ {
566+ if ($ lastReviewDate === null || $ lastReviewDate === '' ) {
567+ return null ;
568+ }
569+
570+ $ normalizedDate = DateTime::createFromFormat ('Y-m-d ' , (string )$ lastReviewDate );
571+ if ($ normalizedDate === false ) {
572+ throw new Exception ('Invalid last review date format. ' , 412 );
573+ }
574+
575+ return $ normalizedDate ;
576+ }
577+
578+ private function getReviewFrequencyLabel (?string $ reviewFrequency , int $ languageIndex ): string
579+ {
580+ if ($ reviewFrequency === null || $ reviewFrequency === '' ) {
581+ return '' ;
582+ }
583+
584+ $ suggestedReviewFrequencies = [
585+ 'Monthly ' ,
586+ 'Quarterly ' ,
587+ 'Semi-annually ' ,
588+ 'Annually ' ,
589+ 'On trigger ' ,
590+ ];
591+
592+ if (\in_array ($ reviewFrequency , $ suggestedReviewFrequencies , true )) {
593+ return $ this ->translateService ->translate ($ reviewFrequency , $ languageIndex );
594+ }
595+
596+ return $ reviewFrequency ;
597+ }
598+
521599 private function duplicateRecommendationRisks (
522600 Entity \InstanceRisk $ fromInstanceRisk ,
523601 Entity \InstanceRisk $ newInstanceRisk
0 commit comments