Skip to content

Commit e8843d8

Browse files
committed
add support for process management
1 parent c0cded9 commit e8843d8

File tree

4 files changed

+264
-2
lines changed

4 files changed

+264
-2
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ to access [kintone][] with its official REST API ([en][APIen], [ja][APIja]).
1313

1414
## Version
1515

16-
0.1.1
16+
0.1.2
1717

1818
## License
1919

app.go

+77-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525

2626
const (
2727
NAME = "kintone-go-SDK"
28-
VERSION = "0.1.1"
28+
VERSION = "0.1.2"
2929
DEFAULT_TIMEOUT = time.Second * 600 // Default value for App.Timeout
3030
)
3131

@@ -390,6 +390,52 @@ func (app *App) GetAllRecords(fields []string) ([]*Record, error) {
390390
}
391391
}
392392

393+
func isAllowedLang(allowedLangs []string, lang string) bool {
394+
for _, allowedLang := range allowedLangs {
395+
if lang == allowedLang {
396+
return true
397+
}
398+
}
399+
return false
400+
}
401+
402+
// GetProcess retrieves the process management settings
403+
// This method can only be used when App is initialized with password authentication
404+
// lang must be one of default, en, zh, ja, user
405+
func (app *App) GetProcess(lang string) (process *Process, err error) {
406+
type request_body struct {
407+
App uint64 `json:"app,string"`
408+
lang string `json:"lang,string"`
409+
}
410+
if app.User == "" || app.Password == "" {
411+
err = errors.New("This API only supports password authentication")
412+
return
413+
}
414+
allowedLangs := []string{"default", "en", "zh", "ja", "user"}
415+
if !isAllowedLang(allowedLangs, lang) {
416+
err = errors.New("Illegal language provided")
417+
return
418+
}
419+
data, _ := json.Marshal(request_body{app.AppId, lang})
420+
req, err := app.newRequest("GET", "app/status", bytes.NewReader(data))
421+
if err != nil {
422+
return
423+
}
424+
resp, err := app.do(req)
425+
if err != nil {
426+
return
427+
}
428+
body, err := parseResponse(resp)
429+
if err != nil {
430+
return
431+
}
432+
process, err = DecodeProcess(body)
433+
if err != nil {
434+
err = ErrInvalidResponse
435+
}
436+
return
437+
}
438+
393439
// FileData stores downloaded file data.
394440
type FileData struct {
395441
ContentType string // MIME type of the contents.
@@ -715,6 +761,36 @@ func (app *App) UpdateRecordsByKey(recs []*Record, ignoreRevision bool, keyField
715761
return err
716762
}
717763

764+
// UpdateRecordStatus updates the Status of a record
765+
func (app *App) UpdateRecordStatus(rec *Record, action *ProcessAction, assignee *Entity, ignoreRevision bool) (err error) {
766+
type request_body struct {
767+
App uint64 `json:"app,string"`
768+
Id uint64 `json:"id,string"`
769+
Revision int64 `json:"revision,string"`
770+
Action string `json:"action"`
771+
Assignee string `json:"assignee,omitempty"`
772+
}
773+
rev := rec.Revision()
774+
if ignoreRevision {
775+
rev = -1
776+
}
777+
var code string
778+
if assignee != nil {
779+
code = assignee.Code
780+
}
781+
data, _ := json.Marshal(request_body{app.AppId, rec.id, rev, action.Name, code})
782+
req, err := app.newRequest("PUT", "record/status", bytes.NewReader(data))
783+
if err != nil {
784+
return
785+
}
786+
resp, err := app.do(req)
787+
if err != nil {
788+
return
789+
}
790+
_, err = parseResponse(resp)
791+
return
792+
}
793+
718794
// DeleteRecords deletes multiple records.
719795
//
720796
// Up to 100 records can be deleted at once.

process.go

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// (C) 2014 Cybozu. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license
3+
// that can be found in the LICENSE file.
4+
5+
package kintone
6+
7+
import (
8+
"encoding/json"
9+
)
10+
11+
// Process represents the process management settings for an application
12+
type Process struct {
13+
Enable bool `json:"enable"`
14+
States map[string](*ProcessState) `json:"states"`
15+
Actions []*ProcessAction `json:"actions"`
16+
Revision string `json:"revision"`
17+
}
18+
19+
// ProcessState represents a process management status
20+
type ProcessState struct {
21+
Name string `json:"name"`
22+
Index string `json:"index"`
23+
Assignee *ProcessAssignee `json:"assignee"`
24+
}
25+
26+
// ProcessAction representes a process management action
27+
type ProcessAction struct {
28+
Name string `json:"name"`
29+
From string `json:"from"`
30+
To string `json:"to"`
31+
FilterCond string `json:"filterCond"`
32+
}
33+
34+
// ProcessAssignee represents a ProcessState assignee
35+
type ProcessAssignee struct {
36+
Type string `json:type`
37+
Entities []*ProcessEntity `json:entities`
38+
}
39+
40+
// ProcessEntity represents a process assignee entity
41+
type ProcessEntity struct {
42+
Entity *Entity `json:entity`
43+
IncludeSubs bool `json:includeSubs`
44+
}
45+
46+
// Entity is the concrete representation of a process entity
47+
type Entity struct {
48+
Type string `json:type`
49+
Code string `json:code`
50+
}
51+
52+
func DecodeProcess(b []byte) (p *Process, err error) {
53+
err = json.Unmarshal(b, &p)
54+
if err != nil {
55+
return
56+
}
57+
return
58+
}

process_test.go

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// (C) 2014 Cybozu. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license
3+
// that can be found in the LICENSE file.
4+
5+
package kintone
6+
7+
import (
8+
"testing"
9+
)
10+
11+
func TestDecodeProcess(t *testing.T) {
12+
t.Parallel()
13+
j := []byte(`
14+
{
15+
"enable": true,
16+
"states": {
17+
"Not started": {
18+
"name": "Not started",
19+
"index": "0",
20+
"assignee": {
21+
"type": "ONE",
22+
"entities": [
23+
]
24+
}
25+
},
26+
"In progress": {
27+
"name": "In progress",
28+
"index": "1",
29+
"assignee": {
30+
"type": "ALL",
31+
"entities": [
32+
{
33+
"entity": {
34+
"type": "USER",
35+
"code": "user1"
36+
},
37+
"includeSubs": false
38+
},
39+
{
40+
"entity": {
41+
"type": "FIELD_ENTITY",
42+
"code": "creator"
43+
},
44+
"includeSubs": false
45+
},
46+
{
47+
"entity": {
48+
"type": "CUSTOM_FIELD",
49+
"code": "Boss"
50+
},
51+
"includeSubs": false
52+
}
53+
]
54+
}
55+
},
56+
"Completed": {
57+
"name": "Completed",
58+
"index": "2",
59+
"assignee": {
60+
"type": "ONE",
61+
"entities": [
62+
]
63+
}
64+
}
65+
},
66+
"actions": [
67+
{
68+
"name": "Start",
69+
"from": "Not started",
70+
"to": "In progress",
71+
"filterCond": "Record_number = \"1\""
72+
},
73+
{
74+
"name": "Complete",
75+
"from": "In progress",
76+
"to": "Completed",
77+
"filterCond": ""
78+
}
79+
],
80+
"revision": "3"
81+
}`)
82+
process, err := DecodeProcess(j)
83+
if err != nil {
84+
t.Fatal(err)
85+
}
86+
if !process.Enable {
87+
t.Errorf("Expected enabled, got %v", process.Enable)
88+
}
89+
if len(process.States) != 3 {
90+
t.Errorf("Expected 3 states, got %v", len(process.States))
91+
}
92+
if len(process.Actions) != 2 {
93+
t.Errorf("Expected 2 actions, got %v", len(process.Actions))
94+
}
95+
if process.Revision != "3" {
96+
t.Errorf("Expected revision to be 3, got %v", process.Revision)
97+
}
98+
notStartedProcess := process.States["Not started"]
99+
if notStartedProcess.Name != "Not started" {
100+
t.Errorf("Expected status name to be \"Not started\", got \"%v\"", notStartedProcess.Name)
101+
}
102+
if notStartedProcess.Index != "0" {
103+
t.Errorf("Expected status index to be 0, got %v", notStartedProcess.Index)
104+
}
105+
if notStartedProcess.Assignee.Type != "ONE" {
106+
t.Errorf("Expected assignee type to be \"ONE\", got \"%v\"", notStartedProcess.Assignee.Type)
107+
}
108+
inProgressProcess := process.States["In progress"]
109+
if len(inProgressProcess.Assignee.Entities) != 3 {
110+
t.Errorf("Expected 0 assignees, got %v", len(inProgressProcess.Assignee.Entities))
111+
}
112+
if inProgressProcess.Assignee.Entities[0].Entity.Code != "user1" {
113+
t.Errorf("Expected entity to be named \"user1\", got \"%v\"", inProgressProcess.Assignee.Entities[0].Entity.Code)
114+
}
115+
if inProgressProcess.Assignee.Entities[0].IncludeSubs {
116+
t.Errorf("Expected entity to not include subs, got %v", inProgressProcess.Assignee.Entities[0].IncludeSubs)
117+
}
118+
completeAction := process.Actions[1]
119+
if completeAction.Name != "Complete" {
120+
t.Errorf("Expected action name to be \"Complete\", got \"%v\"", completeAction.Name)
121+
}
122+
if completeAction.From != "In progress" {
123+
t.Errorf("Expected previous status to be \"In progress\", got \"%v\"", completeAction.From)
124+
}
125+
if completeAction.To != "Completed" {
126+
t.Errorf("Expected next status to be \"Completed\", got \"%v\"", completeAction.To)
127+
}
128+
}

0 commit comments

Comments
 (0)