daisybill_api 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +20 -0
  4. data/lib/daisybill_api.rb +53 -0
  5. data/lib/daisybill_api/configuration.rb +46 -0
  6. data/lib/daisybill_api/data.rb +7 -0
  7. data/lib/daisybill_api/data/client.rb +66 -0
  8. data/lib/daisybill_api/data/rest_client/payload.rb +30 -0
  9. data/lib/daisybill_api/data/url.rb +26 -0
  10. data/lib/daisybill_api/ext.rb +20 -0
  11. data/lib/daisybill_api/ext/associations.rb +39 -0
  12. data/lib/daisybill_api/ext/attributes.rb +103 -0
  13. data/lib/daisybill_api/ext/attributes/attribute.rb +60 -0
  14. data/lib/daisybill_api/ext/attributes/type_castings.rb +78 -0
  15. data/lib/daisybill_api/ext/crud.rb +147 -0
  16. data/lib/daisybill_api/ext/crud/create.rb +107 -0
  17. data/lib/daisybill_api/ext/crud/destroy.rb +28 -0
  18. data/lib/daisybill_api/ext/crud/index.rb +41 -0
  19. data/lib/daisybill_api/ext/crud/show.rb +22 -0
  20. data/lib/daisybill_api/ext/crud/update.rb +37 -0
  21. data/lib/daisybill_api/ext/links.rb +65 -0
  22. data/lib/daisybill_api/ext/links/link.rb +35 -0
  23. data/lib/daisybill_api/ext/pageable_collection.rb +124 -0
  24. data/lib/daisybill_api/models.rb +22 -0
  25. data/lib/daisybill_api/models/address.rb +16 -0
  26. data/lib/daisybill_api/models/attachment.rb +22 -0
  27. data/lib/daisybill_api/models/base.rb +29 -0
  28. data/lib/daisybill_api/models/bill.rb +42 -0
  29. data/lib/daisybill_api/models/bill_payment.rb +22 -0
  30. data/lib/daisybill_api/models/bill_submission.rb +18 -0
  31. data/lib/daisybill_api/models/billing_provider.rb +25 -0
  32. data/lib/daisybill_api/models/claims_administrator.rb +13 -0
  33. data/lib/daisybill_api/models/contact.rb +19 -0
  34. data/lib/daisybill_api/models/employer.rb +13 -0
  35. data/lib/daisybill_api/models/injury.rb +30 -0
  36. data/lib/daisybill_api/models/patient.rb +32 -0
  37. data/lib/daisybill_api/models/place_of_service.rb +29 -0
  38. data/lib/daisybill_api/models/referring_provider.rb +21 -0
  39. data/lib/daisybill_api/models/rendering_provider.rb +23 -0
  40. data/lib/daisybill_api/models/service_line_item.rb +27 -0
  41. data/lib/daisybill_api/version.rb +3 -0
  42. data/spec/daisybill_api/configuration_spec.rb +16 -0
  43. data/spec/daisybill_api/data/client_spec.rb +47 -0
  44. data/spec/daisybill_api/data/rest_client/payload_spec.rb +17 -0
  45. data/spec/daisybill_api/data/url_spec.rb +13 -0
  46. data/spec/daisybill_api/ext/attributes/attribute_spec.rb +120 -0
  47. data/spec/daisybill_api/ext/attributes/type_castings_spec.rb +50 -0
  48. data/spec/daisybill_api/ext/links/link_spec.rb +50 -0
  49. data/spec/daisybill_api/ext/pageable_collection_spec.rb +145 -0
  50. data/spec/daisybill_api/models/address_spec.rb +7 -0
  51. data/spec/daisybill_api/models/attachment_spec.rb +9 -0
  52. data/spec/daisybill_api/models/bill_payment_spec.rb +11 -0
  53. data/spec/daisybill_api/models/bill_spec.rb +22 -0
  54. data/spec/daisybill_api/models/bill_submission_spec.rb +9 -0
  55. data/spec/daisybill_api/models/billing_provider_spec.rb +13 -0
  56. data/spec/daisybill_api/models/claims_administrator_spec.rb +7 -0
  57. data/spec/daisybill_api/models/contact_spec.rb +6 -0
  58. data/spec/daisybill_api/models/employer_spec.rb +7 -0
  59. data/spec/daisybill_api/models/injury_spec.rb +13 -0
  60. data/spec/daisybill_api/models/patient_spec.rb +14 -0
  61. data/spec/daisybill_api/models/place_of_service_spec.rb +14 -0
  62. data/spec/daisybill_api/models/referring_provider_spec.rb +11 -0
  63. data/spec/daisybill_api/models/rendering_provider_spec.rb +12 -0
  64. data/spec/daisybill_api/models/service_line_item_spec.rb +11 -0
  65. data/spec/daisybill_api_spec.rb +35 -0
  66. metadata +289 -0
@@ -0,0 +1,18 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class BillSubmission < DaisybillApi::Models::Base
4
+ rest_actions :index, :show, :create
5
+ path_prefix '/bills', :bill_id
6
+
7
+ attributes(
8
+ id: :integer,
9
+ type: :string,
10
+ mode: :string,
11
+ claims_administrator: DaisybillApi::Models::ClaimsAdministrator,
12
+ readonly: true
13
+ )
14
+
15
+ link :bill, class: 'Bill'
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class BillingProvider < DaisybillApi::Models::Base
4
+ rest_actions :index, :show
5
+
6
+ attributes(
7
+ id: :integer,
8
+ name: :string,
9
+ fein: :string,
10
+ npi: :string,
11
+ telephone: :string,
12
+ fax_number: :string,
13
+ physical_address: DaisybillApi::Models::Address,
14
+ pay_to_address: DaisybillApi::Models::Address,
15
+ dol_provider_number: :string,
16
+ readonly: true
17
+ )
18
+
19
+ has_many :patients, class: 'Patient'
20
+ has_many :rendering_providers, class: 'RenderingProvider'
21
+ has_many :referring_providers, class: 'ReferringProvider'
22
+ has_many :places_of_service, class: 'PlaceOfService'
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class ClaimsAdministrator < DaisybillApi::Models::Base
4
+ rest_actions :index
5
+
6
+ attributes(
7
+ id: :integer,
8
+ name: :string,
9
+ readonly: true
10
+ )
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class Contact
4
+ include DaisybillApi::Ext::Attributes
5
+
6
+ attributes(
7
+ id: :integer,
8
+ first_name: :string,
9
+ last_name: :string,
10
+ company: :string,
11
+ role: :string,
12
+ telephone: :string,
13
+ email: :string,
14
+ fax: :string,
15
+ address: DaisybillApi::Models::Address
16
+ )
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class Employer
4
+ include DaisybillApi::Ext::Attributes
5
+
6
+ attributes(
7
+ id: :integer,
8
+ name: :string,
9
+ address: DaisybillApi::Models::Address
10
+ )
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class Injury < DaisybillApi::Models::Base
4
+ path_prefix '/patients', :patient_id
5
+ rest_actions :index, :show, :create, :update, :destroy
6
+
7
+ attributes(
8
+ id: :integer,
9
+ claims_administrator: DaisybillApi::Models::ClaimsAdministrator,
10
+ review_status: :string,
11
+ review_errors: [:string],
12
+ diagnosis_codes: [:string],
13
+ contacts: [DaisybillApi::Models::Contact],
14
+ readonly: true
15
+ )
16
+ attributes(
17
+ description: :string,
18
+ claim_number: :string,
19
+ adj_number: :string,
20
+ start_date: :date,
21
+ end_date: :date,
22
+ claims_administrator_id: :integer, #TODO: think how to connect it with claims_administrator attribute
23
+ employer: DaisybillApi::Models::Employer
24
+ )
25
+
26
+ link :patient, class: 'Patient'
27
+ has_many :bills, class: 'Bill'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class Patient < DaisybillApi::Models::Base
4
+ path_prefix '/billing_providers', :billing_provider_id
5
+ rest_actions :index, :show, :create, :update, :destroy
6
+
7
+ attributes(
8
+ id: :integer,
9
+ review_status: :string,
10
+ review_errors: [:string],
11
+ readonly: true
12
+ )
13
+ attributes(
14
+ first_name: :string,
15
+ last_name: :string,
16
+ middle_initial: :string,
17
+ suffix: :string,
18
+ gender: :string,
19
+ practice_internal_id: :string,
20
+ date_of_birth: :date,
21
+ ssn: :string,
22
+ telephone: :string,
23
+ address: DaisybillApi::Models::Address
24
+ )
25
+
26
+ has_many :injuries, class: 'Injury'
27
+
28
+ link :billing_provider, class: 'BillingProvider'
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,29 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class PlaceOfService < DaisybillApi::Models::Base
4
+ def self.plural_key
5
+ 'places_of_service'
6
+ end
7
+
8
+ path_prefix '/billing_providers', :billing_provider_id
9
+ rest_actions :index, :show, :create, :update
10
+
11
+ attribute :id, :integer, readonly: true
12
+
13
+ attributes(
14
+ name: :string,
15
+ nick_name: :string,
16
+ county: :string,
17
+ npi: :string,
18
+ active: :boolean,
19
+ authorization_telephone_number: :string,
20
+ authorization_fax_number: :string,
21
+ place_of_service_type_code: :string,
22
+ address: DaisybillApi::Models::Address
23
+ )
24
+
25
+ link :billing_provider, class: 'BillingProvider'
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,21 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class ReferringProvider < DaisybillApi::Models::Base
4
+ path_prefix '/billing_providers', :billing_provider_id
5
+ rest_actions :index, :show, :create, :update
6
+
7
+ attribute :id, :integer, readonly: true
8
+ attributes(
9
+ first_name: :string,
10
+ last_name: :string,
11
+ middle_initial: :string,
12
+ suffix: :string,
13
+ npi: :string,
14
+ state_license_number: :string,
15
+ active: :boolean
16
+ )
17
+
18
+ link :billing_provider, class: 'BillingProvider'
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class RenderingProvider < DaisybillApi::Models::Base
4
+ path_prefix '/billing_providers', :billing_provider_id
5
+ rest_actions :index, :show, :create, :update
6
+
7
+ attribute :id, :integer, readonly: true
8
+ attributes(
9
+ first_name: :string,
10
+ last_name: :string,
11
+ middle_initial: :string,
12
+ suffix: :string,
13
+ npi: :string,
14
+ state_license_number: :string,
15
+ taxonomy_code: :string,
16
+ type_of_specialty: :string,
17
+ active: :boolean
18
+ )
19
+
20
+ link :billing_provider, class: 'BillingProvider'
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ module DaisybillApi
2
+ module Models
3
+ class ServiceLineItem < DaisybillApi::Models::Base
4
+ attributes(
5
+ charge_cents: :integer,
6
+ expected_payment_cents: :integer,
7
+ allowed_cents: :integer,
8
+ balance_due_cents: :integer,
9
+ write_off_cents: :integer,
10
+ readonly: true
11
+ )
12
+
13
+ attributes(
14
+ id: :integer,
15
+ procedure_code: :string,
16
+ units: :float,
17
+ modifier_codes: [:string],
18
+ supplemental_data: :string,
19
+ diagnosis_code_1: :string,
20
+ diagnosis_code_2: :string,
21
+ diagnosis_code_3: :string,
22
+ diagnosis_code_4: :string,
23
+ custom_unit_charge_cents: :integer
24
+ )
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module DaisybillApi
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe DaisybillApi::Configuration do
4
+ let(:config) { DaisybillApi::Configuration.new }
5
+
6
+ context 'default values' do
7
+ it { expect(config.api_token).to be_nil }
8
+ it { expect(config.port).to eq 443 }
9
+ it { expect(config.host).to eq 'go.daisybill.com' }
10
+ it { expect(config.logger).to be_a Logger }
11
+ end
12
+ it "when logger was set to nil" do
13
+ config.logger = nil
14
+ expect(config.logger).to be_a Logger
15
+ end
16
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'returned error with status' do |status|
4
+ its(:status) { is_expected.to eq status }
5
+ its(:response) { is_expected.to be_a Hash }
6
+ its(:response) { is_expected.to have_key('error') }
7
+ end
8
+
9
+ describe DaisybillApi::Data::Client, :vcr do
10
+ let(:method) { :get }
11
+ let(:params) { {} }
12
+ let(:path) { '/billing_providers/25' }
13
+
14
+ subject { DaisybillApi::Data::Client.new(method, path, params) }
15
+
16
+ context 'when everything fine' do
17
+ it { is_expected.to be_success }
18
+ its(:response) { is_expected.to be_a Hash }
19
+ its(:response) { is_expected.to have_key('id') }
20
+ its(:response) { is_expected.to have_key('name') }
21
+ its(:response) { is_expected.to have_key('fein') }
22
+ end
23
+
24
+ context 'when incorrect API token' do
25
+ before { DaisybillApi.configuration.api_token = 'incorrect token' }
26
+
27
+ it_behaves_like 'returned error with status', '401'
28
+ end
29
+
30
+ context 'when incorrect url' do
31
+ let(:path) { '/incorrect/url' }
32
+
33
+ it_behaves_like 'returned error with status', '401'
34
+ end
35
+
36
+ context 'when record was not found' do
37
+ let(:path) { '/billing_providers/unknown-id' }
38
+
39
+ it_behaves_like 'returned error with status', '404'
40
+ end
41
+
42
+ context 'when server raised error' do
43
+ let(:path) { '/raised/error' }
44
+
45
+ it_behaves_like 'returned error with status', '500'
46
+ end
47
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe RestClient::Payload do
4
+ subject { RestClient::Payload.generate(params).to_s }
5
+
6
+ context 'when collection of hashes' do
7
+ let(:params) { { collection: [{ a: 1, b: 2 }, { a: 3, b: 4 }] } }
8
+
9
+ it { is_expected.to eq 'collection[][a]=1&collection[][b]=2&collection[][a]=3&collection[][b]=4' }
10
+ end
11
+
12
+ context 'when value is nil' do
13
+ let(:params) { { empty: '', nil: nil, zero: 0 } }
14
+
15
+ it { is_expected.to eq 'empty=&nil&zero=0' }
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe DaisybillApi::Data::Url do
4
+ before { DaisybillApi.configure { |c| c.api_token = 'token' } }
5
+ let(:path) { 'billing_providers' }
6
+ let(:params) { { page: 1, per_page: 20 } }
7
+
8
+ subject { DaisybillApi::Data::Url.build(path, params).to_s }
9
+
10
+ it { is_expected.to include 'page=1' }
11
+ it { is_expected.to include 'per_page=20' }
12
+ it { is_expected.to include 'api_token=token' }
13
+ end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ describe DaisybillApi::Ext::Attributes::Attribute do
4
+ let(:name) { 'description' }
5
+ let(:type) { :string }
6
+ let(:options) { {} }
7
+ subject { described_class.new name, type, options }
8
+
9
+ it '#value=' do
10
+ expect(DaisybillApi::Ext::Attributes::TypeCastings).to receive(:convert_to).with('value', :string)
11
+ subject.value = 'value'
12
+ end
13
+
14
+ context 'value' do
15
+ let(:type) { [:integer] }
16
+
17
+ its(:value) { is_expected.to eq [] }
18
+ end
19
+
20
+ context '#param_name' do
21
+ subject { super().param_name }
22
+
23
+ it { is_expected.to eq 'description' }
24
+
25
+ context 'when type is model' do
26
+ let(:type) { DaisybillApi::Models::Address }
27
+
28
+ it { is_expected.to eq 'description_attributes' }
29
+ end
30
+
31
+ context 'when type is a simple collection' do
32
+ let(:type) { [:integer] }
33
+
34
+ it { is_expected.to eq 'description' }
35
+ end
36
+
37
+ context 'when type is a collection of models' do
38
+ let(:type) { [DaisybillApi::Models::Address] }
39
+
40
+ it { is_expected.to eq 'description_attributes' }
41
+ end
42
+ end
43
+
44
+ context '#param_value' do
45
+ let(:value) { 'value' }
46
+ before { subject.value = value }
47
+
48
+ it { expect(subject.param_value).to eq 'value' }
49
+
50
+ context 'when type is model' do
51
+ let(:type) { DaisybillApi::Models::Address }
52
+ let(:attrs) { { 'address_1' => 'addr1', 'address_2' => nil, 'city' => 'NY', 'state' => 'NY', 'zip_code' => '123'} }
53
+ let(:value) { type.new attrs }
54
+
55
+ its(:param_value) { is_expected.to eq attrs }
56
+ end
57
+
58
+ context 'when type is collection' do
59
+ let(:type) { [:integer] }
60
+ let(:value) { %w(13 666) }
61
+
62
+ its(:param_value) { is_expected.to eq [13, 666] }
63
+ end
64
+
65
+ context 'when type is collection of models' do
66
+ let(:type) { [DaisybillApi::Models::Address] }
67
+ let(:attrs1) { { 'address_1' => 'addr1', 'address_2' => 'addr2', 'city' => 'City', 'state' => 'st', 'zip_code' => '123' } }
68
+ let(:attrs2) { { 'address_1' => 'addr3', 'address_2' => 'addr4', 'city' => 'city', 'state' => 'St', 'zip_code' => '456' } }
69
+ let(:value) do
70
+ [
71
+ DaisybillApi::Models::Address.new(attrs1),
72
+ DaisybillApi::Models::Address.new(attrs2)
73
+ ]
74
+ end
75
+
76
+ it { expect(subject.param_value).to eq [attrs1, attrs2] }
77
+ end
78
+ end
79
+
80
+ context '#to_param' do
81
+ context 'when not readonly' do
82
+ before { allow(subject).to receive(:readonly?).and_return(false) }
83
+ it 'must call param_name method' do
84
+ expect(subject).to receive(:param_name)
85
+ subject.to_param
86
+ end
87
+
88
+ it 'must call param_name method' do
89
+ expect(subject).to receive(:param_value)
90
+ subject.to_param
91
+ end
92
+ end
93
+
94
+ context 'when readonly' do
95
+ before { allow(subject).to receive(:readonly?).and_return(true) }
96
+
97
+ it 'must not call param_name method' do
98
+ expect(subject).to_not receive(:param_name)
99
+ subject.to_param
100
+ end
101
+
102
+ it 'must not call param_name method' do
103
+ expect(subject).to_not receive(:param_value)
104
+ subject.to_param
105
+ end
106
+ end
107
+ end
108
+
109
+ context '#readonly?' do
110
+ subject { super().readonly? }
111
+
112
+ it { is_expected.to be_falsey }
113
+
114
+ context 'when readonly passed' do
115
+ let(:options) { { readonly: true } }
116
+
117
+ it { is_expected.to be_truthy }
118
+ end
119
+ end
120
+ end