refactor(modules): removed swagger entities and added docs to dtos

This commit is contained in:
Matthieu Haineault 2025-08-11 14:08:55 -04:00
parent a99f39bbf6
commit 80ddc853a4
32 changed files with 610 additions and 892 deletions

View File

@ -169,7 +169,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/EmployeeEntity" "$ref": "#/components/schemas/CreateEmployeeDto"
} }
} }
} }
@ -199,7 +199,7 @@
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/components/schemas/EmployeeEntity" "$ref": "#/components/schemas/CreateEmployeeDto"
} }
} }
} }
@ -239,7 +239,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/EmployeeEntity" "$ref": "#/components/schemas/CreateEmployeeDto"
} }
} }
} }
@ -318,7 +318,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/EmployeeEntity" "$ref": "#/components/schemas/CreateEmployeeDto"
} }
} }
} }
@ -328,7 +328,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/EmployeeEntity" "$ref": "#/components/schemas/CreateEmployeeDto"
} }
} }
} }
@ -371,7 +371,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/TimesheetEntity" "$ref": "#/components/schemas/CreateTimesheetDto"
} }
} }
} }
@ -401,7 +401,7 @@
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/components/schemas/TimesheetEntity" "$ref": "#/components/schemas/CreateTimesheetDto"
} }
} }
} }
@ -441,7 +441,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/TimesheetEntity" "$ref": "#/components/schemas/CreateTimesheetDto"
} }
} }
} }
@ -488,7 +488,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/TimesheetEntity" "$ref": "#/components/schemas/CreateTimesheetDto"
} }
} }
} }
@ -525,7 +525,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/TimesheetEntity" "$ref": "#/components/schemas/CreateTimesheetDto"
} }
} }
} }
@ -593,7 +593,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/ExpenseEntity" "$ref": "#/components/schemas/CreateExpenseDto"
} }
} }
} }
@ -623,7 +623,7 @@
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/components/schemas/ExpenseEntity" "$ref": "#/components/schemas/CreateExpenseDto"
} }
} }
} }
@ -663,7 +663,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/ExpenseEntity" "$ref": "#/components/schemas/CreateExpenseDto"
} }
} }
} }
@ -710,7 +710,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/ExpenseEntity" "$ref": "#/components/schemas/CreateExpenseDto"
} }
} }
} }
@ -747,7 +747,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/ExpenseEntity" "$ref": "#/components/schemas/CreateExpenseDto"
} }
} }
} }
@ -815,7 +815,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/ShiftEntity" "$ref": "#/components/schemas/CreateShiftDto"
} }
} }
} }
@ -845,7 +845,7 @@
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/components/schemas/ShiftEntity" "$ref": "#/components/schemas/CreateShiftDto"
} }
} }
} }
@ -885,7 +885,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/ShiftEntity" "$ref": "#/components/schemas/CreateShiftDto"
} }
} }
} }
@ -932,7 +932,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/ShiftEntity" "$ref": "#/components/schemas/CreateShiftDto"
} }
} }
} }
@ -969,7 +969,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/ShiftEntity" "$ref": "#/components/schemas/CreateShiftDto"
} }
} }
} }
@ -1079,7 +1079,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/LeaveRequestEntity" "$ref": "#/components/schemas/CreateLeaveRequestsDto"
} }
} }
} }
@ -1109,7 +1109,7 @@
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/components/schemas/LeaveRequestEntity" "$ref": "#/components/schemas/CreateLeaveRequestsDto"
} }
} }
} }
@ -1149,7 +1149,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/LeaveRequestEntity" "$ref": "#/components/schemas/CreateLeaveRequestsDto"
} }
} }
} }
@ -1196,7 +1196,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/LeaveRequestEntity" "$ref": "#/components/schemas/CreateLeaveRequestsDto"
} }
} }
} }
@ -1233,7 +1233,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/LeaveRequestEntity" "$ref": "#/components/schemas/CreateLeaveRequestsDto"
} }
} }
} }
@ -1471,7 +1471,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/CustomerEntity" "$ref": "#/components/schemas/CreateCustomerDto"
} }
} }
} }
@ -1501,7 +1501,7 @@
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/components/schemas/CustomerEntity" "$ref": "#/components/schemas/CreateCustomerDto"
} }
} }
} }
@ -1541,7 +1541,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/CustomerEntity" "$ref": "#/components/schemas/CreateCustomerDto"
} }
} }
} }
@ -1588,7 +1588,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/CustomerEntity" "$ref": "#/components/schemas/CreateCustomerDto"
} }
} }
} }
@ -1625,7 +1625,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/CustomerEntity" "$ref": "#/components/schemas/CreateCustomerDto"
} }
} }
} }
@ -1665,7 +1665,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/OAuthSessionEntity" "$ref": "#/components/schemas/CreateOauthSessionDto"
} }
} }
} }
@ -1695,7 +1695,7 @@
"schema": { "schema": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/components/schemas/OAuthSessionEntity" "$ref": "#/components/schemas/CreateOauthSessionDto"
} }
} }
} }
@ -1735,7 +1735,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/OAuthSessionEntity" "$ref": "#/components/schemas/CreateOauthSessionDto"
} }
} }
} }
@ -1782,7 +1782,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/OAuthSessionEntity" "$ref": "#/components/schemas/CreateOauthSessionDto"
} }
} }
} }
@ -1819,7 +1819,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/OAuthSessionEntity" "$ref": "#/components/schemas/CreateOauthSessionDto"
} }
} }
} }
@ -2119,10 +2119,6 @@
"contact": {} "contact": {}
}, },
"tags": [ "tags": [
{
"name": "Users",
"description": ""
},
{ {
"name": "Employees", "name": "Employees",
"description": "" "description": ""
@ -2142,18 +2138,6 @@
{ {
"name": "Leave Requests", "name": "Leave Requests",
"description": "" "description": ""
},
{
"name": "Shift Codes",
"description": ""
},
{
"name": "OAuth Access Tokens",
"description": ""
},
{
"name": "Authorization",
"description": ""
} }
], ],
"servers": [], "servers": [],
@ -2172,6 +2156,16 @@
"CreateEmployeeDto": { "CreateEmployeeDto": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of an employee(primary-key, auto-incremented)"
},
"user_id": {
"type": "string",
"example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d",
"description": "UUID of the user linked to that employee"
},
"first_name": { "first_name": {
"type": "string", "type": "string",
"example": "Frodo", "example": "Frodo",
@ -2199,12 +2193,12 @@
}, },
"external_payroll_id": { "external_payroll_id": {
"type": "number", "type": "number",
"example": "BagginsF7464", "example": 7464,
"description": "Employee`s payroll id" "description": "external ID for the pay system"
}, },
"company_code": { "company_code": {
"type": "number", "type": "number",
"example": "335567447", "example": 335567447,
"description": "Employee`s company code" "description": "Employee`s company code"
}, },
"first_work_day": { "first_work_day": {
@ -2221,6 +2215,8 @@
} }
}, },
"required": [ "required": [
"id",
"user_id",
"first_name", "first_name",
"last_name", "last_name",
"email", "email",
@ -2230,7 +2226,7 @@
"first_work_day" "first_work_day"
] ]
}, },
"EmployeeEntity": { "UpdateEmployeeDto": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "id": {
@ -2243,40 +2239,6 @@
"example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d", "example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d",
"description": "UUID of the user linked to that employee" "description": "UUID of the user linked to that employee"
}, },
"external_payroll_id": {
"type": "number",
"example": 7464,
"description": "external ID for the pay system"
},
"company_code": {
"type": "number",
"example": 335567447,
"description": "company code"
},
"first_work_day": {
"format": "date-time",
"type": "string",
"example": "3018-09-23T00:00:00.000Z",
"description": "Employee first day at work"
},
"last_work_day": {
"format": "date-time",
"type": "string",
"example": "3019-03-25T00:00:00.000Z",
"description": "Employee last day at work"
}
},
"required": [
"id",
"user_id",
"external_payroll_id",
"company_code",
"first_work_day"
]
},
"UpdateEmployeeDto": {
"type": "object",
"properties": {
"first_name": { "first_name": {
"type": "string", "type": "string",
"example": "Frodo", "example": "Frodo",
@ -2304,12 +2266,12 @@
}, },
"external_payroll_id": { "external_payroll_id": {
"type": "number", "type": "number",
"example": "BagginsF7464", "example": 7464,
"description": "Employee`s payroll id" "description": "external ID for the pay system"
}, },
"company_code": { "company_code": {
"type": "number", "type": "number",
"example": "335567447", "example": 335567447,
"description": "Employee`s company code" "description": "Employee`s company code"
}, },
"first_work_day": { "first_work_day": {
@ -2333,23 +2295,29 @@
"CreateTimesheetDto": { "CreateTimesheetDto": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": {
"type": "number",
"example": 1,
"description": "timesheet`s unique ID (auto-generated)"
},
"employee_id": { "employee_id": {
"type": "number", "type": "number",
"example": "426433", "example": 426433,
"description": "employee`s ID number of linked timsheet" "description": "employee`s ID number of linked timsheet"
}, },
"is_approved": { "is_approved": {
"type": "boolean", "type": "boolean",
"example": "True or False or Pending or Denied or Cancelled or Escalated", "example": true,
"description": "Timesheet`s approval status" "description": "Timesheet`s status approval"
} }
}, },
"required": [ "required": [
"id",
"employee_id", "employee_id",
"is_approved" "is_approved"
] ]
}, },
"TimesheetEntity": { "UpdateTimesheetDto": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "id": {
@ -2365,35 +2333,11 @@
"is_approved": { "is_approved": {
"type": "boolean", "type": "boolean",
"example": true, "example": true,
"description": "Timesheet`s approval status" "description": "Timesheet`s status approval"
}
},
"required": [
"id",
"employee_id",
"is_approved"
]
},
"UpdateTimesheetDto": {
"type": "object",
"properties": {
"employee_id": {
"type": "number",
"example": "426433",
"description": "employee`s ID number of linked timsheet"
},
"is_approved": {
"type": "boolean",
"example": "True or False or Pending or Denied or Cancelled or Escalated",
"description": "Timesheet`s approval status"
} }
} }
}, },
"CreateExpenseDto": { "CreateExpenseDto": {
"type": "object",
"properties": {}
},
"ExpenseEntity": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "id": {
@ -2417,16 +2361,21 @@
"example": "3018-10-20T00:00:00.000Z", "example": "3018-10-20T00:00:00.000Z",
"description": "Date where the expense was made" "description": "Date where the expense was made"
}, },
"is_approuved": { "amount": {
"type": "boolean", "type": "number",
"example": "DENIED, APPROUVED, PENDING, etc...", "example": 17.82,
"description": "validation status" "description": "amount in $ for a refund"
}, },
"description": { "description": {
"type": "string", "type": "string",
"example": "Spent for mileage between A and B", "example": "Spent for mileage between A and B",
"description": "explain`s why the expense was made" "description": "explain`s why the expense was made"
}, },
"is_approved": {
"type": "boolean",
"example": "DENIED, APPROUVED, PENDING, etc...",
"description": "validation status"
},
"supervisor_comment": { "supervisor_comment": {
"type": "string", "type": "string",
"example": "Asked X to go there as an emergency response", "example": "Asked X to go there as an emergency response",
@ -2438,20 +2387,59 @@
"timesheet_id", "timesheet_id",
"bank_code_id", "bank_code_id",
"date", "date",
"is_approuved", "amount",
"description", "description",
"is_approved",
"supervisor_comment" "supervisor_comment"
] ]
}, },
"UpdateExpenseDto": { "UpdateExpenseDto": {
"type": "object", "type": "object",
"properties": {} "properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of the expense (auto-generated)"
},
"timesheet_id": {
"type": "number",
"example": 101,
"description": "ID number for a set timesheet"
},
"bank_code_id": {
"type": "number",
"example": 7,
"description": "ID number of an bank code (link with bank-codes)"
},
"date": {
"format": "date-time",
"type": "string",
"example": "3018-10-20T00:00:00.000Z",
"description": "Date where the expense was made"
},
"amount": {
"type": "number",
"example": 17.82,
"description": "amount in $ for a refund"
},
"description": {
"type": "string",
"example": "Spent for mileage between A and B",
"description": "explain`s why the expense was made"
},
"is_approved": {
"type": "boolean",
"example": "DENIED, APPROUVED, PENDING, etc...",
"description": "validation status"
},
"supervisor_comment": {
"type": "string",
"example": "Asked X to go there as an emergency response",
"description": "Supervisro`s justification for the spending of an employee"
}
}
}, },
"CreateShiftDto": { "CreateShiftDto": {
"type": "object",
"properties": {}
},
"ShiftEntity": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "id": {
@ -2499,16 +2487,60 @@
}, },
"UpdateShiftsDto": { "UpdateShiftsDto": {
"type": "object", "type": "object",
"properties": {} "properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of the shift (auto-generated)"
},
"timesheet_id": {
"type": "number",
"example": 101,
"description": "ID number for a set timesheet"
},
"bank_code_id": {
"type": "number",
"example": 7,
"description": "ID number of a shift code (link with bank-codes)"
},
"date": {
"format": "date-time",
"type": "string",
"example": "3018-10-20T00:00:00.000Z",
"description": "Date where the shift takes place"
},
"start_time": {
"format": "date-time",
"type": "string",
"example": "3018-10-20T08:00:00.000Z",
"description": "Start time of the said shift"
},
"end_time": {
"format": "date-time",
"type": "string",
"example": "3018-10-20T17:00:00.000Z",
"description": "End time of the said shift"
}
}
}, },
"CreateLeaveRequestsDto": { "CreateLeaveRequestsDto": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": {
"type": "number",
"example": 1,
"description": "Leave request`s unique id(auto-incremented)"
},
"employee_id": { "employee_id": {
"type": "number", "type": "number",
"example": "4655867", "example": "4655867",
"description": "Employee`s id" "description": "Employee`s id"
}, },
"bank_code_id": {
"type": "number",
"example": 7,
"description": "ID number of a leave-request code (link with bank-codes)"
},
"leave_type": { "leave_type": {
"type": "string", "type": "string",
"example": "Sick or Vacation or Unpaid or Bereavement or Parental or Legal", "example": "Sick or Vacation or Unpaid or Bereavement or Parental or Legal",
@ -2538,7 +2570,9 @@
} }
}, },
"required": [ "required": [
"id",
"employee_id", "employee_id",
"bank_code_id",
"leave_type", "leave_type",
"start_date_time", "start_date_time",
"end_date_time", "end_date_time",
@ -2546,7 +2580,7 @@
"approval_status" "approval_status"
] ]
}, },
"LeaveRequestEntity": { "UpdateLeaveRequestsDto": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "id": {
@ -2554,72 +2588,16 @@
"example": 1, "example": 1,
"description": "Leave request`s unique id(auto-incremented)" "description": "Leave request`s unique id(auto-incremented)"
}, },
"employee_id": {
"type": "number",
"example": 42,
"description": "ID of concerned employee"
},
"leave_type": {
"type": "string",
"example": "SICK",
"enum": [
"SICK",
"VACATION",
"UNPAID",
"BEREAVEMENT",
"PARENTAL",
"LEGAL",
"WEDDING"
],
"description": "type of leave request for an accounting perception"
},
"start_date_time": {
"format": "date-time",
"type": "string",
"example": "22/06/2463",
"description": "Leave request`s start date"
},
"end_date_time": {
"format": "date-time",
"type": "string",
"example": "25/03/3019",
"description": "Leave request`s end date (optionnal)"
},
"comment": {
"type": "string",
"example": "My precious",
"description": "Leave request employee`s comment"
},
"approval_status": {
"type": "string",
"example": "PENDING",
"enum": [
"PENDING",
"APPROVED",
"DENIED",
"CANCELLED",
"ESCALATED"
],
"description": "Leave request`s approval status"
}
},
"required": [
"id",
"employee_id",
"leave_type",
"start_date_time",
"comment",
"approval_status"
]
},
"UpdateLeaveRequestsDto": {
"type": "object",
"properties": {
"employee_id": { "employee_id": {
"type": "number", "type": "number",
"example": "4655867", "example": "4655867",
"description": "Employee`s id" "description": "Employee`s id"
}, },
"bank_code_id": {
"type": "number",
"example": 7,
"description": "ID number of a leave-request code (link with bank-codes)"
},
"leave_type": { "leave_type": {
"type": "string", "type": "string",
"example": "Sick or Vacation or Unpaid or Bereavement or Parental or Legal", "example": "Sick or Vacation or Unpaid or Bereavement or Parental or Legal",
@ -2651,15 +2629,84 @@
}, },
"CreateBankCodeDto": { "CreateBankCodeDto": {
"type": "object", "type": "object",
"properties": {} "properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of a bank-code (auto-generated)"
},
"type": {
"type": "string",
"example": "regular, vacation, emergency, sick, parental, etc",
"description": "Type of codes"
},
"categorie": {
"type": "string",
"example": "shift, expense, leave",
"description": "categorie of the related code"
},
"modifier": {
"type": "number",
"example": "0, 0.72, 1, 1.5, 2",
"description": "modifier number to apply to salary"
},
"bank_code": {
"type": "string",
"example": "G1, G345, G501, G43, G700",
"description": "codes given by the bank"
}
},
"required": [
"id",
"type",
"categorie",
"modifier",
"bank_code"
]
}, },
"UpdateBankCodeDto": { "UpdateBankCodeDto": {
"type": "object", "type": "object",
"properties": {} "properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of a bank-code (auto-generated)"
},
"type": {
"type": "string",
"example": "regular, vacation, emergency, sick, parental, etc",
"description": "Type of codes"
},
"categorie": {
"type": "string",
"example": "shift, expense, leave",
"description": "categorie of the related code"
},
"modifier": {
"type": "number",
"example": "0, 0.72, 1, 1.5, 2",
"description": "modifier number to apply to salary"
},
"bank_code": {
"type": "string",
"example": "G1, G345, G501, G43, G700",
"description": "codes given by the bank"
}
}
}, },
"CreateCustomerDto": { "CreateCustomerDto": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": {
"type": "number",
"example": 1,
"description": "Unique ID of a customer(primary-key, auto-incremented)"
},
"user_id": {
"type": "string",
"example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d",
"description": "UUID of the user linked to that customer"
},
"first_name": { "first_name": {
"type": "string", "type": "string",
"example": "Gandalf", "example": "Gandalf",
@ -2692,13 +2739,15 @@
} }
}, },
"required": [ "required": [
"id",
"user_id",
"first_name", "first_name",
"last_name", "last_name",
"email", "email",
"phone_number" "phone_number"
] ]
}, },
"CustomerEntity": { "UpdateCustomerDto": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "id": {
@ -2711,36 +2760,6 @@
"example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d", "example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d",
"description": "UUID of the user linked to that customer" "description": "UUID of the user linked to that customer"
}, },
"email": {
"type": "string",
"example": "you_shall_not_pass@middleEarth.com",
"description": "customer`s email (optional)"
},
"phone_number": {
"type": "number",
"example": 8436637464,
"description": "customer`s phone number (numbers only)"
},
"residence": {
"type": "string",
"example": "1 Ringbearers way, Mount Doom city, ME, T1R 1N6",
"description": "customer`s residence address (optional)"
},
"invoice_id": {
"type": "number",
"example": 4263253,
"description": "customer`s invoice number (optionnal, unique)"
}
},
"required": [
"id",
"user_id",
"phone_number"
]
},
"UpdateCustomerDto": {
"type": "object",
"properties": {
"first_name": { "first_name": {
"type": "string", "type": "string",
"example": "Gandalf", "example": "Gandalf",
@ -2776,6 +2795,11 @@
"CreateOauthSessionDto": { "CreateOauthSessionDto": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": {
"type": "string",
"example": "cklwi0vb70000z2z20q6f19qk",
"description": "Unique ID of an OAuth token (auto-generated)"
},
"user_id": { "user_id": {
"type": "string", "type": "string",
"example": "S7A2U8R7O6N6", "example": "S7A2U8R7O6N6",
@ -2818,6 +2842,7 @@
} }
}, },
"required": [ "required": [
"id",
"user_id", "user_id",
"application", "application",
"access_token", "access_token",
@ -2825,7 +2850,7 @@
"access_token_expiry" "access_token_expiry"
] ]
}, },
"OAuthSessionEntity": { "UpdateOauthSessionDto": {
"type": "object", "type": "object",
"properties": { "properties": {
"id": { "id": {
@ -2833,82 +2858,6 @@
"example": "cklwi0vb70000z2z20q6f19qk", "example": "cklwi0vb70000z2z20q6f19qk",
"description": "Unique ID of an OAuth token (auto-generated)" "description": "Unique ID of an OAuth token (auto-generated)"
}, },
"user_id": {
"type": "string",
"example": "0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d",
"description": "UUID User`s unique identification number"
},
"application": {
"type": "string",
"example": "app.targo.ca",
"description": "URL in which the access token is used for"
},
"access_token": {
"type": "string",
"example": "L5O6R4D3/O6F3#T8H4E3&R6I4N6G4S7",
"description": "Access token"
},
"refresh_token": {
"type": "string",
"example": "Th3731102h1p07Th3R1n92",
"description": "Refresh token"
},
"access_token_expiry": {
"format": "date-time",
"type": "string",
"example": "3018-12-25T00:00:00.000Z",
"description": "Access token`s expiry date"
},
"refresh_token_expiry": {
"format": "date-time",
"type": "string",
"example": "3019-02-26T00:00:00.000Z",
"description": "Refresh token`s expiry date (optional)"
},
"scopes": {
"example": [
"email",
"profile",
"access_tolkiens"
],
"description": "scopes of infos linked to the access token",
"type": "array",
"items": {
"type": "string"
}
},
"is_revoked": {
"type": "boolean",
"example": false,
"description": "revoke status"
},
"created_at": {
"format": "date-time",
"type": "string",
"example": "2025-07-22",
"description": "creation date"
},
"updated_at": {
"format": "date-time",
"type": "string",
"example": "2025-07-23",
"description": "Latest update (optional)"
}
},
"required": [
"id",
"user_id",
"application",
"access_token",
"refresh_token",
"access_token_expiry",
"is_revoked",
"created_at"
]
},
"UpdateOauthSessionDto": {
"type": "object",
"properties": {
"user_id": { "user_id": {
"type": "string", "type": "string",
"example": "S7A2U8R7O6N6", "example": "S7A2U8R7O6N6",

View File

@ -1,19 +1,41 @@
import { ApiProperty } from "@nestjs/swagger";
import { IsNotEmpty, IsNumber, IsString } from "class-validator"; import { IsNotEmpty, IsNumber, IsString } from "class-validator";
export class CreateBankCodeDto { export class CreateBankCodeDto {
@ApiProperty({
example: 1,
description: 'Unique ID of a bank-code (auto-generated)',
})
id: number;
@ApiProperty({
example: 'regular, vacation, emergency, sick, parental, etc',
description: 'Type of codes',
})
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
type: string; type: string;
@ApiProperty({
example: 'shift, expense, leave',
description: 'categorie of the related code',
})
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
categorie: string; categorie: string;
@ApiProperty({
example: '0, 0.72, 1, 1.5, 2',
description: 'modifier number to apply to salary',
})
@IsNumber() @IsNumber()
@IsNotEmpty() @IsNotEmpty()
modifier: number; modifier: number;
@ApiProperty({
example: 'G1, G345, G501, G43, G700',
description: 'codes given by the bank',
})
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
bank_code: string; bank_code: string;

View File

@ -1,34 +0,0 @@
import { ApiProperty } from "@nestjs/swagger";
export class BankCodesEntity {
@ApiProperty({
example: 1,
description: 'Unique ID of a bank-code (auto-generated)',
})
id: number;
@ApiProperty({
example: 'regular, vacation, emergency, sick, parental, etc',
description: 'Type of codes',
})
type: string;
@ApiProperty({
example: 'shift, expense, leave',
description: 'categorie of the related code',
})
categorie: string;
@ApiProperty({
example: '0, 0.72, 1, 1.5, 2',
description: 'modifier number to apply to salary',
})
modifier: number;
@ApiProperty({
example: 'G1, G345, G501, G43, G700',
description: 'codes given by the bank',
})
bank_code: string;
}

View File

@ -6,7 +6,6 @@ import { UpdateCustomerDto } from '../dtos/update-customer.dto';
import { RolesAllowed } from "src/common/decorators/roles.decorators"; import { RolesAllowed } from "src/common/decorators/roles.decorators";
import { Roles as RoleEnum } from '.prisma/client'; import { Roles as RoleEnum } from '.prisma/client';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { CustomerEntity } from '../dtos/swagger-entities/customers.entity';
@ApiTags('Customers') @ApiTags('Customers')
@ApiBearerAuth('access-token') @ApiBearerAuth('access-token')
@ -18,7 +17,7 @@ export class CustomersController {
@Post() @Post()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Create customer' }) @ApiOperation({ summary: 'Create customer' })
@ApiResponse({ status: 201, description: 'Customer created', type: CustomerEntity }) @ApiResponse({ status: 201, description: 'Customer created', type: CreateCustomerDto })
@ApiResponse({ status: 400, description: 'Invalid task or invalid data' }) @ApiResponse({ status: 400, description: 'Invalid task or invalid data' })
create(@Body() dto: CreateCustomerDto): Promise<Customers> { create(@Body() dto: CreateCustomerDto): Promise<Customers> {
return this.customersService.create(dto); return this.customersService.create(dto);
@ -27,7 +26,7 @@ export class CustomersController {
@Get() @Get()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find all customers' }) @ApiOperation({ summary: 'Find all customers' })
@ApiResponse({ status: 201, description: 'List of customers found', type: CustomerEntity, isArray: true }) @ApiResponse({ status: 201, description: 'List of customers found', type: CreateCustomerDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of customers not found' }) @ApiResponse({ status: 400, description: 'List of customers not found' })
findAll(): Promise<Customers[]> { findAll(): Promise<Customers[]> {
return this.customersService.findAll(); return this.customersService.findAll();
@ -36,7 +35,7 @@ export class CustomersController {
@Get(':id') @Get(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find customer' }) @ApiOperation({ summary: 'Find customer' })
@ApiResponse({ status: 201, description: 'Customer found', type: CustomerEntity }) @ApiResponse({ status: 201, description: 'Customer found', type: CreateCustomerDto })
@ApiResponse({ status: 400, description: 'Customer not found' }) @ApiResponse({ status: 400, description: 'Customer not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise<Customers> { findOne(@Param('id', ParseIntPipe) id: number): Promise<Customers> {
return this.customersService.findOne(id); return this.customersService.findOne(id);
@ -45,7 +44,7 @@ export class CustomersController {
@Patch(':id') @Patch(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE,RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE,RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Update customer' }) @ApiOperation({ summary: 'Update customer' })
@ApiResponse({ status: 201, description: 'Customer updated', type: CustomerEntity }) @ApiResponse({ status: 201, description: 'Customer updated', type: CreateCustomerDto })
@ApiResponse({ status: 400, description: 'Customer not found' }) @ApiResponse({ status: 400, description: 'Customer not found' })
update( update(
@Param('id', ParseIntPipe) id: number, @Param('id', ParseIntPipe) id: number,
@ -57,7 +56,7 @@ export class CustomersController {
@Delete(':id') @Delete(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Delete customer' }) @ApiOperation({ summary: 'Delete customer' })
@ApiResponse({ status: 201, description: 'Customer deleted', type: CustomerEntity }) @ApiResponse({ status: 201, description: 'Customer deleted', type: CreateCustomerDto })
@ApiResponse({ status: 400, description: 'Customer not found' }) @ApiResponse({ status: 400, description: 'Customer not found' })
remove(@Param('id', ParseIntPipe) id: number): Promise<Customers>{ remove(@Param('id', ParseIntPipe) id: number): Promise<Customers>{
return this.customersService.remove(id); return this.customersService.remove(id);

View File

@ -10,6 +10,17 @@ import {
} from "class-validator"; } from "class-validator";
export class CreateCustomerDto { export class CreateCustomerDto {
@ApiProperty({
example: 1,
description: 'Unique ID of a customer(primary-key, auto-incremented)',
})
id: number;
@ApiProperty({
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
description: 'UUID of the user linked to that customer',
})
user_id: string;
@ApiProperty({ @ApiProperty({
example: 'Gandalf', example: 'Gandalf',

View File

@ -1,42 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class CustomerEntity {
@ApiProperty({
example: 1,
description: 'Unique ID of a customer(primary-key, auto-incremented)',
})
id: number;
@ApiProperty({
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
description: 'UUID of the user linked to that customer',
})
user_id: string;
@ApiProperty({
example: 'you_shall_not_pass@middleEarth.com',
description: 'customer`s email (optional)',
required: false,
})
email?: string;
@ApiProperty({
example: 8436637464,
description: 'customer`s phone number (numbers only)',
})
phone_number: number;
@ApiProperty({
example: '1 Ringbearers way, Mount Doom city, ME, T1R 1N6',
description: 'customer`s residence address (optional)',
required: false,
})
residence?: string;
@ApiProperty({
example: 4263253,
description: 'customer`s invoice number (optionnal, unique)',
required: false,
})
invoice_id?: number;
}

View File

@ -5,7 +5,6 @@ import { CreateEmployeeDto } from '../dtos/create-employee.dto';
import { UpdateEmployeeDto } from '../dtos/update-employee.dto'; import { UpdateEmployeeDto } from '../dtos/update-employee.dto';
import { RolesAllowed } from '../../../common/decorators/roles.decorators'; import { RolesAllowed } from '../../../common/decorators/roles.decorators';
import { ApiBearerAuth, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger'; import { ApiBearerAuth, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
import { EmployeeEntity } from '../dtos/swagger-entities/employees.entity';
@ApiTags('Employees') @ApiTags('Employees')
@ApiBearerAuth('access-token') @ApiBearerAuth('access-token')
@ -17,7 +16,7 @@ export class EmployeesController {
@Post() @Post()
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Create employee' }) @ApiOperation({summary: 'Create employee' })
@ApiResponse({ status: 201, description: 'Employee created', type: EmployeeEntity }) @ApiResponse({ status: 201, description: 'Employee created', type: CreateEmployeeDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' }) @ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body() dto: CreateEmployeeDto): Promise<Employees> { create(@Body() dto: CreateEmployeeDto): Promise<Employees> {
return this.employeesService.create(dto); return this.employeesService.create(dto);
@ -26,7 +25,7 @@ export class EmployeesController {
@Get() @Get()
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ACCOUNTING) @RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ACCOUNTING)
@ApiOperation({summary: 'Find all employees' }) @ApiOperation({summary: 'Find all employees' })
@ApiResponse({ status: 200, description: 'List of employees found', type: EmployeeEntity, isArray: true }) @ApiResponse({ status: 200, description: 'List of employees found', type: CreateEmployeeDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of employees not found' }) @ApiResponse({ status: 400, description: 'List of employees not found' })
findAll(): Promise<Employees[]> { findAll(): Promise<Employees[]> {
return this.employeesService.findAll(); return this.employeesService.findAll();
@ -35,7 +34,7 @@ export class EmployeesController {
@Get(':id') @Get(':id')
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR,RoleEnum.ACCOUNTING ) @RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR,RoleEnum.ACCOUNTING )
@ApiOperation({summary: 'Find employee' }) @ApiOperation({summary: 'Find employee' })
@ApiResponse({ status: 200, description: 'Employee found', type: EmployeeEntity }) @ApiResponse({ status: 200, description: 'Employee found', type: CreateEmployeeDto })
@ApiResponse({ status: 400, description: 'Employee not found' }) @ApiResponse({ status: 400, description: 'Employee not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise<Employees> { findOne(@Param('id', ParseIntPipe) id: number): Promise<Employees> {
return this.employeesService.findOne(id); return this.employeesService.findOne(id);
@ -56,8 +55,8 @@ export class EmployeesController {
@ApiBearerAuth('access-token') @ApiBearerAuth('access-token')
@ApiOperation({ summary: 'Update, archive or restore an employee' }) @ApiOperation({ summary: 'Update, archive or restore an employee' })
@ApiParam({ name: 'id', type: Number, description: 'Identifier of the employee' }) @ApiParam({ name: 'id', type: Number, description: 'Identifier of the employee' })
@ApiResponse({ status: 200, description: 'Employee updated or restored', type: EmployeeEntity }) @ApiResponse({ status: 200, description: 'Employee updated or restored', type: CreateEmployeeDto })
@ApiResponse({ status: 202, description: 'Employee archived successfully', type: EmployeeEntity }) @ApiResponse({ status: 202, description: 'Employee archived successfully', type: CreateEmployeeDto })
@ApiResponse({ status: 404, description: 'Employee not found in active or archive' }) @ApiResponse({ status: 404, description: 'Employee not found in active or archive' })
@Patch(':id') @Patch(':id')
async updateOrArchiveOrRestore(@Param('id') id: string, @Body() dto: UpdateEmployeeDto,) { async updateOrArchiveOrRestore(@Param('id') id: string, @Body() dto: UpdateEmployeeDto,) {

View File

@ -12,84 +12,95 @@ import { Type } from 'class-transformer';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
export class CreateEmployeeDto { export class CreateEmployeeDto {
@ApiProperty({
example: 1,
description: 'Unique ID of an employee(primary-key, auto-incremented)',
})
id: number;
@ApiProperty({ @ApiProperty({
example: 'Frodo', example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
description: 'Employee`s first name', description: 'UUID of the user linked to that employee',
}) })
@IsString() user_id: string;
@IsNotEmpty()
first_name: string;
@ApiProperty({ @ApiProperty({
example: 'Baggins', example: 'Frodo',
description: 'Employee`s last name', description: 'Employee`s first name',
}) })
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
last_name: string; first_name: string;
@ApiProperty({ @ApiProperty({
example: 'i_cant_do_this_sam@targointernet.com', example: 'Baggins',
description: 'Employee`s email', description: 'Employee`s last name',
}) })
@IsEmail() @IsString()
@IsOptional() @IsNotEmpty()
email: string; last_name: string;
@ApiProperty({ @ApiProperty({
example: '82538437464', example: 'i_cant_do_this_sam@targointernet.com',
description: 'Employee`s phone number', description: 'Employee`s email',
}) })
@Type(() => Number) @IsEmail()
@IsInt() @IsOptional()
@IsPositive() email: string;
phone_number: number;
@ApiProperty({ @ApiProperty({
example: '1 Bagshot Row, Hobbiton, The Shire, Middle-earth', example: '82538437464',
description: 'Employee`s residence', description: 'Employee`s phone number',
required: false, })
}) @Type(() => Number)
@IsString() @IsInt()
@IsOptional() @IsPositive()
residence?: string; phone_number: number;
@ApiProperty({ @ApiProperty({
example: 'BagginsF7464', example: '1 Bagshot Row, Hobbiton, The Shire, Middle-earth',
description: 'Employee`s payroll id', description: 'Employee`s residence',
}) required: false,
@IsInt() })
@IsPositive() @IsString()
@Type(() => Number) @IsOptional()
external_payroll_id: number; residence?: string;
@ApiProperty({ @ApiProperty({
example: '335567447', example: 7464,
description: 'Employee`s company code', description: 'external ID for the pay system',
}) })
@IsInt() @IsInt()
@IsPositive() @IsPositive()
@Type(() => Number) @Type(() => Number)
company_code: number; external_payroll_id: number;
@ApiProperty({ @ApiProperty({
example: '23/09/3018', example: 335567447,
description: 'Employee`s first working day', description: 'Employee`s company code',
}) })
@IsDateString() @IsInt()
@Type(() => Date) @IsPositive()
@IsDate() @Type(() => Number)
first_work_day: Date; company_code: number;
@ApiProperty({ @ApiProperty({
example: '25/03/3019', example: '23/09/3018',
description: 'Employee`s last working day', description: 'Employee`s first working day',
required: false, })
}) @IsDateString()
@IsDateString() @Type(() => Date)
@Type(() => Date) @IsDate()
@IsDate() first_work_day: Date;
@IsOptional()
last_work_day?: Date; @ApiProperty({
example: '25/03/3019',
description: 'Employee`s last working day',
required: false,
})
@IsDateString()
@Type(() => Date)
@IsDate()
@IsOptional()
last_work_day?: Date;
} }

View File

@ -1,40 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class EmployeeEntity {
@ApiProperty({
example: 1,
description: 'Unique ID of an employee(primary-key, auto-incremented)',
})
id: number;
@ApiProperty({
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
description: 'UUID of the user linked to that employee',
})
user_id: string;
@ApiProperty({
example: 7464,
description: 'external ID for the pay system',
})
external_payroll_id: number;
@ApiProperty({
example: 335567447,
description: 'company code',
})
company_code: number;
@ApiProperty({
example: '3018-09-23T00:00:00.000Z',
description: 'Employee first day at work',
})
first_work_day: Date;
@ApiProperty({
example: '3019-03-25T00:00:00.000Z',
description: 'Employee last day at work',
required: false,
})
last_work_day?: Date;
}

View File

@ -6,7 +6,6 @@ import { Roles as RoleEnum } from '.prisma/client';
import { UpdateExpenseDto } from "../dtos/update-expense.dto"; import { UpdateExpenseDto } from "../dtos/update-expense.dto";
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger"; import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
import { RolesAllowed } from "src/common/decorators/roles.decorators"; import { RolesAllowed } from "src/common/decorators/roles.decorators";
import { ExpenseEntity } from "../dtos/swagger-entities/expenses.entity";
import { ExpensesApprovalService } from "../services/expenses-approval.service"; import { ExpensesApprovalService } from "../services/expenses-approval.service";
import { SearchExpensesDto } from "../dtos/search-expense.dto"; import { SearchExpensesDto } from "../dtos/search-expense.dto";
@ -23,7 +22,7 @@ export class ExpensesController {
@Post() @Post()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Create expense' }) @ApiOperation({ summary: 'Create expense' })
@ApiResponse({ status: 201, description: 'Expense created',type: ExpenseEntity }) @ApiResponse({ status: 201, description: 'Expense created',type: CreateExpenseDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' }) @ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body() dto: CreateExpenseDto): Promise<Expenses> { create(@Body() dto: CreateExpenseDto): Promise<Expenses> {
return this.expensesService.create(dto); return this.expensesService.create(dto);
@ -32,7 +31,7 @@ export class ExpensesController {
@Get() @Get()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find all expenses' }) @ApiOperation({ summary: 'Find all expenses' })
@ApiResponse({ status: 201, description: 'List of expenses found',type: ExpenseEntity, isArray: true }) @ApiResponse({ status: 201, description: 'List of expenses found',type: CreateExpenseDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of expenses not found' }) @ApiResponse({ status: 400, description: 'List of expenses not found' })
@UsePipes(new ValidationPipe({ transform: true, whitelist: true })) @UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
findAll(@Query() filters: SearchExpensesDto): Promise<Expenses[]> { findAll(@Query() filters: SearchExpensesDto): Promise<Expenses[]> {
@ -42,7 +41,7 @@ export class ExpensesController {
@Get(':id') @Get(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find expense' }) @ApiOperation({ summary: 'Find expense' })
@ApiResponse({ status: 201, description: 'Expense found',type: ExpenseEntity }) @ApiResponse({ status: 201, description: 'Expense found',type: CreateExpenseDto })
@ApiResponse({ status: 400, description: 'Expense not found' }) @ApiResponse({ status: 400, description: 'Expense not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise <Expenses> { findOne(@Param('id', ParseIntPipe) id: number): Promise <Expenses> {
return this.expensesService.findOne(id); return this.expensesService.findOne(id);
@ -51,7 +50,7 @@ export class ExpensesController {
@Patch(':id') @Patch(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Expense shift' }) @ApiOperation({ summary: 'Expense shift' })
@ApiResponse({ status: 201, description: 'Expense updated',type: ExpenseEntity }) @ApiResponse({ status: 201, description: 'Expense updated',type: CreateExpenseDto })
@ApiResponse({ status: 400, description: 'Expense not found' }) @ApiResponse({ status: 400, description: 'Expense not found' })
update(@Param('id', ParseIntPipe) id: number, @Body() dto: UpdateExpenseDto) { update(@Param('id', ParseIntPipe) id: number, @Body() dto: UpdateExpenseDto) {
return this.expensesService.update(id,dto); return this.expensesService.update(id,dto);
@ -60,7 +59,7 @@ export class ExpensesController {
@Delete(':id') @Delete(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Delete expense' }) @ApiOperation({ summary: 'Delete expense' })
@ApiResponse({ status: 201, description: 'Expense deleted',type: ExpenseEntity }) @ApiResponse({ status: 201, description: 'Expense deleted',type: CreateExpenseDto })
@ApiResponse({ status: 400, description: 'Expense not found' }) @ApiResponse({ status: 400, description: 'Expense not found' })
remove(@Param('id', ParseIntPipe) id: number): Promise<Expenses> { remove(@Param('id', ParseIntPipe) id: number): Promise<Expenses> {
return this.expensesService.remove(id); return this.expensesService.remove(id);

View File

@ -1,32 +1,67 @@
import { ApiProperty } from "@nestjs/swagger";
import { Type } from "class-transformer"; import { Type } from "class-transformer";
import { IsBoolean, IsDate, IsDateString, IsInt, IsOptional, IsString } from "class-validator"; import { IsBoolean, IsDate, IsDateString, IsInt, IsOptional, IsString } from "class-validator";
export class CreateExpenseDto { export class CreateExpenseDto {
@ApiProperty({
example: 1,
description: 'Unique ID of the expense (auto-generated)',
})
id: number;
@ApiProperty({
example: 101,
description: 'ID number for a set timesheet',
})
@Type(()=> Number) @Type(()=> Number)
@IsInt() @IsInt()
timesheet_id: number; timesheet_id: number;
@ApiProperty({
example: 7,
description: 'ID number of an bank code (link with bank-codes)',
})
@Type(() => Number) @Type(() => Number)
@IsInt() @IsInt()
bank_code_id: number; bank_code_id: number;
@ApiProperty({
example: '3018-10-20T00:00:00.000Z',
description: 'Date where the expense was made',
})
@IsDateString() @IsDateString()
@Type(() => Date) @Type(() => Date)
@IsDate() @IsDate()
date: Date; date: Date;
@ApiProperty({
example: 17.82,
description: 'amount in $ for a refund',
})
@Type(() => Number) @Type(() => Number)
@IsInt() @IsInt()
amount: number amount: number
@ApiProperty({
example:'Spent for mileage between A and B',
description:'explain`s why the expense was made'
})
@IsString() @IsString()
description?: string; description?: string;
@ApiProperty({
example: 'DENIED, APPROUVED, PENDING, etc...',
description: 'validation status',
})
@IsOptional() @IsOptional()
@IsBoolean() @IsBoolean()
is_approved?: boolean; is_approved?: boolean;
@ApiProperty({
example:'Asked X to go there as an emergency response',
description:'Supervisro`s justification for the spending of an employee'
})
@IsString() @IsString()
supervisor_comment?: string; supervisor_comment?: string;
} }

View File

@ -1,46 +0,0 @@
import { ApiProperty } from "@nestjs/swagger";
export class ExpenseEntity {
@ApiProperty({
example: 1,
description: 'Unique ID of the expense (auto-generated)',
})
id: number;
@ApiProperty({
example: 101,
description: 'ID number for a set timesheet',
})
timesheet_id: number;
@ApiProperty({
example: 7,
description: 'ID number of an bank code (link with bank-codes)',
})
bank_code_id: number;
@ApiProperty({
example: '3018-10-20T00:00:00.000Z',
description: 'Date where the expense was made',
})
date: Date;
@ApiProperty({
example: 'DENIED, APPROUVED, PENDING, etc...',
description: 'validation status',
})
is_approuved: boolean;
@ApiProperty({
example:'Spent for mileage between A and B',
description:'explain`s why the expense was made'
})
description: string;
@ApiProperty({
example:'Asked X to go there as an emergency response',
description:'Supervisro`s justification for the spending of an employee'
})
supervisor_comment: string;
}

View File

@ -6,7 +6,6 @@ import { UpdateLeaveRequestsDto } from "../dtos/update-leave-requests.dto";
import { RolesAllowed } from "src/common/decorators/roles.decorators"; import { RolesAllowed } from "src/common/decorators/roles.decorators";
import { LeaveApprovalStatus, Roles as RoleEnum } from '.prisma/client'; import { LeaveApprovalStatus, Roles as RoleEnum } from '.prisma/client';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger"; import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
import { LeaveRequestEntity } from "../dtos/swagger-entities/leave-requests.entity";
import { SearchLeaveRequestsDto } from "../dtos/search-leave-requests.dto"; import { SearchLeaveRequestsDto } from "../dtos/search-leave-requests.dto";
@ApiTags('Leave Requests') @ApiTags('Leave Requests')
@ -19,7 +18,7 @@ export class LeaveRequestController {
@Post() @Post()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Create leave request' }) @ApiOperation({summary: 'Create leave request' })
@ApiResponse({ status: 201, description: 'Leave request created',type: LeaveRequestEntity }) @ApiResponse({ status: 201, description: 'Leave request created',type: CreateLeaveRequestsDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' }) @ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body() dto: CreateLeaveRequestsDto): Promise<LeaveRequests> { create(@Body() dto: CreateLeaveRequestsDto): Promise<LeaveRequests> {
return this. leaveRequetsService.create(dto); return this. leaveRequetsService.create(dto);
@ -28,7 +27,7 @@ export class LeaveRequestController {
@Get() @Get()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Find all leave request' }) @ApiOperation({summary: 'Find all leave request' })
@ApiResponse({ status: 201, description: 'List of Leave requests found',type: LeaveRequestEntity, isArray: true }) @ApiResponse({ status: 201, description: 'List of Leave requests found',type: CreateLeaveRequestsDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of leave request not found' }) @ApiResponse({ status: 400, description: 'List of leave request not found' })
@UsePipes(new ValidationPipe({transform: true, whitelist: true})) @UsePipes(new ValidationPipe({transform: true, whitelist: true}))
findAll(@Query() filters: SearchLeaveRequestsDto): Promise<(LeaveRequests & {daysRequested:number; cost: number})[]> { findAll(@Query() filters: SearchLeaveRequestsDto): Promise<(LeaveRequests & {daysRequested:number; cost: number})[]> {
@ -38,7 +37,7 @@ export class LeaveRequestController {
@Get(':id') @Get(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Find leave request' }) @ApiOperation({summary: 'Find leave request' })
@ApiResponse({ status: 201, description: 'Leave request found',type: LeaveRequestEntity }) @ApiResponse({ status: 201, description: 'Leave request found',type: CreateLeaveRequestsDto })
@ApiResponse({ status: 400, description: 'Leave request not found' }) @ApiResponse({ status: 400, description: 'Leave request not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise<LeaveRequests> { findOne(@Param('id', ParseIntPipe) id: number): Promise<LeaveRequests> {
return this.leaveRequetsService.findOne(id); return this.leaveRequetsService.findOne(id);
@ -47,7 +46,7 @@ export class LeaveRequestController {
@Patch(':id') @Patch(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Update leave request' }) @ApiOperation({summary: 'Update leave request' })
@ApiResponse({ status: 201, description: 'Leave request updated',type: LeaveRequestEntity }) @ApiResponse({ status: 201, description: 'Leave request updated',type: CreateLeaveRequestsDto })
@ApiResponse({ status: 400, description: 'Leave request not found' }) @ApiResponse({ status: 400, description: 'Leave request not found' })
update(@Param('id', ParseIntPipe) id: number,@Body() dto: UpdateLeaveRequestsDto): Promise<LeaveRequests> { update(@Param('id', ParseIntPipe) id: number,@Body() dto: UpdateLeaveRequestsDto): Promise<LeaveRequests> {
return this.leaveRequetsService.update(id, dto); return this.leaveRequetsService.update(id, dto);
@ -56,7 +55,7 @@ export class LeaveRequestController {
@Delete(':id') @Delete(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({summary: 'Delete leave request' }) @ApiOperation({summary: 'Delete leave request' })
@ApiResponse({ status: 201, description: 'Leave request deleted',type: LeaveRequestEntity }) @ApiResponse({ status: 201, description: 'Leave request deleted',type: CreateLeaveRequestsDto })
@ApiResponse({ status: 400, description: 'Leave request not found' }) @ApiResponse({ status: 400, description: 'Leave request not found' })
remove(@Param('id', ParseIntPipe) id: number): Promise<LeaveRequests> { remove(@Param('id', ParseIntPipe) id: number): Promise<LeaveRequests> {
return this.leaveRequetsService.remove(id); return this.leaveRequetsService.remove(id);

View File

@ -4,54 +4,63 @@ import { Type } from "class-transformer";
import { IsEnum, IsInt, IsNotEmpty, IsOptional, IsString } from "class-validator"; import { IsEnum, IsInt, IsNotEmpty, IsOptional, IsString } from "class-validator";
export class CreateLeaveRequestsDto { export class CreateLeaveRequestsDto {
@ApiProperty({ @ApiProperty({
example: '4655867', example: 1,
description: 'Employee`s id', description: 'Leave request`s unique id(auto-incremented)',
}) })
@Type(()=> Number) id: number;
@IsInt() @ApiProperty({
employee_id: number; example: '4655867',
description: 'Employee`s id',
})
@Type(()=> Number)
@IsInt()
employee_id: number;
@Type(()=> Number) @ApiProperty({
@IsInt() example: 7,
bank_code_id: number; description: 'ID number of a leave-request code (link with bank-codes)',
})
@Type(()=> Number)
@IsInt()
bank_code_id: number;
@ApiProperty({ @ApiProperty({
example: 'Sick or Vacation or Unpaid or Bereavement or Parental or Legal', example: 'Sick or Vacation or Unpaid or Bereavement or Parental or Legal',
description: 'type of leave request for an accounting perception', description: 'type of leave request for an accounting perception',
}) })
@IsEnum(LeaveTypes) @IsEnum(LeaveTypes)
leave_type: LeaveTypes; leave_type: LeaveTypes;
@ApiProperty({ @ApiProperty({
example: '22/06/2463', example: '22/06/2463',
description: 'Leave request`s start date', description: 'Leave request`s start date',
}) })
@Type(()=>Date) @Type(()=>Date)
@IsNotEmpty() @IsNotEmpty()
start_date_time:Date; start_date_time:Date;
@ApiProperty({ @ApiProperty({
example: '25/03/3019', example: '25/03/3019',
description: 'Leave request`s end date', description: 'Leave request`s end date',
}) })
@Type(()=>Date) @Type(()=>Date)
@IsOptional() @IsOptional()
end_date_time?: Date; end_date_time?: Date;
@ApiProperty({ @ApiProperty({
example: 'My precious', example: 'My precious',
description: 'Leave request`s comment', description: 'Leave request`s comment',
}) })
@IsString() @IsString()
@IsNotEmpty() @IsNotEmpty()
comment: string; comment: string;
@ApiProperty({ @ApiProperty({
example: 'True or False or Pending or Denied or Cancelled or Escalated', example: 'True or False or Pending or Denied or Cancelled or Escalated',
description: 'Leave request`s approval status', description: 'Leave request`s approval status',
}) })
@IsEnum(LeaveApprovalStatus) @IsEnum(LeaveApprovalStatus)
@IsOptional() @IsOptional()
approval_status?: LeaveApprovalStatus; approval_status?: LeaveApprovalStatus;
} }

View File

@ -1,49 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
import { LeaveApprovalStatus, LeaveTypes } from '@prisma/client';
export class LeaveRequestEntity {
@ApiProperty({
example: 1,
description: 'Leave request`s unique id(auto-incremented)',
})
id: number;
@ApiProperty({
example: 42,
description: 'ID of concerned employee',
})
employee_id: number;
@ApiProperty({
example: 'SICK',
enum: LeaveTypes,
description: 'type of leave request for an accounting perception',
})
leave_type: LeaveTypes;
@ApiProperty({
example: '22/06/2463',
description: 'Leave request`s start date',
})
start_date_time: Date;
@ApiProperty({
example: '25/03/3019',
description: 'Leave request`s end date (optionnal)',
required: false,
})
end_date_time?: Date;
@ApiProperty({
example: 'My precious',
description: 'Leave request employee`s comment',
})
comment: string;
@ApiProperty({
example: 'PENDING',
enum: LeaveApprovalStatus,
description: 'Leave request`s approval status',
})
approval_status: LeaveApprovalStatus;
}

View File

@ -5,7 +5,6 @@ import { Roles as RoleEnum } from '.prisma/client';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { CreateOauthSessionDto } from '../dtos/create-oauth-sessions.dto'; import { CreateOauthSessionDto } from '../dtos/create-oauth-sessions.dto';
import { OauthSessionsService } from '../services/oauth-sessions.service'; import { OauthSessionsService } from '../services/oauth-sessions.service';
import { OAuthSessionEntity } from '../dtos/swagger-entities/oauth-sessions.entity';
import { UpdateOauthSessionDto } from '../dtos/update-oauth-sessions.dto'; import { UpdateOauthSessionDto } from '../dtos/update-oauth-sessions.dto';
@ApiTags('OAuth Sessions') @ApiTags('OAuth Sessions')
@ -18,7 +17,7 @@ export class OauthSessionsController {
@Post() @Post()
@RolesAllowed(RoleEnum.ADMIN) @RolesAllowed(RoleEnum.ADMIN)
@ApiOperation({summary: 'Create OAuth session' }) @ApiOperation({summary: 'Create OAuth session' })
@ApiResponse({ status: 201, description: 'OAuth session created', type: OAuthSessionEntity }) @ApiResponse({ status: 201, description: 'OAuth session created', type: CreateOauthSessionDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' }) @ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body()dto: CreateOauthSessionDto): Promise<OAuthSessions> { create(@Body()dto: CreateOauthSessionDto): Promise<OAuthSessions> {
return this.oauthSessionsService.create(dto); return this.oauthSessionsService.create(dto);
@ -27,7 +26,7 @@ export class OauthSessionsController {
@Get() @Get()
@RolesAllowed(RoleEnum.ADMIN) @RolesAllowed(RoleEnum.ADMIN)
@ApiOperation({summary: 'Find all OAuth session' }) @ApiOperation({summary: 'Find all OAuth session' })
@ApiResponse({ status: 201, description: 'List of OAuth session found', type: OAuthSessionEntity, isArray: true }) @ApiResponse({ status: 201, description: 'List of OAuth session found', type: CreateOauthSessionDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of OAuth session not found' }) @ApiResponse({ status: 400, description: 'List of OAuth session not found' })
findAll(): Promise<OAuthSessions[]> { findAll(): Promise<OAuthSessions[]> {
return this.oauthSessionsService.findAll(); return this.oauthSessionsService.findAll();
@ -36,7 +35,7 @@ export class OauthSessionsController {
@Get(':id') @Get(':id')
@RolesAllowed(RoleEnum.ADMIN) @RolesAllowed(RoleEnum.ADMIN)
@ApiOperation({summary: 'Find OAuth session' }) @ApiOperation({summary: 'Find OAuth session' })
@ApiResponse({ status: 201, description: 'OAuth session found', type: OAuthSessionEntity }) @ApiResponse({ status: 201, description: 'OAuth session found', type: CreateOauthSessionDto })
@ApiResponse({ status: 400, description: 'OAuth session not found' }) @ApiResponse({ status: 400, description: 'OAuth session not found' })
findOne(@Param('id') id: string): Promise<OAuthSessions> { findOne(@Param('id') id: string): Promise<OAuthSessions> {
return this.oauthSessionsService.findOne(id); return this.oauthSessionsService.findOne(id);
@ -45,7 +44,7 @@ export class OauthSessionsController {
@Patch(':id') @Patch(':id')
@RolesAllowed(RoleEnum.ADMIN) @RolesAllowed(RoleEnum.ADMIN)
@ApiOperation({summary: 'Update OAuth session' }) @ApiOperation({summary: 'Update OAuth session' })
@ApiResponse({ status: 201, description: 'OAuth session updated', type: OAuthSessionEntity }) @ApiResponse({ status: 201, description: 'OAuth session updated', type: CreateOauthSessionDto })
@ApiResponse({ status: 400, description: 'OAuth session not found' }) @ApiResponse({ status: 400, description: 'OAuth session not found' })
update(@Param('id') id: string, @Body() dto: UpdateOauthSessionDto): Promise<OAuthSessions> { update(@Param('id') id: string, @Body() dto: UpdateOauthSessionDto): Promise<OAuthSessions> {
return this.oauthSessionsService.update(id,dto); return this.oauthSessionsService.update(id,dto);
@ -54,7 +53,7 @@ export class OauthSessionsController {
@Delete(':id') @Delete(':id')
@RolesAllowed(RoleEnum.ADMIN) @RolesAllowed(RoleEnum.ADMIN)
@ApiOperation({summary: 'Delete OAuth session' }) @ApiOperation({summary: 'Delete OAuth session' })
@ApiResponse({ status: 201, description: 'OAuth session deleted', type: OAuthSessionEntity }) @ApiResponse({ status: 201, description: 'OAuth session deleted', type: CreateOauthSessionDto })
@ApiResponse({ status: 400, description: 'OAuth session not found' }) @ApiResponse({ status: 400, description: 'OAuth session not found' })
remove(@Param('id') id: string): Promise<OAuthSessions> { remove(@Param('id') id: string): Promise<OAuthSessions> {
return this.oauthSessionsService.remove(id); return this.oauthSessionsService.remove(id);

View File

@ -3,63 +3,68 @@ import { Type } from "class-transformer";
import { IsArray, IsDate, IsOptional, IsString, IsUUID } from "class-validator"; import { IsArray, IsDate, IsOptional, IsString, IsUUID } from "class-validator";
export class CreateOauthSessionDto { export class CreateOauthSessionDto {
@ApiProperty({
example: 'cklwi0vb70000z2z20q6f19qk',
description: 'Unique ID of an OAuth token (auto-generated)',
})
id: string;
@ApiProperty({ @ApiProperty({
example: 'S7A2U8R7O6N6', example: 'S7A2U8R7O6N6',
description: 'User`s unique identification number', description: 'User`s unique identification number',
}) })
@IsUUID() @IsUUID()
user_id: string; user_id: string;
@ApiProperty({ @ApiProperty({
example: 'app.targo.ca', example: 'app.targo.ca',
description: 'URL in which the access token is used for', description: 'URL in which the access token is used for',
}) })
@IsString() @IsString()
application: string; application: string;
@IsString() @IsString()
sid: string; sid: string;
@ApiProperty({ @ApiProperty({
example: 'L5O6R4D3/O6F3#T8H4E3&R6I4N6G4S7 ...', example: 'L5O6R4D3/O6F3#T8H4E3&R6I4N6G4S7 ...',
description: 'Access token', description: 'Access token',
}) })
@IsString() @IsString()
access_token: string; access_token: string;
@ApiProperty({ @ApiProperty({
example: 'Th3731102h1p07Th3R1n92', example: 'Th3731102h1p07Th3R1n92',
description: 'Refresh token', description: 'Refresh token',
}) })
@IsString() @IsString()
refresh_token: string; refresh_token: string;
@ApiProperty({ @ApiProperty({
example: '25/12/3018', example: '25/12/3018',
description: 'Access token`s expiry date', description: 'Access token`s expiry date',
}) })
@Type(()=> Date) @Type(()=> Date)
@IsDate() @IsDate()
access_token_expiry: Date; access_token_expiry: Date;
@ApiProperty({ @ApiProperty({
example: '26/02/3019', example: '26/02/3019',
description: 'Refresh token`s expiry date', description: 'Refresh token`s expiry date',
required: false, required: false,
}) })
@Type(()=> Date) @Type(()=> Date)
@IsDate() @IsDate()
@IsOptional() @IsOptional()
refresh_token_expiry?: Date; refresh_token_expiry?: Date;
@ApiProperty({ @ApiProperty({
example: 'access tolkiens, email, etc... ', example: 'access tolkiens, email, etc... ',
description: 'scopes of infos linked to the access token', description: 'scopes of infos linked to the access token',
required: false, required: false,
}) })
@IsArray() @IsArray()
@IsString() @IsString()
@IsOptional() @IsOptional()
scopes?: string[]; scopes?: string[];
} }

View File

@ -1,72 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class OAuthSessionEntity {
@ApiProperty({
example: 'cklwi0vb70000z2z20q6f19qk',
description: 'Unique ID of an OAuth token (auto-generated)',
})
id: string;
@ApiProperty({
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
description: 'UUID User`s unique identification number',
})
user_id: string;
@ApiProperty({
example: 'app.targo.ca',
description: 'URL in which the access token is used for',
})
application: string;
@ApiProperty({
example: 'L5O6R4D3/O6F3#T8H4E3&R6I4N6G4S7',
description: 'Access token',
})
access_token: string;
@ApiProperty({
example: 'Th3731102h1p07Th3R1n92',
description: 'Refresh token',
})
refresh_token: string;
@ApiProperty({
example: '3018-12-25T00:00:00.000Z',
description: 'Access token`s expiry date',
})
access_token_expiry: Date;
@ApiProperty({
example: '3019-02-26T00:00:00.000Z',
description: 'Refresh token`s expiry date (optional)',
required: false,
})
refresh_token_expiry?: Date;
@ApiProperty({
example: ['email', 'profile', 'access_tolkiens'],
description: 'scopes of infos linked to the access token',
required: false,
})
scopes: string[];
@ApiProperty({
example: false,
description: 'revoke status',
})
is_revoked: boolean;
@ApiProperty({
example: '2025-07-22',
description: 'creation date',
})
created_at: Date;
@ApiProperty({
example: '2025-07-23',
description: 'Latest update (optional)',
required: false,
})
updated_at?: Date;
}

View File

@ -5,7 +5,7 @@ import { Module } from "@nestjs/common";
import { PayPeriodsCommandService } from "./services/pay-periods-command.service"; import { PayPeriodsCommandService } from "./services/pay-periods-command.service";
import { PayPeriodsQueryService } from "./services/pay-periods-query.service"; import { PayPeriodsQueryService } from "./services/pay-periods-query.service";
import { TimesheetsModule } from "../timesheets/timesheets.module"; import { TimesheetsModule } from "../timesheets/timesheets.module";
import { TimesheetsApprovalService } from "../timesheets/services/timesheets-approval.service"; import { TimesheetsCommandService } from "../timesheets/services/timesheets-command.service";
import { ExpensesApprovalService } from "../expenses/services/expenses-approval.service"; import { ExpensesApprovalService } from "../expenses/services/expenses-approval.service";
import { ShiftsApprovalService } from "../shifts/services/shifts-approval.service"; import { ShiftsApprovalService } from "../shifts/services/shifts-approval.service";
@ -15,7 +15,7 @@ import { ShiftsApprovalService } from "../shifts/services/shifts-approval.servic
PayPeriodsService, PayPeriodsService,
PayPeriodsQueryService, PayPeriodsQueryService,
PayPeriodsCommandService, PayPeriodsCommandService,
TimesheetsApprovalService, TimesheetsCommandService,
ExpensesApprovalService, ExpensesApprovalService,
ShiftsApprovalService, ShiftsApprovalService,
], ],

View File

@ -1,12 +1,12 @@
import { Injectable, NotFoundException } from "@nestjs/common"; import { Injectable, NotFoundException } from "@nestjs/common";
import { TimesheetsApprovalService } from "src/modules/timesheets/services/timesheets-approval.service"; import { TimesheetsCommandService } from "src/modules/timesheets/services/timesheets-command.service";
import { PrismaService } from "src/prisma/prisma.service"; import { PrismaService } from "src/prisma/prisma.service";
@Injectable() @Injectable()
export class PayPeriodsCommandService { export class PayPeriodsCommandService {
constructor( constructor(
private readonly prisma: PrismaService, private readonly prisma: PrismaService,
private readonly timesheetsApproval: TimesheetsApprovalService, private readonly timesheetsApproval: TimesheetsCommandService,
) {} ) {}
async approvalPayPeriod(year: number , periodNumber: number): Promise<void> { async approvalPayPeriod(year: number , periodNumber: number): Promise<void> {

View File

@ -6,7 +6,6 @@ import { UpdateShiftsDto } from "../dtos/update-shift.dto";
import { RolesAllowed } from "src/common/decorators/roles.decorators"; import { RolesAllowed } from "src/common/decorators/roles.decorators";
import { Roles as RoleEnum } from '.prisma/client'; import { Roles as RoleEnum } from '.prisma/client';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger"; import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
import { ShiftEntity } from "../dtos/swagger-entities/shift.entity";
import { ShiftsApprovalService } from "../services/shifts-approval.service"; import { ShiftsApprovalService } from "../services/shifts-approval.service";
import { SearchShiftsDto } from "../dtos/search-shifts.dto"; import { SearchShiftsDto } from "../dtos/search-shifts.dto";
@ -23,7 +22,7 @@ export class ShiftsController {
@Post() @Post()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Create shift' }) @ApiOperation({ summary: 'Create shift' })
@ApiResponse({ status: 201, description: 'Shift created',type: ShiftEntity }) @ApiResponse({ status: 201, description: 'Shift created',type: CreateShiftDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' }) @ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body() dto: CreateShiftDto): Promise<Shifts> { create(@Body() dto: CreateShiftDto): Promise<Shifts> {
return this.shiftsService.create(dto); return this.shiftsService.create(dto);
@ -32,7 +31,7 @@ export class ShiftsController {
@Get() @Get()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find all shifts' }) @ApiOperation({ summary: 'Find all shifts' })
@ApiResponse({ status: 201, description: 'List of shifts found',type: ShiftEntity, isArray: true }) @ApiResponse({ status: 201, description: 'List of shifts found',type: CreateShiftDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of shifts not found' }) @ApiResponse({ status: 400, description: 'List of shifts not found' })
@UsePipes(new ValidationPipe({ transform: true, whitelist: true })) @UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
findAll(@Query() filters: SearchShiftsDto) { findAll(@Query() filters: SearchShiftsDto) {
@ -42,7 +41,7 @@ export class ShiftsController {
@Get(':id') @Get(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find shift' }) @ApiOperation({ summary: 'Find shift' })
@ApiResponse({ status: 201, description: 'Shift found',type: ShiftEntity }) @ApiResponse({ status: 201, description: 'Shift found',type: CreateShiftDto })
@ApiResponse({ status: 400, description: 'Shift not found' }) @ApiResponse({ status: 400, description: 'Shift not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise<Shifts> { findOne(@Param('id', ParseIntPipe) id: number): Promise<Shifts> {
return this.shiftsService.findOne(id); return this.shiftsService.findOne(id);
@ -51,7 +50,7 @@ export class ShiftsController {
@Patch(':id') @Patch(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Update shift' }) @ApiOperation({ summary: 'Update shift' })
@ApiResponse({ status: 201, description: 'Shift updated',type: ShiftEntity }) @ApiResponse({ status: 201, description: 'Shift updated',type: CreateShiftDto })
@ApiResponse({ status: 400, description: 'Shift not found' }) @ApiResponse({ status: 400, description: 'Shift not found' })
update(@Param('id', ParseIntPipe) id: number,@Body() dto: UpdateShiftsDto): Promise<Shifts> { update(@Param('id', ParseIntPipe) id: number,@Body() dto: UpdateShiftsDto): Promise<Shifts> {
return this.shiftsService.update(id, dto); return this.shiftsService.update(id, dto);
@ -60,7 +59,7 @@ export class ShiftsController {
@Delete(':id') @Delete(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Delete shift' }) @ApiOperation({ summary: 'Delete shift' })
@ApiResponse({ status: 201, description: 'Shift deleted',type: ShiftEntity }) @ApiResponse({ status: 201, description: 'Shift deleted',type: CreateShiftDto })
@ApiResponse({ status: 400, description: 'Shift not found' }) @ApiResponse({ status: 400, description: 'Shift not found' })
remove(@Param('id', ParseIntPipe) id: number): Promise<Shifts> { remove(@Param('id', ParseIntPipe) id: number): Promise<Shifts> {
return this.shiftsService.remove(id); return this.shiftsService.remove(id);

View File

@ -1,26 +1,52 @@
import { ApiProperty } from "@nestjs/swagger";
import { Type } from "class-transformer"; import { Type } from "class-transformer";
import { IsDate, IsDateString, IsInt, IsString } from "class-validator"; import { IsDate, IsDateString, IsInt, IsString } from "class-validator";
export class CreateShiftDto { export class CreateShiftDto {
@ApiProperty({
example: 1,
description: 'Unique ID of the shift (auto-generated)',
})
id: number;
@ApiProperty({
example: 101,
description: 'ID number for a set timesheet',
})
@Type(() => Number) @Type(() => Number)
@IsInt() @IsInt()
timesheet_id: number; timesheet_id: number;
@ApiProperty({
example: 7,
description: 'ID number of a shift code (link with bank-codes)',
})
@Type(() => Number) @Type(() => Number)
@IsInt() @IsInt()
bank_code_id: number; bank_code_id: number;
@ApiProperty({
example: '3018-10-20T00:00:00.000Z',
description: 'Date where the shift takes place',
})
@IsDateString() @IsDateString()
@Type(() => Date) @Type(() => Date)
@IsDate() @IsDate()
date: Date; date: Date;
@ApiProperty({
example: '3018-10-20T08:00:00.000Z',
description: 'Start time of the said shift',
})
@IsDateString() @IsDateString()
@Type(() => Date) @Type(() => Date)
@IsDate() @IsDate()
start_time: Date; start_time: Date;
@ApiProperty({
example: '3018-10-20T17:00:00.000Z',
description: 'End time of the said shift',
})
@IsDateString() @IsDateString()
@Type(() => Date) @Type(() => Date)
@IsDate() @IsDate()

View File

@ -1,39 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class ShiftEntity {
@ApiProperty({
example: 1,
description: 'Unique ID of the shift (auto-generated)',
})
id: number;
@ApiProperty({
example: 101,
description: 'ID number for a set timesheet',
})
timesheet_id: number;
@ApiProperty({
example: 7,
description: 'ID number of a shift code (link with bank-codes)',
})
bank_code_id: number;
@ApiProperty({
example: '3018-10-20T00:00:00.000Z',
description: 'Date where the shift takes place',
})
date: Date;
@ApiProperty({
example: '3018-10-20T08:00:00.000Z',
description: 'Start time of the said shift',
})
start_time: Date;
@ApiProperty({
example: '3018-10-20T17:00:00.000Z',
description: 'End time of the said shift',
})
end_time: Date;
}

View File

@ -1,4 +1,4 @@
import { Injectable, NotFoundException } from "@nestjs/common"; import { Injectable } from "@nestjs/common";
import { Shifts } from "@prisma/client"; import { Shifts } from "@prisma/client";
import { BaseApprovalService } from "src/common/shared/base-approval.service"; import { BaseApprovalService } from "src/common/shared/base-approval.service";
import { PrismaService } from "src/prisma/prisma.service"; import { PrismaService } from "src/prisma/prisma.service";

View File

@ -32,10 +32,11 @@ export class ShiftsOverviewService {
where: { date: { gte: start_date, lte: end_date } }, where: { date: { gte: start_date, lte: end_date } },
include: { include: {
bank_code: true, bank_code: true,
timesheet: { include: { employee: { timesheet: { include: {
include: { user:true, employee: { include: {
supervisor: { include: { user: true } }, user:true,
} }, supervisor: { include: { user: true } },
} },
} }, } },
}, },
}); });
@ -45,9 +46,9 @@ export class ShiftsOverviewService {
include: { include: {
bank_code: true, bank_code: true,
timesheet: { include: { employee: { timesheet: { include: { employee: {
include: { user:true, include: { user:true,
supervisor: { include: { user:true } }, supervisor: { include: { user:true } },
} }, } },
} }, } },
}, },
}); });

View File

@ -6,8 +6,7 @@ import { UpdateTimesheetDto } from '../dtos/update-timesheet.dto';
import { RolesAllowed } from "src/common/decorators/roles.decorators"; import { RolesAllowed } from "src/common/decorators/roles.decorators";
import { Roles as RoleEnum } from '.prisma/client'; import { Roles as RoleEnum } from '.prisma/client';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { TimesheetEntity } from '../dtos/swagger-entities/timesheet.entity'; import { TimesheetsCommandService } from '../services/timesheets-command.service';
import { TimesheetsApprovalService } from '../services/timesheets-approval.service';
import { SearchTimesheetDto } from '../dtos/search-timesheets.dto'; import { SearchTimesheetDto } from '../dtos/search-timesheets.dto';
@ApiTags('Timesheets') @ApiTags('Timesheets')
@ -17,13 +16,13 @@ import { SearchTimesheetDto } from '../dtos/search-timesheets.dto';
export class TimesheetsController { export class TimesheetsController {
constructor( constructor(
private readonly timesheetsService: TimesheetsService, private readonly timesheetsService: TimesheetsService,
private readonly timesheetsApprovalService: TimesheetsApprovalService, private readonly timesheetsCommandService: TimesheetsCommandService,
) {} ) {}
@Post() @Post()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Create timesheet' }) @ApiOperation({ summary: 'Create timesheet' })
@ApiResponse({ status: 201, description: 'Timesheet created', type: TimesheetEntity }) @ApiResponse({ status: 201, description: 'Timesheet created', type: CreateTimesheetDto })
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' }) @ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
create(@Body() dto: CreateTimesheetDto): Promise<Timesheets> { create(@Body() dto: CreateTimesheetDto): Promise<Timesheets> {
return this.timesheetsService.create(dto); return this.timesheetsService.create(dto);
@ -32,7 +31,7 @@ export class TimesheetsController {
@Get() @Get()
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find all timesheets' }) @ApiOperation({ summary: 'Find all timesheets' })
@ApiResponse({ status: 201, description: 'List of timesheet found', type: TimesheetEntity, isArray: true }) @ApiResponse({ status: 201, description: 'List of timesheet found', type: CreateTimesheetDto, isArray: true })
@ApiResponse({ status: 400, description: 'List of timesheets not found' }) @ApiResponse({ status: 400, description: 'List of timesheets not found' })
@UsePipes(new ValidationPipe({transform: true, whitelist: true })) @UsePipes(new ValidationPipe({transform: true, whitelist: true }))
findAll(@Query() filters: SearchTimesheetDto): Promise<any[]> { findAll(@Query() filters: SearchTimesheetDto): Promise<any[]> {
@ -42,7 +41,7 @@ export class TimesheetsController {
@Get(':id') @Get(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Find timesheet' }) @ApiOperation({ summary: 'Find timesheet' })
@ApiResponse({ status: 201, description: 'Timesheet found', type: TimesheetEntity }) @ApiResponse({ status: 201, description: 'Timesheet found', type: CreateTimesheetDto })
@ApiResponse({ status: 400, description: 'Timesheet not found' }) @ApiResponse({ status: 400, description: 'Timesheet not found' })
findOne(@Param('id', ParseIntPipe) id: number): Promise<Timesheets> { findOne(@Param('id', ParseIntPipe) id: number): Promise<Timesheets> {
return this.timesheetsService.findOne(id); return this.timesheetsService.findOne(id);
@ -51,7 +50,7 @@ export class TimesheetsController {
@Patch(':id') @Patch(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Update timesheet' }) @ApiOperation({ summary: 'Update timesheet' })
@ApiResponse({ status: 201, description: 'Timesheet updated', type: TimesheetEntity }) @ApiResponse({ status: 201, description: 'Timesheet updated', type: CreateTimesheetDto })
@ApiResponse({ status: 400, description: 'Timesheet not found' }) @ApiResponse({ status: 400, description: 'Timesheet not found' })
update( update(
@Param('id', ParseIntPipe) id:number, @Param('id', ParseIntPipe) id:number,
@ -63,7 +62,7 @@ export class TimesheetsController {
@Delete(':id') @Delete(':id')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
@ApiOperation({ summary: 'Delete timesheet' }) @ApiOperation({ summary: 'Delete timesheet' })
@ApiResponse({ status: 201, description: 'Timesheet deleted', type: TimesheetEntity }) @ApiResponse({ status: 201, description: 'Timesheet deleted', type: CreateTimesheetDto })
@ApiResponse({ status: 400, description: 'Timesheet not found' }) @ApiResponse({ status: 400, description: 'Timesheet not found' })
remove(@Param('id', ParseIntPipe) id: number): Promise<Timesheets> { remove(@Param('id', ParseIntPipe) id: number): Promise<Timesheets> {
return this.timesheetsService.remove(id); return this.timesheetsService.remove(id);
@ -72,6 +71,6 @@ export class TimesheetsController {
@Patch(':id/approval') @Patch(':id/approval')
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR) @RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
async approve(@Param('id', ParseIntPipe) id: number, @Body('is_approved', ParseBoolPipe) isApproved: boolean) { async approve(@Param('id', ParseIntPipe) id: number, @Body('is_approved', ParseBoolPipe) isApproved: boolean) {
return this.timesheetsApprovalService.updateApproval(id, isApproved); return this.timesheetsCommandService.updateApproval(id, isApproved);
} }
} }

View File

@ -3,9 +3,14 @@ import { Type } from "class-transformer";
import { IsBoolean, IsInt, IsOptional } from "class-validator"; import { IsBoolean, IsInt, IsOptional } from "class-validator";
export class CreateTimesheetDto { export class CreateTimesheetDto {
@ApiProperty({
example: 1,
description: 'timesheet`s unique ID (auto-generated)',
})
id: number;
@ApiProperty({ @ApiProperty({
example: '426433', example: 426433,
description: 'employee`s ID number of linked timsheet', description: 'employee`s ID number of linked timsheet',
}) })
@Type(() => Number) @Type(() => Number)
@ -13,10 +18,10 @@ export class CreateTimesheetDto {
employee_id: number; employee_id: number;
@ApiProperty({ @ApiProperty({
example: 'True or False or Pending or Denied or Cancelled or Escalated', example: true,
description: 'Timesheet`s approval status', description: 'Timesheet`s status approval',
}) })
@IsOptional() @IsOptional()
@IsBoolean() @IsBoolean()
is_approved?: boolean; is_approved?: boolean;
} }

View File

@ -6,15 +6,15 @@ export class SearchTimesheetDto {
@IsOptional() @IsOptional()
@Type(() => Number) @Type(() => Number)
@IsInt() @IsInt()
timesheet_id: number; timesheet_id?: number;
@IsOptional() @IsOptional()
@Type(()=> Number) @Type(()=> Number)
@IsInt() @IsInt()
employee_id: number; employee_id?: number;
@IsOptional() @IsOptional()
@Type(()=> Boolean) @Type(()=> Boolean)
@IsBoolean() @IsBoolean()
is_approved: boolean; is_approved?: boolean;
} }

View File

@ -1,21 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class TimesheetEntity {
@ApiProperty({
example: 1,
description: 'timesheet`s unique ID (auto-generated)',
})
id: number;
@ApiProperty({
example: 426433,
description: 'employee`s ID number of linked timsheet',
})
employee_id: number;
@ApiProperty({
example: true,
description: 'Timesheet`s approval status',
})
is_approved: boolean;
}

View File

@ -1,18 +1,12 @@
import { Injectable, NotFoundException } from "@nestjs/common"; import { Injectable } from "@nestjs/common";
import { Timesheets } from "@prisma/client"; import { Timesheets } from "@prisma/client";
import { BaseApprovalService } from "src/common/shared/base-approval.service"; import { BaseApprovalService } from "src/common/shared/base-approval.service";
import { ExpensesApprovalService } from "src/modules/expenses/services/expenses-approval.service";
import { ShiftsApprovalService } from "src/modules/shifts/services/shifts-approval.service";
import { PrismaService } from "src/prisma/prisma.service"; import { PrismaService } from "src/prisma/prisma.service";
@Injectable() @Injectable()
export class TimesheetsApprovalService extends BaseApprovalService<Timesheets>{ export class TimesheetsCommandService extends BaseApprovalService<Timesheets>{
constructor( constructor(prisma: PrismaService) {super(prisma);}
prisma: PrismaService,
private readonly shiftsApproval: ShiftsApprovalService,
private readonly expensesApproval: ExpensesApprovalService,
) {super(prisma);}
protected get delegate() { protected get delegate() {
return this.prisma.timesheets; return this.prisma.timesheets;

View File

@ -2,7 +2,7 @@ import { Module } from '@nestjs/common';
import { TimesheetsController } from './controllers/timesheets.controller'; import { TimesheetsController } from './controllers/timesheets.controller';
import { TimesheetsService } from './services/timesheets.service'; import { TimesheetsService } from './services/timesheets.service';
import { BusinessLogicsModule } from 'src/modules/business-logics/business-logics.module'; import { BusinessLogicsModule } from 'src/modules/business-logics/business-logics.module';
import { TimesheetsApprovalService } from './services/timesheets-approval.service'; import { TimesheetsCommandService } from './services/timesheets-command.service';
import { ShiftsApprovalService } from '../shifts/services/shifts-approval.service'; import { ShiftsApprovalService } from '../shifts/services/shifts-approval.service';
import { ExpensesApprovalService } from '../expenses/services/expenses-approval.service'; import { ExpensesApprovalService } from '../expenses/services/expenses-approval.service';
@ -11,7 +11,7 @@ import { ExpensesApprovalService } from '../expenses/services/expenses-approval.
controllers: [TimesheetsController], controllers: [TimesheetsController],
providers: [ providers: [
TimesheetsService, TimesheetsService,
TimesheetsApprovalService, TimesheetsCommandService,
ShiftsApprovalService, ShiftsApprovalService,
ExpensesApprovalService ExpensesApprovalService
], ],

View File

@ -1,7 +1,7 @@
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { Roles } from '@prisma/client'; import { Roles } from '@prisma/client';
export class UserEntity { export class UserDto {
@ApiProperty({ @ApiProperty({
example: 'd67f05be-6dd1-464f-b5f7-31b325e21b4a', example: 'd67f05be-6dd1-464f-b5f7-31b325e21b4a',
description: 'User`s unique UUID (primary key)', description: 'User`s unique UUID (primary key)',