stbaldricks 1.5.1.pre
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 +7 -0
- data/LICENSE +21 -0
- data/lib/stbaldricks.rb +2 -0
- data/lib/stbaldricks/api.rb +7 -0
- data/lib/stbaldricks/api_connector.rb +47 -0
- data/lib/stbaldricks/client.rb +7 -0
- data/lib/stbaldricks/configuration.rb +47 -0
- data/lib/stbaldricks/default_logger.rb +24 -0
- data/lib/stbaldricks/endpoints/communicate.rb +67 -0
- data/lib/stbaldricks/endpoints/config.rb +18 -0
- data/lib/stbaldricks/endpoints/contact.rb +12 -0
- data/lib/stbaldricks/endpoints/event.rb +39 -0
- data/lib/stbaldricks/endpoints/event_application.rb +32 -0
- data/lib/stbaldricks/endpoints/fund.rb +24 -0
- data/lib/stbaldricks/endpoints/kid.rb +24 -0
- data/lib/stbaldricks/endpoints/kid_honor.rb +17 -0
- data/lib/stbaldricks/endpoints/lib/entity.rb +247 -0
- data/lib/stbaldricks/endpoints/message.rb +27 -0
- data/lib/stbaldricks/endpoints/newsletter_recipient.rb +41 -0
- data/lib/stbaldricks/endpoints/participant.rb +66 -0
- data/lib/stbaldricks/endpoints/photo.rb +51 -0
- data/lib/stbaldricks/endpoints/recurring_gift.rb +18 -0
- data/lib/stbaldricks/endpoints/search.rb +63 -0
- data/lib/stbaldricks/endpoints/shave_schedule.rb +28 -0
- data/lib/stbaldricks/endpoints/user.rb +106 -0
- data/lib/stbaldricks/entities/batch.rb +29 -0
- data/lib/stbaldricks/entities/campaign.rb +37 -0
- data/lib/stbaldricks/entities/communicate.rb +20 -0
- data/lib/stbaldricks/entities/config.rb +41 -0
- data/lib/stbaldricks/entities/contact.rb +40 -0
- data/lib/stbaldricks/entities/contact_group.rb +29 -0
- data/lib/stbaldricks/entities/document_library.rb +19 -0
- data/lib/stbaldricks/entities/document_library_category.rb +14 -0
- data/lib/stbaldricks/entities/donation.rb +372 -0
- data/lib/stbaldricks/entities/donation/donor_type.rb +13 -0
- data/lib/stbaldricks/entities/donation/how_created.rb +22 -0
- data/lib/stbaldricks/entities/donation/payment_type.rb +17 -0
- data/lib/stbaldricks/entities/donation/promo_code.rb +22 -0
- data/lib/stbaldricks/entities/donation/recipient_type.rb +17 -0
- data/lib/stbaldricks/entities/donation/special_donation_type.rb +78 -0
- data/lib/stbaldricks/entities/donation/status.rb +12 -0
- data/lib/stbaldricks/entities/donation/submitter_type.rb +13 -0
- data/lib/stbaldricks/entities/donor.rb +15 -0
- data/lib/stbaldricks/entities/event.rb +173 -0
- data/lib/stbaldricks/entities/event/fund_relationship_type.rb +15 -0
- data/lib/stbaldricks/entities/event/how_created.rb +14 -0
- data/lib/stbaldricks/entities/event/promo_code.rb +11 -0
- data/lib/stbaldricks/entities/event/status.rb +13 -0
- data/lib/stbaldricks/entities/event/sub_type.rb +16 -0
- data/lib/stbaldricks/entities/event/type.rb +12 -0
- data/lib/stbaldricks/entities/event_application.rb +135 -0
- data/lib/stbaldricks/entities/event_application/model_type.rb +15 -0
- data/lib/stbaldricks/entities/event_application/status.rb +23 -0
- data/lib/stbaldricks/entities/event_donation_summary.rb +18 -0
- data/lib/stbaldricks/entities/event_participant_summary.rb +17 -0
- data/lib/stbaldricks/entities/event_supporter.rb +24 -0
- data/lib/stbaldricks/entities/fund.rb +98 -0
- data/lib/stbaldricks/entities/fundraiser.rb +124 -0
- data/lib/stbaldricks/entities/international_partner.rb +58 -0
- data/lib/stbaldricks/entities/kid.rb +190 -0
- data/lib/stbaldricks/entities/kid_honor.rb +123 -0
- data/lib/stbaldricks/entities/lib/address.rb +25 -0
- data/lib/stbaldricks/entities/lib/base.rb +505 -0
- data/lib/stbaldricks/entities/lib/cacheable.rb +43 -0
- data/lib/stbaldricks/entities/lib/default_cacheable.rb +17 -0
- data/lib/stbaldricks/entities/lib/email_address.rb +15 -0
- data/lib/stbaldricks/entities/lib/error.rb +38 -0
- data/lib/stbaldricks/entities/lib/fundraising_page.rb +20 -0
- data/lib/stbaldricks/entities/lib/geo_location.rb +9 -0
- data/lib/stbaldricks/entities/lib/location.rb +27 -0
- data/lib/stbaldricks/entities/lib/name.rb +17 -0
- data/lib/stbaldricks/entities/lib/not_implemented_object.rb +32 -0
- data/lib/stbaldricks/entities/lib/opt_out_settings.rb +21 -0
- data/lib/stbaldricks/entities/lib/payment.rb +86 -0
- data/lib/stbaldricks/entities/lib/permissions.rb +33 -0
- data/lib/stbaldricks/entities/lib/phone.rb +29 -0
- data/lib/stbaldricks/entities/lib/third_party_media.rb +20 -0
- data/lib/stbaldricks/entities/lib/top_level.rb +99 -0
- data/lib/stbaldricks/entities/lib/venue.rb +18 -0
- data/lib/stbaldricks/entities/memorial.rb +61 -0
- data/lib/stbaldricks/entities/message.rb +65 -0
- data/lib/stbaldricks/entities/newsletter_recipient.rb +17 -0
- data/lib/stbaldricks/entities/organization.rb +90 -0
- data/lib/stbaldricks/entities/page.rb +49 -0
- data/lib/stbaldricks/entities/participant.rb +216 -0
- data/lib/stbaldricks/entities/person.rb +403 -0
- data/lib/stbaldricks/entities/photo.rb +260 -0
- data/lib/stbaldricks/entities/recurring_gift.rb +215 -0
- data/lib/stbaldricks/entities/response.rb +37 -0
- data/lib/stbaldricks/entities/search.rb +223 -0
- data/lib/stbaldricks/entities/section.rb +15 -0
- data/lib/stbaldricks/entities/shave_schedule.rb +69 -0
- data/lib/stbaldricks/entities/summary.rb +32 -0
- data/lib/stbaldricks/entities/team.rb +95 -0
- data/lib/stbaldricks/entities/user.rb +76 -0
- data/lib/stbaldricks/enums/country.rb +223 -0
- data/lib/stbaldricks/enums/feature.rb +29 -0
- data/lib/stbaldricks/enums/league_status.rb +16 -0
- data/lib/stbaldricks/enums/model_type.rb +39 -0
- data/lib/stbaldricks/enums/permission.rb +223 -0
- data/lib/stbaldricks/enums/permission_model_type.rb +21 -0
- data/lib/stbaldricks/enums/province.rb +39 -0
- data/lib/stbaldricks/enums/state.rb +137 -0
- data/lib/stbaldricks/enums/top_level_category_type.rb +25 -0
- data/lib/stbaldricks/errors.rb +18 -0
- data/lib/stbaldricks/log.rb +16 -0
- data/lib/stbaldricks/patches/array.rb +6 -0
- data/lib/stbaldricks/patches/boolean.rb +25 -0
- data/lib/stbaldricks/patches/class.rb +13 -0
- data/lib/stbaldricks/patches/float.rb +9 -0
- data/lib/stbaldricks/patches/hash.rb +16 -0
- data/lib/stbaldricks/patches/integer.rb +9 -0
- data/lib/stbaldricks/patches/nil.rb +25 -0
- data/lib/stbaldricks/patches/string.rb +54 -0
- data/lib/stbaldricks/request.rb +146 -0
- data/lib/stbaldricks/version.rb +5 -0
- metadata +215 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'stbaldricks/entities/lib/address'
|
|
2
|
+
require 'stbaldricks/entities/lib/name'
|
|
3
|
+
require 'stbaldricks/entities/lib/fundraising_page'
|
|
4
|
+
require 'stbaldricks/entities/person'
|
|
5
|
+
require 'stbaldricks/entities/lib/top_level'
|
|
6
|
+
|
|
7
|
+
module SBF
|
|
8
|
+
module Client
|
|
9
|
+
class InternationalPartner < SBF::Client::TopLevelEntity
|
|
10
|
+
actions DEFAULT_CRUD_ACTIONS
|
|
11
|
+
blacklist_action :create
|
|
12
|
+
blacklist_action :update
|
|
13
|
+
blacklist_action :delete
|
|
14
|
+
|
|
15
|
+
disallow_instantiation
|
|
16
|
+
|
|
17
|
+
module Status
|
|
18
|
+
ACTIVE = 'active'
|
|
19
|
+
PENDING = 'pending'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class WebPage < SBF::Client::BaseEntity
|
|
23
|
+
attr_accessor :url
|
|
24
|
+
attr_accessor :custom_url_segment
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class Link < SBF::Client::BaseEntity
|
|
28
|
+
attr_accessor :url
|
|
29
|
+
attr_accessor :text
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class PartialInternationalPartner < SBF::Client::InternationalPartner
|
|
34
|
+
attr_accessor :id
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class FullInternationalPartner < SBF::Client::InternationalPartner
|
|
38
|
+
attr_accessor :id
|
|
39
|
+
attr_accessor :status
|
|
40
|
+
attr_accessor :year
|
|
41
|
+
attr_accessor :country
|
|
42
|
+
attr_accessor :country_name
|
|
43
|
+
attr_accessor :name
|
|
44
|
+
attr_accessor :message
|
|
45
|
+
attr_accessor :description
|
|
46
|
+
entity_attr_accessor :web_page, 'SBF::Client::InternationalPartner::WebPage'
|
|
47
|
+
entity_attr_accessor :link, 'SBF::Client::InternationalPartner::Link'
|
|
48
|
+
attr_accessor :donate_url
|
|
49
|
+
attr_accessor :base_photo_url
|
|
50
|
+
|
|
51
|
+
attr_accessor :created_at
|
|
52
|
+
|
|
53
|
+
def active?
|
|
54
|
+
status == SBF::Client::InternationalPartner::Status::ACTIVE
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
require 'stbaldricks/endpoints/kid'
|
|
2
|
+
require 'stbaldricks/entities/lib/address'
|
|
3
|
+
require 'stbaldricks/entities/lib/name'
|
|
4
|
+
require 'stbaldricks/entities/lib/fundraising_page'
|
|
5
|
+
require 'stbaldricks/entities/person'
|
|
6
|
+
require 'stbaldricks/entities/lib/base'
|
|
7
|
+
require 'stbaldricks/entities/lib/default_cacheable'
|
|
8
|
+
|
|
9
|
+
module SBF
|
|
10
|
+
module Client
|
|
11
|
+
class Diagnosis < SBF::Client::BaseEntity
|
|
12
|
+
attr_accessor :date
|
|
13
|
+
attr_accessor :cancer_type
|
|
14
|
+
attr_accessor :other
|
|
15
|
+
|
|
16
|
+
module CancerType
|
|
17
|
+
ACUTE_LYMPHOBLASTIC_LEUKEMIA = 'acute_lymphoblastic_leukemia'
|
|
18
|
+
ACUTE_MYELOID_LEUKEMIA = 'acute_myeloid_leukemia'
|
|
19
|
+
BRAIN_OR_SPINAL_CORD_TUMOR = 'brain_or_spinal_cord_tumor'
|
|
20
|
+
KIDNEY_SARCOMA = 'kidney_sarcoma'
|
|
21
|
+
EWING_SARCOMA = 'ewing_sarcoma'
|
|
22
|
+
GERM_CELL_TUMOR = 'germ_cell_tumor'
|
|
23
|
+
HEPATOBLASTOMA = 'hepatoblastoma'
|
|
24
|
+
HODGKIN_LYMPHOMA = 'hodgkin_lymphoma'
|
|
25
|
+
LYMPHOMA = 'lymphoma'
|
|
26
|
+
NEUROBLASTOMA = 'neuroblastoma'
|
|
27
|
+
NON_HODGKIN_LYMPHOMA = 'non_hodgkin_lymphoma'
|
|
28
|
+
OSTEOSARCOMA = 'osteosarcoma'
|
|
29
|
+
RETINOBLASTOMA = 'retinoblastoma'
|
|
30
|
+
RHABDOMYOSARCOMA = 'rhabdomyosarcoma'
|
|
31
|
+
WILMS_OR_OTHER_KIDNEY_TUMOR = 'wilms_or_other_kidney_tumor'
|
|
32
|
+
ADULT_WITH_CHILDHOOD_CANCER = 'adult_with_childhood_cancer'
|
|
33
|
+
OTHER_CHILDHOOD_CANCER = 'other_childhood_cancer'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Guardian < SBF::Client::BaseEntity
|
|
38
|
+
module RelationshipType
|
|
39
|
+
SELF_ADULT = 'adult'
|
|
40
|
+
SELF_MINOR = 'minor'
|
|
41
|
+
MOTHER = 'mother'
|
|
42
|
+
FATHER = 'father'
|
|
43
|
+
SISTER = 'sister'
|
|
44
|
+
BROTHER = 'brother'
|
|
45
|
+
AUNT = 'aunt'
|
|
46
|
+
UNCLE = 'uncle'
|
|
47
|
+
GRANDMOTHER = 'grandmother'
|
|
48
|
+
GRANDFATHER = 'grandfather'
|
|
49
|
+
STEP_MOTHER = 'stepmother'
|
|
50
|
+
STEP_FATHER = 'stepfather'
|
|
51
|
+
FRIEND = 'friend'
|
|
52
|
+
COUSIN = 'cousin'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
attr_accessor :name
|
|
56
|
+
attr_accessor :relationship
|
|
57
|
+
entity_attr_accessor :name_pieces, 'SBF::Client::NamePieces'
|
|
58
|
+
entity_attr_accessor :email_address, 'SBF::Client::EmailAddress'
|
|
59
|
+
entity_attr_accessor :phone, 'SBF::Client::Phone'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class TreatmentStatus < SBF::Client::BaseEntity
|
|
63
|
+
attr_accessor :state
|
|
64
|
+
attr_accessor :other
|
|
65
|
+
|
|
66
|
+
module SurvivorState
|
|
67
|
+
IN_TREATMENT = 'in_treatment'
|
|
68
|
+
IN_MAINTENANCE = 'in_maintenance'
|
|
69
|
+
IN_REMISSION = 'in_remission'
|
|
70
|
+
NED = 'no_evidence_of_disease'
|
|
71
|
+
CANCER_FREE = 'cancer_free'
|
|
72
|
+
OTHER_LIVING = 'other_living'
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
module DeceasedState
|
|
76
|
+
ANGEL = 'angel'
|
|
77
|
+
DECEASED = 'deceased'
|
|
78
|
+
PASSED_AWAY = 'passed_away'
|
|
79
|
+
OTHER_DECEASED = 'other_deceased'
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class KidURL < SBF::Client::BaseEntity
|
|
84
|
+
attr_accessor :url
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
class Photos < SBF::Client::BaseEntity
|
|
88
|
+
attr_reader :avatar, :default
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
class KidInstitution < SBF::Client::BaseEntity
|
|
92
|
+
attr_reader :id
|
|
93
|
+
attr_reader :display_name
|
|
94
|
+
attr_reader :city
|
|
95
|
+
attr_reader :state
|
|
96
|
+
attr_reader :zip_code
|
|
97
|
+
attr_reader :country
|
|
98
|
+
attr_reader :created_at
|
|
99
|
+
attr_reader :modified_at
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
class Kid < SBF::Client::TopLevelEntity
|
|
103
|
+
include Entities::DefaultCacheable
|
|
104
|
+
endpoint SBF::Client::KidEndpoint
|
|
105
|
+
actions DEFAULT_CRUD_ACTIONS
|
|
106
|
+
action :find_random
|
|
107
|
+
blacklist_action :create
|
|
108
|
+
blacklist_action :delete
|
|
109
|
+
|
|
110
|
+
disallow_instantiation
|
|
111
|
+
|
|
112
|
+
module Status
|
|
113
|
+
ACTIVE = 'active'
|
|
114
|
+
PENDING = 'pending'
|
|
115
|
+
SUSPENDED = 'suspended'
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
class Relationship < SBF::Client::BaseEntity
|
|
119
|
+
module Type
|
|
120
|
+
SELF_ADULT = 'adult'
|
|
121
|
+
SELF_MINOR = 'minor'
|
|
122
|
+
MOTHER = 'mother'
|
|
123
|
+
FATHER = 'father'
|
|
124
|
+
SISTER = 'sister'
|
|
125
|
+
BROTHER = 'brother'
|
|
126
|
+
AUNT = 'aunt'
|
|
127
|
+
UNCLE = 'uncle'
|
|
128
|
+
GRANDMOTHER = 'grandmother'
|
|
129
|
+
GRANDFATHER = 'grandfather'
|
|
130
|
+
STEP_MOTHER = 'stepmother'
|
|
131
|
+
STEP_FATHER = 'stepfather'
|
|
132
|
+
FRIEND = 'friend'
|
|
133
|
+
COUSIN = 'cousin'
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
module GuardianType
|
|
137
|
+
LEGAL_GUARDIAN = 'legal_guardian'
|
|
138
|
+
NONCUSTODIAL_GUARDIAN = 'non_custodial_guardian'
|
|
139
|
+
OTHER = 'other'
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
class Permissions < SBF::Client::BaseEntity
|
|
143
|
+
attr_accessor :is_editor
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
attr_accessor :kid_id
|
|
147
|
+
entity_attr_accessor :person, 'SBF::Client::FullPerson', 'SBF::Client::PartialPerson'
|
|
148
|
+
attr_accessor :type
|
|
149
|
+
attr_accessor :guardian_type
|
|
150
|
+
attr_accessor :is_submitter
|
|
151
|
+
entity_attr_accessor :permissions, 'SBF::Client::Kid::Relationship::Permissions'
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
class PartialKid < SBF::Client::Kid
|
|
156
|
+
attr_accessor :id
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class FullKid < SBF::Client::Kid
|
|
160
|
+
attr_accessor :id
|
|
161
|
+
attr_accessor :status
|
|
162
|
+
attr_accessor :gender
|
|
163
|
+
attr_accessor :birthday
|
|
164
|
+
attr_accessor :ethnicity
|
|
165
|
+
attr_accessor :date_of_passing
|
|
166
|
+
attr_accessor :display_name
|
|
167
|
+
attr_accessor :display_name_override
|
|
168
|
+
attr_accessor :name
|
|
169
|
+
entity_attr_accessor :name_pieces, 'SBF::Client::NamePieces'
|
|
170
|
+
entity_attr_accessor :address, 'SBF::Client::Address'
|
|
171
|
+
entity_attr_accessor :diagnosis, 'SBF::Client::Diagnosis'
|
|
172
|
+
entity_attr_accessor :treatment_status, 'SBF::Client::TreatmentStatus'
|
|
173
|
+
attr_accessor :web_message
|
|
174
|
+
entity_attr_accessor :photos, 'SBF::Client::Photos'
|
|
175
|
+
entity_attr_accessor :web_page, 'SBF::Client::WebPage'
|
|
176
|
+
entity_attr_accessor :guardian, 'SBF::Client::Guardian'
|
|
177
|
+
entity_collection_attr_accessor :relationships, 'SBF::Client::Kid::Relationship'
|
|
178
|
+
entity_collection_attr_accessor :urls, 'SBF::Client::KidURL'
|
|
179
|
+
entity_collection_attr_reader :institutions, 'SBF::Client::KidInstitution'
|
|
180
|
+
|
|
181
|
+
attr_accessor :created_at
|
|
182
|
+
attr_accessor :modified_at
|
|
183
|
+
attr_accessor :modified_by
|
|
184
|
+
|
|
185
|
+
def active?
|
|
186
|
+
status == SBF::Client::Kid::Status::ACTIVE
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'stbaldricks/endpoints/kid_honor'
|
|
2
|
+
require 'stbaldricks/entities/kid'
|
|
3
|
+
require 'stbaldricks/entities/event'
|
|
4
|
+
require 'stbaldricks/entities/team'
|
|
5
|
+
require 'stbaldricks/entities/participant'
|
|
6
|
+
require 'stbaldricks/entities/fundraiser'
|
|
7
|
+
require 'stbaldricks/entities/lib/top_level'
|
|
8
|
+
|
|
9
|
+
module SBF
|
|
10
|
+
module Client
|
|
11
|
+
class KidHonor < SBF::Client::TopLevelEntity
|
|
12
|
+
endpoint SBF::Client::KidHonorEndpoint
|
|
13
|
+
actions DEFAULT_CRUD_ACTIONS
|
|
14
|
+
blacklist_action :get
|
|
15
|
+
blacklist_action :update
|
|
16
|
+
|
|
17
|
+
attr_accessor :honored_on
|
|
18
|
+
entity_attr_accessor :kid, 'SBF::Client::KidHonor::FullKid', 'SBF::Client::KidHonor::PartialKid'
|
|
19
|
+
multitype_attr_accessor(
|
|
20
|
+
:honorer,
|
|
21
|
+
[
|
|
22
|
+
[
|
|
23
|
+
->(v) { v[:model_type] == SBF::Client::KidHonor::HonorerType::PARTICIPANT },
|
|
24
|
+
'SBF::Client::KidHonor::FullParticipant',
|
|
25
|
+
'SBF::Client::KidHonor::PartialParticipant'
|
|
26
|
+
],
|
|
27
|
+
[
|
|
28
|
+
->(v) { v[:model_type] == SBF::Client::KidHonor::HonorerType::FUNDRAISER },
|
|
29
|
+
'SBF::Client::KidHonor::FullFundraiser',
|
|
30
|
+
'SBF::Client::KidHonor::PartialFundraiser'
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
->(v) { v[:model_type] == SBF::Client::KidHonor::HonorerType::TEAM },
|
|
34
|
+
'SBF::Client::KidHonor::FullTeam',
|
|
35
|
+
'SBF::Client::KidHonor::PartialTeam'
|
|
36
|
+
],
|
|
37
|
+
[
|
|
38
|
+
->(v) { v[:model_type] == SBF::Client::KidHonor::HonorerType::EVENT },
|
|
39
|
+
'SBF::Client::KidHonor::FullEvent',
|
|
40
|
+
'SBF::Client::KidHonor::PartialEvent'
|
|
41
|
+
]
|
|
42
|
+
]
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
module HonorerType
|
|
46
|
+
EVENT = 'event'
|
|
47
|
+
TEAM = 'team'
|
|
48
|
+
PARTICIPANT = 'participant'
|
|
49
|
+
FUNDRAISER = 'fundraiser'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class PartialKid < SBF::Client::PartialKid
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
class FullKid < SBF::Client::FullKid
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class FullParticipant < SBF::Client::FullParticipant
|
|
59
|
+
attr_reader :model_type
|
|
60
|
+
|
|
61
|
+
def model_type
|
|
62
|
+
SBF::Client::KidHonor::HonorerType::PARTICIPANT
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class PartialParticipant < SBF::Client::PartialParticipant
|
|
67
|
+
attr_reader :model_type
|
|
68
|
+
|
|
69
|
+
def model_type
|
|
70
|
+
SBF::Client::KidHonor::HonorerType::PARTICIPANT
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
class FullFundraiser < SBF::Client::FullFundraiser
|
|
75
|
+
attr_reader :model_type
|
|
76
|
+
|
|
77
|
+
def model_type
|
|
78
|
+
SBF::Client::KidHonor::HonorerType::FUNDRAISER
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class PartialFundraiser < SBF::Client::PartialFundraiser
|
|
83
|
+
attr_reader :model_type
|
|
84
|
+
|
|
85
|
+
def model_type
|
|
86
|
+
SBF::Client::KidHonor::HonorerType::FUNDRAISER
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
class FullTeam < SBF::Client::FullTeam
|
|
91
|
+
attr_reader :model_type
|
|
92
|
+
|
|
93
|
+
def model_type
|
|
94
|
+
SBF::Client::KidHonor::HonorerType::TEAM
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
class PartialTeam < SBF::Client::PartialTeam
|
|
99
|
+
attr_reader :model_type
|
|
100
|
+
|
|
101
|
+
def model_type
|
|
102
|
+
SBF::Client::KidHonor::HonorerType::TEAM
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
class FullEvent < SBF::Client::FullEvent
|
|
107
|
+
attr_reader :model_type
|
|
108
|
+
|
|
109
|
+
def model_type
|
|
110
|
+
SBF::Client::KidHonor::HonorerType::EVENT
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
class PartialEvent < SBF::Client::PartialEvent
|
|
115
|
+
attr_reader :model_type
|
|
116
|
+
|
|
117
|
+
def model_type
|
|
118
|
+
SBF::Client::KidHonor::HonorerType::EVENT
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'stbaldricks/entities/lib/base'
|
|
2
|
+
|
|
3
|
+
module SBF
|
|
4
|
+
module Client
|
|
5
|
+
class Address < SBF::Client::BaseEntity
|
|
6
|
+
module Type
|
|
7
|
+
HOME = 'home'
|
|
8
|
+
BUSINESS = 'business'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_accessor :type
|
|
12
|
+
attr_accessor :business_name
|
|
13
|
+
attr_accessor :address1, :address2, :city, :state, :state_name, :zip, :country, :country_name
|
|
14
|
+
attr_accessor :latitude, :longitude
|
|
15
|
+
|
|
16
|
+
def city_state_zip
|
|
17
|
+
csz = ''
|
|
18
|
+
csz += @city + ', ' unless @city.nil?
|
|
19
|
+
csz += @state + ' ' unless @state.nil?
|
|
20
|
+
csz += @zip unless @zip.nil?
|
|
21
|
+
csz.strip
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
# Require all monkey patches
|
|
2
|
+
patch_dir = File.expand_path('../../../patches', __FILE__)
|
|
3
|
+
Dir["#{patch_dir}/*.rb"].each { |file| require file }
|
|
4
|
+
|
|
5
|
+
require 'set'
|
|
6
|
+
require 'stbaldricks/client'
|
|
7
|
+
require 'stbaldricks/entities/lib/error'
|
|
8
|
+
require 'active_model'
|
|
9
|
+
require 'securerandom'
|
|
10
|
+
|
|
11
|
+
module SBF
|
|
12
|
+
module Client
|
|
13
|
+
class BaseEntity
|
|
14
|
+
extend ActiveModel::Naming
|
|
15
|
+
extend ActiveModel::Translation
|
|
16
|
+
include ActiveModel::Conversion
|
|
17
|
+
|
|
18
|
+
attr_reader :errors
|
|
19
|
+
|
|
20
|
+
ELSE = ->(_) { true }
|
|
21
|
+
|
|
22
|
+
# Class level instance variable to keep track of defined attributes
|
|
23
|
+
@attributes = nil
|
|
24
|
+
@optional_attributes = nil
|
|
25
|
+
@entity_attributes = nil
|
|
26
|
+
@not_provided_attributes = nil
|
|
27
|
+
@disallow_instantiation = nil
|
|
28
|
+
|
|
29
|
+
def initialize(data = {})
|
|
30
|
+
# If disallow instantiation has been set, raise an error if someone is trying to call initilaize
|
|
31
|
+
raise SBF::Client::Error, 'Initialize is not valid on a base object. Use the full or partial version' unless self.class.allow_instantiation?
|
|
32
|
+
|
|
33
|
+
super()
|
|
34
|
+
|
|
35
|
+
@errors = ActiveModel::Errors.new(self)
|
|
36
|
+
self.attributes = data
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Overridden from ActiveModel::Naming to remove namespace and Full/Partial
|
|
40
|
+
def model_name
|
|
41
|
+
@_model_name ||= ActiveModel::Name.new(self, SBF::Client, self.class.name.gsub(/::(Full|Partial)/, '::'))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def persisted?
|
|
45
|
+
true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def attributes=(data)
|
|
49
|
+
data ||= {}
|
|
50
|
+
data.each do |key, value|
|
|
51
|
+
# Use the setter if one is available, otherwise set the variable directly
|
|
52
|
+
setter = "#{key}=".to_sym
|
|
53
|
+
if respond_to?(setter, true)
|
|
54
|
+
send(setter, value)
|
|
55
|
+
|
|
56
|
+
else
|
|
57
|
+
instance_variable_set("@#{key}".to_sym, value)
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# For each attribute that may be optional, call mark_attribute_not_provided
|
|
63
|
+
# if the data set does not contain a key with the optional attribute's name
|
|
64
|
+
self.class.optional_attributes.each { |name| mark_attribute_not_provided(name) unless data.key?(name) }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def add_errors(error)
|
|
68
|
+
errors.clear
|
|
69
|
+
count = error.fields.length
|
|
70
|
+
error.fields.each do |field|
|
|
71
|
+
field = field.gsub('_id', '') # Hacky, since API returns DB field that errored instead of View Field
|
|
72
|
+
errors.add(field, error.details) if count > 1
|
|
73
|
+
errors.add(:base, "#{field}: #{error.details}") if count == 1
|
|
74
|
+
end
|
|
75
|
+
errors.add(:base, "#{error.type}: #{error.details}") if count == 0
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def mark_attribute_not_provided(name)
|
|
79
|
+
return if not_provided_attributes.include?(name)
|
|
80
|
+
|
|
81
|
+
# Put the method in the list of not_provided methods
|
|
82
|
+
not_provided_attributes << name
|
|
83
|
+
|
|
84
|
+
# Back up the original version of the setter method if it doesn't already exist
|
|
85
|
+
setter = setter_method_name(name)
|
|
86
|
+
setter_backup = setter_backup_method_name(name)
|
|
87
|
+
singleton_class.send(:alias_method, setter_backup, setter) unless respond_to?(setter_backup, true)
|
|
88
|
+
|
|
89
|
+
# Back up the original version of the getter method if it doesn't already exist
|
|
90
|
+
getter = getter_method_name(name)
|
|
91
|
+
getter_backup = getter_backup_method_name(name)
|
|
92
|
+
singleton_class.send(:alias_method, getter_backup, getter) unless respond_to?(getter_backup, true)
|
|
93
|
+
|
|
94
|
+
# If we set the value in a not_provided method, that means we now have requested the data and we
|
|
95
|
+
# should replace the original getter/setter and set the value using the original method
|
|
96
|
+
define_singleton_method(setter) { |v|
|
|
97
|
+
unmark_attribute_not_provided(name)
|
|
98
|
+
super(v)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# If we try to get the value in a not_provided method, we should raise an error
|
|
102
|
+
define_singleton_method(getter) {
|
|
103
|
+
raise(
|
|
104
|
+
SBF::Client::DataNotProvidedError,
|
|
105
|
+
"Data not provided for the #{name} attribute. This is usually due to the attribute not being requested in the 'with' declaration"
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
private :mark_attribute_not_provided
|
|
110
|
+
|
|
111
|
+
def unmark_attribute_not_provided(name)
|
|
112
|
+
return unless not_provided_attributes.include?(name)
|
|
113
|
+
|
|
114
|
+
# Remove the method from the list of not_provided methods
|
|
115
|
+
not_provided_attributes.delete(name)
|
|
116
|
+
|
|
117
|
+
# Replace the original version of the setter method using the backup
|
|
118
|
+
setter = setter_method_name(name)
|
|
119
|
+
setter_backup = setter_backup_method_name(name)
|
|
120
|
+
singleton_class.send(:alias_method, setter, setter_backup)
|
|
121
|
+
|
|
122
|
+
# Replace the original version of the getter method using the backup
|
|
123
|
+
getter = getter_method_name(name)
|
|
124
|
+
getter_backup = getter_backup_method_name(name)
|
|
125
|
+
singleton_class.send(:alias_method, getter, getter_backup)
|
|
126
|
+
end
|
|
127
|
+
private :unmark_attribute_not_provided
|
|
128
|
+
|
|
129
|
+
def setter_method_name(name)
|
|
130
|
+
"#{name}=".to_sym
|
|
131
|
+
end
|
|
132
|
+
private :setter_method_name
|
|
133
|
+
|
|
134
|
+
def getter_method_name(name)
|
|
135
|
+
name.to_sym
|
|
136
|
+
end
|
|
137
|
+
private :getter_method_name
|
|
138
|
+
|
|
139
|
+
def setter_backup_method_name(name)
|
|
140
|
+
"_#{name}=".to_sym
|
|
141
|
+
end
|
|
142
|
+
private :setter_backup_method_name
|
|
143
|
+
|
|
144
|
+
def getter_backup_method_name(name)
|
|
145
|
+
"_#{name}".to_sym
|
|
146
|
+
end
|
|
147
|
+
private :getter_backup_method_name
|
|
148
|
+
|
|
149
|
+
# So this method is meant to ensure that you don't do SBF::Client::Participant.new and are forced, instead,
|
|
150
|
+
# to be explicit about calling either SBF::Client::FullParticipant.new or SBF::Client::PartialParticipant.new
|
|
151
|
+
def self.disallow_instantiation
|
|
152
|
+
@disallow_instantiation = true
|
|
153
|
+
end
|
|
154
|
+
private_class_method :disallow_instantiation
|
|
155
|
+
|
|
156
|
+
# Class method which retrieves the
|
|
157
|
+
def self.allow_instantiation?
|
|
158
|
+
!@disallow_instantiation
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Class method to retrieve the not_provided_attributes attribute
|
|
162
|
+
def not_provided_attributes
|
|
163
|
+
@not_provided_attributes ||= Set.new
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
###########################################################################################
|
|
167
|
+
# Override for the ruby built-in attribute accessors. Creates a list of attributes that can be
|
|
168
|
+
# accessed at will and adds some helper methods.
|
|
169
|
+
def self.attr_reader(*vars)
|
|
170
|
+
attributes.merge(vars)
|
|
171
|
+
super(*vars)
|
|
172
|
+
add_boolean_methods(vars)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def self.attr_writer(*vars)
|
|
176
|
+
attributes.merge(vars)
|
|
177
|
+
super(*vars)
|
|
178
|
+
add_boolean_methods(vars, true)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def self.attr_accessor(*vars)
|
|
182
|
+
attributes.merge(vars)
|
|
183
|
+
super(*vars)
|
|
184
|
+
add_boolean_methods(vars, true)
|
|
185
|
+
end
|
|
186
|
+
###########################################################################################
|
|
187
|
+
|
|
188
|
+
###########################################################################################
|
|
189
|
+
# Multitype Attribute accessors. These methods take an array of type to class mappings.
|
|
190
|
+
# Expected form is:
|
|
191
|
+
# [[<lamda method which evals to true if this type should be used>, <full class>, <partial class>], [...]]
|
|
192
|
+
def self.multitype_attr_reader(attribute, class_mappings, optional = false)
|
|
193
|
+
entity_attributes << attribute
|
|
194
|
+
optional_attributes << attribute if optional
|
|
195
|
+
attr_reader(attribute)
|
|
196
|
+
add_multitype_setter_method(attribute, class_mappings, true)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def self.multitype_attr_writer(attribute, class_mappings, optional = false)
|
|
200
|
+
entity_attributes << attribute
|
|
201
|
+
optional_attributes << attribute if optional
|
|
202
|
+
attr_writer(attribute)
|
|
203
|
+
add_multitype_setter_method(attribute, class_mappings)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def self.multitype_attr_accessor(attribute, class_mappings, optional = false)
|
|
207
|
+
entity_attributes << attribute
|
|
208
|
+
optional_attributes << attribute if optional
|
|
209
|
+
attr_accessor(attribute)
|
|
210
|
+
add_multitype_setter_method(attribute, class_mappings)
|
|
211
|
+
end
|
|
212
|
+
###########################################################################################
|
|
213
|
+
|
|
214
|
+
###########################################################################################
|
|
215
|
+
# Entity attr accessors are simpler to define/easier to read but they really just create a type mapping
|
|
216
|
+
# for the given inputs and then function the same as the multitype attribute accessors do.
|
|
217
|
+
def self.entity_attr_reader(attribute, full_class, partial_class = nil, optional = false)
|
|
218
|
+
mapping_for_single_class = [[ELSE, full_class, partial_class]]
|
|
219
|
+
multitype_attr_reader(attribute, mapping_for_single_class, optional)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def self.entity_attr_writer(attribute, full_class, partial_class = nil, optional = false)
|
|
223
|
+
mapping_for_single_class = [[ELSE, full_class, partial_class]]
|
|
224
|
+
multitype_attr_writer(attribute, mapping_for_single_class, optional)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def self.entity_attr_accessor(attribute, full_class, partial_class = nil, optional = false)
|
|
228
|
+
mapping_for_single_class = [[ELSE, full_class, partial_class]]
|
|
229
|
+
multitype_attr_accessor(attribute, mapping_for_single_class, optional)
|
|
230
|
+
end
|
|
231
|
+
###########################################################################################
|
|
232
|
+
|
|
233
|
+
###########################################################################################
|
|
234
|
+
# Multitype Collection accessors. These methods take an array of type to class mappings.
|
|
235
|
+
# Expected form is:
|
|
236
|
+
# [[<lamda method which evals to true if this type should be used>, <full class>, <partial class>], [...]]
|
|
237
|
+
def self.multitype_collection_attr_reader(attribute, class_mappings, optional = false)
|
|
238
|
+
collection_attributes << attribute
|
|
239
|
+
optional_attributes << attribute if optional
|
|
240
|
+
attr_reader(attribute)
|
|
241
|
+
add_multitype_collection_setter_method(attribute, class_mappings, true)
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def self.multitype_collection_attr_writer(attribute, class_mappings, optional = false)
|
|
245
|
+
collection_attributes << attribute
|
|
246
|
+
optional_attributes << attribute if optional
|
|
247
|
+
attr_writer(attribute)
|
|
248
|
+
add_multitype_collection_setter_method(attribute, class_mappings)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def self.multitype_collection_attr_accessor(attribute, class_mappings, optional = false)
|
|
252
|
+
collection_attributes << attribute
|
|
253
|
+
optional_attributes << attribute if optional
|
|
254
|
+
attr_accessor(attribute)
|
|
255
|
+
add_multitype_collection_setter_method(attribute, class_mappings)
|
|
256
|
+
end
|
|
257
|
+
###########################################################################################
|
|
258
|
+
|
|
259
|
+
###########################################################################################
|
|
260
|
+
# Entity attr accessors are simpler to define/easier to read but they really just create a type mapping
|
|
261
|
+
# for the given inputs and then function the same as the multitype attribute accessors do.
|
|
262
|
+
def self.entity_collection_attr_reader(attribute, full_class, partial_class = nil, optional = false)
|
|
263
|
+
mapping_for_single_class = [[ELSE, full_class, partial_class]]
|
|
264
|
+
multitype_collection_attr_reader(attribute, mapping_for_single_class, optional)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def self.entity_collection_attr_writer(attribute, full_class, partial_class = nil, optional = false)
|
|
268
|
+
mapping_for_single_class = [[ELSE, full_class, partial_class]]
|
|
269
|
+
multitype_collection_attr_writer(attribute, mapping_for_single_class, optional)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def self.entity_collection_attr_accessor(attribute, full_class, partial_class = nil, optional = false)
|
|
273
|
+
mapping_for_single_class = [[ELSE, full_class, partial_class]]
|
|
274
|
+
multitype_collection_attr_accessor(attribute, mapping_for_single_class, optional)
|
|
275
|
+
end
|
|
276
|
+
###########################################################################################
|
|
277
|
+
|
|
278
|
+
def self.attributes
|
|
279
|
+
@attributes ||= Set.new
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def self.optional_attributes
|
|
283
|
+
@optional_attributes ||= Set.new
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def self.entity_attributes
|
|
287
|
+
@entity_attributes ||= Set.new
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def self.collection_attributes
|
|
291
|
+
@collection_attributes ||= Set.new
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def self.add_boolean_methods(vars, setter = false)
|
|
295
|
+
vars.each do |attribute|
|
|
296
|
+
split_attribute = attribute.to_s.split('is_')
|
|
297
|
+
next if split_attribute.length <= 1
|
|
298
|
+
define_method(:"#{split_attribute.last}?") { send(attribute) }
|
|
299
|
+
define_method(:"#{attribute}=") { |val| instance_variable_set("@#{attribute}".to_sym, val.to_s.to_b) } if setter
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
private_class_method :add_boolean_methods
|
|
303
|
+
|
|
304
|
+
# Creates a private method which resolves the class type based on the class mappings and the value
|
|
305
|
+
# rubocop:disable MethodLength
|
|
306
|
+
def self.add_class_selector_method(attribute, class_mappings)
|
|
307
|
+
method_name = :"select_#{attribute}_class"
|
|
308
|
+
|
|
309
|
+
define_singleton_method(method_name) do |value|
|
|
310
|
+
parsed_class_mappings = get_mappings(attribute, class_mappings)
|
|
311
|
+
|
|
312
|
+
# No class conversion if the value is nil
|
|
313
|
+
return nil if value.nil?
|
|
314
|
+
|
|
315
|
+
if value.is_a?(Hash)
|
|
316
|
+
# Allow setting of the value using a hash
|
|
317
|
+
return NilClass if value.empty?
|
|
318
|
+
|
|
319
|
+
# Find the first class mapping whose check returns true
|
|
320
|
+
check, full_class, partial_class = parsed_class_mappings.find { |check, _, _| check.call(value) }
|
|
321
|
+
raise SBF::Client::Error, "unknown #{attribute} type" if check.nil?
|
|
322
|
+
|
|
323
|
+
# If a user specifies exactly the partial fields, then this should be a partial.
|
|
324
|
+
return partial_class if partial_class && (value.keys - partial_class.attributes.to_a).empty?
|
|
325
|
+
|
|
326
|
+
# Otherwise
|
|
327
|
+
return full_class if full_class
|
|
328
|
+
|
|
329
|
+
else
|
|
330
|
+
# No class conversion if the value is already an entity
|
|
331
|
+
return nil if parsed_class_mappings.any? { |_, c1, c2|
|
|
332
|
+
[c1, c2].compact.any? { |allowed_class|
|
|
333
|
+
if allowed_class.instance_of?(Class)
|
|
334
|
+
# Otherwise, return true if the value is an instance of the allowed class
|
|
335
|
+
value.is_a?(allowed_class)
|
|
336
|
+
|
|
337
|
+
elsif allowed_class.instance_of?(Module)
|
|
338
|
+
# If we specified a module, assume this is an enum and return true if the value
|
|
339
|
+
# is one of the valid constant values for the module
|
|
340
|
+
allowed_class.constants.any? { |const_name| allowed_class.const_get(const_name) == value }
|
|
341
|
+
|
|
342
|
+
end
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
# Convert to child class if given class is a parent of the same name
|
|
347
|
+
parsed_class_mappings.each { |_, c1, c2|
|
|
348
|
+
[c1, c2].compact.each { |allowed_class|
|
|
349
|
+
return allowed_class if allowed_class.ancestors.find { |a| a == value.class && a.demodulize == value.class.demodulize }
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
# Don't know how to handle whatever the user entered. Raise an error.
|
|
354
|
+
# (Nil and Hash are always valid values)
|
|
355
|
+
valid_classes = ['NilClass', Hash]
|
|
356
|
+
parsed_class_mappings.each do |_, class1, class2|
|
|
357
|
+
valid_classes << class1
|
|
358
|
+
valid_classes << class2 unless class2.nil?
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
raise SBF::Client::Error, "Unsupported value for #{name}.#{attribute}: #{value}. Should be one of #{valid_classes.join(', ')}"
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
private_class_method method_name
|
|
366
|
+
end
|
|
367
|
+
# rubocop:enable MethodLength
|
|
368
|
+
private_class_method :add_class_selector_method
|
|
369
|
+
|
|
370
|
+
def self.get_mappings(attribute, class_mappings)
|
|
371
|
+
# Parse the mappings information and save it off
|
|
372
|
+
mapping_var = :"@#{attribute}_class_mappings"
|
|
373
|
+
unless instance_variable_defined?(mapping_var)
|
|
374
|
+
instance_variable_set(mapping_var, parse_class_mappings(class_mappings))
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
instance_variable_get(mapping_var)
|
|
378
|
+
end
|
|
379
|
+
private_class_method :get_mappings
|
|
380
|
+
|
|
381
|
+
# Validates the input structure of the class mappings array and returns a new array with the class strings
|
|
382
|
+
# converted to actual classes
|
|
383
|
+
def self.parse_class_mappings(mappings)
|
|
384
|
+
raise SBF::Client::Error, "Invalid class mapping structure: #{mappings.class}" unless mappings.is_a?(Array)
|
|
385
|
+
|
|
386
|
+
mappings.map do |check, full_class, partial_class|
|
|
387
|
+
raise SBF::Client::Error, "Invalid class mapping check: #{check.class}" unless check.is_a?(Proc)
|
|
388
|
+
|
|
389
|
+
full_class = full_class.to_class
|
|
390
|
+
unless full_class.nil? || full_class.is_a?(NilClass) || full_class.ancestors.include?(BaseEntity) || full_class.instance_of?(Module)
|
|
391
|
+
raise SBF::Client::Error, "Invalid class mapping full class: #{full_class}"
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
partial_class = partial_class.to_class
|
|
395
|
+
unless partial_class.nil? || partial_class.is_a?(NilClass) || partial_class.ancestors.include?(BaseEntity)
|
|
396
|
+
raise SBF::Client::Error, "Invalid class mapping partial class: #{partial_class}"
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
[check, full_class, partial_class]
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
private_class_method :parse_class_mappings
|
|
403
|
+
|
|
404
|
+
# Convert the value to an instance of the appropriate class.
|
|
405
|
+
def convert_value(attribute, value)
|
|
406
|
+
entity_class_selector_method = :"select_#{attribute}_class"
|
|
407
|
+
entity_class = self.class.send(entity_class_selector_method, value)
|
|
408
|
+
|
|
409
|
+
# If the entity_class is nil, then that means don't convert anything
|
|
410
|
+
return value if entity_class.nil?
|
|
411
|
+
|
|
412
|
+
# If the entity_class is the NilClass, return nil
|
|
413
|
+
return nil if entity_class == NilClass
|
|
414
|
+
|
|
415
|
+
# If we are converting to a subclass, we need to first grab the hash of data from the parent object
|
|
416
|
+
value = value.to_hash if !value.is_a?(Hash) && value.respond_to?(:to_hash)
|
|
417
|
+
|
|
418
|
+
# Convert to an instance of the appropriate entity class.
|
|
419
|
+
entity_class.new(value)
|
|
420
|
+
end
|
|
421
|
+
private :convert_value
|
|
422
|
+
|
|
423
|
+
# Base entity setter. Allows for the property to be an array of types.
|
|
424
|
+
def self.add_multitype_setter_method(attribute, class_mappings, private_method = false)
|
|
425
|
+
add_class_selector_method(attribute, class_mappings)
|
|
426
|
+
|
|
427
|
+
method_name = :"#{attribute}="
|
|
428
|
+
define_method(method_name) do |value|
|
|
429
|
+
instance_variable_set(:"@#{attribute}", convert_value(attribute, value))
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
# Make the setter private if requested (so you can set through the constructor but not anywhere else)
|
|
433
|
+
private method_name if private_method
|
|
434
|
+
end
|
|
435
|
+
private_class_method :add_multitype_setter_method
|
|
436
|
+
|
|
437
|
+
# Base collection setter. Allows for the collection to be an array types of types.
|
|
438
|
+
def self.add_multitype_collection_setter_method(attribute, class_mappings, private_method = false)
|
|
439
|
+
add_class_selector_method(attribute, class_mappings)
|
|
440
|
+
|
|
441
|
+
define_method(:"#{attribute}=") do |values|
|
|
442
|
+
values ||= []
|
|
443
|
+
raise SBF::Client::Error, "#{attribute} must be an array" unless values.is_a?(Array)
|
|
444
|
+
converted_collection = values.map { |value| convert_value(attribute, value) }
|
|
445
|
+
instance_variable_set(:"@#{attribute}", converted_collection)
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
# Make the setter private if requested (so you can set through the constructor but not anywhere else)
|
|
449
|
+
private :"#{attribute}=" if private_method
|
|
450
|
+
end
|
|
451
|
+
private_class_method :add_multitype_collection_setter_method
|
|
452
|
+
|
|
453
|
+
# Recursively converts an entity into a Hash
|
|
454
|
+
def to_hash
|
|
455
|
+
entity_hash = {}
|
|
456
|
+
self.class.attributes.each { |key|
|
|
457
|
+
# If the method was not retrieved, do not include it in the hash
|
|
458
|
+
next if not_provided_attributes.include?(key)
|
|
459
|
+
|
|
460
|
+
# Get the value
|
|
461
|
+
value = send(key)
|
|
462
|
+
|
|
463
|
+
# If the value is an Entity, call to_hash on it (recursively)
|
|
464
|
+
if value.is_a?(BaseEntity)
|
|
465
|
+
entity_hash[key] = value.to_hash
|
|
466
|
+
|
|
467
|
+
# If the value is an Array, need to try to call to_hash on each item
|
|
468
|
+
elsif value.is_a?(Array)
|
|
469
|
+
entity_hash[key] = value.map { |element|
|
|
470
|
+
if element.is_a?(BaseEntity)
|
|
471
|
+
next element.to_hash
|
|
472
|
+
else
|
|
473
|
+
next element
|
|
474
|
+
end
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
# Collections should return empty array rather than nil
|
|
478
|
+
elsif value.nil? && self.class.collection_attributes.include?(key)
|
|
479
|
+
entity_hash[key] = []
|
|
480
|
+
|
|
481
|
+
# Just set the value
|
|
482
|
+
else
|
|
483
|
+
entity_hash[key] = value
|
|
484
|
+
|
|
485
|
+
end
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
# Return the hash
|
|
489
|
+
entity_hash
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
# Recursively convert an entity into json
|
|
493
|
+
def to_json(*a)
|
|
494
|
+
to_hash.to_json(*a)
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
def self.inherited(base)
|
|
498
|
+
# Add all of our attributes to the class that is inheriting us.
|
|
499
|
+
base.attributes.merge(attributes) unless attributes.empty?
|
|
500
|
+
base.optional_attributes.merge(optional_attributes) unless optional_attributes.empty?
|
|
501
|
+
base.entity_attributes.merge(entity_attributes) unless entity_attributes.empty?
|
|
502
|
+
end
|
|
503
|
+
end
|
|
504
|
+
end
|
|
505
|
+
end
|