From d5df5c6aaeb38bdfdaa0abf37d97329b8d6a3636 Mon Sep 17 00:00:00 2001 From: Nik Wakelin Date: Thu, 15 Sep 2016 20:57:23 +0100 Subject: [PATCH 1/2] remove a couple of unneccessary files --- CHANGELOG.textile | 119 ---------------------------------------------- init.rb | 1 - 2 files changed, 120 deletions(-) delete mode 100644 CHANGELOG.textile delete mode 100644 init.rb diff --git a/CHANGELOG.textile b/CHANGELOG.textile deleted file mode 100644 index 3318f718..00000000 --- a/CHANGELOG.textile +++ /dev/null @@ -1,119 +0,0 @@ -h2. 2.1.0, released 19/11/2012 - -* Add ability to create payments via the API -* Allow creation of Payments via the API -* Add check for valid invoice_type - -h2. 2.0.19, released 13/07/2012 - -* Handle additional payment fields (payment_id, currency_rate) - -h2. 2.0.18, released 12/07/2012 - -* Add accessor for the expires_at time when renewing access tokens - -h2. 2.0.15, released 15/06/2012 - -* Add support for manual journals - -h2. 2.0.14, released 07/05/2012 - -* Add support for bank transactions - -h2. 2.0.13, released 14/09/2011 - -* Add new Organisation attributes -* Partner app implementation -* Add Invoice#sent_to_contact - -h2. 2.0.12, released 25/05/2011 - -* Add OUTPUT2 and EC Zero-rated income as valid tax types -* Add support for updating invoices -* Add support for oauth_callback - -h2. 2.0.11, released 18/04/2011 - -* Bug fixes - -h2. 2.0.10, released 12/04/2011 - -* Fix issue with TrackingCategory#to_xml - -h2. 2.0.9, released 12/04/2011 - -* Improve handling of ApiExceptions - -h2. 2.0.8, released 14/02/2011 - -* Add support for new undocumented organisation attributes - -h2. 2.0.7, released 09/12/2010 - -* Bug fixes - -h2. 2.0.6, released 14/11/2010 - -* Bug fixes - -h2. 2.0.5, released 21/10/2010 - -* Add support for credit notes. Thanks to malclocke and wasabhi for their contributions - -h2. 2.0.4, released 29/09/2010 - -* Use bundler for dependency management - -h2. 2.0.3, released 29/09/2010 - -* Fix issue caused by Xero updating the Tracking Category XML structure - -h2. 2.0.2, released 23/08/2010 - -* Xero Api version 2.0 - -h2. 1.0.5, released 25/09/2009 - -* This will be the final release before switching to the Xero API version 2.0 -* Allow multiple tracking options per line item - -h2. 1.0.4, released 13/08/2009 - -* Auto-assign Contact#contact_id and Invoice#invoice_id on creation of either of these records. -* Add Xero::Gateway#build_contact and Xero::Gateway#build_invoice factory methods to create Contact/Invoice objects associated with the gateway. -* Add Contact#save method to create/update a contact record based on if it has a contact_id or contact_number. -* Add Invoice#save method to create (insert only currently supported by Xero API) the invoice. -* Add #valid? method to each model class to validate it's contents with the minimum required by the API (without calling the API). -* Add useful API constants throughout the library. -* Allow Invoice and LineItem to auto-calculate line_amount, sub_total, total_tax and total fields. Existing setters for these fields remain (for backwards compatability) but will be deprecated in the future. -* Create XeroGateway::AccountList class to make working with the accounts response more powerful and faster (as it caches the last result). -* Add :updated_after parameter to XeroGateway::Gateway#get_contacts -* Add XeroGateway::Gateway#update_contacts -* Add XeroGateway::Gateway#create_invoices - -h2. 1.0.3, released 09/12/2008 - -* Major refactorings to DRY out gateway.rb -* Removed all messages classes in favour of invoice.to_xml and Invoice.from_xml(element) -* Added unit tests for the handing of errors from Xero - -h2. 1.0.2, released 04/12/2008 - -* Added implementation of GET /api.xro/1.0/tracking - - -h2. 1.0.1, released 02/12/2008 - -* Added implementation of GET /api.xro/1.0/accounts -* Replaced Invoice.id, Contact.id etc with Invoice.invoice_id, Contact.contact_id to avoid Object.id errors - - -h2. 1.0.0, released 01/12/2008 - -* Initial release, including: -* PUT /api.xro/1.0/contact -* GET /api.xro/1.0/contact -* GET /api.xro/1.0/contacts -* PUT /api.xro/1.0/invoice -* GET /api.xro/1.0/invoice -* GET /api.xro/1.0/invoices diff --git a/init.rb b/init.rb deleted file mode 100644 index 67079ab1..00000000 --- a/init.rb +++ /dev/null @@ -1 +0,0 @@ -require 'xero_gateway' \ No newline at end of file From 5ad1fca4561b55a9024c3ec6087c8c0a0678a39e Mon Sep 17 00:00:00 2001 From: Nik Wakelin Date: Thu, 15 Sep 2016 21:22:37 +0100 Subject: [PATCH 2/2] clean up README --- CODE_OF_CONDUCT.md | 74 ++++++++ README.md | 452 ++++++++++++++------------------------------- 2 files changed, 213 insertions(+), 313 deletions(-) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..d05f4bc0 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at [INSERT EMAIL ADDRESS]. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/README.md b/README.md index 2ce89bea..01e7ca76 100644 --- a/README.md +++ b/README.md @@ -1,110 +1,140 @@ Xero API wrapper [![Build Status](https://travis-ci.org/xero-gateway/xero_gateway.svg?branch=master)](https://travis-ci.org/xero-gateway/xero_gateway) [![Gem Version](https://badge.fury.io/rb/xero_gateway.svg)](https://badge.fury.io/rb/xero_gateway) ================ -Introduction ------------- +# Getting Started -This library is designed to help ruby / rails based applications -communicate with the publicly available API for Xero. If you are -unfamiliar with the API, you should first read the documentation, -located here +This is a Ruby gem for communicating with the Xero API. +You can find more information about the Xero API at . -Usage ------ +## Installation - require 'xero_gateway' - gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET) +Just add the `xero_gateway` gem to your Gemfile, like so: -Authenticating with OAuth -------------------------- +```ruby + gem 'xero_gateway' +``` -OAuth is built into this library in a very similar manner to the Twitter -gem by John Nunemaker -([http://github.com/jnunemaker/twitter](http://github.com/jnunemaker/twitter)). -So if you've used that before this will all seem familiar. +## Usage -### Consumer Key & Secret +```ruby + gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET) +``` -First off, you'll need to get a Consumer Key/Secret pair for your -application from Xero.\ -Head to , log in and then click My Applications -> Add Application. +### Authenticating with OAuth -If you want to create a private application (that accesses your own Xero -account rather than your users), you'll need to generate an RSA keypair -and an X509 certificate. This can be done with OpenSSL as below: +The Xero Gateway uses [OAuth 1.0a](https://oauth.net/core/1.0a/) for authentication. Xero Gateway +implements OAuth in a very similar manner to the [Twitter gem by John Nunemaker](http://github.com/jnunemaker/twitter) +, so if you've used that before this will all seem familiar. - openssl genrsa –out privatekey.pem 1024 - openssl req –newkey rsa:1024 –x509 –key privatekey.pem –out publickey.cer –days 365 - openssl pkcs12 –export –out public_privatekey.pfx –inkey privatekey.pem –in publickey.cer + 1. **Get a Consumer Key & Secret** -On the right-hand-side of your application's page there's a box titled -"OAuth Credentials". Use the Key and Secret from this box in order to -set up a new Gateway instance. + First off, you'll need to get a Consumer Key/Secret pair for your + application from Xero.\ + Head to , log in and then click My Applications + > Add Application. -(If you're unsure about the Callback URL, specify nothing - it will -become clear a bit later) + If you want to create a private application (that accesses your own Xero + account rather than your users), you'll need to generate an RSA keypair + and an X509 certificate. This can be done with OpenSSL as below: -### Xero Gateway Initialization + ``` + openssl genrsa –out privatekey.pem 1024 + openssl req –newkey rsa:1024 –x509 –key privatekey.pem –out publickey.cer –days 365 + openssl pkcs12 –export –out public_privatekey.pfx –inkey privatekey.pem –in publickey.cer + ``` - require 'xero_gateway' - gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET) + On the right-hand-side of your application's page there's a box titled + "OAuth Credentials". Use the Key and Secret from this box in order to + set up a new Gateway instance. -or for private applications + (If you're unsure about the Callback URL, specify nothing - it will + become clear a bit later) - require 'xero_gateway' - gateway = XeroGateway::PrivateApp.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET, PATH_TO_YOUR_PRIVATE_KEY) + 2. **Create a Xero Gateway in your App** -### Request Token + ```ruby + gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET) + ``` -You'll then need to get a Request Token from Xero. + or for Private applications - request_token = gateway.request_token + ```ruby + require 'xero_gateway' + gateway = XeroGateway::PrivateApp.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET, PATH_TO_YOUR_PRIVATE_KEY) + ``` -You should keep this around - you'll need it to exchange for an Access -Token later. (If you're using Rails, this means storing it in the -session or something similar) + 3. **Creating a Request Token** -Next, you need to redirect your user to the authorisation url for this -request token. In Rails, that looks something like this: + You'll then need to get a Request Token from Xero. - redirect_to request_token.authorize_url + ```ruby + request_token = gateway.request_token + ``` -You may also provide a callback parameter, which is the URL within your -app the user will be redirected to. See next section for more -information on what parameters Xero sends with this request. + You should keep this around - you'll need it to exchange for an Access + Token later. (If you're using Rails, this means storing it in the + session or something similar) - redirect_to request_token(:oauth_callback => "http://www.something.com/xero/complete").authorize_url + Next, you need to redirect your user to the authorization url for this + request token. In Rails, that looks something like this: -### Retrieving an Access Token + ```ruby + redirect_to request_token.authorize_url + ``` -If you've specified a Callback URL when setting up your application or -provided an oauth\_callback parameter on your request token, your user -will be redirected to that URL with an OAuth Verifier as a GET -parameter. You can then exchange your Request Token for an Access Token -like this (assuming Rails, once again): + You may also provide a callback parameter, which is the URL within your + app the user will be redirected to. See next section for more + information on what parameters Xero sends with this request. - gateway.authorize_from_request(request_token.token, request_token.secret, :oauth_verifier => params[:oauth_verifier]) + ```ruby + request_token = request_token(oauth_callback: "http://yourapp.comcom/xero/callback") + redirect_to request_token.authorize_url + ``` -(If you haven't specified a Callback URL, the user will be presented -with a numeric verifier which they must copy+paste into your -application; see examples/oauth.rb for an example) + 4. **Retrieving an Access Token** -Now you can access Xero API methods: + If you've specified a Callback URL when setting up your application or + provided an oauth\_callback parameter on your request token, your user + will be redirected to that URL with an OAuth Verifier as a GET + parameter. You can then exchange your Request Token for an Access Token + like this (assuming Rails, once again): - gateway.get_contacts + ```ruby + gateway.authorize_from_request(request_token.token, request_token.secret, oauth_verifier: params[:oauth_verifier]) + ``` + + (If you haven't specified a Callback URL, the user will be presented + with a numeric verifier which they must copy+paste into your + application; see examples/oauth.rb for an example) + + Now you can access Xero API methods: + + ```ruby + gateway.get_contacts + # => # params[:oauth_verifier]) + def create + @xero_gateway.authorize_from_request(session[:request_token], session[:request_secret], + oauth_verifier: params[:oauth_verifier]) - session[:xero_auth] = { :access_token => @xero_gateway.access_token.token, - :access_secret => @xero_gateway.access_token.secret } + session[:xero_auth] = { access_token: @xero_gateway.access_token.token, + access_secret: @xero_gateway.access_token.secret } - session.data.delete(:request_token); session.data.delete(:request_secret) - end + session.data.delete(:request_token) + session.data.delete(:request_secret) + end - def destroy - session.data.delete(:xero_auth) - end + def destroy + session.data.delete(:xero_auth) + end - private - - def get_xero_gateway - @xero_gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET) - end + private + def get_xero_gateway + @xero_gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET) end + end +``` + Note that I'm just storing the Access Token + Secret in the session here - you could equally store them in the database if you felt like refreshing them every 30 minutes ;) -Implemented interface methods ------------------------------ - -### GET /api.xro/2.0/contact (get\_contact\_by\_id) - -Gets a contact record for a specific Xero organisation - - result = gateway.get_contact_by_id(contact_id) - contact = result.contact if result.success? - -### GET /api.xro/2.0/contact (get\_contact\_by\_number) - -Gets a contact record for a specific Xero organisation - - gateway.get_contact_by_number(contact_number) - -### GET /api.xro/2.0/contacts (get\_contacts) - -Gets all contact records for a particular Xero customer. - - gateway.get_contacts(:type => :all, :sort => :name, :direction => :desc) - gateway.get_contacts(:type => :all, :modified_since => 1.month.ago) # modified since 1 month ago - -### PUT /api.xro/2.0/contact - -Saves a contact record for a particular Xero customer. - - contact = gateway.build_contact - contact.name = "The contacts name" - contact.email = "whoever@something.com" - contact.phone.number = "555 123 4567" - contact.address.line_1 = "LINE 1 OF THE ADDRESS" - contact.address.line_2 = "LINE 2 OF THE ADDRESS" - contact.address.city = "WELLINGTON" - contact.address.region = "WELLINGTON" - contact.address.country = "NEW ZEALAND" - contact.address.post_code = "6021" - - contact.save - -### POST /api.xro/2.0/contact - -Updates an existing contact record. - - contact_retrieved_from_xero.email = "something_new@something.com" - contact_retrieved_from_xero.save - -### POST /api.xro/2.0/contacts - -Creates a list of contacts or updates them if they have a matching -contact\_id, contact\_number or name.\ -This method uses only a single API request to create/update multiple -contacts. - - contacts = [XeroGateway::Contact.new(:name => 'Joe Bloggs'), XeroGateway::Contact.new(:name => 'Jane Doe')] - result = gateway.update_contacts(contacts) - -### GET /api.xro/2.0/invoice (get\_invoice) - -Gets an invoice record for a specific Xero organisation by either id or -number - - gateway.get_invoice(invoice_id_or_number) - -### GET /api.xro/2.0/invoices (get\_invoices) - -Gets all invoice records for a particular Xero customer. - - gateway.get_invoices - gateway.get_invoices(:modified_since => 1.month.ago) # modified since 1 month ago - -### PUT /api.xro/2.0/invoice - -Inserts an invoice for a specific organization in Xero (Currently only -adding new invoices is allowed). - -Invoice and line item totals are calculated automatically. - - invoice = gateway.build_invoice({ - :invoice_type => "ACCREC", - :due_date => 1.month.from_now, - :invoice_number => "YOUR INVOICE NUMBER", - :reference => "YOUR REFERENCE (NOT NECESSARILY UNIQUE!)", - :line_amount_types => "Inclusive" # "Inclusive", "Exclusive" or "NoTax" - }) - invoice.contact.name = "THE NAME OF THE CONTACT" - invoice.contact.phone.number = "12345" - invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS" - - line_item = XeroGateway::LineItem.new( - :description => "THE DESCRIPTION OF THE LINE ITEM", - :account_code => 200, - :unit_amount => 1000 - ) - - line_item.tracking << XeroGateway::TrackingCategory.new(:name => "tracking category", :options => "tracking option") - - invoice.line_items << line_item - - invoice.create - -### POST /api.xro/2.0/invoice - -Updates an existing invoice record. +## API Methods - invoice_retrieved_from_xero.due_date = Date.today - invoice_retrieved_from_xero.save +You can find a full listing of all implemented methods on [the wiki page](https://github.com/xero-gateway/xero_gateway/wiki/API-Methods). -### PUT /api.xro/2.0/invoices +## Logging -Inserts multiple invoices for a specific organization in Xero (currently -only adding new invoices is allowed).\ -This method uses only a single API request to create/update multiple -contacts. - - invoices = [XeroGateway::Invoice.new(...), XeroGateway::Invoice.new(...)] - result = gateway.create_invoices(invoices) - -### GET /api.xro/2.0/credit\_note (get\_credit\_note\_by\_id) - -Gets an credit\_note record for a specific Xero organisation - - gateway.get_credit_note_by_id(credit_note_id) - -### GET /api.xro/2.0/credit\_note (get\_credit\_note\_by\_number) - -Gets a credit note record for a specific Xero organisation - - gateway.get_credit_note_by_number(credit_note_number) - -### GET /api.xro/2.0/credit\_notes (get\_credit\_notes) - -Gets all credit note records for a particular Xero customer. - - gateway.get_credit_notes - gateway.get_credit_notes(:modified_since => 1.month.ago) # modified since 1 month ago - -### PUT /api.xro/2.0/credit\_note - -Inserts a credit note for a specific organization in Xero (Currently -only adding new credit notes is allowed). - -CreditNote and line item totals are calculated automatically. - - credit_note = gateway.build_credit_note({ - :credit_note_type => "ACCRECCREDIT", - :credit_note_number => "YOUR CREDIT NOTE NUMBER", - :reference => "YOUR REFERENCE (NOT NECESSARILY UNIQUE!)", - :line_amount_types => "Inclusive" # "Inclusive", "Exclusive" or "NoTax" - }) - credit_note.contact.name = "THE NAME OF THE CONTACT" - credit_note.contact.phone.number = "12345" - credit_note.contact.address.line_1 = "LINE 1 OF THE ADDRESS" - credit_note.add_line_item({ - :description => "THE DESCRIPTION OF THE LINE ITEM", - :unit_amount => 1000, - :tax_amount => 125, - :tracking_category => "THE TRACKING CATEGORY FOR THE LINE ITEM", - :tracking_option => "THE TRACKING OPTION FOR THE LINE ITEM" - }) - - credit_note.create - -### PUT /api.xro/2.0/credit\_notes - -Inserts multiple credit notes for a specific organization in Xero -(currently only adding new credit notes is allowed).\ -This method uses only a single API request to create/update multiple -contacts. - - credit_notes = [XeroGateway::CreditNote.new(...), XeroGateway::CreditNote.new(...)] - result = gateway.create_credit_notes(credit_notes) - -### GET /api.xro/2.0/accounts - -Gets all accounts for a specific organization in Xero. - - gateway.get_accounts - -For more advanced (and cached) access to the accounts list, use the -following. - - accounts_list = gateway.get_accounts_list - -Finds account with code of '200' - - sales_account = accounts_list.find_by_code(200) - -Finds all EXPENSE accounts. For a list of valid account types see -XeroGateway::Account::TYPE - - all_expense_accounts = accounts_list.find_all_by_type('EXPENSE') - -Finds all accounts with tax\_type == 'OUTPUT'. For a list of valid tax -types see XeroGateway::Account::TAX\_TYPE - - all_output_tax_accounts = accounts_list.find_all_by_tax_type('OUTPUT') - -### GET /api.xro/2.0/tracking - -Gets all tracking categories and their options for a specific -organization in Xero. - - gateway.get_tracking_categories - -### GET /api.xero/2.0/Organisation - -Retrieves organisation details for the authorised application. - - gateway.get_organisation.organisation - -### GET /api.xero/2.0/Currencies - -Retrieves currencies in use for the authorised application. - - gateway.get_currencies.currencies - -### GET /api.xero/2.0/TaxRates +You can specify a logger to use (so you can track down those tricky +exceptions) by using: -Retrieves Tax Rates in use for the authorised application. +```ruby + gateway.logger = ActiveSupport::BufferedLogger.new("log_file_name.log") +``` - gateway.get_tax_rates.tax_rates +Your logger simply needs to respond to `info`. -Logging -------- +## Contributing -You can specify a logger to use (so you can track down those tricky -exceptions) by using: +We welcome contributions, thanks for pitching in! :sparkles: - gateway.logger = ActiveSupport::BufferedLogger.new("log_file_name.log") +1. Fork the repo +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Make sure you have some tests, and they pass! (`bundle exec rake`) +4. Commit your changes (`git commit -am 'Added some feature'`) +5. Push to the branch (`git push origin my-new-feature`) +6. Create new Pull Request -It doesn't have to be a buffered logger - anything that responds to -"info" will do just fine. +This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.