odoo-fti-be/models/odooService.js
2025-06-17 14:11:45 +08:00

237 lines
7.0 KiB
JavaScript

// models/odooService.js
import axios from "axios";
import { odooConfig } from "../config/odooConfig.js";
import { toOdooDatetimeFormat } from "../utils/date.js"; // Adjust path if needed
const JSON_RPC_URL = `${odooConfig.url}/jsonrpc`;
export const authenticate = async () => {
const payload = {
jsonrpc: "2.0",
method: "call",
params: {
service: "common",
method: "login",
args: [odooConfig.db, odooConfig.email, odooConfig.apiKey],
},
id: 1,
};
const { data } = await axios.post(JSON_RPC_URL, payload);
return data.result;
};
export const fetchEmployees = async () => {
const uid = await authenticate();
const payload = {
jsonrpc: "2.0",
method: "call",
params: {
service: "object",
method: "execute_kw",
args: [
odooConfig.db,
uid,
odooConfig.apiKey,
"hr.employee",
"search_read",
[],
{ fields: ["id", "name", "work_email"], limit: 10 },
],
},
id: 2,
};
const { data } = await axios.post(JSON_RPC_URL, payload);
return data.result;
};
export const checkEmployeeExists = async (employee_id) => {
const uid = await authenticate();
const payload = {
jsonrpc: "2.0",
method: "call",
params: {
service: "object",
method: "execute_kw",
args: [
odooConfig.db,
uid,
odooConfig.apiKey,
"hr.employee",
"search",
[[["id", "=", employee_id]]],
0,
],
},
id: 10,
};
const res = await axios.post(JSON_RPC_URL, payload);
return res.data.result && res.data.result.length > 0;
};
/**
* Toggles attendance check-in/check-out for an employee
* @param {number} employee_id
* @returns {object} status and attendance record info
*/
export const toggleEmployeeAttendance = async (employee_id) => {
try {
const uid = await authenticate();
if (!uid) {
throw new Error("Authentication failed: no user ID returned.");
}
// Optional: Verify employee exists
const checkEmployeePayload = {
jsonrpc: "2.0",
method: "call",
params: {
service: "object",
method: "execute_kw",
args: [
odooConfig.db,
uid,
odooConfig.apiKey,
"hr.employee",
"search",
[[["id", "=", employee_id]]],
],
},
id: 0,
};
const empRes = await axios.post(JSON_RPC_URL, checkEmployeePayload);
if (!empRes.data.result || empRes.data.result.length === 0) {
throw new Error(`Employee with ID ${employee_id} not found.`);
}
// Step 1: Search for open attendance record (check_out = false)
const searchPayload = {
jsonrpc: "2.0",
method: "call",
params: {
service: "object",
method: "execute_kw",
args: [
odooConfig.db,
uid,
odooConfig.apiKey,
"hr.attendance",
"search_read",
[
[
["employee_id", "=", employee_id],
["check_out", "=", false],
],
],
{ fields: ["id", "check_in"], limit: 1 },
],
},
id: 3,
};
const searchRes = await axios.post(JSON_RPC_URL, searchPayload);
const openRecords = searchRes.data.result;
if (openRecords.length > 0) {
// Step 2: Write check_out datetime
const attendanceId = openRecords[0].id;
const now = toOdooDatetimeFormat(new Date());
const writePayload = {
jsonrpc: "2.0",
method: "call",
params: {
service: "object",
method: "execute_kw",
args: [
odooConfig.db,
uid,
odooConfig.apiKey,
"hr.attendance",
"write",
[[attendanceId], { check_out: now }],
],
},
id: 4,
};
const writeRes = await axios.post(JSON_RPC_URL, writePayload);
if (!writeRes.data.result) {
throw new Error("Failed to write check_out datetime.");
}
return {
status: "Checked out",
attendance_id: attendanceId,
check_out: now,
odoo_response: writeRes.data,
};
} else {
// Step 3: Create new attendance record with check_in
const now = toOdooDatetimeFormat(new Date());
const createPayload = {
jsonrpc: "2.0",
method: "call",
params: {
service: "object",
method: "execute_kw",
args: [
odooConfig.db,
uid,
odooConfig.apiKey,
"hr.attendance",
"create",
[{ employee_id, check_in: now }],
],
},
id: 5,
};
const createRes = await axios.post(JSON_RPC_URL, createPayload);
// DEBUG LOGGING - print entire response from Odoo
console.log(
"Create attendance response from Odoo:",
JSON.stringify(createRes.data, null, 2)
);
if (createRes.data.error) {
// Odoo returned an error object - log it and throw
console.error(
"Odoo error during attendance creation:",
createRes.data.error
);
throw new Error(
createRes.data.error.message ||
"Unknown Odoo error during attendance creation"
);
}
if (!createRes.data.result) {
throw new Error(
"Failed to create attendance record - no result returned."
);
}
const attendanceId = createRes.data.result;
return {
status: "Checked in",
attendance_id: attendanceId,
check_in: now,
odoo_response: createRes.data,
};
}
} catch (error) {
console.error("toggleEmployeeAttendance error:", error);
throw error;
}
};