Fix : Receipt & Invoices

This commit is contained in:
elforjani3
2020-10-26 17:45:21 +02:00
parent 947937aff9
commit cbe6934b58
24 changed files with 430 additions and 94 deletions

View File

@@ -11,7 +11,8 @@ import JournalNumberDialog from 'containers/Dialogs/JournalNumberDialog';
import BillNumberDialog from 'containers/Dialogs/BillNumberDialog';
import PaymentNumberDialog from 'containers/Dialogs/PaymentNumberDialog';
import EstimateNumberDialog from 'containers/Dialogs/EstimateNumberDialog';
import ReceiptNumberDialog from 'containers/Dialogs/ReceiptNumberDialog';
import InvoiceNumberDialog from 'containers/Dialogs/InvoiceNumberDialog';
export default function DialogsContainer() {
return (
<div>
@@ -20,6 +21,8 @@ export default function DialogsContainer() {
<BillNumberDialog dialogName={'bill-number-form'} />
<PaymentNumberDialog dialogName={'payment-number-form'} />
<EstimateNumberDialog dialogName={'estimate-number-form'} />
<ReceiptNumberDialog dialogName={'receipt-number-form'} />
<InvoiceNumberDialog dialogName={'invoice-number-form'} />
</div>
);
}

View File

@@ -0,0 +1,74 @@
import React from 'react';
import { DialogContent } from 'components';
import { useQuery, queryCache } from 'react-query';
import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withSettingsActions from 'containers/Settings/withSettingsActions';
import withSettings from 'containers/Settings/withSettings';
import { compose, optionsMapToArray } from 'utils';
/**
* invoice number dialog's content.
*/
function InvoiceNumberDialogContent({
// #withSettings
nextNumber,
numberPrefix,
// #withSettingsActions
requestFetchOptions,
requestSubmitOptions,
// #withDialogActions
closeDialog,
}) {
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
const handleSubmitForm = (values, { setSubmitting }) => {
const options = optionsMapToArray(values).map((option) => {
return { key: option.key, ...option, group: 'sales_invoices' };
});
requestSubmitOptions({ options })
.then(() => {
setSubmitting(false);
closeDialog('invoice-number-form');
setTimeout(() => {
queryCache.invalidateQueries('settings');
}, 250);
})
.catch(() => {
setSubmitting(false);
});
};
const handleClose = () => {
closeDialog('invoice-number-form');
};
return (
<DialogContent isLoading={fetchSettings.isFetching}>
<ReferenceNumberForm
initialNumber={nextNumber}
initialPrefix={numberPrefix}
onSubmit={handleSubmitForm}
onClose={handleClose}
/>
</DialogContent>
);
}
export default compose(
withDialogActions,
withSettingsActions,
withSettings(({ invoiceSettings }) => ({
nextNumber: invoiceSettings?.next_number,
numberPrefix: invoiceSettings?.number_prefix,
})),
) (InvoiceNumberDialogContent);

View File

@@ -0,0 +1,27 @@
import React, { lazy } from 'react';
import { FormattedMessage as T } from 'react-intl';
import { Dialog, DialogSuspense } from 'components';
import withDialogRedux from 'components/DialogReduxConnect';
import { compose } from 'utils';
const InvoiceNumberDialogContent = lazy(() =>
import('./InvoiceNumberDialogContent'),
);
function InvoiceNumberDialog({ dialogName, payload = { id: null }, isOpen }) {
return (
<Dialog
title={<T id={'bill_number_settings'} />}
name={dialogName}
autoFocus={true}
canEscapeKeyClose={true}
isOpen={isOpen}
>
<DialogSuspense>
<InvoiceNumberDialogContent InvoiceNumberId={payload.id} />
</DialogSuspense>
</Dialog>
);
}
export default compose(withDialogRedux())(InvoiceNumberDialog);

View File

@@ -0,0 +1,73 @@
import React from 'react';
import { DialogContent } from 'components';
import { useQuery, queryCache } from 'react-query';
import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withSettingsActions from 'containers/Settings/withSettingsActions';
import withSettings from 'containers/Settings/withSettings';
import { compose, optionsMapToArray } from 'utils';
/**
* Receipt number dialog's content.
*/
function ReceiptNumberDialogContent({
// #withSettings
nextNumber,
numberPrefix,
// #withSettingsActions
requestFetchOptions,
requestSubmitOptions,
// #withDialogActions
closeDialog,
}) {
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
const handleSubmitForm = (values, { setSubmitting }) => {
const options = optionsMapToArray(values).map((option) => {
return { key: option.key, ...option, group: 'sales_receipts' };
});
requestSubmitOptions({ options })
.then(() => {
setSubmitting(false);
closeDialog('receipt-number-form');
setTimeout(() => {
queryCache.invalidateQueries('settings');
}, 250);
})
.catch(() => {
setSubmitting(false);
});
};
const handleClose = () => {
closeDialog('receipt-number-form');
};
return (
<DialogContent isLoading={fetchSettings.isFetching}>
<ReferenceNumberForm
initialNumber={nextNumber}
initialPrefix={numberPrefix}
onSubmit={handleSubmitForm}
onClose={handleClose}
/>
</DialogContent>
);
}
export default compose(
withDialogActions,
withSettingsActions,
withSettings(({ receiptSettings }) => ({
nextNumber: receiptSettings?.next_number,
numberPrefix: receiptSettings?.number_prefix,
})),
)(ReceiptNumberDialogContent);

View File

@@ -0,0 +1,27 @@
import React, { lazy } from 'react';
import { FormattedMessage as T } from 'react-intl';
import { Dialog, DialogSuspense } from 'components';
import withDialogRedux from 'components/DialogReduxConnect';
import { compose } from 'utils';
const ReceiptNumberDialogContent = lazy(() =>
import('./ReceiptNumberDialogContent'),
);
function ReceiptNumberDialog({ dialogName, paylaod = { id: null }, isOpen }) {
return (
<Dialog
name={dialogName}
title={<T id={'receipt_number_settings'} />}
autoFocus={true}
canEscapeKeyClose={true}
isOpen={isOpen}
>
<DialogSuspense>
<ReceiptNumberDialogContent ReceiptNumberId={paylaod.id} />
</DialogSuspense>
</Dialog>
);
}
export default compose(withDialogRedux())(ReceiptNumberDialog);

View File

@@ -21,6 +21,7 @@ import withInvoiceActions from './withInvoiceActions';
import withInvoiceDetail from './withInvoiceDetail';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withMediaActions from 'containers/Media/withMediaActions';
import withSettings from 'containers/Settings/withSettings';
import { AppToaster } from 'components';
import Dragzone from 'components/Dragzone';
@@ -41,7 +42,10 @@ function InvoiceForm({
//#withDashboard
changePageTitle,
changePageSubtitle,
// #withSettings
invoiceNextNumber,
invoiceNumberPrefix,
//#withInvoiceDetail
invoice,
@@ -91,7 +95,7 @@ function InvoiceForm({
due_date: Yup.date()
.required()
.label(formatMessage({ id: 'due_date_' })),
invoice_no: Yup.number()
invoice_no: Yup.string()
.required()
.label(formatMessage({ id: 'invoice_no_' })),
reference_no: Yup.string().min(1).max(255),
@@ -142,13 +146,17 @@ function InvoiceForm({
[],
);
const invoiceNumber = invoiceNumberPrefix
? `${invoiceNumberPrefix}-${invoiceNextNumber}`
: invoiceNextNumber;
const defaultInitialValues = useMemo(
() => ({
customer_id: '',
invoice_date: moment(new Date()).format('YYYY-MM-DD'),
due_date: moment(new Date()).format('YYYY-MM-DD'),
status: 'SEND',
invoice_no: '',
invoice_no: invoiceNumber,
reference_no: '',
invoice_message: '',
terms_conditions: '',
@@ -198,7 +206,6 @@ function InvoiceForm({
}, [invoice]);
const formik = useFormik({
enableReinitialize: true,
validationSchema,
initialValues: {
...initialValues,
@@ -219,9 +226,12 @@ function InvoiceForm({
requestEditInvoice(invoice.id, requestForm)
.then((response) => {
AppToaster.show({
message: formatMessage({
id: 'the_invoice_has_been_successfully_edited',
}),
message: formatMessage(
{
id: 'the_invoice_has_been_successfully_edited',
},
{ number: values.invoice_no },
),
intent: Intent.SUCCESS,
});
setSubmitting(false);
@@ -251,6 +261,11 @@ function InvoiceForm({
}
},
});
useEffect(() => {
formik.setFieldValue('invoice_no', invoiceNumber);
}, [invoiceNumber]);
const handleSubmitClick = useCallback(
(payload) => {
setPayload(payload);
@@ -349,4 +364,9 @@ export default compose(
withDashboardActions,
withMediaActions,
withInvoiceDetail(),
withSettings(({ invoiceSettings }) => ({
invoiceNextNumber: invoiceSettings?.next_number,
invoiceNumberPrefix: invoiceSettings?.number_prefix,
})),
)(InvoiceForm);

View File

@@ -13,15 +13,24 @@ import { Row, Col } from 'react-grid-system';
import moment from 'moment';
import { momentFormatter, compose, tansformDateValue } from 'utils';
import classNames from 'classnames';
import { ListSelect, ErrorMessage, FieldRequiredHint, Hint } from 'components';
import {
ListSelect,
ErrorMessage,
FieldRequiredHint,
Icon,
InputPrependButton,
} from 'components';
import withCustomers from 'containers/Customers/withCustomers';
import withDialogActions from 'containers/Dialog/withDialogActions';
function InvoiceFormHeader({
formik: { errors, touched, setFieldValue, getFieldProps, values },
//#withCustomers
customers,
//#withDialogActions
openDialog,
}) {
const handleDateChange = useCallback(
(date_filed) => (date) => {
@@ -67,6 +76,10 @@ function InvoiceFormHeader({
[setFieldValue],
);
const handleInvoiceNumberChange = useCallback(() => {
openDialog('invoice-number-form', {});
}, [openDialog]);
return (
<div class="page-form page-form--invoice">
<div className={'page-form__primary-section'}>
@@ -149,6 +162,19 @@ function InvoiceFormHeader({
<InputGroup
intent={errors.invoice_no && touched.invoice_no && Intent.DANGER}
minimal={true}
rightElement={
<InputPrependButton
buttonProps={{
onClick: handleInvoiceNumberChange,
icon: <Icon icon={'settings-18'} />,
}}
tooltip={true}
tooltipProps={{
content: 'Setting your auto-generated invoice number',
position: Position.BOTTOM_LEFT,
}}
/>
}
{...getFieldProps('invoice_no')}
/>
</FormGroup>
@@ -174,4 +200,5 @@ export default compose(
withCustomers(({ customers }) => ({
customers,
})),
withDialogActions,
)(InvoiceFormHeader);

View File

@@ -46,15 +46,15 @@ function InvoiceList({
changePageTitle(formatMessage({ id: 'invoice_list' }));
}, [changePageTitle, formatMessage]);
const fetchResourceViews = useQuery(
['resource-views', 'sales_invoices'],
(key, resourceName) => requestFetchResourceViews(resourceName),
);
// const fetchResourceViews = useQuery(
// ['resource-views', 'sales_invoices'],
// (key, resourceName) => requestFetchResourceViews(resourceName),
// );
const fetchResourceFields = useQuery(
['resource-fields', 'sales_invoices'],
(key, resourceName) => requestFetchResourceFields(resourceName),
);
// const fetchResourceFields = useQuery(
// ['resource-fields', 'sales_invoices'],
// (key, resourceName) => requestFetchResourceFields(resourceName),
// );
const fetchInvoices = useQuery(['invoices-table', invoicesTableQuery], () =>
requestFetchInvoiceTable(),
@@ -124,7 +124,7 @@ function InvoiceList({
);
return (
<DashboardInsider
loading={fetchResourceViews.isFetching || fetchResourceFields.isFetching}
// loading={fetchResourceViews.isFetching || fetchResourceFields.isFetching}
name={'sales_invoices'}
>
<InvoiceActionsBar

View File

@@ -2,7 +2,6 @@ import React, { useEffect, useCallback, useState, useMemo } from 'react';
import {
Intent,
Button,
Classes,
Popover,
Menu,
MenuItem,
@@ -95,9 +94,13 @@ function InvoicesDataTable({
const actionMenuList = useCallback(
(invoice) => (
<Menu>
<MenuItem text={formatMessage({ id: 'view_details' })} />
<MenuItem
icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })}
/>
<MenuDivider />
<MenuItem
icon={<Icon icon="pen-18" />}
text={formatMessage({ id: 'edit_invoice' })}
onClick={handleEditInvoice(invoice)}
/>

View File

@@ -24,7 +24,7 @@ import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import withResourceDetail from 'containers/Resources/withResourceDetails';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withReceiptActions from './withReceipActions';
import withReceiptActions from './withReceiptActions';
import withReceipts from './withReceipts';
import { compose } from 'utils';

View File

@@ -18,10 +18,11 @@ import ReceiptFromHeader from './ReceiptFormHeader';
import EstimatesItemsTable from 'containers/Sales/Estimate/EntriesItemsTable';
import ReceiptFormFooter from './ReceiptFormFooter';
import withReceipActions from './withReceipActions';
import withReceiptActions from './withReceiptActions';
import withReceiptDetail from './withReceiptDetail';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withMediaActions from 'containers/Media/withMediaActions';
import withSettings from 'containers/Settings/withSettings';
import { AppToaster } from 'components';
import Dragzone from 'components/Dragzone';
@@ -45,7 +46,10 @@ function ReceiptForm({
//#withDashboard
changePageTitle,
changePageSubtitle,
// #withSettings
receiptNextNumber,
receiptNumberPrefix,
//#own Props
receiptId,
@@ -90,9 +94,9 @@ function ReceiptForm({
receipt_date: Yup.date()
.required()
.label(formatMessage({ id: 'receipt_date_' })),
// receipt_no: Yup.number()
// .required()
// .label(formatMessage({ id: 'receipt_no_' })),
receipt_number: Yup.string()
.required()
.label(formatMessage({ id: 'receipt_no_' })),
deposit_account_id: Yup.number()
.required()
.label(formatMessage({ id: 'deposit_account_' })),
@@ -102,7 +106,7 @@ function ReceiptForm({
.min(1)
.max(1024)
.label(formatMessage({ id: 'receipt_message_' })),
email_send_to: Yup.string().email().nullable(),
send_to_email: Yup.string().email().nullable(),
statement: Yup.string()
.trim()
.min(1)
@@ -143,12 +147,17 @@ function ReceiptForm({
[],
);
const receiptNumber = receiptNumberPrefix
? `${receiptNumberPrefix}-${receiptNextNumber}`
: receiptNextNumber;
const defaultInitialValues = useMemo(
() => ({
customer_id: '',
deposit_account_id: '',
receipt_number: receiptNumber,
receipt_date: moment(new Date()).format('YYYY-MM-DD'),
email_send_to: '',
send_to_email: '',
reference_no: '',
receipt_message: '',
statement: '',
@@ -198,7 +207,6 @@ function ReceiptForm({
}, [receipt]);
const formik = useFormik({
enableReinitialize: true,
validationSchema,
initialValues: {
...initialValues,
@@ -217,9 +225,12 @@ function ReceiptForm({
if (receipt && receipt.id) {
requestEditReceipt(receipt.id, requestForm).then(() => {
AppToaster.show({
message: formatMessage({
id: 'the_receipt_has_been_successfully_edited',
}),
message: formatMessage(
{
id: 'the_receipt_has_been_successfully_edited',
},
{ number: values.receipt_number },
),
intent: Intent.SUCCESS,
});
setSubmitting(false);
@@ -230,9 +241,12 @@ function ReceiptForm({
requestSubmitReceipt(requestForm)
.then((response) => {
AppToaster.show({
message: formatMessage({
id: 'the_receipt_has_been_successfully_created',
}),
message: formatMessage(
{
id: 'the_receipt_has_been_successfully_created',
},
{ number: values.receipt_number },
),
intent: Intent.SUCCESS,
});
setSubmitting(false);
@@ -245,7 +259,6 @@ function ReceiptForm({
}
},
});
console.log(formik.errors, 'ERROR');
const handleDeleteFile = useCallback(
(_deletedFiles) => {
@@ -287,6 +300,10 @@ function ReceiptForm({
);
};
useEffect(() => {
formik.setFieldValue('receipt_number', receiptNumber);
}, [receiptNumber]);
return (
<div className={'receipt-form'}>
<form onSubmit={formik.handleSubmit}>
@@ -342,8 +359,12 @@ function ReceiptForm({
}
export default compose(
withReceipActions,
withReceiptActions,
withDashboardActions,
withMediaActions,
withReceiptDetail(),
withSettings(({ receiptSettings }) => ({
receiptNextNumber: receiptSettings?.next_number,
receiptNumberPrefix: receiptSettings?.number_prefix,
})),
)(ReceiptForm);

View File

@@ -18,11 +18,13 @@ import {
ListSelect,
ErrorMessage,
FieldRequiredHint,
Hint,
Icon,
InputPrependButton,
} from 'components';
import withCustomers from 'containers/Customers/withCustomers';
import withAccounts from 'containers/Accounts/withAccounts';
import withDialogActions from 'containers/Dialog/withDialogActions';
function ReceiptFormHeader({
formik: { errors, touched, setFieldValue, getFieldProps, values },
@@ -31,6 +33,8 @@ function ReceiptFormHeader({
customers,
//#withAccouts
accountsList,
//#withDialogActions
openDialog,
}) {
const handleDateChange = useCallback(
(date) => {
@@ -82,6 +86,10 @@ function ReceiptFormHeader({
[accountsList],
);
const handleReceiptNumberChange = useCallback(() => {
openDialog('receipt-number-form', {});
}, [openDialog]);
return (
<div class="page-form receipt-form">
<div class="page-form__primary-section">
@@ -162,20 +170,39 @@ function ReceiptFormHeader({
</FormGroup>
</div>
{/* receipt_no */}
{/* <FormGroup
<FormGroup
label={<T id={'receipt'} />}
inline={true}
className={('form-group--receipt_no', Classes.FILL)}
className={('form-group--receipt_number', Classes.FILL)}
labelInfo={<FieldRequiredHint />}
intent={errors.receipt_no && touched.receipt_no && Intent.DANGER}
helperText={<ErrorMessage name="receipt_no" {...{ errors, touched }} />}
intent={
errors.receipt_number && touched.receipt_number && Intent.DANGER
}
helperText={
<ErrorMessage name="receipt_number" {...{ errors, touched }} />
}
>
<InputGroup
intent={errors.receipt_no && touched.receipt_no && Intent.DANGER}
intent={
errors.receipt_number && touched.receipt_number && Intent.DANGER
}
minimal={true}
{...getFieldProps('receipt_no')}
rightElement={
<InputPrependButton
buttonProps={{
onClick: handleReceiptNumberChange,
icon: <Icon icon={'settings-18'} />,
}}
tooltip={true}
tooltipProps={{
content: 'Setting your auto-generated receipt number',
position: Position.BOTTOM_LEFT,
}}
/>
}
{...getFieldProps('receipt_number')}
/>
</FormGroup> */}
</FormGroup>
{/*- Reference -*/}
<FormGroup
@@ -197,12 +224,12 @@ function ReceiptFormHeader({
label={<T id={'send_to_email'} />}
inline={true}
className={classNames('form-group--send_to_email', Classes.FILL)}
intent={errors.email_send_to && touched.email_send_to && Intent.DANGER}
intent={errors.send_to_email && touched.send_to_email && Intent.DANGER}
helperText={<ErrorMessage name="reference" {...{ errors, touched }} />}
>
<InputGroup
intent={
errors.email_send_to && touched.email_send_to && Intent.DANGER
errors.send_to_email && touched.send_to_email && Intent.DANGER
}
minimal={true}
{...getFieldProps('send_to_email')}
@@ -219,4 +246,5 @@ export default compose(
withAccounts(({ accountsList }) => ({
accountsList,
})),
withDialogActions,
)(ReceiptFormHeader);

View File

@@ -15,7 +15,7 @@ import ReceiptViewTabs from './ReceiptViewTabs';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withResourceActions from 'containers/Resources/withResourcesActions';
import withReceipts from './withReceipts';
import withReceipActions from './withReceipActions';
import withReceiptActions from './withReceiptActions';
import withViewsActions from 'containers/Views/withViewsActions';
import { compose } from 'utils';
@@ -46,15 +46,15 @@ function ReceiptList({
requestFetchReceiptsTable(),
);
const fetchResourceViews = useQuery(
['resource-views', 'sales_receipts'],
(key, resourceName) => requestFetchResourceViews(resourceName),
);
// const fetchResourceViews = useQuery(
// ['resource-views', 'sales_receipts'],
// (key, resourceName) => requestFetchResourceViews(resourceName),
// );
const fetchResourceFields = useQuery(
['resource-fields', 'sales_receipts'],
(key, resourceName) => requestFetchResourceFields(resourceName),
);
// const fetchResourceFields = useQuery(
// ['resource-fields', 'sales_receipts'],
// (key, resourceName) => requestFetchResourceFields(resourceName),
// );
useEffect(() => {
changePageTitle(formatMessage({ id: 'receipt_list' }));
@@ -140,7 +140,7 @@ function ReceiptList({
return (
<DashboardInsider
name={'sales_receipts'}
loading={fetchResourceViews.isFetching || fetchResourceFields.isFetching}
// loading={fetchResourceViews.isFetching || fetchResourceFields.isFetching}
>
<DashboardPageContent>
<ReceiptActionsBar
@@ -182,7 +182,7 @@ function ReceiptList({
export default compose(
withResourceActions,
withReceipActions,
withReceiptActions,
withDashboardActions,
withViewsActions,
withReceipts(({ receiptTableQuery }) => ({

View File

@@ -9,7 +9,7 @@ import { DashboardViewsTabs } from 'components';
import { useUpdateEffect } from 'hooks';
import withReceipts from './withReceipts';
import withReceiptActions from './withReceipActions';
import withReceiptActions from './withReceiptActions';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withViewDetails from 'containers/Views/withViewDetails';

View File

@@ -8,7 +8,8 @@ import DashboardInsider from 'components/Dashboard/DashboardInsider';
import withCustomersActions from 'containers/Customers/withCustomersActions';
import withAccountsActions from 'containers/Accounts/withAccountsActions';
import withItemsActions from 'containers/Items/withItemsActions';
import withReceipActions from './withReceipActions';
import withReceiptActions from './withReceiptActions';
import withSettingsActions from 'containers/Settings/withSettingsActions';
import { compose } from 'utils';
@@ -24,6 +25,9 @@ function Receipts({
//#withReceiptsActions
requestFetchReceipt,
// #withSettingsActions
requestFetchOptions,
}) {
const history = useHistory();
const { id } = useParams();
@@ -44,6 +48,8 @@ function Receipts({
// Handle fetch Items data table or list
const fetchItems = useQuery('items-table', () => requestFetchItems({}));
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
const handleFormSubmit = useCallback(
(payload) => {
payload.redirect && history.push('/receipts');
@@ -75,8 +81,9 @@ function Receipts({
}
export default compose(
withReceipActions,
withReceiptActions,
withCustomersActions,
withItemsActions,
withAccountsActions,
withSettingsActions,
)(Receipts);

View File

@@ -24,7 +24,7 @@ import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withViewDetails from 'containers/Views/withViewDetails';
import withReceipts from './withReceipts';
import withReceipActions from './withReceipActions';
import withReceiptActions from './withReceiptActions';
import withCurrentView from 'containers/Views/withCurrentView';
function ReceiptsDataTable({
@@ -94,9 +94,13 @@ function ReceiptsDataTable({
const actionMenuList = useCallback(
(estimate) => (
<Menu>
<MenuItem text={formatMessage({ id: 'view_details' })} />
<MenuItem
icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })}
/>
<MenuDivider />
<MenuItem
icon={<Icon icon="pen-18" />}
text={formatMessage({ id: 'edit_receipt' })}
onClick={handleEditReceipt(estimate)}
/>
@@ -134,6 +138,13 @@ function ReceiptsDataTable({
width: 140,
className: 'customer_id',
},
{
id: 'receipt_number',
Header: formatMessage({ id: 'receipt_number' }),
accessor: (row) => `#${row.receipt_number}`,
width: 140,
className: 'receipt_number',
},
{
id: 'deposit_account_id',
Header: formatMessage({ id: 'deposit_account' }),
@@ -142,11 +153,11 @@ function ReceiptsDataTable({
className: 'deposit_account',
},
{
id: 'email_send_to',
id: 'send_to_email',
Header: formatMessage({ id: 'email' }),
accessor: 'email_send_to',
accessor: 'send_to_email',
width: 140,
className: 'email_send_to',
className: 'send_to_email',
},
{
id: 'amount',
@@ -229,7 +240,7 @@ export default compose(
withCurrentView,
withDialogActions,
withDashboardActions,
withReceipActions,
withReceiptActions,
withReceipts(
({
receiptsCurrentPage,

View File

@@ -8,6 +8,8 @@ export default (mapState) => {
billsettings: state.settings.data.bills,
billPaymentSettings: state.settings.data.bill_payments,
estimatesSettings: state.settings.data.sales_estimates,
receiptSettings: state.settings.data.sales_receipts,
invoiceSettings: state.settings.data.sales_invoices,
};
return mapState ? mapState(mapped, state, props) : mapped;
};

View File

@@ -645,9 +645,9 @@ export default {
select_deposit_account: 'Select Deposit Account',
once_delete_this_receipt_you_will_able_to_restore_it: `Once you delete this receipt, you won\'t be able to restore it later. Are you sure you want to delete this receipt?`,
the_receipt_has_been_successfully_created:
'The recepit has been successfully created.',
'The recepit #{number} has been successfully created.',
the_receipt_has_been_successfully_edited:
'The receipt has been successfully edited.',
'The receipt #{number} has been successfully edited.',
the_receipt_has_been_successfully_deleted:
'The receipt has been successfully deleted.',
bill_list: 'Bill List',
@@ -776,8 +776,11 @@ export default {
bigger_or_equals: 'Bigger or equals',
prefix: 'Prefix',
next_number: 'Next Number',
journal_number_settings: 'Journal number Settings',
bill_number_settings: 'Bill number Settings',
payment_number_settings: 'Payment number Settings',
journal_number_settings: 'Journal Number Settings',
bill_number_settings: 'Bill Number Settings',
payment_number_settings: 'Payment Number Settings',
Estimate_number_settings: 'Estimate Number Settings',
receipt_number_settings: 'Receipt Number Settings',
invoice_number_settings: 'Invoice Number Settings',
receipt_number: 'Receipt Number',
};

View File

@@ -67,8 +67,8 @@ export const fetchInvoicesTable = ({ query } = {}) => {
dispatch({
type: t.INVOICES_PAGE_SET,
payload: {
sales_invoices: response.data.sales_invoices.results,
pagination: response.data.sales_invoices.pagination,
sales_invoices: response.data.sales_invoices,
pagination: response.data.pagination,
customViewId: response.data.customViewId || -1,
},
});
@@ -76,13 +76,13 @@ export const fetchInvoicesTable = ({ query } = {}) => {
dispatch({
type: t.INVOICES_ITEMS_SET,
payload: {
sales_invoices: response.data.sales_invoices.results,
sales_invoices: response.data.sales_invoices,
},
});
dispatch({
type: t.INVOICES_PAGINATION_SET,
payload: {
pagination: response.data.sales_invoices.pagination,
pagination: response.data.pagination,
customViewId: response.data.customViewId || -1,
},
});

View File

@@ -80,7 +80,7 @@ const reducer = createReducer(initialState, {
const { pagination, customViewId } = action.payload;
const mapped = {
pageSize: parseInt(pagination.pageSize, 10),
pageSize: parseInt(pagination.page_size, 10),
page: parseInt(pagination.page, 10),
total: parseInt(pagination.total, 10),
};

View File

@@ -6,17 +6,11 @@ export const submitReceipt = ({ form }) => {
new Promise((resolve, reject) => {
ApiService.post('sales/receipts', form)
.then((response) => {
dispatch({
type: t.SET_DASHBOARD_REQUEST_COMPLETED,
});
resolve(response);
})
.catch((error) => {
const { response } = error;
const { data } = response;
dispatch({
type: t.SET_DASHBOARD_REQUEST_COMPLETED,
});
reject(data?.errors);
});
});
@@ -60,12 +54,10 @@ export const fetchReceipt = ({ id }) => {
new Promise((resovle, reject) => {
ApiService.get(`sales/receipts/${id}`)
.then((response) => {
const { receipt } = response.data;
dispatch({
type: t.RECEIPT_SET,
payload: {
id,
receipt: response.data.receipt,
},
payload: { id, receipt },
});
resovle(response);
})
@@ -94,21 +86,21 @@ export const fetchReceiptsTable = ({ query = {} }) => {
dispatch({
type: t.RECEIPTS_PAGE_SET,
payload: {
sales_receipts: response.data.sales_receipts.results,
pagination: response.data.sales_receipts.pagination,
sales_receipts: response.data.sale_receipts,
pagination: response.data.pagination,
customViewId: response.data.customViewId || -1,
},
});
dispatch({
type: t.RECEIPTS_ITEMS_SET,
payload: {
sales_receipts: response.data.sales_receipts.results,
sales_receipts: response.data.sale_receipts,
},
});
dispatch({
type: t.RECEIPTS_PAGINATION_SET,
payload: {
pagination: response.data.sales_receipts.pagination,
pagination: response.data.pagination,
customViewId: response.data.customViewId || -1,
},
});

View File

@@ -60,7 +60,6 @@ const reducer = createReducer(initialState, {
const viewId = customViewId || -1;
const view = state.views[viewId] || {};
state.views[viewId] = {
...view,
pages: {
@@ -76,7 +75,7 @@ const reducer = createReducer(initialState, {
const { pagination, customViewId } = action.payload;
const mapped = {
pageSize: parseInt(pagination.pageSize, 10),
pageSize: parseInt(pagination.page_size, 10),
page: parseInt(pagination.page, 10),
total: parseInt(pagination.total, 10),
};
@@ -85,7 +84,6 @@ const reducer = createReducer(initialState, {
pagesCount: Math.ceil(mapped.total / mapped.pageSize),
pageIndex: Math.max(mapped.page - 1, 0),
};
state.views = {
...state.views,
[customViewId]: {