-
Notifications
You must be signed in to change notification settings - Fork 104
/
tip.rb
153 lines (113 loc) · 3.23 KB
/
tip.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# frozen_string_literal: true
class Tip < ApplicationRecord
belongs_to :user
belongs_to :sendmany
belongs_to :project, inverse_of: :tips
AVAILABLE_AMOUNTS = [
['undecided', ''],
['free', 0],
['tiny', 0.1],
['small', 0.5],
['normal', 1],
['big', 2],
['huge', 5]
].freeze
validates :amount, numericality: { greater_or_equal_than: 0, allow_nil: true }
scope :not_sent, -> { where(sendmany_id: nil) }
def not_sent?
sendmany_id.nil?
end
scope :unpaid, -> { non_refunded.not_sent }
def unpaid?
non_refunded? and not_sent?
end
scope :to_pay, -> { unpaid.decided.not_free.with_address }
def to_pay?
unpaid? and decided? and !free? and with_address?
end
scope :free, -> { where('amount = 0') }
scope :not_free, -> { where('amount > 0') }
def free?
amount.zero?
end
scope :paid, -> { where.not(sendmany_id: nil) }
def paid?
!!sendmany_id
end
scope :refunded, -> { where.not(refunded_at: nil) }
def refunded?
!!refunded_at
end
scope :non_refunded, -> { where(refunded_at: nil) }
def non_refunded?
!refunded?
end
scope :unclaimed, -> { joins(:user).unpaid.where('users.bitcoin_address' => ['', nil]) }
def claimed?
paid? || user.bitcoin_address.present?
end
def unclaimed?
!claimed?
end
scope :with_address, -> { joins(:user).where.not('users.bitcoin_address' => ['', nil]) }
def with_address?
user.bitcoin_address.present?
end
scope :decided, -> { where.not(amount: nil) }
scope :undecided, -> { where(amount: nil) }
def decided?
!!amount
end
def undecided?
!decided?
end
before_save :check_amount_against_project
before_save :touch_decided_at_if_decided
def self.refund_unclaimed
unclaimed.non_refunded
.where.not(decided_at: nil)
.where('tips.decided_at < ?', 1.month.ago)
.find_each do |tip|
tip.touch :refunded_at
end
end
def self.auto_decide_older_tips
undecided.non_refunded
.where('tips.created_at < ?', 1.month.ago)
.find_each do |tip|
tip.amount_percentage = 1
tip.save
end
end
def commit_url
project.commit_url(commit)
end
def amount_percentage
nil
end
def amount_percentage=(percentage)
return if decided?
return if percentage.blank?
return unless AVAILABLE_AMOUNTS.map(&:last).compact.map(&:to_s).include?(percentage.to_s)
self.amount = (project.available_amount * (percentage.to_f / 100)).ceil
end
def check_amount_against_project
return unless amount && amount_changed?
available_amount = project.available_amount
available_amount -= amount_was if amount_was
return if amount <= available_amount
raise "Not enough funds on project to save #{inspect} (available: #{available_amount}). Project #{project.inspect} available_amount: #{project.available_amount} #{project.tips.count} tips: #{project.tips.map(&:amount).join(', ')}"
end
def touch_decided_at_if_decided
self.decided_at = Time.zone.now if amount_changed? && decided?
end
def project_name
project.full_name
end
def user_name
user.display_name
end
def txid
try(:sendmany).try(:txid)
end
end