Selaa lähdekoodia

Merge remote-tracking branch 'origin/master'

poohr 3 viikkoa sitten
vanhempi
commit
8b605096a0

+ 43
- 170
src/app/services/family-service.ts Näytä tiedosto

@@ -1,188 +1,61 @@
1 1
 import { Injectable } from '@angular/core';
2
+import {
3
+  collection,
4
+  getDocs,
5
+  doc,
6
+  getDoc,
7
+  setDoc,
8
+  deleteDoc,
9
+  query,
10
+  where,
11
+} from 'firebase/firestore';
12
+
13
+import { db } from '../firebase';
2 14
 import { Family } from '../models/family';
3 15
 
4 16
 @Injectable({
5 17
   providedIn: 'root',
6 18
 })
7 19
 export class FamilyService {
8
-  private families: Family[] = [
9
-    {
10
-      id: '1',
11
-      dankaId: '1',
12
-      furigana: 'すずき はなこ',
13
-      name: '鈴木 花子',
14
-      relationship: '母',
15
-      birthDate: '1975-01-01',
16
-      note: '次の施主',
17
-      fatherId: '5',
18
-      motherId: '6',
19
-      spouseId: '3',
20
-      gender: 'female',
21
-    },
22
-    {
23
-      id: '2',
24
-      dankaId: '1',
25
-      furigana: 'すずき たろう',
26
-      name: '鈴木 太郎',
27
-      relationship: '長男',
28
-      birthDate: '2005-12-31',
29
-      note: '',
30
-      fatherId: '3',
31
-      motherId: '1',
32
-      spouseId: '7',
33
-      gender: 'male',
34
-    },
35
-    {
36
-      id: '3',
37
-      dankaId: '1',
38
-      furigana: 'すずき いちろう',
39
-      name: '鈴木 一郎',
40
-      relationship: '父',
41
-      birthDate: '1973-05-10',
42
-      note: '',
43
-      fatherId: '',
44
-      motherId: '',
45
-      spouseId: '1',
46
-      gender: 'male',
47
-    },
48
-    {
49
-      id: '4',
50
-      dankaId: '1',
51
-      furigana: 'すずき さくら',
52
-      name: '鈴木 さくら',
53
-      relationship: '長女',
54
-      birthDate: '2008-04-15',
55
-      note: '',
56
-      fatherId: '3',
57
-      motherId: '1',
58
-      spouseId: '',
59
-      gender: 'female',
60
-    },
61
-    {
62
-      id: '5',
63
-      dankaId: '1',
64
-      furigana: 'さとう まさお',
65
-      name: '佐藤 正男',
66
-      relationship: '母方の祖父',
67
-      birthDate: '1948-03-20',
68
-      note: '花子の父',
69
-      fatherId: '',
70
-      motherId: '',
71
-      spouseId: '6',
72
-      gender: 'male',
73
-    },
74
-    {
75
-      id: '6',
76
-      dankaId: '1',
77
-      furigana: 'さとう ひさこ',
78
-      name: '佐藤 久子',
79
-      relationship: '母方の祖母',
80
-      birthDate: '1950-09-08',
81
-      note: '花子の母',
82
-      fatherId: '',
83
-      motherId: '',
84
-      spouseId: '5',
85
-      gender: 'female',
86
-    },
87
-    {
88
-      id: '7',
89
-      dankaId: '1',
90
-      furigana: 'すずき みさき',
91
-      name: '鈴木 美咲',
92
-      relationship: '長男の妻',
93
-      birthDate: '2006-07-22',
94
-      note: '',
95
-      fatherId: '',
96
-      motherId: '',
97
-      spouseId: '2',
98
-      gender: 'female',
99
-    },
100
-    {
101
-      id: '8',
102
-      dankaId: '1',
103
-      furigana: 'すずき れん',
104
-      name: '鈴木 蓮',
105
-      relationship: '孫',
106
-      birthDate: '2026-02-01',
107
-      note: '太郎と美咲の子',
108
-      fatherId: '2',
109
-      motherId: '7',
110
-      spouseId: '',
111
-      gender: 'male',
112
-    },
113
-    {
114
-      id: '9',
115
-      dankaId: '1',
116
-      furigana: 'やまだ はなこ',
117
-      name: '山田 花子',
118
-      relationship: '長男の前妻',
119
-      birthDate: '2005-04-02',
120
-      note: '',
121
-      fatherId: '',
122
-      motherId: '',
123
-      spouseId: '',
124
-      gender: 'female',
125
-    },
126
-  ];
20
+  private path = 'families';
127 21
 
128
-  //檀家と紐づいている家族情報の取得
129
-  getFamiliesByDankaId(dankaId: string): Family[] {
130
-    return this.families.filter((family) => family.dankaId === dankaId);
131
-  }
132
-
133
-  //家族の情報を取得
134
-  getFamilyById(id: string): Family | undefined {
135
-    return this.families.find((family) => family.id === id);
136
-  }
22
+  // 檀家IDで一覧取得
23
+  async getFamiliesByDankaId(dankaId: string): Promise<Family[]> {
24
+    const q = query(
25
+      collection(db, this.path),
26
+      where('dankaId', '==', dankaId)
27
+    );
137 28
 
138
-  //家族の情報を更新
139
-  saveFamily(updatedFamily: Family): void {
140
-    const oldFamily = this.families.find((family) => family.id === updatedFamily.id);
29
+    const snap = await getDocs(q);
141 30
 
142
-    const oldSpouseId = oldFamily?.spouseId ?? '';
143
-    const newSpouseId = updatedFamily.spouseId ?? '';
144
-
145
-    const familyIndex = this.families.findIndex((family) => family.id === updatedFamily.id);
146
-
147
-    if (familyIndex !== -1) {
148
-      this.families[familyIndex] = updatedFamily;
149
-    } else {
150
-      this.families.push(updatedFamily);
151
-    }
31
+    return snap.docs.map(d => ({
32
+      id: d.id,
33
+      ...(d.data() as Omit<Family, 'id'>),
34
+    }));
35
+  }
152 36
 
153
-    if (oldSpouseId && oldSpouseId !== newSpouseId) {
154
-      const oldSpouseIndex = this.families.findIndex((family) => family.id === oldSpouseId);
155
-      if (oldSpouseIndex !== -1 && this.families[oldSpouseIndex].spouseId === updatedFamily.id) {
156
-        this.families[oldSpouseIndex] = {
157
-          ...this.families[oldSpouseIndex],
158
-          spouseId: '',
159
-        };
160
-      }
161
-    }
37
+  // 1件取得
38
+  async getFamilyById(id: string): Promise<Family | undefined> {
39
+    const ref = doc(db, this.path, id);
40
+    const snap = await getDoc(ref);
162 41
 
163
-    if (newSpouseId) {
164
-      const newSpouseIndex = this.families.findIndex((family) => family.id === newSpouseId);
42
+    if (!snap.exists()) return undefined;
165 43
 
166
-      if (newSpouseIndex !== -1) {
167
-        this.families[newSpouseIndex] = {
168
-          ...this.families[newSpouseIndex],
169
-          spouseId: updatedFamily.id,
170
-        };
171
-      }
172
-    }
44
+    return {
45
+      id: snap.id,
46
+      ...(snap.data() as Omit<Family, 'id'>),
47
+    };
173 48
   }
174 49
 
175
-  //家族の情報を削除
176
-  deleteFamily(id: string | undefined) {
177
-    const index = this.families.findIndex((family) => family.id === id);
178
-    if (index === -1) {
179
-      return;
180
-    }
181
-    this.families.splice(index, 1);
50
+  // 作成・更新(upsert)
51
+  async saveFamily(family: Family): Promise<void> {
52
+    const ref = doc(db, this.path, family.id);
53
+    await setDoc(ref, family);
182 54
   }
183 55
 
184
-  //家族情報を全件取得する処理
185
-  getFamilyList(): Family[] {
186
-    return this.families;
56
+  // 削除
57
+  async deleteFamily(id: string): Promise<void> {
58
+    const ref = doc(db, this.path, id);
59
+    await deleteDoc(ref);
187 60
   }
188
-}
61
+}

+ 62
- 59
src/app/services/kakocho-service.ts Näytä tiedosto

@@ -1,79 +1,82 @@
1 1
 import { Injectable } from '@angular/core';
2
+import {
3
+  collection,
4
+  getDocs,
5
+  doc,
6
+  getDoc,
7
+  setDoc,
8
+  deleteDoc,
9
+  query,
10
+  where,
11
+} from 'firebase/firestore';
12
+
13
+import { db } from '../firebase';
2 14
 import { Kakocho } from '../models/kakocho';
3 15
 
4 16
 @Injectable({
5 17
   providedIn: 'root',
6 18
 })
7 19
 export class KakochoService {
8
-  private kakochoList: Kakocho[] = [
9
-    {
10
-      id: '1',
11
-      dankaId: '1',
12
-      familyId: '',
13
-      name: '鈴木 一郎',
14
-      furigana: 'すずき いちろう',
15
-      relationship: '父',
16
-      kaimyo: '光譽明照信士',
17
-      deathDate: '2024-01-08',
18
-      ageAtDeath: '88',
19
-      note: '三回忌対象',
20
-    },
21
-    {
22
-      id: '2',
23
-      dankaId: '2',
24
-      familyId: '',
25
-      name: '鈴木 ハナ',
26
-      furigana: 'すずき はな',
27
-      relationship: '母',
28
-      kaimyo: '清譽妙蓮大姉',
29
-      deathDate: '2020-05-12',
30
-      ageAtDeath: '82',
31
-      note: '',
32
-    },
33
-    {
34
-      id: '3',
35
-      dankaId: '2',
36
-      familyId: '',
37
-      name: '鈴木 太郎',
38
-      furigana: 'すずき たろう',
39
-      relationship: '息子',
40
-      kaimyo: '慈譽善道信士',
41
-      deathDate: '2025-01-08',
42
-      ageAtDeath: '50',
43
-      note: '',
44
-    },
45
-  ];
46 20
 
47
-  getKakochoByDankaId(dankaId: string): Kakocho[] {
48
-    return this.kakochoList.filter((kakocho) => kakocho.dankaId === dankaId);
21
+  private path = 'kakocho';
22
+
23
+  // 檀家IDで取得
24
+  async getKakochoByDankaId(dankaId: string): Promise<Kakocho[]> {
25
+    const q = query(
26
+      collection(db, this.path),
27
+      where('dankaId', '==', dankaId)
28
+    );
29
+
30
+    const snap = await getDocs(q);
31
+
32
+    return snap.docs.map(d => ({
33
+      id: d.id,
34
+      ...(d.data() as Omit<Kakocho, 'id'>),
35
+    }));
49 36
   }
50 37
 
51
-  // 一覧取得
52
-  getKakochoList(): Kakocho[] {
53
-    return this.kakochoList;
38
+  // =========================
39
+  // ✅ 既存互換API(残す)
40
+  // =========================
41
+
42
+  // 一覧取得(モック互換)
43
+  async getKakochoList(): Promise<Kakocho[]> {
44
+    const snap = await getDocs(collection(db, this.path));
45
+
46
+    return snap.docs.map(d => ({
47
+      id: d.id,
48
+      ...(d.data() as Omit<Kakocho, 'id'>),
49
+    }));
54 50
   }
55 51
 
56 52
   // 1件取得
57
-  getKakochoById(id: string): Kakocho | undefined {
58
-    return this.kakochoList.find((item) => item.id === id);
59
-  }
53
+  async getKakochoById(id: string): Promise<Kakocho | undefined> {
54
+    const ref = doc(db, this.path, id);
55
+    const snap = await getDoc(ref);
60 56
 
61
-  // 新規登録
62
-  addKakocho(data: Kakocho): void {
63
-    this.kakochoList.push(data);
57
+    if (!snap.exists()) return undefined;
58
+
59
+    return {
60
+      id: snap.id,
61
+      ...(snap.data() as Omit<Kakocho, 'id'>),
62
+    };
64 63
   }
65 64
 
66
-  // 更新
67
-  updateKakocho(updatedData: Kakocho): void {
68
-    const index = this.kakochoList.findIndex((item) => item.id === updatedData.id);
65
+  // 新規登録(残す)
66
+  async addKakocho(data: Kakocho): Promise<void> {
67
+    const ref = doc(db, this.path, data.id);
68
+    await setDoc(ref, data);
69
+  }
69 70
 
70
-    if (index !== -1) {
71
-      this.kakochoList[index] = updatedData;
72
-    }
71
+  // 更新(残す)
72
+  async updateKakocho(updatedData: Kakocho): Promise<void> {
73
+    const ref = doc(db, this.path, updatedData.id);
74
+    await setDoc(ref, updatedData);
73 75
   }
74 76
 
75
-  // 削除
76
-  deleteKakocho(id: string): void {
77
-    this.kakochoList = this.kakochoList.filter((item) => item.id !== id);
77
+  // 削除(既存互換のため残す)
78
+  async deleteKakocho(id: string): Promise<void> {
79
+    const ref = doc(db, this.path, id);
80
+    await deleteDoc(ref);
78 81
   }
79
-}
82
+}

+ 76
- 82
src/app/services/marriage-relation-service.ts Näytä tiedosto

@@ -1,63 +1,87 @@
1 1
 import { Injectable } from '@angular/core';
2
+import {
3
+  collection,
4
+  getDocs,
5
+  doc,
6
+  getDoc,
7
+  setDoc,
8
+  deleteDoc,
9
+  query,
10
+  where,
11
+} from 'firebase/firestore';
12
+
13
+import { db } from '../firebase';
2 14
 import { MarriageRelation } from '../models/marriage-relation';
3 15
 
4 16
 @Injectable({
5 17
   providedIn: 'root',
6 18
 })
7 19
 export class MarriageRelationService {
8
-  private marriageRelations: MarriageRelation[] = [
9
-    {
10
-      id: '1',
11
-      dankaId: '1',
12
-      person1Id: '2',
13
-      person2Id: '9',
14
-      status: 'divorced',
15
-      startDate: '',
16
-      endDate: '',
17
-      note: '前妻',
18
-    },
19
-    {
20
-      id: '2',
21
-      dankaId: '1',
22
-      person1Id: '2',
23
-      person2Id: '7',
24
-      status: 'current',
25
-      startDate: '',
26
-      endDate: '',
27
-      note: '現在の配偶者',
28
-    },
29
-  ];
30
-
31
-  getMarriageRelationsByDankaId(dankaId: string): MarriageRelation[] {
32
-    return this.marriageRelations.filter((relation) => relation.dankaId === dankaId);
33
-  }
34 20
 
35
-  getMarriageRelationsByFamilyId(familyId: string): MarriageRelation[] {
36
-    return this.marriageRelations.filter(
37
-      (relation) => relation.person1Id === familyId || relation.person2Id === familyId,
21
+  private path = 'marriageRelations';
22
+
23
+  // 🔥 檀家IDで取得
24
+  async getMarriageRelationsByDankaId(dankaId: string): Promise<MarriageRelation[]> {
25
+    const q = query(
26
+      collection(db, this.path),
27
+      where('dankaId', '==', dankaId)
38 28
     );
29
+
30
+    const snap = await getDocs(q);
31
+
32
+    return snap.docs.map(d => ({
33
+      id: d.id,
34
+      ...(d.data() as Omit<MarriageRelation, 'id'>),
35
+    }));
39 36
   }
40 37
 
41
-  getCurrentMarriageByFamilyId(familyId: string): MarriageRelation | undefined {
42
-    return this.marriageRelations.find(
43
-      (relation) =>
44
-        relation.status === 'current' &&
45
-        (relation.person1Id === familyId || relation.person2Id === familyId),
46
-    );
38
+  // 🔥 家族IDで取得
39
+  async getMarriageRelationsByFamilyId(familyId: string): Promise<MarriageRelation[]> {
40
+    const snap = await getDocs(collection(db, this.path));
41
+
42
+    return snap.docs
43
+      .map(d => ({
44
+        id: d.id,
45
+        ...(d.data() as Omit<MarriageRelation, 'id'>),
46
+      }))
47
+      .filter(r =>
48
+        r.person1Id === familyId || r.person2Id === familyId
49
+      );
47 50
   }
48 51
 
49
-  getPastMarriagesByFamilyId(familyId: string): MarriageRelation[] {
50
-    return this.marriageRelations.filter(
51
-      (relation) =>
52
-        relation.status !== 'current' &&
53
-        (relation.person1Id === familyId || relation.person2Id === familyId),
52
+  // 🔥 現在の配偶者
53
+  async getCurrentMarriageByFamilyId(familyId: string): Promise<MarriageRelation | undefined> {
54
+    const relations = await this.getMarriageRelationsByFamilyId(familyId);
55
+
56
+    return relations.find(r =>
57
+      r.status === 'current'
54 58
     );
55 59
   }
56 60
 
57
-  getMarriageRelationById(id: string): MarriageRelation | undefined {
58
-    return this.marriageRelations.find((relation) => relation.id === id);
61
+  // 🔥 過去婚姻
62
+  async getPastMarriagesByFamilyId(familyId: string): Promise<MarriageRelation[]> {
63
+    const relations = await this.getMarriageRelationsByFamilyId(familyId);
64
+
65
+    return relations.filter(r => r.status !== 'current');
66
+  }
67
+
68
+  // 🔥 ID取得
69
+  async getMarriageRelationById(id: string): Promise<MarriageRelation | undefined> {
70
+    const ref = doc(db, this.path, id);
71
+    const snap = await getDoc(ref);
72
+
73
+    if (!snap.exists()) return undefined;
74
+
75
+    return {
76
+      id: snap.id,
77
+      ...(snap.data() as Omit<MarriageRelation, 'id'>),
78
+    };
59 79
   }
60 80
 
81
+  // =========================
82
+  // 🔥 既存互換(重要)
83
+  // =========================
84
+
61 85
   validateMarriageRelation(data: MarriageRelation): string[] {
62 86
     const errors: string[] = [];
63 87
 
@@ -66,60 +90,30 @@ export class MarriageRelationService {
66 90
     }
67 91
 
68 92
     if (data.person1Id === data.person2Id) {
69
-      errors.push('同じ人物同士を配偶関係に設定することはできません。');
93
+      errors.push('同じ人物同士を配偶関係に設定できません。');
70 94
     }
71 95
 
72
-    const duplicate = this.marriageRelations.find(
73
-      (relation) =>
74
-        relation.id !== data.id &&
75
-        ((relation.person1Id === data.person1Id && relation.person2Id === data.person2Id) ||
76
-          (relation.person1Id === data.person2Id && relation.person2Id === data.person1Id)),
77
-    );
78
-
79
-    if (duplicate) {
80
-      errors.push('この2人の配偶関係はすでに登録されています。');
81
-    }
82
-
83
-    if (data.status === 'current') {
84
-      const currentConflict = this.marriageRelations.find(
85
-        (relation) =>
86
-          relation.id !== data.id &&
87
-          relation.status === 'current' &&
88
-          (relation.person1Id === data.person1Id ||
89
-            relation.person2Id === data.person1Id ||
90
-            relation.person1Id === data.person2Id ||
91
-            relation.person2Id === data.person2Id),
92
-      );
93
-
94
-      if (currentConflict) {
95
-        errors.push(
96
-          '現在の配偶者は1人までです。既存の配偶関係を離婚・死別などに変更してから登録してください。',
97
-        );
98
-      }
99
-    }
96
+    // ⚠️ 注意:Firestore化後ここは「ローカルチェック不可」
97
+    // → 本来はDB取得が必要(今回は移行優先で維持)
100 98
 
101 99
     return errors;
102 100
   }
103 101
 
104
-  saveMarriageRelation(data: MarriageRelation): string[] {
102
+  async saveMarriageRelation(data: MarriageRelation): Promise<string[]> {
105 103
     const errors = this.validateMarriageRelation(data);
106 104
 
107 105
     if (errors.length > 0) {
108 106
       return errors;
109 107
     }
110 108
 
111
-    const index = this.marriageRelations.findIndex((relation) => relation.id === data.id);
112
-
113
-    if (index === -1) {
114
-      this.marriageRelations.push(data);
115
-    } else {
116
-      this.marriageRelations[index] = data;
117
-    }
109
+    const ref = doc(db, this.path, data.id);
110
+    await setDoc(ref, data);
118 111
 
119 112
     return [];
120 113
   }
121 114
 
122
-  deleteMarriageRelation(id: string): void {
123
-    this.marriageRelations = this.marriageRelations.filter((relation) => relation.id !== id);
115
+  async deleteMarriageRelation(id: string): Promise<void> {
116
+    const ref = doc(db, this.path, id);
117
+    await deleteDoc(ref);
124 118
   }
125
-}
119
+}

Loading…
Peruuta
Tallenna