quickbooks-ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|