mirror of
https://github.com/HackPlan/RootPanel.git
synced 2026-04-24 03:35:59 +08:00
refactor billing api
This commit is contained in:
@@ -1,20 +1,82 @@
|
||||
{config, plan} = app
|
||||
{mAccount, mBalance} = app.models
|
||||
|
||||
exports.triggerBilling = (account, callback) ->
|
||||
|
||||
|
||||
|
||||
|
||||
exports.cyclicalBilling = ->
|
||||
exports.cyclicalBilling = (callback) ->
|
||||
mAccount.find
|
||||
'attribute.plans.0':
|
||||
$exists: true
|
||||
.toArray (err, accounts) ->
|
||||
for account in accounts
|
||||
exports.calcBilling account,
|
||||
is_force: false
|
||||
async.each accounts, (account, callback) ->
|
||||
exports.triggerBilling account, ->
|
||||
callback()
|
||||
, ->
|
||||
callback()
|
||||
|
||||
exports.cyclicalBilling ->
|
||||
setInterval ->
|
||||
exports.cyclicalBilling ->
|
||||
, config.billing.billing_cycle
|
||||
|
||||
# @param callback(account)
|
||||
exports.triggerBilling = (account, callback) ->
|
||||
modifier =
|
||||
$inc:
|
||||
'attribute.balance': 0
|
||||
|
||||
async.each account.billing.plans, (plan_name, callback) ->
|
||||
plan_info = config.plans[plan_name]
|
||||
|
||||
unless plan_info.billing_by_time
|
||||
return callback()
|
||||
|
||||
last_billing_at = account.billing.last_billing_at[plan_name]
|
||||
|
||||
if last_billing_at
|
||||
next_billing_at = new Date last_billing_at.getTime() + plan_info.billing_by_time.unit * plan_info.billing_by_time.min_billing_unit
|
||||
else
|
||||
last_billing_at = new Date()
|
||||
|
||||
unless last_billing_at and next_billing_at > new Date()
|
||||
return callback()
|
||||
|
||||
billing_unit_count = Math.floor (Date.now() - last_billing_at.getTime()) / plan_info.billing_by_time.unit
|
||||
|
||||
new_last_billing_at = new Date last_billing_at.getTime() + billing_unit_count * plan_info.billing_by_time.unit
|
||||
amount = billing_unit_count * plan_info.billing_by_time.price
|
||||
|
||||
callback null,
|
||||
name: plan_name
|
||||
last_billing_at: new_last_billing_at
|
||||
amount_inc: -amount
|
||||
|
||||
, (err, result) ->
|
||||
result = _.compact result
|
||||
|
||||
if _.isEmpty result
|
||||
return callback()
|
||||
|
||||
modifier =
|
||||
$set: {}
|
||||
$inc:
|
||||
'billing.balance': 0
|
||||
|
||||
for item in result
|
||||
modifier.$set["billing.last_billing_at.#{item.name}"] = item.last_billing_at
|
||||
modifier.$inc['billing.balance'] += item.amount_inc
|
||||
|
||||
mAccount.findAndModify {_id: account._id}, null, modifier, new: true, (err, account) ->
|
||||
mBalance.create account, 'billing', modifier.$inc['billing.balance'],
|
||||
plans: _.pluck result, 'name'
|
||||
billing_time: billing_time_hour
|
||||
is_force: is_force
|
||||
last_billing_at: account.attribute.last_billing_at
|
||||
, ->
|
||||
callback account
|
||||
|
||||
callback()
|
||||
|
||||
exports.forceBilling = (account, plan_name, callback) ->
|
||||
|
||||
|
||||
exports.checkBilling = (account, callback) ->
|
||||
if Date.now() > account.attribute.last_billing_at.getTime() + config.billing.daily_billing_cycle
|
||||
@@ -50,50 +112,6 @@ exports.checkExpired = (account, callback) ->
|
||||
|
||||
callback_back()
|
||||
|
||||
exports.calcBilling = (account, options, callback) ->
|
||||
{is_force} = options
|
||||
|
||||
exports.checkExpired account, (account) ->
|
||||
amount = 0
|
||||
|
||||
for planName in _.filter(account.attribute.plans, (i) -> config.plans[i].price)
|
||||
plan_info = config.plans[planName]
|
||||
|
||||
price = plan_info.price / 30 / 24
|
||||
time_hour = (Date.now() - account.attribute.last_billing_at.getTime()) / 1000 / 3600
|
||||
|
||||
if is_force
|
||||
billing_time_hour = Math.ceil time_hour
|
||||
else
|
||||
billing_time_hour = Math.floor time_hour
|
||||
|
||||
amount += price * billing_time_hour
|
||||
|
||||
if amount <= 0
|
||||
return callback account
|
||||
|
||||
if is_force
|
||||
new_last_billing_at = new Date()
|
||||
else
|
||||
new_last_billing_at = new Date account.attribute.last_billing_at.getTime() + billing_time_hour * 3600 * 1000
|
||||
|
||||
# TODO: 付费套餐与非付费套餐并存的情况
|
||||
|
||||
modifier =
|
||||
$set:
|
||||
'attribute.last_billing_at': new_last_billing_at
|
||||
$inc:
|
||||
'attribute.balance': -amount
|
||||
|
||||
mAccount.findAndModify _id: account._id, {}, modifier, new: true, (err, account) ->
|
||||
mBalance.create account, 'billing', -amount,
|
||||
plans: account.attribute.plans
|
||||
billing_time: billing_time_hour
|
||||
is_force: is_force
|
||||
last_billing_at: account.attribute.last_billing_at
|
||||
, ->
|
||||
callback account
|
||||
|
||||
exports.forceUnsubscribe = (account, callback) ->
|
||||
async.mapSeries account.attribute.plans, (plan_name, callback) ->
|
||||
mAccount.findId account._id, (err, account) ->
|
||||
@@ -110,6 +128,3 @@ exports.calcRemainingTime = (account) ->
|
||||
price += plan_info.price / 30 / 24
|
||||
|
||||
return account.attribute.balance / price
|
||||
|
||||
exports.cyclicalBilling()
|
||||
setInterval exports.cyclicalBilling, config.billing.cyclical_billing
|
||||
|
||||
@@ -19,7 +19,7 @@ genAddress = (bitcoin_secret, callback) ->
|
||||
throw err if err
|
||||
callback body.address
|
||||
|
||||
# @param currency: CNY, USD, JPY
|
||||
# @param currency: CNY, USD, JPY etc.
|
||||
# @param callback(rate)
|
||||
getExchangeRate = (currency, callback) ->
|
||||
REDIS_KEY = "#{config.redis.prefix}:[bitcoin.getExchangeRate]:#{currency}"
|
||||
|
||||
Reference in New Issue
Block a user