rconomic 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -1
- data/lib/economic/current_invoice.rb +43 -4
- data/lib/economic/current_invoice_line.rb +25 -1
- data/lib/economic/debtor.rb +32 -2
- data/lib/economic/debtor_contact.rb +64 -0
- data/lib/economic/entity.rb +44 -10
- data/lib/economic/proxies/current_invoice_line_proxy.rb +1 -8
- data/lib/economic/proxies/current_invoice_proxy.rb +1 -8
- data/lib/economic/proxies/debtor_contact_proxy.rb +38 -0
- data/lib/economic/proxies/debtor_proxy.rb +1 -8
- data/lib/economic/proxies/entity_proxy.rb +23 -10
- data/lib/economic/session.rb +5 -0
- data/lib/rconomic/version.rb +1 -1
- data/lib/rconomic.rb +2 -0
- data/spec/economic/current_invoice_line_spec.rb +11 -0
- data/spec/economic/current_invoice_spec.rb +11 -1
- data/spec/economic/debtor_contact_spec.rb +106 -0
- data/spec/economic/debtor_spec.rb +35 -0
- data/spec/economic/entity_spec.rb +33 -0
- data/spec/economic/proxies/debtor_contact_proxy_spec.rb +55 -0
- data/spec/economic/proxies/debtor_proxy_spec.rb +6 -0
- data/spec/economic/session_spec.rb +10 -0
- data/spec/fixtures/debtor_contact_get_data/success.xml +24 -0
- metadata +10 -7
data/README.md
CHANGED
@@ -63,9 +63,10 @@ Not even remotely... For now, limited to a small subset of all the [available op
|
|
63
63
|
|
64
64
|
| Create | Read | Update
|
65
65
|
-------------------+--------+------+-------
|
66
|
-
Debtor | X | X | X
|
67
66
|
CurrentInvoice | X | X | X
|
68
67
|
CurrentInvoiceLine | X | X | X
|
68
|
+
Debtor | X | X | X
|
69
|
+
DebtorContact | X | X | X
|
69
70
|
|
70
71
|
|
71
72
|
Credits
|
@@ -2,9 +2,29 @@ require 'economic/entity'
|
|
2
2
|
|
3
3
|
module Economic
|
4
4
|
|
5
|
-
#
|
5
|
+
# CurrentInvoices are invoices that are not yet booked. They are therefore not read-only.
|
6
6
|
#
|
7
|
-
# http://www.e-conomic.com/apidocs/Documentation/T_Economic_Api_ICurrentInvoice.html
|
7
|
+
# API documentation: http://www.e-conomic.com/apidocs/Documentation/T_Economic_Api_ICurrentInvoice.html
|
8
|
+
#
|
9
|
+
# Examples
|
10
|
+
#
|
11
|
+
# # Create invoice for debtor:
|
12
|
+
# invoice = debtor.current_invoices.build
|
13
|
+
# invoice.date = Time.now
|
14
|
+
# invoice.due_date = Time.now + 15
|
15
|
+
# invoice.exchange_rate = 100
|
16
|
+
# invoice.is_vat_included = false
|
17
|
+
#
|
18
|
+
# # Add a line to the invoice
|
19
|
+
# invoice_line = invoice.lines.build
|
20
|
+
# invoice_line.description = 'Line on invoice'
|
21
|
+
# invoice_line.unit_handle = { :number => 1 }
|
22
|
+
# invoice_line.product_handle = { :number => 101 }
|
23
|
+
# invoice_line.quantity = 12
|
24
|
+
# invoice_line.unit_net_price = 19.95
|
25
|
+
# invoice.lines << invoice_line
|
26
|
+
#
|
27
|
+
# invoice.save
|
8
28
|
class CurrentInvoice < Entity
|
9
29
|
has_properties :id, :debtor_handle, :debtor_name, :debtor_address, :debtor_postal_code, :debtor_city, :debtor_country, :date, :term_of_payment_handle, :due_date, :currency_handle, :exchange_rate, :is_vat_included, :layout_handle, :delivery_date, :net_amount, :vat_amount, :gross_amount, :margin, :margin_as_percent
|
10
30
|
|
@@ -12,6 +32,25 @@ module Economic
|
|
12
32
|
super
|
13
33
|
end
|
14
34
|
|
35
|
+
def debtor
|
36
|
+
return nil if debtor_handle.blank?
|
37
|
+
@debtor ||= session.debtors.find(debtor_handle)
|
38
|
+
end
|
39
|
+
|
40
|
+
def debtor=(debtor)
|
41
|
+
self.debtor_handle = debtor.handle
|
42
|
+
@debtor = debtor
|
43
|
+
end
|
44
|
+
|
45
|
+
def debtor_handle=(handle)
|
46
|
+
@debtor = nil unless handle == @debtor_handle
|
47
|
+
@debtor_handle = handle
|
48
|
+
end
|
49
|
+
|
50
|
+
def handle
|
51
|
+
Handle.new(:id => @id)
|
52
|
+
end
|
53
|
+
|
15
54
|
# Returns the current invoice lines of CurrentInvoice
|
16
55
|
def lines
|
17
56
|
@lines ||= CurrentInvoiceLineProxy.new(self)
|
@@ -40,7 +79,7 @@ module Economic
|
|
40
79
|
data = ActiveSupport::OrderedHash.new
|
41
80
|
|
42
81
|
data['Id'] = id
|
43
|
-
data['DebtorHandle'] =
|
82
|
+
data['DebtorHandle'] = debtor.handle.to_hash unless debtor.blank?
|
44
83
|
data['DebtorName'] = debtor_name
|
45
84
|
data['DebtorAddress'] = debtor_address unless debtor_address.blank?
|
46
85
|
data['DebtorPostalCode'] = debtor_postal_code unless debtor_postal_code.blank?
|
@@ -69,7 +108,7 @@ module Economic
|
|
69
108
|
|
70
109
|
self.lines.each do |invoice_line|
|
71
110
|
invoice_line.session = session
|
72
|
-
invoice_line.
|
111
|
+
invoice_line.invoice = self
|
73
112
|
invoice_line.save
|
74
113
|
end
|
75
114
|
end
|
@@ -3,9 +3,33 @@ require 'economic/current_invoice'
|
|
3
3
|
|
4
4
|
module Economic
|
5
5
|
|
6
|
+
# Represents a current invoice line.
|
7
|
+
#
|
8
|
+
# API documentation: http://www.e-conomic.com/apidocs/Documentation/T_Economic_Api_ICurrentInvoiceLine.html
|
9
|
+
#
|
10
|
+
# See Economic::CurrentInvoice for usage example
|
6
11
|
class CurrentInvoiceLine < Entity
|
7
12
|
has_properties :invoice_handle, :description, :delivery_date, :unit_handle, :product_handle, :quantity, :unit_net_price, :discount_as_percent, :unit_cost_price, :total_net_amount, :total_margin, :margin_as_percent
|
8
13
|
|
14
|
+
def handle
|
15
|
+
Handle.new(:number => number)
|
16
|
+
end
|
17
|
+
|
18
|
+
def invoice
|
19
|
+
return nil if invoice_handle.blank?
|
20
|
+
@invoice ||= session.current_invoices.find(invoice_handle)
|
21
|
+
end
|
22
|
+
|
23
|
+
def invoice=(invoice)
|
24
|
+
self.invoice_handle = invoice.handle
|
25
|
+
@invoice = invoice
|
26
|
+
end
|
27
|
+
|
28
|
+
def invoice_handle=(handle)
|
29
|
+
@invoice = nil unless handle == @invoice_handle
|
30
|
+
@invoice_handle = handle
|
31
|
+
end
|
32
|
+
|
9
33
|
def initialize_defaults
|
10
34
|
self.invoice_handle = nil
|
11
35
|
self.description = nil
|
@@ -27,7 +51,7 @@ module Economic
|
|
27
51
|
data = ActiveSupport::OrderedHash.new
|
28
52
|
|
29
53
|
data['Number'] = 0 # Doesn't seem to be used
|
30
|
-
data['InvoiceHandle'] =
|
54
|
+
data['InvoiceHandle'] = invoice.handle.to_hash unless invoice.blank?
|
31
55
|
data['Description'] = description unless description.blank?
|
32
56
|
data['DeliveryDate'] = delivery_date
|
33
57
|
data['UnitHandle'] = { 'Number' => unit_handle[:number] } unless unit_handle.blank?
|
data/lib/economic/debtor.rb
CHANGED
@@ -2,9 +2,39 @@ require 'economic/entity'
|
|
2
2
|
|
3
3
|
module Economic
|
4
4
|
|
5
|
+
# Represents a debtor in E-conomic.
|
6
|
+
#
|
7
|
+
# API documentation: http://www.e-conomic.com/apidocs/Documentation/T_Economic_Api_IDebtor.html
|
8
|
+
#
|
9
|
+
# Examples
|
10
|
+
#
|
11
|
+
# # Find a debtor:
|
12
|
+
# debtor = economic.debtors.find(558)
|
13
|
+
#
|
14
|
+
# # Creating a debtor:
|
15
|
+
# debtor = economic.debtors.build
|
16
|
+
# debtor.number = economic.debtors.next_available_number
|
17
|
+
# debtor.debtor_group_handle = { :number => 1 }
|
18
|
+
# debtor.name = 'Apple Inc'
|
19
|
+
# debtor.vat_zone = 'HomeCountry' # HomeCountry, EU, Abroad
|
20
|
+
# debtor.currency_handle = { :code => 'DKK' }
|
21
|
+
# debtor.price_group_handle = { :number => 1 }
|
22
|
+
# debtor.is_accessible = true
|
23
|
+
# debtor.ci_number = '12345678'
|
24
|
+
# debtor.term_of_payment_handle = { :id => 1 }
|
25
|
+
# debtor.layout_handle = { :id => 16 }
|
26
|
+
# debtor.save
|
5
27
|
class Debtor < Entity
|
6
28
|
has_properties :handle, :number, :debtor_group_handle, :name, :vat_zone, :currency_handle, :price_group_handle, :is_accessible, :ean, :public_entry_number, :email, :telephone_and_fax_number, :website, :address, :postal_code, :city, :country, :credit_maximum, :vat_number, :county, :ci_number, :term_of_payment_handle, :layout_handle, :attention_handle, :your_reference_handle, :our_reference_handle, :balance
|
7
29
|
|
30
|
+
def handle
|
31
|
+
Handle.new({:number => @number})
|
32
|
+
end
|
33
|
+
|
34
|
+
def contacts
|
35
|
+
@contacts ||= DebtorContactProxy.new(self)
|
36
|
+
end
|
37
|
+
|
8
38
|
# Provides access to the current invoices - ie invoices that haven't yet been booked
|
9
39
|
def current_invoices
|
10
40
|
@current_invoices ||= CurrentInvoiceProxy.new(self)
|
@@ -15,8 +45,8 @@ module Economic
|
|
15
45
|
def build_soap_data
|
16
46
|
data = ActiveSupport::OrderedHash.new
|
17
47
|
|
18
|
-
data['Handle'] =
|
19
|
-
data['Number'] = number
|
48
|
+
data['Handle'] = handle.to_hash
|
49
|
+
data['Number'] = handle.number
|
20
50
|
data['DebtorGroupHandle'] = { 'Number' => debtor_group_handle[:number] } unless debtor_group_handle.blank?
|
21
51
|
data['Name'] = name
|
22
52
|
data['VatZone'] = vat_zone
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'economic/entity'
|
2
|
+
|
3
|
+
module Economic
|
4
|
+
|
5
|
+
# Represents a debtor contact.
|
6
|
+
#
|
7
|
+
# API documentation: http://www.e-conomic.com/apidocs/Documentation/T_Economic_Api_IDebtorContact.html
|
8
|
+
#
|
9
|
+
# Examples
|
10
|
+
#
|
11
|
+
# # Find contact
|
12
|
+
# contact = economic.contacts.find(5)
|
13
|
+
#
|
14
|
+
# # Creating a contact
|
15
|
+
# contact = debtor.contacts.build
|
16
|
+
# contact.id = 0
|
17
|
+
# contact.number = 0
|
18
|
+
# contact.name = 'John Appleseed'
|
19
|
+
# contact.save
|
20
|
+
class DebtorContact < Entity
|
21
|
+
has_properties :handle, :id, :debtor_handle, :name, :number, :telephone_number, :email, :comments, :external_id, :is_to_receive_email_copy_of_order, :is_to_receive_email_copy_of_invoice
|
22
|
+
|
23
|
+
def debtor
|
24
|
+
return nil if debtor_handle.blank?
|
25
|
+
@debtor ||= session.debtors.find(debtor_handle)
|
26
|
+
end
|
27
|
+
|
28
|
+
def debtor=(debtor)
|
29
|
+
self.debtor_handle = debtor.handle
|
30
|
+
@debtor = debtor
|
31
|
+
end
|
32
|
+
|
33
|
+
def debtor_handle=(handle)
|
34
|
+
@debtor = nil unless handle == @debtor_handle
|
35
|
+
@debtor_handle = handle
|
36
|
+
end
|
37
|
+
|
38
|
+
def handle
|
39
|
+
Handle.new({:id => @id})
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def build_soap_data
|
45
|
+
data = ActiveSupport::OrderedHash.new
|
46
|
+
|
47
|
+
data['Handle'] = handle.to_hash
|
48
|
+
data['Id'] = handle.id
|
49
|
+
data['DebtorHandle'] = debtor.handle.to_hash unless debtor.blank?
|
50
|
+
data['Name'] = name
|
51
|
+
data['Number'] = number unless number.blank?
|
52
|
+
data['TelephoneNumber'] = telephone_number unless telephone_number.blank?
|
53
|
+
data['Email'] = email unless email.blank?
|
54
|
+
data['Comments'] = comments unless comments.blank?
|
55
|
+
data['ExternalId'] = external_id unless external_id.blank?
|
56
|
+
data['IsToReceiveEmailCopyOfOrder'] = is_to_receive_email_copy_of_order || false
|
57
|
+
data['IsToReceiveEmailCopyOfInvoice'] = is_to_receive_email_copy_of_invoice || false
|
58
|
+
|
59
|
+
return data
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
data/lib/economic/entity.rb
CHANGED
@@ -1,8 +1,30 @@
|
|
1
|
+
module Economic
|
2
|
+
class Entity
|
3
|
+
class Handle
|
4
|
+
attr_accessor :id, :number
|
1
5
|
|
6
|
+
def initialize(hash)
|
7
|
+
@id = hash[:id]
|
8
|
+
@number = hash[:number]
|
9
|
+
end
|
2
10
|
|
3
|
-
|
11
|
+
def to_hash
|
12
|
+
hash = {}
|
13
|
+
hash['Id'] = id unless id.blank?
|
14
|
+
hash['Number'] = number unless number.blank?
|
15
|
+
hash
|
16
|
+
end
|
4
17
|
|
5
|
-
|
18
|
+
def [](key)
|
19
|
+
{:id => @id, :number => @number}[key]
|
20
|
+
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
return false if other.nil?
|
24
|
+
return false unless other.respond_to?(:id) && other.respond_to?(:number)
|
25
|
+
self.id == other.id && self.number == other.number
|
26
|
+
end
|
27
|
+
end
|
6
28
|
|
7
29
|
# Internal accessors
|
8
30
|
attr_accessor :persisted, :session, :partial
|
@@ -36,6 +58,13 @@ module Economic
|
|
36
58
|
@properties || []
|
37
59
|
end
|
38
60
|
|
61
|
+
# Returns the class used to instantiate a proxy for Entity
|
62
|
+
def proxy
|
63
|
+
class_name = name.split('::').last
|
64
|
+
proxy_class_name = "#{class_name}Proxy"
|
65
|
+
Economic.const_get(proxy_class_name)
|
66
|
+
end
|
67
|
+
|
39
68
|
# Returns the E-conomic API action name to call
|
40
69
|
def soap_action(action)
|
41
70
|
class_name = self.name
|
@@ -44,6 +73,10 @@ module Economic
|
|
44
73
|
end
|
45
74
|
end
|
46
75
|
|
76
|
+
def handle
|
77
|
+
Handle.new({:number => @number, :id => @id})
|
78
|
+
end
|
79
|
+
|
47
80
|
def initialize(properties = {})
|
48
81
|
initialize_defaults
|
49
82
|
update_properties(properties)
|
@@ -57,13 +90,7 @@ module Economic
|
|
57
90
|
|
58
91
|
# Updates Entity with its data from the API
|
59
92
|
def get_data
|
60
|
-
response =
|
61
|
-
soap.body = {
|
62
|
-
'entityHandle' => {
|
63
|
-
'Number' => number
|
64
|
-
}
|
65
|
-
}
|
66
|
-
end
|
93
|
+
response = proxy.get_data(number)
|
67
94
|
self.update_properties(response)
|
68
95
|
self.partial = false
|
69
96
|
self.persisted = true
|
@@ -97,6 +124,13 @@ module Economic
|
|
97
124
|
!!@partial
|
98
125
|
end
|
99
126
|
|
127
|
+
# Returns a proxy for entities of the current class. For example if called on an
|
128
|
+
# Economic::Debtor it returns an instance of Economic::DebtorProxy with the Debtors session as
|
129
|
+
# owner.
|
130
|
+
def proxy
|
131
|
+
self.class.proxy.new(session)
|
132
|
+
end
|
133
|
+
|
100
134
|
def inspect
|
101
135
|
props = self.class.properties.collect { |p| "#{p}=#{self.send(p).inspect}" }
|
102
136
|
"#<#{self.class}:#{self.object_id} partial=#{partial?}, persisted=#{persisted?}, #{props.join(', ')}>"
|
@@ -128,7 +162,7 @@ module Economic
|
|
128
162
|
end
|
129
163
|
|
130
164
|
def create
|
131
|
-
response = session.request soap_action(
|
165
|
+
response = session.request soap_action(:create_from_data) do
|
132
166
|
soap.body = {'data' => build_soap_data}
|
133
167
|
end
|
134
168
|
|
@@ -2,13 +2,6 @@ require 'economic/proxies/entity_proxy'
|
|
2
2
|
|
3
3
|
module Economic
|
4
4
|
class CurrentInvoiceLineProxy < EntityProxy
|
5
|
-
class << self
|
6
|
-
# Returns the class this proxy is a proxy for
|
7
|
-
def entity_class
|
8
|
-
CurrentInvoiceLine
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
5
|
# Returns a new, unpersisted Economic::CurrentInvoiceLine
|
13
6
|
def build(properties = {})
|
14
7
|
invoice_line = super
|
@@ -20,7 +13,7 @@ module Economic
|
|
20
13
|
|
21
14
|
# Initialize properties in invoice_line with values from owner
|
22
15
|
def initialize_properties_with_values_from_owner(invoice_line)
|
23
|
-
invoice_line.
|
16
|
+
invoice_line.invoice = owner
|
24
17
|
invoice_line
|
25
18
|
end
|
26
19
|
|
@@ -2,13 +2,6 @@ require 'economic/proxies/entity_proxy'
|
|
2
2
|
|
3
3
|
module Economic
|
4
4
|
class CurrentInvoiceProxy < EntityProxy
|
5
|
-
class << self
|
6
|
-
# Returns the class this proxy is a proxy for
|
7
|
-
def entity_class
|
8
|
-
CurrentInvoice
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
5
|
# Returns a new, unpersisted Economic::CurrentInvoice
|
13
6
|
def build(properties = {})
|
14
7
|
invoice = super
|
@@ -20,7 +13,7 @@ module Economic
|
|
20
13
|
|
21
14
|
# Initialize properties in invoice with values from owner
|
22
15
|
def initialize_properties_with_values_from_owner(invoice)
|
23
|
-
invoice.
|
16
|
+
invoice.debtor = owner
|
24
17
|
|
25
18
|
invoice.debtor_name ||= owner.name
|
26
19
|
invoice.debtor_address ||= owner.address
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'economic/proxies/entity_proxy'
|
2
|
+
|
3
|
+
module Economic
|
4
|
+
class DebtorContactProxy < EntityProxy
|
5
|
+
|
6
|
+
# Returns a new, unpersisted Economic::DebtorContact
|
7
|
+
def build(properties = {})
|
8
|
+
contact = super
|
9
|
+
initialize_properties_with_values_from_owner(contact) if owner.is_a?(Debtor)
|
10
|
+
contact
|
11
|
+
end
|
12
|
+
|
13
|
+
# Gets data for DebtorContact from the API
|
14
|
+
def find(id)
|
15
|
+
# This is basically EntityProxy::find duplicated so we can pass id to the API instead of
|
16
|
+
# Number...
|
17
|
+
entity_hash = session.request entity_class.soap_action(:get_data) do
|
18
|
+
soap.body = {
|
19
|
+
'entityHandle' => {
|
20
|
+
'Id' => id
|
21
|
+
}
|
22
|
+
}
|
23
|
+
end
|
24
|
+
entity = build(entity_hash)
|
25
|
+
entity.persisted = true
|
26
|
+
entity
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# Initialize properties in contact with values from owner. Returns contact.
|
32
|
+
def initialize_properties_with_values_from_owner(contact)
|
33
|
+
contact.debtor = owner
|
34
|
+
contact
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -2,17 +2,10 @@ require 'economic/proxies/entity_proxy'
|
|
2
2
|
|
3
3
|
module Economic
|
4
4
|
class DebtorProxy < EntityProxy
|
5
|
-
class << self
|
6
|
-
# Returns the class this proxy is a proxy for
|
7
|
-
def entity_class
|
8
|
-
Debtor
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
5
|
# Returns Debtors that have the given ci_number. The Debtor objects will only be partially loaded
|
13
6
|
def find_by_ci_number(ci_number)
|
14
7
|
# Get a list of DebtorHandles from e-conomic
|
15
|
-
response = session.request
|
8
|
+
response = session.request entity_class.soap_action('FindByCINumber') do
|
16
9
|
soap.body = {
|
17
10
|
'ciNumber' => ci_number
|
18
11
|
}
|
@@ -3,7 +3,9 @@ module Economic
|
|
3
3
|
class << self
|
4
4
|
# Returns the class this Proxy is a proxy for
|
5
5
|
def entity_class
|
6
|
-
|
6
|
+
proxy_class_name = name.split('::').last
|
7
|
+
entity_class_name = proxy_class_name.sub(/Proxy$/, '')
|
8
|
+
Economic.const_get(entity_class_name)
|
7
9
|
end
|
8
10
|
end
|
9
11
|
|
@@ -30,20 +32,31 @@ module Economic
|
|
30
32
|
entity
|
31
33
|
end
|
32
34
|
|
33
|
-
#
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
# Returns the class this proxy manages
|
36
|
+
def entity_class
|
37
|
+
self.class.entity_class
|
38
|
+
end
|
39
|
+
|
40
|
+
# Fetches Entity data from API and returns an Entity initialized with that data
|
41
|
+
def find(handle)
|
42
|
+
handle = Entity::Handle.new(:number => handle) unless handle.is_a?(Entity::Handle)
|
43
|
+
entity_hash = get_data(handle)
|
42
44
|
entity = build(entity_hash)
|
43
45
|
entity.persisted = true
|
44
46
|
entity
|
45
47
|
end
|
46
48
|
|
49
|
+
# Gets data for Entity from the API. Returns Hash with the response data
|
50
|
+
def get_data(handle)
|
51
|
+
handle = Entity::Handle.new(:number => handle) unless handle.is_a?(Entity::Handle)
|
52
|
+
entity_hash = session.request(entity_class.soap_action(:get_data)) do
|
53
|
+
soap.body = {
|
54
|
+
'entityHandle' => handle.to_hash
|
55
|
+
}
|
56
|
+
end
|
57
|
+
entity_hash
|
58
|
+
end
|
59
|
+
|
47
60
|
# Add item to proxy
|
48
61
|
def <<(item)
|
49
62
|
items << item
|
data/lib/economic/session.rb
CHANGED
@@ -28,6 +28,11 @@ module Economic
|
|
28
28
|
client.http.headers["Cookie"] = response.http.headers["Set-Cookie"]
|
29
29
|
end
|
30
30
|
|
31
|
+
# Provides access to the DebtorContacts
|
32
|
+
def contacts
|
33
|
+
@contacts ||= DebtorContactProxy.new(self)
|
34
|
+
end
|
35
|
+
|
31
36
|
# Provides access to the current invoices - ie invoices that haven't yet been booked
|
32
37
|
def current_invoices
|
33
38
|
@current_invoices ||= CurrentInvoiceProxy.new(self)
|
data/lib/rconomic/version.rb
CHANGED
data/lib/rconomic.rb
CHANGED
@@ -5,12 +5,14 @@ require 'active_support/ordered_hash'
|
|
5
5
|
|
6
6
|
require 'economic/session'
|
7
7
|
require 'economic/debtor'
|
8
|
+
require 'economic/debtor_contact'
|
8
9
|
require 'economic/current_invoice'
|
9
10
|
require 'economic/current_invoice_line'
|
10
11
|
|
11
12
|
require 'economic/proxies/current_invoice_proxy'
|
12
13
|
require 'economic/proxies/current_invoice_line_proxy'
|
13
14
|
require 'economic/proxies/debtor_proxy'
|
15
|
+
require 'economic/proxies/debtor_contact_proxy'
|
14
16
|
|
15
17
|
# http://www.e-conomic.com/apidocs/Documentation/index.html
|
16
18
|
# https://www.e-conomic.com/secure/api1/EconomicWebService.asmx
|
@@ -7,4 +7,15 @@ describe Economic::CurrentInvoiceLine do
|
|
7
7
|
it "inherits from Economic::Entity" do
|
8
8
|
Economic::CurrentInvoiceLine.ancestors.should include(Economic::Entity)
|
9
9
|
end
|
10
|
+
|
11
|
+
describe ".proxy" do
|
12
|
+
it "should return a CurrentInvoiceLineProxy" do
|
13
|
+
subject.proxy.should be_instance_of(Economic::CurrentInvoiceLineProxy)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return a proxy owned by session" do
|
17
|
+
subject.proxy.session.should == session
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
10
21
|
end
|
@@ -15,6 +15,16 @@ describe Economic::CurrentInvoice do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
describe ".proxy" do
|
19
|
+
it "should return a CurrentInvoiceProxy" do
|
20
|
+
subject.proxy.should be_instance_of(Economic::CurrentInvoiceProxy)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return a proxy owned by session" do
|
24
|
+
subject.proxy.session.should == session
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
18
28
|
describe "save" do
|
19
29
|
context "when successful" do
|
20
30
|
before :each do
|
@@ -32,7 +42,7 @@ describe Economic::CurrentInvoice do
|
|
32
42
|
|
33
43
|
it "adds the lines to the invoice" do
|
34
44
|
subject.lines.each do |line|
|
35
|
-
line.expects(:
|
45
|
+
line.expects(:invoice=).with(subject)
|
36
46
|
end
|
37
47
|
|
38
48
|
subject.save
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require './spec/spec_helper'
|
2
|
+
|
3
|
+
describe Economic::DebtorContact do
|
4
|
+
let(:session) { make_session }
|
5
|
+
subject { Economic::DebtorContact.new(:session => session) }
|
6
|
+
|
7
|
+
it "inherits from Economic::Entity" do
|
8
|
+
Economic::DebtorContact.ancestors.should include(Economic::Entity)
|
9
|
+
end
|
10
|
+
|
11
|
+
context "when saving" do
|
12
|
+
context "when debtor contact is new" do
|
13
|
+
subject { Economic::DebtorContact.new(:session => session) }
|
14
|
+
|
15
|
+
context "when debtor_handle is nil" do
|
16
|
+
before :each do
|
17
|
+
subject.debtor_handle = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should send request and let e-conomic return an error" do
|
21
|
+
session.expects(:request)
|
22
|
+
subject.save
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe ".debtor" do
|
29
|
+
context "when debtor_handle is not set" do
|
30
|
+
it "returns nil" do
|
31
|
+
subject.debtor.should be_nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when debtor_handle is set" do
|
36
|
+
let(:handle) { Economic::DebtorContact::Handle.new({:number => 42}) }
|
37
|
+
|
38
|
+
before :each do
|
39
|
+
subject.debtor_handle = handle
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns a Debtor" do
|
43
|
+
session.debtors.expects(:find).with(handle).returns(Economic::Debtor.new)
|
44
|
+
subject.debtor.should be_instance_of(Economic::Debtor)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "only looks up the debtor the first time" do
|
48
|
+
session.debtors.expects(:find).with(handle).returns(Economic::Debtor.new)
|
49
|
+
subject.debtor.should === subject.debtor
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe ".debtor=" do
|
55
|
+
let(:debtor) { make_debtor }
|
56
|
+
it "should set debtor_handle" do
|
57
|
+
subject.debtor = debtor
|
58
|
+
subject.debtor_handle.should == debtor.handle
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe ".debtor_handle=" do
|
63
|
+
let(:debtor) { make_debtor }
|
64
|
+
let(:handle) { debtor.handle }
|
65
|
+
|
66
|
+
it "should set debtor_handle" do
|
67
|
+
subject.debtor_handle = handle
|
68
|
+
subject.debtor_handle.should == handle
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when debtor handle is for a different Debtor" do
|
72
|
+
before :each do
|
73
|
+
subject.debtor = debtor
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should clear cached debtor and fetch the new debtor from API" do
|
77
|
+
savon.stubs('Debtor_GetData').returns(:success)
|
78
|
+
subject.debtor_handle = Economic::Debtor::Handle.new({:number => 1234})
|
79
|
+
subject.debtor.should be_instance_of(Economic::Debtor)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when debtor handle is for the current Debtor" do
|
84
|
+
before :each do
|
85
|
+
subject.debtor = debtor
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should not clear cached debtor nor fetch the debtor from API" do
|
89
|
+
savon.stubs('Debtor_GetData').never
|
90
|
+
subject.debtor_handle = handle
|
91
|
+
subject.debtor.should be_instance_of(Economic::Debtor)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe ".proxy" do
|
97
|
+
it "should return a DebtorContactProxy" do
|
98
|
+
subject.proxy.should be_instance_of(Economic::DebtorContactProxy)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should return a proxy owned by session" do
|
102
|
+
subject.proxy.session.should == session
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -8,6 +8,16 @@ describe Economic::Debtor do
|
|
8
8
|
Economic::Debtor.ancestors.should include(Economic::Entity)
|
9
9
|
end
|
10
10
|
|
11
|
+
describe "class methods" do
|
12
|
+
subject { Economic::Debtor }
|
13
|
+
|
14
|
+
describe ".proxy" do
|
15
|
+
it "should return DebtorProxy" do
|
16
|
+
subject.proxy.should == Economic::DebtorProxy
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
11
21
|
context "when saving" do
|
12
22
|
context "when debtor is new" do
|
13
23
|
subject { Economic::Debtor.new(:session => session) }
|
@@ -40,4 +50,29 @@ describe Economic::Debtor do
|
|
40
50
|
end
|
41
51
|
end
|
42
52
|
|
53
|
+
describe ".contacts" do
|
54
|
+
it "returns a DebtorContactProxy" do
|
55
|
+
subject.contacts.should be_instance_of(Economic::DebtorContactProxy)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "memoizes the proxy" do
|
59
|
+
subject.contacts.should === subject.contacts
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should store the session" do
|
63
|
+
subject.session.should_not be_nil
|
64
|
+
subject.contacts.session.should == subject.session
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe ".proxy" do
|
69
|
+
it "should return a DebtorProxy" do
|
70
|
+
subject.proxy.should be_instance_of(Economic::DebtorProxy)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should return a proxy owned by session" do
|
74
|
+
subject.proxy.session.should == session
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
43
78
|
end
|
@@ -4,8 +4,12 @@ class SpecEntity < Economic::Entity
|
|
4
4
|
has_properties :foo, :baz
|
5
5
|
|
6
6
|
def existing_method; end
|
7
|
+
|
8
|
+
def proxy; Economic::SpecEntityProxy.new(session); end
|
7
9
|
end
|
8
10
|
|
11
|
+
class Economic::SpecEntityProxy < Economic::EntityProxy; end
|
12
|
+
|
9
13
|
describe Economic::Entity do
|
10
14
|
let(:session) { make_session }
|
11
15
|
|
@@ -150,6 +154,14 @@ describe Economic::Entity do
|
|
150
154
|
end
|
151
155
|
end
|
152
156
|
|
157
|
+
describe ".proxy" do
|
158
|
+
subject { (e = SpecEntity.new).tap { |e| e.session = session } }
|
159
|
+
|
160
|
+
it "should return SpecEntityProxy" do
|
161
|
+
subject.proxy.should be_instance_of(Economic::SpecEntityProxy)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
153
165
|
describe "update" do
|
154
166
|
subject { (e = SpecEntity.new).tap { |e| e.persisted = true; e.session = session } }
|
155
167
|
|
@@ -177,3 +189,24 @@ describe Economic::Entity do
|
|
177
189
|
end
|
178
190
|
end
|
179
191
|
|
192
|
+
describe Economic::Entity::Handle do
|
193
|
+
|
194
|
+
describe "equality" do
|
195
|
+
let(:handle_a) { Economic::Entity::Handle.new(:id => 1, :number => 2) }
|
196
|
+
let(:handle_b) { Economic::Entity::Handle.new(:id => 1, :number => 2) }
|
197
|
+
let(:handle_c) { Economic::Entity::Handle.new(:id => 1) }
|
198
|
+
let(:handle_d) { Economic::Entity::Handle.new(:id => 1, :number => 3) }
|
199
|
+
|
200
|
+
it "should be equal when both id and number are equal" do
|
201
|
+
handle_a.should == handle_b
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should not be equal when id or number is missing" do
|
205
|
+
handle_a.should_not == handle_c
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should not be equal when id or number is equal and the other isn't" do
|
209
|
+
handle_a.should_not == handle_d
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require './spec/spec_helper'
|
2
|
+
|
3
|
+
describe Economic::DebtorContactProxy do
|
4
|
+
let(:session) { make_session }
|
5
|
+
subject { Economic::DebtorContactProxy.new(session) }
|
6
|
+
|
7
|
+
describe ".new" do
|
8
|
+
it "stores session" do
|
9
|
+
subject.session.should === session
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".build" do
|
14
|
+
it "instantiates a new DebtorContact" do
|
15
|
+
subject.build.should be_instance_of(Economic::DebtorContact)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "assigns the session to the DebtorContact" do
|
19
|
+
subject.build.session.should === session
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should not build a partial DebtorContact" do
|
23
|
+
subject.build.should_not be_partial
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when owner is a Debtor" do
|
27
|
+
let(:debtor) { make_debtor(:session => session) }
|
28
|
+
subject { debtor.contacts }
|
29
|
+
|
30
|
+
it "should use the Debtors session" do
|
31
|
+
subject.build.session.should == debtor.session
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should initialize with values from Debtor" do
|
35
|
+
contact = subject.build
|
36
|
+
contact.debtor_handle.should == debtor.handle
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe ".find" do
|
42
|
+
before :each do
|
43
|
+
savon.stubs('DebtorContact_GetData').returns(:success)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "gets contact data from API" do
|
47
|
+
savon.expects('DebtorContact_GetData').with('entityHandle' => {'Id' => 42}).returns(:success)
|
48
|
+
subject.find(42)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns DebtorContact object" do
|
52
|
+
subject.find(42).should be_instance_of(Economic::DebtorContact)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -38,6 +38,16 @@ describe Economic::Session do
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
describe "contacts" do
|
42
|
+
it "returns a DebtorContactProxy" do
|
43
|
+
subject.contacts.should be_instance_of(Economic::DebtorContactProxy)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "memoizes the proxy" do
|
47
|
+
subject.contacts.should === subject.contacts
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
41
51
|
describe "current_invoices" do
|
42
52
|
it "returns an CurrentInvoiceProxy" do
|
43
53
|
subject.current_invoices.should be_instance_of(Economic::CurrentInvoiceProxy)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
3
|
+
<soap:Body>
|
4
|
+
<DebtorContact_GetDataResponse xmlns="http://e-conomic.com">
|
5
|
+
<DebtorContact_GetDataResult>
|
6
|
+
<Handle>
|
7
|
+
<Id>int</Id>
|
8
|
+
</Handle>
|
9
|
+
<Id>int</Id>
|
10
|
+
<DebtorHandle>
|
11
|
+
<Number>string</Number>
|
12
|
+
</DebtorHandle>
|
13
|
+
<Name>string</Name>
|
14
|
+
<Number>int</Number>
|
15
|
+
<TelephoneNumber>string</TelephoneNumber>
|
16
|
+
<Email>string</Email>
|
17
|
+
<Comments>string</Comments>
|
18
|
+
<ExternalId>string</ExternalId>
|
19
|
+
<IsToReceiveEmailCopyOfOrder>boolean</IsToReceiveEmailCopyOfOrder>
|
20
|
+
<IsToReceiveEmailCopyOfInvoice>boolean</IsToReceiveEmailCopyOfInvoice>
|
21
|
+
</DebtorContact_GetDataResult>
|
22
|
+
</DebtorContact_GetDataResponse>
|
23
|
+
</soap:Body>
|
24
|
+
</soap:Envelope>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rconomic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jakob Skjerning
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-08-
|
19
|
-
default_executable:
|
18
|
+
date: 2011-08-09 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: savon
|
@@ -67,10 +66,12 @@ files:
|
|
67
66
|
- lib/economic/current_invoice.rb
|
68
67
|
- lib/economic/current_invoice_line.rb
|
69
68
|
- lib/economic/debtor.rb
|
69
|
+
- lib/economic/debtor_contact.rb
|
70
70
|
- lib/economic/economic.wsdl
|
71
71
|
- lib/economic/entity.rb
|
72
72
|
- lib/economic/proxies/current_invoice_line_proxy.rb
|
73
73
|
- lib/economic/proxies/current_invoice_proxy.rb
|
74
|
+
- lib/economic/proxies/debtor_contact_proxy.rb
|
74
75
|
- lib/economic/proxies/debtor_proxy.rb
|
75
76
|
- lib/economic/proxies/entity_proxy.rb
|
76
77
|
- lib/economic/session.rb
|
@@ -79,16 +80,19 @@ files:
|
|
79
80
|
- rconomic.gemspec
|
80
81
|
- spec/economic/current_invoice_line_spec.rb
|
81
82
|
- spec/economic/current_invoice_spec.rb
|
83
|
+
- spec/economic/debtor_contact_spec.rb
|
82
84
|
- spec/economic/debtor_spec.rb
|
83
85
|
- spec/economic/entity_spec.rb
|
84
86
|
- spec/economic/proxies/current_invoice_line_proxy_spec.rb
|
85
87
|
- spec/economic/proxies/current_invoice_proxy_spec.rb
|
88
|
+
- spec/economic/proxies/debtor_contact_proxy_spec.rb
|
86
89
|
- spec/economic/proxies/debtor_proxy_spec.rb
|
87
90
|
- spec/economic/session_spec.rb
|
88
91
|
- spec/fixtures/connect/success.xml
|
89
92
|
- spec/fixtures/current_invoice_create_from_data/success.xml
|
90
93
|
- spec/fixtures/current_invoice_get_data/success.xml
|
91
94
|
- spec/fixtures/current_invoice_line_get_data/success.xml
|
95
|
+
- spec/fixtures/debtor_contact_get_data/success.xml
|
92
96
|
- spec/fixtures/debtor_find_by_ci_number/many.xml
|
93
97
|
- spec/fixtures/debtor_get_data/success.xml
|
94
98
|
- spec/fixtures/debtor_get_next_available_number/success.xml
|
@@ -97,7 +101,6 @@ files:
|
|
97
101
|
- spec/fixtures/spec_entity_update_from_data/success.xml
|
98
102
|
- spec/fixtures/wsdl.xml
|
99
103
|
- spec/spec_helper.rb
|
100
|
-
has_rdoc: true
|
101
104
|
homepage: https://github.com/lokalebasen/rconomic
|
102
105
|
licenses: []
|
103
106
|
|
@@ -127,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
130
|
requirements: []
|
128
131
|
|
129
132
|
rubyforge_project:
|
130
|
-
rubygems_version: 1.6
|
133
|
+
rubygems_version: 1.8.6
|
131
134
|
signing_key:
|
132
135
|
specification_version: 3
|
133
136
|
summary: Wrapper for e-conomic.dk's SOAP API.
|