Compare commits

...

51 Commits

Author SHA1 Message Date
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
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
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
78 changed files with 813 additions and 458 deletions

View File

@@ -2,6 +2,53 @@
All notable changes to Bigcapital server-side will be in this file. All notable changes to Bigcapital server-side will be in this file.
## [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 ## [1.6.3] - 21-02-2022
### Fixed ### Fixed

View File

@@ -1,6 +1,6 @@
{ {
"name": "bigcapital-client", "name": "bigcapital-client",
"version": "1.6.3", "version": "1.7.1",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@babel/core": "7.8.4", "@babel/core": "7.8.4",

View File

@@ -1,3 +1,4 @@
export * from './accountTypes';
export * from './TableStyle'; export * from './TableStyle';
export * from './features'; export * from './features';
export * from './cellTypes'; 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

@@ -104,6 +104,7 @@ export * from './Warehouses';
export * from './Currencies'; export * from './Currencies';
export * from './FormTopbar' export * from './FormTopbar'
export * from './Paper'; export * from './Paper';
export * from './Accounts'
const Hint = FieldHint; const Hint = FieldHint;

View File

@@ -4,7 +4,12 @@ import { Popover2 } from '@blueprintjs/popover2';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
import intl from 'react-intl-universal'; 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 { import {
AccountsListFieldCell, AccountsListFieldCell,
MoneyFieldCell, MoneyFieldCell,
@@ -63,7 +68,10 @@ export const ActionsCellRenderer = ({
}; };
const exampleMenu = ( const exampleMenu = (
<Menu> <Menu>
<MenuItem onClick={handleClickRemoveRole} text="Remove line" /> <MenuItem
onClick={handleClickRemoveRole}
text={intl.get('make_journal.entries.remove_row')}
/>
</Menu> </Menu>
); );
return ( return (

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,17 @@
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import * as R from 'ramda'; 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) => { export const transformApiErrors = (errors) => {
const fields = {}; const fields = {};
if (errors.find((e) => e.type === 'NOT_UNIQUE_CODE')) { if (errors.find((e) => e.type === 'NOT_UNIQUE_CODE')) {
@@ -23,7 +33,7 @@ export const transformApiErrors = (errors) => {
/** /**
* Payload transformer in account edit mode. * Payload transformer in account edit mode.
*/ */
function transformEditMode(payload) { function tranformNewChildAccountPayload(payload) {
return { return {
parent_account_id: payload.parentAccountId || '', parent_account_id: payload.parentAccountId || '',
account_type: payload.accountType || '', account_type: payload.accountType || '',
@@ -34,7 +44,7 @@ function transformEditMode(payload) {
/** /**
* Payload transformer in new account with defined type. * Payload transformer in new account with defined type.
*/ */
function transformNewAccountDefinedType(payload) { function transformNewDefinedTypePayload(payload) {
return { return {
account_type: payload.accountType || '', account_type: payload.accountType || '',
}; };
@@ -60,9 +70,9 @@ const defaultPayloadTransform = () => ({});
*/ */
function getConditions() { function getConditions() {
return [ return [
['edit'], [AccountDialogAction.Edit],
['new_child', transformEditMode], [AccountDialogAction.NewChild, tranformNewChildAccountPayload],
['NEW_ACCOUNT_DEFINED_TYPE', transformNewAccountDefinedType], [AccountDialogAction.NewDefinedType, transformNewDefinedTypePayload],
]; ];
} }
@@ -73,7 +83,7 @@ export const transformAccountToForm = (account, payload) => {
const conditions = getConditions(); const conditions = getConditions();
const results = conditions.map((condition) => { const results = conditions.map((condition) => {
const transformer = !isEmpty(condition[1]) const transformer = !isUndefined(condition[1])
? condition[1] ? condition[1]
: defaultPayloadTransform; : defaultPayloadTransform;
@@ -84,3 +94,15 @@ export const transformAccountToForm = (account, payload) => {
}); });
return R.cond(results)(account); 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,15 +9,15 @@ import {
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { Can, FormattedMessage as T } from 'components'; import { Can, FormattedMessage as T } from 'components';
import { AccountAction, AbilitySubject } from '../../../common/abilityOption';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import withDialogActions from 'containers/Dialog/withDialogActions'; import withDialogActions from 'containers/Dialog/withDialogActions';
import withAlertsActions from 'containers/Alert/withAlertActions'; import withAlertsActions from 'containers/Alert/withAlertActions';
import { safeCallback } from 'utils'; import { AccountDialogAction } from 'containers/Dialogs/AccountDialog/utils';
import { AccountAction, AbilitySubject } from '../../../common/abilityOption';
import { compose } from 'utils';
import { useAccountDrawerContext } from './AccountDrawerProvider'; import { useAccountDrawerContext } from './AccountDrawerProvider';
import { compose, safeCallback } from 'utils';
/** /**
* Account drawer action bar. * Account drawer action bar.
@@ -35,17 +35,18 @@ function AccountDrawerActionBar({
// Handle new child button click. // Handle new child button click.
const onNewChildAccount = () => { const onNewChildAccount = () => {
openDialog('account-form', { openDialog('account-form', {
action: 'new_child', action: AccountDialogAction.NewChild,
parentAccountId: account.id, parentAccountId: account.id,
accountType: account.account_type, accountType: account.account_type,
}); });
}; };
// Handle edit account action. // Handle edit account action.
const onEditAccount = () => { const onEditAccount = () => {
openDialog('account-form', { action: 'edit', id: account.id }); openDialog('account-form', {
action: AccountDialogAction.Edit,
id: account.id,
});
}; };
// Handle delete action account. // Handle delete action account.
const onDeleteAccount = () => { const onDeleteAccount = () => {
openAlert('account-delete', { accountId: account.id }); openAlert('account-delete', { accountId: account.id });

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,6 +10,7 @@ import {
Col, Col,
DetailItem, DetailItem,
DetailsMenu, DetailsMenu,
FormatDate,
ExchangeRateDetailItem, ExchangeRateDetailItem,
FormattedMessage as T, FormattedMessage as T,
} from 'components'; } from 'components';
@@ -64,10 +65,12 @@ export default function ExpenseDrawerHeader() {
minLabelSize={'180px'} minLabelSize={'180px'}
> >
<DetailItem label={<T id={'published_at'} />}> <DetailItem label={<T id={'published_at'} />}>
{moment(expense.published_at).format('YYYY MMM DD')} <FormatDate value={expense.published_at} />
</DetailItem> </DetailItem>
<DetailItem label={<T id={'created_at'} />}>2021 Aug 24</DetailItem> <DetailItem label={<T id={'created_at'} />}>
<FormatDate value={expense.created_at} />
</DetailItem>
</DetailsMenu> </DetailsMenu>
</Col> </Col>
</Row> </Row>

View File

@@ -1,6 +1,9 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal';
import { useExpense } from 'hooks/query'; 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(); const ExpenseDrawerDrawerContext = React.createContext();
@@ -8,6 +11,9 @@ const ExpenseDrawerDrawerContext = React.createContext();
* Expense drawer provider. * Expense drawer provider.
*/ */
function ExpenseDrawerProvider({ expenseId, ...props }) { function ExpenseDrawerProvider({ expenseId, ...props }) {
// Features guard.
const { featureCan } = useFeatureCan();
// Fetch the expense details. // Fetch the expense details.
const { const {
data: expense, data: expense,
@@ -28,6 +34,17 @@ function ExpenseDrawerProvider({ expenseId, ...props }) {
return ( return (
<DrawerLoading loading={isExpenseLoading}> <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} /> <ExpenseDrawerDrawerContext.Provider value={provider} {...props} />
</DrawerLoading> </DrawerLoading>
); );

View File

@@ -1,6 +1,4 @@
import React, { lazy } from 'react'; import React, { lazy } from 'react';
import intl from 'react-intl-universal';
import { Drawer, DrawerSuspense } from 'components'; import { Drawer, DrawerSuspense } from 'components';
import withDrawers from 'containers/Drawer/withDrawers'; import withDrawers from 'containers/Drawer/withDrawers';
@@ -22,7 +20,6 @@ function ExpenseDrawer({
<Drawer <Drawer
isOpen={isOpen} isOpen={isOpen}
name={name} name={name}
title={intl.get('expense.drawer.title')}
size={'65%'} size={'65%'}
style={{ minWidth: '700px', maxWidth: '900px' }} style={{ minWidth: '700px', maxWidth: '900px' }}
> >

View File

@@ -5,7 +5,7 @@ import intl from 'react-intl-universal';
import { defaultTo } from 'lodash'; import { defaultTo } from 'lodash';
import clsx from 'classnames'; import clsx from 'classnames';
import { DetailsMenu, DetailItem } from 'components'; import { DetailsMenu, DetailItem, FormatDate } from 'components';
import { useInventoryAdjustmentDrawerContext } from './InventoryAdjustmentDrawerProvider'; import { useInventoryAdjustmentDrawerContext } from './InventoryAdjustmentDrawerProvider';
import InventoryAdjustmentDrawerCls from 'style/components/Drawers/InventoryAdjustmentDrawer.module.scss'; import InventoryAdjustmentDrawerCls from 'style/components/Drawers/InventoryAdjustmentDrawer.module.scss';
@@ -20,7 +20,7 @@ export default function InventoryAdjustmentDetailHeader() {
<div className={clsx(InventoryAdjustmentDrawerCls.detail_panel_header)}> <div className={clsx(InventoryAdjustmentDrawerCls.detail_panel_header)}>
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}> <DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
<DetailItem label={intl.get('date')}> <DetailItem label={intl.get('date')}>
{moment(inventoryAdjustment.date).format('YYYY MMM DD')} <FormatDate value={inventoryAdjustment.date} />
</DetailItem> </DetailItem>
<DetailItem label={intl.get('type')}> <DetailItem label={intl.get('type')}>
@@ -36,7 +36,7 @@ export default function InventoryAdjustmentDetailHeader() {
</DetailItem> </DetailItem>
<DetailItem label={intl.get('published_at')}> <DetailItem label={intl.get('published_at')}>
{moment(inventoryAdjustment.published_at).format('YYYY MMM DD')} <FormatDate value={inventoryAdjustment.published_at} />
</DetailItem> </DetailItem>
<DetailItem label={intl.get('reason')}> <DetailItem label={intl.get('reason')}>
@@ -44,7 +44,7 @@ export default function InventoryAdjustmentDetailHeader() {
</DetailItem> </DetailItem>
<DetailItem label={intl.get('created_at')}> <DetailItem label={intl.get('created_at')}>
{moment(inventoryAdjustment.created_at).format('YYYY MMM DD')} <FormatDate value={inventoryAdjustment.created_at} />
</DetailItem> </DetailItem>
</DetailsMenu> </DetailsMenu>
</div> </div>

View File

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

View File

@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import { DrawerHeaderContent, DrawerLoading } from 'components'; import { DrawerHeaderContent, DrawerLoading } from 'components';
import { useItem } from 'hooks/query'; import { useItem } from 'hooks/query';
import { inactiveStatus } from './utlis';
const ItemDetailDrawerContext = React.createContext(); const ItemDetailDrawerContext = React.createContext();
@@ -27,7 +28,10 @@ function ItemDetailDrawerProvider({ itemId, ...props }) {
return ( return (
<DrawerLoading loading={isItemLoading}> <DrawerLoading loading={isItemLoading}>
<DrawerHeaderContent name="item-detail-drawer" title={item?.name} /> <DrawerHeaderContent
name="item-detail-drawer"
title={inactiveStatus(item)}
/>
<ItemDetailDrawerContext.Provider value={provider} {...props} /> <ItemDetailDrawerContext.Provider value={provider} {...props} />
</DrawerLoading> </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'} />} text={<T id={'edit_journal'} />}
onClick={handleEditManualJournal} onClick={handleEditManualJournal}
/> />
<NavbarDivider />
</Can> </Can>
<Can I={ManualJournalAction.Delete} a={AbilitySubject.ManualJournal}> <Can I={ManualJournalAction.Delete} a={AbilitySubject.ManualJournal}>
<NavbarDivider />
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}
icon={<Icon icon="trash-16" iconSize={16} />} icon={<Icon icon="trash-16" iconSize={16} />}

View File

@@ -3,6 +3,8 @@ import React from 'react';
import { Tag, Intent, Classes, Tooltip, Position } from '@blueprintjs/core'; import { Tag, Intent, Classes, Tooltip, Position } from '@blueprintjs/core';
import { T, Choose, FormatNumberCell, If, Icon } from '../../../components'; import { T, Choose, FormatNumberCell, If, Icon } from '../../../components';
import { Features } from 'common';
import { useFeatureCan } from 'hooks/state';
/** /**
* Note column accessor. * Note column accessor.
@@ -46,8 +48,9 @@ export function ManualJournalDetailsStatus({ manualJournal }) {
/** /**
* Retrieve read-only manual journal entries columns. * Retrieve read-only manual journal entries columns.
*/ */
export const useManualJournalEntriesColumns = () => export const useManualJournalEntriesColumns = () => {
React.useMemo( const { featureCan } = useFeatureCan();
return React.useMemo(
() => [ () => [
{ {
Header: intl.get('account_name'), Header: intl.get('account_name'),
@@ -70,6 +73,17 @@ export const useManualJournalEntriesColumns = () =>
disableSortBy: true, disableSortBy: true,
className: 'note', className: 'note',
}, },
...(featureCan(Features.Branches)
? [
{
Header: intl.get('branch'),
width: 130,
accessor: 'branch.name',
disableSortBy: true,
className: 'branch',
},
]
: []),
{ {
Header: intl.get('credit'), Header: intl.get('credit'),
accessor: 'credit', accessor: 'credit',
@@ -93,5 +107,6 @@ export const useManualJournalEntriesColumns = () =>
align: 'right', align: 'right',
}, },
], ],
[], [featureCan],
); );
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -48,7 +48,10 @@ const ActionsCellRenderer = ({
}; };
const exampleMenu = ( const exampleMenu = (
<Menu> <Menu>
<MenuItem onClick={handleClickRemoveRole} text="Remove line" /> <MenuItem
onClick={handleClickRemoveRole}
text={intl.get('expense.entries.remove_row')}
/>
</Menu> </Menu>
); );
return ( 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. // Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches(query, { const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
enabled: isBranchFeatureCan, enabled: isBranchFeatureCan,
keepPreviousData: true,
}); });
// Provider // Provider

View File

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

View File

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

View File

@@ -10,16 +10,16 @@ const CashFlowStatementDimensionsPanelContext = React.createContext();
* cash flow statement dimensions panel provider. * cash flow statement dimensions panel provider.
* @returns * @returns
*/ */
function CashFlowStatementDimensionsPanelProvider({ query,...props }) { function CashFlowStatementDimensionsPanelProvider({ query, ...props }) {
// Features guard. // Features guard.
const { featureCan } = useFeatureCan(); const { featureCan } = useFeatureCan();
const isBranchFeatureCan = featureCan(Features.Branches); const isBranchFeatureCan = featureCan(Features.Branches);
// Fetches the branches list. // Fetches the branches list.
const { isLoading: isBranchesLoading, data: branches } = useBranches( const { isLoading: isBranchesLoading, data: branches } = useBranches(query, {
query, enabled: isBranchFeatureCan,
{ enabled: isBranchFeatureCan }, keepPreviousData: true,
); });
// Provider // Provider
const provider = { const provider = {

View File

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

View File

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

View File

@@ -3,7 +3,8 @@ import { FormGroup, Classes } from '@blueprintjs/core';
import { FormattedMessage as T } from 'components'; import { FormattedMessage as T } from 'components';
import classNames from 'classnames'; 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 FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
import RadiosAccountingBasis from '../RadiosAccountingBasis'; import RadiosAccountingBasis from '../RadiosAccountingBasis';
@@ -44,12 +45,13 @@ function GLHeaderGeneralPaneContent() {
</Row> </Row>
<Row> <Row>
<Col xs={4}> <Col xs={4}>
<FormGroup <FFormGroup
label={<T id={'specific_accounts'} />} label={<T id={'specific_accounts'} />}
className={classNames('form-group--select-list', Classes.FILL)} name={'accounts'}
className={Classes.FILL}
> >
<AccountsMultiSelect items={accounts} /> <AccountMultiSelect name="accounts" accounts={accounts} />
</FormGroup> </FFormGroup>
</Col> </Col>
</Row> </Row>

View File

@@ -32,6 +32,7 @@ export const getDefaultGeneralLedgerQuery = () => {
basis: 'accural', basis: 'accural',
filterByOption: 'with-transactions', filterByOption: 'with-transactions',
branchesIds: [], branchesIds: [],
accounts: [],
}; };
}; };

View File

@@ -24,12 +24,13 @@ function InventoryValuationHeaderDimensionsProvider({ ...props }) {
// Fetches the warehouses list. // Fetches the warehouses list.
const { data: warehouses, isLoading: isWarehouesLoading } = useWarehouses( const { data: warehouses, isLoading: isWarehouesLoading } = useWarehouses(
null, null,
{ enabled: isWarehouseFeatureCan }, { enabled: isWarehouseFeatureCan, keepPreviousData: true },
); );
// Fetches the branches list. // Fetches the branches list.
const { data: branches, isLoading: isBranchLoading } = useBranches(null, { const { data: branches, isLoading: isBranchLoading } = useBranches(null, {
enabled: isBranchFeatureCan, enabled: isBranchFeatureCan,
keepPreviousData: true,
}); });
// Provider // Provider

View File

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

View File

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

View File

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

View File

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

View File

@@ -64,7 +64,6 @@ export const transitionItemTypeKeyToLabel = (itemTypeKey) => {
const table = { const table = {
service: intl.get('service'), service: intl.get('service'),
inventory: intl.get('inventory'), inventory: intl.get('inventory'),
'non-inventory': intl.get('non_inventory'),
}; };
return typeof table[itemTypeKey] === 'string' ? table[itemTypeKey] : ''; return typeof table[itemTypeKey] === 'string' ? table[itemTypeKey] : '';
}; };
@@ -104,6 +103,14 @@ export const handleDeleteErrors = (errors) => {
intent: Intent.DANGER, 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} loading={isCategoriesLoading}
headerLoading={isCategoriesLoading} headerLoading={isCategoriesLoading}
progressBarLoading={isCategoriesFetching} progressBarLoading={isCategoriesFetching}
expandable={true} expandable={false}
sticky={true} sticky={true}
selectionColumn={true} selectionColumn={true}
TableLoadingRenderer={TableSkeletonRows} TableLoadingRenderer={TableSkeletonRows}

View File

@@ -1,16 +1,19 @@
import * as Yup from 'yup'; import * as Yup from 'yup';
import moment from 'moment';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { DATATYPES_LENGTH } from 'common/dataTypes'; import { DATATYPES_LENGTH } from 'common/dataTypes';
import { isBlank } from 'utils'; import { isBlank } from 'utils';
const BillFormSchema = Yup.object().shape({ const BillFormSchema = Yup.object().shape({
vendor_id: Yup.number() vendor_id: Yup.number().required().label(intl.get('vendor_name_')),
.required() bill_date: Yup.date().required().label(intl.get('bill_date_')),
.label(intl.get('vendor_name_')),
bill_date: Yup.date()
.required()
.label(intl.get('bill_date_')),
due_date: Yup.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() .required()
.label(intl.get('due_date_')), .label(intl.get('due_date_')),
bill_number: Yup.string() bill_number: Yup.string()
@@ -25,7 +28,7 @@ const BillFormSchema = Yup.object().shape({
open: Yup.boolean(), open: Yup.boolean(),
branch_id: Yup.string(), branch_id: Yup.string(),
warehouse_id: Yup.string(), warehouse_id: Yup.string(),
exchange_rate:Yup.number(), exchange_rate: Yup.number(),
entries: Yup.array().of( entries: Yup.array().of(
Yup.object().shape({ Yup.object().shape({
quantity: Yup.number() quantity: Yup.number()

View File

@@ -3,24 +3,28 @@ import intl from 'react-intl-universal';
import styled from 'styled-components'; import styled from 'styled-components';
import { FFormGroup, FEditableText, FormattedMessage as T } from 'components'; import { FFormGroup, FEditableText, FormattedMessage as T } from 'components';
/**
* Payment made form footer left-side.
* @returns {JSX.Element}
*/
export function PaymentMadeFormFooterLeft() { export function PaymentMadeFormFooterLeft() {
return ( return (
<React.Fragment> <React.Fragment>
{/* --------- Statement--------- */} {/* --------- Internal Note--------- */}
<StatementFormGroup <InternalNoteFormGroup
name={'statement'} name={'internal_note'}
label={<T id={'payment_made_form.label.statement'} />} label={<T id={'payment_made.form.internal_note.label'} />}
hintText={'Will be displayed on the Payment'}
> >
<FEditableText <FEditableText
name={'statement'} name={'internal_note'}
placeholder={intl.get('payment_made_form.statement.placeholder')} placeholder={intl.get('payment_made.form.internal_note.placeholder')}
/> />
</StatementFormGroup> </InternalNoteFormGroup>
</React.Fragment> </React.Fragment>
); );
} }
const StatementFormGroup = styled(FFormGroup)`
const InternalNoteFormGroup = styled(FFormGroup)`
&.bp3-form-group { &.bp3-form-group {
margin-bottom: 40px; margin-bottom: 40px;

View File

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

View File

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

View File

@@ -2,16 +2,19 @@ import * as Yup from 'yup';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { DATATYPES_LENGTH } from 'common/dataTypes'; import { DATATYPES_LENGTH } from 'common/dataTypes';
import { isBlank } from 'utils'; import { isBlank } from 'utils';
import moment from 'moment';
const Schema = Yup.object().shape({ const Schema = Yup.object().shape({
customer_id: Yup.number() customer_id: Yup.number().label(intl.get('customer_name_')).required(),
.label(intl.get('customer_name_')) estimate_date: Yup.date().required().label(intl.get('estimate_date_')),
.required(),
estimate_date: Yup.date()
.required()
.label(intl.get('estimate_date_')),
expiration_date: Yup.date() expiration_date: Yup.date()
.required() .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_')), .label(intl.get('expiration_date_')),
estimate_number: Yup.string() estimate_number: Yup.string()
.max(DATATYPES_LENGTH.STRING) .max(DATATYPES_LENGTH.STRING)

View File

@@ -1,4 +1,5 @@
import * as Yup from 'yup'; import * as Yup from 'yup';
import moment from 'moment';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { DATATYPES_LENGTH } from 'common/dataTypes'; import { DATATYPES_LENGTH } from 'common/dataTypes';
import { isBlank } from 'utils'; import { isBlank } from 'utils';
@@ -7,7 +8,15 @@ const getSchema = () =>
Yup.object().shape({ Yup.object().shape({
customer_id: Yup.string().label(intl.get('customer_name_')).required(), customer_id: Yup.string().label(intl.get('customer_name_')).required(),
invoice_date: Yup.date().required().label(intl.get('invoice_date_')), 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() invoice_no: Yup.string()
.max(DATATYPES_LENGTH.STRING) .max(DATATYPES_LENGTH.STRING)
.label(intl.get('invoice_no_')), .label(intl.get('invoice_no_')),

View File

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

View File

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

View File

@@ -7,14 +7,24 @@ export function PaymentReceiveFormFootetLeft() {
return ( return (
<React.Fragment> <React.Fragment>
{/* --------- Statement--------- */} {/* --------- Statement--------- */}
<TermsConditsFormGroup <PaymentMsgFormGroup
name={'statement'} name={'message'}
label={<T id={'payment_receive_form.label.statement'} />} label={<T id={'payment_receive_form.message.label'} />}
hintText={'Will be displayed on the Payment'}
> >
<FEditableText <FEditableText
name={'statement'} name={'message'}
placeholder={intl.get('payment_receive_form.statement.placeholder')} 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> </TermsConditsFormGroup>
</React.Fragment> </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> </ReceiptMsgFormGroup>
{/* --------- Statement--------- */} {/* --------- Terms and conditions --------- */}
<StatementFormGroup <TermsConditsFormGroup
label={<T id={'receipt_form.label.statement'} />} label={<T id={'receipt_form.label.terms_conditions'} />}
name={'statement'} name={'terms_conditions'}
> >
<FEditableText <FEditableText
name={'statement'} name={'terms_conditions'}
placeholder={intl.get('receipt_form.statement.placeholder')} placeholder={intl.get(
'receipt_form.terms_and_conditions.placeholder',
)}
/> />
</StatementFormGroup> </TermsConditsFormGroup>
</React.Fragment> </React.Fragment>
); );
} }
@@ -46,7 +48,7 @@ const ReceiptMsgFormGroup = styled(FFormGroup)`
} }
`; `;
const StatementFormGroup = styled(FFormGroup)` const TermsConditsFormGroup = styled(FFormGroup)`
&.bp3-form-group { &.bp3-form-group {
.bp3-label { .bp3-label {
font-size: 12px; font-size: 12px;

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import { isEmpty } from 'lodash'; import { isEmpty, sumBy } from 'lodash';
import { Intent } from '@blueprintjs/core'; import { Intent } from '@blueprintjs/core';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
@@ -20,7 +20,7 @@ import WarehouseTransferFormDialog from './WarehouseTransferFormDialog';
import withDashboardActions from 'containers/Dashboard/withDashboardActions'; import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withSettings from 'containers/Settings/withSettings'; import withSettings from 'containers/Settings/withSettings';
import { AppToaster, } from 'components'; import { AppToaster } from 'components';
import { useWarehouseTransferFormContext } from './WarehouseTransferFormProvider'; import { useWarehouseTransferFormContext } from './WarehouseTransferFormProvider';
import { compose, orderingLinesIndexes, transactionNumber } from 'utils'; import { compose, orderingLinesIndexes, transactionNumber } from 'utils';
import { WarehouseTransferObserveItemsCost } from './components'; import { WarehouseTransferObserveItemsCost } from './components';
@@ -119,7 +119,7 @@ function WarehouseTransferForm({
.catch(onError); .catch(onError);
} }
}; };
return ( return (
<div <div
className={classNames( className={classNames(
@@ -141,7 +141,7 @@ function WarehouseTransferForm({
<WarehouseTransferFormFooter /> <WarehouseTransferFormFooter />
<WarehouseTransferFormDialog /> <WarehouseTransferFormDialog />
<WarehouseTransferFloatingActions /> <WarehouseTransferFloatingActions />
<WarehouseTransferObserveItemsCost /> <WarehouseTransferObserveItemsCost />
</Form> </Form>
</Formik> </Formik>
</div> </div>

View File

@@ -20,7 +20,7 @@ const Schema = Yup.object().shape({
Yup.object().shape({ Yup.object().shape({
item_id: Yup.number().nullable(), item_id: Yup.number().nullable(),
description: Yup.string().nullable().max(DATATYPES_LENGTH.TEXT), 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, item_id: newRowMeta.itemId,
warehouses: newRowMeta.warehouses, warehouses: newRowMeta.warehouses,
description: '', description: '',
quantity: 0, quantity: '',
}; };
const newRows = mutateTableRow(newRowMeta.rowIndex, newRow, entries); const newRows = mutateTableRow(newRowMeta.rowIndex, newRow, entries);

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import intl from 'react-intl-universal';
import { FFormGroup, FEditableText, FormattedMessage as T } from 'components'; import { FFormGroup, FEditableText, FormattedMessage as T } from 'components';
export function WarehouseTransferFormFooterLeft() { export function WarehouseTransferFormFooterLeft() {
@@ -7,14 +8,12 @@ export function WarehouseTransferFormFooterLeft() {
<React.Fragment> <React.Fragment>
{/* --------- Terms and conditions --------- */} {/* --------- Terms and conditions --------- */}
<TermsConditsFormGroup <TermsConditsFormGroup
label={<T id={'terms_conditions'} />} label={<T id={'warehouse_transfer.form.reason.label'} />}
name={'reason'} name={'reason'}
> >
<FEditableText <FEditableText
name={'reason'} name={'reason'}
placeholder={ placeholder={intl.get('warehouse_transfer.form.reason.placeholder')}
'Enter the terms and conditions of your business to be displayed in your transaction'
}
/> />
</TermsConditsFormGroup> </TermsConditsFormGroup>
</React.Fragment> </React.Fragment>

View File

@@ -1,7 +1,5 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { useFormikContext } from 'formik';
import intl from 'react-intl-universal';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import WarehouseTransferFormHeaderFields from './WarehouseTransferFormHeaderFields'; import WarehouseTransferFormHeaderFields from './WarehouseTransferFormHeaderFields';

View File

@@ -183,20 +183,6 @@ function WarehouseTransferFormHeaderFields({
</FormGroup> </FormGroup>
)} )}
</FastField> </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> </div>
); );
} }

View File

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

View File

@@ -33,6 +33,9 @@ const commonInvalidateQueries = (queryClient) => {
// Invalidate items associated bills transactions. // Invalidate items associated bills transactions.
queryClient.invalidateQueries(t.ITEMS_ASSOCIATED_WITH_BILLS); 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 './creditNote';
export * from './vendorCredit'; export * from './vendorCredit';
export * from './transactionsLocking'; export * from './transactionsLocking';
export * from './warehouses' export * from './warehouses';
export * from './branches'; export * from './branches';
export * from './warehousesTransfers';

View File

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

View File

@@ -27,6 +27,9 @@ const commonInvalidateQueries = (queryClient) => {
// Invalidate // Invalidate
queryClient.invalidateQueries(t.ITEM_ASSOCIATED_WITH_RECEIPTS); queryClient.invalidateQueries(t.ITEM_ASSOCIATED_WITH_RECEIPTS);
// Invalidate item warehouses.
queryClient.invalidateQueries(t.ITEM_WAREHOUSES_LOCATION);
// Invalidate the settings. // Invalidate the settings.
queryClient.invalidateQueries([t.SETTING, t.SETTING_RECEIPTS]); queryClient.invalidateQueries([t.SETTING, t.SETTING_RECEIPTS]);
}; };

View File

@@ -12,7 +12,6 @@ const commonInvalidateQueries = (queryClient) => {
// Invalidate warehouses transfers. // Invalidate warehouses transfers.
queryClient.invalidateQueries(t.WAREHOUSE_TRANSFERS); queryClient.invalidateQueries(t.WAREHOUSE_TRANSFERS);
// queryClient.invalidateQueries(t.WAREHOUSE_TRANSFER);
queryClient.invalidateQueries(t.DASHBOARD_META); 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. * Activate the given warehouse.
*/ */

View File

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

View File

@@ -1361,6 +1361,7 @@
"item.field.sell_account.hint": "أدخل السعر الذي ستبيعه لهذا العنصر.", "item.field.sell_account.hint": "أدخل السعر الذي ستبيعه لهذا العنصر.",
"item_entries.products_services.hint": "أدخل المنتجات أو الخدمات التي تبيعها أو تشتريها لتتبع ما قمت ببيعه أو شرائه.", "item_entries.products_services.hint": "أدخل المنتجات أو الخدمات التي تبيعها أو تشتريها لتتبع ما قمت ببيعه أو شرائه.",
"item_entries.landed.hint": "يتيح لك هذه الخيار إمكانية إضافة تكلفة اضافية علي فاتورة الشراء متال علي ذلك تكاليف الشحن ، ثم تحديد هذه التكلفة لتحميلها علي فاتورة الشراء.", "item_entries.landed.hint": "يتيح لك هذه الخيار إمكانية إضافة تكلفة اضافية علي فاتورة الشراء متال علي ذلك تكاليف الشحن ، ثم تحديد هذه التكلفة لتحميلها علي فاتورة الشراء.",
"item_entries.remove_row": "حذف الصف",
"invoice.auto_increment.auto": "يتم تعيين أرقام الفواتير على وضع الزيادة التلقائي. هل أنت متأكد من تغيير هذا الإعداد؟", "invoice.auto_increment.auto": "يتم تعيين أرقام الفواتير على وضع الزيادة التلقائي. هل أنت متأكد من تغيير هذا الإعداد؟",
"invoice.auto_increment.manually": "يتم تعيين أرقام فواتيرك يدوياً. هل أنت متأكد من تغيير هذه الإعدادات؟", "invoice.auto_increment.manually": "يتم تعيين أرقام فواتيرك يدوياً. هل أنت متأكد من تغيير هذه الإعدادات؟",
"manual_journals.auto_increment.auto": "يتم تعيين أرقام القيود على وضع الزيادة التلقائي. هل أنت متأكد من تغيير هذا الإعداد؟", "manual_journals.auto_increment.auto": "يتم تعيين أرقام القيود على وضع الزيادة التلقائي. هل أنت متأكد من تغيير هذا الإعداد؟",
@@ -1778,7 +1779,7 @@
"credit_note_preview.dialog.title": "معاينة إشعار الدائن PDF", "credit_note_preview.dialog.title": "معاينة إشعار الدائن PDF",
"payment_receive_preview.dialog.title": "معاينة سند الزبون PDF", "payment_receive_preview.dialog.title": "معاينة سند الزبون PDF",
"balance_sheet.comparisons": "مقارنات", "balance_sheet.comparisons": "مقارنات",
"balance_sheet.dimensions": "Dimensions", "balance_sheet.dimensions": "الابعاد",
"balance_sheet.percentage_of_column": "% التغير العمودي", "balance_sheet.percentage_of_column": "% التغير العمودي",
"balance_sheet.percentage_of_row": "% التغير الأفقي", "balance_sheet.percentage_of_row": "% التغير الأفقي",
"balance_sheet.previous_year": "السنة السابقة (س.س)", "balance_sheet.previous_year": "السنة السابقة (س.س)",
@@ -1786,7 +1787,7 @@
"balance_sheet.change": "% التغيرات", "balance_sheet.change": "% التغيرات",
"balance_sheet.previous_period": "الفترة السابقة (ف.س) ", "balance_sheet.previous_period": "الفترة السابقة (ف.س) ",
"profit_loss_sheet.comparisons": "مقارنات", "profit_loss_sheet.comparisons": "مقارنات",
"profit_loss_sheet.dimensions": "Dimensions", "profit_loss_sheet.dimensions": "الابعاد",
"profit_loss_sheet.previous_year": "السنة السابقة (س.س)", "profit_loss_sheet.previous_year": "السنة السابقة (س.س)",
"profit_loss_sheet.total_change": "إجمالي التغيرات", "profit_loss_sheet.total_change": "إجمالي التغيرات",
"profit_loss_sheet.perentage_change": "% التغيرات", "profit_loss_sheet.perentage_change": "% التغيرات",
@@ -1795,13 +1796,10 @@
"profit_loss_sheet.percentage_of_row": "% التغير الأفقي", "profit_loss_sheet.percentage_of_row": "% التغير الأفقي",
"profit_loss_sheet.percentage_of_expense": "% التغير في المصاريف", "profit_loss_sheet.percentage_of_expense": "% التغير في المصاريف",
"profit_loss_sheet.percentage_of_income": "% التغير الإيرادات", "profit_loss_sheet.percentage_of_income": "% التغير الإيرادات",
"report.balance_sheet_comparison.title": "مقارنة الميزانية العمومية", "report.balance_sheet_comparison.title": "مقارنة الميزانية العمومية",
"report.balance_sheet_comparison.desc": "يعرض أصول الشركة والتزاماتها وحقوق المساهمين في نقطة زمنية محددة مقارنة بالسنة الماضية.", "report.balance_sheet_comparison.desc": "يعرض أصول الشركة والتزاماتها وحقوق المساهمين في نقطة زمنية محددة مقارنة بالسنة الماضية.",
"report.profit_loss_sheet_comparison.title": "مقارنة قائمة الدخل", "report.profit_loss_sheet_comparison.title": "مقارنة قائمة الدخل",
"report.profit_loss_sheet_comparison.desc": "يعرض الإيرادات والتكاليف والمصاريف المتكبدة في نقطة محددة ومقارنة بالعام السابق.", "report.profit_loss_sheet_comparison.desc": "يعرض الإيرادات والتكاليف والمصاريف المتكبدة في نقطة محددة ومقارنة بالعام السابق.",
"warehouse_locations.label": "المخازن", "warehouse_locations.label": "المخازن",
"warehouse_locations.column.warehouse_name": "اسم المخزن", "warehouse_locations.column.warehouse_name": "اسم المخزن",
"warehouse_locations.column.quantity": "الكمية", "warehouse_locations.column.quantity": "الكمية",
@@ -1850,6 +1848,7 @@
"warehouse_transfer.column.transfer_quantity": "الكمية ", "warehouse_transfer.column.transfer_quantity": "الكمية ",
"warehouse_transfer.column.source_warehouse": "المصدر", "warehouse_transfer.column.source_warehouse": "المصدر",
"warehouse_transfer.column.destination_warehouse": "الوجهة", "warehouse_transfer.column.destination_warehouse": "الوجهة",
"warehouse_transfer.column.cost_price": "سعر التكلفة",
"warehouse_transfer.auto_increment.auto": "يتم تعيين أرقام النقل على وضع الزيادة التلقائي. هل أنت متأكد من تغيير هذا الإعداد؟", "warehouse_transfer.auto_increment.auto": "يتم تعيين أرقام النقل على وضع الزيادة التلقائي. هل أنت متأكد من تغيير هذا الإعداد؟",
"warehouse_transfer.auto_increment.manually": "يتم تعيين أرقام النقل يدوياً. هل أنت متأكد من تغيير هذه الإعدادات؟", "warehouse_transfer.auto_increment.manually": "يتم تعيين أرقام النقل يدوياً. هل أنت متأكد من تغيير هذه الإعدادات؟",
"warehouse_transfer.setting_your_auto_generated_transfer_no": "تعيين رقم النقل الذي تم إنشاؤه تلقائيًا", "warehouse_transfer.setting_your_auto_generated_transfer_no": "تعيين رقم النقل الذي تم إنشاؤه تلقائيًا",
@@ -1917,7 +1916,7 @@
"branches_multi_select.placeholder": "تصفية حسب الفروع…", "branches_multi_select.placeholder": "تصفية حسب الفروع…",
"warehouses_multi_select.label": "مخازن", "warehouses_multi_select.label": "مخازن",
"warehouses_multi_select.placeholder": "تصفية حسب المخازن…", "warehouses_multi_select.placeholder": "تصفية حسب المخازن…",
"dimensions": "Dimensions", "dimensions": "الأبعاد",
"warehouse_transfer.save_initiate_transfer": "حفظ وبدء النقل", "warehouse_transfer.save_initiate_transfer": "حفظ وبدء النقل",
"warehouse_transfer.save_mark_as_transferred": "حفظ وتم النقل", "warehouse_transfer.save_mark_as_transferred": "حفظ وتم النقل",
"warehouse_transfer.label.transfer_initiated": "بدء النقل", "warehouse_transfer.label.transfer_initiated": "بدء النقل",
@@ -1946,7 +1945,7 @@
"view_customer_details": "عرض تفاصيل العميل ", "view_customer_details": "عرض تفاصيل العميل ",
"view_vendor_details": "عرض تفاصيل المورد ", "view_vendor_details": "عرض تفاصيل المورد ",
"thanks_for_your_business_and_have_a_great_day": "Thanks for your business and have a great day!", "thanks_for_your_business_and_have_a_great_day": "Thanks for your business and have a great day!",
"terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed in your transaction", "terms_and_conditions.placeholder": "أدخل شروط وأحكام عملك ليتم عرضها في المعاملة.",
"expenses.decscrption.placeholder": "Enter the description of your business to be displayed in your transaction", "expenses.decscrption.placeholder": "Enter the description of your business to be displayed in your transaction",
"make_jorunal.decscrption.placeholder": "Enter the description of your business to be displayed in your transaction", "make_jorunal.decscrption.placeholder": "Enter the description of your business to be displayed in your transaction",
"estimate_form.label.total": "إجمالي", "estimate_form.label.total": "إجمالي",
@@ -1954,14 +1953,15 @@
"estimate_form.label.customer_note": "ملاحظة الزبون", "estimate_form.label.customer_note": "ملاحظة الزبون",
"estimate_form.label.terms_conditions": "الشروط والأحكام", "estimate_form.label.terms_conditions": "الشروط والأحكام",
"estimate_form.customer_note.placeholder": "Thanks for your business and have a great day!", "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.terms_and_conditions.placeholder": "أدخل شروط وأحكام عملك ليتم عرضها في المعاملة.",
"invoice_form.label.total": "إجمالي", "invoice_form.label.total": "إجمالي",
"invoice_form.label.subtotal": "المجموع", "invoice_form.label.subtotal": "المجموع",
"invoice_form.label.due_amount": "مبلغ المستحق", "invoice_form.label.due_amount": "مبلغ المستحق",
"invoice_form.label.payment_amount": "مبلغ المدفوع", "invoice_form.label.payment_amount": "مبلغ المدفوع",
"invoice_form.label.invoice_message": "رسالة الفاتورة", "invoice_form.label.invoice_message": "رسالة الفاتورة",
"invoice_form.invoice_message.placeholder": "Thanks for your business and have a great day!", "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": "الشروط والأحكام",
"invoice_form.terms_and_conditions.placeholder": "أدخل شروط وأحكام عملك ليتم عرضها في المعاملة.",
"receipt_form.label.total": "إجمالي", "receipt_form.label.total": "إجمالي",
"receipt_form.label.subtotal": "المجموع", "receipt_form.label.subtotal": "المجموع",
"receipt_form.label.due_amount": "مبلغ المستحق", "receipt_form.label.due_amount": "مبلغ المستحق",
@@ -1975,13 +1975,13 @@
"payment_receive_form.label.subtotal": "المجموع", "payment_receive_form.label.subtotal": "المجموع",
"payment_receive_form.label.total": "إجمالي", "payment_receive_form.label.total": "إجمالي",
"bill_form.label.note": "ملاحظة", "bill_form.label.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": "أدخل شروط وأحكام عملك ليتم عرضها في المعاملة.",
"bill_form.label.subtotal": "المجموع", "bill_form.label.subtotal": "المجموع",
"bill_form.label.total": "إجمالي", "bill_form.label.total": "إجمالي",
"bill_form.label.due_amount": "مبلغ المستحق", "bill_form.label.due_amount": "مبلغ المستحق",
"bill_form.label.payment_amount": "مبلغ المدفوع", "bill_form.label.payment_amount": "مبلغ المدفوع",
"vendor_credit_form.label.note": "ملاحظة", "vendor_credit_form.label.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": "أدخل شروط وأحكام عملك ليتم عرضها في المعاملة.",
"vendor_credit_form.label.subtotal": "المجموع", "vendor_credit_form.label.subtotal": "المجموع",
"vendor_credit_form.label.total": "إجمالي", "vendor_credit_form.label.total": "إجمالي",
"payment_made_form.label.statement": "بيان", "payment_made_form.label.statement": "بيان",
@@ -2006,6 +2006,17 @@
"estimate.warehouse_button.label": "المخزن: {label}", "estimate.warehouse_button.label": "المخزن: {label}",
"receipt.branch_button.label": "الفرع: {label}", "receipt.branch_button.label": "الفرع: {label}",
"receipt.warehouse_button.label": "المخزن: {label}", "receipt.warehouse_button.label": "المخزن: {label}",
"warehouse_transfer.empty_status.title": "", "warehouse_transfer.empty_status.title": "إدارة عمليات النقل بين المخازن",
"warehouse_transfer.empty_status.description": "" "warehouse_transfer.empty_status.description": "غالبًا ماتحتاج الاعمال ذات مخازن متعددة لطلبات نقل البضائع من مخزن إلى آخر عندما تكون في حاجة ماسة إلى البائعين.",
"warehouse_transfer.form.reason.label": "أسباب النقل",
"warehouse_transfer.form.reason.placeholder": "أدخل السبب وراء طلب النقل.",
"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}"
} }

View File

@@ -1164,7 +1164,7 @@
"sorry_about_that_something_went_wrong": "Sorry about that! Something went wrong", "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.", "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", "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.success_message": "The inventory adjustment has been published successfully.",
"inventory_adjustment.publish.alert_message": "Are you sure you want to publish this inventory adjustment?", "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.", "the_contact_has_been_activated_successfully": "The contact has been inactivated successfully.",
@@ -1259,12 +1259,41 @@
"setup.initializing.please_refresh_the_page": "Please refresh the page", "setup.initializing.please_refresh_the_page": "Please refresh the page",
"setup.organization.title": "Lets Get Started", "setup.organization.title": "Lets Get Started",
"setup.organization.description": "Tell the system a little bit about your organization.", "setup.organization.description": "Tell the system a little bit about your organization.",
"plan.capital_basic.title": "Capital Basic",
"plan.feature.sales_invoices": "Sales Invoices.",
"plan.feature.sales_estimates": "Sales Estimates.",
"plan.feature.customers": "Customers.",
"plan.feature.credit_notes": "Credit notes.",
"plan.feature.manual_journals": "Manual Journals.",
"plan.feature.expenses_tracking": "Expenses Tracking",
"plan.feature.basic_financial_reports": "Basic Financial Reports.",
"plan.capital_plus.title": "Capital Plus",
"plan.feature.all_capital_basic": "All Capital Basic features.",
"plan.feature.predefined_user_roles": "Predefined User Roles.",
"plan.feature.custom_tables_views": "Custom Tables Views.",
"plan.feature.transactions_locking": "Transactions Locking.",
"plan.feature.plus_financial_reports": "Plus Financial Reports.",
"plan.feature.custom_fields_resources": "Custom Fields & Resources.",
"plan.essential.title": "Capital Essential",
"plan.feature.all_capital_plus": "All Capital Basic features.",
"plan.feature.sales_purchases_order": "Sales & Purchases Order.",
"plan.feature.purchase_invoices": "Purchase Invoices.",
"plan.feature.inventory_tracking": "Inventory Tracking.",
"plan.feature.custom_roles": "Custom Roles.",
"plan.feature.multiply_currency_transcations": "Multiply Currency Transcations.",
"plan.feature.inventory_reports": "Inventory Reports.",
"plan.feature.landed_cost": "Landed cost.",
"plan.capital_enterprise.title": "Capital Enterprise",
"plan.feature.all_capital_essential": "All Capital Essential features.",
"plan.feature.multiply_branches": "Multiply Branches.",
"plan.feature.multiply_warehouses": "Multiply Warehouses.",
"plan.feature.accounting_dimensions": "Accounting Dimensions.",
"plan.feature.warehouses_reports": "Warehouses Reports.",
"plan.feature.branches_reports": "Branches Reports.",
"plan.professional.title": "Pro", "plan.professional.title": "Pro",
"plan.essential.title": "Essential",
"plan.plus.title": "Plus+", "plan.plus.title": "Plus+",
"plan.feature.sale_purchase_invoice": "Sale and purchase invoices.", "plan.feature.sale_purchase_invoice": "Sale and purchase invoices.",
"plan.feature.receivable_payable_accounts": "Customers/vendors accounts.", "plan.feature.receivable_payable_accounts": "Customers/vendors accounts.",
"plan.feature.expenses_tracking": "Expenses tracking",
"plan.feature.manual_journal": "Manual journals.", "plan.feature.manual_journal": "Manual journals.",
"plan.feature.financial_reports": "Financial reports.", "plan.feature.financial_reports": "Financial reports.",
"plan.feature.one_user_with_accountant": "For one user and accountant", "plan.feature.one_user_with_accountant": "For one user and accountant",
@@ -1275,9 +1304,7 @@
"plan.feature.three_users": "Three users with your accountant", "plan.feature.three_users": "Three users with your accountant",
"plan.feature.advanced_financial_reports": "Advanced financial reports", "plan.feature.advanced_financial_reports": "Advanced financial reports",
"plan.feature.tracking_multi_locations": "Track multi-branches and locations", "plan.feature.tracking_multi_locations": "Track multi-branches and locations",
"plan.feature.all_capital_essential": "All Capital Essential features.",
"plan.feature.projects_accounting": "Projects accounting and timesheets", "plan.feature.projects_accounting": "Projects accounting and timesheets",
"plan.feature.accounting_dimensions": "Accounting dimensions.",
"plan.monthly": "Monthly", "plan.monthly": "Monthly",
"plan.yearly": "Yearly", "plan.yearly": "Yearly",
"payment_via_voucher.success_message": "Payment has been done successfully.", "payment_via_voucher.success_message": "Payment has been done successfully.",
@@ -1338,6 +1365,7 @@
"item.field.sell_account.hint": "Enter price which you goint to sell this item.", "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.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.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.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?", "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?", "manual_journals.auto_increment.auto": "Your Jouranl numbers are set on auto-increment mode. Are you sure changing this setting?",
@@ -1440,6 +1468,7 @@
"AP_aging_summary.filter_options.label": "Filter vendors", "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.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.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})", "customer.link.customer_details": "Customer details ({amount})",
"bad_debt.dialog.written_off_amount": "Written-off amount", "bad_debt.dialog.written_off_amount": "Written-off amount",
"bad_debt.dialog.bad_debt": "Bad debt", "bad_debt.dialog.bad_debt": "Bad debt",
@@ -1524,10 +1553,10 @@
"credit_note.label_credit_note": "Credit Note #", "credit_note.label_credit_note": "Credit Note #",
"credit_note.label_amount_to_credit": "Amount to credit", "credit_note.label_amount_to_credit": "Amount to credit",
"credit_note.label_credit_note_details": "Credit Note details", "credit_note.label_credit_note_details": "Credit Note details",
"credit_note.label_customer_note": "Customer note", "credit_note.label_customer_note": "Customer Note",
"credit_note.label_terms_conditions": "Terms conditions", "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_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 in your transaction", "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_total": "TOTAL",
"credit_note.label_subtotal": "Subtotal", "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?", "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?",
@@ -1754,6 +1783,7 @@
"payment_made.drawer.subtitle": "Branch: {value}", "payment_made.drawer.subtitle": "Branch: {value}",
"manual_journal.drawer.title": "Manual journal details ({number})", "manual_journal.drawer.title": "Manual journal details ({number})",
"expense.drawer.title": "Expense details", "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.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.transactions_locked": "Transactions before {lockedToDate} has been locked. Hence action cannot be performed.",
"global_error.authorized_user_inactive": "The authorized user is inactive.", "global_error.authorized_user_inactive": "The authorized user is inactive.",
@@ -1775,13 +1805,10 @@
"profit_loss_sheet.percentage_of_row": "% of Row", "profit_loss_sheet.percentage_of_row": "% of Row",
"profit_loss_sheet.percentage_of_expense": "% of Expense", "profit_loss_sheet.percentage_of_expense": "% of Expense",
"profit_loss_sheet.percentage_of_income": "% of Income", "profit_loss_sheet.percentage_of_income": "% of Income",
"report.balance_sheet_comparison.title": "Balance Sheet Comparison", "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.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.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.", "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.", "the_vendor_has_been_inactivated_successfully": "The contact has been inactivated successfully.",
"vendor.alert.activated_message": "The vendor has been activated 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.", "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.",
@@ -1793,7 +1820,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.", "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", "credit_note_preview.dialog.title": "Credit Note PDF Preview",
"payment_receive_preview.dialog.title": "Payment Receive PDF Preview", "payment_receive_preview.dialog.title": "Payment Receive PDF Preview",
"warehouses.label": "Warehouses", "warehouses.label": "Warehouses",
"warehouses.label.new_warehouse": "New Warehouse", "warehouses.label.new_warehouse": "New Warehouse",
"warehouse.dialog.label.new_warehouse": "New Warehouse", "warehouse.dialog.label.new_warehouse": "New Warehouse",
@@ -1940,49 +1966,53 @@
"payment_made.error.withdrawal_account_currency_invalid": "The withdrawal account currency should be same vendor currency or organization base currency.", "payment_made.error.withdrawal_account_currency_invalid": "The withdrawal account currency should be same vendor currency or organization base currency.",
"view_customer_details": "View Customer Details", "view_customer_details": "View Customer Details",
"view_vendor_details": "View Vendor Details", "view_vendor_details": "View Vendor Details",
"thanks_for_your_business_and_have_a_great_day": "Thanks for your business and have a great day!",
"terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed in your transaction", "terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed in your transaction",
"expenses.decscrption.placeholder": "Enter the description of your business to be displayed in your transaction", "expenses.decscrption.placeholder": "Enter the description of your business to be displayed in your transaction",
"make_jorunal.decscrption.placeholder": "Enter the description of your business to be displayed in your transaction", "make_jorunal.decscrption.placeholder": "Enter the description of your business to be displayed in your transaction",
"estimate_form.label.total": "TOTAL", "estimate_form.label.total": "TOTAL",
"estimate_form.label.subtotal": "Subtotal", "estimate_form.label.subtotal": "Subtotal",
"estimate_form.label.customer_note": "Customer Note", "estimate_form.label.customer_note": "Customer Note",
"estimate_form.label.terms_conditions": "Terms conditions", "estimate_form.label.terms_conditions": "Terms & Conditions",
"estimate_form.customer_note.placeholder": "Thanks for your business and have a great day!", "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 in your transaction", "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.total": "TOTAL",
"invoice_form.label.subtotal": "Subtotal", "invoice_form.label.subtotal": "Subtotal",
"invoice_form.label.due_amount": "Due amount", "invoice_form.label.due_amount": "Due amount",
"invoice_form.label.payment_amount": "Payment amount", "invoice_form.label.payment_amount": "Payment amount",
"invoice_form.label.invoice_message": "Invoice Message", "invoice_form.label.invoice_message": "Invoice Message",
"invoice_form.invoice_message.placeholder": "Thanks for your business and have a great day!", "invoice_form.label.terms_conditions": "Terms & Conditions",
"invoice_form.terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed in your transaction", "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.total": "TOTAL",
"receipt_form.label.subtotal": "Subtotal", "receipt_form.label.subtotal": "Subtotal",
"receipt_form.label.due_amount": "Due amount", "receipt_form.label.due_amount": "Due amount",
"receipt_form.label.payment_amount": "Payment amount", "receipt_form.label.payment_amount": "Payment amount",
"receipt_form.label.receipt_message": "Receipt Message", "receipt_form.label.receipt_message": "Receipt Message",
"receipt_form.receipt_message.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.statement": "Statement", "receipt_form.label.terms_conditions": "Terms & Conditions",
"receipt_form.statement.placeholder": "Thanks for your business and have a great day!", "receipt_form.terms_and_conditions.placeholder": "Enter the terms and conditions of your business to be displayed on the receipt.",
"payment_receive_form.label.statement": "Statement", "payment_receive_form.label.note": "Note",
"payment_receive_form.statement.placeholder": "Thanks for your business and have a great day!", "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.subtotal": "Subtotal",
"payment_receive_form.label.total": "TOTAL", "payment_receive_form.label.total": "TOTAL",
"bill_form.label.note": "Note", "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.subtotal": "Subtotal",
"bill_form.label.total": "TOTAL", "bill_form.label.total": "TOTAL",
"bill_form.label.due_amount": "Due amount", "bill_form.label.due_amount": "Due amount",
"bill_form.label.payment_amount": "Payment amount", "bill_form.label.payment_amount": "Payment amount",
"vendor_credit_form.label.note": "Note", "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.subtotal": "Subtotal",
"vendor_credit_form.label.total": "TOTAL", "vendor_credit_form.label.total": "TOTAL",
"payment_made_form.label.statement": "Statement", "payment_made_form.label.statement": "Statement",
"payment_made_form.statement.placeholder": "Thanks for your business and have a great day!", "payment_made_form.statement.placeholder": "Thanks for your business and have a great day!",
"payment_made_form.label.subtotal": "Subtotal", "payment_made_form.label.subtotal": "Subtotal",
"payment_made_form.label.total": "TOTAL", "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.subtotal": "Subtotal",
"make_journal.label.total": "TOTAL", "make_journal.label.total": "TOTAL",
"expense.label.subtotal": "Subtotal", "expense.label.subtotal": "Subtotal",
@@ -2001,6 +2031,16 @@
"estimate.warehouse_button.label": "Warehouse: {label}", "estimate.warehouse_button.label": "Warehouse: {label}",
"receipt.branch_button.label": "Branch: {label}", "receipt.branch_button.label": "Branch: {label}",
"receipt.warehouse_button.label": "Warehouse: {label}", "receipt.warehouse_button.label": "Warehouse: {label}",
"warehouse_transfer.empty_status.title": "", "warehouse_transfer.empty_status.title": "Manage transfer orders between warehouses.",
"warehouse_transfer.empty_status.description": "" "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}"
} }

View File

@@ -2,7 +2,6 @@ import { createReducer } from '@reduxjs/toolkit';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import t from 'store/types'; import t from 'store/types';
const getSubscriptionPeriods = () => [ const getSubscriptionPeriods = () => [
{ {
slug: 'month', slug: 'month',
@@ -15,79 +14,110 @@ const getSubscriptionPeriods = () => [
]; ];
const getSubscriptionPlans = () => [ const getSubscriptionPlans = () => [
{
name: intl.get('plan.capital_basic.title'),
slug: 'capital_basic',
description: [
intl.get('plan.feature.sales_invoices'),
intl.get('plan.feature.sales_estimates'),
intl.get('plan.feature.customers'),
intl.get('plan.feature.credit_notes'),
intl.get('plan.feature.manual_journals'),
intl.get('plan.feature.expenses_tracking'),
intl.get('plan.feature.basic_financial_reports'),
],
price: '55',
periods: [
{
slug: 'month',
label: intl.get('plan.monthly'),
price: '55',
},
{
slug: 'year',
label: intl.get('plan.yearly'),
price: '595',
},
],
currencyCode: 'LYD',
},
{
name: intl.get('plan.capital_plus.title'),
slug: 'capital_plus',
description: [
intl.get('plan.feature.all_capital_basic'),
intl.get('plan.feature.predefined_user_roles'),
intl.get('plan.feature.custom_tables_views'),
intl.get('plan.feature.transactions_locking'),
intl.get('plan.feature.plus_financial_reports'),
intl.get('plan.feature.custom_fields_resources'),
],
price: '75',
periods: [
{
slug: 'month',
label: intl.get('plan.monthly'),
price: '75',
},
{
slug: 'year',
label: intl.get('plan.yearly'),
price: '795',
},
],
currencyCode: 'LYD',
},
{ {
name: intl.get('plan.essential.title'), name: intl.get('plan.essential.title'),
slug: 'essentials', slug: 'essentials',
description: [ description: [
intl.get('plan.feature.sale_purchase_invoice'), intl.get('plan.feature.all_capital_plus'),
intl.get('plan.feature.receivable_payable_accounts'), intl.get('plan.feature.sales_purchases_order'),
intl.get('plan.feature.expenses_tracking'), intl.get('plan.feature.purchase_invoices'),
intl.get('plan.feature.manual_journal'), intl.get('plan.feature.inventory_tracking'),
intl.get('plan.feature.financial_reports'), intl.get('plan.feature.custom_roles'),
intl.get('plan.feature.one_user_with_accountant'), intl.get('plan.feature.multiply_currency_transcations'),
intl.get('plan.feature.inventory_reports'),
intl.get('plan.feature.landed_cost'),
], ],
price: '100', price: '95',
periods: [ periods: [
{ {
slug: 'month', slug: 'month',
label: intl.get('plan.monthly'), label: intl.get('plan.monthly'),
price: '100' price: '95',
}, },
{ {
slug: 'year', slug: 'year',
label: intl.get('plan.yearly'), label: intl.get('plan.yearly'),
price: '1,200', price: '995',
}, },
], ],
currencyCode: 'LYD', currencyCode: 'LYD',
}, },
{ {
name: intl.get('plan.professional.title'), name: intl.get('plan.capital_enterprise.title'),
slug: 'plus',
description: [
intl.get('plan.feature.all_capital_essential'),
intl.get('plan.feature.multi_currency'),
intl.get('plan.feature.purchase_sell_orders'),
intl.get('plan.feature.multi_inventory_managment'),
intl.get('plan.feature.three_users'),
intl.get('plan.feature.advanced_financial_reports'),
],
price: '200',
currencyCode: 'LYD',
periods: [
{
slug: 'month',
label: intl.get('plan.monthly'),
price: '200'
},
{
slug: 'year',
label: intl.get('plan.yearly'),
price: '1,200',
},
],
},
{
name: intl.get('plan.plus.title'),
slug: 'enterprise', slug: 'enterprise',
description: [ description: [
intl.get('plan.feture.all_capital_professional_features'), intl.get('plan.feature.all_capital_essential'),
intl.get('plan.feature.tracking_multi_locations'), intl.get('plan.feature.multiply_branches'),
intl.get('plan.feature.projects_accounting'), intl.get('plan.feature.multiply_warehouses'),
intl.get('plan.feature.accounting_dimensions'), intl.get('plan.feature.accounting_dimensions'),
intl.get('plan.feature.warehouses_reports'),
intl.get('plan.feature.branches_reports'),
], ],
price: '300', price: '120',
currencyCode: 'LYD', currencyCode: 'LYD',
periods: [ periods: [
{ {
slug: 'month', slug: 'month',
label: intl.get('plan.monthly'), label: intl.get('plan.monthly'),
price: '300' price: '120',
}, },
{ {
slug: 'year', slug: 'year',
label: intl.get('plan.yearly'), label: intl.get('plan.yearly'),
price: '1,200', price: '1,195',
}, },
], ],
}, },

View File

@@ -1,6 +1,6 @@
.billing-plans{ .billing-plans{
max-width: 753px;
.paragraph{ .paragraph{
font-size: 15px; font-size: 15px;
} }