<commit_before>{Module, Relationship} = require 'jraphical'

module.exports = class JPaymentPlan extends Module

  force =
    forceRefresh  : yes
    forceInterval : 60

  recurly = require 'koding-payment'
  createId = require 'hat'

  {secure, dash}       = require 'bongo'
  {difference, extend} = require 'underscore'

  {permit}             = require '../group/permissionset'

  JUser                = require '../user'
  JPayment             = require './index'
  JPaymentToken        = require './token'
  JPaymentSubscription = require './subscription'

  @share()

  @set
    indexes         :
      planCode      : 'unique'
    sharedMethods   :
      static        : [
        'create'
        'removeByCode'
        'fetchPlans'
        'fetchPlanByCode'
        'fetchAccountDetails'
      ]
      instance      : [
        'fetchToken'
        'subscribe'
        'modify'
        'fetchProducts'
        'updateProducts'
      ]
    schema          :
      planCode      :
        type        : String
        required    : yes
      title         :
        type        : String
        required    : yes
      description   : Object # TODO: see below*
      feeAmount     :
        type        : Number
        validate    : (require './validators').fee
      feeInitial    :
        type        : Number
        validate    : (require './validators').fee
      feeInterval   :
        type        : Number
        default     : 1
      feeUnit       : (require './schema').feeUnit
      product       :
        prefix      : String
        category    : String
        item        : String
        version     : Number
      lastUpdate    : Number
      contents      : Object
      group         :
        type        : String
        required    : yes
      quantities    :
        type        : Object
        default     : -> {}
      tags          : (require './schema').tags
      sortWeight    : Number
    relationships   :
      product       :
        targetType  : 'JPaymentProduct'
        as          : 'plan product'

  # * It seems like we're stuffing some JSON into the description field
  #   on recurly.  I think that's a really bad idea, so let's store any
  #   data that is orthogonal to the recurly API in our own database,
  #   the way we're doing with JPaymentProduct C.T.

  @create = (group, formData, callback) ->

    JGroup = require '../group'

    { title, description, feeAmount, tags, sortWeight } = formData

    plan = new this {
      planCode    : createId()
      title
      description
      feeAmount
      feeInitial  : 0
      feeInterval : 1
      group
      tags
      sortWeight
    }

    plan.save (err) ->
      return callback err  if err

      recurly.createPlan plan, (err) ->
        return callback err  if err

        JGroup.one slug: group, (err, group) ->
          return callback err  if err

          group.addPlan plan, (err) ->
            return callback err  if err

            callback null, plan

  @create$ = permit 'manage products',
    success: (client, formData, callback) ->
      @create client.context.group, formData, callback

  @removeByCode = (planCode, callback) ->
    @one { planCode }, (err, plan) ->
      return callback err  if err
<commit_msg>payment: code style; avoid shadowing<commit_after>{Module, Relationship} = require 'jraphical'

module.exports = class JPaymentPlan extends Module

  force =
    forceRefresh  : yes
    forceInterval : 60

  recurly = require 'koding-payment'
  createId = require 'hat'

  {secure, dash}       = require 'bongo'
  {difference, extend} = require 'underscore'

  {permit}             = require '../group/permissionset'

  JUser                = require '../user'
  JPayment             = require './index'
  JPaymentToken        = require './token'
  JPaymentSubscription = require './subscription'

  @share()

  @set
    indexes         :
      planCode      : 'unique'
    sharedMethods   :
      static        : [
        'create'
        'removeByCode'
        'fetchPlans'
        'fetchPlanByCode'
        'fetchAccountDetails'
      ]
      instance      : [
        'fetchToken'
        'subscribe'
        'modify'
        'fetchProducts'
        'updateProducts'
      ]
    schema          :
      planCode      :
        type        : String
        required    : yes
      title         :
        type        : String
        required    : yes
      description   : Object # TODO: see below*
      feeAmount     :
        type        : Number
        validate    : (require './validators').fee
      feeInitial    :
        type        : Number
        validate    : (require './validators').fee
      feeInterval   :
        type        : Number
        default     : 1
      feeUnit       : (require './schema').feeUnit
      product       :
        prefix      : String
        category    : String
        item        : String
        version     : Number
      lastUpdate    : Number
      contents      : Object
      group         :
        type        : String
        required    : yes
      quantities    :
        type        : Object
        default     : -> {}
      tags          : (require './schema').tags
      sortWeight    : Number
    relationships   :
      product       :
        targetType  : 'JPaymentProduct'
        as          : 'plan product'

  # * It seems like we're stuffing some JSON into the description field
  #   on recurly.  I think that's a really bad idea, so let's store any
  #   data that is orthogonal to the recurly API in our own database,
  #   the way we're doing with JPaymentProduct C.T.

  @create = (groupSlug, formData, callback) ->

    JGroup = require '../group'

    { title, description, feeAmount, tags, sortWeight } = formData

    plan = new this {
      planCode    : createId()
      title
      description
      feeAmount
      feeInitial  : 0
      feeInterval : 1
      group       : groupSlug
      tags
      sortWeight
    }

    plan.save (err) ->
      return callback err  if err

      recurly.createPlan plan, (err) ->
        return callback err  if err

        JGroup.one slug: groupSlug, (err, group) ->
          return callback err  if err

          group.addPlan plan, (err) ->
            return callback err  if err

            callback null, plan

  @create$ = permit 'manage products',
    success: (client, formData, callback) ->
      @create client.context.group, formData, callback

  @removeByCode = (planCode, callback) ->
    @one { planCode }, (err, plan) ->
      return callback err  if err

{'fraction_non_alphanumeric': 0.08497330282227307, 'fraction_numerical': 0.0015255530129672007, 'mean_word_length': 1.5283455456999615, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, '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': '3950485', 'n_tokens_mistral': 1795, 'n_tokens_neox': 1732, 'n_words': 529}