mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-22 07:40:32 +00:00
feat(leng): add leng.
This commit is contained in:
@@ -6,33 +6,30 @@ export const accountsReceivable = [
|
|||||||
sectionTitle: <T id={'accounts_receivable_a_r'} />,
|
sectionTitle: <T id={'accounts_receivable_a_r'} />,
|
||||||
shortcuts: [
|
shortcuts: [
|
||||||
{
|
{
|
||||||
title: 'Sales invoices',
|
title: <T id={'sales_invoices'} />,
|
||||||
description: 'Tracking sales invoices with your customers with payment due date.',
|
description: <T id={'tracking_sales_invoices_with_your_customers'} />,
|
||||||
link: '/invoices',
|
link: '/invoices',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Sales estimates',
|
title: <T id={'sales_estimates'} />,
|
||||||
description:
|
description: <T id={'manage_your_sales_estimates_to_create_quotes'} />,
|
||||||
'Manage your sales estimates to create quotes that can later be turned to a sale invoice.',
|
|
||||||
|
|
||||||
link: '/estimates',
|
link: '/estimates',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Sales receipts',
|
title: <T id={'sales_receipts'} />,
|
||||||
description:
|
description: <T id={'manage_sales_receipts_for_sales_that_get_paid'} />,
|
||||||
'Manage sales receipts for sales that get paid immediately from the customer.',
|
|
||||||
|
|
||||||
link: '/receipts',
|
link: '/receipts',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Customers',
|
title: <T id={'Customers'} />,
|
||||||
description: 'Manage the customers relations with customer receivable and credit balances.',
|
description: <T id={'manage_the_customers_relations_with_customer'} />,
|
||||||
link: '/customers',
|
link: '/customers',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Customers payment',
|
title: <T id={'customers_payment'} />,
|
||||||
description:
|
description: (
|
||||||
'Manage payment transactions from your customers with sale invoices.',
|
<T id={'manage_payment_transactions_from_your_customers'} />
|
||||||
|
),
|
||||||
link: '/payment-receives',
|
link: '/payment-receives',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -44,20 +41,22 @@ export const accountsPayable = [
|
|||||||
sectionTitle: <T id={'accounts_payable_a_p'} />,
|
sectionTitle: <T id={'accounts_payable_a_p'} />,
|
||||||
shortcuts: [
|
shortcuts: [
|
||||||
{
|
{
|
||||||
title: 'Purchase invoices',
|
title: <T id={'purchase_invoices'} />,
|
||||||
description: 'Manage the purchase invoices with your vendors with payment due date.',
|
description: (
|
||||||
|
<T id={'manage_the_purchase_invoices_with_your_vendors'} />
|
||||||
|
),
|
||||||
link: '/bills',
|
link: '/bills',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Vendors',
|
title: <T id={'vendors'} />,
|
||||||
description: 'Manage the vendors relations with vendor payable and debit balances.',
|
description: (
|
||||||
|
<T id={'manage_the_vendors_relations_with_vendor_relations'} />
|
||||||
|
),
|
||||||
link: '/vendors',
|
link: '/vendors',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Vendors payments',
|
title: <T id={'vendors_payments'} />,
|
||||||
description:
|
description: <T id={'manage_payments_transactions_to_your_vendors'} />,
|
||||||
'Manage payments transactions to your vendors with purchase invoices.',
|
|
||||||
|
|
||||||
link: '/payment-mades',
|
link: '/payment-mades',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -69,26 +68,29 @@ export const financialAccounting = [
|
|||||||
sectionTitle: <T id={'financial_accounting'} />,
|
sectionTitle: <T id={'financial_accounting'} />,
|
||||||
shortcuts: [
|
shortcuts: [
|
||||||
{
|
{
|
||||||
title: 'Chart of accounts',
|
title: <T id={'chart_of_accounts'} />,
|
||||||
description:
|
description: (
|
||||||
'Manage your accounts chart to record your transactions and categorise your transactions in parent accounts.',
|
<T
|
||||||
|
id={
|
||||||
|
'manage_your_accounts_chart_to_record_your_transactions_and_categories'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
),
|
||||||
link: '/accounts',
|
link: '/accounts',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Manual journal',
|
title: <T id={'manual_journal'}/>,
|
||||||
description: 'Manage manual journal transactions on accounts, cost centra and projects.',
|
description:<T id={'manage_manual_journal_transactions_on_accounts'}/>,
|
||||||
link: '/manual-journals',
|
link: '/manual-journals',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Expenses',
|
title: <T id={'expenses'}/>,
|
||||||
description:
|
description:<T id={'track_your_indirect_expenses_under_specific_categories'}/>,
|
||||||
'Track your indirect expenses under specific categories such as payroll, rent.',
|
|
||||||
link: '/expenses',
|
link: '/expenses',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Financial statements',
|
title: <T id={'financial_statements'}/>,
|
||||||
description:
|
description:<T id={'show_financial_reports_about_your_organization'}/>,
|
||||||
'Show financial reports about your organization to summarize your business’s financial performance.',
|
|
||||||
link: '/financial-reports',
|
link: '/financial-reports',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -100,20 +102,18 @@ export const productsServices = [
|
|||||||
sectionTitle: <T id={'products_services_inventory'} />,
|
sectionTitle: <T id={'products_services_inventory'} />,
|
||||||
shortcuts: [
|
shortcuts: [
|
||||||
{
|
{
|
||||||
title: 'Products & Services',
|
title: <T id={'products_services'}/>,
|
||||||
description:
|
description:<T id={'manage_your_products_inventory_or_non_inventory'}/>,
|
||||||
'Manage your products (inventory or non-inventory) and services and place them into categories.',
|
|
||||||
link: '/items',
|
link: '/items',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Products & Services Categories',
|
title: <T id={'products_services_categories'}/>,
|
||||||
description:
|
description:<T id={'group_your_products_and_service'}/>,
|
||||||
'Group your products and service into different categories.',
|
|
||||||
link: 'items/categories',
|
link: 'items/categories',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Inventory Adjustments',
|
title: <T id={'inventory_adjustments'}/>,
|
||||||
description: 'Manage your inventory adjustment of inventory items.',
|
description: <T id={'manage_your_inventory_adjustment_of_inventory_items'}/>,
|
||||||
link: '/inventory-adjustments',
|
link: '/inventory-adjustments',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import withBreadcrumbs from 'react-router-breadcrumbs-hoc';
|
|||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import routes from 'routes/dashboard';
|
import routes from 'routes/dashboard';
|
||||||
import { If, Icon } from 'components';
|
import { If, Icon } from 'components';
|
||||||
|
import { FormattedMessage as T } from 'react-intl';
|
||||||
import withDashboard from 'containers/Dashboard/withDashboard';
|
import withDashboard from 'containers/Dashboard/withDashboard';
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ function DashboardBackLink({ dashboardBackLink, breadcrumbs }) {
|
|||||||
<If condition={dashboardBackLink && crumb}>
|
<If condition={dashboardBackLink && crumb}>
|
||||||
<div class="dashboard__back-link">
|
<div class="dashboard__back-link">
|
||||||
<a href="#no-link" onClick={handleClick}>
|
<a href="#no-link" onClick={handleClick}>
|
||||||
<Icon icon={'arrow-left'} iconSize={18} /> Back to list.
|
<Icon icon={'arrow-left'} iconSize={18} /> <T id={'back_to_list'} />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</If>
|
</If>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import ItemsSuggestField from 'components/ItemsSuggestField';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { FormGroup, Classes, Intent } from '@blueprintjs/core';
|
import { FormGroup, Classes, Intent } from '@blueprintjs/core';
|
||||||
|
import { formatMessage } from 'services/intl';
|
||||||
|
|
||||||
import { useCellAutoFocus } from 'hooks';
|
import { useCellAutoFocus } from 'hooks';
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ export default function ItemsListCell({
|
|||||||
purchasable={filterPurchasable}
|
purchasable={filterPurchasable}
|
||||||
inputProps={{
|
inputProps={{
|
||||||
inputRef: (ref) => (fieldRef.current = ref),
|
inputRef: (ref) => (fieldRef.current = ref),
|
||||||
placeholder: 'Enter an item...'
|
placeholder: formatMessage({ id: 'enter_an_item' }),
|
||||||
}}
|
}}
|
||||||
openOnKeyDown={true}
|
openOnKeyDown={true}
|
||||||
blurOnSelectClose={false}
|
blurOnSelectClose={false}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import React, { useState, useCallback, useEffect } from 'react'
|
import React, { useState, useCallback, useEffect } from 'react';
|
||||||
import { useDropzone } from 'react-dropzone'
|
import { useDropzone } from 'react-dropzone';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import Icon from 'components/Icon';
|
import Icon from 'components/Icon';
|
||||||
|
import { formatMessage } from 'services/intl';
|
||||||
|
|
||||||
// const initialFile: {
|
// const initialFile: {
|
||||||
// file: ?File,
|
// file: ?File,
|
||||||
@@ -11,7 +12,7 @@ import Icon from 'components/Icon';
|
|||||||
// };
|
// };
|
||||||
|
|
||||||
export default function Dropzone({
|
export default function Dropzone({
|
||||||
text = 'Drag/Drop files here or click here',
|
text = formatMessage({ id: 'drag_drop_files_here_or_click_here' }),
|
||||||
onDrop,
|
onDrop,
|
||||||
initialFiles = [],
|
initialFiles = [],
|
||||||
onDeleteFile,
|
onDeleteFile,
|
||||||
@@ -21,10 +22,10 @@ export default function Dropzone({
|
|||||||
const [files, setFiles] = useState([]);
|
const [files, setFiles] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFiles([ ...initialFiles ]);
|
setFiles([...initialFiles]);
|
||||||
}, [initialFiles]);
|
}, [initialFiles]);
|
||||||
|
|
||||||
const {getRootProps, getInputProps} = useDropzone({
|
const { getRootProps, getInputProps } = useDropzone({
|
||||||
accept: 'image/*',
|
accept: 'image/*',
|
||||||
onDrop: (acceptedFiles) => {
|
onDrop: (acceptedFiles) => {
|
||||||
const _files = acceptedFiles.map((file) => ({
|
const _files = acceptedFiles.map((file) => ({
|
||||||
@@ -33,27 +34,35 @@ export default function Dropzone({
|
|||||||
uploaded: false,
|
uploaded: false,
|
||||||
}));
|
}));
|
||||||
setFiles(_files);
|
setFiles(_files);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleRemove = useCallback((index) => {
|
const handleRemove = useCallback(
|
||||||
const deletedFile = files.splice(index, 1);
|
(index) => {
|
||||||
setFiles([...files]);
|
const deletedFile = files.splice(index, 1);
|
||||||
onDeleteFile && onDeleteFile(deletedFile);
|
setFiles([...files]);
|
||||||
}, [files, onDeleteFile]);
|
onDeleteFile && onDeleteFile(deletedFile);
|
||||||
|
},
|
||||||
|
[files, onDeleteFile],
|
||||||
|
);
|
||||||
|
|
||||||
const thumbs = files.map((file, index) => (
|
const thumbs = files.map((file, index) => (
|
||||||
<div className={'dropzone-thumb'} key={file.name}>
|
<div className={'dropzone-thumb'} key={file.name}>
|
||||||
<div><img src={file.preview} /></div>
|
<div>
|
||||||
|
<img src={file.preview} />
|
||||||
|
</div>
|
||||||
<button onClick={() => handleRemove(index)}>
|
<button onClick={() => handleRemove(index)}>
|
||||||
<Icon icon={'times'} iconSize={12} />
|
<Icon icon={'times'} iconSize={12} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
));
|
));
|
||||||
|
|
||||||
useEffect(() => () => {
|
useEffect(
|
||||||
files.forEach(file => URL.revokeObjectURL(file.preview));
|
() => () => {
|
||||||
}, [files, onDrop]);
|
files.forEach((file) => URL.revokeObjectURL(file.preview));
|
||||||
|
},
|
||||||
|
[files, onDrop],
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
onDrop && onDrop(files);
|
onDrop && onDrop(files);
|
||||||
@@ -61,16 +70,14 @@ export default function Dropzone({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={classNames('dropzone-container', className)}>
|
<section className={classNames('dropzone-container', className)}>
|
||||||
{(hint) && <div class="dropzone-hint">{ hint }</div>}
|
{hint && <div class="dropzone-hint">{hint}</div>}
|
||||||
|
|
||||||
<div {...getRootProps({ className: 'dropzone' })}>
|
<div {...getRootProps({ className: 'dropzone' })}>
|
||||||
<input {...getInputProps()} />
|
<input {...getInputProps()} />
|
||||||
<p>{ text }</p>
|
<p>{text}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={'dropzone-thumbs'}>
|
<div className={'dropzone-thumbs'}>{thumbs}</div>
|
||||||
{ thumbs }
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ function Pagination({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pagination__pagesize-control">
|
<div class="pagination__pagesize-control">
|
||||||
Page size
|
<T id={'page_size'} />
|
||||||
<HTMLSelect
|
<HTMLSelect
|
||||||
minimal={true}
|
minimal={true}
|
||||||
options={pageSizesOptions}
|
options={pageSizesOptions}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default [
|
|||||||
matchExact: true,
|
matchExact: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'Sales & inventory',
|
text: <T id={'sales_inventory'} />,
|
||||||
label: true,
|
label: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -131,7 +131,9 @@ function MakeJournalEntriesHeader({
|
|||||||
}}
|
}}
|
||||||
tooltip={true}
|
tooltip={true}
|
||||||
tooltipProps={{
|
tooltipProps={{
|
||||||
content: 'Setting your auto-generated journal number',
|
content: (
|
||||||
|
<T id={'setting_your_auto_generated_journal_number'} />
|
||||||
|
),
|
||||||
position: Position.BOTTOM_LEFT,
|
position: Position.BOTTOM_LEFT,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export function ItemHeaderCell() {
|
|||||||
* Item column footer cell.
|
* Item column footer cell.
|
||||||
*/
|
*/
|
||||||
export function ItemFooterCell() {
|
export function ItemFooterCell() {
|
||||||
return <span>Total</span>;
|
return <span><T id={'total'}/></span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { formatMessage } from 'services/intl';
|
||||||
|
|
||||||
import { useItemsCategoriesTableColumns, ActionMenuList } from './components';
|
import { useItemsCategoriesTableColumns, ActionMenuList } from './components';
|
||||||
import DataTable from 'components/DataTable';
|
import DataTable from 'components/DataTable';
|
||||||
@@ -25,11 +26,8 @@ function ItemsCategoryTable({
|
|||||||
openAlert,
|
openAlert,
|
||||||
}) {
|
}) {
|
||||||
// Items categories context.
|
// Items categories context.
|
||||||
const {
|
const { isCategoriesLoading, isCategoriesFetching, itemsCategories } =
|
||||||
isCategoriesLoading,
|
useItemsCategoriesContext();
|
||||||
isCategoriesFetching,
|
|
||||||
itemsCategories,
|
|
||||||
} = useItemsCategoriesContext();
|
|
||||||
|
|
||||||
// Table columns.
|
// Table columns.
|
||||||
const columns = useItemsCategoriesTableColumns();
|
const columns = useItemsCategoriesTableColumns();
|
||||||
@@ -56,7 +54,9 @@ function ItemsCategoryTable({
|
|||||||
sticky={true}
|
sticky={true}
|
||||||
selectionColumn={true}
|
selectionColumn={true}
|
||||||
TableLoadingRenderer={TableSkeletonRows}
|
TableLoadingRenderer={TableSkeletonRows}
|
||||||
noResults={'There is no items categories in table yet.'}
|
noResults={formatMessage({
|
||||||
|
id: 'there_is_no_items_categories_in_table_yet',
|
||||||
|
})}
|
||||||
payload={{
|
payload={{
|
||||||
onDeleteCategory: handleDeleteCategory,
|
onDeleteCategory: handleDeleteCategory,
|
||||||
onEditCategory: handleEditCategory,
|
onEditCategory: handleEditCategory,
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export default function ReferenceNumberFormContent() {
|
|||||||
<FastField name={'incrementMode'}>
|
<FastField name={'incrementMode'}>
|
||||||
{({ form, field, meta: { error, touched } }) => (
|
{({ form, field, meta: { error, touched } }) => (
|
||||||
<Radio
|
<Radio
|
||||||
label="I will enter them manully each time."
|
label={<T id={'i_will_enter_them_manually_each_time'} />}
|
||||||
value="manual"
|
value="manual"
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
form.setFieldValue('incrementMode', 'manual');
|
form.setFieldValue('incrementMode', 'manual');
|
||||||
@@ -88,7 +88,7 @@ export default function ReferenceNumberFormContent() {
|
|||||||
<FastField name={'incrementMode'}>
|
<FastField name={'incrementMode'}>
|
||||||
{({ form, field, meta: { error, touched } }) => (
|
{({ form, field, meta: { error, touched } }) => (
|
||||||
<Radio
|
<Radio
|
||||||
label="Manual entring for this transaction."
|
label={<T id={'manual_entering_for_this_transaction'} />}
|
||||||
value="manual"
|
value="manual"
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
form.setFieldValue('incrementMode', 'manual-transaction');
|
form.setFieldValue('incrementMode', 'manual-transaction');
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { inputIntent } from 'utils';
|
|||||||
export default function EstiamteFormFooter({}) {
|
export default function EstiamteFormFooter({}) {
|
||||||
return (
|
return (
|
||||||
<div class={classNames(CLASSES.PAGE_FORM_FOOTER)}>
|
<div class={classNames(CLASSES.PAGE_FORM_FOOTER)}>
|
||||||
<Postbox title={'Estimate details'} defaultOpen={false}>
|
<Postbox title={<T id={'estimate_details'} />} defaultOpen={false}>
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={8}>
|
<Col md={8}>
|
||||||
{/* --------- Customer Note --------- */}
|
{/* --------- Customer Note --------- */}
|
||||||
@@ -50,7 +50,7 @@ export default function EstiamteFormFooter({}) {
|
|||||||
initialFiles={[]}
|
initialFiles={[]}
|
||||||
// onDrop={handleDropFiles}
|
// onDrop={handleDropFiles}
|
||||||
// onDeleteFile={handleDeleteFile}
|
// onDeleteFile={handleDeleteFile}
|
||||||
hint={'Attachments: Maxiumum size: 20MB'}
|
hint={<T id={'attachments_maximum'} />}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { useMemo } from 'react';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { sumBy } from 'lodash';
|
import { sumBy } from 'lodash';
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
|
import { formatMessage } from 'services/intl';
|
||||||
|
|
||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
|
|
||||||
@@ -18,15 +19,16 @@ function EstimateFormHeader({
|
|||||||
const { values } = useFormikContext();
|
const { values } = useFormikContext();
|
||||||
|
|
||||||
// Calculate the total due amount of bill entries.
|
// Calculate the total due amount of bill entries.
|
||||||
const totalDueAmount = useMemo(() => sumBy(values.entries, 'total'), [
|
const totalDueAmount = useMemo(
|
||||||
values.entries,
|
() => sumBy(values.entries, 'total'),
|
||||||
]);
|
[values.entries],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||||
<EstimateFormHeaderFields />
|
<EstimateFormHeaderFields />
|
||||||
<PageFormBigNumber
|
<PageFormBigNumber
|
||||||
label={'Amount'}
|
label={formatMessage({ id: 'amount' })}
|
||||||
amount={totalDueAmount}
|
amount={totalDueAmount}
|
||||||
currencyCode={baseCurrency}
|
currencyCode={baseCurrency}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ function EstimateFormHeader({
|
|||||||
}}
|
}}
|
||||||
tooltip={true}
|
tooltip={true}
|
||||||
tooltipProps={{
|
tooltipProps={{
|
||||||
content: 'Setting your auto-generated estimate number',
|
content: <T id={'setting_your_auto_generated_estimate_number'}/>,
|
||||||
position: Position.BOTTOM_LEFT,
|
position: Position.BOTTOM_LEFT,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ import React from 'react';
|
|||||||
import { Button, Intent } from '@blueprintjs/core';
|
import { Button, Intent } from '@blueprintjs/core';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { EmptyStatus } from 'components';
|
import { EmptyStatus } from 'components';
|
||||||
|
import { FormattedMessage as T } from 'react-intl';
|
||||||
|
|
||||||
export default function EstimatesEmptyStatus() {
|
export default function EstimatesEmptyStatus() {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EmptyStatus
|
<EmptyStatus
|
||||||
title={"It's time to send estimates to your customers."}
|
title={<T id={'it_s_time_to_send_estimates_to_your_customers'} />}
|
||||||
description={
|
description={
|
||||||
<p>
|
<p>
|
||||||
It is a long established fact that a reader will be distracted by the
|
<T id={'it_is_a_long_established_fact_that_a_reader'} />
|
||||||
readable content of a page when looking at its layout.
|
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
action={
|
action={
|
||||||
@@ -24,10 +24,10 @@ export default function EstimatesEmptyStatus() {
|
|||||||
history.push('/estimates/new');
|
history.push('/estimates/new');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
New sale estimate
|
<T id={'new_sale_estimate'} />
|
||||||
</Button>
|
</Button>
|
||||||
<Button intent={Intent.NONE} large={true}>
|
<Button intent={Intent.NONE} large={true}>
|
||||||
Learn more
|
<T id={'learn_more'} />
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { inputIntent } from 'utils';
|
|||||||
export default function InvoiceFormFooter() {
|
export default function InvoiceFormFooter() {
|
||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_FOOTER)}>
|
<div className={classNames(CLASSES.PAGE_FORM_FOOTER)}>
|
||||||
<Postbox title={'Invoice details'} defaultOpen={false}>
|
<Postbox title={<T id={'invoice_details'} />} defaultOpen={false}>
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={8}>
|
<Col md={8}>
|
||||||
{/* --------- Invoice message --------- */}
|
{/* --------- Invoice message --------- */}
|
||||||
@@ -47,7 +47,7 @@ export default function InvoiceFormFooter() {
|
|||||||
initialFiles={[]}
|
initialFiles={[]}
|
||||||
// onDrop={handleDropFiles}
|
// onDrop={handleDropFiles}
|
||||||
// onDeleteFile={handleDeleteFile}
|
// onDeleteFile={handleDeleteFile}
|
||||||
hint={'Attachments: Maxiumum size: 20MB'}
|
hint={<T id={'attachments_maximum'} />}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { useMemo } from 'react';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { sumBy } from 'lodash';
|
import { sumBy } from 'lodash';
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
|
import { formatMessage } from 'services/intl';
|
||||||
|
|
||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
import InvoiceFormHeaderFields from './InvoiceFormHeaderFields';
|
import InvoiceFormHeaderFields from './InvoiceFormHeaderFields';
|
||||||
@@ -21,15 +22,16 @@ function InvoiceFormHeader({
|
|||||||
const { values } = useFormikContext();
|
const { values } = useFormikContext();
|
||||||
|
|
||||||
// Calculate the total due amount of invoice entries.
|
// Calculate the total due amount of invoice entries.
|
||||||
const totalDueAmount = useMemo(() => sumBy(values.entries, 'total'), [
|
const totalDueAmount = useMemo(
|
||||||
values.entries,
|
() => sumBy(values.entries, 'total'),
|
||||||
]);
|
[values.entries],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||||
<InvoiceFormHeaderFields />
|
<InvoiceFormHeaderFields />
|
||||||
<PageFormBigNumber
|
<PageFormBigNumber
|
||||||
label={'Due Amount'}
|
label={formatMessage({ id: 'due_amount' })}
|
||||||
amount={totalDueAmount}
|
amount={totalDueAmount}
|
||||||
currencyCode={baseCurrency}
|
currencyCode={baseCurrency}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ function InvoiceFormHeaderFields({
|
|||||||
}}
|
}}
|
||||||
tooltip={true}
|
tooltip={true}
|
||||||
tooltipProps={{
|
tooltipProps={{
|
||||||
content: 'Setting your auto-generated invoice number',
|
content: <T id={'setting_your_auto_generated_invoice_number'}/>,
|
||||||
position: Position.BOTTOM_LEFT,
|
position: Position.BOTTOM_LEFT,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { CLASSES } from 'common/classes';
|
|||||||
export default function PaymentReceiveFormFooter({ getFieldProps }) {
|
export default function PaymentReceiveFormFooter({ getFieldProps }) {
|
||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_FOOTER)}>
|
<div className={classNames(CLASSES.PAGE_FORM_FOOTER)}>
|
||||||
<Postbox title={'Payment receive details'} defaultOpen={false}>
|
<Postbox title={<T id={'payment_receive_details'} />} defaultOpen={false}>
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={8}>
|
<Col md={8}>
|
||||||
{/* --------- Statement --------- */}
|
{/* --------- Statement --------- */}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { sumBy } from 'lodash';
|
|||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Money } from 'components';
|
import { Money } from 'components';
|
||||||
|
import { FormattedMessage as T } from 'react-intl';
|
||||||
|
|
||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
import PaymentReceiveHeaderFields from './PaymentReceiveHeaderFields';
|
import PaymentReceiveHeaderFields from './PaymentReceiveHeaderFields';
|
||||||
@@ -33,7 +34,9 @@ function PaymentReceiveFormHeader({
|
|||||||
|
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_BIG_NUMBERS)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_BIG_NUMBERS)}>
|
||||||
<div class="big-amount">
|
<div class="big-amount">
|
||||||
<span class="big-amount__label">Amount Received</span>
|
<span class="big-amount__label">
|
||||||
|
<T id={'amount_received'} />
|
||||||
|
</span>
|
||||||
<h1 class="big-amount__number">
|
<h1 class="big-amount__number">
|
||||||
<Money amount={paymentFullAmount} currency={baseCurrency} />
|
<Money amount={paymentFullAmount} currency={baseCurrency} />
|
||||||
</h1>
|
</h1>
|
||||||
|
|||||||
@@ -70,9 +70,10 @@ function PaymentReceiveHeaderFields({
|
|||||||
const customerFieldRef = useAutofocus();
|
const customerFieldRef = useAutofocus();
|
||||||
|
|
||||||
// Calculates the full-amount received.
|
// Calculates the full-amount received.
|
||||||
const totalDueAmount = useMemo(() => safeSumBy(entries, 'due_amount'), [
|
const totalDueAmount = useMemo(
|
||||||
entries,
|
() => safeSumBy(entries, 'due_amount'),
|
||||||
]);
|
[entries],
|
||||||
|
);
|
||||||
// Handle receive full-amount link click.
|
// Handle receive full-amount link click.
|
||||||
const handleReceiveFullAmountClick = () => {
|
const handleReceiveFullAmountClick = () => {
|
||||||
const newEntries = fullAmountPaymentEntries(entries);
|
const newEntries = fullAmountPaymentEntries(entries);
|
||||||
@@ -200,7 +201,7 @@ function PaymentReceiveHeaderFields({
|
|||||||
small={true}
|
small={true}
|
||||||
minimal={true}
|
minimal={true}
|
||||||
>
|
>
|
||||||
Receive full amount (
|
<T id={'receive_full_amount'} /> (
|
||||||
<Money amount={totalDueAmount} currency={baseCurrency} />)
|
<Money amount={totalDueAmount} currency={baseCurrency} />)
|
||||||
</Button>
|
</Button>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
@@ -232,7 +233,11 @@ function PaymentReceiveHeaderFields({
|
|||||||
}}
|
}}
|
||||||
tooltip={true}
|
tooltip={true}
|
||||||
tooltipProps={{
|
tooltipProps={{
|
||||||
content: 'Setting your auto-generated Payment Receive number',
|
content: (
|
||||||
|
<T
|
||||||
|
id={'setting_your_auto_generated_payment_receive_number'}
|
||||||
|
/>
|
||||||
|
),
|
||||||
position: Position.BOTTOM_LEFT,
|
position: Position.BOTTOM_LEFT,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { useCallback } from 'react';
|
|||||||
import { CloudLoadingIndicator } from 'components';
|
import { CloudLoadingIndicator } from 'components';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
|
import { FormattedMessage as T } from 'react-intl';
|
||||||
|
|
||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
import { usePaymentReceiveInnerContext } from './PaymentReceiveInnerProvider';
|
import { usePaymentReceiveInnerContext } from './PaymentReceiveInnerProvider';
|
||||||
@@ -15,32 +16,37 @@ import { compose, updateTableRow } from 'utils';
|
|||||||
export default function PaymentReceiveItemsTable({
|
export default function PaymentReceiveItemsTable({
|
||||||
entries,
|
entries,
|
||||||
onUpdateData,
|
onUpdateData,
|
||||||
currencyCode
|
currencyCode,
|
||||||
}) {
|
}) {
|
||||||
// Payment receive form context.
|
// Payment receive form context.
|
||||||
const {
|
const { isDueInvoicesFetching } = usePaymentReceiveInnerContext();
|
||||||
isDueInvoicesFetching,
|
|
||||||
} = usePaymentReceiveInnerContext();
|
|
||||||
|
|
||||||
// Payment receive entries form context.
|
// Payment receive entries form context.
|
||||||
const columns = usePaymentReceiveEntriesColumns();
|
const columns = usePaymentReceiveEntriesColumns();
|
||||||
|
|
||||||
// Formik context.
|
// Formik context.
|
||||||
const { values: { customer_id } } = useFormikContext();
|
const {
|
||||||
|
values: { customer_id },
|
||||||
|
} = useFormikContext();
|
||||||
|
|
||||||
// No results message.
|
// No results message.
|
||||||
const noResultsMessage = customer_id
|
const noResultsMessage = customer_id ? (
|
||||||
? 'There is no receivable invoices for this customer that can be applied for this payment'
|
<T id={'there_is_no_receivable_invoices_for_this_customer'} />
|
||||||
: 'Please select a customer to display all open invoices for it.';
|
) : (
|
||||||
|
<T id={'please_select_a_customer_to_display_all_open_invoices_for_it'} />
|
||||||
|
);
|
||||||
|
|
||||||
// Handle update data.
|
// Handle update data.
|
||||||
const handleUpdateData = useCallback((rowIndex, columnId, value) => {
|
const handleUpdateData = useCallback(
|
||||||
const newRows = compose(
|
(rowIndex, columnId, value) => {
|
||||||
updateTableRow(rowIndex, columnId, value),
|
const newRows = compose(updateTableRow(rowIndex, columnId, value))(
|
||||||
)(entries);
|
entries,
|
||||||
|
);
|
||||||
|
|
||||||
onUpdateData(newRows);
|
onUpdateData(newRows);
|
||||||
}, [entries, onUpdateData]);
|
},
|
||||||
|
[entries, onUpdateData],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CloudLoadingIndicator isLoading={isDueInvoicesFetching}>
|
<CloudLoadingIndicator isLoading={isDueInvoicesFetching}>
|
||||||
@@ -53,7 +59,7 @@ export default function PaymentReceiveItemsTable({
|
|||||||
payload={{
|
payload={{
|
||||||
errors: [],
|
errors: [],
|
||||||
updateData: handleUpdateData,
|
updateData: handleUpdateData,
|
||||||
currencyCode
|
currencyCode,
|
||||||
}}
|
}}
|
||||||
noResults={noResultsMessage}
|
noResults={noResultsMessage}
|
||||||
footer={true}
|
footer={true}
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ import React from 'react';
|
|||||||
import { Button, Intent } from '@blueprintjs/core';
|
import { Button, Intent } from '@blueprintjs/core';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { EmptyStatus } from 'components';
|
import { EmptyStatus } from 'components';
|
||||||
|
import { FormattedMessage as T } from 'react-intl';
|
||||||
|
|
||||||
export default function PaymentReceivesEmptyStatus() {
|
export default function PaymentReceivesEmptyStatus() {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EmptyStatus
|
<EmptyStatus
|
||||||
title={"The organization does't receive money, yet!"}
|
title={<T id={'the_organization_doesn_t_receive_money_yet'} />}
|
||||||
description={
|
description={
|
||||||
<p>
|
<p>
|
||||||
It is a long established fact that a reader will be distracted by the
|
<T id={'it_is_a_long_established_fact_that_a_reader'} />
|
||||||
readable content of a page when looking at its layout.
|
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
action={
|
action={
|
||||||
@@ -24,11 +24,11 @@ export default function PaymentReceivesEmptyStatus() {
|
|||||||
history.push('/payment-receives/new');
|
history.push('/payment-receives/new');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
New payment receive
|
<T id={'new_payment_receive'} />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button intent={Intent.NONE} large={true}>
|
<Button intent={Intent.NONE} large={true}>
|
||||||
Learn more
|
<T id={'learn_more'} />
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,10 +65,7 @@ function ReceiptFormHeader({
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Synsc receipt number settings with the form.
|
// Synsc receipt number settings with the form.
|
||||||
useObserveReceiptNoSettings(
|
useObserveReceiptNoSettings(receiptNumberPrefix, receiptNextNumber);
|
||||||
receiptNumberPrefix,
|
|
||||||
receiptNextNumber,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||||
@@ -175,7 +172,11 @@ function ReceiptFormHeader({
|
|||||||
}}
|
}}
|
||||||
tooltip={true}
|
tooltip={true}
|
||||||
tooltipProps={{
|
tooltipProps={{
|
||||||
content: 'Setting your auto-generated receipt number',
|
content: (
|
||||||
|
<T
|
||||||
|
id={'setting_your_auto_generated_payment_receive_number'}
|
||||||
|
/>
|
||||||
|
),
|
||||||
position: Position.BOTTOM_LEFT,
|
position: Position.BOTTOM_LEFT,
|
||||||
}}
|
}}
|
||||||
inputProps={{
|
inputProps={{
|
||||||
|
|||||||
@@ -1066,5 +1066,6 @@ export default {
|
|||||||
transaction_number: 'Transaction number',
|
transaction_number: 'Transaction number',
|
||||||
cash_flow_statement: 'Cash Flow Statement',
|
cash_flow_statement: 'Cash Flow Statement',
|
||||||
statement_of_cash_flow: 'Statement of Cash Flow ',
|
statement_of_cash_flow: 'Statement of Cash Flow ',
|
||||||
inventory_item_details:'Inventory Item Details'
|
inventory_item_details: 'Inventory Item Details',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
"phone_number": "Phone Number",
|
"phone_number": "Phone Number",
|
||||||
"you_email_address_is": "You email address is",
|
"you_email_address_is": "You email address is",
|
||||||
"you_will_use_this_address_to_sign_in_to_bigcapital": "You will use this address to sign in to Bigcapital.",
|
"you_will_use_this_address_to_sign_in_to_bigcapital": "You will use this address to sign in to Bigcapital.",
|
||||||
"signing_in_or_creating":"By signing in or creating an account, you agree with our <a> Terms & Conditions </a> and <a> Privacy Statement </a> ",
|
"signing_in_or_creating": "By signing in or creating an account, you agree with our <a> Terms & Conditions </a> and <a> Privacy Statement </a> ",
|
||||||
"and": "And",
|
"and": "And",
|
||||||
"create_account": "Create Account",
|
"create_account": "Create Account",
|
||||||
"success": "Success",
|
"success": "Success",
|
||||||
@@ -878,5 +878,58 @@
|
|||||||
"transaction_number": "Transaction number",
|
"transaction_number": "Transaction number",
|
||||||
"cash_flow_statement": "Cash Flow Statement",
|
"cash_flow_statement": "Cash Flow Statement",
|
||||||
"statement_of_cash_flow": "Statement of Cash Flow ",
|
"statement_of_cash_flow": "Statement of Cash Flow ",
|
||||||
"inventory_item_details": "Inventory Item Details"
|
"inventory_item_details": "Inventory Item Details",
|
||||||
|
"sales_invoices": "Sales invoices",
|
||||||
|
"tracking_sales_invoices_with_your_customers": "Tracking sales invoices with your customers with payment due date.",
|
||||||
|
"sales_estimates": "Sales estimates",
|
||||||
|
"manage_your_sales_estimates_to_create_quotes": "Manage your sales estimates to create quotes that can later be turned to a sale invoice.",
|
||||||
|
"sales_receipts": "Sales receipts",
|
||||||
|
"manage_sales_receipts_for_sales_that_get_paid": "Manage sales receipts for sales that get paid immediately from the customer.",
|
||||||
|
"manage_the_customers_relations_with_customer": "Manage the customers relations with customer receivable and credit balances.",
|
||||||
|
"customers_payment": "Customers payment",
|
||||||
|
"manage_payment_transactions_from_your_customers": "Manage payment transactions from your customers with sale invoices.",
|
||||||
|
"purchase_invoices": "Purchase invoices",
|
||||||
|
"manage_the_purchase_invoices_with_your_vendors": "Manage the purchase invoices with your vendors with payment due date.",
|
||||||
|
"manage_the_vendors_relations_with_vendor_relations": "Manage the vendors relations with vendor payable and debit balances.",
|
||||||
|
"vendors_payments": "Vendors payments",
|
||||||
|
"manage_payments_transactions_to_your_vendors": "Manage payments transactions to your vendors with purchase invoices.",
|
||||||
|
"manage_your_accounts_chart_to_record_your_transactions_and_categories": "Manage your accounts chart to record your transactions and categories your transactions in parent accounts.",
|
||||||
|
"manage_manual_journal_transactions_on_accounts": "Manage manual journal transactions on accounts, cost centra and projects.",
|
||||||
|
"track_your_indirect_expenses_under_specific_categories": "Track your indirect expenses under specific categories such as payroll, rent.",
|
||||||
|
"financial_statements": "Financial statements",
|
||||||
|
"show_financial_reports_about_your_organization": "Show financial reports about your organization to summarize your business’s financial performance.",
|
||||||
|
"products_services": "Products & Services",
|
||||||
|
"manage_your_products_inventory_or_non_inventory": "Manage your products (inventory or non-inventory) and services and place them into categories.",
|
||||||
|
"products_services_categories": "Products & Services Categories",
|
||||||
|
"group_your_products_and_service": "Group your products and service into different categories.",
|
||||||
|
"inventory_adjustments": "Inventory Adjustments",
|
||||||
|
"manage_your_inventory_adjustment_of_inventory_items": "Manage your inventory adjustment of inventory items.",
|
||||||
|
"page_size": "Page size",
|
||||||
|
"there_is_no_items_categories_in_table_yet": "There is no items categories in table yet.",
|
||||||
|
"sales_inventory": "Sales & inventory",
|
||||||
|
"accounting": "Accounting",
|
||||||
|
"system": "SYSTEM",
|
||||||
|
"it_s_time_to_send_estimates_to_your_customers": "It's time to send estimates to your customers",
|
||||||
|
"it_is_a_long_established_fact_that_a_reader": " It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.",
|
||||||
|
"new_sale_estimate": "New sale estimate",
|
||||||
|
"learn_more": "Learn more",
|
||||||
|
"back_to_list": "Back to list.",
|
||||||
|
"estimate_details": "Estimate details",
|
||||||
|
"attachments_maximum": "Attachments: Maximum size: 20MB",
|
||||||
|
"drag_drop_files_here_or_click_here": "Drag/Drop files here or click here.",
|
||||||
|
"enter_an_item": "Enter an item...",
|
||||||
|
"i_will_enter_them_manually_each_time": "I will enter them manually each time",
|
||||||
|
"manual_entering_for_this_transaction": "Manual entering for this transaction.",
|
||||||
|
"due_amount": "Due Amount",
|
||||||
|
"invoice_details": "Invoice details",
|
||||||
|
"setting_your_auto_generated_estimate_number": "Setting your auto-generated estimate number",
|
||||||
|
"setting_your_auto_generated_journal_number": "Setting your auto-generated journal number",
|
||||||
|
"setting_your_auto_generated_invoice_number": "Setting your auto-generated invoice number",
|
||||||
|
"setting_your_auto_generated_payment_receive_number": "Setting your auto-generated Payment Receive number",
|
||||||
|
"the_organization_doesn_t_receive_money_yet": "The organization doesn't receive money, yet!",
|
||||||
|
"new_payment_receive": "New payment receive",
|
||||||
|
"there_is_no_receivable_invoices_for_this_customer": "There is no receivable invoices for this customer that can be applied for this payment",
|
||||||
|
"please_select_a_customer_to_display_all_open_invoices_for_it": "Please select a customer to display all open invoices for it.",
|
||||||
|
"payment_receive_details": "Payment receive details",
|
||||||
|
"receive_full_amount": "Receive full amount"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user