Coverage for src/inheritance_calculator_core/services/heir_validator.py: 0%

1"""相続人資格検証サービス

2

3日本の民法に基づいて相続人の資格を判定するサービス。

4"""

5 from typing import List, Optional

6 from datetime import date

7

8 from ..models.person import Person

9 from ..models.relationship import (

10 ChildOf,

11 SpouseOf,

12 SiblingOf,

13 Renounced,

14 Disqualified,

15 Disinherited,

16 BloodType,

17)

18 from ..models.inheritance import HeritageRank, SubstitutionType

19 from .base import BaseService

20

21

22 class HeirValidator(BaseService[Person]):

23 """

24 相続人資格検証サービス

25

26 相続人の資格を判定し、相続順位を確定する。

27 """

28

29 def __init__(self) -> None:

30 """初期化"""

31 super().__init__()

32 self.decedent: Optional[Person] = None

33 self.spouses: List[Person] = []

34 self.children: List[Person] = []

35 self.parents: List[Person] = []

36 self.siblings: List[Person] = []

37 self.renounced_persons: List[Person] = []

38 self.disqualified_persons: List[Person] = []

39 self.disinherited_persons: List[Person] = []

40

41 def set_decedent(self, decedent: Person) -> None:

42 """

43 被相続人を設定

44

45 Args:

46 decedent: 被相続人

47 """

48 if not decedent.is_decedent:

49 self.log_warning("Person is not marked as decedent", person=decedent.name)

50

51 self.decedent = decedent

52 self.log_operation("Set decedent", name=decedent.name)

53

54 def is_valid_heir(self, person: Person) -> bool:

55 """

56 相続人として有効かチェック

57

58 Args:

59 person: チェック対象の人物

60

61 Returns:

62 相続人として有効な場合True

63 """

64 if self.decedent is None:

65 raise ValueError("Decedent must be set before validating heirs")

66

67 # 被相続人本人は相続人になれない

68 if person.id == self.decedent.id:

69 return False

70

71 # 死亡している場合の判定

72 if not person.is_alive:

73 # 遺産分割前に死亡した場合は再転相続の対象として一旦有効とする

74 # （後で再転相続処理で実際の相続人に置き換える）

75 if person.died_before_division:

76 return True

77 # それ以外の死亡者は相続人になれない（代襲相続を除く）

78 return False

79

80 # 相続放棄している場合は相続人になれない

81 if person in self.renounced_persons:

82 self.log_info("Person has renounced inheritance", person=person.name)

83 return False

84

85 # 相続欠格の場合は相続人になれない（ただし代襲相続は可能）

86 if person in self.disqualified_persons:

87 self.log_info("Person is disqualified", person=person.name)

88 return False

89

90 # 相続廃除の場合は相続人になれない（ただし代襲相続は可能）

91 if person in self.disinherited_persons:

92 self.log_info("Person is disinherited", person=person.name)

93 return False

94

95 return True

96

97 def validate_spouse(self, spouse: Person) -> bool:

98 """

99 配偶者の相続資格を検証

100

101 民法890条：配偶者は常に相続人となる

102

103 Args:

104 spouse: 配偶者

105

106 Returns:

107 相続人として有効な場合True

108 """

109 if not self.is_valid_heir(spouse):

110 return False

111

112 # 配偶者は常に相続人（民法890条）

113 self.log_operation(

114 "Validated spouse",

115 spouse=spouse.name,

116 basis="民法890条"

117 )

118 return True

119

120 def validate_child(self, child: Person) -> bool:

121 """

122 子の相続資格を検証

123

124 民法887条1項：子は第1順位の相続人

125

126 Args:

127 child: 子

128

129 Returns:

130 相続人として有効な場合True

131 """

132 if not self.is_valid_heir(child):

133 return False

134

135 # 子は第1順位の相続人（民法887条1項）

136 self.log_operation(

137 "Validated child",

138 child=child.name,

139 basis="民法887条1項"

140 )

141 return True

142

143 def validate_parent(self, parent: Person, has_first_rank: bool) -> bool:

144 """

145 直系尊属の相続資格を検証

146

147 民法889条1項1号：第1順位の相続人がいない場合のみ相続

148

149 Args:

150 parent: 直系尊属（父母、祖父母等）

151 has_first_rank: 第1順位の相続人が存在するか

152

153 Returns:

154 相続人として有効な場合True

155 """

156 if not self.is_valid_heir(parent):

157 return False

158

159 # 第1順位の相続人がいる場合は相続できない

160 if has_first_rank:

161 self.log_info(

162 "Parent cannot inherit (first rank heirs exist)",

163 parent=parent.name

164 )

165 return False

166

167 # 直系尊属は第2順位の相続人（民法889条1項1号）

168 self.log_operation(

169 "Validated parent",

170 parent=parent.name,

171 basis="民法889条1項1号"

172 )

173 return True

174

175 def validate_sibling(

176 self,

177 sibling: Person,

178 has_first_rank: bool,

179 has_second_rank: bool

180 ) -> bool:

181 """

182 兄弟姉妹の相続資格を検証

183

184 民法889条1項2号：第1順位、第2順位の相続人がいない場合のみ相続

185

186 Args:

187 sibling: 兄弟姉妹

188 has_first_rank: 第1順位の相続人が存在するか

189 has_second_rank: 第2順位の相続人が存在するか

190

191 Returns:

192 相続人として有効な場合True

193 """

194 if not self.is_valid_heir(sibling):

195 return False

196

197 # 第1順位または第2順位の相続人がいる場合は相続できない

198 if has_first_rank or has_second_rank:

199 self.log_info(

200 "Sibling cannot inherit (higher rank heirs exist)",

201 sibling=sibling.name

202 )

203 return False

204

205 # 兄弟姉妹は第3順位の相続人（民法889条1項2号）

206 self.log_operation(

207 "Validated sibling",

208 sibling=sibling.name,

209 basis="民法889条1項2号"

210 )

211 return True

212

213 def can_substitute(

214 self,

215 deceased_heir: Person,

216 substitute: Person,

217 rank: HeritageRank

218 ) -> bool:

219 """

220 代襲相続が可能かチェック

221

222 民法887条2項・3項：子の代襲相続（制限なし）

223 民法889条2項：兄弟姉妹の代襲相続（1代限り）

224

225 Args:

226 deceased_heir: 死亡した相続人（被代襲者）

227 substitute: 代襲相続人候補

228 rank: 相続順位

229

230 Returns:

231 代襲相続が可能な場合True

232 """

233 if self.decedent is None:

234 raise ValueError("Decedent must be set")

235

236 # 代襲相続人候補が生存していなければならない

237 if not substitute.is_alive:

238 return False

239

240 # 被代襲者が被相続人より先に死亡しているか、

241 # 相続欠格・相続廃除されている必要がある

242 valid_substitution_reason = (

243 (deceased_heir.death_date is not None and

244 self.decedent.death_date is not None and

245 deceased_heir.death_date < self.decedent.death_date) or

246 deceased_heir in self.disqualified_persons or

247 deceased_heir in self.disinherited_persons

248 )

249

250 if not valid_substitution_reason:

251 return False

252

253 # 相続放棄は代襲原因にならない

254 if deceased_heir in self.renounced_persons:

255 self.log_info(

256 "No substitution for renounced heir",

257 deceased=deceased_heir.name

258 )

259 return False

260

261 # 第1順位（子）の代襲：制限なし（民法887条2項・3項）

262 if rank == HeritageRank.FIRST:

263 self.log_operation(

264 "Substitution allowed for child",

265 substitute=substitute.name,

266 deceased=deceased_heir.name,

267 basis="民法887条2項・3項"

268 )

269 return True

270

271 # 第3順位（兄弟姉妹）の代襲：1代限り（民法889条2項）

272 if rank == HeritageRank.THIRD:

273 # 兄弟姉妹の子（甥・姪）までのみ代襲可能

274 self.log_operation(

275 "Substitution allowed for sibling (1 generation only)",

276 substitute=substitute.name,

277 deceased=deceased_heir.name,

278 basis="民法889条2項"

279 )

280 return True

281

282 return False

283

284 def get_substitution_type(self, rank: HeritageRank) -> SubstitutionType:

285 """

286 代襲相続のタイプを取得

287

288 Args:

289 rank: 相続順位

290

291 Returns:

292 代襲相続タイプ

293 """

294 if rank == HeritageRank.FIRST:

295 return SubstitutionType.CHILD

296 elif rank == HeritageRank.THIRD:

297 return SubstitutionType.SIBLING

298 else:

299 return SubstitutionType.NONE