Files
worklenz/worklenz-backend/src/controllers/project-templates/pt-templates-controller.ts
chamikaJ 8825b0410a init
2025-04-17 18:28:54 +05:30

255 lines
11 KiB
TypeScript

import { IWorkLenzRequest } from "../../interfaces/worklenz-request";
import { IWorkLenzResponse } from "../../interfaces/worklenz-response";
import db from "../../config/db";
import { ServerResponse } from "../../models/server-response";
import HandleExceptions from "../../decorators/handle-exceptions";
import { templateData } from "./project-templates";
import ProjectTemplatesControllerBase from "./project-templates-base";
import { LOG_DESCRIPTIONS, TASK_PRIORITY_COLOR_ALPHA, TASK_STATUS_COLOR_ALPHA } from "../../shared/constants";
import { IO } from "../../shared/io";
import { getCurrentProjectsCount, getFreePlanSettings } from "../../shared/paddle-utils";
export default class ProjectTemplatesController extends ProjectTemplatesControllerBase {
@HandleExceptions()
public static async getTemplates(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const q = `SELECT id, name FROM pt_project_templates ORDER BY name;`;
const result = await db.query(q, []);
return res.status(200).send(new ServerResponse(true, result.rows));
}
@HandleExceptions()
public static async getCustomTemplates(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const { searchQuery } = this.toPaginationOptions(req.query, "name");
const q = `SELECT id, name, created_at, FALSE AS selected FROM custom_project_templates WHERE team_id = $1 ${searchQuery} ORDER BY name;`;
const result = await db.query(q, [req.user?.team_id]);
return res.status(200).send(new ServerResponse(true, result.rows));
}
@HandleExceptions()
public static async deleteCustomTemplate(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const { id } = req.params;
const q = `DELETE FROM custom_project_templates WHERE id = $1;`;
await db.query(q, [id]);
return res.status(200).send(new ServerResponse(true, [], "Template deleted successfully."));
}
@HandleExceptions()
public static async getDefaultProjectStatus() {
const q = `SELECT id FROM sys_project_statuses WHERE is_default IS TRUE;`;
const result = await db.query(q, []);
const [data] = result.rows;
return data.id;
}
@HandleExceptions()
public static async getDefaultProjectHealth() {
const q = `SELECT id FROM sys_project_healths WHERE is_default IS TRUE`;
const result = await db.query(q, []);
const [data] = result.rows;
return data.id;
}
@HandleExceptions()
public static async getTemplateById(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const { id } = req.params;
const data = await this.getTemplateData(id);
for (const phase of data.phases) {
phase.color_code = phase.color_code + TASK_STATUS_COLOR_ALPHA;
}
for (const status of data.status) {
status.color_code = status.color_code + TASK_STATUS_COLOR_ALPHA;
}
for (const priority of data.priorities) {
priority.color_code = priority.color_code + TASK_PRIORITY_COLOR_ALPHA;
}
for (const label of data.labels) {
label.color_code = label.color_code + TASK_STATUS_COLOR_ALPHA;
}
return res.status(200).send(new ServerResponse(true, data));
}
@HandleExceptions()
public static async createTemplates(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
for (const template of templateData) {
let template_id: string | null = null;
template_id = await this.insertProjectTemplate(template);
if (template_id) {
await this.insertTemplateProjectPhases(template.phases, template_id);
await this.insertTemplateProjectStatuses(template.status, template_id);
await this.insertTemplateProjectTasks(template.tasks, template_id);
}
}
return res.status(200).send(new ServerResponse(true, []));
}
@HandleExceptions()
public static async importTemplates(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
if (req.user?.subscription_status === "free" && req.user?.owner_id) {
const limits = await getFreePlanSettings();
const projectsCount = await getCurrentProjectsCount(req.user.owner_id);
const projectsLimit = parseInt(limits.projects_limit);
if (parseInt(projectsCount) >= projectsLimit) {
return res.status(200).send(new ServerResponse(false, [], `Sorry, the free plan cannot have more than ${projectsLimit} projects.`));
}
}
const { template_id } = req.body;
let project_id: string | null = null;
const data = await this.getTemplateData(template_id);
if (data) {
data.team_id = req.user?.team_id || null;
data.user_id = req.user?.id || null;
data.folder_id = null;
data.category_id = null;
data.status_id = await this.getDefaultProjectStatus();
data.project_created_log = LOG_DESCRIPTIONS.PROJECT_CREATED;
data.project_member_added_log = LOG_DESCRIPTIONS.PROJECT_MEMBER_ADDED;
data.health_id = await this.getDefaultProjectHealth();
data.working_days = 0;
data.man_days = 0;
data.hours_per_day = 8;
project_id = await this.importTemplate(data);
await this.insertTeamLabels(data.labels, req.user?.team_id);
await this.insertProjectPhases(data.phases, project_id as string);
await this.insertProjectTasks(data.tasks, data.team_id, project_id as string, data.user_id, IO.getSocketById(req.user?.socket_id as string));
return res.status(200).send(new ServerResponse(true, { project_id }));
}
return res.status(200).send(new ServerResponse(true, { project_id }));
}
@HandleExceptions({
raisedExceptions: {
"TEMPLATE_EXISTS_ERROR": `A template with the name "{0}" already exists. Please choose a different name.`
}
})
public static async createCustomTemplate(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const { project_id, templateName, projectIncludes, taskIncludes } = req.body;
const team_id = req.user?.team_id || null;
if (!team_id || !project_id) return res.status(400).send(new ServerResponse(false, {}));
let status, labels, phases = [];
const data = await this.getProjectData(project_id);
if (projectIncludes.statuses) {
status = await this.getProjectStatus(project_id);
}
if (projectIncludes.phases) {
phases = await this.getProjectPhases(project_id);
}
if (projectIncludes.labels) {
labels = await this.getProjectLabels(team_id, project_id);
}
const tasks = await this.getTasksByProject(project_id, taskIncludes);
data.name = templateName;
data.team_id = team_id;
const q = `SELECT create_project_template($1);`;
const result = await db.query(q, [JSON.stringify(data)]);
const [obj] = result.rows;
const template_id = obj.create_project_template.id;
if (template_id) {
if (phases) await this.insertCustomTemplatePhases(phases, template_id);
if (status) await this.insertCustomTemplateStatus(status, template_id, team_id);
if (tasks) await this.insertCustomTemplateTasks(tasks, template_id, team_id);
}
return res.status(200).send(new ServerResponse(true, {}, "Project template created successfully."));
}
@HandleExceptions()
public static async setupAccount(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
const { template_id, team_name } = req.body;
let project_id: string | null = null;
await this.updateTeamName(team_name, req.user?.team_id as string, req.user?.id as string);
const data = await this.getTemplateData(template_id);
if (data) {
data.team_id = req.user?.team_id || null;
data.user_id = req.user?.id || null;
data.folder_id = null;
data.category_id = null;
data.status_id = await this.getDefaultProjectStatus();
data.project_created_log = LOG_DESCRIPTIONS.PROJECT_CREATED;
data.project_member_added_log = LOG_DESCRIPTIONS.PROJECT_MEMBER_ADDED;
data.health_id = await this.getDefaultProjectHealth();
data.working_days = 0;
data.man_days = 0;
data.hours_per_day = 8;
project_id = await this.importTemplate(data);
await this.insertTeamLabels(data.labels, req.user?.team_id);
await this.insertProjectPhases(data.phases, project_id as string);
await this.insertProjectTasks(data.tasks, data.team_id, project_id as string, data.user_id, IO.getSocketById(req.user?.socket_id as string));
await this.handleAccountSetup(project_id as string, data.user_id, team_name);
return res.status(200).send(new ServerResponse(true, { id: project_id }));
}
return res.status(200).send(new ServerResponse(true, { id: project_id }));
}
@HandleExceptions()
public static async importCustomTemplate(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise<IWorkLenzResponse> {
if (req.user?.subscription_status === "free" && req.user?.owner_id) {
const limits = await getFreePlanSettings();
const projectsCount = await getCurrentProjectsCount(req.user.owner_id);
const projectsLimit = parseInt(limits.projects_limit);
if (parseInt(projectsCount) >= projectsLimit) {
return res.status(200).send(new ServerResponse(false, [], `Sorry, the free plan cannot have more than ${projectsLimit} projects.`));
}
}
const { template_id } = req.body;
let project_id: string | null = null;
const data = await this.getCustomTemplateData(template_id);
if (data) {
data.team_id = req.user?.team_id || null;
data.user_id = req.user?.id || null;
data.folder_id = null;
data.category_id = null;
data.status_id = await this.getDefaultProjectStatus();
data.project_created_log = LOG_DESCRIPTIONS.PROJECT_CREATED;
data.project_member_added_log = LOG_DESCRIPTIONS.PROJECT_MEMBER_ADDED;
data.working_days = 0;
data.man_days = 0;
data.hours_per_day = 8;
project_id = await this.importTemplate(data);
await this.deleteDefaultStatusForProject(project_id as string);
await this.insertTeamLabels(data.labels, req.user?.team_id);
await this.insertProjectPhases(data.phases, project_id as string);
await this.insertProjectStatuses(data.status, project_id as string, data.team_id);
await this.insertProjectTasksFromCustom(data.tasks, data.team_id, project_id as string, data.user_id, IO.getSocketById(req.user?.socket_id as string));
return res.status(200).send(new ServerResponse(true, { project_id }));
}
return res.status(200).send(new ServerResponse(true, { project_id }));
}
}