diff --git a/src/config/sidebarMenu.js b/src/config/sidebarMenu.js index 84fece5ab..bf82e5fe2 100644 --- a/src/config/sidebarMenu.js +++ b/src/config/sidebarMenu.js @@ -641,6 +641,10 @@ export default [ ability: ReportsAction.READ_AP_AGING_SUMMARY, }, }, + { + text: , + href: '/financial-reports/realized-gain-loss', + }, { text: , label: true, diff --git a/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLoss.js b/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLoss.js new file mode 100644 index 000000000..529f2a376 --- /dev/null +++ b/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLoss.js @@ -0,0 +1,67 @@ +import React from 'react'; + +import { FinancialStatement } from 'components'; + +import DashboardPageContent from 'components/Dashboard/DashboardPageContent'; + +import RealizedGainOrLossHeader from './RealizedGainOrLossHeader'; +import RealizedGainOrLossTable from './RealizedGainOrLossTable'; +import RealizedGainOrLossActionsBar from './RealizedGainOrLossActionsBar'; + +import withCurrentOrganization from '../../Organization/withCurrentOrganization'; +import withRealizedGainOrLossActions from './withRealizedGainOrLossActions'; +import { RealizedGainOrLossProvider } from './RealizedGainOrLossProvider'; +import { RealizedGainOrLossLoadingBar } from './components'; + +import { compose } from 'utils'; + +/** + * Realized Gain or Loss. + */ +function RealizedGainOrLoss({ + // #withPreferences + organizationName, + + //#withRealizedGainOrLossActions + toggleRealizedGainOrLossFilterDrawer, +}) { + // Handle refetch realized Gain or Loss after filter change. + const handleFilterSubmit = (filter) => {}; + + // Handle format number submit. + const handleNumberFormatSubmit = (values) => {}; + + React.useEffect( + () => () => { + toggleRealizedGainOrLossFilterDrawer(false); + }, + [toggleRealizedGainOrLossFilterDrawer], + ); + + return ( + + + + + + + + +
+ +
+
+
+
+ ); +} + +export default compose( + withCurrentOrganization(({ organization }) => ({ + organizationName: organization.name, + })), + withRealizedGainOrLossActions, +)(RealizedGainOrLoss); diff --git a/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLossActionsBar.js b/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLossActionsBar.js new file mode 100644 index 000000000..4b9ca3c9e --- /dev/null +++ b/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLossActionsBar.js @@ -0,0 +1,122 @@ +import React from 'react'; +import { + NavbarGroup, + NavbarDivider, + Button, + Classes, + Popover, + PopoverInteractionKind, + Position, +} from '@blueprintjs/core'; +import { FormattedMessage as T, Icon } from 'components'; +import classNames from 'classnames'; + +import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; +import NumberFormatDropdown from 'components/NumberFormatDropdown'; + +import { useRealizedGainOrLossContext } from './RealizedGainOrLossProvider'; +import withRealizedGainOrLoss from './withRealizedGainOrLoss'; +import withRealizedGainOrLossActions from './withRealizedGainOrLossActions'; + +import { compose, saveInvoke } from 'utils'; + +/** + * Realized Gain or Loss actions bar. + */ +function RealizedGainOrLossActionsBar({ + //#withRealizedGainOrLoss + isFilterDrawerOpen, + + //#withRealizedGainOrLossActions + toggleRealizedGainOrLossFilterDrawer, + + //#ownProps + numberFormat, + onNumberFormatSubmit, +}) { + // Handle filter toggle click. + const handleFilterToggleClick = () => { + toggleRealizedGainOrLossFilterDrawer(); + }; + + // Handle recalculate report button. + const handleRecalculateReport = () => {}; + + // handle number format form submit. + const handleNumberFormatSubmit = (values) => + saveInvoke(onNumberFormatSubmit, values); + + return ( + + + + + + + + + ); +} + +export default compose( + withRealizedGainOrLoss(({ realizedGainOrLossDrawerFilter }) => ({ + isFilterDrawerOpen: realizedGainOrLossDrawerFilter, + })), + withRealizedGainOrLossActions, +)(RealizedGainOrLossHeader); diff --git a/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLossProvider.js b/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLossProvider.js new file mode 100644 index 000000000..0c8fb18fc --- /dev/null +++ b/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLossProvider.js @@ -0,0 +1,22 @@ +import React from 'react'; +import FinancialReportPage from '../FinancialReportPage'; + +const RealizedGainOrLossContext = React.createContext(); + +/** + * Realized Gain or Loss provider. + */ +function RealizedGainOrLossProvider({ filter, ...props }) { + const provider = {}; + + return ( + + + + ); +} + +const useRealizedGainOrLossContext = () => + React.useContext(RealizedGainOrLossContext); + +export { RealizedGainOrLossProvider, useRealizedGainOrLossContext }; diff --git a/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLossTable.js b/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLossTable.js new file mode 100644 index 000000000..426a0997a --- /dev/null +++ b/src/containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLossTable.js @@ -0,0 +1,21 @@ +import React from 'react'; +import intl from 'react-intl-universal'; + +import { DataTable } from 'components'; +import FinancialSheet from 'components/FinancialSheet'; + +/** + * Realized Gain or Loss table. + */ +export default function RealizedGainOrLossTable({ + // #ownProps + companyName, +}) { + return ( + + ); +} diff --git a/src/containers/FinancialStatements/RealizedGainOrLoss/components.js b/src/containers/FinancialStatements/RealizedGainOrLoss/components.js new file mode 100644 index 000000000..217b440de --- /dev/null +++ b/src/containers/FinancialStatements/RealizedGainOrLoss/components.js @@ -0,0 +1,18 @@ +import React from 'react'; +import { Button } from '@blueprintjs/core'; +import { Icon, If } from 'components'; +import { FormattedMessage as T } from 'components'; + +import { useRealizedGainOrLossContext } from './RealizedGainOrLossProvider'; +import FinancialLoadingBar from '../FinancialLoadingBar'; + +/** + * Realized Gain or Loss loading bar. + */ +export function RealizedGainOrLossLoadingBar() { + return ( + + + + ); +} diff --git a/src/containers/FinancialStatements/RealizedGainOrLoss/withRealizedGainOrLoss.js b/src/containers/FinancialStatements/RealizedGainOrLoss/withRealizedGainOrLoss.js new file mode 100644 index 000000000..5f923884a --- /dev/null +++ b/src/containers/FinancialStatements/RealizedGainOrLoss/withRealizedGainOrLoss.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux'; +import { getRealizedGainOrLossFilterDrawer } from '../../../store/financialStatement/financialStatements.selectors'; + +export default (mapState) => { + const mapStateToProps = (state, props) => { + const mapped = { + realizedGainOrLossDrawerFilter: getRealizedGainOrLossFilterDrawer(state), + }; + return mapState ? mapState(mapped, state, props) : mapped; + }; + return connect(mapStateToProps); +}; diff --git a/src/containers/FinancialStatements/RealizedGainOrLoss/withRealizedGainOrLossActions.js b/src/containers/FinancialStatements/RealizedGainOrLoss/withRealizedGainOrLossActions.js new file mode 100644 index 000000000..95feefac5 --- /dev/null +++ b/src/containers/FinancialStatements/RealizedGainOrLoss/withRealizedGainOrLossActions.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; +import { toggleRealizedGainOrLossFilterDrawer } from '../../../store/financialStatement/financialStatements.actions'; + +const mapDispatchToProps = (dispatch) => ({ + toggleRealizedGainOrLossFilterDrawer: (toggle) => + dispatch(toggleRealizedGainOrLossFilterDrawer(toggle)), +}); + +export default connect(null, mapDispatchToProps); diff --git a/src/hooks/query/types.js b/src/hooks/query/types.js index dd3f7d3e4..cad5be4d3 100644 --- a/src/hooks/query/types.js +++ b/src/hooks/query/types.js @@ -24,6 +24,7 @@ const FINANCIAL_REPORTS = { CASH_FLOW_STATEMENT: 'CASH_FLOW_STATEMENT', INVENTORY_ITEM_DETAILS: 'INVENTORY_ITEM_DETAILS', TRANSACTIONS_BY_REFERENCE: 'TRANSACTIONS_BY_REFERENCE', + REALIZED_GAIN_OR_LOSS: 'REALIZED_GAIN_OR_LOSS', }; const BILLS = { @@ -196,7 +197,6 @@ const WAREHOUSES = { WAREHOUSE: 'WAREHOUSE', WAREHOUSES: 'WAREHOUSES', }; - const WAREHOUSE_TRANSFERS = { WAREHOUSE_TRANSFER: 'WAREHOUSE_TRANSFER', WAREHOUSE_TRANSFERS: 'WAREHOUSE_TRANSFERS', diff --git a/src/routes/dashboard.js b/src/routes/dashboard.js index 8877b2396..866c6d30a 100644 --- a/src/routes/dashboard.js +++ b/src/routes/dashboard.js @@ -376,6 +376,20 @@ export const getDashboardRoutes = () => [ sidebarExpand: false, subscriptionActive: [SUBSCRIPTION_TYPE.MAIN], }, + { + path: `/financial-reports/realized-gain-loss`, + component: lazy(() => + import( + '../containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLoss' + ), + ), + + breadcrumb: intl.get('realized_gain_or_loss.label'), + pageTitle: intl.get('realized_gain_or_loss.label'), + backLink: true, + sidebarExpand: false, + subscriptionActive: [SUBSCRIPTION_TYPE.MAIN], + }, { path: '/financial-reports', component: lazy(() => diff --git a/src/store/financialStatement/financialStatements.actions.js b/src/store/financialStatement/financialStatements.actions.js index 0ef8f9a41..b1229fd9e 100644 --- a/src/store/financialStatement/financialStatements.actions.js +++ b/src/store/financialStatement/financialStatements.actions.js @@ -196,7 +196,7 @@ export function toggleCashFlowStatementFilterDrawer(toggle) { * Toggles display of the inventory item details filter drawer. * @param {boolean} toggle */ - export function toggleInventoryItemDetailsFilterDrawer(toggle) { +export function toggleInventoryItemDetailsFilterDrawer(toggle) { return { type: `${t.INVENTORY_ITEM_DETAILS}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`, payload: { @@ -204,3 +204,16 @@ export function toggleCashFlowStatementFilterDrawer(toggle) { }, }; } + +/** + * Toggle display of the Realized Gain or Loss filter drawer. + * @param {boolean} toggle + */ +export function toggleRealizedGainOrLossCilterDrawer(toggle) { + return { + type: `${t.REALIZED_GAIN_OR_LOSS}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`, + payload: { + toggle, + }, + }; +} diff --git a/src/store/financialStatement/financialStatements.reducer.js b/src/store/financialStatement/financialStatements.reducer.js index 63fea46b2..9c6e0a1ff 100644 --- a/src/store/financialStatement/financialStatements.reducer.js +++ b/src/store/financialStatement/financialStatements.reducer.js @@ -51,6 +51,9 @@ const initialState = { inventoryItemDetails: { displayFilterDrawer: false, }, + realizedGainOrLoss: { + displayFilterDrawer: false, + }, }; /** @@ -102,4 +105,6 @@ export default createReducer(initialState, { t.INVENTORY_ITEM_DETAILS, 'inventoryItemDetails', ), + ...financialStatementFilterToggle(t.REALIZED_GAIN_OR_LOSS, 'realizedGainOrLoss'), + }); diff --git a/src/store/financialStatement/financialStatements.selectors.js b/src/store/financialStatement/financialStatements.selectors.js index f19337fa2..83de44342 100644 --- a/src/store/financialStatement/financialStatements.selectors.js +++ b/src/store/financialStatement/financialStatements.selectors.js @@ -73,6 +73,10 @@ export const inventoryItemDetailsDrawerFilter = (state) => { return filterDrawerByTypeSelector('inventoryItemDetails')(state); }; +export const realizedGainOrLossFilterDrawerSelector = (state) => { + return filterDrawerByTypeSelector('realizedGainOrLoss')(state); +}; + /** * Retrieve balance sheet filter drawer. */ @@ -239,3 +243,13 @@ export const getInventoryItemDetailsFilterDrawer = createSelector( return isOpen; }, ); + +/** + * Retrieve Realized Gain or Loss filter drawer. + */ +export const getRealizedGainOrLossFilterDrawer = createSelector( + realizedGainOrLossFilterDrawerSelector, + (isOpen) => { + return isOpen; + }, +); diff --git a/src/store/financialStatement/financialStatements.types.js b/src/store/financialStatement/financialStatements.types.js index ef82d5b92..cdda1f369 100644 --- a/src/store/financialStatement/financialStatements.types.js +++ b/src/store/financialStatement/financialStatements.types.js @@ -16,4 +16,5 @@ export default { VENDORS_TRANSACTIONS: 'VENDORS TRANSACTIONS', CASH_FLOW_STATEMENT: 'CASH FLOW STATEMENT', INVENTORY_ITEM_DETAILS: 'INVENTORY ITEM DETAILS', + REALIZED_GAIN_OR_LOSS: 'REALIZED GAIN OR LOSS', };