affixapi 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +9 -0
  3. data/LICENSE +19 -0
  4. data/README.md +374 -0
  5. data/Rakefile +10 -0
  6. data/affixapi.gemspec +38 -0
  7. data/docs/AddressNoNonNullRequest.md +26 -0
  8. data/docs/AddressResponse.md +26 -0
  9. data/docs/Class20230301Api.md +1401 -0
  10. data/docs/ClientRequest.md +24 -0
  11. data/docs/ClientResponse.md +26 -0
  12. data/docs/CompanyResponse.md +28 -0
  13. data/docs/CoreApi.md +69 -0
  14. data/docs/CreateEmployeeRequest.md +68 -0
  15. data/docs/CreateEmployeeRequestBankAccount.md +26 -0
  16. data/docs/CreateEmployeeRequestManager.md +26 -0
  17. data/docs/CurrencyRequest.md +15 -0
  18. data/docs/CurrencyResponse.md +15 -0
  19. data/docs/DeveloperApi.md +777 -0
  20. data/docs/DisconnectResponse.md +18 -0
  21. data/docs/EmployeeResponse.md +74 -0
  22. data/docs/EmploymentNoNullEnumRequest.md +30 -0
  23. data/docs/EmploymentResponse.md +30 -0
  24. data/docs/GroupNoNullEnumRequest.md +24 -0
  25. data/docs/GroupResponse.md +24 -0
  26. data/docs/IdAndMessageResponse.md +20 -0
  27. data/docs/IdentityResponse.md +22 -0
  28. data/docs/InlineResponse400.md +20 -0
  29. data/docs/InlineResponse401.md +22 -0
  30. data/docs/InlineResponse409.md +22 -0
  31. data/docs/IntrospectResponse.md +24 -0
  32. data/docs/LocationNoNonNullRequest.md +26 -0
  33. data/docs/LocationResponse.md +26 -0
  34. data/docs/ManagementApi.md +420 -0
  35. data/docs/MessageResponse.md +18 -0
  36. data/docs/ModeRequest.md +15 -0
  37. data/docs/ModeResponse.md +15 -0
  38. data/docs/OfficialApi.md +631 -0
  39. data/docs/PayrunResponse.md +30 -0
  40. data/docs/PayslipResponse.md +44 -0
  41. data/docs/PayslipResponseContributions.md +20 -0
  42. data/docs/PayslipResponseDeductions.md +20 -0
  43. data/docs/PayslipResponseEarnings.md +22 -0
  44. data/docs/PayslipResponseTaxes.md +22 -0
  45. data/docs/ProviderRequest.md +15 -0
  46. data/docs/ProviderResponse.md +15 -0
  47. data/docs/ScopesRequest.md +15 -0
  48. data/docs/ScopesResponse.md +15 -0
  49. data/docs/TimeOffBalanceResponse.md +32 -0
  50. data/docs/TimeOffEntryResponse.md +40 -0
  51. data/docs/TimesheetResponse.md +32 -0
  52. data/docs/TokenRequest.md +26 -0
  53. data/docs/TokenResponse.md +26 -0
  54. data/git_push.sh +58 -0
  55. data/lib/openapi_client/api/class20230301_api.rb +1198 -0
  56. data/lib/openapi_client/api/core_api.rb +79 -0
  57. data/lib/openapi_client/api/developer_api.rb +677 -0
  58. data/lib/openapi_client/api/management_api.rb +380 -0
  59. data/lib/openapi_client/api/official_api.rb +543 -0
  60. data/lib/openapi_client/api_client.rb +390 -0
  61. data/lib/openapi_client/api_error.rb +57 -0
  62. data/lib/openapi_client/configuration.rb +288 -0
  63. data/lib/openapi_client/models/address_no_non_null_request.rb +295 -0
  64. data/lib/openapi_client/models/address_response.rb +295 -0
  65. data/lib/openapi_client/models/client_request.rb +269 -0
  66. data/lib/openapi_client/models/client_response.rb +284 -0
  67. data/lib/openapi_client/models/company_response.rb +279 -0
  68. data/lib/openapi_client/models/create_employee_request.rb +568 -0
  69. data/lib/openapi_client/models/create_employee_request_bank_account.rb +259 -0
  70. data/lib/openapi_client/models/create_employee_request_manager.rb +263 -0
  71. data/lib/openapi_client/models/currency_request.rb +38 -0
  72. data/lib/openapi_client/models/currency_response.rb +38 -0
  73. data/lib/openapi_client/models/disconnect_response.rb +258 -0
  74. data/lib/openapi_client/models/employee_response.rb +608 -0
  75. data/lib/openapi_client/models/employment_no_null_enum_request.rb +329 -0
  76. data/lib/openapi_client/models/employment_response.rb +329 -0
  77. data/lib/openapi_client/models/group_no_null_enum_request.rb +283 -0
  78. data/lib/openapi_client/models/group_response.rb +283 -0
  79. data/lib/openapi_client/models/id_and_message_response.rb +239 -0
  80. data/lib/openapi_client/models/identity_response.rb +250 -0
  81. data/lib/openapi_client/models/inline_response400.rb +227 -0
  82. data/lib/openapi_client/models/inline_response401.rb +299 -0
  83. data/lib/openapi_client/models/inline_response409.rb +278 -0
  84. data/lib/openapi_client/models/introspect_response.rb +269 -0
  85. data/lib/openapi_client/models/location_no_non_null_request.rb +263 -0
  86. data/lib/openapi_client/models/location_response.rb +263 -0
  87. data/lib/openapi_client/models/message_response.rb +223 -0
  88. data/lib/openapi_client/models/mode_request.rb +37 -0
  89. data/lib/openapi_client/models/mode_response.rb +37 -0
  90. data/lib/openapi_client/models/payrun_response.rb +342 -0
  91. data/lib/openapi_client/models/payslip_response.rb +448 -0
  92. data/lib/openapi_client/models/payslip_response_contributions.rb +238 -0
  93. data/lib/openapi_client/models/payslip_response_deductions.rb +238 -0
  94. data/lib/openapi_client/models/payslip_response_earnings.rb +250 -0
  95. data/lib/openapi_client/models/payslip_response_taxes.rb +248 -0
  96. data/lib/openapi_client/models/provider_request.rb +70 -0
  97. data/lib/openapi_client/models/provider_response.rb +70 -0
  98. data/lib/openapi_client/models/scopes_request.rb +55 -0
  99. data/lib/openapi_client/models/scopes_response.rb +55 -0
  100. data/lib/openapi_client/models/time_off_balance_response.rb +342 -0
  101. data/lib/openapi_client/models/time_off_entry_response.rb +408 -0
  102. data/lib/openapi_client/models/timesheet_response.rb +318 -0
  103. data/lib/openapi_client/models/token_request.rb +318 -0
  104. data/lib/openapi_client/models/token_response.rb +318 -0
  105. data/lib/openapi_client/version.rb +15 -0
  106. data/lib/openapi_client.rb +86 -0
  107. data/openapi_client-0.0.1.gem +0 -0
  108. data/pkg/affixapi-0.0.1.gem +0 -0
  109. data/spec/api/class20230301_api_spec.rb +260 -0
  110. data/spec/api/core_api_spec.rb +46 -0
  111. data/spec/api/developer_api_spec.rb +160 -0
  112. data/spec/api/management_api_spec.rb +103 -0
  113. data/spec/api/official_api_spec.rb +135 -0
  114. data/spec/api_client_spec.rb +226 -0
  115. data/spec/configuration_spec.rb +42 -0
  116. data/spec/models/address_no_non_null_request_spec.rb +62 -0
  117. data/spec/models/address_response_spec.rb +62 -0
  118. data/spec/models/client_request_spec.rb +52 -0
  119. data/spec/models/client_response_spec.rb +58 -0
  120. data/spec/models/company_response_spec.rb +64 -0
  121. data/spec/models/create_employee_request_bank_account_spec.rb +58 -0
  122. data/spec/models/create_employee_request_manager_spec.rb +58 -0
  123. data/spec/models/create_employee_request_spec.rb +204 -0
  124. data/spec/models/currency_request_spec.rb +28 -0
  125. data/spec/models/currency_response_spec.rb +28 -0
  126. data/spec/models/disconnect_response_spec.rb +38 -0
  127. data/spec/models/employee_response_spec.rb +222 -0
  128. data/spec/models/employment_no_null_enum_request_spec.rb +78 -0
  129. data/spec/models/employment_response_spec.rb +78 -0
  130. data/spec/models/group_no_null_enum_request_spec.rb +56 -0
  131. data/spec/models/group_response_spec.rb +56 -0
  132. data/spec/models/id_and_message_response_spec.rb +40 -0
  133. data/spec/models/identity_response_spec.rb +46 -0
  134. data/spec/models/inline_response400_spec.rb +40 -0
  135. data/spec/models/inline_response401_spec.rb +54 -0
  136. data/spec/models/inline_response409_spec.rb +50 -0
  137. data/spec/models/introspect_response_spec.rb +52 -0
  138. data/spec/models/location_no_non_null_request_spec.rb +58 -0
  139. data/spec/models/location_response_spec.rb +58 -0
  140. data/spec/models/message_response_spec.rb +34 -0
  141. data/spec/models/mode_request_spec.rb +28 -0
  142. data/spec/models/mode_response_spec.rb +28 -0
  143. data/spec/models/payrun_response_spec.rb +78 -0
  144. data/spec/models/payslip_response_contributions_spec.rb +40 -0
  145. data/spec/models/payslip_response_deductions_spec.rb +40 -0
  146. data/spec/models/payslip_response_earnings_spec.rb +46 -0
  147. data/spec/models/payslip_response_spec.rb +116 -0
  148. data/spec/models/payslip_response_taxes_spec.rb +46 -0
  149. data/spec/models/provider_request_spec.rb +28 -0
  150. data/spec/models/provider_response_spec.rb +28 -0
  151. data/spec/models/scopes_request_spec.rb +28 -0
  152. data/spec/models/scopes_response_spec.rb +28 -0
  153. data/spec/models/time_off_balance_response_spec.rb +80 -0
  154. data/spec/models/time_off_entry_response_spec.rb +108 -0
  155. data/spec/models/timesheet_response_spec.rb +76 -0
  156. data/spec/models/token_request_spec.rb +62 -0
  157. data/spec/models/token_response_spec.rb +62 -0
  158. data/spec/spec_helper.rb +111 -0
  159. metadata +349 -0
@@ -0,0 +1,250 @@
1
+ =begin
2
+ #Affix API
3
+
4
+ #The affixapi.com API documentation. # Introduction Affix API is an OAuth 2.1 application that allows developers to access customer data, without developers needing to manage or maintain integrations; or collect login credentials or API keys from users for these third party systems. # OAuth 2.1 Affix API follows the [OAuth 2.1 spec](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-08). As an OAuth application, Affix API handles not only both the collection of sensitive user credentials or API keys, but also builds and maintains the integrations with the providers, so you don't have to. # How to obtain an access token in order to get started, you must: - register a `client_id` - direct your user to the sign in flow (`https://connect.affixapi.com` [with the appropriate query parameters](https://github.com/affixapi/starter-kit/tree/master/connect)) - capture `authorization_code` we will send to your redirect URI after the sign in flow is complete and exchange that `authorization_code` for a Bearer token # Sandbox keys (developer mode) ### dev ``` eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6ImQ1OTZhMmYzLWYzNzktNGE1ZC1hMmRhLTk4OWJmYWViYTg1ZCIsImlhdCI6MTcwMjkyMDkwMywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5kZXYuZW5naW5lZXJpbmcuYWZmaXhhcGkuY29tIiwic3ViIjoiZGV2ZWxvcGVyIiwiYXVkIjoiM0ZEQUVERjktMURDQTRGNTQtODc5NDlGNkEtNDEwMjc2NDMifQ.VLWYjCQvBS0C3ZA6_J3-U-idZj5EYI2IlDdTjAWBxSIHGufp6cqaVodKsF2BeIqcIeB3P0lW-KL9mY3xGd7ckQ ``` #### `employees` endpoint sample: ``` curl --fail \\ -X GET \\ -H 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6ImQ1OTZhMmYzLWYzNzktNGE1ZC1hMmRhLTk4OWJmYWViYTg1ZCIsImlhdCI6MTcwMjkyMDkwMywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5kZXYuZW5naW5lZXJpbmcuYWZmaXhhcGkuY29tIiwic3ViIjoiZGV2ZWxvcGVyIiwiYXVkIjoiM0ZEQUVERjktMURDQTRGNTQtODc5NDlGNkEtNDEwMjc2NDMifQ.VLWYjCQvBS0C3ZA6_J3-U-idZj5EYI2IlDdTjAWBxSIHGufp6cqaVodKsF2BeIqcIeB3P0lW-KL9mY3xGd7ckQ' \\ 'https://dev.api.affixapi.com/2023-03-01/developer/employees' ``` ### prod ``` eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6IjI5YjFjYTg4LWNlNjktNDgyZC1iNGZjLTkzMWMzZmJkYWM4ZSIsImlhdCI6MTcwMjkyMTA4MywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5wcm9kLmVuZ2luZWVyaW5nLmFmZml4YXBpLmNvbSIsInN1YiI6ImRldmVsb3BlciIsImF1ZCI6IjA4QkIwODFFLUQ5QUI0RDE0LThERjk5MjMzLTY2NjE1Q0U5In0.2zdpFAmiyYiYk6MOcbXNUwwR4M1Fextnaac340x54AidiWXCyw-u9KeavbqfYF6q8a9kcDLrxhJ8Wc_3tIzuVw ``` #### `employees` endpoint sample: ``` curl --fail \\ -X GET \\ -H 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6IjI5YjFjYTg4LWNlNjktNDgyZC1iNGZjLTkzMWMzZmJkYWM4ZSIsImlhdCI6MTcwMjkyMTA4MywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5wcm9kLmVuZ2luZWVyaW5nLmFmZml4YXBpLmNvbSIsInN1YiI6ImRldmVsb3BlciIsImF1ZCI6IjA4QkIwODFFLUQ5QUI0RDE0LThERjk5MjMzLTY2NjE1Q0U5In0.2zdpFAmiyYiYk6MOcbXNUwwR4M1Fextnaac340x54AidiWXCyw-u9KeavbqfYF6q8a9kcDLrxhJ8Wc_3tIzuVw' \\ 'https://api.affixapi.com/2023-03-01/developer/employees' ``` # Webhooks An exciting feature for HR/Payroll modes are webhooks. If enabled, your `webhook_uri` is set on your `client_id` for the respective environment: `dev | prod` Webhooks are configured to make live requests to the underlying integration 1x/hr, and if a difference is detected since the last request, we will send a request to your `webhook_uri` with this shape: ``` { added: <api.v20230301.Employees>[ <api.v20230301.Employee>{ ..., date_of_birth: '2010-08-06', display_full_name: 'Daija Rogahn', employee_number: '57993', employment_status: 'pending', employment_type: 'other', employments: [ { currency: 'eur', effective_date: '2022-02-25', employment_type: 'other', job_title: 'Dynamic Implementation Manager', pay_frequency: 'semimonthly', pay_period: 'YEAR', pay_rate: 96000, }, ], first_name: 'Daija', ... } ], removed: [], updated: [ <api.v20230301.Employee>{ ..., date_of_birth: '2009-11-09', display_full_name: 'Lourdes Stiedemann', employee_number: '63189', employment_status: 'leave', employment_type: 'full_time', employments: [ { currency: 'gbp', effective_date: '2023-01-16', employment_type: 'full_time', job_title: 'Forward Brand Planner', pay_frequency: 'semimonthly', pay_period: 'YEAR', pay_rate: 86000, }, ], first_name: 'Lourdes', } ] } ``` the following headers will be sent with webhook requests: ``` x-affix-api-signature: ab8474e609db95d5df3adc39ea3add7a7544bd215c5c520a30a650ae93a2fba7 x-affix-api-origin: webhooks-employees-webhook user-agent: affixapi.com ``` Before trusting the payload, you should sign the payload and verify the signature matches the signature sent by the `affixapi.com` service. This secures that the data sent to your `webhook_uri` is from the `affixapi.com` server. The signature is created by combining the signing secret (your `client_secret`) with the body of the request sent using a standard HMAC-SHA256 keyed hash. The signature can be created via: - create an `HMAC` with your `client_secret` - update the `HMAC` with the payload - get the hex digest -> this is the signature Sample `typescript` code that follows this recipe: ``` import { createHmac } from 'crypto'; export const computeSignature = ({ str, signingSecret, }: { signingSecret: string; str: string; }): string => { const hmac = createHmac('sha256', signingSecret); hmac.update(str); const signature = hmac.digest('hex'); return signature; }; ``` ## Rate limits Open endpoints (not gated by an API key) (applied at endpoint level): - 15 requests every 1 minute (by IP address) - 25 requests every 5 minutes (by IP address) Gated endpoints (require an API key) (applied at endpoint level): - 40 requests every 1 minute (by IP address) - 40 requests every 5 minutes (by `client_id`) Things to keep in mind: - Open endpoints (not gated by an API key) will likely be called by your users, not you, so rate limits generally would not apply to you. - As a developer, rate limits are applied at the endpoint granularity. - For example, say the rate limits below are 10 requests per minute by ip. from that same ip, within 1 minute, you get: - 10 requests per minute on `/orders`, - another 10 requests per minute on `/items`, - and another 10 requests per minute on `/identity`, - for a total of 30 requests per minute.
5
+
6
+ The version of the OpenAPI document: 2023-03-01
7
+ Contact: developers@affixapi.com
8
+ Generated by: https://openapi-generator.tech
9
+ OpenAPI Generator version: 5.1.1
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module OpenapiClient
17
+ # The breakdown of gross pay
18
+ class PayslipResponseEarnings
19
+ attr_accessor :name
20
+
21
+ # if USD/EUR/GBP, in cent
22
+ attr_accessor :amount
23
+
24
+ # hours, if applicable
25
+ attr_accessor :hours
26
+
27
+ # Attribute mapping from ruby-style variable name to JSON key.
28
+ def self.attribute_map
29
+ {
30
+ :'name' => :'name',
31
+ :'amount' => :'amount',
32
+ :'hours' => :'hours'
33
+ }
34
+ end
35
+
36
+ # Returns all the JSON keys this model knows about
37
+ def self.acceptable_attributes
38
+ attribute_map.values
39
+ end
40
+
41
+ # Attribute type mapping.
42
+ def self.openapi_types
43
+ {
44
+ :'name' => :'String',
45
+ :'amount' => :'Float',
46
+ :'hours' => :'Float'
47
+ }
48
+ end
49
+
50
+ # List of attributes with nullable: true
51
+ def self.openapi_nullable
52
+ Set.new([
53
+ :'hours'
54
+ ])
55
+ end
56
+
57
+ # Initializes the object
58
+ # @param [Hash] attributes Model attributes in the form of hash
59
+ def initialize(attributes = {})
60
+ if (!attributes.is_a?(Hash))
61
+ fail ArgumentError, "The input argument (attributes) must be a hash in `OpenapiClient::PayslipResponseEarnings` initialize method"
62
+ end
63
+
64
+ # check to see if the attribute exists and convert string to symbol for hash key
65
+ attributes = attributes.each_with_object({}) { |(k, v), h|
66
+ if (!self.class.attribute_map.key?(k.to_sym))
67
+ fail ArgumentError, "`#{k}` is not a valid attribute in `OpenapiClient::PayslipResponseEarnings`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
68
+ end
69
+ h[k.to_sym] = v
70
+ }
71
+
72
+ if attributes.key?(:'name')
73
+ self.name = attributes[:'name']
74
+ end
75
+
76
+ if attributes.key?(:'amount')
77
+ self.amount = attributes[:'amount']
78
+ end
79
+
80
+ if attributes.key?(:'hours')
81
+ self.hours = attributes[:'hours']
82
+ end
83
+ end
84
+
85
+ # Show invalid properties with the reasons. Usually used together with valid?
86
+ # @return Array for valid properties with the reasons
87
+ def list_invalid_properties
88
+ invalid_properties = Array.new
89
+ if @name.nil?
90
+ invalid_properties.push('invalid value for "name", name cannot be nil.')
91
+ end
92
+
93
+ if @amount.nil?
94
+ invalid_properties.push('invalid value for "amount", amount cannot be nil.')
95
+ end
96
+
97
+ invalid_properties
98
+ end
99
+
100
+ # Check to see if the all the properties in the model are valid
101
+ # @return true if the model is valid
102
+ def valid?
103
+ return false if @name.nil?
104
+ return false if @amount.nil?
105
+ true
106
+ end
107
+
108
+ # Checks equality by comparing each attribute.
109
+ # @param [Object] Object to be compared
110
+ def ==(o)
111
+ return true if self.equal?(o)
112
+ self.class == o.class &&
113
+ name == o.name &&
114
+ amount == o.amount &&
115
+ hours == o.hours
116
+ end
117
+
118
+ # @see the `==` method
119
+ # @param [Object] Object to be compared
120
+ def eql?(o)
121
+ self == o
122
+ end
123
+
124
+ # Calculates hash code according to all attributes.
125
+ # @return [Integer] Hash code
126
+ def hash
127
+ [name, amount, hours].hash
128
+ end
129
+
130
+ # Builds the object from hash
131
+ # @param [Hash] attributes Model attributes in the form of hash
132
+ # @return [Object] Returns the model itself
133
+ def self.build_from_hash(attributes)
134
+ new.build_from_hash(attributes)
135
+ end
136
+
137
+ # Builds the object from hash
138
+ # @param [Hash] attributes Model attributes in the form of hash
139
+ # @return [Object] Returns the model itself
140
+ def build_from_hash(attributes)
141
+ return nil unless attributes.is_a?(Hash)
142
+ self.class.openapi_types.each_pair do |key, type|
143
+ if attributes[self.class.attribute_map[key]].nil? && self.class.openapi_nullable.include?(key)
144
+ self.send("#{key}=", nil)
145
+ elsif type =~ /\AArray<(.*)>/i
146
+ # check to ensure the input is an array given that the attribute
147
+ # is documented as an array but the input is not
148
+ if attributes[self.class.attribute_map[key]].is_a?(Array)
149
+ self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) })
150
+ end
151
+ elsif !attributes[self.class.attribute_map[key]].nil?
152
+ self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
153
+ end
154
+ end
155
+
156
+ self
157
+ end
158
+
159
+ # Deserializes the data based on type
160
+ # @param string type Data type
161
+ # @param string value Value to be deserialized
162
+ # @return [Object] Deserialized data
163
+ def _deserialize(type, value)
164
+ case type.to_sym
165
+ when :Time
166
+ Time.parse(value)
167
+ when :Date
168
+ Date.parse(value)
169
+ when :String
170
+ value.to_s
171
+ when :Integer
172
+ value.to_i
173
+ when :Float
174
+ value.to_f
175
+ when :Boolean
176
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
177
+ true
178
+ else
179
+ false
180
+ end
181
+ when :Object
182
+ # generic object (usually a Hash), return directly
183
+ value
184
+ when /\AArray<(?<inner_type>.+)>\z/
185
+ inner_type = Regexp.last_match[:inner_type]
186
+ value.map { |v| _deserialize(inner_type, v) }
187
+ when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
188
+ k_type = Regexp.last_match[:k_type]
189
+ v_type = Regexp.last_match[:v_type]
190
+ {}.tap do |hash|
191
+ value.each do |k, v|
192
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
193
+ end
194
+ end
195
+ else # model
196
+ # models (e.g. Pet) or oneOf
197
+ klass = OpenapiClient.const_get(type)
198
+ klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
199
+ end
200
+ end
201
+
202
+ # Returns the string representation of the object
203
+ # @return [String] String presentation of the object
204
+ def to_s
205
+ to_hash.to_s
206
+ end
207
+
208
+ # to_body is an alias to to_hash (backward compatibility)
209
+ # @return [Hash] Returns the object in the form of hash
210
+ def to_body
211
+ to_hash
212
+ end
213
+
214
+ # Returns the object in the form of hash
215
+ # @return [Hash] Returns the object in the form of hash
216
+ def to_hash
217
+ hash = {}
218
+ self.class.attribute_map.each_pair do |attr, param|
219
+ value = self.send(attr)
220
+ if value.nil?
221
+ is_nullable = self.class.openapi_nullable.include?(attr)
222
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
223
+ end
224
+
225
+ hash[param] = _to_hash(value)
226
+ end
227
+ hash
228
+ end
229
+
230
+ # Outputs non-array value in the form of hash
231
+ # For object, use to_hash. Otherwise, just return the value
232
+ # @param [Object] value Any valid value
233
+ # @return [Hash] Returns the value in the form of hash
234
+ def _to_hash(value)
235
+ if value.is_a?(Array)
236
+ value.compact.map { |v| _to_hash(v) }
237
+ elsif value.is_a?(Hash)
238
+ {}.tap do |hash|
239
+ value.each { |k, v| hash[k] = _to_hash(v) }
240
+ end
241
+ elsif value.respond_to? :to_hash
242
+ value.to_hash
243
+ else
244
+ value
245
+ end
246
+ end
247
+
248
+ end
249
+
250
+ end
@@ -0,0 +1,248 @@
1
+ =begin
2
+ #Affix API
3
+
4
+ #The affixapi.com API documentation. # Introduction Affix API is an OAuth 2.1 application that allows developers to access customer data, without developers needing to manage or maintain integrations; or collect login credentials or API keys from users for these third party systems. # OAuth 2.1 Affix API follows the [OAuth 2.1 spec](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-08). As an OAuth application, Affix API handles not only both the collection of sensitive user credentials or API keys, but also builds and maintains the integrations with the providers, so you don't have to. # How to obtain an access token in order to get started, you must: - register a `client_id` - direct your user to the sign in flow (`https://connect.affixapi.com` [with the appropriate query parameters](https://github.com/affixapi/starter-kit/tree/master/connect)) - capture `authorization_code` we will send to your redirect URI after the sign in flow is complete and exchange that `authorization_code` for a Bearer token # Sandbox keys (developer mode) ### dev ``` eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6ImQ1OTZhMmYzLWYzNzktNGE1ZC1hMmRhLTk4OWJmYWViYTg1ZCIsImlhdCI6MTcwMjkyMDkwMywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5kZXYuZW5naW5lZXJpbmcuYWZmaXhhcGkuY29tIiwic3ViIjoiZGV2ZWxvcGVyIiwiYXVkIjoiM0ZEQUVERjktMURDQTRGNTQtODc5NDlGNkEtNDEwMjc2NDMifQ.VLWYjCQvBS0C3ZA6_J3-U-idZj5EYI2IlDdTjAWBxSIHGufp6cqaVodKsF2BeIqcIeB3P0lW-KL9mY3xGd7ckQ ``` #### `employees` endpoint sample: ``` curl --fail \\ -X GET \\ -H 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6ImQ1OTZhMmYzLWYzNzktNGE1ZC1hMmRhLTk4OWJmYWViYTg1ZCIsImlhdCI6MTcwMjkyMDkwMywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5kZXYuZW5naW5lZXJpbmcuYWZmaXhhcGkuY29tIiwic3ViIjoiZGV2ZWxvcGVyIiwiYXVkIjoiM0ZEQUVERjktMURDQTRGNTQtODc5NDlGNkEtNDEwMjc2NDMifQ.VLWYjCQvBS0C3ZA6_J3-U-idZj5EYI2IlDdTjAWBxSIHGufp6cqaVodKsF2BeIqcIeB3P0lW-KL9mY3xGd7ckQ' \\ 'https://dev.api.affixapi.com/2023-03-01/developer/employees' ``` ### prod ``` eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6IjI5YjFjYTg4LWNlNjktNDgyZC1iNGZjLTkzMWMzZmJkYWM4ZSIsImlhdCI6MTcwMjkyMTA4MywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5wcm9kLmVuZ2luZWVyaW5nLmFmZml4YXBpLmNvbSIsInN1YiI6ImRldmVsb3BlciIsImF1ZCI6IjA4QkIwODFFLUQ5QUI0RDE0LThERjk5MjMzLTY2NjE1Q0U5In0.2zdpFAmiyYiYk6MOcbXNUwwR4M1Fextnaac340x54AidiWXCyw-u9KeavbqfYF6q8a9kcDLrxhJ8Wc_3tIzuVw ``` #### `employees` endpoint sample: ``` curl --fail \\ -X GET \\ -H 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6IjI5YjFjYTg4LWNlNjktNDgyZC1iNGZjLTkzMWMzZmJkYWM4ZSIsImlhdCI6MTcwMjkyMTA4MywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5wcm9kLmVuZ2luZWVyaW5nLmFmZml4YXBpLmNvbSIsInN1YiI6ImRldmVsb3BlciIsImF1ZCI6IjA4QkIwODFFLUQ5QUI0RDE0LThERjk5MjMzLTY2NjE1Q0U5In0.2zdpFAmiyYiYk6MOcbXNUwwR4M1Fextnaac340x54AidiWXCyw-u9KeavbqfYF6q8a9kcDLrxhJ8Wc_3tIzuVw' \\ 'https://api.affixapi.com/2023-03-01/developer/employees' ``` # Webhooks An exciting feature for HR/Payroll modes are webhooks. If enabled, your `webhook_uri` is set on your `client_id` for the respective environment: `dev | prod` Webhooks are configured to make live requests to the underlying integration 1x/hr, and if a difference is detected since the last request, we will send a request to your `webhook_uri` with this shape: ``` { added: <api.v20230301.Employees>[ <api.v20230301.Employee>{ ..., date_of_birth: '2010-08-06', display_full_name: 'Daija Rogahn', employee_number: '57993', employment_status: 'pending', employment_type: 'other', employments: [ { currency: 'eur', effective_date: '2022-02-25', employment_type: 'other', job_title: 'Dynamic Implementation Manager', pay_frequency: 'semimonthly', pay_period: 'YEAR', pay_rate: 96000, }, ], first_name: 'Daija', ... } ], removed: [], updated: [ <api.v20230301.Employee>{ ..., date_of_birth: '2009-11-09', display_full_name: 'Lourdes Stiedemann', employee_number: '63189', employment_status: 'leave', employment_type: 'full_time', employments: [ { currency: 'gbp', effective_date: '2023-01-16', employment_type: 'full_time', job_title: 'Forward Brand Planner', pay_frequency: 'semimonthly', pay_period: 'YEAR', pay_rate: 86000, }, ], first_name: 'Lourdes', } ] } ``` the following headers will be sent with webhook requests: ``` x-affix-api-signature: ab8474e609db95d5df3adc39ea3add7a7544bd215c5c520a30a650ae93a2fba7 x-affix-api-origin: webhooks-employees-webhook user-agent: affixapi.com ``` Before trusting the payload, you should sign the payload and verify the signature matches the signature sent by the `affixapi.com` service. This secures that the data sent to your `webhook_uri` is from the `affixapi.com` server. The signature is created by combining the signing secret (your `client_secret`) with the body of the request sent using a standard HMAC-SHA256 keyed hash. The signature can be created via: - create an `HMAC` with your `client_secret` - update the `HMAC` with the payload - get the hex digest -> this is the signature Sample `typescript` code that follows this recipe: ``` import { createHmac } from 'crypto'; export const computeSignature = ({ str, signingSecret, }: { signingSecret: string; str: string; }): string => { const hmac = createHmac('sha256', signingSecret); hmac.update(str); const signature = hmac.digest('hex'); return signature; }; ``` ## Rate limits Open endpoints (not gated by an API key) (applied at endpoint level): - 15 requests every 1 minute (by IP address) - 25 requests every 5 minutes (by IP address) Gated endpoints (require an API key) (applied at endpoint level): - 40 requests every 1 minute (by IP address) - 40 requests every 5 minutes (by `client_id`) Things to keep in mind: - Open endpoints (not gated by an API key) will likely be called by your users, not you, so rate limits generally would not apply to you. - As a developer, rate limits are applied at the endpoint granularity. - For example, say the rate limits below are 10 requests per minute by ip. from that same ip, within 1 minute, you get: - 10 requests per minute on `/orders`, - another 10 requests per minute on `/items`, - and another 10 requests per minute on `/identity`, - for a total of 30 requests per minute.
5
+
6
+ The version of the OpenAPI document: 2023-03-01
7
+ Contact: developers@affixapi.com
8
+ Generated by: https://openapi-generator.tech
9
+ OpenAPI Generator version: 5.1.1
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module OpenapiClient
17
+ class PayslipResponseTaxes
18
+ attr_accessor :name
19
+
20
+ # if USD/EUR/GBP, in cent
21
+ attr_accessor :amount
22
+
23
+ attr_accessor :employer_tax
24
+
25
+ # Attribute mapping from ruby-style variable name to JSON key.
26
+ def self.attribute_map
27
+ {
28
+ :'name' => :'name',
29
+ :'amount' => :'amount',
30
+ :'employer_tax' => :'employer_tax'
31
+ }
32
+ end
33
+
34
+ # Returns all the JSON keys this model knows about
35
+ def self.acceptable_attributes
36
+ attribute_map.values
37
+ end
38
+
39
+ # Attribute type mapping.
40
+ def self.openapi_types
41
+ {
42
+ :'name' => :'String',
43
+ :'amount' => :'Float',
44
+ :'employer_tax' => :'Boolean'
45
+ }
46
+ end
47
+
48
+ # List of attributes with nullable: true
49
+ def self.openapi_nullable
50
+ Set.new([
51
+ :'employer_tax'
52
+ ])
53
+ end
54
+
55
+ # Initializes the object
56
+ # @param [Hash] attributes Model attributes in the form of hash
57
+ def initialize(attributes = {})
58
+ if (!attributes.is_a?(Hash))
59
+ fail ArgumentError, "The input argument (attributes) must be a hash in `OpenapiClient::PayslipResponseTaxes` initialize method"
60
+ end
61
+
62
+ # check to see if the attribute exists and convert string to symbol for hash key
63
+ attributes = attributes.each_with_object({}) { |(k, v), h|
64
+ if (!self.class.attribute_map.key?(k.to_sym))
65
+ fail ArgumentError, "`#{k}` is not a valid attribute in `OpenapiClient::PayslipResponseTaxes`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
66
+ end
67
+ h[k.to_sym] = v
68
+ }
69
+
70
+ if attributes.key?(:'name')
71
+ self.name = attributes[:'name']
72
+ end
73
+
74
+ if attributes.key?(:'amount')
75
+ self.amount = attributes[:'amount']
76
+ end
77
+
78
+ if attributes.key?(:'employer_tax')
79
+ self.employer_tax = attributes[:'employer_tax']
80
+ end
81
+ end
82
+
83
+ # Show invalid properties with the reasons. Usually used together with valid?
84
+ # @return Array for valid properties with the reasons
85
+ def list_invalid_properties
86
+ invalid_properties = Array.new
87
+ if @name.nil?
88
+ invalid_properties.push('invalid value for "name", name cannot be nil.')
89
+ end
90
+
91
+ if @amount.nil?
92
+ invalid_properties.push('invalid value for "amount", amount cannot be nil.')
93
+ end
94
+
95
+ invalid_properties
96
+ end
97
+
98
+ # Check to see if the all the properties in the model are valid
99
+ # @return true if the model is valid
100
+ def valid?
101
+ return false if @name.nil?
102
+ return false if @amount.nil?
103
+ true
104
+ end
105
+
106
+ # Checks equality by comparing each attribute.
107
+ # @param [Object] Object to be compared
108
+ def ==(o)
109
+ return true if self.equal?(o)
110
+ self.class == o.class &&
111
+ name == o.name &&
112
+ amount == o.amount &&
113
+ employer_tax == o.employer_tax
114
+ end
115
+
116
+ # @see the `==` method
117
+ # @param [Object] Object to be compared
118
+ def eql?(o)
119
+ self == o
120
+ end
121
+
122
+ # Calculates hash code according to all attributes.
123
+ # @return [Integer] Hash code
124
+ def hash
125
+ [name, amount, employer_tax].hash
126
+ end
127
+
128
+ # Builds the object from hash
129
+ # @param [Hash] attributes Model attributes in the form of hash
130
+ # @return [Object] Returns the model itself
131
+ def self.build_from_hash(attributes)
132
+ new.build_from_hash(attributes)
133
+ end
134
+
135
+ # Builds the object from hash
136
+ # @param [Hash] attributes Model attributes in the form of hash
137
+ # @return [Object] Returns the model itself
138
+ def build_from_hash(attributes)
139
+ return nil unless attributes.is_a?(Hash)
140
+ self.class.openapi_types.each_pair do |key, type|
141
+ if attributes[self.class.attribute_map[key]].nil? && self.class.openapi_nullable.include?(key)
142
+ self.send("#{key}=", nil)
143
+ elsif type =~ /\AArray<(.*)>/i
144
+ # check to ensure the input is an array given that the attribute
145
+ # is documented as an array but the input is not
146
+ if attributes[self.class.attribute_map[key]].is_a?(Array)
147
+ self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) })
148
+ end
149
+ elsif !attributes[self.class.attribute_map[key]].nil?
150
+ self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
151
+ end
152
+ end
153
+
154
+ self
155
+ end
156
+
157
+ # Deserializes the data based on type
158
+ # @param string type Data type
159
+ # @param string value Value to be deserialized
160
+ # @return [Object] Deserialized data
161
+ def _deserialize(type, value)
162
+ case type.to_sym
163
+ when :Time
164
+ Time.parse(value)
165
+ when :Date
166
+ Date.parse(value)
167
+ when :String
168
+ value.to_s
169
+ when :Integer
170
+ value.to_i
171
+ when :Float
172
+ value.to_f
173
+ when :Boolean
174
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
175
+ true
176
+ else
177
+ false
178
+ end
179
+ when :Object
180
+ # generic object (usually a Hash), return directly
181
+ value
182
+ when /\AArray<(?<inner_type>.+)>\z/
183
+ inner_type = Regexp.last_match[:inner_type]
184
+ value.map { |v| _deserialize(inner_type, v) }
185
+ when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
186
+ k_type = Regexp.last_match[:k_type]
187
+ v_type = Regexp.last_match[:v_type]
188
+ {}.tap do |hash|
189
+ value.each do |k, v|
190
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
191
+ end
192
+ end
193
+ else # model
194
+ # models (e.g. Pet) or oneOf
195
+ klass = OpenapiClient.const_get(type)
196
+ klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
197
+ end
198
+ end
199
+
200
+ # Returns the string representation of the object
201
+ # @return [String] String presentation of the object
202
+ def to_s
203
+ to_hash.to_s
204
+ end
205
+
206
+ # to_body is an alias to to_hash (backward compatibility)
207
+ # @return [Hash] Returns the object in the form of hash
208
+ def to_body
209
+ to_hash
210
+ end
211
+
212
+ # Returns the object in the form of hash
213
+ # @return [Hash] Returns the object in the form of hash
214
+ def to_hash
215
+ hash = {}
216
+ self.class.attribute_map.each_pair do |attr, param|
217
+ value = self.send(attr)
218
+ if value.nil?
219
+ is_nullable = self.class.openapi_nullable.include?(attr)
220
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
221
+ end
222
+
223
+ hash[param] = _to_hash(value)
224
+ end
225
+ hash
226
+ end
227
+
228
+ # Outputs non-array value in the form of hash
229
+ # For object, use to_hash. Otherwise, just return the value
230
+ # @param [Object] value Any valid value
231
+ # @return [Hash] Returns the value in the form of hash
232
+ def _to_hash(value)
233
+ if value.is_a?(Array)
234
+ value.compact.map { |v| _to_hash(v) }
235
+ elsif value.is_a?(Hash)
236
+ {}.tap do |hash|
237
+ value.each { |k, v| hash[k] = _to_hash(v) }
238
+ end
239
+ elsif value.respond_to? :to_hash
240
+ value.to_hash
241
+ else
242
+ value
243
+ end
244
+ end
245
+
246
+ end
247
+
248
+ end
@@ -0,0 +1,70 @@
1
+ =begin
2
+ #Affix API
3
+
4
+ #The affixapi.com API documentation. # Introduction Affix API is an OAuth 2.1 application that allows developers to access customer data, without developers needing to manage or maintain integrations; or collect login credentials or API keys from users for these third party systems. # OAuth 2.1 Affix API follows the [OAuth 2.1 spec](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-08). As an OAuth application, Affix API handles not only both the collection of sensitive user credentials or API keys, but also builds and maintains the integrations with the providers, so you don't have to. # How to obtain an access token in order to get started, you must: - register a `client_id` - direct your user to the sign in flow (`https://connect.affixapi.com` [with the appropriate query parameters](https://github.com/affixapi/starter-kit/tree/master/connect)) - capture `authorization_code` we will send to your redirect URI after the sign in flow is complete and exchange that `authorization_code` for a Bearer token # Sandbox keys (developer mode) ### dev ``` eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6ImQ1OTZhMmYzLWYzNzktNGE1ZC1hMmRhLTk4OWJmYWViYTg1ZCIsImlhdCI6MTcwMjkyMDkwMywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5kZXYuZW5naW5lZXJpbmcuYWZmaXhhcGkuY29tIiwic3ViIjoiZGV2ZWxvcGVyIiwiYXVkIjoiM0ZEQUVERjktMURDQTRGNTQtODc5NDlGNkEtNDEwMjc2NDMifQ.VLWYjCQvBS0C3ZA6_J3-U-idZj5EYI2IlDdTjAWBxSIHGufp6cqaVodKsF2BeIqcIeB3P0lW-KL9mY3xGd7ckQ ``` #### `employees` endpoint sample: ``` curl --fail \\ -X GET \\ -H 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6ImQ1OTZhMmYzLWYzNzktNGE1ZC1hMmRhLTk4OWJmYWViYTg1ZCIsImlhdCI6MTcwMjkyMDkwMywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5kZXYuZW5naW5lZXJpbmcuYWZmaXhhcGkuY29tIiwic3ViIjoiZGV2ZWxvcGVyIiwiYXVkIjoiM0ZEQUVERjktMURDQTRGNTQtODc5NDlGNkEtNDEwMjc2NDMifQ.VLWYjCQvBS0C3ZA6_J3-U-idZj5EYI2IlDdTjAWBxSIHGufp6cqaVodKsF2BeIqcIeB3P0lW-KL9mY3xGd7ckQ' \\ 'https://dev.api.affixapi.com/2023-03-01/developer/employees' ``` ### prod ``` eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6IjI5YjFjYTg4LWNlNjktNDgyZC1iNGZjLTkzMWMzZmJkYWM4ZSIsImlhdCI6MTcwMjkyMTA4MywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5wcm9kLmVuZ2luZWVyaW5nLmFmZml4YXBpLmNvbSIsInN1YiI6ImRldmVsb3BlciIsImF1ZCI6IjA4QkIwODFFLUQ5QUI0RDE0LThERjk5MjMzLTY2NjE1Q0U5In0.2zdpFAmiyYiYk6MOcbXNUwwR4M1Fextnaac340x54AidiWXCyw-u9KeavbqfYF6q8a9kcDLrxhJ8Wc_3tIzuVw ``` #### `employees` endpoint sample: ``` curl --fail \\ -X GET \\ -H 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6Ims5RmxwSFR1YklmZWNsUU5QRVZzeFcxazFZZ0Zfbk1BWllOSGVuOFQxdGciLCJ0eXAiOiJKV1MifQ.eyJwcm92aWRlciI6InNhbmRib3giLCJzY29wZXMiOlsiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2NvbXBhbnkiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWUiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvZW1wbG95ZWVzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL2lkZW50aXR5IiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3BheXJ1bnMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvcGF5cnVucy86cGF5cnVuX2lkIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWJhbGFuY2VzIiwiLzIwMjMtMDMtMDEvZGV2ZWxvcGVyL3RpbWUtb2ZmLWVudHJpZXMiLCIvMjAyMy0wMy0wMS9kZXZlbG9wZXIvdGltZXNoZWV0cyJdLCJ0b2tlbiI6IjI5YjFjYTg4LWNlNjktNDgyZC1iNGZjLTkzMWMzZmJkYWM4ZSIsImlhdCI6MTcwMjkyMTA4MywiaXNzIjoicHVibGljYXBpLWludGVybWVkaWF0ZS5wcm9kLmVuZ2luZWVyaW5nLmFmZml4YXBpLmNvbSIsInN1YiI6ImRldmVsb3BlciIsImF1ZCI6IjA4QkIwODFFLUQ5QUI0RDE0LThERjk5MjMzLTY2NjE1Q0U5In0.2zdpFAmiyYiYk6MOcbXNUwwR4M1Fextnaac340x54AidiWXCyw-u9KeavbqfYF6q8a9kcDLrxhJ8Wc_3tIzuVw' \\ 'https://api.affixapi.com/2023-03-01/developer/employees' ``` # Webhooks An exciting feature for HR/Payroll modes are webhooks. If enabled, your `webhook_uri` is set on your `client_id` for the respective environment: `dev | prod` Webhooks are configured to make live requests to the underlying integration 1x/hr, and if a difference is detected since the last request, we will send a request to your `webhook_uri` with this shape: ``` { added: <api.v20230301.Employees>[ <api.v20230301.Employee>{ ..., date_of_birth: '2010-08-06', display_full_name: 'Daija Rogahn', employee_number: '57993', employment_status: 'pending', employment_type: 'other', employments: [ { currency: 'eur', effective_date: '2022-02-25', employment_type: 'other', job_title: 'Dynamic Implementation Manager', pay_frequency: 'semimonthly', pay_period: 'YEAR', pay_rate: 96000, }, ], first_name: 'Daija', ... } ], removed: [], updated: [ <api.v20230301.Employee>{ ..., date_of_birth: '2009-11-09', display_full_name: 'Lourdes Stiedemann', employee_number: '63189', employment_status: 'leave', employment_type: 'full_time', employments: [ { currency: 'gbp', effective_date: '2023-01-16', employment_type: 'full_time', job_title: 'Forward Brand Planner', pay_frequency: 'semimonthly', pay_period: 'YEAR', pay_rate: 86000, }, ], first_name: 'Lourdes', } ] } ``` the following headers will be sent with webhook requests: ``` x-affix-api-signature: ab8474e609db95d5df3adc39ea3add7a7544bd215c5c520a30a650ae93a2fba7 x-affix-api-origin: webhooks-employees-webhook user-agent: affixapi.com ``` Before trusting the payload, you should sign the payload and verify the signature matches the signature sent by the `affixapi.com` service. This secures that the data sent to your `webhook_uri` is from the `affixapi.com` server. The signature is created by combining the signing secret (your `client_secret`) with the body of the request sent using a standard HMAC-SHA256 keyed hash. The signature can be created via: - create an `HMAC` with your `client_secret` - update the `HMAC` with the payload - get the hex digest -> this is the signature Sample `typescript` code that follows this recipe: ``` import { createHmac } from 'crypto'; export const computeSignature = ({ str, signingSecret, }: { signingSecret: string; str: string; }): string => { const hmac = createHmac('sha256', signingSecret); hmac.update(str); const signature = hmac.digest('hex'); return signature; }; ``` ## Rate limits Open endpoints (not gated by an API key) (applied at endpoint level): - 15 requests every 1 minute (by IP address) - 25 requests every 5 minutes (by IP address) Gated endpoints (require an API key) (applied at endpoint level): - 40 requests every 1 minute (by IP address) - 40 requests every 5 minutes (by `client_id`) Things to keep in mind: - Open endpoints (not gated by an API key) will likely be called by your users, not you, so rate limits generally would not apply to you. - As a developer, rate limits are applied at the endpoint granularity. - For example, say the rate limits below are 10 requests per minute by ip. from that same ip, within 1 minute, you get: - 10 requests per minute on `/orders`, - another 10 requests per minute on `/items`, - and another 10 requests per minute on `/identity`, - for a total of 30 requests per minute.
5
+
6
+ The version of the OpenAPI document: 2023-03-01
7
+ Contact: developers@affixapi.com
8
+ Generated by: https://openapi-generator.tech
9
+ OpenAPI Generator version: 5.1.1
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module OpenapiClient
17
+ class ProviderRequest
18
+ SANDBOX = "sandbox".freeze
19
+ BAMBOOHR = "bamboohr".freeze
20
+ BREATHE = "breathe".freeze
21
+ CEZANNE = "cezanne".freeze
22
+ CHARLIEHR = "charliehr".freeze
23
+ DEEL = "deel".freeze
24
+ DEPUTY = "deputy".freeze
25
+ HAILYHR = "hailyhr".freeze
26
+ HIBOB = "hibob".freeze
27
+ HUMAANS = "humaans".freeze
28
+ IRIS_CASCADE = "iris cascade".freeze
29
+ MOOREPAY = "moorepay".freeze
30
+ NMBRS = "nmbrs".freeze
31
+ PAROLLA_IE = "parolla.ie".freeze
32
+ PAYFIT = "payfit".freeze
33
+ PERSONIO_DE = "personio.de".freeze
34
+ PLANDAY = "planday".freeze
35
+ QUICKBOOKS_UK = "quickbooks uk".freeze
36
+ SAGEHR = "sagehr".freeze
37
+ SAPLINGHR = "saplinghr".freeze
38
+ STAFFOLOGY = "staffology".freeze
39
+ XERO_UK = "xero uk".freeze
40
+ BRAIN_PAYROLL = "brain payroll".freeze
41
+ BRIGHTPAY_CONNECT = "brightpay connect".freeze
42
+ EMPLOYMENT_HERO = "employment hero".freeze
43
+ FACTORIALHR = "factorialhr".freeze
44
+ FOURTHHR = "fourthhr".freeze
45
+ ITRENT = "itrent".freeze
46
+ OYSTERHR = "oysterhr".freeze
47
+ PAYCIRCLE = "paycircle".freeze
48
+ PENTO_IO = "pento.io".freeze
49
+ PEOPLEHR = "peoplehr".freeze
50
+ REMOTE_COM = "remote.com".freeze
51
+ SAGEONE = "sageone".freeze
52
+ SIMPLEPAY_IE = "simplepay.ie".freeze
53
+
54
+ # Builds the enum from string
55
+ # @param [String] The enum value in the form of the string
56
+ # @return [String] The enum value
57
+ def self.build_from_hash(value)
58
+ new.build_from_hash(value)
59
+ end
60
+
61
+ # Builds the enum from string
62
+ # @param [String] The enum value in the form of the string
63
+ # @return [String] The enum value
64
+ def build_from_hash(value)
65
+ constantValues = ProviderRequest.constants.select { |c| ProviderRequest::const_get(c) == value }
66
+ raise "Invalid ENUM value #{value} for class #ProviderRequest" if constantValues.empty?
67
+ value
68
+ end
69
+ end
70
+ end