module Deontic.Civil.PropertyTransfer () where

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

-- ═══════════════════════════════════════════════
-- 물권변동 — Property Transfer (§186, §187, §188)
--
-- §186: 부동산 물권변동은 등기를 하여야 효력이 생긴다.
-- §187: 상속, 공용징수, 판결, 경매 등은 등기 없이도 효력.
-- §188: 동산 물권변동은 인도로 효력이 생긴다.
--
-- FormException layer overrides §186 for §187 cases.
-- ═══════════════════════════════════════════════

type instance Resolvable PropertyTransferAct = '[FormException, Base]

-- 제186조 (부동산물권변동의 효력) / 제188조 (동산물권양도의 효력)
instance Adjudicate PropertyTransferAct '[Base] where
  adjudicate :: PropertyTransferAct
-> Facts PropertyTransferAct -> Judgment '[Base]
adjudicate PropertyTransferAct
_ Facts PropertyTransferAct
facts
    | CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member CivilFact
IsRealProperty Set CivilFact
Facts PropertyTransferAct
facts
    , CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member CivilFact
HasRegistration Set CivilFact
Facts PropertyTransferAct
facts =
        Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Valid
          (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
186 Maybe Int
forall a. Maybe a
Nothing)
          Text
"부동산에 관한 법률행위로 인한 물권의 득실변경은 등기하여야 그 효력이 생긴다."
    | CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member CivilFact
IsRealProperty Set CivilFact
Facts PropertyTransferAct
facts =
        Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Void
          (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
186 Maybe Int
forall a. Maybe a
Nothing)
          Text
"등기를 하지 아니하여 부동산 물권변동의 효력이 없다."
    | CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member CivilFact
IsMovableProperty Set CivilFact
Facts PropertyTransferAct
facts
    , CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member CivilFact
HasDelivery Set CivilFact
Facts PropertyTransferAct
facts =
        Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Valid
          (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
188 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1))
          Text
"동산에 관한 물권의 양도는 그 동산을 인도하여야 효력이 생긴다."
    | CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member CivilFact
IsMovableProperty Set CivilFact
Facts PropertyTransferAct
facts =
        Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Void
          (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
188 (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
Void
          (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
186 Maybe Int
forall a. Maybe a
Nothing)
          Text
"물권변동의 대상이 특정되지 아니하였다."

-- 제187조 (등기를 요하지 아니하는 부동산물권취득)
-- "상속, 공용징수, 판결, 경매 기타 법률의 규정에 의한 부동산에 관한
--  물권의 취득은 등기를 요하지 아니한다."
instance Adjudicate PropertyTransferAct rest
      => Adjudicate PropertyTransferAct (FormException ': rest) where
  adjudicate :: PropertyTransferAct
-> Facts PropertyTransferAct -> Judgment (FormException : rest)
adjudicate PropertyTransferAct
act Facts PropertyTransferAct
facts
    | CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member CivilFact
IsRealProperty Set CivilFact
Facts PropertyTransferAct
facts
    , (CivilFact -> Bool) -> [CivilFact] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts PropertyTransferAct
facts) [CivilFact
ByInheritance, CivilFact
ByCourtOrder, CivilFact
ByPublicAuction, CivilFact
ByExpropriation] =
        Judgment rest
-> Verdict -> ArticleRef -> Text -> Judgment (FormException : 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 PropertyTransferAct
act Facts PropertyTransferAct
facts)
                  Verdict
Valid
                  (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
187 Maybe Int
forall a. Maybe a
Nothing)
                  Text
"상속, 공용징수, 판결, 경매 기타 법률의 규정에 의한 부동산물권취득은 등기를 요하지 아니한다."
    | Bool
otherwise =
        Judgment rest -> Judgment (FormException : rest)
forall (prev :: [*]) l. Judgment prev -> Judgment (l : prev)
JDelegate (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest PropertyTransferAct
act Facts PropertyTransferAct
facts)