@marcfargas/odoo-client 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/odoo-client.d.ts +39 -0
- package/dist/client/odoo-client.d.ts.map +1 -1
- package/dist/client/odoo-client.js +43 -0
- package/dist/client/odoo-client.js.map +1 -1
- package/dist/services/attendance/attendance-service.d.ts +100 -0
- package/dist/services/attendance/attendance-service.d.ts.map +1 -0
- package/dist/services/attendance/attendance-service.js +113 -0
- package/dist/services/attendance/attendance-service.js.map +1 -0
- package/dist/services/attendance/functions.d.ts +72 -0
- package/dist/services/attendance/functions.d.ts.map +1 -0
- package/dist/services/attendance/functions.js +169 -0
- package/dist/services/attendance/functions.js.map +1 -0
- package/dist/services/attendance/index.d.ts +4 -0
- package/dist/services/attendance/index.d.ts.map +1 -0
- package/dist/services/attendance/index.js +12 -0
- package/dist/services/attendance/index.js.map +1 -0
- package/dist/services/attendance/types.d.ts +53 -0
- package/dist/services/attendance/types.d.ts.map +1 -0
- package/dist/services/attendance/types.js +8 -0
- package/dist/services/attendance/types.js.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +2 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/timesheets/functions.d.ts +75 -0
- package/dist/services/timesheets/functions.d.ts.map +1 -0
- package/dist/services/timesheets/functions.js +220 -0
- package/dist/services/timesheets/functions.js.map +1 -0
- package/dist/services/timesheets/index.d.ts +4 -0
- package/dist/services/timesheets/index.d.ts.map +1 -0
- package/dist/services/timesheets/index.js +12 -0
- package/dist/services/timesheets/index.js.map +1 -0
- package/dist/services/timesheets/timesheets-service.d.ts +121 -0
- package/dist/services/timesheets/timesheets-service.d.ts.map +1 -0
- package/dist/services/timesheets/timesheets-service.js +136 -0
- package/dist/services/timesheets/timesheets-service.js.map +1 -0
- package/dist/services/timesheets/types.d.ts +81 -0
- package/dist/services/timesheets/types.d.ts.map +1 -0
- package/dist/services/timesheets/types.js +10 -0
- package/dist/services/timesheets/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -20,6 +20,8 @@ import { OdooSessionInfo } from '../rpc/transport';
|
|
|
20
20
|
import { type SafetyContext, type SafetyLevel } from '../safety';
|
|
21
21
|
import { MailService } from '../services/mail/mail-service';
|
|
22
22
|
import { ModuleManager } from '../services/modules/module-manager';
|
|
23
|
+
import { AttendanceService } from '../services/attendance/attendance-service';
|
|
24
|
+
import { TimesheetsService } from '../services/timesheets/timesheets-service';
|
|
23
25
|
export interface OdooClientConfig {
|
|
24
26
|
url: string;
|
|
25
27
|
database: string;
|
|
@@ -65,6 +67,43 @@ export declare class OdooClient {
|
|
|
65
67
|
* ```
|
|
66
68
|
*/
|
|
67
69
|
get modules(): ModuleManager;
|
|
70
|
+
private _attendance?;
|
|
71
|
+
/**
|
|
72
|
+
* Attendance service — clock in/out and presence tracking.
|
|
73
|
+
*
|
|
74
|
+
* Requires the `hr_attendance` module to be installed.
|
|
75
|
+
*
|
|
76
|
+
* ```typescript
|
|
77
|
+
* await client.attendance.clockIn();
|
|
78
|
+
* const status = await client.attendance.getStatus();
|
|
79
|
+
* await client.attendance.clockOut();
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
get attendance(): AttendanceService;
|
|
83
|
+
private _timesheets?;
|
|
84
|
+
/**
|
|
85
|
+
* Timesheets service — timer-based and manual time tracking on projects.
|
|
86
|
+
*
|
|
87
|
+
* Requires the `hr_timesheet` module to be installed.
|
|
88
|
+
*
|
|
89
|
+
* ```typescript
|
|
90
|
+
* // Timer workflow
|
|
91
|
+
* const entry = await client.timesheets.startTimer({
|
|
92
|
+
* description: 'Feature work',
|
|
93
|
+
* projectId: 5,
|
|
94
|
+
* });
|
|
95
|
+
* // ... later ...
|
|
96
|
+
* await client.timesheets.stopTimer(entry.id);
|
|
97
|
+
*
|
|
98
|
+
* // Manual logging
|
|
99
|
+
* await client.timesheets.logTime({
|
|
100
|
+
* description: 'Code review',
|
|
101
|
+
* projectId: 5,
|
|
102
|
+
* hours: 1.5,
|
|
103
|
+
* });
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
get timesheets(): TimesheetsService;
|
|
68
107
|
/**
|
|
69
108
|
* Override safety context for this client instance.
|
|
70
109
|
* Pass null to explicitly disable, undefined to use global default.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"odoo-client.d.ts","sourceRoot":"","sources":["../../src/client/odoo-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAoB,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAErE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,WAAW,EAIjB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"odoo-client.d.ts","sourceRoot":"","sources":["../../src/client/odoo-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,8 @@ const errors_1 = require("../types/errors");
|
|
|
24
24
|
const safety_1 = require("../safety");
|
|
25
25
|
const mail_service_1 = require("../services/mail/mail-service");
|
|
26
26
|
const module_manager_1 = require("../services/modules/module-manager");
|
|
27
|
+
const attendance_service_1 = require("../services/attendance/attendance-service");
|
|
28
|
+
const timesheets_service_1 = require("../services/timesheets/timesheets-service");
|
|
27
29
|
/**
|
|
28
30
|
* Main client for interacting with Odoo.
|
|
29
31
|
*
|
|
@@ -68,6 +70,47 @@ class OdooClient {
|
|
|
68
70
|
get modules() {
|
|
69
71
|
return (this._modules ??= new module_manager_1.ModuleManager(this));
|
|
70
72
|
}
|
|
73
|
+
_attendance;
|
|
74
|
+
/**
|
|
75
|
+
* Attendance service — clock in/out and presence tracking.
|
|
76
|
+
*
|
|
77
|
+
* Requires the `hr_attendance` module to be installed.
|
|
78
|
+
*
|
|
79
|
+
* ```typescript
|
|
80
|
+
* await client.attendance.clockIn();
|
|
81
|
+
* const status = await client.attendance.getStatus();
|
|
82
|
+
* await client.attendance.clockOut();
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
get attendance() {
|
|
86
|
+
return (this._attendance ??= new attendance_service_1.AttendanceService(this));
|
|
87
|
+
}
|
|
88
|
+
_timesheets;
|
|
89
|
+
/**
|
|
90
|
+
* Timesheets service — timer-based and manual time tracking on projects.
|
|
91
|
+
*
|
|
92
|
+
* Requires the `hr_timesheet` module to be installed.
|
|
93
|
+
*
|
|
94
|
+
* ```typescript
|
|
95
|
+
* // Timer workflow
|
|
96
|
+
* const entry = await client.timesheets.startTimer({
|
|
97
|
+
* description: 'Feature work',
|
|
98
|
+
* projectId: 5,
|
|
99
|
+
* });
|
|
100
|
+
* // ... later ...
|
|
101
|
+
* await client.timesheets.stopTimer(entry.id);
|
|
102
|
+
*
|
|
103
|
+
* // Manual logging
|
|
104
|
+
* await client.timesheets.logTime({
|
|
105
|
+
* description: 'Code review',
|
|
106
|
+
* projectId: 5,
|
|
107
|
+
* hours: 1.5,
|
|
108
|
+
* });
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
get timesheets() {
|
|
112
|
+
return (this._timesheets ??= new timesheets_service_1.TimesheetsService(this));
|
|
113
|
+
}
|
|
71
114
|
// ── Auth ────────────────────────────────────────────────────────────
|
|
72
115
|
/**
|
|
73
116
|
* Override safety context for this client instance.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"odoo-client.js","sourceRoot":"","sources":["../../src/client/odoo-client.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;AAEH,gDAAqE;AACrE,4CAAiE;AACjE,sCAMmB;AACnB,gEAA4D;AAC5D,uEAAmE;
|
|
1
|
+
{"version":3,"file":"odoo-client.js","sourceRoot":"","sources":["../../src/client/odoo-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attendance service — the typed interface exposed via `client.attendance.*`
|
|
3
|
+
*
|
|
4
|
+
* Delegates to standalone functions in functions.ts.
|
|
5
|
+
*
|
|
6
|
+
* Provides clock-in/out and attendance status for hr.attendance model.
|
|
7
|
+
* Requires the `hr_attendance` module to be installed.
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/odoo/odoo/blob/17.0/addons/hr_attendance/models/hr_attendance.py
|
|
10
|
+
*/
|
|
11
|
+
import type { OdooClient } from '../../client/odoo-client';
|
|
12
|
+
import type { AttendanceRecord, AttendanceListOptions, AttendanceStatus } from './types';
|
|
13
|
+
/**
|
|
14
|
+
* Attendance service for managing employee clock-in/out.
|
|
15
|
+
*
|
|
16
|
+
* Access via `client.attendance` — never instantiate directly.
|
|
17
|
+
*
|
|
18
|
+
* The hr.attendance model tracks physical presence:
|
|
19
|
+
* - Clock in creates a record with check_in = now
|
|
20
|
+
* - Clock out sets check_out = now on the open record
|
|
21
|
+
* - Odoo enforces one open attendance per employee at a time
|
|
22
|
+
*
|
|
23
|
+
* All methods accept an optional employeeId. When omitted, the current
|
|
24
|
+
* user's linked hr.employee record is used automatically.
|
|
25
|
+
*/
|
|
26
|
+
export declare class AttendanceService {
|
|
27
|
+
private client;
|
|
28
|
+
/** @internal */
|
|
29
|
+
constructor(client: OdooClient);
|
|
30
|
+
/**
|
|
31
|
+
* Clock in — create an open attendance record.
|
|
32
|
+
*
|
|
33
|
+
* Creates an hr.attendance with check_in = now.
|
|
34
|
+
* Fails if the employee is already clocked in.
|
|
35
|
+
*
|
|
36
|
+
* @param employeeId - Employee ID (omit for current user's employee)
|
|
37
|
+
* @returns The created attendance record
|
|
38
|
+
* @throws OdooValidationError if already clocked in
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const record = await client.attendance.clockIn();
|
|
43
|
+
* console.log(`Clocked in at ${record.check_in}`);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
clockIn(employeeId?: number): Promise<AttendanceRecord>;
|
|
47
|
+
/**
|
|
48
|
+
* Clock out — close the current open attendance.
|
|
49
|
+
*
|
|
50
|
+
* Sets check_out = now on the open attendance record.
|
|
51
|
+
* Fails if the employee is not currently clocked in.
|
|
52
|
+
*
|
|
53
|
+
* @param employeeId - Employee ID (omit for current user's employee)
|
|
54
|
+
* @returns The updated attendance record (with worked_hours)
|
|
55
|
+
* @throws OdooValidationError if not clocked in
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const record = await client.attendance.clockOut();
|
|
60
|
+
* console.log(`Worked ${record.worked_hours.toFixed(2)} hours`);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
clockOut(employeeId?: number): Promise<AttendanceRecord>;
|
|
64
|
+
/**
|
|
65
|
+
* Get attendance status — check if currently clocked in.
|
|
66
|
+
*
|
|
67
|
+
* @param employeeId - Employee ID (omit for current user's employee)
|
|
68
|
+
* @returns Status with checkedIn flag and current attendance if any
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const status = await client.attendance.getStatus();
|
|
73
|
+
* if (status.checkedIn) {
|
|
74
|
+
* console.log(`${status.employee[1]} clocked in since ${status.currentAttendance!.check_in}`);
|
|
75
|
+
* } else {
|
|
76
|
+
* console.log(`${status.employee[1]} is not in the office`);
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
getStatus(employeeId?: number): Promise<AttendanceStatus>;
|
|
81
|
+
/**
|
|
82
|
+
* List attendance records with optional filters.
|
|
83
|
+
*
|
|
84
|
+
* @param options - Filter by employee, date range, pagination
|
|
85
|
+
* @returns Array of attendance records
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* // Today's attendances for current user's employee
|
|
90
|
+
* const today = new Date().toISOString().split('T')[0];
|
|
91
|
+
* const records = await client.attendance.list({
|
|
92
|
+
* dateFrom: today,
|
|
93
|
+
* dateTo: today,
|
|
94
|
+
* employeeId: 42,
|
|
95
|
+
* });
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
list(options?: AttendanceListOptions): Promise<AttendanceRecord[]>;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=attendance-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attendance-service.d.ts","sourceRoot":"","sources":["../../../src/services/attendance/attendance-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAQzF;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAiB;IAEhB,OAAO,CAAC,MAAM;IAD1B,gBAAgB;gBACI,MAAM,EAAE,UAAU;IAEtC;;;;;;;;;;;;;;;OAeG;IACG,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI7D;;;;;;;;;;;;;;;OAeG;IACG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI9D;;;;;;;;;;;;;;;OAeG;IACG,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI/D;;;;;;;;;;;;;;;;OAgBG;IACG,IAAI,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAGzE"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Attendance service — the typed interface exposed via `client.attendance.*`
|
|
4
|
+
*
|
|
5
|
+
* Delegates to standalone functions in functions.ts.
|
|
6
|
+
*
|
|
7
|
+
* Provides clock-in/out and attendance status for hr.attendance model.
|
|
8
|
+
* Requires the `hr_attendance` module to be installed.
|
|
9
|
+
*
|
|
10
|
+
* @see https://github.com/odoo/odoo/blob/17.0/addons/hr_attendance/models/hr_attendance.py
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.AttendanceService = void 0;
|
|
14
|
+
const functions_1 = require("./functions");
|
|
15
|
+
/**
|
|
16
|
+
* Attendance service for managing employee clock-in/out.
|
|
17
|
+
*
|
|
18
|
+
* Access via `client.attendance` — never instantiate directly.
|
|
19
|
+
*
|
|
20
|
+
* The hr.attendance model tracks physical presence:
|
|
21
|
+
* - Clock in creates a record with check_in = now
|
|
22
|
+
* - Clock out sets check_out = now on the open record
|
|
23
|
+
* - Odoo enforces one open attendance per employee at a time
|
|
24
|
+
*
|
|
25
|
+
* All methods accept an optional employeeId. When omitted, the current
|
|
26
|
+
* user's linked hr.employee record is used automatically.
|
|
27
|
+
*/
|
|
28
|
+
class AttendanceService {
|
|
29
|
+
client;
|
|
30
|
+
/** @internal */
|
|
31
|
+
constructor(client) {
|
|
32
|
+
this.client = client;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Clock in — create an open attendance record.
|
|
36
|
+
*
|
|
37
|
+
* Creates an hr.attendance with check_in = now.
|
|
38
|
+
* Fails if the employee is already clocked in.
|
|
39
|
+
*
|
|
40
|
+
* @param employeeId - Employee ID (omit for current user's employee)
|
|
41
|
+
* @returns The created attendance record
|
|
42
|
+
* @throws OdooValidationError if already clocked in
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const record = await client.attendance.clockIn();
|
|
47
|
+
* console.log(`Clocked in at ${record.check_in}`);
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
async clockIn(employeeId) {
|
|
51
|
+
return (0, functions_1.clockIn)(this.client, employeeId);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Clock out — close the current open attendance.
|
|
55
|
+
*
|
|
56
|
+
* Sets check_out = now on the open attendance record.
|
|
57
|
+
* Fails if the employee is not currently clocked in.
|
|
58
|
+
*
|
|
59
|
+
* @param employeeId - Employee ID (omit for current user's employee)
|
|
60
|
+
* @returns The updated attendance record (with worked_hours)
|
|
61
|
+
* @throws OdooValidationError if not clocked in
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const record = await client.attendance.clockOut();
|
|
66
|
+
* console.log(`Worked ${record.worked_hours.toFixed(2)} hours`);
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
async clockOut(employeeId) {
|
|
70
|
+
return (0, functions_1.clockOut)(this.client, employeeId);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get attendance status — check if currently clocked in.
|
|
74
|
+
*
|
|
75
|
+
* @param employeeId - Employee ID (omit for current user's employee)
|
|
76
|
+
* @returns Status with checkedIn flag and current attendance if any
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const status = await client.attendance.getStatus();
|
|
81
|
+
* if (status.checkedIn) {
|
|
82
|
+
* console.log(`${status.employee[1]} clocked in since ${status.currentAttendance!.check_in}`);
|
|
83
|
+
* } else {
|
|
84
|
+
* console.log(`${status.employee[1]} is not in the office`);
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
async getStatus(employeeId) {
|
|
89
|
+
return (0, functions_1.getStatus)(this.client, employeeId);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* List attendance records with optional filters.
|
|
93
|
+
*
|
|
94
|
+
* @param options - Filter by employee, date range, pagination
|
|
95
|
+
* @returns Array of attendance records
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* // Today's attendances for current user's employee
|
|
100
|
+
* const today = new Date().toISOString().split('T')[0];
|
|
101
|
+
* const records = await client.attendance.list({
|
|
102
|
+
* dateFrom: today,
|
|
103
|
+
* dateTo: today,
|
|
104
|
+
* employeeId: 42,
|
|
105
|
+
* });
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
async list(options) {
|
|
109
|
+
return (0, functions_1.listAttendances)(this.client, options);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.AttendanceService = AttendanceService;
|
|
113
|
+
//# sourceMappingURL=attendance-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attendance-service.js","sourceRoot":"","sources":["../../../src/services/attendance/attendance-service.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAIH,2CAKqB;AAErB;;;;;;;;;;;;GAYG;AACH,MAAa,iBAAiB;IAER;IADpB,gBAAgB;IAChB,YAAoB,MAAkB;QAAlB,WAAM,GAAN,MAAM,CAAY;IAAG,CAAC;IAE1C;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,OAAO,CAAC,UAAmB;QAC/B,OAAO,IAAA,mBAAQ,EAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,QAAQ,CAAC,UAAmB;QAChC,OAAO,IAAA,oBAAS,EAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,SAAS,CAAC,UAAmB;QACjC,OAAO,IAAA,qBAAU,EAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,IAAI,CAAC,OAA+B;QACxC,OAAO,IAAA,2BAAgB,EAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;CACF;AApFD,8CAoFC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attendance standalone functions for Odoo hr.attendance.
|
|
3
|
+
*
|
|
4
|
+
* Provides clock-in, clock-out, and status-check operations.
|
|
5
|
+
*
|
|
6
|
+
* The hr.attendance model stores presence records:
|
|
7
|
+
* - A record with check_in but no check_out = employee is currently present
|
|
8
|
+
* - A record with both check_in and check_out = completed attendance
|
|
9
|
+
*
|
|
10
|
+
* Odoo enforces that an employee can only have ONE open attendance at a time
|
|
11
|
+
* (constraint: _check_validity). Attempting to clock in twice throws a
|
|
12
|
+
* ValidationError.
|
|
13
|
+
*
|
|
14
|
+
* @see https://github.com/odoo/odoo/blob/17.0/addons/hr_attendance/models/hr_attendance.py
|
|
15
|
+
*/
|
|
16
|
+
import type { OdooClient } from '../../client/odoo-client';
|
|
17
|
+
import type { AttendanceRecord, AttendanceListOptions, AttendanceStatus } from './types';
|
|
18
|
+
/**
|
|
19
|
+
* Resolve the employee ID for the current user.
|
|
20
|
+
*
|
|
21
|
+
* If employeeId is provided, returns it. Otherwise, looks up the
|
|
22
|
+
* hr.employee linked to the authenticated user.
|
|
23
|
+
*
|
|
24
|
+
* @throws OdooValidationError if no employee record found for current user
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveEmployeeId(client: OdooClient, employeeId?: number): Promise<number>;
|
|
27
|
+
/**
|
|
28
|
+
* Clock in — create an open attendance record.
|
|
29
|
+
*
|
|
30
|
+
* Creates an hr.attendance record with check_in = now (UTC).
|
|
31
|
+
* Odoo's _check_validity constraint ensures no overlapping attendances.
|
|
32
|
+
*
|
|
33
|
+
* @param client - Authenticated OdooClient
|
|
34
|
+
* @param employeeId - Employee ID (omit to use current user's employee)
|
|
35
|
+
* @returns The created attendance record
|
|
36
|
+
*
|
|
37
|
+
* @throws OdooValidationError if employee is already clocked in
|
|
38
|
+
*/
|
|
39
|
+
export declare function clockIn(client: OdooClient, employeeId?: number): Promise<AttendanceRecord>;
|
|
40
|
+
/**
|
|
41
|
+
* Clock out — set check_out on the current open attendance.
|
|
42
|
+
*
|
|
43
|
+
* Finds the open attendance (check_out = false) for the employee
|
|
44
|
+
* and sets check_out = now (UTC).
|
|
45
|
+
*
|
|
46
|
+
* @param client - Authenticated OdooClient
|
|
47
|
+
* @param employeeId - Employee ID (omit to use current user's employee)
|
|
48
|
+
* @returns The updated attendance record (with worked_hours computed)
|
|
49
|
+
*
|
|
50
|
+
* @throws OdooValidationError if employee is not currently clocked in
|
|
51
|
+
*/
|
|
52
|
+
export declare function clockOut(client: OdooClient, employeeId?: number): Promise<AttendanceRecord>;
|
|
53
|
+
/**
|
|
54
|
+
* Get the attendance status for an employee.
|
|
55
|
+
*
|
|
56
|
+
* Returns whether the employee is currently clocked in, and if so,
|
|
57
|
+
* the open attendance record.
|
|
58
|
+
*
|
|
59
|
+
* @param client - Authenticated OdooClient
|
|
60
|
+
* @param employeeId - Employee ID (omit to use current user's employee)
|
|
61
|
+
* @returns Attendance status
|
|
62
|
+
*/
|
|
63
|
+
export declare function getStatus(client: OdooClient, employeeId?: number): Promise<AttendanceStatus>;
|
|
64
|
+
/**
|
|
65
|
+
* List attendance records with optional filtering.
|
|
66
|
+
*
|
|
67
|
+
* @param client - Authenticated OdooClient
|
|
68
|
+
* @param options - Filter and pagination options
|
|
69
|
+
* @returns Array of attendance records
|
|
70
|
+
*/
|
|
71
|
+
export declare function listAttendances(client: OdooClient, options?: AttendanceListOptions): Promise<AttendanceRecord[]>;
|
|
72
|
+
//# sourceMappingURL=functions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../../src/services/attendance/functions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAOzF;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBhG;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA+BhG;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6BjG;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,UAAU,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAqB3B;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAqB7B"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Attendance standalone functions for Odoo hr.attendance.
|
|
4
|
+
*
|
|
5
|
+
* Provides clock-in, clock-out, and status-check operations.
|
|
6
|
+
*
|
|
7
|
+
* The hr.attendance model stores presence records:
|
|
8
|
+
* - A record with check_in but no check_out = employee is currently present
|
|
9
|
+
* - A record with both check_in and check_out = completed attendance
|
|
10
|
+
*
|
|
11
|
+
* Odoo enforces that an employee can only have ONE open attendance at a time
|
|
12
|
+
* (constraint: _check_validity). Attempting to clock in twice throws a
|
|
13
|
+
* ValidationError.
|
|
14
|
+
*
|
|
15
|
+
* @see https://github.com/odoo/odoo/blob/17.0/addons/hr_attendance/models/hr_attendance.py
|
|
16
|
+
*/
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.resolveEmployeeId = resolveEmployeeId;
|
|
22
|
+
exports.clockIn = clockIn;
|
|
23
|
+
exports.clockOut = clockOut;
|
|
24
|
+
exports.getStatus = getStatus;
|
|
25
|
+
exports.listAttendances = listAttendances;
|
|
26
|
+
const debug_1 = __importDefault(require("debug"));
|
|
27
|
+
const errors_1 = require("../../types/errors");
|
|
28
|
+
const log = (0, debug_1.default)('odoo-client:attendance');
|
|
29
|
+
/** Fields we always fetch for attendance records. */
|
|
30
|
+
const ATTENDANCE_FIELDS = ['employee_id', 'check_in', 'check_out', 'worked_hours'];
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the employee ID for the current user.
|
|
33
|
+
*
|
|
34
|
+
* If employeeId is provided, returns it. Otherwise, looks up the
|
|
35
|
+
* hr.employee linked to the authenticated user.
|
|
36
|
+
*
|
|
37
|
+
* @throws OdooValidationError if no employee record found for current user
|
|
38
|
+
*/
|
|
39
|
+
async function resolveEmployeeId(client, employeeId) {
|
|
40
|
+
if (employeeId)
|
|
41
|
+
return employeeId;
|
|
42
|
+
const session = client.getSession();
|
|
43
|
+
if (!session?.uid) {
|
|
44
|
+
throw new errors_1.OdooValidationError('Cannot resolve employee: no active session. Call authenticate() first.');
|
|
45
|
+
}
|
|
46
|
+
const employees = await client.searchRead('hr.employee', [['user_id', '=', session.uid]], {
|
|
47
|
+
fields: ['id'],
|
|
48
|
+
limit: 1,
|
|
49
|
+
});
|
|
50
|
+
if (employees.length === 0) {
|
|
51
|
+
throw new errors_1.OdooValidationError(`No hr.employee record found for user ID ${session.uid}. ` +
|
|
52
|
+
'Create an employee record linked to this user, or pass employeeId explicitly.');
|
|
53
|
+
}
|
|
54
|
+
return employees[0].id;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Clock in — create an open attendance record.
|
|
58
|
+
*
|
|
59
|
+
* Creates an hr.attendance record with check_in = now (UTC).
|
|
60
|
+
* Odoo's _check_validity constraint ensures no overlapping attendances.
|
|
61
|
+
*
|
|
62
|
+
* @param client - Authenticated OdooClient
|
|
63
|
+
* @param employeeId - Employee ID (omit to use current user's employee)
|
|
64
|
+
* @returns The created attendance record
|
|
65
|
+
*
|
|
66
|
+
* @throws OdooValidationError if employee is already clocked in
|
|
67
|
+
*/
|
|
68
|
+
async function clockIn(client, employeeId) {
|
|
69
|
+
const empId = await resolveEmployeeId(client, employeeId);
|
|
70
|
+
log('Clocking in employee %d', empId);
|
|
71
|
+
// Check if already clocked in
|
|
72
|
+
const open = await client.searchRead('hr.attendance', [
|
|
73
|
+
['employee_id', '=', empId],
|
|
74
|
+
['check_out', '=', false],
|
|
75
|
+
], { fields: ATTENDANCE_FIELDS, limit: 1 });
|
|
76
|
+
if (open.length > 0) {
|
|
77
|
+
throw new errors_1.OdooValidationError(`Employee ${empId} is already clocked in (attendance ID: ${open[0].id}, ` +
|
|
78
|
+
`since: ${open[0].check_in}). Clock out first.`);
|
|
79
|
+
}
|
|
80
|
+
const now = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
81
|
+
const id = await client.create('hr.attendance', {
|
|
82
|
+
employee_id: empId,
|
|
83
|
+
check_in: now,
|
|
84
|
+
});
|
|
85
|
+
log('Clocked in employee %d → attendance %d at %s', empId, id, now);
|
|
86
|
+
const [record] = await client.read('hr.attendance', id, ATTENDANCE_FIELDS);
|
|
87
|
+
return record;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Clock out — set check_out on the current open attendance.
|
|
91
|
+
*
|
|
92
|
+
* Finds the open attendance (check_out = false) for the employee
|
|
93
|
+
* and sets check_out = now (UTC).
|
|
94
|
+
*
|
|
95
|
+
* @param client - Authenticated OdooClient
|
|
96
|
+
* @param employeeId - Employee ID (omit to use current user's employee)
|
|
97
|
+
* @returns The updated attendance record (with worked_hours computed)
|
|
98
|
+
*
|
|
99
|
+
* @throws OdooValidationError if employee is not currently clocked in
|
|
100
|
+
*/
|
|
101
|
+
async function clockOut(client, employeeId) {
|
|
102
|
+
const empId = await resolveEmployeeId(client, employeeId);
|
|
103
|
+
log('Clocking out employee %d', empId);
|
|
104
|
+
const open = await client.searchRead('hr.attendance', [
|
|
105
|
+
['employee_id', '=', empId],
|
|
106
|
+
['check_out', '=', false],
|
|
107
|
+
], { fields: ATTENDANCE_FIELDS, limit: 1 });
|
|
108
|
+
if (open.length === 0) {
|
|
109
|
+
throw new errors_1.OdooValidationError(`Employee ${empId} is not clocked in. Cannot clock out.`);
|
|
110
|
+
}
|
|
111
|
+
const attendance = open[0];
|
|
112
|
+
const now = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
113
|
+
await client.write('hr.attendance', attendance.id, { check_out: now });
|
|
114
|
+
log('Clocked out employee %d → attendance %d at %s', empId, attendance.id, now);
|
|
115
|
+
const [record] = await client.read('hr.attendance', attendance.id, ATTENDANCE_FIELDS);
|
|
116
|
+
return record;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get the attendance status for an employee.
|
|
120
|
+
*
|
|
121
|
+
* Returns whether the employee is currently clocked in, and if so,
|
|
122
|
+
* the open attendance record.
|
|
123
|
+
*
|
|
124
|
+
* @param client - Authenticated OdooClient
|
|
125
|
+
* @param employeeId - Employee ID (omit to use current user's employee)
|
|
126
|
+
* @returns Attendance status
|
|
127
|
+
*/
|
|
128
|
+
async function getStatus(client, employeeId) {
|
|
129
|
+
const empId = await resolveEmployeeId(client, employeeId);
|
|
130
|
+
log('Checking attendance status for employee %d', empId);
|
|
131
|
+
// Get employee display name
|
|
132
|
+
const [employee] = await client.read('hr.employee', empId, ['name']);
|
|
133
|
+
const open = await client.searchRead('hr.attendance', [
|
|
134
|
+
['employee_id', '=', empId],
|
|
135
|
+
['check_out', '=', false],
|
|
136
|
+
], { fields: ATTENDANCE_FIELDS, limit: 1 });
|
|
137
|
+
return {
|
|
138
|
+
checkedIn: open.length > 0,
|
|
139
|
+
currentAttendance: open.length > 0 ? open[0] : null,
|
|
140
|
+
employee: [empId, employee.name],
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* List attendance records with optional filtering.
|
|
145
|
+
*
|
|
146
|
+
* @param client - Authenticated OdooClient
|
|
147
|
+
* @param options - Filter and pagination options
|
|
148
|
+
* @returns Array of attendance records
|
|
149
|
+
*/
|
|
150
|
+
async function listAttendances(client, options = {}) {
|
|
151
|
+
const domain = [];
|
|
152
|
+
if (options.employeeId) {
|
|
153
|
+
domain.push(['employee_id', '=', options.employeeId]);
|
|
154
|
+
}
|
|
155
|
+
if (options.dateFrom) {
|
|
156
|
+
domain.push(['check_in', '>=', `${options.dateFrom} 00:00:00`]);
|
|
157
|
+
}
|
|
158
|
+
if (options.dateTo) {
|
|
159
|
+
domain.push(['check_in', '<=', `${options.dateTo} 23:59:59`]);
|
|
160
|
+
}
|
|
161
|
+
log('Listing attendances with domain: %o', domain);
|
|
162
|
+
return client.searchRead('hr.attendance', domain, {
|
|
163
|
+
fields: ATTENDANCE_FIELDS,
|
|
164
|
+
limit: options.limit,
|
|
165
|
+
offset: options.offset,
|
|
166
|
+
order: options.order ?? 'check_in desc',
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=functions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functions.js","sourceRoot":"","sources":["../../../src/services/attendance/functions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { AttendanceService } from './attendance-service';
|
|
2
|
+
export { clockIn, clockOut, getStatus, listAttendances, resolveEmployeeId } from './functions';
|
|
3
|
+
export type { AttendanceRecord, AttendanceListOptions, AttendanceStatus } from './types';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/attendance/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC/F,YAAY,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveEmployeeId = exports.listAttendances = exports.getStatus = exports.clockOut = exports.clockIn = exports.AttendanceService = void 0;
|
|
4
|
+
var attendance_service_1 = require("./attendance-service");
|
|
5
|
+
Object.defineProperty(exports, "AttendanceService", { enumerable: true, get: function () { return attendance_service_1.AttendanceService; } });
|
|
6
|
+
var functions_1 = require("./functions");
|
|
7
|
+
Object.defineProperty(exports, "clockIn", { enumerable: true, get: function () { return functions_1.clockIn; } });
|
|
8
|
+
Object.defineProperty(exports, "clockOut", { enumerable: true, get: function () { return functions_1.clockOut; } });
|
|
9
|
+
Object.defineProperty(exports, "getStatus", { enumerable: true, get: function () { return functions_1.getStatus; } });
|
|
10
|
+
Object.defineProperty(exports, "listAttendances", { enumerable: true, get: function () { return functions_1.listAttendances; } });
|
|
11
|
+
Object.defineProperty(exports, "resolveEmployeeId", { enumerable: true, get: function () { return functions_1.resolveEmployeeId; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/attendance/index.ts"],"names":[],"mappings":";;;AAAA,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,yCAA+F;AAAtF,oGAAA,OAAO,OAAA;AAAE,qGAAA,QAAQ,OAAA;AAAE,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,8GAAA,iBAAiB,OAAA"}
|