Skip to content

Commit

Permalink
Merge branch 'develop' into feature/business_tax_return
Browse files Browse the repository at this point in the history
  • Loading branch information
Luphia authored Aug 21, 2024
2 parents d1ef046 + acfafd3 commit 732467e
Show file tree
Hide file tree
Showing 26 changed files with 886 additions and 608 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "iSunFA",
"version": "0.8.0+20",
"version": "0.8.0+22",
"private": false,
"scripts": {
"dev": "next dev",
Expand Down
2 changes: 1 addition & 1 deletion prisma/seed_json/employee_project.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"employeeId": 1001,
"projectId": 1000,
"startDate": 1635724800,
"endDate": 1635811200,
"endDate": null,
"createdAt": 1635724800,
"updatedAt": 1635724800
}
Expand Down
60 changes: 57 additions & 3 deletions prisma/seed_json/milestone.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"id":1015,
"id": 1015,
"projectId": 1001,
"startDate": 1709578219,
"endDate": 1712256619,
Expand Down Expand Up @@ -81,7 +81,7 @@
"updatedAt": 1717637165
},
{
"id":1014,
"id": 1014,
"projectId": 1007,
"startDate": 1717637165,
"endDate": 1718179676,
Expand Down Expand Up @@ -142,5 +142,59 @@
"status": "Archived",
"createdAt": 1709578219,
"updatedAt": 1709578219
},
{
"id": 1016,
"projectId": 1009,
"startDate": 0,
"endDate": 0,
"status": "Designing",
"createdAt": 1709578219,
"updatedAt": 1709578219
},
{
"id": 1017,
"projectId": 1009,
"startDate": 0,
"endDate": 0,
"status": "Beta Testing",
"createdAt": 1709578219,
"updatedAt": 1709578219
},
{
"id": 1018,
"projectId": 1009,
"startDate": 0,
"endDate": 0,
"status": "Develop",
"createdAt": 1709578219,
"updatedAt": 1709578219
},
{
"id": 1019,
"projectId": 1009,
"startDate": 0,
"endDate": 0,
"status": "Selling",
"createdAt": 1709578219,
"updatedAt": 1709578219
},
{
"id": 1020,
"projectId": 1009,
"startDate": 0,
"endDate": 0,
"status": "Sold",
"createdAt": 1709578219,
"updatedAt": 1709578219
},
{
"id": 1021,
"projectId": 1009,
"startDate": 0,
"endDate": 0,
"status": "Archived",
"createdAt": 1709578219,
"updatedAt": 1709578219
}
]
]
11 changes: 11 additions & 0 deletions prisma/seed_json/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,16 @@
"createdAt": 1651368365,
"updatedAt": 1651368365,
"deletedAt": null
},
{
"id": 1009,
"companyId": 1000,
"name": "Test update Project",
"completedPercent": 83,
"stage": "Beta Testing",
"imageId": "TP",
"createdAt": 1651368365,
"updatedAt": 1651368365,
"deletedAt": null
}
]
10 changes: 7 additions & 3 deletions src/lib/utils/repo/authentication.repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@ import { timestampInSeconds } from '@/lib/utils/common';

export async function getUserByCredential(
credentialId: string
): Promise<(Authentication & { user: User }) | null> {
let user: (Authentication & { user: User }) | null = null;
): Promise<(Authentication & { user: User & { userAgreements: UserAgreement[] } }) | null> {
let user: (Authentication & { user: User & { userAgreements: UserAgreement[] } }) | null = null;
if (credentialId.trim() !== '') {
user = await prisma.authentication.findUnique({
where: {
credentialId,
OR: [{ deletedAt: 0 }, { deletedAt: null }],
},
include: {
user: true,
user: {
include: {
userAgreements: true,
},
},
},
});
}
Expand Down
12 changes: 5 additions & 7 deletions src/lib/utils/repo/employee.repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,11 @@ export async function getProjectsByEmployeeId(employeeIdNumber: number) {
employeeId: employeeIdNumber,
endDate: null,
},
select: {
project: {
select: {
id: true,
name: true,
},
},
include: {
project: true,
},
orderBy: {
startDate: 'asc',
},
});
return projects;
Expand Down
3 changes: 3 additions & 0 deletions src/lib/utils/repo/profit_comparison.repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export async function getProjectLists(companyId: number) {
where: {
companyId,
},
orderBy: {
name: 'asc',
},
});
}

Expand Down
3 changes: 1 addition & 2 deletions src/lib/utils/repo_test/employee.repo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,10 @@ describe('Employee Repository Tests', () => {
});
describe('getProjectsByEmployeeId', () => {
it('should get projects by employee id', async () => {
const employeeId = 1000;
const employeeId = 1001;
const projectsFromDb = await getProjectsByEmployeeId(employeeId);
expect(projectsFromDb).toBeDefined();
expect(Array.isArray(projectsFromDb)).toBe(true);
expect(projectsFromDb.length).toBeGreaterThan(0);
expect(projectsFromDb[0].project.id).toEqual(employeeProjects[0].projectId);
});
});
Expand Down
12 changes: 12 additions & 0 deletions src/lib/utils/repo_test/trasaction_test/project_members.tx.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ describe('ProjectMembers Transaction Tests', () => {
});
expect(existingMembers.length).toBe(2);
await updateProjectMembers(testProjectId, memberIdList); // Reset the members
await prisma.employeeProject.deleteMany({
where: {
projectId: testProjectId,
employeeId: {
in: [1000, 1001, 1002],
},
endDate: { not: null },
id: {
gte: 10000000,
},
},
});
}, 10000);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import { formatMilestoneList } from '@/lib/utils/formatter/milestone.formatter';
import { IMilestone } from '@/interfaces/project';

let milestoneList: IMilestone[] = [];
const testProjectId = 1000;
const testProjectId = 1009;

beforeAll(async () => {
const listedMilestone = await listProjectMilestone(testProjectId);
milestoneList = formatMilestoneList(listedMilestone);
});

describe('Project Milestone Tests', () => {
const defaultStage = 'Beta Testing';
const updateStage = 'Sold';
const defaultStage = 'Develop';
const updateStage = 'Selling';
const now = Date.now();
const nowTimestamp = timestampInSeconds(now);

Expand Down
105 changes: 62 additions & 43 deletions src/pages/api/v1/company/[companyId]/account/[accountId]/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { getSession } from '@/lib/utils/session';
import { AuthFunctionsKeys } from '@/interfaces/auth';

function formatParams(companyId: unknown, accountId: string | string[] | undefined) {
// ToDo: (20240613 - Murky) - need to use type guard instead
const isCompanyIdValid = !Number.isNaN(Number(companyId));
const isAccountIdValid = isParamNumeric(accountId);

Expand All @@ -33,6 +32,9 @@ function formatParams(companyId: unknown, accountId: string | string[] | undefin
async function getCompanyIdAccountId(req: NextApiRequest, res: NextApiResponse) {
const session = await getSession(req, res);
const { userId, companyId } = session;
if (!userId) {
throw new Error(STATUS_MESSAGE.UNAUTHORIZED_ACCESS);
}
const isAuth = await checkAuthorization([AuthFunctionsKeys.admin], { userId, companyId });
if (!isAuth) {
throw new Error(STATUS_MESSAGE.FORBIDDEN);
Expand All @@ -45,69 +47,86 @@ async function getCompanyIdAccountId(req: NextApiRequest, res: NextApiResponse)
};
}

export async function handleGetRequest(companyIdNumber: number, accountIdNumber: number) {
async function handleGetRequest(
req: NextApiRequest,
res: NextApiResponse<IResponseData<IAccount | null>>
) {
let statusMessage: string = STATUS_MESSAGE.BAD_REQUEST;
let payload: IAccount | null = null;

const { companyIdNumber, accountIdNumber } = await getCompanyIdAccountId(req, res);
const accountFromDb = await findFirstAccountInPrisma(accountIdNumber, companyIdNumber);
const account = accountFromDb ? formatAccount(accountFromDb) : ({} as IAccount);
const { httpCode, result } = formatApiResponse<IAccount>(STATUS_MESSAGE.SUCCESS, account);
return {
httpCode,
result,
};
statusMessage = STATUS_MESSAGE.SUCCESS;
payload = account;

return { statusMessage, payload };
}

async function handlePutRequest(companyIdNumber: number, accountIdNumber: number, name: string) {
async function handlePutRequest(
req: NextApiRequest,
res: NextApiResponse<IResponseData<IAccount | null>>
) {
let statusMessage: string = STATUS_MESSAGE.BAD_REQUEST;
let payload: IAccount | null = null;

const { companyIdNumber, accountIdNumber } = await getCompanyIdAccountId(req, res);
const { name } = req.body;
const updatedAccount = await updateAccountInPrisma(accountIdNumber, companyIdNumber, name);
const account = updatedAccount ? formatAccount(updatedAccount) : ({} as IAccount);
const { httpCode, result } = formatApiResponse<IAccount>(STATUS_MESSAGE.SUCCESS_UPDATE, account);
return {
httpCode,
result,
};
statusMessage = STATUS_MESSAGE.SUCCESS_UPDATE;
payload = account;

return { statusMessage, payload };
}

async function handleDeleteRequest(companyIdNumber: number, accountIdNumber: number) {
async function handleDeleteRequest(
req: NextApiRequest,
res: NextApiResponse<IResponseData<IAccount | null>>
) {
let statusMessage: string = STATUS_MESSAGE.BAD_REQUEST;
let payload: IAccount | null = null;

const { companyIdNumber, accountIdNumber } = await getCompanyIdAccountId(req, res);
const deletedAccount = await softDeleteAccountInPrisma(accountIdNumber, companyIdNumber);
const account = deletedAccount ? formatAccount(deletedAccount) : ({} as IAccount);
const { httpCode, result } = formatApiResponse<IAccount>(STATUS_MESSAGE.SUCCESS_DELETE, account);
return {
httpCode,
result,
};
}
statusMessage = STATUS_MESSAGE.SUCCESS_DELETE;
payload = account;

export function handleErrorResponse(res: NextApiResponse, message: string) {
const { httpCode, result } = formatApiResponse<IAccount>(message, {} as IAccount);
return {
httpCode,
result,
};
return { statusMessage, payload };
}

const methodHandlers: {
[key: string]: (
req: NextApiRequest,
res: NextApiResponse
) => Promise<{ statusMessage: string; payload: IAccount | null }>;
} = {
GET: handleGetRequest,
PUT: handlePutRequest,
DELETE: handleDeleteRequest,
};

export default async function handler(
req: NextApiRequest,
res: NextApiResponse<IResponseData<IAccount>>
res: NextApiResponse<IResponseData<IAccount | null>>
) {
let statusMessage: string = STATUS_MESSAGE.BAD_REQUEST;
let payload: IAccount | null = null;

try {
const { companyIdNumber, accountIdNumber } = await getCompanyIdAccountId(req, res);
if (req.method === 'GET') {
const { httpCode, result } = await handleGetRequest(companyIdNumber, accountIdNumber);
res.status(httpCode).json(result);
} else if (req.method === 'PUT') {
const { name } = req.body;
const { httpCode, result } = await handlePutRequest(companyIdNumber, accountIdNumber, name);
res.status(httpCode).json(result);
} else if (req.method === 'DELETE') {
const { httpCode, result } = await handleDeleteRequest(companyIdNumber, accountIdNumber);
res.status(httpCode).json(result);
const handleRequest = methodHandlers[req.method || ''];
if (handleRequest) {
({ statusMessage, payload } = await handleRequest(req, res));
} else {
throw new Error(STATUS_MESSAGE.METHOD_NOT_ALLOWED);
statusMessage = STATUS_MESSAGE.METHOD_NOT_ALLOWED;
}
} catch (_error) {
const error = _error as Error;
// Info Murky (20240416): Debugging
// eslint-disable-next-line no-console
console.error(error.message);
const { httpCode, result } = handleErrorResponse(res, error.message);
statusMessage = error.message;
payload = null;
} finally {
const { httpCode, result } = formatApiResponse<IAccount | null>(statusMessage, payload);
res.status(httpCode).json(result);
}
}
7 changes: 5 additions & 2 deletions src/pages/api/v1/company/[companyId]/account/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export function formatGetQuery(companyId: number, req: NextApiRequest): IAccount
sortBy: formattedSortBy,
sortOrder: formattedSortOrder,
searchKey: formattedSearchKey,
isDeleted: formattedIsDeleted
isDeleted: formattedIsDeleted,
};
}

Expand Down Expand Up @@ -220,6 +220,9 @@ export async function handlePostRequest(
const session = await getSession(req, res);
const { userId, companyId } = session;
const { accountId, name } = req.body;
if (!userId) {
throw new Error(STATUS_MESSAGE.UNAUTHORIZED_ACCESS);
}
const isAuth = await checkAuthorization([AuthFunctionsKeys.admin], { userId, companyId });
if (!isAuth) {
throw new Error(STATUS_MESSAGE.FORBIDDEN);
Expand All @@ -233,7 +236,7 @@ export async function handlePostRequest(
}
const latestSubAccount = await findLatestSubAccountInPrisma(parentAccount);
const newCode = setNewCode(parentAccount, latestSubAccount);
const newName = parentAccount.name + "-" + String(name);
const newName = parentAccount.name + '-' + String(name);
const newOwnAccount = {
companyId: companyIdNumber,
system: parentAccount.system,
Expand Down
Loading

0 comments on commit 732467e

Please sign in to comment.