xeroizer-3-pre-beta 3.0.0.pre.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (429) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +41 -0
  3. data/README.md +34 -0
  4. data/lib/class_level_inheritable_attributes.rb +28 -0
  5. data/lib/xeroizer.rb +117 -0
  6. data/lib/xeroizer/application_http_proxy.rb +30 -0
  7. data/lib/xeroizer/ca-certificates.crt +2694 -0
  8. data/lib/xeroizer/configuration.rb +19 -0
  9. data/lib/xeroizer/connection.rb +31 -0
  10. data/lib/xeroizer/exceptions.rb +161 -0
  11. data/lib/xeroizer/generic_application.rb +90 -0
  12. data/lib/xeroizer/http.rb +160 -0
  13. data/lib/xeroizer/http_encoding_helper.rb +49 -0
  14. data/lib/xeroizer/http_response.rb +154 -0
  15. data/lib/xeroizer/logging.rb +8 -0
  16. data/lib/xeroizer/models/account.rb +72 -0
  17. data/lib/xeroizer/models/accounts_payable.rb +13 -0
  18. data/lib/xeroizer/models/accounts_receivable.rb +13 -0
  19. data/lib/xeroizer/models/address.rb +41 -0
  20. data/lib/xeroizer/models/allocation.rb +13 -0
  21. data/lib/xeroizer/models/attachment.rb +95 -0
  22. data/lib/xeroizer/models/balances.rb +17 -0
  23. data/lib/xeroizer/models/bank_account.rb +13 -0
  24. data/lib/xeroizer/models/bank_transaction.rb +95 -0
  25. data/lib/xeroizer/models/bank_transfer.rb +28 -0
  26. data/lib/xeroizer/models/batch_payment.rb +24 -0
  27. data/lib/xeroizer/models/batch_payments.rb +14 -0
  28. data/lib/xeroizer/models/bills.rb +13 -0
  29. data/lib/xeroizer/models/branding_theme.rb +62 -0
  30. data/lib/xeroizer/models/contact.rb +77 -0
  31. data/lib/xeroizer/models/contact_group.rb +64 -0
  32. data/lib/xeroizer/models/contact_person.rb +20 -0
  33. data/lib/xeroizer/models/contact_purchases_tracking_category.rb +19 -0
  34. data/lib/xeroizer/models/contact_sales_tracking_category.rb +19 -0
  35. data/lib/xeroizer/models/credit_note.rb +164 -0
  36. data/lib/xeroizer/models/currency.rb +30 -0
  37. data/lib/xeroizer/models/employee.rb +73 -0
  38. data/lib/xeroizer/models/expense_claim.rb +29 -0
  39. data/lib/xeroizer/models/external_link.rb +16 -0
  40. data/lib/xeroizer/models/from_bank_account.rb +13 -0
  41. data/lib/xeroizer/models/invoice.rb +229 -0
  42. data/lib/xeroizer/models/invoice_reminder.rb +19 -0
  43. data/lib/xeroizer/models/item.rb +39 -0
  44. data/lib/xeroizer/models/item_purchase_details.rb +20 -0
  45. data/lib/xeroizer/models/item_sales_details.rb +19 -0
  46. data/lib/xeroizer/models/journal.rb +27 -0
  47. data/lib/xeroizer/models/journal_line.rb +29 -0
  48. data/lib/xeroizer/models/journal_line_tracking_category.rb +21 -0
  49. data/lib/xeroizer/models/line_amount_type.rb +11 -0
  50. data/lib/xeroizer/models/line_item.rb +64 -0
  51. data/lib/xeroizer/models/line_item_sum.rb +21 -0
  52. data/lib/xeroizer/models/manual_journal.rb +49 -0
  53. data/lib/xeroizer/models/manual_journal_line.rb +28 -0
  54. data/lib/xeroizer/models/online_invoice.rb +37 -0
  55. data/lib/xeroizer/models/option.rb +18 -0
  56. data/lib/xeroizer/models/organisation.rb +85 -0
  57. data/lib/xeroizer/models/overpayment.rb +40 -0
  58. data/lib/xeroizer/models/payment.rb +48 -0
  59. data/lib/xeroizer/models/payment_service.rb +22 -0
  60. data/lib/xeroizer/models/payment_terms.rb +16 -0
  61. data/lib/xeroizer/models/payroll/address.rb +53 -0
  62. data/lib/xeroizer/models/payroll/bank_account.rb +35 -0
  63. data/lib/xeroizer/models/payroll/benefit_line.rb +26 -0
  64. data/lib/xeroizer/models/payroll/benefit_type.rb +45 -0
  65. data/lib/xeroizer/models/payroll/deduction_line.rb +32 -0
  66. data/lib/xeroizer/models/payroll/deduction_type.rb +49 -0
  67. data/lib/xeroizer/models/payroll/earnings_line.rb +39 -0
  68. data/lib/xeroizer/models/payroll/earnings_type.rb +53 -0
  69. data/lib/xeroizer/models/payroll/employee.rb +67 -0
  70. data/lib/xeroizer/models/payroll/leave_application.rb +27 -0
  71. data/lib/xeroizer/models/payroll/leave_line.rb +30 -0
  72. data/lib/xeroizer/models/payroll/leave_period.rb +15 -0
  73. data/lib/xeroizer/models/payroll/pay_items.rb +22 -0
  74. data/lib/xeroizer/models/payroll/pay_run.rb +33 -0
  75. data/lib/xeroizer/models/payroll/pay_schedule.rb +40 -0
  76. data/lib/xeroizer/models/payroll/pay_template.rb +24 -0
  77. data/lib/xeroizer/models/payroll/payment_method.rb +24 -0
  78. data/lib/xeroizer/models/payroll/paystub.rb +44 -0
  79. data/lib/xeroizer/models/payroll/reimbursement_line.rb +21 -0
  80. data/lib/xeroizer/models/payroll/reimbursement_type.rb +22 -0
  81. data/lib/xeroizer/models/payroll/salary_and_wage.rb +29 -0
  82. data/lib/xeroizer/models/payroll/super_line.rb +40 -0
  83. data/lib/xeroizer/models/payroll/tax_declaration.rb +50 -0
  84. data/lib/xeroizer/models/payroll/time_off_line.rb +20 -0
  85. data/lib/xeroizer/models/payroll/time_off_type.rb +32 -0
  86. data/lib/xeroizer/models/payroll/work_location.rb +25 -0
  87. data/lib/xeroizer/models/phone.rb +26 -0
  88. data/lib/xeroizer/models/prepayment.rb +41 -0
  89. data/lib/xeroizer/models/purchase_order.rb +49 -0
  90. data/lib/xeroizer/models/receipt.rb +39 -0
  91. data/lib/xeroizer/models/repeating_invoice.rb +80 -0
  92. data/lib/xeroizer/models/sales.rb +13 -0
  93. data/lib/xeroizer/models/schedule.rb +34 -0
  94. data/lib/xeroizer/models/tax_component.rb +13 -0
  95. data/lib/xeroizer/models/tax_rate.rb +36 -0
  96. data/lib/xeroizer/models/to_bank_account.rb +13 -0
  97. data/lib/xeroizer/models/tracking_category.rb +23 -0
  98. data/lib/xeroizer/models/tracking_category_child.rb +20 -0
  99. data/lib/xeroizer/models/user.rb +26 -0
  100. data/lib/xeroizer/oauth.rb +162 -0
  101. data/lib/xeroizer/oauth2.rb +66 -0
  102. data/lib/xeroizer/oauth2_application.rb +42 -0
  103. data/lib/xeroizer/partner_application.rb +52 -0
  104. data/lib/xeroizer/payroll_application.rb +33 -0
  105. data/lib/xeroizer/private_application.rb +26 -0
  106. data/lib/xeroizer/public_application.rb +22 -0
  107. data/lib/xeroizer/record/application_helper.rb +32 -0
  108. data/lib/xeroizer/record/base.rb +203 -0
  109. data/lib/xeroizer/record/base_model.rb +253 -0
  110. data/lib/xeroizer/record/base_model_http_proxy.rb +141 -0
  111. data/lib/xeroizer/record/model_definition_helper.rb +101 -0
  112. data/lib/xeroizer/record/payroll_base.rb +29 -0
  113. data/lib/xeroizer/record/payroll_base_model.rb +29 -0
  114. data/lib/xeroizer/record/record_association_helper.rb +141 -0
  115. data/lib/xeroizer/record/validation_helper.rb +75 -0
  116. data/lib/xeroizer/record/validators/associated_validator.rb +34 -0
  117. data/lib/xeroizer/record/validators/block_validator.rb +22 -0
  118. data/lib/xeroizer/record/validators/inclusion_of_validator.rb +22 -0
  119. data/lib/xeroizer/record/validators/length_of_validator.rb +23 -0
  120. data/lib/xeroizer/record/validators/presence_of_validator.rb +19 -0
  121. data/lib/xeroizer/record/validators/validator.rb +33 -0
  122. data/lib/xeroizer/record/xml_helper.rb +144 -0
  123. data/lib/xeroizer/report/aged_receivables_by_contact.rb +42 -0
  124. data/lib/xeroizer/report/base.rb +42 -0
  125. data/lib/xeroizer/report/cell.rb +32 -0
  126. data/lib/xeroizer/report/cell_xml_helper.rb +74 -0
  127. data/lib/xeroizer/report/factory.rb +54 -0
  128. data/lib/xeroizer/report/row/header.rb +12 -0
  129. data/lib/xeroizer/report/row/row.rb +48 -0
  130. data/lib/xeroizer/report/row/section.rb +10 -0
  131. data/lib/xeroizer/report/row/summary.rb +9 -0
  132. data/lib/xeroizer/report/row/xml_helper.rb +77 -0
  133. data/lib/xeroizer/report/xml_helper.rb +58 -0
  134. data/lib/xeroizer/response.rb +74 -0
  135. data/lib/xeroizer/version.rb +3 -0
  136. data/test/acceptance/about_creating_bank_transactions_test.rb +170 -0
  137. data/test/acceptance/about_creating_prepayment_test.rb +41 -0
  138. data/test/acceptance/about_fetching_bank_transactions_test.rb +53 -0
  139. data/test/acceptance/about_online_invoice_test.rb +25 -0
  140. data/test/acceptance/acceptance_test.rb +77 -0
  141. data/test/acceptance/bank_transaction_reference_data.rb +32 -0
  142. data/test/acceptance/bank_transfer_test.rb +21 -0
  143. data/test/acceptance/bulk_operations_test.rb +50 -0
  144. data/test/acceptance/connections_test.rb +11 -0
  145. data/test/stub_responses/accounts.xml +589 -0
  146. data/test/stub_responses/api_exception.xml +153 -0
  147. data/test/stub_responses/bad_request.json +6 -0
  148. data/test/stub_responses/bogus_oauth_error +1 -0
  149. data/test/stub_responses/branding_themes.xml +20 -0
  150. data/test/stub_responses/connections.json +16 -0
  151. data/test/stub_responses/contact.xml +54 -0
  152. data/test/stub_responses/contact_with_details.xml +79 -0
  153. data/test/stub_responses/contacts.xml +0 -0
  154. data/test/stub_responses/create_credit_note.xml +104 -0
  155. data/test/stub_responses/create_invoice.xml +64 -0
  156. data/test/stub_responses/credit_note.xml +75 -0
  157. data/test/stub_responses/credit_note_not_found_error.xml +1 -0
  158. data/test/stub_responses/credit_notes.xml +169 -0
  159. data/test/stub_responses/currencies.xml +12 -0
  160. data/test/stub_responses/employees.xml +29 -0
  161. data/test/stub_responses/expired_oauth2_token.json +6 -0
  162. data/test/stub_responses/generic_response_error.json +6 -0
  163. data/test/stub_responses/invalid_api_key_error.xml +1 -0
  164. data/test/stub_responses/invalid_consumer_key +1 -0
  165. data/test/stub_responses/invalid_oauth2_request_token.json +6 -0
  166. data/test/stub_responses/invalid_request_token +1 -0
  167. data/test/stub_responses/invalid_tenant_header.json +6 -0
  168. data/test/stub_responses/invoice.xml +84 -0
  169. data/test/stub_responses/invoice_not_found_error.xml +1 -0
  170. data/test/stub_responses/invoices.xml +1899 -0
  171. data/test/stub_responses/items.xml +112 -0
  172. data/test/stub_responses/manual_journal.xml +45 -0
  173. data/test/stub_responses/manual_journals.xml +40 -0
  174. data/test/stub_responses/nonce_used +1 -0
  175. data/test/stub_responses/object_not_found.json +6 -0
  176. data/test/stub_responses/organisation.xml +55 -0
  177. data/test/stub_responses/organisations.xml +35 -0
  178. data/test/stub_responses/payment_service.xml +15 -0
  179. data/test/stub_responses/payments.xml +1121 -0
  180. data/test/stub_responses/prepayments.xml +27 -0
  181. data/test/stub_responses/rate_limit_exceeded +1 -0
  182. data/test/stub_responses/records/contact-043892a1-aef1-4c18-88d8-b8ccb6d31466.xml +38 -0
  183. data/test/stub_responses/records/contact-09664078-efe2-4a88-89a5-67eac9b0047b.xml +40 -0
  184. data/test/stub_responses/records/contact-0a4cf37b-a1a8-4753-9ee2-f9207f63a8ff.xml +48 -0
  185. data/test/stub_responses/records/contact-0e74f929-11b9-4255-a035-1fdfe573e676.xml +40 -0
  186. data/test/stub_responses/records/contact-0f471ca5-15c9-405e-a1b9-7cc35194b673.xml +38 -0
  187. data/test/stub_responses/records/contact-13cd4c47-baa6-4f07-93f6-6442310df4bf.xml +47 -0
  188. data/test/stub_responses/records/contact-158a2667-82ee-43bf-8f33-a6cc9524092d.xml +38 -0
  189. data/test/stub_responses/records/contact-17465072-6fa3-40bf-bc42-97765d9e1bea.xml +38 -0
  190. data/test/stub_responses/records/contact-1975b0ed-b7ba-4c61-bae8-2aa6d78b0dee.xml +39 -0
  191. data/test/stub_responses/records/contact-1b2be6e9-8d58-4da9-aaf8-4fe5471b653c.xml +53 -0
  192. data/test/stub_responses/records/contact-1c40da58-fe1d-4e97-b729-b2abdae94d9e.xml +38 -0
  193. data/test/stub_responses/records/contact-258176a5-c622-4394-9c94-6f88c3ea12e5.xml +40 -0
  194. data/test/stub_responses/records/contact-299dd3a0-a417-4a37-8a04-2f55e91963e5.xml +40 -0
  195. data/test/stub_responses/records/contact-2be39278-5154-4ed1-8eb0-676f25acfc66.xml +40 -0
  196. data/test/stub_responses/records/contact-2e58cff6-488c-4a32-884b-baf848010229.xml +40 -0
  197. data/test/stub_responses/records/contact-2faccd41-935e-40aa-b74e-e2fc28ac34c3.xml +38 -0
  198. data/test/stub_responses/records/contact-31af01e7-2ca7-45b9-a500-b02db996568e.xml +38 -0
  199. data/test/stub_responses/records/contact-344f1113-a25b-4344-b82e-bedeacc17c8e.xml +40 -0
  200. data/test/stub_responses/records/contact-3e776c4b-ea9e-4bb1-96be-6b0c7a71a37f.xml +39 -0
  201. data/test/stub_responses/records/contact-3fc1fc6c-e5ff-4e40-b6f3-7eb535637d87.xml +38 -0
  202. data/test/stub_responses/records/contact-416ab20c-5357-4beb-a740-e8d175d71efb.xml +38 -0
  203. data/test/stub_responses/records/contact-41a42865-f15a-4fa1-b643-47877608f557.xml +54 -0
  204. data/test/stub_responses/records/contact-42771b60-19a7-4692-af81-dd9f9b9362d4.xml +43 -0
  205. data/test/stub_responses/records/contact-451ceb28-9610-44c9-8f35-3225482f2413.xml +40 -0
  206. data/test/stub_responses/records/contact-4ab343ad-1ebb-4afe-9d48-1814a93c2081.xml +38 -0
  207. data/test/stub_responses/records/contact-4bb77692-42d4-4565-85a0-8849eb85e039.xml +39 -0
  208. data/test/stub_responses/records/contact-4dec292f-3ab7-46a8-83e4-5fb5eac42c7f.xml +40 -0
  209. data/test/stub_responses/records/contact-4e2f192e-8397-4d4d-97ca-a4fc5ac531bf.xml +38 -0
  210. data/test/stub_responses/records/contact-5188c17c-7786-4436-ad6e-9da2997386d0.xml +40 -0
  211. data/test/stub_responses/records/contact-52442753-b1c4-40b7-9b79-c33997de5837.xml +40 -0
  212. data/test/stub_responses/records/contact-565acaa9-e7f3-4fbf-80c3-16b081ddae10.xml +38 -0
  213. data/test/stub_responses/records/contact-571a2414-81ff-4f8f-8498-d91d83793131.xml +44 -0
  214. data/test/stub_responses/records/contact-58697449-85ef-46ae-83fc-6a9446f037fb.xml +40 -0
  215. data/test/stub_responses/records/contact-58bf2ae3-5144-4628-8de2-e165ac2bcdc6.xml +40 -0
  216. data/test/stub_responses/records/contact-5d41dafd-eb7e-42c1-bd5a-ba3be1da0960.xml +38 -0
  217. data/test/stub_responses/records/contact-5f005a09-5ce4-4fb4-8096-e69c18be636e.xml +38 -0
  218. data/test/stub_responses/records/contact-60d578d9-3e10-4aef-b5dc-9d9fd60a3633.xml +47 -0
  219. data/test/stub_responses/records/contact-62392126-dba4-4a75-b907-5875ebf75259.xml +40 -0
  220. data/test/stub_responses/records/contact-642c7fb5-e8e5-48e1-a710-39a18c6c3217.xml +40 -0
  221. data/test/stub_responses/records/contact-64aebf9c-bb89-4b38-b99b-405bd1ece6fd.xml +40 -0
  222. data/test/stub_responses/records/contact-64eedbc9-1fa0-485a-837f-705f23188161.xml +38 -0
  223. data/test/stub_responses/records/contact-65e96c9f-1595-4653-9a8a-2a36d49223c2.xml +40 -0
  224. data/test/stub_responses/records/contact-67d26b93-ccb4-4890-9bf1-284b70ea755d.xml +38 -0
  225. data/test/stub_responses/records/contact-69d3e538-44b3-4e00-a5f6-7dddcb6e0656.xml +40 -0
  226. data/test/stub_responses/records/contact-6a8450bc-f81a-4bb0-a8f6-aa4afe9497c7.xml +40 -0
  227. data/test/stub_responses/records/contact-6c70e424-41d6-4b9b-af3e-b3a9f3589106.xml +40 -0
  228. data/test/stub_responses/records/contact-6de0b0cf-560c-4503-aab3-e1543c329deb.xml +54 -0
  229. data/test/stub_responses/records/contact-72dd6a02-396e-42a2-a4d6-cc3fa75dfece.xml +41 -0
  230. data/test/stub_responses/records/contact-755f1475-d255-43a8-bedc-5ea7fd26c71f.xml +51 -0
  231. data/test/stub_responses/records/contact-78a9d0a0-3d8c-4f84-af3e-f260bf4a9dc0.xml +38 -0
  232. data/test/stub_responses/records/contact-79aa39ca-22b0-42c2-9026-78757a29d665.xml +42 -0
  233. data/test/stub_responses/records/contact-804f4140-5978-48fe-ba20-b56e5b834b18.xml +40 -0
  234. data/test/stub_responses/records/contact-812d4f28-1681-4241-8e34-d15c5520ba35.xml +38 -0
  235. data/test/stub_responses/records/contact-860b99a9-0958-4c8d-a98f-bb1f092b16bb.xml +60 -0
  236. data/test/stub_responses/records/contact-87c8da45-97cc-46be-b170-398da0eacfb8.xml +40 -0
  237. data/test/stub_responses/records/contact-8a154a19-6c6c-404b-bbc9-6deae2d18251.xml +38 -0
  238. data/test/stub_responses/records/contact-8bb6931d-2865-44e9-9a23-ed1fb9c7a46c.xml +40 -0
  239. data/test/stub_responses/records/contact-936c9759-01da-4063-b472-424ab9f48212.xml +38 -0
  240. data/test/stub_responses/records/contact-9d12a994-9640-4b75-95cc-3de1e9d0ef09.xml +38 -0
  241. data/test/stub_responses/records/contact-9fe59245-1fbb-4157-93c3-dc97388f3746.xml +40 -0
  242. data/test/stub_responses/records/contact-a06a7225-6f8a-4522-8400-c534dd43a16e.xml +40 -0
  243. data/test/stub_responses/records/contact-a76a85fe-73a2-46fa-aba7-791f36103cdb.xml +40 -0
  244. data/test/stub_responses/records/contact-a93b5f40-0346-4d21-9181-431e129911c0.xml +40 -0
  245. data/test/stub_responses/records/contact-abf272dd-6b1d-4829-af88-c57bf55855e3.xml +38 -0
  246. data/test/stub_responses/records/contact-ad24c33b-256b-4157-ad56-cbcf0e8db7b1.xml +47 -0
  247. data/test/stub_responses/records/contact-b107129d-f4c9-438e-9573-64b778527f4a.xml +40 -0
  248. data/test/stub_responses/records/contact-b233288a-aa26-4b26-9fc7-779d797dd56f.xml +40 -0
  249. data/test/stub_responses/records/contact-b2b5333a-2546-4975-891f-d71a8a640d23.xml +38 -0
  250. data/test/stub_responses/records/contact-b4d149bf-1823-4bd2-96da-9032388c9686.xml +40 -0
  251. data/test/stub_responses/records/contact-b78d4fd1-4306-4d83-a0b9-61458d1c53a2.xml +40 -0
  252. data/test/stub_responses/records/contact-b7d108a8-d5f7-4f16-a7c9-26eaed98e8de.xml +40 -0
  253. data/test/stub_responses/records/contact-baeed0f3-7989-4874-99b3-59f23032cb73.xml +38 -0
  254. data/test/stub_responses/records/contact-bc51a3a1-b7f6-46ca-ac9e-19b87e6ca100.xml +40 -0
  255. data/test/stub_responses/records/contact-be9f3aab-52f5-4d9c-94b4-87f7d9e5ee8b.xml +38 -0
  256. data/test/stub_responses/records/contact-c135f994-01e4-427b-9e15-acfe8a477c16.xml +49 -0
  257. data/test/stub_responses/records/contact-c14edf75-15e4-4a9c-86e4-f52e2fe7cfa4.xml +40 -0
  258. data/test/stub_responses/records/contact-ca9b9abc-c2dc-4221-8101-31f464d314cc.xml +44 -0
  259. data/test/stub_responses/records/contact-cc4db604-9ed8-4eef-8a29-51b5b70496a0.xml +38 -0
  260. data/test/stub_responses/records/contact-cce9b044-be4a-43b3-9dc7-c027d8dd35b2.xml +38 -0
  261. data/test/stub_responses/records/contact-d0cd2c4f-18a0-4f7c-a32a-2db00f29d298.xml +43 -0
  262. data/test/stub_responses/records/contact-d6851dc2-9ed9-4515-bc0b-810b09c06a6a.xml +38 -0
  263. data/test/stub_responses/records/contact-d6a384fb-f46f-41a3-8ac7-b7bc9e0b5efa.xml +46 -0
  264. data/test/stub_responses/records/contact-d74e61cf-2ad0-4f0d-b9d1-6a808e3f70cf.xml +40 -0
  265. data/test/stub_responses/records/contact-d9ab0f61-3b56-4e2b-be39-f33c11bd99e3.xml +40 -0
  266. data/test/stub_responses/records/contact-dbb1f0b5-a71b-4458-8462-104acd0fec6b.xml +38 -0
  267. data/test/stub_responses/records/contact-dd981bd6-40dd-496d-a282-bf7d3391b8b9.xml +40 -0
  268. data/test/stub_responses/records/contact-e1826204-cc0a-42a5-a6d0-4b352d9d5953.xml +40 -0
  269. data/test/stub_responses/records/contact-e2d955db-f366-42dd-87f7-fbdb4da2306f.xml +40 -0
  270. data/test/stub_responses/records/contact-e32e2130-3d27-443a-8313-48fffa03cf53.xml +40 -0
  271. data/test/stub_responses/records/contact-e3a68332-d322-4816-8678-73a537c8cd33.xml +38 -0
  272. data/test/stub_responses/records/contact-e6ac76a3-ca32-4fa1-8ef9-6a4bf8b0ec2a.xml +40 -0
  273. data/test/stub_responses/records/contact-e6ca965d-7c48-480e-be39-e847307f474a.xml +38 -0
  274. data/test/stub_responses/records/contact-e77d1f20-2e8e-46ec-9a10-50335a216724.xml +40 -0
  275. data/test/stub_responses/records/contact-e8b98c13-a424-41d2-ba0e-7b7621411e7a.xml +38 -0
  276. data/test/stub_responses/records/contact-e8e9a2c2-3e7e-48ed-8528-c3d61b28f276.xml +39 -0
  277. data/test/stub_responses/records/contact-eb43fcc6-87ec-4a0a-b243-d718bee4e2cb.xml +38 -0
  278. data/test/stub_responses/records/contact-ef6f54c1-eb45-4956-b8cd-1be82ad665f2.xml +43 -0
  279. data/test/stub_responses/records/contact-efdb3600-f233-42e2-8f18-ce7e2a95e4b1.xml +38 -0
  280. data/test/stub_responses/records/contact-f7eca431-5c97-4d24-93fd-004bb8a6c644.xml +40 -0
  281. data/test/stub_responses/records/contact-fb078879-5d6d-474f-825f-61dc90689349.xml +38 -0
  282. data/test/stub_responses/records/contact-fc39b273-4aa2-4785-99ca-24672f6c0000.xml +38 -0
  283. data/test/stub_responses/records/contact-fc9ec3a6-a2fe-4300-a8cb-ca8a0b3662e0.xml +40 -0
  284. data/test/stub_responses/records/contact-fdf96102-7491-44b6-bf4d-7a77ff25f890.xml +40 -0
  285. data/test/stub_responses/records/contact-fe61ead1-8afc-4f0b-beda-066620227aad.xml +38 -0
  286. data/test/stub_responses/records/credit_note-371cd138-1e5c-4ec1-a8c6-a1c10e8bdab1.xml +73 -0
  287. data/test/stub_responses/records/credit_note-3bffc09b-79f2-490d-b91b-c59b700b43a4.xml +95 -0
  288. data/test/stub_responses/records/credit_note-43c678ee-f357-48e2-b192-b6e3634762f9.xml +94 -0
  289. data/test/stub_responses/records/credit_note-482c018b-d329-4e05-9b4f-7a4cfc695aa0.xml +77 -0
  290. data/test/stub_responses/records/credit_note-4f67130a-749a-4ee6-98b2-743adbc11245.xml +62 -0
  291. data/test/stub_responses/records/credit_note-50e98404-2fba-4031-af67-8ba4bb227c44.xml +77 -0
  292. data/test/stub_responses/records/credit_note-7df8949c-b71f-40c0-bbcf-39f2f450f286.xml +75 -0
  293. data/test/stub_responses/records/credit_note-b356e488-2678-4be4-ad4b-d294df2d48d6.xml +78 -0
  294. data/test/stub_responses/records/invoice-0032f627-3156-4d30-9b1c-4d3b994dc921.xml +84 -0
  295. data/test/stub_responses/records/invoice-00c9511b-24b9-4190-a90a-8abf2fe9f4a0.xml +76 -0
  296. data/test/stub_responses/records/invoice-024d7994-a26c-4c20-9894-13934840fc31.xml +74 -0
  297. data/test/stub_responses/records/invoice-0e64a623-c2a1-446a-93ed-eb897f118cbc.xml +97 -0
  298. data/test/stub_responses/records/invoice-15e88e57-2554-4496-a18e-eb3f5c622345.xml +75 -0
  299. data/test/stub_responses/records/invoice-166f0588-d0ba-458c-b28a-8edd4c8fc463.xml +75 -0
  300. data/test/stub_responses/records/invoice-1d1ba340-afa2-4f4c-8ff7-a147bda9a47b.xml +93 -0
  301. data/test/stub_responses/records/invoice-290ef4c4-baec-492b-b4dd-c102826470ae.xml +87 -0
  302. data/test/stub_responses/records/invoice-30a87092-31b5-4a2c-831e-327486533dd2.xml +79 -0
  303. data/test/stub_responses/records/invoice-30dbd181-72a8-43df-b392-4241bf43d5fc.xml +79 -0
  304. data/test/stub_responses/records/invoice-33e4123e-7cdd-4f05-9a0a-eb8adeb2b868.xml +94 -0
  305. data/test/stub_responses/records/invoice-387db692-26ac-47e6-b6cc-015343809bda.xml +75 -0
  306. data/test/stub_responses/records/invoice-3b28bf11-ed2f-4cf4-8e9e-fcae730cc292.xml +91 -0
  307. data/test/stub_responses/records/invoice-3fcb9847-b350-412e-ab90-7d9d774ad881.xml +91 -0
  308. data/test/stub_responses/records/invoice-440613e4-4785-4eff-9ba1-c432816cf8c7.xml +78 -0
  309. data/test/stub_responses/records/invoice-4602eda6-abe9-448e-b65f-ae6bea21f0eb.xml +98 -0
  310. data/test/stub_responses/records/invoice-46441f63-873f-4cdc-a278-b8fe516f3abb.xml +94 -0
  311. data/test/stub_responses/records/invoice-4ad1ec01-f4a3-41d7-bbb4-d2ab2fec8e65.xml +74 -0
  312. data/test/stub_responses/records/invoice-4b9afceb-f7c7-4e64-8aac-7b009971fd52.xml +86 -0
  313. data/test/stub_responses/records/invoice-4edbf6d5-4e92-43af-bedd-7effc0b86833.xml +70 -0
  314. data/test/stub_responses/records/invoice-4fad1af2-b871-4ac5-a15a-3c5e32d2e2c4.xml +93 -0
  315. data/test/stub_responses/records/invoice-52ee4d67-cae4-462c-adb2-182c39017f3d.xml +83 -0
  316. data/test/stub_responses/records/invoice-54585f46-c1a0-4432-bd4f-c1fae2fba59b.xml +67 -0
  317. data/test/stub_responses/records/invoice-5613938b-9e27-472e-92ae-3b038b669d10.xml +87 -0
  318. data/test/stub_responses/records/invoice-5aa9451d-95d1-4f95-a966-bbab2573f71c.xml +75 -0
  319. data/test/stub_responses/records/invoice-5aadcd34-01a9-4b8d-a2bb-d7cc1de9fa45.xml +89 -0
  320. data/test/stub_responses/records/invoice-5f6deadf-36a2-495a-9980-ceb11e8af9a9.xml +85 -0
  321. data/test/stub_responses/records/invoice-625ffe1b-f5d8-438e-a376-981de5f5a733.xml +77 -0
  322. data/test/stub_responses/records/invoice-64cd559e-8e03-46af-b461-8555285cee71.xml +86 -0
  323. data/test/stub_responses/records/invoice-666f8dbb-bc9a-476c-8ec4-4665d7f83190.xml +63 -0
  324. data/test/stub_responses/records/invoice-66fbe37f-49b1-43fd-97ed-85114022cd2f.xml +79 -0
  325. data/test/stub_responses/records/invoice-673dd7cc-beb7-4697-83d4-0c47cb400cc2.xml +95 -0
  326. data/test/stub_responses/records/invoice-69fc971e-9b37-41c5-9c87-174330f22343.xml +66 -0
  327. data/test/stub_responses/records/invoice-70e6db69-e5a4-42c7-a397-aa3212c2945f.xml +75 -0
  328. data/test/stub_responses/records/invoice-762aa45d-4632-45b5-8087-b4f47690665e.xml +54 -0
  329. data/test/stub_responses/records/invoice-766d1289-b440-4675-a656-1a0612ecac77.xml +76 -0
  330. data/test/stub_responses/records/invoice-76bcb361-f93b-4513-b312-5a4af306d276.xml +67 -0
  331. data/test/stub_responses/records/invoice-76e3f056-479f-417c-a72b-f3d767899b87.xml +91 -0
  332. data/test/stub_responses/records/invoice-77b338ef-ecc0-4b95-a0d7-2617b0054611.xml +114 -0
  333. data/test/stub_responses/records/invoice-7be9956d-5316-4f6b-a66a-d355b3f159b2.xml +84 -0
  334. data/test/stub_responses/records/invoice-7dae876a-b424-436b-a4e6-17b3fdeec80c.xml +91 -0
  335. data/test/stub_responses/records/invoice-7e862d93-8dab-4856-8b0c-d844e09d750f.xml +68 -0
  336. data/test/stub_responses/records/invoice-803f70b0-56d9-4157-9787-41df271777a0.xml +84 -0
  337. data/test/stub_responses/records/invoice-86102312-aa3f-438c-9938-6840f4d8dda6.xml +75 -0
  338. data/test/stub_responses/records/invoice-8694c9c5-7097-4449-a708-b8c1982921a4.xml +69 -0
  339. data/test/stub_responses/records/invoice-86d6e00f-ef56-49f7-9a54-796ccd5ca057.xml +85 -0
  340. data/test/stub_responses/records/invoice-88e77f0f-54a5-4efc-a979-7e22223cc4d7.xml +66 -0
  341. data/test/stub_responses/records/invoice-8b0ccb6a-d9b7-4da5-8360-ef7fb157b5aa.xml +66 -0
  342. data/test/stub_responses/records/invoice-935fc854-8037-4111-8d91-993010c331cc.xml +74 -0
  343. data/test/stub_responses/records/invoice-95ef3000-c764-4ba9-a66a-b6e2d161f839.xml +62 -0
  344. data/test/stub_responses/records/invoice-962ef33f-c9d2-4602-9b9f-93a02bea23b3.xml +93 -0
  345. data/test/stub_responses/records/invoice-9868b472-1983-48e9-8edf-7e81ddf2c03a.xml +85 -0
  346. data/test/stub_responses/records/invoice-9a448e9b-a9fa-4a8b-98f5-6dc892a37374.xml +62 -0
  347. data/test/stub_responses/records/invoice-a1d04a14-96a8-4067-a0ff-8136990a354f.xml +91 -0
  348. data/test/stub_responses/records/invoice-a3bc62ef-f11b-4a9c-a4f9-a342bda371b5.xml +66 -0
  349. data/test/stub_responses/records/invoice-a6894ca0-60ee-4d45-9dd4-b44fcba46ec5.xml +90 -0
  350. data/test/stub_responses/records/invoice-a77268ce-74b2-483d-a2b3-70dbdc9e49d2.xml +78 -0
  351. data/test/stub_responses/records/invoice-a9f765e6-b9bc-4505-a47b-fb3ecb327e7b.xml +88 -0
  352. data/test/stub_responses/records/invoice-aa0173af-8707-4e7f-8dde-4c7a357bd312.xml +109 -0
  353. data/test/stub_responses/records/invoice-ab63738a-370a-43a5-bfa3-620d684e66d0.xml +83 -0
  354. data/test/stub_responses/records/invoice-b0344791-5a8a-40dd-a208-d99a461a6c10.xml +84 -0
  355. data/test/stub_responses/records/invoice-b1e53910-473c-46a3-b3cb-38ece571220e.xml +76 -0
  356. data/test/stub_responses/records/invoice-b2c02d0b-41a8-4d4d-97d7-014c78b3547d.xml +93 -0
  357. data/test/stub_responses/records/invoice-b75b3928-ab72-4424-8b93-9cdbbde4cd72.xml +90 -0
  358. data/test/stub_responses/records/invoice-bcd8a71f-aa31-4d0f-8a01-13ea26363ddf.xml +94 -0
  359. data/test/stub_responses/records/invoice-bfbb7c45-de02-45e7-b065-d9863ecfb0d8.xml +66 -0
  360. data/test/stub_responses/records/invoice-c12aff7e-12bf-4185-8702-460929f19674.xml +77 -0
  361. data/test/stub_responses/records/invoice-c3380b96-976d-4b3e-8b26-8d01eb6a3742.xml +87 -0
  362. data/test/stub_responses/records/invoice-c963f2b0-cbe1-4abd-9ccc-7e512c942068.xml +67 -0
  363. data/test/stub_responses/records/invoice-cba46b29-3788-4158-b668-ab10160ccbfe.xml +78 -0
  364. data/test/stub_responses/records/invoice-d62646b9-d0a9-4fdb-9561-756a8b7eba45.xml +63 -0
  365. data/test/stub_responses/records/invoice-dba2f021-f149-4191-a126-5351d587ab0e.xml +75 -0
  366. data/test/stub_responses/records/invoice-de5d9c29-21b3-4342-958b-ed72c4bd7ab0.xml +108 -0
  367. data/test/stub_responses/records/invoice-e3d96555-2876-4364-a46a-7551a4f52611.xml +123 -0
  368. data/test/stub_responses/records/invoice-e4a0afbd-aea0-450b-ae23-0ce921e84a77.xml +102 -0
  369. data/test/stub_responses/records/invoice-e9cb9ecb-58ef-43a8-bd20-69a85338142d.xml +76 -0
  370. data/test/stub_responses/records/invoice-ec9a6f67-7128-4a63-8ba3-5e516f455f9b.xml +94 -0
  371. data/test/stub_responses/records/invoice-ed0f2587-84fc-4aef-bc4b-b1a262e24484.xml +81 -0
  372. data/test/stub_responses/records/invoice-f362ca53-8ade-4047-865a-bb64bee5863d.xml +74 -0
  373. data/test/stub_responses/records/invoice-f571c38b-5be1-41e1-ad5a-ff6184284beb.xml +114 -0
  374. data/test/stub_responses/records/invoice-f5832195-5cd3-4660-ad3f-b73d9c64f263.xml +85 -0
  375. data/test/stub_responses/records/invoice-f9c857eb-64cd-4235-a078-d04b52c77ea7.xml +76 -0
  376. data/test/stub_responses/records/manual_journal-4765d07b-aa03-4e56-9166-50661958c864.xml +38 -0
  377. data/test/stub_responses/records/manual_journal-53fc5558-5b76-4ecd-ae5c-c4af3ccde87c.xml +31 -0
  378. data/test/stub_responses/records/manual_journal-bb6cfcfc-4500-4475-bd3a-93ee512428e0.xml +31 -0
  379. data/test/stub_responses/records/manual_journal-f00a355b-7374-445c-886b-0437bea4095c.xml +45 -0
  380. data/test/stub_responses/records/prepayment-7d3619b1-82cc-405b-8f44-9d4f9a787a8a.xml +92 -0
  381. data/test/stub_responses/records/repeating_invoice-ad3550bc-1ae0-45c0-a782-48c6d2061127.xml +43 -0
  382. data/test/stub_responses/refresh_responses.rb +29 -0
  383. data/test/stub_responses/repeating_invoices.xml +43 -0
  384. data/test/stub_responses/reports/trial_balance.xml +1435 -0
  385. data/test/stub_responses/tax_rates.xml +198 -0
  386. data/test/stub_responses/token_expired +1 -0
  387. data/test/stub_responses/tracking_categories.xml +27 -0
  388. data/test/stub_responses/unknown_error.xml +1 -0
  389. data/test/stub_responses/users.xml +17 -0
  390. data/test/test_helper.rb +72 -0
  391. data/test/unit/generic_application_test.rb +52 -0
  392. data/test/unit/http_test.rb +302 -0
  393. data/test/unit/models/address_test.rb +92 -0
  394. data/test/unit/models/bank_transaction_model_parsing_test.rb +133 -0
  395. data/test/unit/models/bank_transaction_test.rb +44 -0
  396. data/test/unit/models/bank_transaction_validation_test.rb +115 -0
  397. data/test/unit/models/contact_test.rb +132 -0
  398. data/test/unit/models/credit_note_test.rb +37 -0
  399. data/test/unit/models/employee_test.rb +43 -0
  400. data/test/unit/models/invoice_test.rb +133 -0
  401. data/test/unit/models/journal_line_test.rb +22 -0
  402. data/test/unit/models/journal_test.rb +44 -0
  403. data/test/unit/models/line_item_sum_test.rb +25 -0
  404. data/test/unit/models/line_item_test.rb +59 -0
  405. data/test/unit/models/manual_journal_test.rb +25 -0
  406. data/test/unit/models/organisation_test.rb +52 -0
  407. data/test/unit/models/payment_service_test.rb +29 -0
  408. data/test/unit/models/phone_test.rb +31 -0
  409. data/test/unit/models/prepayment_test.rb +21 -0
  410. data/test/unit/models/repeating_invoice_test.rb +36 -0
  411. data/test/unit/models/tax_rate_test.rb +132 -0
  412. data/test/unit/oauth2_test.rb +171 -0
  413. data/test/unit/oauth_config_test.rb +20 -0
  414. data/test/unit/oauth_test.rb +179 -0
  415. data/test/unit/private_application_test.rb +20 -0
  416. data/test/unit/record/base_model_test.rb +58 -0
  417. data/test/unit/record/base_test.rb +174 -0
  418. data/test/unit/record/block_validator_test.rb +125 -0
  419. data/test/unit/record/connection_test.rb +60 -0
  420. data/test/unit/record/model_definition_test.rb +165 -0
  421. data/test/unit/record/parse_params_test.rb +59 -0
  422. data/test/unit/record/parse_where_hash_test.rb +63 -0
  423. data/test/unit/record/record_association_test.rb +93 -0
  424. data/test/unit/record/validators_test.rb +228 -0
  425. data/test/unit/record_definition_test.rb +27 -0
  426. data/test/unit/report_definition_test.rb +26 -0
  427. data/test/unit/report_test.rb +154 -0
  428. data/test/unit_test_helper.rb +16 -0
  429. metadata +1024 -0
@@ -0,0 +1,19 @@
1
+ module Xeroizer
2
+ OAuthCredentials = Struct.new "OAuthCredentials", :consumer_key, :consumer_secret, :key_file
3
+
4
+ class OAuthConfig
5
+ class << self
6
+ def load yaml_text
7
+ require "yaml"
8
+ yaml = YAML.load yaml_text
9
+ consumer_credential = yaml["consumer"]
10
+
11
+ OAuthCredentials.new(
12
+ consumer_credential["key"],
13
+ consumer_credential["secret"],
14
+ consumer_credential["key_file"]
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ module Xeroizer
2
+ class Connection
3
+ class << self
4
+ def current_connections(client)
5
+ response = do_request(client)
6
+
7
+ if response.success?
8
+ JSON.parse(response.plain_body).map do |connection_json|
9
+ new(connection_json)
10
+ end
11
+ else
12
+ raise Xeroizer::OAuth::TokenInvalid, response.plain_body
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def do_request(client)
19
+ client.get('https://api.xero.com/connections')
20
+ end
21
+ end
22
+
23
+ def initialize(json)
24
+ @json = json
25
+ end
26
+
27
+ def method_missing(name, *_args)
28
+ @json.send(:[], name.to_s.camelcase(:lower))
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,161 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ module Xeroizer
16
+
17
+ class XeroizerError < StandardError; end
18
+
19
+ class ApiException < XeroizerError
20
+
21
+ attr_reader :type, :message, :xml, :parsed_xml, :request_body
22
+
23
+ def initialize(type, message, xml, parsed_xml, request_body)
24
+ @type = type
25
+ @message = message
26
+ @xml = xml
27
+ @parsed_xml = parsed_xml
28
+ @request_body = request_body
29
+ end
30
+
31
+ def message
32
+ "#{@type}: #{@message} \n Generated by the following XML: \n #{@xml}"
33
+ end
34
+
35
+ def validation_errors
36
+ errors = []
37
+ @parsed_xml.xpath("//ValidationError").each do |err|
38
+ errors << err.text.gsub(/^\s+/, '').gsub(/\s+$/, '')
39
+ end
40
+ errors
41
+ rescue
42
+ []
43
+ end
44
+
45
+ end
46
+
47
+ class UnparseableResponse < XeroizerError
48
+
49
+ def initialize(root_element_name)
50
+ @root_element_name = root_element_name
51
+ end
52
+
53
+ def message
54
+ "A root element of #{@root_element_name} was returned, and we don't understand that!"
55
+ end
56
+
57
+ end
58
+
59
+ class ObjectNotFound < XeroizerError
60
+
61
+ def initialize(api_endpoint)
62
+ @api_endpoint = api_endpoint
63
+ end
64
+
65
+ def message
66
+ "Couldn't find object for API Endpoint #{@api_endpoint}"
67
+ end
68
+
69
+ end
70
+
71
+ class InvoiceNotFoundError < XeroizerError; end
72
+
73
+ class CreditNoteNotFoundError < XeroizerError; end
74
+
75
+ class MethodNotAllowed < XeroizerError
76
+
77
+ def initialize(klass, method)
78
+ @klass = klass
79
+ @method = method
80
+ end
81
+
82
+ def message
83
+ "Method #{@method} not allowed on #{@klass}"
84
+ end
85
+
86
+ end
87
+
88
+ class RecordKeyMustBeDefined < XeroizerError
89
+
90
+ def initialize(possible_keys)
91
+ @possible_keys = possible_keys
92
+ end
93
+
94
+ def message
95
+ "One of the keys #{@possible_keys.join(', ')} need to be defined to update the record."
96
+ end
97
+
98
+ end
99
+
100
+ class RecordInvalid < XeroizerError; end
101
+
102
+ class SettingTotalDirectlyNotSupported < XeroizerError
103
+
104
+ def initialize(attribute_name)
105
+ @attribute_name = attribute_name
106
+ end
107
+
108
+ def message
109
+ "Can't set the total #{@attribute_name} directly as this is calculated automatically."
110
+ end
111
+
112
+ end
113
+
114
+ class InvalidAttributeInWhere < XeroizerError
115
+
116
+ def initialize(model_name, attribute_name)
117
+ @model_name = model_name
118
+ @attribute_name = attribute_name
119
+ end
120
+
121
+ def message
122
+ "#{@attribute_name} is not an attribute of #{@model_name}."
123
+ end
124
+
125
+ end
126
+
127
+ class AssociationTypeMismatch < XeroizerError
128
+
129
+ def initialize(model_class, actual_class)
130
+ @model_class = model_class
131
+ @actual_class = actual_class
132
+ end
133
+
134
+ def message
135
+ "#{@model_class} expected, got #{@actual_class}"
136
+ end
137
+
138
+ end
139
+
140
+ class CannotChangeInvoiceStatus < XeroizerError
141
+
142
+ def initialize(invoice, new_status)
143
+ @invoice = invoice
144
+ @new_status = new_status
145
+ end
146
+
147
+ def message
148
+ case @new_status
149
+ when 'DELETED', 'VOIDED'
150
+ unless @invoice.payments.size == 0
151
+ "There must be no payments in this invoice to change to '#{@new_status}'"
152
+ end
153
+
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ class InvalidClientError < XeroizerError; end
160
+
161
+ end
@@ -0,0 +1,90 @@
1
+ require 'xeroizer/record/application_helper'
2
+
3
+ module Xeroizer
4
+ class GenericApplication
5
+
6
+ include Http
7
+ extend Record::ApplicationHelper
8
+
9
+ attr_reader :client, :logger, :rate_limit_sleep, :rate_limit_max_attempts,
10
+ :default_headers, :unitdp, :before_request, :after_request, :around_request, :nonce_used_max_attempts
11
+
12
+ attr_accessor :xero_url
13
+
14
+ extend Forwardable
15
+ def_delegators :client, :access_token
16
+
17
+ record :Account
18
+ record :Allocation
19
+ record :Attachment
20
+ record :Balances
21
+ record :BatchPayment
22
+ record :BrandingTheme
23
+ record :Contact
24
+ record :ContactGroup
25
+ record :CreditNote
26
+ record :Currency
27
+ record :Employee
28
+ record :ExpenseClaim
29
+ record :Invoice
30
+ record :InvoiceReminder
31
+ record :OnlineInvoice
32
+ record :Item
33
+ record :Journal
34
+ record :LineItem
35
+ record :ManualJournal
36
+ record :Organisation
37
+ record :Payment
38
+ record :PaymentService
39
+ record :Prepayment
40
+ record :Overpayment
41
+ record :PurchaseOrder
42
+ record :Receipt
43
+ record :RepeatingInvoice
44
+ record :Schedule
45
+ record :TaxRate
46
+ record :TrackingCategory
47
+ record :TrackingCategoryChild
48
+ record :BankTransaction
49
+ record :BankTransfer
50
+ record :User
51
+
52
+ report :AgedPayablesByContact
53
+ report :AgedReceivablesByContact
54
+ report :BalanceSheet
55
+ report :BankStatement
56
+ report :BankSummary
57
+ report :BudgetSummary
58
+ report :ExecutiveSummary
59
+ report :ProfitAndLoss
60
+ report :TrialBalance
61
+
62
+ public
63
+
64
+ # Never used directly. Use sub-classes instead.
65
+ # @see PublicApplication
66
+ # @see PrivateApplication
67
+ # @see PartnerApplication
68
+ def initialize(client, options = {})
69
+ raise Xeroizer::InvalidClientError.new unless [OAuth, OAuth2].member?(client.class)
70
+ @xero_url = options[:xero_url] || "https://api.xero.com/api.xro/2.0"
71
+ @rate_limit_sleep = options[:rate_limit_sleep] || false
72
+ @rate_limit_max_attempts = options[:rate_limit_max_attempts] || 5
73
+ @nonce_used_max_attempts = options[:nonce_used_max_attempts] || 1
74
+ @default_headers = options[:default_headers] || {}
75
+ @before_request = options.delete(:before_request)
76
+ @after_request = options.delete(:after_request)
77
+ @around_request = options.delete(:around_request)
78
+ @client = client
79
+ @logger = options[:logger] || false
80
+ @unitdp = options[:unitdp] || 2
81
+ end
82
+
83
+ def payroll(options = {})
84
+ xero_client = self.clone
85
+ xero_client.xero_url = options[:xero_url] || "https://api.xero.com/payroll.xro/1.0"
86
+ @payroll ||= PayrollApplication.new(xero_client)
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,160 @@
1
+ # Copyright (c) 2008 Tim Connor <tlconnor@gmail.com>
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ module Xeroizer
16
+ module Http
17
+ class BadResponse < XeroizerError; end
18
+ RequestInfo = Struct.new(:url, :headers, :params, :body, :method)
19
+
20
+ ACCEPT_MIME_MAP = {
21
+ :pdf => 'application/pdf',
22
+ :json => 'application/json'
23
+ }
24
+
25
+ # Shortcut method for #http_request with `method` = :get.
26
+ #
27
+ # @param [OAuth] client OAuth client
28
+ # @param [String] url URL of request
29
+ # @param [Hash] extra_params extra query string parameters.
30
+ def http_get(client, url, extra_params = {})
31
+ http_request(client, :get, url, nil, extra_params)
32
+ end
33
+
34
+ # Shortcut method for #http_request with `method` = :post.
35
+ #
36
+ # @param [OAuth] client OAuth client
37
+ # @param [String] url URL of request
38
+ # @param [String] body XML message to post.
39
+ # @param [Hash] extra_params extra query string parameters.
40
+ def http_post(client, url, body, extra_params = {})
41
+ http_request(client, :post, url, body, extra_params)
42
+ end
43
+
44
+ # Shortcut method for #http_request with `method` = :put.
45
+ #
46
+ # @param [OAuth] client OAuth client
47
+ # @param [String] url URL of request
48
+ # @param [String] body XML message to put.
49
+ # @param [Hash] extra_params extra query string parameters.
50
+ def http_put(client, url, body, extra_params = {})
51
+ http_request(client, :put, url, body, extra_params)
52
+ end
53
+
54
+ private
55
+
56
+ def http_request(client, method, url, request_body, params = {})
57
+ # headers = {'Accept-Encoding' => 'gzip, deflate'}
58
+
59
+ headers = self.default_headers.merge({ 'charset' => 'utf-8' })
60
+
61
+ # include the unitdp query string parameter
62
+ params.merge!(unitdp_param(url))
63
+
64
+ if method != :get
65
+ headers['Content-Type'] ||= "application/x-www-form-urlencoded"
66
+ end
67
+
68
+ content_type = params.delete(:content_type)
69
+ headers['Content-Type'] = content_type if content_type
70
+
71
+ # HAX. Xero completely misuse the If-Modified-Since HTTP header.
72
+ headers['If-Modified-Since'] = params.delete(:ModifiedAfter).utc.strftime("%Y-%m-%dT%H:%M:%S") if params[:ModifiedAfter]
73
+
74
+ # Allow 'Accept' header to be specified with :accept parameter.
75
+ # Valid values are :pdf or :json.
76
+ if params[:response]
77
+ response_type = params.delete(:response)
78
+ headers['Accept'] = case response_type
79
+ when Symbol then ACCEPT_MIME_MAP[response_type]
80
+ else response_type
81
+ end
82
+ end
83
+
84
+ if params.any?
85
+ url += "?" + params.map {|key, value| "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"}.join("&")
86
+ end
87
+
88
+ uri = URI.parse(url)
89
+
90
+ attempts = 0
91
+
92
+ request_info = RequestInfo.new(url, headers, params, request_body, method)
93
+ before_request.call(request_info) if before_request
94
+
95
+ begin
96
+ attempts += 1
97
+ logger.info("XeroGateway Request: #{method.to_s.upcase} #{uri.request_uri}") if self.logger
98
+
99
+ raw_body = params.delete(:raw_body) ? request_body : {:xml => request_body}
100
+
101
+ response = with_around_request(request_info) do
102
+ case method
103
+ when :get then client.get(uri.request_uri, headers)
104
+ when :post then client.post(uri.request_uri, raw_body, headers)
105
+ when :put then client.put(uri.request_uri, raw_body, headers)
106
+ end
107
+ end
108
+
109
+ log_response(response, uri)
110
+ after_request.call(request_info, response) if after_request
111
+
112
+ HttpResponse.from_response(response, request_body, url).body
113
+ rescue Xeroizer::OAuth::NonceUsed => exception
114
+ raise if attempts > nonce_used_max_attempts
115
+ logger.info("Nonce used: " + exception.to_s) if self.logger
116
+ sleep_for(1)
117
+ retry
118
+ rescue Xeroizer::OAuth::RateLimitExceeded
119
+ if self.rate_limit_sleep
120
+ raise if attempts > rate_limit_max_attempts
121
+ logger.info("Rate limit exceeded, retrying") if self.logger
122
+ sleep_for(self.rate_limit_sleep)
123
+ retry
124
+ else
125
+ raise
126
+ end
127
+ end
128
+ end
129
+
130
+ def with_around_request(request, &block)
131
+ if around_request
132
+ around_request.call(request, &block)
133
+ else
134
+ block.call
135
+ end
136
+ end
137
+
138
+ def log_response(response, uri)
139
+ if self.logger
140
+ logger.info("XeroGateway Response (#{response.code})")
141
+ logger.add(response.code.to_i == 200 ? Logger::DEBUG : Logger::INFO) {
142
+ "#{uri.request_uri}\n== Response Body\n\n#{response.plain_body}\n== End Response Body"
143
+ }
144
+ end
145
+ end
146
+
147
+ def sleep_for(seconds = 1)
148
+ sleep seconds
149
+ end
150
+
151
+ # unitdp query string parameter to be added to request params
152
+ # when the application option has been set and the model has line items
153
+ # https://developer.xero.com/documentation/api-guides/rounding-in-xero#unitamount
154
+ def unitdp_param(request_url)
155
+ models = [/Invoices/, /CreditNotes/, /BankTransactions/, /Receipts/, /Items/, /Overpayments/, /Prepayments/]
156
+ self.unitdp == 4 && models.any?{ |m| request_url =~ m } ? {:unitdp => 4} : {}
157
+ end
158
+
159
+ end
160
+ end