refactor models

This commit is contained in:
jysperm
2015-04-02 07:02:24 +08:00
parent 847dceb220
commit 5d05580c34
9 changed files with 205 additions and 98 deletions

View File

@@ -131,6 +131,9 @@ Account.search = (identification) ->
else
return @findById identification
Account.findByGroup = (group, options...) ->
@find groups: group, options...
Account.authenticate = (token_code) ->
@findOneAndUpdate(
'tokens.code': token_code
@@ -146,6 +149,9 @@ Account.authenticate = (token_code) ->
code: token_code
}
Account::pick = ->
return _.omit @, 'password', 'password_salt', 'tokens'
Account::createToken = (type, payload) ->
token = new Token
type: type
@@ -175,11 +181,10 @@ Account::setEmail = (email) ->
Account::updatePreferences = (preferences) ->
Account::increaseBalance = (amount, type, payload) ->
Financials.createLog(@, type, amount, payload).then =>
@update
$inc:
balance: amount
Account::increaseBalance = (amount) ->
@update
$inc:
balance: amount
Account::inGroup = (group) ->
return group in @groups

View File

@@ -1,7 +1,9 @@
{_, async} = app.libs
{mabolo} = app
{ObjectID} = mabolo
_ = require 'underscore'
Q = require 'q'
Coworker = mabolo.model 'Coworker',
account_id:
required: true
@@ -23,11 +25,11 @@ Component = mabolo.model 'Component',
required: true
type: String
template:
provider:
required: true
type: String
node_name:
node:
required: true
type: String
@@ -64,25 +66,21 @@ Component::markAsStatus = (status) ->
$set:
status: status
Component::populate = (callback) ->
{Account} = app.models
Component::populate = ->
Account.find
_id:
$in: [
@account_id, _.pluck(@coworkers, 'account_id')...
]
async.parallel
account: (callback) =>
Account.findById @account_id, callback
.then (accounts) =>
@account = _.find accounts, ({_id}) =>
return @account_id.equals _id
coworkers: (callback) =>
async.each @coworkers, (coworker, callback) ->
Account.findById coworker.account_id, (err, account) ->
callback _.extend coworker,
account: account
, callback
for coworker in @coworkers
coworker.account = _.find accounts, ({_id}) ->
return coworker.account_id.equals _id
, (err, result) =>
{account, coworkers} = result
callback _.extend @,
account: account
coworkers: coworkers
component_type: app.components[@template]
node: app.nodes[@node_name]
return _.extend @,
provider: rp.components.byName @provider
node: rp.nodes.byName @node

View File

@@ -1,3 +1,5 @@
Q = require 'q'
{mabolo} = app
{ObjectID} = mabolo
@@ -12,6 +14,10 @@ Financials = mabolo.model 'Financials',
type: String
enum: ['deposit', 'billing']
status:
type: String
enum: ['pending', 'rejected', 'canceled', 'success', 'processing']
amount:
required: true
type: Number
@@ -20,16 +26,75 @@ Financials = mabolo.model 'Financials',
type: Date
default: -> new Date()
payload:
options:
type: Object
Financials.createLog = (account, type, amount, payload) ->
Q().then ->
unless isFinite amount
throw new Error 'invalid_amount'
Financials.createLog = (account, type, amount, options) ->
@create
account_id: account._id
type: type
amount: Math.abs amount
options: options
@create
account_id: account._id
type: type
amount: amount
payload: payload
Financials.getDepositLogs = (account, {req, limit}) ->
@find(
account_id: account._id
type: 'deposit'
,
sort:
created_at: -1
limit: limit
).then (financials) ->
Q.all financials.map (financial) ->
provider = app.extends.payments.byName financial.payload.provider
if provider
provider.populateFinancials req, financial
else
return financial
Financials.getBillingLogs = (account, {limit}) ->
@find
account_id: account._id
type: 'billing'
,
sort:
created_at: -1
limit: limit
Financials.createDepositRequest = (account, {amount, provider, order_id}) ->
@create
account_id: account._id
type: 'deposit'
status: 'pending'
amount: amount
options:
provider: provider
order_id: order_id
Financials::updateStatus = (status) ->
updateDepositStatus = =>
if @status == status
return
Financials.findOneAndUpdate(
_id: @_id
status: @status
,
status: status
).then (result) =>
unless result
return
if status == 'success'
@populate().then ->
@account.increaseBalance @amount
if @type == 'deposit'
updateDepositStatus()
else
throw new Error "cant update status for `#{@type}` type"
Financials::populate = ->
Account.findById(@account_id).then (account) =>
@account = account

View File

@@ -1,77 +1,66 @@
{utils, config, models, mabolo} = app
{_, async} = app.libs
{ObjectID} = mabolo
Notification = mabolo.model 'Notification',
account_id:
type: ObjectID
ref: 'Account'
group_name:
type: String
target:
required: true
type: Object
type:
required: true
type: String
enum: ['payment_success', 'ticket_create', 'ticket_reply']
level:
required: true
type: String
enum: ['notice', 'event', 'log']
enum: []
created_at:
type: Date
default: -> new Date()
payload:
read_at:
type: Date
title:
required: true
type: String
body:
required: true
type: String
body_html:
required: true
type: String
options:
type: Object
notices_level =
ticket_create: 'notice'
ticket_reply: 'notice'
ticket_update: 'event'
Notification::isGroupNotice = ->
return @target instanceof ObjectID
Notification.createNotice = (account, type, notice) ->
level = notices_level[type]
Notification::sendMail = ->
sendMail = (to, subject, html) ->
Q.Promise (resolve, reject) ->
app.mailer.sendMail
from: config.email.from
replyTo: config.email.reply_to
to: to
subject: subject
html: html
, (err, result) ->
if err
reject err
else
resolve result
Notification.create
account_id: account._id
type: type
level: level
payload: notice
.then ->
app.mailer.sendMail
from: config.email.send_from
to: account.email
subject: notice.title
html: notice.body
, ->
callback notification
@populate().then =>
if @isGroupNotice()
Account.findByGroup(@target).then (accounts) =>
Q.all accounts.map (account) =>
sendMail account.email, @title, @body_html
Notification.createGroupNotice = (group, type, notice) ->
level = exports.notices_level[type]
else
Account.findById(@target).then (account) =>
sendMail account.email, @title, @body_html
notification = new Notification
group_name: group
type: type
level: level
payload: notice
notification.save ->
unless level == NOTICE
callback notification
Account.find
groups: 'root'
, (err, accounts) ->
async.each accounts, (account, callback) ->
app.mailer.sendMail
from: config.email.send_from
to: account.email
subject: notice.title
html: notice.body
, callback
, (err) ->
logger.error err if err
callback notification
Notification::populate = ->
@provider = rp.extends.notification.byName @type
@provider.populateNotification @

View File

@@ -1,5 +1,6 @@
_ = require 'underscore'
{models, logger, mabolo} = app
{_} = app.libs
{ObjectID} = mabolo
SecurityLog = mabolo.model 'SecurityLog',

View File

@@ -36,7 +36,7 @@ Ticket = mabolo.model 'Ticket',
status:
required: true
type: String
enum: ['open', 'pending', 'finish', 'closed']
enum: ['opening', 'pending', 'finished', 'closed']
content:
required: true
@@ -88,6 +88,28 @@ Ticket.getTickets = (account) ->
sort:
updated_at: -1
Ticket.getTicketsGroupByStatus = (account, options) ->
getTicketsOfStatus = (status) =>
@find
status: status
,
sort:
updated_at: -1
limit: options?[status]?.limit
Q.all([
getTicketsOfStatus 'pending'
getTicketsOfStatus 'opening'
getTicketsOfStatus 'finished'
getTicketsOfStatus 'closed'
]).then ([pending, opening, finished, closed]) ->
return {
pending: pending
opening: opening
finished: finished
closed: closed
}
Ticket::hasMember = (account) ->
return _.some @members, (member_id) ->
return member_id.equals account._id
@@ -140,7 +162,7 @@ Ticket::createReply = (account, {content, status}) ->
.thenResolve reply
Ticket::populateAccounts = ->
app.models.Account.find
Account.find
_id:
$in: [
@account_id, @members..., _.pluck(@replies, 'account_id')...

View File

@@ -0,0 +1,27 @@
rp.extends.coupons.register
name: 'cash'
validate: (account, coupon) ->
apply_log = _.find coupon.apply_log, (log) ->
return log.account_id.equals account._id
if apply_log
return false
CouponCode.findOne
type: 'cash'
'options.category': coupon.options.category
'apply_log.account_id': account._id
.then (coupon) ->
if coupon
return false
else
return true
apply: (account, coupon) ->
account.incBalance coupon.options.amount, 'deposit',
type: 'coupon'
order_id: coupon.code
populateCoupon: (coupon) ->
return coupon