xeroizer-float 2.15.3.1

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 (337) hide show
  1. data/.bundle/config +2 -0
  2. data/.gitattributes +22 -0
  3. data/Gemfile +19 -0
  4. data/Gemfile.lock +57 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +529 -0
  7. data/Rakefile +55 -0
  8. data/VERSION +1 -0
  9. data/lib/big_decimal_to_s.rb +9 -0
  10. data/lib/class_level_inheritable_attributes.rb +25 -0
  11. data/lib/xeroizer.rb +64 -0
  12. data/lib/xeroizer/application_http_proxy.rb +30 -0
  13. data/lib/xeroizer/ca-certificates.crt +2642 -0
  14. data/lib/xeroizer/configuration.rb +19 -0
  15. data/lib/xeroizer/exceptions.rb +129 -0
  16. data/lib/xeroizer/generic_application.rb +54 -0
  17. data/lib/xeroizer/http.rb +167 -0
  18. data/lib/xeroizer/http_encoding_helper.rb +49 -0
  19. data/lib/xeroizer/logging.rb +8 -0
  20. data/lib/xeroizer/models/account.rb +67 -0
  21. data/lib/xeroizer/models/address.rb +32 -0
  22. data/lib/xeroizer/models/bank_account.rb +12 -0
  23. data/lib/xeroizer/models/bank_transaction.rb +75 -0
  24. data/lib/xeroizer/models/branding_theme.rb +22 -0
  25. data/lib/xeroizer/models/contact.rb +49 -0
  26. data/lib/xeroizer/models/contact_group.rb +16 -0
  27. data/lib/xeroizer/models/credit_note.rb +130 -0
  28. data/lib/xeroizer/models/currency.rb +18 -0
  29. data/lib/xeroizer/models/employee.rb +28 -0
  30. data/lib/xeroizer/models/external_link.rb +16 -0
  31. data/lib/xeroizer/models/invoice.rb +192 -0
  32. data/lib/xeroizer/models/item.rb +27 -0
  33. data/lib/xeroizer/models/item_purchase_details.rb +19 -0
  34. data/lib/xeroizer/models/item_sales_details.rb +19 -0
  35. data/lib/xeroizer/models/journal.rb +25 -0
  36. data/lib/xeroizer/models/journal_line.rb +28 -0
  37. data/lib/xeroizer/models/journal_line_tracking_category.rb +20 -0
  38. data/lib/xeroizer/models/line_amount_type.rb +11 -0
  39. data/lib/xeroizer/models/line_item.rb +40 -0
  40. data/lib/xeroizer/models/line_item_sum.rb +21 -0
  41. data/lib/xeroizer/models/manual_journal.rb +42 -0
  42. data/lib/xeroizer/models/manual_journal_line.rb +27 -0
  43. data/lib/xeroizer/models/option.rb +18 -0
  44. data/lib/xeroizer/models/organisation.rb +34 -0
  45. data/lib/xeroizer/models/payment.rb +42 -0
  46. data/lib/xeroizer/models/phone.rb +25 -0
  47. data/lib/xeroizer/models/tax_rate.rb +25 -0
  48. data/lib/xeroizer/models/tracking_category.rb +23 -0
  49. data/lib/xeroizer/models/tracking_category_child.rb +20 -0
  50. data/lib/xeroizer/oauth.rb +130 -0
  51. data/lib/xeroizer/partner_application.rb +46 -0
  52. data/lib/xeroizer/private_application.rb +27 -0
  53. data/lib/xeroizer/public_application.rb +21 -0
  54. data/lib/xeroizer/record/application_helper.rb +32 -0
  55. data/lib/xeroizer/record/base.rb +155 -0
  56. data/lib/xeroizer/record/base_model.rb +144 -0
  57. data/lib/xeroizer/record/base_model_http_proxy.rb +117 -0
  58. data/lib/xeroizer/record/model_definition_helper.rb +99 -0
  59. data/lib/xeroizer/record/record_association_helper.rb +140 -0
  60. data/lib/xeroizer/record/validation_helper.rb +71 -0
  61. data/lib/xeroizer/record/validators/associated_validator.rb +33 -0
  62. data/lib/xeroizer/record/validators/block_validator.rb +22 -0
  63. data/lib/xeroizer/record/validators/inclusion_of_validator.rb +22 -0
  64. data/lib/xeroizer/record/validators/presence_of_validator.rb +19 -0
  65. data/lib/xeroizer/record/validators/validator.rb +33 -0
  66. data/lib/xeroizer/record/xml_helper.rb +133 -0
  67. data/lib/xeroizer/report/aged_receivables_by_contact.rb +43 -0
  68. data/lib/xeroizer/report/base.rb +43 -0
  69. data/lib/xeroizer/report/cell.rb +32 -0
  70. data/lib/xeroizer/report/cell_xml_helper.rb +74 -0
  71. data/lib/xeroizer/report/factory.rb +53 -0
  72. data/lib/xeroizer/report/row/header.rb +12 -0
  73. data/lib/xeroizer/report/row/row.rb +48 -0
  74. data/lib/xeroizer/report/row/section.rb +10 -0
  75. data/lib/xeroizer/report/row/summary.rb +9 -0
  76. data/lib/xeroizer/report/row/xml_helper.rb +77 -0
  77. data/lib/xeroizer/report/xml_helper.rb +58 -0
  78. data/lib/xeroizer/response.rb +55 -0
  79. data/test/acceptance/about_creating_bank_transactions_test.rb +162 -0
  80. data/test/acceptance/about_fetching_bank_transactions_test.rb +56 -0
  81. data/test/acceptance/acceptance_test.rb +53 -0
  82. data/test/acceptance/bank_transaction_reference_data.rb +31 -0
  83. data/test/stub_responses/accounts.xml +589 -0
  84. data/test/stub_responses/api_exception.xml +153 -0
  85. data/test/stub_responses/bogus_oauth_error +1 -0
  86. data/test/stub_responses/branding_themes.xml +20 -0
  87. data/test/stub_responses/contact.xml +40 -0
  88. data/test/stub_responses/contacts.xml +0 -0
  89. data/test/stub_responses/create_credit_note.xml +104 -0
  90. data/test/stub_responses/create_invoice.xml +64 -0
  91. data/test/stub_responses/credit_note.xml +75 -0
  92. data/test/stub_responses/credit_note_not_found_error.xml +1 -0
  93. data/test/stub_responses/credit_notes.xml +169 -0
  94. data/test/stub_responses/currencies.xml +12 -0
  95. data/test/stub_responses/employees.xml +29 -0
  96. data/test/stub_responses/invalid_api_key_error.xml +1 -0
  97. data/test/stub_responses/invalid_consumer_key +1 -0
  98. data/test/stub_responses/invalid_request_token +1 -0
  99. data/test/stub_responses/invoice.xml +84 -0
  100. data/test/stub_responses/invoice_not_found_error.xml +1 -0
  101. data/test/stub_responses/invoices.xml +1899 -0
  102. data/test/stub_responses/items.xml +112 -0
  103. data/test/stub_responses/manual_journal.xml +45 -0
  104. data/test/stub_responses/manual_journals.xml +40 -0
  105. data/test/stub_responses/organisation.xml +25 -0
  106. data/test/stub_responses/organisations.xml +25 -0
  107. data/test/stub_responses/payments.xml +1121 -0
  108. data/test/stub_responses/rate_limit_exceeded +1 -0
  109. data/test/stub_responses/records/contact-043892a1-aef1-4c18-88d8-b8ccb6d31466.xml +38 -0
  110. data/test/stub_responses/records/contact-09664078-efe2-4a88-89a5-67eac9b0047b.xml +40 -0
  111. data/test/stub_responses/records/contact-0a4cf37b-a1a8-4753-9ee2-f9207f63a8ff.xml +48 -0
  112. data/test/stub_responses/records/contact-0e74f929-11b9-4255-a035-1fdfe573e676.xml +40 -0
  113. data/test/stub_responses/records/contact-0f471ca5-15c9-405e-a1b9-7cc35194b673.xml +38 -0
  114. data/test/stub_responses/records/contact-13cd4c47-baa6-4f07-93f6-6442310df4bf.xml +47 -0
  115. data/test/stub_responses/records/contact-158a2667-82ee-43bf-8f33-a6cc9524092d.xml +38 -0
  116. data/test/stub_responses/records/contact-17465072-6fa3-40bf-bc42-97765d9e1bea.xml +38 -0
  117. data/test/stub_responses/records/contact-1975b0ed-b7ba-4c61-bae8-2aa6d78b0dee.xml +39 -0
  118. data/test/stub_responses/records/contact-1b2be6e9-8d58-4da9-aaf8-4fe5471b653c.xml +53 -0
  119. data/test/stub_responses/records/contact-1c40da58-fe1d-4e97-b729-b2abdae94d9e.xml +38 -0
  120. data/test/stub_responses/records/contact-258176a5-c622-4394-9c94-6f88c3ea12e5.xml +40 -0
  121. data/test/stub_responses/records/contact-299dd3a0-a417-4a37-8a04-2f55e91963e5.xml +40 -0
  122. data/test/stub_responses/records/contact-2be39278-5154-4ed1-8eb0-676f25acfc66.xml +40 -0
  123. data/test/stub_responses/records/contact-2e58cff6-488c-4a32-884b-baf848010229.xml +40 -0
  124. data/test/stub_responses/records/contact-2faccd41-935e-40aa-b74e-e2fc28ac34c3.xml +38 -0
  125. data/test/stub_responses/records/contact-31af01e7-2ca7-45b9-a500-b02db996568e.xml +38 -0
  126. data/test/stub_responses/records/contact-344f1113-a25b-4344-b82e-bedeacc17c8e.xml +40 -0
  127. data/test/stub_responses/records/contact-3e776c4b-ea9e-4bb1-96be-6b0c7a71a37f.xml +39 -0
  128. data/test/stub_responses/records/contact-3fc1fc6c-e5ff-4e40-b6f3-7eb535637d87.xml +38 -0
  129. data/test/stub_responses/records/contact-416ab20c-5357-4beb-a740-e8d175d71efb.xml +38 -0
  130. data/test/stub_responses/records/contact-41a42865-f15a-4fa1-b643-47877608f557.xml +54 -0
  131. data/test/stub_responses/records/contact-42771b60-19a7-4692-af81-dd9f9b9362d4.xml +43 -0
  132. data/test/stub_responses/records/contact-451ceb28-9610-44c9-8f35-3225482f2413.xml +40 -0
  133. data/test/stub_responses/records/contact-4ab343ad-1ebb-4afe-9d48-1814a93c2081.xml +38 -0
  134. data/test/stub_responses/records/contact-4bb77692-42d4-4565-85a0-8849eb85e039.xml +39 -0
  135. data/test/stub_responses/records/contact-4dec292f-3ab7-46a8-83e4-5fb5eac42c7f.xml +40 -0
  136. data/test/stub_responses/records/contact-4e2f192e-8397-4d4d-97ca-a4fc5ac531bf.xml +38 -0
  137. data/test/stub_responses/records/contact-5188c17c-7786-4436-ad6e-9da2997386d0.xml +40 -0
  138. data/test/stub_responses/records/contact-52442753-b1c4-40b7-9b79-c33997de5837.xml +40 -0
  139. data/test/stub_responses/records/contact-565acaa9-e7f3-4fbf-80c3-16b081ddae10.xml +38 -0
  140. data/test/stub_responses/records/contact-571a2414-81ff-4f8f-8498-d91d83793131.xml +44 -0
  141. data/test/stub_responses/records/contact-58697449-85ef-46ae-83fc-6a9446f037fb.xml +40 -0
  142. data/test/stub_responses/records/contact-58bf2ae3-5144-4628-8de2-e165ac2bcdc6.xml +40 -0
  143. data/test/stub_responses/records/contact-5d41dafd-eb7e-42c1-bd5a-ba3be1da0960.xml +38 -0
  144. data/test/stub_responses/records/contact-5f005a09-5ce4-4fb4-8096-e69c18be636e.xml +38 -0
  145. data/test/stub_responses/records/contact-60d578d9-3e10-4aef-b5dc-9d9fd60a3633.xml +47 -0
  146. data/test/stub_responses/records/contact-62392126-dba4-4a75-b907-5875ebf75259.xml +40 -0
  147. data/test/stub_responses/records/contact-642c7fb5-e8e5-48e1-a710-39a18c6c3217.xml +40 -0
  148. data/test/stub_responses/records/contact-64aebf9c-bb89-4b38-b99b-405bd1ece6fd.xml +40 -0
  149. data/test/stub_responses/records/contact-64eedbc9-1fa0-485a-837f-705f23188161.xml +38 -0
  150. data/test/stub_responses/records/contact-65e96c9f-1595-4653-9a8a-2a36d49223c2.xml +40 -0
  151. data/test/stub_responses/records/contact-67d26b93-ccb4-4890-9bf1-284b70ea755d.xml +38 -0
  152. data/test/stub_responses/records/contact-69d3e538-44b3-4e00-a5f6-7dddcb6e0656.xml +40 -0
  153. data/test/stub_responses/records/contact-6a8450bc-f81a-4bb0-a8f6-aa4afe9497c7.xml +40 -0
  154. data/test/stub_responses/records/contact-6c70e424-41d6-4b9b-af3e-b3a9f3589106.xml +40 -0
  155. data/test/stub_responses/records/contact-6de0b0cf-560c-4503-aab3-e1543c329deb.xml +54 -0
  156. data/test/stub_responses/records/contact-72dd6a02-396e-42a2-a4d6-cc3fa75dfece.xml +41 -0
  157. data/test/stub_responses/records/contact-755f1475-d255-43a8-bedc-5ea7fd26c71f.xml +51 -0
  158. data/test/stub_responses/records/contact-78a9d0a0-3d8c-4f84-af3e-f260bf4a9dc0.xml +38 -0
  159. data/test/stub_responses/records/contact-79aa39ca-22b0-42c2-9026-78757a29d665.xml +42 -0
  160. data/test/stub_responses/records/contact-804f4140-5978-48fe-ba20-b56e5b834b18.xml +40 -0
  161. data/test/stub_responses/records/contact-812d4f28-1681-4241-8e34-d15c5520ba35.xml +38 -0
  162. data/test/stub_responses/records/contact-860b99a9-0958-4c8d-a98f-bb1f092b16bb.xml +60 -0
  163. data/test/stub_responses/records/contact-87c8da45-97cc-46be-b170-398da0eacfb8.xml +40 -0
  164. data/test/stub_responses/records/contact-8a154a19-6c6c-404b-bbc9-6deae2d18251.xml +38 -0
  165. data/test/stub_responses/records/contact-8bb6931d-2865-44e9-9a23-ed1fb9c7a46c.xml +40 -0
  166. data/test/stub_responses/records/contact-936c9759-01da-4063-b472-424ab9f48212.xml +38 -0
  167. data/test/stub_responses/records/contact-9d12a994-9640-4b75-95cc-3de1e9d0ef09.xml +38 -0
  168. data/test/stub_responses/records/contact-9fe59245-1fbb-4157-93c3-dc97388f3746.xml +40 -0
  169. data/test/stub_responses/records/contact-a06a7225-6f8a-4522-8400-c534dd43a16e.xml +40 -0
  170. data/test/stub_responses/records/contact-a76a85fe-73a2-46fa-aba7-791f36103cdb.xml +40 -0
  171. data/test/stub_responses/records/contact-a93b5f40-0346-4d21-9181-431e129911c0.xml +40 -0
  172. data/test/stub_responses/records/contact-abf272dd-6b1d-4829-af88-c57bf55855e3.xml +38 -0
  173. data/test/stub_responses/records/contact-ad24c33b-256b-4157-ad56-cbcf0e8db7b1.xml +47 -0
  174. data/test/stub_responses/records/contact-b107129d-f4c9-438e-9573-64b778527f4a.xml +40 -0
  175. data/test/stub_responses/records/contact-b233288a-aa26-4b26-9fc7-779d797dd56f.xml +40 -0
  176. data/test/stub_responses/records/contact-b2b5333a-2546-4975-891f-d71a8a640d23.xml +38 -0
  177. data/test/stub_responses/records/contact-b4d149bf-1823-4bd2-96da-9032388c9686.xml +40 -0
  178. data/test/stub_responses/records/contact-b78d4fd1-4306-4d83-a0b9-61458d1c53a2.xml +40 -0
  179. data/test/stub_responses/records/contact-b7d108a8-d5f7-4f16-a7c9-26eaed98e8de.xml +40 -0
  180. data/test/stub_responses/records/contact-baeed0f3-7989-4874-99b3-59f23032cb73.xml +38 -0
  181. data/test/stub_responses/records/contact-bc51a3a1-b7f6-46ca-ac9e-19b87e6ca100.xml +40 -0
  182. data/test/stub_responses/records/contact-be9f3aab-52f5-4d9c-94b4-87f7d9e5ee8b.xml +38 -0
  183. data/test/stub_responses/records/contact-c135f994-01e4-427b-9e15-acfe8a477c16.xml +49 -0
  184. data/test/stub_responses/records/contact-c14edf75-15e4-4a9c-86e4-f52e2fe7cfa4.xml +40 -0
  185. data/test/stub_responses/records/contact-ca9b9abc-c2dc-4221-8101-31f464d314cc.xml +44 -0
  186. data/test/stub_responses/records/contact-cc4db604-9ed8-4eef-8a29-51b5b70496a0.xml +38 -0
  187. data/test/stub_responses/records/contact-cce9b044-be4a-43b3-9dc7-c027d8dd35b2.xml +38 -0
  188. data/test/stub_responses/records/contact-d0cd2c4f-18a0-4f7c-a32a-2db00f29d298.xml +43 -0
  189. data/test/stub_responses/records/contact-d6851dc2-9ed9-4515-bc0b-810b09c06a6a.xml +38 -0
  190. data/test/stub_responses/records/contact-d6a384fb-f46f-41a3-8ac7-b7bc9e0b5efa.xml +46 -0
  191. data/test/stub_responses/records/contact-d74e61cf-2ad0-4f0d-b9d1-6a808e3f70cf.xml +40 -0
  192. data/test/stub_responses/records/contact-d9ab0f61-3b56-4e2b-be39-f33c11bd99e3.xml +40 -0
  193. data/test/stub_responses/records/contact-dbb1f0b5-a71b-4458-8462-104acd0fec6b.xml +38 -0
  194. data/test/stub_responses/records/contact-dd981bd6-40dd-496d-a282-bf7d3391b8b9.xml +40 -0
  195. data/test/stub_responses/records/contact-e1826204-cc0a-42a5-a6d0-4b352d9d5953.xml +40 -0
  196. data/test/stub_responses/records/contact-e2d955db-f366-42dd-87f7-fbdb4da2306f.xml +40 -0
  197. data/test/stub_responses/records/contact-e32e2130-3d27-443a-8313-48fffa03cf53.xml +40 -0
  198. data/test/stub_responses/records/contact-e3a68332-d322-4816-8678-73a537c8cd33.xml +38 -0
  199. data/test/stub_responses/records/contact-e6ac76a3-ca32-4fa1-8ef9-6a4bf8b0ec2a.xml +40 -0
  200. data/test/stub_responses/records/contact-e6ca965d-7c48-480e-be39-e847307f474a.xml +38 -0
  201. data/test/stub_responses/records/contact-e77d1f20-2e8e-46ec-9a10-50335a216724.xml +40 -0
  202. data/test/stub_responses/records/contact-e8b98c13-a424-41d2-ba0e-7b7621411e7a.xml +38 -0
  203. data/test/stub_responses/records/contact-e8e9a2c2-3e7e-48ed-8528-c3d61b28f276.xml +39 -0
  204. data/test/stub_responses/records/contact-eb43fcc6-87ec-4a0a-b243-d718bee4e2cb.xml +38 -0
  205. data/test/stub_responses/records/contact-ef6f54c1-eb45-4956-b8cd-1be82ad665f2.xml +43 -0
  206. data/test/stub_responses/records/contact-efdb3600-f233-42e2-8f18-ce7e2a95e4b1.xml +38 -0
  207. data/test/stub_responses/records/contact-f7eca431-5c97-4d24-93fd-004bb8a6c644.xml +40 -0
  208. data/test/stub_responses/records/contact-fb078879-5d6d-474f-825f-61dc90689349.xml +38 -0
  209. data/test/stub_responses/records/contact-fc39b273-4aa2-4785-99ca-24672f6c0000.xml +38 -0
  210. data/test/stub_responses/records/contact-fc9ec3a6-a2fe-4300-a8cb-ca8a0b3662e0.xml +40 -0
  211. data/test/stub_responses/records/contact-fdf96102-7491-44b6-bf4d-7a77ff25f890.xml +40 -0
  212. data/test/stub_responses/records/contact-fe61ead1-8afc-4f0b-beda-066620227aad.xml +38 -0
  213. data/test/stub_responses/records/credit_note-371cd138-1e5c-4ec1-a8c6-a1c10e8bdab1.xml +73 -0
  214. data/test/stub_responses/records/credit_note-3bffc09b-79f2-490d-b91b-c59b700b43a4.xml +95 -0
  215. data/test/stub_responses/records/credit_note-43c678ee-f357-48e2-b192-b6e3634762f9.xml +94 -0
  216. data/test/stub_responses/records/credit_note-482c018b-d329-4e05-9b4f-7a4cfc695aa0.xml +77 -0
  217. data/test/stub_responses/records/credit_note-4f67130a-749a-4ee6-98b2-743adbc11245.xml +62 -0
  218. data/test/stub_responses/records/credit_note-50e98404-2fba-4031-af67-8ba4bb227c44.xml +77 -0
  219. data/test/stub_responses/records/credit_note-7df8949c-b71f-40c0-bbcf-39f2f450f286.xml +75 -0
  220. data/test/stub_responses/records/credit_note-b356e488-2678-4be4-ad4b-d294df2d48d6.xml +78 -0
  221. data/test/stub_responses/records/invoice-0032f627-3156-4d30-9b1c-4d3b994dc921.xml +84 -0
  222. data/test/stub_responses/records/invoice-00c9511b-24b9-4190-a90a-8abf2fe9f4a0.xml +76 -0
  223. data/test/stub_responses/records/invoice-024d7994-a26c-4c20-9894-13934840fc31.xml +74 -0
  224. data/test/stub_responses/records/invoice-0e64a623-c2a1-446a-93ed-eb897f118cbc.xml +97 -0
  225. data/test/stub_responses/records/invoice-15e88e57-2554-4496-a18e-eb3f5c622345.xml +75 -0
  226. data/test/stub_responses/records/invoice-166f0588-d0ba-458c-b28a-8edd4c8fc463.xml +75 -0
  227. data/test/stub_responses/records/invoice-1d1ba340-afa2-4f4c-8ff7-a147bda9a47b.xml +93 -0
  228. data/test/stub_responses/records/invoice-290ef4c4-baec-492b-b4dd-c102826470ae.xml +87 -0
  229. data/test/stub_responses/records/invoice-30a87092-31b5-4a2c-831e-327486533dd2.xml +79 -0
  230. data/test/stub_responses/records/invoice-30dbd181-72a8-43df-b392-4241bf43d5fc.xml +79 -0
  231. data/test/stub_responses/records/invoice-33e4123e-7cdd-4f05-9a0a-eb8adeb2b868.xml +94 -0
  232. data/test/stub_responses/records/invoice-387db692-26ac-47e6-b6cc-015343809bda.xml +75 -0
  233. data/test/stub_responses/records/invoice-3b28bf11-ed2f-4cf4-8e9e-fcae730cc292.xml +91 -0
  234. data/test/stub_responses/records/invoice-3fcb9847-b350-412e-ab90-7d9d774ad881.xml +91 -0
  235. data/test/stub_responses/records/invoice-440613e4-4785-4eff-9ba1-c432816cf8c7.xml +78 -0
  236. data/test/stub_responses/records/invoice-4602eda6-abe9-448e-b65f-ae6bea21f0eb.xml +98 -0
  237. data/test/stub_responses/records/invoice-46441f63-873f-4cdc-a278-b8fe516f3abb.xml +94 -0
  238. data/test/stub_responses/records/invoice-4ad1ec01-f4a3-41d7-bbb4-d2ab2fec8e65.xml +74 -0
  239. data/test/stub_responses/records/invoice-4b9afceb-f7c7-4e64-8aac-7b009971fd52.xml +86 -0
  240. data/test/stub_responses/records/invoice-4edbf6d5-4e92-43af-bedd-7effc0b86833.xml +70 -0
  241. data/test/stub_responses/records/invoice-4fad1af2-b871-4ac5-a15a-3c5e32d2e2c4.xml +93 -0
  242. data/test/stub_responses/records/invoice-52ee4d67-cae4-462c-adb2-182c39017f3d.xml +83 -0
  243. data/test/stub_responses/records/invoice-54585f46-c1a0-4432-bd4f-c1fae2fba59b.xml +67 -0
  244. data/test/stub_responses/records/invoice-5613938b-9e27-472e-92ae-3b038b669d10.xml +87 -0
  245. data/test/stub_responses/records/invoice-5aa9451d-95d1-4f95-a966-bbab2573f71c.xml +75 -0
  246. data/test/stub_responses/records/invoice-5aadcd34-01a9-4b8d-a2bb-d7cc1de9fa45.xml +89 -0
  247. data/test/stub_responses/records/invoice-5f6deadf-36a2-495a-9980-ceb11e8af9a9.xml +85 -0
  248. data/test/stub_responses/records/invoice-625ffe1b-f5d8-438e-a376-981de5f5a733.xml +77 -0
  249. data/test/stub_responses/records/invoice-64cd559e-8e03-46af-b461-8555285cee71.xml +86 -0
  250. data/test/stub_responses/records/invoice-666f8dbb-bc9a-476c-8ec4-4665d7f83190.xml +63 -0
  251. data/test/stub_responses/records/invoice-66fbe37f-49b1-43fd-97ed-85114022cd2f.xml +79 -0
  252. data/test/stub_responses/records/invoice-673dd7cc-beb7-4697-83d4-0c47cb400cc2.xml +95 -0
  253. data/test/stub_responses/records/invoice-69fc971e-9b37-41c5-9c87-174330f22343.xml +66 -0
  254. data/test/stub_responses/records/invoice-70e6db69-e5a4-42c7-a397-aa3212c2945f.xml +75 -0
  255. data/test/stub_responses/records/invoice-762aa45d-4632-45b5-8087-b4f47690665e.xml +54 -0
  256. data/test/stub_responses/records/invoice-766d1289-b440-4675-a656-1a0612ecac77.xml +76 -0
  257. data/test/stub_responses/records/invoice-76bcb361-f93b-4513-b312-5a4af306d276.xml +67 -0
  258. data/test/stub_responses/records/invoice-76e3f056-479f-417c-a72b-f3d767899b87.xml +91 -0
  259. data/test/stub_responses/records/invoice-77b338ef-ecc0-4b95-a0d7-2617b0054611.xml +114 -0
  260. data/test/stub_responses/records/invoice-7be9956d-5316-4f6b-a66a-d355b3f159b2.xml +84 -0
  261. data/test/stub_responses/records/invoice-7dae876a-b424-436b-a4e6-17b3fdeec80c.xml +91 -0
  262. data/test/stub_responses/records/invoice-7e862d93-8dab-4856-8b0c-d844e09d750f.xml +68 -0
  263. data/test/stub_responses/records/invoice-803f70b0-56d9-4157-9787-41df271777a0.xml +84 -0
  264. data/test/stub_responses/records/invoice-86102312-aa3f-438c-9938-6840f4d8dda6.xml +75 -0
  265. data/test/stub_responses/records/invoice-8694c9c5-7097-4449-a708-b8c1982921a4.xml +69 -0
  266. data/test/stub_responses/records/invoice-86d6e00f-ef56-49f7-9a54-796ccd5ca057.xml +85 -0
  267. data/test/stub_responses/records/invoice-88e77f0f-54a5-4efc-a979-7e22223cc4d7.xml +66 -0
  268. data/test/stub_responses/records/invoice-8b0ccb6a-d9b7-4da5-8360-ef7fb157b5aa.xml +66 -0
  269. data/test/stub_responses/records/invoice-935fc854-8037-4111-8d91-993010c331cc.xml +74 -0
  270. data/test/stub_responses/records/invoice-95ef3000-c764-4ba9-a66a-b6e2d161f839.xml +62 -0
  271. data/test/stub_responses/records/invoice-962ef33f-c9d2-4602-9b9f-93a02bea23b3.xml +93 -0
  272. data/test/stub_responses/records/invoice-9868b472-1983-48e9-8edf-7e81ddf2c03a.xml +85 -0
  273. data/test/stub_responses/records/invoice-9a448e9b-a9fa-4a8b-98f5-6dc892a37374.xml +62 -0
  274. data/test/stub_responses/records/invoice-a1d04a14-96a8-4067-a0ff-8136990a354f.xml +91 -0
  275. data/test/stub_responses/records/invoice-a3bc62ef-f11b-4a9c-a4f9-a342bda371b5.xml +66 -0
  276. data/test/stub_responses/records/invoice-a6894ca0-60ee-4d45-9dd4-b44fcba46ec5.xml +90 -0
  277. data/test/stub_responses/records/invoice-a77268ce-74b2-483d-a2b3-70dbdc9e49d2.xml +78 -0
  278. data/test/stub_responses/records/invoice-a9f765e6-b9bc-4505-a47b-fb3ecb327e7b.xml +88 -0
  279. data/test/stub_responses/records/invoice-aa0173af-8707-4e7f-8dde-4c7a357bd312.xml +109 -0
  280. data/test/stub_responses/records/invoice-ab63738a-370a-43a5-bfa3-620d684e66d0.xml +83 -0
  281. data/test/stub_responses/records/invoice-b0344791-5a8a-40dd-a208-d99a461a6c10.xml +84 -0
  282. data/test/stub_responses/records/invoice-b1e53910-473c-46a3-b3cb-38ece571220e.xml +76 -0
  283. data/test/stub_responses/records/invoice-b2c02d0b-41a8-4d4d-97d7-014c78b3547d.xml +93 -0
  284. data/test/stub_responses/records/invoice-b75b3928-ab72-4424-8b93-9cdbbde4cd72.xml +90 -0
  285. data/test/stub_responses/records/invoice-bcd8a71f-aa31-4d0f-8a01-13ea26363ddf.xml +94 -0
  286. data/test/stub_responses/records/invoice-bfbb7c45-de02-45e7-b065-d9863ecfb0d8.xml +66 -0
  287. data/test/stub_responses/records/invoice-c12aff7e-12bf-4185-8702-460929f19674.xml +77 -0
  288. data/test/stub_responses/records/invoice-c3380b96-976d-4b3e-8b26-8d01eb6a3742.xml +87 -0
  289. data/test/stub_responses/records/invoice-c963f2b0-cbe1-4abd-9ccc-7e512c942068.xml +67 -0
  290. data/test/stub_responses/records/invoice-cba46b29-3788-4158-b668-ab10160ccbfe.xml +78 -0
  291. data/test/stub_responses/records/invoice-d62646b9-d0a9-4fdb-9561-756a8b7eba45.xml +63 -0
  292. data/test/stub_responses/records/invoice-dba2f021-f149-4191-a126-5351d587ab0e.xml +75 -0
  293. data/test/stub_responses/records/invoice-de5d9c29-21b3-4342-958b-ed72c4bd7ab0.xml +108 -0
  294. data/test/stub_responses/records/invoice-e3d96555-2876-4364-a46a-7551a4f52611.xml +123 -0
  295. data/test/stub_responses/records/invoice-e4a0afbd-aea0-450b-ae23-0ce921e84a77.xml +102 -0
  296. data/test/stub_responses/records/invoice-e9cb9ecb-58ef-43a8-bd20-69a85338142d.xml +76 -0
  297. data/test/stub_responses/records/invoice-ec9a6f67-7128-4a63-8ba3-5e516f455f9b.xml +94 -0
  298. data/test/stub_responses/records/invoice-ed0f2587-84fc-4aef-bc4b-b1a262e24484.xml +81 -0
  299. data/test/stub_responses/records/invoice-f362ca53-8ade-4047-865a-bb64bee5863d.xml +74 -0
  300. data/test/stub_responses/records/invoice-f571c38b-5be1-41e1-ad5a-ff6184284beb.xml +114 -0
  301. data/test/stub_responses/records/invoice-f5832195-5cd3-4660-ad3f-b73d9c64f263.xml +85 -0
  302. data/test/stub_responses/records/invoice-f9c857eb-64cd-4235-a078-d04b52c77ea7.xml +76 -0
  303. data/test/stub_responses/records/manual_journal-4765d07b-aa03-4e56-9166-50661958c864.xml +38 -0
  304. data/test/stub_responses/records/manual_journal-53fc5558-5b76-4ecd-ae5c-c4af3ccde87c.xml +31 -0
  305. data/test/stub_responses/records/manual_journal-bb6cfcfc-4500-4475-bd3a-93ee512428e0.xml +31 -0
  306. data/test/stub_responses/records/manual_journal-f00a355b-7374-445c-886b-0437bea4095c.xml +45 -0
  307. data/test/stub_responses/refresh_responses.rb +29 -0
  308. data/test/stub_responses/reports/trial_balance.xml +1435 -0
  309. data/test/stub_responses/tax_rates.xml +118 -0
  310. data/test/stub_responses/token_expired +1 -0
  311. data/test/stub_responses/tracking_categories.xml +27 -0
  312. data/test/stub_responses/unknown_error.xml +1 -0
  313. data/test/test_helper.rb +67 -0
  314. data/test/unit/models/bank_transaction_model_parsing_test.rb +133 -0
  315. data/test/unit/models/bank_transaction_test.rb +47 -0
  316. data/test/unit/models/bank_transaction_validation_test.rb +87 -0
  317. data/test/unit/models/contact_test.rb +26 -0
  318. data/test/unit/models/credit_note_test.rb +37 -0
  319. data/test/unit/models/invoice_test.rb +113 -0
  320. data/test/unit/models/journal_line_test.rb +22 -0
  321. data/test/unit/models/line_item_sum_test.rb +24 -0
  322. data/test/unit/models/line_item_test.rb +70 -0
  323. data/test/unit/oauth_config_test.rb +20 -0
  324. data/test/unit/oauth_test.rb +97 -0
  325. data/test/unit/private_application_test.rb +20 -0
  326. data/test/unit/record/base_model_test.rb +50 -0
  327. data/test/unit/record/base_test.rb +94 -0
  328. data/test/unit/record/block_validator_test.rb +125 -0
  329. data/test/unit/record/model_definition_test.rb +159 -0
  330. data/test/unit/record/parse_where_hash_test.rb +63 -0
  331. data/test/unit/record/record_association_test.rb +93 -0
  332. data/test/unit/record/validators_test.rb +228 -0
  333. data/test/unit/record_definition_test.rb +27 -0
  334. data/test/unit/report_definition_test.rb +26 -0
  335. data/test/unit/report_test.rb +145 -0
  336. data/xeroizer.gemspec +405 -0
  337. metadata +561 -0
@@ -0,0 +1,74 @@
1
+ module Xeroizer
2
+ module Report
3
+ module CellXmlHelper
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ base.send :include, InstanceMethods
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ public
13
+
14
+ # Create an instance of Cell from the node.
15
+ #
16
+ # Additionally, parse the attributes and return them as a hash to the
17
+ # cell. If a cell's attributes look like:
18
+ #
19
+ # <Attributes>
20
+ # <Attribute>
21
+ # <Value>1335b8b2-4d63-4af8-937f-04087ae2e36e</Value>
22
+ # <Id>account</Id>
23
+ # </Attribute>
24
+ # </Attributes>
25
+ #
26
+ # Return a hash like:
27
+ #
28
+ # {
29
+ # 'account' => '1335b8b2-4d63-4af8-937f-04087ae2e36e'
30
+ # }
31
+ def build_from_node(node)
32
+ cell = new
33
+ node.elements.each do | element |
34
+ case element.name.to_s
35
+ when 'Value' then cell.value = parse_value(element.text)
36
+ when 'Attributes'
37
+ element.elements.each do | attribute_node |
38
+ (id, value) = parse_attribute(attribute_node)
39
+ cell.attributes[id] = value
40
+ end
41
+ end
42
+ end
43
+ cell
44
+ end
45
+
46
+ protected
47
+
48
+ def parse_value(value)
49
+ case value
50
+ when /^[-]?\d+(\.\d+)?$/ then BigDecimal.new(value)
51
+ when /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/ then Time.xmlschema(value)
52
+ else value
53
+ end
54
+ end
55
+
56
+ def parse_attribute(attribute_node)
57
+ id = nil
58
+ value = nil
59
+ attribute_node.elements.each do | element |
60
+ case element.name.to_s
61
+ when 'Id' then id = element.text
62
+ when 'Value' then value = element.text
63
+ end
64
+ end
65
+ [id, value]
66
+ end
67
+ end
68
+
69
+ module InstanceMethods
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,53 @@
1
+ require 'xeroizer/application_http_proxy'
2
+ require 'xeroizer/report/base'
3
+ require 'xeroizer/report/aged_receivables_by_contact'
4
+
5
+ module Xeroizer
6
+ module Report
7
+ class Factory
8
+
9
+ include ApplicationHttpProxy
10
+
11
+ attr_reader :application
12
+ attr_reader :report_type
13
+
14
+ public
15
+
16
+ def initialize(application, report_type)
17
+ @application = application
18
+ @report_type = report_type
19
+ end
20
+
21
+ # Retreive a report with the `options` as a hash containing
22
+ # valid query-string parameters to pass to the API.
23
+ def get(options = {})
24
+ response_xml = options[:cache_file] ? File.read(options[:cache_file]) : http_get(options)
25
+ response = Response.parse(response_xml, options) do | response, elements |
26
+ parse_reports(response, elements)
27
+ end
28
+ response.response_items.first # there is is only one
29
+ end
30
+
31
+ def api_controller_name
32
+ "Reports/#{report_type}"
33
+ end
34
+
35
+ def klass
36
+ begin
37
+ @_klass_cache ||= Xeroizer::Report.const_get(report_type)
38
+ rescue NameError => ex # use default class
39
+ Base
40
+ end
41
+ end
42
+
43
+ protected
44
+
45
+ def parse_reports(response, elements)
46
+ elements.each do | element |
47
+ response.response_items << klass.build_from_node(element, self)
48
+ end
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,12 @@
1
+ module Xeroizer
2
+ module Report
3
+ class HeaderRow < Row
4
+
5
+ def column_index(column_name)
6
+ @_column_index_cache ||= {}
7
+ @_column_index_cache[column_name] ||= cells.find_index { | cell | cell.value == column_name.to_s }
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,48 @@
1
+ require 'xeroizer/report/row/xml_helper'
2
+
3
+ module Xeroizer
4
+ module Report
5
+ class Row
6
+
7
+ include RowXmlHelper
8
+
9
+ attr_reader :report
10
+
11
+ attr_accessor :type
12
+ attr_accessor :title
13
+ attr_accessor :rows
14
+ attr_accessor :cells
15
+
16
+ attr_accessor :parent
17
+
18
+ attr_accessor :header
19
+
20
+ public
21
+
22
+ def initialize(report)
23
+ @rows = []
24
+ @cells = []
25
+ @report = report
26
+ end
27
+
28
+ def header?; @type == 'Header'; end
29
+ def summary?; @type == 'SummaryRow'; end
30
+ def section?; @type == 'Section'; end
31
+ def row?; @type == 'Row'; end
32
+
33
+ def child?
34
+ !parent.nil?
35
+ end
36
+
37
+ def parent?
38
+ rows.size > 0
39
+ end
40
+
41
+ def cell(column_name)
42
+ index = header.column_index(column_name)
43
+ cells[index] if index >= 0
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,10 @@
1
+ module Xeroizer
2
+ module Report
3
+ class SectionRow < Row
4
+
5
+ attr_accessor :header
6
+ attr_accessor :summary
7
+
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Xeroizer
2
+ module Report
3
+ class SummaryRow < Row
4
+
5
+ attr_accessor :header
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,77 @@
1
+ module Xeroizer
2
+ module Report
3
+ module RowXmlHelper
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ base.send :include, InstanceMethods
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ public
13
+
14
+ def build_from_node(node, report, parent = nil)
15
+ row_type = node.xpath('RowType').first.text
16
+ row = nil
17
+ case row_type
18
+ when 'Header'
19
+ row = HeaderRow.new(report);
20
+ parent.header = row if parent
21
+ report.header ||= row
22
+
23
+ when 'Section'
24
+ row = SectionRow.new(report)
25
+ row.header = report.header
26
+ report.sections << row
27
+
28
+ when 'SummaryRow'
29
+ row = SummaryRow.new(report);
30
+ row.header = report.header
31
+ if parent
32
+ parent.summary = row
33
+
34
+ # Also add this summary row to the report if the section
35
+ # title is blank and the report doesn't already have one.
36
+ if parent.title.to_s == '' && report.summary.nil?
37
+ report.summary = row
38
+ end
39
+ else
40
+ report.summary = row
41
+ end
42
+
43
+ else
44
+ row = Row.new(report)
45
+ row.header = report.header
46
+
47
+ end
48
+ row.parent = parent
49
+
50
+ node.elements.each do | element |
51
+ case element.name.to_s
52
+ when 'RowType' then row.type = element.text
53
+ when 'Title' then row.title = element.text
54
+ when 'Rows'
55
+ element.elements.each do | row_node |
56
+ row.rows << Row.build_from_node(row_node, report, row)
57
+ end
58
+
59
+ when 'Cells'
60
+ element.elements.each do | cell_node |
61
+ row.cells << Cell.build_from_node(cell_node)
62
+ end
63
+
64
+ end
65
+ end
66
+
67
+ row
68
+ end
69
+
70
+ end
71
+
72
+ module InstanceMethods
73
+ end
74
+
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,58 @@
1
+ module Xeroizer
2
+ module Report
3
+ module XmlHelper
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ base.send :include, InstanceMethods
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ public
13
+
14
+ def build_from_node(node, factory)
15
+ report = new(factory)
16
+
17
+ extract_report_details(report, node)
18
+
19
+ rows = node.xpath("Rows/Row")
20
+ extract_rows(report, rows) if rows && rows.size > 0
21
+
22
+ report
23
+ end
24
+
25
+ protected
26
+
27
+ # Extract header details for the report response.
28
+ def extract_report_details(report, node)
29
+ node.elements.each do | element |
30
+ case element.name.to_s
31
+ when 'ReportID' then report.id = element.text
32
+ when 'ReportName' then report.name = element.text
33
+ when 'ReportType' then report.type = element.text
34
+ when 'ReportDate' then report.date = Date.parse(element.text)
35
+ when 'UpdatedDateUTC' then report.updated_at = Time.parse(element.text)
36
+ when 'ReportTitles'
37
+ element.elements.each do | title_element |
38
+ report.titles << title_element.text
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ # Extract the report rows
45
+ def extract_rows(report, rows)
46
+ rows.each do | row_node |
47
+ report.rows << Row.build_from_node(row_node, report)
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ module InstanceMethods
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,55 @@
1
+ module Xeroizer
2
+ class Response
3
+
4
+ attr_accessor :id, :status, :errors, :provider, :date_time, :response_items, :request_params, :request_xml, :response_xml
5
+
6
+ class << self
7
+
8
+ # Parse the response retreived during any request.
9
+ def parse(raw_response, request = {}, options = {}, &block)
10
+ response = Xeroizer::Response.new
11
+ response.response_xml = raw_response
12
+
13
+ doc = Nokogiri::XML(raw_response) { | cfg | cfg.noblanks }
14
+
15
+ # check for responses we don't understand
16
+ raise Xeroizer::UnparseableResponse.new(doc.root.name) unless doc.root.name == 'Response'
17
+
18
+ doc.root.elements.each do | element |
19
+
20
+ # Text element
21
+ if element.children && element.children.size == 1 && element.children.first.text?
22
+ case element.name
23
+ when 'Id' then response.id = element.text
24
+ when 'Status' then response.status = element.text
25
+ when 'ProviderName' then response.provider = element.text
26
+ when 'DateTimeUTC' then response.date_time = Time.parse(element.text)
27
+ end
28
+
29
+ # Records in response
30
+ elsif element.children && element.children.size > 0
31
+ yield(response, element.children, element.children.first.name)
32
+ end
33
+ end
34
+
35
+ response
36
+ end
37
+
38
+ end
39
+
40
+ public
41
+
42
+ def initialize
43
+ @response_items = []
44
+ end
45
+
46
+ def success?
47
+ status == 'OK'
48
+ end
49
+
50
+ def error
51
+ errors.blank? ? nil : errors[0]
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,162 @@
1
+ require "test_helper"
2
+ require "acceptance_test"
3
+
4
+ class AboutCreatingBankTransactions < Test::Unit::TestCase
5
+ include AcceptanceTest
6
+
7
+ let :client do
8
+ Xeroizer::PrivateApplication.new(@consumer_key, @consumer_secret, @key_file)
9
+ end
10
+
11
+ def setup
12
+ super
13
+ all_accounts = client.Account.all
14
+ @account = all_accounts.select{|acct| acct.status == "ACTIVE" && acct.type == "REVENUE"}.first
15
+ @bank_account = all_accounts.select{|acct| acct.status == "ACTIVE" && acct.type == "BANK"}.first
16
+ end
17
+
18
+ can "create a new SPEND bank transaction" do
19
+ new_transaction = client.BankTransaction.build(
20
+ :type => "SPEND",
21
+ :contact => { :name => "Jazz Kang" },
22
+ :line_items => any_line_items(@account),
23
+ :bank_account => { :account_id => @bank_account.account_id }
24
+ )
25
+
26
+ assert new_transaction.save, "Save failed with the following errors: #{new_transaction.errors.inspect}"
27
+ assert_exists new_transaction
28
+ end
29
+
30
+ can "update a SPEND bank transaction, for example by setting its status" do
31
+ new_transaction = client.BankTransaction.build(
32
+ :type => "SPEND",
33
+ :contact => { :name => "Jazz Kang" },
34
+ :line_items => any_line_items(@account),
35
+ :bank_account => { :account_id => @bank_account.account_id }
36
+ )
37
+
38
+ assert new_transaction.save, "Save failed with the following errors: #{new_transaction.errors.inspect}"
39
+
40
+ assert_exists new_transaction
41
+
42
+ the_new_type = "RECEIVE"
43
+
44
+ expected_id = new_transaction.id
45
+
46
+ new_transaction.type = the_new_type
47
+
48
+ assert new_transaction.save, "Update failed with the following errors: #{new_transaction.errors.inspect}"
49
+
50
+ assert_equal expected_id, new_transaction.id, "Expected the id to be the same because it has been updated"
51
+
52
+ refreshed_bank_transaction = client.BankTransaction.find expected_id
53
+
54
+ assert_equal the_new_type, refreshed_bank_transaction.type,
55
+ "Expected the bank transaction to've had its type updated"
56
+ end
57
+
58
+ can "update a bank transaction by adding line items provided you calculate the tax_amount correctly" do
59
+ new_transaction = client.BankTransaction.build(
60
+ :type => "SPEND",
61
+ :contact => { :name => "Jazz Kang" },
62
+ :line_items => any_line_items(@account),
63
+ :bank_account => { :account_id => @bank_account.account_id },
64
+ :line_amount_types => "Exclusive"
65
+ )
66
+
67
+ assert new_transaction.save, "Save failed with the following errors: #{new_transaction.errors.inspect}"
68
+ assert_exists new_transaction
69
+
70
+ expected_id = new_transaction.id
71
+
72
+ tax_rate = get_tax_rate(@account.tax_type).effective_rate
73
+
74
+ unit_price = BigDecimal("1337.00")
75
+
76
+ the_new_line_items = [
77
+ {
78
+ :description => "Burrito skin",
79
+ :quantity => 1,
80
+ :unit_amount => unit_price,
81
+ :account_code => @account.code,
82
+ :tax_type => @account.tax_type,
83
+ :tax_amount => get_exclusive_tax(unit_price, tax_rate)
84
+ }
85
+ ]
86
+
87
+ new_transaction.line_items = the_new_line_items
88
+
89
+ assert new_transaction.save, "Update failed with the following errors: #{new_transaction.errors.inspect}"
90
+
91
+ refreshed_bank_transaction = client.BankTransaction.find expected_id
92
+
93
+ assert_equal expected_id, new_transaction.id,
94
+ "Expected the id to be the same because it has been updated"
95
+
96
+ assert_equal 1, refreshed_bank_transaction.line_items.size,
97
+ "Expected the bank transaction to've had its line items updated to just one"
98
+
99
+ the_first_line_item = refreshed_bank_transaction.line_items.first
100
+
101
+ assert_equal "Burrito skin", the_first_line_item.description,
102
+ "Expected the bank transaction to've had its line items updated, " +
103
+ "but the first one's description does not match: #{the_first_line_item.inspect}"
104
+ end
105
+
106
+ def get_inclusive_tax(amount, tax_rate)
107
+ inclusive_tax = amount * (1 - (100/(100 + tax_rate)))
108
+ BigDecimal(inclusive_tax.to_s).round(2)
109
+ end
110
+
111
+ def get_exclusive_tax(amount, tax_rate)
112
+ exclusive_tax = amount * (tax_rate/100)
113
+ BigDecimal(exclusive_tax.to_s).round(2)
114
+ end
115
+
116
+ def get_tax_rate tax_type
117
+ @all_tax_types ||= client.TaxRate.all
118
+ @all_tax_types.select{|tax_rate| tax_rate.tax_type == tax_type}.first
119
+ end
120
+
121
+ can "create a new RECEIVE bank transaction" do
122
+ new_transaction = client.BankTransaction.build(
123
+ :type => "RECEIVE",
124
+ :contact => { :name => "Jazz Kang" },
125
+ :line_items => any_line_items(@account),
126
+ :bank_account => { :account_id => @bank_account.account_id }
127
+ )
128
+
129
+ assert new_transaction.save, "Save failed with the following errors: #{new_transaction.errors.inspect}"
130
+ assert_exists new_transaction
131
+ end
132
+
133
+ it "treats line item unit_amounts as tax EXCLUSIVE"
134
+ must "not set the tax_amount manually on line items"
135
+
136
+ def assert_exists(bank_transaction)
137
+ assert_not_nil bank_transaction.id,
138
+ "Cannot check for exitence unless the bank transaction has non-null identifier"
139
+ assert_not_nil client.BankTransaction.find bank_transaction.id
140
+ end
141
+
142
+ def any_line_items(account)
143
+ [{
144
+ :description => "Clingfilm bike shorts",
145
+ :quantity => 1,
146
+ :unit_amount => "17.00",
147
+ :account_code => account.code,
148
+ :tax_type => account.tax_type
149
+ }]
150
+ end
151
+
152
+ it "fails with RuntimeError when you try and create a new bank account" do
153
+ new_account = client.Account.build(
154
+ :name => "Example bank account",
155
+ :code => "ACC-001"
156
+ )
157
+
158
+ assert_raise RuntimeError do
159
+ new_account.save
160
+ end
161
+ end
162
+ end