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