diff --git a/.env.sample b/.env.sample index 8ac24176..a4004c2d 100644 --- a/.env.sample +++ b/.env.sample @@ -29,7 +29,7 @@ S3_UPLOAD_BUCKET="" S3_UPLOAD_REGION="" # Misc -PROCESSING_FEE="26" +PROCESSING_FEE="31" CONFIRMATION_EMAIL_FROM="" INVOICE_LINK_TTL_DAYS="7" APPLICATION_DOCUMENT_LINK_TTL_HOURS="1" \ No newline at end of file diff --git a/README.md b/README.md index 71f42824..1b65755f 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ npx prisma db seed --preview-feature 5. Verify database ```bash -docker exec -it rcd_db /bin/bash -c "psql -U postgres -d rcd" +docker exec -it rcd_db bash -c "psql -U postgres -d rcd" ``` ## Run locally (Heroku) diff --git a/components/applicant/FAQs.tsx b/components/applicant/FAQs.tsx index e3d77d22..652ffba7 100644 --- a/components/applicant/FAQs.tsx +++ b/components/applicant/FAQs.tsx @@ -139,8 +139,8 @@ const OVERVIEW_FAQs: ReadonlyArray<{ question: string; answer: ReactNode | strin RCD will send you a Renewal Form approximately one (1) month before your permit is set to expire. This is applicable to all permanent permit holders. Once you receive your renewal notice you can renew your permit online, over the phone or by mailing in your completed - renewal form. There is a processing fee to renew your permit (fee is $26 as at April - 2022). As well, we ask that you also return your expired permit. + renewal form. There is a processing fee to renew your permit (fee is $31 as at August + 2023). As well, we ask that you also return your expired permit.

Use the RCD Accessible Parking Permit Online Portal (online portal) to update your contact @@ -195,8 +195,8 @@ const OVERVIEW_FAQs: ReadonlyArray<{ question: string; answer: ReactNode | strin

If you have lost your parking permit, please notify us right away. If you would like to request a replacement process, please complete the Replacement Declaration Form and we - will issue a replacement permit. However, there will be a processing fee (fee is $26 as at - April 2022). As well you are required to complete a declaration form that attests that in + will issue a replacement permit. However, there will be a processing fee (fee is $31 as at + August 2023). As well you are required to complete a declaration form that attests that in event that you find the lost permit you will return it to our office as the permit is no longer valid. Any permit holder using a permit that has been reported lost is at risk of a ticket or even towing of vehicle as this permit is no longer valid.{' '} @@ -281,7 +281,7 @@ const TRAVELLING_FAQs: ReadonlyArray<{ question: string; answer: ReactNode | str temporary permit, you will need to present official documentation from the issuing agency in your country. This information is needed to help to confirm that you are a valid accessible parking permit holder in your home jurisdiction. There is a Canadian processing - fee for any permit issued (fee is $26 as at April 2022). + fee for any permit issued (fee is $31 as at August 2023).

), @@ -313,7 +313,7 @@ const TRAVELLING_FAQs: ReadonlyArray<{ question: string; answer: ReactNode | str is all done through the processing fee that you pay as well as any donations that you make. As well, we have an established policy that hardship assistance is available upon request to anyone who does not have the economic resources to cover the cost of the - processing fee. Processing fee is $26 as at April 2022. + processing fee. Processing fee is $31 as at August 2023.

), @@ -328,9 +328,7 @@ const TRAVELLING_FAQs: ReadonlyArray<{ question: string; answer: ReactNode | str 604-232-2404 and we are more than happy to help.

- - Click here - {' '} + Click here{' '} for details on our location, directions on best ways to find us and our hours of operation.

diff --git a/lib/applicants/resolvers.ts b/lib/applicants/resolvers.ts index 6e8c4e6d..e014c8a6 100644 --- a/lib/applicants/resolvers.ts +++ b/lib/applicants/resolvers.ts @@ -79,6 +79,7 @@ export const applicants: Resolver< expiryDateRangeTo = undefined, search = undefined, dateOfBirth = undefined, + permitId = undefined, } = filter; let expiryDateUpperBound, @@ -148,7 +149,11 @@ export const applicants: Resolver< // Permit status and expiry date range filters both look at the permit expiryDate. // For this reason we need to filter on expiryDate twice to take both filters in account. const permitFilter = - expiryDateLowerBound || expiryDateUpperBound || expiryDateRangeFrom || expiryDateRangeTo + expiryDateLowerBound || + expiryDateUpperBound || + expiryDateRangeFrom || + expiryDateRangeTo || + permitId ? { some: { AND: [ @@ -164,6 +169,11 @@ export const applicants: Resolver< lte: expiryDateRangeTo?.toISOString(), }, }, + { + rcdPermitId: { + equals: permitId ?? undefined, + }, + }, ], }, } diff --git a/lib/applicants/schema.ts b/lib/applicants/schema.ts index fd82d524..585ff12d 100644 --- a/lib/applicants/schema.ts +++ b/lib/applicants/schema.ts @@ -158,6 +158,7 @@ export default gql` expiryDateRangeTo: Date search: String dateOfBirth: Date + permitId: Int limit: Int offset: Int } diff --git a/lib/application-processing/field-resolvers.ts b/lib/application-processing/field-resolvers.ts index a667a303..5200c4d2 100644 --- a/lib/application-processing/field-resolvers.ts +++ b/lib/application-processing/field-resolvers.ts @@ -63,9 +63,8 @@ export const applicationProcessingAppNumberEmployeeResolver: FieldResolver< ApplicationProcessing & { id: number }, Employee > = async (parent, _, { prisma }) => { - return await prisma.application + return await prisma.applicationProcessing .findUnique({ where: { id: parent.id } }) - .applicationProcessing() .appNumberEmployee(); }; @@ -76,9 +75,8 @@ export const applicationProcessingAppHolepunchedEmployeeResolver: FieldResolver< ApplicationProcessing & { id: number }, Employee > = async (parent, _, { prisma }) => { - return await prisma.application + return await prisma.applicationProcessing .findUnique({ where: { id: parent.id } }) - .applicationProcessing() .appHolepunchedEmployee(); }; @@ -89,9 +87,8 @@ export const applicationProcessingWalletCardCreatedEmployeeResolver: FieldResolv ApplicationProcessing & { id: number }, Employee > = async (parent, _, { prisma }) => { - return await prisma.application + return await prisma.applicationProcessing .findUnique({ where: { id: parent.id } }) - .applicationProcessing() .walletCardCreatedEmployee(); }; @@ -102,9 +99,8 @@ export const applicationProcessingReviewRequestCompletedEmployeeResolver: FieldR ApplicationProcessing & { id: number }, Employee > = async (parent, _, { prisma }) => { - return await prisma.application + return await prisma.applicationProcessing .findUnique({ where: { id: parent.id } }) - .applicationProcessing() .reviewRequestEmployee(); }; @@ -115,9 +111,8 @@ export const applicationProcessingDocumentsUrlEmployeeResolver: FieldResolver< ApplicationProcessing & { id: number }, Employee > = async (parent, _, { prisma }) => { - return await prisma.application + return await prisma.applicationProcessing .findUnique({ where: { id: parent.id } }) - .applicationProcessing() .documentsUrlEmployee(); }; @@ -128,9 +123,8 @@ export const applicationProcessingAppMailedEmployeeResolver: FieldResolver< ApplicationProcessing & { id: number }, Employee > = async (parent, _, { prisma }) => { - return await prisma.application + return await prisma.applicationProcessing .findUnique({ where: { id: parent.id } }) - .applicationProcessing() .appMailedEmployee(); }; @@ -141,8 +135,7 @@ export const applicationProcessingPaymentRefundedEmployeeResolver: FieldResolver ApplicationProcessing & { id: number }, Employee > = async (parent, _, { prisma }) => { - return await prisma.application + return await prisma.applicationProcessing .findUnique({ where: { id: parent.id } }) - .applicationProcessing() .paymentRefundedEmployee(); }; diff --git a/lib/application-processing/resolvers.ts b/lib/application-processing/resolvers.ts index bf39f9dd..18349582 100644 --- a/lib/application-processing/resolvers.ts +++ b/lib/application-processing/resolvers.ts @@ -321,7 +321,7 @@ export const completeApplication: Resolver< }, }, }, - // If guardian information given, upsert. Otherwise, delete (SET NULL) + // If guardian information given, upsert. ...(guardian ? { guardian: { @@ -331,7 +331,11 @@ export const completeApplication: Resolver< }, }, } - : { guardian: { delete: true } }), + : { + guardian: { + disconnect: true, + }, + }), }, }); diff --git a/lib/applications/validation.ts b/lib/applications/validation.ts index f8634ced..b3b93581 100644 --- a/lib/applications/validation.ts +++ b/lib/applications/validation.ts @@ -447,7 +447,6 @@ export const applicantFacingRenewalDoctorSchema = object().shape({ is: true, then: string() .typeError('Please enter the MSP number') - .matches(/^\d+$/, 'Must only contain numbers') .required('Please enter the MSP number'), }), doctorAddressLine1: string() diff --git a/lib/graphql/types.ts b/lib/graphql/types.ts index 4404b578..2f189962 100644 --- a/lib/graphql/types.ts +++ b/lib/graphql/types.ts @@ -63,6 +63,7 @@ export type ApplicantsFilter = { expiryDateRangeTo: Maybe; search: Maybe; dateOfBirth: Maybe; + permitId: Maybe; limit: Maybe; offset: Maybe; }; diff --git a/lib/invoices/utils.ts b/lib/invoices/utils.ts index f6c9c0bd..bfad9bfb 100644 --- a/lib/invoices/utils.ts +++ b/lib/invoices/utils.ts @@ -213,9 +213,9 @@ const pdfDefinition = (input: { `${address.addressLine2 ? `${address.addressLine2} - ` : ''}${address.addressLine1}\n`, `${address.city} ${address.province} ${formatPostalCode(address.postalCode)}`, ], - alignment: 'left', - margin: [40, 170, 0, 0], + absolutePosition: { x: 80, y: 740 }, fontSize: 12, + lineHeight: 1.4, }, ], styles: { diff --git a/lib/physicians/validation.ts b/lib/physicians/validation.ts index faefdec9..10ffe333 100644 --- a/lib/physicians/validation.ts +++ b/lib/physicians/validation.ts @@ -81,9 +81,7 @@ export const physicianAssessmentMutationSchema = physicianAssessmentSchema.shape export const requestPhysicianInformationSchema = object({ firstName: string().required('Please enter a first name'), lastName: string().required('Please enter a last name'), - mspNumber: string() - .matches(/^\d+$/, 'Must only contain numbers') - .required('Please enter the MSP number'), + mspNumber: string().required('Please enter the MSP number'), phone: string() .required('Please enter a phone number') .matches(phoneNumberRegex, 'Please enter a valid phone number in the format 000-000-0000'), diff --git a/package.json b/package.json index 9d56c568..9c3b56a0 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "react-helmet": "^6.1.0", "react-intersection-observer": "^8.32.0", "react-table": "^7.7.0", - "shopify-buy": "^2.13.0", + "shopify-buy": "^2.20.0", "typescript": "^4.4.2", "unstated-next": "^1.1.0", "yup": "^0.32.11" diff --git a/pages/admin/permit-holders.tsx b/pages/admin/permit-holders.tsx index 96bf439d..bc4bda7c 100644 --- a/pages/admin/permit-holders.tsx +++ b/pages/admin/permit-holders.tsx @@ -66,6 +66,7 @@ const PermitHolders: NextPage = () => { const [searchFilter, setSearchFilter] = useState(''); const { dateRange, addDayToDateRange, dateRangeString } = useDateRangePicker(); const [dateOfBirthFilter, setDateOfBirthFilter] = useState(''); + const [permitIdFilter, setPermitIdFilter] = useState(null); // Pagination const [sortOrder, setSortOrder] = useState([['name', SortOrder.ASC]]); @@ -91,6 +92,7 @@ const PermitHolders: NextPage = () => { expiryDateRangeTo: dateRange.to?.getTime(), search: debouncedSearchFilter, dateOfBirth: dateOfBirthFilter || null, + permitId: permitIdFilter, offset: pageNumber * PAGE_SIZE, limit: PAGE_SIZE, order: sortOrder, @@ -351,6 +353,28 @@ const PermitHolders: NextPage = () => { _focus={{ border: 'none' }} /> + + + Permit ID: + + setPermitIdFilter(event.target.valueAsNumber)} + border="none" + _focus={{ border: 'none' }} + /> + diff --git a/pages/api/payment-received.ts b/pages/api/payment-received.ts index 44670caa..040a954f 100644 --- a/pages/api/payment-received.ts +++ b/pages/api/payment-received.ts @@ -13,7 +13,7 @@ import logger from '@lib/utils/logging'; * Example request body: * { * id: '4646400131094', - * total_tip_received: '26.00', + * total_tip_received: '31.00', * order_id: '8', * billing_address: { * address1: '165 University Avenue West', diff --git a/pages/index.tsx b/pages/index.tsx index 9f8de8ea..46490b40 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -65,7 +65,7 @@ export default function Landing() { Provide your date of birth - Complete the online form and pay a $26 processing fee + Complete the online form and pay a $31 processing fee diff --git a/prisma/dev-seed-utils/applications.ts b/prisma/dev-seed-utils/applications.ts index 066e2e9a..c9c0d564 100644 --- a/prisma/dev-seed-utils/applications.ts +++ b/prisma/dev-seed-utils/applications.ts @@ -23,7 +23,7 @@ const applications: Array = [ postalCode: 'A1B2C3', permitType: 'PERMANENT', paymentMethod: 'CASH', - processingFee: new Prisma.Decimal(26), + processingFee: new Prisma.Decimal(31), donationAmount: new Prisma.Decimal(0), shippingAddressSameAsHomeAddress: false, shippingFullName: 'Applicant One', @@ -97,7 +97,7 @@ const applications: Array = [ postalCode: 'B1C2D3', permitType: 'PERMANENT', paymentMethod: 'CHEQUE', - processingFee: new Prisma.Decimal(26), + processingFee: new Prisma.Decimal(31), donationAmount: new Prisma.Decimal(10), shippingAddressSameAsHomeAddress: true, shippingFullName: null, @@ -154,7 +154,7 @@ const applications: Array = [ postalCode: 'B1C2D3', permitType: 'PERMANENT', paymentMethod: 'CHEQUE', - processingFee: new Prisma.Decimal(26), + processingFee: new Prisma.Decimal(31), donationAmount: new Prisma.Decimal(100), shippingAddressSameAsHomeAddress: true, shippingFullName: null, @@ -205,7 +205,7 @@ const applications: Array = [ postalCode: 'B1C2D3', permitType: 'TEMPORARY', paymentMethod: 'MASTERCARD', - processingFee: new Prisma.Decimal(26), + processingFee: new Prisma.Decimal(31), donationAmount: new Prisma.Decimal(0), shippingAddressSameAsHomeAddress: true, shippingFullName: null, @@ -279,7 +279,7 @@ const applications: Array = [ postalCode: 'A1B2C3', permitType: 'PERMANENT', paymentMethod: 'SHOPIFY', - processingFee: new Prisma.Decimal(26), + processingFee: new Prisma.Decimal(31), donationAmount: new Prisma.Decimal(20), shippingAddressSameAsHomeAddress: true, shippingFullName: null, diff --git a/tools/admin/requests/create-new.ts b/tools/admin/requests/create-new.ts index 132d133c..be516b0c 100644 --- a/tools/admin/requests/create-new.ts +++ b/tools/admin/requests/create-new.ts @@ -194,7 +194,7 @@ export const INITIAL_ADDITIONAL_QUESTIONS: AdditionalInformationFormData = { // Initial data for payment details in application forms export const INITIAL_PAYMENT_DETAILS: PaymentInformationFormData = { paymentMethod: null, - processingFee: '26', + processingFee: '31', donationAmount: '', shippingAddressSameAsHomeAddress: false, shippingFullName: '', diff --git a/tools/hooks/graphql.ts b/tools/hooks/graphql.ts index 3c05ba2d..fa491dbc 100644 --- a/tools/hooks/graphql.ts +++ b/tools/hooks/graphql.ts @@ -35,15 +35,12 @@ const useMutation = < onCompleted: data => { for (const key in data) { const result = data[key] as unknown as { ok: boolean; error?: string }; - if ('ok' in result && 'error' in result) { - if (!result.ok) { - toast({ - status: 'error', - description: result.error, - isClosable: true, - }); - } - } + if (result.ok) continue; + toast({ + status: 'error', + description: result.error, + isClosable: true, + }); } options?.onCompleted && options.onCompleted(data); }, diff --git a/yarn.lock b/yarn.lock index f28d2a5d..47d54648 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9322,10 +9322,10 @@ shelljs@0.8.4: interpret "^1.0.0" rechoir "^0.6.2" -shopify-buy@^2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/shopify-buy/-/shopify-buy-2.13.0.tgz#2f066752bd9614a92faceeb5a3f870c75f88bb32" - integrity sha512-MueiBWvQIzpCFTp+wRQF5O1N8J9a5y88mBbhLw7x4L8x1UhiMYbjPPC02jGpHml3Lm5eu11yNZYA5TsmUDJc7A== +shopify-buy@^2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/shopify-buy/-/shopify-buy-2.20.0.tgz#b6455e78c01e28b0ddca61fb0c5a15ab66720a2c" + integrity sha512-xe6VlqJtI/c8BYeH2hhOw7gZSsbHUeGFUwVyAzQOR422Ml4UXTFld0GcbW88tkR/Vgy2tj592EL2paCws2fZzQ== side-channel@^1.0.4: version "1.0.4"