feat: deduct from redis new api schema
This commit is contained in:
134
server/src/_luaScripts/luaUtils/apiSubscriptionUtils.lua
Normal file
134
server/src/_luaScripts/luaUtils/apiSubscriptionUtils.lua
Normal file
@@ -0,0 +1,134 @@
|
||||
-- apiSubscriptionUtils.lua
|
||||
-- Shared utility functions for subscription merging and manipulation
|
||||
|
||||
-- Helper function to get subscription key for grouping (plan_id:normalized_status)
|
||||
-- Normalizes status: "active" or past_due=true -> "active", otherwise uses actual status
|
||||
local function getSubscriptionKey(subscription)
|
||||
local status = subscription.status
|
||||
-- Normalize status: "active" or past_due=true -> "active", otherwise use actual status
|
||||
if status == "active" or (subscription.past_due == true) then
|
||||
status = "active"
|
||||
end
|
||||
return subscription.plan_id .. ":" .. status
|
||||
end
|
||||
|
||||
-- Helper function to merge subscriptions array by plan ID and normalized status
|
||||
-- Groups subscriptions by key (plan_id:normalized_status) and merges quantities
|
||||
-- Used by getCustomer.lua to merge customer + entity subscriptions
|
||||
-- Parameters: subscriptionsArray - array of subscriptions to merge
|
||||
-- Returns: array of merged subscriptions
|
||||
local function mergeSubscriptions(subscriptionsArray)
|
||||
if not subscriptionsArray or #subscriptionsArray == 0 then
|
||||
return {}
|
||||
end
|
||||
|
||||
local record = {}
|
||||
|
||||
for _, curr in ipairs(subscriptionsArray) do
|
||||
local key = getSubscriptionKey(curr)
|
||||
local latest = record[key]
|
||||
|
||||
local currStartedAt = curr.started_at
|
||||
|
||||
-- Start with latest (or current if no latest exists), then override specific fields
|
||||
local mergedSubscription = {}
|
||||
if latest then
|
||||
-- Copy all fields from latest first
|
||||
for k, v in pairs(latest) do
|
||||
mergedSubscription[k] = v
|
||||
end
|
||||
else
|
||||
-- Copy all fields from current
|
||||
for k, v in pairs(curr) do
|
||||
mergedSubscription[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
-- Apply merge logic for specific fields
|
||||
if latest then
|
||||
-- canceled_at: current.canceled_at if exists, else latest.canceled_at, else null
|
||||
if curr.canceled_at and curr.canceled_at ~= cjson.null and curr.canceled_at ~= nil then
|
||||
mergedSubscription.canceled_at = curr.canceled_at
|
||||
elseif latest.canceled_at and latest.canceled_at ~= cjson.null and latest.canceled_at ~= nil then
|
||||
mergedSubscription.canceled_at = latest.canceled_at
|
||||
else
|
||||
mergedSubscription.canceled_at = cjson.null
|
||||
end
|
||||
|
||||
-- started_at: latest.started_at ? min(latest.started_at, current.started_at) : current.started_at
|
||||
if latest.started_at then
|
||||
mergedSubscription.started_at = math.min(latest.started_at, currStartedAt)
|
||||
else
|
||||
mergedSubscription.started_at = currStartedAt
|
||||
end
|
||||
|
||||
-- quantity: (latest.quantity or 0) + (current.quantity or 0)
|
||||
local latestQuantity = latest.quantity or 0
|
||||
local currQuantity = curr.quantity or 0
|
||||
mergedSubscription.quantity = latestQuantity + currQuantity
|
||||
|
||||
-- past_due: true if either is true
|
||||
mergedSubscription.past_due = (latest.past_due == true) or (curr.past_due == true)
|
||||
else
|
||||
-- First subscription in group, ensure defaults
|
||||
mergedSubscription.canceled_at = curr.canceled_at or cjson.null
|
||||
mergedSubscription.started_at = currStartedAt
|
||||
mergedSubscription.quantity = curr.quantity or 0
|
||||
mergedSubscription.past_due = curr.past_due or false
|
||||
end
|
||||
|
||||
record[key] = mergedSubscription
|
||||
end
|
||||
|
||||
-- Convert record back to array
|
||||
local mergedSubscriptions = {}
|
||||
for _, subscription in pairs(record) do
|
||||
table.insert(mergedSubscriptions, subscription)
|
||||
end
|
||||
|
||||
return mergedSubscriptions
|
||||
end
|
||||
|
||||
-- Helper function to merge customer subscriptions into entity subscriptions
|
||||
-- Adds customer subscriptions that don't already exist in entity subscriptions (by subscription key)
|
||||
-- Does NOT merge quantities - only adds missing subscriptions
|
||||
-- Used by getEntity.lua to add customer subscriptions to entity subscriptions
|
||||
-- Parameters:
|
||||
-- entitySubscriptions - array of entity subscriptions (base)
|
||||
-- customerSubscriptions - array of customer subscriptions to add
|
||||
-- Returns: array of merged subscriptions (entity subscriptions + customer subscriptions that don't exist)
|
||||
local function mergeCustomerSubscriptionsIntoEntity(entitySubscriptions, customerSubscriptions)
|
||||
if not customerSubscriptions or #customerSubscriptions == 0 then
|
||||
return entitySubscriptions or {}
|
||||
end
|
||||
|
||||
if not entitySubscriptions then
|
||||
entitySubscriptions = {}
|
||||
end
|
||||
|
||||
-- Build a set of existing subscription keys in entity subscriptions
|
||||
local existingKeys = {}
|
||||
for _, subscription in ipairs(entitySubscriptions) do
|
||||
local key = getSubscriptionKey(subscription)
|
||||
existingKeys[key] = true
|
||||
end
|
||||
|
||||
-- Add customer subscriptions that don't exist in entity subscriptions
|
||||
local mergedSubscriptions = {}
|
||||
|
||||
-- First, add all entity subscriptions
|
||||
for _, subscription in ipairs(entitySubscriptions) do
|
||||
table.insert(mergedSubscriptions, subscription)
|
||||
end
|
||||
|
||||
-- Then, add customer subscriptions that don't exist
|
||||
for _, customerSubscription in ipairs(customerSubscriptions) do
|
||||
local key = getSubscriptionKey(customerSubscription)
|
||||
if not existingKeys[key] then
|
||||
table.insert(mergedSubscriptions, customerSubscription)
|
||||
end
|
||||
end
|
||||
|
||||
return mergedSubscriptions
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user