├── .rspec
├── .gemrelease
├── lib
└── quickbooks
│ ├── version.rb
│ ├── model
│ ├── description_line_detail.rb
│ ├── entity_ref.rb
│ ├── line_ex.rb
│ ├── name_value.rb
│ ├── item_group_detail.rb
│ ├── other_contact_info.rb
│ ├── item_change.rb
│ ├── delivery_info.rb
│ ├── vendor_change.rb
│ ├── customer_change.rb
│ ├── payment_change.rb
│ ├── validator.rb
│ ├── credit_memo_change.rb
│ ├── linked_transaction.rb
│ ├── refund_receipt_change.rb
│ ├── invoice_change.rb
│ ├── has_line_items.rb
│ ├── bill_payment_credit_card.rb
│ ├── telephone_number.rb
│ ├── sales_tax_rate_list.rb
│ ├── purchase_tax_rate_list.rb
│ ├── entity.rb
│ ├── web_site_address.rb
│ ├── change_model.rb
│ ├── check_payment.rb
│ ├── base_model_json.rb
│ ├── item_group_line.rb
│ ├── transaction_tax_detail.rb
│ ├── email_address.rb
│ ├── group_line_detail.rb
│ ├── fault.rb
│ ├── bill_payment_check.rb
│ ├── effective_tax_rate.rb
│ ├── global_tax_calculation.rb
│ ├── document_numbering.rb
│ ├── markup_info.rb
│ ├── tax_rate_detail.rb
│ ├── payment_line_detail.rb
│ ├── invoice_group_line_detail.rb
│ ├── custom_field.rb
│ ├── tax_line.rb
│ ├── discount_override.rb
│ ├── budget_line_item.rb
│ ├── attachable_ref.rb
│ ├── sub_total_line_detail.rb
│ ├── base_reference.rb
│ ├── company_currency.rb
│ ├── tax_agency.rb
│ ├── meta_data.rb
│ ├── account_based_expense_line_detail.rb
│ ├── deposit_line_detail.rb
│ ├── bill_payment_line_item.rb
│ ├── credit_card_payment.rb
│ ├── tax_line_detail.rb
│ ├── discount_line_detail.rb
│ ├── tax_code.rb
│ ├── budget.rb
│ ├── sales_item_line_detail.rb
│ ├── transfer.rb
│ ├── payment_method.rb
│ ├── exchange_rate.rb
│ ├── class.rb
│ ├── attachable.rb
│ ├── access_token_response.rb
│ ├── department.rb
│ ├── definition.rb
│ ├── item_based_expense_line_detail.rb
│ ├── physical_address.rb
│ ├── deposit_line_item.rb
│ ├── tax_rate.rb
│ ├── term.rb
│ ├── tax_rate_detail_line.rb
│ ├── upload.rb
│ ├── journal_entry_line_detail.rb
│ ├── change_data_capture.rb
│ └── report.rb
│ ├── service
│ ├── budget.rb
│ ├── tax_code.rb
│ ├── tax_rate.rb
│ ├── tax_agency.rb
│ ├── attachable.rb
│ ├── tax_service.rb
│ ├── company_info.rb
│ ├── item_change.rb
│ ├── invoice_change.rb
│ ├── payment_change.rb
│ ├── vendor_change.rb
│ ├── bill.rb
│ ├── customer_change.rb
│ ├── deposit.rb
│ ├── transfer.rb
│ ├── credit_memo_change.rb
│ ├── purchase.rb
│ ├── journal_entry.rb
│ ├── refund_receipt_change.rb
│ ├── credit_memo.rb
│ ├── term.rb
│ ├── bill_payment.rb
│ ├── time_activity.rb
│ ├── purchase_order.rb
│ ├── refund_receipt.rb
│ ├── vendor_credit.rb
│ ├── account.rb
│ ├── customer.rb
│ ├── batch.rb
│ ├── company_currency.rb
│ ├── preferences.rb
│ ├── estimate.rb
│ ├── class.rb
│ ├── department.rb
│ ├── vendor.rb
│ ├── change_service.rb
│ ├── employee.rb
│ ├── change_data_capture.rb
│ ├── exchange_rate.rb
│ ├── payment.rb
│ ├── service_crud_json.rb
│ ├── payment_method.rb
│ ├── item.rb
│ ├── upload.rb
│ ├── reports.rb
│ ├── base_service_json.rb
│ ├── access_token.rb
│ └── invoice.rb
│ └── util
│ ├── logging.rb
│ ├── collection.rb
│ └── query_builder.rb
├── Gemfile
├── spec
├── fixtures
│ ├── monkey.jpg
│ ├── custom_field_date.xml
│ ├── custom_field_string.xml
│ ├── custom_field_number.xml
│ ├── item_change.xml
│ ├── invoice_change.xml
│ ├── vendor_change.xml
│ ├── customer_change.xml
│ ├── payment_change.xml
│ ├── credit_memo_change.xml
│ ├── refund_receipt_change.xml
│ ├── item_delete_success_response.xml
│ ├── invoice_delete_success_response.xml
│ ├── deposit_delete_success_response.xml
│ ├── payment_delete_success_response.xml
│ ├── bill_payment_delete_success_response.xml
│ ├── deleted_time_activity.xml
│ ├── tax_rate_detail_line.xml
│ ├── disconnect_200.xml
│ ├── query_validation_error.xml
│ ├── disconnect_270.xml
│ ├── access_token_24.xml
│ ├── access_token_270.xml
│ ├── access_token_212.xml
│ ├── tax_service.xml
│ ├── throttle_exceeded_error.xml
│ ├── company_currency.xml
│ ├── generic_error.xml
│ ├── class.xml
│ ├── fault.xml
│ ├── json
│ │ └── tax_service_error_dup.json
│ ├── tax_agency.xml
│ ├── too_many_requests_error.xml
│ ├── attachable_create_response.xml
│ ├── item_changes.xml
│ ├── vendor_changes.xml
│ ├── invoice_changes.xml
│ ├── customer_changes.xml
│ ├── exchange_rate.xml
│ ├── payment_changes.xml
│ ├── department.xml
│ ├── credit_memo_changes.xml
│ ├── access_token_200.xml
│ ├── refund_receipt_changes.xml
│ ├── exchange_rate_by_currency.xml
│ ├── invoice_sparse_create_request.xml
│ ├── customer_duplicate_error.xml
│ ├── fetch_payment_method_by_id.xml
│ ├── deleted_payment_method.xml
│ ├── deleted_company_currency.xml
│ ├── fetch_company_currency_by_id.xml
│ ├── term.xml
│ ├── fetch_class_by_id.xml
│ ├── tax_service_entity.xml
│ ├── deleted_class.xml
│ ├── transfer.xml
│ ├── payment.xml
│ ├── company_currency_query.xml
│ ├── tax_agency_entity.xml
│ ├── item.xml
│ ├── fetch_payment_method_by_name.xml
│ ├── fetch_department_by_id.xml
│ ├── deleted_department.xml
│ ├── bill_payment_check_response.xml
│ ├── tax_agencies.xml
│ ├── exchange_rates.xml
│ ├── payment_void_response_success.xml
│ ├── terms.xml
│ ├── fetch_term_by_id.xml
│ ├── fetch_payment_by_id.xml
│ ├── term_delete_success_response.xml
│ ├── fetch_item_by_id.xml
│ ├── bill_payment_cc_response.xml
│ ├── tax_rate.xml
│ ├── time_activity.xml
│ ├── tax_rates.xml
│ ├── transfers.xml
│ ├── fetch_bill_payment_by_id.xml
│ ├── term_by_id.xml
│ ├── fetch_time_activity_by_id.xml
│ ├── payments.xml
│ ├── payment_by_id.xml
│ ├── fetch_account_by_id.xml
│ ├── tax_code.xml
│ ├── bill_payments.xml
│ ├── bill_line_item_expense.xml
│ ├── upload_create_response.xml
│ ├── vendor_credit.xml
│ ├── purchase_create.xml
│ ├── fetch_deposit_by_id.xml
│ ├── purchase_credit_card_response.xml
│ ├── attachables.xml
│ ├── deposit.xml
│ ├── payment_with_line_extras.xml
│ ├── employee.xml
│ ├── bill_create_request.xml
│ ├── sales_receipt.xml
│ ├── fetch_employee_by_id.xml
│ ├── deleted_employee.xml
│ └── items.xml
├── lib
│ ├── quickbooks_spec.rb
│ └── quickbooks
│ │ ├── model
│ │ ├── telephone_number_spec.rb
│ │ ├── item_change_spec.rb
│ │ ├── vendor_change_spec.rb
│ │ ├── invoice_change_spec.rb
│ │ ├── payment_change_spec.rb
│ │ ├── customer_change_spec.rb
│ │ ├── credit_memo_change_spec.rb
│ │ ├── sales_line_item_detail_spec.rb
│ │ ├── exchange_rate_spec.rb
│ │ ├── refund_receipt_change_spec.rb
│ │ ├── company_currency_spec.rb
│ │ ├── payment_method_spec.rb
│ │ ├── access_token_response_spec.rb
│ │ ├── tax_rate_spec.rb
│ │ ├── tax_agency_spec.rb
│ │ ├── budget_spec.rb
│ │ ├── fault_spec.rb
│ │ ├── preferences_spec.rb
│ │ ├── class_spec.rb
│ │ ├── transaction_tax_detail_spec.rb
│ │ ├── custom_field_spec.rb
│ │ ├── department_spec.rb
│ │ ├── transfer_spec.rb
│ │ ├── time_activity_spec.rb
│ │ ├── tax_code_spec.rb
│ │ ├── account_spec.rb
│ │ └── term_spec.rb
│ │ ├── service
│ │ ├── tax_code_spec.rb
│ │ ├── tax_rate_spec.rb
│ │ ├── purchase_order_spec.rb
│ │ ├── transfer_spec.rb
│ │ ├── preferences_spec.rb
│ │ ├── base_service_json_spec.rb
│ │ ├── budget_spec.rb
│ │ ├── item_change_spec.rb
│ │ ├── upload_spec.rb
│ │ ├── vendor_change_spec.rb
│ │ ├── invoice_change_spec.rb
│ │ ├── payment_change_spec.rb
│ │ ├── customer_change_spec.rb
│ │ ├── company_info_spec.rb
│ │ ├── credit_memo_change_spec.rb
│ │ ├── refund_receipt_change_spec.rb
│ │ ├── account_spec.rb
│ │ ├── purchase_spec.rb
│ │ ├── exchange_rate_spec.rb
│ │ ├── batch_spec.rb
│ │ ├── attachable_spec.rb
│ │ └── tax_agency_spec.rb
│ │ └── util
│ │ ├── collection_spec.rb
│ │ └── query_builder_spec.rb
├── support
│ ├── fixture_helpers.rb
│ ├── net_helpers.rb
│ └── oauth_helpers.rb
└── spec_helper.rb
├── .gitignore
├── RELEASE.md
├── .travis.yml
├── Rakefile
├── quickbooks-ruby.gemspec
├── LICENSE.txt
└── webapp
└── .env
/.rspec:
--------------------------------------------------------------------------------
1 | --require spec_helper
2 |
--------------------------------------------------------------------------------
/.gemrelease:
--------------------------------------------------------------------------------
1 | bump:
2 | tag: true
3 |
--------------------------------------------------------------------------------
/lib/quickbooks/version.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 |
3 | VERSION = "0.6.4"
4 |
5 | end
6 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'http://rubygems.org'
2 |
3 | ruby RUBY_VERSION
4 |
5 | gem 'pry'
6 |
7 | gemspec
8 |
--------------------------------------------------------------------------------
/spec/fixtures/monkey.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DV/quickbooks-ruby/master/spec/fixtures/monkey.jpg
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | tmp/
2 | coverage/
3 | quickbooks-ruby-*.gem
4 |
5 | Gemfile.lock
6 |
7 | .ruby-version
8 | .ruby-gemset
9 | .bundle
10 | .idea
11 |
--------------------------------------------------------------------------------
/spec/fixtures/custom_field_date.xml:
--------------------------------------------------------------------------------
1 |
2 | LastUpdated
3 | DateType
4 | 2013-04-04
5 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/description_line_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class DescriptionLineDetail < BaseModel
4 |
5 | end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/spec/fixtures/custom_field_string.xml:
--------------------------------------------------------------------------------
1 |
2 | SalesAssociate
3 | StringType
4 | Miller
5 |
--------------------------------------------------------------------------------
/spec/fixtures/custom_field_number.xml:
--------------------------------------------------------------------------------
1 |
2 | NumberOfWatermelons
3 | NumberType
4 | 43
5 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks_spec.rb:
--------------------------------------------------------------------------------
1 | describe Quickbooks do
2 |
3 | describe "VERSION" do
4 | subject { Quickbooks::VERSION }
5 | it { should be_a String }
6 | end
7 |
8 | end
9 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/entity_ref.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class EntityRef < BaseModel
4 | xml_accessor :type
5 | xml_accessor :value
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/spec/fixtures/item_change.xml:
--------------------------------------------------------------------------------
1 | -
2 | 39
3 |
4 | 2014-12-08T19:36:24-08:00
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/invoice_change.xml:
--------------------------------------------------------------------------------
1 |
2 | 39
3 |
4 | 2014-12-08T19:36:24-08:00
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/vendor_change.xml:
--------------------------------------------------------------------------------
1 |
2 | 39
3 |
4 | 2014-12-08T19:36:24-08:00
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/customer_change.xml:
--------------------------------------------------------------------------------
1 |
2 | 39
3 |
4 | 2014-12-08T19:36:24-08:00
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/payment_change.xml:
--------------------------------------------------------------------------------
1 |
2 | 39
3 |
4 | 2014-12-08T19:36:24-08:00
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/credit_memo_change.xml:
--------------------------------------------------------------------------------
1 |
2 | 39
3 |
4 | 2014-12-08T19:36:24-08:00
5 |
6 |
7 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/line_ex.rb:
--------------------------------------------------------------------------------
1 |
2 | module Quickbooks
3 | module Model
4 | class LineEx < BaseModel
5 |
6 | xml_accessor :name_values, :from => "NameValue", :as => [NameValue]
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/fixtures/refund_receipt_change.xml:
--------------------------------------------------------------------------------
1 |
2 | 40
3 |
4 | 2014-12-09T19:30:24-08:00
5 |
6 |
7 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/name_value.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class NameValue < BaseModel
4 | xml_accessor :name, :from => "Name"
5 | xml_accessor :value, :from => "Value"
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/spec/fixtures/item_delete_success_response.xml:
--------------------------------------------------------------------------------
1 |
2 | -
3 | 2
4 |
5 |
--------------------------------------------------------------------------------
/spec/fixtures/invoice_delete_success_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1
4 |
5 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/budget.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Budget < BaseService
4 |
5 | private
6 |
7 | def model
8 | Quickbooks::Model::Budget
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/fixtures/deposit_delete_success_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 148
4 |
5 |
--------------------------------------------------------------------------------
/spec/fixtures/payment_delete_success_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 8748
4 |
5 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/tax_code.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class TaxCode < BaseService
4 |
5 | private
6 |
7 | def model
8 | Quickbooks::Model::TaxCode
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/tax_rate.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class TaxRate < BaseService
4 |
5 | private
6 |
7 | def model
8 | Quickbooks::Model::TaxRate
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/tax_agency.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class TaxAgency < BaseService
4 |
5 | private
6 |
7 | def model
8 | Quickbooks::Model::TaxAgency
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/attachable.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Attachable < BaseService
4 |
5 | private
6 |
7 | def model
8 | Quickbooks::Model::Attachable
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/tax_service.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class TaxService < BaseServiceJSON
4 | private
5 |
6 | def model
7 | Quickbooks::Model::TaxService
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/item_group_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class ItemGroupDetail < BaseModel
4 | include HasLineItems
5 |
6 | xml_accessor :line_items, :from => 'ItemGroupLine', :as => [ItemGroupLine]
7 | end
8 | end
9 | end
--------------------------------------------------------------------------------
/spec/fixtures/bill_payment_delete_success_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 623
4 |
5 |
6 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/company_info.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class CompanyInfo < BaseService
4 |
5 | private
6 |
7 | def model
8 | Quickbooks::Model::CompanyInfo
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/other_contact_info.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class OtherContactInfo < BaseModel
4 | xml_accessor :type, :from => 'Type'
5 | xml_accessor :telephone, :from => 'Telephone', :as => TelephoneNumber
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/item_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | # Refer to: https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/change_data_capture
4 | class ItemChange < ChangeModel
5 | XML_NODE = "Item"
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/delivery_info.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class DeliveryInfo < BaseModel
4 | xml_accessor :delivery_type, :from => 'DeliveryType'
5 | xml_accessor :delivery_time, :from => 'DeliveryTime', :as => DateTime
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/vendor_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | # Refer to: https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/change_data_capture
4 | class VendorChange < ChangeModel
5 | XML_NODE = "Vendor"
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/customer_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | # Refer to: https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/change_data_capture
4 | class CustomerChange < ChangeModel
5 | XML_NODE = "Customer"
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/payment_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | # Refer to: https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/change_data_capture
4 | class PaymentChange < ChangeModel
5 | XML_NODE = "Payment"
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/validator.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | module Validator
4 |
5 | def line_item_size
6 | validates_length_of :line_items, :minimum => 1, :message => 'At least 1 line item is required'
7 | end
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/spec/fixtures/deleted_time_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1
4 | Description
5 |
6 |
7 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/credit_memo_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | # Refer to: https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/change_data_capture
4 | class CreditMemoChange < ChangeModel
5 | XML_NODE = "CreditMemo"
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/linked_transaction.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class LinkedTransaction < BaseModel
4 | xml_accessor :txn_id, :from => 'TxnId'
5 | xml_accessor :txn_type, :from => 'TxnType'
6 | xml_accessor :txn_line_id, :from => 'TxnLineId'
7 | end
8 | end
9 | end
--------------------------------------------------------------------------------
/lib/quickbooks/model/refund_receipt_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | # Refer to: https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/change_data_capture
4 | class RefundReceiptChange < ChangeModel
5 | XML_NODE = "RefundReceipt"
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/spec/fixtures/tax_rate_detail_line.xml:
--------------------------------------------------------------------------------
1 |
2 | 1
3 | Rate Detail Line Spec
4 | 3.5
5 | 2
6 | Sales
7 |
8 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/invoice_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | # Refer to:
4 | # - https://developer.intuit.com/docs/0100_quickbooks_online/0200_dev_guides/accounting/change_data_capture
5 | class InvoiceChange < ChangeModel
6 | XML_NODE = "Invoice"
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/telephone_number_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::TelephoneNumber" do
2 |
3 | it "can be initialized with a number" do
4 | number = "415-555-1212"
5 | tel = Quickbooks::Model::TelephoneNumber.new(number)
6 | tel.free_form_number.should == number
7 | end
8 |
9 | end
10 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/item_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class ItemChange < ChangeService
4 |
5 | private
6 |
7 | def entity
8 | "Item"
9 | end
10 |
11 | def model
12 | Quickbooks::Model::ItemChange
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/spec/fixtures/disconnect_200.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 0
4 | 2011-11-23T17:15:27.21097Z
5 |
6 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/invoice_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class InvoiceChange < ChangeService
4 |
5 | private
6 |
7 | def entity
8 | "Invoice"
9 | end
10 |
11 | def model
12 | Quickbooks::Model::InvoiceChange
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/payment_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class PaymentChange < ChangeService
4 |
5 | private
6 |
7 | def entity
8 | "Payment"
9 | end
10 |
11 | def model
12 | Quickbooks::Model::PaymentChange
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/vendor_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class VendorChange < ChangeService
4 |
5 | private
6 |
7 | def entity
8 | "Vendor"
9 | end
10 |
11 | def model
12 | Quickbooks::Model::VendorChange
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/RELEASE.md:
--------------------------------------------------------------------------------
1 | ## How to Release
2 |
3 | * Bump version number in `lib/quickbooks/version.rb`
4 | * Document changes in `HISTORY.md`
5 | * Run `gem release quickbooks-ruby.gemspec` -- requires the `gem-release` gem
6 |
7 | * Tag the release
8 | $ git tag -a v0.5.0 -m "0.5.0"
9 |
10 | * Push with tags
11 | git push origin --tags
12 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/bill.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Bill < BaseService
4 |
5 | def delete(bill)
6 | delete_by_query_string(bill)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::Bill
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/customer_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class CustomerChange < ChangeService
4 |
5 | private
6 |
7 | def entity
8 | "Customer"
9 | end
10 |
11 | def model
12 | Quickbooks::Model::CustomerChange
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 | rvm:
3 | - 1.9.3
4 | - 2.0.0
5 | - 2.1.0
6 | - 2.2.0
7 | # Bundler 1.13 added support for `ruby RUBY_VERSION` in the Gemfile
8 | before_install: gem install bundler -v '>= 1.13.0'
9 |
10 | sudo: false
11 | notifications:
12 | email:
13 | - toolbag@gmail.com
14 | - christian@minimul.com
15 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/deposit.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Deposit < BaseService
4 |
5 | def delete(payment)
6 | delete_by_query_string(payment)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::Deposit
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/transfer.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Transfer < BaseService
4 |
5 | def delete(transfer)
6 | delete_by_query_string(transfer)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::Transfer
13 | end
14 | end
15 | end
16 | end
--------------------------------------------------------------------------------
/lib/quickbooks/service/credit_memo_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class CreditMemoChange < ChangeService
4 |
5 | private
6 |
7 | def entity
8 | "CreditMemo"
9 | end
10 |
11 | def model
12 | Quickbooks::Model::CreditMemoChange
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/purchase.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Purchase < BaseService
4 |
5 | def delete(purchase)
6 | delete_by_query_string(purchase)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::Purchase
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/has_line_items.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | module HasLineItems
4 | def initialize(*args)
5 | ensure_line_items_initialization
6 | super
7 | end
8 |
9 | def ensure_line_items_initialization
10 | self.line_items ||= []
11 | end
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/journal_entry.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class JournalEntry < BaseService
4 |
5 | def delete(entry)
6 | delete_by_query_string(entry)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::JournalEntry
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/refund_receipt_change.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class RefundReceiptChange < ChangeService
4 |
5 | private
6 |
7 | def entity
8 | "RefundReceipt"
9 | end
10 |
11 | def model
12 | Quickbooks::Model::RefundReceiptChange
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/credit_memo.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class CreditMemo < BaseService
4 |
5 | def delete(credit_memo)
6 | delete_by_query_string(credit_memo)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::CreditMemo
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/term.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Term < BaseService
4 |
5 | def delete(term)
6 | term.active = false
7 | update(term, :sparse => true)
8 | end
9 |
10 | private
11 |
12 | def model
13 | Quickbooks::Model::Term
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/bill_payment_credit_card.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class BillPaymentCreditCard < BaseModel
4 | xml_accessor :cc_account_ref, :from => 'CCAccountRef', :as => BaseReference
5 | xml_accessor :cc_detail, :from => 'CCDetail', :as => CreditCardPayment
6 |
7 | reference_setters
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/bill_payment.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class BillPayment < BaseService
4 |
5 | def delete(bill_payment)
6 | delete_by_query_string(bill_payment)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::BillPayment
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/time_activity.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class TimeActivity < BaseService
4 |
5 | def delete(time_activity)
6 | delete_by_query_string(time_activity)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::TimeActivity
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/spec/fixtures/query_validation_error.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Invalid query
5 | QueryValidationError: value 0 is too small. Min allowed value is 1
6 |
7 |
8 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/telephone_number.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class TelephoneNumber < BaseModel
4 | xml_accessor :free_form_number, :from => 'FreeFormNumber'
5 |
6 | def initialize(number = nil)
7 | unless number.nil?
8 | self.free_form_number = number
9 | end
10 | end
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/purchase_order.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class PurchaseOrder < BaseService
4 |
5 | def delete(purchase_order)
6 | delete_by_query_string(purchase_order)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::PurchaseOrder
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/refund_receipt.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class RefundReceipt < BaseService
4 |
5 | def delete(refund_receipt)
6 | delete_by_query_string(refund_receipt)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::RefundReceipt
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/vendor_credit.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class VendorCredit < BaseService
4 |
5 | def delete(vendor_credit)
6 | delete_by_query_string(vendor_credit)
7 | end
8 |
9 | private
10 |
11 | def model
12 | Quickbooks::Model::VendorCredit
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/account.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Account < BaseService
4 |
5 | def delete(account)
6 | account.active = false
7 | update(account, :sparse => true)
8 | end
9 |
10 | private
11 |
12 | def model
13 | Quickbooks::Model::Account
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/fixtures/disconnect_270.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | OAuth Token rejected
4 | 270
5 | 2011-11-24T17:45:27.11097Z
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/access_token_24.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Invalid App Token
4 | 24
5 | 2012-01-04T19:21:21.0782072Z
6 |
7 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/sales_tax_rate_list.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class SalesTaxRateList < BaseModel
4 | XML_COLLECTION_NODE = "SalesTaxRateList"
5 | XML_NODE = "SalesTaxRateList"
6 | REST_RESOURCE = "salestaxratelist"
7 |
8 | xml_accessor :tax_rate_detail, :from => "TaxRateDetail", :as => [TaxRateDetail]
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/customer.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Customer < BaseService
4 |
5 | def delete(customer)
6 | customer.active = false
7 | update(customer, :sparse => true)
8 | end
9 |
10 | private
11 |
12 | def model
13 | Quickbooks::Model::Customer
14 | end
15 |
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/spec/fixtures/access_token_270.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | OAuth Token Rejected
4 | 270
5 | 2012-01-04T19:21:21.0782072Z
6 |
7 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/batch.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Batch < BaseService
4 |
5 | def make_request(entity, options = {})
6 | response = do_http_post(url_for_resource('batch'), valid_xml_document(entity.to_xml_ns), options[:query])
7 | Quickbooks::Model::BatchResponse.from_xml(response.plain_body)
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/fixtures/access_token_212.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Token Refresh Window Out of Bounds
4 | 212
5 | 2012-01-04T19:21:21.0782072Z
6 |
7 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/purchase_tax_rate_list.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class PurchaseTaxRateList < BaseModel
4 | XML_COLLECTION_NODE = "PurchaseTaxRateList"
5 | XML_NODE = "PurchaseTaxRateList"
6 | REST_RESOURCE = "purchasetaxratelist"
7 |
8 | xml_accessor :tax_rate_detail, :from => "TaxRateDetail", :as => [TaxRateDetail]
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/fixtures/tax_service.xml:
--------------------------------------------------------------------------------
1 |
2 | Rate Spec
3 | 1
4 |
5 | 1
6 | Rate Spec
7 | 3.5
8 | 2
9 | Sales
10 |
11 |
12 |
--------------------------------------------------------------------------------
/spec/fixtures/throttle_exceeded_error.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | message=ThrottleExceeded; errorCode=003001; statusCode=403
5 | The request limit was reached. Try again later
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/entity.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class Entity < BaseModel
4 | include NameEntity::Quality
5 |
6 | xml_accessor :type, :from => 'Type'
7 | xml_accessor :entity_ref, :as => BaseReference
8 |
9 | reference_setters :entity_ref
10 |
11 | #== Validations
12 | validate :entity_type_is_valid
13 |
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/web_site_address.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class WebSiteAddress < BaseModel
4 | xml_accessor :uri, :from => 'URI'
5 |
6 | def initialize(uri = nil)
7 | self.uri = uri if uri
8 | end
9 |
10 | def to_xml(options = {})
11 | return "" if uri.to_s.empty?
12 | super(options)
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/change_model.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | # Refer to: https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/change_data_capture
4 | class ChangeModel < BaseModel
5 | xml_accessor :id, :from => 'Id'
6 | xml_accessor :status, :from => '@status'
7 | xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/spec/fixtures/company_currency.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1
4 | 3
5 |
6 | 2013-04-20T10:32:18-07:00
7 | 2013-07-11T08:27:06-07:00
8 |
9 | Euro
10 | EUR
11 | true
12 |
13 |
--------------------------------------------------------------------------------
/spec/fixtures/generic_error.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | An application error has occurred while processing your request
5 | System Failure Error: Could not find resource for relative : some more info here
6 |
7 |
8 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/check_payment.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class CheckPayment < BaseModel
4 | xml_accessor :check_number, :from => 'CheckNum'
5 | xml_accessor :status, :from => 'Status'
6 | xml_accessor :name_on_account, :from => 'NameOnAcct'
7 | xml_accessor :account_number, :from => 'AcctNum'
8 | xml_accessor :bank_name, :from => 'BankName'
9 | end
10 | end
11 | end
--------------------------------------------------------------------------------
/spec/fixtures/class.xml:
--------------------------------------------------------------------------------
1 |
2 | 1
3 | 1
4 |
5 | 2014-04-16T05:40:25-07:00
6 | 2014-04-16T05:40:25-07:00
7 |
8 | Design
9 | false
10 | Design
11 | true
12 |
13 |
--------------------------------------------------------------------------------
/spec/fixtures/fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Length exceeds limit
4 | Length of the field exceeds 21 chars
5 |
6 |
7 | Illegal number format
8 | ZipCode should be a number with at least 5 digits
9 |
10 |
11 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/company_currency.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class CompanyCurrency < BaseService
4 |
5 | def delete(company_currency)
6 | company_currency.active = false
7 | update(company_currency, :sparse => true)
8 | end
9 |
10 | private
11 |
12 | def model
13 | Quickbooks::Model::CompanyCurrency
14 | end
15 |
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/spec/fixtures/json/tax_service_error_dup.json:
--------------------------------------------------------------------------------
1 | {
2 | "Fault": {
3 | "Error": [
4 | {
5 | "Message": "Duplicate Name Exists Error",
6 | "Detail": "The name supplied already exists. : Another tax rate is already using this \nname. Please use a different name.",
7 | "code": "6240",
8 | "element": ""
9 | }
10 | ],
11 | "type": "ValidationFault"
12 | },
13 | "time": "2015-08-07T05:35:56.791-07:00"
14 | }
15 |
--------------------------------------------------------------------------------
/spec/support/fixture_helpers.rb:
--------------------------------------------------------------------------------
1 | module FixtureHelpers
2 | def fixture_path
3 | File.expand_path("../../fixtures", __FILE__)
4 | end
5 |
6 | def fixture(file)
7 | File.new(fixture_path + '/' + file).read
8 | end
9 |
10 | def json_fixture(file)
11 | File.new("#{fixture_path}/json/#{file.to_s}.json").read
12 | end
13 |
14 | end
15 |
16 | RSpec.configure do |config|
17 | config.include(FixtureHelpers)
18 | end
19 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/base_model_json.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class BaseModelJSON < BaseModel
4 |
5 | def to_json
6 | params = {}
7 | attributes.each_pair do |k, v|
8 | next if v.blank?
9 | params[k.camelize] = v.is_a?(Array) ? v.inject([]){|mem, item| mem << item.to_json; mem} : v
10 | end
11 | params.to_json
12 | end
13 |
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/util/logging.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Util
3 | module Logging
4 | def log(msg)
5 | ::Quickbooks.log(msg)
6 | end
7 |
8 | def log_xml(str)
9 | if ::Quickbooks.log_xml_pretty_print? && !(str and str.empty?)
10 | Nokogiri::XML(str).to_xml
11 | else
12 | str
13 | end
14 | rescue => e
15 | e
16 | end
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/spec/fixtures/tax_agency.xml:
--------------------------------------------------------------------------------
1 |
2 | 1
3 | 0
4 |
5 | 2013-12-11T10:59:51-08:00
6 | 2013-12-11T10:59:51-08:00
7 |
8 | First TaxAgency
9 | false
10 | true
11 |
12 |
--------------------------------------------------------------------------------
/lib/quickbooks/util/collection.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | class Collection
3 | include Enumerable
4 | attr_accessor :entries
5 |
6 | attr_accessor :body
7 |
8 | # Legacy Attributes (v2)
9 | attr_accessor :count, :current_page
10 |
11 | # v3 Attributes
12 | attr_accessor :start_position, :max_results, :total_count
13 |
14 | def each(*args, &block)
15 | (entries|| []).each *args, &block
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/spec/fixtures/too_many_requests_error.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | message=ThrottleExceeded; errorCode=003001; statusCode=429
6 | The request limit was reached. Try again later
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/item_change_spec.rb:
--------------------------------------------------------------------------------
1 | require 'nokogiri'
2 |
3 | describe "Quickbooks::Model::ItemChange" do
4 | it "parse from XML" do
5 | xml = fixture("item_change.xml")
6 | item = Quickbooks::Model::ItemChange.from_xml(xml)
7 | item.status.should == 'Deleted'
8 | item.id.should == "39"
9 |
10 | item.meta_data.should_not be_nil
11 | item.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
12 | end
13 | end
--------------------------------------------------------------------------------
/lib/quickbooks/model/item_group_line.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class ItemGroupLine < BaseModel
4 | xml_accessor :item_ref, :from => 'ItemRef', :as => BaseReference
5 | xml_accessor :quantity, :from => 'Qty'
6 |
7 | def id
8 | item_ref.value.to_i
9 | end
10 |
11 | def name
12 | item_ref.name
13 | end
14 |
15 | def type
16 | item_ref.type
17 | end
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/spec/fixtures/attachable_create_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2700000000002413265
4 | 0
5 |
6 | 2015-02-07T15:12:13-08:00
7 | 2015-02-07T15:12:13-08:00
8 |
9 | A note
10 |
11 |
--------------------------------------------------------------------------------
/spec/fixtures/item_changes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 | 39
6 |
7 | 2014-12-08T19:36:24-08:00
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/transaction_tax_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class TransactionTaxDetail < BaseModel
4 |
5 | xml_accessor :txn_tax_code_ref, :from => 'TxnTaxCodeRef', :as => BaseReference
6 | xml_accessor :total_tax, :from => 'TotalTax', :as => BigDecimal, :to_xml => to_xml_big_decimal
7 | xml_accessor :lines, :from => 'TaxLine', :as => [TaxLine]
8 |
9 | reference_setters :txn_tax_code_ref
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/fixtures/vendor_changes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 39
6 |
7 | 2014-12-08T19:36:24-08:00
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/email_address.rb:
--------------------------------------------------------------------------------
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
20 |
--------------------------------------------------------------------------------
/spec/fixtures/invoice_changes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 39
6 |
7 | 2014-12-08T19:36:24-08:00
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/spec/fixtures/customer_changes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 39
6 |
7 | 2014-12-08T19:36:24-08:00
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/spec/fixtures/exchange_rate.xml:
--------------------------------------------------------------------------------
1 |
2 | 9
3 | 0
4 |
5 | 2013-12-11T10:59:51-08:00
6 | 2013-12-11T10:59:51-08:00
7 |
8 | EUR
9 | USD
10 | 2.5
11 | 2015-07-07
12 |
13 |
--------------------------------------------------------------------------------
/spec/fixtures/payment_changes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 39
6 |
7 | 2014-12-08T19:36:24-08:00
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/vendor_change_spec.rb:
--------------------------------------------------------------------------------
1 | require 'nokogiri'
2 |
3 | describe "Quickbooks::Model::VendorChange" do
4 | it "parse from XML" do
5 | xml = fixture("vendor_change.xml")
6 | vendor = Quickbooks::Model::VendorChange.from_xml(xml)
7 | vendor.status.should == 'Deleted'
8 | vendor.id.should == "39"
9 |
10 | vendor.meta_data.should_not be_nil
11 | vendor.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
12 | end
13 | end
--------------------------------------------------------------------------------
/lib/quickbooks/model/group_line_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class GroupLineDetail < BaseModel
4 | include HasLineItems
5 |
6 | xml_accessor :group_item_ref, :from => 'CustomerRef', :as => BaseReference
7 | xml_accessor :quantity, :from => 'Quantity', :as => BigDecimal, :to_xml => to_xml_big_decimal
8 | xml_accessor :line_items, :from => 'Line', :as => [Line]
9 |
10 | reference_setters :group_item_ref
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/fixtures/department.xml:
--------------------------------------------------------------------------------
1 |
2 | 1
3 | 0
4 |
5 | 2013-08-13T11:49:31-07:00
6 | 2013-08-13T11:49:31-07:00
7 |
8 | Sales Department
9 | false
10 | Sales Department
11 | true
12 |
13 |
--------------------------------------------------------------------------------
/spec/fixtures/credit_memo_changes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 39
6 |
7 | 2014-12-08T19:36:24-08:00
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/invoice_change_spec.rb:
--------------------------------------------------------------------------------
1 | require 'nokogiri'
2 |
3 | describe "Quickbooks::Model::InvoiceChange" do
4 | it "parse from XML" do
5 | xml = fixture("invoice_change.xml")
6 | invoice = Quickbooks::Model::InvoiceChange.from_xml(xml)
7 | invoice.status.should == 'Deleted'
8 | invoice.id.should == "39"
9 |
10 | invoice.meta_data.should_not be_nil
11 | invoice.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
12 | end
13 | end
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/tax_code_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::TaxCode" do
2 | before(:all) { construct_service :tax_code }
3 |
4 | it "can query tax codes" do
5 | stub_request(:get,
6 | @service.url_for_query,
7 | ["200", "OK"],
8 | fixture("tax_codes.xml"))
9 |
10 | tax_codes = @service.query
11 |
12 | tax_codes.entries.count.should eq(11)
13 | tax_codes.entries.first.name.should eq("TAX")
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/fixtures/access_token_200.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 0
5 | 2012-01-04T19:21:21.0782072Z
6 | qye2eIdQ5H5yMyrlJflUWh712xfFXjyNnW1MfbC0rz04TfCP
7 | cyDeUNQTkFzoR0KkDn7viN6uLQxWTobeEUKW7I79
8 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/payment_change_spec.rb:
--------------------------------------------------------------------------------
1 | require 'nokogiri'
2 |
3 | describe "Quickbooks::Model::PaymentChange" do
4 | it "parse from XML" do
5 | xml = fixture("payment_change.xml")
6 | payment = Quickbooks::Model::PaymentChange.from_xml(xml)
7 | payment.status.should == 'Deleted'
8 | payment.id.should == "39"
9 |
10 | payment.meta_data.should_not be_nil
11 | payment.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/fault.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class Fault < BaseModel
4 | class Error
5 | include ROXML
6 | xml_name 'Error'
7 | xml_accessor :code, :from => "@code"
8 | xml_accessor :element, :from => "@element"
9 | xml_accessor :message, :from => "Message"
10 | xml_accessor :detail, :from => "Detail"
11 | end
12 |
13 | xml_accessor :errors, :as => [Quickbooks::Model::Fault::Error]
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/spec/fixtures/refund_receipt_changes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 40
6 |
7 | 2014-12-09T19:30:24-08:00
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/customer_change_spec.rb:
--------------------------------------------------------------------------------
1 | require 'nokogiri'
2 |
3 | describe "Quickbooks::Model::CustomerChange" do
4 | it "parse from XML" do
5 | xml = fixture("customer_change.xml")
6 | customer = Quickbooks::Model::CustomerChange.from_xml(xml)
7 | customer.status.should == 'Deleted'
8 | customer.id.should == "39"
9 |
10 | customer.meta_data.should_not be_nil
11 | customer.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
12 | end
13 | end
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/tax_rate_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::TaxRate" do
2 | before(:all) { construct_service :tax_rate }
3 |
4 | it "can query tax rates" do
5 | stub_request(:get,
6 | @service.url_for_query,
7 | ["200", "OK"],
8 | fixture("tax_rates.xml"))
9 |
10 | tax_rates = @service.query
11 |
12 | tax_rates.entries.count.should eq(1)
13 | tax_rates.entries.first.name.should eq("Mountain View")
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/bill_payment_check.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class BillPaymentCheck < BaseModel
4 | xml_accessor :bank_account_ref, :from => 'BankAccountRef', :as => BaseReference
5 | xml_accessor :print_status, :from => 'PrintStatus'
6 | xml_accessor :check_detail, :from => 'CheckDetail', :as => CheckPayment
7 | xml_accessor :payee_address, :from => 'PayeeAddr', :as => PhysicalAddress
8 |
9 | reference_setters :bank_account_ref
10 | end
11 | end
12 | end
--------------------------------------------------------------------------------
/spec/fixtures/exchange_rate_by_currency.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2013-12-11T10:59:51-08:00
5 |
6 | EUR
7 | USD
8 | 2.5
9 | 2015-07-07
10 |
11 |
12 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/effective_tax_rate.rb:
--------------------------------------------------------------------------------
1 | require 'time'
2 |
3 | module Quickbooks
4 | module Model
5 | class EffectiveTaxRate < BaseModel
6 | XML_COLLECTION_NODE = "EffectiveTaxRate"
7 | XML_NODE = "EffectiveTaxRate"
8 | REST_RESOURCE = "effectivetaxrate"
9 |
10 | xml_accessor :rate_value, :from => 'RateValue'
11 | xml_accessor :effective_date, :from => 'EffectiveDate', :as => Time
12 | xml_accessor :end_date, :from => 'EndDate', :as => Time
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/preferences.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Preferences < BaseService
4 |
5 | def url_for_query(query = nil, start_position = 1, max_results = 20, options = {})
6 | url = super(query, start_position, max_results, options)
7 | "#{url}&minorversion=#{Quickbooks::Model::Preferences::MINORVERSION}"
8 | end
9 |
10 | private
11 |
12 | def model
13 | Quickbooks::Model::Preferences
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/fixtures/invoice_sparse_create_request.xml:
--------------------------------------------------------------------------------
1 |
2 | 1001
3 | 2013-11-20
4 |
5 | Plush Baby Doll
6 | 50
7 | SalesItemLineDetail
8 |
9 | 1
10 | 50
11 | 1
12 |
13 |
14 | 1
15 |
--------------------------------------------------------------------------------
/spec/fixtures/customer_duplicate_error.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Duplicate Name Exists Error
6 | The name supplied already exists. : Another $$customer$$ is already using this name. Please use a different name.
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | unless ENV['CI']
3 | require 'simplecov'
4 | SimpleCov.start do
5 | add_filter 'spec'
6 | end
7 | end
8 |
9 | require 'rubygems'
10 | require 'rspec'
11 | require 'fakeweb'
12 | require 'oauth'
13 | require 'quickbooks-ruby'
14 | require 'json'
15 | require 'pry'
16 |
17 | Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |f| require f }
18 |
19 | RSpec.configure do |config|
20 | config.color = true
21 | end
22 |
23 | I18n.enforce_available_locales = false
24 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/global_tax_calculation.rb:
--------------------------------------------------------------------------------
1 | module GlobalTaxCalculation
2 | extend ActiveSupport::Concern
3 |
4 | TAX_INCLUSIVE = "TaxInclusive"
5 | TAX_EXCLUDED = "TaxExcluded"
6 | NOT_APPLICABLE = "NotApplicable"
7 | GLOBAL_TAX_CALCULATION = [TAX_INCLUSIVE, TAX_EXCLUDED, NOT_APPLICABLE]
8 |
9 | included do
10 | xml_accessor :global_tax_calculation, :from => 'GlobalTaxCalculation'
11 | validates_inclusion_of :global_tax_calculation, :in => GLOBAL_TAX_CALCULATION, allow_blank: true
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/document_numbering.rb:
--------------------------------------------------------------------------------
1 | module DocumentNumbering
2 |
3 | # Convenience method for proper AutoDocNumber tag
4 | # construction, which should be blank if auto
5 | # document numbering is desired.
6 | def auto_doc_number!
7 | self.auto_doc_number = ''
8 | end
9 |
10 | private
11 |
12 | def document_numbering
13 | if !auto_doc_number.nil? && !doc_number.nil?
14 | errors.add(:doc_number, "DocumentNumber should not be specified if AutoDocNumber is.")
15 | end
16 | end
17 |
18 | end
19 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/markup_info.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class MarkupInfo < BaseModel
4 | xml_accessor :percent_based, :from => 'PercentBased'
5 | xml_accessor :value, :from => 'Value', :as => BigDecimal, :to_xml => to_xml_big_decimal
6 | xml_accessor :percent, :from => 'Percent', :as => BigDecimal, :to_xml => to_xml_big_decimal
7 | xml_accessor :price_level_ref, :from => 'PriceLevelRef', :as => BaseReference
8 |
9 | reference_setters :price_level_ref
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/tax_rate_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class TaxRateDetail < BaseModel
4 | XML_COLLECTION_NODE = "TaxRateDetail"
5 | XML_NODE = "TaxRateDetail"
6 | REST_RESOURCE = "taxratedetail"
7 |
8 | xml_accessor :tax_rate_ref, :from => "TaxRateRef", :as => BaseReference
9 | xml_accessor :tax_type_applicable, :from => "TaxTypeApplicable"
10 | xml_accessor :tax_order, :from => "TaxOrder"
11 |
12 | reference_setters :tax_rate_ref
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/credit_memo_change_spec.rb:
--------------------------------------------------------------------------------
1 | require 'nokogiri'
2 |
3 | describe "Quickbooks::Model::CreditMemoChange" do
4 | it "parse from XML" do
5 | xml = fixture("credit_memo_change.xml")
6 | credit_memo = Quickbooks::Model::CreditMemoChange.from_xml(xml)
7 | credit_memo.status.should == 'Deleted'
8 | credit_memo.id.should == "39"
9 |
10 | credit_memo.meta_data.should_not be_nil
11 | credit_memo.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/sales_line_item_detail_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::SalesItemLineDetail" do
2 |
3 | it "rate percent should be a decimal/float if set" do
4 | detail = Quickbooks::Model::SalesItemLineDetail.new
5 | detail.rate_percent = 10
6 | detail.to_xml.at_css('RatePercent').content.should == '10.0'
7 | end
8 |
9 | it "rate percent should not be included if not set" do
10 | detail = Quickbooks::Model::SalesItemLineDetail.new
11 | detail.to_xml.should_not =~ /RatePercent/
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/payment_line_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class PaymentLineDetail < BaseModel
4 | xml_accessor :item_ref, :from => 'ItemRef', :as => BaseReference
5 | xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
6 | xml_accessor :balance, :from => 'Balance', :as => BigDecimal, :to_xml => to_xml_big_decimal
7 | xml_accessor :discount, :from => 'Discount', :as => DiscountOverride
8 |
9 | reference_setters :item_ref, :class_ref
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/exchange_rate_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::ExchangeRate" do
2 | it "parse from XML" do
3 | xml = fixture("exchange_rate.xml")
4 | item = Quickbooks::Model::ExchangeRate.from_xml(xml)
5 | item.id.should == "9"
6 | item.sync_token.should == 0
7 | item.meta_data.should_not be_nil
8 | item.source_currency_code.should == "EUR"
9 | item.target_currency_code.should == "USD"
10 | item.rate.should == 2.5
11 | item.as_of_date.to_date.should == Date.civil(2015, 07, 07)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_payment_method_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 7
4 | 0
5 |
6 | 2013-12-09T10:44:18-08:00
7 | 2013-12-09T10:44:18-08:00
8 |
9 | Discover
10 | true
11 | CREDIT_CARD
12 |
13 |
14 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/purchase_order_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::PurchaseOrder" do
2 |
3 | before(:all) do
4 | construct_service :purchase_order
5 | end
6 |
7 | it "can delete a vendor" do
8 | model = Quickbooks::Model::PurchaseOrder
9 | purchase_order = model.new
10 | xml = fixture("deleted_purchase_order.xml")
11 | stub_request(:post, @service.url_for_resource(model::REST_RESOURCE), ["200", "OK"], xml, {}, false)
12 | expect(@service.delete(purchase_order)).to eq true
13 |
14 | end
15 |
16 | end
17 |
--------------------------------------------------------------------------------
/spec/fixtures/deleted_payment_method.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 7
4 | 0
5 |
6 | 2013-12-09T10:44:18-08:00
7 | 2013-12-09T10:44:18-08:00
8 |
9 | Discover (Deleted)
10 | false
11 | CREDIT_CARD
12 |
13 |
14 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/refund_receipt_change_spec.rb:
--------------------------------------------------------------------------------
1 | require 'nokogiri'
2 |
3 | describe "Quickbooks::Model::RefundReceiptChange" do
4 | it "parse from XML" do
5 | xml = fixture("refund_receipt_change.xml")
6 | refund_receipt = Quickbooks::Model::RefundReceiptChange.from_xml(xml)
7 | refund_receipt.status.should == 'Deleted'
8 | refund_receipt.id.should == "40"
9 |
10 | refund_receipt.meta_data.should_not be_nil
11 | refund_receipt.meta_data.last_updated_time.should == DateTime.parse("2014-12-09T19:30:24-08:00")
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/invoice_group_line_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class InvoiceGroupLineDetail < InvoiceLineItem
4 | include HasLineItems
5 |
6 | xml_accessor :id, :from => 'Id'
7 | xml_accessor :group_item_ref, :from => 'GroupItemRef', :as => BaseReference
8 | xml_accessor :quantity, :from => 'Quantity', :as => BigDecimal, :to_xml => to_xml_big_decimal
9 | xml_accessor :line_items, :from => 'Line', :as => [InvoiceLineItem]
10 |
11 | reference_setters :group_item_ref
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/transfer_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::Transfer" do
2 | before(:all) do
3 | construct_service :transfer
4 | end
5 |
6 | it "can query for transfers" do
7 | xml = fixture("transfers.xml")
8 | model = Quickbooks::Model::Transfer
9 |
10 | stub_request(:get, @service.url_for_query, ["200", "OK"], xml)
11 | transfers_query = @service.query
12 | transfers_query.entries.count.should == 1
13 |
14 | transfer = transfers_query.entries.first
15 | transfer.amount.should == 250.00
16 | end
17 |
18 | end
--------------------------------------------------------------------------------
/lib/quickbooks/model/custom_field.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class CustomField < BaseModel
4 | xml_accessor :id, :from => 'DefinitionId', :as => Integer
5 | xml_accessor :name, :from => 'Name'
6 | xml_accessor :type, :from => 'Type'
7 | xml_accessor :string_value, :from => 'StringValue'
8 | xml_accessor :boolean_value, :from => 'BooleanValue'
9 | xml_accessor :date_value, :from => 'DateValue', :as => Date
10 | xml_accessor :number_value, :from => 'NumberValue', :as => Integer
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/fixtures/deleted_company_currency.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1
5 | 3
6 |
7 | 2013-04-20T10:32:18-07:00
8 | 2013-07-11T08:27:06-07:00
9 |
10 | Euro
11 | EUR
12 | false
13 |
14 |
15 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_company_currency_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1
5 | 3
6 |
7 | 2013-04-20T10:32:18-07:00
8 | 2013-07-11T08:27:06-07:00
9 |
10 | Euro
11 | EUR
12 | true
13 |
14 |
15 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/company_currency_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::CompanyCurrency" do
2 | it "parse from XML" do
3 | xml = fixture('company_currency.xml')
4 | company_currency = Quickbooks::Model::CompanyCurrency.from_xml(xml)
5 |
6 | company_currency.id.should == "1"
7 | company_currency.sync_token.should == 3
8 |
9 | company_currency.meta_data.should_not be_nil
10 | company_currency.name.should == "Euro"
11 | company_currency.code.should == "EUR"
12 | company_currency.active?.should == true
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/tax_line.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class TaxLine < BaseModel
4 |
5 | xml_accessor :id, :from => 'Id'
6 | xml_accessor :line_num, :from => 'LineNum', :as => Integer
7 | xml_accessor :description, :from => 'Description'
8 | xml_accessor :amount, :from => 'Amount', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
9 | xml_accessor :detail_type, :from => 'DetailType'
10 |
11 | xml_accessor :tax_line_detail, :from => 'TaxLineDetail', :as => TaxLineDetail
12 |
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/fixtures/term.xml:
--------------------------------------------------------------------------------
1 |
2 | 11
3 | 0
4 |
5 | 2013-07-11T17:46:39-07:00
6 | 2013-07-11T17:46:42-07:00
7 |
8 | TermForV3Testing-1373590184130
9 | true
10 | DATE_DRIVEN
11 | 4.0000000
12 | 1
13 | 2
14 | 3
15 |
16 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_class_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2
4 | 2
5 |
6 | 2014-04-16T05:40:25-07:00
7 | 2014-04-16T05:40:25-07:00
8 |
9 | Design
10 | false
11 | Design
12 | true
13 |
14 |
15 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/discount_override.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class DiscountOverride < BaseModel
4 | xml_accessor :discount_ref, :from => 'DiscountRef', :as => BaseReference
5 | xml_accessor :percent_based?, :from => 'PercentBased'
6 | xml_accessor :discount_percent, :from => 'DiscountPercent', :as => BigDecimal, :to_xml => to_xml_big_decimal
7 | xml_accessor :discount_account_ref, :from => 'DiscountAccountRef', :as => BaseReference
8 |
9 | reference_setters :discount_ref, :discount_account_ref
10 |
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/fixtures/tax_service_entity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | First Tax Service
5 | 1
6 |
7 | 1
8 | Rate Spec
9 | 3.5
10 | 2
11 | Sales
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/estimate.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Estimate < BaseService
4 |
5 | def delete(estimate)
6 | delete_by_query_string(estimate)
7 | end
8 |
9 | def pdf(estimate)
10 | url = "#{url_for_resource(model::REST_RESOURCE)}/#{estimate.id}/pdf"
11 | response = do_http_raw_get(url, {}, {'Accept' => 'application/pdf'})
12 | response.plain_body
13 | end
14 |
15 | private
16 |
17 | def model
18 | Quickbooks::Model::Estimate
19 | end
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/spec/fixtures/deleted_class.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 3000000000000299495
4 | 0
5 |
6 | 2014-04-16T05:40:25-07:00
7 | 2014-04-16T05:40:25-07:00
8 |
9 | Design (Deleted)
10 | false
11 | Design
12 | false
13 |
14 |
15 |
--------------------------------------------------------------------------------
/spec/fixtures/transfer.xml:
--------------------------------------------------------------------------------
1 |
2 | 148
3 | 0
4 |
5 | 2016-02-11T06:00:44-08:00
6 | 2016-02-11T06:00:44-08:00
7 |
8 | 2016-02-11
9 | USD
10 | Important notes to explain this transaction
11 | 36
12 | 35
13 | 250.00
14 |
--------------------------------------------------------------------------------
/spec/fixtures/payment.xml:
--------------------------------------------------------------------------------
1 |
2 | 8748
3 | 0
4 |
5 | 2013-07-11T17:51:41-07:00
6 | 2013-07-11T17:51:42-07:00
7 |
8 | 2013-07-11
9 | Payment smoke test
10 | 25342
11 | 4
12 | 40.00
13 | 40.00
14 | false
15 |
16 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/payment_method_spec.rb:
--------------------------------------------------------------------------------
1 | describe Quickbooks::Model::PaymentMethod do
2 | it "must have a valid type if defined" do
3 | account = Quickbooks::Model::PaymentMethod.new
4 |
5 | # It should allow nil
6 | account.valid?
7 | account.errors.keys.include?(:type).should == false
8 |
9 | account.type = 'Undocummented Type'
10 | account.valid?
11 | account.errors.keys.include?(:type).should == true
12 |
13 | account.type = Quickbooks::Model::PaymentMethod::CREDIT_CARD
14 | account.valid?
15 | account.errors.keys.include?(:type).should == false
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/fixtures/company_currency_query.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 1
6 | 3
7 |
8 | 2013-04-20T10:32:18-07:00
9 | 2013-07-11T08:27:06-07:00
10 |
11 | Euro
12 | EUR
13 | true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/spec/fixtures/tax_agency_entity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1
5 | 0
6 |
7 | 2013-12-11T10:59:51-08:00
8 | 2013-12-11T10:59:51-08:00
9 |
10 | First TaxAgency
11 | false
12 | true
13 |
14 |
15 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/util/collection_spec.rb:
--------------------------------------------------------------------------------
1 | describe Quickbooks::Collection do
2 | it "is has an #each" do
3 | collection = Quickbooks::Collection.new()
4 | collection.entries = [:foo]
5 | expect{ |b| collection.each &b}.to yield_with_args(:foo)
6 | end
7 | it "has a method from enumerable" do
8 | collection = Quickbooks::Collection.new()
9 | collection.entries = [:foo]
10 | expect( collection.first).to be(:foo)
11 | end
12 | it "doesn't error when no entries are set" do
13 | collection = Quickbooks::Collection.new()
14 | expect{collection.first}.to_not raise_error
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/budget_line_item.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class BudgetLineItem < BaseModel
4 |
5 | xml_accessor :date, :from => 'BudgetDate', :as => Date
6 | xml_accessor :amount, :from => 'Amount'
7 | xml_accessor :account_ref, :from => 'AccountRef', :as => BaseReference
8 | xml_accessor :customer_ref, :from => 'CustomerRef', :as => BaseReference
9 | xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
10 | xml_accessor :department_ref, :from => 'DepartmentRef', :as => BaseReference
11 |
12 | reference_setters
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/preferences_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::Preferences" do
2 | before(:all) do
3 | construct_service :preferences
4 | end
5 |
6 | it "can query for preferences" do
7 | xml = fixture("preferences_query.xml")
8 | model = Quickbooks::Model::Preferences
9 |
10 | stub_request(:get, @service.url_for_query, ["200", "OK"], xml)
11 | preferences_query = @service.query
12 | preferences_query.entries.count.should == 1
13 |
14 | preferences = preferences_query.entries.first
15 | preferences.accounting_info.customer_terminology.should == "Customers"
16 | end
17 |
18 | end
--------------------------------------------------------------------------------
/lib/quickbooks/service/class.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Class < BaseService
4 |
5 | def update(entity, options = {})
6 | raise Quickbooks::InvalidModelException.new('Class sparse update is not supported by Intuit at this time') if options[:sparse] && options[:sparse] == true
7 | super(entity, options)
8 | end
9 |
10 | def delete(classs)
11 | classs.active = false
12 | update(classs, :sparse => false)
13 | end
14 |
15 | private
16 |
17 | def model
18 | Quickbooks::Model::Class
19 | end
20 |
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/spec/fixtures/item.xml:
--------------------------------------------------------------------------------
1 | -
2 | 2
3 | 0
4 |
5 | 2013-11-16T17:42:03-08:00
6 | 2013-11-16T17:42:03-08:00
7 |
8 | Plush Baby Doll
9 | PBD01
10 | A fine baby doll - in many colors
11 | true
12 | false
13 | 50
14 | Service
15 | 1
16 | 0
17 | false
18 |
19 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_payment_method_by_name.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 7
5 | 0
6 |
7 | 2013-12-09T10:44:18-08:00
8 | 2013-12-09T10:44:18-08:00
9 |
10 | Discover
11 | true
12 | CREDIT_CARD
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/attachable_ref.rb:
--------------------------------------------------------------------------------
1 | require 'quickbooks/model/entity_ref'
2 | require 'quickbooks/model/custom_field'
3 |
4 | module Quickbooks
5 | module Model
6 | class AttachableRef < BaseModel
7 | xml_accessor :entity_ref, :as => BaseReference
8 | xml_accessor :line_info
9 | xml_accessor :include_on_send?
10 | xml_accessor :inactive?
11 | xml_accessor :no_ref_only?
12 | xml_accessor :custom_fields, :as => [CustomField]
13 |
14 | def initialize(an_entity_ref = nil)
15 | if an_entity_ref
16 | self.entity_ref = an_entity_ref
17 | end
18 | end
19 |
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/department.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Department < BaseService
4 |
5 | def update(entity, options = {})
6 | raise Quickbooks::InvalidModelException.new('Department sparse update is not supported by Intuit at this time') if options[:sparse] && options[:sparse] == true
7 | super(entity, options)
8 | end
9 |
10 | def delete(department)
11 | department.active = false
12 | update(department, :sparse => false)
13 | end
14 |
15 | private
16 |
17 | def model
18 | Quickbooks::Model::Department
19 | end
20 |
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/access_token_response_spec.rb:
--------------------------------------------------------------------------------
1 | describe Quickbooks::Model::AccessTokenResponse do
2 | it "can parse a successful response" do
3 | xml = fixture("access_token_200.xml")
4 | response = Quickbooks::Model::AccessTokenResponse.from_xml(xml)
5 | response.error?.should == false
6 | response.error_message.should == ""
7 | response.token.length.should > 0
8 | response.secret.length.should > 0
9 | end
10 |
11 | it "can parse a unsuccessful response" do
12 | xml = fixture("access_token_270.xml")
13 | response = Quickbooks::Model::AccessTokenResponse.from_xml(xml)
14 | response.error?.should == true
15 | end
16 | end
--------------------------------------------------------------------------------
/lib/quickbooks/model/sub_total_line_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class SubTotalLineDetail < BaseModel
4 | xml_accessor :item_ref, :from => 'ItemRef', :as => BaseReference
5 | xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
6 | xml_accessor :unit_price, :from => 'UnitPrice', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
7 | xml_accessor :quantity, :from => 'Qty', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
8 | xml_accessor :tax_code_ref, :from => 'TaxCodeRef', :as => BaseReference
9 |
10 | reference_setters :item_ref, :class_ref, :tax_code_ref
11 | end
12 | end
13 | end
--------------------------------------------------------------------------------
/lib/quickbooks/service/vendor.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Vendor < BaseService
4 |
5 | # override update as sparse is not supported
6 | def update(entity, options = {})
7 | raise InvalidModelException.new('Vendor sparse update is not supported by Intuit at this time') if options[:sparse] && options[:sparse] == true
8 | super(entity, options)
9 | end
10 |
11 | def delete(vendor)
12 | vendor.active = false
13 | update(vendor, :sparse => false)
14 | end
15 |
16 | private
17 |
18 | def model
19 | Quickbooks::Model::Vendor
20 | end
21 |
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_department_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2
4 | 0
5 |
6 | 2013-08-13T11:52:48-07:00
7 | 2013-08-13T11:52:48-07:00
8 |
9 | Marketing Department
10 | false
11 | Marketing Department
12 | true
13 |
14 |
15 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/tax_rate_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::TaxRate" do
2 | it "parse from XML" do
3 | xml = fixture("tax_rate.xml")
4 | item = Quickbooks::Model::TaxRate.from_xml(xml)
5 | item.id.should == "9"
6 | item.sync_token.should == 0
7 | item.meta_data.should_not be_nil
8 | item.name.should == "Santa Clara County"
9 | item.description.should == "Sales Tax"
10 | item.should be_active
11 | item.rate_value.should == 0.5
12 | item.agency_ref.value.should == "3"
13 | item.effective_tax_rate.should_not be_nil
14 | item.special_tax_type.should == "NONE"
15 | item.display_type.should == "ReadOnly"
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/fixtures/deleted_department.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2
4 | 0
5 |
6 | 2013-08-13T11:52:48-07:00
7 | 2013-08-13T11:52:48-07:00
8 |
9 | Marketing Department (Deleted)
10 | false
11 | Marketing Department
12 | false
13 |
14 |
15 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/base_service_json_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | module Quickbooks
4 | module Service
5 | describe ServiceCrudJSON do
6 |
7 | it "has the correct content-type" do
8 | json_service = construct_service :tax_service
9 | expect(json_service.class::HTTP_CONTENT_TYPE).to eq 'application/json'
10 | end
11 |
12 | it "has the correct content-type" do
13 | json_service = construct_service :tax_service
14 | json_service.send(:parse_json, json_fixture(:tax_service_error_dup))
15 | expect { json_service.send(:parse_intuit_error) }.to_not raise_exception
16 | end
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/base_reference.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class BaseReference < BaseModel
4 | xml_convention :camelcase
5 | xml_accessor :name, :from => '@name' # Attribute with name 'name'
6 | xml_accessor :value, :from => :content
7 | xml_accessor :type, :from => '@type' # Attribute with name 'type'
8 |
9 | def initialize(value=nil, attributes={})
10 | self.value = value
11 | attributes.each {|key, value| public_send("#{key}=", value) }
12 | end
13 |
14 | def to_i
15 | self.value.to_i
16 | end
17 |
18 | def to_s
19 | self.value.to_s
20 | end
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/company_currency.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class CompanyCurrency < BaseModel
4 | include NameEntity::PermitAlterations
5 |
6 | XML_COLLECTION_NODE = 'CompanyCurrency'
7 | XML_NODE = 'CompanyCurrency'
8 | REST_RESOURCE = 'companycurrency'
9 |
10 | xml_name XML_NODE
11 | xml_accessor :id, :from => 'Id'
12 | xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
13 | xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
14 | xml_accessor :name, :from => 'Name'
15 | xml_accessor :code, :from => 'Code'
16 | xml_accessor :active?, :from => 'Active'
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/change_service.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class ChangeService < BaseService
4 |
5 | def url_for_query(query = nil, start_position = 1, max_results = 20)
6 | q = entity
7 | q = "#{q}{query}" if query.present?
8 |
9 | "#{url_for_base}/cdc?entities=#{q}"
10 | end
11 |
12 | def since(timestamp)
13 | query("changedSince=#{URI.encode_www_form_component(timestamp.iso8601)}")
14 | end
15 |
16 | private
17 |
18 | def entity
19 | raise NotImplementedError
20 | end
21 |
22 | def model
23 | raise NotImplementedError
24 | end
25 |
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/spec/fixtures/bill_payment_check_response.xml:
--------------------------------------------------------------------------------
1 |
2 | 623
3 | 1
4 |
5 | 2015-12-15T00:00:00-08:00
6 | 2015-12-15T00:00:00-08:00
7 |
8 | 1
9 | 2015-12-15
10 | Acct. 1JK90
11 | 32
12 | Check
13 |
14 | 133
15 | NotSet
16 |
17 | 110.00
18 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require "rubygems"
2 | require "bundler"
3 | require "bundler/gem_tasks"
4 |
5 | Bundler.setup
6 |
7 | require "rake"
8 | require "rspec"
9 | require "rspec/core/rake_task"
10 |
11 | $:.unshift File.expand_path("../lib", __FILE__)
12 | require "quickbooks-ruby"
13 |
14 | task :default => :spec
15 |
16 | desc "Run all specs"
17 | RSpec::Core::RakeTask.new(:spec) do |t|
18 | t.pattern = 'spec/**/*_spec.rb'
19 | end
20 |
21 |
22 | desc "Open an irb (or pry) session preloaded with Quickbooks"
23 | task :console do
24 | begin
25 | require 'pry'
26 | sh %{pry -I lib -r quickbooks-ruby.rb}
27 | rescue LoadError => _
28 | sh 'irb -rubygems -I lib -r quickbooks.rb'
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/employee.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Employee < BaseService
4 |
5 | # override update as sparse is not supported
6 | def update(entity, options = {})
7 | raise Quickbooks::InvalidModelException.new('Employee sparse update is not supported by Intuit at this time') if options[:sparse] && options[:sparse] == true
8 | super(entity, options)
9 | end
10 |
11 | def delete(employee)
12 | employee.active = false
13 | update(employee, :sparse => false)
14 | end
15 |
16 | private
17 |
18 | def model
19 | Quickbooks::Model::Employee
20 | end
21 |
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/fixtures/tax_agencies.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1
5 | 0
6 |
7 | 2013-12-11T10:59:51-08:00
8 | 2013-12-11T10:59:51-08:00
9 |
10 | First TaxAgency
11 | false
12 | true
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/tax_agency.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class TaxAgency < BaseModel
4 | XML_COLLECTION_NODE = "TaxAgency"
5 | XML_NODE = "TaxAgency"
6 | REST_RESOURCE = "taxagency"
7 |
8 | xml_accessor :id, :from => "Id"
9 | xml_accessor :sync_token, :from => "SyncToken", :as => Integer
10 | xml_accessor :meta_data, :from => "MetaData", :as => MetaData
11 | xml_accessor :tax_tracked_on_purchases?, :from => "TaxTrackedOnPurchases"
12 | xml_accessor :tax_tracked_on_sales?, :from => "TaxTrackedOnSales"
13 | xml_accessor :display_name, :from => "DisplayName"
14 |
15 | validates_presence_of :display_name
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/change_data_capture.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class ChangeDataCapture < BaseService
4 |
5 | def url_for_query(entity_list, query=nil)
6 | q = entity_list.join(",")
7 | q = "#{q}{query}" if query.present?
8 | return "#{url_for_base}/cdc?entities=#{q}"
9 | end
10 |
11 | def since(entity_list, timestamp)
12 | do_http_get(url_for_query(entity_list, "changedSince=#{URI.encode_www_form_component(timestamp.iso8601)}"))
13 | model.new(:xml => @last_response_xml)
14 | end
15 |
16 | private
17 |
18 | def model
19 | Quickbooks::Model::ChangeDataCapture
20 | end
21 |
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/fixtures/exchange_rates.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 9
5 | 0
6 |
7 | 2013-12-11T10:59:51-08:00
8 | 2013-12-11T10:59:51-08:00
9 |
10 | EUR
11 | USD
12 | 2.5
13 | 2015-07-07
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/spec/fixtures/payment_void_response_success.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 8748
4 | 0
5 |
6 | 2013-07-11T17:51:41-07:00
7 | 2013-07-11T17:51:42-07:00
8 |
9 | 2013-07-11
10 | Voided
11 | 25342
12 | 4
13 | 0
14 | 0
15 | false
16 |
17 |
--------------------------------------------------------------------------------
/spec/support/net_helpers.rb:
--------------------------------------------------------------------------------
1 | module NetHelpers
2 |
3 | # +strict+ indicates whether we want to use a regex for a matching URL, which is needed
4 | # for URLs that use query params. If you don't need use query params
5 | # than its suggested to use strict = true
6 | def stub_request(method, url, status = ["200", "OK"], body = nil, headers = {}, strict = true)
7 | if !strict
8 | if url.is_a?(String)
9 | url = url.gsub('?', '\?')
10 | end
11 | uri = %r|#{url}|
12 | else
13 | uri = url
14 | end
15 | FakeWeb.register_uri(method, uri, { :status => status, :body => body }.merge(headers))
16 | end
17 | end
18 |
19 | RSpec.configure do |config|
20 | config.include(NetHelpers)
21 | end
22 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/tax_agency_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::TaxAgency" do
2 | it "parse from XML" do
3 | xml = fixture("tax_agency.xml")
4 | item = Quickbooks::Model::TaxAgency.from_xml(xml)
5 |
6 | item.id.should == "1"
7 | item.sync_token.should == 0
8 | item.meta_data.should_not be_nil
9 | item.display_name.should == "First TaxAgency"
10 | item.tax_tracked_on_purchases?.should be_false
11 | item.tax_tracked_on_sales?.should be_true
12 | end
13 |
14 | it "should require display_name for create / update" do
15 | invoice = Quickbooks::Model::TaxAgency.new
16 | invoice.should_not be_valid
17 | invoice.errors.keys.include?(:display_name).should be_true
18 | end
19 |
20 | end
21 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/meta_data.rb:
--------------------------------------------------------------------------------
1 | require 'time'
2 |
3 | module Quickbooks
4 | module Model
5 | class MetaData < BaseModel
6 | xml_accessor :create_time, :from => 'CreateTime', :as => Time
7 | xml_accessor :last_updated_time, :from => 'LastUpdatedTime', :as => Time
8 |
9 | def to_xml(options = {})
10 | xml = %Q{}
11 | xml = "#{xml}#{formatted_date(create_time)}"
12 | xml = "#{xml}#{formatted_date(last_updated_time)}"
13 | xml
14 | end
15 |
16 | private
17 |
18 | def formatted_date(datetime)
19 | datetime.strftime('%Y-%m-%dT%H:%M:%S%z')
20 | end
21 |
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/fixtures/terms.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 11
4 | 0
5 |
6 | 2013-07-11T17:46:39-07:00
7 | 2013-07-11T17:46:39-07:00
8 |
9 | TermForV3Testing-1373590184130
10 | true
11 | DATE_DRIVEN
12 | 4.0000000
13 | 1
14 | 2
15 | 3
16 |
17 |
18 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/account_based_expense_line_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class AccountBasedExpenseLineDetail < BaseModel
4 | xml_accessor :customer_ref, :from => 'CustomerRef', :as => BaseReference
5 | xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
6 | xml_accessor :account_ref, :from => 'AccountRef', :as => BaseReference
7 | xml_accessor :billable_status, :from => 'BillableStatus'
8 | xml_accessor :tax_amount, :from => 'UnitPrice', :as => BigDecimal, :to_xml => to_xml_big_decimal
9 | xml_accessor :tax_code_ref, :from => 'TaxCodeRef', :as => BaseReference
10 |
11 | reference_setters :customer_ref, :class_ref, :account_ref, :tax_code_ref
12 |
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_term_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 11
4 | 0
5 |
6 | 2013-07-11T17:46:39-07:00
7 | 2013-07-11T17:46:39-07:00
8 |
9 | TermForV3Testing-1373590184130
10 | true
11 | DATE_DRIVEN
12 | 4.0000000
13 | 1
14 | 2
15 | 3
16 |
17 |
18 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/deposit_line_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class DepositLineDetail < BaseModel
4 |
5 | xml_accessor :entity_ref, :from => 'Entity', :as => BaseReference
6 | xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
7 | xml_accessor :account_ref, :from => 'AccountRef', :as => BaseReference
8 | xml_accessor :payment_method_ref, :from => 'PaymentMethodRef', :as => BaseReference
9 | xml_accessor :check_num, :from => 'CheckNum'
10 | xml_accessor :txn_type, :from => 'TxnType'
11 | xml_accessor :custom_fields, :from => 'CustomField', :as => [CustomField]
12 |
13 | reference_setters :class_ref, :account_ref, :payment_method_ref, :entity_ref
14 |
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/bill_payment_line_item.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class BillPaymentLineItem < BaseModel
4 |
5 | #== Constants
6 | PAYMENT_LINE_DETAIL = 'PaymentLineDetail'
7 | DISCOUNT_LINE_DETAIL = 'DiscountLineDetail'
8 |
9 | xml_accessor :id, :from => 'Id'
10 | xml_accessor :line_num, :from => 'LineNum', :as => Integer
11 | xml_accessor :description, :from => 'Description'
12 | xml_accessor :amount, :from => 'Amount', :as => BigDecimal, :to_xml => to_xml_big_decimal
13 | xml_accessor :detail_type, :from => 'DetailType'
14 |
15 | xml_accessor :linked_transactions, :from => 'LinkedTxn', :as => [LinkedTransaction]
16 |
17 | #== Various detail types
18 |
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/exchange_rate.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class ExchangeRate < BaseService
4 |
5 | def fetch_by_currency(source_currency_code, as_of_date = nil)
6 | url = url_for_resource(model::REST_RESOURCE)
7 | params = { sourcecurrencycode: source_currency_code }
8 | params[:asofdate] = as_of_date unless as_of_date.nil?
9 |
10 | response = do_http_get(url, params)
11 | if response.code.to_i == 200
12 | model.from_xml(parse_singular_entity_response(model, response.plain_body))
13 | else
14 | nil
15 | end
16 | end
17 |
18 | private
19 |
20 | def model
21 | Quickbooks::Model::ExchangeRate
22 | end
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_payment_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 8748
4 | 0
5 |
6 | 2013-07-11T17:51:41-07:00
7 | 2013-07-11T17:51:41-07:00
8 |
9 | 2013-07-11
10 | Payment smoke test
11 | 25342
12 | 4
13 | 40.00
14 | 40.00
15 | false
16 |
17 |
18 |
--------------------------------------------------------------------------------
/spec/fixtures/term_delete_success_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 11
4 | 1
5 |
6 | 2013-07-11T17:46:39-07:00
7 | 2013-07-11T17:46:40-07:00
8 |
9 | TermForV3Testing-1373590184515
10 | false
11 | DATE_DRIVEN
12 | 10.0000000
13 | 1
14 | 2
15 | 3
16 |
17 |
18 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_item_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 | -
3 | 2
4 | 0
5 |
6 | 2013-11-16T17:42:03-08:00
7 | 2013-11-16T17:42:03-08:00
8 |
9 | Plush Baby Doll
10 | A fine baby doll - in many colors
11 | true
12 | false
13 | 50
14 | Service
15 | 1
16 | 0
17 | false
18 |
19 |
--------------------------------------------------------------------------------
/spec/fixtures/bill_payment_cc_response.xml:
--------------------------------------------------------------------------------
1 |
2 | 812
3 | 0
4 |
5 | 2013-10-18T10:19:48-07:00
6 | 2013-10-18T10:19:48-07:00
7 |
8 | 2013-10-18
9 | 5-487-00
10 |
11 | 336.00
12 |
13 | 134
14 | Bill
15 |
16 |
17 | 38
18 | CreditCard
19 |
20 | 135
21 |
22 | 336.00
23 |
--------------------------------------------------------------------------------
/spec/fixtures/tax_rate.xml:
--------------------------------------------------------------------------------
1 |
2 | 9
3 | 0
4 |
5 | 2013-12-11T10:59:51-08:00
6 | 2013-12-11T10:59:51-08:00
7 |
8 | Santa Clara County
9 | Sales Tax
10 | true
11 | 0.5
12 | 3
13 |
14 | 17.5
15 | 1970-01-01T00:00:00-08:00
16 | 2014-06-30T00:00:00-07:00
17 |
18 | NONE
19 | ReadOnly
20 |
21 |
--------------------------------------------------------------------------------
/spec/fixtures/time_activity.xml:
--------------------------------------------------------------------------------
1 |
2 | 1255
3 | 0
4 |
5 | 2014-02-05T07:17:08-08:00
6 | 2014-02-05T07:17:08-08:00
7 |
8 | 2014-02-05
9 | Employee
10 | 66
11 | 123
12 | 49
13 | 100100000000000321233
14 | Billable
15 | false
16 | 115
17 | 1
18 | 0
19 | Description 1
20 |
21 |
--------------------------------------------------------------------------------
/spec/fixtures/tax_rates.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1
5 | 0
6 |
7 | 2013-03-15T17:05:13-07:00
8 | 2013-03-15T17:05:13-07:00
9 |
10 | Mountain View
11 | Sales Tax
12 | true
13 | 10
14 | 1
15 | NONE
16 | ReadOnly
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/credit_card_payment.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class CreditCardPayment < BaseModel
4 | xml_accessor :number, :from => 'Number'
5 | xml_accessor :type, :from => 'Type'
6 | xml_accessor :name_on_account, :from => 'NameOnAcct'
7 | xml_accessor :expiry_month, :from => 'CcExpiryMonth', :as => Integer
8 | xml_accessor :expiry_year, :from => 'CcExpiryYear', :as => Integer
9 | xml_accessor :bill_address, :from => 'BillAddrStreet'
10 | xml_accessor :postal_code, :from => 'PostalCode'
11 | xml_accessor :commercial_card_code, :from => 'CommercialCardCode'
12 | xml_accessor :txn_mode, :from => 'CCTxnMode'
13 | xml_accessor :txn_type, :from => 'CCTxnType'
14 | xml_accessor :previous_txn_id, :from => 'PrevCCTransId'
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/fixtures/transfers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 148
5 | 0
6 |
7 | 2016-02-11T06:00:44-08:00
8 | 2016-02-11T06:00:44-08:00
9 |
10 | 2016-02-11
11 | USD
12 | BABABABAB
13 | 36
14 | 35
15 | 250.00
16 |
17 |
18 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/budget_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::Budget" do
2 |
3 | it "parse from XML" do
4 | xml = fixture("budget.xml")
5 | budget = Quickbooks::Model::Budget.from_xml(xml)
6 |
7 | budget.sync_token.should == 1
8 | budget.active?.should == true
9 | budget.line_items.count.should == 192
10 |
11 | line1 = budget.line_items[0]
12 | line1.date.should == Date.parse("2015-01-01")
13 | line1.amount.should == '0'
14 | line1.account_ref.value.should == '14'
15 | line1.account_ref.name.should == 'Miscellaneous'
16 |
17 | line2 = budget.line_items[23]
18 | line2.date.should == Date.parse("2015-12-01")
19 | line2.amount.should == '475.00'
20 | line2.account_ref.value.should == '45'
21 | line2.account_ref.name.should == 'Landscaping Services'
22 | end
23 |
24 | end
25 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/fault_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Quickbooks::Model::Fault do
4 | it "should parse from xml" do
5 | fault_xml = fixture("fault.xml")
6 | fault = Quickbooks::Model::Fault.from_xml(fault_xml)
7 | fault.errors.size.should == 2
8 | first_error = fault.errors.first
9 | first_error.code.should == "2050"
10 | first_error.element.should == "firstname"
11 | first_error.message.should == "Length exceeds limit"
12 | first_error.detail.should == "Length of the field exceeds 21 chars"
13 | last_error = fault.errors.last
14 | last_error.code.should == "2080"
15 | last_error.element.should == "postalcode"
16 | last_error.message.should == "Illegal number format"
17 | last_error.detail.should == "ZipCode should be a number with at least 5 digits"
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/budget_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::Budget" do
2 | before(:all) do
3 | construct_service :budget
4 | end
5 |
6 | it "can query for budgets" do
7 | xml = fixture("budgets.xml")
8 | model = Quickbooks::Model::Invoice
9 |
10 | stub_request(:get, @service.url_for_query, ["200", "OK"], xml)
11 | budgets = @service.query
12 | budgets.entries.count.should == 2
13 | first_budget = budgets.entries[0]
14 | first_budget.id.should == "1"
15 | end
16 |
17 | it "can fetch a Budget by ID" do
18 | xml = fixture("fetch_budget_by_id.xml")
19 | model = Quickbooks::Model::Budget
20 | stub_request(:get, "#{@service.url_for_resource(model::REST_RESOURCE)}/1", ["200", "OK"], xml)
21 | budget = @service.fetch_by_id(1)
22 | budget.name.should == "TestBudgie"
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_bill_payment_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 623
4 | 1
5 |
6 | 2015-12-15T00:00:00-08:00
7 | 2015-12-15T00:00:00-08:00
8 |
9 | 1
10 | 2015-12-15
11 | Acct. 1JK90
12 | 32
13 | Check
14 |
15 | 133
16 | NotSet
17 |
18 | 110.00
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/tax_line_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class TaxLineDetail < BaseModel
4 |
5 | xml_accessor :percent_based?, :from => 'PercentBased'
6 | xml_accessor :net_amount_taxable, :from => 'NetAmountTaxable', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
7 | xml_accessor :tax_inclusive_amount, :from => 'TaxInclusiveAmount', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
8 | xml_accessor :override_delta_amount, :from => 'OverrideDeltaAmount', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
9 | xml_accessor :tax_percent, :from => 'TaxPercent', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
10 | xml_accessor :tax_rate_ref, :from => 'TaxRateRef', :as => BaseReference
11 |
12 | reference_setters :tax_rate_ref
13 |
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/spec/fixtures/term_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 11
5 | 2
6 |
7 | 2013-07-11T17:46:39-07:00
8 | 2013-07-11T17:46:40-07:00
9 |
10 | null-1373590184786
11 | true
12 | DATE_DRIVEN
13 | 20.0000000
14 | 1
15 | 2
16 | 3
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/preferences_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::Preferences" do
2 | it "should parse from XML" do
3 | xml = fixture("preferences.xml")
4 | preferences = Quickbooks::Model::Preferences.from_xml(xml)
5 |
6 | preferences.accounting_info.customer_terminology.should == "Customers"
7 | preferences.currency.home_currency.should == "USD"
8 |
9 | preferences.tax.using_sales_tax?.should be_false
10 | preferences.tax.partner_tax_enabled?.should be_false
11 | preferences.time_tracking.bill_customers?.should be_true
12 |
13 | preferences.email_messages.invoice_message.subject.should == "Invoice from Demo Company"
14 | preferences.email_messages.estimate_message.message.should include("We look forward to working with you.")
15 |
16 | preferences.other_prefs["SalesFormsPrefs.DefaultItem"].should == "1"
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/item_change_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::ItemChange" do
2 | let(:service) { construct_service :item_change }
3 |
4 | it "can query for items" do
5 | xml = fixture("item_changes.xml")
6 | model = Quickbooks::Model::ItemChange
7 |
8 | stub_request(:get, service.url_for_query, ["200", "OK"], xml)
9 | items = service.query
10 | items.entries.count.should == 1
11 |
12 | first_item = items.entries.first
13 | first_item.status.should == 'Deleted'
14 | first_item.id.should == "39"
15 |
16 | first_item.meta_data.should_not be_nil
17 | first_item.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
18 | end
19 |
20 | describe "#url_for_query" do
21 | subject { service.url_for_query }
22 | it { should eq "#{service.url_for_base}/cdc?entities=Item" }
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/payment.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Payment < BaseService
4 |
5 | def delete(payment)
6 | delete_by_query_string(payment)
7 | end
8 |
9 | def void(entity, options = {})
10 | raise Quickbooks::InvalidModelException.new(entity.errors.full_messages.join(',')) unless entity.valid?
11 | xml = entity.to_xml_ns(options)
12 | url = "#{url_for_resource(model::REST_RESOURCE)}?include=void"
13 |
14 | response = do_http_post(url, valid_xml_document(xml), {})
15 | if response.code.to_i == 200
16 | model.from_xml(parse_singular_entity_response(model, response.plain_body))
17 | else
18 | false
19 | end
20 | end
21 |
22 | private
23 |
24 | def model
25 | Quickbooks::Model::Payment
26 | end
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/service_crud_json.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | module ServiceCrudJSON
4 |
5 | def fetch_by_id(id, params = {})
6 | raise NotImplementedError
7 | end
8 |
9 | def create(entity, options = {})
10 | raise Quickbooks::InvalidModelException.new(entity.errors.full_messages.join(',')) unless entity.valid?
11 | response = do_http(:post, url_for_resource(model.resource_for_singular), entity.to_json, options)
12 | if response.code.to_i == 200
13 | JSON.parse(response.plain_body)
14 | else
15 | nil
16 | end
17 | end
18 | alias :update :create
19 |
20 | def delete
21 | raise NotImplementedError
22 | end
23 |
24 | def delete_by_query_string
25 | raise NotImplementedError
26 | end
27 |
28 | end
29 | end
30 | end
31 |
32 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/upload_spec.rb:
--------------------------------------------------------------------------------
1 | describe Quickbooks::Service::Upload do
2 | before(:all) do
3 | construct_service :upload
4 | end
5 |
6 | it "can create an upload" do
7 | xml = fixture("upload_create_response.xml")
8 | stub_request(:post, @service.url_for_resource('upload'), ["200", "OK"], xml, {}, true)
9 |
10 | attachable = Quickbooks::Model::Attachable.new
11 | attachable.file_name = "monkey.jpg"
12 | attachable.note = "A note"
13 | entity = Quickbooks::Model::EntityRef.new
14 | entity.type = 'Customer'
15 | entity.value = 3
16 | attachable.attachable_ref = Quickbooks::Model::AttachableRef.new(entity)
17 |
18 | path = File.join(fixture_path, "monkey.jpg")
19 | mime = "image/jpeg"
20 |
21 | response = @service.upload(path, mime, attachable)
22 |
23 | response.note.should == attachable.note
24 | end
25 |
26 | end
27 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/discount_line_detail.rb:
--------------------------------------------------------------------------------
1 | # https://developer.intuit.com/docs/0025_quickbooksapi/0050_data_services/030_entity_services_reference/invoice#DiscountLineDetail
2 | module Quickbooks
3 | module Model
4 | class DiscountLineDetail < BaseModel
5 | xml_accessor :discount_ref, :from => 'DiscountRef', :as => BaseReference
6 | xml_accessor :percent_based?, :from => 'PercentBased'
7 | xml_accessor :discount_percent, :from => 'DiscountPercent', :as => BigDecimal, :to_xml => to_xml_big_decimal
8 | xml_accessor :discount_account_ref, :from => 'DiscountAccountRef', :as => BaseReference
9 | xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
10 | xml_accessor :tax_code_ref, :from => 'TaxCodeRef', :as => BaseReference
11 |
12 | reference_setters :tax_code_ref, :class_ref, :discount_ref, :discount_account_ref
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/class_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::Class" do
2 |
3 | it "parse from XML" do
4 | xml = fixture("class.xml")
5 | classs = Quickbooks::Model::Class.from_xml(xml)
6 | classs.sync_token.should == 1
7 | classs.name.should == 'Design'
8 | classs.sub_class?.should == false
9 | classs.fully_qualified_name.should == 'Design'
10 | classs.active?.should == true
11 | end
12 |
13 | it "can't assign a bad name" do
14 | classs = Quickbooks::Model::Class.new
15 | classs.name = "My:Class"
16 | classs.valid?
17 | classs.errors.keys.should include(:name)
18 | end
19 |
20 | it "cannot update an invalid model" do
21 | classs = Quickbooks::Model::Class.new
22 | classs.valid_for_update?.should == false
23 | classs.to_xml_ns.should match('Class')
24 | classs.errors.keys.should include(:sync_token)
25 | end
26 |
27 | end
28 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/tax_code.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class TaxCode < BaseModel
4 | XML_COLLECTION_NODE = "TaxCode"
5 | XML_NODE = "TaxCode"
6 | REST_RESOURCE = "taxcode"
7 |
8 | xml_accessor :id, :from => "Id"
9 | xml_accessor :sync_token, :from => "SyncToken", :as => Integer
10 | xml_accessor :meta_data, :from => "MetaData", :as => MetaData
11 | xml_accessor :name, :from => "Name"
12 | xml_accessor :description, :from => "Description"
13 | xml_accessor :active?, :from => "Active"
14 | xml_accessor :taxable?, :from => "Taxable"
15 | xml_accessor :tax_group?, :from => "TaxGroup"
16 | xml_accessor :sales_tax_rate_list, :from => "SalesTaxRateList", :as => SalesTaxRateList
17 | xml_accessor :purchase_tax_rate_list, :from => "PurchaseTaxRateList", :as => PurchaseTaxRateList
18 |
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/payment_method.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class PaymentMethod < BaseService
4 |
5 | def fetch_by_name(name)
6 | self.query(search_name_query(name)).entries.first
7 | end
8 |
9 | def search_name_query(name)
10 | "SELECT * FROM PaymentMethod WHERE Name = '#{name}'"
11 | end
12 |
13 | def update(entity, options = {})
14 | raise Quickbooks::InvalidModelException.new('Payment Method sparse update is not supported by Intuit at this time') if options[:sparse] && options[:sparse] == true
15 | super(entity, options)
16 | end
17 |
18 | def delete(department)
19 | department.active = false
20 | update(department, :sparse => false)
21 | end
22 |
23 | private
24 |
25 | def model
26 | Quickbooks::Model::PaymentMethod
27 | end
28 | end
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/vendor_change_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::VendorChange" do
2 | let(:service) { construct_service :vendor_change }
3 |
4 | it "can query for vendors" do
5 | xml = fixture("vendor_changes.xml")
6 | model = Quickbooks::Model::VendorChange
7 |
8 | stub_request(:get, service.url_for_query, ["200", "OK"], xml)
9 | vendors = service.query
10 | vendors.entries.count.should == 1
11 |
12 | first_vendor = vendors.entries.first
13 | first_vendor.status.should == 'Deleted'
14 | first_vendor.id.should == "39"
15 |
16 | first_vendor.meta_data.should_not be_nil
17 | first_vendor.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
18 | end
19 |
20 | describe "#url_for_query" do
21 | subject { service.url_for_query }
22 | it { should eq "#{service.url_for_base}/cdc?entities=Vendor" }
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_time_activity_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1
4 | 0
5 |
6 | 2014-02-05T07:17:08-08:00
7 | 2014-02-05T07:17:08-08:00
8 |
9 | 2014-02-05
10 | Employee
11 | 66
12 | 123
13 | 49
14 | Billable
15 | false
16 | 115
17 | 1
18 | 30
19 | Description 1
20 |
21 |
22 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/transaction_tax_detail_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::TransactionTaxDetail" do
2 | it "allows setting of the TxnTaxCodeRef via #txn_tax_code_ref_id=" do
3 | transaction_tax_detail = Quickbooks::Model::TransactionTaxDetail.new
4 | transaction_tax_detail.total_tax = 42
5 | transaction_tax_detail.txn_tax_code_id = 42
6 | transaction_tax_detail.txn_tax_code_ref.value.should == 42
7 | end
8 |
9 | it "total tax should be a decimal/float" do
10 | transaction_tax_detail = Quickbooks::Model::TransactionTaxDetail.new
11 | transaction_tax_detail.total_tax = 42
12 | transaction_tax_detail.to_xml.at_css('TotalTax').content.should == '42.0'
13 | end
14 |
15 | it "total tax should not be included if not set" do
16 | transaction_tax_detail = Quickbooks::Model::TransactionTaxDetail.new
17 | transaction_tax_detail.to_xml.should_not =~ /TotalTax/
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/invoice_change_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::InvoiceChange" do
2 | let(:service) { construct_service :invoice_change }
3 |
4 | it "can query for invoices" do
5 | xml = fixture("invoice_changes.xml")
6 | model = Quickbooks::Model::InvoiceChange
7 |
8 | stub_request(:get, service.url_for_query, ["200", "OK"], xml)
9 | invoices = service.query
10 | invoices.entries.count.should == 1
11 |
12 | first_invoice = invoices.entries.first
13 | first_invoice.status.should == 'Deleted'
14 | first_invoice.id.should == "39"
15 |
16 | first_invoice.meta_data.should_not be_nil
17 | first_invoice.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
18 | end
19 |
20 | describe "#url_for_query" do
21 | subject { service.url_for_query }
22 | it { should eq "#{service.url_for_base}/cdc?entities=Invoice" }
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/payment_change_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::PaymentChange" do
2 | let(:service) { construct_service :payment_change }
3 |
4 | it "can query for payments" do
5 | xml = fixture("payment_changes.xml")
6 | model = Quickbooks::Model::PaymentChange
7 |
8 | stub_request(:get, service.url_for_query, ["200", "OK"], xml)
9 | payments = service.query
10 | payments.entries.count.should == 1
11 |
12 | first_payment = payments.entries.first
13 | first_payment.status.should == 'Deleted'
14 | first_payment.id.should == "39"
15 |
16 | first_payment.meta_data.should_not be_nil
17 | first_payment.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
18 | end
19 |
20 | describe "#url_for_query" do
21 | subject { service.url_for_query }
22 | it { should eq "#{service.url_for_base}/cdc?entities=Payment" }
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/spec/fixtures/payments.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 8748
5 | 1
6 |
7 | 2013-07-11T17:51:41-07:00
8 | 2013-07-11T17:51:43-07:00
9 |
10 | 2013-07-11
11 | H60jzmw0Uq
12 | 25342
13 | 4
14 | 40.00
15 | 40.00
16 | false
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/spec/fixtures/payment_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 8748
5 | 1
6 |
7 | 2013-07-11T17:51:41-07:00
8 | 2013-07-11T17:51:43-07:00
9 |
10 | 2013-07-11
11 | H60jzmw0Uq
12 | 25342
13 | 4
14 | 40.00
15 | 40.00
16 | false
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/budget.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class Budget < BaseModel
4 | include HasLineItems
5 |
6 | XML_COLLECTION_NODE = "Budget"
7 | XML_NODE = "Budget"
8 | REST_RESOURCE = 'budget'
9 |
10 | xml_name XML_NODE
11 |
12 | xml_accessor :id, :from => 'Id'
13 | xml_accessor :name, :from => 'Name'
14 | xml_accessor :type, :from => 'BudgetType'
15 | xml_accessor :entry_type, :from => 'BudgetEntryType'
16 | xml_accessor :start_date, :from => 'StartDate'
17 | xml_accessor :end_date, :from => 'EndDate'
18 | xml_accessor :active?, :from => 'Active'
19 | xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
20 | xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
21 |
22 | xml_accessor :line_items, :from => 'BudgetDetail', :as => [BudgetLineItem]
23 |
24 | reference_setters
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/customer_change_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::CustomerChange" do
2 | let(:service) { construct_service :customer_change }
3 |
4 | it "can query for customers" do
5 | xml = fixture("customer_changes.xml")
6 | model = Quickbooks::Model::CustomerChange
7 |
8 | stub_request(:get, service.url_for_query, ["200", "OK"], xml)
9 | customers = service.query
10 | customers.entries.count.should == 1
11 |
12 | first_customer = customers.entries.first
13 | first_customer.status.should == 'Deleted'
14 | first_customer.id.should == "39"
15 |
16 | first_customer.meta_data.should_not be_nil
17 | first_customer.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
18 | end
19 |
20 | describe "#url_for_query" do
21 | subject { service.url_for_query }
22 | it { should eq "#{service.url_for_base}/cdc?entities=Customer" }
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_account_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1
4 | 0
5 |
6 | 2013-11-15T12:43:10-08:00
7 | 2013-11-15T12:43:10-08:00
8 |
9 | Sales of Product Income
10 | false
11 | Sales of Product Income
12 | true
13 | Revenue
14 | Income
15 | SalesOfProductIncome
16 | 0
17 | 0
18 | USD
19 |
20 |
21 |
--------------------------------------------------------------------------------
/spec/fixtures/tax_code.xml:
--------------------------------------------------------------------------------
1 |
2 | 2
3 | 0
4 |
5 | 2014-02-19T12:08:08-08:00
6 | 2014-02-19T12:08:08-08:00
7 |
8 | Stupid tax
9 | Stupid tax
10 | true
11 | true
12 | true
13 |
14 |
15 | 1
16 | TaxOnAmount
17 | 0
18 |
19 |
20 |
21 |
22 | 2
23 | TaxOnAmount
24 | 0
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/spec/fixtures/bill_payments.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 623
5 | 1
6 |
7 | 2015-12-15T00:00:00-08:00
8 | 2015-12-15T00:00:00-08:00
9 |
10 | 1
11 | 2015-12-15
12 | Acct. 1JK90
13 | 32
14 | Check
15 |
16 | 133
17 | NotSet
18 |
19 | 110.00
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/sales_item_line_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class SalesItemLineDetail < BaseModel
4 | xml_accessor :item_ref, :from => 'ItemRef', :as => BaseReference
5 | xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
6 | xml_accessor :unit_price, :from => 'UnitPrice', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
7 | xml_accessor :rate_percent, :from => 'RatePercent', :as => BigDecimal, :to_xml => to_xml_big_decimal
8 | xml_accessor :price_level_ref, :from => 'PriceLevelRef', :as => BaseReference
9 | xml_accessor :quantity, :from => 'Qty', :as => BigDecimal, :to_xml => Proc.new { |val| val.to_f }
10 | xml_accessor :tax_code_ref, :from => 'TaxCodeRef', :as => BaseReference
11 | xml_accessor :service_date, :from => 'ServiceDate', :as => Date
12 |
13 | reference_setters :item_ref, :class_ref, :price_level_ref, :tax_code_ref
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/spec/fixtures/bill_line_item_expense.xml:
--------------------------------------------------------------------------------
1 |
2 | 17
3 | 2017-12-16
4 |
5 | 1
6 | 700.00
7 | ItemBasedExpenseLineDetail
8 |
9 | 1001
10 | 100000000000128320
11 | 9.79
12 | NON
13 |
14 | true
15 | 10
16 |
17 |
18 |
19 | 4
20 | 38
21 | 755.12
22 | 2018-12-26
23 |
24 |
--------------------------------------------------------------------------------
/spec/fixtures/upload_create_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2700000000002443649
5 | 0
6 |
7 | 2015-02-12T08:56:11-08:00
8 | 2015-02-12T08:56:11-08:00
9 |
10 | monkey.jpg
11 | /v3/company/12345/download/2700000000002443649
12 | https://intuit-qbo-prod-15.s3.amazonaws.com/1002341430%2Fattachments%2Fmonkey-1423760170483.jpgD
13 | 105840
14 | image/jpeg
15 | A note
16 | /v3/company/12345/attachable-thumbnail/2700000000002443649
17 |
18 |
19 |
--------------------------------------------------------------------------------
/spec/fixtures/vendor_credit.xml:
--------------------------------------------------------------------------------
1 |
2 | 11
3 | 0
4 |
5 | 2013-10-10T11:16:32-07:00
6 | 2013-10-10T11:16:32-07:00
7 |
8 | 2013-09-20
9 |
10 | 1
11 | 90.00
12 | AccountBasedExpenseLineDetail
13 |
14 | 2
15 | 8
16 | Billable
17 | TAX
18 |
19 |
20 | 5
21 | 38
22 | 90.00
23 |
24 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/company_info_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::CompanyInfo" do
2 | before(:all) do
3 | construct_service :company_info
4 | end
5 |
6 | it "can query for company info" do
7 | xml = fixture("company_info_query.xml")
8 | model = Quickbooks::Model::CompanyInfo
9 |
10 | stub_request(:get, @service.url_for_query, ["200", "OK"], xml)
11 | company_info_query = @service.query
12 | company_info_query.entries.count.should == 1
13 |
14 | company_info = company_info_query.entries.first
15 | company_info.company_name.should == 'Acme Corp.'
16 | end
17 |
18 | it "can fetch company info by ID" do
19 | xml = fixture("fetch_company_info_by_id.xml")
20 | model = Quickbooks::Model::CompanyInfo
21 | stub_request(:get, "#{@service.url_for_resource(model::REST_RESOURCE)}/1", ["200", "OK"], xml)
22 | company_info = @service.fetch_by_id(1)
23 | company_info.company_name.should == "Acme Corp."
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/credit_memo_change_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::CreditMemoChange" do
2 | let(:service) { construct_service :credit_memo_change }
3 |
4 | it "can query for credit memos" do
5 | xml = fixture("credit_memo_changes.xml")
6 | model = Quickbooks::Model::CreditMemoChange
7 |
8 | stub_request(:get, service.url_for_query, ["200", "OK"], xml)
9 | credit_memos = service.query
10 | credit_memos.entries.count.should == 1
11 |
12 | first_credit_memo = credit_memos.entries.first
13 | first_credit_memo.status.should == 'Deleted'
14 | first_credit_memo.id.should == "39"
15 |
16 | first_credit_memo.meta_data.should_not be_nil
17 | first_credit_memo.meta_data.last_updated_time.should == DateTime.parse("2014-12-08T19:36:24-08:00")
18 | end
19 |
20 | describe "#url_for_query" do
21 | subject { service.url_for_query }
22 | it { should eq "#{service.url_for_base}/cdc?entities=CreditMemo" }
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/item.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Item < BaseService
4 |
5 | def delete(item)
6 | item.active = false
7 | update(item, :sparse => true)
8 | end
9 |
10 | def url_for_resource(resource)
11 | url = super(resource)
12 | "#{url}?minorversion=#{Quickbooks::Model::Item::MINORVERSION}"
13 | end
14 |
15 | def fetch_by_id(id, params = {})
16 | url = "#{url_for_base}/item/#{id}?minorversion=#{Quickbooks::Model::Item::MINORVERSION}"
17 | fetch_object(model, url, params)
18 | end
19 |
20 | def url_for_query(query = nil, start_position = 1, max_results = 20, options = {})
21 | url = super(query, start_position, max_results, options)
22 | "#{url}&minorversion=#{Quickbooks::Model::Item::MINORVERSION}"
23 | end
24 |
25 | private
26 |
27 | def model
28 | Quickbooks::Model::Item
29 | end
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/transfer.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class Transfer < BaseModel
4 | XML_COLLECTION_NODE = "Transfer"
5 | XML_NODE = "Transfer"
6 | REST_RESOURCE = 'transfer'
7 |
8 | xml_accessor :id, :from => 'Id'
9 | xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
10 | xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
11 | xml_accessor :txn_date, :from => 'TxnDate', :as => Date
12 | xml_accessor :currency_ref, :from => 'CurrencyRef', :as => BaseReference
13 | xml_accessor :private_note, :from => 'PrivateNote'
14 | xml_accessor :from_account_ref, :from => 'FromAccountRef', :as => BaseReference
15 | xml_accessor :to_account_ref, :from => 'ToAccountRef', :as => BaseReference
16 | xml_accessor :amount, :from => 'Amount', :as => BigDecimal, :to_xml => to_xml_big_decimal
17 |
18 | reference_setters :currency_ref, :to_account_ref, :from_account_ref
19 | end
20 | end
21 | end
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/custom_field_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::CustomField" do
2 |
3 | it "parse from XML as String" do
4 | xml = fixture("custom_field_string.xml")
5 | field = Quickbooks::Model::CustomField.from_xml(xml)
6 | field.name.should == "SalesAssociate"
7 | field.type.should == "StringType"
8 | field.string_value.should == "Miller"
9 | end
10 |
11 | it "parse from XML as Date" do
12 | xml = fixture("custom_field_date.xml")
13 | field = Quickbooks::Model::CustomField.from_xml(xml)
14 | field.name.should == "LastUpdated"
15 | field.type.should == "DateType"
16 | field.date_value.should == Date.civil(2013, 4, 4)
17 | end
18 |
19 | it "parse from XML as Number" do
20 | xml = fixture("custom_field_number.xml")
21 | field = Quickbooks::Model::CustomField.from_xml(xml)
22 | field.name.should == "NumberOfWatermelons"
23 | field.type.should == "NumberType"
24 | field.number_value.should == 43
25 | end
26 |
27 | end
--------------------------------------------------------------------------------
/lib/quickbooks/model/payment_method.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class PaymentMethod < BaseModel
4 | REST_RESOURCE = 'paymentmethod'
5 | XML_COLLECTION_NODE = "PaymentMethod"
6 | XML_NODE = "PaymentMethod"
7 | include NameEntity::PermitAlterations
8 |
9 | CREDIT_CARD = "CREDIT_CARD"
10 | NON_CREDIT_CARD = "NON_CREDIT_CARD"
11 |
12 | PAYMENT_METHOD_TYPES = [CREDIT_CARD, NON_CREDIT_CARD]
13 |
14 | xml_accessor :id, :from => 'Id'
15 | xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
16 | xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
17 | xml_accessor :name, :from => 'Name'
18 | xml_accessor :type, :from => 'Type'
19 | xml_accessor :active?, :from => 'Active'
20 | xml_accessor :amount, :from => 'Amount', :as => BigDecimal, :to_xml => to_xml_big_decimal
21 |
22 | validates_inclusion_of :type, :in => PAYMENT_METHOD_TYPES, :allow_nil => true
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/spec/fixtures/purchase_create.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 160
4 | 0
5 |
6 | 2015-03-31T08:27:00-0400
7 | 2015-03-31T08:27:00-0400
8 |
9 | 2015-03-31
10 |
11 | 1
12 | Rink Liner
13 | 419.99
14 | AccountBasedExpenseLineDetail
15 |
16 | 1
17 | 28
18 | NotBillable
19 | NON
20 |
21 |
22 | 36
23 | Cash
24 | 419.99
25 |
26 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/department_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::Department" do
2 |
3 | it "parse from XML" do
4 | xml = fixture("department.xml")
5 | department = Quickbooks::Model::Department.from_xml(xml)
6 | department.sync_token.should == 0
7 | department.name.should == 'Sales Department'
8 | department.sub_department?.should == false
9 | department.fully_qualified_name.should == 'Sales Department'
10 | department.active?.should == true
11 | end
12 |
13 | it "can't assign a bad name" do
14 | department = Quickbooks::Model::Department.new
15 | department.name = "This:Department"
16 | department.valid?
17 | department.errors.keys.should include(:name)
18 | end
19 |
20 | it "cannot update an invalid model" do
21 | department = Quickbooks::Model::Department.new
22 | department.valid_for_update?.should == false
23 | department.to_xml_ns.should match('Department')
24 | department.errors.keys.should include(:sync_token)
25 | end
26 |
27 | end
28 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/refund_receipt_change_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::RefundReceiptChange" do
2 | let(:service) { construct_service :refund_receipt_change }
3 |
4 | it "can query for refund_receipts" do
5 | xml = fixture("refund_receipt_changes.xml")
6 | model = Quickbooks::Model::RefundReceiptChange
7 |
8 | stub_request(:get, service.url_for_query, ["200", "OK"], xml)
9 | refund_receipts = service.query
10 | refund_receipts.entries.count.should == 1
11 |
12 | first_refund_receipt = refund_receipts.entries.first
13 | first_refund_receipt.status.should == 'Deleted'
14 | first_refund_receipt.id.should == "40"
15 |
16 | first_refund_receipt.meta_data.should_not be_nil
17 | first_refund_receipt.meta_data.last_updated_time.should == DateTime.parse("2014-12-09T19:30:24-08:00")
18 | end
19 |
20 | describe "#url_for_query" do
21 | subject { service.url_for_query }
22 | it { should eq "#{service.url_for_base}/cdc?entities=RefundReceipt" }
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/exchange_rate.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class ExchangeRate < BaseModel
4 | XML_COLLECTION_NODE = "ExchangeRate"
5 | XML_NODE = "ExchangeRate"
6 | REST_RESOURCE = "exchangerate"
7 |
8 | xml_accessor :id, :from => "Id"
9 | xml_accessor :sync_token, :from => "SyncToken", :as => Integer
10 | xml_accessor :meta_data, :from => "MetaData", :as => MetaData
11 |
12 | xml_accessor :custom_fields, :from => 'CustomField', :as => [CustomField]
13 | xml_accessor :source_currency_code, :from => 'SourceCurrencyCode'
14 | xml_accessor :target_currency_code, :from => 'TargetCurrencyCode'
15 | xml_accessor :rate, :from => 'Rate', :as => BigDecimal, :to_xml => to_xml_big_decimal
16 | xml_accessor :as_of_date, :from => 'AsOfDate', :as => Date
17 |
18 | validates_presence_of :source_currency_code, :rate, :as_of_date
19 | validates_length_of :source_currency_code, :is => 3
20 | validates_length_of :target_currency_code, :is => 3
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/spec/fixtures/fetch_deposit_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 62
4 | 0
5 |
6 | 2014-11-11T15:22:31-08:00
7 | 2014-11-11T15:22:31-08:00
8 |
9 | Deposit Note
10 | 2014-11-11
11 |
12 | 78
13 |
14 | 38
15 | SalesReceipt
16 | 0
17 |
18 |
19 |
20 | 140
21 |
22 | 47
23 | SalesReceipt
24 | 0
25 |
26 |
27 | 35
28 | 218.75
29 |
30 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/transfer_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::Transfer" do
2 | it "parse from XML" do
3 | xml = fixture("transfer.xml")
4 | transfer = Quickbooks::Model::Transfer.from_xml(xml)
5 | transfer.id.should == "148"
6 | transfer.sync_token.should == 0
7 |
8 | transfer.meta_data.should_not be_nil
9 | transfer.meta_data.create_time.should == DateTime.parse("2016-02-11T06:00:44-08:00")
10 | transfer.meta_data.last_updated_time.should == DateTime.parse("2016-02-11T06:00:44-08:00")
11 | transfer.txn_date.should == Date.civil(2016, 2, 11)
12 | transfer.currency_ref.name.should == "United States Dollar"
13 | transfer.currency_ref.value.should == "USD"
14 | transfer.private_note.should == "Important notes to explain this transaction"
15 | transfer.from_account_ref.name.should == "Savings"
16 | transfer.from_account_ref.value.should == "36"
17 | transfer.to_account_ref.name.should == "Checking"
18 | transfer.to_account_ref.value.should == "35"
19 | transfer.amount.should == 250.00
20 | end
21 | end
--------------------------------------------------------------------------------
/lib/quickbooks/util/query_builder.rb:
--------------------------------------------------------------------------------
1 | require 'uri'
2 |
3 | module Quickbooks
4 | module Util
5 | class QueryBuilder
6 |
7 | VALUE_QUOTE = "'"
8 |
9 | def initialize
10 | end
11 |
12 | def clause(field, operator, value)
13 | value = case value
14 | when DateTime, Time
15 | value.iso8601
16 | when Date
17 | value.strftime('%Y-%m-%d')
18 | when Array
19 | value = value.map{|v| v.to_s.gsub("'", "\\\\'") }
20 | else
21 | # escape single quotes with an escaped backslash
22 | value = value.gsub("'", "\\\\'")
23 | end
24 |
25 | if operator.downcase == 'in' && value.is_a?(Array)
26 | value = value.map{|v| "#{VALUE_QUOTE}#{v}#{VALUE_QUOTE}"}
27 | "#{field} #{operator} (#{value.join(', ')})"
28 | else
29 | "#{field} #{operator} #{VALUE_QUOTE}#{value}#{VALUE_QUOTE}"
30 | end
31 | end
32 |
33 | end
34 | end
35 | end
36 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/class.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class Class < BaseModel
4 | XML_COLLECTION_NODE = "Class"
5 | XML_NODE = "Class"
6 | REST_RESOURCE = 'class'
7 | include NameEntity::Quality
8 | include NameEntity::PermitAlterations
9 |
10 | xml_name XML_NODE
11 | xml_accessor :id, :from => 'Id'
12 | xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
13 | xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
14 | xml_accessor :name, :from => 'Name'
15 | xml_accessor :sub_class, :from => 'SubClass'
16 | xml_accessor :parent_ref, :from => 'ParentRef', :as => BaseReference
17 | xml_accessor :fully_qualified_name, :from => 'FullyQualifiedName' # ReadOnly
18 | xml_accessor :active?, :from => 'Active'
19 |
20 | reference_setters :parent_ref
21 |
22 | #== Validations
23 | validate :names_cannot_contain_invalid_characters
24 |
25 | def sub_class?
26 | sub_class.to_s == 'true'
27 | end
28 |
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/attachable.rb:
--------------------------------------------------------------------------------
1 | require 'quickbooks/model/attachable_ref'
2 |
3 | module Quickbooks
4 | module Model
5 | class Attachable < BaseModel
6 |
7 | XML_COLLECTION_NODE = "Attachable"
8 | XML_NODE = "Attachable"
9 | REST_RESOURCE = 'attachable'
10 |
11 | xml_accessor :id, :from => 'Id'
12 | xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
13 | xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
14 | xml_accessor :attachable_ref, :as => AttachableRef
15 | xml_accessor :file_name
16 | xml_accessor :file_access_uri
17 | xml_accessor :temp_download_uri
18 | xml_accessor :size
19 | xml_accessor :content_type
20 | xml_accessor :category
21 | xml_accessor :lat
22 | xml_accessor :long
23 | xml_accessor :place_name
24 | xml_accessor :note
25 | xml_accessor :tag
26 | xml_accessor :thumbnail_file_access_uri
27 | xml_accessor :thumbnail_temp_download_uri
28 |
29 | reference_setters :attachable_ref
30 |
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/access_token_response.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class AccessTokenResponse < BaseModel
4 | xml_convention :camelcase
5 | xml_accessor :error_code, :from => 'ErrorCode'
6 | xml_accessor :error_message, :from => 'ErrorMessage'
7 | xml_accessor :token, :from => 'OAuthToken'
8 | xml_accessor :secret, :from => 'OAuthTokenSecret'
9 | xml_accessor :server_time, :from => 'ServerTime', :as => Time
10 |
11 | def error?
12 | error_code.to_i != 0
13 | end
14 |
15 | end
16 | end
17 | end
18 |
19 | =begin
20 |
21 |
22 |
23 | 0
24 | 2012-01-04T19:21:21.0782072Z
25 | qye2eIdQ5H5yMyrlJflUWh712xfFXjyNnW1MfbC0rz04TfCP
26 | cyDeUNQTkFzoR0KkDn7viN6uLQxWTobeEUKW7I79
27 |
28 |
29 | =end
--------------------------------------------------------------------------------
/spec/fixtures/purchase_credit_card_response.xml:
--------------------------------------------------------------------------------
1 |
2 | 6834
3 | 0
4 |
5 | 2013-04-23T18:44:42-07:00
6 | 2013-04-23T18:44:42-07:00
7 |
8 | 2013-01-04
9 |
10 | 1
11 | this is description only.
12 | 0
13 | AccountBasedExpenseLineDetail
14 |
15 | 60
16 | NotBillable
17 | NON
18 |
19 |
20 | 64
21 | CreditCard
22 | 1
23 | false
24 | 0
25 | TaxExcluded
26 |
27 |
--------------------------------------------------------------------------------
/spec/fixtures/attachables.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2700000000001439108
5 | 0
6 |
7 | 2014-08-18T09:58:06-07:00
8 | 2014-08-18T09:58:06-07:00
9 |
10 | monkey.jpg
11 | /v3/company/1002341430/download/2700000000001439108
12 | https://intuit-qbo-prod-30.s3.amazonaws.com/1002341430%2Fattachments%2Fmonkey.jpg
13 | 105840
14 | image/jpeg
15 | /v3/company/1002341430/attachable-thumbnail/2700000000001439108
16 | https://intuit-qbo-prod-30.s3.amazonaws.com/1002341430%2Fattachmentthumbnails%2Ftn_monkey.jpg
17 |
18 |
19 |
--------------------------------------------------------------------------------
/spec/support/oauth_helpers.rb:
--------------------------------------------------------------------------------
1 | module OauthHelpers
2 | def construct_oauth
3 | FakeWeb.allow_net_connect = false
4 |
5 | oauth_consumer = OAuth::Consumer.new("app_key", "app_secret", {
6 | :site => "https://oauth.intuit.com",
7 | :request_token_path => "/oauth/v1/get_request_token",
8 | :authorize_url => "https://appcenter.intuit.com/Connect/Begin",
9 | :access_token_path => "/oauth/v1/get_access_token"
10 | })
11 |
12 | OAuth::AccessToken.new(oauth_consumer, "token", "secret")
13 | end
14 |
15 | def construct_service(model, access_token=construct_oauth)
16 | @service = "Quickbooks::Service::#{model.to_s.camelcase}".constantize.new
17 | @service.access_token = access_token
18 | @service.company_id = "9991111222"
19 | @service
20 | end
21 |
22 | def construct_compact_service(model)
23 | @service = "Quickbooks::Service::#{model.to_s.camelcase}".constantize.new(access_token: construct_oauth, company_id:"9991111222")
24 | end
25 | end
26 |
27 | RSpec.configure do |config|
28 | config.include(OauthHelpers)
29 | end
30 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/department.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class Department < BaseModel
4 | XML_COLLECTION_NODE = "Department"
5 | XML_NODE = "Department"
6 | REST_RESOURCE = 'department'
7 | include NameEntity::Quality
8 | include NameEntity::PermitAlterations
9 |
10 | xml_name XML_NODE
11 | xml_accessor :id, :from => 'Id'
12 | xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
13 | xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
14 | xml_accessor :name, :from => 'Name'
15 | xml_accessor :sub_department, :from => 'SubDepartment'
16 | xml_accessor :parent_ref, :from => 'ParentRef', :as => BaseReference
17 | xml_accessor :fully_qualified_name, :from => 'FullyQualifiedName' # ReadOnly
18 | xml_accessor :active?, :from => 'Active'
19 |
20 | reference_setters :parent_ref
21 |
22 | #== Validations
23 | validate :names_cannot_contain_invalid_characters
24 |
25 | def sub_department?
26 | sub_department.to_s == 'true'
27 | end
28 |
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/quickbooks-ruby.gemspec:
--------------------------------------------------------------------------------
1 | $:.unshift File.expand_path("../lib", __FILE__)
2 | require "quickbooks/version"
3 |
4 | Gem::Specification.new do |gem|
5 | gem.name = "quickbooks-ruby"
6 | gem.version = Quickbooks::VERSION
7 |
8 | gem.author = "Cody Caughlan"
9 | gem.email = "toolbag@gmail.com"
10 | gem.homepage = "http://github.com/ruckus/quickbooks-ruby"
11 | gem.summary = "REST API to Quickbooks Online"
12 | gem.license = 'MIT'
13 | gem.description = "QBO V3 REST API to Quickbooks Online"
14 |
15 | gem.files = Dir['lib/**/*']
16 |
17 | gem.add_dependency 'oauth', '0.4.7'
18 | gem.add_dependency 'roxml', '>= 3.3.1', '< 4.1'
19 | gem.add_dependency 'nokogiri' # promiscuous mode
20 | gem.add_dependency 'activemodel' # promiscuous mode
21 | gem.add_dependency 'multipart-post' # promiscuous mode
22 |
23 | gem.add_development_dependency 'rake', '10.1.0'
24 | gem.add_development_dependency 'simplecov', '0.7.1'
25 | gem.add_development_dependency 'rr', '~> 1.0.2'
26 | gem.add_development_dependency 'rspec', '2.14.1'
27 | gem.add_development_dependency 'fakeweb', '1.3.0'
28 | end
29 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Cody Caughlan
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/account_spec.rb:
--------------------------------------------------------------------------------
1 | describe Quickbooks::Service::Account do
2 | before(:all) do
3 | construct_service :account
4 | end
5 |
6 | it "can query for accounts" do
7 | xml = fixture("accounts.xml")
8 | stub_request(:get, @service.url_for_query, ["200", "OK"], xml, {}, true)
9 |
10 | accounts = @service.query
11 | accounts.entries.count.should == 10
12 |
13 | sales = accounts.entries.first
14 | sales.name.should == 'Cost of Goods Sold'
15 | end
16 |
17 | it "can fetch an account by ID" do
18 | xml = fixture("fetch_account_by_id.xml")
19 | model = Quickbooks::Model::Account
20 | stub_request(:get, "#{@service.url_for_resource(model::REST_RESOURCE)}/1", ["200", "OK"], xml)
21 | account = @service.fetch_by_id(1)
22 |
23 | account.name.should == "Sales of Product Income"
24 | account.classification.should == Quickbooks::Model::Account::REVENUE
25 | account.tax_account?.should == nil
26 | account.currency_ref.to_s.should == 'USD'
27 | account.current_balance.should == 0
28 | account.current_balance_with_sub_accounts.should == 0
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/webapp/.env:
--------------------------------------------------------------------------------
1 | OAUTH_CLIENT_ID=Q0gp5eNzm0eBqpIwabAhqjCGwk70UTBBZF993r4xMMnXHLl7x5
2 | OAUTH_CLIENT_SECRET=i5AgJfMgyNvXhjuK0XVXp92fucieuSsBRtCdstOU
3 | OAUTH_REDIRECT_URI=https://vinoqbwc.ngrok.io/oauth2callback
4 | #OAUTH_REDIRECT_URI=http://localhost:4567/oauth2callback
5 |
6 | REALM_ID=1313827825
7 |
8 | TOKEN=eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..2x43y21fTn_VuZeGfk58IA.fVyiBbWoMbs1k-HNGHQgJy02egHln1I-vspJ5LiK1pAngbEof8Kyx9ZcXpziGZGY-1vYrdy-vAUSx9IlfDkeJUD5-9keMtGcpTtpjk3dE4pKGVixpUisN9WZwV4fBRouLofV6M1nW6FA3PQZAFYmlBIvvF8wVkIDxsDe1VV6zBbh9ueqF4Wp8bLT718e46DUXf4aLNFh_j24XSZpRwPKS88fUIbQ9FurpB70y44JO2OKl4xq5dfn5XuGCFqbDffsafi8ugSD0LLJHtAJiDTEzmYA7JQNfUmjIEQlXf2b5LMSK_L0OBvBp9a-Om2UwDzfJWEl0l48d82eb_kLXIPdgsTecJqXacpH86OTAZTCTzXm19FJ_CMpIPJ4SI7j5muLixWUWjOKKZwFxAXay6PyOremx6IJu5kseg3oEtvEk_XWfD3HSc8EvVxdChE-rlCqSH59fm0OoLffSlzrnqHaxXMZG5P1Ow-mCGTvmnPcipxQHEQvOuQ-ldXsOONTMl48rQwow4SMoC2lXyTzwT1oOxMqur3Xjw8o6WWhnaLt3mDsTS3WfjcQHIgvV5Jb09x81W1hGhs3VOv4ge01wv1sDKqGn1x1sMMt1HopVpagRB4fM3QO0Lvh7-4F5dtd9fCrydFPsw4YNCY9ajUnvP7pqdoT4QnOSvuAgWUIBzC5ccc._aM7ScFbAgqq8J-j-NGuWQ
9 | REFRESH_TOKEN=Q011524972938ScjZuzP7MgOkzY1esCekaph7cpTBwSogmdO5k
10 |
--------------------------------------------------------------------------------
/spec/fixtures/deposit.xml:
--------------------------------------------------------------------------------
1 |
2 | 155
3 | 0
4 |
5 | 2015-03-07T11:30:04-07:00
6 | 2015-03-07T11:30:04-07:00
7 |
8 | Deposit smoke test
9 | 2015-03-07
10 | USD
11 |
12 | 262
13 |
14 | 154
15 | Payment
16 | 0
17 |
18 |
19 |
20 | 1
21 | 1
22 | -62.50
23 | DepositLineDetail
24 |
25 | 58
26 | 31
27 | 1
28 |
29 |
30 | 4
31 | 200.00
32 |
33 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/upload.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Upload < BaseService
4 |
5 | XML_NODE = "AttachableResponse"
6 |
7 | # path_to_file: String - path to file
8 | # mime_type: String - the MIME type of the file, e.g. image/jpeg
9 | # attachable: Quickbooks::Model::Attachable meta-data details, can be null
10 | def upload(path_to_file, mime_type, attachable = nil)
11 | url = url_for_resource("upload")
12 | uploadIO = UploadIO.new(path_to_file, mime_type)
13 | response = do_http_file_upload(uploadIO, url, attachable)
14 | prefix = "AttachableResponse/xmlns:Attachable"
15 | if response.code.to_i == 200
16 | model.from_xml(parse_singular_entity_response(model, response.plain_body, prefix))
17 | else
18 | nil
19 | end
20 | end
21 |
22 | def download(uploadId)
23 | url = url_for_resource("download/#{uploadId}")
24 | do_http_get(url, {}, headers)
25 | end
26 |
27 | private
28 |
29 | def model
30 | Quickbooks::Model::Attachable
31 | end
32 |
33 | end
34 | end
35 | end
36 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/definition.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | module Definition
4 |
5 | def self.included(base)
6 | base.extend(ClassMethods)
7 | end
8 |
9 | module ClassMethods
10 | # https://developer.intuit.com/docs/0025_quickbooksapi/0050_data_services
11 | TRANSACTION_ENTITIES = %w{
12 | Bill
13 | BillPayment
14 | CreditMemo
15 | Estimate
16 | Invoice
17 | JournalEntry
18 | Payment
19 | Purchase
20 | PurchaseOrder
21 | RefundReceipt
22 | SalesReceipt
23 | TimeActivity
24 | VendorCredit
25 | }
26 |
27 | def is_transaction_entity?
28 | TRANSACTION_ENTITIES.include?(self.name.demodulize)
29 | end
30 |
31 | def is_name_list_entity?
32 | !self.is_transaction_entity?
33 | end
34 | end
35 |
36 | def is_transaction_entity?
37 | self.class.is_transaction_entity?
38 | end
39 |
40 | def is_name_list_entity?
41 | self.class.is_name_list_entity?
42 | end
43 |
44 | end
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/item_based_expense_line_detail.rb:
--------------------------------------------------------------------------------
1 | require 'quickbooks/model/markup_info'
2 |
3 | module Quickbooks
4 | module Model
5 | class ItemBasedExpenseLineDetail < BaseModel
6 | xml_accessor :item_ref, :from => 'ItemRef', :as => BaseReference
7 | xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
8 | xml_accessor :unit_price, :from => 'UnitPrice', :as => BigDecimal, :to_xml => to_xml_big_decimal
9 | xml_accessor :rate_percent, :from => 'RatePercent', :as => BigDecimal, :to_xml => to_xml_big_decimal
10 | xml_accessor :price_level_ref, :from => 'PriceLevelRef', :as => BaseReference
11 | xml_accessor :markup_info, :from => 'MarkupInfo', :as => MarkupInfo
12 | xml_accessor :quantity, :from => 'Qty', :as => BigDecimal, :to_xml => to_xml_big_decimal
13 | xml_accessor :tax_code_ref, :from => 'TaxCodeRef', :as => BaseReference
14 | xml_accessor :customer_ref, :from => 'CustomerRef', :as => BaseReference
15 | xml_accessor :billable_status, :from => 'BillableStatus'
16 |
17 | reference_setters :item_ref, :class_ref, :price_level_ref, :customer_ref, :tax_code_ref
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/physical_address.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class PhysicalAddress < BaseModel
4 | xml_accessor :id, :from => 'Id'
5 | xml_accessor :line1, :from => 'Line1'
6 | xml_accessor :line2, :from => 'Line2'
7 | xml_accessor :line3, :from => 'Line3'
8 | xml_accessor :line4, :from => 'Line4'
9 | xml_accessor :line5, :from => 'Line5'
10 | xml_accessor :city, :from => 'City'
11 | xml_accessor :country, :from => 'Country'
12 | xml_accessor :country_sub_division_code, :from => 'CountrySubDivisionCode'
13 | xml_accessor :postal_code, :from => 'PostalCode'
14 | xml_accessor :note, :from => 'Note'
15 | xml_accessor :lat, :from => 'Lat'
16 | xml_accessor :lon, :from => 'Long'
17 |
18 | def zip
19 | postal_code
20 | end
21 |
22 | def lat_to_f
23 | BigDecimal.new(lat)
24 | end
25 |
26 | def lon_to_f
27 | BigDecimal.new(lon)
28 | end
29 |
30 | def have_lat?
31 | lat.to_s != "INVALID"
32 | end
33 |
34 | def have_lon?
35 | lon.to_s != "INVALID"
36 | end
37 |
38 | end
39 | end
40 | end
--------------------------------------------------------------------------------
/spec/fixtures/payment_with_line_extras.xml:
--------------------------------------------------------------------------------
1 |
2 | 83
3 | 0
4 |
5 | 2017-07-17T14:26:54-07:00
6 | 2017-07-17T14:26:54-07:00
7 |
8 | 2016-09-16
9 | USD
10 |
11 | 2400.00
12 |
13 | 68
14 | Invoice
15 |
16 |
17 |
18 | txnId
19 | 68
20 |
21 |
22 | txnOpenBalance
23 | 2400.00
24 |
25 |
26 | txnReferenceNumber
27 | 1246
28 |
29 |
30 |
31 | 3
32 | 4
33 | 2400.00
34 | 0
35 | false
36 |
37 |
38 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/time_activity_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::TimeActivity" do
2 |
3 | it "parse from XML" do
4 | xml = fixture("time_activity.xml")
5 | time_activity = Quickbooks::Model::TimeActivity.from_xml(xml)
6 | time_activity.sync_token.should == 0
7 | time_activity.txn_date.should == "2014-02-05"
8 | time_activity.name_of.should == "Employee"
9 | time_activity.employee_ref.value.should == "66"
10 | time_activity.employee_ref.name.should == "John Smith"
11 | time_activity.customer_ref.value.should == "123"
12 | time_activity.customer_ref.name.should == "Test Customer"
13 | time_activity.item_ref.value.should == "49"
14 | time_activity.item_ref.name.should == "General Consulting"
15 | time_activity.class_ref.value.should == "100100000000000321233"
16 | time_activity.class_ref.name.should == "Training"
17 | time_activity.billable_status.should == "Billable"
18 | time_activity.taxable.should == "false"
19 | time_activity.hourly_rate.should == "115"
20 | time_activity.hours.should == 1
21 | time_activity.minutes.should == 0
22 | time_activity.description.should == "Description 1"
23 | end
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/util/query_builder_spec.rb:
--------------------------------------------------------------------------------
1 | describe Quickbooks::Util::QueryBuilder do
2 | it "can escape a single-quoted query" do
3 | expected = "DisplayName LIKE '%O\\'Halloran'"
4 | generated = subject.clause("DisplayName", "LIKE", "%O'Halloran")
5 | expected.should == generated
6 | end
7 |
8 | it "parses a Time value to the required format" do
9 | time = Time.new(2014, 10, 31, 2, 2, 2, "+00:00")
10 | expected = "Metadata.LastUpdatedTime > '#{time.iso8601}'"
11 | generated = subject.clause("Metadata.LastUpdatedTime", ">", time)
12 | expected.should == generated
13 | end
14 |
15 | it "parses a Date value the required format" do
16 | date = Date.new(2014)
17 | expected = "DueDate > '#{date.strftime('%Y-%m-%d')}'"
18 | generated = subject.clause("DueDate", ">", date)
19 | expected.should == generated
20 | end
21 |
22 | it "parses an IN query with an array of values" do
23 | values = [10, 20, "something", "40", "it's a quote!"]
24 | expected = "DocNumber IN ('10', '20', 'something', '40', 'it\\'s a quote!')"
25 | generated = subject.clause("DocNumber", "IN", values)
26 | expected.should == generated
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/purchase_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::Purchase" do
2 | before(:all) do
3 | construct_service :purchase
4 | @resource_url = @service.url_for_resource(Quickbooks::Model::Purchase::REST_RESOURCE)
5 | end
6 |
7 | it "cannot create a Purchase without any line items" do
8 | purchase = Quickbooks::Model::Purchase.new
9 | expect(purchase.valid?).to be_false
10 | expect(purchase.errors.keys.include?(:line_items)).to be_true
11 | end
12 |
13 | it "created for account based expense" do
14 | xml = fixture("purchase_create.xml")
15 | stub_request(:post, @resource_url, ["200", "OK"], xml)
16 |
17 | purchase = Quickbooks::Model::Purchase.new
18 | purchase.payment_type = 'Cash'
19 | purchase.account_id = 36
20 | line_item = Quickbooks::Model::PurchaseLineItem.new
21 | line_item.amount = 419.99
22 | line_item.description = "Rink Liner"
23 | line_item.account_based_expense! do |detail|
24 | detail.account_id = 28
25 | detail.customer_id = 1
26 | end
27 | purchase.line_items << line_item
28 | result = @service.create(purchase)
29 | expect(result.id).to eq '160'
30 | end
31 | end
32 |
33 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/tax_code_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::TaxCode" do
2 | it "parse from XML" do
3 | xml = fixture("tax_code.xml")
4 | item = Quickbooks::Model::TaxCode.from_xml(xml)
5 | item.id.should == "2"
6 | item.sync_token.should == 0
7 | item.meta_data.should_not be_nil
8 | item.name.should == "Stupid tax"
9 | item.description.should == "Stupid tax"
10 | item.should be_active
11 | item.should be_taxable
12 | item.should be_tax_group
13 |
14 | sales_tax_rate_detail = item.sales_tax_rate_list.tax_rate_detail.first
15 | sales_tax_rate_detail.tax_rate_ref.value.should == "1"
16 | sales_tax_rate_detail.tax_rate_ref.name.should == "Stupid tax"
17 | sales_tax_rate_detail.tax_type_applicable.should == "TaxOnAmount"
18 | sales_tax_rate_detail.tax_order.should == "0"
19 |
20 | purchase_tax_rate_detail = item.purchase_tax_rate_list.tax_rate_detail.first
21 | purchase_tax_rate_detail.tax_rate_ref.value.should == "2"
22 | purchase_tax_rate_detail.tax_rate_ref.name.should == "Banana tax"
23 | purchase_tax_rate_detail.tax_type_applicable.should == "TaxOnAmount"
24 | purchase_tax_rate_detail.tax_order.should == "0"
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/reports.rb:
--------------------------------------------------------------------------------
1 | # Docs: https://developer.intuit.com/docs/0100_accounting/0400_references/reports
2 | module Quickbooks
3 | module Service
4 | class Reports < BaseService
5 |
6 | def url_for_query(which_report = 'BalanceSheet', date_macro = 'This Fiscal Year-to-date', options = {})
7 | if(options == {})
8 | return "#{url_for_base}/reports/#{which_report}?date_macro=#{URI.encode_www_form_component(date_macro)}"
9 | else
10 | options_string = ""
11 | options.each do |key, value|
12 | options_string += "#{key}=#{value}&"
13 | end
14 | options_string = options_string[0..-2]
15 | options_string.gsub!(/\s/,"%20")
16 | return "#{url_for_base}/reports/#{which_report}?#{options_string}"
17 | end
18 | end
19 |
20 | def query(object_query = 'BalanceSheet', date_macro = 'This Fiscal Year-to-date', options = {})
21 | do_http_get(url_for_query(object_query, date_macro, options))
22 | model.new(:xml => @last_response_xml)
23 | end
24 |
25 | private
26 |
27 | def model
28 | Quickbooks::Model::Report
29 | end
30 |
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/deposit_line_item.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class DepositLineItem < BaseModel
4 |
5 | #== Constants
6 | DEPOSIT_LINE_DETAIL = 'DepositLineDetail'
7 |
8 | xml_accessor :id, :from => 'Id'
9 | xml_accessor :line_num, :from => 'LineNum', :as => Integer
10 | xml_accessor :description, :from => 'Description'
11 | xml_accessor :amount, :from => 'Amount', :as => BigDecimal, :to_xml => to_xml_big_decimal
12 | xml_accessor :linked_transactions, :from => 'LinkedTxn', :as => [LinkedTransaction]
13 |
14 | xml_accessor :detail_type, :from => 'DetailType'
15 |
16 | #== Various detail types
17 | xml_accessor :deposit_line_detail, :from => 'DepositLineDetail', :as => DepositLineDetail
18 |
19 | xml_accessor :custom_fields, :from => 'CustomField', :as => [CustomField]
20 |
21 |
22 | def deposit_line_detail?
23 | detail_type.to_s == DEPOSIT_LINE_DETAIL
24 | end
25 |
26 | def deposit_line_detail!
27 | self.detail_type = DEPOSIT_LINE_DETAIL
28 | self.deposit_line_detail = DepositLineDetail.new
29 |
30 | yield self.deposit_line_detail if block_given?
31 | end
32 |
33 | end
34 | end
35 | end
36 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/tax_rate.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class TaxRate < BaseModel
4 | XML_COLLECTION_NODE = "TaxRate"
5 | XML_NODE = "TaxRate"
6 | REST_RESOURCE = "taxrate"
7 |
8 | xml_accessor :id, :from => "Id"
9 | xml_accessor :sync_token, :from => "SyncToken", :as => Integer
10 | xml_accessor :meta_data, :from => "MetaData", :as => MetaData
11 | xml_accessor :name, :from => "Name"
12 | xml_accessor :description, :from => "Description"
13 | xml_accessor :active?, :from => "Active"
14 | xml_accessor :rate_value, :from => "RateValue", :as => BigDecimal, :to_xml => :to_f.to_proc
15 | xml_accessor :agency_ref, :from => "AgencyRef", :as => BaseReference
16 | xml_accessor :tax_return_line_ref, :from => "TaxReturnLineRef", :as => BaseReference
17 | xml_accessor :special_tax_type, :from => "SpecialTaxType"
18 | xml_accessor :display_type, :from => "DisplayType"
19 | xml_accessor :effective_tax_rate, :from => "EffectiveTaxRate", :as => [EffectiveTaxRate]
20 |
21 | validates_presence_of :name, :rate_value
22 |
23 | reference_setters :agency_ref
24 | reference_setters :tax_return_line_ref
25 |
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/term.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class Term < BaseModel
4 | XML_COLLECTION_NODE = "Term"
5 | XML_NODE = "Term"
6 | REST_RESOURCE = 'term'
7 |
8 | xml_accessor :id, :from => 'Id'
9 | xml_accessor :sync_token, :from => 'SyncToken', :as => Integer
10 | xml_accessor :meta_data, :from => 'MetaData', :as => MetaData
11 | xml_accessor :name, :from => 'Name'
12 | xml_accessor :active?, :from => 'Active'
13 | xml_accessor :type, :from => 'Type'
14 | xml_accessor :discount_percent, :from => 'DiscountPercent', :as => BigDecimal
15 | xml_accessor :due_days, :from => 'DueDays', :as => Integer
16 | xml_accessor :discount_days, :from => 'DiscountDays', :as => Integer
17 | xml_accessor :day_of_month_due, :from => 'DayOfMonthDue', :as => Integer
18 | xml_accessor :due_next_month_days, :from => 'DueNextMonthDays', :as => Integer
19 | xml_accessor :discount_day_of_month, :from => 'DiscountDayOfMonth', :as => Integer
20 | xml_accessor :attachable_ref, :from => 'AttachableRef', :as => BaseReference
21 |
22 | validates_presence_of :name
23 |
24 | reference_setters :attachable_ref
25 |
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/base_service_json.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class BaseServiceJSON < BaseService
4 | include ServiceCrudJSON
5 | HTTP_CONTENT_TYPE = 'application/json'
6 | HTTP_ACCEPT = 'application/json'
7 | attr_reader :last_response_json
8 |
9 | private
10 |
11 | def parse_json(json)
12 | @last_response_json = json
13 | end
14 |
15 | def response_is_error?
16 | @last_response_json['Fault'].present?
17 | end
18 |
19 | def parse_intuit_error
20 | error = {:message => "", :detail => "", :type => nil, :code => 0}
21 | resp = JSON.parse(@last_response_json)
22 | fault = resp['Fault']
23 | if fault.present?
24 | error[:type] = fault['type'] if fault.has_key?('type')
25 | if fault_error = fault['Error'].first
26 | error[:message] = fault_error['Message']
27 | error[:detail] = fault_error['Detail']
28 | error[:code] = fault_error['code']
29 | end
30 | end
31 | error
32 | rescue Exception => exception
33 | error[:detail] = @last_response_json.to_s
34 | error
35 | end
36 |
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/exchange_rate_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::ExchangeRate" do
2 | before(:all) { construct_service :exchange_rate }
3 |
4 | it "can query exchange rates" do
5 | stub_request(:get,
6 | @service.url_for_query,
7 | ["200", "OK"],
8 | fixture("exchange_rates.xml"))
9 |
10 | exchange_rates = @service.query
11 |
12 | exchange_rates.entries.count.should eq(1)
13 | exchange_rates.entries.first.source_currency_code.should eq("EUR")
14 | exchange_rates.entries.first.target_currency_code.should eq("USD")
15 | exchange_rates.entries.first.rate.should eq(2.5)
16 | end
17 |
18 | it "can query exchange rates by currency" do
19 | model = Quickbooks::Model::ExchangeRate
20 | stub_request(:get,
21 | "#{@service.url_for_resource(model::REST_RESOURCE)}?sourcecurrencycode=EUR",
22 | ["200", "OK"],
23 | fixture("exchange_rate_by_currency.xml"))
24 |
25 | exchange_rate = @service.fetch_by_currency('EUR')
26 |
27 | exchange_rate.source_currency_code.should eq("EUR")
28 | exchange_rate.target_currency_code.should eq("USD")
29 | exchange_rate.rate.should eq(2.5)
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/tax_rate_detail_line.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class TaxRateDetailLine < BaseModel
4 |
5 | xml_accessor :tax_rate_id, :from => "TaxRateId"
6 | xml_accessor :tax_rate_name, :from => "TaxRateName"
7 | xml_accessor :rate_value, :from => "RateValue"
8 | xml_accessor :tax_agency_id, :from => "TaxAgencyId"
9 | xml_accessor :tax_applicable_on, :from => 'TaxApplicableOn', :as => :text
10 |
11 | validates :tax_rate_name, presence: true, length: { maximum: 100 }, if: Proc.new {|line| line.tax_rate_id.blank?}
12 | validates :tax_agency_id, presence: true, numericality: {greater_than: 0}, if: Proc.new {|line| line.tax_rate_id.blank?}
13 | validates :rate_value, presence: true, numericality: {less_than_or_equal_to: 100}, if: Proc.new {|line| line.tax_rate_id.blank?}
14 | validates :tax_rate_id, numericality: true, if: Proc.new {|line| line.tax_rate_name.blank? && tax_agency_id.blank? && rate_value.blank? }
15 |
16 | validates :tax_applicable_on, inclusion: {in: %w(Sales Purchase)}
17 |
18 | def to_json
19 | attributes.inject({}){|mem, item| mem[item.first.camelize] = item.last if item.last.present?; mem}
20 | end
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/spec/fixtures/employee.xml:
--------------------------------------------------------------------------------
1 |
2 | 48
3 | 0
4 |
5 | 2013-10-11T08:28:30-07:00
6 | 2013-10-11T08:28:30-07:00
7 |
8 | false
9 | Jenny
10 | Miller
11 | Jenny Miller
12 | Jenny Miller
13 | true
14 |
15 | 525-7891
16 |
17 |
18 | jenny.employee@intuit.com
19 |
20 | XXX-XX-XXXX
21 |
22 | 50
23 | 45 N. Elm Street
24 | Middlefield
25 | CA
26 | 93242
27 |
28 | true
29 | 115.00
30 | 1995-06-01
31 | female
32 | 2013-11-01
33 |
34 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/access_token.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class AccessToken < BaseService
4 |
5 | RENEW_URL = "https://appcenter.intuit.com/api/v1/connection/reconnect"
6 | DISCONNECT_URL = "https://appcenter.intuit.com/api/v1/connection/disconnect"
7 |
8 | # https://developer.intuit.com/docs/0025_quickbooksapi/0053_auth_auth/oauth_management_api#Reconnect
9 | def renew
10 | result = nil
11 | response = do_http_get(RENEW_URL)
12 | if response
13 | code = response.code.to_i
14 | if code == 200
15 | result = Quickbooks::Model::AccessTokenResponse.from_xml(response.plain_body)
16 | end
17 | end
18 |
19 | result
20 | end
21 |
22 | # https://developer.intuit.com/docs/0025_quickbooksapi/0053_auth_auth/oauth_management_api#Disconnect
23 | def disconnect
24 | result = nil
25 | response = do_http_get(DISCONNECT_URL)
26 | if response
27 | code = response.code.to_i
28 | if code == 200
29 | result = Quickbooks::Model::AccessTokenResponse.from_xml(response.plain_body)
30 | end
31 | end
32 |
33 | result
34 | end
35 |
36 | end
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/batch_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Service::Batch" do
2 | before(:all) do
3 | construct_service :batch
4 | end
5 |
6 | it "make batch request with success" do
7 | xml = fixture("batch_response.xml")
8 | stub_request(:post, @service.url_for_resource('batch'), ["200", "OK"], xml)
9 | batch_resp = @service.make_request(Quickbooks::Model::BatchRequest.new)
10 | batch_resp.class.should == Quickbooks::Model::BatchResponse
11 | end
12 |
13 | it "make batch request with error" do
14 | xml = fixture("batch_response.xml")
15 | stub_request(:post, @service.url_for_resource('batch'), ["400", ""], xml)
16 | Proc.new{
17 | @service.make_request(Quickbooks::Model::BatchRequest.new)
18 | }.should raise_error(Quickbooks::IntuitRequestException)
19 | end
20 |
21 | it "allows user to specify a RequestId in a create call" do
22 | requestid = "foobar123"
23 | xml = fixture("batch_response.xml")
24 | stub_request(:post, "#{@service.url_for_resource('batch')}?requestid=#{requestid}", ["200", "OK"], xml)
25 | batch_resp = @service.make_request(Quickbooks::Model::BatchRequest.new, :query => {:requestid => requestid})
26 | batch_resp.class.should == Quickbooks::Model::BatchResponse
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/upload.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class Upload < BaseModel
4 | xml_convention :camelcase
5 |
6 | #xml_accessor :attache, :as => Attachable
7 |
8 | end
9 | end
10 | end
11 |
12 | =begin
13 |
14 | Response XML:
15 |
16 |
17 |
18 |
19 | 2700000000001439108
20 | 0
21 |
22 | 2014-08-18T09:58:06-07:00
23 | 2014-08-18T09:58:06-07:00
24 |
25 | monkey.jpg
26 | /v3/company/1002341430/download/2700000000001439108
27 | https://intuit-qbo-prod-30.s3.amazonaws.com/1002341430%2Fattachments%2Fmonkey.jpg?Expires=1408381986&AWSAccessKeyId=AKIAJEXDXKNYCBUNCCCQ&Signature=WOVACYm6zi1rM5EGZRq3d3AMSM0%3D
28 | 105840
29 | image/jpeg
30 | /v3/company/1002341430/attachable-thumbnail/2700000000001439108
31 |
32 |
33 |
34 |
35 | =end
36 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/attachable_spec.rb:
--------------------------------------------------------------------------------
1 | describe Quickbooks::Service::Account do
2 | before(:all) do
3 | construct_service :attachable
4 | end
5 |
6 | it "can query for attachables" do
7 | xml = fixture("attachables.xml")
8 | stub_request(:get, @service.url_for_query, ["200", "OK"], xml, {}, true)
9 |
10 | attachables = @service.query
11 | attachables.entries.count.should == 1
12 |
13 | monkey = attachables.entries.first
14 | monkey.file_name.should == 'monkey.jpg'
15 | end
16 |
17 | it "can create an attachble" do
18 | xml = fixture("attachable_create_response.xml")
19 | stub_request(:post, @service.url_for_resource('attachable'), ["200", "OK"], xml, {}, true)
20 |
21 | attachable = Quickbooks::Model::Attachable.new
22 | attachable.file_name = "monkey.jpg"
23 | attachable.note = "A note"
24 | entity = Quickbooks::Model::BaseReference.new(3, type: 'Customer')
25 | attachable.attachable_ref = Quickbooks::Model::AttachableRef.new(entity)
26 | n = Nokogiri::XML(attachable.to_xml.to_s)
27 | n.at('AttachableRef > EntityRef').content.should == '3'
28 | n.at('AttachableRef > EntityRef')[:type].should == 'Customer'
29 | response = @service.create(attachable)
30 | response.note.should == attachable.note
31 | end
32 |
33 | end
34 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/journal_entry_line_detail.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class JournalEntryLineDetail < BaseModel
4 | include NameEntity::Quality
5 |
6 | xml_accessor :posting_type, :from => 'PostingType'
7 | xml_accessor :entity, :from => 'Entity', :as => Entity
8 | xml_accessor :account_ref, :from => 'AccountRef', :as => BaseReference
9 | xml_accessor :class_ref, :from => 'ClassRef', :as => BaseReference
10 | xml_accessor :department_ref, :from => 'DepartmentRef', :as => BaseReference
11 |
12 | xml_accessor :tax_code_ref, :from => 'TaxCodeRef', :as => BaseReference
13 | xml_accessor :tax_applicable_on, :from => 'TaxApplicableOn', :as => :text
14 | xml_accessor :tax_amount, :from => 'TaxAmount', :as => BigDecimal, :to_xml => to_xml_big_decimal
15 |
16 | xml_accessor :billable_status, :from => 'BillableStatus'
17 |
18 | reference_setters :account_ref, :class_ref, :department_ref, :tax_code_ref
19 |
20 | validates_length_of :description, :maximum => 4000
21 | validates_numericality_of :tax_amount, allow_nil: true, greater_than_or_equal_to:0.0, less_than_or_equal_to:999999999.0
22 | validate :posting_type_is_valid
23 | validate :billable_status_is_valid
24 | validate :journal_line_entry_tax
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/spec/fixtures/bill_create_request.xml:
--------------------------------------------------------------------------------
1 |
2 | 17
3 | 2017-12-16
4 |
5 | 1
6 | 700.00
7 | AccountBasedExpenseLineDetail
8 |
9 | 100000000000128320
10 | 42
11 | NotBillable
12 | NON
13 |
14 |
15 |
16 | 2
17 | 55.12
18 | AccountBasedExpenseLineDetail
19 |
20 | 100000000000128320
21 | 77
22 | NotBillable
23 | NON
24 |
25 |
26 | 4
27 | 38
28 | 755.12
29 | 2018-12-26
30 |
--------------------------------------------------------------------------------
/spec/fixtures/sales_receipt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2
4 | 0
5 |
6 | 2013-12-10T05:35:42-08:00
7 | 2013-12-10T05:35:42-08:00
8 |
9 | 1002
10 | 2013-12-10
11 | private
12 | BRL
13 |
14 | 1
15 | 1
16 | 10.00
17 | SalesItemLineDetail
18 |
19 | 1
20 | 10
21 | 1
22 |
23 |
24 |
25 | 10.00
26 | SubTotalLineDetail
27 |
28 |
29 | 1
30 | memo!
31 | NotApplicable
32 | 10.00
33 | NotSet
34 | NotSet
35 | 0
36 | 28
37 |
38 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/account_spec.rb:
--------------------------------------------------------------------------------
1 | describe Quickbooks::Model::Account do
2 | it "must have a name for create / update" do
3 | account = Quickbooks::Model::Account.new
4 | account.valid?
5 | account.errors.keys.include?(:name).should == true
6 |
7 | account.name = Array.new(102).join("a") # 101 character, too long
8 | account.valid?
9 | account.errors.keys.include?(:name).should == true
10 |
11 | account.name = "Invalid name with :"
12 | account.valid?
13 | account.errors.keys.include?(:name).should == true
14 |
15 | account.name = "Invalid name with \""
16 | account.valid?
17 | account.errors.keys.include?(:name).should == true
18 |
19 | account.name = "Regular"
20 | account.valid?
21 | account.errors.keys.include?(:name).should == false
22 | end
23 |
24 | it "must have a classifiction" do
25 | account = Quickbooks::Model::Account.new
26 | account.valid?
27 | account.errors.keys.include?(:classification).should == true
28 |
29 | account.classification = 'Undocummented Classification'
30 | account.valid?
31 | account.errors.keys.include?(:classification).should == true
32 |
33 | account.classification = Quickbooks::Model::Account::LIABILITY
34 | account.valid?
35 | account.errors.keys.include?(:classification).should == false
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/change_data_capture.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class ChangeDataCapture < BaseModel
4 |
5 | attr_accessor :xml
6 |
7 | TYPES = ["Bill", "BillPayment", "CreditMemo", "Deposit", "Invoice", "JournalEntry", "Payment",
8 | "Purchase", "RefundReceipt", "SalesReceipt", "PurchaseOrder", "VendorCredit", "Transfer",
9 | "Estimate", "Account", "Budget", "Class", "Customer", "Department", "Employee", "Item",
10 | "PaymentMethod", "Term", "Vendor"]
11 |
12 | def all_types
13 | data = {}
14 | TYPES.each do |entity|
15 | if xml.css(entity).first != nil
16 | data[entity] = all_of_type(entity)
17 | end
18 | end
19 | data
20 | end
21 |
22 | private
23 |
24 | def all_of_type(entity)
25 | parse_block(xml.css(entity).first.parent, entity)
26 | end
27 |
28 | def parse_block(node, entity)
29 | model = "Quickbooks::Model::#{entity}".constantize
30 | models = []
31 | all_items = node.css(entity).map do |item|
32 | if item.attribute("status").try(:value) == "Deleted"
33 | Quickbooks::Model::ChangeModel.from_xml(item)
34 | else
35 | model.from_xml(item)
36 | end
37 | end
38 | end
39 |
40 | end
41 | end
42 | end
--------------------------------------------------------------------------------
/spec/fixtures/fetch_employee_by_id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2
4 | 0
5 |
6 | 2013-10-11T08:28:30-07:00
7 | 2013-10-11T08:28:30-07:00
8 |
9 | false
10 | Lindy
11 | Miller
12 | Lindy Miller
13 | Lindy Miller
14 | true
15 |
16 | 525-7892
17 |
18 |
19 | lindy.employee@intuit.com
20 |
21 | XXX-XX-XXXX
22 |
23 | 50
24 | 99 N. Elm Street
25 | Middlesburg
26 | VA
27 | 93242
28 |
29 | true
30 | 215.00
31 | 1991-03-28
32 | female
33 | 2013-09-01
34 |
35 |
--------------------------------------------------------------------------------
/spec/fixtures/deleted_employee.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2
4 | 1
5 |
6 | 2013-10-11T08:28:30-07:00
7 | 2013-10-11T08:28:30-07:00
8 |
9 | false
10 | Lindy
11 | Miller
12 | Lindy Miller (Deleted)
13 | Lindy Miller
14 | false
15 |
16 | 525-7892
17 |
18 |
19 | lindy.employee@intuit.com
20 |
21 | XXX-XX-XXXX
22 |
23 | 50
24 | 99 N. Elm Street
25 | Middlesburg
26 | VA
27 | 93242
28 |
29 | true
30 | 215.00
31 | 1991-03-28
32 | female
33 | 2013-09-01
34 |
35 |
--------------------------------------------------------------------------------
/lib/quickbooks/model/report.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Model
3 | class Report < BaseModel
4 |
5 | attr_accessor :xml
6 |
7 | def all_rows
8 | @all_rows ||= xml.css("ColData:first-child").map {|node| parse_row(node.parent) }
9 | end
10 |
11 | def columns
12 | @columns ||= begin
13 | nodes = xml.css('Column')
14 | nodes.map do |node|
15 | # There is also a ColType field, but it does not seem valuable to capture
16 | node.at('ColTitle').content
17 | end
18 | end
19 | end
20 |
21 | def find_row(label)
22 | all_rows.find {|r| r[0] == label }
23 | end
24 |
25 | private
26 |
27 | # Parses the given row:
28 | #
29 | #
30 | #
31 | #
32 | #
33 | #
34 | # To:
35 | # ['Checking', BigDecimal(1201.00), BigDecimal(200.50)]
36 | def parse_row(row_node)
37 | row_node.elements.map.with_index do |el, i|
38 | value = el.attr('value')
39 |
40 | next nil if value.blank?
41 | next value if value.to_s.match(/^\d+$|^\d+.\d+$|^-\d+|^-\d+.\d+$|^.\d+$/).nil?
42 | BigDecimal(value)
43 | end
44 | end
45 |
46 | end
47 | end
48 | end
49 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/service/tax_agency_spec.rb:
--------------------------------------------------------------------------------
1 | describe Quickbooks::Service::TaxAgency do
2 | before(:all) { construct_service :tax_agency }
3 |
4 | before do
5 | subject.company_id = "9991111222"
6 | subject.access_token = construct_oauth
7 | end
8 |
9 | let(:model) { Quickbooks::Model::TaxAgency }
10 | let(:tax_agency) { model.new(display_name: 'First TaxAgency')}
11 | let(:resource) { model::REST_RESOURCE }
12 |
13 | it "can query tax agency" do
14 | stub_request(:get,
15 | @service.url_for_query,
16 | ["200", "OK"],
17 | fixture("tax_agencies.xml"))
18 | tax_agencies = @service.query
19 | tax_agencies.entries.count.should eq(1)
20 | tax_agencies.entries.first.display_name.should eq("First TaxAgency")
21 | end
22 |
23 | it "can create tax agency" do
24 | xml = fixture("tax_agency_entity.xml")
25 | stub_request(:post, subject.url_for_resource(resource), ["200", "OK"], xml)
26 |
27 | entity = subject.create(tax_agency)
28 | expect(entity.display_name).to eq tax_agency.display_name
29 | end
30 |
31 | it "can not create tax agency without display_name" do
32 | agency = model.new
33 |
34 | expect {
35 | subject.create(agency)
36 | }.to raise_error(Quickbooks::InvalidModelException)
37 |
38 | expect(agency.errors.messages).to have_key(:display_name)
39 | end
40 |
41 | end
42 |
--------------------------------------------------------------------------------
/spec/fixtures/items.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 | 2
5 | 0
6 |
7 | 2013-11-16T17:42:03-08:00
8 | 2013-11-16T17:42:03-08:00
9 |
10 | Plush Baby Doll
11 | A fine baby doll - in many colors
12 | true
13 | false
14 | 50
15 | Service
16 | 1
17 | 0
18 | false
19 |
20 | -
21 | 1
22 | 0
23 |
24 | 2013-11-15T11:28:31-08:00
25 | 2013-11-15T11:28:31-08:00
26 |
27 | Sales
28 | true
29 | false
30 | 0
31 | Service
32 | 1
33 | 0
34 | false
35 |
36 |
37 |
--------------------------------------------------------------------------------
/lib/quickbooks/service/invoice.rb:
--------------------------------------------------------------------------------
1 | module Quickbooks
2 | module Service
3 | class Invoice < BaseService
4 |
5 | def delete(invoice)
6 | delete_by_query_string(invoice)
7 | end
8 |
9 | def send(invoice, email_address=nil)
10 | query = email_address.present? ? "?sendTo=#{email_address}" : ""
11 | url = "#{url_for_resource(model::REST_RESOURCE)}/#{invoice.id}/send#{query}"
12 | response = do_http_post(url,{})
13 | if response.code.to_i == 200
14 | model.from_xml(parse_singular_entity_response(model, response.plain_body))
15 | else
16 | nil
17 | end
18 | end
19 |
20 | def pdf(invoice)
21 | url = "#{url_for_resource(model::REST_RESOURCE)}/#{invoice.id}/pdf"
22 | response = do_http_raw_get(url, {}, {'Accept' => 'application/pdf'})
23 | response.plain_body
24 | end
25 |
26 | def void(invoice, options = {})
27 | url = "#{url_for_resource(model::REST_RESOURCE)}?operation=void"
28 |
29 | xml = invoice.to_xml_ns(options)
30 | response = do_http_post(url, valid_xml_document(xml))
31 | if response.code.to_i == 200
32 | model.from_xml(parse_singular_entity_response(model, response.plain_body))
33 | else
34 | false
35 | end
36 | end
37 |
38 | private
39 |
40 | def model
41 | Quickbooks::Model::Invoice
42 | end
43 | end
44 | end
45 | end
46 |
--------------------------------------------------------------------------------
/spec/lib/quickbooks/model/term_spec.rb:
--------------------------------------------------------------------------------
1 | describe "Quickbooks::Model::Term" do
2 | it "parses from XML" do
3 | xml = fixture("term.xml")
4 | term = Quickbooks::Model::Term.from_xml(xml)
5 |
6 | term.id.should == "11"
7 | term.sync_token.should == 0
8 | term.meta_data.create_time.should == Time.new(2013, 7, 11, 17, 46, 39, "-07:00")
9 | term.meta_data.last_updated_time.should == Time.new(2013, 7, 11, 17, 46, 42, "-07:00")
10 | term.name.should == "TermForV3Testing-1373590184130"
11 | term.active?.should be_true
12 | term.type.should == "DATE_DRIVEN"
13 | term.discount_percent.should == 4.0
14 | term.due_days.should be_nil
15 | term.discount_days.should be_nil
16 | term.day_of_month_due.should == 1
17 | term.due_next_month_days.should == 2
18 | term.discount_day_of_month.should == 3
19 | end
20 |
21 | it "is invalid without a name" do
22 | term = Quickbooks::Model::Term.new
23 | term.should_not be_valid
24 | end
25 |
26 | it "is valid with a name" do
27 | term = Quickbooks::Model::Term.new
28 | term.name = "Cool Term, Yo"
29 | term.should be_valid
30 | end
31 |
32 | describe "#active?" do
33 | it "returns true when active == 'true'" do
34 | term = Quickbooks::Model::Term.new
35 | term.active = "true"
36 | term.should be_true
37 | end
38 |
39 | it "returns false when active == 'false'" do
40 | term = Quickbooks::Model::Term.new
41 | term.active = "false"
42 | term.should_not be_false
43 | end
44 | end
45 | end
46 |
--------------------------------------------------------------------------------