osm 1.2.25 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +7 -0
- data/lib/osm.rb +1 -1
- data/lib/osm/event.rb +11 -2
- data/lib/osm/online_payment.rb +521 -0
- data/osm.gemspec +1 -0
- data/spec/osm/event_spec.rb +12 -0
- data/spec/osm/online_payment_spec.rb +490 -0
- data/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 651a0cdcdd3d694935cd01e1500494bf8cd4c7cf
|
|
4
|
+
data.tar.gz: 3e28fa840b8b180292c469f068f6667c01f9bbc9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6a31dd0a2da75b15f7c53fb2346e238d0044c3ecca6f04ad14c49bd06818f856987d185474f88a016b76f5df76e889e10464012ace57829bad3d6e049cf8c617
|
|
7
|
+
data.tar.gz: 0bf8a3ac116819ddda8b030c5caad9b6e77896be6b0e9d075ff92905bc82fda39c536d9ca215d58e221a1e40e9e5bbbba830feaff57abda82488c8e84d4f934b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## Version 1.3.0
|
|
2
|
+
|
|
3
|
+
* Add fetching of file names for events (unable to download)
|
|
4
|
+
* Add fetching of payment schedules - Osm::OnlinePayment::Schedule
|
|
5
|
+
* Add fetching of member's payments for a schedule
|
|
6
|
+
* Add updating a member's payment status
|
|
7
|
+
|
|
1
8
|
## Version 1.2.25
|
|
2
9
|
|
|
3
10
|
* Add fetching My.SCOUT parent login history - Osm::Myscout::ParentLoginHistory.get_for_section
|
data/README.md
CHANGED
|
@@ -113,8 +113,13 @@ however it should be noted that when the OSM API adds a feature it can be diffic
|
|
|
113
113
|
* Groupings (e.g. Sixes, Patrols)
|
|
114
114
|
* Invoices (Gold required)
|
|
115
115
|
* Members
|
|
116
|
+
* My.SCOUT Templates
|
|
116
117
|
* Notepad
|
|
117
118
|
* Notepads
|
|
119
|
+
* Online Payments:
|
|
120
|
+
* Schedules
|
|
121
|
+
* Payment Statuses
|
|
122
|
+
* Payment Status History
|
|
118
123
|
* Programme
|
|
119
124
|
* Register Data
|
|
120
125
|
* Register Structure
|
|
@@ -140,6 +145,8 @@ however it should be noted that when the OSM API adds a feature it can be diffic
|
|
|
140
145
|
* Grouping
|
|
141
146
|
* Invoices (Gold required)
|
|
142
147
|
* Member
|
|
148
|
+
* My.SCOUT Templates
|
|
149
|
+
* Online payments - payment status
|
|
143
150
|
* Register Attendance
|
|
144
151
|
|
|
145
152
|
### Create
|
data/lib/osm.rb
CHANGED
|
@@ -174,7 +174,7 @@ module Osm
|
|
|
174
174
|
replace_with = options[:replace_with] || {}
|
|
175
175
|
|
|
176
176
|
values = instance.attributes.sort.map{ |(k,v)|
|
|
177
|
-
(replace_with.keys.include?(k) && !v.nil?) ? "#{k}.#{replace_with[k]}: #{v.try(replace_with[k])}" : "#{k}: #{v.inspect}"
|
|
177
|
+
(replace_with.keys.include?(k) && !v.nil?) ? "#{k}.#{replace_with[k]}: #{v.try(replace_with[k]).inspect}" : "#{k}: #{v.inspect}"
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
return "#<#{instance.class.name} #{values.join(', ')} >"
|
data/lib/osm/event.rb
CHANGED
|
@@ -28,6 +28,8 @@ module Osm
|
|
|
28
28
|
# @return [Boolean] if the event has been archived
|
|
29
29
|
# @!attribute [rw] badges
|
|
30
30
|
# @return [Array<Osm::Event::BadgeLink>] the badge links for the event
|
|
31
|
+
# @!attribute [rw] files
|
|
32
|
+
# @return [Array<String>] the files attached to this event
|
|
31
33
|
# @!attribute [rw] columns
|
|
32
34
|
# @return [Array<Osm::Event::Column>] the custom columns for the event
|
|
33
35
|
# @!attribute [rw] notepad
|
|
@@ -59,6 +61,7 @@ module Osm
|
|
|
59
61
|
attribute :notes, :type => String, :default => ''
|
|
60
62
|
attribute :archived, :type => Boolean, :default => false
|
|
61
63
|
attribute :badges, :default => []
|
|
64
|
+
attribute :files, :default => []
|
|
62
65
|
attribute :columns, :default => []
|
|
63
66
|
attribute :notepad, :type => String, :default => ''
|
|
64
67
|
attribute :public_notepad, :type => String, :default => ''
|
|
@@ -72,8 +75,8 @@ module Osm
|
|
|
72
75
|
|
|
73
76
|
if ActiveModel::VERSION::MAJOR < 4
|
|
74
77
|
attr_accessible :id, :section_id, :name, :start, :finish, :cost, :location, :notes, :archived,
|
|
75
|
-
:fields, :badges, :columns, :notepad, :public_notepad, :confirm_by_date,
|
|
76
|
-
:reminders, :attendance_limit, :attendance_limit_includes_leaders,
|
|
78
|
+
:fields, :badges, :files, :columns, :notepad, :public_notepad, :confirm_by_date,
|
|
79
|
+
:allow_changes, :reminders, :attendance_limit, :attendance_limit_includes_leaders,
|
|
77
80
|
:attendance_reminder, :allow_booking
|
|
78
81
|
end
|
|
79
82
|
|
|
@@ -83,6 +86,7 @@ module Osm
|
|
|
83
86
|
validates_presence_of :name
|
|
84
87
|
validates :badges, :array_of => {:item_type => Osm::Event::BadgeLink, :item_valid => true}
|
|
85
88
|
validates :columns, :array_of => {:item_type => Osm::Event::Column, :item_valid => true}
|
|
89
|
+
validates :files, :array_of => {:item_type => String}
|
|
86
90
|
validates_inclusion_of :allow_changes, :in => [true, false]
|
|
87
91
|
validates_inclusion_of :reminders, :in => [true, false]
|
|
88
92
|
validates_inclusion_of :attendance_limit_includes_leaders, :in => [true, false]
|
|
@@ -120,7 +124,12 @@ module Osm
|
|
|
120
124
|
unless data['items'].nil?
|
|
121
125
|
data['items'].map { |i| i['eventid'].to_i }.each do |event_id|
|
|
122
126
|
event_data = api.perform_query("events.php?action=getEvent§ionid=#{section_id}&eventid=#{event_id}")
|
|
127
|
+
files_data = api.perform_query("ext/uploads/events/?action=listAttachments§ionid=#{section_id}&eventid=#{event_id}")
|
|
128
|
+
files = files_data.is_a?(Hash) ? files_data['files'] : files_data
|
|
129
|
+
files = [] unless files.is_a?(Array)
|
|
130
|
+
|
|
123
131
|
event = self.new_event_from_data(event_data)
|
|
132
|
+
event.files = files
|
|
124
133
|
events.push event
|
|
125
134
|
ids.push event.id
|
|
126
135
|
cache_write(api, ['event', event.id], event)
|
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
module Osm
|
|
2
|
+
|
|
3
|
+
class OnlinePayment
|
|
4
|
+
|
|
5
|
+
class Schedule < Osm::Model
|
|
6
|
+
class Payment < Osm::Model; end # Ensure the constant exists for the validators
|
|
7
|
+
class PaymentStatus < Osm::Model; end # Ensure the constant exists for validators
|
|
8
|
+
|
|
9
|
+
SORT_BY = [:section_id, :name, :id]
|
|
10
|
+
PAY_NOW_OPTIONS = {
|
|
11
|
+
-1 => 'Allowed at all times',
|
|
12
|
+
0 => 'Permanently disabled',
|
|
13
|
+
7 => 'Allowed within 1 week of due day',
|
|
14
|
+
14 => 'Allowed within 2 weeks of due day',
|
|
15
|
+
21 => 'Allowed within 3 weeks of due day',
|
|
16
|
+
28 => 'Allowed within 4 weeks of due day',
|
|
17
|
+
42 => 'Allowed within 6 weeks of due day',
|
|
18
|
+
56 => 'Allowed within 8 weeks of due day',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
# @!attribute [rw] id
|
|
22
|
+
# @return [FixNum] the schedule's ID
|
|
23
|
+
# @!attribute [rw] section_id
|
|
24
|
+
# @return [FixNum] the ID of the section the schedule belongs to
|
|
25
|
+
# @!attribute [rw] account_id
|
|
26
|
+
# @return [FixNum] the ID of the bank account this schedule is tied to
|
|
27
|
+
# @!attribute [rw] name
|
|
28
|
+
# @return [String] the name of the schedule
|
|
29
|
+
# @!attribute [rw] description
|
|
30
|
+
# @return [String] the description of what the schedule is for
|
|
31
|
+
# @!attribute [rw] archived
|
|
32
|
+
# @return [Boolean] whether the schedule has been archived
|
|
33
|
+
# @!attribute [rw] gift_aid
|
|
34
|
+
# @return [Boolean] whether payments made using this schedule are eligable for gift aid
|
|
35
|
+
# @!attribute [rw] require_all
|
|
36
|
+
# @return [Boolean] whether to require all payments within the schedule by default
|
|
37
|
+
# @!attribute [rw] pay_now
|
|
38
|
+
# @return [FixNum] controls the use of the pay now feature in OSM, see the PAY_NOW_OPTIONS hash
|
|
39
|
+
# @!attribute [rw] annual_limit
|
|
40
|
+
# @return [String] the maximum amount you'll be able to collect in a rolling 12 month period using this schedule
|
|
41
|
+
# @!attribute [rw] payments
|
|
42
|
+
# @return [Array<Payment>] the payments which make up this schedule
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
attribute :id, type: Integer
|
|
46
|
+
attribute :section_id, type: Integer
|
|
47
|
+
attribute :account_id, type: Integer
|
|
48
|
+
attribute :name, type: String
|
|
49
|
+
attribute :description, type: String, default: ''
|
|
50
|
+
attribute :archived, type: Boolean
|
|
51
|
+
attribute :gift_aid, type: Boolean
|
|
52
|
+
attribute :require_all, type: Boolean
|
|
53
|
+
attribute :pay_now, type: Integer
|
|
54
|
+
attribute :annual_limit, type: String
|
|
55
|
+
attribute :payments, type: Object, default: []
|
|
56
|
+
|
|
57
|
+
if ActiveModel::VERSION::MAJOR < 4
|
|
58
|
+
attr_accessible :id, :section_id, :account_id, :name, :description, :archived, :gift_aid,
|
|
59
|
+
:require_all, :pay_now, :annual_limit, :payments
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
validates_numericality_of :id, only_integer: true, greater_than: 0
|
|
63
|
+
validates_numericality_of :section_id, only_integer: true, greater_than: 0
|
|
64
|
+
validates_numericality_of :account_id, only_integer: true, greater_than: 0
|
|
65
|
+
validates_presence_of :annual_limit
|
|
66
|
+
validates_presence_of :name
|
|
67
|
+
validates_inclusion_of :pay_now, in: PAY_NOW_OPTIONS.keys
|
|
68
|
+
validates_inclusion_of :archived, in: [true, false]
|
|
69
|
+
validates_inclusion_of :gift_aid, in: [true, false]
|
|
70
|
+
validates_inclusion_of :require_all, in: [true, false]
|
|
71
|
+
validates :payments, array_of: {item_type: Osm::OnlinePayment::Schedule::Payment, item_valid: true}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# @!method initialize
|
|
75
|
+
# Initialize a new Schedule
|
|
76
|
+
# @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# Get a simple list of schedules for a section
|
|
80
|
+
# @param [Osm::Api] api The api to use to make the request
|
|
81
|
+
# @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to get the due badges for
|
|
82
|
+
# @!macro options_get
|
|
83
|
+
# @return [Array<Hash>]
|
|
84
|
+
def self.get_list_for_section(api, section, options={})
|
|
85
|
+
require_ability_to(api, :read, :finance, section, options)
|
|
86
|
+
section_id = section.to_i
|
|
87
|
+
cache_key = ['online_payments', 'schedule_list', section_id]
|
|
88
|
+
|
|
89
|
+
if !options[:no_cache] && Osm::Model.cache_exist?(api, cache_key)
|
|
90
|
+
return cache_read(api, cache_key)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
data = api.perform_query("ext/finances/onlinepayments/?action=getSchemes§ionid=#{section_id}")
|
|
94
|
+
data = data.is_a?(Hash) ? data['items'] : nil
|
|
95
|
+
data ||= []
|
|
96
|
+
data.map!{ |i| {id: Osm::to_i_or_nil(i['schemeid']), name: i['name'].to_s } }
|
|
97
|
+
|
|
98
|
+
cache_write(api, cache_key, data)
|
|
99
|
+
return data
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# Get all payment schedules for a section
|
|
104
|
+
# @param [Osm::Api] api The api to use to make the request
|
|
105
|
+
# @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to get the due badges for
|
|
106
|
+
# @!macro options_get
|
|
107
|
+
# @return [Array<Osm::OnlinePayment::Schedule>]
|
|
108
|
+
def self.get_for_section(api, section, options={})
|
|
109
|
+
require_ability_to(api, :read, :finance, section, options)
|
|
110
|
+
|
|
111
|
+
get_list_for_section(api, section, options).map do |schedule|
|
|
112
|
+
get(api, section, schedule[:id], options)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
# Get a payment schedules for a section
|
|
118
|
+
# @param [Osm::Api] api The api to use to make the request
|
|
119
|
+
# @param [Osm::Section, Fixnum, #to_i] section The section (or its ID) to get the due badges for
|
|
120
|
+
# @param [Fixnum, #to_i] schedule The ID of the payment schedule to get
|
|
121
|
+
# @!macro options_get
|
|
122
|
+
# @return [Array<Osm::OnlinePayment::Schedule>]
|
|
123
|
+
def self.get(api, section, schedule, options={})
|
|
124
|
+
require_ability_to(api, :read, :finance, section, options)
|
|
125
|
+
section_id = section.to_i
|
|
126
|
+
schedule_id = schedule.to_i
|
|
127
|
+
cache_key = ['online_payments', 'schedule', schedule_id]
|
|
128
|
+
|
|
129
|
+
if !options[:no_cache] && cache_exist?(api, cache_key)
|
|
130
|
+
data = cache_read(api, cache_key)
|
|
131
|
+
return data if data.section_id.eql?(section_id)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
data = api.perform_query("ext/finances/onlinepayments/?action=getPaymentSchedule§ionid=#{section_id}&schemeid=#{schedule_id}&allpayments=true")
|
|
135
|
+
schedule = new(
|
|
136
|
+
id: Osm::to_i_or_nil(data['schemeid']),
|
|
137
|
+
section_id: section_id,
|
|
138
|
+
account_id: Osm::to_i_or_nil(data['accountid']),
|
|
139
|
+
name: data['name'],
|
|
140
|
+
description: data['description'],
|
|
141
|
+
archived: data['archived'].eql?('1'),
|
|
142
|
+
gift_aid: data['giftaid'].eql?('1'),
|
|
143
|
+
require_all: data['defaulton'].eql?('1'),
|
|
144
|
+
pay_now: data['paynow'],
|
|
145
|
+
annual_limit: data['preauth_amount'],
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
(data['payments'] || []).each do |payment_data|
|
|
149
|
+
payment = Payment.new(
|
|
150
|
+
amount: payment_data['amount'],
|
|
151
|
+
archived: payment_data['archived'].eql?('1'),
|
|
152
|
+
due_date: Osm::parse_date(payment_data['date']),
|
|
153
|
+
name: payment_data['name'].to_s,
|
|
154
|
+
id: Osm::to_i_or_nil(payment_data['paymentid']),
|
|
155
|
+
schedule: schedule,
|
|
156
|
+
)
|
|
157
|
+
schedule.payments.push payment
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
cache_write(api, cache_key, schedule)
|
|
161
|
+
return schedule
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
# Get payments made by members for the schedule
|
|
166
|
+
# @param [Osm::Api] api The api to use to make the request
|
|
167
|
+
# @param [Osm::Term, Fixnum, #to_i] term The term (or it's id) to get details for (defaults to current term)
|
|
168
|
+
# @!macro options_get
|
|
169
|
+
# @return [Array<Osm::OnlinePayment::Schedule::PaymentsForMember>]
|
|
170
|
+
def get_payments_for_members(api, term=nil, options={})
|
|
171
|
+
require_ability_to(api, :read, :finance, section_id, options)
|
|
172
|
+
|
|
173
|
+
if term.nil?
|
|
174
|
+
section = Osm::Section.get(api, section_id, options)
|
|
175
|
+
term = section.waiting? ? -1 : Osm::Term.get_current_term_for_section(api, section)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
cache_key = ['online_payments', 'for_members', id, term.to_i]
|
|
179
|
+
if !options[:no_cache] && cache_exist?(api, cache_key)
|
|
180
|
+
return cache_read(api, cache_key)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
data = api.perform_query("ext/finances/onlinepayments/?action=getPaymentStatus§ionid=#{section_id}&schemeid=#{id}&termid=#{term.to_i}")
|
|
184
|
+
data = data['items'] || []
|
|
185
|
+
data.map! do |item|
|
|
186
|
+
payments_data = {}
|
|
187
|
+
payments.each do |payment|
|
|
188
|
+
unless item[payment.id.to_s].nil?
|
|
189
|
+
payments_data[payment.id] = PaymentStatus.build_from_json(item[payment.id.to_s], payment)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
PaymentsForMember.new(
|
|
194
|
+
member_id: Osm::to_i_or_nil(item['scoutid']),
|
|
195
|
+
section_id: section_id,
|
|
196
|
+
grouping_id: Osm::to_i_or_nil(item['patrolid']),
|
|
197
|
+
first_name: item['firstname'],
|
|
198
|
+
last_name: item['lastname'],
|
|
199
|
+
start_date: require_all ? Osm::parse_date(item['startdate']) : nil,
|
|
200
|
+
direct_debit: item['directdebit'].downcase.to_sym,
|
|
201
|
+
payments: payments_data,
|
|
202
|
+
schedule: self,
|
|
203
|
+
)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
cache_write(api, cache_key, data)
|
|
207
|
+
return data
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# Get unarchived payments for the schedule
|
|
213
|
+
# @return [Array<Osm::OnlinePayment::Schedule::Payment>]
|
|
214
|
+
def current_payments
|
|
215
|
+
payments.select{ |p| !p.archived? }
|
|
216
|
+
end
|
|
217
|
+
# Check if there are any unarchived payments for the schedule
|
|
218
|
+
# @return [Boolean]
|
|
219
|
+
def current_payments?
|
|
220
|
+
payments.any?{ |p| !p.archived? }
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Get archived payments for the schedule
|
|
224
|
+
# @return [Array<Osm::OnlinePayment::Schedule::Payment>]
|
|
225
|
+
def archived_payments
|
|
226
|
+
payments.select{ |p| p.archived? }
|
|
227
|
+
end
|
|
228
|
+
# Check if there are any archived payments for the schedule
|
|
229
|
+
# @return [Boolean]
|
|
230
|
+
def archived_payments?
|
|
231
|
+
payments.any?{ |p| p.archived? }
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def to_s
|
|
235
|
+
"#{id} -> #{name}"
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
class Payment < Osm::Model
|
|
240
|
+
# @!attribute [rw] id
|
|
241
|
+
# @return [FixNum] the payment's ID
|
|
242
|
+
# @!attribute [rw] amount
|
|
243
|
+
# @return [Sreing] the amount of the payment
|
|
244
|
+
# @!attribute [rw] name
|
|
245
|
+
# @return [String] the name given to the payment
|
|
246
|
+
# @!attribute [rw] archived
|
|
247
|
+
# @return [Boolean] whether the payment has been archived
|
|
248
|
+
# @!attribute [rw] date
|
|
249
|
+
# @return [Date] the payment's due date
|
|
250
|
+
# @!attribute [rw] schedule
|
|
251
|
+
# @return [Osm::OnlnePayment::Schedule] the schedule the payment belongs to
|
|
252
|
+
|
|
253
|
+
attribute :id, type: Integer
|
|
254
|
+
attribute :amount, type: String
|
|
255
|
+
attribute :name, type: String
|
|
256
|
+
attribute :archived, type: Boolean
|
|
257
|
+
attribute :due_date, type: Object
|
|
258
|
+
attribute :schedule, type: Object
|
|
259
|
+
|
|
260
|
+
if ActiveModel::VERSION::MAJOR < 4
|
|
261
|
+
attr_accessible :id, :amount, :name, :archived, :due_date, :schedule
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
validates_numericality_of :id, only_integer: true, greater_than: 0
|
|
265
|
+
validates_presence_of :amount
|
|
266
|
+
validates_presence_of :name
|
|
267
|
+
validates_presence_of :due_date
|
|
268
|
+
validates_presence_of :schedule
|
|
269
|
+
validates_inclusion_of :archived, in: [true, false]
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
# @!method initialize
|
|
273
|
+
# Initialize a new Payment
|
|
274
|
+
# @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
# Check if the payment is past due (or will be past due on the passed date)
|
|
278
|
+
# @param [Date] date The date to check for (defaults to today)
|
|
279
|
+
# @return [Boolean]
|
|
280
|
+
def past_due?(date=Date.today)
|
|
281
|
+
date > due_date
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def inspect
|
|
285
|
+
Osm.inspect_instance(self, {:replace_with => {'schedule' => :to_s}})
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
end # Schedule::Payment class
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
class PaymentsForMember < Osm::Model
|
|
292
|
+
attribute :first_name, type: String
|
|
293
|
+
attribute :last_name, type: String
|
|
294
|
+
attribute :member_id, type: Integer
|
|
295
|
+
attribute :direct_debit, type: Object
|
|
296
|
+
attribute :start_date, type: Object
|
|
297
|
+
attribute :payments, type: Object, default: {} # payment_id -> Array of statuses
|
|
298
|
+
attribute :schedule, type: Object
|
|
299
|
+
|
|
300
|
+
if ActiveModel::VERSION::MAJOR < 4
|
|
301
|
+
attr_accessible :first_name, :last_name, :member_id, :direct_debit, :start_date, :payments, :schedule
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
validates_numericality_of :member_id, only_integer: true, greater_than: 0
|
|
305
|
+
validates_presence_of :first_name
|
|
306
|
+
validates_presence_of :last_name
|
|
307
|
+
validates_presence_of :schedule
|
|
308
|
+
validates_inclusion_of :direct_debit, in: [:active, :inactive, :cancelled]
|
|
309
|
+
validates :payments, hash: {key_type: Fixnum, value_type: Array}
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
# @!method initialize
|
|
313
|
+
# Initialize a new Schedule
|
|
314
|
+
# @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
# Get the most recent status for a member's payment
|
|
318
|
+
# @param [Osm::OnlinePayment::Schedule::Payment, Fixnum, #to_i] payment The payment (or it's ID) to check
|
|
319
|
+
# @return [Boolean]
|
|
320
|
+
def latest_status_for(payment)
|
|
321
|
+
@latest_status ||= Hash[ payments.map{ |k,v| [k, v.sort[0]] } ]
|
|
322
|
+
@latest_status[payment.to_i]
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# Check if the status of a member's payment is considered paid
|
|
326
|
+
# @param [Osm::OnlinePayment::Schedule::Payment, Fixnum, #to_i] payment The payment (or it's ID) to check
|
|
327
|
+
# @return [Boolean, nil]
|
|
328
|
+
def paid?(payment)
|
|
329
|
+
status = latest_status_for(payment.to_i)
|
|
330
|
+
return nil if status.nil?
|
|
331
|
+
[:paid, :paid_manually, :received, :initiated].include?(status.status)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# Check if the status of a member's payment is considered unpaid
|
|
335
|
+
# @param [Osm::OnlinePayment::Schedule::Payment, Fixnum, #to_i] payment The payment (or it's ID) to check
|
|
336
|
+
# @return [Boolean, nil]
|
|
337
|
+
def unpaid?(payment)
|
|
338
|
+
status = latest_status_for(payment.to_i)
|
|
339
|
+
return nil if status.nil?
|
|
340
|
+
[:required].include?(status.status)
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
# Check if a payment is over due (or will be over due on the passed date)
|
|
344
|
+
# @param [Osm::OnlinePayment::Schedule::Payment, Fixnum, #to_i] payment The payment (or it's ID) to check
|
|
345
|
+
# @param [Date] date The date to check for (defaults to today)
|
|
346
|
+
# @return [Boolean] whether the member's payment is unpaid and the payment's due date has passed
|
|
347
|
+
def over_due?(payment, date=nil)
|
|
348
|
+
unpaid?(payment) && payment.past_due?(date)
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# Check if the member has an active direct debit for this schedule
|
|
352
|
+
# @return [Boolean]
|
|
353
|
+
def active_direct_debit?
|
|
354
|
+
direct_debit.eql?(:active)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# Update the status of a payment for the member in OSM
|
|
358
|
+
# @param [Osm::Api] api The api to use to make the request
|
|
359
|
+
# @param [Osm::OnlinePayment::Schedule::Payment, Fixnum, #to_i] payment The payment (or it's ID) to update
|
|
360
|
+
# @param [Symbol] status What to update the status to (:required, :not_required or :paid_manually)
|
|
361
|
+
# @param [Boolean] gift_aid Whether to update the gift aid record too (only relevant when setting to :paid_manually)
|
|
362
|
+
# @return [Boolean] whether the update was made in OSM
|
|
363
|
+
def update_payment_status(api, payment, status, gift_aid=false)
|
|
364
|
+
payment_id = payment.to_i
|
|
365
|
+
fail ArgumentError, "#{payment_id} is not a valid payment for the schedule." unless schedule.payments.map(&:id).include?(payment_id)
|
|
366
|
+
fail ArgumentError, "status must be either :required, :not_required or :paid_manually. You passed in #{status.inspect}" unless [:required, :not_required, :paid_manually].include?(status)
|
|
367
|
+
|
|
368
|
+
gift_aid = false unless payment.schedule.gift_aid?
|
|
369
|
+
api_status = {
|
|
370
|
+
required: 'Payment required',
|
|
371
|
+
not_required: 'Payment not required',
|
|
372
|
+
paid_manually: 'Paid manually',
|
|
373
|
+
}[status]
|
|
374
|
+
|
|
375
|
+
data = api.perform_query("ext/finances/onlinepayments/?action=updatePaymentStatus", {
|
|
376
|
+
'sectionid' => schedule.section_id,
|
|
377
|
+
'schemeid' => schedule.id,
|
|
378
|
+
'scoutid' => member_id,
|
|
379
|
+
'paymentid' => payment_id,
|
|
380
|
+
'giftaid' => gift_aid,
|
|
381
|
+
'value' => api_status,
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
data = data[payment_id.to_s]
|
|
385
|
+
return false if data.nil? # No data (at all) for this payment
|
|
386
|
+
data = PaymentStatus.build_from_json(data)
|
|
387
|
+
return false if data.nil? # No history for payment so it didn't get updated
|
|
388
|
+
data = data.sort[0]
|
|
389
|
+
return false if data.nil? # No history for payment so it didn't get updated
|
|
390
|
+
return false unless data.status.eql?(status) # Latest status is not what we set
|
|
391
|
+
return true
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# Mark a payment as required by the member
|
|
395
|
+
# @param [Osm::Api] api The api to use to make the request
|
|
396
|
+
# @param [Osm::OnlinePayment::Schedule::Payment, Fixnum, #to_i] payment The payment (or it's ID) to update
|
|
397
|
+
# @return [Boolean] whether the update was made in OSM
|
|
398
|
+
def mark_payment_required(api, payment)
|
|
399
|
+
update_payment_status(api, payment, :required)
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
# Mark a payment as not required by the member
|
|
403
|
+
# @param [Osm::Api] api The api to use to make the request
|
|
404
|
+
# @param [Osm::OnlinePayment::Schedule::Payment, Fixnum, #to_i] payment The payment (or it's ID) to update
|
|
405
|
+
# @return [Boolean] whether the update was made in OSM
|
|
406
|
+
def mark_payment_not_required(api, payment)
|
|
407
|
+
update_payment_status(api, payment, :not_required)
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
# Mark a payment as paid by the member
|
|
411
|
+
# @param [Osm::Api] api The api to use to make the request
|
|
412
|
+
# @param [Osm::OnlinePayment::Schedule::Payment, Fixnum, #to_i] payment The payment (or it's ID) to update
|
|
413
|
+
# @param [Boolean] gift_aid Whether to update the gift aid record too
|
|
414
|
+
# @return [Boolean] whether the update was made in OSM
|
|
415
|
+
def mark_payment_paid_manually(api, payment, gift_aid=false)
|
|
416
|
+
update_payment_status(api, payment, :paid_manually, gift_aid)
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
end # Schedule::PaymentsForMember class
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
class PaymentStatus < Osm::Model
|
|
423
|
+
VALID_STATUSES = [:required, :not_required, :initiated, :paid, :received, :paid_manually]
|
|
424
|
+
|
|
425
|
+
attribute :id, type: Integer
|
|
426
|
+
attribute :payment, type: Object
|
|
427
|
+
attribute :timestamp, type: Object
|
|
428
|
+
attribute :status, type: Object
|
|
429
|
+
attribute :details, type: String
|
|
430
|
+
attribute :updated_by, type: String
|
|
431
|
+
attribute :updated_by_id, type: Integer
|
|
432
|
+
|
|
433
|
+
if ActiveModel::VERSION::MAJOR < 4
|
|
434
|
+
attr_accessible :id, :payment, :timestamp, :status, :details, :updated_by, :updated_by_id
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
validates_numericality_of :id, only_integer: true, greater_than: 0
|
|
438
|
+
validates_numericality_of :updated_by_id, only_integer: true, greater_than_or_equal_to: -2
|
|
439
|
+
validates_presence_of :payment
|
|
440
|
+
validates_presence_of :timestamp
|
|
441
|
+
validates_presence_of :updated_by
|
|
442
|
+
validates_inclusion_of :status, in: VALID_STATUSES
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
# @!method initialize
|
|
446
|
+
# Initialize a new PaymentStatus
|
|
447
|
+
# @param [Hash] attributes The hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
# @!method required?
|
|
451
|
+
# Whether the status is :required
|
|
452
|
+
# @return (Boolean)
|
|
453
|
+
# @!method not_required?
|
|
454
|
+
# Whether the status is :not_required
|
|
455
|
+
# @return (Boolean)
|
|
456
|
+
# @!method initiated?
|
|
457
|
+
# Whether the status is :initiated
|
|
458
|
+
# @return (Boolean)
|
|
459
|
+
# @!method paid?
|
|
460
|
+
# Whether the status is :paid
|
|
461
|
+
# @return (Boolean)
|
|
462
|
+
# @!method received?
|
|
463
|
+
# Whether the status is :received
|
|
464
|
+
# @return (Boolean)
|
|
465
|
+
# @!method paid_manually?
|
|
466
|
+
# Whether the status is :paid_manually
|
|
467
|
+
# @return (Boolean)
|
|
468
|
+
VALID_STATUSES.each do |attribute|
|
|
469
|
+
define_method "#{attribute}?" do
|
|
470
|
+
status.eql?(attribute)
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
def <=>(another)
|
|
476
|
+
result = -(self.timestamp <=> another.try(:timestamp))
|
|
477
|
+
result = self.payment <=> another.try(:payment) if result.eql?(0)
|
|
478
|
+
result = self.id <=> another.try(:id) if result.eql?(0)
|
|
479
|
+
return result
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
def inspect
|
|
483
|
+
Osm.inspect_instance(self, {:replace_with => {'payment' => :id}})
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
protected
|
|
487
|
+
def self.build_from_json(json, payment=nil)
|
|
488
|
+
data = ActiveSupport::JSON.decode(json)
|
|
489
|
+
return [] unless data.is_a?(Hash)
|
|
490
|
+
data = data['status']
|
|
491
|
+
return [] unless data.is_a?(Array)
|
|
492
|
+
|
|
493
|
+
status_map = {
|
|
494
|
+
'Payment required' => :required,
|
|
495
|
+
'Payment not required' => :not_required,
|
|
496
|
+
'Initiated' => :initiated,
|
|
497
|
+
'Paid' => :paid,
|
|
498
|
+
'Received' => :received,
|
|
499
|
+
'Paid manually' => :paid_manually,
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
data.map! do |item|
|
|
503
|
+
new(
|
|
504
|
+
id: Osm::to_i_or_nil(item['statusid']),
|
|
505
|
+
payment: payment,
|
|
506
|
+
timestamp: Time.strptime(item['statustimestamp'], '%d/%m/%Y %H:%M'),
|
|
507
|
+
status: status_map[item['status']],
|
|
508
|
+
details: item['details'],
|
|
509
|
+
updated_by: item['firstname'],
|
|
510
|
+
updated_by_id: item['who'].to_i,
|
|
511
|
+
)
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
end # Schedule::PaymentStatus class
|
|
516
|
+
|
|
517
|
+
end # Schedule class
|
|
518
|
+
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
end
|
data/osm.gemspec
CHANGED
|
@@ -32,5 +32,6 @@ Gem::Specification.new do |s|
|
|
|
32
32
|
s.add_development_dependency 'rb-inotify', '~> 0.9'
|
|
33
33
|
s.add_development_dependency 'coveralls', '~> 0.7'
|
|
34
34
|
s.add_development_dependency 'simplecov', '~> 0.7'
|
|
35
|
+
s.add_development_dependency 'listen', '< 3.1' # Actually required by another dependency but >= 3.1 causing issues
|
|
35
36
|
|
|
36
37
|
end
|
data/spec/osm/event_spec.rb
CHANGED
|
@@ -16,6 +16,7 @@ describe "Event" do
|
|
|
16
16
|
:notes => 'None',
|
|
17
17
|
:archived => '0',
|
|
18
18
|
:badges => [],
|
|
19
|
+
:files => [],
|
|
19
20
|
:columns => [],
|
|
20
21
|
:notepad => 'notepad',
|
|
21
22
|
:public_notepad => 'public notepad',
|
|
@@ -39,6 +40,7 @@ describe "Event" do
|
|
|
39
40
|
event.notes.should == 'None'
|
|
40
41
|
event.archived.should == false
|
|
41
42
|
event.badges.should == []
|
|
43
|
+
event.files.should == []
|
|
42
44
|
event.columns.should == []
|
|
43
45
|
event.notepad.should == 'notepad'
|
|
44
46
|
event.public_notepad.should == 'public notepad'
|
|
@@ -208,6 +210,7 @@ describe "Event" do
|
|
|
208
210
|
|
|
209
211
|
FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/events.php?action=getEvents§ionid=1&showArchived=true", :body => @events_body.to_json, :content_type => 'application/json')
|
|
210
212
|
FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/events.php?action=getEvent§ionid=1&eventid=2", :body => @event_body.to_json, :content_type => 'application/json')
|
|
213
|
+
FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/ext/uploads/events/?action=listAttachments§ionid=1&eventid=2", :body => '{"files":["file1.txt", "file2.txt"]}', :content_type => 'application/json')
|
|
211
214
|
|
|
212
215
|
Osm::Model.stub(:get_user_permissions) { {:events => [:read, :write]} }
|
|
213
216
|
end
|
|
@@ -252,9 +255,16 @@ describe "Event" do
|
|
|
252
255
|
event.badges[1].badge_type.should == :staged
|
|
253
256
|
event.badges[1].requirement_id.should == 4
|
|
254
257
|
event.badges[1].data.should == '1'
|
|
258
|
+
event.files.should == ['file1.txt', 'file2.txt']
|
|
255
259
|
event.valid?.should == true
|
|
256
260
|
end
|
|
257
261
|
|
|
262
|
+
it "Handles no files being an empty array not a hash" do
|
|
263
|
+
FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/ext/uploads/events/?action=listAttachments§ionid=1&eventid=2", :body => '[]', :content_type => 'application/json')
|
|
264
|
+
expect{ @event = Osm::Event.get(@api, 1, 2) }.to_not raise_error
|
|
265
|
+
@event.files.should == []
|
|
266
|
+
end
|
|
267
|
+
|
|
258
268
|
it "Handles a blank config" do
|
|
259
269
|
@event_body['config'] = ''
|
|
260
270
|
FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/events.php?action=getEvent§ionid=1&eventid=2", :body => @event_body.to_json,:content_type => 'application/json')
|
|
@@ -313,6 +323,8 @@ describe "Event" do
|
|
|
313
323
|
FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/events.php?action=getEvents§ionid=1&showArchived=true", :body => body.to_json, :content_type => 'application/json')
|
|
314
324
|
FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/events.php?action=getEvent§ionid=1&eventid=1", :body => {'config' => '[]', 'archived' => '0', 'eventid' => '1'}.to_json, :content_type => 'application/json')
|
|
315
325
|
FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/events.php?action=getEvent§ionid=1&eventid=2", :body => {'config' => '[]', 'archived' => '1', 'eventid' => '2'}.to_json, :content_type => 'application/json')
|
|
326
|
+
FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/ext/uploads/events/?action=listAttachments§ionid=1&eventid=1", :body => '[]', :content_type => 'application/json')
|
|
327
|
+
FakeWeb.register_uri(:post, "https://www.onlinescoutmanager.co.uk/ext/uploads/events/?action=listAttachments§ionid=1&eventid=2", :body => '[]', :content_type => 'application/json')
|
|
316
328
|
|
|
317
329
|
events = Osm::Event.get_for_section(@api, 1)
|
|
318
330
|
OsmTest::Cache.clear
|
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe "Online payments" do
|
|
5
|
+
|
|
6
|
+
describe "Schedule" do
|
|
7
|
+
|
|
8
|
+
it "Create" do
|
|
9
|
+
schedule = Osm::OnlinePayment::Schedule.new(
|
|
10
|
+
id: 1,
|
|
11
|
+
section_id: 2,
|
|
12
|
+
account_id: 3,
|
|
13
|
+
name: 'A payment schedule',
|
|
14
|
+
description: 'What this payment schedule is used for',
|
|
15
|
+
archived: true,
|
|
16
|
+
gift_aid: true,
|
|
17
|
+
require_all: true,
|
|
18
|
+
pay_now: 14,
|
|
19
|
+
annual_limit: '100',
|
|
20
|
+
payments: [],
|
|
21
|
+
)
|
|
22
|
+
schedule.id.should == 1
|
|
23
|
+
schedule.section_id.should == 2
|
|
24
|
+
schedule.account_id.should == 3
|
|
25
|
+
schedule.name.should == 'A payment schedule'
|
|
26
|
+
schedule.description.should == 'What this payment schedule is used for'
|
|
27
|
+
schedule.archived.should == true
|
|
28
|
+
schedule.gift_aid.should == true
|
|
29
|
+
schedule.require_all.should == true
|
|
30
|
+
schedule.pay_now.should == 14
|
|
31
|
+
schedule.annual_limit.should == '100'
|
|
32
|
+
schedule.payments.should == []
|
|
33
|
+
schedule.valid?.should == true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "Provides current payments" do
|
|
37
|
+
payment1 = Osm::OnlinePayment::Schedule::Payment.new(id: 1, archived: false)
|
|
38
|
+
payment2 = Osm::OnlinePayment::Schedule::Payment.new(id: 2, archived: true)
|
|
39
|
+
schedule = Osm::OnlinePayment::Schedule.new(payments: [payment1, payment2])
|
|
40
|
+
schedule.current_payments.should == [payment1]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "Checks for current payments" do
|
|
44
|
+
payment1 = Osm::OnlinePayment::Schedule::Payment.new(id: 1, archived: false)
|
|
45
|
+
payment2 = Osm::OnlinePayment::Schedule::Payment.new(id: 2, archived: true)
|
|
46
|
+
schedule = Osm::OnlinePayment::Schedule.new()
|
|
47
|
+
|
|
48
|
+
schedule.payments = [payment1]
|
|
49
|
+
schedule.current_payments?.should == true
|
|
50
|
+
|
|
51
|
+
schedule.payments = [payment2]
|
|
52
|
+
schedule.current_payments?.should == false
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "Provides archived payments" do
|
|
56
|
+
payment1 = Osm::OnlinePayment::Schedule::Payment.new(id: 1, archived: false)
|
|
57
|
+
payment2 = Osm::OnlinePayment::Schedule::Payment.new(id: 2, archived: true)
|
|
58
|
+
schedule = Osm::OnlinePayment::Schedule.new(payments: [payment1, payment2])
|
|
59
|
+
schedule.archived_payments.should == [payment2]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "Checks for archived payments" do
|
|
63
|
+
payment1 = Osm::OnlinePayment::Schedule::Payment.new(id: 1, archived: false)
|
|
64
|
+
payment2 = Osm::OnlinePayment::Schedule::Payment.new(id: 2, archived: true)
|
|
65
|
+
schedule = Osm::OnlinePayment::Schedule.new()
|
|
66
|
+
|
|
67
|
+
schedule.payments = [payment2]
|
|
68
|
+
schedule.archived_payments?.should == true
|
|
69
|
+
|
|
70
|
+
schedule.payments = [payment1]
|
|
71
|
+
schedule.archived_payments?.should == false
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "Sorts by section_id, name then id" do
|
|
75
|
+
schedule1 = Osm::OnlinePayment::Schedule.new(section_id: 1, name: 'A', id: 1)
|
|
76
|
+
schedule2 = Osm::OnlinePayment::Schedule.new(section_id: 2, name: 'A', id: 1)
|
|
77
|
+
schedule3 = Osm::OnlinePayment::Schedule.new(section_id: 2, name: 'B', id: 1)
|
|
78
|
+
schedule4 = Osm::OnlinePayment::Schedule.new(section_id: 2, name: 'B', id: 2)
|
|
79
|
+
schedules = [schedule3, schedule2, schedule4, schedule1]
|
|
80
|
+
schedules.sort.should == [schedule1, schedule2, schedule3, schedule4]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "Converts to a string" do
|
|
84
|
+
schedule = Osm::OnlinePayment::Schedule.new(id: 1, name: 'Name')
|
|
85
|
+
schedule.to_s.should == '1 -> Name'
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
describe "Uses OSM's API" do
|
|
90
|
+
|
|
91
|
+
it "Gets summary list" do
|
|
92
|
+
@api.should_receive(:perform_query).with('ext/finances/onlinepayments/?action=getSchemes§ionid=1'){ {'items'=>[{"schemeid"=>"539","name"=>"Events"}]} }
|
|
93
|
+
result = Osm::OnlinePayment::Schedule.get_list_for_section(@api, 1)
|
|
94
|
+
result.should == [{id: 539, name: 'Events'}]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "Gets an individual schedule" do
|
|
98
|
+
data = {"schemeid"=>"2","sectionid"=>"1","accountid"=>"3","name"=>"Schedule name","preauth_amount"=>"12.34","description"=>"Schedule description","giftaid"=>"1","defaulton"=>"1","paynow"=>"-1","archived"=>"1","payments"=>[{"paymentid"=>"4","schemeid"=>"2","date"=>"2013-03-21","amount"=>"1.23","name"=>"Payment name","archived"=>"1"}]}
|
|
99
|
+
@api.should_receive(:perform_query).with('ext/finances/onlinepayments/?action=getPaymentSchedule§ionid=1&schemeid=2&allpayments=true'){ data }
|
|
100
|
+
schedule = Osm::OnlinePayment::Schedule.get(@api, 1, 2)
|
|
101
|
+
schedule.id.should == 2
|
|
102
|
+
schedule.section_id.should == 1
|
|
103
|
+
schedule.account_id.should == 3
|
|
104
|
+
schedule.name.should == 'Schedule name'
|
|
105
|
+
schedule.description.should == 'Schedule description'
|
|
106
|
+
schedule.archived.should == true
|
|
107
|
+
schedule.gift_aid.should == true
|
|
108
|
+
schedule.require_all.should == true
|
|
109
|
+
schedule.pay_now.should == -1
|
|
110
|
+
schedule.annual_limit.should == '12.34'
|
|
111
|
+
schedule.payments.count.should == 1
|
|
112
|
+
schedule.valid?.should == true
|
|
113
|
+
payment = schedule.payments[0]
|
|
114
|
+
payment.id.should == 4
|
|
115
|
+
payment.amount.should == '1.23'
|
|
116
|
+
payment.name.should == 'Payment name'
|
|
117
|
+
payment.archived.should == true
|
|
118
|
+
payment.due_date.should == Date.new(2013, 3, 21)
|
|
119
|
+
payment.schedule.should == schedule
|
|
120
|
+
payment.valid?.should == true
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "Gets all schedules for a section" do
|
|
124
|
+
Osm::OnlinePayment::Schedule.should_receive(:get_list_for_section).with(@api, 5, {}){ [{id: 6, name: 'A'}, {id: 7, name: 'B'}] }
|
|
125
|
+
Osm::OnlinePayment::Schedule.should_receive(:get).with(@api, 5, 6, {}){ 'A' }
|
|
126
|
+
Osm::OnlinePayment::Schedule.should_receive(:get).with(@api, 5, 7, {}){ 'B' }
|
|
127
|
+
Osm::OnlinePayment::Schedule.get_for_section(@api, 5).should == ['A', 'B']
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
describe "Gets member's payments" do
|
|
131
|
+
|
|
132
|
+
before :each do
|
|
133
|
+
@payment = Osm::OnlinePayment::Schedule::Payment.new(id: 4)
|
|
134
|
+
@schedule = Osm::OnlinePayment::Schedule.new(
|
|
135
|
+
id: 1,
|
|
136
|
+
section_id: 2,
|
|
137
|
+
payments: [@payment]
|
|
138
|
+
)
|
|
139
|
+
body = {'items'=>[ {
|
|
140
|
+
'directdebit'=>'Active', 'firstname'=>'John', 'lastname'=>'Snow', 'patrolid'=>'5', 'scoutid'=>'6',
|
|
141
|
+
'startdate'=>'2015-02-03',
|
|
142
|
+
'4'=>'{"status":[{"statusid":"7","scoutid":"6","schemeid":"1","paymentid":"8","statustimestamp":"03/02/2016 20:51","status":"Paid manually","details":"","editable":"1","latest":"1","who":"0","firstname":"System"}]}',
|
|
143
|
+
} ]}
|
|
144
|
+
@api.should_receive(:perform_query).with('ext/finances/onlinepayments/?action=getPaymentStatus§ionid=2&schemeid=1&termid=3').once{ body }
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it 'For a "collect all" schedule' do
|
|
148
|
+
@schedule.require_all = true
|
|
149
|
+
p4m = @schedule.get_payments_for_members(@api, 3)
|
|
150
|
+
p4m.is_a?(Array).should == true
|
|
151
|
+
p4m.size.should == 1
|
|
152
|
+
p4m = p4m[0]
|
|
153
|
+
p4m.member_id.should == 6
|
|
154
|
+
p4m.first_name.should == 'John'
|
|
155
|
+
p4m.last_name.should == 'Snow'
|
|
156
|
+
p4m.start_date.should == Date.new(2015, 2, 3)
|
|
157
|
+
p4m.direct_debit.should == :active
|
|
158
|
+
p4m.payments.size.should == 1
|
|
159
|
+
payment = p4m.payments[4][0]
|
|
160
|
+
payment.id.should == 7
|
|
161
|
+
payment.payment.should == @payment
|
|
162
|
+
payment.timestamp.should == Time.new(2016, 2, 3, 20, 51)
|
|
163
|
+
payment.status.should == :paid_manually
|
|
164
|
+
payment.details.should == ''
|
|
165
|
+
payment.updated_by.should == 'System'
|
|
166
|
+
payment.updated_by_id.should == 0
|
|
167
|
+
payment.valid?.should == true
|
|
168
|
+
p4m.valid?.should == true
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'For a "not collect all" schedule' do
|
|
172
|
+
@schedule.require_all = false
|
|
173
|
+
p4m = @schedule.get_payments_for_members(@api, 3)[0]
|
|
174
|
+
p4m.start_date.should == nil # Only difference to a "collect all" type
|
|
175
|
+
p4m.valid?.should == true
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "When it needs to fetch a term" do
|
|
179
|
+
section = Osm::Section.new(id: 2)
|
|
180
|
+
Osm::Term.stub(:get_current_term_for_section).and_return(Osm::Term.new(id: 3))
|
|
181
|
+
Osm::Section.stub(:get).and_return(section)
|
|
182
|
+
p4m = @schedule.get_payments_for_members(@api)[0]
|
|
183
|
+
p4m.member_id.should == 6
|
|
184
|
+
p4m.valid?.should == true
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end # describe Schedule : Uses OSM's API : Get member's payments
|
|
188
|
+
|
|
189
|
+
end # describe Schedule : Uses OSM's API
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
describe "Payment" do
|
|
193
|
+
|
|
194
|
+
it "Create" do
|
|
195
|
+
schedule = Osm::OnlinePayment::Schedule.new()
|
|
196
|
+
schedule.stub('valid?'){ true }
|
|
197
|
+
payment = Osm::OnlinePayment::Schedule::Payment.new(
|
|
198
|
+
id: 1,
|
|
199
|
+
amount: '12.34',
|
|
200
|
+
name: 'A payment',
|
|
201
|
+
archived: true,
|
|
202
|
+
due_date: Date.new(2016, 5, 1),
|
|
203
|
+
schedule: schedule,
|
|
204
|
+
)
|
|
205
|
+
payment.id.should == 1
|
|
206
|
+
payment.amount.should == '12.34'
|
|
207
|
+
payment.name.should == 'A payment'
|
|
208
|
+
payment.archived.should == true
|
|
209
|
+
payment.due_date.should == Date.new(2016, 5, 1)
|
|
210
|
+
payment.schedule.should == schedule
|
|
211
|
+
payment.valid?.should == true
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it "Checks if a payment is past due" do
|
|
215
|
+
payment = Osm::OnlinePayment::Schedule::Payment.new(due_date: Date.new(2016, 5, 2))
|
|
216
|
+
payment.past_due?(Date.new(2016, 5, 1)).should == false
|
|
217
|
+
payment.past_due?(Date.new(2016, 5, 2)).should == false
|
|
218
|
+
payment.past_due?(Date.new(2016, 5, 3)).should == true
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
end # describe Schedule -> Payment
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
describe "PaymentsForMember" do
|
|
225
|
+
|
|
226
|
+
it "Create" do
|
|
227
|
+
schedule = Osm::OnlinePayment::Schedule.new
|
|
228
|
+
p4m = Osm::OnlinePayment::Schedule::PaymentsForMember.new(
|
|
229
|
+
first_name: 'John',
|
|
230
|
+
last_name: 'Smith',
|
|
231
|
+
member_id: 1,
|
|
232
|
+
direct_debit: :active,
|
|
233
|
+
start_date: Date.new(2016, 6, 7),
|
|
234
|
+
payments: {},
|
|
235
|
+
schedule: schedule,
|
|
236
|
+
)
|
|
237
|
+
p4m.first_name.should == 'John'
|
|
238
|
+
p4m.last_name.should == 'Smith'
|
|
239
|
+
p4m.member_id.should == 1
|
|
240
|
+
p4m.direct_debit.should == :active
|
|
241
|
+
p4m.start_date.should == Date.new(2016, 6, 7)
|
|
242
|
+
p4m.payments.should == {}
|
|
243
|
+
p4m.schedule.should == schedule
|
|
244
|
+
p4m.valid?.should == true
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
it "Gets most recent status for a payment" do
|
|
248
|
+
payments = {
|
|
249
|
+
1 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(id: 1, timestamp: Time.new(2016, 1, 2, 3, 4))],
|
|
250
|
+
2 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(id: 2, timestamp: Time.new(2016, 1, 2, 3, 4))],
|
|
251
|
+
3 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(id: 3, timestamp: Time.new(2016, 1, 2, 3, 4)), Osm::OnlinePayment::Schedule::PaymentStatus.new(id: 4, timestamp: Time.new(2016, 1, 2, 3, 5))],
|
|
252
|
+
}
|
|
253
|
+
p4m = Osm::OnlinePayment::Schedule::PaymentsForMember.new(payments: payments)
|
|
254
|
+
|
|
255
|
+
p4m.latest_status_for(1).id.should == 1
|
|
256
|
+
p4m.latest_status_for(Osm::OnlinePayment::Schedule::Payment.new(id: 2)).id.should == 2
|
|
257
|
+
p4m.latest_status_for(3).id.should == 4
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it "Works out if a payment is paid" do
|
|
261
|
+
payments = {
|
|
262
|
+
1 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :required)],
|
|
263
|
+
2 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :not_required)],
|
|
264
|
+
3 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :initiated)],
|
|
265
|
+
4 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :paid)],
|
|
266
|
+
5 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :received)],
|
|
267
|
+
6 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :paid_manually)],
|
|
268
|
+
}
|
|
269
|
+
p4m = Osm::OnlinePayment::Schedule::PaymentsForMember.new(payments: payments)
|
|
270
|
+
|
|
271
|
+
p4m.paid?(1).should == false
|
|
272
|
+
p4m.paid?(2).should == false
|
|
273
|
+
p4m.paid?(3).should == true
|
|
274
|
+
p4m.paid?(4).should == true
|
|
275
|
+
p4m.paid?(5).should == true
|
|
276
|
+
p4m.paid?(6).should == true
|
|
277
|
+
p4m.paid?(7).should == nil
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it "Works out if a payment is unpaid" do
|
|
281
|
+
payments = {
|
|
282
|
+
1 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :required)],
|
|
283
|
+
2 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :not_required)],
|
|
284
|
+
3 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :initiated)],
|
|
285
|
+
4 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :paid)],
|
|
286
|
+
5 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :received)],
|
|
287
|
+
6 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :paid_manually)],
|
|
288
|
+
}
|
|
289
|
+
p4m = Osm::OnlinePayment::Schedule::PaymentsForMember.new(payments: payments)
|
|
290
|
+
|
|
291
|
+
p4m.unpaid?(1).should == true
|
|
292
|
+
p4m.unpaid?(2).should == false
|
|
293
|
+
p4m.unpaid?(3).should == false
|
|
294
|
+
p4m.unpaid?(4).should == false
|
|
295
|
+
p4m.unpaid?(5).should == false
|
|
296
|
+
p4m.unpaid?(6).should == false
|
|
297
|
+
p4m.unpaid?(7).should == nil
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
it "Tells if the user has an active direct debit" do
|
|
301
|
+
p4m = Osm::OnlinePayment::Schedule::PaymentsForMember.new(direct_debit: :active)
|
|
302
|
+
p4m.active_direct_debit?.should == true
|
|
303
|
+
|
|
304
|
+
p4m = Osm::OnlinePayment::Schedule::PaymentsForMember.new(direct_debit: :inactive)
|
|
305
|
+
p4m.active_direct_debit?.should == false
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
describe "Works out if a payment is over due" do
|
|
309
|
+
|
|
310
|
+
before :each do
|
|
311
|
+
@payment = Osm::OnlinePayment::Schedule::Payment.new(id: 1, due_date: Date.new(2016, 1, 2))
|
|
312
|
+
paid_payments = { 1 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :paid, payment: @payment)] }
|
|
313
|
+
@paid = Osm::OnlinePayment::Schedule::PaymentsForMember.new(payments: paid_payments)
|
|
314
|
+
unpaid_payments = { 1 => [Osm::OnlinePayment::Schedule::PaymentStatus.new(status: :required, payment: @payment)] }
|
|
315
|
+
@unpaid = Osm::OnlinePayment::Schedule::PaymentsForMember.new(payments: unpaid_payments)
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it "Due date in over" do
|
|
319
|
+
date = Date.new(2016, 1, 3)
|
|
320
|
+
@paid.over_due?(@payment, date).should == false
|
|
321
|
+
@unpaid.over_due?(@payment, date).should == true
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it "Due date in present" do
|
|
325
|
+
# Due today means that it is not over being due
|
|
326
|
+
date = Date.new(2016, 1, 2)
|
|
327
|
+
@paid.over_due?(@payment, date).should == false
|
|
328
|
+
@unpaid.over_due?(@payment, date).should == false
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
it "Due date in future" do
|
|
332
|
+
date = Date.new(2016, 1, 1)
|
|
333
|
+
@paid.over_due?(@payment, date).should == false
|
|
334
|
+
@unpaid.over_due?(@payment, date).should == false
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
end # describe Schedule -> PaymentsForMember : is payment past due?
|
|
338
|
+
|
|
339
|
+
describe "Update a payment in OSM" do
|
|
340
|
+
|
|
341
|
+
before :each do
|
|
342
|
+
@schedule = Osm::OnlinePayment::Schedule.new(id: 10, section_id: 4, gift_aid: true)
|
|
343
|
+
@payment = Osm::OnlinePayment::Schedule::Payment.new(id: 1, schedule: @schedule)
|
|
344
|
+
@schedule.payments = [@payment]
|
|
345
|
+
@status = Osm::OnlinePayment::Schedule::PaymentStatus.new(id: 2, payment: @payment)
|
|
346
|
+
@p4m = Osm::OnlinePayment::Schedule::PaymentsForMember.new(member_id: 3, payments: {1=>[@status]}, schedule: @schedule)
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
describe "Using update_payment_status method" do
|
|
350
|
+
it "Success" do
|
|
351
|
+
@api.should_receive(:perform_query).with('ext/finances/onlinepayments/?action=updatePaymentStatus', {'sectionid'=>4,'schemeid'=>10,'scoutid'=>3,'paymentid'=>1,'giftaid'=>false,'value'=>'Payment not required'})
|
|
352
|
+
.once{ {'scoutid'=>'3', 'firstname'=>'John', 'lastname'=>'Smith', 'patrolid'=>'5', 'startdate'=>'1970-01-01', 'directdebit'=>'cancelled', '1'=>'{"status":[{"statusid":"6","scoutid":"3","schemeid":"4","paymentid":"1","statustimestamp":"01/02/2003 04:05","status":"Payment not required","details":"","editable":"0","latest":"1","who":"0","firstname":"System generated"}]}'} }
|
|
353
|
+
@p4m.update_payment_status(@api, @payment, :not_required).should == true
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
describe "Failure" do
|
|
357
|
+
it "No history for payment" do
|
|
358
|
+
@api.should_receive(:perform_query).with('ext/finances/onlinepayments/?action=updatePaymentStatus', {'sectionid'=>4,'schemeid'=>10,'scoutid'=>3,'paymentid'=>1,'giftaid'=>true,'value'=>'Paid manually'})
|
|
359
|
+
.once{ {'scoutid'=>'3', 'firstname'=>'John', 'lastname'=>'Smith', 'patrolid'=>'5', 'startdate'=>'1970-01-01', 'directdebit'=>'cancelled', '1'=>'{"status":[]}'} }
|
|
360
|
+
@p4m.update_payment_status(@api, @payment, :paid_manually, true).should == false
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
it "No payment data" do
|
|
364
|
+
@api.should_receive(:perform_query).with('ext/finances/onlinepayments/?action=updatePaymentStatus', {'sectionid'=>4,'schemeid'=>10,'scoutid'=>3,'paymentid'=>1,'giftaid'=>true,'value'=>'Paid manually'})
|
|
365
|
+
.once{ {'scoutid'=>'3', 'firstname'=>'John', 'lastname'=>'Smith', 'patrolid'=>'5', 'startdate'=>'1970-01-01', 'directdebit'=>'cancelled'} }
|
|
366
|
+
@p4m.update_payment_status(@api, @payment, :paid_manually, true).should == false
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
it "Latest status is not what we set" do
|
|
370
|
+
@api.should_receive(:perform_query).with('ext/finances/onlinepayments/?action=updatePaymentStatus', {'sectionid'=>4,'schemeid'=>10,'scoutid'=>3,'paymentid'=>1,'giftaid'=>true,'value'=>'Paid manually'})
|
|
371
|
+
.once{ {'scoutid'=>'3', 'firstname'=>'John', 'lastname'=>'Smith', 'patrolid'=>'5', 'startdate'=>'1970-01-01', 'directdebit'=>'cancelled', '1'=>'{"status":[{"statusid":"6","scoutid":"3","schemeid":"4","paymentid":"1","statustimestamp":"01/02/2003 04:05","status":"Payment not required","details":"","editable":"0","latest":"1","who":"0","firstname":"System generated"}]}'} }
|
|
372
|
+
@p4m.update_payment_status(@api, @payment, :paid_manually, true).should == false
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
it "Fails if payment is not in the schedule" do
|
|
377
|
+
expect{ @p4m.update_payment_status(@api, 2, :paid_manually) }.to raise_error ArgumentError, '2 is not a valid payment for the schedule.'
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
it "Fails if given a bad status" do
|
|
381
|
+
expect{ @p4m.update_payment_status(@api, 1, :invalid) }.to raise_error ArgumentError, 'status must be either :required, :not_required or :paid_manually. You passed in :invalid'
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
describe "Ignores gift aid parameter if appropriate" do # pass in true and check if calls out with false
|
|
385
|
+
it "Schedule is a gift aid one" do
|
|
386
|
+
@api.should_receive(:perform_query).with('ext/finances/onlinepayments/?action=updatePaymentStatus', {'sectionid'=>4,'schemeid'=>10,'scoutid'=>3,'paymentid'=>1,'giftaid'=>true,'value'=>'Paid manually'})
|
|
387
|
+
.once{ {'scoutid'=>'3', 'firstname'=>'John', 'lastname'=>'Smith', 'patrolid'=>'5', 'startdate'=>'1970-01-01', 'directdebit'=>'cancelled', '1'=>'{"status":[{"statusid":"6","scoutid":"3","schemeid":"4","paymentid":"1","statustimestamp":"01/02/2003 04:05","status":"Paid manually","details":"","editable":"0","latest":"1","who":"0","firstname":"System generated"}]}'} }
|
|
388
|
+
@p4m.update_payment_status(@api, @payment, :paid_manually, true).should == true
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it "Schedule is NOT a gift aid one" do
|
|
392
|
+
@schedule.gift_aid = false
|
|
393
|
+
@api.should_receive(:perform_query).with('ext/finances/onlinepayments/?action=updatePaymentStatus', {'sectionid'=>4,'schemeid'=>10,'scoutid'=>3,'paymentid'=>1,'giftaid'=>false,'value'=>'Paid manually'})
|
|
394
|
+
.once{ {'scoutid'=>'3', 'firstname'=>'John', 'lastname'=>'Smith', 'patrolid'=>'5', 'startdate'=>'1970-01-01', 'directdebit'=>'cancelled', '1'=>'{"status":[{"statusid":"6","scoutid":"3","schemeid":"4","paymentid":"1","statustimestamp":"01/02/2003 04:05","status":"Paid manually","details":"","editable":"0","latest":"1","who":"0","firstname":"System generated"}]}'} }
|
|
395
|
+
@p4m.update_payment_status(@api, @payment, :paid_manually, true).should == true
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
end # Using update_payment_status method
|
|
400
|
+
|
|
401
|
+
describe "Using" do
|
|
402
|
+
it "mark_payment_required" do
|
|
403
|
+
@p4m.should_receive(:update_payment_status).with(@api, @payment, :required).once{ true }
|
|
404
|
+
@p4m.mark_payment_required(@api, @payment).should == true
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
it "mark_payment_not_required" do
|
|
408
|
+
@p4m.should_receive(:update_payment_status).with(@api, @payment, :not_required).once{ true }
|
|
409
|
+
@p4m.mark_payment_not_required(@api, @payment).should == true
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
describe "mark_payment_paid_manually" do
|
|
413
|
+
it "Updating gift aid" do
|
|
414
|
+
@p4m.should_receive(:update_payment_status).with(@api, @payment, :paid_manually, true).once{ true }
|
|
415
|
+
@p4m.mark_payment_paid_manually(@api, @payment, true).should == true
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
it "Not updating gift aid" do
|
|
419
|
+
@p4m.should_receive(:update_payment_status).with(@api, @payment, :paid_manually, false).once{ true }
|
|
420
|
+
@p4m.mark_payment_paid_manually(@api, @payment, false).should == true
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
end # describe Schedule -> PaymentsForMember : Update a payment in OSM
|
|
427
|
+
|
|
428
|
+
end # describe Schedule -> PaymentsForMember
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
describe "Payment status" do
|
|
432
|
+
|
|
433
|
+
it "Create" do
|
|
434
|
+
payment = Osm::OnlinePayment::Schedule::Payment.new
|
|
435
|
+
payment.stub('valid?'){ true }
|
|
436
|
+
status = Osm::OnlinePayment::Schedule::PaymentStatus.new(
|
|
437
|
+
id: 1,
|
|
438
|
+
payment: payment,
|
|
439
|
+
details: 'Details',
|
|
440
|
+
timestamp: Time.new(2016, 4, 5, 6, 7),
|
|
441
|
+
status: :paid,
|
|
442
|
+
updated_by: 'My.SCOUT',
|
|
443
|
+
updated_by_id: -2,
|
|
444
|
+
)
|
|
445
|
+
status.id.should == 1
|
|
446
|
+
status.payment.should == payment
|
|
447
|
+
status.details.should == 'Details'
|
|
448
|
+
status.timestamp.should == Time.new(2016, 4, 5, 6, 7)
|
|
449
|
+
status.status.should == :paid
|
|
450
|
+
status.updated_by.should == 'My.SCOUT'
|
|
451
|
+
status.updated_by_id.should == -2
|
|
452
|
+
status.valid?.should == true
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
it "Sorts by timestamp (desc), payment then id" do
|
|
456
|
+
status1 = Osm::OnlinePayment::Schedule::PaymentStatus.new(timestamp: Time.new(2016, 1, 2, 3, 6), payment: 1, id: 1)
|
|
457
|
+
status2 = Osm::OnlinePayment::Schedule::PaymentStatus.new(timestamp: Time.new(2016, 1, 2, 3, 5), payment: 1, id: 1)
|
|
458
|
+
status3 = Osm::OnlinePayment::Schedule::PaymentStatus.new(timestamp: Time.new(2016, 1, 2, 3, 5), payment: 2, id: 1)
|
|
459
|
+
status4 = Osm::OnlinePayment::Schedule::PaymentStatus.new(timestamp: Time.new(2016, 1, 2, 3, 5), payment: 2, id: 2)
|
|
460
|
+
statuses = [status3, status1, status4, status2]
|
|
461
|
+
statuses.sort.should == [status1, status2, status3, status4]
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
describe "Has status checking method for" do
|
|
465
|
+
before :each do
|
|
466
|
+
@payments = []
|
|
467
|
+
Osm::OnlinePayment::Schedule::PaymentStatus::VALID_STATUSES.each do |status|
|
|
468
|
+
payment = Osm::OnlinePayment::Schedule::PaymentStatus.new(status: status)
|
|
469
|
+
@payments.push payment
|
|
470
|
+
instance_variable_set("@#{status}_payment", payment)
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
Osm::OnlinePayment::Schedule::PaymentStatus::VALID_STATUSES.each do |status|
|
|
475
|
+
it status.to_s do
|
|
476
|
+
payment = instance_variable_get("@#{status}_payment")
|
|
477
|
+
payment.send("#{status}?").should == true
|
|
478
|
+
(Osm::OnlinePayment::Schedule::PaymentStatus::VALID_STATUSES - [status]).each do |i|
|
|
479
|
+
payment.send("#{i}?").should == false
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
end
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
end # describe Schedule -> PaymentStatus
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
end # describe Schedule
|
|
489
|
+
|
|
490
|
+
end
|
data/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: osm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Robert Gauld
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-
|
|
11
|
+
date: 2016-05-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -202,6 +202,20 @@ dependencies:
|
|
|
202
202
|
- - "~>"
|
|
203
203
|
- !ruby/object:Gem::Version
|
|
204
204
|
version: '0.7'
|
|
205
|
+
- !ruby/object:Gem::Dependency
|
|
206
|
+
name: listen
|
|
207
|
+
requirement: !ruby/object:Gem::Requirement
|
|
208
|
+
requirements:
|
|
209
|
+
- - "<"
|
|
210
|
+
- !ruby/object:Gem::Version
|
|
211
|
+
version: '3.1'
|
|
212
|
+
type: :development
|
|
213
|
+
prerelease: false
|
|
214
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
215
|
+
requirements:
|
|
216
|
+
- - "<"
|
|
217
|
+
- !ruby/object:Gem::Version
|
|
218
|
+
version: '3.1'
|
|
205
219
|
description: Use the Online Scout Manager API (https://www.onlinescoutmanager.co.uk)
|
|
206
220
|
to retrieve and save data.
|
|
207
221
|
email:
|
|
@@ -239,6 +253,7 @@ files:
|
|
|
239
253
|
- lib/osm/member.rb
|
|
240
254
|
- lib/osm/model.rb
|
|
241
255
|
- lib/osm/myscout.rb
|
|
256
|
+
- lib/osm/online_payment.rb
|
|
242
257
|
- lib/osm/register.rb
|
|
243
258
|
- lib/osm/section.rb
|
|
244
259
|
- lib/osm/sms.rb
|
|
@@ -263,6 +278,7 @@ files:
|
|
|
263
278
|
- spec/osm/member_spec.rb
|
|
264
279
|
- spec/osm/model_spec.rb
|
|
265
280
|
- spec/osm/myscout_spec.rb
|
|
281
|
+
- spec/osm/online_payment_spec.rb
|
|
266
282
|
- spec/osm/osm_spec.rb
|
|
267
283
|
- spec/osm/register_spec.rb
|
|
268
284
|
- spec/osm/section_spec.rb
|