Files
TheTree_mock/scripts/facility/service_request.gd
T

139 lines
4.6 KiB
GDScript

class_name ServiceRequest
extends RefCounted
## Immutable-at-enqueue quotation for one facility visit.
##
## FacilityService owns the lifecycle. Price and policy values are copied when
## this object is configured so later facility policy changes cannot alter an
## already queued request.
var request_id: StringName = &""
var guest_ids: Array[StringName] = []
var facility_id: StringName = &""
var service_type: StringName = &"default"
var created_at := 0
var quoted_price := 0
var policy_snapshot: Dictionary = {}
var policy_revision := 0
var reserved_inventory_ids: Array[StringName] = []
var preference_match := 0
var expected_quality := 0
var expected_wait := 0
var priority := 0
var enqueued_at := -1
var service_minutes := 1
func configure(
p_request_id: StringName,
p_facility_id: StringName,
p_guest_ids: Array[StringName],
p_service_type: StringName,
p_created_at: int,
options: Dictionary = {}
) -> ServiceRequest:
request_id = p_request_id
facility_id = p_facility_id
guest_ids.assign(p_guest_ids)
service_type = p_service_type
created_at = maxi(p_created_at, 0)
quoted_price = maxi(int(_value(options, &"quoted_price", 0)), 0)
policy_snapshot = _dictionary_copy(_value(options, &"policy_snapshot", {}))
policy_revision = maxi(int(_value(options, &"policy_revision", 0)), 0)
reserved_inventory_ids = _string_name_array(
_value(options, &"reserved_inventory_ids", [])
)
preference_match = int(_value(options, &"preference_match", 0))
expected_quality = int(_value(options, &"expected_quality", 0))
expected_wait = maxi(int(_value(options, &"expected_wait", 0)), 0)
priority = int(_value(options, &"priority", 0))
enqueued_at = int(_value(options, &"enqueued_at", -1))
service_minutes = maxi(int(_value(options, &"service_minutes", 1)), 1)
return self
func is_valid() -> bool:
if request_id.is_empty() or facility_id.is_empty() or service_type.is_empty():
return false
if guest_ids.is_empty() or service_minutes <= 0 or quoted_price < 0:
return false
var seen: Dictionary = {}
for guest_id: StringName in guest_ids:
if guest_id.is_empty() or seen.has(guest_id):
return false
seen[guest_id] = true
return true
func create_snapshot() -> Dictionary:
return {
&"request_id": String(request_id),
&"guest_ids": _names_to_strings(guest_ids),
&"facility_id": String(facility_id),
&"service_type": String(service_type),
&"created_at": created_at,
&"quoted_price": quoted_price,
&"policy_snapshot": policy_snapshot.duplicate(true),
&"policy_revision": policy_revision,
&"reserved_inventory_ids": _names_to_strings(reserved_inventory_ids),
&"preference_match": preference_match,
&"expected_quality": expected_quality,
&"expected_wait": expected_wait,
&"priority": priority,
&"enqueued_at": enqueued_at,
&"service_minutes": service_minutes,
}
static func from_snapshot(snapshot: Dictionary) -> ServiceRequest:
if not snapshot.get(&"guest_ids", null) is Array:
return null
if not snapshot.get(&"policy_snapshot", null) is Dictionary:
return null
if not snapshot.get(&"reserved_inventory_ids", null) is Array:
return null
var request := ServiceRequest.new().configure(
StringName(snapshot.get(&"request_id", "")),
StringName(snapshot.get(&"facility_id", "")),
_string_name_array(snapshot.get(&"guest_ids", [])),
StringName(snapshot.get(&"service_type", "default")),
int(snapshot.get(&"created_at", 0)),
{
&"quoted_price": snapshot.get(&"quoted_price", 0),
&"policy_snapshot": snapshot.get(&"policy_snapshot", {}),
&"policy_revision": snapshot.get(&"policy_revision", 0),
&"reserved_inventory_ids": snapshot.get(&"reserved_inventory_ids", []),
&"preference_match": snapshot.get(&"preference_match", 0),
&"expected_quality": snapshot.get(&"expected_quality", 0),
&"expected_wait": snapshot.get(&"expected_wait", 0),
&"priority": snapshot.get(&"priority", 0),
&"enqueued_at": snapshot.get(&"enqueued_at", -1),
&"service_minutes": snapshot.get(&"service_minutes", 1),
}
)
return request if request.is_valid() else null
static func _value(source: Dictionary, key: StringName, fallback: Variant) -> Variant:
return source.get(key, source.get(String(key), fallback))
static func _dictionary_copy(source: Variant) -> Dictionary:
return source.duplicate(true) if source is Dictionary else {}
static func _string_name_array(source: Variant) -> Array[StringName]:
var values: Array[StringName] = []
if not source is Array:
return values
for value: Variant in source:
values.append(StringName(value))
return values
static func _names_to_strings(source: Array[StringName]) -> Array[String]:
var values: Array[String] = []
for value: StringName in source:
values.append(String(value))
return values