Skip to content

Commit

Permalink
Merge pull request #4187 from stairaku/PSP-8317
Browse files Browse the repository at this point in the history
PSP-8317: Lease and Licence Edit/View Fee Denomination forms
  • Loading branch information
stairaku authored Jul 12, 2024
2 parents f885901 + 4c7f370 commit bf8d31a
Show file tree
Hide file tree
Showing 16 changed files with 1,192 additions and 0 deletions.
6 changes: 6 additions & 0 deletions source/backend/apimodels/Models/Concepts/Lease/LeaseMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.FileChecklistItems, src => src.PimsLeaseChecklistItems)
.Map(dest => dest.PrimaryArbitrationCity, src => src.PrimaryArbitrationCity)
.Map(dest => dest.Periods, src => src.PimsLeasePeriods)
.Map(dest => dest.IsPublicBenefit, src => src.IsPublicBenefit)
.Map(dest => dest.IsFinancialGain, src => src.IsFinancialGain)
.Map(dest => dest.FeeDeterminationNote, src => src.FeeDeterminationNote)
.Map(dest => dest.Renewals, src => src.PimsLeaseRenewals);

config.NewConfig<LeaseModel, PimsLease>()
Expand Down Expand Up @@ -104,6 +107,9 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.PimsLeaseChecklistItems, src => src.FileChecklistItems)
.Map(dest => dest.PrimaryArbitrationCity, src => src.PrimaryArbitrationCity)
.Map(dest => dest.ProjectId, src => src.Project != null ? src.Project.Id : (long?)null)
.Map(dest => dest.IsPublicBenefit, src => src.IsPublicBenefit)
.Map(dest => dest.IsFinancialGain, src => src.IsFinancialGain)
.Map(dest => dest.FeeDeterminationNote, src => src.FeeDeterminationNote)
.Map(dest => dest.PimsLeaseRenewals, src => src.Renewals)
.IgnoreNullValues(true);
}
Expand Down
15 changes: 15 additions & 0 deletions source/backend/apimodels/Models/Concepts/Lease/LeaseModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,21 @@ public class LeaseModel : FileWithChecklistModel
/// get/set - The project associated with this lease.
/// </summary>
public ProjectModel Project { get; set; }

/// <summary>
/// get/set - is public benefit.
/// </summary>
public bool? IsPublicBenefit { get; set; }

/// <summary>
/// get/set is financial gain.
/// </summary>
public bool? IsFinancialGain { get; set; }

/// <summary>
/// get/set - fee determination notes.
/// </summary>
public string FeeDeterminationNote { get; set; }
#endregion
}
}
3 changes: 3 additions & 0 deletions source/frontend/src/features/leases/add/AddLeaseYupSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ export const AddLeaseYupSchema = Yup.object().shape({
primaryArbitrationCity: Yup.string()
.nullable()
.max(200, 'Primary arbitration city must be at most ${max} characters'),
feeDeterminationNote: Yup.string()
.nullable()
.max(1000, 'Fee determination notes must be at most ${max} characters'),
renewals: Yup.array().of(
Yup.object().shape({
renewalNote: Yup.string().max(2000, 'Renewal note must be at most ${max} characters'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { act, getByText, render, RenderOptions } from '@testing-library/react';
import { getDefaultFormLease, LeaseFormModel } from '../models';
import { AddLeaseYupSchema } from './AddLeaseYupSchema';
import { createMemoryHistory } from 'history';
import FeeDeterminationSubForm, { IFeeDeterminationSubFormProps } from './FeeDeterminationSubForm';
import { Formik, FormikProps } from 'formik';
import React from 'react';
import { noop } from 'lodash';
import { fillInput, renderAsync } from '@/utils/test-utils';
import { lookupCodesSlice } from '@/store/slices/lookupCodes';
import { mockLookups } from '@/mocks/lookups.mock';
import { Simulate } from 'react-dom/test-utils';

const history = createMemoryHistory();
const storeState = {
[lookupCodesSlice.name]: { lookupCodes: mockLookups },
};

describe('LeaseFeeDeterminationSubForm component', () => {
const setup = async (
renderOptions: RenderOptions & Partial<IFeeDeterminationSubFormProps> = {},
) => {
// render component under test
const component = await renderAsync(
<Formik onSubmit={noop} initialValues={getDefaultFormLease()}>
{formikProps => <FeeDeterminationSubForm formikProps={formikProps} />}
</Formik>,
{
...renderOptions,
claims: [],
store: storeState,
history,
},
);

return {
component,
};
};
it('renders as expected', async () => {
const { component } = await setup({});
expect(component.asFragment()).toMatchSnapshot();
});

it('displays expected Nominal fee', async () => {
const {
component: { container },
} = await setup({});

let suggestedFeeField = await container.querySelector("span[data-testid='suggestedFee']");

expect(suggestedFeeField).toHaveTextContent('Unknown');

await act(async () => {
await fillInput(container, 'isPublicBenefit', 'true', 'select');
await fillInput(container, 'isFinancialGain', 'false', 'select');
});

expect(suggestedFeeField).toHaveTextContent('$1 - Nominal');
});

it('displays expected LAF fee', async () => {
const {
component: { container },
} = await setup({});

let suggestedFeeField = await container.querySelector("span[data-testid='suggestedFee']");

expect(suggestedFeeField).toHaveTextContent('Unknown');

await act(async () => {
await fillInput(container, 'isPublicBenefit', 'true', 'select');
await fillInput(container, 'isFinancialGain', 'true', 'select');
});

expect(suggestedFeeField).toHaveTextContent('Licence Administration Fee (LAF) *');
});

it('displays expected FMV fee', async () => {
const {
component: { container },
} = await setup({});

let suggestedFeeField = await container.querySelector("span[data-testid='suggestedFee']");

expect(suggestedFeeField).toHaveTextContent('Unknown');

await act(async () => {
await fillInput(container, 'isPublicBenefit', 'false', 'select');
await fillInput(container, 'isFinancialGain', 'true', 'select');
});

expect(suggestedFeeField).toHaveTextContent('Fair Market Value (FMV) - (Licence Administration Fee Minimum)');
});

it('displays expected LAF fee', async () => {
const {
component: { container },
} = await setup({});

let suggestedFeeField = await container.querySelector("span[data-testid='suggestedFee']");

expect(suggestedFeeField).toHaveTextContent('Unknown');

await act(async () => {
await fillInput(container, 'isPublicBenefit', 'true', 'select');
await fillInput(container, 'isFinancialGain', 'true', 'select');
});

expect(suggestedFeeField).toHaveTextContent('Licence Administration Fee (LAF) *');
});

it('displays expected LAF fee', async () => {
const {
component: { container },
} = await setup({});

let suggestedFeeField = await container.querySelector("span[data-testid='suggestedFee']");

expect(suggestedFeeField).toHaveTextContent('Unknown');

await act(async () => {
await fillInput(container, 'isPublicBenefit', 'true', 'select');
await fillInput(container, 'isFinancialGain', 'true', 'select');
});

expect(suggestedFeeField).toHaveTextContent('Licence Administration Fee (LAF) *');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { FormikProps, getIn } from 'formik';
import { useEffect, useState } from 'react';

import { TextArea } from '@/components/common/form';
import { InlineYesNoSelect } from '@/components/common/form/styles';
import { Section } from '@/components/common/Section/Section';
import { SectionField } from '@/components/common/Section/SectionField';

import { getSuggestedFee } from '../leaseUtils';
import { LeaseFormModel } from '../models';

export interface IFeeDeterminationSubFormProps {
formikProps: FormikProps<LeaseFormModel>;
}

const FeeDeterminationSubForm: React.FunctionComponent<IFeeDeterminationSubFormProps> = ({
formikProps,
}) => {
const { values } = formikProps;
const isPublicBenefit = getIn(values, 'isPublicBenefit');
const financialGain = getIn(values, 'isFinancialGain');

const [fee, setFee] = useState('');

useEffect(() => {
setFee(getSuggestedFee(isPublicBenefit, financialGain));
}, [isPublicBenefit, financialGain]);

return (
<Section header="Fee Determination">
<SectionField label="Public benefit" labelWidth="2" contentWidth="8">
<InlineYesNoSelect field="isPublicBenefit" />
</SectionField>

<SectionField label="Financial gain" labelWidth="2" contentWidth="8">
<InlineYesNoSelect field="isFinancialGain" />
</SectionField>

<SectionField
label="Sugested fee"
tooltip="Licence Administration Fee (LAF) *: If the financial gain far outweighs the public benefit, Fair Market Value should be considered over Licence Administration Fee."
labelWidth="2"
contentWidth="8"
>
<span data-testid="suggestedFee">{fee}</span>
</SectionField>

<SectionField
label="Notes"
tooltip="Deviations from standard fees should be explained here"
labelWidth="2"
contentWidth="8"
>
<TextArea field="feeDeterminationNote" />
</SectionField>
</Section>
);
};

export default FeeDeterminationSubForm;
Loading

0 comments on commit bf8d31a

Please sign in to comment.