Compare commits

..

70 Commits

Author SHA1 Message Date
a.bouhuolia
682b296f7c fix(FlexGrid): BIG-378 Reports drawers columns css conflict. 2022-04-15 22:33:08 +02:00
Ahmed Bouhuolia
e662bf7af9 Update CHANGELOG.md 2022-04-15 06:34:18 +02:00
a.bouhuolia
a829ceb709 Merge branch 'develop' into main 2022-04-15 06:29:34 +02:00
a.bouhuolia
cdce00187b Merge branch 'feature/tooltip-oneline' into develop 2022-04-15 06:26:42 +02:00
a.bouhuolia
91a38b34cc feat: add readonly entriese details as oneline with tooltip for more details. 2022-04-15 06:24:24 +02:00
a.bouhuolia
1b97a162e8 Merge branch 'BIG-entries-columns' of https://github.com/bigcapitalhq/client into develop 2022-04-15 04:36:08 +02:00
elforjani13
e8e12e63ea feat: add tooltip cell to detail. 2022-04-10 13:46:05 +02:00
elforjani13
80feba6005 feat(sales/purchases): add tooltip cell to detail. 2022-04-09 02:04:31 +02:00
elforjani13
cc457e1e43 feat: estimate tooltip. 2022-04-09 00:42:34 +02:00
a.bouhuolia
2ced5dc013 feat(TextOverlayTooltip): WIP 2022-04-08 06:04:12 +02:00
Ahmed Bouhuolia
dd86c2993e Merge pull request #50 from bigcapitalhq/BIG-372-activate-branches-and-warehouses-dialog-reloading-once-activating
BIG-372: activate branches & warehouses reloading.
2022-04-08 05:21:31 +02:00
a.bouhuolia
bd05a4a188 fix(GeneralLedger): BIG-373 Issue general ledger report select specific account. 2022-04-08 05:19:11 +02:00
elforjani13
8160cbe402 feat: add entries-columns. 2022-04-06 16:52:44 +02:00
elforjani13
0ef6bebfb8 BIG-372: activate branches & warehouses reloading. 2022-04-06 15:00:30 +02:00
a.bouhuolia
91ff3fdccb Merge branch 'main' into develop 2022-04-05 06:08:54 +02:00
a.bouhuolia
edd37fff78 fix(PaymaentViaVocher): make the plan is fixed. 2022-04-05 06:06:02 +02:00
a.bouhuolia
679f7ce96c Merge branch 'develop' into main 2022-04-05 05:27:28 +02:00
Ahmed Bouhuolia
79b3ab9ec7 Update CHANGELOG.md 2022-04-05 05:26:48 +02:00
a.bouhuolia
e7158b7ba7 feat(i18n): add the missing arabic localization. 2022-04-05 05:25:26 +02:00
Ahmed Bouhuolia
569bc1c4a4 Merge pull request #49 from bigcapitalhq/billingplans
Billingplans
2022-04-05 05:16:28 +02:00
elforjani13
b880732087 feat: add billing plans. 2022-04-04 23:52:29 +02:00
elforjani13
b1e7720bd9 BIG-378: add Localize to invoice. 2022-04-04 17:58:39 +02:00
a.bouhuolia
5eb9968095 Merge branch 'develop' into main 2022-03-31 15:09:25 +02:00
Ahmed Bouhuolia
b0cf8f723f Merge pull request #47 from bigcapitalhq/BIG-354-validate-the-warehouse-transfer-quantity-should-be-above-zero
BIG-354: Validate the warehouse transfer.
2022-03-31 15:05:34 +02:00
Ahmed Bouhuolia
b0a826e62a Merge branch 'develop' into BIG-354-validate-the-warehouse-transfer-quantity-should-be-above-zero 2022-03-31 15:05:27 +02:00
elforjani13
6daa9f09a5 BIG-354: fix validate the warehouse transfer. 2022-03-31 14:58:36 +02:00
Ahmed Bouhuolia
f828d85880 Merge pull request #45 from bigcapitalhq/BIG-344-add-branch-details-to-manual-journal-and-expense-drawer-details
BIG-344: add branch to manual journal & expense.
2022-03-31 14:56:35 +02:00
elforjani13
46d895bef9 BIG-354: Validate the warehouse transfer. 2022-03-31 14:50:40 +02:00
Ahmed Bouhuolia
1fa26c7cb7 Merge pull request #46 from bigcapitalhq/BIG-278-fix-created-at-in-expense-details
BIG-278: add created_at in expense details.
2022-03-31 14:30:21 +02:00
a.bouhuolia
41d2fc63cb chore(Changelog): add the missing logs. 2022-03-31 14:08:22 +02:00
a.bouhuolia
4814a40fa9 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-03-31 14:07:21 +02:00
a.bouhuolia
b903aa3eb2 dump v1.7.2 version with changelogs. 2022-03-31 14:07:17 +02:00
elforjani13
872b98fb0d BIG-278: add created_at in expense details. 2022-03-31 13:57:07 +02:00
elforjani13
b849bfaa95 BIG-344: add branch to manual journal & expense. 2022-03-31 13:39:15 +02:00
Ahmed Bouhuolia
756af3c4d3 Merge pull request #43 from bigcapitalhq/BIG-141-add-inactive-status-to-item-drawer-details
Big 141 add inactive status to item drawer details
2022-03-31 00:52:51 +02:00
Ahmed Bouhuolia
b935d13918 Merge branch 'develop' into BIG-141-add-inactive-status-to-item-drawer-details 2022-03-31 00:52:41 +02:00
Ahmed Bouhuolia
4aea9cb19b Merge pull request #41 from bigcapitalhq/BIG-356-add-localize-remove-line-entries
Big 356 add localize remove line entries
2022-03-31 00:51:38 +02:00
Ahmed Bouhuolia
d22212e6e3 Merge branch 'develop' into BIG-356-add-localize-remove-line-entries 2022-03-31 00:51:28 +02:00
Ahmed Bouhuolia
6a6ff16c48 Merge pull request #44 from bigcapitalhq/BIG-238-validate-bill-due-date-should-be-equal-or-bigger-than-bill-date
Big 238 validate bill due date should be equal or bigger than bill date
2022-03-31 00:49:31 +02:00
Ahmed Bouhuolia
d08894820d Merge pull request #39 from bigcapitalhq/BIG-354-validate-the-warehouse-transfer-quantity-should-be-above-zero
BIG-354: warehouse transfer validate.
2022-03-31 00:49:07 +02:00
elforjani13
2db32b8ee8 BIG-141: add inactive status to item details. 2022-03-30 17:17:23 +02:00
elforjani13
86c6de361b BIG-356: add localize remove line entries. 2022-03-30 16:34:51 +02:00
elforjani13
9bd13b0d46 BIG-355: remove expandable in item categories. 2022-03-30 16:31:34 +02:00
elforjani13
30b17d697f BIG-355: remove expandable in item categories. 2022-03-30 16:28:42 +02:00
elforjani13
ce674466fe BIG-238: Validate bill due date. 2022-03-30 15:09:11 +02:00
elforjani13
373a695c4c BIG-236: Validate estimate expiration date. 2022-03-30 15:06:58 +02:00
elforjani13
3f4ffdc995 BIG-237: Validate invoice due date. 2022-03-30 15:04:55 +02:00
elforjani13
a9c2a5c5f0 BIG-354: warehouse transfer validate. 2022-03-28 21:38:56 +02:00
a.bouhuolia
908d232cb9 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-03-28 19:26:09 +02:00
a.bouhuolia
10af33f1dc fix: BIG-352 Add terms and conditions/notes field to a warehouse transfer. 2022-03-28 19:25:06 +02:00
a.bouhuolia
767d807490 fix: BIG-352 Add terms and conditions/notes field to a warehouse transfer. 2022-03-28 19:06:38 +02:00
Ahmed Bouhuolia
ba1d945dca Merge pull request #38 from bigcapitalhq/BIG-284-cash-flow-statement-loading-bar-not-working
BIG-284: cash flow statement loading bar.
2022-03-28 16:23:42 +02:00
elforjani13
03ea8643e7 BIG-284: cash flow statment loading bar. 2022-03-28 16:18:54 +02:00
Ahmed Bouhuolia
3d78e5d397 Merge pull request #36 from bigcapitalhq/BIG-301-fix-navbar-divider-in-action-bar-detail-casl-ability
fix: navbar divider.
2022-03-28 16:07:20 +02:00
Ahmed Bouhuolia
fffd255eb1 Merge pull request #37 from bigcapitalhq/BIG-add-keepPreviousData
BIG: add keepPreviousData option on use query.
2022-03-28 16:05:42 +02:00
Ahmed Bouhuolia
d0f09a0164 Merge pull request #34 from bigcapitalhq/BIG-351-invalid-date-in-the-inventory-adjustment-detail
Big 351 invalid date in the inventory adjustment detail
2022-03-28 16:01:37 +02:00
elforjani13
7774d9f5ab BIG: add keepPreviousData . 2022-03-28 16:01:07 +02:00
Ahmed Bouhuolia
e5ab240dfd Merge pull request #33 from bigcapitalhq/BIG-221-remove-non-inventory-radio-choice-on-item-form
BIG-221: remove non inventory radio.
2022-03-28 15:54:59 +02:00
elforjani13
2b07917399 BIG-352: invalid date. 2022-03-28 15:48:36 +02:00
elforjani13
79099e1abc BIG-280: optimize select. 2022-03-28 15:46:37 +02:00
elforjani13
e87b22801b BIG-221: remove non inventory radio. 2022-03-28 13:46:41 +02:00
elforjani13
e0eaa56b5c fix: navbar divider. 2022-03-28 13:26:21 +02:00
a.bouhuolia
d842722183 fix: add the missed imported warehouse transfers. 2022-03-28 12:08:53 +02:00
a.bouhuolia
9c14f10edf Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-03-28 12:01:39 +02:00
a.bouhuolia
6a8137729f fix(Account): BIG-296 Issue when creating a new child account from chart of accounts list. 2022-03-28 12:01:29 +02:00
a.bouhuolia
5c601fcf2d fix(Account): BIG-296 Issue when creating a new child account from chart of accounts list. 2022-03-28 11:58:12 +02:00
elforjani13
86cab7988c feat: handle item error. 2022-03-24 15:03:25 +02:00
Ahmed Bouhuolia
8404fee10a dump v1.7.0-rc.1 2022-03-24 13:12:14 +02:00
elforjani13
99a23889bc feat: add warehouses transfers query. 2022-03-24 12:19:46 +02:00
elforjani13
5e2000d252 feat: add invalidate item warehouses. 2022-03-24 11:50:06 +02:00
108 changed files with 1561 additions and 725 deletions

View File

@@ -2,6 +2,60 @@
All notable changes to Bigcapital server-side will be in this file.
## [1.7.3-rc.2] - 15-04-2022
### Fixed
- `BIG-372` Activate branches and warehouses dialog reloading once activating.
- `BIG-373` Issue general ledger report select specific account.
- `BIG-377` Make readonly details entries as oneline with tooltip for more details.
## [1.7.2-rc.2] - 04-04-2022
### Fixed
- Add the missing Arabic localization.
- Subscription plans modifications.
## [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

42
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "bigcapital-client",
"version": "1.5.8",
"version": "1.7.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1043,17 +1043,6 @@
"to-fast-properties": "^2.0.0"
}
},
"@blueprintjs-formik/core": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@blueprintjs-formik/core/-/core-0.1.5.tgz",
"integrity": "sha512-H0aXiNMYC8RwhWR1F2O77dcRcRITijUX5we51G4AK2Vmp1yXCmNb0piN9ftsjL5vVIvIsMKWg+dfbwREmB5VWg==",
"requires": {
"lodash.get": "^4.4.2",
"lodash.keyby": "^4.6.0",
"styled-components": "^5.3.3",
"web-vitals": "^2.1.4"
}
},
"@blueprintjs-formik/select": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@blueprintjs-formik/select/-/select-0.1.4.tgz",
@@ -1980,6 +1969,16 @@
"integrity": "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==",
"dev": true
},
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"dev": true,
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/http-proxy": {
"version": "1.17.3",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.3.tgz",
@@ -2240,6 +2239,25 @@
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw=="
},
"@types/styled-components": {
"version": "5.1.25",
"resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.25.tgz",
"integrity": "sha512-fgwl+0Pa8pdkwXRoVPP9JbqF0Ivo9llnmsm+7TCI330kbPIFd9qv1Lrhr37shf4tnxCOSu+/IgqM7uJXLWZZNQ==",
"dev": true,
"requires": {
"@types/hoist-non-react-statics": "*",
"@types/react": "*",
"csstype": "^3.0.2"
},
"dependencies": {
"csstype": {
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz",
"integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==",
"dev": true
}
}
},
"@types/testing-library__dom": {
"version": "6.12.1",
"resolved": "https://registry.npmjs.org/@types/testing-library__dom/-/testing-library__dom-6.12.1.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "bigcapital-client",
"version": "1.6.3",
"version": "1.7.1",
"private": true,
"dependencies": {
"@babel/core": "7.8.4",
@@ -150,6 +150,7 @@
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react-router-dom": "^5.1.8",
"@types/styled-components": "^5.1.25",
"@types/yup": "^0.29.13",
"@welldone-software/why-did-you-render": "^6.0.0-rc.1",
"compression-webpack-plugin": "^6.1.0",

View File

@@ -1,3 +1,4 @@
export * from './accountTypes';
export * from './TableStyle';
export * from './features';
export * from './cellTypes';

View File

@@ -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 (
<MenuItem
icon={isSelected ? 'tick' : 'blank'}
text={account.name}
label={account.code}
key={account.id}
onClick={handleClick}
/>
);
};
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 (
<FMultiSelect
items={accounts}
popoverProps={{
minimal: true,
}}
{...accountSelectProps}
{...rest}
/>
);
}

View File

@@ -0,0 +1 @@
export * from './AccountMultiSelect';

View File

@@ -11,7 +11,7 @@ export const CommercialDocHeader = styled.div`
`;
export const CommercialDocTopHeader = styled.div`
margin-bottom: 25px;
margin-bottom: 30px;
`;
export const CommercialDocEntriesTable = styled(DataTable)`

View File

@@ -0,0 +1,27 @@
import React from 'react';
import { Tooltip, Position } from '@blueprintjs/core';
/**
* Text overview tooltip cell.
* @returns {JSX.Element}
*/
export function TextOverviewTooltipCell({ cell: { value } }) {
const SUBMENU_POPOVER_MODIFIERS = {
flip: { boundariesElement: 'viewport', padding: 20 },
offset: { offset: '0, 10' },
preventOverflow: { boundariesElement: 'viewport', padding: 40 },
};
return (
<Tooltip
content={value}
position={Position.BOTTOM_LEFT}
boundary={'viewport'}
minimal={true}
modifiers={SUBMENU_POPOVER_MODIFIERS}
targetClassName={'table-tooltip-overview-target'}
>
{value}
</Tooltip>
);
}

View File

@@ -10,6 +10,7 @@ import CheckBoxFieldCell from './CheckBoxFieldCell';
import SwitchFieldCell from './SwitchFieldCell';
import TextAreaCell from './TextAreaCell';
import BranchesListFieldCell from './BranchesListFieldCell';
import { TextOverviewTooltipCell } from './TextOverviewTooltipCell';
export {
AccountsListFieldCell,
@@ -25,4 +26,5 @@ export {
SwitchFieldCell,
TextAreaCell,
BranchesListFieldCell,
TextOverviewTooltipCell,
};

View File

@@ -0,0 +1,16 @@
import styled from 'styled-components';
import { FlexProps } from './interfaces';
export const FlexStyled = styled.div<FlexProps>`
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: ${({ align }) => align || 'center'};
&:after {
content: '';
max-width: ${({ col, gap = 1 }) =>
col && col < 12 ? `${(100 * col) / 12 - gap}%` : '100%'};
width: 100%;
}
`;

View File

@@ -0,0 +1,26 @@
import * as React from 'react';
import { FlexProps } from './interfaces';
import { FlexItem } from './FlexItem';
import { FlexStyled } from './Flex.style';
export function Flex({
children,
col = 12,
gap,
align,
className,
style,
}: FlexProps) {
return (
<FlexStyled
col={col}
gap={gap}
align={align}
className={className}
style={style}
>
{children}
<FlexItem col={col} gap={gap} />
</FlexStyled>
);
}

View File

@@ -0,0 +1,19 @@
import styled from 'styled-components';
import { ItemProps } from './interfaces';
export const FlexItem = styled.div<ItemProps>`
width: 100%;
max-width: ${({ col, gap = 1 }) =>
col && col < 12 ? `${(100 * col) / 12 - gap}%` : '100%'};
${({ marginBottom }) =>
marginBottom &&
`
margin-bottom: ${marginBottom}px;
`}
${({ stretch }) =>
stretch &&
`
display: flex;
align-self: stretch;
`}
`;

View File

@@ -0,0 +1 @@
export * from './FlexItem.style';

View File

@@ -0,0 +1,4 @@
export * from './Flex.style';
export * from './Flex';
export * from './FlexItem.style';
export * from './interfaces';

View File

@@ -0,0 +1,22 @@
import { HTMLAttributes, Component, StyleHTMLAttributes } from 'react';
export type Range = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
export interface ItemProps extends HTMLAttributes<HTMLDivElement> {
gap?: number;
col: Range;
marginBottom?: number;
stretch?: boolean;
as?: string | Component;
className?: string;
style?: StyleHTMLAttributes<HTMLDivElement>;
}
export interface FlexProps extends HTMLAttributes<HTMLDivElement> {
gap?: number;
align?: 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch';
col?: Range;
className?: string;
style?: StyleHTMLAttributes<HTMLDivElement>;
as?: string | Component;
}

View File

@@ -49,7 +49,6 @@ import DrawerHeaderContent from './Drawer/DrawerHeaderContent';
import Postbox from './Postbox';
import AccountsSuggestField from './AccountsSuggestField';
import MaterialProgressBar from './MaterialProgressBar';
import { MoneyFieldCell } from './DataTableCells';
import AvaterCell from './AvaterCell';
import { ItemsMultiSelect } from './Items';
@@ -102,8 +101,11 @@ export * from './ExchangeRate';
export * from './Branches';
export * from './Warehouses';
export * from './Currencies';
export * from './FormTopbar'
export * from './FormTopbar';
export * from './Paper';
export * from './Accounts';
export * from './DataTableCells';
export * from './FlexGrid';
const Hint = FieldHint;
@@ -166,7 +168,6 @@ export {
Postbox,
AccountsSuggestField,
MaterialProgressBar,
MoneyFieldCell,
ItemsMultiSelect,
AvaterCell,
MoreMenuItems,

45
src/config/interfaces.tsx Normal file
View File

@@ -0,0 +1,45 @@
export enum ISidebarMenuItemType {
Label = 'label',
Link = 'link',
Group = 'group',
Overlay = 'overlay'
}
export interface ISidebarMenuItemOverlay extends ISidebarMenuItemCommon {
type: ISidebarMenuItemType.Overlay;
}
export interface ISidebarMenuItemLink extends ISidebarMenuItemCommon {
text: string | JSX.Element;
href: string;
type: ISidebarMenuItemType.Link;
matchExact?: boolean;
}
export interface ISidebarMenuItemLabel extends ISidebarMenuItemCommon {
text?: string;
type: ISidebarMenuItemType.Label;
}
export interface ISidebarMenuItemGroup extends ISidebarMenuItemCommon {
type: ISidebarMenuItemType.Group;
}
export interface ISidebarMenuItemPermission {
subject: string;
ability: string;
}
export interface ISidebarMenuItemCommon {
ability?: ISidebarMenuItemPermission | ISidebarMenuItemPermission[];
feature?: string;
disabled?: boolean;
children?: ISidebarMenuItem[];
onlySubscriptionExpired?: boolean;
}
export type ISidebarMenuItem =
| ISidebarMenuItemLink
| ISidebarMenuItemLabel
| ISidebarMenuItemGroup
| ISidebarMenuItemOverlay;

View File

@@ -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 = (
<Menu>
<MenuItem onClick={handleClickRemoveRole} text="Remove line" />
<MenuItem
onClick={handleClickRemoveRole}
text={intl.get('make_journal.entries.remove_row')}
/>
</Menu>
);
return (

View File

@@ -15,6 +15,8 @@ import withSettings from '../Settings/withSettings';
import { useAccountsChartContext } from './AccountsChartProvider';
import { useMemorizedColumnsWidths } from '../../hooks';
import { AccountDialogAction } from '../Dialogs/AccountDialog/utils';
import withAlertsActions from 'containers/Alert/withAlertActions';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withDrawerActions from 'containers/Drawer/withDrawerActions';
@@ -58,7 +60,10 @@ function AccountsDataTable({
// Handle edit account action.
const handleEditAccount = (account) => {
openDialog('account-form', { action: 'edit', id: account.id });
openDialog('account-form', {
action: AccountDialogAction.Edit,
id: account.id,
});
};
// Handle view detail account.
@@ -69,7 +74,7 @@ function AccountsDataTable({
// Handle new child button click.
const handleNewChildAccount = (account) => {
openDialog('account-form', {
action: 'new_child',
action: AccountDialogAction.NewChild,
parentAccountId: account.id,
accountType: account.account_type,
});

View File

@@ -16,6 +16,9 @@ import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withCashflowAccountsTableActions from '../AccountTransactions/withCashflowAccountsTableActions';
import { AccountDialogAction } from '../../Dialogs/AccountDialog/utils';
import { ACCOUNT_TYPE } from '../../../common';
import { compose } from 'utils';
/**
@@ -37,15 +40,15 @@ function CashFlowAccountsActionsBar({
// Handle add bank account.
const handleAddBankAccount = () => {
openDialog('account-form', {
action: 'NEW_ACCOUNT_DEFINED_TYPE',
accountType: 'cash',
action: AccountDialogAction.NewDefinedType,
accountType: ACCOUNT_TYPE.CASH,
});
};
// Handle add cash account.
const handleAddCashAccount = () => {
openDialog('account-form', {
action: 'NEW_ACCOUNT_DEFINED_TYPE',
accountType: 'bank',
action: AccountDialogAction.NewDefinedType,
accountType: ACCOUNT_TYPE.BANK,
});
};
// Handle inactive switch changing.

View File

@@ -5,21 +5,9 @@ import AccountDialogForm from './AccountDialogForm';
/**
* Account dialog content.
*/
export default function AccountDialogContent({
dialogName,
accountId,
action,
parentAccountId,
accountType,
}) {
export default function AccountDialogContent({ dialogName, payload }) {
return (
<AccountDialogProvider
dialogName={dialogName}
accountId={accountId}
action={action}
parentAccountId={parentAccountId}
accountType={accountType}
>
<AccountDialogProvider dialogName={dialogName} payload={payload}>
<AccountDialogForm />
</AccountDialogProvider>
);

View File

@@ -43,9 +43,7 @@ function AccountFormDialogContent({
account,
accountId,
action,
parentAccountId,
accountType,
payload,
isNewMode,
dialogName,
} = useAccountDialogContext();
@@ -101,7 +99,6 @@ function AccountFormDialogContent({
.catch(handleError);
}
};
// Form initial values in create and edit mode.
const initialValues = {
...defaultInitialValues,
@@ -111,11 +108,7 @@ function AccountFormDialogContent({
* as well.
*/
...transformToForm(
transformAccountToForm(account, {
action,
parentAccountId,
accountType,
}),
transformAccountToForm(account, payload),
defaultInitialValues,
),
};
@@ -133,7 +126,7 @@ function AccountFormDialogContent({
>
<AccountDialogFormContent
dialogName={dialogName}
action={action}
action={payload?.action}
onClose={handleClose}
/>
</Formik>

View File

@@ -39,7 +39,8 @@ function AccountFormDialogFields({
const accountNameFieldRef = useAutofocus();
// Account form context.
const { accounts, accountsTypes, currencies } = useAccountDialogContext();
const { fieldsDisabled, accounts, accountsTypes, currencies } =
useAccountDialogContext();
return (
<Form>
@@ -62,11 +63,7 @@ function AccountFormDialogFields({
form.setFieldValue('account_type', accountType.key);
form.setFieldValue('currency_code', '');
}}
disabled={
action === 'edit' ||
action === 'new_child' ||
action === 'NEW_ACCOUNT_DEFINED_TYPE'
}
disabled={fieldsDisabled.accountType}
popoverProps={{ minimal: true }}
popoverFill={true}
/>
@@ -209,7 +206,7 @@ function AccountFormDialogFields({
<Button
intent={Intent.PRIMARY}
loading={isSubmitting}
style={{ minWidth: '75px' }}
style={{ minWidth: '95px' }}
type="submit"
>
{action === 'edit' ? <T id={'edit'} /> : <T id={'submit'} />}

View File

@@ -8,21 +8,14 @@ import {
useAccounts,
useEditAccount,
} from 'hooks/query';
import { AccountDialogAction, getDisabledFormFields } from './utils';
const AccountDialogContext = createContext();
/**
* Account form provider.
*/
function AccountDialogProvider({
accountId,
parentAccountId,
action,
accountType,
dialogName,
...props
}) {
function AccountDialogProvider({ dialogName, payload, ...props }) {
// Create and edit account mutations.
const { mutateAsync: createAccountMutate } = useCreateAccount();
const { mutateAsync: editAccountMutate } = useEditAccount();
@@ -35,22 +28,31 @@ function AccountDialogProvider({
useAccountsTypes();
// Fetches the specific account details.
const { data: account, isLoading: isAccountLoading } = useAccount(accountId, {
enabled: !!accountId,
});
const { data: account, isLoading: isAccountLoading } = useAccount(
payload.accountId,
{
enabled:
!!payload.accountId && payload.action === AccountDialogAction.Edit,
},
);
// Handle fetch Currencies data table
const { data: currencies, isLoading: isCurrenciesLoading } = useCurrencies();
const isNewMode = !accountId;
const isNewMode = !payload?.action;
// Retrieves the disabled fields of the form.
const fieldsDisabled = React.useMemo(
() => getDisabledFormFields(account, payload),
[account, payload],
);
// Provider payload.
const provider = {
dialogName,
accountId,
parentAccountId,
action,
accountType,
payload,
fieldsDisabled,
currencies,
createAccountMutate,

View File

@@ -18,9 +18,11 @@ function AccountFormDialog({
<Dialog
name={dialogName}
title={
(payload.action === 'edit') ?
(<T id={'edit_account'} />) :
(<T id={'new_account'} />)
payload.action === 'edit' ? (
<T id={'edit_account'} />
) : (
<T id={'new_account'} />
)
}
className={'dialog--account-form'}
autoFocus={true}
@@ -28,18 +30,10 @@ function AccountFormDialog({
isOpen={isOpen}
>
<DialogSuspense>
<AccountDialogContent
dialogName={dialogName}
accountId={payload.id}
action={payload.action}
parentAccountId={payload.parentAccountId}
accountType={payload.accountType}
/>
<AccountDialogContent dialogName={dialogName} payload={payload} />
</DialogSuspense>
</Dialog>
);
}
export default compose(
withDialogRedux(),
)(AccountFormDialog);
export default compose(withDialogRedux())(AccountFormDialog);

View File

@@ -1,7 +1,17 @@
import intl from 'react-intl-universal';
import * as R from 'ramda';
import { isEmpty } from 'lodash';
import { isUndefined } from 'lodash';
//
export const AccountDialogAction = {
Edit: 'edit',
NewChild: 'NewChild',
NewDefinedType: 'NewDefinedType',
};
/**
* Transformes the response API errors.
*/
export const transformApiErrors = (errors) => {
const fields = {};
if (errors.find((e) => e.type === 'NOT_UNIQUE_CODE')) {
@@ -23,7 +33,7 @@ export const transformApiErrors = (errors) => {
/**
* Payload transformer in account edit mode.
*/
function transformEditMode(payload) {
function tranformNewChildAccountPayload(payload) {
return {
parent_account_id: payload.parentAccountId || '',
account_type: payload.accountType || '',
@@ -34,7 +44,7 @@ function transformEditMode(payload) {
/**
* Payload transformer in new account with defined type.
*/
function transformNewAccountDefinedType(payload) {
function transformNewDefinedTypePayload(payload) {
return {
account_type: payload.accountType || '',
};
@@ -60,9 +70,9 @@ const defaultPayloadTransform = () => ({});
*/
function getConditions() {
return [
['edit'],
['new_child', transformEditMode],
['NEW_ACCOUNT_DEFINED_TYPE', transformNewAccountDefinedType],
[AccountDialogAction.Edit],
[AccountDialogAction.NewChild, tranformNewChildAccountPayload],
[AccountDialogAction.NewDefinedType, transformNewDefinedTypePayload],
];
}
@@ -73,7 +83,7 @@ export const transformAccountToForm = (account, payload) => {
const conditions = getConditions();
const results = conditions.map((condition) => {
const transformer = !isEmpty(condition[1])
const transformer = !isUndefined(condition[1])
? condition[1]
: defaultPayloadTransform;
@@ -84,3 +94,15 @@ export const transformAccountToForm = (account, payload) => {
});
return R.cond(results)(account);
};
/**
* Detarmines whether the for fields are disabled.
*/
export const getDisabledFormFields = (account, payload) => {
return {
accountType:
payload.action === AccountDialogAction.Edit ||
payload.action === AccountDialogAction.NewChild ||
payload.action === AccountDialogAction.NewDefinedType,
};
};

View File

@@ -9,7 +9,7 @@ const BranchActivateContext = React.createContext();
* Branch activate form provider.
*/
function BranchActivateFormProvider({ dialogName, ...props }) {
const { mutateAsync: activateBranches, isLoading } = useActivateBranches();
const { mutateAsync: activateBranches } = useActivateBranches();
// State provider.
const provider = {
@@ -18,7 +18,7 @@ function BranchActivateFormProvider({ dialogName, ...props }) {
};
return (
<DialogContent isLoading={isLoading}>
<DialogContent>
<BranchActivateContext.Provider value={provider} {...props} />
</DialogContent>
);

View File

@@ -36,7 +36,7 @@ function PaymentViaLicenseDialogContent({
setSubmitting(true);
const mutateValues = {
plan_slug: `${values.plan_slug}-${values.period}ly`,
plan_slug: `essentials-monthly`,
license_code: values.license_code,
};
// Payment via voucher mutate.

View File

@@ -9,8 +9,7 @@ const WarehouseActivateContext = React.createContext();
* warehouse activate form provider.
*/
function WarehouseActivateFormProvider({ dialogName, ...props }) {
const { mutateAsync: activateWarehouses, isLoading } =
useActivateWarehouses();
const { mutateAsync: activateWarehouses } = useActivateWarehouses();
// State provider.
const provider = {
@@ -19,7 +18,7 @@ function WarehouseActivateFormProvider({ dialogName, ...props }) {
};
return (
<DialogContent isLoading={isLoading}>
<DialogContent>
<WarehouseActivateContext.Provider value={provider} {...props} />
</DialogContent>
);

View File

@@ -9,15 +9,15 @@ import {
} from '@blueprintjs/core';
import { Can, FormattedMessage as T } from 'components';
import { AccountAction, AbilitySubject } from '../../../common/abilityOption';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withAlertsActions from 'containers/Alert/withAlertActions';
import { safeCallback } from 'utils';
import { AccountAction, AbilitySubject } from '../../../common/abilityOption';
import { compose } from 'utils';
import { AccountDialogAction } from 'containers/Dialogs/AccountDialog/utils';
import { useAccountDrawerContext } from './AccountDrawerProvider';
import { compose, safeCallback } from 'utils';
/**
* Account drawer action bar.
@@ -35,17 +35,18 @@ function AccountDrawerActionBar({
// Handle new child button click.
const onNewChildAccount = () => {
openDialog('account-form', {
action: 'new_child',
action: AccountDialogAction.NewChild,
parentAccountId: account.id,
accountType: account.account_type,
});
};
// Handle edit account action.
const onEditAccount = () => {
openDialog('account-form', { action: 'edit', id: account.id });
openDialog('account-form', {
action: AccountDialogAction.Edit,
id: account.id,
});
};
// Handle delete action account.
const onDeleteAccount = () => {
openAlert('account-delete', { accountId: account.id });

View File

@@ -95,9 +95,9 @@ function BillDetailActionsBar({
onClick={handleQuickBillPayment}
/>
</If>
<NavbarDivider />
</Can>
<Can I={BillAction.Delete} a={AbilitySubject.Bill}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}

View File

@@ -13,57 +13,81 @@ import {
} from '@blueprintjs/core';
import {
FormatNumberCell,
TextOverviewTooltipCell,
FormattedMessage as T,
Choose,
Icon,
} from '../../../components';
import { getColumnWidth } from 'utils';
import { useBillDrawerContext } from './BillDrawerProvider';
/**
* Retrieve bill readonly details entries table columns.
*/
export const useBillReadonlyEntriesTableColumns = () =>
React.useMemo(
export const useBillReadonlyEntriesTableColumns = () => {
const {
bill: { entries },
} = useBillDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('product_and_service'),
accessor: 'item.name',
Cell: TextOverviewTooltipCell,
width: 150,
className: 'item',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('description'),
accessor: 'description',
Cell: TextOverviewTooltipCell,
className: 'description',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('quantity'),
accessor: 'quantity',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'quantity', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('rate'),
accessor: 'rate',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'rate', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'amount', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
],
[],
);
};
/**
* Bill details status.

View File

@@ -10,56 +10,81 @@ import {
Tag,
Intent,
} from '@blueprintjs/core';
import { getColumnWidth } from 'utils';
import {
Icon,
FormattedMessage as T,
TextOverviewTooltipCell,
FormatNumberCell,
Choose,
} from '../../../components';
import { useCreditNoteDetailDrawerContext } from './CreditNoteDetailDrawerProvider';
export const useCreditNoteReadOnlyEntriesColumns = () =>
React.useMemo(
export const useCreditNoteReadOnlyEntriesColumns = () => {
// credit note details drawer context.
const {
creditNote: { entries },
} = useCreditNoteDetailDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('product_and_service'),
accessor: 'item.name',
Cell: TextOverviewTooltipCell,
width: 150,
className: 'name',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('description'),
accessor: 'description',
Cell: TextOverviewTooltipCell,
className: 'description',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('quantity'),
accessor: 'quantity',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'quantity', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('rate'),
accessor: 'rate',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'rate', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'amount', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
],
[],
);
};
/**
* Credit note more actions mneu.

View File

@@ -131,17 +131,17 @@ function CustomerDetailsActionsBar({
/>
</Popover>
<NavbarDivider />
<Can I={CustomerAction.Edit} a={AbilitySubject.Customer}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon="pen-18" />}
text={intl.get('customer.drawer.action.edit')}
onClick={handleEditContact}
/>
<NavbarDivider />
</Can>
<Can I={CustomerAction.Delete} a={AbilitySubject.Customer}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}

View File

@@ -96,9 +96,9 @@ function EstimateDetailActionsBar({
intent={Intent.DANGER}
onClick={handleDeleteEstimate}
/>
<NavbarDivider />
</Can>
<Can I={SaleEstimateAction.NotifyBySms} a={AbilitySubject.Estimate}>
<NavbarDivider />
<MoreMenuItems
payload={{
onNotifyViaSMS: handleNotifyViaSMS,

View File

@@ -1,47 +1,74 @@
import React from 'react';
import intl from 'react-intl-universal';
import { FormatNumberCell } from '../../../components';
import { FormatNumberCell, TextOverviewTooltipCell } from '../../../components';
import { getColumnWidth } from 'utils';
import { useEstimateDetailDrawerContext } from './EstimateDetailDrawerProvider';
/**
* Retrieve table columns of estimate readonly entries details.
*/
export const useEstimateReadonlyEntriesColumns = () =>
React.useMemo(() => [
{
Header: intl.get('product_and_service'),
accessor: 'item.name',
width: 150,
className: 'name',
disableSortBy: true,
},
{
Header: intl.get('description'),
accessor: 'description',
className: 'description',
disableSortBy: true,
},
{
Header: intl.get('quantity'),
accessor: 'quantity',
Cell: FormatNumberCell,
width: 100,
align: 'right',
disableSortBy: true,
},
{
Header: intl.get('rate'),
accessor: 'rate',
Cell: FormatNumberCell,
width: 100,
align: 'right',
disableSortBy: true,
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: 100,
align: 'right',
disableSortBy: true,
},
], []);
export const useEstimateReadonlyEntriesColumns = () => {
// estimate details drawer context.
const {
estimate: { entries },
} = useEstimateDetailDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('product_and_service'),
accessor: 'item.name',
Cell: TextOverviewTooltipCell,
width: 150,
className: 'name',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('description'),
accessor: 'description',
Cell: TextOverviewTooltipCell,
className: 'description',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('quantity'),
accessor: 'quantity',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'quantity', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('rate'),
accessor: 'rate',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'rate', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'amount', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
],
[],
);
};

View File

@@ -55,9 +55,9 @@ function ExpenseDrawerActionBar({
text={<T id={'edit_expense'} />}
onClick={handleEditExpense}
/>
<NavbarDivider />
</Can>
<Can I={ExpenseAction.Delete} a={AbilitySubject.Expense}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon="trash-16" iconSize={16} />}

View File

@@ -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'}
>
<DetailItem label={<T id={'published_at'} />}>
{moment(expense.published_at).format('YYYY MMM DD')}
<FormatDate value={expense.published_at} />
</DetailItem>
<DetailItem label={<T id={'created_at'} />}>2021 Aug 24</DetailItem>
<DetailItem label={<T id={'created_at'} />}>
<FormatDate value={expense.created_at} />
</DetailItem>
</DetailsMenu>
</Col>
</Row>

View File

@@ -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 (
<DrawerLoading loading={isExpenseLoading}>
<DrawerHeaderContent
name="expense-drawer"
title={intl.get('expense.drawer.title')}
subTitle={
featureCan(Features.Branches)
? intl.get('expense.drawer.subtitle', {
value: expense.branch?.name,
})
: null
}
/>
<ExpenseDrawerDrawerContext.Provider value={provider} {...props} />
</DrawerLoading>
);

View File

@@ -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({
<Drawer
isOpen={isOpen}
name={name}
title={intl.get('expense.drawer.title')}
size={'65%'}
style={{ minWidth: '700px', maxWidth: '900px' }}
>

View File

@@ -1,33 +1,46 @@
import React from 'react';
import intl from 'react-intl-universal';
import { FormatNumberCell } from '../../../components';
import { FormatNumberCell, TextOverviewTooltipCell } from '../../../components';
import { useExpenseDrawerContext } from './ExpenseDrawerProvider';
import { getColumnWidth } from 'utils';
/**
* Retrieve expense readonly details entries table columns.
*/
export const useExpenseReadEntriesColumns = () =>
React.useMemo(
export const useExpenseReadEntriesColumns = () => {
// Expense drawer context.
const {
expense: { categories },
} = useExpenseDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('expense_account'),
accessor: 'expense_account.name',
Cell: TextOverviewTooltipCell,
width: 110,
disableSortBy: true,
textOverview: true,
className: 'account',
},
{
Header: intl.get('description'),
accessor: 'description',
width: 110,
disableSortBy: true,
Cell: TextOverviewTooltipCell,
className: 'description',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(categories, 'amount', {
minWidth: 60,
magicSpacing: 5,
}),
disableSortBy: true,
className: 'amount',
align: 'right',
@@ -35,3 +48,4 @@ export const useExpenseReadEntriesColumns = () =>
],
[],
);
};

View File

@@ -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() {
<div className={clsx(InventoryAdjustmentDrawerCls.detail_panel_header)}>
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
<DetailItem label={intl.get('date')}>
{moment(inventoryAdjustment.date).format('YYYY MMM DD')}
<FormatDate value={inventoryAdjustment.date} />
</DetailItem>
<DetailItem label={intl.get('type')}>
@@ -36,7 +36,7 @@ export default function InventoryAdjustmentDetailHeader() {
</DetailItem>
<DetailItem label={intl.get('published_at')}>
{moment(inventoryAdjustment.published_at).format('YYYY MMM DD')}
<FormatDate value={inventoryAdjustment.published_at} />
</DetailItem>
<DetailItem label={intl.get('reason')}>
@@ -44,7 +44,7 @@ export default function InventoryAdjustmentDetailHeader() {
</DetailItem>
<DetailItem label={intl.get('created_at')}>
{moment(inventoryAdjustment.created_at).format('YYYY MMM DD')}
<FormatDate value={inventoryAdjustment.created_at} />
</DetailItem>
</DetailsMenu>
</div>

View File

@@ -1,37 +1,60 @@
import React from 'react';
import intl from 'react-intl-universal';
import { getColumnWidth } from 'utils';
import { TextOverviewTooltipCell } from 'components';
import { useInventoryAdjustmentDrawerContext } from './InventoryAdjustmentDrawerProvider';
export const useInventoryAdjustmentEntriesColumns = () =>
React.useMemo(
export const useInventoryAdjustmentEntriesColumns = () => {
// Inventory adjustment details drawer context.
const {
inventoryAdjustment: { entries },
} = useInventoryAdjustmentDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('inventory_adjustment.column.product'),
accessor: 'item.name',
width: 150,
Cell: TextOverviewTooltipCell,
width: 100,
className: 'name',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('quantity'),
accessor: 'quantity',
width: 100,
width: getColumnWidth(entries, 'quantity', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('cost'),
accessor: 'cost',
width: 100,
width: getColumnWidth(entries, 'cost', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('value'),
accessor: 'value',
width: 100,
width: getColumnWidth(entries, 'value', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
],
[],
);
};

View File

@@ -11,12 +11,14 @@ import {
Intent,
Tag,
} from '@blueprintjs/core';
import { getColumnWidth } from 'utils';
import {
FormatNumberCell,
Icon,
FormattedMessage as T,
Choose,
Can,
TextOverviewTooltipCell,
} from 'components';
import {
SaleInvoiceAction,
@@ -27,49 +29,69 @@ import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
/**
* Retrieve invoice readonly details table columns.
*/
export const useInvoiceReadonlyEntriesColumns = () =>
React.useMemo(
export const useInvoiceReadonlyEntriesColumns = () => {
// Invoice details drawer context.
const {
invoice: { entries },
} = useInvoiceDetailDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('product_and_service'),
accessor: 'item.name',
width: 150,
className: 'name',
Cell: TextOverviewTooltipCell,
disableSortBy: true,
textOverview: true,
width: 150,
},
{
Header: intl.get('description'),
accessor: 'description',
className: 'description',
Cell: TextOverviewTooltipCell,
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('quantity'),
accessor: 'quantity',
Cell: FormatNumberCell,
width: 100,
align: 'right',
disableSortBy: true,
textOverview: true,
width: getColumnWidth(entries, 'quantity', {
minWidth: 60,
magicSpacing: 5,
}),
},
{
Header: intl.get('rate'),
accessor: 'rate',
Cell: FormatNumberCell,
width: 100,
align: 'right',
disableSortBy: true,
textOverview: true,
width: getColumnWidth(entries, 'rate', {
minWidth: 60,
magicSpacing: 5,
}),
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: 100,
align: 'right',
disableSortBy: true,
textOverview: true,
width: getColumnWidth(entries, 'amount', {
minWidth: 60,
magicSpacing: 5,
}),
},
],
[],
);
};
/**
* Invoice details more actions menu.

View File

@@ -55,10 +55,9 @@ function ItemDetailActionsBar({
text={<T id={'edit_item'} />}
onClick={handleEditItem}
/>
<NavbarDivider />
</Can>
<Can I={ItemAction.Delete} a={AbilitySubject.Item}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}

View File

@@ -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 (
<DrawerLoading loading={isItemLoading}>
<DrawerHeaderContent name="item-detail-drawer" title={item?.name} />
<DrawerHeaderContent
name="item-detail-drawer"
title={inactiveStatus(item)}
/>
<ItemDetailDrawerContext.Provider value={provider} {...props} />
</DrawerLoading>
);

View File

@@ -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 (
<Choose>
<Choose.When condition={!item.active}>
{item.name}
<StatusTag intent={Intent.NONE} minimal={true} round={true}>
<T id={'item.details.inactive'} />
</StatusTag>
</Choose.When>
<Choose.Otherwise>{item.name}</Choose.Otherwise>
</Choose>
);
}
const StatusTag = styled(Tag)`
font-size: 11px;
margin-left: 10px;
`;

View File

@@ -55,9 +55,9 @@ function ManualJournalDrawerActionBar({
text={<T id={'edit_journal'} />}
onClick={handleEditManualJournal}
/>
<NavbarDivider />
</Can>
<Can I={ManualJournalAction.Delete} a={AbilitySubject.ManualJournal}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon="trash-16" iconSize={16} />}

View File

@@ -10,7 +10,10 @@ import { TableStyle } from '../../../common';
* Manual journal drawer table.
*/
export default function ManualJournalDrawerTable() {
// Retrieves the readonly manual journal entries columns.
const columns = useManualJournalEntriesColumns();
// Manual journal drawer context.
const { manualJournal } = useManualJournalDrawerContext();
return (

View File

@@ -1,26 +1,17 @@
import intl from 'react-intl-universal';
import React from 'react';
import { Tag, Intent, Classes, Tooltip, Position } from '@blueprintjs/core';
import { Tag, Intent } from '@blueprintjs/core';
import { T, Choose, FormatNumberCell, If, Icon } from '../../../components';
/**
* Note column accessor.
*/
export function NoteAccessor(row) {
return (
<If condition={row.note}>
<Tooltip
className={Classes.TOOLTIP_INDICATOR}
content={row.note}
position={Position.LEFT_TOP}
hoverOpenDelay={50}
>
<Icon icon={'file-alt'} iconSize={16} />
</Tooltip>
</If>
);
}
import {
T,
Choose,
FormatNumberCell,
TextOverviewTooltipCell,
} from '../../../components';
import { Features } from 'common';
import { getColumnWidth } from 'utils';
import { useFeatureCan } from 'hooks/state';
import { useManualJournalDrawerContext } from './ManualJournalDrawerProvider';
/**
* Publish column accessor.
@@ -46,52 +37,79 @@ export function ManualJournalDetailsStatus({ manualJournal }) {
/**
* Retrieve read-only manual journal entries columns.
*/
export const useManualJournalEntriesColumns = () =>
React.useMemo(
export const useManualJournalEntriesColumns = () => {
const { featureCan } = useFeatureCan();
// manual journal details drawer context.
const {
manualJournal: { entries },
} = useManualJournalDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('account_name'),
Cell: TextOverviewTooltipCell,
accessor: 'account.name',
width: 130,
disableSortBy: true,
className: 'account',
textOverview: true,
},
{
Header: intl.get('contact'),
accessor: 'contact.display_name',
width: 130,
Cell: TextOverviewTooltipCell,
width: 100,
disableSortBy: true,
className: 'contact',
textOverview: true,
},
{
Header: intl.get('note'),
accessor: NoteAccessor,
width: 80,
accessor: 'note',
Cell: TextOverviewTooltipCell,
disableSortBy: true,
className: 'note',
textOverview: true,
width: 100,
},
...(featureCan(Features.Branches)
? [
{
Header: intl.get('branch'),
width: 100,
accessor: 'branch.name',
disableSortBy: true,
},
]
: []),
{
Header: intl.get('credit'),
accessor: 'credit',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'credit', {
minWidth: 60,
magicSpacing: 5,
}),
disableResizable: true,
disableSortBy: true,
textOverview: true,
formatNumber: { noZero: true },
className: 'credit',
align: 'right',
},
{
Header: intl.get('debit'),
accessor: 'debit',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'debit', {
minWidth: 60,
magicSpacing: 5,
}),
disableResizable: true,
textOverview: true,
disableSortBy: true,
formatNumber: { noZero: true },
className: 'debit',
align: 'right',
},
],
[],
);
};

View File

@@ -58,9 +58,9 @@ function PaymentMadeDetailActionsBar({
text={<T id={'edit_payment_made'} />}
onClick={handleEditPaymentMade}
/>
<NavbarDivider />
</Can>
<Can I={PaymentMadeAction.Delete} a={AbilitySubject.PaymentMade}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}

View File

@@ -3,43 +3,65 @@ import intl from 'react-intl-universal';
import moment from 'moment';
import { FormatNumberCell } from '../../../components';
import { getColumnWidth } from 'utils';
import { usePaymentMadeDetailContext } from './PaymentMadeDetailProvider';
export const usePaymentMadeEntriesColumns = () =>
React.useMemo(() => [
{
Header: intl.get('date'),
accessor: (row) => moment(row.date).format('YYYY MMM DD'),
width: 100,
disableSortBy: true,
className: 'date',
},
{
Header: intl.get('bill_number'),
accessor: 'bill_no',
width: 150,
disableSortBy: true,
className: 'bill_number',
},
{
Header: intl.get('bill_amount'),
accessor: 'bill.amount',
Cell: FormatNumberCell,
align: 'right',
},
{
Header: intl.get('due_amount'),
accessor: 'bill.due_amount',
Cell: FormatNumberCell,
width: 100,
disableSortBy: true,
align: 'right',
},
{
Header: intl.get('payment_amount'),
accessor: 'payment_amount',
Cell: FormatNumberCell,
width: 100,
disableSortBy: true,
align: 'right',
},
], []);
export const usePaymentMadeEntriesColumns = () => {
// Payment made details context.
const {
paymentMade: { entries },
} = usePaymentMadeDetailContext();
return React.useMemo(
() => [
{
Header: intl.get('date'),
accessor: (row) => moment(row.date).format('YYYY MMM DD'),
width: 100,
disableSortBy: true,
className: 'date',
},
{
Header: intl.get('bill_number'),
accessor: 'bill_no',
width: 150,
disableSortBy: true,
className: 'bill_number',
},
{
Header: intl.get('bill_amount'),
accessor: 'bill.amount',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'bill.amount', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
},
{
Header: intl.get('due_amount'),
accessor: 'bill.due_amount',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'bill.due_amount', {
minWidth: 60,
magicSpacing: 5,
}),
disableSortBy: true,
align: 'right',
},
{
Header: intl.get('payment_amount'),
accessor: 'payment_amount',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'payment_amount', {
minWidth: 60,
magicSpacing: 5,
}),
disableSortBy: true,
textOverview: true,
align: 'right',
},
],
[],
);
};

View File

@@ -95,12 +95,12 @@ function PaymentReceiveActionsBar({
intent={Intent.DANGER}
onClick={handleDeletePaymentReceive}
/>
<NavbarDivider />
</Can>
<Can
I={PaymentReceiveAction.NotifyBySms}
a={AbilitySubject.PaymentReceive}
>
<NavbarDivider />
<MoreMenuItems
payload={{
onNotifyViaSMS: handleNotifyViaSMS,

View File

@@ -2,12 +2,18 @@ import React from 'react';
import intl from 'react-intl-universal';
import moment from 'moment';
import { FormatNumberCell } from '../../../components';
import { getColumnWidth } from 'utils';
import { usePaymentReceiveDetailContext } from './PaymentReceiveDetailProvider';
/**
* Retrieve payment entries table columns.
*/
export const usePaymentReceiveEntriesColumns = () =>
React.useMemo(
export const usePaymentReceiveEntriesColumns = () => {
const {
paymentReceive: { entries },
} = usePaymentReceiveDetailContext();
return React.useMemo(
() => [
{
Header: intl.get('date'),
@@ -27,24 +33,38 @@ export const usePaymentReceiveEntriesColumns = () =>
Header: intl.get('invoice_amount'),
accessor: 'invoice.balance',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'invoice.balance', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
textOverview: true,
},
{
Header: intl.get('amount_due'),
accessor: 'invoice.due_amount',
Cell: FormatNumberCell,
align: 'right',
width: 100,
width: getColumnWidth(entries, 'invoice.due_amount', {
minWidth: 60,
magicSpacing: 5,
}),
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('payment_amount'),
accessor: 'invoice.payment_amount',
Cell: FormatNumberCell,
align: 'right',
width: 100,
width: getColumnWidth(entries, 'invoice.payment_amount', {
minWidth: 60,
magicSpacing: 5,
}),
disableSortBy: true,
textOverview: true,
},
],
[],
);
};

View File

@@ -92,9 +92,9 @@ function ReceiptDetailActionBar({
intent={Intent.DANGER}
onClick={safeCallback(onDeleteReceipt)}
/>
<NavbarDivider />
</Can>
<Can I={SaleReceiptAction.NotifyBySms} a={AbilitySubject.Receipt}>
<NavbarDivider />
<MoreMenuItems
payload={{
onNotifyViaSMS: handleNotifyViaSMS,

View File

@@ -1,44 +1,69 @@
import React from 'react';
import intl from 'react-intl-universal';
import { FormatNumberCell } from '../../../components';
import { getColumnWidth } from 'utils';
import { FormatNumberCell, TextOverviewTooltipCell } from '../../../components';
import { useReceiptDetailDrawerContext } from './ReceiptDetailDrawerProvider.js';
export const useReceiptReadonlyEntriesTableColumns = () => React.useMemo(() => [
{
Header: intl.get('product_and_service'),
accessor: 'item.name',
width: 150,
className: 'name',
disableSortBy: true
},
{
Header: intl.get('description'),
accessor: 'description',
className: 'description',
disableSortBy: true
},
{
Header: intl.get('quantity'),
accessor: 'quantity',
Cell: FormatNumberCell,
width: 100,
align: 'right',
disableSortBy: true
},
{
Header: intl.get('rate'),
accessor: 'rate',
Cell: FormatNumberCell,
width: 100,
align: 'right',
disableSortBy: true
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: 100,
align: 'right',
disableSortBy: true
},
], []);
export const useReceiptReadonlyEntriesTableColumns = () => {
// Receipt details drawer context.
const {
receipt: { entries },
} = useReceiptDetailDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('product_and_service'),
accessor: 'item.name',
Cell: TextOverviewTooltipCell,
width: 150,
className: 'name',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('description'),
accessor: 'description',
Cell: TextOverviewTooltipCell,
className: 'description',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('quantity'),
accessor: 'quantity',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'quantity', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
},
{
Header: intl.get('rate'),
accessor: 'rate',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'rate', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'amount', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
],
[],
);
};

View File

@@ -79,10 +79,10 @@ function VendorCreditDetailActionsBar({
text={<T id={'refund'} />}
onClick={handleRefundVendorCredit}
/>
<NavbarDivider />
</If>
</Can>
<Can I={VendorCreditAction.Delete} a={AbilitySubject.VendorCredit}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}

View File

@@ -10,59 +10,82 @@ import {
Tag,
Intent,
} from '@blueprintjs/core';
import { getColumnWidth } from 'utils';
import {
Icon,
FormattedMessage as T,
TextOverviewTooltipCell,
FormatNumberCell,
Choose,
} from '../../../components';
import { useVendorCreditDetailDrawerContext } from './VendorCreditDetailDrawerProvider';
/**
* Retrieve vendor credit readonly details entries table columns.
*/
export const useVendorCreditReadonlyEntriesTableColumns = () =>
React.useMemo(
export const useVendorCreditReadonlyEntriesTableColumns = () => {
const {
vendorCredit: { entries },
} = useVendorCreditDetailDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('product_and_service'),
accessor: 'item.name',
Cell: TextOverviewTooltipCell,
width: 150,
className: 'item',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('description'),
accessor: 'description',
Cell: TextOverviewTooltipCell,
className: 'description',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('quantity'),
accessor: 'quantity',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'quantity', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('rate'),
accessor: 'rate',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'rate', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'amount', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
],
[],
);
};
/**
* Vendor note more actions menu.

View File

@@ -102,17 +102,17 @@ function VendorDetailsActionsBar({
icon={<Icon icon={'plus'} />}
/>
</Popover>
<NavbarDivider />
<Can I={VendorAction.Edit} a={AbilitySubject.Vendor}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon="pen-18" />}
text={<T id={'vendor.drawer.action.edit'} />}
onClick={safeCallback(onEditContact)}
/>
<NavbarDivider />
</Can>
<Can I={VendorAction.Delete} a={AbilitySubject.Vendor}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}

View File

@@ -1,40 +1,58 @@
import React from 'react';
import intl from 'react-intl-universal';
import { Intent, Tag } from '@blueprintjs/core';
import { getColumnWidth } from 'utils';
import { useWarehouseDetailDrawerContext } from './WarehouseTransferDetailDrawerProvider';
import {
FormattedMessage as T,
FormatNumberCell,
TextOverviewTooltipCell,
Choose,
} from '../../../components';
export const useWarehouseTransferReadOnlyEntriesColumns = () =>
React.useMemo(
/**
* Retrieves the readonly warehouse transfer entries columns.
*/
export const useWarehouseTransferReadOnlyEntriesColumns = () => {
const {
warehouseTransfer: { entries },
} = useWarehouseDetailDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('warehouse_transfer.column.item_name'),
accessor: 'item.name',
width: 150,
Cell: TextOverviewTooltipCell,
width: 100,
className: 'name',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('warehouse_transfer.column.description'),
accessor: 'description',
Cell: TextOverviewTooltipCell,
className: 'description',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('warehouse_transfer.column.transfer_quantity'),
accessor: 'quantity',
Cell: FormatNumberCell,
width: 100,
width: getColumnWidth(entries, 'quantity', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
},
],
[],
);
};
/**
* Warehouses transfer details status.

View File

@@ -43,7 +43,10 @@ export function ActionsCellRenderer({
const exampleMenu = (
<Menu>
<MenuItem onClick={onRemoveRole} text="Remove line" />
<MenuItem
onClick={onRemoveRole}
text={<T id={'item_entries.remove_row'} />}
/>
</Menu>
);

View File

@@ -48,7 +48,10 @@ const ActionsCellRenderer = ({
};
const exampleMenu = (
<Menu>
<MenuItem onClick={handleClickRemoveRole} text="Remove line" />
<MenuItem
onClick={handleClickRemoveRole}
text={intl.get('expense.entries.remove_row')}
/>
</Menu>
);
return (
@@ -163,4 +166,4 @@ export function ExpensesExchangeRateInputField({ ...props }) {
/>
);
}
ExpensesExchangeRateInputField.cellType = CellType.Field;
ExpensesExchangeRateInputField.cellType = CellType.Field;

View File

@@ -18,6 +18,7 @@ function APAgingSummaryHeaderDimensionsProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
keepPreviousData: true,
});
// Provider

View File

@@ -18,6 +18,7 @@ function ARAgingSummaryHeaderDimensionsProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
keepPreviousData: true,
});
// Provider

View File

@@ -4,7 +4,7 @@ import { FastField, Field } from 'formik';
import { FormGroup, Checkbox } from '@blueprintjs/core';
import styled from 'styled-components';
import { Row, Col, FieldHint, FormattedMessage as T } from 'components';
import { Flex, FlexItem, FieldHint, FormattedMessage as T } from 'components';
import {
handlePreviousYearCheckBoxChange,
handlePreviousYearChangeCheckboxChange,
@@ -15,11 +15,11 @@ import {
} from './utils';
/**
* Balance sheet header - Comparison panal.
* Balance sheet header - Comparison panal - Comparisons fields.
*/
export default function BalanceSheetHeaderComparisonPanal() {
function BalanceSheetHeaderComparisonPanalFields() {
return (
<BalanceSheetComparisonWrap>
<>
{/**----------- Previous Year -----------*/}
<Field name={'previousYear'} type={'checkbox'}>
{({ form, field }) => (
@@ -33,8 +33,9 @@ export default function BalanceSheetHeaderComparisonPanal() {
</FormGroup>
)}
</Field>
<Row>
<Col xs={3}>
<FlexSubFields align={'left'}>
<FlexItem col={6}>
<Field name={'previousYearAmountChange'} type={'checkbox'}>
{({ form, field }) => (
<FormGroup labelInfo={<FieldHint />}>
@@ -48,8 +49,9 @@ export default function BalanceSheetHeaderComparisonPanal() {
</FormGroup>
)}
</Field>
</Col>
<Col xs={3}>
</FlexItem>
<FlexItem col={6}>
<FastField name={'previousYearPercentageChange'} type={'checkbox'}>
{({ form, field }) => (
<FormGroup labelInfo={<FieldHint />}>
@@ -62,8 +64,9 @@ export default function BalanceSheetHeaderComparisonPanal() {
</FormGroup>
)}
</FastField>
</Col>
</Row>
</FlexItem>
</FlexSubFields>
{/*------------ Previous Period -----------*/}
<FastField name={'previousPeriod'} type={'checkbox'}>
{({ form, field }) => (
@@ -78,8 +81,9 @@ export default function BalanceSheetHeaderComparisonPanal() {
</FormGroup>
)}
</FastField>
<Row>
<Col xs={3}>
<FlexSubFields>
<FlexItem col={6}>
<FastField name={'previousPeriodAmountChange'} type={'checkbox'}>
{({ form, field }) => (
<FormGroup labelInfo={<FieldHint />}>
@@ -93,8 +97,9 @@ export default function BalanceSheetHeaderComparisonPanal() {
</FormGroup>
)}
</FastField>
</Col>
<Col xs={3}>
</FlexItem>
<FlexItem col={6}>
<FastField name={'previousPeriodPercentageChange'} type={'checkbox'}>
{({ form, field }) => (
<FormGroup labelInfo={<FieldHint />}>
@@ -107,8 +112,8 @@ export default function BalanceSheetHeaderComparisonPanal() {
</FormGroup>
)}
</FastField>
</Col>
</Row>
</FlexItem>
</FlexSubFields>
{/**----------- % of Column -----------*/}
<FastField name={'percentageOfColumn'} type={'checkbox'}>
@@ -137,19 +142,33 @@ export default function BalanceSheetHeaderComparisonPanal() {
</FormGroup>
)}
</FastField>
</>
);
}
/**
* Balance sheet header - Comparison panal.
*/
export default function BalanceSheetHeaderComparisonPanal() {
return (
<BalanceSheetComparisonWrap>
<BalanceSheetComparisonFieldsWrap>
<BalanceSheetHeaderComparisonPanalFields />
</BalanceSheetComparisonFieldsWrap>
</BalanceSheetComparisonWrap>
);
}
const BalanceSheetComparisonWrap = styled.div`
.row {
margin-left: 0.15rem;
.col {
min-width: 150px !important;
max-width: 190px !important;
}
}
.bp3-form-group {
margin-bottom: 3px;
}
`;
const FlexSubFields = styled(Flex)`
padding-left: 20px;
`;
const BalanceSheetComparisonFieldsWrap = styled.div`
width: 400px;
`;

View File

@@ -19,6 +19,7 @@ function BalanceSheetHeaderDimensionsProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
keepPreviousData: true,
});
// Provider

View File

@@ -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 = {

View File

@@ -26,9 +26,9 @@ export const useCashFlowStatementColumns = () => {
* Cash flow statement loading bar.
*/
export function CashFlowStatementLoadingBar() {
const { isCashFlowLoading } = useCashFlowStatementContext();
const { isCashFlowFetching } = useCashFlowStatementContext();
return (
<If condition={isCashFlowLoading}>
<If condition={isCashFlowFetching}>
<FinancialLoadingBar />
</If>
);

View File

@@ -19,6 +19,7 @@ function GeneralLedgerHeaderDimensionsPanelProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
keepPreviousData: true,
});
// Provider

View File

@@ -1,9 +1,9 @@
import React from 'react';
import { FormGroup, Classes } from '@blueprintjs/core';
import { 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 +44,13 @@ function GLHeaderGeneralPaneContent() {
</Row>
<Row>
<Col xs={4}>
<FormGroup
<FFormGroup
label={<T id={'specific_accounts'} />}
className={classNames('form-group--select-list', Classes.FILL)}
name={'accountsIds'}
className={Classes.FILL}
>
<AccountsMultiSelect items={accounts} />
</FormGroup>
<AccountMultiSelect name="accountsIds" accounts={accounts} />
</FFormGroup>
</Col>
</Row>

View File

@@ -32,6 +32,7 @@ export const getDefaultGeneralLedgerQuery = () => {
basis: 'accural',
filterByOption: 'with-transactions',
branchesIds: [],
accountsIds: [],
};
};
@@ -48,8 +49,9 @@ const parseGeneralLedgerQuery = (locationQuery) => {
return {
...transformed,
// Ensures the branches ids is always array.
// Ensures the branches, accounts ids is always array.
branchesIds: castArray(transformed.branchesIds),
accountsIds: castArray(transformed.accountsIds),
};
};

View File

@@ -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

View File

@@ -15,9 +15,12 @@ function ProfitLossSheetProvider({ query, ...props }) {
isFetching,
isLoading,
refetch,
} = useProfitLossSheet({
...transformFilterFormToQuery(query),
});
} = useProfitLossSheet(
{
...transformFilterFormToQuery(query),
},
{ keepPreviousData: true },
);
const provider = {
profitLossSheet,

View File

@@ -1,11 +1,11 @@
import React from 'react';
import { FastField, Field } from 'formik';
import { FastField } from 'formik';
import { FormGroup, Checkbox } from '@blueprintjs/core';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components';
import { Flex, FlexItem, FormattedMessage as T } from 'components';
import { Row, Col, FieldHint } from '../../../components';
import { FieldHint } from '../../../components';
import {
handlePreviousYearCheckBoxChange,
handlePreviousPeriodCheckBoxChange,
@@ -16,11 +16,12 @@ import {
} from './utils';
/**
* ProfitLoss sheet header -comparison panel.
* Profit/loss comparisons panel fields.
* @returns {JSX.Element}
*/
export default function ProfitLossSheetHeaderComparisonPanel() {
function ProfitLossComaprsionPanelFields() {
return (
<ProfitLossSheetComparisonWrap>
<>
{/**----------- Previous Year -----------*/}
<FastField name={'previousYear'} type={'checkbox'}>
{({ form, field }) => (
@@ -35,8 +36,9 @@ export default function ProfitLossSheetHeaderComparisonPanel() {
</FormGroup>
)}
</FastField>
<Row>
<Col xs={3}>
<FlexSubFields>
<FlexItem col={6}>
<FastField name={'previousYearAmountChange'} type={'checkbox'}>
{({ form, field }) => (
<FormGroup labelInfo={<FieldHint />}>
@@ -50,8 +52,8 @@ export default function ProfitLossSheetHeaderComparisonPanel() {
</FormGroup>
)}
</FastField>
</Col>
<Col xs={3}>
</FlexItem>
<FlexItem col={6}>
<FastField name={'previousYearPercentageChange'} type={'checkbox'}>
{({ form, field }) => (
<FormGroup labelInfo={<FieldHint />}>
@@ -65,8 +67,9 @@ export default function ProfitLossSheetHeaderComparisonPanel() {
</FormGroup>
)}
</FastField>
</Col>
</Row>
</FlexItem>
</FlexSubFields>
{/**----------- Previous Period (PP) -----------*/}
<FastField name={'previousPeriod'} type={'checkbox'}>
{({ form, field }) => (
@@ -81,8 +84,9 @@ export default function ProfitLossSheetHeaderComparisonPanel() {
</FormGroup>
)}
</FastField>
<Row>
<Col xs={3}>
<FlexSubFields>
<FlexItem col={6}>
<FastField name={'previousPeriodAmountChange'} type={'checkbox'}>
{({ form, field }) => (
<FormGroup labelInfo={<FieldHint />}>
@@ -96,8 +100,8 @@ export default function ProfitLossSheetHeaderComparisonPanel() {
</FormGroup>
)}
</FastField>
</Col>
<Col xs={3}>
</FlexItem>
<FlexItem col={6}>
<FastField name={'previousPeriodPercentageChange'} type={'checkbox'}>
{({ form, field }) => (
<FormGroup labelInfo={<FieldHint />}>
@@ -111,8 +115,9 @@ export default function ProfitLossSheetHeaderComparisonPanel() {
</FormGroup>
)}
</FastField>
</Col>
</Row>
</FlexItem>
</FlexSubFields>
{/**----------- % of Column -----------*/}
<FastField name={'percentageColumn'} type={'checkbox'}>
{({ field }) => (
@@ -126,6 +131,7 @@ export default function ProfitLossSheetHeaderComparisonPanel() {
</FormGroup>
)}
</FastField>
{/**----------- % of Row -----------*/}
<FastField name={'percentageRow'} type={'checkbox'}>
{({ field }) => (
@@ -139,6 +145,7 @@ export default function ProfitLossSheetHeaderComparisonPanel() {
</FormGroup>
)}
</FastField>
{/**----------- % of Expense -----------*/}
<FastField name={'percentageExpense'} type={'checkbox'}>
{({ field }) => (
@@ -152,6 +159,7 @@ export default function ProfitLossSheetHeaderComparisonPanel() {
</FormGroup>
)}
</FastField>
{/**----------- % of Income -----------*/}
<FastField name={'percentageIncome'} type={'checkbox'}>
{({ field }) => (
@@ -165,19 +173,33 @@ export default function ProfitLossSheetHeaderComparisonPanel() {
</FormGroup>
)}
</FastField>
</>
);
}
/**
* ProfitLoss sheet header -comparison panel.
*/
export default function ProfitLossSheetHeaderComparisonPanel() {
return (
<ProfitLossSheetComparisonWrap>
<ProfitLossComaprsionFieldsWrap>
<ProfitLossComaprsionPanelFields />
</ProfitLossComaprsionFieldsWrap>
</ProfitLossSheetComparisonWrap>
);
}
const ProfitLossSheetComparisonWrap = styled.div`
.row {
margin-left: 0.15rem;
.col {
min-width: 150px !important;
max-width: 190px !important;
}
}
.bp3-form-group {
margin-bottom: 3px;
}
`;
const FlexSubFields = styled(Flex)`
padding-left: 20px;
`;
const ProfitLossComaprsionFieldsWrap = styled.div`
max-width: 400px;
`;

View File

@@ -19,6 +19,7 @@ function ProfitLossSheetHeaderDimensionsProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
keepPreviousData: true,
});
// Provider

View File

@@ -18,6 +18,7 @@ function TrialBLHeaderDimensionsPanelProvider({ query, ...props }) {
// Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan,
keepPreviousData: true,
});
// Provider

View File

@@ -12,7 +12,6 @@ function VendorsBalanceSummaryProvider({ filter, ...props }) {
const query = React.useMemo(() => transformFilterFormToQuery(filter), [
filter,
]);
// Fetching vendors balance summary report based on the given query.
const {
data: VendorBalanceSummary,

View File

@@ -47,11 +47,6 @@ export default function ItemFormPrimarySection() {
<div class="mb1">
<FormattedHTMLMessage id={'products_you_buy_and_or_sell'} />
</div>
<div class="mb1">
<FormattedHTMLMessage
id={'products_you_buy_and_or_sell_but_don_t_need'}
/>
</div>
</>
);
@@ -86,7 +81,6 @@ export default function ItemFormPrimarySection() {
disabled={!isNewMode && item.type === 'inventory'}
>
<Radio label={<T id={'service'} />} value="service" />
<Radio label={<T id={'non_inventory'} />} value="non-inventory" />
<Radio label={<T id={'inventory'} />} value="inventory" />
</RadioGroup>
</FormGroup>
@@ -126,7 +120,11 @@ export default function ItemFormPrimarySection() {
helperText={<ErrorMessage name={'code'} />}
inline={true}
>
<InputGroup medium={true} intent={inputIntent({ error, touched })} {...field} />
<InputGroup
medium={true}
intent={inputIntent({ error, touched })}
{...field}
/>
</FormGroup>
)}
</FastField>

View File

@@ -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,
});
}
};
/**

View File

@@ -50,7 +50,7 @@ function ItemsCategoryTable({
loading={isCategoriesLoading}
headerLoading={isCategoriesLoading}
progressBarLoading={isCategoriesFetching}
expandable={true}
expandable={false}
sticky={true}
selectionColumn={true}
TableLoadingRenderer={TableSkeletonRows}

View File

@@ -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()

View File

@@ -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 (
<React.Fragment>
{/* --------- Statement--------- */}
<StatementFormGroup
name={'statement'}
label={<T id={'payment_made_form.label.statement'} />}
hintText={'Will be displayed on the Payment'}
{/* --------- Internal Note--------- */}
<InternalNoteFormGroup
name={'internal_note'}
label={<T id={'payment_made.form.internal_note.label'} />}
>
<FEditableText
name={'statement'}
placeholder={intl.get('payment_made_form.statement.placeholder')}
name={'internal_note'}
placeholder={intl.get('payment_made.form.internal_note.placeholder')}
/>
</StatementFormGroup>
</InternalNoteFormGroup>
</React.Fragment>
);
}
const StatementFormGroup = styled(FFormGroup)`
const InternalNoteFormGroup = styled(FFormGroup)`
&.bp3-form-group {
margin-bottom: 40px;

View File

@@ -103,7 +103,7 @@ function PaymentMadeFormProvider({ query, paymentMadeId, ...props }) {
<DashboardInsider
loading={
isVendorsLoading ||
isItemsFetching ||
isItemsLoading ||
isAccountsLoading ||
isPaymentLoading
}

View File

@@ -10,7 +10,6 @@ export function CreditNoteFormFooterLeft() {
<CreditNoteMsgFormGroup
name={'note'}
label={<T id={'credit_note.label_customer_note'} />}
hintText={'Will be displayed on the invoice'}
>
<FEditableText
name={'note'}
@@ -24,9 +23,9 @@ export function CreditNoteFormFooterLeft() {
>
<FEditableText
name={'terms_conditions'}
placeholder={
<T id={'credit_note.label_terms_and_conditions.placeholder'} />
}
placeholder={intl.get(
'credit_note.label_terms_and_conditions.placeholder',
)}
/>
</TermsConditsFormGroup>
</React.Fragment>

View File

@@ -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)

View File

@@ -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_')),

View File

@@ -10,7 +10,6 @@ export function InvoiceFormFooterLeft() {
<InvoiceMsgFormGroup
name={'invoice_message'}
label={<T id={'invoice_message'} />}
hintText={'Will be displayed on the invoice'}
>
<FEditableText
name={'invoice_message'}
@@ -20,7 +19,7 @@ export function InvoiceFormFooterLeft() {
{/* --------- Terms and conditions --------- */}
<TermsConditsFormGroup
label={<T id={'invoice_form.label.invoice_message'} />}
label={<T id={'invoice_form.label.terms_conditions'} />}
name={'terms_conditions'}
>
<FEditableText

View File

@@ -147,7 +147,7 @@ function InvoiceFormHeaderFields({
</FastField>
</Col>
<Col className={'col--due-date'}>
<Col xs={6}>
{/* ----------- Due date ----------- */}
<FastField name={'due_date'}>
{({ form, field: { value }, meta: { error, touched } }) => (

View File

@@ -7,14 +7,24 @@ export function PaymentReceiveFormFootetLeft() {
return (
<React.Fragment>
{/* --------- Statement--------- */}
<TermsConditsFormGroup
name={'statement'}
label={<T id={'payment_receive_form.label.statement'} />}
hintText={'Will be displayed on the Payment'}
<PaymentMsgFormGroup
name={'message'}
label={<T id={'payment_receive_form.message.label'} />}
>
<FEditableText
name={'statement'}
placeholder={intl.get('payment_receive_form.statement.placeholder')}
name={'message'}
placeholder={intl.get('payment_receive_form.message.placeholder')}
/>
</PaymentMsgFormGroup>
{/* --------- Internal Note--------- */}
<TermsConditsFormGroup
name={'internal_note'}
label={<T id={'payment_receive_form.label.note'} />}
>
<FEditableText
name={'internal_note'}
placeholder={intl.get('payment_receive_form.internal_note.placeholder')}
/>
</TermsConditsFormGroup>
</React.Fragment>
@@ -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;
}
}
`;

View File

@@ -18,16 +18,18 @@ export function ReceiptFormFooterLeft() {
/>
</ReceiptMsgFormGroup>
{/* --------- Statement--------- */}
<StatementFormGroup
label={<T id={'receipt_form.label.statement'} />}
name={'statement'}
{/* --------- Terms and conditions --------- */}
<TermsConditsFormGroup
label={<T id={'receipt_form.label.terms_conditions'} />}
name={'terms_conditions'}
>
<FEditableText
name={'statement'}
placeholder={intl.get('receipt_form.statement.placeholder')}
name={'terms_conditions'}
placeholder={intl.get(
'receipt_form.terms_and_conditions.placeholder',
)}
/>
</StatementFormGroup>
</TermsConditsFormGroup>
</React.Fragment>
);
}
@@ -46,7 +48,7 @@ const ReceiptMsgFormGroup = styled(FFormGroup)`
}
`;
const StatementFormGroup = styled(FFormGroup)`
const TermsConditsFormGroup = styled(FFormGroup)`
&.bp3-form-group {
.bp3-label {
font-size: 12px;

View File

@@ -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 (
<div
className={classNames(
@@ -141,7 +141,7 @@ function WarehouseTransferForm({
<WarehouseTransferFormFooter />
<WarehouseTransferFormDialog />
<WarehouseTransferFloatingActions />
<WarehouseTransferObserveItemsCost />
<WarehouseTransferObserveItemsCost />
</Form>
</Formik>
</div>

View File

@@ -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),
}),
),
});

View File

@@ -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);

View File

@@ -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() {
<React.Fragment>
{/* --------- Terms and conditions --------- */}
<TermsConditsFormGroup
label={<T id={'terms_conditions'} />}
label={<T id={'warehouse_transfer.form.reason.label'} />}
name={'reason'}
>
<FEditableText
name={'reason'}
placeholder={
'Enter the terms and conditions of your business to be displayed in your transaction'
}
placeholder={intl.get('warehouse_transfer.form.reason.placeholder')}
/>
</TermsConditsFormGroup>
</React.Fragment>

View File

@@ -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';

View File

@@ -183,20 +183,6 @@ function WarehouseTransferFormHeaderFields({
</FormGroup>
)}
</FastField>
{/*------------ reason -----------*/}
<FastField name={'reason'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'reason'} />}
className={'form-group--reason'}
intent={inputIntent({ error, touched })}
inline={true}
helperText={<ErrorMessage name={'reason'} />}
>
<InputGroup minimal={true} {...field} />
</FormGroup>
)}
</FastField>
</div>
);
}

View File

@@ -21,7 +21,10 @@ export function ActionsCellRenderer({
const exampleMenu = (
<Menu>
<MenuItem onClick={onRemoveRole} text="Remove line" />
<MenuItem
onClick={onRemoveRole}
text={intl.get('warehouse_transfer.entries.remove_row')}
/>
</Menu>
);

View File

@@ -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);
};
/**

View File

@@ -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';

View File

@@ -34,6 +34,9 @@ const commonInvalidateQueries = (queryClient) => {
// Invalidate
queryClient.invalidateQueries(t.ITEM_ASSOCIATED_WITH_INVOICES);
// Invalidate item warehouses.
queryClient.invalidateQueries(t.ITEM_WAREHOUSES_LOCATION);
};
/**

Some files were not shown because too many files have changed in this diff Show More