BIG-14: avoid allocate landed cost on non-inventory items.

This commit is contained in:
a.bouhuolia
2021-09-13 18:27:01 +02:00
parent bffc50a492
commit 4188f3f1b5
17 changed files with 188 additions and 111 deletions

View File

@@ -1,6 +1,5 @@
import React, { useEffect, useCallback } from 'react';
import classNames from 'classnames';
import { useItem } from 'hooks/query';
import { CLASSES } from 'common/classes';
import { DataTableEditable } from 'components';
@@ -9,12 +8,13 @@ import { useEditableItemsEntriesColumns } from './components';
import {
saveInvoke,
compose,
updateTableRow,
updateTableCell,
updateMinEntriesLines,
updateAutoAddNewLine,
updateRemoveLineByIndex,
} from 'utils';
import { updateItemsEntriesTotal, ITEM_TYPE } from './utils';
import { updateItemsEntriesTotal, useFetchItemRow } from './utils';
import { updateTableRow } from '../../utils';
/**
* Items entries table.
@@ -30,62 +30,9 @@ function ItemsEntriesTable({
linesNumber,
currencyCode,
itemType, // sellable or purchasable
landedCost = false
landedCost = false,
}) {
const [rows, setRows] = React.useState(initialEntries);
const [rowItem, setRowItem] = React.useState(null);
const [cellsLoading, setCellsLoading] = React.useState(null);
// Fetches the item details.
const {
data: item,
isFetching: isItemFetching,
isSuccess: isItemSuccess,
} = useItem(rowItem && rowItem.itemId, {
enabled: !!(rowItem && rowItem.itemId),
});
// Once the item start loading give the table cells loading state.
useEffect(() => {
if (rowItem && isItemFetching) {
setCellsLoading([
[rowItem.rowIndex, 'rate'],
[rowItem.rowIndex, 'description'],
[rowItem.rowIndex, 'quantity'],
[rowItem.rowIndex, 'discount'],
]);
} else {
setCellsLoading(null);
}
}, [isItemFetching, setCellsLoading, rowItem]);
// Once the item selected and fetched set the initial details to the table.
useEffect(() => {
if (isItemSuccess && item && rowItem) {
const { rowIndex } = rowItem;
const price =
itemType === ITEM_TYPE.PURCHASABLE
? item.cost_price
: item.sell_price;
const description =
itemType === ITEM_TYPE.PURCHASABLE
? item.cost_description
: item.sell_description;
// Update the rate, description and quantity data of the row.
const newRows = compose(
updateItemsEntriesTotal,
updateTableRow(rowIndex, 'rate', price),
updateTableRow(rowIndex, 'description', description),
updateTableRow(rowIndex, 'quantity', 1),
)(rows);
setRows(newRows);
setRowItem(null);
saveInvoke(onUpdateData, newRows);
}
}, [item, rowItem, rows, itemType, onUpdateData, isItemSuccess]);
// Allows to observes `entries` to make table rows outside controlled.
useEffect(() => {
@@ -97,22 +44,38 @@ function ItemsEntriesTable({
// Editiable items entries columns.
const columns = useEditableItemsEntriesColumns({ landedCost });
// Handles the editor data update.
const handleUpdateData = useCallback(
(rowIndex, columnId, value) => {
if (columnId === 'item_id') {
setRowItem({ rowIndex, columnId, itemId: value });
}
// Handle the fetch item row details.
const { setItemRow, cellsLoading, isItemFetching } = useFetchItemRow({
landedCost,
itemType,
notifyNewRow: (newRow, rowIndex) => {
// Update the rate, description and quantity data of the row.
const newRows = compose(
updateAutoAddNewLine(defaultEntry, ['item_id']),
updateItemsEntriesTotal,
updateTableRow(rowIndex, columnId, value),
updateTableRow(rowIndex, newRow),
)(rows);
setRows(newRows);
onUpdateData(newRows);
},
[rows, defaultEntry, onUpdateData],
});
// Handles the editor data update.
const handleUpdateData = useCallback(
(rowIndex, columnId, value) => {
if (columnId === 'item_id') {
setItemRow({ rowIndex, columnId, itemId: value });
}
const newRows = compose(
updateAutoAddNewLine(defaultEntry, ['item_id']),
updateItemsEntriesTotal,
updateTableCell(rowIndex, columnId, value),
)(rows);
setRows(newRows);
onUpdateData(newRows);
},
[rows, defaultEntry, onUpdateData, setItemRow],
);
// Handle table rows removing by index.

View File

@@ -179,6 +179,7 @@ export function useEditableItemsEntriesColumns({ landedCost }) {
accessor: 'landed_cost',
Cell: CheckBoxFieldCell,
width: 100,
disabledAccessor: 'landed_cost_disabled',
disableSortBy: true,
disableResizing: true,
className: 'landed-cost',

View File

@@ -1,6 +1,9 @@
import React from 'react';
import * as R from 'ramda';
import { sumBy, isEmpty, last } from 'lodash';
import * as R from 'ramda';
import { toSafeNumber } from 'utils';
import { useItem } from 'hooks/query';
import { toSafeNumber, saveInvoke } from 'utils';
/**
* Retrieve item entry total from the given rate, quantity and discount.
@@ -52,4 +55,79 @@ export const ensureEntriesHaveEmptyLine = R.curry((defaultEntry, entries) => {
return [...entries, defaultEntry];
}
return entries;
});
});
export const isLandedCostDisabled = (item) =>
['service', 'non-inventory'].indexOf(item.type) !== -1;
/**
* Handle fetch item row details and retrieves the new table row.
*/
export function useFetchItemRow({ landedCost, itemType, notifyNewRow }) {
const [itemRow, setItemRow] = React.useState(null);
const [cellsLoading, setCellsLoading] = React.useState(null);
// Fetches the item details.
const {
data: item,
isFetching: isItemFetching,
isSuccess: isItemSuccess,
} = useItem(itemRow && itemRow.itemId, {
enabled: !!(itemRow && itemRow.itemId),
});
// Once the item start loading give the table cells loading state.
React.useEffect(() => {
if (itemRow && isItemFetching) {
setCellsLoading([
[itemRow.rowIndex, 'rate'],
[itemRow.rowIndex, 'description'],
[itemRow.rowIndex, 'quantity'],
[itemRow.rowIndex, 'discount'],
]);
} else {
setCellsLoading(null);
}
}, [isItemFetching, setCellsLoading, itemRow]);
// Once the item selected and fetched set the initial details to the table.
React.useEffect(() => {
if (isItemSuccess && item && itemRow) {
const { rowIndex } = itemRow;
const price =
itemType === ITEM_TYPE.PURCHASABLE ? item.cost_price : item.sell_price;
const description =
itemType === ITEM_TYPE.PURCHASABLE
? item.cost_description
: item.sell_description;
// Detarmines whether the landed cost checkbox should be disabled.
const landedCostDisabled = isLandedCostDisabled(item);
// The new row.
const newRow = {
rate: price,
description,
quantity: 1,
...(landedCost
? {
landed_cost: false,
landed_cost_disabled: landedCostDisabled,
}
: {}),
};
setItemRow(null);
saveInvoke(notifyNewRow, newRow, rowIndex);
}
}, [item, itemRow, itemType, isItemSuccess, landedCost, notifyNewRow]);
return {
isItemFetching,
isItemSuccess,
item,
setItemRow,
itemRow,
cellsLoading,
};
}