feat : inventory adjustments.

This commit is contained in:
elforjani3
2021-01-11 09:42:01 +02:00
parent 097b9fdb3a
commit 9c00da3613
23 changed files with 1031 additions and 20 deletions

View File

@@ -0,0 +1,176 @@
import React, { useCallback, useMemo } from 'react';
import {
Button,
Popover,
Menu,
Intent,
MenuItem,
MenuDivider,
Position,
} from '@blueprintjs/core';
import { FormattedMessage as T, useIntl } from 'react-intl';
import moment from 'moment';
import classNames from 'classnames';
import {
DataTable,
If,
Money,
Choose,
Icon,
LoadingIndicator,
} from 'components';
import { CLASSES } from 'common/classes';
import { useIsValuePassed } from 'hooks';
import withDialogActions from 'containers/Dialog/withDialogActions';
// withInventoryAdjustments
// withInventoryAdjustmentsActions
import { compose, saveInvoke } from 'utils';
import { withRouter } from 'react-router-dom';
function InventoryAdjustmentDataTable({
// #ownProps
onDeleteInventoryAdjustment,
onSelectedRowsChange,
}) {
const { formatMessage } = useIntl();
const handleDeleteInventoryAdjustment = useCallback(
(_inventory) => {
saveInvoke(onDeleteInventoryAdjustment, _inventory);
},
[onDeleteInventoryAdjustment],
);
const actionMenuList = useCallback(
(adjustment) => (
<Menu>
<MenuItem
icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })}
/>
<MenuDivider />
<MenuItem
text={formatMessage({ id: 'delete_adjustment' })}
icon={<Icon icon="trash-16" iconSize={16} />}
intent={Intent.DANGER}
onClick={handleDeleteInventoryAdjustment(adjustment)}
/>
</Menu>
),
[handleDeleteInventoryAdjustment, formatMessage],
);
const onRowContextMenu = useCallback(
(cell) => actionMenuList(cell.row.original),
[actionMenuList],
);
const columns = useMemo(
() => [
{
id: 'date',
Header: formatMessage({ id: 'date' }),
accessor: (r) => moment(r.date).format('YYYY MMM DD'),
width: 115,
className: 'date',
},
{
id: 'type',
Header: formatMessage({ id: 'type' }),
accessor: 'type',
className: 'type',
width: 100,
},
{
id: 'reason',
Header: formatMessage({ id: 'reason' }),
// accessor: (r) => (
// <Tooltip
// content={}
// position={Position.RIGHT_BOTTOM}
// >
// </Tooltip>
// ),
className: 'reason',
width: 115,
},
{
id: 'reference',
Header: formatMessage({ id: 'reference' }),
accessor: (row) => `#${row.reference}`,
className: 'reference',
width: 100,
},
{
id: 'status',
Header: formatMessage({ id: 'status' }),
accessor: 'status',
width: 95,
className: 'status',
},
{
id: 'description',
Header: formatMessage({ id: 'description' }),
disableSorting: true,
width: 85,
className: 'description',
},
{
id: 'created_at',
Header: formatMessage({ id: 'created_at' }),
accessor: (r) => moment(r.created_at).format('YYYY MMM DD'),
width: 125,
className: 'created_at',
},
{
id: 'actions',
Header: '',
Cell: ({ cell }) => (
<Popover
content={actionMenuList(cell.row.original)}
position={Position.RIGHT_BOTTOM}
>
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
</Popover>
),
className: 'actions',
width: 50,
disableResizing: true,
},
],
[actionMenuList, formatMessage],
);
const handleSelectedRowsChange = useCallback(
(selectedRows) => {
saveInvoke(
onSelectedRowsChange,
selectedRows.map((s) => s.original),
);
},
[onSelectedRowsChange],
);
// const showEmptyStatus = [
// ].every((condition) => condition === true);
return (
<div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
<LoadingIndicator
// loading={}
>
<DataTable noInitialFetch={true} columns={columns} data={[]} />
</LoadingIndicator>
</div>
);
}
export default compose(
withRouter,
withDialogActions,
)(InventoryAdjustmentDataTable);

View File

@@ -0,0 +1,81 @@
import React, { useEffect, useState, useCallback, useMemo } from 'react';
import { useQuery } from 'react-query';
import { Alert, Intent } from '@blueprintjs/core';
import { FormattedMessage as T, useIntl } from 'react-intl';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import InventoryAdjustmentDataTable from './InventoryAdjustmentDataTable';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
//withInventoryAdjustmentsActions
import { compose } from 'utils';
import { Route, Switch } from 'react-router-dom';
/**
* Inventory Adjustment List.
*/
function InventoryAdjustmentList({
// #withDashboardActions
changePageTitle,
// #withInventoryAdjustmentsActions
}) {
const { formatMessage } = useIntl();
const [selectedRows, setSelectedRows] = useState([]);
const [deleteInventoryAdjustment, setDeleteInventoryAdjustment] = useState(
false,
);
useEffect(() => {
changePageTitle(formatMessage({ id: 'inventory_adjustment_list' }));
}, [changePageTitle, formatMessage]);
const fetchInventoryAdjustments = useQuery(
['inventory-adjustment-list'],
() => {},
);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback(
(inventory) => {
setSelectedRows(inventory);
},
[setSelectedRows],
);
const handleDeleteInventoryAdjustment = useCallback(
(adjustment) => {
setDeleteInventoryAdjustment(adjustment);
},
[setDeleteInventoryAdjustment],
);
const handleCancelInventoryAdjustmentDelete = useCallback(() => {
setDeleteInventoryAdjustment(false);
}, [setDeleteInventoryAdjustment]);
const handleConfirmInventoryAdjustmentDelete = useCallback(() => {}, []);
// Calculates the data table selected rows count.
const selectedRowsCount = useMemo(() => Object.values(selectedRows).length, [
selectedRows,
]);
return (
<DashboardInsider>
<DashboardPageContent>
<Switch>
<Route exact={true}>
<InventoryAdjustmentDataTable
onDeleteInventoryAdjustment={handleDeleteInventoryAdjustment}
onSelectedRowsChange={handleSelectedRowsChange}
/>
</Route>
</Switch>
</DashboardPageContent>
</DashboardInsider>
);
}
export default compose(withDashboardActions)(InventoryAdjustmentList);

View File

@@ -27,6 +27,7 @@ import { CLASSES } from 'common/classes';
import withItems from 'containers/Items/withItems';
import withItemsActions from 'containers/Items/withItemsActions';
import withSettings from 'containers/Settings/withSettings';
import withDialogActions from 'containers/Dialog/withDialogActions';
import { compose, saveInvoke, isBlank, defaultToTransform } from 'utils';
// Items datatable.
@@ -38,6 +39,9 @@ function ItemsDataTable({
itemsCurrentViewId,
itemsPagination,
// #withDialogActions
openDialog,
// #withItemsActions
addItemsTableQueries,
@@ -84,6 +88,11 @@ function ItemsDataTable({
},
[onDeleteItem],
);
const handleMakeAdjustment = useCallback(() => {
openDialog('inventory-adjustment-form', {});
}, [openDialog]);
const actionMenuList = useCallback(
(item) => (
<Menu>
@@ -111,6 +120,13 @@ function ItemsDataTable({
onClick={() => onActivateItem(item)}
/>
</If>
<If condition={item.type === 'inventory'}>
<MenuItem
text={formatMessage({ id: 'make_adjustment' })}
onClick={handleMakeAdjustment}
/>
</If>
<MenuItem
text={formatMessage({ id: 'delete_item' })}
icon={<Icon icon="trash-16" iconSize={16} />}
@@ -300,4 +316,5 @@ export default compose(
baseCurrency: organizationSettings?.baseCurrency,
})),
withItemsActions,
withDialogActions,
)(ItemsDataTable);

View File

@@ -0,0 +1,24 @@
import { connect } from 'react-redux';
import {
submitInventoryAdjustment,
deleteInventoryAdjustment,
fetchInventoryAdjustmentsTable,
} from 'store/inventoryAdjustments/inventoryAdjustment.actions';
import t from 'store/types';
const mapDispatchToProps = (dispatch) => ({
requestSubmitInventoryAdjustment: (form) =>
dispatch(submitInventoryAdjustment({ form })),
requestFetchInventoryAdjustmentTable: (query = {}) =>
dispatch(fetchInventoryAdjustmentsTable({ query: { ...query } })),
requestDeleteInventoryAdjustment: (id) =>
dispatch(deleteInventoryAdjustment({ id })),
addInventoryAdjustmentTableQueries: (queries) =>
dispatch({
type: t.INVENTORY_ADJUSTMENTS_TABLE_QUERIES_ADD,
payload: { queries },
}),
});
export default connect(null, mapDispatchToProps);

View File

@@ -0,0 +1,4 @@
import { connect } from 'react-redux';