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:
@@ -1,7 +1,10 @@
|
||||
class_name OperatingLedgerPanel
|
||||
extends VBoxContainer
|
||||
|
||||
const LayerSkin := preload("res://scripts/ui/layer_interface_skin.gd")
|
||||
|
||||
## Projection only: authoritative close and ledger entries own all amounts.
|
||||
var _initial_layer := 0
|
||||
var _runtime: Variant
|
||||
var _clock: Variant
|
||||
var _cash_label: Label
|
||||
@@ -12,18 +15,21 @@ var _selected_day := -1
|
||||
var _picker_days: Array[int] = []
|
||||
|
||||
|
||||
func setup(runtime: Variant, clock: Variant) -> void:
|
||||
func setup(runtime: Variant, clock: Variant, style_button := Callable(), layer := 0) -> void:
|
||||
_initial_layer = layer
|
||||
_runtime = runtime
|
||||
_clock = clock
|
||||
name = "OperatingLedgerPanel"
|
||||
add_theme_constant_override("separation", 8)
|
||||
var heading := Label.new()
|
||||
heading.text = "帳簿 · 06:00締め"
|
||||
heading.text = "帳簿 · 00:00締め"
|
||||
heading.add_theme_color_override("font_color", Color("55371e"))
|
||||
LayerSkin.register_text(heading, _initial_layer)
|
||||
add_child(heading)
|
||||
_cash_label = _label()
|
||||
_day_picker = OptionButton.new()
|
||||
_day_picker.name = "LedgerDayPicker"
|
||||
if style_button.is_valid(): style_button.call(_day_picker)
|
||||
_day_picker.item_selected.connect(func(index: int) -> void:
|
||||
_selected_day = _day_picker.get_item_id(index)
|
||||
refresh())
|
||||
@@ -33,16 +39,26 @@ func setup(runtime: Variant, clock: Variant) -> void:
|
||||
refresh()
|
||||
|
||||
|
||||
func select_latest_close() -> void:
|
||||
_selected_day = -1
|
||||
_day_picker.get_popup().hide()
|
||||
refresh()
|
||||
|
||||
|
||||
func get_report() -> Dictionary:
|
||||
if _runtime == null:
|
||||
return {}
|
||||
var minute: int = _clock.absolute_minute
|
||||
var business_day := maxi(1, int(floor(float(minute - 360) / 1440.0)) + 1)
|
||||
var start := (business_day - 1) * 1440 + 360
|
||||
var business_day := minute / 1440 + 1
|
||||
var start := (business_day - 1) * 1440
|
||||
if _runtime.operations_coordinator != null:
|
||||
business_day = _runtime.operations_coordinator.get_open_financial_day()
|
||||
start = _runtime.operations_coordinator.get_financial_period_start(business_day)
|
||||
var inflow := 0
|
||||
var outflow := 0
|
||||
var construction_outflow := 0
|
||||
var wage_outflow := 0
|
||||
var upkeep_outflow := 0
|
||||
for entry: LedgerEntry in _runtime.economy_service.get_entries():
|
||||
if entry.absolute_minute < start or entry.absolute_minute > minute or entry.category == &"INITIALIZATION":
|
||||
continue
|
||||
@@ -52,6 +68,8 @@ func get_report() -> Dictionary:
|
||||
outflow += entry.amount
|
||||
if entry.category == &"CONSTRUCTION":
|
||||
construction_outflow += entry.amount
|
||||
elif entry.category == &"MAINTENANCE_PAYMENT":
|
||||
upkeep_outflow += entry.amount
|
||||
elif entry.category == &"WAGE":
|
||||
wage_outflow += entry.amount
|
||||
var summaries: Array[Dictionary] = []
|
||||
@@ -68,6 +86,8 @@ func get_report() -> Dictionary:
|
||||
&"cash": _runtime.economy_service.get_balance(&"PLAYER_CASH"),
|
||||
&"cash_in": inflow, &"cash_out": outflow, &"cash_net": inflow - outflow,
|
||||
&"construction_cash_out": construction_outflow, &"wage_cash_out": wage_outflow,
|
||||
&"upkeep_cash_out": upkeep_outflow,
|
||||
&"upkeep_arrears": _runtime.upkeep_settlement.get_arrears_total(),
|
||||
&"closed_days": summaries, &"selected_close": selected.duplicate(true),
|
||||
}
|
||||
|
||||
@@ -78,13 +98,13 @@ func refresh() -> void:
|
||||
if _day_picker.get_popup().visible:
|
||||
return
|
||||
var report := get_report()
|
||||
_cash_label.text = "第%d営業日 · 手持ち %dG\n本日の入金 +%dG / 出金 −%dG\nうち建築 %dG / 給与支払 %dG\n資金増減 %+dG(営業利益は下の決算)" % [report[&"business_day"], report[&"cash"], report[&"cash_in"], report[&"cash_out"], report[&"construction_cash_out"], report[&"wage_cash_out"], report[&"cash_net"]]
|
||||
_cash_label.text = "第%d営業日 · 手持ち %dG\n本日の入金 +%dG / 出金 −%dG\nうち建築 %dG / 給与支払 %dG / 維持費支払 %dG\n未払い維持費 %dG\n資金増減 %+dG(営業利益は下の決算)" % [report[&"business_day"], report[&"cash"], report[&"cash_in"], report[&"cash_out"], report[&"construction_cash_out"], report[&"wage_cash_out"], report[&"upkeep_cash_out"], report[&"upkeep_arrears"], report[&"cash_net"]]
|
||||
var summary: Dictionary = report[&"selected_close"]
|
||||
if summary.is_empty():
|
||||
if not _day_picker.disabled or _day_picker.item_count == 0:
|
||||
_day_picker.clear()
|
||||
_picker_days.clear()
|
||||
_day_picker.add_item("決算は翌朝06:00に確定します")
|
||||
_day_picker.add_item("決算は翌日00:00に確定します")
|
||||
_day_picker.disabled = true
|
||||
_closed_label.text = "建築後の手持ち資金だけで営業成績は決まりません。宿泊などの売上と日々の費用をここで確認できます。"
|
||||
_facility_label.text = ""
|
||||
@@ -105,6 +125,10 @@ func refresh() -> void:
|
||||
for key: StringName in [&"maintenance", &"utilities", &"taxes_and_interest", &"fines"]:
|
||||
other += int(totals.get(key, 0))
|
||||
_closed_label.text = "売上 %dG / 返金 %dG\n運営費(仕入れ・契約金等) %dG\n給与 %dG / その他 %dG\n営業利益 %+dG\n前日比 %+dG / 未払給与 %dG\n帳簿照合:%s" % [totals.get(&"revenue", 0), totals.get(&"refunds", 0), totals.get(&"cost_of_goods", 0), totals.get(&"wages", 0), other, summary.get(&"net_profit", 0), summary.get(&"previous_day_delta", 0), summary.get(&"arrears_total", 0), "一致" if bool(summary.get(&"balanced", false)) else "差額あり"]
|
||||
var legacy: bool = _runtime.operations_coordinator.is_legacy_financial_history(int(summary[&"day"]))
|
||||
_closed_label.text += "\n%s %d回%s" % ["旧版の連続未払い" if legacy else "連続赤字", int(summary.get(&"consecutive_insolvency_count", 0)), "" if legacy else "(3回でゲーム終了)"]
|
||||
var close_minute := int(summary[&"closed_at"]) % 1440
|
||||
_closed_label.text += "\n確定時刻 %02d:%02d" % [close_minute / 60, close_minute % 60]
|
||||
var lines: PackedStringArray = ["施設別 · 売上 / 費用 / 利益"]
|
||||
var rows: Dictionary = summary.get(&"facility_profit_loss", {})
|
||||
var ids := rows.keys()
|
||||
@@ -115,6 +139,14 @@ func refresh() -> void:
|
||||
if facility != null:
|
||||
var definition: FacilityDefinition = _runtime.definition_registry.get_facility(facility.definition_id)
|
||||
label = "%s (%d,%d)" % [definition.display_name if definition != null else facility.definition_id, facility.origin.x, facility.origin.y]
|
||||
else:
|
||||
# Corridors and stairs are completed construction entities without
|
||||
# service instances, but their ownership upkeep still appears here.
|
||||
var completed: Dictionary = _runtime.construction_service.get_facility(StringName(id))
|
||||
if not completed.is_empty():
|
||||
var definition: FacilityDefinition = _runtime.definition_registry.get_facility(completed[&"definition_id"])
|
||||
var origin: Vector3i = completed[&"origin"]
|
||||
label = "%s (%d,%d)" % [definition.display_name if definition != null else completed[&"definition_id"], origin.x, origin.y]
|
||||
var row: Dictionary = rows[id]
|
||||
lines.append("%s\n%dG / %dG / %+dG" % [label, row.get(&"revenue", 0), row.get(&"expenses", 0), row.get(&"net_profit", 0)])
|
||||
_facility_label.text = "\n".join(lines) if not rows.is_empty() else "施設別の記帳はまだありません。"
|
||||
@@ -124,6 +156,7 @@ func _label() -> Label:
|
||||
var label := Label.new()
|
||||
label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
label.add_theme_color_override("font_color", Color("55371e"))
|
||||
LayerSkin.register_text(label, _initial_layer)
|
||||
label.add_theme_font_size_override("font_size", 13)
|
||||
add_child(label)
|
||||
return label
|
||||
|
||||
Reference in New Issue
Block a user