Files
TheTree_mock/scripts/ui/operating_ledger_panel.gd
T

130 lines
5.6 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
class_name OperatingLedgerPanel
extends VBoxContainer
## Projection only: authoritative close and ledger entries own all amounts.
var _runtime: Variant
var _clock: Variant
var _cash_label: Label
var _day_picker: OptionButton
var _closed_label: Label
var _facility_label: Label
var _selected_day := -1
var _picker_days: Array[int] = []
func setup(runtime: Variant, clock: Variant) -> void:
_runtime = runtime
_clock = clock
name = "OperatingLedgerPanel"
add_theme_constant_override("separation", 8)
var heading := Label.new()
heading.text = "帳簿 · 06:00締め"
heading.add_theme_color_override("font_color", Color("55371e"))
add_child(heading)
_cash_label = _label()
_day_picker = OptionButton.new()
_day_picker.name = "LedgerDayPicker"
_day_picker.item_selected.connect(func(index: int) -> void:
_selected_day = _day_picker.get_item_id(index)
refresh())
add_child(_day_picker)
_closed_label = _label()
_facility_label = _label()
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 inflow := 0
var outflow := 0
var construction_outflow := 0
var wage_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
if entry.debit_account == &"PLAYER_CASH":
inflow += entry.amount
if entry.credit_account == &"PLAYER_CASH":
outflow += entry.amount
if entry.category == &"CONSTRUCTION":
construction_outflow += entry.amount
elif entry.category == &"WAGE":
wage_outflow += entry.amount
var summaries: Array[Dictionary] = []
if _runtime.operations_coordinator != null:
summaries = _runtime.operations_coordinator.get_day_summaries()
var selected: Dictionary = {}
for summary: Dictionary in summaries:
if int(summary.get(&"day", -1)) == _selected_day:
selected = summary
if selected.is_empty() and not summaries.is_empty():
selected = summaries.back()
return {
&"business_day": business_day, &"period_start": start,
&"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,
&"closed_days": summaries, &"selected_close": selected.duplicate(true),
}
func refresh() -> void:
if _runtime == null or _cash_label == null:
return
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"]]
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.disabled = true
_closed_label.text = "建築後の手持ち資金だけで営業成績は決まりません。宿泊などの売上と日々の費用をここで確認できます。"
_facility_label.text = ""
return
_day_picker.disabled = false
var days: Array[int] = []
for day: Dictionary in report[&"closed_days"]:
days.append(int(day[&"day"]))
if not _day_picker.get_popup().visible:
if days != _picker_days:
_day_picker.clear()
_picker_days = days
for day_number: int in days:
_day_picker.add_item("第%d営業日 · 確定" % day_number, day_number)
_day_picker.select(_picker_days.find(int(summary[&"day"])))
var totals: Dictionary = summary.get(&"category_totals", {})
var other := 0
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 lines: PackedStringArray = ["施設別 · 売上 / 費用 / 利益"]
var rows: Dictionary = summary.get(&"facility_profit_loss", {})
var ids := rows.keys()
ids.sort()
for id: Variant in ids:
var facility: FacilityInstance = _runtime.facility_service.get_instance(StringName(id))
var label := String(id)
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]
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 "施設別の記帳はまだありません。"
func _label() -> Label:
var label := Label.new()
label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
label.add_theme_color_override("font_color", Color("55371e"))
label.add_theme_font_size_override("font_size", 13)
add_child(label)
return label