Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ppr reporter reimbursement confirmation #163

Merged
merged 1 commit into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion backend/emails/emails.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,26 @@ const sendEmailPPRPurchasedAndReceiptsSubmittedToCoordinator = async (ppr) => {
getMainMessageHTML(
`Item ${ppr.codename} has been purchased and receipts have been submitted! Please review the expense claim form and reimburse the reporter out of WATonomous' cash account.`
) +
(await getUPRTicketInfoHTML(ppr)) +
(await getPPRTicketInfoHTML(ppr)) +
getTicketLinkHTML(ppr.path)
const To = await getEmailToSection(ppr.reporter_id, [
EMAIL_RECIPIENTS.finance,
EMAIL_RECIPIENTS.coordinator,
])
await sendEmail({
Subject,
HTMLPart,
To,
})
}

const sendEmailPPRReimbursedToReporter = async (ppr) => {
const Subject = `[Reimbursed] ${ppr.codename}`
const HTMLPart =
getMainMessageHTML(
`Your Personal Purchase Request has been reimbursed! Please visit the ticket link below to confirm your reimbursement has been received.`
) +
(await getPPRTicketInfoHTML(ppr)) +
getTicketLinkHTML(ppr.path)
const To = await getEmailToSection(ppr.reporter_id, [
EMAIL_RECIPIENTS.finance,
Expand Down Expand Up @@ -564,6 +583,7 @@ module.exports = {
sendEmailPPRApprovedToReporter,
sendEmailPPRCreatedToApprovers,
sendEmailPPRPurchasedAndReceiptsSubmittedToCoordinator,
sendEmailPPRReimbursedToReporter,
PurchaseRequestInvalidated,
PersonalPurchaseApproved,
UWFinancePurchaseApproved,
Expand Down
5 changes: 4 additions & 1 deletion backend/service/personalpurchases.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
sendEmailPPRCreatedToApprovers,
sendEmailPPRApprovedToReporter,
sendEmailPPRPurchasedAndReceiptsSubmittedToCoordinator,
sendEmailPPRReimbursedToReporter,
} = require('../emails/emails')

const getAllPersonalPurchases = () => {
Expand Down Expand Up @@ -36,9 +37,11 @@ const updatePersonalPurchase = async (id, body) => {
const newPurchaseTicket = PersonalPurchase.findByIdAndUpdate(id, body, {
new: true,
})
const annotatedPPR = await getPersonalPurchase(id)
if (body?.status === 'PURCHASED_AND_RECEIPTS_SUBMITTED') {
const annotatedPPR = await getPersonalPurchase(id)
sendEmailPPRPurchasedAndReceiptsSubmittedToCoordinator(annotatedPPR)
} else if (body?.status === 'REPORTER_REIMBURSE_CONFIRMATION') {
sendEmailPPRReimbursedToReporter(annotatedPPR)
}
return newPurchaseTicket
}
Expand Down
61 changes: 44 additions & 17 deletions frontend/src/components/TicketContent/PPRAdminContentTable.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,51 @@
import { Button, Center, Heading, VStack } from '@chakra-ui/react'
import React from 'react'
import { useRecoilValue } from 'recoil'
import { currentTicketState } from '../../state/atoms'
import { useRecoilValue, useSetRecoilState } from 'recoil'
import { allTicketsState, currentTicketState } from '../../state/atoms'
import { axiosPreset } from '../../axiosConfig'
import { TICKET_ENDPOINTS } from '../../constants'
import { getAllTickets } from '../../utils/globalSetters'

const PPRAdminContentTable = () => {
const currentTicket = useRecoilValue(currentTicketState)
const setAllTickets = useSetRecoilState(allTicketsState)
const handleUpdateStatus = async (nextStatus) => {
const payload = {
status: nextStatus,
}
await axiosPreset.patch(
`${TICKET_ENDPOINTS.PPR}/${currentTicket._id}`,
payload
)
await getAllTickets(setAllTickets)
}
const getTransitionBody = () => {
switch (currentTicket.status) {
case 'PURCHASED_AND_RECEIPTS_SUBMITTED':
return getPurchasedAndReceiptsSubmittedBody()
default:
return (
<>
<h1>No Current Actions Available</h1>
</>
)
}
}
const getPurchasedAndReceiptsSubmittedBody = () => {
return (
<Center pb="7px">
<Button
colorScheme="blue"
size="sm"
onClick={() =>
handleUpdateStatus('REPORTER_REIMBURSE_CONFIRMATION')
}
>
Confirm Reporter Reimbursed
</Button>
</Center>
)
}
return (
<VStack
border="1px solid black"
Expand All @@ -13,21 +54,7 @@ const PPRAdminContentTable = () => {
mb="30px"
>
<Heading size="md">Admin View</Heading>
{
<Center pb="7px">
<Button
colorScheme="blue"
size="sm"
disabled={
currentTicket?.po_number?.length +
currentTicket?.requisition_number?.length ===
0
}
>
Transition Status
</Button>
</Center>
}
<Center pb="7px">{getTransitionBody()}</Center>
</VStack>
)
}
Expand Down
75 changes: 56 additions & 19 deletions frontend/src/components/TicketContent/PPRReporterTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { getAllTickets } from '../../utils/globalSetters'
const PPRReporterTable = ({ currentTicket, supportingDocuments }) => {
const setAllTickets = useSetRecoilState(allTicketsState)

const transitionToPurchasedAndReceiptsSubmitted = async () => {
const transitionStatus = async (status) => {
const payload = {
status: 'PURCHASED_AND_RECEIPTS_SUBMITTED',
status: status,
}
await axiosPreset.patch(
`${TICKET_ENDPOINTS.PPR}/${currentTicket._id}`,
Expand All @@ -20,6 +20,59 @@ const PPRReporterTable = ({ currentTicket, supportingDocuments }) => {
await getAllTickets(setAllTickets)
}

const getPurchasedAndRequestReimbursementBody = () => {
return (
<Tooltip
hasArrow
label="Please upload at least one supporting document before requesting reimbursement."
isDisabled={supportingDocuments.length !== 0}
>
<Button
colorScheme="blue"
size="sm"
mr="20px"
onClick={() => {
transitionStatus('PURCHASED_AND_RECEIPTS_SUBMITTED')
}}
disabled={supportingDocuments.length === 0}
>
Confirm Item(s) Purchased and Request Reimbursement
</Button>
</Tooltip>
)
}

const getReimbursementConfirmationBody = () => {
return (
<Button
colorScheme="blue"
size="sm"
mr="20px"
onClick={() => {
transitionStatus('REPORTER_REIMBURSED')
}}
disabled={supportingDocuments.length === 0}
>
Confirm Item(s) have been Reimbursed
</Button>
)
}

const getTransitionBody = () => {
switch (currentTicket.status) {
case 'READY_TO_BUY':
return getPurchasedAndRequestReimbursementBody()
case 'REPORTER_REIMBURSE_CONFIRMATION':
return getReimbursementConfirmationBody()
default:
return (
<>
<h1>No Current Actions Available</h1>
</>
)
}
}

return (
<VStack
border="1px solid black"
Expand All @@ -28,23 +81,7 @@ const PPRReporterTable = ({ currentTicket, supportingDocuments }) => {
mb="30px"
>
<Heading size="md">Reporter View</Heading>
<Center pb="7px">
<Tooltip
hasArrow
label="Please upload at least one supporting document before requesting reimbursement."
isDisabled={supportingDocuments.length !== 0}
>
<Button
colorScheme="blue"
size="sm"
mr="20px"
onClick={transitionToPurchasedAndReceiptsSubmitted}
disabled={supportingDocuments.length === 0}
>
Confirm Item(s) Purchased and Request Reimbursement
</Button>
</Tooltip>
</Center>
<Center pb="7px">{getTransitionBody()}</Center>
</VStack>
)
}
Expand Down
13 changes: 6 additions & 7 deletions frontend/src/pages/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,12 @@ const Dashboard = () => {
return (
<>
{auth.isAdmin && <PPRAdminContentTable />}
{isReporter() &&
currentTicket.status === 'READY_TO_BUY' && (
<PPRReporterTable
supportingDocuments={supportingDocuments}
currentTicket={currentTicket}
/>
)}
{isReporter() && (
<PPRReporterTable
supportingDocuments={supportingDocuments}
currentTicket={currentTicket}
/>
)}
<PPRContentTable />
</>
)
Expand Down
Loading