package api import ( "encoding/json" "fmt" "io" "log" "net/url" ) type JobsResponse struct { Data struct { Jobs []Job `json:"jobs"` } `json:"data"` } type Job struct { ID int64 `json:"id"` Name string `json:"name"` CustomName *string `json:"customName"` Type string `json:"type"` JobTypeWeight int `json:"jobTypeWeight"` Status string `json:"status"` Visibility []string `json:"visibility"` Number int `json:"number"` RefNumber string `json:"refNumber"` Description *string `json:"description"` ScheduledDate *int64 `json:"scheduledDate"` CompletedOn *int64 `json:"completedOn"` ServiceLine string `json:"serviceLine"` EstimatedPrice *float64 `json:"estimatedPrice"` Vendor Vendor `json:"vendor"` Customer Customer `json:"customer"` Location Location `json:"location"` Owner Owner `json:"owner"` Tags []Tag `json:"tags"` Appointments []Appointment `json:"appointments"` CurrentAppointment Appointment `json:"currentAppointment"` AssignedOffice Location `json:"assignedOffice"` Offices []Location `json:"offices"` Terms *Term `json:"terms"` Contract *Contract `json:"contract"` PrimaryContact *PrimaryContact `json:"primaryContact"` } type Vendor struct { ID int64 `json:"id"` URI string `json:"uri"` Name string `json:"name"` Status string `json:"status"` } type Customer struct { ID int64 `json:"id"` URI string `json:"uri"` Name string `json:"name"` Status string `json:"status"` } type Location struct { ID int64 `json:"id"` URI string `json:"uri"` Name string `json:"name"` RefNumber string `json:"refNumber"` Lat float64 `json:"lat"` Lon float64 `json:"lon"` Address Address `json:"address"` } type Address struct { Street string `json:"street"` City string `json:"city"` State string `json:"state"` PostalCode string `json:"postalCode"` } func (a Address) String() string { return fmt.Sprintf("%s, %s, %s %s", a.Street, a.City, a.State, a.PostalCode) } type Owner struct { ID int64 `json:"id"` URI string `json:"uri"` Name string `json:"name"` Status string `json:"status"` Email string `json:"email"` } type Tag struct { ID int64 `json:"id"` URI string `json:"uri"` Name string `json:"name"` } type Appointment struct { ID int64 `json:"id"` URI string `json:"uri"` Name string `json:"name"` Status string `json:"status"` WindowStart *int64 `json:"windowStart"` WindowEnd *int64 `json:"windowEnd"` Techs []Tech `json:"techs"` Released bool `json:"released"` } type Tech struct { ID int64 `json:"id"` Name string `json:"name"` Email string `json:"email"` } type Term struct { ID int64 `json:"id"` Name string `json:"name"` } type Contract struct { ID int64 `json:"id"` Name string `json:"name"` } type PrimaryContact struct { ID int64 `json:"id"` URI string `json:"uri"` Email string `json:"email"` } func (s *Session) SearchJobs(filters url.Values) ([]Job, error) { endpoint := "/job?" query := filters.Encode() url := endpoint + query resp, err := s.DoRequest("GET", url, nil) if err != nil { return nil, err } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) log.Printf("Raw API Response: %s", string(body)) if resp.StatusCode != 200 { return nil, fmt.Errorf("failed to search jobs: %s, response: %s", resp.Status, string(body)) } var result JobsResponse if err := json.Unmarshal(body, &result); err != nil { return nil, fmt.Errorf("error unmarshalling response: %v", err) } log.Printf("Parsed Data: %+v", result.Data) return result.Data.Jobs, nil } func (s *Session) GetAttachmentsForJob(jobID string) (map[string]interface{}, error) { resp, err := s.DoRequest("GET", fmt.Sprintf("/job/%s/paperwork", jobID), nil) if err != nil { return nil, err } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) if resp.StatusCode != 200 { return nil, fmt.Errorf("failed to get attachments: %s, response: %s", resp.Status, string(body)) } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { return nil, fmt.Errorf("error unmarshalling response: %v", err) } return result, nil } func (s *Session) DeleteAttachment(attachmentID string) error { resp, err := s.DoRequest("DELETE", fmt.Sprintf("/attachment/%s", attachmentID), nil) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != 200 && resp.StatusCode != 204 { body, _ := io.ReadAll(resp.Body) return fmt.Errorf("failed to delete attachment: %s, response: %s", resp.Status, string(body)) } return nil } func (s *Session) GetDeficiencyInfoForJob(jobID string) ([]map[string]interface{}, error) { resp, err := s.DoRequest("GET", fmt.Sprintf("/deficiency/%s", jobID), nil) if err != nil { return nil, err } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) if resp.StatusCode != 200 { return nil, fmt.Errorf("failed to get deficiency info: %s, response: %s", resp.Status, string(body)) } var result struct { Data []map[string]interface{} `json:"data"` } if err := json.Unmarshal(body, &result); err != nil { return nil, fmt.Errorf("error unmarshalling response: %v", err) } return result.Data, nil }