143 lines
4.1 KiB
Lua
143 lines
4.1 KiB
Lua
-- ============================================================================
|
|
-- READ SUBJECT BALANCES
|
|
-- Functions to read shared SubjectBalance payloads from Redis hashes.
|
|
-- Balance keys are built by the TS caller and passed in via
|
|
-- params.balance_keys_by_feature_id to keep this script portable across
|
|
-- Redis/Dragonfly cluster modes (no key construction inside Lua).
|
|
-- ============================================================================
|
|
|
|
local function decode_subject_balance(raw_value)
|
|
local decoded = safe_decode(raw_value)
|
|
if type(decoded) ~= 'table' then
|
|
return nil
|
|
end
|
|
return decoded
|
|
end
|
|
|
|
local function read_subject_balances(params)
|
|
local balances_by_id = {}
|
|
local missing_customer_entitlement_ids = {}
|
|
local entries_by_balance_key = {}
|
|
local seen_ids_by_balance_key = {}
|
|
local balance_keys_by_feature_id = safe_table(params.balance_keys_by_feature_id)
|
|
|
|
local function queue_balance_read(customer_entitlement_id, feature_id)
|
|
if not (customer_entitlement_id and feature_id) then
|
|
return false
|
|
end
|
|
|
|
local balance_key = balance_keys_by_feature_id[feature_id]
|
|
if not balance_key then
|
|
return false
|
|
end
|
|
|
|
if entries_by_balance_key[balance_key] == nil then
|
|
entries_by_balance_key[balance_key] = {
|
|
feature_id = feature_id,
|
|
customer_entitlement_ids = {},
|
|
}
|
|
seen_ids_by_balance_key[balance_key] = {}
|
|
end
|
|
|
|
if seen_ids_by_balance_key[balance_key][customer_entitlement_id] then
|
|
return true
|
|
end
|
|
seen_ids_by_balance_key[balance_key][customer_entitlement_id] = true
|
|
|
|
table.insert(
|
|
entries_by_balance_key[balance_key].customer_entitlement_ids,
|
|
customer_entitlement_id
|
|
)
|
|
return true
|
|
end
|
|
|
|
for _, ent_obj in ipairs(params.customer_entitlement_deductions or {}) do
|
|
local customer_entitlement_id = ent_obj.customer_entitlement_id
|
|
if customer_entitlement_id then
|
|
local queued = queue_balance_read(customer_entitlement_id, ent_obj.feature_id)
|
|
if not queued then
|
|
table.insert(missing_customer_entitlement_ids, customer_entitlement_id)
|
|
end
|
|
end
|
|
end
|
|
|
|
for balance_key, entry in pairs(entries_by_balance_key) do
|
|
local hmget_args = { 'HMGET', balance_key }
|
|
for _, customer_entitlement_id in ipairs(entry.customer_entitlement_ids) do
|
|
table.insert(hmget_args, customer_entitlement_id)
|
|
end
|
|
|
|
local raw_values = redis.call(unpack(hmget_args))
|
|
|
|
for index, customer_entitlement_id in ipairs(entry.customer_entitlement_ids) do
|
|
local raw_value = raw_values[index]
|
|
local subject_balance = decode_subject_balance(raw_value)
|
|
|
|
if subject_balance == nil then
|
|
table.insert(
|
|
missing_customer_entitlement_ids,
|
|
customer_entitlement_id
|
|
)
|
|
else
|
|
balances_by_id[customer_entitlement_id] = {
|
|
balance_key = balance_key,
|
|
customer_entitlement_id = customer_entitlement_id,
|
|
feature_id = entry.feature_id,
|
|
subject_balance = subject_balance,
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
return {
|
|
balances_by_id = balances_by_id,
|
|
missing_customer_entitlement_ids = missing_customer_entitlement_ids,
|
|
}
|
|
end
|
|
|
|
local function read_rollover_data(rollover)
|
|
if type(rollover) ~= 'table' then
|
|
return nil
|
|
end
|
|
|
|
return {
|
|
balance = safe_number(rollover.balance),
|
|
usage = safe_number(rollover.usage),
|
|
entities = safe_table(rollover.entities),
|
|
}
|
|
end
|
|
|
|
local function read_current_balance(subject_balance)
|
|
if type(subject_balance) ~= 'table' then
|
|
return 0
|
|
end
|
|
|
|
return safe_number(subject_balance.balance)
|
|
end
|
|
|
|
local function read_current_entity_balance(subject_balance, entity_id)
|
|
if type(subject_balance) ~= 'table' or is_nil(entity_id) then
|
|
return nil
|
|
end
|
|
|
|
local entities = safe_table(subject_balance.entities)
|
|
local entity_balance = entities[entity_id]
|
|
|
|
if type(entity_balance) ~= 'table' then
|
|
return nil
|
|
end
|
|
|
|
return {
|
|
balance = safe_number(entity_balance.balance),
|
|
adjustment = safe_number(entity_balance.adjustment),
|
|
}
|
|
end
|
|
|
|
local function read_current_entities(subject_balance)
|
|
if type(subject_balance) ~= 'table' then
|
|
return {}
|
|
end
|
|
|
|
return safe_table(subject_balance.entities)
|
|
end
|