mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 04:40:32 +00:00
refactoring: payment made form.
This commit is contained in:
@@ -4,7 +4,7 @@ import { Intent } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { sumBy, isEmpty, omit } from 'lodash';
|
||||
import { isEmpty, omit } from 'lodash';
|
||||
import { CLASSES } from 'common/classes';
|
||||
|
||||
import { EditBillFormSchema, CreateBillFormSchema } from './BillForm.schema';
|
||||
@@ -68,7 +68,7 @@ export default function BillForm() {
|
||||
const entries = values.entries.filter(
|
||||
(item) => item.item_id && item.quantity,
|
||||
);
|
||||
const totalQuantity = safeSumBy(entries, (entry) => entry.quantity);
|
||||
const totalQuantity = safeSumBy(entries, 'quantity');
|
||||
|
||||
if (totalQuantity === 0) {
|
||||
AppToaster.show({
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
import { DashboardContentTable, DashboardPageContent } from 'components';
|
||||
|
||||
import 'style/pages/Bills/List.scss';
|
||||
|
||||
import { BillsListProvider } from './BillsListProvider';
|
||||
|
||||
import BillsActionsBar from './BillsActionsBar';
|
||||
|
||||
@@ -9,31 +9,34 @@ import { DataTableEditable } from 'components';
|
||||
import { usePaymentMadeEntriesTableColumns } from './components';
|
||||
|
||||
import { usePaymentMadeFormContext } from './PaymentMadeFormProvider';
|
||||
import { compose, updateTableRow, safeSumBy } from 'utils';
|
||||
import withAlertActions from 'containers/Alert/withAlertActions';
|
||||
|
||||
/**
|
||||
* Payment made items table.
|
||||
*/
|
||||
export default function PaymentMadeItemsTable() {
|
||||
function PaymentMadeEntriesTable({
|
||||
onUpdateData,
|
||||
entries,
|
||||
|
||||
// #withAlertsActions
|
||||
openAlert
|
||||
}) {
|
||||
const {
|
||||
paymentVendorId,
|
||||
dueBills,
|
||||
isDueBillsFetching,
|
||||
isNewMode,
|
||||
} = usePaymentMadeFormContext();
|
||||
|
||||
const columns = usePaymentMadeEntriesTableColumns();
|
||||
|
||||
// Detarmines takes vendor payable bills entries in create mode
|
||||
// or payment made entries in edit mode.
|
||||
const computedTableEntries = useMemo(() => [], []);
|
||||
|
||||
// Triggers `onUpdateData` event that passes changed entries.
|
||||
const triggerUpdateData = useCallback((entries) => {}, []);
|
||||
|
||||
const triggerOnFetchBillsSuccess = useCallback((bills) => {}, []);
|
||||
|
||||
|
||||
// Handle update data.
|
||||
const handleUpdateData = useCallback((rows) => {}, []);
|
||||
const handleUpdateData = useCallback((rowIndex, columnId, value) => {
|
||||
const newRows = compose(
|
||||
updateTableRow(rowIndex, columnId, value),
|
||||
)(entries);
|
||||
|
||||
onUpdateData(newRows);
|
||||
}, [onUpdateData, entries]);
|
||||
|
||||
// Detarmines the right no results message before selecting vendor and aftering
|
||||
// selecting vendor id.
|
||||
@@ -41,13 +44,22 @@ export default function PaymentMadeItemsTable() {
|
||||
? 'There is no payable bills for this vendor that can be applied for this payment'
|
||||
: 'Please select a vendor to display all open bills for it.';
|
||||
|
||||
// Handle clear all lines action.
|
||||
const handleClearAllLines = () => {
|
||||
const fullAmount = safeSumBy(entries, 'payment_amount');
|
||||
|
||||
if (fullAmount > 0) {
|
||||
openAlert('clear-all-lines-payment-made');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<CloudLoadingIndicator isLoading={isDueBillsFetching}>
|
||||
<DataTableEditable
|
||||
progressBarLoading={isDueBillsFetching}
|
||||
className={classNames(CLASSES.DATATABLE_EDITOR_ITEMS_ENTRIES)}
|
||||
columns={columns}
|
||||
data={[]}
|
||||
data={entries}
|
||||
spinnerProps={false}
|
||||
payload={{
|
||||
errors: [],
|
||||
@@ -58,7 +70,7 @@ export default function PaymentMadeItemsTable() {
|
||||
<Button
|
||||
small={true}
|
||||
className={'button--secondary button--clear-lines'}
|
||||
// onClick={handleClickClearAllLines}
|
||||
onClick={handleClearAllLines}
|
||||
>
|
||||
<T id={'clear_all_lines'} />
|
||||
</Button>
|
||||
@@ -68,3 +80,7 @@ export default function PaymentMadeItemsTable() {
|
||||
</CloudLoadingIndicator>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withAlertActions
|
||||
)(PaymentMadeEntriesTable);
|
||||
@@ -2,7 +2,7 @@ import React, { useMemo } from 'react';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { sumBy, omit } from 'lodash';
|
||||
import { sumBy, pick } from 'lodash';
|
||||
import classNames from 'classnames';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
@@ -11,7 +11,8 @@ import { AppToaster } from 'components';
|
||||
import PaymentMadeHeader from './PaymentMadeFormHeader';
|
||||
import PaymentMadeFloatingActions from './PaymentMadeFloatingActions';
|
||||
import PaymentMadeFooter from './PaymentMadeFooter';
|
||||
import PaymentMadeItemsTable from './PaymentMadeItemsTable';
|
||||
import PaymentMadeFormBody from './PaymentMadeFormBody';
|
||||
import { PaymentMadeInnerProvider } from './PaymentMadeInnerProvider';
|
||||
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
import {
|
||||
@@ -32,7 +33,9 @@ function PaymentMadeForm() {
|
||||
// Payment made form context.
|
||||
const {
|
||||
isNewMode,
|
||||
paymentMade,
|
||||
paymentMadeId,
|
||||
paymentMadeEditPage,
|
||||
paymentEntriesEditPage,
|
||||
submitPayload,
|
||||
createPaymentMadeMutate,
|
||||
editPaymentMadeMutate,
|
||||
@@ -43,14 +46,14 @@ function PaymentMadeForm() {
|
||||
() => ({
|
||||
...(!isNewMode
|
||||
? {
|
||||
...transformToEditForm(paymentMade, []),
|
||||
...transformToEditForm(paymentMadeEditPage, paymentEntriesEditPage),
|
||||
}
|
||||
: {
|
||||
...defaultPaymentMade,
|
||||
entries: orderingLinesIndexes(defaultPaymentMade.entries),
|
||||
}),
|
||||
}),
|
||||
[isNewMode, paymentMade],
|
||||
[isNewMode, paymentMadeEditPage, paymentEntriesEditPage],
|
||||
);
|
||||
|
||||
// Handle the form submit.
|
||||
@@ -62,9 +65,9 @@ function PaymentMadeForm() {
|
||||
|
||||
// Filters entries that have no `bill_id` or `payment_amount`.
|
||||
const entries = values.entries
|
||||
.filter((item) => !item.bill_id || item.payment_amount)
|
||||
.filter((item) => item.bill_id && item.payment_amount)
|
||||
.map((entry) => ({
|
||||
...omit(entry, ['due_amount']),
|
||||
...pick(entry, ['payment_amount', 'bill_id']),
|
||||
}));
|
||||
// Total payment amount of entries.
|
||||
const totalPaymentAmount = sumBy(entries, 'payment_amount');
|
||||
@@ -96,7 +99,11 @@ function PaymentMadeForm() {
|
||||
submitPayload.resetForm && resetForm();
|
||||
};
|
||||
|
||||
const onError = ({ response: { error: { data: errors } } }) => {
|
||||
const onError = ({
|
||||
response: {
|
||||
error: { data: errors },
|
||||
},
|
||||
}) => {
|
||||
const getError = (errorType) => errors.find((e) => e.type === errorType);
|
||||
|
||||
if (getError(ERRORS.PAYMENT_NUMBER_NOT_UNIQUE)) {
|
||||
@@ -109,7 +116,7 @@ function PaymentMadeForm() {
|
||||
};
|
||||
|
||||
if (!isNewMode) {
|
||||
editPaymentMadeMutate([paymentMade.id, form])
|
||||
editPaymentMadeMutate([paymentMadeId, form])
|
||||
.then(onSaved)
|
||||
.catch(onError);
|
||||
} else {
|
||||
@@ -133,13 +140,12 @@ function PaymentMadeForm() {
|
||||
onSubmit={handleSubmitForm}
|
||||
>
|
||||
<Form>
|
||||
<PaymentMadeHeader />
|
||||
|
||||
<div className={classNames(CLASSES.PAGE_FORM_BODY)}>
|
||||
<PaymentMadeItemsTable />
|
||||
</div>
|
||||
<PaymentMadeFooter />
|
||||
<PaymentMadeFloatingActions />
|
||||
<PaymentMadeInnerProvider>
|
||||
<PaymentMadeHeader />
|
||||
<PaymentMadeFormBody />
|
||||
<PaymentMadeFooter />
|
||||
<PaymentMadeFloatingActions />
|
||||
</PaymentMadeInnerProvider>
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { FastField } from 'formik';
|
||||
import classNames from 'classnames';
|
||||
import { CLASSES } from 'common/classes';
|
||||
import PaymentMadeEntriesTable from './PaymentMadeEntriesTable';
|
||||
|
||||
export default function PaymentMadeFormBody() {
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_BODY)}>
|
||||
<FastField name={'entries'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
<PaymentMadeEntriesTable
|
||||
entries={value}
|
||||
onUpdateData={(newEntries) => {
|
||||
form.setFieldValue('entries', newEntries);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -18,10 +18,10 @@ function PaymentMadeFormHeader({
|
||||
baseCurrency,
|
||||
}) {
|
||||
// Formik form context.
|
||||
const { values } = useFormikContext();
|
||||
const { values: { entries } } = useFormikContext();
|
||||
|
||||
// Calculate the payment amount of the entries.
|
||||
const amountPaid = useMemo(() => sumBy(values, 'payment_amount'), [values]);
|
||||
const amountPaid = useMemo(() => sumBy(entries, 'payment_amount'), [entries]);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import {
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
Position,
|
||||
Classes,
|
||||
ControlGroup,
|
||||
Button
|
||||
} from '@blueprintjs/core';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { FastField } from 'formik';
|
||||
import { FastField, Field, useFormikContext, ErrorMessage } from 'formik';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { toSafeInteger } from 'lodash';
|
||||
import classNames from 'classnames';
|
||||
import { CLASSES } from 'common/classes';
|
||||
import {
|
||||
AccountsSelectList,
|
||||
ContactSelecetList,
|
||||
ErrorMessage,
|
||||
FieldRequiredHint,
|
||||
InputPrependText,
|
||||
Money,
|
||||
Hint,
|
||||
Icon,
|
||||
MoneyInputGroup
|
||||
} from 'components';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
import { usePaymentMadeFormContext } from './PaymentMadeFormProvider';
|
||||
@@ -28,20 +30,43 @@ import {
|
||||
tansformDateValue,
|
||||
inputIntent,
|
||||
compose,
|
||||
safeSumBy,
|
||||
fullAmountPaymentEntries,
|
||||
amountPaymentEntries,
|
||||
} from 'utils';
|
||||
|
||||
/**
|
||||
* Payment made form header fields.
|
||||
*/
|
||||
function PaymentMadeFormHeaderFields({ baseCurrency }) {
|
||||
// Formik form context.
|
||||
const { values: { entries }, setFieldValue } = useFormikContext();
|
||||
|
||||
// Payment made form context.
|
||||
const {
|
||||
vendors,
|
||||
accounts,
|
||||
isNewMode,
|
||||
setPaymentVendorId,
|
||||
} = usePaymentMadeFormContext();
|
||||
|
||||
// Sumation of payable full-amount.
|
||||
const payableFullAmount = useMemo(() => safeSumBy(entries, 'due_amount'), [entries]);
|
||||
|
||||
// Handle receive full-amount click.
|
||||
const handleReceiveFullAmountClick = () => {
|
||||
const newEntries = fullAmountPaymentEntries(entries);
|
||||
const fullAmount = safeSumBy(newEntries, 'payment_amount');
|
||||
|
||||
const payableFullAmount = 0;
|
||||
setFieldValue('entries', newEntries);
|
||||
setFieldValue('full_amount', fullAmount);
|
||||
};
|
||||
|
||||
// Handles the full-amount field blur.
|
||||
const onFullAmountBlur = (value) => {
|
||||
const newEntries = amountPaymentEntries(toSafeInteger(value), entries);
|
||||
setFieldValue('entries', newEntries);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||
@@ -96,8 +121,8 @@ function PaymentMadeFormHeaderFields({ baseCurrency }) {
|
||||
</FastField>
|
||||
|
||||
{/* ------------ Full amount ------------ */}
|
||||
<FastField name={'full_amount'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<Field name={'full_amount'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'full_amount'} />}
|
||||
inline={true}
|
||||
@@ -108,24 +133,27 @@ function PaymentMadeFormHeaderFields({ baseCurrency }) {
|
||||
>
|
||||
<ControlGroup>
|
||||
<InputPrependText text={baseCurrency} />
|
||||
<InputGroup
|
||||
intent={inputIntent({ error, touched })}
|
||||
minimal={true}
|
||||
{...field}
|
||||
<MoneyInputGroup
|
||||
value={value}
|
||||
onChange={(value) => {
|
||||
setFieldValue('full_amount', value);
|
||||
}}
|
||||
onBlurValue={onFullAmountBlur}
|
||||
/>
|
||||
</ControlGroup>
|
||||
|
||||
<a
|
||||
// onClick={handleReceiveFullAmountClick}
|
||||
href="#"
|
||||
<Button
|
||||
onClick={handleReceiveFullAmountClick}
|
||||
className={'receive-full-amount'}
|
||||
small={true}
|
||||
minimal={true}
|
||||
>
|
||||
Receive full amount (
|
||||
<Money amount={payableFullAmount} currency={baseCurrency} />)
|
||||
</a>
|
||||
</Button>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
</Field>
|
||||
|
||||
{/* ------------ Payment number ------------ */}
|
||||
<FastField name={'payment_number'}>
|
||||
|
||||
@@ -3,11 +3,10 @@ import {
|
||||
useAccounts,
|
||||
useVendors,
|
||||
useItems,
|
||||
usePaymentMade,
|
||||
usePaymentMadeEditPage,
|
||||
useSettings,
|
||||
useCreatePaymentMade,
|
||||
useEditPaymentMade,
|
||||
useDueBills,
|
||||
} from 'hooks/query';
|
||||
import { DashboardInsider } from 'components';
|
||||
|
||||
@@ -39,20 +38,13 @@ function PaymentMadeFormProvider({ paymentMadeId, ...props }) {
|
||||
|
||||
// Handle fetch specific payment made details.
|
||||
const {
|
||||
data: { paymentMade, payableBills, paymentBills },
|
||||
data: { paymentMade: paymentMadeEditPage, entries: paymentEntriesEditPage },
|
||||
isFetching: isPaymentFetching,
|
||||
isLoading: isPaymentLoading,
|
||||
} = usePaymentMade(paymentMadeId, {
|
||||
} = usePaymentMadeEditPage(paymentMadeId, {
|
||||
enabled: !!paymentMadeId,
|
||||
});
|
||||
|
||||
// Retrieve the due bills of the given vendor.
|
||||
const {
|
||||
data: dueBills,
|
||||
isLoading: isDueBillsLoading,
|
||||
isFetching: isDueBillsFetching,
|
||||
} = useDueBills(paymentVendorId, { enabled: !!paymentVendorId });
|
||||
|
||||
// Fetch payment made settings.
|
||||
useSettings();
|
||||
|
||||
@@ -66,12 +58,10 @@ function PaymentMadeFormProvider({ paymentMadeId, ...props }) {
|
||||
const provider = {
|
||||
paymentMadeId,
|
||||
accounts,
|
||||
paymentMade,
|
||||
payableBills,
|
||||
paymentBills,
|
||||
paymentEntriesEditPage,
|
||||
paymentMadeEditPage,
|
||||
vendors,
|
||||
items,
|
||||
dueBills,
|
||||
submitPayload,
|
||||
paymentVendorId,
|
||||
|
||||
@@ -82,8 +72,6 @@ function PaymentMadeFormProvider({ paymentMadeId, ...props }) {
|
||||
isVendorsFetching,
|
||||
isPaymentFetching,
|
||||
isPaymentLoading,
|
||||
isDueBillsLoading,
|
||||
isDueBillsFetching,
|
||||
|
||||
createPaymentMadeMutate,
|
||||
editPaymentMadeMutate,
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { useFormikContext } from 'formik';
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, { createContext, useContext, useEffect } from 'react';
|
||||
import { usePaymentMadeNewPageEntries } from 'hooks/query';
|
||||
import { usePaymentMadeFormContext } from './PaymentMadeFormProvider';
|
||||
|
||||
const PaymentMadeInnerContext = createContext();
|
||||
|
||||
/**
|
||||
* Payment made inner form provider.
|
||||
*/
|
||||
function PaymentMadeInnerProvider({ ...props }) {
|
||||
const { isNewMode } = usePaymentMadeFormContext();
|
||||
|
||||
// Formik context.
|
||||
const {
|
||||
values: { vendor_id: vendorId },
|
||||
setFieldValue,
|
||||
} = useFormikContext();
|
||||
|
||||
const {
|
||||
data: newPageEntries,
|
||||
isLoading: isNewEntriesLoading,
|
||||
isFetching: isNewEntriesFetching,
|
||||
} = usePaymentMadeNewPageEntries(vendorId, {
|
||||
enabled: !!vendorId && isNewMode,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!isNewEntriesFetching && !isEmpty(newPageEntries)) {
|
||||
setFieldValue('entries', newPageEntries)
|
||||
}
|
||||
}, [isNewEntriesFetching, newPageEntries, setFieldValue]);
|
||||
|
||||
// Provider payload.
|
||||
const provider = {
|
||||
newPageEntries,
|
||||
isNewEntriesLoading,
|
||||
isNewEntriesFetching
|
||||
};
|
||||
|
||||
return <PaymentMadeInnerContext.Provider value={provider} {...props} />;
|
||||
}
|
||||
|
||||
const usePaymentMadeInnerContext = () => useContext(PaymentMadeInnerContext);
|
||||
|
||||
export { PaymentMadeInnerProvider, usePaymentMadeInnerContext };
|
||||
@@ -3,16 +3,17 @@ import { useIntl } from "react-intl";
|
||||
import moment from 'moment';
|
||||
import { Money } from 'components';
|
||||
import { safeSumBy, formattedAmount } from 'utils';
|
||||
import { MoneyFieldCell } from 'components/DataTableCells';
|
||||
|
||||
function BillNumberAccessor(row) {
|
||||
return `#${row?.bill_number || ''}`
|
||||
return row?.bill_no ? row?.bill_no : '-';
|
||||
}
|
||||
|
||||
function IndexTableCell({ row: { index } }) {
|
||||
return (<span>{index + 1}</span>);
|
||||
}
|
||||
|
||||
function BillDateTableCell({ value }) {
|
||||
function BillDateCell({ value }) {
|
||||
return moment(value).format('YYYY MMM DD');
|
||||
}
|
||||
/**
|
||||
@@ -39,6 +40,14 @@ function PaymentAmountFooterCell({ rows }) {
|
||||
return <span>{ formattedAmount(totalPaymentAmount, 'USD') }</span>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mobey table cell.
|
||||
*/
|
||||
function MoneyTableCell({ value }) {
|
||||
return <Money amount={value} currency={"USD"} />
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Payment made entries table columns
|
||||
*/
|
||||
@@ -54,13 +63,15 @@ export function usePaymentMadeEntriesTableColumns() {
|
||||
width: 40,
|
||||
disableResizing: true,
|
||||
disableSortBy: true,
|
||||
className: 'index'
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'Date' }),
|
||||
id: 'bill_date',
|
||||
accessor: 'bill_date',
|
||||
Cell: BillDateTableCell,
|
||||
Cell: BillDateCell,
|
||||
disableSortBy: true,
|
||||
width: 250,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'bill_number' }),
|
||||
@@ -71,6 +82,7 @@ export function usePaymentMadeEntriesTableColumns() {
|
||||
{
|
||||
Header: formatMessage({ id: 'bill_amount' }),
|
||||
accessor: 'amount',
|
||||
Cell: MoneyTableCell,
|
||||
Footer: AmountFooterCell,
|
||||
disableSortBy: true,
|
||||
className: '',
|
||||
@@ -78,6 +90,7 @@ export function usePaymentMadeEntriesTableColumns() {
|
||||
{
|
||||
Header: formatMessage({ id: 'amount_due' }),
|
||||
accessor: 'due_amount',
|
||||
Cell: MoneyTableCell,
|
||||
Footer: DueAmountFooterCell,
|
||||
disableSortBy: true,
|
||||
className: '',
|
||||
@@ -85,6 +98,7 @@ export function usePaymentMadeEntriesTableColumns() {
|
||||
{
|
||||
Header: formatMessage({ id: 'payment_amount' }),
|
||||
accessor: 'payment_amount',
|
||||
Cell: MoneyFieldCell,
|
||||
Footer: PaymentAmountFooterCell,
|
||||
disableSortBy: true,
|
||||
className: '',
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import moment from 'moment';
|
||||
import { sumBy } from 'lodash';
|
||||
import { transformToForm } from 'utils';
|
||||
import { safeSumBy, transformToForm } from 'utils';
|
||||
|
||||
export const ERRORS = {
|
||||
PAYMENT_NUMBER_NOT_UNIQUE: 'PAYMENT.NUMBER.NOT.UNIQUE',
|
||||
PAYMENT_NUMBER_NOT_UNIQUE: 'PAYMENT.NUMBER.NOT.UNIQUE',
|
||||
};
|
||||
|
||||
|
||||
// Default payment made entry values.
|
||||
export const defaultPaymentMadeEntry = {
|
||||
bill_id: '',
|
||||
@@ -30,7 +28,7 @@ export const defaultPaymentMade = {
|
||||
export const transformToEditForm = (paymentMade, paymentMadeEntries) => {
|
||||
return {
|
||||
...transformToForm(paymentMade, defaultPaymentMade),
|
||||
full_amount: sumBy(paymentMade.entries, 'payment_amount'),
|
||||
full_amount: safeSumBy(paymentMadeEntries, 'payment_amount'),
|
||||
entries: [
|
||||
...paymentMadeEntries.map((paymentMadeEntry) => ({
|
||||
...transformToForm(paymentMadeEntry, defaultPaymentMadeEntry),
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import 'style/pages/PaymentMade/List.scss';
|
||||
|
||||
import { DashboardContentTable, DashboardPageContent } from 'components';
|
||||
import PaymentMadeActionsBar from './PaymentMadeActionsBar';
|
||||
import PaymentMadesAlerts from '../PaymentMadesAlerts';
|
||||
|
||||
@@ -27,7 +27,7 @@ export function usePaymentMades(query, props) {
|
||||
data: defaultTo(states.data, {
|
||||
paymentMades: [],
|
||||
pagination: {},
|
||||
filterMeta: {}
|
||||
filterMeta: {},
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -42,8 +42,9 @@ export function useCreatePaymentMade(props) {
|
||||
return useMutation(
|
||||
(values) => apiRequest.post('purchases/bill_payments', values),
|
||||
{
|
||||
onSuccess: () => {
|
||||
onSuccess: (res, values) => {
|
||||
client.invalidateQueries('PAYMENT_MADES');
|
||||
client.invalidateQueries(['PAYMENT_MADE_NEW_PAGE_ENTRIES', values.vendor_id]);
|
||||
},
|
||||
...props,
|
||||
},
|
||||
@@ -63,6 +64,8 @@ export function useEditPaymentMade(props) {
|
||||
onSuccess: (res, [id, values]) => {
|
||||
client.invalidateQueries('PAYMENT_MADES');
|
||||
client.invalidateQueries(['PAYMENT_MADE', id]);
|
||||
|
||||
client.invalidateQueries(['PAYMENT_MADE_NEW_PAGE_ENTRIES', values.vendor_id]);
|
||||
},
|
||||
...props,
|
||||
},
|
||||
@@ -82,6 +85,7 @@ export function useDeletePaymentMade(props) {
|
||||
onSuccess: (res, id) => {
|
||||
client.invalidateQueries('PAYMENT_MADES');
|
||||
client.invalidateQueries(['PAYMENT_MADE', id]);
|
||||
|
||||
},
|
||||
...props,
|
||||
},
|
||||
@@ -91,17 +95,16 @@ export function useDeletePaymentMade(props) {
|
||||
/**
|
||||
* Retrieve specific payment made.
|
||||
*/
|
||||
export function usePaymentMade(id, props) {
|
||||
export function usePaymentMadeEditPage(id, props) {
|
||||
const apiRequest = useApiRequest();
|
||||
|
||||
const states = useQuery(
|
||||
['PAYMENT_MADE', id],
|
||||
() => apiRequest.get(`purchases/bill_payments/${id}`),
|
||||
() => apiRequest.get(`purchases/bill_payments/${id}/edit-page`),
|
||||
{
|
||||
select: res => ({
|
||||
select: (res) => ({
|
||||
paymentMade: res.data.bill_payment,
|
||||
payableBills: res.data.payable_bills,
|
||||
paymentBills: res.data.payment_bills,
|
||||
entries: res.data.entries,
|
||||
}),
|
||||
...props,
|
||||
},
|
||||
@@ -112,3 +115,23 @@ export function usePaymentMade(id, props) {
|
||||
data: defaultTo(states.data, {}),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreive payment made new page entries.
|
||||
* @param {number} vendorId -
|
||||
*/
|
||||
export function usePaymentMadeNewPageEntries(vendorId, props) {
|
||||
const apiRequest = useApiRequest();
|
||||
|
||||
return useQuery(
|
||||
['PAYMENT_MADE_NEW_PAGE_ENTRIES', vendorId],
|
||||
() =>
|
||||
apiRequest.get(`purchases/bill_payments/new-page/entries`, {
|
||||
params: { vendor_id: vendorId },
|
||||
}),
|
||||
{
|
||||
select: (res) => res.data.entries,
|
||||
...props,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function useApiRequest() {
|
||||
const locale = 'en';
|
||||
|
||||
if (token) {
|
||||
request.headers.common['x-access-token'] = token;
|
||||
request.headers.common['X-Access-Token'] = token;
|
||||
}
|
||||
if (organizationId) {
|
||||
request.headers.common['organization-id'] = organizationId;
|
||||
|
||||
18
client/src/style/pages/Bills/List.scss
Normal file
18
client/src/style/pages/Bills/List.scss
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
.dashboard__insider--bills{
|
||||
|
||||
.bigcapital-datatable{
|
||||
|
||||
.tbody{
|
||||
|
||||
.td.amount {
|
||||
|
||||
.cell-inner{
|
||||
> span{
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
client/src/style/pages/PaymentMade/List.scss
Normal file
18
client/src/style/pages/PaymentMade/List.scss
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
.dashboard__insider--payment-mades-list{
|
||||
|
||||
.bigcapital-datatable{
|
||||
|
||||
.tbody{
|
||||
|
||||
.td.amount {
|
||||
|
||||
.cell-inner{
|
||||
> span{
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,18 @@
|
||||
&.bp3-inline{
|
||||
max-width: 470px;
|
||||
}
|
||||
a.receive-full-amount{
|
||||
button.receive-full-amount{
|
||||
width: auto;
|
||||
padding: 0;
|
||||
min-height: auto;
|
||||
font-size: 12px;
|
||||
margin-top: 6px;
|
||||
display: inline-block;
|
||||
margin-top: 4px;
|
||||
background-color: transparent;
|
||||
color: #0052cc;
|
||||
|
||||
&:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,4 +576,28 @@ export function safeSumBy(entries, getter) {
|
||||
.map(row => toSafeNumber(_.get(row, getter)))
|
||||
.sum()
|
||||
.value();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const fullAmountPaymentEntries = (entries) => {
|
||||
return entries.map((item) => ({
|
||||
...item,
|
||||
payment_amount: item.due_amount,
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
export const amountPaymentEntries = (amount, entries) => {
|
||||
let total = amount;
|
||||
|
||||
return entries.map((item) => {
|
||||
const diff = Math.min(item.due_amount, total);
|
||||
total -= Math.max(diff, 0);
|
||||
|
||||
return {
|
||||
...item,
|
||||
payment_amount: diff,
|
||||
};
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user