github.com/schmorrison/Zoho@v1.1.4/recruit/jobopenings.go (about)

     1  package recruit
     2  
     3  import (
     4  	"encoding/xml"
     5  	"fmt"
     6  	"strconv"
     7  	"time"
     8  
     9  	zoho "github.com/schmorrison/Zoho"
    10  )
    11  
    12  // https://www.zoho.com/recruit/developer-guide/apiv2/get-records.html
    13  func (c *API) GetJobOpenings(
    14  	params map[string]zoho.Parameter,
    15  ) (data JobOpeningsResponse, err error) {
    16  	endpoint := zoho.Endpoint{
    17  		Name: "GetJobOpenings",
    18  		URL: fmt.Sprintf(
    19  			"https://recruit.zoho.%s/recruit/v2/%s",
    20  			c.ZohoTLD,
    21  			JobOpeningsModule,
    22  		),
    23  		Method:       zoho.HTTPGet,
    24  		ResponseData: &JobOpeningsResponse{},
    25  		URLParameters: map[string]zoho.Parameter{
    26  			"fields":        "",
    27  			"sort_order":    "",
    28  			"sort_by":       "",
    29  			"converted":     "false",
    30  			"approved":      "true",
    31  			"page":          "1",
    32  			"per_page":      "200",
    33  			"cvid":          "",
    34  			"territory_id":  "",
    35  			"include_child": "",
    36  		},
    37  	}
    38  
    39  	if len(params) > 0 {
    40  		for k, v := range params {
    41  			endpoint.URLParameters[k] = v
    42  		}
    43  	}
    44  
    45  	err = c.Zoho.HTTPRequest(&endpoint)
    46  	if err != nil {
    47  		return JobOpeningsResponse{}, fmt.Errorf("failed to retrieve JobOpenings: %s", err)
    48  	}
    49  
    50  	if v, ok := endpoint.ResponseData.(*JobOpeningsResponse); ok {
    51  		return *v, nil
    52  	}
    53  
    54  	return JobOpeningsResponse{}, fmt.Errorf("no 'JobOpeningsResponse' returned")
    55  }
    56  
    57  // https://www.zoho.com/recruit/developer-guide/apiv2/get-records.html
    58  func (c *API) GetJobOpeningsById(id string) (data JobOpeningsResponse, err error) {
    59  	endpoint := zoho.Endpoint{
    60  		Name: "GetJobOpeningsById",
    61  		URL: fmt.Sprintf(
    62  			"https://recruit.zoho.%s/recruit/v2/%s/%s",
    63  			c.ZohoTLD,
    64  			JobOpeningsModule,
    65  			id,
    66  		),
    67  		Method:       zoho.HTTPGet,
    68  		ResponseData: &JobOpeningsResponse{},
    69  	}
    70  
    71  	err = c.Zoho.HTTPRequest(&endpoint)
    72  	if err != nil {
    73  		return JobOpeningsResponse{}, fmt.Errorf("failed to retrieve JobOpening with id: %s", err)
    74  	}
    75  
    76  	if v, ok := endpoint.ResponseData.(*JobOpeningsResponse); ok {
    77  		return *v, nil
    78  	}
    79  
    80  	return JobOpeningsResponse{}, fmt.Errorf("no 'JobOpeningsResponse' returned")
    81  }
    82  
    83  // https://www.zoho.com/recruit/developer-guide/apiv2/search-records.html
    84  func (c *API) SearchJobOpenings(
    85  	params map[string]zoho.Parameter,
    86  ) (data JobOpeningsResponse, err error) {
    87  	endpoint := zoho.Endpoint{
    88  		Name: "SearchJobOpenings",
    89  		URL: fmt.Sprintf(
    90  			"https://recruit.zoho.%s/recruit/v2/%s/search",
    91  			c.ZohoTLD,
    92  			JobOpeningsModule,
    93  		),
    94  		Method:       zoho.HTTPGet,
    95  		ResponseData: &JobOpeningsResponse{},
    96  		URLParameters: map[string]zoho.Parameter{
    97  			"per_page": "200",
    98  		},
    99  	}
   100  
   101  	if len(params) > 0 {
   102  		for k, v := range params {
   103  			endpoint.URLParameters[k] = v
   104  		}
   105  	}
   106  
   107  	// log.Printf("%+v\n", endpoint)
   108  
   109  	err = c.Zoho.HTTPRequest(&endpoint)
   110  	if err != nil {
   111  		return JobOpeningsResponse{}, fmt.Errorf(
   112  			"failed to retrieve searched %s: %s",
   113  			JobOpeningsModule,
   114  			err.Error(),
   115  		)
   116  	}
   117  
   118  	if v, ok := endpoint.ResponseData.(*JobOpeningsResponse); ok {
   119  		return *v, nil
   120  	}
   121  
   122  	return JobOpeningsResponse{}, fmt.Errorf("no 'JobOpeningsResponse' returned")
   123  }
   124  
   125  type JobOpening struct {
   126  	ClientName struct {
   127  		Name string `json:"name,omitempty"`
   128  		ID   string `json:"id,omitempty"`
   129  	} `json:"Client_Name,omitempty"`
   130  	Salary         interface{} `json:"Salary,omitempty"`
   131  	CurrencySymbol string      `json:"$currency_symbol,omitempty"`
   132  	AccountManager struct {
   133  		Name string `json:"name,omitempty"`
   134  		ID   string `json:"id,omitempty"`
   135  	} `json:"Account_Manager,omitempty"`
   136  	NoOfCandidatesHired int       `json:"No_of_Candidates_Hired,omitempty"`
   137  	TargetDate          string    `json:"Target_Date,omitempty"`
   138  	LastActivityTime    time.Time `json:"Last_Activity_Time,omitempty"`
   139  	Industry            string    `json:"Industry,omitempty"`
   140  	ModifiedBy          struct {
   141  		Name string `json:"name,omitempty"`
   142  		ID   string `json:"id,omitempty"`
   143  	} `json:"Modified_By,omitempty"`
   144  	ProcessFlow     bool   `json:"$process_flow,omitempty"`
   145  	ExpectedRevenue int    `json:"Expected_Revenue,omitempty"`
   146  	IsHotJobOpening bool   `json:"Is_Hot_Job_Opening,omitempty"`
   147  	ZipCode         string `json:"Zip_Code,omitempty"`
   148  	ID              string `json:"id,omitempty"`
   149  	Approved        bool   `json:"$approved,omitempty"`
   150  	Publish         bool   `json:"Publish,omitempty"`
   151  	DateOpened      string `json:"Date_Opened,omitempty"`
   152  	Approval        struct {
   153  		Delegate bool `json:"delegate,omitempty"`
   154  		Approve  bool `json:"approve,omitempty"`
   155  		Reject   bool `json:"reject,omitempty"`
   156  		Resubmit bool `json:"resubmit,omitempty"`
   157  	} `json:"$approval,omitempty"`
   158  	ModifiedTime             time.Time   `json:"Modified_Time,omitempty"`
   159  	ActualRevenue            interface{} `json:"Actual_Revenue,omitempty"`
   160  	RemoteJob                bool        `json:"Remote_Job,omitempty"`
   161  	CreatedTime              time.Time   `json:"Created_Time,omitempty"`
   162  	Followed                 bool        `json:"$followed,omitempty"`
   163  	NoOfCandidatesAssociated int         `json:"No_of_Candidates_Associated,omitempty"`
   164  	Editable                 bool        `json:"$editable,omitempty"`
   165  	IsLocked                 bool        `json:"Is_Locked,omitempty"`
   166  	City                     string      `json:"City,omitempty"`
   167  	JobOpeningStatus         string      `json:"Job_Opening_Status,omitempty"`
   168  	RevenuePerPosition       int         `json:"Revenue_per_Position,omitempty"`
   169  	ContactName              struct {
   170  		Name string `json:"name,omitempty"`
   171  		ID   string `json:"id,omitempty"`
   172  	} `json:"Contact_Name,omitempty"`
   173  	AssociatedTags []struct {
   174  		Name string `json:"name,omitempty"`
   175  		ID   string `json:"id,omitempty"`
   176  	} `json:"Associated_Tags,omitempty"`
   177  	AssignedRecruiter []struct {
   178  		Name     string `json:"name,omitempty"`
   179  		ID       string `json:"id,omitempty"`
   180  		Email    string `json:"email,omitempty"`
   181  		PhotoSrc string `json:"photoSrc,omitempty"`
   182  	} `json:"Assigned_Recruiter,omitempty"`
   183  	MissedRevenue     interface{} `json:"Missed_Revenue,omitempty"`
   184  	JobOpeningID      string      `json:"Job_Opening_ID,omitempty"`
   185  	JobDescription    string      `json:"Job_Description,omitempty"`
   186  	WorkExperience    string      `json:"Work_Experience,omitempty"`
   187  	JobType           string      `json:"Job_Type,omitempty"`
   188  	JobOpeningName    string      `json:"Job_Opening_Name,omitempty"`
   189  	NumberOfPositions string      `json:"Number_of_Positions,omitempty"`
   190  	State             string      `json:"State,omitempty"`
   191  	Country           string      `json:"Country,omitempty"`
   192  	CreatedBy         struct {
   193  		Name string `json:"name,omitempty"`
   194  		ID   string `json:"id,omitempty"`
   195  	} `json:"Created_By,omitempty"`
   196  	IsAttachmentPresent bool `json:"Is_Attachment_Present,omitempty"`
   197  }
   198  
   199  type JobOpeningsResponse struct {
   200  	Data []JobOpening `json:"data,omitempty"`
   201  	Info PageInfo     `json:"info,omitempty"`
   202  }
   203  
   204  // https://www.zoho.com/recruit/developer-guide/apiv2/get-associated-records.html
   205  func (c *API) GetAssociatedCandidates(
   206  	recordId string,
   207  ) (data AssociatedCandidatesResponse, err error) {
   208  	endpoint := zoho.Endpoint{
   209  		Name: "GetAssociatedCandidates",
   210  		URL: fmt.Sprintf(
   211  			"https://recruit.zoho.%s/recruit/v2/%s/%s/associate",
   212  			c.ZohoTLD,
   213  			Job_OpeningsModule,
   214  			recordId,
   215  		),
   216  		Method:       zoho.HTTPGet,
   217  		ResponseData: &AssociatedCandidatesResponse{},
   218  	}
   219  
   220  	err = c.Zoho.HTTPRequest(&endpoint)
   221  	if err != nil {
   222  		return AssociatedCandidatesResponse{}, fmt.Errorf(
   223  			"failed to get associated candidates of %s: %s",
   224  			JobOpeningsModule,
   225  			err.Error(),
   226  		)
   227  	}
   228  
   229  	if v, ok := endpoint.ResponseData.(*AssociatedCandidatesResponse); ok {
   230  		return *v, nil
   231  	}
   232  
   233  	return AssociatedCandidatesResponse{}, fmt.Errorf("no 'AssociatedCandidatesResponse' returned")
   234  }
   235  
   236  type AssociatedCandidatesResponse struct {
   237  	Data []struct {
   238  		Origin                   string      `json:"Origin"`
   239  		Email                    string      `json:"Email"`
   240  		CurrencySymbol           string      `json:"$currency_symbol"`
   241  		LastActivityTime         time.Time   `json:"Last_Activity_Time"`
   242  		HighestQualificationHeld interface{} `json:"Highest_Qualification_Held"`
   243  		SkillSet                 interface{} `json:"Skill_Set"`
   244  		Converted                bool        `json:"$converted"`
   245  		ProcessFlow              bool        `json:"$process_flow"`
   246  		UpdatedOn                time.Time   `json:"Updated_On"`
   247  		CurrentEmployer          string      `json:"Current_Employer"`
   248  		Street                   interface{} `json:"Street"`
   249  		ZipCode                  interface{} `json:"Zip_Code"`
   250  		ID                       string      `json:"id"`
   251  		ExperienceInYears        int         `json:"Experience_in_Years"`
   252  		Approved                 bool        `json:"$approved"`
   253  		Approval                 struct {
   254  			Delegate bool `json:"delegate"`
   255  			Approve  bool `json:"approve"`
   256  			Reject   bool `json:"reject"`
   257  			Resubmit bool `json:"resubmit"`
   258  		} `json:"$approval"`
   259  		CandidateStatus string      `json:"Candidate_Status"`
   260  		CandidateID     string      `json:"Candidate_ID"`
   261  		LastMailedTime  interface{} `json:"Last_Mailed_Time"`
   262  		CreatedTime     time.Time   `json:"Created_Time"`
   263  		Followed        bool        `json:"$followed"`
   264  		CandidateOwner  struct {
   265  			Name string `json:"name"`
   266  			ID   string `json:"id"`
   267  		} `json:"Candidate_Owner"`
   268  		Editable       bool          `json:"$editable"`
   269  		IsLocked       bool          `json:"Is_Locked"`
   270  		City           string        `json:"City"`
   271  		IsUnqualified  bool          `json:"Is_Unqualified"`
   272  		AssociatedTags []interface{} `json:"Associated_Tags"`
   273  		AdditionalInfo interface{}   `json:"Additional_Info"`
   274  		State          interface{}   `json:"State"`
   275  		Country        interface{}   `json:"Country"`
   276  		CreatedBy      struct {
   277  			Name string `json:"name"`
   278  			ID   string `json:"id"`
   279  		} `json:"Created_By"`
   280  		SecondaryEmail      interface{} `json:"Secondary_Email"`
   281  		IsAttachmentPresent bool        `json:"Is_Attachment_Present"`
   282  		Rating              interface{} `json:"Rating"`
   283  		AppliedWithLinkedin interface{} `json:"$applied_with_linkedin"`
   284  		Website             interface{} `json:"Website"`
   285  		Twitter             interface{} `json:"Twitter"`
   286  		CurrentJobTitle     string      `json:"Current_Job_Title"`
   287  		Salutation          interface{} `json:"Salutation"`
   288  		Source              string      `json:"Source"`
   289  		FirstName           string      `json:"First_Name"`
   290  		FullName            string      `json:"Full_Name"`
   291  		ModifiedBy          struct {
   292  			Name string `json:"name"`
   293  			ID   string `json:"id"`
   294  		} `json:"Modified_By"`
   295  		SkypeID         interface{} `json:"Skype_ID"`
   296  		Phone           interface{} `json:"Phone"`
   297  		EmailOptOut     bool        `json:"Email_Opt_Out"`
   298  		ConvertedDetail struct {
   299  		} `json:"$converted_detail"`
   300  		CareerPageInviteStatus      string      `json:"Career_Page_Invite_Status"`
   301  		Mobile                      string      `json:"Mobile"`
   302  		LastName                    string      `json:"Last_Name"`
   303  		CurrentSalary               interface{} `json:"Current_Salary"`
   304  		AssociatedAnySocialProfiles interface{} `json:"Associated_any_Social_Profiles"`
   305  		Fax                         interface{} `json:"Fax"`
   306  		ExpectedSalary              interface{} `json:"Expected_Salary"`
   307  	} `json:"data"`
   308  	Info PageInfo `json:"info,omitempty"`
   309  }
   310  
   311  // ============================== ABANDONED DUE TO ZOHO API v1 not properly working ==============================
   312  // https://help.zoho.com/portal/en/kb/recruit/developer-guide/api-methods/articles/getsearchrecords
   313  func (c *API) XMLSearchJobOpenings(
   314  	params map[string]zoho.Parameter,
   315  ) (data JobOpeningsResponse, err error) {
   316  	endpoint := zoho.Endpoint{
   317  		Name: "XMLSearchJobOpenings",
   318  		URL: fmt.Sprintf(
   319  			"https://recruit.zoho.%s/recruit/private/xml/%s/getSearchRecords",
   320  			c.ZohoTLD,
   321  			JobOpeningsModule,
   322  		),
   323  		Method:       zoho.HTTPGet,
   324  		ResponseData: &XMLJobOpeningsResponse{},
   325  		URLParameters: map[string]zoho.Parameter{
   326  			"fromIndex":       "1",     // Integer | Default value - 1
   327  			"toIndex":         "200",   // Integer | Default value - 20 | Maximum value - 200
   328  			"version":         "2",     // This will fetch responses based on the latest API implementation.
   329  			"newFormat":       "1",     // 1 - To exclude fields with "null" values while inserting data from your Recruit account.
   330  			"selectColumns":   "(ALL)", // mandatory eg: (Job Description) | Module(Job Description)
   331  			"searchCondition": "",      // mandatory eg: (Associated Tags|=|JobIsPublished)
   332  		},
   333  	}
   334  
   335  	if len(params) > 0 {
   336  		for k, v := range params {
   337  			endpoint.URLParameters[k] = v
   338  		}
   339  	}
   340  
   341  	// log.Printf("%s\n", endpoint)
   342  
   343  	err = c.Zoho.HTTPRequest(&endpoint)
   344  	if err != nil {
   345  		return JobOpeningsResponse{}, fmt.Errorf(
   346  			"failed to retrieve XML searched %s: %s",
   347  			JobOpeningsModule,
   348  			err.Error(),
   349  		)
   350  	}
   351  
   352  	if v, ok := endpoint.ResponseData.(*XMLJobOpeningsResponse); ok {
   353  		// Convert to Json
   354  		total, _ := strconv.Atoi(v.Result.JobOpenings.Row.No)
   355  		dataXML := v.Result.JobOpenings.Row.FL
   356  
   357  		res := &JobOpeningsResponse{}
   358  		items := make([]JobOpening, 0)
   359  
   360  		for i := 0; i <= total; i++ {
   361  			switch dataXML[i].Val {
   362  			case "JOBOPENINGID":
   363  				items = append(items, JobOpening{ID: dataXML[i].Text})
   364  			case "CLIENTID":
   365  				items = append(items, JobOpening{})
   366  			case "Client Name":
   367  				items = append(items, JobOpening{})
   368  			case "Posting Title":
   369  				items = append(items, JobOpening{JobOpeningName: dataXML[i].Text})
   370  			case "Job Opening ID":
   371  				items = append(items, JobOpening{JobOpeningID: dataXML[i].Text})
   372  			case "Job Description":
   373  				items = append(items, JobOpening{JobDescription: dataXML[i].Text})
   374  			}
   375  		}
   376  
   377  		res.Data = items
   378  
   379  		return *res, nil
   380  	}
   381  
   382  	return JobOpeningsResponse{}, fmt.Errorf("no 'JobOpeningsResponse' returned")
   383  }
   384  
   385  // https://help.zoho.com/portal/en/kb/recruit/developer-guide/api-methods/articles/getrecordbyid#Purpose
   386  func (c *API) XMLgetRecordById(params map[string]zoho.Parameter) (data JobOpening, err error) {
   387  	endpoint := zoho.Endpoint{
   388  		Name: "XMLgetRecordById",
   389  		URL: fmt.Sprintf(
   390  			"https://recruit.zoho.%s/recruit/private/xml/%s/getRecordById",
   391  			c.ZohoTLD,
   392  			JobOpeningsModule,
   393  		),
   394  		Method:       zoho.HTTPGet,
   395  		ResponseData: &XMLJobOpeningsResponse{},
   396  		URLParameters: map[string]zoho.Parameter{
   397  			"id":        "",  // mandatory
   398  			"version":   "2", // This will fetch responses based on the latest API implementation.
   399  			"newFormat": "1", // 1 - To exclude fields with "null" values while inserting data from your Recruit account.
   400  		},
   401  	}
   402  
   403  	if len(params) > 0 {
   404  		for k, v := range params {
   405  			endpoint.URLParameters[k] = v
   406  		}
   407  	}
   408  
   409  	// log.Printf("%s\n", endpoint)
   410  
   411  	err = c.Zoho.HTTPRequest(&endpoint)
   412  	if err != nil {
   413  		return JobOpening{}, fmt.Errorf(
   414  			"failed to retrieve XML searched %s: %s",
   415  			JobOpeningsModule,
   416  			err.Error(),
   417  		)
   418  	}
   419  
   420  	if v, ok := endpoint.ResponseData.(*XMLJobOpeningsResponse); ok {
   421  		// Convert to Json
   422  		xmlData := v.Result.JobOpenings.Row.FL
   423  		res := &data
   424  
   425  		for _, item := range xmlData {
   426  			switch item.Val {
   427  			case "Job Description":
   428  				data.JobDescription = item.Text
   429  			}
   430  		}
   431  		return *res, nil
   432  	}
   433  
   434  	return JobOpening{}, fmt.Errorf("no 'JobOpening' returned")
   435  }
   436  
   437  type XMLJobOpeningsResponse struct {
   438  	XMLName xml.Name `xml:"response"`
   439  	Text    string   `xml:",chardata"`
   440  	URI     string   `xml:"uri,attr"`
   441  	Result  struct {
   442  		Text        string `xml:",chardata"`
   443  		JobOpenings struct {
   444  			Text string `xml:",chardata"`
   445  			Row  struct {
   446  				Text string `xml:",chardata"`
   447  				No   string `xml:"no,attr"`
   448  				FL   []struct {
   449  					Text string `xml:",chardata"`
   450  					Val  string `xml:"val,attr"`
   451  				} `xml:"FL"`
   452  			} `xml:"row"`
   453  		} `xml:"JobOpenings"`
   454  	} `xml:"result"`
   455  }
   456  
   457  // https://help.zoho.com/portal/en/kb/recruit/developer-guide/api-methods/articles/getrecords#Request_Parameters
   458  func (c *API) XMLGetRecords(
   459  	params map[string]zoho.Parameter,
   460  ) (data XMLGetRecordsResponse, err error) {
   461  	endpoint := zoho.Endpoint{
   462  		Name: "XMLGetRecords",
   463  		URL: fmt.Sprintf(
   464  			"https://recruit.zoho.%s/recruit/private/xml/%s/getRecordById",
   465  			c.ZohoTLD,
   466  			JobOpeningsModule,
   467  		),
   468  		Method:       zoho.HTTPGet,
   469  		ResponseData: &XMLGetRecordsResponse{},
   470  		URLParameters: map[string]zoho.Parameter{
   471  			"version":       "2", // This will fetch responses based on the latest API implementation.
   472  			"id":            "",  // 1 - To exclude fields with "null" values while inserting data from your Recruit account.
   473  			"selectColumns": "",  // mandatory eg: (Job Description) | Module(Job Description)
   474  		},
   475  	}
   476  
   477  	if len(params) > 0 {
   478  		for k, v := range params {
   479  			endpoint.URLParameters[k] = v
   480  		}
   481  	}
   482  
   483  	// log.Printf("ENDPOINT: %s\n", endpoint)
   484  
   485  	err = c.Zoho.HTTPRequest(&endpoint)
   486  	if err != nil {
   487  		return XMLGetRecordsResponse{}, fmt.Errorf(
   488  			"failed to retrieve XML get %s: %s",
   489  			JobOpeningsModule,
   490  			err.Error(),
   491  		)
   492  	}
   493  
   494  	if v, ok := endpoint.ResponseData.(*XMLGetRecordsResponse); ok {
   495  		return *v, nil
   496  	}
   497  
   498  	return XMLGetRecordsResponse{}, fmt.Errorf("no 'XMLGetRecordsResponse' returned")
   499  }
   500  
   501  type XMLGetRecordsResponse struct {
   502  	XMLName xml.Name `xml:"response"`
   503  	Text    string   `xml:",chardata"`
   504  	URI     string   `xml:"uri,attr"`
   505  	Result  struct {
   506  		Text        string `xml:",chardata"`
   507  		JobOpenings struct {
   508  			Text string `xml:",chardata"`
   509  			Row  struct {
   510  				Text string `xml:",chardata"`
   511  				No   string `xml:"no,attr"`
   512  				FL   []struct {
   513  					Text string `xml:",chardata"`
   514  					Val  string `xml:"val,attr"`
   515  				} `xml:"FL"`
   516  			} `xml:"row"`
   517  		} `xml:"JobOpenings"`
   518  	} `xml:"result"`
   519  }