dhis2 2.3.8 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. checksums.yaml +4 -4
  2. data/.github/PULL_REQUEST_TEMPLATE.md +11 -0
  3. data/Gemfile +2 -1
  4. data/README.md +208 -68
  5. data/Rakefile +4 -2
  6. data/bin/console +1 -0
  7. data/changelog.md +7 -0
  8. data/dhis2.gemspec +8 -8
  9. data/lib/dhis2/api/base.rb +5 -94
  10. data/lib/dhis2/api/bulk_creatable.rb +28 -0
  11. data/lib/dhis2/api/constants.rb +13 -0
  12. data/lib/dhis2/api/creatable.rb +47 -0
  13. data/lib/dhis2/api/deletable.rb +12 -0
  14. data/lib/dhis2/api/event_creation_status.rb +58 -0
  15. data/lib/dhis2/api/findable.rb +52 -0
  16. data/lib/dhis2/api/import_summary.rb +61 -0
  17. data/lib/dhis2/api/listable.rb +78 -0
  18. data/lib/dhis2/api/query_parameters_formatter.rb +50 -0
  19. data/lib/dhis2/api/shared/analytic.rb +20 -0
  20. data/lib/dhis2/api/shared/category_combo.rb +29 -0
  21. data/lib/dhis2/api/shared/category_option_combo.rb +23 -0
  22. data/lib/dhis2/api/shared/constants.rb +35 -0
  23. data/lib/dhis2/api/shared/data_element_group.rb +25 -0
  24. data/lib/dhis2/api/shared/data_set.rb +22 -0
  25. data/lib/dhis2/api/shared/data_value.rb +26 -0
  26. data/lib/dhis2/api/shared/data_value_set.rb +58 -0
  27. data/lib/dhis2/api/shared/event.rb +54 -0
  28. data/lib/dhis2/api/shared/organisation_unit.rb +17 -0
  29. data/lib/dhis2/api/shared/organisation_unit_group.rb +21 -0
  30. data/lib/dhis2/api/shared/report_tables.rb +32 -0
  31. data/lib/dhis2/api/shared/resource_table.rb +19 -0
  32. data/lib/dhis2/api/shared/save_validator.rb +47 -0
  33. data/lib/dhis2/api/shared/system_info.rb +19 -0
  34. data/lib/dhis2/api/updatable.rb +33 -0
  35. data/lib/dhis2/api/version224/analytic.rb +10 -0
  36. data/lib/dhis2/api/version224/attribute.rb +23 -0
  37. data/lib/dhis2/api/version224/category_combo.rb +25 -0
  38. data/lib/dhis2/api/version224/category_option_combo.rb +23 -0
  39. data/lib/dhis2/api/version224/constants.rb +22 -0
  40. data/lib/dhis2/api/version224/data_element.rb +45 -0
  41. data/lib/dhis2/api/version224/data_element_group.rb +22 -0
  42. data/lib/dhis2/api/version224/data_set.rb +53 -0
  43. data/lib/dhis2/api/version224/data_value.rb +11 -0
  44. data/lib/dhis2/api/version224/data_value_set.rb +25 -0
  45. data/lib/dhis2/api/version224/event.rb +31 -0
  46. data/lib/dhis2/api/version224/index.rb +27 -0
  47. data/lib/dhis2/api/version224/indicator.rb +24 -0
  48. data/lib/dhis2/api/version224/indicator_group.rb +20 -0
  49. data/lib/dhis2/api/version224/indicator_type.rb +20 -0
  50. data/lib/dhis2/api/version224/organisation_unit.rb +24 -0
  51. data/lib/dhis2/api/version224/organisation_unit_group.rb +22 -0
  52. data/lib/dhis2/api/version224/organisation_unit_group_set.rb +20 -0
  53. data/lib/dhis2/api/version224/organisation_unit_level.rb +21 -0
  54. data/lib/dhis2/api/version224/program.rb +26 -0
  55. data/lib/dhis2/api/version224/report.rb +20 -0
  56. data/lib/dhis2/api/version224/report_table.rb +21 -0
  57. data/lib/dhis2/api/version224/resource_table.rb +11 -0
  58. data/lib/dhis2/api/version224/save_validator.rb +48 -0
  59. data/lib/dhis2/api/version224/system_info.rb +11 -0
  60. data/lib/dhis2/api/version224/user.rb +15 -0
  61. data/lib/dhis2/api/version225/analytic.rb +10 -0
  62. data/lib/dhis2/api/version225/attribute.rb +23 -0
  63. data/lib/dhis2/api/version225/category_combo.rb +25 -0
  64. data/lib/dhis2/api/version225/category_option_combo.rb +23 -0
  65. data/lib/dhis2/api/version225/constants.rb +22 -0
  66. data/lib/dhis2/api/version225/data_element.rb +45 -0
  67. data/lib/dhis2/api/version225/data_element_group.rb +22 -0
  68. data/lib/dhis2/api/version225/data_set.rb +35 -0
  69. data/lib/dhis2/api/version225/data_value.rb +11 -0
  70. data/lib/dhis2/api/version225/data_value_set.rb +25 -0
  71. data/lib/dhis2/api/version225/event.rb +31 -0
  72. data/lib/dhis2/api/version225/index.rb +26 -0
  73. data/lib/dhis2/api/version225/indicator.rb +24 -0
  74. data/lib/dhis2/api/version225/indicator_group.rb +20 -0
  75. data/lib/dhis2/api/version225/indicator_type.rb +20 -0
  76. data/lib/dhis2/api/version225/organisation_unit.rb +24 -0
  77. data/lib/dhis2/api/version225/organisation_unit_group.rb +22 -0
  78. data/lib/dhis2/api/version225/organisation_unit_group_set.rb +20 -0
  79. data/lib/dhis2/api/version225/organisation_unit_level.rb +21 -0
  80. data/lib/dhis2/api/version225/program.rb +26 -0
  81. data/lib/dhis2/api/version225/report.rb +20 -0
  82. data/lib/dhis2/api/version225/report_table.rb +21 -0
  83. data/lib/dhis2/api/version225/resource_table.rb +11 -0
  84. data/lib/dhis2/api/version225/system_info.rb +11 -0
  85. data/lib/dhis2/api/version225/user.rb +15 -0
  86. data/lib/dhis2/api/version226/analytic.rb +10 -0
  87. data/lib/dhis2/api/version226/attribute.rb +23 -0
  88. data/lib/dhis2/api/version226/category_combo.rb +25 -0
  89. data/lib/dhis2/api/version226/category_option_combo.rb +23 -0
  90. data/lib/dhis2/api/version226/constants.rb +22 -0
  91. data/lib/dhis2/api/version226/data_element.rb +42 -0
  92. data/lib/dhis2/api/version226/data_element_group.rb +22 -0
  93. data/lib/dhis2/api/version226/data_set.rb +32 -0
  94. data/lib/dhis2/api/version226/data_value.rb +11 -0
  95. data/lib/dhis2/api/version226/data_value_set.rb +25 -0
  96. data/lib/dhis2/api/version226/event.rb +31 -0
  97. data/lib/dhis2/api/version226/index.rb +26 -0
  98. data/lib/dhis2/api/version226/indicator.rb +24 -0
  99. data/lib/dhis2/api/version226/indicator_group.rb +20 -0
  100. data/lib/dhis2/api/version226/indicator_type.rb +20 -0
  101. data/lib/dhis2/api/version226/organisation_unit.rb +24 -0
  102. data/lib/dhis2/api/version226/organisation_unit_group.rb +22 -0
  103. data/lib/dhis2/api/version226/organisation_unit_group_set.rb +20 -0
  104. data/lib/dhis2/api/version226/organisation_unit_level.rb +21 -0
  105. data/lib/dhis2/api/version226/program.rb +24 -0
  106. data/lib/dhis2/api/version226/report.rb +20 -0
  107. data/lib/dhis2/api/version226/report_table.rb +21 -0
  108. data/lib/dhis2/api/version226/resource_table.rb +11 -0
  109. data/lib/dhis2/api/version226/system_info.rb +11 -0
  110. data/lib/dhis2/api/version226/user.rb +15 -0
  111. data/lib/dhis2/api/version227/analytic.rb +10 -0
  112. data/lib/dhis2/api/version227/attribute.rb +23 -0
  113. data/lib/dhis2/api/version227/category_combo.rb +25 -0
  114. data/lib/dhis2/api/version227/category_option_combo.rb +23 -0
  115. data/lib/dhis2/api/version227/constants.rb +22 -0
  116. data/lib/dhis2/api/version227/data_element.rb +42 -0
  117. data/lib/dhis2/api/version227/data_element_group.rb +22 -0
  118. data/lib/dhis2/api/version227/data_set.rb +32 -0
  119. data/lib/dhis2/api/version227/data_value.rb +11 -0
  120. data/lib/dhis2/api/version227/data_value_set.rb +25 -0
  121. data/lib/dhis2/api/version227/event.rb +31 -0
  122. data/lib/dhis2/api/version227/index.rb +26 -0
  123. data/lib/dhis2/api/version227/indicator.rb +24 -0
  124. data/lib/dhis2/api/version227/indicator_group.rb +20 -0
  125. data/lib/dhis2/api/version227/indicator_type.rb +20 -0
  126. data/lib/dhis2/api/version227/organisation_unit.rb +24 -0
  127. data/lib/dhis2/api/version227/organisation_unit_group.rb +22 -0
  128. data/lib/dhis2/api/version227/organisation_unit_group_set.rb +20 -0
  129. data/lib/dhis2/api/version227/organisation_unit_level.rb +21 -0
  130. data/lib/dhis2/api/version227/program.rb +24 -0
  131. data/lib/dhis2/api/version227/report.rb +20 -0
  132. data/lib/dhis2/api/version227/report_table.rb +21 -0
  133. data/lib/dhis2/api/version227/resource_table.rb +11 -0
  134. data/lib/dhis2/api/version227/system_info.rb +11 -0
  135. data/lib/dhis2/api/version227/user.rb +15 -0
  136. data/lib/dhis2/api/version228/analytic.rb +10 -0
  137. data/lib/dhis2/api/version228/attribute.rb +23 -0
  138. data/lib/dhis2/api/version228/category_combo.rb +25 -0
  139. data/lib/dhis2/api/version228/category_option_combo.rb +23 -0
  140. data/lib/dhis2/api/version228/constants.rb +22 -0
  141. data/lib/dhis2/api/version228/data_element.rb +41 -0
  142. data/lib/dhis2/api/version228/data_element_group.rb +22 -0
  143. data/lib/dhis2/api/version228/data_set.rb +32 -0
  144. data/lib/dhis2/api/version228/data_value.rb +11 -0
  145. data/lib/dhis2/api/version228/data_value_set.rb +25 -0
  146. data/lib/dhis2/api/version228/event.rb +31 -0
  147. data/lib/dhis2/api/version228/index.rb +26 -0
  148. data/lib/dhis2/api/version228/indicator.rb +24 -0
  149. data/lib/dhis2/api/version228/indicator_group.rb +20 -0
  150. data/lib/dhis2/api/version228/indicator_type.rb +20 -0
  151. data/lib/dhis2/api/version228/organisation_unit.rb +24 -0
  152. data/lib/dhis2/api/version228/organisation_unit_group.rb +22 -0
  153. data/lib/dhis2/api/version228/organisation_unit_group_set.rb +20 -0
  154. data/lib/dhis2/api/version228/organisation_unit_level.rb +21 -0
  155. data/lib/dhis2/api/version228/program.rb +24 -0
  156. data/lib/dhis2/api/version228/report.rb +20 -0
  157. data/lib/dhis2/api/version228/report_table.rb +21 -0
  158. data/lib/dhis2/api/version228/resource_table.rb +11 -0
  159. data/lib/dhis2/api/version228/system_info.rb +11 -0
  160. data/lib/dhis2/api/version228/user.rb +15 -0
  161. data/lib/dhis2/case.rb +46 -0
  162. data/lib/dhis2/classes.rb +44 -0
  163. data/lib/dhis2/client.rb +152 -89
  164. data/lib/dhis2/collection_wrapper.rb +13 -3
  165. data/lib/dhis2/configuration.rb +55 -1
  166. data/lib/dhis2/error.rb +19 -0
  167. data/lib/dhis2/pager.rb +8 -3
  168. data/lib/dhis2/version.rb +1 -1
  169. data/lib/dhis2.rb +51 -42
  170. metadata +168 -50
  171. data/lib/dhis2/api/analytic.rb +0 -20
  172. data/lib/dhis2/api/attribute.rb +0 -8
  173. data/lib/dhis2/api/category_combo.rb +0 -28
  174. data/lib/dhis2/api/category_option_combo.rb +0 -8
  175. data/lib/dhis2/api/data_element.rb +0 -34
  176. data/lib/dhis2/api/data_element_group.rb +0 -32
  177. data/lib/dhis2/api/data_set.rb +0 -33
  178. data/lib/dhis2/api/data_value.rb +0 -15
  179. data/lib/dhis2/api/data_value_set.rb +0 -71
  180. data/lib/dhis2/api/event.rb +0 -36
  181. data/lib/dhis2/api/indicator.rb +0 -8
  182. data/lib/dhis2/api/indicator_group.rb +0 -8
  183. data/lib/dhis2/api/organisation_unit.rb +0 -66
  184. data/lib/dhis2/api/organisation_unit_group.rb +0 -38
  185. data/lib/dhis2/api/organisation_unit_group_set.rb +0 -6
  186. data/lib/dhis2/api/organisation_unit_level.rb +0 -8
  187. data/lib/dhis2/api/program.rb +0 -8
  188. data/lib/dhis2/api/report.rb +0 -8
  189. data/lib/dhis2/api/report_table.rb +0 -8
  190. data/lib/dhis2/api/resource_table.rb +0 -14
  191. data/lib/dhis2/api/system_info.rb +0 -13
  192. data/lib/dhis2/api/user.rb +0 -8
  193. data/lib/dhis2/import_error.rb +0 -6
  194. data/lib/dhis2/status.rb +0 -42
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31237affd866d0b4d8f2f3d206ee0f4e87fc0887
4
- data.tar.gz: 3342245ed20209d6cf8d14b43b6afd84c1a2195f
3
+ metadata.gz: bbd753676f45e7c6c2463428dae5bc1efd78ece2
4
+ data.tar.gz: f6fb3aba7601265b2671cecfb7f278f1d3635c2a
5
5
  SHA512:
6
- metadata.gz: 7b92380e27981c30c95779d27b2cfa9310280c29e672859428a638e7bd1f801ca27d4c1106d8ba3ae9cda577e7785f575d43c9dde777a725576cda4047100b39
7
- data.tar.gz: a0cd65724a439e6467aac2673bf21bc853cb1ebdc0d21ca3d2dafccb0a1be7c7db0e4a3719bf3372b2a98e814a318e842bc3c8746965f20b893c31a15305c8f3
6
+ metadata.gz: a319ce37b00057817630ddd0929e6abfaa711e71dddccdd6ac39e86326c0529860092fe12a93f8d28edef621ca732f52ad2336c1aa126a5c6daa5cd90c614bd4
7
+ data.tar.gz: cc02f664d800aa80ce1768336614dc2d2ca6fced9151118c823d2f3d3c43ba51ea17829f3db729f49726395da592df1ebdf5ac2eece873f21ed6ab0d129f2b3c
@@ -0,0 +1,11 @@
1
+ ## Self proof reading checklist
2
+
3
+ - [ ] Did I run Pronto and fixed all warnings
4
+ - [ ] Make sure all naming and code will remain understandable in 6 month by someone new to the project or by you.
5
+ - [ ] Did I test the right thing?
6
+ - [ ] Did I test corner cases, non happy path (defensive testing)?
7
+ - [ ] Check that I used the ad-hoc patterns and created files accordingly (Presenters, Services, Search object, Form object,...)
8
+ - [ ] Check code efficiency with record intensive project (eg: DRC)
9
+ - [ ] Update documentation,readme accordingly
10
+
11
+ Thanks!
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
- source 'https://rubygems.org'
1
+ # frozen_string_literal: true
2
+ source "https://rubygems.org"
2
3
 
3
4
  # Specify your gem's dependencies in dhis2.gemspec
4
5
  gemspec
data/README.md CHANGED
@@ -32,102 +32,189 @@ The functionalities are available as a module. First thing you need to do is to
32
32
 
33
33
  * Global configuration (to call a single Dhis2 instance):
34
34
 
35
- ```ruby
36
- Dhis2.configure do |config|
37
- config.url = "https://play.dhis2.org/demo"
38
- config.user = "admin"
39
- config.password = "district"
40
- end
41
- Dhis2.client.data_elements.list # => Array[<DataElement>,..]
42
-
43
- # Or alternatively
44
- Dhis2.configure do |config|
45
- config.url = "https://admin:district@play.dhis2.org/demo"
46
- end
47
- Dhis2.client.data_elements.list # => Array[<DataElement>,..]
48
- ```
35
+ ```ruby
36
+ Dhis2.configure do |config|
37
+ config.url = "https://play.dhis2.org/2.28"
38
+ config.user = "admin"
39
+ config.password = "district"
40
+ config.version = "2.28"
41
+ end
42
+ ::Dhis2.client.data_elements.list # => Array[<DataElement>,..]
43
+
44
+ # Or alternatively
45
+ ::Dhis2.configure do |config|
46
+ url: "https://admin:district@play.dhis2.org/2.28",
47
+ version: "2.28"
48
+ )
49
+ ::Dhis2.clientt.data_elements.list # => Array[<DataElement>,..]
50
+ ```
49
51
 
50
52
  * Local configuration: (in case you need to access different Dhis2 instances inside a single project):
51
53
 
52
- ```ruby
53
- client = Dhis2::Client.new(url: "https://play.dhis2.org/demo", user: "admin", password: "district")
54
- client.data_elements.list # => Array[<DataElement>,..]
55
-
56
- # Or alternatively
57
- client = Dhis2::Client.new("https://admin:district@play.dhis2.org/demo")
58
- client.data_elements.list # => Array[<DataElement>,..]
59
- ```
54
+ ```ruby
55
+ configuration = Dhis2::Configuration.new.tap do |config|
56
+ config.url = "https://play.dhis2.org/2.28"
57
+ config.user = "admin"
58
+ config.password = "district"
59
+ config.version = "2.28"
60
+ end
61
+ client = ::Dhis2::Client.new(configuration.client_params)
62
+ client.data_elements.list # => Array[<DataElement>,..]
63
+
64
+ # Or alternatively
65
+ client = ::Dhis2::Client.new(
66
+ url: "https://admin:district@play.dhis2.org/2.28",
67
+ version: "2.28"
68
+ )
69
+ client.data_elements.list # => Array[<DataElement>,..]
70
+ ```
60
71
 
61
72
  Regarding SSL, there is an option to disregard SSL error messages (such as bad certificates). USE THIS AT YOUR OWN RISK - it may allow you to access a server that would return in error without it... but you cannot trust the response.
62
73
 
63
74
  ```ruby
64
- dangerous_client = Dhis2::Client.new(url: "https://play.dhis2.org/demo", user: "admin", password: "district", no_ssl_verification: true);
75
+ dangerous_configuration = Dhis2::Configuration.new.tap do |config|
76
+ config.url = "https://play.dhis2.org/2.28"
77
+ config.user = "admin"
78
+ config.password = "district"
79
+ config.version = "2.28"
80
+ config.no_ssl_verification = true
81
+ end
82
+ ```
83
+
84
+ * Not sure of your version? Check it
85
+
86
+ ```ruby
87
+ Dhis2.get_version({ user: 'admin', password: 'district', url: 'https://play.dhis2.org/demo'})
65
88
  ```
66
89
 
90
+
67
91
  ### Search for meta elements
68
92
 
69
93
  All subsequent calls can be done on the objects themselves and are going to use the provided url and credentials
70
94
 
71
- org_unit_levels = Dhis2.client.organisation_unit_levels.list
95
+ ```ruby
96
+ org_unit_levels = Dhis2.client.organisation_unit_levels.list
97
+ ```
72
98
 
73
99
  The various methods are taking an optional hash parameter to be used for ´filter´ and ´fields´ values:
74
100
 
75
- org_units = Dhis2.client.organisation_units.list(filter: "level:eq:2", fields: %w(id level displayName parent))
101
+ ```ruby
102
+ org_units = Dhis2.client.organisation_units.list(filter: "level:eq:2", fields: %w(id level displayName parent))
103
+ ```
76
104
 
77
105
  If you want all fields, simply specify `:all`
78
106
 
79
- org_units = Dhis2.client.organisation_units.list(filter: "level:eq:2", fields: :all)
107
+ ```ruby
108
+ org_units = Dhis2.client.organisation_units.list(filter: "level:eq:2", fields: :all)
109
+ ```
80
110
 
81
111
  Notes that any field found in the resulting JSON will be accessible from the object.
82
112
 
113
+ ### Raw data
114
+
115
+ By default, the gem transforms data from the api so you get underscore case. But this may not be needed and can hurt performance.
116
+
117
+ If you simply need raw data from your Dhis2:
118
+
119
+ ```ruby
120
+ org_units = Dhis2.client.organisation_units.list({}, true)
121
+ ```
122
+
83
123
  ### Pagination
84
124
 
85
125
  Following the DHIS2 API, all calls are paginated - you can access the page info using the `pager` property on the returned list:
86
126
 
87
- org_units = Dhis2.client.organisation_units.list(filter: "level:eq:2", fields: %w(id level displayName parent))
88
- org_units.pager.page # current page
89
- org_units.pager.page_count # number of pages
90
- org_units.pager.total # number of records
127
+ ```ruby
128
+ org_units = Dhis2.client.organisation_units.list(filter: "level:eq:2", fields: %w(id level displayName parent))
129
+ org_units.pager.page # current page
130
+ org_units.pager.page_count # number of pages
131
+ org_units.pager.total # number of records
132
+ ```
133
+
134
+ ### Get all paginated elements
135
+
136
+ It can be tedious to iterate over a paginated collection. Thus you can use `fetch_paginated_data` which will get all pages for you and yield each element automatically.
137
+
138
+ ```ruby
139
+ Dhis2.client.organisation_units.fetch_paginated_data(
140
+ filter: "level:eq:2",
141
+ fields: %w(id level displayName parent)
142
+ ).each do |organisation_unit, pager|
143
+ # do what you need here
144
+ end
145
+
146
+ # If you want pagination info in the loop:
147
+ Dhis2.client.organisation_units.fetch_paginated_data({
148
+ filter: "level:eq:2",
149
+ fields: %w(id level displayName parent)
150
+ },
151
+ { with_pager: true}
152
+ ).each do |organisation_unit, pager|
153
+ # do what you need here
154
+ end
155
+
156
+ # Dhis2.client.organisation_units.fetch_paginated_data is an Enumerable. If you want all objects in an array, without pager:
157
+ Dhis2.client.organisation_units.fetch_paginated_data.to_a
91
158
 
92
159
  ### Retrieve a single element
93
160
 
94
161
  You can also retreive a single element using its id with `find`(in this case, all fields are returned by default):
95
162
 
96
- ou = Dhis2.client.organisation_units.find(id)
163
+ ```ruby
164
+ ou = Dhis2.client.organisation_units.find(id)
165
+ ```
97
166
 
98
167
  `find` also accepts multiple ids - query will not be paginated and will return all fields for the given objects:
99
168
 
100
- ous = Dhis2.client.organisation_units.find([id1, id2, id3])
169
+ ```ruby
170
+ ous = Dhis2.client.organisation_units.find([id1, id2, id3])
171
+ ```
172
+
173
+ An issue could arise if you try to get too many elements at once.
174
+
175
+ ```ruby
176
+ ous = Dhis2.client.organisation_units.find(super_long_array)
177
+ #=> would raise an exception because the generated url would be too long
178
+
179
+ # instead do
180
+ ous = Dhis2.client.organisation_units.find_paginated(super_long_array)
181
+ ```
101
182
 
102
183
  If you have an equality condition or set of equality conditions that should return a single element, you can use `find_by` instead of the longer list option:
103
184
 
104
- # Instead of this:
105
- data_element = Dhis2.client.data_elements.list(filter: "code:eq:C27", fields: :all).first
185
+ ```ruby
186
+ # Instead of this:
187
+ data_element = Dhis2.client.data_elements.list(filter: "code:eq:C27", fields: :all).first
106
188
 
107
- # Just do:
108
- data_element = Dhis2.client.data_elements.find_by(code: "C27")
189
+ # Just do:
190
+ data_element = Dhis2.client.data_elements.find_by(code: "C27")
191
+ ```
109
192
 
110
193
  ### Manage relations
111
194
 
112
195
  You can add or remove items in collections using `add_relation` and `remove_relation`:
113
196
 
114
- data_set = Dhis2.client.data_sets.list(page_size:1).first
115
- data_element = Dhis2.client.data_elements.list(page_size: 1).first
116
- data_set.add_relation(:dataSetElements, data_element.id)
117
- ...
118
- data_set.remove_relation(:dataSetElements, data_element.id)
197
+ ```ruby
198
+ data_set = Dhis2.client.data_sets.list(page_size:1).first
199
+ data_element = Dhis2.client.data_elements.list(page_size: 1).first
200
+ data_set.add_relation(:dataSetElements, data_element.id)
201
+ ...
202
+ data_set.remove_relation(:dataSetElements, data_element.id)
203
+ ```
119
204
 
120
205
  ### Values
121
206
 
122
207
  You can retreive data values this way:
123
208
 
124
- ds = Dhis2.client.data_sets.find_by(name: "Child Health")
125
- organisation_unit = Dhis2.client.organisation_units.find_by(name: "Baoma")
126
- period = "201512"
127
- value_sets = Dhis2.client.data_value_sets.list(
128
- data_sets: [ds.id],
129
- organisation_unit: organisation_unit.id, periods: [period]
130
- )
209
+ ```ruby
210
+ ds = Dhis2.client.data_sets.find_by(name: "Child Health")
211
+ organisation_unit = Dhis2.client.organisation_units.find_by(name: "Baoma")
212
+ period = "201512"
213
+ value_sets = Dhis2.client.data_value_sets.list(
214
+ data_sets: [ds.id],
215
+ organisation_unit: organisation_unit.id, periods: [period]
216
+ )
217
+ ```
131
218
 
132
219
  ## Supported items
133
220
 
@@ -161,9 +248,11 @@ The API is currently limited to actions on the following elements:
161
248
 
162
249
  You can update a given item by retreiving it using its id, making any modification on it then calling "update":
163
250
 
164
- org_unit = Dhis2.client.organisation_units.find(id)
165
- org_unit.short_name = "New Short Name"
166
- org_unit.update
251
+ ```ruby
252
+ org_unit = Dhis2.client.organisation_units.find(id)
253
+ org_unit.short_name = "New Short Name"
254
+ org_unit.update
255
+ ```
167
256
 
168
257
  This uses DHIS2 "full update" ('PUT') and not the "partial update" feature (see below), so it requires a fully formed object to work (get it either with `find` which takes all the fields or with the `fields: :all´ option).
169
258
 
@@ -171,32 +260,58 @@ This uses DHIS2 "full update" ('PUT') and not the "partial update" feature (see
171
260
 
172
261
  You can update a single or more attributes via the "update_attributes" method:
173
262
 
174
- org_unit = Dhis2.client.organisation_units.list(fields: :all, filter: "name:eq:#{org_unit_name}").first
175
- new_attributes = { name: "New name" }
176
- org_unit.update_attributes(new_attributes)
263
+ ```ruby
264
+ org_unit = Dhis2.client.organisation_units.list(fields: :all, filter: "name:eq:#{org_unit_name}").first
265
+ new_attributes = { name: "New name" }
266
+ org_unit.update_attributes(new_attributes)
267
+ ```
177
268
 
178
269
  Note that partial updates will no work with custom attributes at this time (while the full update will)
179
270
 
180
271
  ## Create
181
272
 
182
- A very basic **write** use case exists for `DataElement` and `DataSet`:
273
+ A very basic **write** use case exists for `DataElement`:
274
+
275
+ ```ruby
276
+ data_element = Dhis2.client.data_elements.create({
277
+ name: "TesTesT1",
278
+ short_name: "TTT1"
279
+ })
280
+ ```
281
+
282
+ We do validate arguments and the response status. `Dhis2::CreationError` exception is raised in case of error.
283
+
284
+ ### Bulk create
183
285
 
184
- elements = [
185
- { name: "TesTesT1", short_name: "TTT1" },
186
- { name: "TesTesT2", short_name: "TTT2" }
187
- ]
188
- status = Dhis2.client.data_elements.create(elements)
189
- status.success? # => true
190
- status.total_imported # => 2
286
+ Whenever you need to create many elements at the same time, you can use `bulk_create`:
191
287
 
192
- DHIS2 API does not return the ids of the created elements, but you can retreive them with their (unique) name or code.
288
+ ```ruby
289
+ elements = [
290
+ { name: "TesTesT1", short_name: "TTT1" },
291
+ { name: "TesTesT2", short_name: "TTT2" }
292
+ ]
293
+ summary = Dhis2.client.data_elements.bulk_create(elements)
294
+ # would raise Dhis2::BulkCreationError on error
295
+ summary.imported_count # => 1
296
+ summary.updated_count # => 1
297
+ summary.ignored_count # => 0
298
+ ```
299
+
300
+ ### Raw input
193
301
 
194
- elements = [
195
- { name: "TesTesT2", short_name: "TTT2" }
196
- ]
197
- status = Dhis2.client.data_elements.create(elements)
198
- element = Dhis2.client.data_elements.find_by(name: "TesTesT2")
302
+ You might have data in camel case already and need to use it as is. In this case, we do not validate your input and do not create an object out of the response. Yet we validate the object has been properly created and return the plain response from the API.
199
303
 
304
+ ```ruby
305
+ response = Dhis2.client.data_elements.create({
306
+ name: "TesTesT1",
307
+ shortName: "TTT1"
308
+ }, true)
309
+
310
+ summary = Dhis2.client.data_elements.bulk_create([{
311
+ name: "TesTesT1",
312
+ shortName: "TTT1"
313
+ }], true)
314
+ ```
200
315
 
201
316
  ## Trigger analytics
202
317
 
@@ -204,6 +319,31 @@ You can trigger Analytics with
204
319
 
205
320
  Dhis2.client.resource_tables.analytics
206
321
 
322
+ ## Raw output
323
+
324
+ To get raw data from Dhis2, ie no underscore case, no object, just plain json, you can specify you want the raw output:
325
+
326
+ ```ruby
327
+ client.data_elements.list({}, true)
328
+ #returns a PaginatedArray which elements look like:
329
+ {"id"=>"FTRrcoaog83", "displayName"=>"Accute Flaccid Paralysis (Deaths < 5 yrs)"}
330
+
331
+ client.data_elements.fetch_paginated_data({}, { raw: true }) do |data_element|
332
+ # use data_element as hash
333
+ end
334
+ ```
335
+
336
+ ## Instantiating objects
337
+
338
+ It can be tedious to manually type `Dhis2::Api::Version228::DataElement` (or any other class) and adapt it for each version number.
339
+
340
+ There is a convenient method to get it directly:
341
+
342
+ ```ruby
343
+ Dhis2::DataElement["2.28"]
344
+ #=> Dhis2::Api::Version228::DataElement
345
+ ```
346
+
207
347
  ## Development
208
348
 
209
349
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake test` and `bundle exec rspec` to run the tests. Note that the tests are using the DHIS2 demo server, which is reset every day but can be updated by anyone - so if someone change the password of the default user, the tests are going to fail.
data/Rakefile CHANGED
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rake/testtask"
3
5
 
4
6
  Rake::TestTask.new(:test) do |t|
5
7
  t.libs << "test"
6
8
  t.libs << "lib"
7
- t.test_files = FileList['test/**/*_test.rb']
9
+ t.test_files = FileList["test/**/*_test.rb"]
8
10
  end
9
11
 
10
- task :default => :test
12
+ task default: :test
data/bin/console CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
  require "dhis2"
data/changelog.md ADDED
@@ -0,0 +1,7 @@
1
+ # Version 3
2
+ - passing version is mandatory: we use dedicated classes for each Dhis2 versions. This lets us adapt validations, constants and methods.
3
+ - we can get raw json from Dhis2 (skip class instantiation and case change)
4
+ - we can send raw json to Dhis2 (skip case change and validations)
5
+ - to complement `list`, `fetch_paginated_data` iterates over all elements requesting each page if necessary
6
+ - `root_junction` is now an allowed query param
7
+ - fixtures contain payload from versions 2.24 to 2.28 to help you check what data is received
data/dhis2.gemspec CHANGED
@@ -1,7 +1,8 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+ # frozen_string_literal: true
3
+ lib = File.expand_path("../lib", __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'dhis2/version'
5
+ require "dhis2/version"
5
6
 
6
7
  Gem::Specification.new do |spec|
7
8
  spec.name = "dhis2"
@@ -9,8 +10,8 @@ Gem::Specification.new do |spec|
9
10
  spec.authors = ["Martin Van Aken"]
10
11
  spec.email = ["mvanaken@bluesquare.org"]
11
12
 
12
- spec.summary = %q{Simple Ruby wrapper on DHIS2 API.}
13
- spec.description = %q{Allows to retreive items from a DHIS2 server in a more "Ruby way".}
13
+ spec.summary = "Simple Ruby wrapper on DHIS2 API."
14
+ spec.description = 'Allows to retreive items from a DHIS2 server in a more "Ruby way".'
14
15
  spec.homepage = "http://github.com/blsq/dhis2"
15
16
  spec.license = "MIT"
16
17
 
@@ -19,17 +20,16 @@ Gem::Specification.new do |spec|
19
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
21
  spec.require_paths = ["lib"]
21
22
 
22
- spec.add_dependency 'rest-client'
23
+ spec.add_dependency "rest-client"
24
+ spec.add_dependency "dry-validation", "0.11.1"
23
25
 
24
- spec.add_development_dependency "bundler", "~> 1.12"
25
- spec.add_development_dependency "rake", "~> 10.0"
26
26
  spec.add_development_dependency "minitest", "~> 5.0"
27
27
  spec.add_development_dependency "minitest-reporters"
28
28
  spec.add_development_dependency "faker", "~> 1.6", ">= 1.6.3"
29
29
  spec.add_development_dependency "byebug"
30
30
 
31
31
  spec.add_development_dependency "rspec"
32
- spec.add_development_dependency "webmock"
32
+ spec.add_development_dependency "webmock", "3.1.0"
33
33
  spec.add_development_dependency "simplecov"
34
34
  spec.add_development_dependency "rest-client-logger"
35
35
  end
@@ -4,118 +4,29 @@ module Dhis2
4
4
  module Api
5
5
  class Base < OpenStruct
6
6
  class << self
7
- def inherited(base)
8
- Dhis2::Client.register_resource(base)
9
- end
10
-
11
- def find(client, id, options = {})
12
- raise "Missing id" if id.nil?
13
-
14
- if id.class == Array
15
- list(client, filter: "id:in:[#{id.join(',')}]", fields: :all, page_size: id.size)
16
- elsif options.any?
17
- params = []
18
- options.each do |name, value|
19
- params << [name, value]
20
- end
21
- params = client.class.deep_change_case(params, :camelize)
22
- json_response = client.get("#{resource_name}/#{id}", RestClient::ParamsArray.new(params))
23
- new(client, json_response)
24
- else
25
- response = client.get("#{resource_name}/#{id}")
26
- new(client, response)
27
- end
28
- end
29
-
30
- def find_by(client, clauses)
31
- filter = []
32
- clauses.each do |field, value|
33
- filter << "#{field}:eq:#{value}"
34
- end
35
- list(client, fields: :all, filter: filter).first
36
- end
37
-
38
- def list(client, options = {})
39
- json_response = client.get(resource_name, format_query_parameters(options))
40
- resource_key = client.class.underscore(resource_name)
41
- PaginatedArray.new(
42
- json_response[resource_key].map { |raw_resource| new(client, raw_resource) },
43
- json_response["pager"]
44
- )
7
+ def resource_key
8
+ Dhis2::Case.underscore(resource_name)
45
9
  end
46
10
 
47
11
  def resource_name
48
12
  simple_name = name.split("::").last
49
13
  simple_name[0].downcase + simple_name[1..-1] + "s"
50
14
  end
51
-
52
- def format_query_parameters(options)
53
- params = []
54
- params.push([:page, options[:page]]) if options[:page]
55
- params.push([:pageSize, options[:page_size]]) if options[:page_size]
56
- params.push([:fields, format_fields(options[:fields])]) if options[:fields]
57
- params.concat(format_filter(options[:filter])) if options[:filter]
58
-
59
- RestClient::ParamsArray.new(params)
60
- end
61
-
62
- def format_fields(fields)
63
- if fields.respond_to?(:join)
64
- fields.join(",")
65
- elsif fields == :all
66
- ":all"
67
- else
68
- fields
69
- end
70
- end
71
-
72
- def format_filter(filter)
73
- if filter.respond_to?(:map)
74
- filter.map do |subfilter|
75
- [:filter, subfilter]
76
- end
77
- else
78
- [[:filter, filter]]
79
- end
80
- end
81
15
  end
82
16
 
83
17
  def initialize(client, raw_data)
84
- raw_data["display_name"] ||= raw_data["name"] # for backward compatbility with v2.19
85
18
  super(raw_data)
86
- self.client = client
87
- end
88
-
89
- def update_attributes(attributes)
90
- client.patch("#{self.class.resource_name}/#{id}", attributes)
91
- attributes.each do |key, value|
92
- self[key] = value
93
- end
94
- self
95
- end
96
-
97
- def add_relation(relation, relation_id)
98
- client.post("#{self.class.resource_name}/#{id}/#{relation}/#{relation_id}", {})
99
- self
100
- end
101
19
 
102
- def remove_relation(relation, relation_id)
103
- client.delete("#{self.class.resource_name}/#{id}/#{relation}/#{relation_id}", {})
104
- self
20
+ self.client = client
105
21
  end
106
22
 
107
- def delete
108
- client.delete("#{self.class.resource_name}/#{id}")
109
- true
23
+ def to_h
24
+ super.tap {|h| h.delete(:client) }
110
25
  end
111
26
 
112
27
  def ==(other)
113
28
  self.class == other.class && id == other.id
114
29
  end
115
-
116
- def update
117
- client.put("#{self.class.resource_name}/#{id}", to_h)
118
- end
119
30
  end
120
31
  end
121
32
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dhis2
4
+ module Api
5
+ module BulkCreatable
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ BulkCreationStatusClass = ::Dhis2::Api::ImportSummary
13
+
14
+ # args is a hash like: { data_element_groups: [{ name: "foo" }, { name: "bar" }] }
15
+ def bulk_create(client, args, raw_input = false)
16
+ response = client.post(path: "metadata", payload: args, raw_input: raw_input)
17
+ self::BulkCreationStatusClass.new(response).tap do |summary|
18
+ unless summary.bulk_success?
19
+ exception = Dhis2::BulkCreationError.new("Didnt create bulk of data properly.\n Response: #{response.to_json}")
20
+ exception.import_summary = summary
21
+ raise exception
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dhis2
4
+ module Api
5
+ module Constants
6
+ DATA_DIMENSION_TYPES = %w(ATTRIBUTE DISAGGREGATION).freeze
7
+ DOMAIN_TYPES = %w(TRACKER AGGREGATE).freeze
8
+ FEATURE_TYPES = %w(SYMBOL POLYGON MULTI_POLYGON NONE POINT).freeze
9
+ PERIOD_TYPES = %w(Daily Weekly Monthly BiMonthly Quarterly SixMonthly Yearly).freeze
10
+ PROGRAM_TYPES = %w(WITHOUT_REGISTRATION WITH_REGISTRATION).freeze
11
+ end
12
+ end
13
+ end