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,34 @@
1
+ module Xeroizer
2
+ module Record
3
+
4
+ class Validator
5
+
6
+ class AssociatedValidator < Validator
7
+
8
+ def valid?(record)
9
+ case record.class.fields[attribute][:type]
10
+ when :belongs_to
11
+ return true if options[:allow_blanks] && record[attribute].nil?
12
+ unless record[attribute].is_a?(Xeroizer::Record::Base) && record[attribute].valid?
13
+ record.errors << [attribute, options[:message] || "must be valid"]
14
+ end
15
+
16
+ when :has_many
17
+ return true if options[:allow_blanks] && (record[attribute].nil? || (record[attribute].is_a?(Array) && record[attribute].size == 0))
18
+ if record[attribute].is_a?(Array) && record[attribute].size > 0
19
+ unless record[attribute].all? { | r | r.is_a?(Xeroizer::Record::Base) && r.valid? }
20
+ record.errors << [attribute, options[:message] || "must all be valid"]
21
+ end
22
+ else
23
+ record.errors << [attribute, "must have one or more records"]
24
+ end
25
+
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,22 @@
1
+ module Xeroizer
2
+ module Record
3
+ class Validator
4
+ class BlockValidator < Validator
5
+ def valid?(record)
6
+ fail "No block provided" unless options[:block]
7
+
8
+ result = record.instance_eval &options[:block]
9
+
10
+ record.errors << [attribute, message] unless result == true
11
+ end
12
+
13
+ private
14
+
15
+ def message
16
+ supplied_message = options[:message] || ""
17
+ supplied_message.empty? ? "block condition failed" : supplied_message
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module Xeroizer
2
+ module Record
3
+
4
+ class Validator
5
+
6
+ class InclusionOfValidator < Validator
7
+
8
+ def valid?(record)
9
+ if options[:in] && options[:in].is_a?(Array)
10
+ return true if options[:allow_blanks] && (record[attribute].nil? || record[attribute].to_s == '')
11
+ unless options[:in].include?(record[attribute])
12
+ record.errors << [attribute, options[:message] || "not one of #{options[:in].join(', ')}"]
13
+ end
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ module Xeroizer
2
+ module Record
3
+
4
+ class Validator
5
+
6
+ class LengthOfValidator < Validator
7
+
8
+ def valid?(record)
9
+ if options[:max] && record.attributes[attribute].to_s.length > options[:max]
10
+ record.errors << [attribute, options[:message] || "must be shorter than #{options[:max]} characters"]
11
+ end
12
+
13
+ if options[:min] && record.attributes[attribute].to_s.length < options[:min]
14
+ record.errors << [attribute, options[:message] || "must be greater than #{options[:min]} characters"]
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ module Xeroizer
2
+ module Record
3
+
4
+ class Validator
5
+
6
+ class PresenceOfValidator < Validator
7
+
8
+ def valid?(record)
9
+ if record[attribute].nil? || record[attribute].to_s == ''
10
+ record.errors << [attribute, options[:message] || "can't be blank"]
11
+ end
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ module Xeroizer
2
+ module Record
3
+
4
+ class Validator
5
+
6
+ attr_reader :attribute
7
+ attr_reader :options
8
+
9
+ def initialize(attribute, options = {})
10
+ @attribute = attribute
11
+ @options = options
12
+ end
13
+
14
+ def validate(record)
15
+ valid?(record) if run_validator?(record, options)
16
+ end
17
+
18
+ def run_validator?(record, options)
19
+ return false if options[:if] && !condition?(record, options[:if])
20
+ return false if options[:unless] && condition?(record, options[:unless])
21
+ true
22
+ end
23
+
24
+ def condition?(record, condition)
25
+ return condition.call(record) if condition.respond_to? :call
26
+ return record.send(condition) if condition.is_a? Symbol
27
+ raise "Validation condition must be a Symbol or an Object that responds to call"
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,144 @@
1
+ require 'active_support/time'
2
+
3
+ module Xeroizer
4
+ module Record
5
+ module XmlHelper
6
+
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+ base.send :include, InstanceMethods
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ # Build a record instance from the XML node.
15
+ def build_from_node(node, parent, base_module)
16
+ record = new(parent)
17
+ node.elements.each do | element |
18
+ field = self.fields[element.name.to_s.underscore.to_sym]
19
+ if field
20
+ value = case field[:type]
21
+ when :guid then element.text
22
+ when :string then element.text
23
+ when :boolean then (element.text == 'true')
24
+ when :integer then element.text.to_i
25
+ when :decimal then BigDecimal(element.text)
26
+ when :date then Date.parse(element.text)
27
+ when :datetime then Time.parse(element.text)
28
+ when :datetime_utc then ActiveSupport::TimeZone['UTC'].parse(element.text).utc
29
+ when :belongs_to
30
+ model_name = field[:model_name] ? field[:model_name].to_sym : element.name.to_sym
31
+ base_module.const_get(model_name).build_from_node(element, parent, base_module)
32
+
33
+ when :has_many
34
+ if element.element_children.size > 0
35
+ sub_field_name = field[:model_name] ? field[:model_name].to_sym : element.children.first.name.to_sym
36
+ sub_parent = record.new_model_class(sub_field_name)
37
+ element.children.inject([]) do | list, inner_element |
38
+ list << base_module.const_get(sub_field_name).build_from_node(inner_element, sub_parent, base_module)
39
+ end
40
+ end
41
+
42
+ end
43
+ if field[:calculated]
44
+ record.attributes[field[:internal_name]] = value
45
+ else
46
+ record.send("#{field[:internal_name]}=".to_sym, value)
47
+ end
48
+ end
49
+ end
50
+
51
+ parent.mark_clean(record)
52
+ record
53
+ end
54
+
55
+ end
56
+
57
+ module InstanceMethods
58
+
59
+ public
60
+
61
+ # Turn a record into its XML representation.
62
+ def to_xml(b = Builder::XmlMarkup.new(:indent => 2))
63
+ optional_root_tag(parent.class.optional_xml_root_name, b) do |c|
64
+ c.tag!(model.class.xml_node_name || model.model_name) {
65
+ attributes.each do | key, value |
66
+ field = self.class.fields[key]
67
+ value = self.send(key) if field[:calculated]
68
+ xml_value_from_field(b, field, value) unless value.nil?
69
+ end
70
+ }
71
+ end
72
+ end
73
+
74
+ protected
75
+
76
+ # Add top-level root name if required.
77
+ # E.g. Payments need specifying in the form:
78
+ # <Payments>
79
+ # <Payment>
80
+ # ...
81
+ # </Payment>
82
+ # </Payments>
83
+ def optional_root_tag(root_name, b, &block)
84
+ if root_name
85
+ b.tag!(root_name) { |c| yield(c) }
86
+ else
87
+ yield(b)
88
+ end
89
+ end
90
+
91
+ # Format an attribute for use in the XML passed to Xero.
92
+ def xml_value_from_field(b, field, value)
93
+ case field[:type]
94
+ when :guid then b.tag!(field[:api_name], value)
95
+ when :string then b.tag!(field[:api_name], value)
96
+ when :boolean then b.tag!(field[:api_name], value ? 'true' : 'false')
97
+ when :integer then b.tag!(field[:api_name], value.to_i)
98
+ when :decimal
99
+ real_value = case value
100
+ when BigDecimal then value.to_s
101
+ when String then BigDecimal(value).to_s
102
+ else value
103
+ end
104
+ b.tag!(field[:api_name], real_value)
105
+
106
+ when :date
107
+ real_value = case value
108
+ when Date then value.strftime("%Y-%m-%d")
109
+ when Time then value.utc.strftime("%Y-%m-%d")
110
+ when NilClass then nil
111
+ else raise ArgumentError.new("Expected Date or Time object for the #{field[:api_name]} field")
112
+ end
113
+ b.tag!(field[:api_name], real_value)
114
+
115
+ when :datetime then b.tag!(field[:api_name], value.utc.strftime("%Y-%m-%dT%H:%M:%S"))
116
+ when :belongs_to
117
+ value.to_xml(b)
118
+ nil
119
+
120
+ when :has_many
121
+ if value.size > 0
122
+ sub_parent = value.first.parent
123
+ b.tag!(sub_parent.class.xml_root_name || sub_parent.model_name.pluralize) {
124
+ value.each { | record | record.to_xml(b) }
125
+ }
126
+ nil
127
+ end
128
+
129
+ end
130
+ end
131
+
132
+ def association_to_xml(association_name)
133
+ builder = Builder::XmlMarkup.new(indent: 2)
134
+ records = send(association_name)
135
+
136
+ optional_root_tag(association_name.to_s.camelize, builder) do |b|
137
+ records.each { |record| record.to_xml(b) }
138
+ end
139
+ end
140
+ end
141
+
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,42 @@
1
+ module Xeroizer
2
+ module Report
3
+ class AgedReceivablesByContact < Base
4
+
5
+ public
6
+
7
+ def total
8
+ @_total_cache ||= summary.cell(:Total).value
9
+ end
10
+
11
+ def total_paid
12
+ @_total_paid_cache ||= summary.cell(:Paid).value
13
+ end
14
+
15
+ def total_credited
16
+ @_total_credited_cache ||= summary.cell(:Credited).value
17
+ end
18
+
19
+ def total_due
20
+ @_total_due_cache ||= summary.cell(:Due).value
21
+ end
22
+
23
+ def total_overdue
24
+ return @_total_due_cache if @_total_due_cache
25
+
26
+ now = Time.now
27
+ @_total_due_cache = sum(:Due) do | row |
28
+ due_date = row.cell('Due Date').value
29
+ due_date && due_date < now
30
+ end
31
+ end
32
+
33
+ def sum(column_name, &block)
34
+ sections.first.rows.inject(BigDecimal('0')) do | sum, row |
35
+ sum += row.cell(column_name).value if row.class == Xeroizer::Report::Row && (block.nil? || block.call(row))
36
+ sum
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ require 'xeroizer/report/cell'
2
+ require 'xeroizer/report/row/row'
3
+ require 'xeroizer/report/row/header'
4
+ require 'xeroizer/report/row/section'
5
+ require 'xeroizer/report/row/summary'
6
+ require 'xeroizer/report/xml_helper'
7
+
8
+ module Xeroizer
9
+ module Report
10
+ class Base
11
+
12
+ include XmlHelper
13
+
14
+ attr_reader :factory
15
+
16
+ attr_accessor :id
17
+ attr_accessor :name
18
+ attr_accessor :type
19
+ attr_accessor :titles
20
+ attr_accessor :date
21
+ attr_accessor :updated_at
22
+
23
+ attr_accessor :rows
24
+
25
+ attr_accessor :header
26
+ attr_accessor :summary
27
+ attr_accessor :sections
28
+
29
+ public
30
+
31
+ def initialize(factory)
32
+ @titles = []
33
+ @rows = []
34
+ @sections = []
35
+ @factory = factory
36
+ end
37
+
38
+ protected
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,32 @@
1
+ require 'xeroizer/report/cell_xml_helper'
2
+
3
+ module Xeroizer
4
+ module Report
5
+ class Cell
6
+
7
+ include CellXmlHelper
8
+
9
+ attr_accessor :value
10
+ attr_accessor :attributes
11
+
12
+ public
13
+
14
+ def initialize
15
+ @attributes = {}
16
+ end
17
+
18
+ # Return first attribute's ID in the hash. Assumes there is only one as hashes get out of order.
19
+ # In all cases I've seen so far there is only one attribute returned.
20
+ def attribute_id
21
+ @attributes.each { | id, value | return id }
22
+ end
23
+
24
+ # Return first attribute's value in the hash. Assumes there is only one as hashes get out of order.
25
+ # In all cases I've seen so far there is only one attribute returned.
26
+ def attribute_value
27
+ @attributes.each { | id, value | return value }
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -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 /\A[-]?\d+(\.\d+)?\z/ then BigDecimal(value)
51
+ when /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\z/ 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