diff --git a/source/backend/api/Areas/DocumentGeneration/DocumentGenerationRequest.cs b/source/backend/api/Areas/DocumentGeneration/DocumentGenerationRequest.cs index 6fcc9b93f1..c719f22e2d 100644 --- a/source/backend/api/Areas/DocumentGeneration/DocumentGenerationRequest.cs +++ b/source/backend/api/Areas/DocumentGeneration/DocumentGenerationRequest.cs @@ -17,7 +17,7 @@ public class DocumentGenerationRequest /// /// get/set - The template type to use for generation. /// - public FormDocumentType TemplateType { get; set; } + public FormTypes TemplateType { get; set; } /// /// get/set - the type the document template should be converted to when returned from cdogs. diff --git a/source/backend/api/Services/DocumentGenerationService.cs b/source/backend/api/Services/DocumentGenerationService.cs index 42d80d71f8..807caa3cab 100644 --- a/source/backend/api/Services/DocumentGenerationService.cs +++ b/source/backend/api/Services/DocumentGenerationService.cs @@ -68,7 +68,7 @@ public async Task> UploadFileTemplate(IFormFile fileRaw return result; } - public async Task> GenerateDocument(FormDocumentType templateType, JsonElement templateData, ConvertToTypes? convertTo) + public async Task> GenerateDocument(FormTypes templateType, JsonElement templateData, ConvertToTypes? convertTo) { this.Logger.LogInformation("Generating document"); diff --git a/source/backend/api/Services/IDocumentGenerationService.cs b/source/backend/api/Services/IDocumentGenerationService.cs index 7209e67e8e..1704eafee4 100644 --- a/source/backend/api/Services/IDocumentGenerationService.cs +++ b/source/backend/api/Services/IDocumentGenerationService.cs @@ -17,6 +17,6 @@ public interface IDocumentGenerationService Task> UploadFileTemplate(IFormFile fileRaw); - Task> GenerateDocument(FormDocumentType templateType, JsonElement templateData, ConvertToTypes? convertTo); + Task> GenerateDocument(FormTypes templateType, JsonElement templateData, ConvertToTypes? convertTo); } } diff --git a/source/backend/apimodels/CodeTypes/FormDocumentType.cs b/source/backend/apimodels/CodeTypes/FormTypes.cs similarity index 62% rename from source/backend/apimodels/CodeTypes/FormDocumentType.cs rename to source/backend/apimodels/CodeTypes/FormTypes.cs index 165c9098ed..0c1d089fa1 100644 --- a/source/backend/apimodels/CodeTypes/FormDocumentType.cs +++ b/source/backend/apimodels/CodeTypes/FormTypes.cs @@ -3,55 +3,49 @@ namespace Pims.Api.Models.CodeTypes { + /// + /// [PIMS_FORM_TYPE] table. + /// [JsonConverter(typeof(JsonStringEnumMemberConverter))] - public enum FormDocumentType + public enum FormTypes { - // Payment requisition (H120) - [EnumMember(Value = "H120")] - H120, - - // Offer agreement - Section 3 (H179 A) - [EnumMember(Value = "H179A")] - H179A, - - // Offer agreement - Partial (H179 P) - [EnumMember(Value = "H179P")] - H179P, - - // Offer agreement - Total (H179 T) - [EnumMember(Value = "H179T")] - H179T, - - // Letter - [EnumMember(Value = "LETTER")] - LETTER, - - // Conditions of Entry (H0443) - [EnumMember(Value = "H0443")] - H0443, - - // License of Occupation (H0074) - [EnumMember(Value = "H0074")] - H0074, - - // Notice of Expropriation (Form 1) [EnumMember(Value = "FORM1")] FORM1, - // Certificate of Approval of Expropriation (Form 5) [EnumMember(Value = "FORM5")] FORM5, - // Notice of Advance Payment (Form 8) [EnumMember(Value = "FORM8")] FORM8, - // Vesting Notice (Form 9) [EnumMember(Value = "FORM9")] FORM9, - // H1005A + [EnumMember(Value = "H0074")] + H0074, + + [EnumMember(Value = "H0443")] + H0443, + [EnumMember(Value = "H1005A")] H1005A, + + [EnumMember(Value = "H1005")] + H1005, + + [EnumMember(Value = "H120")] + H120, + + [EnumMember(Value = "H179A")] + H179A, + + [EnumMember(Value = "H179P")] + H179P, + + [EnumMember(Value = "H179T")] + H179T, + + [EnumMember(Value = "LETTER")] + LETTER, } } diff --git a/source/backend/apimodels/CodeTypes/LeaseLicenceTypes.cs b/source/backend/apimodels/CodeTypes/LeaseLicenceTypes.cs new file mode 100644 index 0000000000..1a27c4e74b --- /dev/null +++ b/source/backend/apimodels/CodeTypes/LeaseLicenceTypes.cs @@ -0,0 +1,51 @@ +using System.Runtime.Serialization; +using System.Text.Json.Serialization; + +namespace Pims.Api.Models.CodeTypes +{ + [JsonConverter(typeof(JsonStringEnumMemberConverter))] + public enum LeaseLicenceTypes + { + [EnumMember(Value = "LICONSTRC")] + LICONSTRC, + + [EnumMember(Value = "LIMOTIPRJ")] + LIMOTIPRJ, + + [EnumMember(Value = "LIOCCACCS")] + LIOCCACCS, + + [EnumMember(Value = "LIOCCTTLD")] + LIOCCTTLD, + + [EnumMember(Value = "LIOCCUSE")] + LIOCCUSE, + + [EnumMember(Value = "LIOCCUTIL")] + LIOCCUTIL, + + [EnumMember(Value = "LIPPUBHWY")] + LIPPUBHWY, + + [EnumMember(Value = "LSGRND")] + LSGRND, + + [EnumMember(Value = "LSREG")] + LSREG, + + [EnumMember(Value = "LSUNREG")] + LSUNREG, + + [EnumMember(Value = "MANUFHOME")] + MANUFHOME, + + [EnumMember(Value = "OTHER")] + OTHER, + + [EnumMember(Value = "RESLNDTEN")] + RESLNDTEN, + + [EnumMember(Value = "ROADXING")] + ROADXING, + } +} diff --git a/source/frontend/src/features/leases/detail/LeasePages/payment/TermPaymentsContainer.tsx b/source/frontend/src/features/leases/detail/LeasePages/payment/TermPaymentsContainer.tsx index ad44025a4c..6d92f8b4f9 100644 --- a/source/frontend/src/features/leases/detail/LeasePages/payment/TermPaymentsContainer.tsx +++ b/source/frontend/src/features/leases/detail/LeasePages/payment/TermPaymentsContainer.tsx @@ -8,7 +8,7 @@ import LoadingBackdrop from '@/components/common/LoadingBackdrop'; import { ModalContext } from '@/contexts/modalContext'; import { LeaseStateContext } from '@/features/leases/context/LeaseContext'; import { LeaseFormModel } from '@/features/leases/models'; -import { useGenerateH1005a } from '@/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateH1005a'; +import { useGenerateLicenceOfOccupation } from '@/features/mapSideBar/acquisition/common/GenerateForm/hooks/useGenerateLicenceOfOccupation'; import { LeasePageProps } from '@/features/mapSideBar/lease/LeaseContainer'; import { useLeasePaymentRepository } from '@/hooks/repositories/useLeasePaymentRepository'; import { useLeaseTermRepository } from '@/hooks/repositories/useLeaseTermRepository'; @@ -30,7 +30,7 @@ export const TermPaymentsContainer: React.FunctionComponent< React.PropsWithChildren > = ({ formikRef, onSuccess }) => { const { lease } = useContext(LeaseStateContext); - const generateH1005a = useGenerateH1005a(); + const generateH1005a = useGenerateLicenceOfOccupation(); const [editModalValues, setEditModalValues] = useState(undefined); const [editPaymentModalValues, setEditPaymentModalValues] = useState< FormLeasePayment | undefined diff --git a/source/frontend/src/features/leases/detail/LeasePages/payment/TermsPaymentsContainer.test.tsx b/source/frontend/src/features/leases/detail/LeasePages/payment/TermsPaymentsContainer.test.tsx index 531b486b07..2381d2232b 100644 --- a/source/frontend/src/features/leases/detail/LeasePages/payment/TermsPaymentsContainer.test.tsx +++ b/source/frontend/src/features/leases/detail/LeasePages/payment/TermsPaymentsContainer.test.tsx @@ -21,9 +21,6 @@ import { screen, userEvent, waitFor, - prettyDOM, - waitForElementToBeRemoved, - getByTestId, } from '@/utils/test-utils'; import { defaultFormLeaseTerm, FormLeaseTerm } from './models'; @@ -123,12 +120,14 @@ describe('TermsPaymentsContainer component', () => { beforeEach(() => { mockAxios.resetHistory(); }); + it('renders as expected', async () => { const { component } = await setup({ claims: [Claims.LEASE_EDIT] }); await act(async () => {}); expect(component.asFragment()).toMatchSnapshot(); }); + it('renders with data as expected', async () => { const { component } = await setup({ claims: [Claims.LEASE_EDIT], @@ -152,6 +151,7 @@ describe('TermsPaymentsContainer component', () => { expect(getByDisplayValue('Jan 01, 2020')).toBeVisible(); }); + it('makes a post request when adding a new term', async () => { const { component: { getAllByText, getByText }, @@ -282,10 +282,12 @@ describe('TermsPaymentsContainer component', () => { expect(useLeaseTermRepository().deleteLeaseTerm.execute).toHaveBeenCalled(); }); }); + describe('payments logic tests', () => { mockGetLeaseTerms.execute.mockResolvedValue( defaultLeaseWithTermsPayments.terms.map(t => FormLeaseTerm.toApi(t)), ); + it('makes a post request when adding a new payment', async () => { mockGetLeaseTerms.execute.mockResolvedValue( (mockGetLeaseTerms.response = defaultLeaseWithTermsPayments.terms.map(t => @@ -339,6 +341,7 @@ describe('TermsPaymentsContainer component', () => { await act(async () => userEvent.click(saveButton)); expect(mockAxios.history.put.length).toBe(1); }); + it('asks for confirmation when deleting a payment', async () => { mockGetLeaseTerms.execute.mockResolvedValue( (mockGetLeaseTerms.response = defaultLeaseWithTermsPayments.terms.map(t => diff --git a/source/frontend/src/features/leases/detail/LeasePages/payment/table/terms/TermsForm.test.tsx b/source/frontend/src/features/leases/detail/LeasePages/payment/table/terms/TermsForm.test.tsx index 4b190c846b..e8bef3826c 100644 --- a/source/frontend/src/features/leases/detail/LeasePages/payment/table/terms/TermsForm.test.tsx +++ b/source/frontend/src/features/leases/detail/LeasePages/payment/table/terms/TermsForm.test.tsx @@ -18,6 +18,7 @@ import { import { defaultFormLeaseTerm, FormLeasePayment } from '../../models'; import TermsForm, { ITermsFormProps } from './TermsForm'; import { createRef } from 'react'; +import { ApiGen_CodeTypes_LeaseLicenceTypes } from '@/models/api/generated/ApiGen_CodeTypes_LeaseLicenceTypes'; const history = createMemoryHistory(); const mockAxios = new MockAdapter(axios); @@ -111,6 +112,7 @@ describe('TermsForm component', () => { expect(component.asFragment()).toMatchSnapshot(); }); + test.each([ ['ANNUAL', '$1,000.00', '$1,050.00'], ['SEMIANN', '$1,000.00', '$2,100.00'], @@ -135,6 +137,7 @@ describe('TermsForm component', () => { expect(findCell(row, 8)?.textContent).toBe(total); }, ); + it('Does not display certain fields if the end date is not supplied', async () => { const { findFirstRow, findCell } = await setup({ store: undefined, @@ -462,13 +465,13 @@ describe('TermsForm component', () => { expect(findCell(row, 11)?.textContent).toContain('Generate H1005(a)'); }); - it('calls onGenerate when generation button is clicked', async () => { + it('calls onGenerate H1005A when generation button is clicked', async () => { const { component: { queryAllByTitle }, } = await setup({ initialValues: { ...new LeaseFormModel(), - leaseTypeCode: 'LIOCCUTIL', + leaseTypeCode: ApiGen_CodeTypes_LeaseLicenceTypes.LIOCCUTIL, terms: [ { ...defaultTestFormLeaseTerm, @@ -485,4 +488,28 @@ describe('TermsForm component', () => { await act(async () => userEvent.click(generateButton)); expect(onGenerate).toHaveBeenCalled(); }); + + it('calls onGenerate H1005 when generation button is clicked', async () => { + const { + component: { queryAllByTitle }, + } = await setup({ + initialValues: { + ...new LeaseFormModel(), + leaseTypeCode: ApiGen_CodeTypes_LeaseLicenceTypes.LIPPUBHWY, + terms: [ + { + ...defaultTestFormLeaseTerm, + isTermExercised: false, + payments: [{ amountTotal: 1, receivedDate: '2020-01-01T18:00' }] as FormLeasePayment[], + }, + ], + }, + }); + + const generateButton = queryAllByTitle('Generate H1005')[0]; + expect(generateButton).toBeVisible(); + + await act(async () => userEvent.click(generateButton)); + expect(onGenerate).toHaveBeenCalled(); + }); }); diff --git a/source/frontend/src/features/leases/detail/LeasePages/payment/table/terms/columns.tsx b/source/frontend/src/features/leases/detail/LeasePages/payment/table/terms/columns.tsx index 2f087cc56a..250c0c1e71 100644 --- a/source/frontend/src/features/leases/detail/LeasePages/payment/table/terms/columns.tsx +++ b/source/frontend/src/features/leases/detail/LeasePages/payment/table/terms/columns.tsx @@ -16,6 +16,7 @@ import { import { Claims } from '@/constants'; import { LeaseTermStatusTypes } from '@/constants/leaseStatusTypes'; import useKeycloakWrapper from '@/hooks/useKeycloakWrapper'; +import { ApiGen_CodeTypes_LeaseLicenceTypes } from '@/models/api/generated/ApiGen_CodeTypes_LeaseLicenceTypes'; import { ISystemConstant } from '@/store/slices/systemConstants'; import { NumberFieldValue } from '@/typings/NumberFieldValue'; import { prettyFormatDate } from '@/utils'; @@ -123,13 +124,28 @@ const termActions = ( {hasClaim(Claims.LEASE_VIEW) && index === 0 && !!leaseTypeCode && - ['LIOCCACCS', 'LIOCCTTLD', 'LIOCCUSE', 'LIOCCUTIL'].includes(leaseTypeCode) && ( + [ + ApiGen_CodeTypes_LeaseLicenceTypes.LIOCCACCS.toString(), + ApiGen_CodeTypes_LeaseLicenceTypes.LIOCCTTLD.toString(), + ApiGen_CodeTypes_LeaseLicenceTypes.LIOCCUSE.toString(), + ApiGen_CodeTypes_LeaseLicenceTypes.LIOCCUTIL.toString(), + ].includes(leaseTypeCode) && ( )} + + {hasClaim(Claims.LEASE_VIEW) && + index === 0 && + leaseTypeCode === ApiGen_CodeTypes_LeaseLicenceTypes.LIPPUBHWY.toString() && ( + + )} {hasClaim(Claims.LEASE_EDIT) && (