139 lines
4.6 KiB
GDScript
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
|