missions api2

This commit is contained in:
alma 2025-05-06 16:00:55 +02:00
parent f53684eb1c
commit df1cc29b57

View File

@ -48,46 +48,79 @@ export class LeantimeService {
console.log(`Creating project with dates: start=${formattedStartDate}, end=${formattedEndDate}`); console.log(`Creating project with dates: start=${formattedStartDate}, end=${formattedEndDate}`);
// Create the project - Follow the exact same pattern from user creation which works // Create project values object
// This pattern matches the Leantime PHP backend expectations const projectData = {
name: mission.name,
clientId: clientId,
details: mission.intention || '',
type: 'project',
start: formattedStartDate,
end: formattedEndDate,
status: 'open',
psettings: 'restricted'
};
console.log('Creating project with data:', JSON.stringify(projectData, null, 2));
// Create with direct call to createProject
const createResponse = await axios.post(
this.getApiEndpoint(),
{
method: 'leantime.rpc.Projects.createProject',
jsonrpc: '2.0',
id: 1,
params: projectData
},
{
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.apiToken
}
}
);
// Log the response
console.log('Create response status:', createResponse.status);
console.log('Create response data:', JSON.stringify(createResponse.data, null, 2));
if (createResponse.data && createResponse.data.result) {
const projectId = createResponse.data.result;
console.log(`Created Leantime project with ID: ${projectId}`);
// If the mission has a logo, set it as project avatar
if (mission.logo) {
await this.setProjectAvatar(projectId, mission.logo);
}
// Assign users to the project
if (mission.missionUsers && mission.missionUsers.length > 0) {
await this.assignUsersToProject(projectId, mission.missionUsers);
}
return projectId;
}
// Fall back to addProject if createProject fails
console.log('createProject failed, trying addProject...');
const payload = { const payload = {
method: 'leantime.rpc.Projects.Projects.addProject', method: 'leantime.rpc.Projects.addProject',
jsonrpc: '2.0', jsonrpc: '2.0',
id: 1, id: 1,
params: { params: {
// Use the same pattern of indexed properties + named properties that works in createLeantimeUser name: mission.name,
values: { clientId: clientId,
'0': 0, // project ID will be set by Leantime details: mission.intention || '',
'1': mission.name, // name type: 'project',
'2': mission.intention || '', // details start: formattedStartDate,
'3': clientId, // clientId end: formattedEndDate,
'4': 'project', // type status: 'open',
'5': formattedStartDate, // start psettings: 'restricted'
'6': formattedEndDate, // end
'7': 'open', // status
'8': 0, // hourBudget
'9': 0, // dollarBudget
'10': 'restricted', // psettings
// Also include named keys for robustness
clientId: clientId,
name: mission.name,
details: mission.intention || '',
type: 'project',
start: formattedStartDate,
end: formattedEndDate,
status: 'open',
hourBudget: 0,
dollarBudget: 0,
psettings: 'restricted'
}
} }
}; };
// Log the full payload console.log('addProject payload:', JSON.stringify(payload, null, 2));
console.log('Project creation payload:', JSON.stringify(payload, null, 2));
// Create the project
const response = await axios.post( const response = await axios.post(
this.getApiEndpoint(), this.getApiEndpoint(),
payload, payload,
@ -99,9 +132,8 @@ export class LeantimeService {
} }
); );
// Log the response console.log('addProject response status:', response.status);
console.log('Leantime response status:', response.status); console.log('addProject response data:', JSON.stringify(response.data, null, 2));
console.log('Leantime response:', JSON.stringify(response.data, null, 2));
if (!response.data || !response.data.result) { if (!response.data || !response.data.result) {
throw new Error(`Failed to create Leantime project: ${JSON.stringify(response.data)}`); throw new Error(`Failed to create Leantime project: ${JSON.stringify(response.data)}`);
@ -224,16 +256,19 @@ export class LeantimeService {
*/ */
async assignUserToProject(projectId: number, userId: string, role: string): Promise<void> { async assignUserToProject(projectId: number, userId: string, role: string): Promise<void> {
try { try {
console.log(`Assigning user ${userId} to project ${projectId} with role ${role}`);
// Try with Projects.addUser first
const response = await axios.post( const response = await axios.post(
this.getApiEndpoint(), this.getApiEndpoint(),
{ {
method: 'leantime.rpc.Projects.Projects.assignUserToProject', method: 'leantime.rpc.Projects.addUser',
jsonrpc: '2.0', jsonrpc: '2.0',
id: 1, id: 1,
params: { params: {
projectId, projectId: projectId,
userId, userId: userId,
role role: role
} }
}, },
{ {
@ -244,11 +279,39 @@ export class LeantimeService {
} }
); );
if (!response.data || !response.data.result) { if (response.data && response.data.result) {
throw new Error(`Failed to assign user to project: ${JSON.stringify(response.data)}`); console.log(`Assigned user ${userId} to project ${projectId} with role ${role}`);
return;
} }
console.log(`Assigned user ${userId} to project ${projectId} with role ${role}`); // If that fails, try with the alternative format
console.log('First method failed, trying Projects.Projects.assignUserToProject...');
const altResponse = await axios.post(
this.getApiEndpoint(),
{
method: 'leantime.rpc.Projects.Projects.assignUserToProject',
jsonrpc: '2.0',
id: 1,
params: {
projectId: projectId,
userId: userId,
role: role
}
},
{
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.apiToken
}
}
);
if (!altResponse.data || !altResponse.data.result) {
throw new Error(`Failed to assign user to project with both methods: ${JSON.stringify(altResponse.data)}`);
}
console.log(`Assigned user ${userId} to project ${projectId} with role ${role} using alternative method`);
} catch (error) { } catch (error) {
console.error(`Error assigning user ${userId} to project ${projectId}:`, error); console.error(`Error assigning user ${userId} to project ${projectId}:`, error);
// Don't fail if individual user assignment fails // Don't fail if individual user assignment fails
@ -366,12 +429,46 @@ export class LeantimeService {
*/ */
async getUserByEmail(email: string): Promise<string | null> { async getUserByEmail(email: string): Promise<string | null> {
try { try {
console.log(`Looking up user with email: ${email}`);
// Try getUserByEmail first (direct lookup method)
try {
const directResponse = await axios.post(
this.getApiEndpoint(),
{
method: 'leantime.rpc.Users.Users.getUserByEmail',
jsonrpc: '2.0',
id: 1,
params: {
email: email
}
},
{
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.apiToken
}
}
);
if (directResponse.data &&
directResponse.data.result &&
directResponse.data.result !== false &&
directResponse.data.result.id) {
console.log(`Found user by direct email lookup: ${directResponse.data.result.id}`);
return directResponse.data.result.id;
}
} catch (directError) {
console.log('Direct email lookup failed, trying alternate method...');
}
// Fall back to get all users and filter
const response = await axios.post( const response = await axios.post(
this.getApiEndpoint(), this.getApiEndpoint(),
{ {
method: 'leantime.rpc.Users.Users.getAll', method: 'leantime.rpc.Users.Users.getAll',
jsonrpc: '2.0', jsonrpc: '2.0',
id: 1, id: 1
}, },
{ {
headers: { headers: {
@ -386,9 +483,28 @@ export class LeantimeService {
} }
const users = response.data.result; const users = response.data.result;
const user = users.find((u: any) => u.email === email);
return user ? user.id : null; // First try exact email match
let user = users.find((u: any) => u.email === email || u.username === email);
// If that fails, try case-insensitive match
if (!user) {
const lowerEmail = email.toLowerCase();
user = users.find((u: any) =>
(u.email && u.email.toLowerCase() === lowerEmail) ||
(u.username && u.username.toLowerCase() === lowerEmail)
);
}
if (user) {
console.log(`Found user with email ${email}: ID ${user.id}`);
return user.id;
} else {
// If user is still not found, we might need to create them
// This would require additional code to create a user if needed
console.log(`No user found with email ${email}`);
return null;
}
} catch (error) { } catch (error) {
console.error('Error getting user by email:', error); console.error('Error getting user by email:', error);
return null; return null;