From fce2edfa3ffcc31d8a8c1c695fd94fdfc542ba2c Mon Sep 17 00:00:00 2001 From: Anki Batsukh Date: Thu, 28 Sep 2023 11:24:06 +0200 Subject: [PATCH 01/20] update lumpsum service api to v2 and prepare for pagination --- src/clockodo.ts | 73 +++++++++++++++++++++++++++++++++++---- src/lib/api.ts | 1 + src/lib/requiredParams.ts | 3 ++ 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/clockodo.ts b/src/clockodo.ts index 0fe3db8b..e1d1f47a 100644 --- a/src/clockodo.ts +++ b/src/clockodo.ts @@ -291,14 +291,33 @@ export class Clockodo { const { id, ...remainingParams } = params; - return this.api.get("/lumpsumservices/" + id, remainingParams); + return this.api.get("/v2/lumpsumservices/" + id, remainingParams); } // This endpoint still uses the old lumpSum casing async getLumpSumServices( - params?: Params + params?: Params + ): Promise> { + const pages = await this.api.getAllPages( + "/v2/lumpsumservices", + params + ); + const [{ paging, ...remainingResponse }] = pages; + const lumpSumServices = pages.flatMap( + ({ lumpSumServices }) => lumpSumServices + ); + + return { + ...remainingResponse, + lumpSumServices, + }; + } + + // This endpoint still uses the old lumpSum casing + async getLumpSumServicesPage( + params?: Params ): Promise { - return this.api.get("/lumpsumservices", params); + return this.api.get("/v2/lumpsumservices", params); } async getTargethoursRow( @@ -396,6 +415,16 @@ export class Clockodo { return this.api.post("/v2/customers", params); } + async addLumpsumService( + params: Params< + Pick + > + ): Promise { + REQUIRED.checkRequired(params, REQUIRED.ADD_LUMPSUM_SERVICE); + + return this.api.post("/v2/lumpsumservices", params); + } + async addEntry( params: Params< | Pick @@ -499,6 +528,18 @@ export class Clockodo { return this.api.put("/v2/customers/" + id, params); } + async editLumpsumService( + params: Params< + Pick + > + ) { + REQUIRED.checkRequired(params, REQUIRED.EDIT_LUMPSUM_SERVICE); + + const { id } = params; + + return this.api.put("/v2/lumpsumservices/" + id, params); + } + async editEntry( params: Params> ): Promise { @@ -617,6 +658,16 @@ export class Clockodo { return this.api.delete("/v2/entries/" + id, params); } + async deleteLumpsumService( + params: Params> + ): Promise { + REQUIRED.checkRequired(params, REQUIRED.DELETE_LUMPSUM_SERVICE); + + const { id } = params; + + return this.api.delete("/v2/lumpsumservices/" + id, params); + } + async deleteEntryGroup( params: Params<{ timeSince: string; timeUntil: string }> ): Promise { @@ -800,14 +851,22 @@ export type ServiceReturnType = { service: Service }; export type ServicesReturnType = { services: Array }; export type TeamReturnType = { team: Team }; export type TeamsReturnType = { teams: Array }; + +export type LumpsumServiceParams = { + /** Filter lumpsum service by search term */ + filterFulltext?: string; + /** Filter lumpsum service by active flag */ + filterActive?: boolean; +}; export type LumpsumServiceReturnType = { // This endpoint still uses the old lumpSum casing lumpSumService: LumpsumService; }; -export type LumpsumServicesReturnType = { - // This endpoint still uses the old lumpSum casing - lumpSumServices: Array; -}; +export type LumpsumServicesReturnType = ResponseWithPaging & + ResponseWithFilter<"active" | "fulltext"> & { + // This endpoint still uses the old lumpSum casing + lumpSumServices: Array; + }; export type UserReturnType = { user: User }; export type UsersReturnType = { users: Array }; export type EntryReturnType = { entry: Entry }; diff --git a/src/lib/api.ts b/src/lib/api.ts index 2a922740..0c456c5d 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -53,6 +53,7 @@ export type Filter = { timeSince: string; timeUntil: string; active: BooleanAsNumber; + fulltext: string; }; export type ResponseWithPaging = { diff --git a/src/lib/requiredParams.ts b/src/lib/requiredParams.ts index 5df18778..1f823579 100644 --- a/src/lib/requiredParams.ts +++ b/src/lib/requiredParams.ts @@ -1,5 +1,6 @@ export const ADD_ABSENCE = ["dateSince", "dateUntil", "type"] as const; export const ADD_CUSTOMER = ["name"] as const; +export const ADD_LUMPSUM_SERVICE = ["name", "price"] as const; export const ADD_TIME_ENTRY = [ "customersId", "servicesId", @@ -35,10 +36,12 @@ export const DEACTIVATE_PROJECT = ["id"] as const; export const DEACTIVATE_SERVICE = ["id"] as const; export const DEACTIVATE_USER = ["id"] as const; export const DELETE_ENTRY = ["id"] as const; +export const DELETE_LUMPSUM_SERVICE = ["id"] as const; export const DELETE_ENTRY_GROUP = ["timeSince", "timeUntil"] as const; export const DELETE_ABSENCE = ["id"] as const; export const DELETE_TEAM = ["id"] as const; export const EDIT_CUSTOMER = ["id"] as const; +export const EDIT_LUMPSUM_SERVICE = ["id"] as const; export const EDIT_PROJECT = ["id"] as const; export const EDIT_SERVICE = ["id"] as const; export const EDIT_TEAM = ["id"] as const; From dfe93cca77b157ae8fe4343bda55927cdddcdfe8 Mon Sep 17 00:00:00 2001 From: Anki Batsukh Date: Mon, 2 Oct 2023 10:26:29 +0200 Subject: [PATCH 02/20] allow pagination request with itemsPerPage --- src/lib/api.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/api.ts b/src/lib/api.ts index 0c456c5d..22fec2db 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -29,6 +29,7 @@ export type Params< export type ParamsWithPage = { page?: number; + itemsPerPage?: number; }; export type Paging = { From d89cb1898002f94548ed1643a8661975bdb02125 Mon Sep 17 00:00:00 2001 From: Anki Batsukh Date: Tue, 3 Oct 2023 10:16:23 +0200 Subject: [PATCH 03/20] add fulltext filter to mapping --- src/lib/mappings.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/mappings.ts b/src/lib/mappings.ts index c7a93c90..dfa37374 100644 --- a/src/lib/mappings.ts +++ b/src/lib/mappings.ts @@ -20,6 +20,7 @@ export const queryParamMapping: Record = { filterTimeSince: "filter[time_since]", filterTimeUntil: "filter[time_until]", filterActive: "filter[active]", + filterFulltext: "filter[fulltext]", // excludeIds needs to stay in camelCase. // This seems to be an inconsistency in the API. excludeIds: "excludeIds", From 794198d9dced2738b53043c3064e6a452c1eee57 Mon Sep 17 00:00:00 2001 From: Anki Batsukh Date: Thu, 5 Oct 2023 11:47:14 +0200 Subject: [PATCH 04/20] update service API to /v2 --- src/clockodo.test.ts | 18 ++++++------ src/clockodo.ts | 57 +++++++++++++++++++++++++++---------- src/lib/requiredParams.ts | 6 ++-- src/mocks.ts | 1 + src/models/service.mocks.ts | 16 +++++++++++ 5 files changed, 71 insertions(+), 27 deletions(-) create mode 100644 src/models/service.mocks.ts diff --git a/src/clockodo.test.ts b/src/clockodo.test.ts index 6ea23587..7095af8a 100644 --- a/src/clockodo.test.ts +++ b/src/clockodo.test.ts @@ -1052,37 +1052,37 @@ describe("Clockodo (instance)", () => { }); }); - describe("deactivateCustomer()", () => { - it("correctly builds deactivateCustomer() request", async () => { + describe("deleteCustomer()", () => { + it("correctly builds deleteCustomer() request", async () => { const nockScope = nock(CLOCKODO_API) .delete("/v2/customers/343") .reply(200, {}); - await clockodo.deactivateCustomer({ id: 343 }); + await clockodo.deleteCustomer({ id: 343 }); nockScope.done(); }); }); - describe("deactivateProject()", () => { - it("correctly builds deactivateProject() request", async () => { + describe("deleteProject()", () => { + it("correctly builds deleteProject() request", async () => { const nockScope = nock(CLOCKODO_API) .delete("/v2/projects/8") .reply(200, {}); - await clockodo.deactivateProject({ id: 8 }); + await clockodo.deleteProject({ id: 8 }); nockScope.done(); }); }); - describe("deactivateService()", () => { - it("correctly builds deactivateService() request", async () => { + describe("deleteService()", () => { + it("correctly builds deleteService() request", async () => { const nockScope = nock(CLOCKODO_API) .delete("/services/94") .reply(200, {}); - await clockodo.deactivateService({ id: 94 }); + await clockodo.deleteService({ id: 94 }); nockScope.done(); }); diff --git a/src/clockodo.ts b/src/clockodo.ts index e1d1f47a..7ccc100d 100644 --- a/src/clockodo.ts +++ b/src/clockodo.ts @@ -267,8 +267,26 @@ export class Clockodo { return this.api.get("/services/" + id, remainingParams); } - async getServices(params?: Params): Promise { - return this.api.get("/services", params); + async getServices( + params?: Params + ): Promise> { + const pages = await this.api.getAllPages( + "/v2/services", + params + ); + const [{ paging, ...remainingResponse }] = pages; + const services = pages.flatMap(({ services }) => services); + + return { + ...remainingResponse, + services, + }; + } + + async getServicesPage( + params?: Params + ): Promise { + return this.api.get("/v2/services", params); } async getTeam(params: Params<{ id: Team["id"] }>): Promise { @@ -459,7 +477,7 @@ export class Clockodo { ): Promise { REQUIRED.checkRequired(params, REQUIRED.ADD_SERVICE); - return this.api.post("/services", params); + return this.api.post("/v2/services", params); } async addTeam( @@ -575,7 +593,7 @@ export class Clockodo { const { id } = params; - return this.api.put("/services/" + id, params); + return this.api.put("/v2/services/" + id, params); } async editTeam( @@ -598,34 +616,34 @@ export class Clockodo { return this.api.put("/users/" + id, params); } - async deactivateCustomer( - params: Params> + async deleteCustomer( + params: Params> ): Promise { - REQUIRED.checkRequired(params, REQUIRED.DEACTIVATE_CUSTOMER); + REQUIRED.checkRequired(params, REQUIRED.DELETE_CUSTOMER); const { id } = params; return this.api.delete("/v2/customers/" + id, params); } - async deactivateProject( - params: Params> + async deleteProject( + params: Params> ): Promise { - REQUIRED.checkRequired(params, REQUIRED.DEACTIVATE_PROJECT); + REQUIRED.checkRequired(params, REQUIRED.DELETE_PROJECT); const { id } = params; return this.api.delete("/v2/projects/" + id, params); } - async deactivateService( - params: Params> + async deleteService( + params: Params> ): Promise { - REQUIRED.checkRequired(params, REQUIRED.DEACTIVATE_SERVICE); + REQUIRED.checkRequired(params, REQUIRED.DELETE_SERVICE); const { id } = params; - return this.api.delete("/services/" + id, params); + return this.api.delete("/v2/services/" + id, params); } async deactivateUser( @@ -847,8 +865,17 @@ export type ProjectsReturnType = ResponseWithPaging & projects: Array; }; export type ProjectReturnType = { project: Project }; + +export type ServiceParams = { + /** Filter service by search term */ + filterFulltext?: string; + /** Filter service by active flag */ + filterActive?: boolean; +}; export type ServiceReturnType = { service: Service }; -export type ServicesReturnType = { services: Array }; +export type ServicesReturnType = ResponseWithPaging & + ResponseWithFilter<"active" | "fulltext"> & { services: Array }; + export type TeamReturnType = { team: Team }; export type TeamsReturnType = { teams: Array }; diff --git a/src/lib/requiredParams.ts b/src/lib/requiredParams.ts index 1f823579..7527c8cd 100644 --- a/src/lib/requiredParams.ts +++ b/src/lib/requiredParams.ts @@ -31,11 +31,11 @@ export const CHANGE_CLOCK_DURATION = [ "durationBefore", "duration", ] as const; -export const DEACTIVATE_CUSTOMER = ["id"] as const; -export const DEACTIVATE_PROJECT = ["id"] as const; -export const DEACTIVATE_SERVICE = ["id"] as const; +export const DELETE_CUSTOMER = ["id"] as const; +export const DELETE_PROJECT = ["id"] as const; export const DEACTIVATE_USER = ["id"] as const; export const DELETE_ENTRY = ["id"] as const; +export const DELETE_SERVICE = ["id"] as const; export const DELETE_LUMPSUM_SERVICE = ["id"] as const; export const DELETE_ENTRY_GROUP = ["timeSince", "timeUntil"] as const; export const DELETE_ABSENCE = ["id"] as const; diff --git a/src/mocks.ts b/src/mocks.ts index c9b9646e..e90b0502 100644 --- a/src/mocks.ts +++ b/src/mocks.ts @@ -7,6 +7,7 @@ export * from "./models/entry.mocks.js"; // export * from "./models/holidayscarry.mocks.js"; // export * from "./models/holidaysquota.mocks.js"; export * from "./models/lumpsumService.mocks.js"; +export * from "./models/service.mocks.js"; export * from "./models/nonbusinessDay.mocks.js"; export * from "./models/project.mocks.js"; // export * from "./models/service.mocks.js"; diff --git a/src/models/service.mocks.ts b/src/models/service.mocks.ts new file mode 100644 index 00000000..df934fe9 --- /dev/null +++ b/src/models/service.mocks.ts @@ -0,0 +1,16 @@ +import { faker } from "@faker-js/faker"; +import { Service } from "./Service.js"; + +export const createServiceMocks = ({ count = 1 }: { count?: number } = {}) => + Array.from({ length: count }, (_, index): Service => { + return { + id: index, + name: faker.commerce.productName(), + number: faker.datatype.hexadecimal(), + active: faker.datatype.boolean(), + note: + index % 2 === 0 + ? null + : faker.lorem.sentences(faker.datatype.number({ min: 1, max: 3 })), + }; + }); From b0629465e8213cd3e5ef8e6e29acf9fa6eb1bab2 Mon Sep 17 00:00:00 2001 From: Dominik Sumer Date: Mon, 9 Oct 2023 15:45:58 +0200 Subject: [PATCH 05/20] feat: added overtimecarry model and api request --- src/clockodo.ts | 17 +++++++++++++++++ src/index.ts | 1 + src/mocks.ts | 1 + src/models/overtimecarry.mocks.ts | 16 ++++++++++++++++ src/models/overtimecarry.ts | 12 ++++++++++++ 5 files changed, 47 insertions(+) create mode 100644 src/models/overtimecarry.mocks.ts create mode 100644 src/models/overtimecarry.ts diff --git a/src/clockodo.ts b/src/clockodo.ts index 0fe3db8b..ecae70b6 100644 --- a/src/clockodo.ts +++ b/src/clockodo.ts @@ -41,6 +41,7 @@ import { WorkTimeChangeRequestStatus, WorkTimeDay, } from "./models/workTimes.js"; +import { OvertimecarryRow } from "./models/overtimecarry.js"; export class Clockodo { api: Api; @@ -765,6 +766,12 @@ export class Clockodo { remainingParams ); } + + async getOvertimecarry( + params?: Params + ): Promise { + return this.api.get("/overtimecarry", params); + } } export type AbsenceReturnType = { absence: Absence }; @@ -1053,3 +1060,13 @@ export type AddWorkTimesChangeRequestReturnType = **/ replacedChangeRequest: null; }; + +export type OvertimecarryRowReturnType = { + overtimecarry: Array; +}; +export type OvertimecarryRowParams = { + /** The user ID by which the overtime carry rows should be filtered */ + usersId?: number; + /** The year to which the data should be restricted to */ + year?: number; +}; diff --git a/src/index.ts b/src/index.ts index f7c29bf8..8ef76776 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ export * from "./models/holidaysquota.js"; export * from "./models/lumpsumService.js"; export * from "./models/nonbusinessDay.js"; export * from "./models/nonbusinessGroup.js"; +export * from "./models/overtimecarry.js"; export * from "./models/project.js"; export * from "./models/service.js"; export * from "./models/targethours.js"; diff --git a/src/mocks.ts b/src/mocks.ts index c9b9646e..fdae7fa8 100644 --- a/src/mocks.ts +++ b/src/mocks.ts @@ -8,6 +8,7 @@ export * from "./models/entry.mocks.js"; // export * from "./models/holidaysquota.mocks.js"; export * from "./models/lumpsumService.mocks.js"; export * from "./models/nonbusinessDay.mocks.js"; +export * from "./models/overtimecarry.mocks.js"; export * from "./models/project.mocks.js"; // export * from "./models/service.mocks.js"; export * from "./models/targethours.mocks.js"; diff --git a/src/models/overtimecarry.mocks.ts b/src/models/overtimecarry.mocks.ts new file mode 100644 index 00000000..cb30d58f --- /dev/null +++ b/src/models/overtimecarry.mocks.ts @@ -0,0 +1,16 @@ +import { faker } from "@faker-js/faker"; +import { OvertimecarryRow } from "./overtimecarry.js"; + +export const createOvertimecarryMocks = ({ + count = 1, + usersId = 0, +}: { count?: number; usersId?: number } = {}) => { + return Array.from({ length: count }, (): OvertimecarryRow => { + return { + usersId, + year: faker.datatype.number({ min: 1900, max: 2024 }), + note: faker.datatype.boolean() ? faker.lorem.sentences(2) : null, + hours: faker.datatype.number({ min: 0, max: 100 }), + }; + }); +}; diff --git a/src/models/overtimecarry.ts b/src/models/overtimecarry.ts new file mode 100644 index 00000000..7053c693 --- /dev/null +++ b/src/models/overtimecarry.ts @@ -0,0 +1,12 @@ +export type OvertimecarryRow = { + /** The related employee's ID */ + usersId: number; + /** + * Year for which the overtime carryover applies + * Format YYYY + */ + year: number; + /** Number of hours */ + hours: number; + note: string | null; +}; From 3f9ec6f06a800cf4d77791fb8d17638f0021aa57 Mon Sep 17 00:00:00 2001 From: Anki Batsukh Date: Tue, 10 Oct 2023 10:26:15 +0200 Subject: [PATCH 06/20] typo --- src/models/service.mocks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/service.mocks.ts b/src/models/service.mocks.ts index df934fe9..0a2528d2 100644 --- a/src/models/service.mocks.ts +++ b/src/models/service.mocks.ts @@ -1,5 +1,5 @@ import { faker } from "@faker-js/faker"; -import { Service } from "./Service.js"; +import { Service } from "./service.js"; export const createServiceMocks = ({ count = 1 }: { count?: number } = {}) => Array.from({ length: count }, (_, index): Service => { From b5e1a52412ec877124d095e4d90ed90d599a7d85 Mon Sep 17 00:00:00 2001 From: Dominik Sumer Date: Tue, 10 Oct 2023 16:40:27 +0200 Subject: [PATCH 07/20] updated users api to v2 --- src/clockodo.ts | 16 ++++++++-------- src/lib/requiredParams.ts | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/clockodo.ts b/src/clockodo.ts index 0fe3db8b..dbce4e08 100644 --- a/src/clockodo.ts +++ b/src/clockodo.ts @@ -322,11 +322,11 @@ export class Clockodo { const { id, ...remainingParams } = params; - return this.api.get("/users/" + id, remainingParams); + return this.api.get("/v2/users/" + id, remainingParams); } async getUsers(params?: Params): Promise { - return this.api.get("/users", params); + return this.api.get("/v2/users", params); } async getUserReport< @@ -446,7 +446,7 @@ export class Clockodo { ): Promise { REQUIRED.checkRequired(params, REQUIRED.ADD_USER); - return this.api.post("/users", params); + return this.api.post("/v2/users", params); } async startClock( @@ -554,7 +554,7 @@ export class Clockodo { const { id } = params; - return this.api.put("/users/" + id, params); + return this.api.put("/v2/users/" + id, params); } async deactivateCustomer( @@ -587,14 +587,14 @@ export class Clockodo { return this.api.delete("/services/" + id, params); } - async deactivateUser( - params: Params> + async deleteUser( + params: Params> ): Promise { - REQUIRED.checkRequired(params, REQUIRED.DEACTIVATE_USER); + REQUIRED.checkRequired(params, REQUIRED.DELETE_USER); const { id } = params; - return this.api.delete("/users/" + id, params); + return this.api.delete("/v2/users/" + id, params); } async deleteAbsence( diff --git a/src/lib/requiredParams.ts b/src/lib/requiredParams.ts index 5df18778..08bb66a3 100644 --- a/src/lib/requiredParams.ts +++ b/src/lib/requiredParams.ts @@ -33,7 +33,7 @@ export const CHANGE_CLOCK_DURATION = [ export const DEACTIVATE_CUSTOMER = ["id"] as const; export const DEACTIVATE_PROJECT = ["id"] as const; export const DEACTIVATE_SERVICE = ["id"] as const; -export const DEACTIVATE_USER = ["id"] as const; +export const DELETE_USER = ["id"] as const; export const DELETE_ENTRY = ["id"] as const; export const DELETE_ENTRY_GROUP = ["timeSince", "timeUntil"] as const; export const DELETE_ABSENCE = ["id"] as const; From 970e82de00980c90f31155f52f0f93fc87a5240f Mon Sep 17 00:00:00 2001 From: Dominik Sumer Date: Tue, 10 Oct 2023 16:56:54 +0200 Subject: [PATCH 08/20] updated readme and test --- README.md | 6 +++--- src/clockodo.test.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 33f72493..38eb1c57 100644 --- a/README.md +++ b/README.md @@ -790,14 +790,14 @@ await clockodo.deactivateService({ id: 94 }); --- -### deactivateUser() +### deleteUser() -Deactivates (not deletes) user. +Deletes user. #### Example: ```js -await clockodo.deactivateUser({ id: 7 }); +await clockodo.deleteUser({ id: 7 }); ``` --- diff --git a/src/clockodo.test.ts b/src/clockodo.test.ts index 6ea23587..65fc9271 100644 --- a/src/clockodo.test.ts +++ b/src/clockodo.test.ts @@ -1088,11 +1088,11 @@ describe("Clockodo (instance)", () => { }); }); - describe("deactivateUser()", () => { - it("correctly builds deactivateUser() request", async () => { + describe("deleteUser()", () => { + it("correctly builds deleteUser() request", async () => { const nockScope = nock(CLOCKODO_API).delete("/users/7").reply(200, {}); - await clockodo.deactivateUser({ id: 7 }); + await clockodo.deleteUser({ id: 7 }); nockScope.done(); }); From 24a4ea37002d86f3b9e50c301867ca9538715e7c Mon Sep 17 00:00:00 2001 From: Anki Batsukh Date: Wed, 11 Oct 2023 16:05:00 +0200 Subject: [PATCH 09/20] update tests --- src/clockodo.test.ts | 117 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 6 deletions(-) diff --git a/src/clockodo.test.ts b/src/clockodo.test.ts index 7095af8a..d911be21 100644 --- a/src/clockodo.test.ts +++ b/src/clockodo.test.ts @@ -194,6 +194,46 @@ describe("Clockodo (instance)", () => { }); }); + describe("getLumpSumService()", () => { + it("correctly builds getLumpSumService() request", async () => { + const nockScope = nock(CLOCKODO_API) + .get("/v2/lumpsumservices/777") + .reply(200, {}); + + await clockodo.getLumpSumService({ id: 777 }); + + nockScope.done(); + }); + }); + + describe("getLumpSumServicesPage()", () => { + it("correctly builds getLumpSumServicesPage() request", async () => { + const nockScope = nock(CLOCKODO_API) + .get("/v2/lumpsumservices") + .reply(200, {}); + + await clockodo.getLumpSumServicesPage(); + + nockScope.done(); + }); + }); + + describe("getLumpSumServices()", () => { + it("requests all lumpSumService pages", async () => { + const nockScope = setupPaginatedApiMock({ + baseUrl: "/v2/lumpsumservices?", + countPages: 3, + createPageResponse: (page) => ({ lumpSumServices: [page] }), + }); + + const { lumpSumServices } = await clockodo.getLumpSumServices(); + + expect(lumpSumServices).toMatchObject([1, 2, 3]); + + nockScope.done(); + }); + }); + describe("getEntry()", () => { it("correctly builds getEntry() request", async () => { const nockScope = nock(CLOCKODO_API) @@ -413,11 +453,27 @@ describe("Clockodo (instance)", () => { }); }); + describe("getServicesPage()", () => { + it("correctly builds getServicesPage() request", async () => { + const nockScope = nock(CLOCKODO_API).get("/v2/services").reply(200, {}); + + await clockodo.getServicesPage(); + + nockScope.done(); + }); + }); + describe("getServices()", () => { - it("correctly builds getServices() request", async () => { - const nockScope = nock(CLOCKODO_API).get("/services").reply(200, {}); + it("requests all getServices pages", async () => { + const nockScope = setupPaginatedApiMock({ + baseUrl: "/v2/services?", + countPages: 3, + createPageResponse: (page) => ({ services: [page] }), + }); - await clockodo.getServices(); + const { services } = await clockodo.getServices(); + + expect(services).toMatchObject([1, 2, 3]); nockScope.done(); }); @@ -649,6 +705,26 @@ describe("Clockodo (instance)", () => { }); }); + describe("addLumpsumService()", () => { + it("correctly builds addLumpsumService() request", async () => { + const expectedParameters = { + name: "Weyland-Yutani", + price: 1, + }; + + const nockScope = nock(CLOCKODO_API) + .post("/v2/lumpsumservices", expectedParameters) + .reply(200, {}); + + await clockodo.addLumpsumService({ + name: "Weyland-Yutani", + price: 1, + }); + + nockScope.done(); + }); + }); + describe("addProject()", () => { it("correctly builds addProject() request", async () => { const expectedParameters = { @@ -679,7 +755,7 @@ describe("Clockodo (instance)", () => { }; const nockScope = nock(CLOCKODO_API) - .post("/services", expectedParameters) + .post("/v2/services", expectedParameters) .reply(200, {}); await clockodo.addService({ name: "Thinking", active: true }); @@ -923,6 +999,23 @@ describe("Clockodo (instance)", () => { }); }); + describe("editLumpsumService()", () => { + it("correctly builds editLumpsumService() request", async () => { + const lumpsumService = { + id: 15, + name: "Mystery Gang", + }; + + const nockScope = nock(CLOCKODO_API) + .put("/v2/lumpsumservices/15", mapRequestBody(lumpsumService)) + .reply(200, {}); + + await clockodo.editLumpsumService(lumpsumService); + + nockScope.done(); + }); + }); + describe("editProject()", () => { it("correctly builds editProject() request", async () => { const project = { @@ -949,7 +1042,7 @@ describe("Clockodo (instance)", () => { }; const nockScope = nock(CLOCKODO_API) - .put("/services/23", mapRequestBody(service)) + .put("/v2/services/23", mapRequestBody(service)) .reply(200, {}); await clockodo.editService(service); @@ -1079,7 +1172,7 @@ describe("Clockodo (instance)", () => { describe("deleteService()", () => { it("correctly builds deleteService() request", async () => { const nockScope = nock(CLOCKODO_API) - .delete("/services/94") + .delete("/v2/services/94") .reply(200, {}); await clockodo.deleteService({ id: 94 }); @@ -1088,6 +1181,18 @@ describe("Clockodo (instance)", () => { }); }); + describe("deleteLumpsumService()", () => { + it("correctly builds deleteLumpsumService() request", async () => { + const nockScope = nock(CLOCKODO_API) + .delete("/v2/lumpsumservices/94") + .reply(200, {}); + + await clockodo.deleteLumpsumService({ id: 94 }); + + nockScope.done(); + }); + }); + describe("deactivateUser()", () => { it("correctly builds deactivateUser() request", async () => { const nockScope = nock(CLOCKODO_API).delete("/users/7").reply(200, {}); From dad018cb036e1ff8454ccf5f20eb64def6c88944 Mon Sep 17 00:00:00 2001 From: Dominik Sumer Date: Mon, 16 Oct 2023 08:45:36 +0200 Subject: [PATCH 10/20] added test for overtimecarry --- src/clockodo.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/clockodo.test.ts b/src/clockodo.test.ts index 6ea23587..75aa782d 100644 --- a/src/clockodo.test.ts +++ b/src/clockodo.test.ts @@ -592,6 +592,18 @@ describe("Clockodo (instance)", () => { nockScope.done(); }); }); + + describe("getOvertimecarry()", () => { + it("correctly builds getOvertimecarry() request", async () => { + const nockScope = nock(CLOCKODO_API) + .get("/overtimecarry?users_id=17&year=2028") + .reply(200, {}); + + await clockodo.getOvertimecarry({ usersId: 17, year: 2028 }); + + nockScope.done(); + }); + }); }); describe("POST", () => { From 0fb6afeb39167913eef73b91131cfa6148ae4c77 Mon Sep 17 00:00:00 2001 From: Dominik Sumer Date: Mon, 16 Oct 2023 08:50:34 +0200 Subject: [PATCH 11/20] fixed tests for new user endpoints --- src/clockodo.test.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/clockodo.test.ts b/src/clockodo.test.ts index 65fc9271..8c955ade 100644 --- a/src/clockodo.test.ts +++ b/src/clockodo.test.ts @@ -447,7 +447,9 @@ describe("Clockodo (instance)", () => { describe("getUser()", () => { it("correctly builds getUser() request", async () => { - const nockScope = nock(CLOCKODO_API).get("/users/1263").reply(200, {}); + const nockScope = nock(CLOCKODO_API) + .get("/v2/users/1263") + .reply(200, {}); await clockodo.getUser({ id: 1263 }); @@ -457,7 +459,7 @@ describe("Clockodo (instance)", () => { describe("getUsers()", () => { it("correctly builds getUsers() request", async () => { - const nockScope = nock(CLOCKODO_API).get("/users").reply(200, {}); + const nockScope = nock(CLOCKODO_API).get("/v2/users").reply(200, {}); await clockodo.getUsers(); @@ -698,7 +700,7 @@ describe("Clockodo (instance)", () => { }; const nockScope = nock(CLOCKODO_API) - .post("/users", expectedParameters) + .post("/v2/users", expectedParameters) .reply(200, {}); await clockodo.addUser({ @@ -966,7 +968,7 @@ describe("Clockodo (instance)", () => { }; const nockScope = nock(CLOCKODO_API) - .put("/users/33", mapRequestBody(user)) + .put("/v2/users/33", mapRequestBody(user)) .reply(200, {}); await clockodo.editUser(user); @@ -1090,7 +1092,9 @@ describe("Clockodo (instance)", () => { describe("deleteUser()", () => { it("correctly builds deleteUser() request", async () => { - const nockScope = nock(CLOCKODO_API).delete("/users/7").reply(200, {}); + const nockScope = nock(CLOCKODO_API) + .delete("/v2/users/7") + .reply(200, {}); await clockodo.deleteUser({ id: 7 }); From 367a3d5612faa01cf4f4d39ffb7c1cbea9059b40 Mon Sep 17 00:00:00 2001 From: Dominik Sumer Date: Thu, 19 Oct 2023 15:14:41 +0200 Subject: [PATCH 12/20] adjusted mock creation --- src/models/overtimecarry.mocks.ts | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/models/overtimecarry.mocks.ts b/src/models/overtimecarry.mocks.ts index cb30d58f..9a749844 100644 --- a/src/models/overtimecarry.mocks.ts +++ b/src/models/overtimecarry.mocks.ts @@ -1,16 +1,26 @@ import { faker } from "@faker-js/faker"; import { OvertimecarryRow } from "./overtimecarry.js"; +type Options = { + count?: number; + hoursMinMax?: [number, number]; + yearMinMax?: [number, number]; +}; + export const createOvertimecarryMocks = ({ count = 1, - usersId = 0, -}: { count?: number; usersId?: number } = {}) => { + hoursMinMax = [0, 100], + yearMinMax = [1900, 2024], +}: Options = {}) => { return Array.from({ length: count }, (): OvertimecarryRow => { return { - usersId, - year: faker.datatype.number({ min: 1900, max: 2024 }), + usersId: 0, + year: faker.datatype.number({ min: yearMinMax[0], max: yearMinMax[1] }), note: faker.datatype.boolean() ? faker.lorem.sentences(2) : null, - hours: faker.datatype.number({ min: 0, max: 100 }), + hours: faker.datatype.number({ + min: hoursMinMax[0], + max: hoursMinMax[1], + }), }; }); }; From f8fd5756a936d61c5ed9b91059b36a56476ccb63 Mon Sep 17 00:00:00 2001 From: Dominik Sumer Date: Thu, 19 Oct 2023 16:06:54 +0200 Subject: [PATCH 13/20] added field that defines if a targethoursRow was generated as test data --- .../targethours.mocks.test.ts.snap | 20 +++++++++++++++++++ src/models/targethours.mocks.ts | 1 + src/models/targethours.ts | 2 ++ 3 files changed, 23 insertions(+) diff --git a/src/models/__snapshots__/targethours.mocks.test.ts.snap b/src/models/__snapshots__/targethours.mocks.test.ts.snap index f12eebce..77a134b4 100644 --- a/src/models/__snapshots__/targethours.mocks.test.ts.snap +++ b/src/models/__snapshots__/targethours.mocks.test.ts.snap @@ -8,6 +8,7 @@ Array [ "dateUntil": "2019-04-30", "id": 0, "monthlyTarget": 48093, + "testData": false, "type": "monthly", "usersId": 0, "workdayFriday": true, @@ -24,6 +25,7 @@ Array [ "dateUntil": "2019-07-31", "id": 1, "monthlyTarget": 44025, + "testData": false, "type": "monthly", "usersId": 0, "workdayFriday": true, @@ -40,6 +42,7 @@ Array [ "dateUntil": "2019-09-30", "id": 2, "monthlyTarget": 65472, + "testData": false, "type": "monthly", "usersId": 0, "workdayFriday": false, @@ -61,6 +64,7 @@ Array [ "monday": 0, "saturday": 4, "sunday": 0, + "testData": false, "thursday": 4.16, "tuesday": 24, "type": "weekly", @@ -78,6 +82,7 @@ Array [ "monday": 24, "saturday": 0, "sunday": 24, + "testData": false, "thursday": 2.74, "tuesday": 3, "type": "weekly", @@ -95,6 +100,7 @@ Array [ "monday": 5.36, "saturday": 0, "sunday": 5.36, + "testData": false, "thursday": 6, "tuesday": 0, "type": "weekly", @@ -112,6 +118,7 @@ Array [ "monday": 6.11, "saturday": 24, "sunday": 6.11, + "testData": false, "thursday": 0, "tuesday": 1, "type": "weekly", @@ -129,6 +136,7 @@ Array [ "monday": 0, "saturday": 24, "sunday": 0, + "testData": false, "thursday": 5.02, "tuesday": 4, "type": "weekly", @@ -146,6 +154,7 @@ Array [ "monday": 1, "saturday": 1.22, "sunday": 1, + "testData": false, "thursday": 0, "tuesday": 0, "type": "weekly", @@ -163,6 +172,7 @@ Array [ "monday": 5, "saturday": 24, "sunday": 5, + "testData": false, "thursday": 2, "tuesday": 0, "type": "weekly", @@ -180,6 +190,7 @@ Array [ "monday": 24, "saturday": 6, "sunday": 24, + "testData": false, "thursday": 0, "tuesday": 2, "type": "weekly", @@ -197,6 +208,7 @@ Array [ "monday": 1.21, "saturday": 0, "sunday": 1.21, + "testData": false, "thursday": 8, "tuesday": 3, "type": "weekly", @@ -214,6 +226,7 @@ Array [ "monday": 24, "saturday": 0, "sunday": 24, + "testData": false, "thursday": 6, "tuesday": 3, "type": "weekly", @@ -231,6 +244,7 @@ Array [ "monday": 24, "saturday": 8, "sunday": 24, + "testData": false, "thursday": 3, "tuesday": 6.84, "type": "weekly", @@ -248,6 +262,7 @@ Array [ "monday": 0, "saturday": 4, "sunday": 0, + "testData": false, "thursday": 2.71, "tuesday": 4, "type": "weekly", @@ -265,6 +280,7 @@ Array [ "monday": 7.25, "saturday": 4, "sunday": 7.25, + "testData": false, "thursday": 24, "tuesday": 7, "type": "weekly", @@ -282,6 +298,7 @@ Array [ "monday": 0, "saturday": 2.06, "sunday": 0, + "testData": false, "thursday": 24, "tuesday": 0, "type": "weekly", @@ -299,6 +316,7 @@ Array [ "monday": 0, "saturday": 24, "sunday": 0, + "testData": false, "thursday": 0, "tuesday": 4, "type": "weekly", @@ -316,6 +334,7 @@ Array [ "monday": 0, "saturday": 24, "sunday": 0, + "testData": false, "thursday": 0, "tuesday": 3.6, "type": "weekly", @@ -333,6 +352,7 @@ Array [ "monday": 24, "saturday": 0, "sunday": 24, + "testData": false, "thursday": 0, "tuesday": 3.66, "type": "weekly", diff --git a/src/models/targethours.mocks.ts b/src/models/targethours.mocks.ts index 3b64d2ac..d7ceda99 100644 --- a/src/models/targethours.mocks.ts +++ b/src/models/targethours.mocks.ts @@ -32,6 +32,7 @@ const createCommonTargethoursRowMock = (dateSince: Date) => { dateUntil: null, compensationMonthly: faker.datatype.number({ min: 0, max: 8 }), usersId: 0, + testData: false, }; }; diff --git a/src/models/targethours.ts b/src/models/targethours.ts index dd2dc048..b5b58ff7 100644 --- a/src/models/targethours.ts +++ b/src/models/targethours.ts @@ -22,6 +22,8 @@ type CommonTargethoursRow = { compensationMonthly: number; /** The related employee's ID */ usersId: number; + /** Defines if the Targethoursrow was generated as test data */ + testData: boolean; }; export type TargethoursRowWeekly = CommonTargethoursRow & { From 8b6a03754d39a013d943283c5eb3cf580b8c631c Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 24 Oct 2023 14:47:47 +0000 Subject: [PATCH 14/20] chore(release): 21.15.0 [skip ci] # [21.15.0](https://github.com/peerigon/clockodo/compare/v21.14.0...v21.15.0) (2023-10-24) ### Features * Add overtimecarry endpoint ([db9aca4](https://github.com/peerigon/clockodo/commit/db9aca46e6fec0366767e8c63d3d6509e11381d8)) * added overtimecarry model and api request ([b062946](https://github.com/peerigon/clockodo/commit/b0629465e8213cd3e5ef8e6e29acf9fa6eb1bab2)) --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78d23d44..e01f172e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# [21.15.0](https://github.com/peerigon/clockodo/compare/v21.14.0...v21.15.0) (2023-10-24) + + +### Features + +* Add overtimecarry endpoint ([db9aca4](https://github.com/peerigon/clockodo/commit/db9aca46e6fec0366767e8c63d3d6509e11381d8)) +* added overtimecarry model and api request ([b062946](https://github.com/peerigon/clockodo/commit/b0629465e8213cd3e5ef8e6e29acf9fa6eb1bab2)) + # [21.14.0](https://github.com/peerigon/clockodo/compare/v21.13.0...v21.14.0) (2023-10-24) ### Features From be49a6e1f4c03aa9913f1098ac447579973cff4b Mon Sep 17 00:00:00 2001 From: Johannes Ewald Date: Tue, 24 Oct 2023 17:08:12 +0200 Subject: [PATCH 15/20] Rename deactivate to delete --- README.md | 18 +++++++++--------- src/clockodo.test.ts | 18 +++++++++--------- src/clockodo.ts | 18 +++++++++--------- src/lib/requiredParams.ts | 6 +++--- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 38eb1c57..dc020153 100644 --- a/README.md +++ b/README.md @@ -754,38 +754,38 @@ await clockodo.editUser({ id: 33, name: "Moalo Loco" }); ## Delete methods -### deactivateCustomer() +### deleteCustomer() -Deactivates (not deletes) customer. +Deletes the customer. #### Example: ```js -await clockodo.deactivateCustomer({ id: 343 }); +await clockodo.deleteCustomer({ id: 343 }); ``` --- -### deactivateProject() +### deleteProject() -Deactivates (not deletes) project. +Deletes the project. #### Example: ```js -await clockodo.deactivateProject({ id: 8 }); +await clockodo.deleteProject({ id: 8 }); ``` --- -### deactivateService() +### deleteService() -Deactivates (not deletes) service. +Deletes the service. #### Example: ```js -await clockodo.deactivateService({ id: 94 }); +await clockodo.deleteService({ id: 94 }); ``` --- diff --git a/src/clockodo.test.ts b/src/clockodo.test.ts index 8c955ade..f58e7a94 100644 --- a/src/clockodo.test.ts +++ b/src/clockodo.test.ts @@ -1054,37 +1054,37 @@ describe("Clockodo (instance)", () => { }); }); - describe("deactivateCustomer()", () => { - it("correctly builds deactivateCustomer() request", async () => { + describe("deleteCustomer()", () => { + it("correctly builds deleteCustomer() request", async () => { const nockScope = nock(CLOCKODO_API) .delete("/v2/customers/343") .reply(200, {}); - await clockodo.deactivateCustomer({ id: 343 }); + await clockodo.deleteCustomer({ id: 343 }); nockScope.done(); }); }); - describe("deactivateProject()", () => { - it("correctly builds deactivateProject() request", async () => { + describe("deleteProject()", () => { + it("correctly builds deleteProject() request", async () => { const nockScope = nock(CLOCKODO_API) .delete("/v2/projects/8") .reply(200, {}); - await clockodo.deactivateProject({ id: 8 }); + await clockodo.deleteProject({ id: 8 }); nockScope.done(); }); }); - describe("deactivateService()", () => { - it("correctly builds deactivateService() request", async () => { + describe("deleteService()", () => { + it("correctly builds deleteService() request", async () => { const nockScope = nock(CLOCKODO_API) .delete("/services/94") .reply(200, {}); - await clockodo.deactivateService({ id: 94 }); + await clockodo.deleteService({ id: 94 }); nockScope.done(); }); diff --git a/src/clockodo.ts b/src/clockodo.ts index dbce4e08..b2186f85 100644 --- a/src/clockodo.ts +++ b/src/clockodo.ts @@ -557,30 +557,30 @@ export class Clockodo { return this.api.put("/v2/users/" + id, params); } - async deactivateCustomer( - params: Params> + async deleteCustomer( + params: Params> ): Promise { - REQUIRED.checkRequired(params, REQUIRED.DEACTIVATE_CUSTOMER); + REQUIRED.checkRequired(params, REQUIRED.DELETE_CUSTOMER); const { id } = params; return this.api.delete("/v2/customers/" + id, params); } - async deactivateProject( - params: Params> + async deleteProject( + params: Params> ): Promise { - REQUIRED.checkRequired(params, REQUIRED.DEACTIVATE_PROJECT); + REQUIRED.checkRequired(params, REQUIRED.DELETE_PROJECT); const { id } = params; return this.api.delete("/v2/projects/" + id, params); } - async deactivateService( - params: Params> + async deleteService( + params: Params> ): Promise { - REQUIRED.checkRequired(params, REQUIRED.DEACTIVATE_SERVICE); + REQUIRED.checkRequired(params, REQUIRED.DELETE_SERVICE); const { id } = params; diff --git a/src/lib/requiredParams.ts b/src/lib/requiredParams.ts index 08bb66a3..5b1352ab 100644 --- a/src/lib/requiredParams.ts +++ b/src/lib/requiredParams.ts @@ -30,9 +30,9 @@ export const CHANGE_CLOCK_DURATION = [ "durationBefore", "duration", ] as const; -export const DEACTIVATE_CUSTOMER = ["id"] as const; -export const DEACTIVATE_PROJECT = ["id"] as const; -export const DEACTIVATE_SERVICE = ["id"] as const; +export const DELETE_CUSTOMER = ["id"] as const; +export const DELETE_PROJECT = ["id"] as const; +export const DELETE_SERVICE = ["id"] as const; export const DELETE_USER = ["id"] as const; export const DELETE_ENTRY = ["id"] as const; export const DELETE_ENTRY_GROUP = ["timeSince", "timeUntil"] as const; From 8916f42ef69e205a60539c8c8da041fdab5e8331 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 24 Oct 2023 15:21:16 +0000 Subject: [PATCH 16/20] chore(release): 22.0.0 [skip ci] # [22.0.0](https://github.com/peerigon/clockodo/compare/v21.15.0...v22.0.0) (2023-10-24) ### Features * Replace deactivate... with delete... ([67e0b33](https://github.com/peerigon/clockodo/commit/67e0b336a342886c04df8a70636c020a58a02f28)) ### BREAKING CHANGES * There are no `deactivate...` methods anymore. In order to deactivate a customer, project, ..., you need to call `edit...` with `active: false`. --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e01f172e..50f61797 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# [22.0.0](https://github.com/peerigon/clockodo/compare/v21.15.0...v22.0.0) (2023-10-24) + + +### Features + +* Replace deactivate... with delete... ([67e0b33](https://github.com/peerigon/clockodo/commit/67e0b336a342886c04df8a70636c020a58a02f28)) + + +### BREAKING CHANGES + +* There are no `deactivate...` methods anymore. In order to deactivate a customer, project, ..., you need to call `edit...` with `active: false`. + # [21.15.0](https://github.com/peerigon/clockodo/compare/v21.14.0...v21.15.0) (2023-10-24) From c4053ab04163add5ff75d45b29ddf50289810e37 Mon Sep 17 00:00:00 2001 From: Dominik Sumer Date: Thu, 2 Nov 2023 10:44:43 +0100 Subject: [PATCH 17/20] bumped services and lumpsumservices to v3 --- src/clockodo.test.ts | 26 ++++++++++++++------------ src/clockodo.ts | 24 ++++++++++++------------ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/clockodo.test.ts b/src/clockodo.test.ts index 406f4427..65431515 100644 --- a/src/clockodo.test.ts +++ b/src/clockodo.test.ts @@ -197,7 +197,7 @@ describe("Clockodo (instance)", () => { describe("getLumpSumService()", () => { it("correctly builds getLumpSumService() request", async () => { const nockScope = nock(CLOCKODO_API) - .get("/v2/lumpsumservices/777") + .get("/v3/lumpsumservices/777") .reply(200, {}); await clockodo.getLumpSumService({ id: 777 }); @@ -209,7 +209,7 @@ describe("Clockodo (instance)", () => { describe("getLumpSumServicesPage()", () => { it("correctly builds getLumpSumServicesPage() request", async () => { const nockScope = nock(CLOCKODO_API) - .get("/v2/lumpsumservices") + .get("/v3/lumpsumservices") .reply(200, {}); await clockodo.getLumpSumServicesPage(); @@ -221,7 +221,7 @@ describe("Clockodo (instance)", () => { describe("getLumpSumServices()", () => { it("requests all lumpSumService pages", async () => { const nockScope = setupPaginatedApiMock({ - baseUrl: "/v2/lumpsumservices?", + baseUrl: "/v3/lumpsumservices?", countPages: 3, createPageResponse: (page) => ({ lumpSumServices: [page] }), }); @@ -445,7 +445,9 @@ describe("Clockodo (instance)", () => { describe("getService()", () => { it("correctly builds getService() request", async () => { - const nockScope = nock(CLOCKODO_API).get("/services/10").reply(200, {}); + const nockScope = nock(CLOCKODO_API) + .get("/v3/services/10") + .reply(200, {}); await clockodo.getService({ id: 10 }); @@ -455,7 +457,7 @@ describe("Clockodo (instance)", () => { describe("getServicesPage()", () => { it("correctly builds getServicesPage() request", async () => { - const nockScope = nock(CLOCKODO_API).get("/v2/services").reply(200, {}); + const nockScope = nock(CLOCKODO_API).get("/v3/services").reply(200, {}); await clockodo.getServicesPage(); @@ -466,7 +468,7 @@ describe("Clockodo (instance)", () => { describe("getServices()", () => { it("requests all getServices pages", async () => { const nockScope = setupPaginatedApiMock({ - baseUrl: "/v2/services?", + baseUrl: "/v3/services?", countPages: 3, createPageResponse: (page) => ({ services: [page] }), }); @@ -751,7 +753,7 @@ describe("Clockodo (instance)", () => { }; const nockScope = nock(CLOCKODO_API) - .post("/v2/lumpsumservices", expectedParameters) + .post("/v3/lumpsumservices", expectedParameters) .reply(200, {}); await clockodo.addLumpsumService({ @@ -793,7 +795,7 @@ describe("Clockodo (instance)", () => { }; const nockScope = nock(CLOCKODO_API) - .post("/v2/services", expectedParameters) + .post("/v3/services", expectedParameters) .reply(200, {}); await clockodo.addService({ name: "Thinking", active: true }); @@ -1045,7 +1047,7 @@ describe("Clockodo (instance)", () => { }; const nockScope = nock(CLOCKODO_API) - .put("/v2/lumpsumservices/15", mapRequestBody(lumpsumService)) + .put("/v3/lumpsumservices/15", mapRequestBody(lumpsumService)) .reply(200, {}); await clockodo.editLumpsumService(lumpsumService); @@ -1080,7 +1082,7 @@ describe("Clockodo (instance)", () => { }; const nockScope = nock(CLOCKODO_API) - .put("/v2/services/23", mapRequestBody(service)) + .put("/v3/services/23", mapRequestBody(service)) .reply(200, {}); await clockodo.editService(service); @@ -1210,7 +1212,7 @@ describe("Clockodo (instance)", () => { describe("deleteService()", () => { it("correctly builds deleteService() request", async () => { const nockScope = nock(CLOCKODO_API) - .delete("/v2/services/94") + .delete("/v3/services/94") .reply(200, {}); await clockodo.deleteService({ id: 94 }); @@ -1222,7 +1224,7 @@ describe("Clockodo (instance)", () => { describe("deleteLumpsumService()", () => { it("correctly builds deleteLumpsumService() request", async () => { const nockScope = nock(CLOCKODO_API) - .delete("/v2/lumpsumservices/94") + .delete("/v3/lumpsumservices/94") .reply(200, {}); await clockodo.deleteLumpsumService({ id: 94 }); diff --git a/src/clockodo.ts b/src/clockodo.ts index 523cf993..7237d01d 100644 --- a/src/clockodo.ts +++ b/src/clockodo.ts @@ -267,14 +267,14 @@ export class Clockodo { const { id, ...remainingParams } = params; - return this.api.get("/services/" + id, remainingParams); + return this.api.get("/v3/services/" + id, remainingParams); } async getServices( params?: Params ): Promise> { const pages = await this.api.getAllPages( - "/v2/services", + "/v3/services", params ); const [{ paging, ...remainingResponse }] = pages; @@ -289,7 +289,7 @@ export class Clockodo { async getServicesPage( params?: Params ): Promise { - return this.api.get("/v2/services", params); + return this.api.get("/v3/services", params); } async getTeam(params: Params<{ id: Team["id"] }>): Promise { @@ -312,7 +312,7 @@ export class Clockodo { const { id, ...remainingParams } = params; - return this.api.get("/v2/lumpsumservices/" + id, remainingParams); + return this.api.get("/v3/lumpsumservices/" + id, remainingParams); } // This endpoint still uses the old lumpSum casing @@ -320,7 +320,7 @@ export class Clockodo { params?: Params ): Promise> { const pages = await this.api.getAllPages( - "/v2/lumpsumservices", + "/v3/lumpsumservices", params ); const [{ paging, ...remainingResponse }] = pages; @@ -338,7 +338,7 @@ export class Clockodo { async getLumpSumServicesPage( params?: Params ): Promise { - return this.api.get("/v2/lumpsumservices", params); + return this.api.get("/v3/lumpsumservices", params); } async getTargethoursRow( @@ -443,7 +443,7 @@ export class Clockodo { ): Promise { REQUIRED.checkRequired(params, REQUIRED.ADD_LUMPSUM_SERVICE); - return this.api.post("/v2/lumpsumservices", params); + return this.api.post("/v3/lumpsumservices", params); } async addEntry( @@ -480,7 +480,7 @@ export class Clockodo { ): Promise { REQUIRED.checkRequired(params, REQUIRED.ADD_SERVICE); - return this.api.post("/v2/services", params); + return this.api.post("/v3/services", params); } async addTeam( @@ -558,7 +558,7 @@ export class Clockodo { const { id } = params; - return this.api.put("/v2/lumpsumservices/" + id, params); + return this.api.put("/v3/lumpsumservices/" + id, params); } async editEntry( @@ -596,7 +596,7 @@ export class Clockodo { const { id } = params; - return this.api.put("/v2/services/" + id, params); + return this.api.put("/v3/services/" + id, params); } async editTeam( @@ -646,7 +646,7 @@ export class Clockodo { const { id } = params; - return this.api.delete("/v2/services/" + id, params); + return this.api.delete("/v3/services/" + id, params); } async deleteUser( @@ -686,7 +686,7 @@ export class Clockodo { const { id } = params; - return this.api.delete("/v2/lumpsumservices/" + id, params); + return this.api.delete("/v3/lumpsumservices/" + id, params); } async deleteEntryGroup( From 58c2072a4725d8d434438c78cf346edd60316dbe Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 6 Nov 2023 08:47:27 +0000 Subject: [PATCH 18/20] chore(release): 22.1.0 [skip ci] # [22.1.0](https://github.com/peerigon/clockodo/compare/v22.0.0...v22.1.0) (2023-11-06) ### Features * Add testData property to targethoursRow ([#140](https://github.com/peerigon/clockodo/issues/140)) ([9c2e511](https://github.com/peerigon/clockodo/commit/9c2e5119004eeb89c95b53e42815e95fbf5e071e)) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50f61797..f269d200 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [22.1.0](https://github.com/peerigon/clockodo/compare/v22.0.0...v22.1.0) (2023-11-06) + + +### Features + +* Add testData property to targethoursRow ([#140](https://github.com/peerigon/clockodo/issues/140)) ([9c2e511](https://github.com/peerigon/clockodo/commit/9c2e5119004eeb89c95b53e42815e95fbf5e071e)) + # [22.0.0](https://github.com/peerigon/clockodo/compare/v21.15.0...v22.0.0) (2023-10-24) From 256a867f06ae47ba43f55773c8850971bcfe9f06 Mon Sep 17 00:00:00 2001 From: Johannes Ewald Date: Mon, 6 Nov 2023 14:31:05 +0100 Subject: [PATCH 19/20] Fix incorrect Pick --- src/clockodo.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/clockodo.ts b/src/clockodo.ts index 7237d01d..1f3acaa6 100644 --- a/src/clockodo.ts +++ b/src/clockodo.ts @@ -680,7 +680,9 @@ export class Clockodo { } async deleteLumpsumService( - params: Params> + params: Params< + Pick + > ): Promise { REQUIRED.checkRequired(params, REQUIRED.DELETE_LUMPSUM_SERVICE); From 7de751e1a395b44b2a9dfc662420edd0d9fbfded Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 6 Nov 2023 13:44:22 +0000 Subject: [PATCH 20/20] chore(release): 22.2.0 [skip ci] # [22.2.0](https://github.com/peerigon/clockodo/compare/v22.1.0...v22.2.0) (2023-11-06) ### Features * Use v3 API for services and lumpsum services ([#131](https://github.com/peerigon/clockodo/issues/131)) ([1a8ba9d](https://github.com/peerigon/clockodo/commit/1a8ba9d1fad6a6251a1116a39bfd1886a048bce1)) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index feb8aef1..1d25503d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [22.2.0](https://github.com/peerigon/clockodo/compare/v22.1.0...v22.2.0) (2023-11-06) + + +### Features + +* Use v3 API for services and lumpsum services ([#131](https://github.com/peerigon/clockodo/issues/131)) ([1a8ba9d](https://github.com/peerigon/clockodo/commit/1a8ba9d1fad6a6251a1116a39bfd1886a048bce1)) + # [22.1.0](https://github.com/peerigon/clockodo/compare/v22.0.0...v22.1.0) (2023-11-06)