daisybill_api 0.1.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.
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