<commit_before>Bongo = require "bongo"
{secure, signature, Base} = Bongo

module.exports = class Payment extends Base
  @share()

  ERR_USER_NOT_CONFIRMED = 'ERR_USER_NOT_CONFIRMED'

  @set
    sharedMethods     :
      static          :
        subscribe         :
          (signature Object, Function)
        subscriptions     :
          (signature Object, Function)
        invoices          :
          (signature Object, Function)
        creditCard        :
          (signature Object, Function)
        updateCreditCard  :
          (signature Object, Function)
        canChangePlan     :
          (signature Object, Function)
        logOrder          :
          (signature Object, Function)
        getToken          :
          (signature Object, Function)
        canUserPurchase   :
          (signature Function)


  { get, post, deleteReq } = require "./socialapi/requests"

  socialProxyUrl = "/api/social"


  @subscribe = secure (client, data, callback)->
    requiredParams = [
      "token", "email", "planTitle", "planInterval", "provider"
    ]

    @canUserPurchase client, (err, confirmed) ->
      return callback err  if err
      return callback { message: ERR_USER_NOT_CONFIRMED }  unless confirmed

      validateParams requiredParams, data, (err)->
        return callback err  if err

        canChangePlan client, data.planTitle, (err)->
          return callback err  if err

          data.accountId = getAccountId client
          url = "#{socialProxyUrl}/payments/subscribe"

          post url, data, (err, response)->
            callback err, response

            data.status = if err then "$failed" else "$success"

            SiftScience = require "./siftscience"
            SiftScience.transaction client, data, (err)->
              log "logging to SiftScience failed", err  if err


  @subscriptions$ = secure (client, data, callback)->
    Payment.subscriptions client, data, callback

  @subscriptions = (client, data, callback)->
    data.accountId = getAccountId client
    url = "#{socialProxyUrl}/payments/subscriptions?account_id=#{data.accountId}"

    get url, data, callback

  @invoices = secure (client, data, callback)->
    data.accountId = getAccountId client
    url = "#{socialProxyUrl}/payments/invoices/#{data.accountId}"

    get url, data, callback

  @creditCard = secure (client, data, callback)->
    data.accountId = getAccountId client
    url = "#{socialProxyUrl}/payments/creditcard/#{data.accountId}"

    get url, data, callback

  @updateCreditCard = secure (client, data, callback)->
    requiredParams = [ "token" , "provider"]

    validateParams requiredParams, data, (err)->
      return callback err  if err

      data.accountId = getAccountId client
      url = "#{socialProxyUrl}/payments/creditcard/update"

      post url, data, callback

  @canChangePlan = secure (client, data, callback)->
    requiredParams = [ "planTitle" ]

    validateParams requiredParams, data, (err)->
      return callback err  if err

      canChangePlan client, data.planTitle, callback

  @deleteAccount = (client, callback)->
    accountId = getAccountId client
    url = "#{socialProxyUrl}/payments/customers/#{accountId}"

    deleteReq url, {}, callback

  @getToken = (data, callback)->
    requiredParams = [ "planTitle", "planInterval" ]

    validateParams requiredParams, data, (err)->
      return callback err  if err

      url = "#{socialProxyUrl}/payments/paypal/token"
      get url, data, callback


  @logOrder = secure (client, raw, callback)->
    SiftScience = require "./siftscience"
    SiftScience.createOrder client, raw, callback

  @canUserPurchase = secure (client, callback)->
    {connection : {delegate}} = client

    if delegate.type isnt "registered"
      return callback {message:"guests are not allowed"}

    delegate.fetchUser (err, user)->
      return callback err  if err
      callback null, user.status is "confirmed"

  validateParams = (requiredParams, data, callback)->
    for param in requiredParams
      if not data[param]
        return callback {message: "#{param} is required"}

    callback null

  getAccountId = (client)->
    return client.connection.delegate.getId()

  getUserName = (client)->
    return client.connection.delegate.profile.nickname

  prettifyFeature = (name)->
    switch name
      when "alwaysOn"
        "alwaysOn vms"
      when "storage"
        "GB storage"
      when "total"
        "total vms"

  canChangePlan = (client, planTitle, callback)->
    fetchPlan client, planTitle, (err, plan)->
      return callback err  if err

      fetchUsage client, (err, usage)->
        return callback err  if err

        for name in ["alwaysOn", "storage", "total"]
          if usage[name] > plan[name]
            return callback {
              "message"   : "Sorry, your request to downgrade can't be processed because you are currently using more resources than the plan you are trying to downgrade to allows."
              "allowed"   : plan[name]
              "usage"     : usage[name]
              "planTitle" : planTitle
              "name"      : prettifyFeature name
            }

        callback null

  fetchUsage = (client, callback)->
    ComputeProvider = require "./computeproviders/computeprovider"
    ComputeProvider.fetchUsage client, { provider: "koding" }, callback

  fetchPlan = (client, planTitle, callback)->

    plans = require "./computeproviders/plans"
    plan  = plans[planTitle]

    return callback {"message" : "plan not found"}  unless plan

    fetchReferrerSpace client, (err, space)->
      return callback err  if err<commit_msg>Payment: it seems we need to clone the plan where ever we require it<commit_after>Bongo = require "bongo"
{secure, signature, Base} = Bongo

module.exports = class Payment extends Base
  @share()

  ERR_USER_NOT_CONFIRMED = 'ERR_USER_NOT_CONFIRMED'

  @set
    sharedMethods     :
      static          :
        subscribe         :
          (signature Object, Function)
        subscriptions     :
          (signature Object, Function)
        invoices          :
          (signature Object, Function)
        creditCard        :
          (signature Object, Function)
        updateCreditCard  :
          (signature Object, Function)
        canChangePlan     :
          (signature Object, Function)
        logOrder          :
          (signature Object, Function)
        getToken          :
          (signature Object, Function)
        canUserPurchase   :
          (signature Function)


  { get, post, deleteReq } = require "./socialapi/requests"

  socialProxyUrl = "/api/social"


  @subscribe = secure (client, data, callback)->
    requiredParams = [
      "token", "email", "planTitle", "planInterval", "provider"
    ]

    @canUserPurchase client, (err, confirmed) ->
      return callback err  if err
      return callback { message: ERR_USER_NOT_CONFIRMED }  unless confirmed

      validateParams requiredParams, data, (err)->
        return callback err  if err

        canChangePlan client, data.planTitle, (err)->
          return callback err  if err

          data.accountId = getAccountId client
          url = "#{socialProxyUrl}/payments/subscribe"

          post url, data, (err, response)->
            callback err, response

            data.status = if err then "$failed" else "$success"

            SiftScience = require "./siftscience"
            SiftScience.transaction client, data, (err)->
              log "logging to SiftScience failed", err  if err


  @subscriptions$ = secure (client, data, callback)->
    Payment.subscriptions client, data, callback

  @subscriptions = (client, data, callback)->
    data.accountId = getAccountId client
    url = "#{socialProxyUrl}/payments/subscriptions?account_id=#{data.accountId}"

    get url, data, callback

  @invoices = secure (client, data, callback)->
    data.accountId = getAccountId client
    url = "#{socialProxyUrl}/payments/invoices/#{data.accountId}"

    get url, data, callback

  @creditCard = secure (client, data, callback)->
    data.accountId = getAccountId client
    url = "#{socialProxyUrl}/payments/creditcard/#{data.accountId}"

    get url, data, callback

  @updateCreditCard = secure (client, data, callback)->
    requiredParams = [ "token" , "provider"]

    validateParams requiredParams, data, (err)->
      return callback err  if err

      data.accountId = getAccountId client
      url = "#{socialProxyUrl}/payments/creditcard/update"

      post url, data, callback

  @canChangePlan = secure (client, data, callback)->
    requiredParams = [ "planTitle" ]

    validateParams requiredParams, data, (err)->
      return callback err  if err

      canChangePlan client, data.planTitle, callback

  @deleteAccount = (client, callback)->
    accountId = getAccountId client
    url = "#{socialProxyUrl}/payments/customers/#{accountId}"

    deleteReq url, {}, callback

  @getToken = (data, callback)->
    requiredParams = [ "planTitle", "planInterval" ]

    validateParams requiredParams, data, (err)->
      return callback err  if err

      url = "#{socialProxyUrl}/payments/paypal/token"
      get url, data, callback


  @logOrder = secure (client, raw, callback)->
    SiftScience = require "./siftscience"
    SiftScience.createOrder client, raw, callback

  @canUserPurchase = secure (client, callback)->
    {connection : {delegate}} = client

    if delegate.type isnt "registered"
      return callback {message:"guests are not allowed"}

    delegate.fetchUser (err, user)->
      return callback err  if err
      callback null, user.status is "confirmed"

  validateParams = (requiredParams, data, callback)->
    for param in requiredParams
      if not data[param]
        return callback {message: "#{param} is required"}

    callback null

  getAccountId = (client)->
    return client.connection.delegate.getId()

  getUserName = (client)->
    return client.connection.delegate.profile.nickname

  prettifyFeature = (name)->
    switch name
      when "alwaysOn"
        "alwaysOn vms"
      when "storage"
        "GB storage"
      when "total"
        "total vms"

  canChangePlan = (client, planTitle, callback)->
    fetchPlan client, planTitle, (err, plan)->
      return callback err  if err

      fetchUsage client, (err, usage)->
        return callback err  if err

        for name in ["alwaysOn", "storage", "total"]
          if usage[name] > plan[name]
            return callback {
              "message"   : "Sorry, your request to downgrade can't be processed because you are currently using more resources than the plan you are trying to downgrade to allows."
              "allowed"   : plan[name]
              "usage"     : usage[name]
              "planTitle" : planTitle
              "name"      : prettifyFeature name
            }

        callback null

  fetchUsage = (client, callback)->
    ComputeProvider = require "./computeproviders/computeprovider"
    ComputeProvider.fetchUsage client, { provider: "koding" }, callback

  fetchPlan = (client, planTitle, callback)->

    plans   = require "./computeproviders/plans"

    return callback {"message" : "plan not found"}  unless plans[planTitle]

    {clone} = require 'underscore'
    plan    = clone plans[planTitle]

    fetchReferrerSpace client, (err, space)->
      return callback err  if err
{'fraction_non_alphanumeric': 0.10131035089262158, 'fraction_numerical': 0.0, 'mean_word_length': 2.5851197982345524, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4547646', 'n_tokens_mistral': 3148, 'n_tokens_neox': 2999, 'n_words': 936}