sk_api_schema 0.0.18 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,26 @@
1
+ = Changelog for SalesKing API Schema
2
+
3
+ A more detailed view of the changes can be found in the {commit messages}[https://github.com/salesking/sk_api_schema/commits/]
4
+
5
+ 2011-04
6
+ * added tags
7
+ * added documents
8
+ * reduced default objects in list to 10, max is 100
9
+ * added field parameter to limit returned fields in ruby to_hash_from_schema & SK
10
+ * added created_at & number filtering to client
11
+ * added _delete field to line_item & address, to be able to destroy them since both are transfered within their parent object
12
+
13
+ 2011-03
14
+ * added subscriptions
15
+ * added memoizing to ruby schema reader
16
+
17
+ 2011-02
18
+ * added moneybookers, premium_sms to payment methods
19
+ * added auth_permission
20
+ * added external_ref to documents
21
+ * added company
22
+ * added recurring
23
+ * added source param to copy documents
24
+
25
+ 2010-11 - 2011-01
26
+ * initial version
data/README.rdoc CHANGED
@@ -1,23 +1,28 @@
1
- = SalesKing Api Schema
1
+ = SalesKing API Schema
2
2
 
3
- SalesKing API description using JSON Schema(http://json-schema.org/). A schema
4
- describes the resource in terms of available fields, CRUD actions and
3
+ Our API definition is using JSON Schema(http://json-schema.org/). A schema
4
+ describes a resource in terms of available fields, CRUD actions and
5
5
  relationships with other resources.
6
6
 
7
7
  For ruby users this project provides a gem with some basic utility functions
8
- besides the schema. Other languages can take advantage of the raw json files.
8
+ besides the schema. Other languages should take advantage of the raw json files.
9
9
 
10
10
  == Tutorial & Docs
11
11
 
12
- http://dev.blog.salesking.eu/api/
12
+ * API Browser visualized JSON Schema - http://sk-api-browser.heroku.com/
13
+ * API Intro - http://dev.blog.salesking.eu/api/
13
14
 
14
15
  == Versioning
15
16
 
16
- The API-version is kept in the folder-name and as long as there are no major
17
+ The main API-version is kept in the folder-name and as long as there are no major
17
18
  changes(breaking backwards compatibility), the version number will remain.
18
19
 
19
20
  The gem has its own version number. It is used by SalesKing to deliver it's
20
- resources BUT changes might not be directly reflected.
21
+ resources BUT changes might not be directly reflected. To see what version of
22
+ the gem we are using go to:
23
+
24
+ my.salesking.eu/api/schema?gem_version=1
25
+
21
26
  A new gem version indicates a change, but we first try it on our staging environment
22
27
  before any live instances are updated and the schema becomes public available.
23
28
 
@@ -25,9 +30,19 @@ You can get the current schema at your SalesKing api url:
25
30
  my.salesking.eu/api/schema
26
31
  my.salesking.eu/api/clients/schema
27
32
 
28
- The version to use can be set with the "v" url parameter:
33
+ The schema version(NOT the gem version) can be set with the "v" url parameter
34
+ in any call, but is pretty useless as long as we are in v1.0
29
35
  my.salesking.eu/api/clients?v='1.0'
30
36
 
37
+ == Save the planet
38
+
39
+ By default the api returns an object with all available properties(fields). You
40
+ can limit those by passing an array or comma-separated string in the fields
41
+ parameter:
42
+ my.salesking.eu/api/clients?fields=id,organisation
43
+ my.salesking.eu/api/clients?fields[]=id&fields[]=organisation
44
+
45
+ Please try to only request the fields you really need, to save computing power!
31
46
 
32
47
  == Notice:
33
48
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.18
1
+ 0.1.0
@@ -40,7 +40,8 @@
40
40
  "created_at": {
41
41
  "description": "Date the object was created in SK. Never changes afterwards",
42
42
  "format":"date-time",
43
- "readonly":true, "type":"string"
43
+ "readonly":true,
44
+ "type":"string"
44
45
  },
45
46
  "updated_at": {
46
47
  "description": "Date the object was edited in SK.",
@@ -60,6 +61,10 @@
60
61
  "long": {
61
62
  "description": "Geolocation longitude",
62
63
  "type":"string"
64
+ },
65
+ "_delete": {
66
+ "description": "When set an existing address will be deleted. This switch is only used when addresses are passed-in nested inside their parent object(a contact).",
67
+ "type":"boolean"
63
68
  }
64
69
  }
65
70
  }
@@ -23,6 +23,16 @@
23
23
  "readonly":true,
24
24
  "type":"string"
25
25
  },
26
+ "related_object_type": {
27
+ "description": "Object type of the attachment parent. Is the camelcased base class name: Document for invoice, credit_note,.., Contact for client",
28
+ "required":true,
29
+ "type":"string"
30
+ },
31
+ "related_object_id": {
32
+ "description": "uuid of the attachment parent object.",
33
+ "required":true,
34
+ "type":"string"
35
+ },
26
36
  "content_type": {
27
37
  "description": "Auto detected on upload. Might not always reflect the real content type",
28
38
  "readonly":true,
@@ -43,16 +53,60 @@
43
53
  "readonly":true,
44
54
  "type":"string"
45
55
  },
46
- "updated_at": {
47
- "description": "Date the object was edited in SK.",
48
- "format":"date-time",
49
- "readonly":true,
50
- "type":"string"
51
- },
52
56
  "team_id":{
53
57
  "description": "A team uuid. If set only the team and its parent teams can see the record.",
54
58
  "type":"string"
55
59
  }
56
60
 
57
- }
61
+ },
62
+ "links":[
63
+ { "rel": "self",
64
+ "href": "attachments/{id}"
65
+ },
66
+ { "rel": "instances",
67
+ "href": "attachments",
68
+ "properties" : {
69
+ "page":{
70
+ "title" : "Page",
71
+ "description": "In paginated results set the page to look for",
72
+ "type":"number"
73
+ },
74
+ "per_page":{
75
+ "title" : "Per page",
76
+ "description": "Results per page. Default is 10, max is 100",
77
+ "type":"number"
78
+ },
79
+ "filter[q]":{
80
+ "title" : "Search",
81
+ "description": "Search in filename",
82
+ "type":"string"
83
+ },
84
+ "filter[from]":{
85
+ "title" : "From date",
86
+ "description": "All objects created at and after the date",
87
+ "type" : "date"
88
+ },
89
+ "filter[to]":{
90
+ "title" : "To date",
91
+ "description": "All objects created at and before the date",
92
+ "type" : "date"
93
+ },
94
+ "sort_by":{
95
+ "title" : "Sort by",
96
+ "description": "Sort the results by the given field",
97
+ "enum":["filename","related_object_id","related_object_type", "created_at"],
98
+ "type": "string"
99
+ },
100
+ "sort":{
101
+ "title" : "Sort",
102
+ "enum":["ASC","DESC"],
103
+ "description": "Sort the results in ASC or DESC"
104
+ }
105
+ }
106
+ },
107
+ { "rel": "destroy",
108
+ "href": "attachments/{id}",
109
+ "method": "DELETE"
110
+ }
111
+ ]
58
112
  }
@@ -36,6 +36,11 @@
36
36
  "description": "In paginated results set the page to look for",
37
37
  "type":"number"
38
38
  },
39
+ "per_page":{
40
+ "title" : "Per page",
41
+ "description": "Results per page. Default is 10, max is 100",
42
+ "type":"number"
43
+ },
39
44
  "filter[q]":{
40
45
  "title" : "Search",
41
46
  "description": "Search in name and context names",
@@ -157,9 +157,14 @@
157
157
  "description": "In paginated results set the page to look for",
158
158
  "type":"number"
159
159
  },
160
+ "per_page":{
161
+ "title" : "Per page",
162
+ "description": "Results per page. Default is 10, max is 100",
163
+ "type":"number"
164
+ },
160
165
  "filter[q]":{
161
166
  "title" : "Search",
162
- "description": "Search in first, last_name, organisation, email, number",
167
+ "description": "Wildcard search in first, last_name, organisation, email, number",
163
168
  "type":"string"
164
169
  },
165
170
  "filter[tags]":{
@@ -167,13 +172,20 @@
167
172
  "description": "Filter by a space delimited list of tags",
168
173
  "type":"string"
169
174
  },
170
- "filter[from]":{
175
+ "filter[created_at_from]":{
171
176
  "title" : "From date",
172
- "description": "All objects with a date after the date"
177
+ "description": "All objects with a creation date after the date, including given datetime. ISO 8601 format YYY-MM-DDThh:mm:ss+z",
178
+ "type" : "date-time"
173
179
  },
174
- "filter[to]":{
180
+ "filter[created_at_to]":{
175
181
  "title" : "To date",
176
- "description": "All objects with date before the date"
182
+ "description": "All objects with a creation date before the date, including given datetime. ISO 8601 format YYY-MM-DDThh:mm:ss+z",
183
+ "type" : "date-time"
184
+ },
185
+ "filter[number]":{
186
+ "title" : "By number",
187
+ "description": "Search by number where the number is matched from the start: %number",
188
+ "type" : "date"
177
189
  },
178
190
  "sort_by":{
179
191
  "title" : "Sort by",
@@ -200,6 +212,9 @@
200
212
  "href": "clients",
201
213
  "method": "POST"
202
214
  },
215
+ { "rel": "documents",
216
+ "href": "clients/{id}/documents"
217
+ },
203
218
  { "rel": "attachments",
204
219
  "href": "clients/{id}/attachments"
205
220
  },
@@ -52,6 +52,11 @@
52
52
  "description": "In paginated results set the page to look for",
53
53
  "type":"number"
54
54
  },
55
+ "per_page":{
56
+ "title" : "Per page",
57
+ "description": "Results per page. Default is 10, max is 100",
58
+ "type":"number"
59
+ },
55
60
  "filter[q]":{
56
61
  "title" : "Search",
57
62
  "description": "Search in text",
@@ -59,11 +64,13 @@
59
64
  },
60
65
  "filter[from]":{
61
66
  "title" : "From date",
62
- "description": "All objects with a date after the date"
67
+ "description": "All objects with a date after the date",
68
+ "type" : "date"
63
69
  },
64
70
  "filter[to]":{
65
71
  "title" : "To date",
66
- "description": "All objects with date before the date"
72
+ "description": "All objects with date before the date",
73
+ "type" : "date"
67
74
  },
68
75
  "sort_by":{
69
76
  "title" : "Sort by",
@@ -90,7 +90,7 @@
90
90
  "line_items":{
91
91
  "description": "Line items for the document",
92
92
  "type":"array",
93
- "properties":{"$ref":"./address.json#properties"}
93
+ "properties":{"$ref":"./line_item.json#properties"}
94
94
  },
95
95
  "created_at":{
96
96
  "description": "Date the object was created in SK. Never changes afterwards.",
@@ -156,6 +156,11 @@
156
156
  "description": "In paginated results set the page to look for",
157
157
  "type":"number"
158
158
  },
159
+ "per_page":{
160
+ "title" : "Per page",
161
+ "description": "Results per page. Default is 10, max is 100",
162
+ "type":"number"
163
+ },
159
164
  "filter[q]":{
160
165
  "title" : "Search",
161
166
  "description": "Search in title, number, addressfield",
@@ -168,11 +173,13 @@
168
173
  },
169
174
  "filter[from]":{
170
175
  "title" : "From date",
171
- "description": "All objects with a date after the date"
176
+ "description": "All objects with a date after the date",
177
+ "type" :"date"
172
178
  },
173
179
  "filter[to]":{
174
180
  "title" : "To date",
175
- "description": "All objects with date before the date"
181
+ "description": "All objects with date before the date",
182
+ "type" :"date"
176
183
  },
177
184
  "sort_by":{
178
185
  "title" : "Sort by",
@@ -0,0 +1,157 @@
1
+ { "type":"object",
2
+ "title": "document",
3
+ "description": "This resource is readonly and serves as a convinient way to query documents independent of their type(invoice, order,..). The specific document type is set in each object in the result-set.",
4
+ "properties":{
5
+ "id":{
6
+ "description": "UUID assigned by SK",
7
+ "identity":true,
8
+ "readonly":true,
9
+ "type":"string"
10
+ },
11
+ "object_type":{
12
+ "description": "The specific type of the document",
13
+ "type":"string"
14
+ },
15
+ "number":{
16
+ "description": "Unique number assigned by SK user or object number schema.",
17
+ "type":"string"
18
+ },
19
+ "address_field":{
20
+ "description": "Receiver address, normally shown in envelope window. Defaults to client address_field.",
21
+ "type":"string"
22
+ },
23
+ "date":{
24
+ "description": "Date the docuent is issued. Automatically set when document is opened. Required for non-draft documents.",
25
+ "format":"date",
26
+ "type":"string"
27
+ },
28
+ "external_ref":{
29
+ "description": "Some external reference, whatever this may be.",
30
+ "type":"string"
31
+ },
32
+ "title":{
33
+ "description": "The headline of a document. Use SK placeholders to prevent exessive typing e.g. 'Your invoice [number]'",
34
+ "type":"string"
35
+ },
36
+ "notes_before":{
37
+ "description": "Notes shown before the line items. Normaly contains salutation and other introductional information. SK placeholders can be used.",
38
+ "type":"string"
39
+ },
40
+ "notes_after":{
41
+ "description": "Notes shown after the line items. Can contain information about payments, bank account or a thank-you message. SK placeholders can be used.",
42
+ "type":"string"
43
+ },
44
+ "tag_list": {
45
+ "description": "Space separated list of tags.",
46
+ "type":"string"
47
+ },
48
+ "precision":{
49
+ "description": "Decimal places for displayed(printed) money values. gross_total and net_total will always be displayed rounded to a precision of 2. When greater 2 use net_total_base(also in line_item) to show the net val with the set precision(3,4).",
50
+ "type":"number",
51
+ "enum": [2,3,4],
52
+ "default":2
53
+ },
54
+ "client_id":{
55
+ "description": "The clients uuid",
56
+ "type":"string",
57
+ "required":true
58
+ },
59
+ "team_id":{
60
+ "description": "A team uuid. If set only the team and its parent teams can see the record.",
61
+ "type":"string"
62
+ },
63
+ "line_items":{
64
+ "description": "Line items for the document",
65
+ "type":"array",
66
+ "properties":{"$ref":"./line_items.json#properties"}
67
+ },
68
+ "created_at":{
69
+ "description": "Date the object was created in SK. Never changes afterwards.",
70
+ "format":"date-time",
71
+ "readonly":true,
72
+ "type":"string"
73
+ },
74
+ "updated_at":{
75
+ "description": "Date the object was edited in SK.",
76
+ "format":"date-time",
77
+ "readonly":true,
78
+ "type":"string"
79
+ },
80
+ "gross_total":{
81
+ "description": "Gross total of all line items, 2 decimals places",
82
+ "readonly":true,
83
+ "type":"number"
84
+ },
85
+ "tax_total":{
86
+ "description": "Tax total, 2 decimals places",
87
+ "readonly":true,
88
+ "type":"number"
89
+ },
90
+ "net_total":{
91
+ "description": "Net total, 2 decimals places",
92
+ "readonly":true,
93
+ "type":"number"
94
+ },
95
+ "net_total_base":{
96
+ "description": "Net total, decimals places as set in precision, default 2",
97
+ "readonly":true,
98
+ "type":"number"
99
+ },
100
+ "net_total_base_raw":{
101
+ "description": "Net total, 6 decimal places. Summmed items net_total_base_raw (incl discount)",
102
+ "readonly":true,
103
+ "type":"number"
104
+ }
105
+ },
106
+ "links":[
107
+ { "rel": "self",
108
+ "href": "documents/{id}"
109
+ },
110
+ { "rel": "instances",
111
+ "href": "documents",
112
+ "properties" : {
113
+ "page":{
114
+ "title" : "Page",
115
+ "description": "In paginated results set the page to look for",
116
+ "type":"number"
117
+ },
118
+ "per_page":{
119
+ "title" : "Per page",
120
+ "description": "Results per page. Default is 10, max is 100",
121
+ "type":"number"
122
+ },
123
+ "filter[q]":{
124
+ "title" : "Search",
125
+ "description": "Search in title, number, addressfield",
126
+ "type":"string"
127
+ },
128
+ "filter[tags]":{
129
+ "title" : "Tags",
130
+ "description": "Filter by a space delimited list of tags",
131
+ "type":"string"
132
+ },
133
+ "filter[from]":{
134
+ "title" : "From date",
135
+ "description": "All objects with a date after the date",
136
+ "type" : "date"
137
+ },
138
+ "filter[to]":{
139
+ "title" : "To date",
140
+ "description": "All objects with date before the date",
141
+ "type" : "date"
142
+ },
143
+ "sort_by":{
144
+ "title" : "Sort by",
145
+ "description": "Sort the results by the given field => number",
146
+ "enum":["title", "number", "created_at", "updated_at", "client_id", "price_total", "price_tax", "date", "due_date"],
147
+ "type": "string"
148
+ },
149
+ "sort":{
150
+ "title" : "Sort",
151
+ "enum":["ASC","DESC"],
152
+ "description": "Sort the results in ASC or DESC"
153
+ }
154
+ }
155
+ }
156
+ ]
157
+ }
data/json/v1.0/email.json CHANGED
@@ -92,6 +92,11 @@
92
92
  "description": "In paginated results set the page to look for",
93
93
  "type":"number"
94
94
  },
95
+ "per_page":{
96
+ "title" : "Per page",
97
+ "description": "Results per page. Default is 10, max is 100",
98
+ "type":"number"
99
+ },
95
100
  "filter[q]":{
96
101
  "title" : "Search",
97
102
  "description": "Search in body and subject",
@@ -111,11 +116,13 @@
111
116
  },
112
117
  "filter[from]":{
113
118
  "title" : "From date",
114
- "description": "All objects updated on/after the date"
119
+ "description": "All objects updated on/after the date",
120
+ "type" : "date"
115
121
  },
116
122
  "filter[to]":{
117
123
  "title" : "To date",
118
- "description": "All objects updated on/before the date"
124
+ "description": "All objects updated on/before the date",
125
+ "type" : "date"
119
126
  },
120
127
  "sort_by":{
121
128
  "title" : "Sort by",
@@ -58,6 +58,11 @@
58
58
  "description": "In paginated results set the page to look for",
59
59
  "type":"number"
60
60
  },
61
+ "per_page":{
62
+ "title" : "Per page",
63
+ "description": "Results per page. Default is 10, max is 100",
64
+ "type":"number"
65
+ },
61
66
  "sort_by":{
62
67
  "title" : "Sort by",
63
68
  "description": "Sort the results by the given field => number",
@@ -86,7 +86,7 @@
86
86
  "line_items":{
87
87
  "description": "Line items for the document",
88
88
  "type":"array",
89
- "properties":{"$ref":"./address.json#properties"}
89
+ "properties":{"$ref":"./line_item.json#properties"}
90
90
  },
91
91
  "created_at":{
92
92
  "description": "Date the object was created in SK. Never changes afterwards.",
@@ -142,6 +142,11 @@
142
142
  "description": "In paginated results set the page to look for",
143
143
  "type":"number"
144
144
  },
145
+ "per_page":{
146
+ "title" : "Per page",
147
+ "description": "Results per page. Default is 10, max is 100",
148
+ "type":"number"
149
+ },
145
150
  "filter[q]":{
146
151
  "title" : "Search",
147
152
  "description": "Search in title, number, addressfield",
@@ -154,11 +159,13 @@
154
159
  },
155
160
  "filter[from]":{
156
161
  "title" : "From date",
157
- "description": "All objects with a date after the date"
162
+ "description": "All objects with a date after the date",
163
+ "type" : "date"
158
164
  },
159
165
  "filter[to]":{
160
166
  "title" : "To date",
161
- "description": "All objects with date before the date"
167
+ "description": "All objects with date before the date",
168
+ "type" : "date"
162
169
  },
163
170
  "sort_by":{
164
171
  "title" : "Sort by",
@@ -85,14 +85,20 @@
85
85
  "description": "In paginated results set the page to look for",
86
86
  "type":"number"
87
87
  },
88
-
88
+ "per_page":{
89
+ "title" : "Per page",
90
+ "description": "Results per page. Default is 10, max is 100",
91
+ "type":"number"
92
+ },
89
93
  "filter[from]":{
90
94
  "title" : "From date",
91
- "description": "All objects with a date after the date"
95
+ "description": "All objects with a date after the date",
96
+ "type" : "date"
92
97
  },
93
98
  "filter[to]":{
94
99
  "title" : "To date",
95
- "description": "All objects with date before the date"
100
+ "description": "All objects with date before the date",
101
+ "type" : "date"
96
102
  },
97
103
  "sort_by":{
98
104
  "title" : "Sort by",
@@ -57,6 +57,11 @@
57
57
  "description": "In paginated results set the page to look for",
58
58
  "type":"number"
59
59
  },
60
+ "per_page":{
61
+ "title" : "Per page",
62
+ "description": "Results per page. Default is 10, max is 100",
63
+ "type":"number"
64
+ },
60
65
  "sort_by":{
61
66
  "title" : "Sort by",
62
67
  "description": "Sort the results by the given field => number",
@@ -91,7 +91,7 @@
91
91
  "line_items":{
92
92
  "description": "Line items for the document",
93
93
  "type":"array",
94
- "properties":{"$ref":"./address.json#properties"}
94
+ "properties":{"$ref":"./line_item.json#properties"}
95
95
  },
96
96
  "created_at":{
97
97
  "description": "Date the object was created in SK. Never changes afterwards.",
@@ -157,6 +157,11 @@
157
157
  "description": "In paginated results set the page to look for",
158
158
  "type":"number"
159
159
  },
160
+ "per_page":{
161
+ "title" : "Per page",
162
+ "description": "Results per page. Default is 10, max is 100",
163
+ "type":"number"
164
+ },
160
165
  "filter[q]":{
161
166
  "title" : "Search",
162
167
  "description": "Search in title, number, addressfield",
@@ -169,11 +174,13 @@
169
174
  },
170
175
  "filter[from]":{
171
176
  "title" : "From date",
172
- "description": "All objects with a date after the date"
177
+ "description": "All objects with a date after the date",
178
+ "type" : "date"
173
179
  },
174
180
  "filter[to]":{
175
181
  "title" : "To date",
176
- "description": "All objects with date before the date"
182
+ "description": "All objects with date before the date",
183
+ "type" : "date"
177
184
  },
178
185
  "sort_by":{
179
186
  "title" : "Sort by",
@@ -44,7 +44,7 @@
44
44
  "required":true
45
45
  },
46
46
  "product_id":{
47
- "description": "An item can reference a product. This makes it easier to track a products turnover and the documents it is used on. Also ee use_product",
47
+ "description": "A uuid of a product, referenced in this item. This makes it easier to track a products turnover and list the documents it is used on. Also see use_product",
48
48
  "type":"string"
49
49
  },
50
50
  "use_product":{
@@ -62,6 +62,10 @@
62
62
  "format":"date-time",
63
63
  "readonly":true,
64
64
  "type":"string"
65
+ },
66
+ "_delete": {
67
+ "description": "When set an existing item will be deleted. This switch is used for items passed-in nested inside their parent object(a document), which is default as long as there is no line item endpoint available.",
68
+ "type":"boolean"
65
69
  }
66
70
  }
67
71
  }
data/json/v1.0/order.json CHANGED
@@ -76,7 +76,7 @@
76
76
  "line_items":{
77
77
  "description": "Line items for the document",
78
78
  "type":"array",
79
- "properties":{"$ref":"./address.json#properties"}
79
+ "properties":{"$ref":"./line_item.json#properties"}
80
80
  },
81
81
  "created_at":{
82
82
  "description": "Date the object was created in SK. Never changes afterwards.",
@@ -132,6 +132,11 @@
132
132
  "description": "In paginated results set the page to look for",
133
133
  "type":"number"
134
134
  },
135
+ "per_page":{
136
+ "title" : "Per page",
137
+ "description": "Results per page. Default is 10, max is 100",
138
+ "type":"number"
139
+ },
135
140
  "filter[q]":{
136
141
  "title" : "Search",
137
142
  "description": "Search in title, number, addressfield",
@@ -144,11 +149,13 @@
144
149
  },
145
150
  "filter[from]":{
146
151
  "title" : "From date",
147
- "description": "All objects with a date after the date"
152
+ "description": "All objects with a date after the date",
153
+ "type" : "date"
148
154
  },
149
155
  "filter[to]":{
150
156
  "title" : "To date",
151
- "description": "All objects with date before the date"
157
+ "description": "All objects with date before the date",
158
+ "type" : "date"
152
159
  },
153
160
  "sort_by":{
154
161
  "title" : "Sort by",
@@ -61,6 +61,11 @@
61
61
  "description": "In paginated results set the page to look for",
62
62
  "type":"number"
63
63
  },
64
+ "per_page":{
65
+ "title" : "Per page",
66
+ "description": "Results per page. Default is 10, max is 100",
67
+ "type":"number"
68
+ },
64
69
  "filter[q]":{
65
70
  "title" : "Search",
66
71
  "description": "Search in title, number, addressfield",
@@ -68,11 +73,14 @@
68
73
  },
69
74
  "filter[from]":{
70
75
  "title" : "From date",
71
- "description": "All objects with a date after the date"
76
+ "description": "All objects with a date after the date",
77
+ "type" : "date"
78
+
72
79
  },
73
80
  "filter[to]":{
74
81
  "title" : "To date",
75
- "description": "All objects with date before the date"
82
+ "description": "All objects with date before the date",
83
+ "type" : "date"
76
84
  },
77
85
  "sort_by":{
78
86
  "title" : "Sort by",
@@ -81,7 +81,7 @@
81
81
  "line_items":{
82
82
  "description": "Line items for the document. Defaults to invoice.gross_total and late fee values from settings",
83
83
  "type":"array",
84
- "properties":{"$ref":"./address.json#properties"}
84
+ "properties":{"$ref":"./line_item.json#properties"}
85
85
  },
86
86
  "created_at":{
87
87
  "description": "Date the object was created in SK. Never changes afterwards.",
@@ -122,6 +122,11 @@
122
122
  "description": "In paginated results set the page to look for",
123
123
  "type":"number"
124
124
  },
125
+ "per_page":{
126
+ "title" : "Per page",
127
+ "description": "Results per page. Default is 10, max is 100",
128
+ "type":"number"
129
+ },
125
130
  "filter[q]":{
126
131
  "title" : "Search",
127
132
  "description": "Search in title, number, addressfield",
@@ -134,11 +139,13 @@
134
139
  },
135
140
  "filter[from]":{
136
141
  "title" : "From date",
137
- "description": "All objects with a date after the date"
142
+ "description": "All objects with a date after the date",
143
+ "type" : "date"
138
144
  },
139
145
  "filter[to]":{
140
146
  "title" : "To date",
141
- "description": "All objects with date before the date"
147
+ "description": "All objects with date before the date",
148
+ "type" : "date"
142
149
  },
143
150
  "sort_by":{
144
151
  "title" : "Sort by",
@@ -66,6 +66,11 @@
66
66
  "description": "In paginated results set the page to look for",
67
67
  "type":"number"
68
68
  },
69
+ "per_page":{
70
+ "title" : "Per page",
71
+ "description": "Results per page. Default is 10, max is 100",
72
+ "type":"number"
73
+ },
69
74
  "filter[q]":{
70
75
  "title" : "Search",
71
76
  "description": "Searches in number, name, description, price",
@@ -88,7 +88,7 @@
88
88
  "line_items":{
89
89
  "description": "Line items for the document",
90
90
  "type":"array",
91
- "properties":{"$ref":"./address.json#properties"}
91
+ "properties":{"$ref":"./line_item.json#properties"}
92
92
  },
93
93
  "created_at":{
94
94
  "description": "Date the object was created in SK. Never changes afterwards.",
@@ -144,6 +144,11 @@
144
144
  "description": "In paginated results set the page to look for",
145
145
  "type":"number"
146
146
  },
147
+ "per_page":{
148
+ "title" : "Per page",
149
+ "description": "Results per page. Default is 10, max is 100",
150
+ "type":"number"
151
+ },
147
152
  "filter[q]":{
148
153
  "title" : "Search",
149
154
  "description": "Search in title, number, addressfield",
@@ -156,11 +161,13 @@
156
161
  },
157
162
  "filter[from]":{
158
163
  "title" : "From date",
159
- "description": "All objects with a date after the date"
164
+ "description": "All objects with a date after the date",
165
+ "type" : "date"
160
166
  },
161
167
  "filter[to]":{
162
168
  "title" : "To date",
163
- "description": "All objects with date before the date"
169
+ "description": "All objects with date before the date",
170
+ "type" : "date"
164
171
  },
165
172
  "sort_by":{
166
173
  "title" : "Sort by",
@@ -0,0 +1,63 @@
1
+ { "type":"object",
2
+ "title": "tag",
3
+ "description":"A tag",
4
+ "properties": {
5
+ "id": {
6
+ "description": "uuid of the object.",
7
+ "identity":true,
8
+ "readonly":true,
9
+ "type":"string"
10
+ },
11
+ "name": {
12
+ "description": "The tag itself",
13
+ "readonly":true,
14
+ "type":"string"
15
+ },
16
+ "taggings_count": {
17
+ "description": "Usage count of this tag, for all objects in whole company scope.",
18
+ "readonly":true,
19
+ "type":"number"
20
+ }
21
+ },
22
+ "links":[
23
+ { "rel": "self",
24
+ "href": "tags/{id}"
25
+ },
26
+ { "rel": "instances",
27
+ "href": "tags",
28
+ "properties" : {
29
+ "page":{
30
+ "title" : "Page",
31
+ "description": "In paginated results set the page to look for",
32
+ "type":"number"
33
+ },
34
+ "per_page":{
35
+ "title" : "Per page",
36
+ "description": "Results per page. Default is 10, max is 100",
37
+ "type":"number"
38
+ },
39
+ "filter[q]":{
40
+ "title" : "Search",
41
+ "description": "Search in name",
42
+ "type":"string"
43
+ },
44
+ "filter[related_object_type]":{
45
+ "title" : "Related object type",
46
+ "description": "Filter tags by their related object base type",
47
+ "type":"string"
48
+ },
49
+ "sort_by":{
50
+ "title" : "Sort by",
51
+ "description": "Sort the results by the given field",
52
+ "enum":["filename","taggings_count"],
53
+ "type": "string"
54
+ },
55
+ "sort":{
56
+ "title" : "Sort",
57
+ "enum":["ASC","DESC"],
58
+ "description": "Sort the results in ASC or DESC"
59
+ }
60
+ }
61
+ }
62
+ ]
63
+ }
@@ -53,6 +53,11 @@
53
53
  "description": "In paginated results set the page to look for",
54
54
  "type":"number"
55
55
  },
56
+ "per_page":{
57
+ "title" : "Per page",
58
+ "description": "Results per page. Default is 10, max is 100",
59
+ "type":"number"
60
+ },
56
61
  "sort_by":{
57
62
  "title" : "Sort by",
58
63
  "description": "Sort the results by the given field => number",
data/lib/sk_api_schema.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'active_support'
2
2
  require 'active_support/core_ext/hash/indifferent_access'
3
+ require 'active_support/core_ext/string/inflections'
3
4
  module SK
4
5
  module Api
5
6
  class Schema
@@ -9,23 +10,29 @@ module SK
9
10
  # class var remembering already read-in schema's
10
11
  # {
11
12
  # 'v1.0'=>{
12
- # 'invoice'=>{schema}
13
- # 'credit_note'=>{schema}
13
+ # :invoice =>{schema}
14
+ # :credit_note =>{schema}
14
15
  # }
15
16
  # }
16
17
  # === Return
17
- #<Hash>::
18
+ #<Hash{String=>Hash{Symbol=>HashWithIndifferentAccess}}>::
18
19
  def registry
19
20
  @registry ||={}
20
21
  end
22
+
23
+ def registry_reset
24
+ @registry = nil
25
+ end
21
26
  # Read a schema with a given version and return it as hash
22
27
  # See ../json folder for available schema's and versions
23
28
  # === Parameter
24
29
  # schema<String|Symbol>::name of the schema, available ones are in json directory
25
- # version<String>:: version to read, this is the folder name where the schema is in.
30
+ # version<String>:: version to read, the folder name where the schema is in.
31
+ # Can be used without v-prefix
26
32
  # === Return
27
33
  # <HashWithIndifferentAccess>:: schema as hash
28
34
  def read(schema, version)
35
+ schema = schema.to_sym
29
36
  return registry[version][schema] if registry[version] && registry[version][schema]
30
37
  # prefix version with v1.0 of v is not present
31
38
  v = (version =~ /^v/) ? version : "v#{version}"
@@ -33,7 +40,7 @@ module SK
33
40
  # read schema from file
34
41
  file_path = File.join(File.dirname(__FILE__), '../json', v, "#{schema}.json")
35
42
  plain_data = File.open(file_path, 'r'){|f| f.read}
36
- # remember
43
+ # remember & return
37
44
  registry[v][schema] = ActiveSupport::JSON.decode(plain_data).with_indifferent_access
38
45
  end
39
46
 
@@ -41,46 +48,65 @@ module SK
41
48
  # them as array
42
49
  # See ../json folder for available schema's and versions
43
50
  # === Parameter
44
- # schema<String|Symbol>::name of the schema, available ones are in json directory
51
+ # schema<String|Symbol>:: version to read, equals json/foldername v1.0 or
52
+ # use without prefix 1.0
45
53
  # === Return
46
54
  # Array[<HashWithIndifferentAccess>]:: array of schemas as hash
47
55
  def read_all(version)
48
56
  schemas = []
49
57
  v = (version =~ /^v/) ? version : "v#{version}"
58
+ registry[v] = {} unless registry[v]
50
59
  file_path = File.join(File.dirname(__FILE__), '../json', v, '*.json')
51
60
  Dir.glob( file_path ).each do |file|
52
- schema = File.open(file, 'r'){|f| f.read}
53
- schemas << ActiveSupport::JSON.decode(schema).with_indifferent_access
61
+ schema_name = File.basename(file, ".json").to_sym
62
+ schemas << read(schema_name, v)
54
63
  end
55
64
  schemas
56
65
  end
57
66
 
58
67
  # Create a Hash with the available (api)object attributes defined in the
59
- # according schema properties. This is the meat of the object-to-api
60
- # workflow
68
+ # according schema properties. This is the meat of the
69
+ # object-to-api-markup workflow
61
70
  #
62
71
  # === Example
63
72
  # obj = Invoice.new(:title =>'hello world', :number=>'4711')
64
- # obj_hash = Sk::Api::Schema.to_hash_from_schema(obj, 'v1.0')
65
73
  #
66
- # obj_hash => { invoice =>{'title'=>'hello world', 'number'=>'4711' } }
74
+ # obj_hash = SK::Api::Schema.to_hash_from_schema(obj, 'v1.0')
75
+ # => { 'invoice' =>{'title'=>'hello world', 'number'=>'4711' } }
76
+ #
77
+ # obj_hash = SK::Api::Schema.to_hash_from_schema(obj, 'v1.0', :fields=>['title'])
78
+ # => { 'invoice' =>{'title'=>'hello world' } }
67
79
  #
80
+ # obj_hash = SK::Api::Schema.to_hash_from_schema(obj, 'v1.0', :class_name=>:document)
81
+ # => { 'document' =>{'title'=>'hello world' } }
82
+ #
68
83
  # === Parameter
69
84
  # obj<Object>:: An ruby object which is returned as hash
70
- # version<String>:: the schema version, must be a valid folder name see #self.read
85
+ # version<String>:: the schema version, must be a valid folder name see
86
+ # #self.read
87
+ # opts<Hash{Symbol=>Mixed} >:: additional options
88
+ #
89
+ # ==== opts Parameter
90
+ # class_name<String|Symbol>:: Name of the class to use as hash key. Should be
91
+ # a lowered, underscored name and it MUST have an existing schema file.
92
+ # Use it to override the default, which is obj.class.name
93
+ # fields<Array[String]>:: Fields/properties to return. If not set all
94
+ # schema's properties are used.
71
95
  #
72
96
  # === Return
73
97
  # <Hash{String=>{String=>Mixed}}>:: The object as hash:
74
98
  # { invoice =>{'title'=>'hello world', 'number'=>''4711 } }
75
- def to_hash_from_schema(obj, version)
99
+ def to_hash_from_schema(obj, version, opts={})
100
+ fields = opts[:fields]
76
101
  # get objects class name without inheritance
77
- obj_class_name = obj.class.name.split('::').last.underscore
78
- # init data hash
102
+ real_class_name = obj.class.name.split('::').last.underscore
103
+ class_name = opts[:class_name] || real_class_name
79
104
  data = {}
80
105
  # get schema
81
- schema = read(obj_class_name, version)
106
+ schema = read(class_name, version)
82
107
  # iterate over the defined schema fields
83
108
  schema['properties'].each do |field, prop|
109
+ next if fields && !fields.include?(field)
84
110
  if prop['type'] == 'array'
85
111
  data[field] = [] # always set an empty array
86
112
  if rel_objects = obj.send( field )
@@ -100,9 +126,10 @@ module SK
100
126
  data[field] = obj.send(field) if obj.respond_to?(field.to_sym)
101
127
  end
102
128
  end
103
- hsh = { obj_class_name => data }
129
+ hsh = { "#{class_name}" => data }
104
130
  #add links if present
105
- links = parse_links(obj, schema)
131
+ real_class_schema = read(real_class_name, version)
132
+ links = parse_links(obj, real_class_schema)
106
133
  links && hsh['links'] = links
107
134
  # return hash
108
135
  hsh
@@ -5,17 +5,18 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sk_api_schema}
8
- s.version = "0.0.18"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Georg Leciejewski"]
12
- s.date = %q{2011-03-10}
12
+ s.date = %q{2011-04-28}
13
13
  s.description = %q{SalesKing API JSON schema and utility methods}
14
14
  s.email = %q{gl@salesking.eu}
15
15
  s.extra_rdoc_files = [
16
16
  "README.rdoc"
17
17
  ]
18
18
  s.files = [
19
+ "CHANGELOG.rdoc",
19
20
  "README.rdoc",
20
21
  "Rakefile",
21
22
  "VERSION",
@@ -26,6 +27,7 @@ Gem::Specification.new do |s|
26
27
  "json/v1.0/comment.json",
27
28
  "json/v1.0/company.json",
28
29
  "json/v1.0/credit_note.json",
30
+ "json/v1.0/document.json",
29
31
  "json/v1.0/email.json",
30
32
  "json/v1.0/email_template.json",
31
33
  "json/v1.0/estimate.json",
@@ -39,6 +41,7 @@ Gem::Specification.new do |s|
39
41
  "json/v1.0/product.json",
40
42
  "json/v1.0/recurring.json",
41
43
  "json/v1.0/sub.json",
44
+ "json/v1.0/tag.json",
42
45
  "json/v1.0/text_template.json",
43
46
  "json/v1.0/user.json",
44
47
  "lib/sk_api_schema.rb",
@@ -48,7 +51,7 @@ Gem::Specification.new do |s|
48
51
  ]
49
52
  s.homepage = %q{http://github.com/salesking/sk_api_schema}
50
53
  s.require_paths = ["lib"]
51
- s.rubygems_version = %q{1.5.2}
54
+ s.rubygems_version = %q{1.6.2}
52
55
  s.summary = %q{SalesKing API JSON Schema}
53
56
  s.test_files = [
54
57
  "spec/sk_api_schema_spec.rb",
@@ -2,6 +2,9 @@ require 'spec/spec_helper'
2
2
 
3
3
  describe SK::Api::Schema do
4
4
 
5
+ before :each do
6
+ SK::Api::Schema.registry_reset
7
+ end
5
8
  it "should read json schema file" do
6
9
  schema = SK::Api::Schema.read(:invoice, 'v1.0')
7
10
  schema[:title].should == 'invoice'
@@ -87,6 +90,25 @@ describe SK::Api::Schema, 'object parsing' do
87
90
  "id"=>"some-uuid", "description"=>"Yummi Pork chopped by mexian emigrants", "price_single"=>0.99}}]
88
91
  end
89
92
 
93
+ it "should parse object given fields" do
94
+ @invoice.line_items = [@item]
95
+ @invoice.client = @client
96
+ fields = %w(id title client)
97
+ obj_hash = SK::Api::Schema.to_hash_from_schema(@invoice, 'v1.0', :fields=>fields)
98
+ obj_hash["invoice"]['client']['client'].should == {"number"=>"911", "addresses"=>[], "id"=>"some-uuid", "organisation"=>"Dirty Food Inc.", "last_name"=>nil}
99
+ obj_hash["invoice"]["client"]['links'].should_not be_nil
100
+ obj_hash["invoice"].keys.sort.should == fields.sort
101
+ end
102
+
103
+ it "should use different class name as object hash key" do
104
+ @invoice.line_items = [@item]
105
+ @invoice.client = @client
106
+ obj_hash = SK::Api::Schema.to_hash_from_schema(@invoice, 'v1.0', :class_name=>:document)
107
+ schema = SK::Api::Schema.read(:document, 'v1.0')
108
+ # check included fields, which should not be all fields from schema since our dummy invoice object does not responds_to all
109
+ intersect_keys = schema['properties'].keys & obj_hash["document"].keys
110
+ intersect_keys.sort.should == obj_hash["document"].keys.sort
111
+ end
90
112
  end
91
113
 
92
114
  ################################################################################
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sk_api_schema
3
3
  version: !ruby/object:Gem::Version
4
- hash: 59
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 18
10
- version: 0.0.18
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Georg Leciejewski
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-10 00:00:00 +01:00
18
+ date: 2011-04-28 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -55,6 +55,7 @@ extensions: []
55
55
  extra_rdoc_files:
56
56
  - README.rdoc
57
57
  files:
58
+ - CHANGELOG.rdoc
58
59
  - README.rdoc
59
60
  - Rakefile
60
61
  - VERSION
@@ -65,6 +66,7 @@ files:
65
66
  - json/v1.0/comment.json
66
67
  - json/v1.0/company.json
67
68
  - json/v1.0/credit_note.json
69
+ - json/v1.0/document.json
68
70
  - json/v1.0/email.json
69
71
  - json/v1.0/email_template.json
70
72
  - json/v1.0/estimate.json
@@ -78,6 +80,7 @@ files:
78
80
  - json/v1.0/product.json
79
81
  - json/v1.0/recurring.json
80
82
  - json/v1.0/sub.json
83
+ - json/v1.0/tag.json
81
84
  - json/v1.0/text_template.json
82
85
  - json/v1.0/user.json
83
86
  - lib/sk_api_schema.rb
@@ -114,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
117
  requirements: []
115
118
 
116
119
  rubyforge_project:
117
- rubygems_version: 1.5.2
120
+ rubygems_version: 1.6.2
118
121
  signing_key:
119
122
  specification_version: 3
120
123
  summary: SalesKing API JSON Schema