diff --git a/client/src/components/MenuItemLabel.js b/client/src/components/MenuItemLabel.js
index c11b9a2d2..ab0826f73 100644
--- a/client/src/components/MenuItemLabel.js
+++ b/client/src/components/MenuItemLabel.js
@@ -3,5 +3,5 @@ import React from 'react';
export default function MenuItemLabel({
text
}) {
- return ();
+ return ();
}
\ No newline at end of file
diff --git a/client/src/components/Sidebar/SidebarMenu.js b/client/src/components/Sidebar/SidebarMenu.js
index 4354e9e5e..6a41f891d 100644
--- a/client/src/components/Sidebar/SidebarMenu.js
+++ b/client/src/components/Sidebar/SidebarMenu.js
@@ -1,5 +1,5 @@
-import React from 'react';
-import { Menu, MenuDivider } from '@blueprintjs/core';
+import React, { useMemo } from 'react';
+import { Menu, MenuDivider, Button } from '@blueprintjs/core';
import { useHistory, useLocation } from 'react-router-dom';
import sidebarMenuList from 'config/sidebarMenu';
import Icon from 'components/Icon';
@@ -16,16 +16,31 @@ export default function SidebarMenu() {
const children = Array.isArray(item.children)
? menuItemsMapper(item.children)
: null;
- const isActive =
- (item.href && item.href === location.pathname) ||
- (item.children &&
- item.children.some((c) => c.href === location.pathname));
+
+ const matchPath = (pathname, path) => {
+ return item.matchExact ? pathname === path : pathname.indexOf(path) !== -1;
+ };
+ const isActive = (item.children) ?
+ item.children.some((c) => matchPath(location.pathname, c.href)) :
+ (item.href && matchPath(location.pathname, item.href));
const handleItemClick = () => {
if (item.href) {
history.push(item.href);
}
};
+
+ const maybeRenderLabel = (item) => item.newTabHref ? (
+ }
+ onClick={(event) => {
+ history.push(item.newTabHref);
+ event.stopPropagation();
+ }}
+ />
+ ) : null;
+
return item.spacer ? (
) : item.divider ? (
@@ -38,7 +53,7 @@ export default function SidebarMenu() {
active={isActive}
icon={}
text={item.text}
- label={item.label}
+ label={maybeRenderLabel(item)}
disabled={item.disabled}
children={children}
dropdownType={item.dropdownType || 'collapse'}
diff --git a/client/src/config/sidebarMenu.js b/client/src/config/sidebarMenu.js
index a7bfc0332..5efbe8664 100644
--- a/client/src/config/sidebarMenu.js
+++ b/client/src/config/sidebarMenu.js
@@ -1,4 +1,4 @@
-import React from 'react';
+ import React from 'react';
import { FormattedMessage as T } from 'react-intl';
export default [
@@ -13,7 +13,6 @@ export default [
{
divider: true,
},
-
{
text: 'Sales & inventory',
label: true,
@@ -41,16 +40,18 @@ export default [
{
text: ,
href: '/estimates',
+ newTabHref: '/estimates/new',
},
-
{
text: ,
href: '/invoices',
+ newTabHref: '/invoices/new',
},
{
text: ,
href: '/payment-receives',
+ newTabHref: '/payment-receives/new',
},
{
divider: true,
@@ -58,6 +59,7 @@ export default [
{
text: ,
href: '/receipts',
+ newTabHref: '/receipts/new',
},
],
},
@@ -67,11 +69,12 @@ export default [
{
text: ,
href: '/bills',
+ newTabHref: '/bills/new',
},
-
{
text: ,
href: '/payment-mades',
+ newTabHref: '/payment-mades/new',
},
],
},
@@ -81,10 +84,12 @@ export default [
{
text: ,
href: '/customers',
+ newTabHref: '/customers/new',
},
{
text: ,
href: '/vendors',
+ newTabHref: '/vendors/new',
},
],
},
@@ -139,6 +144,7 @@ export default [
{
text: ,
href: '/financial-reports',
+ matchExact: true,
},
{
divider: true,
diff --git a/client/src/containers/Entries/EditableItemsEntriesTable.js b/client/src/containers/Entries/EditableItemsEntriesTable.js
index 052ec7d39..ebf109bf1 100644
--- a/client/src/containers/Entries/EditableItemsEntriesTable.js
+++ b/client/src/containers/Entries/EditableItemsEntriesTable.js
@@ -9,6 +9,9 @@ export default function EditableItemsEntriesTable({
defaultEntry,
minLinesNumber = 2,
linesNumber = 5,
+
+ filterSellableItems = false,
+ filterPurchasableItems = false,
}) {
const { setFieldValue, values } = useFormikContext();
const [clearLinesAlert, setClearLinesAlert] = useState(false);
@@ -58,6 +61,8 @@ export default function EditableItemsEntriesTable({
}}
entries={value}
errors={error}
+ filterPurchasableItems={filterPurchasableItems}
+ filterSellableItems={filterSellableItems}
onClickAddNewRow={handleClickAddNewRow}
onClickClearAllLines={handleClearAllLines}
onClickRemoveRow={handleClickRemoveLine}
diff --git a/client/src/containers/Entries/ItemsEntriesTable.js b/client/src/containers/Entries/ItemsEntriesTable.js
index e5c5c9c07..c15435a1c 100644
--- a/client/src/containers/Entries/ItemsEntriesTable.js
+++ b/client/src/containers/Entries/ItemsEntriesTable.js
@@ -91,6 +91,8 @@ function ItemsEntriesTable({
onClickRemoveRow,
onClickAddNewRow,
onClickClearAllLines,
+ filterPurchasableItems = false,
+ filterSellableItems = false,
}) {
const [rows, setRows] = useState([]);
const { formatMessage } = useIntl();
@@ -117,6 +119,8 @@ function ItemsEntriesTable({
Cell: ItemsListCell,
disableSortBy: true,
width: 180,
+ filterPurchasable: filterPurchasableItems,
+ filterSellable: filterSellableItems,
},
{
Header: formatMessage({ id: 'description' }),
diff --git a/client/src/containers/Items/ItemForm.js b/client/src/containers/Items/ItemForm.js
index 125b3d4ca..90b8af793 100644
--- a/client/src/containers/Items/ItemForm.js
+++ b/client/src/containers/Items/ItemForm.js
@@ -33,7 +33,7 @@ const defaultInitialValues = {
active: true,
name: '',
type: 'service',
- sku: '',
+ code: '',
cost_price: '',
sell_price: '',
cost_account_id: '',
diff --git a/client/src/containers/Items/ItemForm.schema.js b/client/src/containers/Items/ItemForm.schema.js
index b535acb76..3d7b7a6aa 100644
--- a/client/src/containers/Items/ItemForm.schema.js
+++ b/client/src/containers/Items/ItemForm.schema.js
@@ -1,4 +1,5 @@
import * as Yup from 'yup';
+import { defaultTo } from 'lodash';
import { formatMessage } from 'services/intl';
import { DATATYPES_LENGTH } from 'common/dataTypes';
@@ -15,7 +16,7 @@ const Schema = Yup.object().shape({
.min(0)
.max(DATATYPES_LENGTH.STRING)
.label(formatMessage({ id: 'item_type_' })),
- sku: Yup.string().trim().min(0).max(DATATYPES_LENGTH.STRING),
+ code: Yup.string().trim().min(0).max(DATATYPES_LENGTH.STRING),
cost_price: Yup.number().when(['purchasable'], {
is: true,
then: Yup.number()
@@ -61,8 +62,8 @@ const Schema = Yup.object().shape({
export const transformItemFormData = (item, defaultValue) => {
return {
...item,
- sellable: item?.sellable ? Boolean(item.sellable) : defaultValue.sellable,
- purchasable: item?.purchasable ? Boolean(item.purchasable) : defaultValue.purchasable,
+ sellable: !!defaultTo(item?.sellable, defaultValue.sellable),
+ purchasable: !!defaultTo(item?.purchasable, defaultValue.purchasable),
};
}
diff --git a/client/src/containers/Items/ItemFormBody.js b/client/src/containers/Items/ItemFormBody.js
index 274930060..c346aac17 100644
--- a/client/src/containers/Items/ItemFormBody.js
+++ b/client/src/containers/Items/ItemFormBody.js
@@ -27,7 +27,7 @@ function ItemFormBody({ accountsList, baseCurrency }) {
{/*------------- Purchasable checbox ------------- */}
- {({ field }) => (
+ {({ form, field }) => (
{/*------------- Selling price ------------- */}
-
+
{({ form, field: { value }, meta: { error, touched } }) => (
}
@@ -67,7 +67,7 @@ function ItemFormBody({ accountsList, baseCurrency }) {
)}
-
+
{/*------------- Selling account ------------- */}
@@ -93,6 +93,7 @@ function ItemFormBody({ accountsList, baseCurrency }) {
selectedAccountId={value}
disabled={!form.values.sellable}
filterByTypes={['income']}
+ popoverFill={true}
/>
)}
@@ -118,7 +119,7 @@ function ItemFormBody({ accountsList, baseCurrency }) {
{/*------------- Cost price ------------- */}
-
+
{({ field, form, field: { value }, meta: { error, touched } }) => (
}
@@ -141,7 +142,7 @@ function ItemFormBody({ accountsList, baseCurrency }) {
)}
-
+
{/*------------- Cost account ------------- */}
@@ -167,6 +168,7 @@ function ItemFormBody({ accountsList, baseCurrency }) {
selectedAccountId={value}
disabled={!form.values.purchasable}
filterByTypes={['cost_of_goods_sold']}
+ popoverFill={true}
/>
)}
diff --git a/client/src/containers/Items/ItemFormPrimarySection.js b/client/src/containers/Items/ItemFormPrimarySection.js
index abe955387..ab318e55f 100644
--- a/client/src/containers/Items/ItemFormPrimarySection.js
+++ b/client/src/containers/Items/ItemFormPrimarySection.js
@@ -135,7 +135,7 @@ function ItemFormPrimarySection({
{/*----------- Item category ----------*/}
-
+
{({ form, field: { value }, meta: { error, touched } }) => (
}
@@ -143,7 +143,6 @@ function ItemFormPrimarySection({
intent={inputIntent({ error, touched })}
helperText={}
className={classNames(
- 'form-group--select-list',
'form-group--category',
Classes.FILL,
)}
@@ -154,7 +153,6 @@ function ItemFormPrimarySection({
onCategorySelected={(category) => {
form.setFieldValue('category_id', category.id);
}}
- popoverProps={{ minimal: true }}
/>
)}
diff --git a/client/src/containers/Items/ItemsDataTable.js b/client/src/containers/Items/ItemsDataTable.js
index 03eba0f8d..0afec335e 100644
--- a/client/src/containers/Items/ItemsDataTable.js
+++ b/client/src/containers/Items/ItemsDataTable.js
@@ -111,8 +111,8 @@ function ItemsDataTable({
},
{
Header: formatMessage({ id: 'item_code' }),
- accessor: 'sku',
- className: 'sku',
+ accessor: 'code',
+ className: 'code',
width: 120,
},
{
diff --git a/client/src/containers/Purchases/Bill/BillForm.js b/client/src/containers/Purchases/Bill/BillForm.js
index 7b591ab2b..e9488d242 100644
--- a/client/src/containers/Purchases/Bill/BillForm.js
+++ b/client/src/containers/Purchases/Bill/BillForm.js
@@ -22,7 +22,7 @@ import withBillDetail from './withBillDetail';
import { AppToaster } from 'components';
import { ERROR } from 'common/errors';
-import { compose, repeatValue, orderingLinesIndexes } from 'utils';
+import { compose, repeatValue, defaultToTransform, orderingLinesIndexes } from 'utils';
const MIN_LINES_NUMBER = 5;
@@ -207,7 +207,10 @@ function BillForm({
{({ isSubmitting, values }) => (