@hed-hog/operations 0.0.304 → 0.0.305
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/controllers/operations-projects.controller.d.ts +15 -0
- package/dist/controllers/operations-projects.controller.d.ts.map +1 -1
- package/dist/controllers/operations-tasks.controller.d.ts +41 -10
- package/dist/controllers/operations-tasks.controller.d.ts.map +1 -1
- package/dist/controllers/operations-tasks.controller.js +11 -0
- package/dist/controllers/operations-tasks.controller.js.map +1 -1
- package/dist/dto/create-task.dto.d.ts +7 -1
- package/dist/dto/create-task.dto.d.ts.map +1 -1
- package/dist/dto/create-task.dto.js +38 -5
- package/dist/dto/create-task.dto.js.map +1 -1
- package/dist/dto/list-tasks.dto.d.ts +1 -1
- package/dist/dto/list-tasks.dto.d.ts.map +1 -1
- package/dist/dto/list-tasks.dto.js +2 -2
- package/dist/dto/list-tasks.dto.js.map +1 -1
- package/dist/dto/update-task.dto.d.ts +7 -1
- package/dist/dto/update-task.dto.d.ts.map +1 -1
- package/dist/dto/update-task.dto.js +38 -5
- package/dist/dto/update-task.dto.js.map +1 -1
- package/dist/operations.service.d.ts +68 -12
- package/dist/operations.service.d.ts.map +1 -1
- package/dist/operations.service.js +380 -101
- package/dist/operations.service.js.map +1 -1
- package/hedhog/data/route.yaml +13 -0
- package/hedhog/frontend/app/_components/collaborator-details-screen.tsx.ejs +44 -44
- package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +168 -213
- package/hedhog/frontend/app/_components/collaborator-select-with-create.tsx.ejs +256 -256
- package/hedhog/frontend/app/_components/contract-form-screen.tsx.ejs +7 -7
- package/hedhog/frontend/app/_components/contract-template-form-screen.tsx.ejs +306 -306
- package/hedhog/frontend/app/_components/contract-template-select-with-create.tsx.ejs +247 -247
- package/hedhog/frontend/app/_components/contract-wizard-sheet.tsx.ejs +3520 -3520
- package/hedhog/frontend/app/_components/project-details-screen.tsx.ejs +1504 -52
- package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +528 -403
- package/hedhog/frontend/app/_components/section-card.tsx.ejs +25 -18
- package/hedhog/frontend/app/_components/system-user-select-with-create.tsx.ejs +609 -0
- package/hedhog/frontend/app/_lib/types.ts.ejs +5 -0
- package/hedhog/frontend/app/_lib/utils/format.ts.ejs +7 -7
- package/hedhog/frontend/app/_lib/utils/forms.ts.ejs +48 -1
- package/hedhog/frontend/app/collaborator-types/page.tsx.ejs +502 -502
- package/hedhog/frontend/app/collaborators/page.tsx.ejs +10 -7
- package/hedhog/frontend/app/contracts/page.tsx.ejs +938 -938
- package/hedhog/frontend/app/projects/[id]/edit/page.tsx.ejs +1 -1
- package/hedhog/frontend/app/projects/page.tsx.ejs +360 -133
- package/hedhog/frontend/messages/en.json +27 -4
- package/hedhog/frontend/messages/pt.json +27 -4
- package/hedhog/table/operations_project.yaml +9 -0
- package/hedhog/table/operations_task.yaml +43 -4
- package/package.json +5 -5
- package/src/controllers/operations-tasks.controller.ts +11 -0
- package/src/dto/create-task.dto.ts +47 -7
- package/src/dto/list-tasks.dto.ts +3 -3
- package/src/dto/update-task.dto.ts +47 -7
- package/src/operations.service.ts +556 -88
|
@@ -107,7 +107,7 @@ const FINANCIAL_TERM_TYPE_VALUES = ['value', 'payment', 'revenue', 'fine', 'othe
|
|
|
107
107
|
const RECURRENCE_VALUES = ['one_time', 'monthly', 'quarterly', 'yearly', 'other'];
|
|
108
108
|
const REVISION_TYPE_VALUES = ['amendment', 'renewal', 'revision', 'addendum', 'other'];
|
|
109
109
|
const REVISION_STATUS_VALUES = ['draft', 'active', 'completed', 'cancelled'];
|
|
110
|
-
const TASK_STATUS_VALUES = ['
|
|
110
|
+
const TASK_STATUS_VALUES = ['todo', 'doing', 'review', 'done'];
|
|
111
111
|
let OperationsService = OperationsService_1 = class OperationsService {
|
|
112
112
|
constructor(prisma, aiService, integrationApi, fileService, settingService, accessService, localeService) {
|
|
113
113
|
this.prisma = prisma;
|
|
@@ -834,6 +834,20 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
834
834
|
if (data.equityParticipation !== undefined) {
|
|
835
835
|
await this.replaceCollaboratorEquityParticipation(tx, collaboratorId, data.equityParticipation);
|
|
836
836
|
}
|
|
837
|
+
if (data.compensationAmount !== undefined ||
|
|
838
|
+
data.contractDescription !== undefined ||
|
|
839
|
+
data.autoGenerateContractDraft !== undefined ||
|
|
840
|
+
data.joinedAt !== undefined ||
|
|
841
|
+
data.weeklyCapacityHours !== undefined ||
|
|
842
|
+
data.supervisorCollaboratorId !== undefined ||
|
|
843
|
+
data.collaboratorType !== undefined ||
|
|
844
|
+
data.collaboratorTypeId !== undefined ||
|
|
845
|
+
data.collaboratorTypeSlug !== undefined ||
|
|
846
|
+
data.code !== undefined ||
|
|
847
|
+
data.personId !== undefined ||
|
|
848
|
+
data.displayName !== undefined) {
|
|
849
|
+
await this.syncHiringContractDraft(tx, actor.userId, collaboratorId, data);
|
|
850
|
+
}
|
|
837
851
|
});
|
|
838
852
|
return this.getCollaboratorByIdForUser(userId, collaboratorId);
|
|
839
853
|
}
|
|
@@ -1021,8 +1035,8 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
1021
1035
|
p.progress_percent AS "progressPercent",
|
|
1022
1036
|
p.delivery_model AS "deliveryModel",
|
|
1023
1037
|
p.budget_amount AS "budgetAmount",
|
|
1024
|
-
p.start_date AS "startDate",
|
|
1025
|
-
p.end_date AS "endDate",
|
|
1038
|
+
TO_CHAR(p.start_date, 'YYYY-MM-DD') AS "startDate",
|
|
1039
|
+
TO_CHAR(p.end_date, 'YYYY-MM-DD') AS "endDate",
|
|
1026
1040
|
c.name AS "contractName",
|
|
1027
1041
|
c.status AS "contractStatus",
|
|
1028
1042
|
m.display_name AS "managerName",
|
|
@@ -1090,8 +1104,8 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
1090
1104
|
MAX(pa.id)::int AS "projectAssignmentId",
|
|
1091
1105
|
MAX(pa.role_label) AS "roleLabel",
|
|
1092
1106
|
p.status,
|
|
1093
|
-
p.start_date AS "startDate",
|
|
1094
|
-
p.end_date AS "endDate"
|
|
1107
|
+
TO_CHAR(p.start_date, 'YYYY-MM-DD') AS "startDate",
|
|
1108
|
+
TO_CHAR(p.end_date, 'YYYY-MM-DD') AS "endDate"
|
|
1095
1109
|
FROM operations_project_assignment pa
|
|
1096
1110
|
JOIN operations_project p
|
|
1097
1111
|
ON p.id = pa.project_id
|
|
@@ -1178,52 +1192,84 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
1178
1192
|
return this.buildPaginationResult(rows.map((row) => (Object.assign(Object.assign({}, row), { label: [row.name, row.projectName].filter(Boolean).join(' • ') }))), Number((_b = totalRow === null || totalRow === void 0 ? void 0 : totalRow.total) !== null && _b !== void 0 ? _b : 0), pagination.page, pagination.pageSize);
|
|
1179
1193
|
}
|
|
1180
1194
|
async createTask(userId, data) {
|
|
1181
|
-
var _a, _b, _c, _d;
|
|
1195
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
1182
1196
|
const actor = await this.getActorContext(userId);
|
|
1183
|
-
|
|
1197
|
+
if (!actor.isCollaborator && !actor.isDirector && !actor.isSupervisor) {
|
|
1198
|
+
throw new common_1.ForbiddenException('Operations collaborator access is required.');
|
|
1199
|
+
}
|
|
1184
1200
|
this.requireFields(data, ['name']);
|
|
1185
|
-
|
|
1186
|
-
|
|
1201
|
+
let assignmentId = null;
|
|
1202
|
+
let projectId = null;
|
|
1203
|
+
if (data.projectId || data.projectAssignmentId) {
|
|
1204
|
+
const assignment = await this.resolveProjectAssignmentForActor(this.prisma, actor, {
|
|
1205
|
+
projectId: (_a = data.projectId) !== null && _a !== void 0 ? _a : null,
|
|
1206
|
+
projectAssignmentId: (_b = data.projectAssignmentId) !== null && _b !== void 0 ? _b : null,
|
|
1207
|
+
});
|
|
1208
|
+
await this.assertProjectAccess(actor, assignment.projectId);
|
|
1209
|
+
assignmentId = assignment.id;
|
|
1210
|
+
projectId = assignment.projectId;
|
|
1211
|
+
}
|
|
1212
|
+
else if (data.projectId) {
|
|
1213
|
+
projectId = data.projectId;
|
|
1214
|
+
await this.assertProjectAccess(actor, projectId);
|
|
1215
|
+
}
|
|
1216
|
+
else {
|
|
1217
|
+
throw new common_1.BadRequestException('Either projectId or projectAssignmentId is required.');
|
|
1218
|
+
}
|
|
1219
|
+
if (!projectId) {
|
|
1220
|
+
projectId = (_c = data.projectId) !== null && _c !== void 0 ? _c : null;
|
|
1187
1221
|
}
|
|
1188
|
-
const assignment = await this.resolveOwnedProjectAssignment(this.prisma, actor.collaboratorId, {
|
|
1189
|
-
projectId: (_a = data.projectId) !== null && _a !== void 0 ? _a : null,
|
|
1190
|
-
projectAssignmentId: (_b = data.projectAssignmentId) !== null && _b !== void 0 ? _b : null,
|
|
1191
|
-
});
|
|
1192
|
-
await this.assertProjectAccess(actor, assignment.projectId);
|
|
1193
1222
|
const name = this.normalizeOptionalText(data.name);
|
|
1194
1223
|
if (!name) {
|
|
1195
1224
|
throw new common_1.BadRequestException('Field "name" is required.');
|
|
1196
1225
|
}
|
|
1226
|
+
const maxPositionRow = await this.querySingle(`SELECT MAX(position) AS max_pos
|
|
1227
|
+
FROM operations_task
|
|
1228
|
+
WHERE project_id = $1
|
|
1229
|
+
AND status = $2::operations_task_status_574c143dbe_enum
|
|
1230
|
+
AND deleted_at IS NULL`, [projectId, (_d = data.status) !== null && _d !== void 0 ? _d : 'todo']);
|
|
1231
|
+
const nextPosition = ((_e = maxPositionRow === null || maxPositionRow === void 0 ? void 0 : maxPositionRow.max_pos) !== null && _e !== void 0 ? _e : -1) + 1;
|
|
1197
1232
|
const created = await this.querySingle(`INSERT INTO operations_task (
|
|
1233
|
+
project_id,
|
|
1198
1234
|
project_assignment_id,
|
|
1235
|
+
assignee_collaborator_id,
|
|
1199
1236
|
name,
|
|
1200
1237
|
description,
|
|
1238
|
+
priority,
|
|
1201
1239
|
status,
|
|
1240
|
+
due_date,
|
|
1241
|
+
estimate_hours,
|
|
1242
|
+
position,
|
|
1243
|
+
tags,
|
|
1202
1244
|
created_at,
|
|
1203
1245
|
updated_at
|
|
1204
1246
|
) VALUES (
|
|
1205
|
-
$1,
|
|
1206
|
-
$
|
|
1207
|
-
$
|
|
1208
|
-
$
|
|
1209
|
-
NOW(),
|
|
1210
|
-
NOW()
|
|
1247
|
+
$1, $2, $3, $4, $5,
|
|
1248
|
+
$6::operations_task_priority_394ab327eb_enum,
|
|
1249
|
+
$7::operations_task_status_574c143dbe_enum,
|
|
1250
|
+
$8::date, $9::decimal, $10, $11, NOW(), NOW()
|
|
1211
1251
|
)
|
|
1212
1252
|
RETURNING id`, [
|
|
1213
|
-
|
|
1253
|
+
projectId,
|
|
1254
|
+
assignmentId,
|
|
1255
|
+
(_f = data.assigneeCollaboratorId) !== null && _f !== void 0 ? _f : null,
|
|
1214
1256
|
name,
|
|
1215
1257
|
this.normalizeOptionalText(data.description),
|
|
1216
|
-
(
|
|
1258
|
+
(_g = data.priority) !== null && _g !== void 0 ? _g : 'medium',
|
|
1259
|
+
(_h = data.status) !== null && _h !== void 0 ? _h : 'todo',
|
|
1260
|
+
(_j = data.dueDate) !== null && _j !== void 0 ? _j : null,
|
|
1261
|
+
(_k = data.estimateHours) !== null && _k !== void 0 ? _k : null,
|
|
1262
|
+
(_l = data.position) !== null && _l !== void 0 ? _l : nextPosition,
|
|
1263
|
+
(_m = data.tags) !== null && _m !== void 0 ? _m : null,
|
|
1217
1264
|
]);
|
|
1218
|
-
return this.
|
|
1265
|
+
return this.getProjectBoardTask((_o = created === null || created === void 0 ? void 0 : created.id) !== null && _o !== void 0 ? _o : 0);
|
|
1219
1266
|
}
|
|
1220
1267
|
async updateTask(userId, taskId, data) {
|
|
1221
1268
|
const actor = await this.getActorContext(userId);
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
throw new common_1.BadRequestException('Collaborator context is required.');
|
|
1269
|
+
if (!actor.isCollaborator && !actor.isDirector && !actor.isSupervisor) {
|
|
1270
|
+
throw new common_1.ForbiddenException('Operations collaborator access is required.');
|
|
1225
1271
|
}
|
|
1226
|
-
const current = await this.
|
|
1272
|
+
const current = await this.getTaskRecordForActor(this.prisma, actor, taskId);
|
|
1227
1273
|
await this.assertProjectAccess(actor, current.projectId);
|
|
1228
1274
|
const nextName = data.name !== undefined
|
|
1229
1275
|
? this.normalizeOptionalText(data.name)
|
|
@@ -1232,42 +1278,50 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
1232
1278
|
throw new common_1.BadRequestException('Field "name" is required.');
|
|
1233
1279
|
}
|
|
1234
1280
|
await this.prisma.$transaction(async (tx) => {
|
|
1235
|
-
var _a, _b, _c, _d;
|
|
1236
|
-
|
|
1237
|
-
|
|
1281
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
1282
|
+
let nextAssignmentId = current.projectAssignmentId;
|
|
1283
|
+
let nextProjectId = current.projectId;
|
|
1284
|
+
if (data.projectId !== undefined || data.projectAssignmentId !== undefined) {
|
|
1285
|
+
const nextAssignment = await this.resolveProjectAssignmentForActor(tx, actor, {
|
|
1238
1286
|
projectId: (_a = data.projectId) !== null && _a !== void 0 ? _a : null,
|
|
1239
1287
|
projectAssignmentId: (_b = data.projectAssignmentId) !== null && _b !== void 0 ? _b : null,
|
|
1240
|
-
})
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
await this.assertProjectAccess(actor, nextAssignment.projectId);
|
|
1288
|
+
});
|
|
1289
|
+
await this.assertProjectAccess(actor, nextAssignment.projectId);
|
|
1290
|
+
nextAssignmentId = nextAssignment.id;
|
|
1291
|
+
nextProjectId = nextAssignment.projectId;
|
|
1292
|
+
}
|
|
1246
1293
|
await tx.$executeRawUnsafe(`UPDATE operations_task
|
|
1247
|
-
SET
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1294
|
+
SET project_id = $1,
|
|
1295
|
+
project_assignment_id = $2,
|
|
1296
|
+
assignee_collaborator_id = $3,
|
|
1297
|
+
name = $4,
|
|
1298
|
+
description = $5,
|
|
1299
|
+
priority = $6::operations_task_priority_394ab327eb_enum,
|
|
1300
|
+
status = $7::operations_task_status_574c143dbe_enum,
|
|
1301
|
+
due_date = $8::date,
|
|
1302
|
+
estimate_hours = $9::decimal,
|
|
1303
|
+
position = $10,
|
|
1304
|
+
tags = $11,
|
|
1251
1305
|
updated_at = NOW()
|
|
1252
|
-
WHERE id = $
|
|
1253
|
-
AND deleted_at IS NULL`,
|
|
1306
|
+
WHERE id = $12
|
|
1307
|
+
AND deleted_at IS NULL`, nextProjectId, nextAssignmentId, data.assigneeCollaboratorId !== undefined
|
|
1308
|
+
? ((_c = data.assigneeCollaboratorId) !== null && _c !== void 0 ? _c : null)
|
|
1309
|
+
: current.assigneeCollaboratorId, nextName, data.description !== undefined
|
|
1254
1310
|
? this.normalizeOptionalText(data.description)
|
|
1255
|
-
: ((
|
|
1311
|
+
: ((_d = current.description) !== null && _d !== void 0 ? _d : null), (_e = data.priority) !== null && _e !== void 0 ? _e : current.priority, (_f = data.status) !== null && _f !== void 0 ? _f : current.status, data.dueDate !== undefined ? ((_g = data.dueDate) !== null && _g !== void 0 ? _g : null) : current.dueDate, data.estimateHours !== undefined ? ((_h = data.estimateHours) !== null && _h !== void 0 ? _h : null) : current.estimateHours, data.position !== undefined ? data.position : current.position, data.tags !== undefined ? ((_j = data.tags) !== null && _j !== void 0 ? _j : null) : current.tags, taskId);
|
|
1256
1312
|
});
|
|
1257
|
-
return this.
|
|
1313
|
+
return this.getProjectBoardTask(taskId);
|
|
1258
1314
|
}
|
|
1259
1315
|
async removeTask(userId, taskId) {
|
|
1260
1316
|
const actor = await this.getActorContext(userId);
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
throw new common_1.BadRequestException('Collaborator context is required.');
|
|
1317
|
+
if (!actor.isCollaborator && !actor.isDirector && !actor.isSupervisor) {
|
|
1318
|
+
throw new common_1.ForbiddenException('Operations collaborator access is required.');
|
|
1264
1319
|
}
|
|
1265
|
-
const current = await this.
|
|
1320
|
+
const current = await this.getTaskRecordForActor(this.prisma, actor, taskId);
|
|
1266
1321
|
await this.assertProjectAccess(actor, current.projectId);
|
|
1267
1322
|
await this.prisma.$transaction(async (tx) => {
|
|
1268
1323
|
await tx.$executeRawUnsafe(`UPDATE operations_task
|
|
1269
1324
|
SET deleted_at = COALESCE(deleted_at, NOW()),
|
|
1270
|
-
status = 'archived',
|
|
1271
1325
|
updated_at = NOW()
|
|
1272
1326
|
WHERE id = $1
|
|
1273
1327
|
AND deleted_at IS NULL`, taskId);
|
|
@@ -1479,10 +1533,11 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
1479
1533
|
this.ensureDirector(actor);
|
|
1480
1534
|
this.requireFields(data, ['code', 'name']);
|
|
1481
1535
|
const createdProjectId = await this.prisma.$transaction(async (tx) => {
|
|
1482
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
|
|
1536
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
|
|
1483
1537
|
const created = await tx.$queryRawUnsafe(`INSERT INTO operations_project (
|
|
1484
1538
|
contract_id,
|
|
1485
1539
|
manager_collaborator_id,
|
|
1540
|
+
client_person_id,
|
|
1486
1541
|
code,
|
|
1487
1542
|
name,
|
|
1488
1543
|
client_name,
|
|
@@ -1496,33 +1551,33 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
1496
1551
|
created_at,
|
|
1497
1552
|
updated_at
|
|
1498
1553
|
) VALUES (
|
|
1499
|
-
$1, $2, $3, $4, $5, $6,
|
|
1500
|
-
$
|
|
1501
|
-
$
|
|
1502
|
-
$
|
|
1503
|
-
$
|
|
1554
|
+
$1, $2, $3, $4, $5, $6, $7,
|
|
1555
|
+
$8::operations_project_status_965e8d4b2d_enum,
|
|
1556
|
+
$9,
|
|
1557
|
+
$10::operations_project_delivery_model_75ee11b3b7_enum,
|
|
1558
|
+
$11, $12::date, $13::date, NOW(), NOW()
|
|
1504
1559
|
)
|
|
1505
|
-
RETURNING id`, (_a = data.contractId) !== null && _a !== void 0 ? _a : null, (_b = data.managerCollaboratorId) !== null && _b !== void 0 ? _b : null, data.code, data.name, (
|
|
1506
|
-
const projectId = (
|
|
1507
|
-
if ((
|
|
1560
|
+
RETURNING id`, (_a = data.contractId) !== null && _a !== void 0 ? _a : null, (_b = data.managerCollaboratorId) !== null && _b !== void 0 ? _b : null, (_c = data.clientPersonId) !== null && _c !== void 0 ? _c : null, data.code, data.name, (_d = data.clientName) !== null && _d !== void 0 ? _d : null, (_e = data.summary) !== null && _e !== void 0 ? _e : null, (_f = data.status) !== null && _f !== void 0 ? _f : 'planning', (_g = data.progressPercent) !== null && _g !== void 0 ? _g : null, (_h = data.deliveryModel) !== null && _h !== void 0 ? _h : 'project_delivery', (_j = data.budgetAmount) !== null && _j !== void 0 ? _j : null, (_k = data.startDate) !== null && _k !== void 0 ? _k : null, (_l = data.endDate) !== null && _l !== void 0 ? _l : null);
|
|
1561
|
+
const projectId = (_m = created[0]) === null || _m === void 0 ? void 0 : _m.id;
|
|
1562
|
+
if ((_o = data.teamAssignments) === null || _o === void 0 ? void 0 : _o.length) {
|
|
1508
1563
|
await this.replaceProjectAssignments(tx, projectId, data.teamAssignments);
|
|
1509
1564
|
}
|
|
1510
1565
|
if (!data.contractId && data.autoGenerateContractDraft !== false) {
|
|
1511
1566
|
const contractId = await this.createProjectContractDraft(tx, actor.userId, {
|
|
1512
1567
|
projectId,
|
|
1513
|
-
contractTemplateId: (
|
|
1568
|
+
contractTemplateId: (_p = data.contractTemplateId) !== null && _p !== void 0 ? _p : null,
|
|
1514
1569
|
projectCode: data.code,
|
|
1515
1570
|
projectName: data.name,
|
|
1516
|
-
clientName: (
|
|
1517
|
-
managerCollaboratorId: (
|
|
1518
|
-
startDate: (
|
|
1519
|
-
endDate: (
|
|
1520
|
-
budgetAmount: (
|
|
1521
|
-
monthlyHourCap: (
|
|
1522
|
-
billingModel: (
|
|
1523
|
-
contractCode: (
|
|
1524
|
-
contractName: (
|
|
1525
|
-
description: (
|
|
1571
|
+
clientName: (_q = data.clientName) !== null && _q !== void 0 ? _q : data.name,
|
|
1572
|
+
managerCollaboratorId: (_r = data.managerCollaboratorId) !== null && _r !== void 0 ? _r : null,
|
|
1573
|
+
startDate: (_s = data.startDate) !== null && _s !== void 0 ? _s : null,
|
|
1574
|
+
endDate: (_t = data.endDate) !== null && _t !== void 0 ? _t : null,
|
|
1575
|
+
budgetAmount: (_u = data.budgetAmount) !== null && _u !== void 0 ? _u : null,
|
|
1576
|
+
monthlyHourCap: (_v = data.monthlyHourCap) !== null && _v !== void 0 ? _v : null,
|
|
1577
|
+
billingModel: (_w = data.billingModel) !== null && _w !== void 0 ? _w : 'time_and_material',
|
|
1578
|
+
contractCode: (_x = data.contractCode) !== null && _x !== void 0 ? _x : null,
|
|
1579
|
+
contractName: (_y = data.contractName) !== null && _y !== void 0 ? _y : null,
|
|
1580
|
+
description: (_0 = (_z = data.contractDescription) !== null && _z !== void 0 ? _z : data.summary) !== null && _0 !== void 0 ? _0 : null,
|
|
1526
1581
|
});
|
|
1527
1582
|
await tx.$executeRawUnsafe(`UPDATE operations_project
|
|
1528
1583
|
SET contract_id = $1,
|
|
@@ -1541,18 +1596,19 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
1541
1596
|
const params = [];
|
|
1542
1597
|
this.pushUpdate(updates, params, 'contract_id', data.contractId);
|
|
1543
1598
|
this.pushUpdate(updates, params, 'manager_collaborator_id', data.managerCollaboratorId);
|
|
1599
|
+
this.pushUpdate(updates, params, 'client_person_id', data.clientPersonId);
|
|
1544
1600
|
this.pushUpdate(updates, params, 'code', data.code);
|
|
1545
1601
|
this.pushUpdate(updates, params, 'name', data.name);
|
|
1546
1602
|
this.pushUpdate(updates, params, 'client_name', data.clientName);
|
|
1547
1603
|
this.pushUpdate(updates, params, 'summary', data.summary);
|
|
1548
1604
|
this.pushUpdate(updates, params, 'status', data.status, 'operations_project_status_965e8d4b2d_enum');
|
|
1549
1605
|
this.pushUpdate(updates, params, 'progress_percent', data.progressPercent);
|
|
1550
|
-
this.pushUpdate(updates, params, 'delivery_model', data.deliveryModel, 'operations_project_delivery_model_75ee11b3b7_enum');
|
|
1606
|
+
this.pushUpdate(updates, params, 'delivery_model', data.deliveryModel === '' ? null : data.deliveryModel, 'operations_project_delivery_model_75ee11b3b7_enum');
|
|
1551
1607
|
this.pushUpdate(updates, params, 'budget_amount', data.budgetAmount);
|
|
1552
1608
|
this.pushUpdate(updates, params, 'start_date', data.startDate, 'date');
|
|
1553
1609
|
this.pushUpdate(updates, params, 'end_date', data.endDate, 'date');
|
|
1554
1610
|
await this.prisma.$transaction(async (tx) => {
|
|
1555
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
|
|
1611
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7;
|
|
1556
1612
|
if (updates.length) {
|
|
1557
1613
|
params.push(projectId);
|
|
1558
1614
|
await tx.$executeRawUnsafe(`UPDATE operations_project
|
|
@@ -1565,30 +1621,46 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
1565
1621
|
}
|
|
1566
1622
|
const nextContractId = data.contractId !== undefined
|
|
1567
1623
|
? data.contractId
|
|
1568
|
-
: ((_a = currentProject.
|
|
1624
|
+
: ((_b = (_a = currentProject.relatedContract) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null);
|
|
1569
1625
|
const shouldGenerateDraft = !nextContractId && data.autoGenerateContractDraft === true;
|
|
1570
1626
|
if (shouldGenerateDraft) {
|
|
1571
1627
|
const contractId = await this.createProjectContractDraft(tx, actor.userId, {
|
|
1572
1628
|
projectId,
|
|
1573
|
-
contractTemplateId: (
|
|
1574
|
-
projectCode: (
|
|
1575
|
-
projectName: (
|
|
1576
|
-
clientName: (
|
|
1577
|
-
managerCollaboratorId: (
|
|
1578
|
-
startDate: (
|
|
1579
|
-
endDate: (
|
|
1580
|
-
budgetAmount: (
|
|
1581
|
-
monthlyHourCap: (
|
|
1582
|
-
billingModel: (
|
|
1583
|
-
contractCode: (
|
|
1584
|
-
contractName: (
|
|
1585
|
-
description: (
|
|
1629
|
+
contractTemplateId: (_c = data.contractTemplateId) !== null && _c !== void 0 ? _c : null,
|
|
1630
|
+
projectCode: (_d = data.code) !== null && _d !== void 0 ? _d : currentProject.code,
|
|
1631
|
+
projectName: (_e = data.name) !== null && _e !== void 0 ? _e : currentProject.name,
|
|
1632
|
+
clientName: (_g = (_f = data.clientName) !== null && _f !== void 0 ? _f : currentProject.clientName) !== null && _g !== void 0 ? _g : currentProject.name,
|
|
1633
|
+
managerCollaboratorId: (_j = (_h = data.managerCollaboratorId) !== null && _h !== void 0 ? _h : currentProject.managerCollaboratorId) !== null && _j !== void 0 ? _j : null,
|
|
1634
|
+
startDate: (_l = (_k = data.startDate) !== null && _k !== void 0 ? _k : currentProject.startDate) !== null && _l !== void 0 ? _l : null,
|
|
1635
|
+
endDate: (_o = (_m = data.endDate) !== null && _m !== void 0 ? _m : currentProject.endDate) !== null && _o !== void 0 ? _o : null,
|
|
1636
|
+
budgetAmount: (_q = (_p = data.budgetAmount) !== null && _p !== void 0 ? _p : currentProject.budgetAmount) !== null && _q !== void 0 ? _q : null,
|
|
1637
|
+
monthlyHourCap: (_t = (_r = data.monthlyHourCap) !== null && _r !== void 0 ? _r : (_s = currentProject.relatedContract) === null || _s === void 0 ? void 0 : _s.monthlyHourCap) !== null && _t !== void 0 ? _t : null,
|
|
1638
|
+
billingModel: (_w = (_u = data.billingModel) !== null && _u !== void 0 ? _u : (_v = currentProject.relatedContract) === null || _v === void 0 ? void 0 : _v.billingModel) !== null && _w !== void 0 ? _w : 'time_and_material',
|
|
1639
|
+
contractCode: (_z = (_x = data.contractCode) !== null && _x !== void 0 ? _x : (_y = currentProject.relatedContract) === null || _y === void 0 ? void 0 : _y.code) !== null && _z !== void 0 ? _z : null,
|
|
1640
|
+
contractName: (_2 = (_0 = data.contractName) !== null && _0 !== void 0 ? _0 : (_1 = currentProject.relatedContract) === null || _1 === void 0 ? void 0 : _1.name) !== null && _2 !== void 0 ? _2 : null,
|
|
1641
|
+
description: (_7 = (_6 = (_5 = (_3 = data.contractDescription) !== null && _3 !== void 0 ? _3 : (_4 = currentProject.relatedContract) === null || _4 === void 0 ? void 0 : _4.description) !== null && _5 !== void 0 ? _5 : data.summary) !== null && _6 !== void 0 ? _6 : currentProject.summary) !== null && _7 !== void 0 ? _7 : null,
|
|
1586
1642
|
});
|
|
1587
1643
|
await tx.$executeRawUnsafe(`UPDATE operations_project
|
|
1588
1644
|
SET contract_id = $1,
|
|
1589
1645
|
updated_at = NOW()
|
|
1590
1646
|
WHERE id = $2`, contractId, projectId);
|
|
1591
1647
|
}
|
|
1648
|
+
else if (nextContractId &&
|
|
1649
|
+
(data.monthlyHourCap !== undefined || data.billingModel !== undefined)) {
|
|
1650
|
+
const contractUpdates = [];
|
|
1651
|
+
const contractParams = [];
|
|
1652
|
+
this.pushUpdate(contractUpdates, contractParams, 'monthly_hour_cap', data.monthlyHourCap);
|
|
1653
|
+
this.pushUpdate(contractUpdates, contractParams, 'billing_model', data.billingModel === ''
|
|
1654
|
+
? null
|
|
1655
|
+
: data.billingModel, 'operations_contract_billing_model_409dc7fea2_enum');
|
|
1656
|
+
if (contractUpdates.length) {
|
|
1657
|
+
contractParams.push(nextContractId);
|
|
1658
|
+
await tx.$executeRawUnsafe(`UPDATE operations_contract
|
|
1659
|
+
SET ${contractUpdates.join(', ')},
|
|
1660
|
+
updated_at = NOW()
|
|
1661
|
+
WHERE id = $${contractParams.length}`, ...contractParams);
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1592
1664
|
});
|
|
1593
1665
|
return this.getProjectById(userId, projectId);
|
|
1594
1666
|
}
|
|
@@ -3930,6 +4002,8 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
3930
4002
|
const project = await this.querySingle(`SELECT p.id,
|
|
3931
4003
|
p.contract_id AS "contractId",
|
|
3932
4004
|
p.manager_collaborator_id AS "managerCollaboratorId",
|
|
4005
|
+
p.client_person_id AS "clientPersonId",
|
|
4006
|
+
client_person.avatar_id AS "clientAvatarId",
|
|
3933
4007
|
p.code,
|
|
3934
4008
|
p.name,
|
|
3935
4009
|
p.client_name AS "clientName",
|
|
@@ -3938,8 +4012,8 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
3938
4012
|
p.progress_percent AS "progressPercent",
|
|
3939
4013
|
p.delivery_model AS "deliveryModel",
|
|
3940
4014
|
p.budget_amount AS "budgetAmount",
|
|
3941
|
-
p.start_date AS "startDate",
|
|
3942
|
-
p.end_date AS "endDate",
|
|
4015
|
+
TO_CHAR(p.start_date, 'YYYY-MM-DD') AS "startDate",
|
|
4016
|
+
TO_CHAR(p.end_date, 'YYYY-MM-DD') AS "endDate",
|
|
3943
4017
|
c.name AS "contractName",
|
|
3944
4018
|
c.status AS "contractStatus",
|
|
3945
4019
|
c.contract_category AS "contractCategory",
|
|
@@ -3950,6 +4024,7 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
3950
4024
|
FROM operations_project p
|
|
3951
4025
|
LEFT JOIN operations_contract c ON c.id = p.contract_id
|
|
3952
4026
|
LEFT JOIN operations_collaborator m ON m.id = p.manager_collaborator_id
|
|
4027
|
+
LEFT JOIN person client_person ON client_person.id = p.client_person_id
|
|
3953
4028
|
LEFT JOIN operations_project_assignment pa
|
|
3954
4029
|
ON pa.project_id = p.id
|
|
3955
4030
|
AND pa.deleted_at IS NULL
|
|
@@ -3965,24 +4040,29 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
3965
4040
|
) project_role_locale ON TRUE
|
|
3966
4041
|
WHERE p.id = $1
|
|
3967
4042
|
AND p.deleted_at IS NULL
|
|
3968
|
-
GROUP BY p.id, c.id, m.id`, [projectId, actorCollaboratorId !== null && actorCollaboratorId !== void 0 ? actorCollaboratorId : null]);
|
|
4043
|
+
GROUP BY p.id, c.id, m.id, client_person.id`, [projectId, actorCollaboratorId !== null && actorCollaboratorId !== void 0 ? actorCollaboratorId : null]);
|
|
3969
4044
|
if (!project) {
|
|
3970
4045
|
throw new common_1.NotFoundException('Project not found.');
|
|
3971
4046
|
}
|
|
3972
4047
|
const [assignments, relatedContract, timesheetSummary, operationalIndicators] = await Promise.all([
|
|
3973
4048
|
this.queryRows(`SELECT pa.id,
|
|
3974
4049
|
pa.collaborator_id AS "collaboratorId",
|
|
4050
|
+
c.user_id AS "userId",
|
|
4051
|
+
person_record.avatar_id AS "personAvatarId",
|
|
4052
|
+
collaborator_user.photo_id AS "userPhotoId",
|
|
3975
4053
|
c.display_name AS "collaboratorName",
|
|
3976
4054
|
pa.project_role_id AS "projectRoleId",
|
|
3977
4055
|
COALESCE(project_role_locale.name, pa.role_label) AS "roleLabel",
|
|
3978
4056
|
pa.allocation_percent AS "allocationPercent",
|
|
3979
4057
|
pa.weekly_hours AS "weeklyHours",
|
|
3980
4058
|
pa.is_billable AS "isBillable",
|
|
3981
|
-
pa.start_date AS "startDate",
|
|
3982
|
-
pa.end_date AS "endDate",
|
|
4059
|
+
TO_CHAR(pa.start_date, 'YYYY-MM-DD') AS "startDate",
|
|
4060
|
+
TO_CHAR(pa.end_date, 'YYYY-MM-DD') AS "endDate",
|
|
3983
4061
|
pa.status
|
|
3984
4062
|
FROM operations_project_assignment pa
|
|
3985
4063
|
JOIN operations_collaborator c ON c.id = pa.collaborator_id
|
|
4064
|
+
LEFT JOIN person person_record ON person_record.id = c.person_id
|
|
4065
|
+
LEFT JOIN "user" collaborator_user ON collaborator_user.id = c.user_id
|
|
3986
4066
|
LEFT JOIN operations_project_role project_role
|
|
3987
4067
|
ON project_role.id = pa.project_role_id
|
|
3988
4068
|
AND project_role.deleted_at IS NULL
|
|
@@ -4004,8 +4084,8 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
4004
4084
|
contract_category AS "contractCategory",
|
|
4005
4085
|
billing_model AS "billingModel",
|
|
4006
4086
|
status,
|
|
4007
|
-
start_date AS "startDate",
|
|
4008
|
-
end_date AS "endDate",
|
|
4087
|
+
TO_CHAR(start_date, 'YYYY-MM-DD') AS "startDate",
|
|
4088
|
+
TO_CHAR(end_date, 'YYYY-MM-DD') AS "endDate",
|
|
4009
4089
|
budget_amount AS "budgetAmount",
|
|
4010
4090
|
monthly_hour_cap AS "monthlyHourCap",
|
|
4011
4091
|
description,
|
|
@@ -4152,7 +4232,8 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
4152
4232
|
FROM operations_contract c
|
|
4153
4233
|
WHERE c.related_collaborator_id = $1
|
|
4154
4234
|
AND c.deleted_at IS NULL
|
|
4155
|
-
ORDER BY c.
|
|
4235
|
+
ORDER BY CASE WHEN c.origin_type = 'employee_hiring' THEN 0 ELSE 1 END,
|
|
4236
|
+
c.created_at DESC`, [collaboratorId]),
|
|
4156
4237
|
this.queryRows(`SELECT weekday,
|
|
4157
4238
|
is_working_day AS "isWorkingDay",
|
|
4158
4239
|
start_time AS "startTime",
|
|
@@ -4260,34 +4341,148 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
4260
4341
|
}
|
|
4261
4342
|
return assignment[0];
|
|
4262
4343
|
}
|
|
4344
|
+
async resolveProjectAssignmentForActor(client, actor, input) {
|
|
4345
|
+
if (actor.collaboratorId && !actor.isDirector && !actor.isSupervisor) {
|
|
4346
|
+
return this.resolveOwnedProjectAssignment(client, actor.collaboratorId, input);
|
|
4347
|
+
}
|
|
4348
|
+
if (!input.projectId && !input.projectAssignmentId) {
|
|
4349
|
+
throw new common_1.BadRequestException('Either projectId or projectAssignmentId is required.');
|
|
4350
|
+
}
|
|
4351
|
+
const params = [];
|
|
4352
|
+
const filters = ['pa.deleted_at IS NULL', 'p.deleted_at IS NULL'];
|
|
4353
|
+
if (input.projectAssignmentId) {
|
|
4354
|
+
filters.push(`pa.id = ${this.param(params, input.projectAssignmentId)}`);
|
|
4355
|
+
}
|
|
4356
|
+
if (input.projectId) {
|
|
4357
|
+
filters.push(`pa.project_id = ${this.param(params, input.projectId)}`);
|
|
4358
|
+
}
|
|
4359
|
+
const assignment = (await client.$queryRawUnsafe(`SELECT pa.id,
|
|
4360
|
+
pa.project_id AS "projectId",
|
|
4361
|
+
p.name AS "projectName",
|
|
4362
|
+
p.code AS "projectCode",
|
|
4363
|
+
pa.role_label AS "roleLabel"
|
|
4364
|
+
FROM operations_project_assignment pa
|
|
4365
|
+
JOIN operations_project p
|
|
4366
|
+
ON p.id = pa.project_id
|
|
4367
|
+
WHERE ${filters.join(' AND ')}
|
|
4368
|
+
ORDER BY CASE WHEN pa.status = 'active' THEN 0 ELSE 1 END,
|
|
4369
|
+
pa.start_date DESC NULLS LAST,
|
|
4370
|
+
pa.id DESC
|
|
4371
|
+
LIMIT 1`, ...params));
|
|
4372
|
+
if (!assignment[0]) {
|
|
4373
|
+
throw new common_1.NotFoundException('Project assignment not found.');
|
|
4374
|
+
}
|
|
4375
|
+
return assignment[0];
|
|
4376
|
+
}
|
|
4263
4377
|
async getOwnedTaskRecord(client, collaboratorId, taskId) {
|
|
4264
4378
|
const task = (await client.$queryRawUnsafe(`SELECT t.id,
|
|
4265
4379
|
t.name,
|
|
4266
4380
|
t.description,
|
|
4381
|
+
t.priority,
|
|
4267
4382
|
t.status,
|
|
4383
|
+
t.due_date AS "dueDate",
|
|
4384
|
+
t.estimate_hours AS "estimateHours",
|
|
4385
|
+
t.position,
|
|
4386
|
+
t.tags,
|
|
4387
|
+
t.assignee_collaborator_id AS "assigneeCollaboratorId",
|
|
4268
4388
|
t.project_assignment_id AS "projectAssignmentId",
|
|
4269
|
-
pa.project_id AS "projectId",
|
|
4389
|
+
COALESCE(t.project_id, pa.project_id) AS "projectId",
|
|
4270
4390
|
p.name AS "projectName",
|
|
4271
4391
|
p.code AS "projectCode"
|
|
4272
4392
|
FROM operations_task t
|
|
4273
|
-
JOIN operations_project_assignment pa
|
|
4393
|
+
LEFT JOIN operations_project_assignment pa
|
|
4274
4394
|
ON pa.id = t.project_assignment_id
|
|
4275
4395
|
AND pa.deleted_at IS NULL
|
|
4276
|
-
JOIN operations_project p
|
|
4277
|
-
ON p.id = pa.project_id
|
|
4396
|
+
LEFT JOIN operations_project p
|
|
4397
|
+
ON p.id = COALESCE(t.project_id, pa.project_id)
|
|
4278
4398
|
AND p.deleted_at IS NULL
|
|
4279
4399
|
WHERE t.id = $1
|
|
4280
4400
|
AND t.deleted_at IS NULL
|
|
4281
|
-
AND
|
|
4401
|
+
AND (
|
|
4402
|
+
pa.collaborator_id = $2
|
|
4403
|
+
OR t.project_id IN (
|
|
4404
|
+
SELECT pa2.project_id FROM operations_project_assignment pa2
|
|
4405
|
+
WHERE pa2.collaborator_id = $2 AND pa2.deleted_at IS NULL
|
|
4406
|
+
)
|
|
4407
|
+
)
|
|
4282
4408
|
LIMIT 1`, taskId, collaboratorId));
|
|
4283
4409
|
if (!task[0]) {
|
|
4284
4410
|
throw new common_1.ForbiddenException('The selected task is not assigned to the authenticated collaborator.');
|
|
4285
4411
|
}
|
|
4286
4412
|
return task[0];
|
|
4287
4413
|
}
|
|
4288
|
-
async
|
|
4289
|
-
|
|
4290
|
-
|
|
4414
|
+
async getTaskRecordForActor(client, actor, taskId) {
|
|
4415
|
+
if (actor.collaboratorId && !actor.isDirector && !actor.isSupervisor) {
|
|
4416
|
+
return this.getOwnedTaskRecord(client, actor.collaboratorId, taskId);
|
|
4417
|
+
}
|
|
4418
|
+
const task = await this.getProjectBoardTask(taskId);
|
|
4419
|
+
if (!(task === null || task === void 0 ? void 0 : task.projectId)) {
|
|
4420
|
+
throw new common_1.NotFoundException('Task not found.');
|
|
4421
|
+
}
|
|
4422
|
+
return task;
|
|
4423
|
+
}
|
|
4424
|
+
async listProjectBoardTasks(userId, projectId) {
|
|
4425
|
+
const actor = await this.getActorContext(userId);
|
|
4426
|
+
this.ensureCollaborator(actor);
|
|
4427
|
+
await this.assertProjectAccess(actor, projectId);
|
|
4428
|
+
const rows = await this.queryRows(`SELECT t.id,
|
|
4429
|
+
t.name,
|
|
4430
|
+
t.description,
|
|
4431
|
+
t.priority,
|
|
4432
|
+
t.status,
|
|
4433
|
+
t.due_date AS "dueDate",
|
|
4434
|
+
t.estimate_hours AS "estimateHours",
|
|
4435
|
+
t.position,
|
|
4436
|
+
t.tags,
|
|
4437
|
+
t.assignee_collaborator_id AS "assigneeCollaboratorId",
|
|
4438
|
+
ac.display_name AS "assigneeName",
|
|
4439
|
+
au.photo_id AS "assigneeUserPhotoId",
|
|
4440
|
+
ap.avatar_id AS "assigneePersonAvatarId",
|
|
4441
|
+
t.project_assignment_id AS "projectAssignmentId",
|
|
4442
|
+
t.created_at AS "createdAt"
|
|
4443
|
+
FROM operations_task t
|
|
4444
|
+
LEFT JOIN operations_collaborator ac
|
|
4445
|
+
ON ac.id = t.assignee_collaborator_id AND ac.deleted_at IS NULL
|
|
4446
|
+
LEFT JOIN "user" au
|
|
4447
|
+
ON au.id = ac.user_id
|
|
4448
|
+
LEFT JOIN person ap
|
|
4449
|
+
ON ap.id = ac.person_id
|
|
4450
|
+
WHERE COALESCE(t.project_id, (
|
|
4451
|
+
SELECT pa.project_id FROM operations_project_assignment pa
|
|
4452
|
+
WHERE pa.id = t.project_assignment_id AND pa.deleted_at IS NULL
|
|
4453
|
+
LIMIT 1
|
|
4454
|
+
)) = $1
|
|
4455
|
+
AND t.deleted_at IS NULL
|
|
4456
|
+
ORDER BY t.status ASC, t.position ASC, t.id ASC`, [projectId]);
|
|
4457
|
+
return rows;
|
|
4458
|
+
}
|
|
4459
|
+
async getProjectBoardTask(taskId) {
|
|
4460
|
+
var _a;
|
|
4461
|
+
const rows = await this.queryRows(`SELECT t.id,
|
|
4462
|
+
t.name,
|
|
4463
|
+
t.description,
|
|
4464
|
+
t.priority,
|
|
4465
|
+
t.status,
|
|
4466
|
+
t.due_date AS "dueDate",
|
|
4467
|
+
t.estimate_hours AS "estimateHours",
|
|
4468
|
+
t.position,
|
|
4469
|
+
t.tags,
|
|
4470
|
+
t.assignee_collaborator_id AS "assigneeCollaboratorId",
|
|
4471
|
+
ac.display_name AS "assigneeName",
|
|
4472
|
+
au.photo_id AS "assigneeUserPhotoId",
|
|
4473
|
+
ap.avatar_id AS "assigneePersonAvatarId",
|
|
4474
|
+
t.project_assignment_id AS "projectAssignmentId",
|
|
4475
|
+
COALESCE(t.project_id, pa.project_id) AS "projectId",
|
|
4476
|
+
t.created_at AS "createdAt"
|
|
4477
|
+
FROM operations_task t
|
|
4478
|
+
LEFT JOIN operations_collaborator ac
|
|
4479
|
+
ON ac.id = t.assignee_collaborator_id AND ac.deleted_at IS NULL
|
|
4480
|
+
LEFT JOIN "user" au ON au.id = ac.user_id
|
|
4481
|
+
LEFT JOIN person ap ON ap.id = ac.person_id
|
|
4482
|
+
LEFT JOIN operations_project_assignment pa
|
|
4483
|
+
ON pa.id = t.project_assignment_id AND pa.deleted_at IS NULL
|
|
4484
|
+
WHERE t.id = $1`, [taskId]);
|
|
4485
|
+
return (_a = rows[0]) !== null && _a !== void 0 ? _a : null;
|
|
4291
4486
|
}
|
|
4292
4487
|
async getOrCreateTimesheetForWorkDate(client, collaboratorId, workDate) {
|
|
4293
4488
|
var _a, _b, _c;
|
|
@@ -4846,6 +5041,90 @@ let OperationsService = OperationsService_1 = class OperationsService {
|
|
|
4846
5041
|
? Math.round(Number(input.weeklyCapacityHours) * 4)
|
|
4847
5042
|
: null, (_c = input.description) !== null && _c !== void 0 ? _c : null, createdByUserId);
|
|
4848
5043
|
}
|
|
5044
|
+
async syncHiringContractDraft(client, updatedByUserId, collaboratorId, data) {
|
|
5045
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
5046
|
+
const collaborator = await client.$queryRawUnsafe(`SELECT c.id,
|
|
5047
|
+
c.code,
|
|
5048
|
+
COALESCE(NULLIF(c.display_name, ''), person_record.name) AS "displayName",
|
|
5049
|
+
collaborator_type.slug AS "collaboratorTypeSlug",
|
|
5050
|
+
c.supervisor_collaborator_id AS "supervisorCollaboratorId",
|
|
5051
|
+
c.joined_at AS "joinedAt",
|
|
5052
|
+
c.weekly_capacity_hours AS "weeklyCapacityHours"
|
|
5053
|
+
FROM operations_collaborator c
|
|
5054
|
+
LEFT JOIN person person_record
|
|
5055
|
+
ON person_record.id = c.person_id
|
|
5056
|
+
LEFT JOIN operations_collaborator_type collaborator_type
|
|
5057
|
+
ON collaborator_type.id = c.collaborator_type_id
|
|
5058
|
+
AND collaborator_type.deleted_at IS NULL
|
|
5059
|
+
WHERE c.id = $1
|
|
5060
|
+
AND c.deleted_at IS NULL
|
|
5061
|
+
LIMIT 1`, collaboratorId);
|
|
5062
|
+
const currentCollaborator = (_a = collaborator[0]) !== null && _a !== void 0 ? _a : null;
|
|
5063
|
+
if (!currentCollaborator) {
|
|
5064
|
+
throw new common_1.NotFoundException('Collaborator not found.');
|
|
5065
|
+
}
|
|
5066
|
+
const hiringContracts = (await client.$queryRawUnsafe(`SELECT id,
|
|
5067
|
+
budget_amount AS "budgetAmount",
|
|
5068
|
+
description
|
|
5069
|
+
FROM operations_contract
|
|
5070
|
+
WHERE related_collaborator_id = $1
|
|
5071
|
+
AND origin_type = 'employee_hiring'
|
|
5072
|
+
AND deleted_at IS NULL
|
|
5073
|
+
ORDER BY created_at DESC
|
|
5074
|
+
LIMIT 1`, collaboratorId));
|
|
5075
|
+
const hiringContract = (_b = hiringContracts[0]) !== null && _b !== void 0 ? _b : null;
|
|
5076
|
+
const collaboratorCode = (_c = this.normalizeOptionalText(currentCollaborator.code)) !== null && _c !== void 0 ? _c : `COL-${collaboratorId}`;
|
|
5077
|
+
const displayName = (_d = this.normalizeOptionalText(currentCollaborator.displayName)) !== null && _d !== void 0 ? _d : `Collaborator ${collaboratorId}`;
|
|
5078
|
+
const collaboratorTypeSlug = (_e = this.normalizeOptionalText(currentCollaborator.collaboratorTypeSlug)) !== null && _e !== void 0 ? _e : 'other';
|
|
5079
|
+
const startDate = data.joinedAt !== undefined
|
|
5080
|
+
? (_f = data.joinedAt) !== null && _f !== void 0 ? _f : null
|
|
5081
|
+
: (_g = currentCollaborator.joinedAt) !== null && _g !== void 0 ? _g : null;
|
|
5082
|
+
const weeklyCapacityHours = data.weeklyCapacityHours !== undefined
|
|
5083
|
+
? (_h = data.weeklyCapacityHours) !== null && _h !== void 0 ? _h : null
|
|
5084
|
+
: (_j = currentCollaborator.weeklyCapacityHours) !== null && _j !== void 0 ? _j : null;
|
|
5085
|
+
const compensationAmount = data.compensationAmount !== undefined
|
|
5086
|
+
? (_k = data.compensationAmount) !== null && _k !== void 0 ? _k : null
|
|
5087
|
+
: (_l = hiringContract === null || hiringContract === void 0 ? void 0 : hiringContract.budgetAmount) !== null && _l !== void 0 ? _l : null;
|
|
5088
|
+
const description = data.contractDescription !== undefined
|
|
5089
|
+
? this.normalizeOptionalText(data.contractDescription)
|
|
5090
|
+
: (_m = hiringContract === null || hiringContract === void 0 ? void 0 : hiringContract.description) !== null && _m !== void 0 ? _m : null;
|
|
5091
|
+
const supervisorCollaboratorId = data.supervisorCollaboratorId !== undefined
|
|
5092
|
+
? (_o = data.supervisorCollaboratorId) !== null && _o !== void 0 ? _o : null
|
|
5093
|
+
: (_p = currentCollaborator.supervisorCollaboratorId) !== null && _p !== void 0 ? _p : null;
|
|
5094
|
+
if (!hiringContract) {
|
|
5095
|
+
if (data.autoGenerateContractDraft === false) {
|
|
5096
|
+
return;
|
|
5097
|
+
}
|
|
5098
|
+
await this.createHiringContractDraft(client, updatedByUserId, {
|
|
5099
|
+
collaboratorId,
|
|
5100
|
+
collaboratorCode,
|
|
5101
|
+
displayName,
|
|
5102
|
+
collaboratorType: collaboratorTypeSlug,
|
|
5103
|
+
supervisorCollaboratorId,
|
|
5104
|
+
startDate,
|
|
5105
|
+
weeklyCapacityHours,
|
|
5106
|
+
compensationAmount,
|
|
5107
|
+
description,
|
|
5108
|
+
});
|
|
5109
|
+
return;
|
|
5110
|
+
}
|
|
5111
|
+
await client.$executeRawUnsafe(`UPDATE operations_contract
|
|
5112
|
+
SET code = $1,
|
|
5113
|
+
name = $2,
|
|
5114
|
+
contract_category = $3::operations_contract_contract_category_70d553ea09_enum,
|
|
5115
|
+
contract_type = $4::operations_contract_contract_type_48331e2ebf_enum,
|
|
5116
|
+
client_name = $5,
|
|
5117
|
+
billing_model = $6::operations_contract_billing_model_409dc7fea2_enum,
|
|
5118
|
+
account_manager_collaborator_id = $7,
|
|
5119
|
+
start_date = $8::date,
|
|
5120
|
+
effective_date = $8::date,
|
|
5121
|
+
budget_amount = $9,
|
|
5122
|
+
monthly_hour_cap = $10,
|
|
5123
|
+
description = $11,
|
|
5124
|
+
updated_by_user_id = $12,
|
|
5125
|
+
updated_at = NOW()
|
|
5126
|
+
WHERE id = $13`, `HIR-${collaboratorCode}`, this.buildHiringContractName(displayName, collaboratorTypeSlug), this.mapContractCategoryForCollaboratorType(collaboratorTypeSlug), this.mapContractTypeForCollaboratorType(collaboratorTypeSlug), displayName, this.mapBillingModelForCollaboratorType(collaboratorTypeSlug), supervisorCollaboratorId, startDate !== null && startDate !== void 0 ? startDate : new Date().toISOString().slice(0, 10), compensationAmount, weeklyCapacityHours ? Math.round(Number(weeklyCapacityHours) * 4) : null, description, updatedByUserId, hiringContract.id);
|
|
5127
|
+
}
|
|
4849
5128
|
async createProjectContractDraft(client, createdByUserId, input) {
|
|
4850
5129
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
4851
5130
|
const templateRows = input.contractTemplateId
|