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

1"""Neo4jサービス

2

3相続計算結果をNeo4jに保存するサービス。

4"""

5 from typing import List, Dict

6 from datetime import date

7 import logging

8

9 from ..database.neo4j_client import Neo4jClient

10 from ..database.repositories import PersonRepository, RelationshipRepository

11 from ..models.person import Person

12 from ..models.relationship import BloodType

13 from ..models.inheritance import InheritanceResult

14 from ..utils.exceptions import DatabaseException

15

16

17 class Neo4jService:

18 """

19 Neo4jデータ保存サービス

20

21 相続計算に使用した人物情報と関係性をNeo4jに保存する。

22 """

23

24 def __init__(self, client: Neo4jClient) -> None:

25 """

26 初期化

27

28 Args:

29 client: Neo4jクライアント

30 """

31 self.client = client

32 self.person_repo = PersonRepository(client)

33 self.relationship_repo = RelationshipRepository(client)

34 self.logger = logging.getLogger(__name__)

35

36 def save_inheritance_case(

37 self,

38 decedent: Person,

39 spouses: List[Person],

40 children: List[Person],

41 parents: List[Person],

42 siblings: List[Person],

43 renounced: List[Person],

44 disqualified: List[Person],

45 disinherited: List[Person],

46 sibling_blood_types: Dict[str, BloodType],

47 result: InheritanceResult

48 ) -> None:

49 """

50 相続ケースをNeo4jに保存

51

52 Args:

53 decedent: 被相続人

54 spouses: 配偶者リスト

55 children: 子リスト

56 parents: 直系尊属リスト

57 siblings: 兄弟姉妹リスト

58 renounced: 相続放棄者リスト

59 disqualified: 相続欠格者リスト

60 disinherited: 相続廃除者リスト

61 sibling_blood_types: 兄弟姉妹の血縁タイプ

62 result: 計算結果

63

64 Raises:

65 DatabaseException: 保存に失敗した場合

66 """

67 try:

68 with self.client.transaction():

69 # 被相続人を保存

70 self.logger.info(f"Saving decedent: {decedent.name}")

71 self.person_repo.create(decedent)

72

73 # 配偶者を保存

74 for spouse in spouses:

75 self.logger.info(f"Saving spouse: {spouse.name}")

76 self.person_repo.create(spouse)

77 self.relationship_repo.create_spouse_of(

78 person1_name=decedent.name,

79 person2_name=spouse.name,

80 is_current=True

81 )

82

83 # 子を保存

84 for child in children:

85 self.logger.info(f"Saving child: {child.name}")

86 self.person_repo.create(child)

87 self.relationship_repo.create_child_of(

88 child_name=child.name,

89 parent_name=decedent.name

90 )

91

92 # 直系尊属を保存

93 for parent in parents:

94 self.logger.info(f"Saving parent: {parent.name}")

95 self.person_repo.create(parent)

96 self.relationship_repo.create_child_of(

97 child_name=decedent.name,

98 parent_name=parent.name

99 )

100

101 # 兄弟姉妹を保存

102 for sibling in siblings:

103 self.logger.info(f"Saving sibling: {sibling.name}")

104 self.person_repo.create(sibling)

105 blood_type = sibling_blood_types.get(sibling.name, BloodType.FULL)

106 self.relationship_repo.create_sibling_of(

107 person1_name=decedent.name,

108 person2_name=sibling.name,

109 blood_type=blood_type

110 )

111

112 # 相続放棄者を保存

113 for person in renounced:

114 self.logger.info(f"Saving renounced: {person.name}")

115 # 既に人物ノードが存在する可能性があるため、存在チェック

116 if not self.person_repo.find_by_name(person.name):

117 self.person_repo.create(person)

118

119 # 放棄日は被相続人の死亡日、またはデフォルト値を使用

120 renounce_date = decedent.death_date if decedent.death_date is not None else date.today()

121

122 self.relationship_repo.create_renounced(

123 person_name=person.name,

124 decedent_name=decedent.name,

125 renounce_date=renounce_date

126 )

127

128 self.logger.info("Successfully saved inheritance case to Neo4j")

129

130 except Exception as e:

131 self.logger.error(f"Failed to save inheritance case: {e}", exc_info=True)

132 raise DatabaseException(f"Neo4j保存エラー: {str(e)}")

133

134 def clear_all_data(self) -> None:

135 """

136 全データを削除（テスト用）

137

138 Warning:

139 本番環境では使用しないこと

140 """

141 self.logger.warning("Clearing all data from Neo4j")

142 self.client.clear_database()