diff --git a/CHANGELOG.md b/CHANGELOG.md
index 03f5da752..8b1592013 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,47 @@
All notable changes to Bigcapital server-side will be in this file.
+## [1.7.1-rc.2] - 30-03-2022
+
+## Added
+ - `BIG-141` Add inactive status to item drawer details.
+ - `BIG-278` Add created at date on expense details.
+ - `BIG-350` Add empty status content of warehouse transfers service.
+ - `BIG-344` Add branch details to manual journal and expense details.
+## Fixed
+ - `BIG-221` Remove Non-inventory radio choice on item form.
+ - `BIG-236` Validate estimate expiration date should be equal or bigger than estimate date.
+ - `BIG-237` Validate invoice due date should be equal or bigger than invoice date.
+ - `BIG-238` Validate bill due date should be equal or bigger than bill date.
+ - `BIG-280` Optimize style of multi-select accounts menu.
+ - `BIG-284` Cashflow statement loading bar.
+ - `BIG-296` Creating a new child account from accounts list.
+ - `BIG-301` Navigation bar divider on actions bar hide with permissions control.
+ - `BIG-304` Adding cash or bank account from cash flow service.
+ - `BIG-351` Invalid date in the inventory adjustment detail.
+ - `BIG-352` Fix terms and notes fields on footer of all services.
+ - `BIG-354` Validate the warehouse transfer quantity should be above zero.
+
+## [1.7.0-rc.1] - 24-03-2022
+
+## Added
+ - Multiply currencies with foreign currencies.
+ - Multiply warehouses to track inventory items.
+ - Multiply branches to track organization transactions.
+ - Transfer orders between warehouses.
+ - Integrate financial reports with multiply branches.
+ - Integrate inventory reports with multiply warehouses.
+
+## Changes
+ - Optimize style of sale invoice form.
+ - Optimize style of sale receipt form.
+ - Optimize style of credit note form.
+ - Optimize style of payment receive form.
+ - Optimize style of bill form.
+ - Optimize style of payment made form.
+ - Optimize style of manual journal form.
+ - Optimize style of expense form.
+
## [1.6.3] - 21-02-2022
### Fixed
diff --git a/package.json b/package.json
index d4a827375..cf7f8a161 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "bigcapital-client",
- "version": "1.6.3",
+ "version": "1.7.1",
"private": true,
"dependencies": {
"@babel/core": "7.8.4",
diff --git a/src/components/Accounts/AccountMultiSelect.js b/src/components/Accounts/AccountMultiSelect.js
new file mode 100644
index 000000000..8e9d54882
--- /dev/null
+++ b/src/components/Accounts/AccountMultiSelect.js
@@ -0,0 +1,73 @@
+import React from 'react';
+import styled from 'styled-components';
+import { MenuItem } from '@blueprintjs/core';
+import { FMultiSelect } from '../Forms';
+import classNames from 'classnames';
+import { Classes } from '@blueprintjs/popover2';
+
+/**
+ *
+ * @param {*} query
+ * @param {*} account
+ * @param {*} _index
+ * @param {*} exactMatch
+ * @returns
+ */
+const accountItemPredicate = (query, account, _index, exactMatch) => {
+ const normalizedTitle = account.name.toLowerCase();
+ const normalizedQuery = query.toLowerCase();
+
+ if (exactMatch) {
+ return normalizedTitle === normalizedQuery;
+ } else {
+ return `${account.code}. ${normalizedTitle}`.indexOf(normalizedQuery) >= 0;
+ }
+};
+
+/**
+ *
+ * @param {*} account
+ * @param {*} param1
+ * @returns
+ */
+const accountItemRenderer = (
+ account,
+ { handleClick, modifiers, query },
+ { isSelected },
+) => {
+ return (
+
+ );
+};
+
+const accountSelectProps = {
+ itemPredicate: accountItemPredicate,
+ itemRenderer: accountItemRenderer,
+ valueAccessor: (item) => item.id,
+ labelAccessor: (item) => item.code,
+ tagRenderer: (item) => item.name,
+};
+
+/**
+ * branches mulit select.
+ * @param {*} param0
+ * @returns {JSX.Element}
+ */
+export function AccountMultiSelect({ accounts, ...rest }) {
+ return (
+
+ );
+}
diff --git a/src/components/Accounts/index.js b/src/components/Accounts/index.js
new file mode 100644
index 000000000..791394be9
--- /dev/null
+++ b/src/components/Accounts/index.js
@@ -0,0 +1 @@
+export * from './AccountMultiSelect';
diff --git a/src/components/index.js b/src/components/index.js
index 16e1003b6..c91a4f1a1 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -104,6 +104,7 @@ export * from './Warehouses';
export * from './Currencies';
export * from './FormTopbar'
export * from './Paper';
+export * from './Accounts'
const Hint = FieldHint;
diff --git a/src/containers/Accounting/MakeJournal/components.js b/src/containers/Accounting/MakeJournal/components.js
index cec39f28c..260adddd4 100644
--- a/src/containers/Accounting/MakeJournal/components.js
+++ b/src/containers/Accounting/MakeJournal/components.js
@@ -4,7 +4,12 @@ import { Popover2 } from '@blueprintjs/popover2';
import { useFormikContext } from 'formik';
import intl from 'react-intl-universal';
-import { ExchangeRateInputGroup, Icon, Hint, FormattedMessage as T } from 'components';
+import {
+ ExchangeRateInputGroup,
+ Icon,
+ Hint,
+ FormattedMessage as T,
+} from 'components';
import {
AccountsListFieldCell,
MoneyFieldCell,
@@ -63,7 +68,10 @@ export const ActionsCellRenderer = ({
};
const exampleMenu = (
);
return (
diff --git a/src/containers/Drawers/BillDrawer/BillDetailActionsBar.js b/src/containers/Drawers/BillDrawer/BillDetailActionsBar.js
index 7f78410b5..833b156d9 100644
--- a/src/containers/Drawers/BillDrawer/BillDetailActionsBar.js
+++ b/src/containers/Drawers/BillDrawer/BillDetailActionsBar.js
@@ -95,9 +95,9 @@ function BillDetailActionsBar({
onClick={handleQuickBillPayment}
/>
-
+
}
diff --git a/src/containers/Drawers/CustomerDetailsDrawer/CustomerDetailsActionsBar.js b/src/containers/Drawers/CustomerDetailsDrawer/CustomerDetailsActionsBar.js
index 226927dba..f27a0e281 100644
--- a/src/containers/Drawers/CustomerDetailsDrawer/CustomerDetailsActionsBar.js
+++ b/src/containers/Drawers/CustomerDetailsDrawer/CustomerDetailsActionsBar.js
@@ -131,17 +131,17 @@ function CustomerDetailsActionsBar({
/>
-
+
}
text={intl.get('customer.drawer.action.edit')}
onClick={handleEditContact}
/>
-
+
}
diff --git a/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailActionsBar.js b/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailActionsBar.js
index 21c669274..fd28a0952 100644
--- a/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailActionsBar.js
+++ b/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailActionsBar.js
@@ -96,9 +96,9 @@ function EstimateDetailActionsBar({
intent={Intent.DANGER}
onClick={handleDeleteEstimate}
/>
-
+
}
onClick={handleEditExpense}
/>
-
+
}
diff --git a/src/containers/Drawers/ExpenseDrawer/ExpenseDrawerHeader.js b/src/containers/Drawers/ExpenseDrawer/ExpenseDrawerHeader.js
index 816970709..f8187b2a5 100644
--- a/src/containers/Drawers/ExpenseDrawer/ExpenseDrawerHeader.js
+++ b/src/containers/Drawers/ExpenseDrawer/ExpenseDrawerHeader.js
@@ -10,6 +10,7 @@ import {
Col,
DetailItem,
DetailsMenu,
+ FormatDate,
ExchangeRateDetailItem,
FormattedMessage as T,
} from 'components';
@@ -64,10 +65,12 @@ export default function ExpenseDrawerHeader() {
minLabelSize={'180px'}
>
}>
- {moment(expense.published_at).format('YYYY MMM DD')}
+
- }>2021 Aug 24
+ }>
+
+
diff --git a/src/containers/Drawers/ExpenseDrawer/ExpenseDrawerProvider.js b/src/containers/Drawers/ExpenseDrawer/ExpenseDrawerProvider.js
index 90e4b87a1..f5da42cc8 100644
--- a/src/containers/Drawers/ExpenseDrawer/ExpenseDrawerProvider.js
+++ b/src/containers/Drawers/ExpenseDrawer/ExpenseDrawerProvider.js
@@ -1,6 +1,9 @@
import React from 'react';
+import intl from 'react-intl-universal';
import { useExpense } from 'hooks/query';
-import { DrawerLoading } from 'components';
+import { DrawerHeaderContent, DrawerLoading } from 'components';
+import { Features } from 'common';
+import { useFeatureCan } from 'hooks/state';
const ExpenseDrawerDrawerContext = React.createContext();
@@ -8,6 +11,9 @@ const ExpenseDrawerDrawerContext = React.createContext();
* Expense drawer provider.
*/
function ExpenseDrawerProvider({ expenseId, ...props }) {
+ // Features guard.
+ const { featureCan } = useFeatureCan();
+
// Fetch the expense details.
const {
data: expense,
@@ -28,6 +34,17 @@ function ExpenseDrawerProvider({ expenseId, ...props }) {
return (
+
);
diff --git a/src/containers/Drawers/ExpenseDrawer/index.js b/src/containers/Drawers/ExpenseDrawer/index.js
index cb3c56f66..92ad685b6 100644
--- a/src/containers/Drawers/ExpenseDrawer/index.js
+++ b/src/containers/Drawers/ExpenseDrawer/index.js
@@ -1,6 +1,4 @@
import React, { lazy } from 'react';
-import intl from 'react-intl-universal';
-
import { Drawer, DrawerSuspense } from 'components';
import withDrawers from 'containers/Drawer/withDrawers';
@@ -22,7 +20,6 @@ function ExpenseDrawer({
diff --git a/src/containers/Drawers/InventoryAdjustmentDetailDrawer/InventoryAdjustmentDetailHeader.js b/src/containers/Drawers/InventoryAdjustmentDetailDrawer/InventoryAdjustmentDetailHeader.js
index 91529092d..c047132b4 100644
--- a/src/containers/Drawers/InventoryAdjustmentDetailDrawer/InventoryAdjustmentDetailHeader.js
+++ b/src/containers/Drawers/InventoryAdjustmentDetailDrawer/InventoryAdjustmentDetailHeader.js
@@ -5,7 +5,7 @@ import intl from 'react-intl-universal';
import { defaultTo } from 'lodash';
import clsx from 'classnames';
-import { DetailsMenu, DetailItem } from 'components';
+import { DetailsMenu, DetailItem, FormatDate } from 'components';
import { useInventoryAdjustmentDrawerContext } from './InventoryAdjustmentDrawerProvider';
import InventoryAdjustmentDrawerCls from 'style/components/Drawers/InventoryAdjustmentDrawer.module.scss';
@@ -20,7 +20,7 @@ export default function InventoryAdjustmentDetailHeader() {
- {moment(inventoryAdjustment.date).format('YYYY MMM DD')}
+
@@ -36,7 +36,7 @@ export default function InventoryAdjustmentDetailHeader() {
- {moment(inventoryAdjustment.published_at).format('YYYY MMM DD')}
+
@@ -44,7 +44,7 @@ export default function InventoryAdjustmentDetailHeader() {
- {moment(inventoryAdjustment.created_at).format('YYYY MMM DD')}
+
diff --git a/src/containers/Drawers/ItemDetailDrawer/ItemDetailActionsBar.js b/src/containers/Drawers/ItemDetailDrawer/ItemDetailActionsBar.js
index 39489bb90..738d82781 100644
--- a/src/containers/Drawers/ItemDetailDrawer/ItemDetailActionsBar.js
+++ b/src/containers/Drawers/ItemDetailDrawer/ItemDetailActionsBar.js
@@ -55,10 +55,9 @@ function ItemDetailActionsBar({
text={}
onClick={handleEditItem}
/>
-
-
+
}
diff --git a/src/containers/Drawers/ItemDetailDrawer/ItemDetailDrawerProvider.js b/src/containers/Drawers/ItemDetailDrawer/ItemDetailDrawerProvider.js
index c748e559b..fa811cf1d 100644
--- a/src/containers/Drawers/ItemDetailDrawer/ItemDetailDrawerProvider.js
+++ b/src/containers/Drawers/ItemDetailDrawer/ItemDetailDrawerProvider.js
@@ -1,6 +1,7 @@
import React from 'react';
import { DrawerHeaderContent, DrawerLoading } from 'components';
import { useItem } from 'hooks/query';
+import { inactiveStatus } from './utlis';
const ItemDetailDrawerContext = React.createContext();
@@ -27,7 +28,10 @@ function ItemDetailDrawerProvider({ itemId, ...props }) {
return (
-
+
);
diff --git a/src/containers/Drawers/ItemDetailDrawer/utlis.js b/src/containers/Drawers/ItemDetailDrawer/utlis.js
new file mode 100644
index 000000000..72b46fe3d
--- /dev/null
+++ b/src/containers/Drawers/ItemDetailDrawer/utlis.js
@@ -0,0 +1,27 @@
+import React from 'react';
+import styled from 'styled-components';
+import { Intent, Tag } from '@blueprintjs/core';
+import { Choose, FormattedMessage as T } from '../../../components';
+
+/**
+ * items inactive status.
+ * @returns {React.JSX}
+ */
+export function inactiveStatus(item) {
+ return (
+
+
+ {item.name}
+
+
+
+
+ {item.name}
+
+ );
+}
+
+const StatusTag = styled(Tag)`
+ font-size: 11px;
+ margin-left: 10px;
+`;
diff --git a/src/containers/Drawers/ManualJournalDrawer/ManualJournalDrawerActionBar.js b/src/containers/Drawers/ManualJournalDrawer/ManualJournalDrawerActionBar.js
index a4d435107..31f29a0e7 100644
--- a/src/containers/Drawers/ManualJournalDrawer/ManualJournalDrawerActionBar.js
+++ b/src/containers/Drawers/ManualJournalDrawer/ManualJournalDrawerActionBar.js
@@ -55,9 +55,9 @@ function ManualJournalDrawerActionBar({
text={}
onClick={handleEditManualJournal}
/>
-
+
}
diff --git a/src/containers/Drawers/ManualJournalDrawer/utils.js b/src/containers/Drawers/ManualJournalDrawer/utils.js
index 944c4f784..31e38ccf0 100644
--- a/src/containers/Drawers/ManualJournalDrawer/utils.js
+++ b/src/containers/Drawers/ManualJournalDrawer/utils.js
@@ -3,6 +3,8 @@ import React from 'react';
import { Tag, Intent, Classes, Tooltip, Position } from '@blueprintjs/core';
import { T, Choose, FormatNumberCell, If, Icon } from '../../../components';
+import { Features } from 'common';
+import { useFeatureCan } from 'hooks/state';
/**
* Note column accessor.
@@ -46,8 +48,9 @@ export function ManualJournalDetailsStatus({ manualJournal }) {
/**
* Retrieve read-only manual journal entries columns.
*/
-export const useManualJournalEntriesColumns = () =>
- React.useMemo(
+export const useManualJournalEntriesColumns = () => {
+ const { featureCan } = useFeatureCan();
+ return React.useMemo(
() => [
{
Header: intl.get('account_name'),
@@ -70,6 +73,17 @@ export const useManualJournalEntriesColumns = () =>
disableSortBy: true,
className: 'note',
},
+ ...(featureCan(Features.Branches)
+ ? [
+ {
+ Header: intl.get('branch'),
+ width: 130,
+ accessor: 'branch.name',
+ disableSortBy: true,
+ className: 'branch',
+ },
+ ]
+ : []),
{
Header: intl.get('credit'),
accessor: 'credit',
@@ -93,5 +107,6 @@ export const useManualJournalEntriesColumns = () =>
align: 'right',
},
],
- [],
+ [featureCan],
);
+};
diff --git a/src/containers/Drawers/PaymentMadeDetailDrawer/PaymentMadeDetailActionsBar.js b/src/containers/Drawers/PaymentMadeDetailDrawer/PaymentMadeDetailActionsBar.js
index d0731aeac..2ecdf1a12 100644
--- a/src/containers/Drawers/PaymentMadeDetailDrawer/PaymentMadeDetailActionsBar.js
+++ b/src/containers/Drawers/PaymentMadeDetailDrawer/PaymentMadeDetailActionsBar.js
@@ -58,9 +58,9 @@ function PaymentMadeDetailActionsBar({
text={}
onClick={handleEditPaymentMade}
/>
-
+
}
diff --git a/src/containers/Drawers/PaymentReceiveDetailDrawer/PaymentReceiveActionsBar.js b/src/containers/Drawers/PaymentReceiveDetailDrawer/PaymentReceiveActionsBar.js
index 14f305f80..3ef447af7 100644
--- a/src/containers/Drawers/PaymentReceiveDetailDrawer/PaymentReceiveActionsBar.js
+++ b/src/containers/Drawers/PaymentReceiveDetailDrawer/PaymentReceiveActionsBar.js
@@ -95,12 +95,12 @@ function PaymentReceiveActionsBar({
intent={Intent.DANGER}
onClick={handleDeletePaymentReceive}
/>
-
+
-
+
}
onClick={handleRefundVendorCredit}
/>
-
+
}
diff --git a/src/containers/Drawers/VendorDetailsDrawer/VendorDetailsActionsBar.js b/src/containers/Drawers/VendorDetailsDrawer/VendorDetailsActionsBar.js
index 82d1c2967..74d346ea7 100644
--- a/src/containers/Drawers/VendorDetailsDrawer/VendorDetailsActionsBar.js
+++ b/src/containers/Drawers/VendorDetailsDrawer/VendorDetailsActionsBar.js
@@ -102,17 +102,17 @@ function VendorDetailsActionsBar({
icon={}
/>
-
+
}
text={}
onClick={safeCallback(onEditContact)}
/>
-
+
}
diff --git a/src/containers/Entries/components.js b/src/containers/Entries/components.js
index bb0bc53a2..d7877cd1b 100644
--- a/src/containers/Entries/components.js
+++ b/src/containers/Entries/components.js
@@ -43,7 +43,7 @@ export function ActionsCellRenderer({
const exampleMenu = (
);
diff --git a/src/containers/Expenses/ExpenseForm/components.js b/src/containers/Expenses/ExpenseForm/components.js
index 417d81506..c0426d9a3 100644
--- a/src/containers/Expenses/ExpenseForm/components.js
+++ b/src/containers/Expenses/ExpenseForm/components.js
@@ -48,7 +48,10 @@ const ActionsCellRenderer = ({
};
const exampleMenu = (
);
return (
@@ -163,4 +166,4 @@ export function ExpensesExchangeRateInputField({ ...props }) {
/>
);
}
-ExpensesExchangeRateInputField.cellType = CellType.Field;
\ No newline at end of file
+ExpensesExchangeRateInputField.cellType = CellType.Field;
diff --git a/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryHeaderDimensionsProvider.js b/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryHeaderDimensionsProvider.js
index d3a9e733b..3b28d8dcf 100644
--- a/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryHeaderDimensionsProvider.js
+++ b/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryHeaderDimensionsProvider.js
@@ -18,6 +18,7 @@ function APAgingSummaryHeaderDimensionsProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
+ keepPreviousData: true,
});
// Provider
diff --git a/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryHeaderDimensionsProvider.js b/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryHeaderDimensionsProvider.js
index fdd7c278b..71ad214ec 100644
--- a/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryHeaderDimensionsProvider.js
+++ b/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryHeaderDimensionsProvider.js
@@ -18,6 +18,7 @@ function ARAgingSummaryHeaderDimensionsProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
+ keepPreviousData: true,
});
// Provider
diff --git a/src/containers/FinancialStatements/BalanceSheet/BalanceSheetHeaderDimensionsProvider.js b/src/containers/FinancialStatements/BalanceSheet/BalanceSheetHeaderDimensionsProvider.js
index aaa1fe40a..be4fae5f6 100644
--- a/src/containers/FinancialStatements/BalanceSheet/BalanceSheetHeaderDimensionsProvider.js
+++ b/src/containers/FinancialStatements/BalanceSheet/BalanceSheetHeaderDimensionsProvider.js
@@ -19,6 +19,7 @@ function BalanceSheetHeaderDimensionsProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
+ keepPreviousData: true,
});
// Provider
diff --git a/src/containers/FinancialStatements/CashFlowStatement/CashFlowStatementDimensionsPanelProvider.js b/src/containers/FinancialStatements/CashFlowStatement/CashFlowStatementDimensionsPanelProvider.js
index 9b4ac1a79..a570eda1d 100644
--- a/src/containers/FinancialStatements/CashFlowStatement/CashFlowStatementDimensionsPanelProvider.js
+++ b/src/containers/FinancialStatements/CashFlowStatement/CashFlowStatementDimensionsPanelProvider.js
@@ -10,16 +10,16 @@ const CashFlowStatementDimensionsPanelContext = React.createContext();
* cash flow statement dimensions panel provider.
* @returns
*/
-function CashFlowStatementDimensionsPanelProvider({ query,...props }) {
+function CashFlowStatementDimensionsPanelProvider({ query, ...props }) {
// Features guard.
const { featureCan } = useFeatureCan();
const isBranchFeatureCan = featureCan(Features.Branches);
// Fetches the branches list.
- const { isLoading: isBranchesLoading, data: branches } = useBranches(
- query,
- { enabled: isBranchFeatureCan },
- );
+ const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
+ enabled: isBranchFeatureCan,
+ keepPreviousData: true,
+ });
// Provider
const provider = {
diff --git a/src/containers/FinancialStatements/CashFlowStatement/components.js b/src/containers/FinancialStatements/CashFlowStatement/components.js
index 6cbd8e796..09c042a02 100644
--- a/src/containers/FinancialStatements/CashFlowStatement/components.js
+++ b/src/containers/FinancialStatements/CashFlowStatement/components.js
@@ -26,9 +26,9 @@ export const useCashFlowStatementColumns = () => {
* Cash flow statement loading bar.
*/
export function CashFlowStatementLoadingBar() {
- const { isCashFlowLoading } = useCashFlowStatementContext();
+ const { isCashFlowFetching } = useCashFlowStatementContext();
return (
-
+
);
diff --git a/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderDimensionsPanelProvider.js b/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderDimensionsPanelProvider.js
index bdc93a85c..54df09df7 100644
--- a/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderDimensionsPanelProvider.js
+++ b/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderDimensionsPanelProvider.js
@@ -19,6 +19,7 @@ function GeneralLedgerHeaderDimensionsPanelProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
+ keepPreviousData: true,
});
// Provider
diff --git a/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderGeneralPane.js b/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderGeneralPane.js
index 5aef980ec..3c196589c 100644
--- a/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderGeneralPane.js
+++ b/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderGeneralPane.js
@@ -3,7 +3,8 @@ import { FormGroup, Classes } from '@blueprintjs/core';
import { FormattedMessage as T } from 'components';
import classNames from 'classnames';
-import { AccountsMultiSelect, Row, Col } from 'components';
+import { AccountMultiSelect, Row, Col } from 'components';
+import { FFormGroup } from '../../../components/Forms';
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
import RadiosAccountingBasis from '../RadiosAccountingBasis';
@@ -44,12 +45,13 @@ function GLHeaderGeneralPaneContent() {
- }
- className={classNames('form-group--select-list', Classes.FILL)}
+ name={'accounts'}
+ className={Classes.FILL}
>
-
-
+
+
diff --git a/src/containers/FinancialStatements/GeneralLedger/common.js b/src/containers/FinancialStatements/GeneralLedger/common.js
index 8463342b1..5d97024c6 100644
--- a/src/containers/FinancialStatements/GeneralLedger/common.js
+++ b/src/containers/FinancialStatements/GeneralLedger/common.js
@@ -32,6 +32,7 @@ export const getDefaultGeneralLedgerQuery = () => {
basis: 'accural',
filterByOption: 'with-transactions',
branchesIds: [],
+ accounts: [],
};
};
diff --git a/src/containers/FinancialStatements/InventoryValuation/InventoryValuationHeaderDimensionsPanelProvider.js b/src/containers/FinancialStatements/InventoryValuation/InventoryValuationHeaderDimensionsPanelProvider.js
index 1985ffaa5..f314aae68 100644
--- a/src/containers/FinancialStatements/InventoryValuation/InventoryValuationHeaderDimensionsPanelProvider.js
+++ b/src/containers/FinancialStatements/InventoryValuation/InventoryValuationHeaderDimensionsPanelProvider.js
@@ -24,12 +24,13 @@ function InventoryValuationHeaderDimensionsProvider({ ...props }) {
// Fetches the warehouses list.
const { data: warehouses, isLoading: isWarehouesLoading } = useWarehouses(
null,
- { enabled: isWarehouseFeatureCan },
+ { enabled: isWarehouseFeatureCan, keepPreviousData: true },
);
// Fetches the branches list.
const { data: branches, isLoading: isBranchLoading } = useBranches(null, {
enabled: isBranchFeatureCan,
+ keepPreviousData: true,
});
// Provider
diff --git a/src/containers/FinancialStatements/ProfitLossSheet/ProfitLossProvider.js b/src/containers/FinancialStatements/ProfitLossSheet/ProfitLossProvider.js
index 6ae218172..447437764 100644
--- a/src/containers/FinancialStatements/ProfitLossSheet/ProfitLossProvider.js
+++ b/src/containers/FinancialStatements/ProfitLossSheet/ProfitLossProvider.js
@@ -15,9 +15,12 @@ function ProfitLossSheetProvider({ query, ...props }) {
isFetching,
isLoading,
refetch,
- } = useProfitLossSheet({
- ...transformFilterFormToQuery(query),
- });
+ } = useProfitLossSheet(
+ {
+ ...transformFilterFormToQuery(query),
+ },
+ { keepPreviousData: true },
+ );
const provider = {
profitLossSheet,
diff --git a/src/containers/FinancialStatements/ProfitLossSheet/ProfitLossSheetHeaderDimensionsProvider.js b/src/containers/FinancialStatements/ProfitLossSheet/ProfitLossSheetHeaderDimensionsProvider.js
index b1ac95e97..def49072f 100644
--- a/src/containers/FinancialStatements/ProfitLossSheet/ProfitLossSheetHeaderDimensionsProvider.js
+++ b/src/containers/FinancialStatements/ProfitLossSheet/ProfitLossSheetHeaderDimensionsProvider.js
@@ -19,6 +19,7 @@ function ProfitLossSheetHeaderDimensionsProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
+ keepPreviousData: true,
});
// Provider
diff --git a/src/containers/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetHeaderDimensionsPanelProvider.js b/src/containers/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetHeaderDimensionsPanelProvider.js
index ece357e23..3a49470e7 100644
--- a/src/containers/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetHeaderDimensionsPanelProvider.js
+++ b/src/containers/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetHeaderDimensionsPanelProvider.js
@@ -18,6 +18,7 @@ function TrialBLHeaderDimensionsPanelProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
+ keepPreviousData: true,
});
// Provider
diff --git a/src/containers/Items/ItemFormPrimarySection.js b/src/containers/Items/ItemFormPrimarySection.js
index 4e779f514..88987a2a7 100644
--- a/src/containers/Items/ItemFormPrimarySection.js
+++ b/src/containers/Items/ItemFormPrimarySection.js
@@ -47,11 +47,6 @@ export default function ItemFormPrimarySection() {
-
-
-
>
);
@@ -86,7 +81,6 @@ export default function ItemFormPrimarySection() {
disabled={!isNewMode && item.type === 'inventory'}
>
} value="service" />
- } value="non-inventory" />
} value="inventory" />
@@ -126,7 +120,11 @@ export default function ItemFormPrimarySection() {
helperText={}
inline={true}
>
-
+
)}
diff --git a/src/containers/Items/utils.js b/src/containers/Items/utils.js
index 406746786..6f3da4c94 100644
--- a/src/containers/Items/utils.js
+++ b/src/containers/Items/utils.js
@@ -64,7 +64,6 @@ export const transitionItemTypeKeyToLabel = (itemTypeKey) => {
const table = {
service: intl.get('service'),
inventory: intl.get('inventory'),
- 'non-inventory': intl.get('non_inventory'),
};
return typeof table[itemTypeKey] === 'string' ? table[itemTypeKey] : '';
};
@@ -104,6 +103,14 @@ export const handleDeleteErrors = (errors) => {
intent: Intent.DANGER,
});
}
+ if (
+ errors.find((error) => error.type === 'ITEM_HAS_ASSOCIATED_TRANSACTIONS')
+ ) {
+ AppToaster.show({
+ message: intl.get('item.error.you_could_not_delete_item_has_associated'),
+ intent: Intent.DANGER,
+ });
+ }
};
/**
diff --git a/src/containers/ItemsCategories/ItemCategoriesTable.js b/src/containers/ItemsCategories/ItemCategoriesTable.js
index 5f2436e91..305865f45 100644
--- a/src/containers/ItemsCategories/ItemCategoriesTable.js
+++ b/src/containers/ItemsCategories/ItemCategoriesTable.js
@@ -50,7 +50,7 @@ function ItemsCategoryTable({
loading={isCategoriesLoading}
headerLoading={isCategoriesLoading}
progressBarLoading={isCategoriesFetching}
- expandable={true}
+ expandable={false}
sticky={true}
selectionColumn={true}
TableLoadingRenderer={TableSkeletonRows}
diff --git a/src/containers/Purchases/Bills/BillForm/BillForm.schema.js b/src/containers/Purchases/Bills/BillForm/BillForm.schema.js
index 6f77262b2..258ad5be4 100644
--- a/src/containers/Purchases/Bills/BillForm/BillForm.schema.js
+++ b/src/containers/Purchases/Bills/BillForm/BillForm.schema.js
@@ -1,16 +1,19 @@
import * as Yup from 'yup';
+import moment from 'moment';
import intl from 'react-intl-universal';
import { DATATYPES_LENGTH } from 'common/dataTypes';
import { isBlank } from 'utils';
const BillFormSchema = Yup.object().shape({
- vendor_id: Yup.number()
- .required()
- .label(intl.get('vendor_name_')),
- bill_date: Yup.date()
- .required()
- .label(intl.get('bill_date_')),
+ vendor_id: Yup.number().required().label(intl.get('vendor_name_')),
+ bill_date: Yup.date().required().label(intl.get('bill_date_')),
due_date: Yup.date()
+ .min(Yup.ref('bill_date'), ({ path, min }) =>
+ intl.get('bill.validation.due_date', {
+ path,
+ min: moment(min).format('YYYY/MM/DD'),
+ }),
+ )
.required()
.label(intl.get('due_date_')),
bill_number: Yup.string()
@@ -25,7 +28,7 @@ const BillFormSchema = Yup.object().shape({
open: Yup.boolean(),
branch_id: Yup.string(),
warehouse_id: Yup.string(),
- exchange_rate:Yup.number(),
+ exchange_rate: Yup.number(),
entries: Yup.array().of(
Yup.object().shape({
quantity: Yup.number()
diff --git a/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormFooterLeft.js b/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormFooterLeft.js
index 700c2ba9a..1cedd9ef9 100644
--- a/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormFooterLeft.js
+++ b/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormFooterLeft.js
@@ -3,24 +3,28 @@ import intl from 'react-intl-universal';
import styled from 'styled-components';
import { FFormGroup, FEditableText, FormattedMessage as T } from 'components';
+/**
+ * Payment made form footer left-side.
+ * @returns {JSX.Element}
+ */
export function PaymentMadeFormFooterLeft() {
return (
- {/* --------- Statement--------- */}
- }
- hintText={'Will be displayed on the Payment'}
+ {/* --------- Internal Note--------- */}
+ }
>
-
+
);
}
-const StatementFormGroup = styled(FFormGroup)`
+
+const InternalNoteFormGroup = styled(FFormGroup)`
&.bp3-form-group {
margin-bottom: 40px;
diff --git a/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormProvider.js b/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormProvider.js
index af51416f8..e11f0a691 100644
--- a/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormProvider.js
+++ b/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormProvider.js
@@ -103,7 +103,7 @@ function PaymentMadeFormProvider({ query, paymentMadeId, ...props }) {
}
- hintText={'Will be displayed on the invoice'}
>
- }
+ placeholder={intl.get(
+ 'credit_note.label_terms_and_conditions.placeholder',
+ )}
/>
diff --git a/src/containers/Sales/Estimates/EstimateForm/EstimateForm.schema.js b/src/containers/Sales/Estimates/EstimateForm/EstimateForm.schema.js
index 46bd23f5f..78cc4139d 100644
--- a/src/containers/Sales/Estimates/EstimateForm/EstimateForm.schema.js
+++ b/src/containers/Sales/Estimates/EstimateForm/EstimateForm.schema.js
@@ -2,16 +2,19 @@ import * as Yup from 'yup';
import intl from 'react-intl-universal';
import { DATATYPES_LENGTH } from 'common/dataTypes';
import { isBlank } from 'utils';
+import moment from 'moment';
const Schema = Yup.object().shape({
- customer_id: Yup.number()
- .label(intl.get('customer_name_'))
- .required(),
- estimate_date: Yup.date()
- .required()
- .label(intl.get('estimate_date_')),
+ customer_id: Yup.number().label(intl.get('customer_name_')).required(),
+ estimate_date: Yup.date().required().label(intl.get('estimate_date_')),
expiration_date: Yup.date()
.required()
+ .min(Yup.ref('estimate_date'), ({ path, min }) =>
+ intl.get('estimate.validation.expiration_date', {
+ path,
+ min: moment(min).format('YYYY/MM/DD'),
+ }),
+ )
.label(intl.get('expiration_date_')),
estimate_number: Yup.string()
.max(DATATYPES_LENGTH.STRING)
diff --git a/src/containers/Sales/Invoices/InvoiceForm/InvoiceForm.schema.js b/src/containers/Sales/Invoices/InvoiceForm/InvoiceForm.schema.js
index eaedac85f..9d68c079a 100644
--- a/src/containers/Sales/Invoices/InvoiceForm/InvoiceForm.schema.js
+++ b/src/containers/Sales/Invoices/InvoiceForm/InvoiceForm.schema.js
@@ -1,4 +1,5 @@
import * as Yup from 'yup';
+import moment from 'moment';
import intl from 'react-intl-universal';
import { DATATYPES_LENGTH } from 'common/dataTypes';
import { isBlank } from 'utils';
@@ -7,7 +8,15 @@ const getSchema = () =>
Yup.object().shape({
customer_id: Yup.string().label(intl.get('customer_name_')).required(),
invoice_date: Yup.date().required().label(intl.get('invoice_date_')),
- due_date: Yup.date().required().label(intl.get('due_date_')),
+ due_date: Yup.date()
+ .min(Yup.ref('invoice_date'), ({ path, min }) =>
+ intl.get('invoice.validation.due_date', {
+ path,
+ min: moment(min).format('YYYY/MM/DD'),
+ }),
+ )
+ .required()
+ .label(intl.get('due_date_')),
invoice_no: Yup.string()
.max(DATATYPES_LENGTH.STRING)
.label(intl.get('invoice_no_')),
diff --git a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormFooterLeft.js b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormFooterLeft.js
index 426c67f94..98181f91a 100644
--- a/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormFooterLeft.js
+++ b/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormFooterLeft.js
@@ -10,7 +10,6 @@ export function InvoiceFormFooterLeft() {
}
- hintText={'Will be displayed on the invoice'}
>
}
+ label={}
name={'terms_conditions'}
>
{/* --------- Statement--------- */}
+ }
+ >
+
+
+
+ {/* --------- Internal Note--------- */}
}
- hintText={'Will be displayed on the Payment'}
+ name={'internal_note'}
+ label={}
>
@@ -32,3 +42,17 @@ const TermsConditsFormGroup = styled(FFormGroup)`
}
}
`;
+
+const PaymentMsgFormGroup = styled(FFormGroup)`
+ &.bp3-form-group {
+ margin-bottom: 40px;
+
+ .bp3-label {
+ font-size: 12px;
+ margin-bottom: 12px;
+ }
+ .bp3-form-content {
+ margin-left: 10px;
+ }
+ }
+`;
diff --git a/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormFooterLeft.js b/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormFooterLeft.js
index 4429726d0..1e9b7e8f6 100644
--- a/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormFooterLeft.js
+++ b/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormFooterLeft.js
@@ -18,16 +18,18 @@ export function ReceiptFormFooterLeft() {
/>
- {/* --------- Statement--------- */}
- }
- name={'statement'}
+ {/* --------- Terms and conditions --------- */}
+ }
+ name={'terms_conditions'}
>
-
+
);
}
@@ -46,7 +48,7 @@ const ReceiptMsgFormGroup = styled(FFormGroup)`
}
`;
-const StatementFormGroup = styled(FFormGroup)`
+const TermsConditsFormGroup = styled(FFormGroup)`
&.bp3-form-group {
.bp3-label {
font-size: 12px;
diff --git a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferForm.js b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferForm.js
index c61ce2b92..1359c6132 100644
--- a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferForm.js
+++ b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferForm.js
@@ -1,7 +1,7 @@
import React from 'react';
import intl from 'react-intl-universal';
import { Formik, Form } from 'formik';
-import { isEmpty } from 'lodash';
+import { isEmpty, sumBy } from 'lodash';
import { Intent } from '@blueprintjs/core';
import { useHistory } from 'react-router-dom';
import { CLASSES } from 'common/classes';
@@ -20,7 +20,7 @@ import WarehouseTransferFormDialog from './WarehouseTransferFormDialog';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withSettings from 'containers/Settings/withSettings';
-import { AppToaster, } from 'components';
+import { AppToaster } from 'components';
import { useWarehouseTransferFormContext } from './WarehouseTransferFormProvider';
import { compose, orderingLinesIndexes, transactionNumber } from 'utils';
import { WarehouseTransferObserveItemsCost } from './components';
@@ -119,7 +119,7 @@ function WarehouseTransferForm({
.catch(onError);
}
};
-
+
return (
-
+
diff --git a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferForm.schema.js b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferForm.schema.js
index 026bc5e20..3fab6b29a 100644
--- a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferForm.schema.js
+++ b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferForm.schema.js
@@ -20,7 +20,7 @@ const Schema = Yup.object().shape({
Yup.object().shape({
item_id: Yup.number().nullable(),
description: Yup.string().nullable().max(DATATYPES_LENGTH.TEXT),
- quantity: Yup.number().nullable().max(DATATYPES_LENGTH.INT_10),
+ quantity: Yup.number().min(1).max(DATATYPES_LENGTH.INT_10),
}),
),
});
diff --git a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormEntriesTable.js b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormEntriesTable.js
index b4336cb13..09e8f5990 100644
--- a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormEntriesTable.js
+++ b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormEntriesTable.js
@@ -45,7 +45,7 @@ export default function WarehouseTransferFormEntriesTable({
item_id: newRowMeta.itemId,
warehouses: newRowMeta.warehouses,
description: '',
- quantity: 0,
+ quantity: '',
};
const newRows = mutateTableRow(newRowMeta.rowIndex, newRow, entries);
diff --git a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormFooterLeft.js b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormFooterLeft.js
index c09d7db5e..4f3edc6ec 100644
--- a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormFooterLeft.js
+++ b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormFooterLeft.js
@@ -1,5 +1,6 @@
import React from 'react';
import styled from 'styled-components';
+import intl from 'react-intl-universal';
import { FFormGroup, FEditableText, FormattedMessage as T } from 'components';
export function WarehouseTransferFormFooterLeft() {
@@ -7,14 +8,12 @@ export function WarehouseTransferFormFooterLeft() {
{/* --------- Terms and conditions --------- */}
}
+ label={}
name={'reason'}
>
diff --git a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormHeader.js b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormHeader.js
index 3137b1e99..7a6ebc57a 100644
--- a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormHeader.js
+++ b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormHeader.js
@@ -1,7 +1,5 @@
import React from 'react';
import classNames from 'classnames';
-import { useFormikContext } from 'formik';
-import intl from 'react-intl-universal';
import { CLASSES } from 'common/classes';
import WarehouseTransferFormHeaderFields from './WarehouseTransferFormHeaderFields';
diff --git a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormHeaderFields.js b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormHeaderFields.js
index 038d99a8a..acebd4c14 100644
--- a/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormHeaderFields.js
+++ b/src/containers/WarehouseTransfers/WarehouseTransferForm/WarehouseTransferFormHeaderFields.js
@@ -183,20 +183,6 @@ function WarehouseTransferFormHeaderFields({
)}
- {/*------------ reason -----------*/}
-
- {({ field, meta: { error, touched } }) => (
- }
- className={'form-group--reason'}
- intent={inputIntent({ error, touched })}
- inline={true}
- helperText={}
- >
-
-
- )}
-
);
}
diff --git a/src/containers/WarehouseTransfers/utils.js b/src/containers/WarehouseTransfers/utils.js
index cc118fdd7..638a55a22 100644
--- a/src/containers/WarehouseTransfers/utils.js
+++ b/src/containers/WarehouseTransfers/utils.js
@@ -21,7 +21,10 @@ export function ActionsCellRenderer({
const exampleMenu = (
);
diff --git a/src/hooks/query/bills.js b/src/hooks/query/bills.js
index 24806a3b6..e4421761d 100644
--- a/src/hooks/query/bills.js
+++ b/src/hooks/query/bills.js
@@ -33,6 +33,9 @@ const commonInvalidateQueries = (queryClient) => {
// Invalidate items associated bills transactions.
queryClient.invalidateQueries(t.ITEMS_ASSOCIATED_WITH_BILLS);
+
+ // Invalidate item warehouses.
+ queryClient.invalidateQueries(t.ITEM_WAREHOUSES_LOCATION);
};
/**
diff --git a/src/hooks/query/index.js b/src/hooks/query/index.js
index 1d4fa2f8d..4fe11e9b7 100644
--- a/src/hooks/query/index.js
+++ b/src/hooks/query/index.js
@@ -33,5 +33,6 @@ export * from './roles';
export * from './creditNote';
export * from './vendorCredit';
export * from './transactionsLocking';
-export * from './warehouses'
+export * from './warehouses';
export * from './branches';
+export * from './warehousesTransfers';
diff --git a/src/hooks/query/invoices.js b/src/hooks/query/invoices.js
index 39513148b..ef6679313 100644
--- a/src/hooks/query/invoices.js
+++ b/src/hooks/query/invoices.js
@@ -34,6 +34,9 @@ const commonInvalidateQueries = (queryClient) => {
// Invalidate
queryClient.invalidateQueries(t.ITEM_ASSOCIATED_WITH_INVOICES);
+
+ // Invalidate item warehouses.
+ queryClient.invalidateQueries(t.ITEM_WAREHOUSES_LOCATION);
};
/**
diff --git a/src/hooks/query/receipts.js b/src/hooks/query/receipts.js
index c2cbeaa22..725e9fecb 100644
--- a/src/hooks/query/receipts.js
+++ b/src/hooks/query/receipts.js
@@ -27,6 +27,9 @@ const commonInvalidateQueries = (queryClient) => {
// Invalidate
queryClient.invalidateQueries(t.ITEM_ASSOCIATED_WITH_RECEIPTS);
+ // Invalidate item warehouses.
+ queryClient.invalidateQueries(t.ITEM_WAREHOUSES_LOCATION);
+
// Invalidate the settings.
queryClient.invalidateQueries([t.SETTING, t.SETTING_RECEIPTS]);
};
diff --git a/src/hooks/query/warehouses.js b/src/hooks/query/warehouses.js
index acea73d4a..b2cd0eaea 100644
--- a/src/hooks/query/warehouses.js
+++ b/src/hooks/query/warehouses.js
@@ -12,7 +12,6 @@ const commonInvalidateQueries = (queryClient) => {
// Invalidate warehouses transfers.
queryClient.invalidateQueries(t.WAREHOUSE_TRANSFERS);
- // queryClient.invalidateQueries(t.WAREHOUSE_TRANSFER);
queryClient.invalidateQueries(t.DASHBOARD_META);
};
@@ -105,164 +104,6 @@ export function useWarehouse(id, props, requestProps) {
);
}
-/**
- * Create a new warehouse transfer.
- */
-export function useCreateWarehouseTransfer(props) {
- const queryClient = useQueryClient();
- const apiRequest = useApiRequest();
-
- return useMutation(
- (values) => apiRequest.post('warehouses/transfers', values),
- {
- onSuccess: (res, values) => {
- // Common invalidate queries.
- commonInvalidateQueries(queryClient);
- },
- ...props,
- },
- );
-}
-
-/**
- * Edits the given warehouse transfer.
- */
-export function useEditWarehouseTransfer(props) {
- const queryClient = useQueryClient();
- const apiRequest = useApiRequest();
-
- return useMutation(
- ([id, values]) => apiRequest.post(`warehouses/transfers/${id}`, values),
- {
- onSuccess: (res, [id, values]) => {
- // Invalidate specific sale invoice.
- queryClient.invalidateQueries([t.WAREHOUSE_TRANSFER, id]);
-
- // Common invalidate queries.
- commonInvalidateQueries(queryClient);
- },
- ...props,
- },
- );
-}
-
-/**
- * Deletes the given warehouse Transfer.
- */
-export function useDeleteWarehouseTransfer(props) {
- const queryClient = useQueryClient();
- const apiRequest = useApiRequest();
-
- return useMutation((id) => apiRequest.delete(`warehouses/transfers/${id}`), {
- onSuccess: (res, id) => {
- // Common invalidate queries.
- commonInvalidateQueries(queryClient);
- },
- ...props,
- });
-}
-
-const transformWarehousesTransfer = (res) => ({
- warehousesTransfers: res.data.data,
- pagination: transformPagination(res.data.pagination),
- filterMeta: res.data.filter,
-});
-
-/**
- * Retrieve Warehoues list.
- */
-export function useWarehousesTransfers(query, props) {
- return useRequestQuery(
- [t.WAREHOUSE_TRANSFERS, query],
- { method: 'get', url: 'warehouses/transfers', params: query },
- {
- select: transformWarehousesTransfer,
- defaultData: {
- warehousesTransfers: [],
- pagination: {
- page: 1,
- pageSize: 20,
- total: 0,
- },
- filterMeta: {},
- },
- ...props,
- },
- );
-}
-
-/**
- * Retrieve the warehouse transfer details.
- * @param {number}
- */
-export function useWarehouseTransfer(id, props, requestProps) {
- return useRequestQuery(
- [t.WAREHOUSE_TRANSFER, id],
- { method: 'get', url: `warehouses/transfers/${id}`, ...requestProps },
- {
- select: (res) => res.data.data,
- defaultData: {},
- ...props,
- },
- );
-}
-
-/**
- *
- * @param {*} props
- * @returns
- */
-export function useInitiateWarehouseTransfer(props) {
- const queryClient = useQueryClient();
- const apiRequest = useApiRequest();
-
- return useMutation(
- (id) => apiRequest.put(`warehouses/transfers/${id}/initiate`),
- {
- onSuccess: (res, id) => {
- queryClient.invalidateQueries([t.WAREHOUSE_TRANSFER, id]);
-
- // Common invalidate queries.
- commonInvalidateQueries(queryClient);
- },
- ...props,
- },
- );
-}
-
-/**
- *
- * @param {*} props
- * @returns
- */
-export function useTransferredWarehouseTransfer(props) {
- const queryClient = useQueryClient();
- const apiRequest = useApiRequest();
-
- return useMutation(
- (id) => apiRequest.put(`warehouses/transfers/${id}/transferred`),
- {
- onSuccess: (res, id) => {
- queryClient.invalidateQueries([t.WAREHOUSE_TRANSFER, id]);
-
- // Common invalidate queries.
- commonInvalidateQueries(queryClient);
- },
- ...props,
- },
- );
-}
-
-export function useRefreshWarehouseTransfers() {
- const queryClient = useQueryClient();
-
- return {
- refresh: () => {
- queryClient.invalidateQueries(t.WAREHOUSE_TRANSFERS);
- },
- };
-}
-
/**
* Activate the given warehouse.
*/
diff --git a/src/hooks/query/warehousesTransfers.js b/src/hooks/query/warehousesTransfers.js
new file mode 100644
index 000000000..414201183
--- /dev/null
+++ b/src/hooks/query/warehousesTransfers.js
@@ -0,0 +1,172 @@
+import { useQueryClient, useMutation } from 'react-query';
+import { transformPagination } from 'utils';
+import { useRequestQuery } from '../useQueryRequest';
+import useApiRequest from '../useRequest';
+import t from './types';
+
+// Common invalidate queries.
+const commonInvalidateQueries = (queryClient) => {
+ // Invalidate warehouses transfers.
+ queryClient.invalidateQueries(t.WAREHOUSE_TRANSFERS);
+
+ // Invalidate item warehouses.
+ queryClient.invalidateQueries(t.ITEM_WAREHOUSES_LOCATION);
+};
+
+/**
+ * Create a new warehouse transfer.
+ */
+export function useCreateWarehouseTransfer(props) {
+ const queryClient = useQueryClient();
+ const apiRequest = useApiRequest();
+
+ return useMutation(
+ (values) => apiRequest.post('warehouses/transfers', values),
+ {
+ onSuccess: (res, values) => {
+ // Common invalidate queries.
+ commonInvalidateQueries(queryClient);
+ },
+ ...props,
+ },
+ );
+}
+
+/**
+ * Edits the given warehouse transfer.
+ */
+export function useEditWarehouseTransfer(props) {
+ const queryClient = useQueryClient();
+ const apiRequest = useApiRequest();
+
+ return useMutation(
+ ([id, values]) => apiRequest.post(`warehouses/transfers/${id}`, values),
+ {
+ onSuccess: (res, [id, values]) => {
+ // Invalidate specific sale invoice.
+ queryClient.invalidateQueries([t.WAREHOUSE_TRANSFER, id]);
+
+ // Common invalidate queries.
+ commonInvalidateQueries(queryClient);
+ },
+ ...props,
+ },
+ );
+}
+
+/**
+ * Deletes the given warehouse Transfer.
+ */
+export function useDeleteWarehouseTransfer(props) {
+ const queryClient = useQueryClient();
+ const apiRequest = useApiRequest();
+
+ return useMutation((id) => apiRequest.delete(`warehouses/transfers/${id}`), {
+ onSuccess: (res, id) => {
+ // Common invalidate queries.
+ commonInvalidateQueries(queryClient);
+ },
+ ...props,
+ });
+}
+
+const transformWarehousesTransfer = (res) => ({
+ warehousesTransfers: res.data.data,
+ pagination: transformPagination(res.data.pagination),
+ filterMeta: res.data.filter,
+});
+
+/**
+ * Retrieve Warehoues list.
+ */
+export function useWarehousesTransfers(query, props) {
+ return useRequestQuery(
+ [t.WAREHOUSE_TRANSFERS, query],
+ { method: 'get', url: 'warehouses/transfers', params: query },
+ {
+ select: transformWarehousesTransfer,
+ defaultData: {
+ warehousesTransfers: [],
+ pagination: {
+ page: 1,
+ pageSize: 20,
+ total: 0,
+ },
+ filterMeta: {},
+ },
+ ...props,
+ },
+ );
+}
+
+/**
+ * Retrieve the warehouse transfer details.
+ * @param {number}
+ */
+export function useWarehouseTransfer(id, props, requestProps) {
+ return useRequestQuery(
+ [t.WAREHOUSE_TRANSFER, id],
+ { method: 'get', url: `warehouses/transfers/${id}`, ...requestProps },
+ {
+ select: (res) => res.data.data,
+ defaultData: {},
+ ...props,
+ },
+ );
+}
+
+/**
+ *
+ * @param {*} props
+ * @returns
+ */
+export function useInitiateWarehouseTransfer(props) {
+ const queryClient = useQueryClient();
+ const apiRequest = useApiRequest();
+
+ return useMutation(
+ (id) => apiRequest.put(`warehouses/transfers/${id}/initiate`),
+ {
+ onSuccess: (res, id) => {
+ queryClient.invalidateQueries([t.WAREHOUSE_TRANSFER, id]);
+
+ // Common invalidate queries.
+ commonInvalidateQueries(queryClient);
+ },
+ ...props,
+ },
+ );
+}
+
+/**
+ *
+ * @param {*} props
+ * @returns
+ */
+export function useTransferredWarehouseTransfer(props) {
+ const queryClient = useQueryClient();
+ const apiRequest = useApiRequest();
+
+ return useMutation(
+ (id) => apiRequest.put(`warehouses/transfers/${id}/transferred`),
+ {
+ onSuccess: (res, id) => {
+ queryClient.invalidateQueries([t.WAREHOUSE_TRANSFER, id]);
+
+ // Common invalidate queries.
+ commonInvalidateQueries(queryClient);
+ },
+ ...props,
+ },
+ );
+}
+
+export function useRefreshWarehouseTransfers() {
+ const queryClient = useQueryClient();
+
+ return {
+ refresh: () => {
+ queryClient.invalidateQueries(t.WAREHOUSE_TRANSFERS);
+ },
+ };
+}
diff --git a/src/lang/ar/index.json b/src/lang/ar/index.json
index 741050853..16a9b5723 100644
--- a/src/lang/ar/index.json
+++ b/src/lang/ar/index.json
@@ -1360,6 +1360,7 @@
"item.field.sell_account.hint": "أدخل السعر الذي ستبيعه لهذا العنصر.",
"item_entries.products_services.hint": "أدخل المنتجات أو الخدمات التي تبيعها أو تشتريها لتتبع ما قمت ببيعه أو شرائه.",
"item_entries.landed.hint": "يتيح لك هذه الخيار إمكانية إضافة تكلفة اضافية علي فاتورة الشراء متال علي ذلك تكاليف الشحن ، ثم تحديد هذه التكلفة لتحميلها علي فاتورة الشراء.",
+ "item_entries.remove_row": "حذف الصف",
"invoice.auto_increment.auto": "يتم تعيين أرقام الفواتير على وضع الزيادة التلقائي. هل أنت متأكد من تغيير هذا الإعداد؟",
"invoice.auto_increment.manually": "يتم تعيين أرقام فواتيرك يدوياً. هل أنت متأكد من تغيير هذه الإعدادات؟",
"manual_journals.auto_increment.auto": "يتم تعيين أرقام القيود على وضع الزيادة التلقائي. هل أنت متأكد من تغيير هذا الإعداد؟",
@@ -1797,13 +1798,10 @@
"profit_loss_sheet.percentage_of_row": "% التغير الأفقي",
"profit_loss_sheet.percentage_of_expense": "% التغير في المصاريف",
"profit_loss_sheet.percentage_of_income": "% التغير الإيرادات",
-
"report.balance_sheet_comparison.title": "مقارنة الميزانية العمومية",
"report.balance_sheet_comparison.desc": "يعرض أصول الشركة والتزاماتها وحقوق المساهمين في نقطة زمنية محددة مقارنة بالسنة الماضية.",
-
"report.profit_loss_sheet_comparison.title": "مقارنة قائمة الدخل",
"report.profit_loss_sheet_comparison.desc": "يعرض الإيرادات والتكاليف والمصاريف المتكبدة في نقطة محددة ومقارنة بالعام السابق.",
-
"warehouse_locations.label": "المخازن",
"warehouse_locations.column.warehouse_name": "اسم المخزن",
"warehouse_locations.column.quantity": "الكمية",
@@ -1852,6 +1850,7 @@
"warehouse_transfer.column.transfer_quantity": "الكمية ",
"warehouse_transfer.column.source_warehouse": "المصدر",
"warehouse_transfer.column.destination_warehouse": "الوجهة",
+ "warehouse_transfer.column.cost_price": "سعر التكلفة",
"warehouse_transfer.auto_increment.auto": "يتم تعيين أرقام النقل على وضع الزيادة التلقائي. هل أنت متأكد من تغيير هذا الإعداد؟",
"warehouse_transfer.auto_increment.manually": "يتم تعيين أرقام النقل يدوياً. هل أنت متأكد من تغيير هذه الإعدادات؟",
"warehouse_transfer.setting_your_auto_generated_transfer_no": "تعيين رقم النقل الذي تم إنشاؤه تلقائيًا",
@@ -2008,6 +2007,17 @@
"estimate.warehouse_button.label": "المخزن: {label}",
"receipt.branch_button.label": "الفرع: {label}",
"receipt.warehouse_button.label": "المخزن: {label}",
- "warehouse_transfer.empty_status.title": "",
- "warehouse_transfer.empty_status.description": ""
+ "warehouse_transfer.empty_status.title": "إدارة عمليات النقل بين المخازن",
+ "warehouse_transfer.empty_status.description": "غالبًا ماتحتاج الاعمال ذات مخازن متعددة لطلبات نقل البضائع من مخزن إلى آخر عندما تكون في حاجة ماسة إلى البائعين.",
+ "warehouse_transfer.form.reason.label": "أسباب النقل",
+ "warehouse_transfer.form.reason.placeholder": "Enter the reason behind the transfer order.",
+ "item.error.you_could_not_delete_item_has_associated": "لا يمكنك حذف العنصر لديه معاملات مرتبطة به ",
+ "warehouse_transfer.quantity_cannot_be_zero_or_empty": "لا يمكن أن تكون الكمية صفراً أو فارغة.",
+ "invoice.validation.due_date": "يجب أن يكون حقل {path} في وقت لاحق من {min}",
+ "estimate.validation.expiration_date": "يجب أن يكون حقل {path} في وقت لاحق من {min}",
+ "make_journal.entries.remove_row": "حذف الصف",
+ "expense.entries.remove_row": "حذف الصف",
+ "warehouse_transfer.entries.remove_row": "حذف الصف",
+ "item.details.inactive": "غير نشط",
+ "bill.validation.due_date": "يجب أن يكون حقل {path} في وقت لاحق من {min}"
}
\ No newline at end of file
diff --git a/src/lang/en/index.json b/src/lang/en/index.json
index 937c7936c..3d4760696 100644
--- a/src/lang/en/index.json
+++ b/src/lang/en/index.json
@@ -1163,7 +1163,7 @@
"sorry_about_that_something_went_wrong": "Sorry about that! Something went wrong",
"if_the_problem_stuck_please_contact_us_as_soon_as_possible": "If the problem stuck, please contact us as soon as possible.",
"non-inventory": "Non-Inventory",
- "terms_conditions": "Terms conditions",
+ "terms_conditions": "Terms & Conditions",
"inventory_adjustment.publish.success_message": "The inventory adjustment has been published successfully.",
"inventory_adjustment.publish.alert_message": "Are you sure you want to publish this inventory adjustment?",
"the_contact_has_been_activated_successfully": "The contact has been inactivated successfully.",
@@ -1337,6 +1337,7 @@
"item.field.sell_account.hint": "Enter price which you goint to sell this item.",
"item_entries.products_services.hint": "Enter products or services you sell or buy to keep tracking what your sold or purchased.",
"item_entries.landed.hint": "This options allows you to be able to add additional cost eg. freight then allocate cost to the items in your bills.",
+ "item_entries.remove_row": "Remove line",
"invoice.auto_increment.auto": "Your invoice numbers are set on auto-increment mode. Are you sure changing this setting?",
"invoice.auto_increment.manually": "Your invoice numbers are set on manual mode. Are you sure chaning this settings?",
"manual_journals.auto_increment.auto": "Your Jouranl numbers are set on auto-increment mode. Are you sure changing this setting?",
@@ -1439,6 +1440,7 @@
"AP_aging_summary.filter_options.label": "Filter vendors",
"item.error.type_cannot_change_with_item_has_transactions": "Cannot change item type to inventory with item has associated transactions.",
"item.error.cannot_change_inventory_account": "Cannot change item inventory account while the item has transactions.",
+ "item.error.you_could_not_delete_item_has_associated": "You could not delete item that has associated transactions",
"customer.link.customer_details": "Customer details ({amount})",
"bad_debt.dialog.written_off_amount": "Written-off amount",
"bad_debt.dialog.bad_debt": "Bad debt",
@@ -1523,10 +1525,10 @@
"credit_note.label_credit_note": "Credit Note #",
"credit_note.label_amount_to_credit": "Amount to credit",
"credit_note.label_credit_note_details": "Credit Note details",
- "credit_note.label_customer_note": "Customer note",
- "credit_note.label_terms_conditions": "Terms conditions",
- "credit_note.label_customer_note.placeholder": "Thanks for your business and have a great day!",
- "credit_note.label_terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed in your transaction",
+ "credit_note.label_customer_note": "Customer Note",
+ "credit_note.label_terms_conditions": "Terms & Conditions",
+ "credit_note.label_customer_note.placeholder": "This message will be displayed on the credit note.",
+ "credit_note.label_terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed on the credit note.",
"credit_note.label_total": "TOTAL",
"credit_note.label_subtotal": "Subtotal",
"credit_note.once_delete_this_credit_note": "Once you delete this credit note, you won't be able to restore it later. Are you sure you want to delete this credit note?",
@@ -1756,6 +1758,7 @@
"payment_made.drawer.subtitle": "Branch: {value}",
"manual_journal.drawer.title": "Manual journal details ({number})",
"expense.drawer.title": "Expense details",
+ "expense.drawer.subtitle": "Branch: {value}",
"global_error.you_dont_have_permissions": "You do not have permissions to access this page.",
"global_error.transactions_locked": "Transactions before {lockedToDate} has been locked. Hence action cannot be performed.",
"global_error.authorized_user_inactive": "The authorized user is inactive.",
@@ -1777,13 +1780,10 @@
"profit_loss_sheet.percentage_of_row": "% of Row",
"profit_loss_sheet.percentage_of_expense": "% of Expense",
"profit_loss_sheet.percentage_of_income": "% of Income",
-
"report.balance_sheet_comparison.title": "Balance Sheet Comparison",
"report.balance_sheet_comparison.desc": "Reports a company's assets, liabilities and shareholders' equity compared to previous year.",
-
"report.profit_loss_sheet_comparison.title": "Profit/Loss Comparison",
"report.profit_loss_sheet_comparison.desc": "Reports the revenues, costs and expenses incurred at a specific point and compared to previous year.",
-
"the_vendor_has_been_inactivated_successfully": "The contact has been inactivated successfully.",
"vendor.alert.activated_message": "The vendor has been activated successfully.",
"vendor.alert.are_you_sure_want_to_inactivate_this_vendor": "Are you sure want to inactivate this vendor? You will to able to activate it later.",
@@ -1795,7 +1795,6 @@
"customer.alert.are_you_sure_want_to_inactivate_this_customer": "Are you sure want to inactivate this customer? You will to able to activate it later.",
"credit_note_preview.dialog.title": "Credit Note PDF Preview",
"payment_receive_preview.dialog.title": "Payment Receive PDF Preview",
-
"warehouses.label": "Warehouses",
"warehouses.label.new_warehouse": "New Warehouse",
"warehouse.dialog.label.new_warehouse": "New Warehouse",
@@ -1949,42 +1948,47 @@
"estimate_form.label.total": "TOTAL",
"estimate_form.label.subtotal": "Subtotal",
"estimate_form.label.customer_note": "Customer Note",
- "estimate_form.label.terms_conditions": "Terms conditions",
- "estimate_form.customer_note.placeholder": "Thanks for your business and have a great day!",
- "estimate_form.terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed in your transaction",
+ "estimate_form.label.terms_conditions": "Terms & Conditions",
+ "estimate_form.customer_note.placeholder": "This message will be displayed on the estimate.",
+ "estimate_form.terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed on the estimate.",
"invoice_form.label.total": "TOTAL",
"invoice_form.label.subtotal": "Subtotal",
"invoice_form.label.due_amount": "Due amount",
"invoice_form.label.payment_amount": "Payment amount",
"invoice_form.label.invoice_message": "Invoice Message",
- "invoice_form.invoice_message.placeholder": "Thanks for your business and have a great day!",
- "invoice_form.terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed in your transaction",
+ "invoice_form.label.terms_conditions": "Terms & Conditions",
+ "invoice_form.invoice_message.placeholder": "This message will be displayed on the invoice.",
+ "invoice_form.terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed on the invoice.",
"receipt_form.label.total": "TOTAL",
"receipt_form.label.subtotal": "Subtotal",
"receipt_form.label.due_amount": "Due amount",
"receipt_form.label.payment_amount": "Payment amount",
"receipt_form.label.receipt_message": "Receipt Message",
- "receipt_form.receipt_message.placeholder": "Thanks for your business and have a great day!",
- "receipt_form.label.statement": "Statement",
- "receipt_form.statement.placeholder": "Thanks for your business and have a great day!",
- "payment_receive_form.label.statement": "Statement",
- "payment_receive_form.statement.placeholder": "Thanks for your business and have a great day!",
+ "receipt_form.receipt_message.placeholder": "This message will be displayed on the receipt.",
+ "receipt_form.label.terms_conditions": "Terms & Conditions",
+ "receipt_form.terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed on the receipt.",
+ "payment_receive_form.label.note": "Note",
+ "payment_receive_form.internal_note.placeholder": "Internal notes (Not visible to the customer).",
+ "payment_receive_form.message.label": "Payment Message",
+ "payment_receive_form.message.placeholder": "This message will be displayed on the payment receipt.",
"payment_receive_form.label.subtotal": "Subtotal",
"payment_receive_form.label.total": "TOTAL",
"bill_form.label.note": "Note",
- "bill_form.label.note.placeholder": "Enter the terms and conditions of your business to be displayed in your transaction",
+ "bill_form.label.note.placeholder": "Internal note (Not visible to the vendor).",
"bill_form.label.subtotal": "Subtotal",
"bill_form.label.total": "TOTAL",
"bill_form.label.due_amount": "Due amount",
"bill_form.label.payment_amount": "Payment amount",
"vendor_credit_form.label.note": "Note",
- "vendor_credit_form.note.placeholder": "Enter the terms and conditions of your business to be displayed in your transaction",
+ "vendor_credit_form.note.placeholder": "Internal note (Not visible to the vendor).",
"vendor_credit_form.label.subtotal": "Subtotal",
"vendor_credit_form.label.total": "TOTAL",
"payment_made_form.label.statement": "Statement",
"payment_made_form.statement.placeholder": "Thanks for your business and have a great day!",
"payment_made_form.label.subtotal": "Subtotal",
"payment_made_form.label.total": "TOTAL",
+ "payment_made.form.internal_note.label": "Note",
+ "payment_made.form.internal_note.placeholder": "Internal note (Not visible to the vendor).",
"make_journal.label.subtotal": "Subtotal",
"make_journal.label.total": "TOTAL",
"expense.label.subtotal": "Subtotal",
@@ -2003,6 +2007,16 @@
"estimate.warehouse_button.label": "Warehouse: {label}",
"receipt.branch_button.label": "Branch: {label}",
"receipt.warehouse_button.label": "Warehouse: {label}",
- "warehouse_transfer.empty_status.title": "",
- "warehouse_transfer.empty_status.description": ""
+ "warehouse_transfer.empty_status.title": "Manage transfer orders between warehouses.",
+ "warehouse_transfer.empty_status.description": "Business with multiply warehouses often transfers items from on warehouse to another when they are in immediate need of vendors.",
+ "warehouse_transfer.form.reason.label": "Reason",
+ "warehouse_transfer.form.reason.placeholder": "Enter the reason behind the transfer order.",
+ "warehouse_transfer.quantity_cannot_be_zero_or_empty": "Quantity cannot be zero or empty.",
+ "invoice.validation.due_date": "{path} field must be later than {min}",
+ "estimate.validation.expiration_date": "{path} field must be later than {min}",
+ "make_journal.entries.remove_row": "Remove line",
+ "expense.entries.remove_row": "Remove line",
+ "warehouse_transfer.entries.remove_row": "Remove line",
+ "item.details.inactive": "Inactive",
+ "bill.validation.due_date": "{path} field must be later than {min}"
}
\ No newline at end of file