Skip to content

Commit

Permalink
Multi-permit needed (Multi-authorization project) stats added
Browse files Browse the repository at this point in the history
  • Loading branch information
sanjaytkbabu committed Aug 28, 2024
1 parent 657429d commit 1bb5c2f
Show file tree
Hide file tree
Showing 13 changed files with 313 additions and 28 deletions.
4 changes: 2 additions & 2 deletions app/src/controllers/permit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ const controller = {
}
},

async listPermits(req: Request<{ activityId: string }>, res: Response, next: NextFunction) {
async listPermits(req: Request<never, { activityId?: string }>, res: Response, next: NextFunction) {
try {
const response = await permitService.listPermits(req.params.activityId);
const response = await permitService.listPermits(req.query?.activityId);
res.status(200).json(response);
} catch (e: unknown) {
next(e);
Expand Down
252 changes: 252 additions & 0 deletions app/src/db/migrations/20240718000000_007-rbac.ts

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions app/src/routes/v1/permit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ const router = express.Router();
router.use(requireSomeAuth);
router.use(requireSomeGroup);

// Permit list endpoint
router.get(
'/',
hasAuthorization(Resource.PERMIT, Action.READ),
permitValidator.listPermits,
(req: Request, res: Response, next: NextFunction): void => {
permitController.listPermits(req, res, next);
}
);

// Permit create endpoint
router.put(
'/',
Expand Down Expand Up @@ -46,16 +56,6 @@ router.delete(
}
);

// Permit list by activity endpoint
router.get(
'/list/:activityId',
hasAuthorization(Resource.PERMIT, Action.READ),
permitValidator.listPermits,
(req: Request, res: Response, next: NextFunction): void => {
permitController.listPermits(req, res, next);
}
);

// Permit types endpoint
router.get(
'/types',
Expand Down
6 changes: 3 additions & 3 deletions app/src/services/permit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,17 @@ const service = {

/**
* @function listPermits
* Retrieve a list of permits associated with a given activity
* Retrieve all permits if no activityId is provided, otherwise retrieve permits for a specific activity
* @param {string} activityId PCNS Activity ID
* @returns {Promise<Permit[]>} The result of running the findMany operation
*/
listPermits: async (activityId: string) => {
listPermits: async (activityId?: string) => {
const response = await prisma.permit.findMany({
include: {
permit_type: true
},
where: {
activity_id: activityId
activity_id: activityId ? activityId : undefined
},
orderBy: {
permit_type: {
Expand Down
4 changes: 2 additions & 2 deletions app/src/validators/permit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ const schema = {
})
},
listPermits: {
params: Joi.object({
activityId: activityId
query: Joi.object({
activityId: Joi.string().min(8).max(8).allow(null)
})
},
updatePermit: {
Expand Down
8 changes: 4 additions & 4 deletions app/tests/unit/controllers/permit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ describe('listPermits', () => {
it('should return 200 if all good', async () => {
const now = new Date();
const req = {
params: { activityId: 'ACT_ID' },
query: { activityId: 'ACT_ID' },
currentContext: CURRENT_CONTEXT
};

Expand All @@ -275,14 +275,14 @@ describe('listPermits', () => {
await permitController.listPermits(req as any, res as any, next);

expect(listSpy).toHaveBeenCalledTimes(1);
expect(listSpy).toHaveBeenCalledWith(req.params.activityId);
expect(listSpy).toHaveBeenCalledWith(req.query.activityId);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toHaveBeenCalledWith(permitList);
});

it('calls next if the permit service fails to list permits', async () => {
const req = {
params: { activityId: 'ACT_ID' },
query: { activityId: 'ACT_ID' },
currentContext: CURRENT_CONTEXT
};

Expand All @@ -294,7 +294,7 @@ describe('listPermits', () => {
await permitController.listPermits(req as any, res as any, next);

expect(listSpy).toHaveBeenCalledTimes(1);
expect(listSpy).toHaveBeenCalledWith(req.params.activityId);
expect(listSpy).toHaveBeenCalledWith(req.query.activityId);
expect(res.status).toHaveBeenCalledTimes(0);
expect(next).toHaveBeenCalledTimes(1);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ function isFinanciallySupported(data: Submission) {
:sortable="true"
style="min-width: 125px"
/>
<Column
field="multiPermitsNeeded"
header="Multi-authorization project"
:sortable="true"
style="min-width: 125px"
/>
<Column
field="assignedTo"
header="Assigned to"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ watch(
<td class="col-1 text-right">{{ statistics.total_submissions }}</td>
<td class="col-2 text-right">{{ getPercentage(statistics.total_submissions) }}%</td>
</tr>
<tr>
<td class="col-9">Multi-authorization projects</td>
<td class="col-1 text-right">{{ statistics.multi_permits_needed }}</td>
<td class="col-2 text-right">{{ getPercentage(statistics.multi_permits_needed) }}%</td>
</tr>
<tr>
<td class="col-9">
Submissions by range
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import SubmissionBringForwardCalendar from '@/components/housing/submission/Subm
import SubmissionListNavigator from '@/components/housing/submission/SubmissionListNavigator.vue';
import SubmissionStatistics from '@/components/housing/submission/SubmissionStatistics.vue';
import { Accordion, AccordionTab, TabPanel, TabView, useToast } from '@/lib/primevue';
import { enquiryService, noteService, submissionService } from '@/services';
import { enquiryService, noteService, permitService, submissionService } from '@/services';
import { useAuthNStore, useAuthZStore } from '@/store';
import { Action, Initiative, Resource, RouteName, StorageKey } from '@/utils/enums/application';
import { Action, BasicResponse, Initiative, Resource, RouteName, StorageKey } from '@/utils/enums/application';
import { SubmissionType } from '@/utils/enums/housing';
import { BringForwardType, IntakeStatus } from '@/utils/enums/housing';
import { formatDate } from '@/utils/formatters';
import type { Ref } from 'vue';
import type { BringForward, Enquiry, Statistics, Submission } from '@/types';
import type { BringForward, Enquiry, Permit, Statistics, Submission } from '@/types';
// Constants
const NOTES_TAB_INDEX = {
Expand All @@ -37,6 +37,7 @@ const bringForward: Ref<Array<BringForward>> = ref([]);
const enquiries: Ref<Array<Enquiry>> = ref([]);
const myBringForward: Ref<Array<BringForward>> = ref([]);
const myAssignedTo: Ref<Set<string>> = ref(new Set<string>());
const permits: Ref<Array<Permit>> = ref([]);
const loading: Ref<boolean> = ref(true);
const submissions: Ref<Array<Submission>> = ref([]);
const statistics: Ref<Statistics | undefined> = ref(undefined);
Expand Down Expand Up @@ -95,9 +96,10 @@ onMounted(async () => {
// To pull data from CHEFS
await submissionService.getSubmissions();
[enquiries.value, submissions.value, statistics.value, bringForward.value] = (
[enquiries.value, permits.value, submissions.value, statistics.value, bringForward.value] = (
await Promise.all([
enquiryService.getEnquiries(),
permitService.listPermits(),
submissionService.searchSubmissions({
includeUser: true,
intakeStatus: [IntakeStatus.ASSIGNED, IntakeStatus.COMPLETED, IntakeStatus.SUBMITTED]
Expand All @@ -108,6 +110,7 @@ onMounted(async () => {
).map((r) => r.data);
assignEnquiries();
assignMultiPermitsNeeded();
const profile = getProfile.value;
Expand Down Expand Up @@ -161,6 +164,23 @@ function assignEnquiries() {
});
}
// Set multiPermitsNeeded property of each submission to Yes/No (count)
// if the submission have more than one permit with needed Yes
function assignMultiPermitsNeeded() {
submissions.value.forEach((sub) => {
let multiPermitsNeededCount = 0;
if (Array.isArray(permits.value)) {
permits.value.forEach((permit) => {
if (permit.activityId === sub.activityId && permit.needed?.toUpperCase() === BasicResponse.YES.toUpperCase()) {
multiPermitsNeededCount++;
}
});
}
if (multiPermitsNeededCount > 1) sub.multiPermitsNeeded = `${BasicResponse.YES} (${multiPermitsNeededCount})`;
else sub.multiPermitsNeeded = BasicResponse.NO;
});
}
watch(accordionIndex, () => {
if (accordionIndex.value !== null) {
window.sessionStorage.setItem(StorageKey.BF_ACCORDION_IDX, accordionIndex.value.toString());
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/services/permitService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export default {
* @function listPermits
* @returns {Promise} An axios response
*/
async listPermits(activityId: string) {
return appAxios().get(`permit/list/${activityId}`);
async listPermits(activityId?: string) {
return appAxios().get('permit', { params: { activityId } });
},

/**
Expand Down
1 change: 1 addition & 0 deletions frontend/src/types/Statistics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type Statistics = {
intake_submitted: number;
intake_assigned: number;
intake_completed: number;
multi_permits_needed: number;
state_new: number;
state_inprogress: number;
state_delayed: number;
Expand Down
1 change: 1 addition & 0 deletions frontend/src/types/Submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type Submission = {
projectLocationDescription: string;
singleFamilyUnits: string;
multiFamilyUnits: string;
multiPermitsNeeded: string;
otherUnitsDescription: string;
otherUnits: string;
hasRentalUnits: string;
Expand Down
2 changes: 1 addition & 1 deletion frontend/tests/unit/service/permitService.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ describe('permitService test', () => {
it('calls get permit list', async () => {
await permitService.listPermits(TEST_ID);
expect(getSpy).toHaveBeenCalledTimes(1);
expect(getSpy).toHaveBeenCalledWith(`${PATH}/list/${TEST_ID}`);
expect(getSpy).toHaveBeenCalledWith(`${PATH}`, { params: { activityId: TEST_ID } });
});

it('calls get permit list with wrong ID', async () => {
Expand Down

0 comments on commit 1bb5c2f

Please sign in to comment.