diff --git a/src/leases/components/leaseSections/rent/OldDwellingsInHousingCompaniesPriceIndex.tsx b/src/leases/components/leaseSections/rent/OldDwellingsInHousingCompaniesPriceIndex.tsx new file mode 100644 index 00000000..5832f2c8 --- /dev/null +++ b/src/leases/components/leaseSections/rent/OldDwellingsInHousingCompaniesPriceIndex.tsx @@ -0,0 +1,97 @@ +import React, { Fragment, PureComponent } from 'react'; +import { Row, Column } from "react-foundation"; +import { getCurrentLeaseStartDate, getAttributes as getLeaseAttributes } from '@/leases/selectors'; +import { flowRight } from 'lodash'; +import { connect } from 'react-redux'; +import type { + OldDwellingsInHousingCompaniesPriceIndex as OldDwellingsInHousingCompaniesPriceIndexProps, + IndexPointFigureYearly as IndexPointFigureYearlyProps, +} from '@/leases/types'; +import BoxItemContainer from '@/components/content/BoxItemContainer'; +import { withWindowResize } from '@/components/resize/WindowResizeHandler'; +import FormText from "@/components/form/FormText"; +import FormTextTitle from '@/components/form/FormTextTitle'; +import { LeaseFieldTitles, LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldPaths, LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldTitles } from '@/leases/enums'; +import { getUiDataLeaseKey } from '@/uiData/helpers'; +import { formatDate } from '@/util/helpers'; + +type Props = { + oldDwellingsInHousingCompaniesPriceIndex: OldDwellingsInHousingCompaniesPriceIndexProps; + leaseStartDate: string; +}; + +const getLastYearsIndexPointNumber = (pointFigures: IndexPointFigureYearlyProps[]): string => { + const lastYear = new Date().getFullYear() - 1; + const lastYearIndex = pointFigures?.find((x: IndexPointFigureYearlyProps) => x.year == lastYear) || null; + return lastYearIndex ? `${lastYearIndex.year} * ${lastYearIndex.value}` : 'Indeksipisteluvut puuttuvat'; +} + +const getReviewDaysSorted = (pointFigures: IndexPointFigureYearlyProps[]): IndexPointFigureYearlyProps[] => { + // deep copy + const sortedNumbers = JSON.parse(JSON.stringify(pointFigures)); + + sortedNumbers.sort((a: IndexPointFigureYearlyProps, b: IndexPointFigureYearlyProps) => a.year - b.year); + return sortedNumbers; +} + +class OldDwellingsInHousingCompaniesPriceIndexView extends PureComponent { + render() { + const { + oldDwellingsInHousingCompaniesPriceIndex, + leaseStartDate + } = this.props; + const { + name, + point_figures: pointFigures, + source_table_label: sourceTableLabel + } = oldDwellingsInHousingCompaniesPriceIndex || {}; + return + + + + + {LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldTitles.NAME} + + {name} + + + + {LeaseFieldTitles.START_DATE} + + {formatDate(leaseStartDate)} + + + + {LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldTitles.NUMBERS} + + {getLastYearsIndexPointNumber(pointFigures)} + {sourceTableLabel} + + + + {LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldTitles.REVIEW_DAYS} + + <> + {pointFigures && !!pointFigures.length ? + getReviewDaysSorted(pointFigures).map( + (number: IndexPointFigureYearlyProps, index: number) => { + return + {`1.1.${number.year}`} + + } + ) + : ""} + + + + + + } +} + +export default flowRight(withWindowResize, connect(state => { + return { + leaseAttributes: getLeaseAttributes(state), + leaseStartDate: getCurrentLeaseStartDate(state) + }; +}))(OldDwellingsInHousingCompaniesPriceIndexView); \ No newline at end of file diff --git a/src/leases/components/leaseSections/rent/OldDwellingsInHousingCompaniesPriceIndexEdit.tsx b/src/leases/components/leaseSections/rent/OldDwellingsInHousingCompaniesPriceIndexEdit.tsx new file mode 100644 index 00000000..dd88a847 --- /dev/null +++ b/src/leases/components/leaseSections/rent/OldDwellingsInHousingCompaniesPriceIndexEdit.tsx @@ -0,0 +1,149 @@ +import React, { Fragment, PureComponent } from "react"; +import { Row, Column } from "react-foundation"; +import { + getCurrentLeaseStartDate, + getAttributes as getLeaseAttributes, +} from "@/leases/selectors"; +import { flowRight } from "lodash"; +import { connect } from "react-redux"; +import type { + OldDwellingsInHousingCompaniesPriceIndex as OldDwellingsInHousingCompaniesPriceIndexProps, + IndexPointFigureYearly as IndexPointFigureYearlyProps, +} from "@/leases/types"; +import BoxItemContainer from "@/components/content/BoxItemContainer"; +import { withWindowResize } from "@/components/resize/WindowResizeHandler"; +import FormText from "@/components/form/FormText"; +import FormTextTitle from "@/components/form/FormTextTitle"; +import { + LeaseFieldTitles, + LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldPaths, + LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldTitles, +} from "@/leases/enums"; +import { getUiDataLeaseKey } from "@/uiData/helpers"; +import { formatDate } from "@/util/helpers"; + +type Props = { + oldDwellingsInHousingCompaniesPriceIndex: OldDwellingsInHousingCompaniesPriceIndexProps; + leaseStartDate: string; +}; + +const getLastYearsIndexPointNumber = ( + pointFigures: IndexPointFigureYearlyProps[] +): string => { + const lastYear = new Date().getFullYear() - 1; + const lastYearIndex = + pointFigures?.find( + (x: IndexPointFigureYearlyProps) => x.year == lastYear + ) || null; + return lastYearIndex + ? `${lastYearIndex.year} * ${lastYearIndex.value}` + : "Indeksipisteluvut puuttuvat"; +}; + +const getReviewDaysSorted = ( + pointFigures: IndexPointFigureYearlyProps[] +): IndexPointFigureYearlyProps[] => { + // deep copy + const sortedNumbers = JSON.parse(JSON.stringify(pointFigures)); + + sortedNumbers.sort( + (a: IndexPointFigureYearlyProps, b: IndexPointFigureYearlyProps) => + a.year - b.year + ); + return sortedNumbers; +}; + +class OldDwellingsInHousingCompaniesPriceIndexViewEdit extends PureComponent { + render() { + const { oldDwellingsInHousingCompaniesPriceIndex, leaseStartDate } = + this.props; + + console.log("oldDwellingsInHousingCompaniesPriceIndex", oldDwellingsInHousingCompaniesPriceIndex); + + if (!oldDwellingsInHousingCompaniesPriceIndex) { + return

Lisää tasotarkistus

; + } + + const { + name, + point_figures: pointFigures, + source_table_label: sourceTableLabel, + } = oldDwellingsInHousingCompaniesPriceIndex || {}; + return ( + + + + + + { + LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldTitles.NAME + } + + {name} + + + {LeaseFieldTitles.START_DATE} + {formatDate(leaseStartDate)} + + + + { + LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldTitles.NUMBERS + } + + {getLastYearsIndexPointNumber(pointFigures)} + {sourceTableLabel} + + + + { + LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldTitles.REVIEW_DAYS + } + + <> + {pointFigures && !!pointFigures.length + ? getReviewDaysSorted(pointFigures).map( + (number: IndexPointFigureYearlyProps, index: number) => { + return ( + + {`1.1.${number.year}`} + + ); + } + ) + : ""} + + + + + + ); + } +} + +export default flowRight( + withWindowResize, + connect((state) => { + return { + leaseAttributes: getLeaseAttributes(state), + leaseStartDate: getCurrentLeaseStartDate(state), + }; + }) +)(OldDwellingsInHousingCompaniesPriceIndexViewEdit); diff --git a/src/leases/components/leaseSections/rent/RentItem.tsx b/src/leases/components/leaseSections/rent/RentItem.tsx index fc57b519..bdcc0912 100644 --- a/src/leases/components/leaseSections/rent/RentItem.tsx +++ b/src/leases/components/leaseSections/rent/RentItem.tsx @@ -20,11 +20,13 @@ import { formatDateRange, getFieldOptions, getLabelOfOption, isActive, isArchive import { getAttributes as getLeaseAttributes, getCollapseStateByKey } from "@/leases/selectors"; import type { Attributes } from "types"; import type { ServiceUnit } from "@/serviceUnits/types"; +import OldDwellingsInHousingCompaniesPriceIndexView from "./OldDwellingsInHousingCompaniesPriceIndex"; const formName = FormNames.LEASE_RENTS; type Props = { contractRentsCollapseState: boolean; equalizedRentsCollapseState: boolean; + oldDwellingsInHousingCompaniesPriceIndexCollapseState: boolean; fixedInitialYearRentsCollapseState: boolean; indexAdjustedRentsCollapseState: boolean; leaseAttributes: Attributes; @@ -40,6 +42,7 @@ type Props = { const RentItem = ({ contractRentsCollapseState, equalizedRentsCollapseState, + oldDwellingsInHousingCompaniesPriceIndexCollapseState, fixedInitialYearRentsCollapseState, indexAdjustedRentsCollapseState, leaseAttributes, @@ -94,6 +97,7 @@ const RentItem = ({ const active = isActive(rent), archived = isArchived(rent), rentType = get(rent, 'type'), + oldDwellingsInHousingCompaniesPriceIndex = get(rent, 'old_dwellings_in_housing_companies_price_index', {}), fixedInitialYearRents = get(rent, 'fixed_initial_year_rents', []), contractRents = get(rent, 'contract_rents', []), indexAdjustedRents = get(rent, 'index_adjusted_rents', []), @@ -105,6 +109,7 @@ const RentItem = ({ rentTypeIsIndex2022 = rentType === RentTypes.INDEX2022, rentTypeIsManual = rentType === RentTypes.MANUAL, rentTypeIsFixed = rentType === RentTypes.FIXED; + return {formatDateRange(rent.start_date, rent.end_date) || '-'} @@ -112,7 +117,14 @@ const RentItem = ({ } headerTitle={ {getLabelOfOption(typeOptions, rentType) || '-'} } onToggle={handleRentCollapseToggle}> - + + + + {oldDwellingsInHousingCompaniesPriceIndex && + + + } + {(rentTypeIsIndex || rentTypeIsIndex2022 || rentTypeIsManual) && @@ -152,11 +164,12 @@ const RentItem = ({ ; }; -export default connect((state, props) => { +export default connect((state, props: Props) => { const id = props.rent.id; return { contractRentsCollapseState: getCollapseStateByKey(state, `${ViewModes.READONLY}.${formName}.${id}.contract_rents`), equalizedRentsCollapseState: getCollapseStateByKey(state, `${ViewModes.READONLY}.${formName}.${id}.equalized_rents`), + oldDwellingsInHousingCompaniesPriceIndexCollapseState: getCollapseStateByKey(state, `${ViewModes.READONLY}.${formName}.${id}.old_dwellings_in_housing_companies_price_index`), fixedInitialYearRentsCollapseState: getCollapseStateByKey(state, `${ViewModes.READONLY}.${formName}.${id}.fixed_initial_year_rents`), indexAdjustedRentsCollapseState: getCollapseStateByKey(state, `${ViewModes.READONLY}.${formName}.${id}.index_adjusted_rents`), leaseAttributes: getLeaseAttributes(state), diff --git a/src/leases/components/leaseSections/rent/RentItemEdit.tsx b/src/leases/components/leaseSections/rent/RentItemEdit.tsx index e9f7edd7..249e7ed1 100644 --- a/src/leases/components/leaseSections/rent/RentItemEdit.tsx +++ b/src/leases/components/leaseSections/rent/RentItemEdit.tsx @@ -17,7 +17,7 @@ import PayableRents from "./PayableRents"; import RentAdjustmentsEdit from "./RentAdjustmentsEdit"; import { receiveCollapseStates } from "@/leases/actions"; import { FormNames, ViewModes } from "@/enums"; -import { ContractRentPeriods, LeaseRentsFieldPaths, LeaseRentFixedInitialYearRentsFieldPaths, LeaseRentFixedInitialYearRentsFieldTitles, LeaseRentContractRentsFieldPaths, LeaseRentContractRentsFieldTitles, LeaseIndexAdjustedRentsFieldPaths, LeaseIndexAdjustedRentsFieldTitles, LeaseRentAdjustmentsFieldPaths, LeaseRentAdjustmentsFieldTitles, LeasePayableRentsFieldPaths, LeasePayableRentsFieldTitles, LeaseEqualizedRentsFieldPaths, LeaseEqualizedRentsFieldTitles, RentDueDateTypes, RentTypes } from "@/leases/enums"; +import { ContractRentPeriods, LeaseRentsFieldPaths, LeaseRentFixedInitialYearRentsFieldPaths, LeaseRentFixedInitialYearRentsFieldTitles, LeaseRentContractRentsFieldPaths, LeaseRentContractRentsFieldTitles, LeaseIndexAdjustedRentsFieldPaths, LeaseIndexAdjustedRentsFieldTitles, LeaseRentAdjustmentsFieldPaths, LeaseRentAdjustmentsFieldTitles, LeasePayableRentsFieldPaths, LeasePayableRentsFieldTitles, LeaseEqualizedRentsFieldPaths, LeaseEqualizedRentsFieldTitles, RentDueDateTypes, RentTypes, LeaseRentsFieldTitles, LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldTitles } from "@/leases/enums"; import { UsersPermissions } from "@/usersPermissions/enums"; import { getUiDataLeaseKey } from "@/uiData/helpers"; import { formatDateRange, getFieldOptions, getLabelOfOption, hasPermissions, isActive, isArchived, isEmptyValue, isFieldAllowedToRead } from "@/util/helpers"; @@ -25,6 +25,7 @@ import { getAttributes as getLeaseAttributes, getCollapseStateByKey, getErrorsBy import { getUsersPermissions } from "@/usersPermissions/selectors"; import type { Attributes } from "types"; import type { UsersPermissions as UsersPermissionsType } from "@/usersPermissions/types"; +import OldDwellingsInHousingCompaniesPriceIndexEdit from "./OldDwellingsInHousingCompaniesPriceIndexEdit"; type Props = { change: (...args: Array) => any; contractRentsCollapseState: boolean; @@ -34,6 +35,7 @@ type Props = { equalizedRentsCollapseState: boolean; errors: Record | null | undefined; field: string; + oldDwellingsInHousingCompaniesPriceIndexCollapseState: boolean; fixedInitialYearRents: Array>; fixedInitialYearRentsCollapseState: boolean; index: number; @@ -194,6 +196,9 @@ class RentItemEdit extends PureComponent { handleRentCollapseToggle = (val: boolean) => { this.handleCollapseToggle('rent', val); }; + handleOldDwellingsInHousingCompaniesPriceIndexCollapseState = (val: boolean) => { + this.handleCollapseToggle('old_dwellings_in_housing_companies_price_index', val); + } handleFixedInitialYearRentsCollapseToggle = (val: boolean) => { this.handleCollapseToggle('fixed_initial_year_rents', val); }; @@ -227,6 +232,7 @@ class RentItemEdit extends PureComponent { equalizedRentsCollapseState, field, fixedInitialYearRents, + oldDwellingsInHousingCompaniesPriceIndexCollapseState, fixedInitialYearRentsCollapseState, indexAdjustedRentsCollapseState, isSaveClicked, @@ -256,6 +262,7 @@ class RentItemEdit extends PureComponent { rentTypeIsIndex2022 = rentType === RentTypes.INDEX2022, rentTypeIsManual = rentType === RentTypes.MANUAL, rentTypeIsFixed = rentType === RentTypes.FIXED; + const oldDwellingsInHousingCompaniesPriceIndex = get(savedRent, 'old_dwellings_in_housing_companies_price_index'); return {getLabelOfOption(typeOptions, get(savedRent, 'type')) || '-'} } headerSubtitles={ @@ -269,6 +276,12 @@ class RentItemEdit extends PureComponent { + + + + + + {(rentTypeIsIndex || rentTypeIsIndex2022 || rentTypeIsManual) && @@ -329,6 +342,7 @@ export default connect((state, props) => { if (id) { newProps.equalizedRentsCollapseState = getCollapseStateByKey(state, `${ViewModes.READONLY}.${formName}.${id}.equalized_rents`); + newProps.oldDwellingsInHousingCompaniesPriceIndexCollapseState = getCollapseStateByKey(state, `${ViewModes.EDIT}.${formName}.${id}.old_dwellings_in_housing_companies_price_index`); newProps.fixedInitialYearRentsCollapseState = getCollapseStateByKey(state, `${ViewModes.EDIT}.${formName}.${id}.fixed_initial_year_rents`); newProps.indexAdjustedRentsCollapseState = getCollapseStateByKey(state, `${ViewModes.EDIT}.${formName}.${id}.index_adjusted_rents`); newProps.payableRentsCollapseState = getCollapseStateByKey(state, `${ViewModes.EDIT}.${formName}.${id}.payable_rents`); diff --git a/src/leases/enums.ts b/src/leases/enums.ts index 5c5d5dfb..e9ee0456 100644 --- a/src/leases/enums.ts +++ b/src/leases/enums.ts @@ -867,7 +867,8 @@ export const LeaseRentsFieldPaths = { Y_VALUE: 'rents.child.children.y_value', YEARLY_DUE_DATES: 'rents.child.children.yearly_due_dates', Y_VALUE_START: 'rents.child.children.y_value_start', - OVERRIDE_RECEIVABLE_TYPE: 'rents.child.children.override_receivable_type' + OVERRIDE_RECEIVABLE_TYPE: 'rents.child.children.override_receivable_type', + OLD_DWELLINGS_IN_HOUSING_COMPANIES_PRICE_INDEX: 'rents.child.children.old_dwellings_in_housing_companies_price_index', }; /** @@ -922,6 +923,30 @@ export const LeaseRentDueDatesFieldTitles = { MONTH: 'Kuukausi' }; + +/** + * Lease rent old dwellings in housing companies price index field paths enumerable. + * + * @type {{}} + */ +export const LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldPaths = { + OLD_DWELLINGS_IN_HOUSING_COMPANIES_PRICE_INDEX: 'rents.child.children.old_dwellings_in_housing_companies_price_index', + NAME: 'rents.child.children.old_dwellings_in_housing_companies_price_index.name', + NUMBERS: 'rents.child.children.old_dwellings_in_housing_companies_price_index.numbers', +}; + +/** + * Lease rent old dwellings in housing companies price index field titles enumerable. + * + * @type {{}} + */ +export const LeaseRentOldDwellingsInHousingCompaniesPriceIndexFieldTitles = { + OLD_DWELLINGS_IN_HOUSING_COMPANIES_PRICE_INDEX: 'Tasotarkistus', + NAME: 'Tyyppi', + NUMBERS: 'Indeksipisteluku', + REVIEW_DAYS: 'Tarkistuspäivät', +}; + /** * Lease rent fixed initial year rents field paths enumerable. * diff --git a/src/leases/helpers.ts b/src/leases/helpers.ts index de715715..47d7d4fd 100644 --- a/src/leases/helpers.ts +++ b/src/leases/helpers.ts @@ -1638,6 +1638,7 @@ export const getContentRents = (lease: Record): Array | null | undefi return get(state.lease.collapseStates, key); }; export const getLeasesForContractNumbers: Selector = (state: RootState): LeaseList => state.lease.leasesForContractNumbers; -export const getIsFetchingLeasesForContractNumbers: Selector = (state: RootState): boolean => state.lease.isFetchingLeasesForContractNumbers; \ No newline at end of file +export const getIsFetchingLeasesForContractNumbers: Selector = (state: RootState): boolean => state.lease.isFetchingLeasesForContractNumbers; + +// Selectors for lease attributes +export const getCurrentLeaseStartDate: Selector = (state: RootState): string => get(state.lease.current, 'start_date', ''); \ No newline at end of file diff --git a/src/leases/types.ts b/src/leases/types.ts index ccf6e339..761bb4bd 100644 --- a/src/leases/types.ts +++ b/src/leases/types.ts @@ -1,5 +1,6 @@ import type { Action, ApiResponse, Attributes, Methods } from "@/types"; import type { ServiceUnit } from "@/serviceUnits/types"; + export type LeaseState = { attributes: Attributes; byId: Record; @@ -11,7 +12,7 @@ export type LeaseState = { isEditMode: boolean; isFetching: boolean; isFetchingByBBox: boolean; - isFetchingById: {}; + isFetchingById: Record; isFetchingAttributes: boolean; isSaveClicked: boolean; isSaving: boolean; @@ -49,6 +50,22 @@ export type IntendedUse = { name: string; service_unit: ServiceUnit["id"]; }; +export type IndexPointFigureYearly = { + value: number; + year: number; + region: string; + comment: string; +} +export type OldDwellingsInHousingCompaniesPriceIndex = { + code: string; + name: string; + comment: string; + source: string; + source_table_updated?: string; + source_table_label: string; + url: string; + point_figures: IndexPointFigureYearly[]; +} export type FetchAttributesAction = Action; export type ReceiveAttributesAction = Action; export type ReceiveMethodsAction = Action;