daisybill_api 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +20 -0
- data/lib/daisybill_api.rb +53 -0
- data/lib/daisybill_api/configuration.rb +46 -0
- data/lib/daisybill_api/data.rb +7 -0
- data/lib/daisybill_api/data/client.rb +66 -0
- data/lib/daisybill_api/data/rest_client/payload.rb +30 -0
- data/lib/daisybill_api/data/url.rb +26 -0
- data/lib/daisybill_api/ext.rb +20 -0
- data/lib/daisybill_api/ext/associations.rb +39 -0
- data/lib/daisybill_api/ext/attributes.rb +103 -0
- data/lib/daisybill_api/ext/attributes/attribute.rb +60 -0
- data/lib/daisybill_api/ext/attributes/type_castings.rb +78 -0
- data/lib/daisybill_api/ext/crud.rb +147 -0
- data/lib/daisybill_api/ext/crud/create.rb +107 -0
- data/lib/daisybill_api/ext/crud/destroy.rb +28 -0
- data/lib/daisybill_api/ext/crud/index.rb +41 -0
- data/lib/daisybill_api/ext/crud/show.rb +22 -0
- data/lib/daisybill_api/ext/crud/update.rb +37 -0
- data/lib/daisybill_api/ext/links.rb +65 -0
- data/lib/daisybill_api/ext/links/link.rb +35 -0
- data/lib/daisybill_api/ext/pageable_collection.rb +124 -0
- data/lib/daisybill_api/models.rb +22 -0
- data/lib/daisybill_api/models/address.rb +16 -0
- data/lib/daisybill_api/models/attachment.rb +22 -0
- data/lib/daisybill_api/models/base.rb +29 -0
- data/lib/daisybill_api/models/bill.rb +42 -0
- data/lib/daisybill_api/models/bill_payment.rb +22 -0
- data/lib/daisybill_api/models/bill_submission.rb +18 -0
- data/lib/daisybill_api/models/billing_provider.rb +25 -0
- data/lib/daisybill_api/models/claims_administrator.rb +13 -0
- data/lib/daisybill_api/models/contact.rb +19 -0
- data/lib/daisybill_api/models/employer.rb +13 -0
- data/lib/daisybill_api/models/injury.rb +30 -0
- data/lib/daisybill_api/models/patient.rb +32 -0
- data/lib/daisybill_api/models/place_of_service.rb +29 -0
- data/lib/daisybill_api/models/referring_provider.rb +21 -0
- data/lib/daisybill_api/models/rendering_provider.rb +23 -0
- data/lib/daisybill_api/models/service_line_item.rb +27 -0
- data/lib/daisybill_api/version.rb +3 -0
- data/spec/daisybill_api/configuration_spec.rb +16 -0
- data/spec/daisybill_api/data/client_spec.rb +47 -0
- data/spec/daisybill_api/data/rest_client/payload_spec.rb +17 -0
- data/spec/daisybill_api/data/url_spec.rb +13 -0
- data/spec/daisybill_api/ext/attributes/attribute_spec.rb +120 -0
- data/spec/daisybill_api/ext/attributes/type_castings_spec.rb +50 -0
- data/spec/daisybill_api/ext/links/link_spec.rb +50 -0
- data/spec/daisybill_api/ext/pageable_collection_spec.rb +145 -0
- data/spec/daisybill_api/models/address_spec.rb +7 -0
- data/spec/daisybill_api/models/attachment_spec.rb +9 -0
- data/spec/daisybill_api/models/bill_payment_spec.rb +11 -0
- data/spec/daisybill_api/models/bill_spec.rb +22 -0
- data/spec/daisybill_api/models/bill_submission_spec.rb +9 -0
- data/spec/daisybill_api/models/billing_provider_spec.rb +13 -0
- data/spec/daisybill_api/models/claims_administrator_spec.rb +7 -0
- data/spec/daisybill_api/models/contact_spec.rb +6 -0
- data/spec/daisybill_api/models/employer_spec.rb +7 -0
- data/spec/daisybill_api/models/injury_spec.rb +13 -0
- data/spec/daisybill_api/models/patient_spec.rb +14 -0
- data/spec/daisybill_api/models/place_of_service_spec.rb +14 -0
- data/spec/daisybill_api/models/referring_provider_spec.rb +11 -0
- data/spec/daisybill_api/models/rendering_provider_spec.rb +12 -0
- data/spec/daisybill_api/models/service_line_item_spec.rb +11 -0
- data/spec/daisybill_api_spec.rb +35 -0
- 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,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,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,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
|