Record original-alignment implementation and traceability checkpoint

Capture current source, content data, tests, asset licenses, and original-specification traceability. Original implementation remains incomplete. The accepted matching UI generation passed 154 suites and 12,253 checks, with eight rendered staff-contract screens reviewed. Latest native Windows and full-original acceptance remain outstanding.
This commit is contained in:
Takeshi
2026-09-30 23:52:24 +09:00
parent 6077e02ebe
commit 5dde0c5ec2
490 changed files with 54051 additions and 809 deletions
+34 -9
View File
@@ -1,14 +1,16 @@
class_name BusinessManagementPanel
extends VBoxContainer
const LayerSkin := preload("res://scripts/ui/layer_interface_skin.gd")
## Policy drafts are local; accepted commands and read models belong to Runtime.
signal status_requested(message: String, success: bool)
signal action_requested(action: StringName)
const KEY_PREFIX := "ui.business."
const COMMAND: StringName = &"set_facility_policy"
const GUEST_POLICY_EXPLANATION := "料金変更は新規受付から。受付済みの料金は変わりません。\n休業すると待機中のお客様は別の施設を探します。開始済みのサービスは完了まで続きます。休業中も給与は発生します。"
const SUPPLY_POLICY_EXPLANATION := "休業中は調理と新しい補給を止めます。在庫と運搬中の荷物は保持し、積込済みの荷物は納品先の営業状況に従って配送します。消費期限は経過し、給与も発生します。"
const GUEST_POLICY_EXPLANATION := "料金変更は新規受付から。受付済みの料金は変わりません。\n休業すると待機中のお客様は別の施設を探します。開始済みのサービスは完了まで続きます。休業中も給与と施設維持費は発生します。"
const SUPPLY_POLICY_EXPLANATION := "休業中は調理と新しい補給を止めます。在庫と運搬中の荷物は保持し、積込済みの荷物は納品先の営業状況に従って配送します。消費期限は経過し、給与と施設維持費も発生します。"
const STATE_NAMES := {&"BROKEN": "故障中", &"NO_ACCESS": "経路なし", &"NO_POWER": "魔力不足", &"NO_STAFF": "職員不足", &"CLOSED": "休業中", &"DEGRADED": "状態悪化", &"OPEN": "稼働中"}
const REASONS := {
&"FACILITY_NOT_FOUND": "施設が見つかりません。選び直してください。",
@@ -53,7 +55,9 @@ func _ready() -> void:
_build_interface()
_built = true
if _runtime != null:
if _runtime.has_signal(&"snapshot_published"):
if _runtime.has_signal(&"state_updated"):
_runtime.connect(&"state_updated", _on_snapshot_published)
elif _runtime.has_signal(&"snapshot_published"):
_runtime.connect(&"snapshot_published", _on_snapshot_published)
if _runtime.has_signal(&"command_completed"):
_runtime.connect(&"command_completed", _on_command_completed)
@@ -85,6 +89,7 @@ func _build_interface() -> void:
for color_name: StringName in [&"font_color", &"font_pressed_color", &"font_hover_color", &"font_hover_pressed_color", &"font_focus_color"]:
business_open_button.add_theme_color_override(color_name, Color("55371e"))
business_open_button.add_theme_color_override("font_disabled_color", Color("766650"))
LayerSkin.register_toggle_text(business_open_button, LayerSkin.active_layer(self))
business_open_button.add_theme_font_size_override("font_size", 13)
business_open_button.toggled.connect(func(_enabled: bool) -> void: _store_draft())
add_child(business_open_button)
@@ -129,9 +134,13 @@ func refresh() -> void:
business_open_button.set_pressed_no_signal(bool(draft.get(&"business_open", true)))
var pending := _has_pending(selected_facility_id)
var can_price := bool(row.get(&"can_price", false))
var is_cleaning := StringName(row.get(&"definition_id", &"")) == &"cleaning_room"
var is_supply := StringName(row.get(&"definition_id", &"")) in [&"kitchen", &"warehouse"]
business_open_button.text = "営業する" if is_supply else "新規の受付を開く"
explanation_label.text = SUPPLY_POLICY_EXPLANATION if is_supply else GUEST_POLICY_EXPLANATION
if is_cleaning:
business_open_button.text = "清掃業務を有効にする"
explanation_label.text = "配置した清掃員が汚れた施設へ向かいます。清掃業務を無効にすると、途中の清掃も中断します。維持費と給与は継続します。"
facility_option.disabled = _rows(&"facilities").is_empty()
price_option.disabled = row.is_empty() or not can_price or pending or price_option.item_count == 0
business_open_button.disabled = row.is_empty() or pending
@@ -141,21 +150,36 @@ func refresh() -> void:
facility_status_label.text = "施設が完成すると営業を設定できます。"
quote_label.text = "施設を選んでください。"
effect_label.text = ""
if int(row.get(&"faith_per_service", 0)) > 0:
effect_label.text += "\n礼拝完了ごとに信仰+%d" % int(row[&"faith_per_service"])
today_label.text = "本日の実績はまだありません。"
else:
facility_status_label.text = "%s · %s\n待ち %d人 / 利用中 %d人" % [("営業する設定" if is_supply else "受付を開く設定") if bool(row.get(&"business_open", true)) else ("休業する設定" if is_supply else "新規受付を停止中"), String(STATE_NAMES.get(StringName(row.get(&"state", &"")), "状態確認中")), int(row.get(&"queued_count", 0)), int(row.get(&"active_count", 0))]
facility_status_label.text = "%s · %s\n待ち %d人 / 利用中 %d人\n同時利用上限 %s" % [("営業する設定" if is_supply else "受付を開く設定") if bool(row.get(&"business_open", true)) else ("休業する設定" if is_supply else "新規受付を停止中"), String(STATE_NAMES.get(StringName(row.get(&"state", &"")), "状態確認中")), int(row.get(&"queued_customer_count", 0)), int(row.get(&"active_customer_count", 0)), ("%d人" % int(row[&"customer_capacity"])) if int(row.get(&"customer_capacity", -1)) >= 0 else "未設定"]
if is_supply:
facility_status_label.text = "%s · %s\n保管・補給の状況は「商品」で確認。" % ["営業する設定" if bool(row.get(&"business_open", true)) else "休業する設定", String(STATE_NAMES.get(StringName(row.get(&"state", &"")), "状態確認中"))]
if is_cleaning:
facility_status_label.text = "%s · %s\n顧客利用なし・清掃員の業務拠点" % ["清掃業務を有効にする設定" if bool(row.get(&"business_open", true)) else "清掃業務を停止中", String(STATE_NAMES.get(StringName(row.get(&"state", &"")), "状態確認中"))]
if int(row.get(&"cleanliness", -1)) >= 0:
facility_status_label.text += "\n清潔度 %d / 100" % int(row[&"cleanliness"])
if not String(row.get(&"cleaning_status", "")).is_empty():
facility_status_label.text += "\n" + String(row[&"cleaning_status"])
if can_price:
var mode := StringName(draft.get(&"price_mode", &"standard"))
var quoted := FacilityPricing.quote(int(row.get(&"base_price", 0)), {&"price_mode": mode})
var unit := String({&"standard_room": "泊", &"cafeteria": "食"}.get(StringName(row.get(&"definition_id", &"")), "回"))
var quoted := FacilityPricing.apply_multiplier(FacilityPricing.quote(int(row.get(&"base_price", 0)), {&"price_mode": mode}) * int(row.get(&"donation_multiplier", 1)), int(row.get(&"floor_price_multiplier_bp", 10000)))
var unit := String({&"standard_room": "泊", &"premium_room": "泊", &"cafeteria": "食"}.get(StringName(row.get(&"definition_id", &"")), "回"))
quote_label.text = "設定後 %dG / %s\n現在 %dG · 標準 %dG" % [quoted, unit, int(row.get(&"price", 0)), int(row.get(&"base_price", 0))]
effect_label.text = _price_effect(mode)
if int(row.get(&"donation_multiplier", 1)) == 3:
effect_label.text += "\nアメリア配置:寄付金3倍"
if int(row.get(&"floor_price_multiplier_bp", 10000)) == 12000:
effect_label.text += "\nアンリ配置フロア:利用料金+20%"
else:
quote_label.text = "この施設に利用料金はありません。"
effect_label.text = "営業・休業を設定できます。" if is_supply else "受付の開閉だけを設定できます。"
today_label.text = "本日の記帳 · 06:00〜\n売上 %dG · 直接支出 %dG\n給与の配賦と利益は翌朝の帳簿で確認。" % [int(row.get(&"today_revenue", 0)), int(row.get(&"today_expenses", 0))]
if is_cleaning: effect_label.text = "清掃業務の有効・無効を設定できます。"
if int(row.get(&"faith_per_service", 0)) > 0:
effect_label.text += "\n礼拝完了ごとに信仰+%d" % int(row[&"faith_per_service"])
today_label.text = "本日の記帳 · 00:00〜\n売上 %dG · 直接支出 %dG\n給与の配賦と利益は翌日の帳簿で確認。" % [int(row.get(&"today_revenue", 0)), int(row.get(&"today_expenses", 0))]
_refreshing = false
@@ -263,7 +287,7 @@ func _on_command_completed(result: Variant) -> void:
refresh()
func _on_snapshot_published(_snapshot: Dictionary, _digest: String) -> void:
func _on_snapshot_published(_snapshot: Dictionary = {}, _digest: String = "") -> void:
if is_visible_in_tree():
refresh()
@@ -344,7 +368,7 @@ func _facility_row(id: StringName) -> Dictionary:
func _set_result(message: String, success: bool) -> void:
result_label.text = message
result_label.add_theme_color_override("font_color", Color("397346") if success else Color("a7402e"))
LayerSkin.register_status_text(result_label, success, LayerSkin.active_layer(self))
status_requested.emit(message, success)
@@ -357,6 +381,7 @@ func _label(value: String, node_name := "") -> Label:
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
label.add_theme_font_size_override("font_size", 13)
label.add_theme_color_override("font_color", Color("55371e"))
LayerSkin.register_text(label, LayerSkin.active_layer(self))
return label