SHase964
commited on
Commit
·
aaa46c0
1
Parent(s):
235098d
fix: チェックボックス
Browse files- report_creator_ui.py +56 -44
report_creator_ui.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
-
import html
|
| 2 |
-
import time
|
| 3 |
from dataclasses import dataclass
|
| 4 |
from datetime import datetime, timedelta
|
| 5 |
from enum import Enum
|
|
|
|
|
|
|
| 6 |
from typing import ClassVar
|
| 7 |
|
| 8 |
import gradio as gr
|
|
@@ -60,34 +60,34 @@ class ReportCreatorUI:
|
|
| 60 |
"latest_period": 36,
|
| 61 |
"latest_year": 2023,
|
| 62 |
"settlement_month": 3,
|
| 63 |
-
"settlement_period": "4月1日〜3月31日"
|
| 64 |
},
|
| 65 |
"祖師ヶ谷大蔵パーク・ホームズ": {
|
| 66 |
"latest_period": 28,
|
| 67 |
"latest_year": 2023,
|
| 68 |
"settlement_month": 6,
|
| 69 |
-
"settlement_period": "7月1日〜6月30日"
|
| 70 |
},
|
| 71 |
"パークシティ弦巻": {
|
| 72 |
"latest_period": 24,
|
| 73 |
"latest_year": 2023,
|
| 74 |
"settlement_month": 6,
|
| 75 |
-
"settlement_period": "7月1日〜6月30日"
|
| 76 |
},
|
| 77 |
"パークホームズ学芸大学グレーススクエア": {
|
| 78 |
"latest_period": 13,
|
| 79 |
"latest_year": 2023,
|
| 80 |
"settlement_month": 3,
|
| 81 |
-
"settlement_period": "4月1日〜3月31日"
|
| 82 |
},
|
| 83 |
"パーク・ノヴァ猿江恩賜公園": {
|
| 84 |
"latest_period": 34,
|
| 85 |
"latest_year": 2023,
|
| 86 |
"settlement_month": 6,
|
| 87 |
-
"settlement_period": "7月1日〜6月30日"
|
| 88 |
-
}
|
| 89 |
}
|
| 90 |
-
|
| 91 |
# 物件名の候補リスト(辞書のキーから生成)
|
| 92 |
BUKKEN_CHOICES: ClassVar[list[str]] = list(BUKKEN_DATA.keys())
|
| 93 |
|
|
@@ -399,40 +399,60 @@ class ReportCreatorUI:
|
|
| 399 |
def _validate_period_input(self, period_text: str, bukken_name: str) -> tuple[str, str, str, str]:
|
| 400 |
"""期数入力のバリデーションと期間計算"""
|
| 401 |
if not period_text.strip():
|
| 402 |
-
return
|
| 403 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 404 |
try:
|
| 405 |
period = int(period_text)
|
| 406 |
except ValueError:
|
| 407 |
-
return
|
| 408 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 409 |
if period <= 0:
|
| 410 |
-
return
|
| 411 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
# 物件データから最新期数を取得
|
| 413 |
if bukken_name in self.BUKKEN_DATA:
|
| 414 |
latest_period = self.BUKKEN_DATA[bukken_name]["latest_period"]
|
| 415 |
if period > latest_period:
|
| 416 |
-
return
|
| 417 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 418 |
# 決算期間を計算
|
| 419 |
settlement_month = self.BUKKEN_DATA[bukken_name]["settlement_month"]
|
| 420 |
latest_year = self.BUKKEN_DATA[bukken_name]["latest_year"]
|
| 421 |
-
|
| 422 |
# 期数から年度を計算(最新期数と最新年度から逆算)
|
| 423 |
year_diff = latest_period - period
|
| 424 |
target_year = latest_year - year_diff
|
| 425 |
-
|
| 426 |
if settlement_month == 3: # 3月決算
|
| 427 |
start_date = f"{target_year}年4月1日"
|
| 428 |
end_date = f"{target_year + 1}年3月31日"
|
| 429 |
else: # 6月決算
|
| 430 |
start_date = f"{target_year}年7月1日"
|
| 431 |
end_date = f"{target_year + 1}年6月30日"
|
| 432 |
-
|
| 433 |
period_info = f"{start_date} 〜 {end_date}"
|
| 434 |
return gr.update(), gr.update(value="", visible=False), gr.update(value=period_info, visible=True)
|
| 435 |
-
|
| 436 |
return gr.update(), gr.update(value="", visible=False), gr.update(value="", visible=True)
|
| 437 |
|
| 438 |
def _get_custom_css(self) -> str:
|
|
@@ -927,20 +947,12 @@ class ReportCreatorUI:
|
|
| 927 |
gr.Markdown("期")
|
| 928 |
with gr.Column(scale=8, min_width=300):
|
| 929 |
# 期数情報表示エリア(常に表示、内容は動的に変更)
|
| 930 |
-
self.period_info = gr.Markdown(
|
| 931 |
-
value="",
|
| 932 |
-
visible=True,
|
| 933 |
-
elem_classes=["period-info"]
|
| 934 |
-
)
|
| 935 |
with gr.Row():
|
| 936 |
with gr.Column(scale=1.3, min_width=1):
|
| 937 |
gr.Markdown("")
|
| 938 |
with gr.Column(scale=4, min_width=1):
|
| 939 |
-
self.period_alert = gr.Markdown(
|
| 940 |
-
value="",
|
| 941 |
-
visible=False,
|
| 942 |
-
elem_classes=["period-alert"]
|
| 943 |
-
)
|
| 944 |
with gr.Row():
|
| 945 |
with gr.Column(scale=0.3, min_width=1):
|
| 946 |
gr.Markdown("")
|
|
@@ -1971,7 +1983,6 @@ class ReportCreatorUI:
|
|
| 1971 |
outputs=[self.attendance_submission_alert],
|
| 1972 |
)
|
| 1973 |
|
| 1974 |
-
|
| 1975 |
def _update_all_rows(self):
|
| 1976 |
"""全ての行を更新"""
|
| 1977 |
updates = []
|
|
@@ -2223,6 +2234,9 @@ class ReportCreatorUI:
|
|
| 2223 |
|
| 2224 |
def _prepare_content_generation(self):
|
| 2225 |
"""本文生成の準備"""
|
|
|
|
|
|
|
|
|
|
| 2226 |
time.sleep(1)
|
| 2227 |
|
| 2228 |
# 各議案の本文を生成 (初回のみ)
|
|
@@ -2459,7 +2473,7 @@ class ReportCreatorUI:
|
|
| 2459 |
elem_classes = ["resolution-conflict", "small-dropdown"]
|
| 2460 |
else: # 普通決議
|
| 2461 |
elem_classes = ["resolution-normal", "small-dropdown"]
|
| 2462 |
-
|
| 2463 |
return gr.Dropdown(elem_classes=elem_classes)
|
| 2464 |
|
| 2465 |
def _on_resolution_change(self, agenda_index: int, value: str):
|
|
@@ -2477,7 +2491,7 @@ class ReportCreatorUI:
|
|
| 2477 |
|
| 2478 |
# ボタンのタイトルを更新
|
| 2479 |
button_update = self._update_button_title(agenda_index, value)
|
| 2480 |
-
|
| 2481 |
# ドロップダウンのクラスを更新
|
| 2482 |
dropdown_update = self._update_dropdown_class(value)
|
| 2483 |
|
|
@@ -2818,20 +2832,16 @@ class ReportCreatorUI:
|
|
| 2818 |
if not selected:
|
| 2819 |
print("DEBUG: No selection, returning empty values")
|
| 2820 |
return "", "", "", gr.update(), gr.update()
|
| 2821 |
-
|
| 2822 |
# 選択された値を各フィールドに反映
|
| 2823 |
keiyaku_name = f"{selected}管理組合"
|
| 2824 |
print(f"DEBUG: Setting selected_bukken='{selected}', keiyaku_name='{keiyaku_name}'")
|
| 2825 |
-
|
| 2826 |
# 期数が入力されている場合は期間情報も更新
|
| 2827 |
if period_text.strip():
|
| 2828 |
_, alert_update, info_update = self._validate_period_input(period_text, selected)
|
| 2829 |
return selected, keiyaku_name, selected, alert_update, info_update
|
| 2830 |
-
|
| 2831 |
-
return selected, keiyaku_name, selected, gr.update(), gr.update()
|
| 2832 |
-
|
| 2833 |
-
|
| 2834 |
-
|
| 2835 |
|
| 2836 |
def _generate_word(self) -> str:
|
| 2837 |
"""Word出力"""
|
|
@@ -3139,7 +3149,7 @@ class ReportCreatorUI:
|
|
| 3139 |
print(f"Time comparison error: {e}")
|
| 3140 |
return gr.Markdown(value="", visible=False)
|
| 3141 |
|
| 3142 |
-
def _check_document_distribution_date(self, distribution_date, meeting_date):
|
| 3143 |
"""議案書配布日が開催日の1週間以上前かチェック"""
|
| 3144 |
try:
|
| 3145 |
# 日付が空の場合はアラートを非表示
|
|
@@ -3173,7 +3183,7 @@ class ReportCreatorUI:
|
|
| 3173 |
print(f"Document distribution date error: {e}")
|
| 3174 |
return gr.Markdown(value="", visible=False)
|
| 3175 |
|
| 3176 |
-
def _check_attendance_deadline(self, attendance_deadline, meeting_date):
|
| 3177 |
"""出席届の提出期限が開催日の1週間以上前かチェック"""
|
| 3178 |
try:
|
| 3179 |
# 日付が空の場合はアラートを非表示
|
|
@@ -3196,7 +3206,9 @@ class ReportCreatorUI:
|
|
| 3196 |
one_week_later = attendance_deadline_dt + timedelta(days=7)
|
| 3197 |
if one_week_later >= meeting_dt:
|
| 3198 |
days_diff = (meeting_dt - attendance_deadline_dt).days
|
| 3199 |
-
alert_message =
|
|
|
|
|
|
|
| 3200 |
return gr.Markdown(value=alert_message, visible=True, elem_classes=["date-alert"])
|
| 3201 |
return gr.Markdown(value="", visible=False)
|
| 3202 |
|
|
|
|
|
|
|
|
|
|
| 1 |
from dataclasses import dataclass
|
| 2 |
from datetime import datetime, timedelta
|
| 3 |
from enum import Enum
|
| 4 |
+
import html
|
| 5 |
+
import time
|
| 6 |
from typing import ClassVar
|
| 7 |
|
| 8 |
import gradio as gr
|
|
|
|
| 60 |
"latest_period": 36,
|
| 61 |
"latest_year": 2023,
|
| 62 |
"settlement_month": 3,
|
| 63 |
+
"settlement_period": "4月1日〜3月31日",
|
| 64 |
},
|
| 65 |
"祖師ヶ谷大蔵パーク・ホームズ": {
|
| 66 |
"latest_period": 28,
|
| 67 |
"latest_year": 2023,
|
| 68 |
"settlement_month": 6,
|
| 69 |
+
"settlement_period": "7月1日〜6月30日",
|
| 70 |
},
|
| 71 |
"パークシティ弦巻": {
|
| 72 |
"latest_period": 24,
|
| 73 |
"latest_year": 2023,
|
| 74 |
"settlement_month": 6,
|
| 75 |
+
"settlement_period": "7月1日〜6月30日",
|
| 76 |
},
|
| 77 |
"パークホームズ学芸大学グレーススクエア": {
|
| 78 |
"latest_period": 13,
|
| 79 |
"latest_year": 2023,
|
| 80 |
"settlement_month": 3,
|
| 81 |
+
"settlement_period": "4月1日〜3月31日",
|
| 82 |
},
|
| 83 |
"パーク・ノヴァ猿江恩賜公園": {
|
| 84 |
"latest_period": 34,
|
| 85 |
"latest_year": 2023,
|
| 86 |
"settlement_month": 6,
|
| 87 |
+
"settlement_period": "7月1日〜6月30日",
|
| 88 |
+
},
|
| 89 |
}
|
| 90 |
+
|
| 91 |
# 物件名の候補リスト(辞書のキーから生成)
|
| 92 |
BUKKEN_CHOICES: ClassVar[list[str]] = list(BUKKEN_DATA.keys())
|
| 93 |
|
|
|
|
| 399 |
def _validate_period_input(self, period_text: str, bukken_name: str) -> tuple[str, str, str, str]:
|
| 400 |
"""期数入力のバリデーションと期間計算"""
|
| 401 |
if not period_text.strip():
|
| 402 |
+
return (
|
| 403 |
+
gr.update(),
|
| 404 |
+
gr.update(value="", visible=False),
|
| 405 |
+
gr.update(value="", visible=True),
|
| 406 |
+
gr.update(value="", visible=True),
|
| 407 |
+
)
|
| 408 |
+
|
| 409 |
try:
|
| 410 |
period = int(period_text)
|
| 411 |
except ValueError:
|
| 412 |
+
return (
|
| 413 |
+
gr.update(),
|
| 414 |
+
gr.update(value="⚠️ 不適切なデータです", visible=True),
|
| 415 |
+
gr.update(value="", visible=True),
|
| 416 |
+
gr.update(value="", visible=True),
|
| 417 |
+
)
|
| 418 |
+
|
| 419 |
if period <= 0:
|
| 420 |
+
return (
|
| 421 |
+
gr.update(),
|
| 422 |
+
gr.update(value="⚠️ 不適切なデータです", visible=True),
|
| 423 |
+
gr.update(value="", visible=True),
|
| 424 |
+
gr.update(value="", visible=True),
|
| 425 |
+
)
|
| 426 |
+
|
| 427 |
# 物件データから最新期数を取得
|
| 428 |
if bukken_name in self.BUKKEN_DATA:
|
| 429 |
latest_period = self.BUKKEN_DATA[bukken_name]["latest_period"]
|
| 430 |
if period > latest_period:
|
| 431 |
+
return (
|
| 432 |
+
gr.update(),
|
| 433 |
+
gr.update(value="⚠️ 記入した期数のデータがありません", visible=True),
|
| 434 |
+
gr.update(value="", visible=True),
|
| 435 |
+
gr.update(value="", visible=True),
|
| 436 |
+
)
|
| 437 |
+
|
| 438 |
# 決算期間を計算
|
| 439 |
settlement_month = self.BUKKEN_DATA[bukken_name]["settlement_month"]
|
| 440 |
latest_year = self.BUKKEN_DATA[bukken_name]["latest_year"]
|
| 441 |
+
|
| 442 |
# 期数から年度を計算(最新期数と最新年度から逆算)
|
| 443 |
year_diff = latest_period - period
|
| 444 |
target_year = latest_year - year_diff
|
| 445 |
+
|
| 446 |
if settlement_month == 3: # 3月決算
|
| 447 |
start_date = f"{target_year}年4月1日"
|
| 448 |
end_date = f"{target_year + 1}年3月31日"
|
| 449 |
else: # 6月決算
|
| 450 |
start_date = f"{target_year}年7月1日"
|
| 451 |
end_date = f"{target_year + 1}年6月30日"
|
| 452 |
+
|
| 453 |
period_info = f"{start_date} 〜 {end_date}"
|
| 454 |
return gr.update(), gr.update(value="", visible=False), gr.update(value=period_info, visible=True)
|
| 455 |
+
|
| 456 |
return gr.update(), gr.update(value="", visible=False), gr.update(value="", visible=True)
|
| 457 |
|
| 458 |
def _get_custom_css(self) -> str:
|
|
|
|
| 947 |
gr.Markdown("期")
|
| 948 |
with gr.Column(scale=8, min_width=300):
|
| 949 |
# 期数情報表示エリア(常に表示、内容は動的に変更)
|
| 950 |
+
self.period_info = gr.Markdown(value="", visible=True, elem_classes=["period-info"])
|
|
|
|
|
|
|
|
|
|
|
|
|
| 951 |
with gr.Row():
|
| 952 |
with gr.Column(scale=1.3, min_width=1):
|
| 953 |
gr.Markdown("")
|
| 954 |
with gr.Column(scale=4, min_width=1):
|
| 955 |
+
self.period_alert = gr.Markdown(value="", visible=False, elem_classes=["period-alert"])
|
|
|
|
|
|
|
|
|
|
|
|
|
| 956 |
with gr.Row():
|
| 957 |
with gr.Column(scale=0.3, min_width=1):
|
| 958 |
gr.Markdown("")
|
|
|
|
| 1983 |
outputs=[self.attendance_submission_alert],
|
| 1984 |
)
|
| 1985 |
|
|
|
|
| 1986 |
def _update_all_rows(self):
|
| 1987 |
"""全ての行を更新"""
|
| 1988 |
updates = []
|
|
|
|
| 2234 |
|
| 2235 |
def _prepare_content_generation(self):
|
| 2236 |
"""本文生成の準備"""
|
| 2237 |
+
# Step3に入る時は確実にチェック状態をクリア
|
| 2238 |
+
self.state.checked_agendas.clear()
|
| 2239 |
+
|
| 2240 |
time.sleep(1)
|
| 2241 |
|
| 2242 |
# 各議案の本文を生成 (初回のみ)
|
|
|
|
| 2473 |
elem_classes = ["resolution-conflict", "small-dropdown"]
|
| 2474 |
else: # 普通決議
|
| 2475 |
elem_classes = ["resolution-normal", "small-dropdown"]
|
| 2476 |
+
|
| 2477 |
return gr.Dropdown(elem_classes=elem_classes)
|
| 2478 |
|
| 2479 |
def _on_resolution_change(self, agenda_index: int, value: str):
|
|
|
|
| 2491 |
|
| 2492 |
# ボタンのタイトルを更新
|
| 2493 |
button_update = self._update_button_title(agenda_index, value)
|
| 2494 |
+
|
| 2495 |
# ドロップダウンのクラスを更新
|
| 2496 |
dropdown_update = self._update_dropdown_class(value)
|
| 2497 |
|
|
|
|
| 2832 |
if not selected:
|
| 2833 |
print("DEBUG: No selection, returning empty values")
|
| 2834 |
return "", "", "", gr.update(), gr.update()
|
| 2835 |
+
|
| 2836 |
# 選択された値を各フィールドに反映
|
| 2837 |
keiyaku_name = f"{selected}管理組合"
|
| 2838 |
print(f"DEBUG: Setting selected_bukken='{selected}', keiyaku_name='{keiyaku_name}'")
|
| 2839 |
+
|
| 2840 |
# 期数が入力されている場合は期間情報も更新
|
| 2841 |
if period_text.strip():
|
| 2842 |
_, alert_update, info_update = self._validate_period_input(period_text, selected)
|
| 2843 |
return selected, keiyaku_name, selected, alert_update, info_update
|
| 2844 |
+
return selected, keiyaku_name, selected, gr.update(), gr.update()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2845 |
|
| 2846 |
def _generate_word(self) -> str:
|
| 2847 |
"""Word出力"""
|
|
|
|
| 3149 |
print(f"Time comparison error: {e}")
|
| 3150 |
return gr.Markdown(value="", visible=False)
|
| 3151 |
|
| 3152 |
+
def _check_document_distribution_date(self, distribution_date, meeting_date): # TODO: 下と統合できる
|
| 3153 |
"""議案書配布日が開催日の1週間以上前かチェック"""
|
| 3154 |
try:
|
| 3155 |
# 日付が空の場合はアラートを非表示
|
|
|
|
| 3183 |
print(f"Document distribution date error: {e}")
|
| 3184 |
return gr.Markdown(value="", visible=False)
|
| 3185 |
|
| 3186 |
+
def _check_attendance_deadline(self, attendance_deadline, meeting_date): # TODO: 上と統合できる
|
| 3187 |
"""出席届の提出期限が開催日の1週間以上前かチェック"""
|
| 3188 |
try:
|
| 3189 |
# 日付が空の場合はアラートを非表示
|
|
|
|
| 3206 |
one_week_later = attendance_deadline_dt + timedelta(days=7)
|
| 3207 |
if one_week_later >= meeting_dt:
|
| 3208 |
days_diff = (meeting_dt - attendance_deadline_dt).days
|
| 3209 |
+
alert_message = (
|
| 3210 |
+
f"⚠️ 出席届の提出期限から開催日まで{days_diff}日しかありません(1週間以上前の提出が必要です)"
|
| 3211 |
+
)
|
| 3212 |
return gr.Markdown(value=alert_message, visible=True, elem_classes=["date-alert"])
|
| 3213 |
return gr.Markdown(value="", visible=False)
|
| 3214 |
|