| @@ -11,7 +11,7 @@ func createEntity(entityType string, jsonB []byte) (entity interface{}, err erro | |||
| url := crmSite + "api/v1/" + entityType | |||
| jsonStr, err := postRAW(jsonB, url, crmBuildCommonAPIHeader()) | |||
| if err != nil { | |||
| log.Println(err) | |||
| entity, _ = rescueDuplicate(err, entityType) | |||
| return | |||
| } | |||
| return json2Entity(entityType, jsonStr) | |||
| @@ -85,3 +85,22 @@ func json2Entity(entityType string, data string) (r interface{}, err error) { | |||
| } | |||
| return | |||
| } | |||
| func rescueDuplicate(e error, entityType string) (entity interface{}, success bool) { | |||
| if !isErrIndicateDuplicate(e) { | |||
| return | |||
| } | |||
| entity, err := e.(errorHTTPResponse).XStatusReason().Data2Entity(entityType) | |||
| success = err == nil | |||
| return | |||
| } | |||
| func isErrIndicateDuplicate(e error) (yes bool) { | |||
| err, isOurError := e.(errorHTTPResponse) | |||
| if !isOurError { | |||
| return | |||
| } | |||
| reason := err.XStatusReason() | |||
| yes = strings.ToLower(reason.Reason) == "duplicate" | |||
| return | |||
| } | |||
| @@ -69,6 +69,23 @@ func TestCreateDuplicate(t *testing.T) { | |||
| //try to create it again | |||
| entity, err := createEntity("Lead", b) | |||
| ehttp := err.(errorHTTPResponse) | |||
| AssertEqual(t, err == nil, false, "should have error for duplicates") | |||
| AssertEqual(t, isErrIndicateDuplicate(err), true, "this should be duplicate error") | |||
| } | |||
| func TestCreateEntityServerNotFound(t *testing.T) { | |||
| SetupConfig() | |||
| crmSite = "https://not-exist.hitxy.org.au/" // | |||
| e := crmdLead{} | |||
| e.FirstName = "ff" + time.Now().Format("2006-jan-02 03:04:05") | |||
| e.LastName = "ll" | |||
| e.Password = "pp" | |||
| e.Status = "New" | |||
| e.WechatHitxyID = "someopenid" | |||
| b, _ := json.Marshal(e) | |||
| entity, err := createEntity("Lead", b) | |||
| AssertEqual(t, isErrIndicateDuplicate(err), false, "this should not be a duplicate error") | |||
| AssertEqual(t, entity, nil, "should not be able to create entity, it should be nil") | |||
| } | |||
| @@ -2,6 +2,9 @@ package main | |||
| import ( | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| "log" | |||
| "net/http" | |||
| ) | |||
| @@ -23,12 +26,37 @@ func errorHTTPResponseNew(r *http.Response, msg string) (e errorHTTPResponse) { | |||
| } | |||
| type crmdReason struct { | |||
| Reason string `json:"reason"` | |||
| Data string `json:"data"` | |||
| Reason string `json:"reason"` | |||
| Data map[string]*json.RawMessage `json:"data"` | |||
| } | |||
| func (e *errorHTTPResponse) XStatusReason() (r crmdReason) { | |||
| func (e errorHTTPResponse) XStatusReason() (r crmdReason) { | |||
| jsonStr := e.HTTPHeader.Get("X-Status-Reason") | |||
| json.Unmarshal([]byte(jsonStr), &r) | |||
| return | |||
| } | |||
| func (m crmdReason) Data2Entity(entityType string) (r interface{}, err error) { | |||
| if len(m.Data) > 1 { | |||
| log.Println("Warning: Multiple data object found, only choose first one") | |||
| log.Println(m) | |||
| } | |||
| //only take one object | |||
| for _, v := range m.Data { | |||
| switch entityType { | |||
| case "Lead": | |||
| e := crmdLead{} | |||
| err = json.Unmarshal(*v, &e) | |||
| r = e | |||
| case "Account": | |||
| //r = crmdAccount{} | |||
| default: | |||
| msg := fmt.Sprintf("(crmdReason) Data2Entity: Unknown EntityType %s", entityType) | |||
| err = errors.New(msg) | |||
| log.Fatalln(err) | |||
| } | |||
| break //after procesing first ojbect, we quite, neglect all the rest | |||
| } | |||
| return | |||
| } | |||