quickbooks-ruby 0.0.1
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/lib/quickbooks.rb +81 -0
- data/lib/quickbooks/http_encoding_helper.rb +49 -0
- data/lib/quickbooks/model/base_model.rb +41 -0
- data/lib/quickbooks/model/custom_field.rb +9 -0
- data/lib/quickbooks/model/customer.rb +118 -0
- data/lib/quickbooks/model/customer_ref.rb +21 -0
- data/lib/quickbooks/model/discount_override.rb +15 -0
- data/lib/quickbooks/model/email_address.rb +19 -0
- data/lib/quickbooks/model/invoice.rb +96 -0
- data/lib/quickbooks/model/invoice_item_ref.rb +21 -0
- data/lib/quickbooks/model/invoice_line_item.rb +45 -0
- data/lib/quickbooks/model/item.rb +99 -0
- data/lib/quickbooks/model/linked_transaction.rb +9 -0
- data/lib/quickbooks/model/meta_data.rb +24 -0
- data/lib/quickbooks/model/payment_line_detail.rb +10 -0
- data/lib/quickbooks/model/physical_address.rb +24 -0
- data/lib/quickbooks/model/sales_item_line_detail.rb +14 -0
- data/lib/quickbooks/model/sub_total_line_detail.rb +11 -0
- data/lib/quickbooks/model/telephone_number.rb +7 -0
- data/lib/quickbooks/model/web_site_address.rb +16 -0
- data/lib/quickbooks/service/base_service.rb +317 -0
- data/lib/quickbooks/service/customer.rb +23 -0
- data/lib/quickbooks/service/invoice.rb +21 -0
- data/lib/quickbooks/service/item.rb +22 -0
- data/lib/quickbooks/service/service_crud.rb +61 -0
- data/lib/quickbooks/util/logging.rb +9 -0
- data/lib/quickbooks/version.rb +5 -0
- metadata +224 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 22455ec12ce95cceccc04131008bbcee20de080b
|
4
|
+
data.tar.gz: 0e87c10779104d91aa8a100297c738cb905861b0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 74ba6b76bab8e057cb7dc3c6a706e1e70226f4459bfd78e6ac6308f752129f225e5cdb77546216d54e79d0f6d1f8e7abecc880da46cf070f7675c539598a3eef
|
7
|
+
data.tar.gz: 81652a925524f36c044d79e9c7f8bc9c33b739130cafbc6faf757376dd6969868ecc0cb04f36294758d9abcd0b058aa59485e59cac531354bb9806c1d61cb8f5
|
data/lib/quickbooks.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'roxml'
|
2
|
+
require 'logger'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'logger'
|
5
|
+
require 'active_model'
|
6
|
+
require 'cgi'
|
7
|
+
require 'date'
|
8
|
+
require 'forwardable'
|
9
|
+
require 'oauth'
|
10
|
+
require 'quickbooks/util/logging'
|
11
|
+
|
12
|
+
#== Models
|
13
|
+
require 'quickbooks/model/base_model'
|
14
|
+
require 'quickbooks/model/meta_data'
|
15
|
+
require 'quickbooks/model/custom_field'
|
16
|
+
require 'quickbooks/model/invoice_item_ref'
|
17
|
+
require 'quickbooks/model/sales_item_line_detail'
|
18
|
+
require 'quickbooks/model/sub_total_line_detail'
|
19
|
+
require 'quickbooks/model/customer_ref'
|
20
|
+
require 'quickbooks/model/discount_override'
|
21
|
+
require 'quickbooks/model/payment_line_detail'
|
22
|
+
require 'quickbooks/model/item'
|
23
|
+
|
24
|
+
|
25
|
+
require 'quickbooks/model/telephone_number'
|
26
|
+
require 'quickbooks/model/email_address'
|
27
|
+
require 'quickbooks/model/web_site_address'
|
28
|
+
require 'quickbooks/model/physical_address'
|
29
|
+
require 'quickbooks/model/linked_transaction'
|
30
|
+
require 'quickbooks/model/invoice_line_item'
|
31
|
+
require 'quickbooks/model/invoice'
|
32
|
+
require 'quickbooks/model/customer'
|
33
|
+
|
34
|
+
#== Services
|
35
|
+
require 'quickbooks/service/base_service'
|
36
|
+
require 'quickbooks/service/service_crud'
|
37
|
+
require 'quickbooks/service/customer'
|
38
|
+
require 'quickbooks/service/invoice'
|
39
|
+
require 'quickbooks/service/item'
|
40
|
+
|
41
|
+
class InvalidModelException < StandardError; end
|
42
|
+
|
43
|
+
module Quickbooks
|
44
|
+
@@logger = nil
|
45
|
+
|
46
|
+
class << self
|
47
|
+
def logger
|
48
|
+
@@logger ||= ::Logger.new($stdout) # TODO: replace with a real log file
|
49
|
+
end
|
50
|
+
|
51
|
+
def logger=(logger)
|
52
|
+
@@logger = logger
|
53
|
+
end
|
54
|
+
|
55
|
+
# set logging on or off
|
56
|
+
attr_writer :log
|
57
|
+
|
58
|
+
# Returns whether to log. Defaults to 'false'.
|
59
|
+
def log?
|
60
|
+
@log ||= false
|
61
|
+
end
|
62
|
+
|
63
|
+
def log(msg)
|
64
|
+
if log?
|
65
|
+
logger.info(msg)
|
66
|
+
logger.flush if logger.respond_to?(:flush)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end # << self
|
70
|
+
|
71
|
+
class Collection
|
72
|
+
attr_accessor :entries
|
73
|
+
|
74
|
+
# Legacy Attributes (v2)
|
75
|
+
attr_accessor :count, :current_page
|
76
|
+
|
77
|
+
# v3 Attributes
|
78
|
+
attr_accessor :start_position, :max_results, :total_count
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Intended to extend the Net::HTTP response object
|
2
|
+
# and adds support for decoding gzip and deflate encoded pages
|
3
|
+
#
|
4
|
+
# Author: Jason Stirk <http://griffin.oobleyboo.com>
|
5
|
+
# Home: http://griffin.oobleyboo.com/projects/http_encoding_helper
|
6
|
+
# Created: 5 September 2007
|
7
|
+
# Last Updated: 23 November 2007
|
8
|
+
#
|
9
|
+
# Usage:
|
10
|
+
#
|
11
|
+
# require 'net/http'
|
12
|
+
# require 'http_encoding_helper'
|
13
|
+
# headers={'Accept-Encoding' => 'gzip, deflate' }
|
14
|
+
# http = Net::HTTP.new('griffin.oobleyboo.com', 80)
|
15
|
+
# http.start do |h|
|
16
|
+
# request = Net::HTTP::Get.new('/', headers)
|
17
|
+
# response = http.request(request)
|
18
|
+
# content=response.plain_body # Method from our library
|
19
|
+
# puts "Transferred: #{response.body.length} bytes"
|
20
|
+
# puts "Compression: #{response['content-encoding']}"
|
21
|
+
# puts "Extracted: #{response.plain_body.length} bytes"
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
|
25
|
+
require 'zlib'
|
26
|
+
require 'stringio'
|
27
|
+
|
28
|
+
class Net::HTTPResponse
|
29
|
+
# Return the uncompressed content
|
30
|
+
def plain_body
|
31
|
+
encoding=self['content-encoding']
|
32
|
+
content=nil
|
33
|
+
if encoding then
|
34
|
+
case encoding
|
35
|
+
when 'gzip'
|
36
|
+
i=Zlib::GzipReader.new(StringIO.new(self.body))
|
37
|
+
content=i.read
|
38
|
+
when 'deflate'
|
39
|
+
i=Zlib::Inflate.new
|
40
|
+
content=i.inflate(self.body)
|
41
|
+
else
|
42
|
+
raise "Unknown encoding - #{encoding}"
|
43
|
+
end
|
44
|
+
else
|
45
|
+
content=self.body
|
46
|
+
end
|
47
|
+
return content
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Model
|
3
|
+
class BaseModel
|
4
|
+
include ActiveModel::Validations
|
5
|
+
include ROXML
|
6
|
+
xml_convention :camelcase
|
7
|
+
|
8
|
+
# ROXML doesnt insert the namespaces into generated XML so we need to do it ourselves
|
9
|
+
# insert the static namespaces in the first opening tag that matches the +model_name+
|
10
|
+
def to_xml_inject_ns(model_name, options = {})
|
11
|
+
s = StringIO.new
|
12
|
+
xml = to_xml(options).write_to(s, :indent => 0, :indent_text => '')
|
13
|
+
destination_name = options.fetch(:destination_name, nil)
|
14
|
+
destination_name ||= model_name
|
15
|
+
|
16
|
+
sparse = options.fetch(:sparse, false)
|
17
|
+
sparse_string = %{sparse="#{sparse}"}
|
18
|
+
step1 = s.string.sub("<#{model_name}>", "<#{destination_name} #{Quickbooks::Service::BaseService::XML_NS} #{sparse_string}>")
|
19
|
+
step2 = step1.sub("</#{model_name}>", "</#{destination_name}>")
|
20
|
+
step2
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_xml_ns(options = {})
|
24
|
+
to_xml_inject_ns(self.class::XML_NODE, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
|
29
|
+
# These can be over-ridden in each model object as needed
|
30
|
+
def resource_for_collection
|
31
|
+
self::REST_RESOURCE
|
32
|
+
end
|
33
|
+
|
34
|
+
def resource_for_singular
|
35
|
+
self::REST_RESOURCE
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# == Business Rules
|
2
|
+
# * The DisplayName, GivenName, MiddleName, FamilyName, and PrintOnCheckName attributes must not contain a colon,":".
|
3
|
+
# * The DisplayName attribute must be unique across all other customers, employees, vendors, and other names.
|
4
|
+
# * The PrimaryEmailAddress attribute must contain an at sign, "@," and dot, ".".
|
5
|
+
# * Nested customer objects can be used to define sub-customers, jobs, or a combination of both, under a parent.
|
6
|
+
# * Up to four levels of nesting can be defined under a top-level customer object.
|
7
|
+
# * The Job attribute defines whether the object is a top-level customer or nested sub-customer/job.
|
8
|
+
# * Either the DisplayName attribute or at least one of Title, GivenName, MiddleName, FamilyName, Suffix, or FullyQualifiedName attributes are required during create.
|
9
|
+
|
10
|
+
module Quickbooks
|
11
|
+
module Model
|
12
|
+
class Customer < BaseModel
|
13
|
+
XML_COLLECTION_NODE = "Customer"
|
14
|
+
XML_NODE = "Customer"
|
15
|
+
REST_RESOURCE = 'customer'
|
16
|
+
|
17
|
+
xml_name XML_NODE
|
18
|
+
xml_accessor :id, :from => 'Id', :as => Integer
|
19
|
+
xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
|
20
|
+
xml_accessor :meta_data, :from => 'MetaData', :as => Quickbooks::Model::MetaData
|
21
|
+
xml_accessor :title, :from => 'Title'
|
22
|
+
xml_accessor :given_name, :from => 'GivenName'
|
23
|
+
xml_accessor :middle_name, :from => 'MiddleName'
|
24
|
+
xml_accessor :family_name, :from => 'FamilyName'
|
25
|
+
xml_accessor :company_name, :from => 'CompanyName'
|
26
|
+
xml_accessor :display_name, :from => 'DisplayName'
|
27
|
+
xml_accessor :print_on_check_name, :from => 'PrintOnCheckName'
|
28
|
+
xml_accessor :active, :from => 'Active'
|
29
|
+
xml_accessor :primary_phone, :from => 'PrimaryPhone', :as => Quickbooks::Model::TelephoneNumber
|
30
|
+
xml_accessor :alternate_phone, :from => 'AlternatePhone', :as => Quickbooks::Model::TelephoneNumber
|
31
|
+
xml_accessor :mobile_phone, :from => 'Mobile', :as => Quickbooks::Model::TelephoneNumber
|
32
|
+
xml_accessor :fax_phone, :from => 'Fax', :as => Quickbooks::Model::TelephoneNumber
|
33
|
+
xml_accessor :primary_email_address, :from => 'PrimaryEmailAddr', :as => Quickbooks::Model::EmailAddress
|
34
|
+
xml_accessor :web_site, :from => 'WebAddr', :as => Quickbooks::Model::WebSiteAddress
|
35
|
+
xml_accessor :billing_address, :from => 'BillAddr', :as => Quickbooks::Model::PhysicalAddress
|
36
|
+
xml_accessor :shipping_address, :from => 'ShipAddr', :as => Quickbooks::Model::PhysicalAddress
|
37
|
+
xml_accessor :job, :from => 'Job'
|
38
|
+
xml_accessor :bill_with_parent, :from => 'BillWithParent'
|
39
|
+
xml_accessor :parent_ref, :from => 'ParentRef', :as => Integer
|
40
|
+
xml_accessor :level, :from => 'Level'
|
41
|
+
xml_accessor :sales_term_ref, :from => 'SalesTermRef', :as => Integer
|
42
|
+
xml_accessor :payment_method_ref, :from => 'PaymentMethodRef'
|
43
|
+
xml_accessor :balance, :from => 'Balance', :as => Float
|
44
|
+
xml_accessor :open_balance_date, :from => 'OpenBalanceDate', :as => Date
|
45
|
+
xml_accessor :balance_with_jobs, :from => 'BalanceWithJobs', :as => Float
|
46
|
+
xml_accessor :preferred_delivery_method, :from => 'PreferredDeliveryMethod'
|
47
|
+
xml_accessor :resale_num, :from => 'ResaleNum'
|
48
|
+
xml_accessor :suffix, :from => 'Suffix'
|
49
|
+
xml_accessor :fully_qualified_name, :from => 'FullyQualifiedName'
|
50
|
+
xml_accessor :taxable, :from => 'Taxable'
|
51
|
+
xml_accessor :notes, :from => 'Notes'
|
52
|
+
|
53
|
+
validate :names_cannot_contain_invalid_characters
|
54
|
+
validate :email_address_is_valid
|
55
|
+
|
56
|
+
def active?
|
57
|
+
active.to_s == 'true'
|
58
|
+
end
|
59
|
+
|
60
|
+
def job?
|
61
|
+
job.to_s == 'true'
|
62
|
+
end
|
63
|
+
|
64
|
+
def bill_with_parent?
|
65
|
+
bill_with_parent.to_s == 'true'
|
66
|
+
end
|
67
|
+
|
68
|
+
def taxable?
|
69
|
+
taxable.to_s == 'true'
|
70
|
+
end
|
71
|
+
|
72
|
+
def valid_for_update?
|
73
|
+
if sync_token.nil?
|
74
|
+
errors.add(:sync_token, "Missing required attribute SyncToken for update")
|
75
|
+
end
|
76
|
+
errors.empty?
|
77
|
+
end
|
78
|
+
|
79
|
+
def valid_for_create?
|
80
|
+
valid?
|
81
|
+
errors.empty?
|
82
|
+
end
|
83
|
+
|
84
|
+
def email_address=(email_address)
|
85
|
+
self.primary_email_address = Quickbooks::Model::EmailAddress.new(email_address)
|
86
|
+
end
|
87
|
+
|
88
|
+
def email_address
|
89
|
+
primary_email_address
|
90
|
+
end
|
91
|
+
|
92
|
+
# To delete an account Intuit requires we provide Id and SyncToken fields
|
93
|
+
def valid_for_deletion?
|
94
|
+
return false if(id.nil? || sync_token.nil?)
|
95
|
+
id.to_i > 0 && !sync_token.to_s.empty? && sync_token.to_i >= 0
|
96
|
+
end
|
97
|
+
|
98
|
+
def names_cannot_contain_invalid_characters
|
99
|
+
[:display_name, :given_name, :middle_name, :family_name, :print_on_check_name].each do |property|
|
100
|
+
value = send(property).to_s
|
101
|
+
if value.index(':')
|
102
|
+
errors.add(property, ":#{property} cannot contain a colon (:).")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def email_address_is_valid
|
108
|
+
if primary_email_address
|
109
|
+
address = primary_email_address.address
|
110
|
+
unless address.index('@') && address.index('.')
|
111
|
+
errors.add(:primary_email_address, "Email address must contain @ and . (dot)")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Model
|
3
|
+
class CustomerRef < BaseModel
|
4
|
+
xml_convention :camelcase
|
5
|
+
xml_accessor :name, :from => '@name' # Attribute with name 'name'
|
6
|
+
xml_accessor :value, :from => :content
|
7
|
+
|
8
|
+
def initialize(value = nil)
|
9
|
+
self.value = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_i
|
13
|
+
self.value.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
self.value.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Model
|
3
|
+
class DiscountOverride < BaseModel
|
4
|
+
xml_accessor :discount_ref, :from => 'DiscountRef', :as => Integer
|
5
|
+
xml_accessor :percent_based, :from => 'PercentBased'
|
6
|
+
xml_accessor :discount_percent, :from => 'DiscountPercent', :as => Float
|
7
|
+
xml_accessor :discount_account_ref, :from => 'DiscountAccountRef', :as => Integer
|
8
|
+
|
9
|
+
def percent_based?
|
10
|
+
percent_based.to_s == 'true'
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Quickbooks
|
2
|
+
module Model
|
3
|
+
class EmailAddress < BaseModel
|
4
|
+
xml_accessor :address, :from => 'Address'
|
5
|
+
|
6
|
+
def to_xml(options = {})
|
7
|
+
return "" if address.to_s.empty?
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(email_address = nil)
|
12
|
+
unless email_address.nil?
|
13
|
+
self.address = email_address
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# == Business Rules
|
2
|
+
# * An invoice must have at least one Line that describes an item.
|
3
|
+
# * An invoice must have CustomerRef populated.
|
4
|
+
# * The DocNumber attribute is populated automatically by the data service if not supplied.
|
5
|
+
# * If ShipAddr, BillAddr, or both are not provided, the appropriate customer address from Customer is used to fill those values.
|
6
|
+
# * DocNumber, if supplied, must be unique.
|
7
|
+
|
8
|
+
module Quickbooks
|
9
|
+
module Model
|
10
|
+
class Invoice < BaseModel
|
11
|
+
|
12
|
+
#== Constants
|
13
|
+
REST_RESOURCE = 'invoice'
|
14
|
+
XML_COLLECTION_NODE = "Invoice"
|
15
|
+
XML_NODE = "Invoice"
|
16
|
+
|
17
|
+
xml_accessor :id, :from => 'Id', :as => Integer
|
18
|
+
xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
|
19
|
+
xml_accessor :meta_data, :from => 'MetaData', :as => Quickbooks::Model::MetaData
|
20
|
+
xml_accessor :custom_fields, :from => 'CustomField', :as => [Quickbooks::Model::CustomField]
|
21
|
+
xml_accessor :doc_number, :from => 'DocNumber'
|
22
|
+
xml_accessor :txn_date, :from => 'TxnDate', :as => Date
|
23
|
+
xml_accessor :private_note, :from => 'PrivateNote'
|
24
|
+
xml_accessor :linked_transactions, :from => 'LinkedTxn', :as => [Quickbooks::Model::LinkedTransaction]
|
25
|
+
xml_accessor :line_items, :from => 'Line', :as => [Quickbooks::Model::InvoiceLineItem]
|
26
|
+
xml_accessor :txn_tax_detail, :from => 'TxnTaxDetail'
|
27
|
+
xml_accessor :customer_ref, :from => 'CustomerRef', :as => Quickbooks::Model::CustomerRef
|
28
|
+
xml_accessor :customer_memo, :from => 'CustomerMemo'
|
29
|
+
xml_accessor :billing_address, :from => 'BillAddr', :as => Quickbooks::Model::PhysicalAddress
|
30
|
+
xml_accessor :shipping_address, :from => 'ShipAddr', :as => Quickbooks::Model::PhysicalAddress
|
31
|
+
xml_accessor :class_ref, :from => 'ClassRef'
|
32
|
+
xml_accessor :sales_term_ref, :from => 'SalesTermRef', :as => Integer
|
33
|
+
xml_accessor :due_date, :from => 'DueDate', :as => Date
|
34
|
+
xml_accessor :ship_method_ref, :from => 'ShipMethodRef'
|
35
|
+
xml_accessor :ship_date, :from => 'ShipDate', :as => Date
|
36
|
+
xml_accessor :tracking_num, :from => 'TrackingNum'
|
37
|
+
xml_accessor :ar_account_ref, :from => 'ARAccountRef', :as => Integer
|
38
|
+
xml_accessor :total_amount, :from => 'TotalAmt', :as => Float
|
39
|
+
xml_accessor :apply_tax_after_discount, :from => 'ApplyTaxAfterDiscount'
|
40
|
+
xml_accessor :print_status, :from => 'PrintStatus'
|
41
|
+
xml_accessor :email_status, :from => 'EmailStatus'
|
42
|
+
xml_accessor :balance, :from => 'Balance', :as => Float
|
43
|
+
xml_accessor :deposit, :from => 'Deposit', :as => Float
|
44
|
+
xml_accessor :department_ref, :from => 'DepartmentRef'
|
45
|
+
xml_accessor :allow_ipn_payment, :from => 'AllowIPNPayment'
|
46
|
+
xml_accessor :allow_online_payment, :from => 'AllowOnlinePayment'
|
47
|
+
xml_accessor :allow_online_credit_card_payment, :from => 'AllowOnlineCreditCardPayment'
|
48
|
+
xml_accessor :allow_online_ach_payment, :from => 'AllowOnlineACHPayment'
|
49
|
+
|
50
|
+
#== Validations
|
51
|
+
validates_length_of :line_items, :minimum => 1
|
52
|
+
validate :existence_of_customer_ref
|
53
|
+
|
54
|
+
def initialize
|
55
|
+
ensure_line_items_initialization
|
56
|
+
super
|
57
|
+
end
|
58
|
+
|
59
|
+
def apply_tax_after_discount?
|
60
|
+
apply_tax_after_discount.to_s == 'true'
|
61
|
+
end
|
62
|
+
|
63
|
+
def allow_ipn_payment?
|
64
|
+
allow_ipn_payment.to_s == 'true'
|
65
|
+
end
|
66
|
+
|
67
|
+
def allow_online_payment?
|
68
|
+
allow_online_payment.to_s == 'true'
|
69
|
+
end
|
70
|
+
|
71
|
+
def allow_online_credit_card_payment?
|
72
|
+
allow_online_credit_card_payment.to_s == 'true'
|
73
|
+
end
|
74
|
+
|
75
|
+
def allow_online_ach_payment?
|
76
|
+
allow_online_ach_payment.to_s == 'true'
|
77
|
+
end
|
78
|
+
|
79
|
+
def customer_id=(customer_id)
|
80
|
+
self.customer_ref = Quickbooks::Model::CustomerRef.new(customer_id)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def existence_of_customer_ref
|
86
|
+
if customer_ref.nil? || (customer_ref && customer_ref.value == 0)
|
87
|
+
errors.add(:customer_ref, "CustomerRef is required and must be a non-zero value.")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def ensure_line_items_initialization
|
92
|
+
self.line_items ||= []
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|