Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added invoice receipts #12

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--colour
--format documentation
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
# Version 0.3.2
Added current_invoice_receipt_number and current_invoice_receipt_sequence_id to sequences.

# Version 0.3.1.1
Merged changes from other contributors. Bumped version.

# Version 0.3.0
More big changes on this version:
- added logo option to send email
- added transport guides client
- set params_encoder = Faraday::FlatParamsEncoder in GET requests. We need this for the way that IX accepts arrays in GET requests. See https://github.com/lostisland/faraday/issues/78
- fixed missing owner_invoice_id, manual_sequence_number, currency_code, rate params on update credit note and debit note
- added models for address, message, transport guide
- added tests for transport guides

# Version 0.2.5
Big changes on this version:
- updated send email endpoint for invoices
- cleanup gemspec file
- started cleaning up test files from should to expect
- added manual_sequence_number field to invoices. Required for non portuguese accounts with manual sequence numbering.
- added saft_hash field to invoices
- added currency, multicurrency to invoices. not supported officially.
- added owner_invoice_id to credit_note. not working.

# Version 0.2.0
Support for 429 RateLimitExceeded code
Added Invoice Receipt
Added supplier model

# Version 0.1.9.1
Fixed problem with duplicated mb_reference

Expand Down
53 changes: 52 additions & 1 deletion EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,46 @@

Here's some examples for the most common objects and endpoints. You could also take a look at the spec folder for extensive tests.


### Invoice Receipts

invoices = @client.invoice_receipts
puts invoices

invoice = Invoicexpress::Models::InvoiceReceipt.new(
:date => Date.new(2015, 5, 8),
:due_date => Date.new(2015, 6, 16),
:tax_exemption => "M01",
:client => Invoicexpress::Models::Client.new(
:name => "Pedro Sousa",
:email=> '[email protected]'
),
:items => [
Invoicexpress::Models::Item.new(
:name => "Playstation 4",
:unit_price => 399,
:quantity => 2,
:unit => "unit",
),
Invoicexpress::Models::Item.new(
:name => "Oculus Rift",
:unit_price => 350,
:quantity => 1,
:unit => "unit",
)
]
)

invoice_1 = @client.create_invoice_receipt(invoice)
invoice_2 = @client.invoice_receipt(5827534)
invoice_2.tax_exemption="M01"
@client.update_invoice_receipt(invoice_2)

state = Invoicexpress::Models::InvoiceState.new(
:state => "finalized"
)
@client.update_invoice_receipt_state(invoice_2.id, state)

### Simplified Invoices

simple_invoices = @client.simplified_invoices
Expand Down Expand Up @@ -161,7 +201,7 @@ Here's some examples for the most common objects and endpoints. You could also t
top_c = @client.top_clients
top_d = @client.top_debtors
quarter = @client.quarterly_results(2011)

### Schedules


Expand Down Expand Up @@ -267,3 +307,14 @@ To update a schedule we need to pass these fields.
]
)
purchase_order = @client.create_purchase_order(purchase_order)

### Sequences

sequences = @client.sequences
puts sequences

seq = @client.sequence 453193
puts seq.current_invoice_sequence_id
puts seq.current_simplified_invoice_sequence_id
puts seq.current_receipt_sequence_id
puts seq.current_transport_sequence_id
8 changes: 4 additions & 4 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
source "https://rubygems.org"

gem 'rake'
gem 'yard'
# gem 'byebug'
gemspec

group :development do
#gem 'rake'
gem 'yard'
gem 'kramdown'
gem 'pry'
#gem 'libxml-ruby', '2.8.0'
end

group :test do
gem 'rspec', '>= 2.11'
gem 'webmock'
gem 'simplecov', :require => false
end

gemspec
25 changes: 21 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Run bundle, the project should need:
* Client - 100%
* Sequences - 100%
* Users - 100%
* Invoices - 100%
* Invoices - 80%
* Cash Invoices - 100%
* Items - 100%
* Charts - 100%
Expand All @@ -28,6 +28,7 @@ Run bundle, the project should need:
* Schedules - 100%
* Sim. Invoices - 100%
* Purch. Orders - 100%
* Invoice Receipts - 100%

## Tests

Expand All @@ -41,21 +42,37 @@ Run bundle, the project should need:
* Sim. Invoices - 100%
* Credit Notes - 100%
* Purch. Orders - 100%
* Inv. Receipts - 0%

## Documentation

We've included docs for all methods. Refer to the doc folder and client section.

## Testing locally

Run the tests from spec/ with

rspec spec/


## Developing the gem further

Run the rake task

rake console

to launch IRB with the gem loaded and you can use the following examples from the next section. If you want to use a proxy to inspect the requests you can use Postman, ex: http://blog.getpostman.com/2016/06/26/using-postman-proxy-to-capture-and-inspect-api-calls-from-ios-or-android-devices/

## Examples

If using from inside a rails project use:

require 'invoicexpress'

client = Invoicexpress::Client.new(
:account_name => "yourusername",
:api_key => "yourapikey"
screen_name: "yourusername",
api_key: "yourapikey",
proxy: "192.168.1.201:5555"
)

Examples for API are located in the EXAMPLES.md file.

4 changes: 4 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ namespace :doc do
]
end
end

task :console do
exec "irb -r invoicexpress -I ./lib"
end
29 changes: 17 additions & 12 deletions invoicexpress.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,29 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'invoicexpress/version'

Gem::Specification.new do |spec|
spec.add_development_dependency 'bundler', '~> 1.0'

spec.add_dependency 'faraday', '~> 0.8'
spec.add_dependency 'faraday_middleware', '~> 0.9'
spec.add_dependency 'happymapper', '~> 0.4'

spec.authors = ["Think Orange"]
spec.name = 'invoicexpress'
spec.description = %q{Simple wrapper for invoicexpress.com API}
spec.email = ['[email protected]']
spec.authors = ["Think Orange"]
spec.licenses = ['MIT']
spec.homepage = "https://github.com/weareswat/invoicexpress-gem"
spec.summary = spec.description
spec.version = Invoicexpress::VERSION
spec.platform = Gem::Platform::RUBY

spec.files = %w(CHANGELOG.md README.md Rakefile invoicexpress.gemspec)
spec.files += Dir.glob("lib/**/*.rb")
spec.files += Dir.glob("spec/**/*")
spec.homepage = "http://invoicexpress.com"
spec.licenses = ['MIT']
spec.name = 'invoicexpress'
spec.require_paths = ['lib']
spec.required_rubygems_version = '>= 1.3.6'
spec.summary = spec.description
spec.test_files = Dir.glob("spec/**/*")
spec.version = Invoicexpress::VERSION

spec.add_development_dependency 'bundler', '~> 1.0'
spec.add_development_dependency "rake"
#spec.add_development_dependency "rspec"
#spec.add_development_dependency "rspec-rails"

spec.add_dependency 'faraday', '~> 0.8'
spec.add_dependency 'faraday_middleware', '~> 0.9'
spec.add_dependency 'happymapper', '~> 0.4'
end
1 change: 1 addition & 0 deletions lib/faraday/response/raise_invoicexpress_errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Response::RaiseInvoicexpressErrors < Response::Middleware
ERROR_MAP = {
401 => Invoicexpress::Unauthorized,
422 => Invoicexpress::UnprocessableEntity,
429 => Invoicexpress::RateLimitExceeded,
500 => Invoicexpress::InternalServerError,
}

Expand Down
5 changes: 4 additions & 1 deletion lib/invoicexpress/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
require 'invoicexpress/client/debit_notes'
require 'invoicexpress/client/credit_notes'
require 'invoicexpress/client/simplified_invoices'
require 'invoicexpress/client/invoice_receipts'
require 'invoicexpress/client/transport_guides'


module Invoicexpress
Expand Down Expand Up @@ -51,6 +53,7 @@ def initialize(options={})
include Invoicexpress::Client::DebitNotes
include Invoicexpress::Client::CreditNotes
include Invoicexpress::Client::SimplifiedInvoices

include Invoicexpress::Client::InvoiceReceipts
include Invoicexpress::Client::TransportGuides
end
end
129 changes: 129 additions & 0 deletions lib/invoicexpress/client/invoice_receipts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
require 'invoicexpress/models'

module Invoicexpress
class Client
module InvoiceReceipts

# Returns all your invoice receipts
#
# @option options [Integer] page (1) You can ask a specific page of invoice receipts
#
# @return [Invoicexpress::Models::InvoiceReceipts] A struct with results (pagination) and all the invoice receipts
# @raise Invoicexpress::Unauthorized When the client is unauthorized
def invoice_receipts(options={})
params = { :page => 1, :klass => Invoicexpress::Models::InvoiceReceipt }
get("invoice_receipts.xml", params.merge(options))
end



# Returns all the information about a invoice receipt:
# - Basic information (date, status, sequence number)
# - Client
# - Document items
# - Document timeline
# Document timeline is composed by:
# - Date, time and the user who created it
# - Type of the event
# The complete list of timeline events is:
# - create
# - edited
# - send_email
# - canceled
# - deleted
# - settled
# - second_copy
# - archived
# - unarchived
# - comment
#
# @param invoice_receipt_id [String] Requested invoice_receipt_id
# @return [Invoicexpress::Models::InvoiceReceipt] The requested invoice
# @raise Invoicexpress::Unauthorized When the client is unauthorized
# @raise Invoicexpress::NotFound When the invoice_receipt doesn't exist
def invoice_receipt(invoice_receipt_id, options={})
params = { :klass => Invoicexpress::Models::InvoiceReceipt }

get("invoice_receipts/#{invoice_receipt_id}.xml", params.merge(options))
end

# Creates a new invoice receipt. Also allows to create a new client and/or new items in the same request.
# If the client name does not exist a new one is created.
# If items do not exist with the given names, new ones will be created.
# If item name already exists, the item is updated with the new values.
# Regarding item taxes, if the tax name is not found, no tax is applyed to that item.
# Portuguese accounts should also send the IVA exemption reason if the invoice contains exempt items(IVA 0%)
#
# @param simplified_invoice [Invoicexpress::Models::SimplifiedInvoice] The invoice receipt to create
# @return [Invoicexpress::Models::SimplifiedInvoice] The created invoice receipt
# @raise Invoicexpress::Unauthorized When the client is unauthorized
# @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
def create_invoice_receipt(invoice_receipt, options={})
raise(ArgumentError, "invoice receipt has the wrong type") unless invoice_receipt.is_a?(Invoicexpress::Models::InvoiceReceipt)

params = { :klass => Invoicexpress::Models::InvoiceReceipt, :body => invoice_receipt }
post("invoice_receipts.xml", params.merge(options))
end

# Updates a invoice receipt
# It also allows you to create a new client and/or items in the same request.
# If the client name does not exist a new client is created.
# Regarding item taxes, if the tax name is not found, no tax will be applied to that item.
# If item does not exist with the given name, a new one will be created.
# If item exists it will be updated with the new values
# Be careful when updating the document items, any missing items from the original document will be deleted.
#
# @param invoice_receipt [Invoicexpress::Models::InvoiceReceipt] The invoice receipt to update
# @raise Invoicexpress::Unauthorized When the client is unauthorized
# @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
# @raise Invoicexpress::NotFound When the invoice receiptdoesn't exist
def update_invoice_receipt(invoice_receipt, options={})
raise(ArgumentError, "invoice receipt has the wrong type") unless invoice_receipt.is_a?(Invoicexpress::Models::InvoiceReceipt)
if !invoice_receipt.id
raise ArgumentError, "Invoice ID is required"
end
params = { :klass => Invoicexpress::Models::InvoiceReceipt, :body => invoice_receipt.to_core }
put("invoice_receipts/#{invoice_receipt.id}.xml", params.merge(options))
end

# Changes the state of a invoice receipt
# Possible state transitions:
# - draft to final – finalized
# - draft to deleted – deleted
# - settled to final – unsettled
# - final to second copy – second_copy
# - final or second copy to canceled – canceled
# - final or second copy to settled – settled
# Any other transitions will fail.
# When canceling a invoice you must specify a reason.
#
# @param invoice_receipt_id [String] The invoice receipt id to change
# @param invoice_receipt_state [Invoicexpress::Models::InvoiceState] The new state
# @return [Invoicexpress::Models::InvoiceReceipt] The updated invoice receipt
# @raise Invoicexpress::Unauthorized When the client is unauthorized
# @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
# @raise Invoicexpress::NotFound When the simplified invoice doesn't exist
def update_invoice_receipt_state(invoice_receipt_id, simplified_invoice_state, options={})
raise(ArgumentError, "invoice receipt state has the wrong type") unless simplified_invoice_state.is_a?(Invoicexpress::Models::InvoiceState)

params = { :klass => Invoicexpress::Models::InvoiceReceipt, :body => simplified_invoice_state }
put("invoice_receipts/#{invoice_receipt_id}/change-state.xml", params.merge(options))
end

# Sends the invoice receipt through email
#
# @param invoice_receipt_id [String] The invoice receipt id to send
# @param message [Invoicexpress::Models::Message] The message to send
# @raise Invoicexpress::Unauthorized When the client is unauthorized
# @raise Invoicexpress::UnprocessableEntity When there are errors on the submission
# @raise Invoicexpress::NotFound When the invoice receipt doesn't exist
def invoice_receipt_mail(invoice_receipt_id, message, options={})
raise(ArgumentError, "message has the wrong type") unless message.is_a?(Invoicexpress::Models::Message)

params = { :body => message, :klass => Invoicexpress::Models::InvoiceReceipt }
put("invoice_receipts/#{invoice_receipt_id}/email-document.xml", params.merge(options))
end

end
end
end
Loading