mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 06:40:31 +00:00
Fix: Purchases Bills & feat: BillNumberDialog
This commit is contained in:
@@ -8,13 +8,14 @@ import AccountFormDialog from 'containers/Dialogs/AccountFormDialog';
|
|||||||
// import InviteUserDialog from 'containers/Dialogs/InviteUserDialog';
|
// import InviteUserDialog from 'containers/Dialogs/InviteUserDialog';
|
||||||
// import ExchangeRateDialog from 'containers/Dialogs/ExchangeRateDialog';
|
// import ExchangeRateDialog from 'containers/Dialogs/ExchangeRateDialog';
|
||||||
import JournalNumberDialog from 'containers/Dialogs/JournalNumberDialog';
|
import JournalNumberDialog from 'containers/Dialogs/JournalNumberDialog';
|
||||||
|
import BillNumberDialog from 'containers/Dialogs/BillNumberDialog';
|
||||||
|
|
||||||
export default function DialogsContainer() {
|
export default function DialogsContainer() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AccountFormDialog dialogName={'account-form'} />
|
<AccountFormDialog dialogName={'account-form'} />
|
||||||
<JournalNumberDialog dialogName={'journal-number-form'} />
|
<JournalNumberDialog dialogName={'journal-number-form'} />
|
||||||
|
<BillNumberDialog dialogName={'bill-number-form'} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
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 withBillActions from 'containers/Purchases/Bill/withBillActions';
|
||||||
|
|
||||||
|
import { compose, optionsMapToArray } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bill number dialog's content.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function BillNumberDialogContent({
|
||||||
|
// #withSettings
|
||||||
|
nextNumber,
|
||||||
|
numberPrefix,
|
||||||
|
|
||||||
|
// #withSettingsActions
|
||||||
|
requestFetchOptions,
|
||||||
|
requestSubmitOptions,
|
||||||
|
|
||||||
|
// #withDialogActions
|
||||||
|
closeDialog,
|
||||||
|
|
||||||
|
// #withBillActions
|
||||||
|
setBillNumberChanged,
|
||||||
|
}) {
|
||||||
|
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
|
||||||
|
|
||||||
|
const handleSubmitForm = (values, { setSubmitting }) => {
|
||||||
|
const options = optionsMapToArray(values).map((option) => {
|
||||||
|
return { key: option.key, ...option, group: 'bills' };
|
||||||
|
});
|
||||||
|
|
||||||
|
requestSubmitOptions({ options })
|
||||||
|
.then(() => {
|
||||||
|
setSubmitting(false);
|
||||||
|
closeDialog('bill-number-form');
|
||||||
|
setBillNumberChanged(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
queryCache.invalidateQueries('settings');
|
||||||
|
}, 250);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setSubmitting(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
closeDialog('bill-number-form');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogContent isLoading={fetchSettings.isFetching}>
|
||||||
|
<ReferenceNumberForm
|
||||||
|
initialNumber={nextNumber}
|
||||||
|
initialPrefix={numberPrefix}
|
||||||
|
onSubmit={handleSubmitForm}
|
||||||
|
onClose={handleClose}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
withDialogActions,
|
||||||
|
withSettingsActions,
|
||||||
|
withSettings(({ billsettings }) => ({
|
||||||
|
nextNumber: billsettings?.next_number,
|
||||||
|
numberPrefix: billsettings?.number_prefix,
|
||||||
|
})),
|
||||||
|
withBillActions,
|
||||||
|
)(BillNumberDialogContent);
|
||||||
26
client/src/containers/Dialogs/BillNumberDialog/index.js
Normal file
26
client/src/containers/Dialogs/BillNumberDialog/index.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
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 BillNumberDialogContent = lazy(() => import('./BillNumberDialogContent'));
|
||||||
|
|
||||||
|
function BillNumberDialog({ dialogName, payload = { id: null }, isOpen }) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
name={dialogName}
|
||||||
|
title={<T id={'bill_number_settings'} />}
|
||||||
|
autoFocus={true}
|
||||||
|
canEscapeKeyClose={true}
|
||||||
|
isOpen={isOpen}
|
||||||
|
className={'dialog--journal-number-settings'}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<BillNumberDialogContent billNumberId={payload.id} />
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(withDialogRedux())(BillNumberDialog);
|
||||||
@@ -20,8 +20,10 @@ import BillFormFooter from './BillFormFooter';
|
|||||||
|
|
||||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
import withMediaActions from 'containers/Media/withMediaActions';
|
import withMediaActions from 'containers/Media/withMediaActions';
|
||||||
|
import withBills from './withBills';
|
||||||
import withBillActions from './withBillActions';
|
import withBillActions from './withBillActions';
|
||||||
import withBillDetail from './withBillDetail';
|
import withBillDetail from './withBillDetail';
|
||||||
|
import withSettings from 'containers/Settings/withSettings';
|
||||||
|
|
||||||
import { AppToaster } from 'components';
|
import { AppToaster } from 'components';
|
||||||
import Dragzone from 'components/Dragzone';
|
import Dragzone from 'components/Dragzone';
|
||||||
@@ -29,7 +31,7 @@ import useMedia from 'hooks/useMedia';
|
|||||||
|
|
||||||
import { compose, repeatValue } from 'utils';
|
import { compose, repeatValue } from 'utils';
|
||||||
|
|
||||||
const MIN_LINES_NUMBER = 4;
|
const MIN_LINES_NUMBER = 5;
|
||||||
|
|
||||||
function BillForm({
|
function BillForm({
|
||||||
//#WithMedia
|
//#WithMedia
|
||||||
@@ -39,10 +41,17 @@ function BillForm({
|
|||||||
//#withBillActions
|
//#withBillActions
|
||||||
requestSubmitBill,
|
requestSubmitBill,
|
||||||
requestEditBill,
|
requestEditBill,
|
||||||
|
setBillNumberChanged,
|
||||||
|
|
||||||
//#withDashboard
|
//#withDashboard
|
||||||
changePageTitle,
|
changePageTitle,
|
||||||
changePageSubtitle,
|
|
||||||
|
// #withBills
|
||||||
|
nextBillNumberChanged,
|
||||||
|
|
||||||
|
// #withSettings
|
||||||
|
billNextNumber,
|
||||||
|
billNumberPrefix,
|
||||||
|
|
||||||
//#withBillDetail
|
//#withBillDetail
|
||||||
bill,
|
bill,
|
||||||
@@ -83,7 +92,6 @@ function BillForm({
|
|||||||
}
|
}
|
||||||
}, [changePageTitle, bill, formatMessage]);
|
}, [changePageTitle, bill, formatMessage]);
|
||||||
|
|
||||||
// @todo abstruct validation schema to sperated file.
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
vendor_id: Yup.number()
|
vendor_id: Yup.number()
|
||||||
.required()
|
.required()
|
||||||
@@ -94,11 +102,11 @@ function BillForm({
|
|||||||
due_date: Yup.date()
|
due_date: Yup.date()
|
||||||
.required()
|
.required()
|
||||||
.label(formatMessage({ id: 'due_date_' })),
|
.label(formatMessage({ id: 'due_date_' })),
|
||||||
bill_number: Yup.number()
|
bill_number: Yup.string()
|
||||||
.required()
|
.required()
|
||||||
.label(formatMessage({ id: 'bill_number_' })),
|
.label(formatMessage({ id: 'bill_number_' })),
|
||||||
reference_no: Yup.string().min(1).max(255),
|
reference_no: Yup.string().nullable().min(1).max(255),
|
||||||
status: Yup.string().required().nullable(),
|
// status: Yup.string().required().nullable(),
|
||||||
note: Yup.string()
|
note: Yup.string()
|
||||||
.trim()
|
.trim()
|
||||||
.min(1)
|
.min(1)
|
||||||
@@ -128,27 +136,34 @@ function BillForm({
|
|||||||
[onFormSubmit],
|
[onFormSubmit],
|
||||||
);
|
);
|
||||||
|
|
||||||
const defaultBill = useMemo(() => ({
|
const defaultBill = useMemo(
|
||||||
index: 0,
|
() => ({
|
||||||
item_id: null,
|
index: 0,
|
||||||
rate: null,
|
item_id: null,
|
||||||
discount: 0,
|
rate: null,
|
||||||
quantity: null,
|
discount: 0,
|
||||||
description: '',
|
quantity: null,
|
||||||
}));
|
description: '',
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const billNumber = billNumberPrefix
|
||||||
|
? `${billNumberPrefix}-${billNextNumber}`
|
||||||
|
: billNextNumber;
|
||||||
|
|
||||||
const defaultInitialValues = useMemo(
|
const defaultInitialValues = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
vendor_id: '',
|
vendor_id: '',
|
||||||
bill_number: '',
|
bill_number: billNumber,
|
||||||
bill_date: moment(new Date()).format('YYYY-MM-DD'),
|
bill_date: moment(new Date()).format('YYYY-MM-DD'),
|
||||||
due_date: moment(new Date()).format('YYYY-MM-DD'),
|
due_date: moment(new Date()).format('YYYY-MM-DD'),
|
||||||
status: 'Bill',
|
// status: 'Bill',
|
||||||
reference_no: '',
|
reference_no: '',
|
||||||
note: '',
|
note: '',
|
||||||
entries: [...repeatValue(defaultBill, MIN_LINES_NUMBER)],
|
entries: [...repeatValue(defaultBill, MIN_LINES_NUMBER)],
|
||||||
}),
|
}),
|
||||||
[defaultBill],
|
[defaultBill, billNumber],
|
||||||
);
|
);
|
||||||
|
|
||||||
const orderingIndex = (_bill) => {
|
const orderingIndex = (_bill) => {
|
||||||
@@ -209,9 +224,12 @@ function BillForm({
|
|||||||
requestEditBill(bill.id, requestForm)
|
requestEditBill(bill.id, requestForm)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
message: formatMessage({
|
message: formatMessage(
|
||||||
id: 'the_bill_has_been_successfully_edited',
|
{
|
||||||
}),
|
id: 'the_bill_has_been_successfully_edited',
|
||||||
|
},
|
||||||
|
{ number: values.bill_number },
|
||||||
|
),
|
||||||
intent: Intent.SUCCESS,
|
intent: Intent.SUCCESS,
|
||||||
});
|
});
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
@@ -242,10 +260,16 @@ function BillForm({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
formik.setFieldValue('bill_number', billNumber);
|
||||||
|
setBillNumberChanged(false);
|
||||||
|
}, [nextBillNumberChanged, billNumber]);
|
||||||
|
|
||||||
const handleSubmitClick = useCallback(
|
const handleSubmitClick = useCallback(
|
||||||
(payload) => {
|
(payload) => {
|
||||||
setPayload(payload);
|
setPayload(payload);
|
||||||
formik.submitForm();
|
formik.submitForm();
|
||||||
|
formik.setSubmitting(false);
|
||||||
},
|
},
|
||||||
[setPayload, formik],
|
[setPayload, formik],
|
||||||
);
|
);
|
||||||
@@ -315,6 +339,7 @@ function BillForm({
|
|||||||
formik={formik}
|
formik={formik}
|
||||||
onSubmitClick={handleSubmitClick}
|
onSubmitClick={handleSubmitClick}
|
||||||
bill={bill}
|
bill={bill}
|
||||||
|
disabled={formik.isSubmitting}
|
||||||
onCancelClick={handleCancelClick}
|
onCancelClick={handleCancelClick}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -323,7 +348,12 @@ function BillForm({
|
|||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withBillActions,
|
withBillActions,
|
||||||
|
withBillDetail(),
|
||||||
|
withBills(({ nextBillNumberChanged }) => ({ nextBillNumberChanged })),
|
||||||
withDashboardActions,
|
withDashboardActions,
|
||||||
withMediaActions,
|
withMediaActions,
|
||||||
withBillDetail(),
|
withSettings(({ billsettings }) => ({
|
||||||
|
billNextNumber: billsettings?.next_number,
|
||||||
|
billNumberPrefix: billsettings?.number_prefix,
|
||||||
|
})),
|
||||||
)(BillForm);
|
)(BillForm);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export default function BillFormFooter({
|
|||||||
<div className={'form__floating-footer'}>
|
<div className={'form__floating-footer'}>
|
||||||
<Button
|
<Button
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
|
loading={isSubmitting}
|
||||||
intent={Intent.PRIMARY}
|
intent={Intent.PRIMARY}
|
||||||
type="submit"
|
type="submit"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -23,6 +24,7 @@ export default function BillFormFooter({
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
|
loading={isSubmitting}
|
||||||
intent={Intent.PRIMARY}
|
intent={Intent.PRIMARY}
|
||||||
className={'ml1'}
|
className={'ml1'}
|
||||||
name={'save'}
|
name={'save'}
|
||||||
|
|||||||
@@ -14,16 +14,17 @@ import moment from 'moment';
|
|||||||
import { momentFormatter, compose, tansformDateValue } from 'utils';
|
import { momentFormatter, compose, tansformDateValue } from 'utils';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import {
|
import {
|
||||||
AccountsSelectList,
|
|
||||||
ListSelect,
|
ListSelect,
|
||||||
ErrorMessage,
|
ErrorMessage,
|
||||||
FieldRequiredHint,
|
FieldRequiredHint,
|
||||||
Hint,
|
Icon,
|
||||||
|
InputPrependButton,
|
||||||
} from 'components';
|
} from 'components';
|
||||||
|
|
||||||
// import withCustomers from 'containers/Customers/withCustomers';
|
// import withCustomers from 'containers/Customers/withCustomers';
|
||||||
import withVendors from 'containers/Vendors/withVendors';
|
import withVendors from 'containers/Vendors/withVendors';
|
||||||
import withAccounts from 'containers/Accounts/withAccounts';
|
import withAccounts from 'containers/Accounts/withAccounts';
|
||||||
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
function BillFormHeader({
|
function BillFormHeader({
|
||||||
formik: { errors, touched, setFieldValue, getFieldProps, values },
|
formik: { errors, touched, setFieldValue, getFieldProps, values },
|
||||||
@@ -33,6 +34,9 @@ function BillFormHeader({
|
|||||||
vendorItems,
|
vendorItems,
|
||||||
//#withAccouts
|
//#withAccouts
|
||||||
accountsList,
|
accountsList,
|
||||||
|
|
||||||
|
// #withDialog
|
||||||
|
openDialog,
|
||||||
}) {
|
}) {
|
||||||
const handleDateChange = useCallback(
|
const handleDateChange = useCallback(
|
||||||
(date_filed) => (date) => {
|
(date_filed) => (date) => {
|
||||||
@@ -76,6 +80,10 @@ function BillFormHeader({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBillNumberChange = useCallback(() => {
|
||||||
|
openDialog('bill-number-form', {});
|
||||||
|
}, [openDialog]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="page-form page-form--bill">
|
<div className="page-form page-form--bill">
|
||||||
<div className={'page-form__primary-section'}>
|
<div className={'page-form__primary-section'}>
|
||||||
@@ -91,7 +99,7 @@ function BillFormHeader({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ListSelect
|
<ListSelect
|
||||||
items={vendorsCurrentPage}
|
items={vendorItems}
|
||||||
noResults={<MenuItem disabled={true} text="No results." />}
|
noResults={<MenuItem disabled={true} text="No results." />}
|
||||||
itemRenderer={vendorNameRenderer}
|
itemRenderer={vendorNameRenderer}
|
||||||
itemPredicate={filterVendorAccount}
|
itemPredicate={filterVendorAccount}
|
||||||
@@ -146,7 +154,7 @@ function BillFormHeader({
|
|||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'bill_number'} />}
|
label={<T id={'bill_number'} />}
|
||||||
inline={true}
|
inline={true}
|
||||||
className={('form-group--estimate', Classes.FILL)}
|
className={('form-group--bill_number', Classes.FILL)}
|
||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
intent={errors.bill_number && touched.bill_number && Intent.DANGER}
|
intent={errors.bill_number && touched.bill_number && Intent.DANGER}
|
||||||
helperText={
|
helperText={
|
||||||
@@ -156,6 +164,19 @@ function BillFormHeader({
|
|||||||
<InputGroup
|
<InputGroup
|
||||||
intent={errors.bill_number && touched.bill_number && Intent.DANGER}
|
intent={errors.bill_number && touched.bill_number && Intent.DANGER}
|
||||||
minimal={true}
|
minimal={true}
|
||||||
|
rightElement={
|
||||||
|
<InputPrependButton
|
||||||
|
buttonProps={{
|
||||||
|
onClick: handleBillNumberChange,
|
||||||
|
icon: <Icon icon={'settings-18'} />,
|
||||||
|
}}
|
||||||
|
tooltip={true}
|
||||||
|
tooltipProps={{
|
||||||
|
content: 'Setting your auto-generated bill number',
|
||||||
|
position: Position.BOTTOM_LEFT,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
{...getFieldProps('bill_number')}
|
{...getFieldProps('bill_number')}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
@@ -185,4 +206,5 @@ export default compose(
|
|||||||
withAccounts(({ accountsList }) => ({
|
withAccounts(({ accountsList }) => ({
|
||||||
accountsList,
|
accountsList,
|
||||||
})),
|
})),
|
||||||
|
withDialogActions,
|
||||||
)(BillFormHeader);
|
)(BillFormHeader);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import withVendorActions from 'containers/Vendors/withVendorActions';
|
|||||||
import withAccountsActions from 'containers/Accounts/withAccountsActions';
|
import withAccountsActions from 'containers/Accounts/withAccountsActions';
|
||||||
import withItemsActions from 'containers/Items/withItemsActions';
|
import withItemsActions from 'containers/Items/withItemsActions';
|
||||||
import withBillActions from './withBillActions';
|
import withBillActions from './withBillActions';
|
||||||
|
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
||||||
|
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
|
|
||||||
@@ -24,6 +25,9 @@ function Bills({
|
|||||||
|
|
||||||
//# withBilleActions
|
//# withBilleActions
|
||||||
requestFetchBill,
|
requestFetchBill,
|
||||||
|
|
||||||
|
// #withSettingsActions
|
||||||
|
requestFetchOptions,
|
||||||
}) {
|
}) {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@@ -41,6 +45,8 @@ function Bills({
|
|||||||
// Handle fetch Items data table or list
|
// Handle fetch Items data table or list
|
||||||
const fetchItems = useQuery('items-list', () => requestFetchItems({}));
|
const fetchItems = useQuery('items-list', () => requestFetchItems({}));
|
||||||
|
|
||||||
|
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
|
||||||
|
|
||||||
const handleFormSubmit = useCallback(
|
const handleFormSubmit = useCallback(
|
||||||
(payload) => {
|
(payload) => {
|
||||||
payload.redirect && history.push('/bills');
|
payload.redirect && history.push('/bills');
|
||||||
@@ -82,4 +88,5 @@ export default compose(
|
|||||||
withVendorActions,
|
withVendorActions,
|
||||||
withItemsActions,
|
withItemsActions,
|
||||||
withAccountsActions,
|
withAccountsActions,
|
||||||
|
withSettingsActions,
|
||||||
)(Bills);
|
)(Bills);
|
||||||
|
|||||||
@@ -96,9 +96,13 @@ function BillsDataTable({
|
|||||||
const actionMenuList = useCallback(
|
const actionMenuList = useCallback(
|
||||||
(bill) => (
|
(bill) => (
|
||||||
<Menu>
|
<Menu>
|
||||||
<MenuItem text={formatMessage({ id: 'view_details' })} />
|
<MenuItem
|
||||||
|
icon={<Icon icon="reader-18" />}
|
||||||
|
text={formatMessage({ id: 'view_details' })}
|
||||||
|
/>
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
icon={<Icon icon="pen-18" />}
|
||||||
text={formatMessage({ id: 'edit_bill' })}
|
text={formatMessage({ id: 'edit_bill' })}
|
||||||
onClick={handleEditBill(bill)}
|
onClick={handleEditBill(bill)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import t from 'store/types';
|
|||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
requestSubmitBill: (form) => dispatch(submitBill({ form })),
|
requestSubmitBill: (form) => dispatch(submitBill({ form })),
|
||||||
requestFetchBill: (id) => dispatch(fetchBill({ id })),
|
requestFetchBill: (id) => dispatch(fetchBill({ id })),
|
||||||
requestEditBill: (id, form) => dispatch(editBill( id, form )),
|
requestEditBill: (id, form) => dispatch(editBill(id, form)),
|
||||||
requestDeleteBill: (id) => dispatch(deleteBill({ id })),
|
requestDeleteBill: (id) => dispatch(deleteBill({ id })),
|
||||||
requestFetchBillsTable: (query = {}) =>
|
requestFetchBillsTable: (query = {}) =>
|
||||||
dispatch(fetchBillsTable({ query: { ...query } })),
|
dispatch(fetchBillsTable({ query: { ...query } })),
|
||||||
@@ -27,6 +27,11 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
type: t.BILLS_TABLE_QUERIES_ADD,
|
type: t.BILLS_TABLE_QUERIES_ADD,
|
||||||
queries,
|
queries,
|
||||||
}),
|
}),
|
||||||
|
setBillNumberChanged: (isChanged) =>
|
||||||
|
dispatch({
|
||||||
|
type: t.BILL_NUMBER_CHANGED,
|
||||||
|
payload: { isChanged },
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps);
|
export default connect(null, mapDispatchToProps);
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ export default (mapState) => {
|
|||||||
billsItems: state.bills.items,
|
billsItems: state.bills.items,
|
||||||
billsTableQuery: tableQuery,
|
billsTableQuery: tableQuery,
|
||||||
|
|
||||||
// @todo un-unncessery shit.
|
|
||||||
billsPageination: getBillsPaginationMeta(state, props, tableQuery),
|
billsPageination: getBillsPaginationMeta(state, props, tableQuery),
|
||||||
billsLoading: state.bills.loading,
|
billsLoading: state.bills.loading,
|
||||||
|
nextBillNumberChanged: state.bills.nextBillNumberChanged,
|
||||||
};
|
};
|
||||||
return mapState ? mapState(mapped, state, props) : mapped;
|
return mapState ? mapState(mapped, state, props) : mapped;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ export default (mapState) => {
|
|||||||
const mapped = {
|
const mapped = {
|
||||||
organizationSettings: state.settings.data.organization,
|
organizationSettings: state.settings.data.organization,
|
||||||
manualJournalsSettings: state.settings.data.manual_journals,
|
manualJournalsSettings: state.settings.data.manual_journals,
|
||||||
|
billsettings: state.settings.data.bills,
|
||||||
};
|
};
|
||||||
return mapState ? mapState(mapped, state, props) : mapped;
|
return mapState ? mapState(mapped, state, props) : mapped;
|
||||||
};
|
};
|
||||||
|
|
||||||
return connect(mapStateToProps);
|
return connect(mapStateToProps);
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export default (mapState) => {
|
|||||||
const mapped = {
|
const mapped = {
|
||||||
vendorsCurrentPage: getVendorsItems(state, props, query),
|
vendorsCurrentPage: getVendorsItems(state, props, query),
|
||||||
vendorViews: getResourceViews(state, props, 'vendors'),
|
vendorViews: getResourceViews(state, props, 'vendors'),
|
||||||
vendorItems: state.vendors.items,
|
vendorItems: Object.values(state.vendors.items),
|
||||||
vendorTableQuery: query,
|
vendorTableQuery: query,
|
||||||
vendorsPageination: getVendorsPaginationMeta(state, props, query),
|
vendorsPageination: getVendorsPaginationMeta(state, props, query),
|
||||||
vendorsLoading: state.vendors.loading,
|
vendorsLoading: state.vendors.loading,
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ export default {
|
|||||||
once_delete_this_item_you_will_able_to_restore_it: `Once you delete this item, you won\'t be able to restore the item later. Are you sure you want to delete ?<br /><br />If you're not sure, you can inactivate it instead.`,
|
once_delete_this_item_you_will_able_to_restore_it: `Once you delete this item, you won\'t be able to restore the item later. Are you sure you want to delete ?<br /><br />If you're not sure, you can inactivate it instead.`,
|
||||||
the_item_has_been_successfully_deleted:
|
the_item_has_been_successfully_deleted:
|
||||||
'The item has been successfully deleted.',
|
'The item has been successfully deleted.',
|
||||||
the_item_has_been_successfully_edited:
|
the_item_has_been_successfully_edited:
|
||||||
'The item #{number} has been successfully edited.',
|
'The item #{number} has been successfully edited.',
|
||||||
the_item_category_has_been_successfully_created:
|
the_item_category_has_been_successfully_created:
|
||||||
'The item category has been successfully created.',
|
'The item category has been successfully created.',
|
||||||
@@ -777,4 +777,5 @@ export default {
|
|||||||
prefix: 'Prefix',
|
prefix: 'Prefix',
|
||||||
next_number: 'Next Number',
|
next_number: 'Next Number',
|
||||||
journal_number_settings: 'Journal number settings',
|
journal_number_settings: 'Journal number settings',
|
||||||
|
bill_number_settings: 'Bill number settings',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,21 +19,21 @@ export const fetchBillsTable = ({ query = {} }) => {
|
|||||||
dispatch({
|
dispatch({
|
||||||
type: t.BILLS_PAGE_SET,
|
type: t.BILLS_PAGE_SET,
|
||||||
payload: {
|
payload: {
|
||||||
bills: response.data.bills.results,
|
bills: response.data.bills,
|
||||||
pagination: response.data.bills.pagination,
|
pagination: response.data.pagination,
|
||||||
customViewId: response.data.customViewId || -1,
|
customViewId: response.data.customViewId || -1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
dispatch({
|
dispatch({
|
||||||
type: t.BILLS_ITEMS_SET,
|
type: t.BILLS_ITEMS_SET,
|
||||||
payload: {
|
payload: {
|
||||||
bills: response.data.bills.results,
|
bills: response.data.bills,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
dispatch({
|
dispatch({
|
||||||
type: t.BILLS_PAGINATION_SET,
|
type: t.BILLS_PAGINATION_SET,
|
||||||
payload: {
|
payload: {
|
||||||
pagination: response.data.bills.pagination,
|
pagination: response.data.pagination,
|
||||||
customViewId: response.data.customViewId || -1,
|
customViewId: response.data.customViewId || -1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -66,7 +66,19 @@ export const deleteBill = ({ id }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const submitBill = ({ form }) => {
|
export const submitBill = ({ form }) => {
|
||||||
return (dispatch) => ApiService.post('purchases/bills', form);
|
return (dispatch) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
ApiService.post('purchases/bills', form)
|
||||||
|
.then((response) => {
|
||||||
|
resolve(response);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const { response } = error;
|
||||||
|
const { data } = response;
|
||||||
|
|
||||||
|
reject(data?.errors);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchBill = ({ id }) => {
|
export const fetchBill = ({ id }) => {
|
||||||
@@ -91,5 +103,17 @@ export const fetchBill = ({ id }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const editBill = (id, form) => {
|
export const editBill = (id, form) => {
|
||||||
return (dispatch) => ApiService.post(`purchases/bills/${id}`, form);
|
return (dispatch) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
ApiService.post(`purchases/bills/${id}`, form)
|
||||||
|
.then((response) => {
|
||||||
|
resolve(response);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const { response } = error;
|
||||||
|
const { data } = response;
|
||||||
|
|
||||||
|
reject(data?.errors);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const initialState = {
|
|||||||
page_size: 5,
|
page_size: 5,
|
||||||
page: 1,
|
page: 1,
|
||||||
},
|
},
|
||||||
|
nextBillNumberChanged: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultBill = {
|
const defaultBill = {
|
||||||
@@ -98,6 +99,11 @@ const reducer = createReducer(initialState, {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[t.BILL_NUMBER_CHANGED]: (state, action) => {
|
||||||
|
const { isChanged } = action.payload;
|
||||||
|
state.nextBillNumberChanged = isChanged;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default createTableQueryReducers('bills', reducer);
|
export default createTableQueryReducers('bills', reducer);
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ export default {
|
|||||||
BILLS_PAGINATION_SET: 'BILLS_PAGINATION_SET',
|
BILLS_PAGINATION_SET: 'BILLS_PAGINATION_SET',
|
||||||
BILLS_PAGE_SET: 'BILLS_PAGE_SET',
|
BILLS_PAGE_SET: 'BILLS_PAGE_SET',
|
||||||
BILLS_ITEMS_SET: 'BILLS_ITEMS_SET',
|
BILLS_ITEMS_SET: 'BILLS_ITEMS_SET',
|
||||||
|
BILL_NUMBER_CHANGED: 'BILL_NUMBER_CHANGED',
|
||||||
};
|
};
|
||||||
|
|||||||
2
client/src/store/vendors/vendors.actions.js
vendored
2
client/src/store/vendors/vendors.actions.js
vendored
@@ -17,7 +17,7 @@ export const fetchVendorsTable = ({ query }) => {
|
|||||||
payload: {
|
payload: {
|
||||||
vendors: response.data.vendors,
|
vendors: response.data.vendors,
|
||||||
pagination: response.data.pagination,
|
pagination: response.data.pagination,
|
||||||
customViewId: response.data.customViewId,
|
customViewId: response.data.customViewId || -1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
dispatch({
|
dispatch({
|
||||||
|
|||||||
@@ -1,58 +1,66 @@
|
|||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
organization: [
|
organization: [
|
||||||
{
|
{
|
||||||
key: 'name',
|
key: "name",
|
||||||
type: 'string',
|
type: "string",
|
||||||
config: true,
|
config: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'base_currency',
|
key: "base_currency",
|
||||||
type: 'string',
|
type: "string",
|
||||||
config: true,
|
config: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'industry',
|
key: "industry",
|
||||||
type: 'string',
|
type: "string",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'location',
|
key: "location",
|
||||||
type: 'string',
|
type: "string",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'fiscal_year',
|
key: "fiscal_year",
|
||||||
type: 'string',
|
type: "string",
|
||||||
// config: true,
|
// config: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'financial_date_start',
|
key: "financial_date_start",
|
||||||
type: 'string',
|
type: "string",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'language',
|
key: "language",
|
||||||
type: 'string',
|
type: "string",
|
||||||
config: true,
|
config: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'time_zone',
|
key: "time_zone",
|
||||||
type: 'string',
|
type: "string",
|
||||||
// config: true,
|
// config: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'date_format',
|
key: "date_format",
|
||||||
type: 'string',
|
type: "string",
|
||||||
// config: true,
|
// config: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
manual_journals: [
|
manual_journals: [
|
||||||
{
|
{
|
||||||
key: 'next_number',
|
key: "next_number",
|
||||||
type: 'number',
|
type: "number",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'number_prefix',
|
key: "number_prefix",
|
||||||
type: 'string',
|
type: "string",
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
|
bills: [
|
||||||
|
{
|
||||||
|
key: "next_number",
|
||||||
|
type: "number",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "number_prefix",
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user