1 | |
2 | type Paylocity = { |
3 | clientId: string |
4 | clientSecret: string |
5 | } |
6 | |
7 | * Update employee |
8 | * Update Employee API will update existing employee data in WebPay. |
9 | */ |
10 | export async function main( |
11 | auth: Paylocity, |
12 | companyId: string, |
13 | employeeId: string, |
14 | body: { |
15 | additionalDirectDeposit?: { |
16 | accountNumber?: string |
17 | accountType?: string |
18 | amount?: number |
19 | amountType?: string |
20 | blockSpecial?: false | true |
21 | isSkipPreNote?: false | true |
22 | nameOnAccount?: string |
23 | preNoteDate?: string |
24 | routingNumber?: string |
25 | }[] |
26 | additionalRate?: { |
27 | changeReason?: string |
28 | costCenter1?: string |
29 | costCenter2?: string |
30 | costCenter3?: string |
31 | effectiveDate?: string |
32 | endCheckDate?: string |
33 | job?: string |
34 | rate?: number |
35 | rateCode?: string |
36 | rateNotes?: string |
37 | ratePer?: string |
38 | shift?: string |
39 | }[] |
40 | benefitSetup?: { |
41 | benefitClass?: string |
42 | benefitClassEffectiveDate?: string |
43 | benefitSalary?: number |
44 | benefitSalaryEffectiveDate?: string |
45 | doNotApplyAdministrativePeriod?: false | true |
46 | isMeasureAcaEligibility?: false | true |
47 | } |
48 | birthDate?: string |
49 | companyName?: string |
50 | currency?: string |
51 | customBooleanFields?: { |
52 | category: 'PayrollAndHR' |
53 | label: string |
54 | value: false | true |
55 | }[] |
56 | customDateFields?: { |
57 | category: 'PayrollAndHR' |
58 | label: string |
59 | value: string |
60 | }[] |
61 | customDropDownFields?: { |
62 | category: 'PayrollAndHR' |
63 | label: string |
64 | value: string |
65 | }[] |
66 | customNumberFields?: { |
67 | category: 'PayrollAndHR' |
68 | label: string |
69 | value: number |
70 | }[] |
71 | customTextFields?: { |
72 | category: 'PayrollAndHR' |
73 | label: string |
74 | value: string |
75 | }[] |
76 | departmentPosition?: { |
77 | changeReason?: string |
78 | clockBadgeNumber?: string |
79 | costCenter1?: string |
80 | costCenter2?: string |
81 | costCenter3?: string |
82 | effectiveDate?: string |
83 | employeeType?: string |
84 | equalEmploymentOpportunityClass?: string |
85 | isMinimumWageExempt?: false | true |
86 | isOvertimeExempt?: false | true |
87 | isSupervisorReviewer?: false | true |
88 | isUnionDuesCollected?: false | true |
89 | isUnionInitiationCollected?: false | true |
90 | jobTitle?: string |
91 | payGroup?: string |
92 | positionCode?: string |
93 | reviewerCompanyNumber?: string |
94 | reviewerEmployeeId?: string |
95 | shift?: string |
96 | supervisorCompanyNumber?: string |
97 | supervisorEmployeeId?: string |
98 | tipped?: string |
99 | unionAffiliationDate?: string |
100 | unionCode?: string |
101 | unionPosition?: string |
102 | workersCompensation?: string |
103 | } |
104 | disabilityDescription?: string |
105 | emergencyContacts?: { |
106 | address1?: string |
107 | address2?: string |
108 | city?: string |
109 | country?: string |
110 | county?: string |
111 | email?: string |
112 | firstName: string |
113 | homePhone?: string |
114 | lastName: string |
115 | mobilePhone?: string |
116 | notes?: string |
117 | pager?: string |
118 | primaryPhone?: string |
119 | priority?: string |
120 | relationship?: string |
121 | state?: string |
122 | syncEmployeeInfo?: false | true |
123 | workExtension?: string |
124 | workPhone?: string |
125 | zip?: string |
126 | }[] |
127 | employeeId?: string |
128 | ethnicity?: string |
129 | federalTax?: { |
130 | amount?: number |
131 | exemptions?: number |
132 | filingStatus?: string |
133 | percentage?: number |
134 | taxCalculationCode?: string |
135 | } |
136 | firstName?: string |
137 | gender?: string |
138 | homeAddress?: { |
139 | address1?: string |
140 | address2?: string |
141 | city?: string |
142 | country?: string |
143 | county?: string |
144 | emailAddress?: string |
145 | mobilePhone?: string |
146 | phone?: string |
147 | postalCode?: string |
148 | state?: string |
149 | } |
150 | isHighlyCompensated?: false | true |
151 | isSmoker?: false | true |
152 | lastName?: string |
153 | localTax?: { |
154 | exemptions?: number |
155 | exemptions2?: number |
156 | filingStatus?: string |
157 | residentPSD?: string |
158 | taxCode?: string |
159 | workPSD?: string |
160 | }[] |
161 | mainDirectDeposit?: { |
162 | accountNumber?: string |
163 | accountType?: string |
164 | blockSpecial?: false | true |
165 | isSkipPreNote?: false | true |
166 | nameOnAccount?: string |
167 | preNoteDate?: string |
168 | routingNumber?: string |
169 | } |
170 | maritalStatus?: string |
171 | middleName?: string |
172 | nonPrimaryStateTax?: { |
173 | amount?: number |
174 | exemptions?: number |
175 | exemptions2?: number |
176 | filingStatus?: string |
177 | percentage?: number |
178 | reciprocityCode?: string |
179 | specialCheckCalc?: string |
180 | taxCalculationCode?: string |
181 | taxCode?: string |
182 | } |
183 | ownerPercent?: number |
184 | preferredName?: string |
185 | primaryPayRate?: { |
186 | annualSalary?: number |
187 | baseRate?: number |
188 | beginCheckDate?: string |
189 | changeReason?: string |
190 | defaultHours?: number |
191 | effectiveDate?: string |
192 | isAutoPay?: false | true |
193 | payFrequency?: string |
194 | payGrade?: string |
195 | payRateNote?: string |
196 | payType?: string |
197 | ratePer?: string |
198 | salary?: number |
199 | } |
200 | primaryStateTax?: { |
201 | amount?: number |
202 | exemptions?: number |
203 | exemptions2?: number |
204 | filingStatus?: string |
205 | percentage?: number |
206 | specialCheckCalc?: string |
207 | taxCalculationCode?: string |
208 | taxCode?: string |
209 | } |
210 | priorLastName?: string |
211 | salutation?: string |
212 | ssn?: string |
213 | status?: { |
214 | adjustedSeniorityDate?: string |
215 | changeReason?: string |
216 | effectiveDate?: string |
217 | employeeStatus?: string |
218 | hireDate?: string |
219 | isEligibleForRehire?: false | true |
220 | reHireDate?: string |
221 | } |
222 | suffix?: string |
223 | taxSetup?: { |
224 | fitwExemptNotes?: string |
225 | fitwExemptReason?: string |
226 | futaExemptNotes?: string |
227 | futaExemptReason?: string |
228 | isEmployee943?: false | true |
229 | isPension?: false | true |
230 | isStatutory?: false | true |
231 | medExemptNotes?: string |
232 | medExemptReason?: string |
233 | sitwExemptNotes?: string |
234 | sitwExemptReason?: string |
235 | ssExemptNotes?: string |
236 | ssExemptReason?: string |
237 | suiExemptNotes?: string |
238 | suiExemptReason?: string |
239 | suiState?: string |
240 | taxDistributionCode1099R?: string |
241 | taxForm?: string |
242 | } |
243 | veteranDescription?: string |
244 | webTime?: { |
245 | badgeNumber?: string |
246 | chargeRate?: number |
247 | isTimeLaborEnabled?: false | true |
248 | } |
249 | workAddress?: { |
250 | address1?: string |
251 | address2?: string |
252 | city?: string |
253 | country?: string |
254 | county?: string |
255 | emailAddress?: string |
256 | location?: string |
257 | mailStop?: string |
258 | mobilePhone?: string |
259 | pager?: string |
260 | phone?: string |
261 | phoneExtension?: string |
262 | postalCode?: string |
263 | state?: string |
264 | } |
265 | workEligibility?: { |
266 | alienOrAdmissionDocumentNumber?: string |
267 | attestedDate?: string |
268 | countryOfIssuance?: string |
269 | foreignPassportNumber?: string |
270 | i94AdmissionNumber?: string |
271 | i9DateVerified?: string |
272 | i9Notes?: string |
273 | isI9Verified?: false | true |
274 | isSsnVerified?: false | true |
275 | ssnDateVerified?: string |
276 | ssnNotes?: string |
277 | visaType?: string |
278 | workAuthorization?: string |
279 | workUntil?: string |
280 | } |
281 | } |
282 | ) { |
283 | const url = new URL( |
284 | `https://dc1prodgwext.paylocity.com/api/v2/companies/${companyId}/employees/${employeeId}` |
285 | ) |
286 |
|
287 | const response = await fetch(url, { |
288 | method: 'PATCH', |
289 | headers: { |
290 | 'Content-Type': 'application/json', |
291 | Authorization: |
292 | 'Bearer ' + |
293 | (await getOAuthToken(auth, 'https://dc1prodgwext.paylocity.com/public/security/v1/token')) |
294 | }, |
295 | body: JSON.stringify(body) |
296 | }) |
297 | if (!response.ok) { |
298 | const text = await response.text() |
299 | throw new Error(`${response.status} ${text}`) |
300 | } |
301 | return await response.text() |
302 | } |
303 |
|
304 | async function getOAuthToken(auth: Paylocity, tokenUrl: string): Promise<string> { |
305 | const params = new URLSearchParams({ |
306 | grant_type: 'client_credentials', |
307 | client_id: auth.clientId, |
308 | client_secret: auth.clientSecret |
309 | }) |
310 |
|
311 | const response = await fetch(tokenUrl, { |
312 | method: 'POST', |
313 | headers: { |
314 | Authorization: 'Basic ' + btoa(`${auth.clientId}:${auth.clientSecret}`), |
315 | 'Content-Type': 'application/x-www-form-urlencoded' |
316 | }, |
317 | body: params.toString() |
318 | }) |
319 |
|
320 | if (!response.ok) { |
321 | const text = await response.text() |
322 | throw new Error(`OAuth token request failed: ${response.status} ${text}`) |
323 | } |
324 |
|
325 | const data = await response.json() |
326 | return data.access_token |
327 | } |
328 |
|