packages feed

casa-reoc-0.1.0.0: src/ReOC/Risk.hs

{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wall #-}

-- | The risk rating matrix of the operations manual (Appendix E, Table 12).
module ReOC.Risk (
  riskLevelOf,
  riskRating,
  likelihoodValue,
  consequenceValue,
  keyPositionAbbreviation,
  riskReviewDue,
) where

import Control.Lens (cloneLens, view)
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Time.Calendar.Month (Month)
import ReOC.Amendment (addMonths)
import ReOC.Data.Consequence (Consequence (..))
import ReOC.Data.KeyPosition (KeyPosition (..))
import ReOC.Data.Likelihood (Likelihood (..))
import ReOC.Data.Risk (Risk)
import ReOC.Data.RiskAssessment (RiskAssessment)
import ReOC.Data.RiskLevel (RiskLevel (..))
import ReOC.Name.DateEntered (DateEnteredLike (..))
import ReOC.Name.ReviewMonths (ReviewMonthsLike (..))
import ReOC.Name.RiskConsequence (RiskConsequenceLike (..))
import ReOC.Name.RiskLikelihood (RiskLikelihoodLike (..))
import ReOC.Primitive.ReviewMonths (reviewMonthsNatural)

-- | The level of a risk, from the risk rating matrix.
riskLevelOf :: RiskAssessment -> RiskLevel
riskLevelOf r =
  let row catastrophic hazardous moderate minor negligible =
        case view (cloneLens riskConsequence) r of
          Catastrophic -> catastrophic
          Hazardous -> hazardous
          Moderate -> moderate
          Minor -> minor
          Negligible -> negligible
   in case view (cloneLens riskLikelihood) r of
        Frequent -> row High High High Medium Medium
        Occasional -> row High High Medium Medium Medium
        Remote -> row High Medium Medium Medium Low
        Improbable -> row Medium Medium Medium Low Low
        ExtremelyImprobable -> row Medium Low Low Low Low

-- | The value of a likelihood, from 5 (frequent) to 1 (extremely improbable).
likelihoodValue :: Likelihood -> Text
likelihoodValue = \case
  Frequent -> "5"
  Occasional -> "4"
  Remote -> "3"
  Improbable -> "2"
  ExtremelyImprobable -> "1"

-- | The value of a consequence, from A (catastrophic) to E (negligible).
consequenceValue :: Consequence -> Text
consequenceValue = \case
  Catastrophic -> "A"
  Hazardous -> "B"
  Moderate -> "C"
  Minor -> "D"
  Negligible -> "E"

-- | The rating of a risk, such as @2A@.
riskRating :: RiskAssessment -> Text
riskRating r =
  Text.concat [likelihoodValue (view (cloneLens riskLikelihood) r), consequenceValue (view (cloneLens riskConsequence) r)]

-- | The abbreviation of a key position.
keyPositionAbbreviation :: KeyPosition -> Text
keyPositionAbbreviation = \case
  ChiefExecutiveOfficer -> "CEO"
  ChiefRemotePilot -> "CRP"
  MaintenanceController -> "MC"

-- | The month in which a risk is due for review.
riskReviewDue :: Risk -> Month
riskReviewDue k =
  addMonths (reviewMonthsNatural (view (cloneLens reviewMonths) k)) (view (cloneLens dateEntered) k)