GitHub PullRequestReviewCommentEvent at 2014-12-08 10:24:16
Repository: spree
Actor: houndci
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/spree/spree/pulls/comments/21444572","id":21444572,"diff_hunk":"@@ -0,0 +1,245 @@\n+class Spree::StoreCredit < ActiveRecord::Base\n+  acts_as_paranoid\n+\n+  VOID_ACTION       = 'void'\n+  CREDIT_ACTION     = 'credit'\n+  CAPTURE_ACTION    = 'capture'\n+  ELIGIBLE_ACTION   = 'eligible'\n+  AUTHORIZE_ACTION  = 'authorize'\n+  ALLOCATION_ACTION = 'allocation'\n+\n+  DEFAULT_CREATED_BY_EMAIL = \"spree@example.com\"\n+\n+  belongs_to :user\n+  belongs_to :category, class_name: \"Spree::StoreCreditCategory\"\n+  belongs_to :created_by, class_name: \"Spree::User\"\n+  belongs_to :credit_type, class_name: 'Spree::StoreCreditType', :foreign_key => 'type_id'\n+  has_many :store_credit_events\n+\n+  validates_presence_of :user_id, :category_id, :type_id, :created_by_id, :currency\n+  validates_numericality_of :amount, { greater_than: 0 }\n+  validates_numericality_of :amount_used, { greater_than_or_equal_to: 0 }\n+  validate :amount_used_less_than_or_equal_to_amount\n+  validate :amount_authorized_less_than_or_equal_to_amount\n+\n+  delegate :name, to: :category, prefix: true\n+  delegate :email, to: :created_by, prefix: true\n+\n+  scope :order_by_priority, -> { includes(:credit_type).order('spree_store_credit_types.priority ASC') }\n+\n+  before_validation :associate_credit_type\n+  after_save :store_event\n+  before_destroy :validate_no_amount_used\n+\n+  attr_accessor :action, :action_amount, :action_originator, :action_authorization_code\n+\n+  def display_amount\n+    Spree::Money.new(amount)\n+  end\n+\n+  def display_amount_used\n+    Spree::Money.new(amount_used)\n+  end\n+\n+  def amount_remaining\n+    amount - amount_used - amount_authorized\n+  end\n+\n+  def authorize(amount, order_currency, options={})\n+    authorization_code = options[:action_authorization_code]\n+    if authorization_code\n+      if store_credit_events.find_by(action: AUTHORIZE_ACTION, authorization_code: authorization_code)\n+        # Don't authorize again on capture\n+        return true\n+      end\n+    else\n+      authorization_code = generate_authorization_code\n+    end\n+\n+    if validate_authorization(amount, order_currency)\n+      update_attributes!({\n+        action: AUTHORIZE_ACTION,\n+        action_amount: amount,\n+        action_originator: options[:action_originator],\n+        action_authorization_code: authorization_code,\n+\n+        amount_authorized: self.amount_authorized + amount,\n+      })\n+      authorization_code\n+    else\n+      errors.add(:base, Spree.t('store_credit_payment_method.insufficient_authorized_amount'))\n+      false\n+    end\n+  end\n+\n+  def validate_authorization(amount, order_currency)\n+    if amount_remaining.to_d < amount.to_d\n+      errors.add(:base, Spree.t('store_credit_payment_method.insufficient_funds'))\n+    elsif currency != order_currency\n+      errors.add(:base, Spree.t('store_credit_payment_method.currency_mismatch'))\n+    end\n+    return errors.blank?\n+  end\n+\n+  def capture(amount, authorization_code, order_currency, options={})\n+    return false unless authorize(amount, order_currency, action_authorization_code: authorization_code)\n+\n+    if amount <= amount_authorized\n+      if currency != order_currency\n+        errors.add(:base, Spree.t('store_credit_payment_method.currency_mismatch'))\n+        false\n+      else\n+        update_attributes!({\n+          action: CAPTURE_ACTION,\n+          action_amount: amount,\n+          action_originator: options[:action_originator],\n+          action_authorization_code: authorization_code,\n+\n+          amount_used: self.amount_used + amount,\n+          amount_authorized: self.amount_authorized - amount,\n+        })\n+        authorization_code\n+      end\n+    else\n+      errors.add(:base, Spree.t('store_credit_payment_method.insufficient_authorized_amount'))\n+      false\n+    end\n+  end\n+\n+  def void(authorization_code, options={})\n+    if auth_event = store_credit_events.find_by(action: AUTHORIZE_ACTION, authorization_code: authorization_code)\n+      self.update_attributes!({\n+        action: VOID_ACTION,\n+        action_amount: auth_event.amount,\n+        action_authorization_code: authorization_code,\n+        action_originator: options[:action_originator],\n+\n+        amount_authorized: amount_authorized - auth_event.amount,\n+      })\n+      true\n+    else\n+      errors.add(:base, Spree.t('store_credit_payment_method.unable_to_void', auth_code: authorization_code))\n+      false\n+    end\n+  end\n+\n+  def credit(amount, authorization_code, order_currency, options={})\n+    # Find the amount related to this authorization_code in order to add the store credit back\n+    capture_event = store_credit_events.find_by(action: CAPTURE_ACTION, authorization_code: authorization_code)\n+\n+    if currency != order_currency  # sanity check to make sure the order currency hasn't changed since the auth\n+      errors.add(:base, Spree.t('store_credit_payment_method.currency_mismatch'))\n+      false\n+    elsif capture_event && amount <= capture_event.amount\n+      action_attributes = {\n+        action: CREDIT_ACTION,\n+        action_amount: amount,\n+        action_originator: options[:action_originator],\n+        action_authorization_code: authorization_code,\n+      }\n+      create_credit_record(amount, action_attributes)\n+      true\n+    else\n+      errors.add(:base, Spree.t('store_credit_payment_method.unable_to_credit', auth_code: authorization_code))\n+      false\n+    end\n+  end\n+\n+  def actions\n+    [CAPTURE_ACTION, VOID_ACTION, CREDIT_ACTION]\n+  end\n+\n+  def can_capture?(payment)\n+    payment.pending? || payment.checkout?\n+  end\n+\n+  def can_void?(payment)\n+    payment.pending?\n+  end\n+\n+  def can_credit?(payment)\n+    payment.completed? && payment.credit_allowed > 0\n+  end\n+\n+  def generate_authorization_code\n+    \"#{self.id}-SC-#{Time.now.utc.strftime(\"%Y%m%d%H%M%S%6N\")}\"\n+  end\n+\n+  class << self\n+    def default_created_by\n+      Spree.user_class.find_by(email: DEFAULT_CREATED_BY_EMAIL)\n+    end\n+  end\n+\n+  private\n+\n+  def create_credit_record(amount, action_attributes={})\n+    # Setting credit_to_new_allocation to true will create a new allocation anytime #credit is called\n+    # If it is not set, it will update the store credit's amount in place\n+    credit = if Spree::StoreCredits::Configuration.credit_to_new_allocation\n+      Spree::StoreCredit.new({\n+        amount: amount,\n+        user_id: self.user_id,\n+        category_id: self.category_id,\n+        created_by_id: self.created_by_id,\n+        currency: self.currency,\n+        type_id: self.type_id,\n+        memo: credit_allocation_memo,\n+      })","path":"core/app/models/spree/store_credit.rb","position":188,"original_position":188,"commit_id":"53a8226cae8a26131b87ed3642599d11a2105cb3","original_commit_id":"53a8226cae8a26131b87ed3642599d11a2105cb3","user":{"login":"houndci","id":6697940,"avatar_url":"https://avatars.githubusercontent.com/u/6697940?v=3","gravatar_id":"","url":"https://api.github.com/users/houndci","html_url":"https://github.com/houndci","followers_url":"https://api.github.com/users/houndci/followers","following_url":"https://api.github.com/users/houndci/following{/other_user}","gists_url":"https://api.github.com/users/houndci/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci/subscriptions","organizations_url":"https://api.github.com/users/houndci/orgs","repos_url":"https://api.github.com/users/houndci/repos","events_url":"https://api.github.com/users/houndci/events{/privacy}","received_events_url":"https://api.github.com/users/houndci/received_events","type":"User","site_admin":false},"body":"Indent the right brace the same as the first position after the preceding left parenthesis.","created_at":"2014-12-08T10:24:16Z","updated_at":"2014-12-08T10:24:16Z","html_url":"https://github.com/spree/spree/pull/5625#discussion_r21444572","pull_request_url":"https://api.github.com/repos/spree/spree/pulls/5625","_links":{"self":{"href":"https://api.github.com/repos/spree/spree/pulls/comments/21444572"},"html":{"href":"https://github.com/spree/spree/pull/5625#discussion_r21444572"},"pull_request":{"href":"https://api.github.com/repos/spree/spree/pulls/5625"}}},"pull_request":{"url":"https://api.github.com/repos/spree/spree/pulls/5625","id":24589215,"html_url":"https://github.com/spree/spree/pull/5625","diff_url":"https://github.com/spree/spree/pull/5625.diff","patch_url":"https://github.com/spree/spree/pull/5625.patch","issue_url":"https://api.github.com/repos/spree/spree/issues/5625","number":5625,"state":"open","locked":false,"title":"Move store credits in core","user":{"login":"IrvinFan","id":5523239,"avatar_url":"https://avatars.githubusercontent.com/u/5523239?v=3","gravatar_id":"","url":"https://api.github.com/users/IrvinFan","html_url":"https://github.com/IrvinFan","followers_url":"https://api.github.com/users/IrvinFan/followers","following_url":"https://api.github.com/users/IrvinFan/following{/other_user}","gists_url":"https://api.github.com/users/IrvinFan/gists{/gist_id}","starred_url":"https://api.github.com/users/IrvinFan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IrvinFan/subscriptions","organizations_url":"https://api.github.com/users/IrvinFan/orgs","repos_url":"https://api.github.com/users/IrvinFan/repos","events_url":"https://api.github.com/users/IrvinFan/events{/privacy}","received_events_url":"https://api.github.com/users/IrvinFan/received_events","type":"User","site_admin":false},"body":"This is the starting point of merging store credits feature (but leave gift cards feature) from extension https://github.com/paulo-surfdome/spree_store_credit_payment_method/tree/move_credit_out into Spree.\r\n\r\nHere is the approach we took: go through codes in the directories in https://github.com/paulo-surfdome/spree_store_credit_payment_method/tree/move_credit_out and copy (new file) or merge (decorator) store credits related codes into Spree. And at the same time remove those codes from the extension (Related PR: https://github.com/spree-contrib/spree_store_credit_payment_method/pull/24).\r\n\r\nRight now the key components are done. Anyone can take from here.\r\n\r\n- [x] merge app directory\r\n- [x] merge bin directory\r\n- [x] merge db directory\r\n- [ ] merge config directory\r\n- [ ] merge lib directory\r\n- [ ] merge spec directory\r\n- [ ] implement store frontend UI \r\n","created_at":"2014-11-18T05:12:13Z","updated_at":"2014-12-08T10:24:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"90293200a73489eee4156eeef6ec91bc9288c923","assignee":null,"milestone":{"url":"https://api.github.com/repos/spree/spree/milestones/27","labels_url":"https://api.github.com/repos/spree/spree/milestones/27/labels","id":709927,"number":27,"title":"v3.0.0","description":"","creator":{"login":"JDutil","id":25104,"avatar_url":"https://avatars.githubusercontent.com/u/25104?v=3","gravatar_id":"","url":"https://api.github.com/users/JDutil","html_url":"https://github.com/JDutil","followers_url":"https://api.github.com/users/JDutil/followers","following_url":"https://api.github.com/users/JDutil/following{/other_user}","gists_url":"https://api.github.com/users/JDutil/gists{/gist_id}","starred_url":"https://api.github.com/users/JDutil/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JDutil/subscriptions","organizations_url":"https://api.github.com/users/JDutil/orgs","repos_url":"https://api.github.com/users/JDutil/repos","events_url":"https://api.github.com/users/JDutil/events{/privacy}","received_events_url":"https://api.github.com/users/JDutil/received_events","type":"User","site_admin":false},"open_issues":31,"closed_issues":5,"state":"open","created_at":"2014-07-03T22:04:28Z","updated_at":"2014-12-05T22:21:48Z","due_on":"2025-07-31T07:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/spree/spree/pulls/5625/commits","review_comments_url":"https://api.github.com/repos/spree/spree/pulls/5625/comments","review_comment_url":"https://api.github.com/repos/spree/spree/pulls/comments/{number}","comments_url":"https://api.github.com/repos/spree/spree/issues/5625/comments","statuses_url":"https://api.github.com/repos/spree/spree/statuses/53a8226cae8a26131b87ed3642599d11a2105cb3","head":{"label":"IrvinFan:move_store_credits_in_core","ref":"move_store_credits_in_core","sha":"53a8226cae8a26131b87ed3642599d11a2105cb3","user":{"login":"IrvinFan","id":5523239,"avatar_url":"https://avatars.githubusercontent.com/u/5523239?v=3","gravatar_id":"","url":"https://api.github.com/users/IrvinFan","html_url":"https://github.com/IrvinFan","followers_url":"https://api.github.com/users/IrvinFan/followers","following_url":"https://api.github.com/users/IrvinFan/following{/other_user}","gists_url":"https://api.github.com/users/IrvinFan/gists{/gist_id}","starred_url":"https://api.github.com/users/IrvinFan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IrvinFan/subscriptions","organizations_url":"https://api.github.com/users/IrvinFan/orgs","repos_url":"https://api.github.com/users/IrvinFan/repos","events_url":"https://api.github.com/users/IrvinFan/events{/privacy}","received_events_url":"https://api.github.com/users/IrvinFan/received_events","type":"User","site_admin":false},"repo":{"id":22971723,"name":"spree","full_name":"IrvinFan/spree","owner":{"login":"IrvinFan","id":5523239,"avatar_url":"https://avatars.githubusercontent.com/u/5523239?v=3","gravatar_id":"","url":"https://api.github.com/users/IrvinFan","html_url":"https://github.com/IrvinFan","followers_url":"https://api.github.com/users/IrvinFan/followers","following_url":"https://api.github.com/users/IrvinFan/following{/other_user}","gists_url":"https://api.github.com/users/IrvinFan/gists{/gist_id}","starred_url":"https://api.github.com/users/IrvinFan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IrvinFan/subscriptions","organizations_url":"https://api.github.com/users/IrvinFan/orgs","repos_url":"https://api.github.com/users/IrvinFan/repos","events_url":"https://api.github.com/users/IrvinFan/events{/privacy}","received_events_url":"https://api.github.com/users/IrvinFan/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/IrvinFan/spree","description":"Spree is a complete open source e-commerce solution for Ruby on Rails.","fork":true,"url":"https://api.github.com/repos/IrvinFan/spree","forks_url":"https://api.github.com/repos/IrvinFan/spree/forks","keys_url":"https://api.github.com/repos/IrvinFan/spree/keys{/key_id}","collaborators_url":"https://api.github.com/repos/IrvinFan/spree/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/IrvinFan/spree/teams","hooks_url":"https://api.github.com/repos/IrvinFan/spree/hooks","issue_events_url":"https://api.github.com/repos/IrvinFan/spree/issues/events{/number}","events_url":"https://api.github.com/repos/IrvinFan/spree/events","assignees_url":"https://api.github.com/repos/IrvinFan/spree/assignees{/user}","branches_url":"https://api.github.com/repos/IrvinFan/spree/branches{/branch}","tags_url":"https://api.github.com/repos/IrvinFan/spree/tags","blobs_url":"https://api.github.com/repos/IrvinFan/spree/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/IrvinFan/spree/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/IrvinFan/spree/git/refs{/sha}","trees_url":"https://api.github.com/repos/IrvinFan/spree/git/trees{/sha}","statuses_url":"https://api.github.com/repos/IrvinFan/spree/statuses/{sha}","languages_url":"https://api.github.com/repos/IrvinFan/spree/languages","stargazers_url":"https://api.github.com/repos/IrvinFan/spree/stargazers","contributors_url":"https://api.github.com/repos/IrvinFan/spree/contributors","subscribers_url":"https://api.github.com/repos/IrvinFan/spree/subscribers","subscription_url":"https://api.github.com/repos/IrvinFan/spree/subscription","commits_url":"https://api.github.com/repos/IrvinFan/spree/commits{/sha}","git_commits_url":"https://api.github.com/repos/IrvinFan/spree/git/commits{/sha}","comments_url":"https://api.github.com/repos/IrvinFan/spree/comments{/number}","issue_comment_url":"https://api.github.com/repos/IrvinFan/spree/issues/comments/{number}","contents_url":"https://api.github.com/repos/IrvinFan/spree/contents/{+path}","compare_url":"https://api.github.com/repos/IrvinFan/spree/compare/{base}...{head}","merges_url":"https://api.github.com/repos/IrvinFan/spree/merges","archive_url":"https://api.github.com/repos/IrvinFan/spree/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/IrvinFan/spree/downloads","issues_url":"https://api.github.com/repos/IrvinFan/spree/issues{/number}","pulls_url":"https://api.github.com/repos/IrvinFan/spree/pulls{/number}","milestones_url":"https://api.github.com/repos/IrvinFan/spree/milestones{/number}","notifications_url":"https://api.github.com/repos/IrvinFan/spree/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/IrvinFan/spree/labels{/name}","releases_url":"https://api.github.com/repos/IrvinFan/spree/releases{/id}","created_at":"2014-08-14T23:19:53Z","updated_at":"2014-11-17T22:24:14Z","pushed_at":"2014-12-08T10:23:46Z","git_url":"git://github.com/IrvinFan/spree.git","ssh_url":"git@github.com:IrvinFan/spree.git","clone_url":"https://github.com/IrvinFan/spree.git","svn_url":"https://github.com/IrvinFan/spree","homepage":"http://spreecommerce.com","size":68277,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"spree:master","ref":"master","sha":"1893133ee40742e6ace714f05fb5e6c11914f2b9","user":{"login":"spree","id":56702,"avatar_url":"https://avatars.githubusercontent.com/u/56702?v=3","gravatar_id":"","url":"https://api.github.com/users/spree","html_url":"https://github.com/spree","followers_url":"https://api.github.com/users/spree/followers","following_url":"https://api.github.com/users/spree/following{/other_user}","gists_url":"https://api.github.com/users/spree/gists{/gist_id}","starred_url":"https://api.github.com/users/spree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spree/subscriptions","organizations_url":"https://api.github.com/users/spree/orgs","repos_url":"https://api.github.com/users/spree/repos","events_url":"https://api.github.com/users/spree/events{/privacy}","received_events_url":"https://api.github.com/users/spree/received_events","type":"Organization","site_admin":false},"repo":{"id":3314,"name":"spree","full_name":"spree/spree","owner":{"login":"spree","id":56702,"avatar_url":"https://avatars.githubusercontent.com/u/56702?v=3","gravatar_id":"","url":"https://api.github.com/users/spree","html_url":"https://github.com/spree","followers_url":"https://api.github.com/users/spree/followers","following_url":"https://api.github.com/users/spree/following{/other_user}","gists_url":"https://api.github.com/users/spree/gists{/gist_id}","starred_url":"https://api.github.com/users/spree/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spree/subscriptions","organizations_url":"https://api.github.com/users/spree/orgs","repos_url":"https://api.github.com/users/spree/repos","events_url":"https://api.github.com/users/spree/events{/privacy}","received_events_url":"https://api.github.com/users/spree/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/spree/spree","description":"Spree is a complete open source e-commerce solution for Ruby on Rails.","fork":false,"url":"https://api.github.com/repos/spree/spree","forks_url":"https://api.github.com/repos/spree/spree/forks","keys_url":"https://api.github.com/repos/spree/spree/keys{/key_id}","collaborators_url":"https://api.github.com/repos/spree/spree/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/spree/spree/teams","hooks_url":"https://api.github.com/repos/spree/spree/hooks","issue_events_url":"https://api.github.com/repos/spree/spree/issues/events{/number}","events_url":"https://api.github.com/repos/spree/spree/events","assignees_url":"https://api.github.com/repos/spree/spree/assignees{/user}","branches_url":"https://api.github.com/repos/spree/spree/branches{/branch}","tags_url":"https://api.github.com/repos/spree/spree/tags","blobs_url":"https://api.github.com/repos/spree/spree/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/spree/spree/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/spree/spree/git/refs{/sha}","trees_url":"https://api.github.com/repos/spree/spree/git/trees{/sha}","statuses_url":"https://api.github.com/repos/spree/spree/statuses/{sha}","languages_url":"https://api.github.com/repos/spree/spree/languages","stargazers_url":"https://api.github.com/repos/spree/spree/stargazers","contributors_url":"https://api.github.com/repos/spree/spree/contributors","subscribers_url":"https://api.github.com/repos/spree/spree/subscribers","subscription_url":"https://api.github.com/repos/spree/spree/subscription","commits_url":"https://api.github.com/repos/spree/spree/commits{/sha}","git_commits_url":"https://api.github.com/repos/spree/spree/git/commits{/sha}","comments_url":"https://api.github.com/repos/spree/spree/comments{/number}","issue_comment_url":"https://api.github.com/repos/spree/spree/issues/comments/{number}","contents_url":"https://api.github.com/repos/spree/spree/contents/{+path}","compare_url":"https://api.github.com/repos/spree/spree/compare/{base}...{head}","merges_url":"https://api.github.com/repos/spree/spree/merges","archive_url":"https://api.github.com/repos/spree/spree/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/spree/spree/downloads","issues_url":"https://api.github.com/repos/spree/spree/issues{/number}","pulls_url":"https://api.github.com/repos/spree/spree/pulls{/number}","milestones_url":"https://api.github.com/repos/spree/spree/milestones{/number}","notifications_url":"https://api.github.com/repos/spree/spree/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/spree/spree/labels{/name}","releases_url":"https://api.github.com/repos/spree/spree/releases{/id}","created_at":"2008-03-10T14:45:35Z","updated_at":"2014-12-08T06:25:17Z","pushed_at":"2014-12-05T22:24:43Z","git_url":"git://github.com/spree/spree.git","ssh_url":"git@github.com:spree/spree.git","clone_url":"https://github.com/spree/spree.git","svn_url":"https://github.com/spree/spree","homepage":"http://spreecommerce.com","size":125944,"stargazers_count":5732,"watchers_count":5732,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2667,"mirror_url":null,"open_issues_count":121,"forks":2667,"open_issues":121,"watchers":5732,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/spree/spree/pulls/5625"},"html":{"href":"https://github.com/spree/spree/pull/5625"},"issue":{"href":"https://api.github.com/repos/spree/spree/issues/5625"},"comments":{"href":"https://api.github.com/repos/spree/spree/issues/5625/comments"},"review_comments":{"href":"https://api.github.com/repos/spree/spree/pulls/5625/comments"},"review_comment":{"href":"https://api.github.com/repos/spree/spree/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/spree/spree/pulls/5625/commits"},"statuses":{"href":"https://api.github.com/repos/spree/spree/statuses/53a8226cae8a26131b87ed3642599d11a2105cb3"}}}}