{-# LANGUAGE LambdaCase #-}
module Deontic.Civil.Persons () where

import qualified Data.Set as Set
import Deontic.Core.Types
import Deontic.Core.Verdict
import Deontic.Core.Layer
import Deontic.Core.Adjudicate
import Deontic.Civil.Types (MinorAct(..), CivilFact(..))

type instance Resolvable MinorAct = '[Proviso, Base]

-- 제5조(미성년자의 법률행위) ① 본문
-- "미성년자가 법률행위를 함에는 법정대리인의 동의를 얻어야 한다."
instance Adjudicate MinorAct '[Base] where
  adjudicate :: MinorAct -> Facts MinorAct -> Judgment '[Base]
adjudicate (MinorAct PersonId
_actor ActId
actId) Facts MinorAct
facts
    | ActId -> Set CivilFact -> Bool
hasConsent ActId
actId Set CivilFact
Facts MinorAct
facts =
        Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Valid
          (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
5 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1))
          Text
"미성년자가 법률행위를 함에는 법정대리인의 동의를 얻어야 한다."
    | Bool
otherwise =
        Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Voidable
          (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
5 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1))
          Text
"미성년자가 법률행위를 함에는 법정대리인의 동의를 얻어야 한다."

-- 제5조 ① 단서
-- "권리만을 얻거나 의무만을 면하는 법률행위는 그러하지 아니하다."
instance Adjudicate MinorAct rest
      => Adjudicate MinorAct (Proviso ': rest) where
  adjudicate :: MinorAct -> Facts MinorAct -> Judgment (Proviso : rest)
adjudicate MinorAct
act Facts MinorAct
facts
    | CivilFact
MerelyAcquiresRight CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts MinorAct
facts =
        Judgment rest
-> Verdict -> ArticleRef -> Text -> Judgment (Proviso : rest)
forall (prev :: [*]) l.
Judgment prev
-> Verdict -> ArticleRef -> Text -> Judgment (l : prev)
JOverride (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest MinorAct
act Facts MinorAct
facts)
                  Verdict
Valid
                  (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
5 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1))
                  Text
"권리만을 얻거나 의무만을 면하는 법률행위는 그러하지 아니하다."
    | Bool
otherwise =
        Judgment rest -> Judgment (Proviso : rest)
forall (prev :: [*]) l. Judgment prev -> Judgment (l : prev)
JDelegate (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest MinorAct
act Facts MinorAct
facts)

hasConsent :: ActId -> Set.Set CivilFact -> Bool
hasConsent :: ActId -> Set CivilFact -> Bool
hasConsent ActId
actId Set CivilFact
facts =
  (CivilFact -> Bool) -> [CivilFact] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\case HasConsent PersonId
_ ActId
a -> ActId
a ActId -> ActId -> Bool
forall a. Eq a => a -> a -> Bool
== ActId
actId; CivilFact
_ -> Bool
False) (Set CivilFact -> [CivilFact]
forall a. Set a -> [a]
Set.toList Set CivilFact
facts)