mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
feat: add status & opened alert in credit & vendor.
This commit is contained in:
@@ -26,35 +26,40 @@ export default function CreditNoteFloatingActions() {
|
||||
const { resetForm, submitForm, isSubmitting } = useFormikContext();
|
||||
|
||||
// Credit note form context.
|
||||
const { setSubmitPayload, isNewMode } = useCreditNoteFormContext();
|
||||
const { setSubmitPayload, creditNote } = useCreditNoteFormContext();
|
||||
|
||||
// Handle submit, save and anothe new button click.
|
||||
const handleSubmitAndNewBtnClick = (event) => {
|
||||
setSubmitPayload({ redirect: false, status: true, resetForm: true });
|
||||
// Handle submit as open button click.
|
||||
const handleSubmitOpenBtnClick = (event) => {
|
||||
setSubmitPayload({ redirect: true, open: true });
|
||||
submitForm();
|
||||
};
|
||||
|
||||
// Handle submit as save & continue editing button click.
|
||||
const handleSubmitSaveContinueEditingBtnClick = (event) => {
|
||||
setSubmitPayload({ redirect: false, status: true });
|
||||
// Handle submit, open and anothe new button click.
|
||||
const handleSubmitOpenAndNewBtnClick = (event) => {
|
||||
setSubmitPayload({ redirect: false, open: true, resetForm: true });
|
||||
submitForm();
|
||||
};
|
||||
|
||||
// Handle submit as open & continue editing button click.
|
||||
const handleSubmitOpenContinueEditingBtnClick = (event) => {
|
||||
setSubmitPayload({ redirect: false, open: true });
|
||||
submitForm();
|
||||
};
|
||||
// Handle submit as draft button click.
|
||||
const handleSubmitDraftBtnClick = (event) => {
|
||||
setSubmitPayload({ redirect: true, status: false });
|
||||
setSubmitPayload({ redirect: true, open: false });
|
||||
submitForm();
|
||||
};
|
||||
|
||||
// handle submit as draft & new button click.
|
||||
const handleSubmitDraftAndNewBtnClick = (event) => {
|
||||
setSubmitPayload({ redirect: false, status: false, resetForm: true });
|
||||
setSubmitPayload({ redirect: false, open: false, resetForm: true });
|
||||
submitForm();
|
||||
};
|
||||
|
||||
// Handle submit as draft & continue editing button click.
|
||||
const handleSubmitDraftContinueEditingBtnClick = (event) => {
|
||||
setSubmitPayload({ redirect: false, status: false });
|
||||
setSubmitPayload({ redirect: false, open: false });
|
||||
submitForm();
|
||||
};
|
||||
|
||||
@@ -63,89 +68,114 @@ export default function CreditNoteFloatingActions() {
|
||||
history.goBack();
|
||||
};
|
||||
|
||||
// Handle submit button click.
|
||||
const handleSubmitBtnClick = (event) => {
|
||||
setSubmitPayload({ redirect: true });
|
||||
submitForm();
|
||||
};
|
||||
|
||||
const handleClearBtnClick = (event) => {
|
||||
resetForm();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_FLOATING_ACTIONS)}>
|
||||
{/* ----------- Save ----------- */}
|
||||
<ButtonGroup>
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
loading={isSubmitting}
|
||||
intent={Intent.PRIMARY}
|
||||
onClick={handleSubmitBtnClick}
|
||||
text={<T id={'save'} />}
|
||||
/>
|
||||
|
||||
<Popover
|
||||
content={
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={<T id={'save_and_new'} />}
|
||||
onClick={handleSubmitAndNewBtnClick}
|
||||
/>
|
||||
<MenuItem
|
||||
text={<T id={'save_continue_editing'} />}
|
||||
onClick={handleSubmitSaveContinueEditingBtnClick}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
minimal={true}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
position={Position.BOTTOM_LEFT}
|
||||
>
|
||||
{/* ----------- Save And Open ----------- */}
|
||||
<If condition={!creditNote || !creditNote?.is_open}>
|
||||
<ButtonGroup>
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
loading={isSubmitting}
|
||||
intent={Intent.PRIMARY}
|
||||
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
|
||||
onClick={handleSubmitOpenBtnClick}
|
||||
text={<T id={'save_open'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</ButtonGroup>
|
||||
{/* ----------- Save As Draft ----------- */}
|
||||
<ButtonGroup>
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
className={'ml1'}
|
||||
onClick={handleSubmitDraftBtnClick}
|
||||
text={<T id={'save_as_draft'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={<T id={'save_and_new'} />}
|
||||
onClick={handleSubmitDraftAndNewBtnClick}
|
||||
/>
|
||||
<MenuItem
|
||||
text={<T id={'save_continue_editing'} />}
|
||||
onClick={handleSubmitDraftContinueEditingBtnClick}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
minimal={true}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
position={Position.BOTTOM_LEFT}
|
||||
>
|
||||
<Popover
|
||||
content={
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={<T id={'open_and_new'} />}
|
||||
onClick={handleSubmitOpenAndNewBtnClick}
|
||||
/>
|
||||
<MenuItem
|
||||
text={<T id={'open_continue_editing'} />}
|
||||
onClick={handleSubmitOpenContinueEditingBtnClick}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
minimal={true}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
position={Position.BOTTOM_LEFT}
|
||||
>
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
intent={Intent.PRIMARY}
|
||||
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
|
||||
/>
|
||||
</Popover>
|
||||
</ButtonGroup>
|
||||
{/* ----------- Save As Draft ----------- */}
|
||||
<ButtonGroup>
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
|
||||
className={'ml1'}
|
||||
onClick={handleSubmitDraftBtnClick}
|
||||
text={<T id={'save_as_draft'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</ButtonGroup>
|
||||
<Popover
|
||||
content={
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={<T id={'save_and_new'} />}
|
||||
onClick={handleSubmitDraftAndNewBtnClick}
|
||||
/>
|
||||
<MenuItem
|
||||
text={<T id={'save_continue_editing'} />}
|
||||
onClick={handleSubmitDraftContinueEditingBtnClick}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
minimal={true}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
position={Position.BOTTOM_LEFT}
|
||||
>
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
|
||||
/>
|
||||
</Popover>
|
||||
</ButtonGroup>
|
||||
</If>
|
||||
{/* ----------- Save and New ----------- */}
|
||||
<If condition={creditNote && creditNote?.is_open}>
|
||||
<ButtonGroup>
|
||||
<Button
|
||||
loading={isSubmitting}
|
||||
intent={Intent.PRIMARY}
|
||||
onClick={handleSubmitOpenBtnClick}
|
||||
text={<T id={'save'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={<T id={'save_and_new'} />}
|
||||
onClick={handleSubmitOpenAndNewBtnClick}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
minimal={true}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
position={Position.BOTTOM_LEFT}
|
||||
>
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
intent={Intent.PRIMARY}
|
||||
rightIcon={<Icon icon="arrow-drop-up-16" iconSize={20} />}
|
||||
/>
|
||||
</Popover>
|
||||
</ButtonGroup>
|
||||
</If>
|
||||
{/* ----------- Clear & Reset----------- */}
|
||||
<Button
|
||||
className={'ml1'}
|
||||
disabled={isSubmitting}
|
||||
onClick={handleClearBtnClick}
|
||||
text={isNewMode ? <T id={'reset'} /> : <T id={'clear'} />}
|
||||
text={creditNote ? <T id={'reset'} /> : <T id={'clear'} />}
|
||||
/>
|
||||
{/* ----------- Cancel ----------- */}
|
||||
<Button
|
||||
|
||||
@@ -97,6 +97,7 @@ function CreditNoteForm({
|
||||
}
|
||||
const form = {
|
||||
...transformFormValuesToRequest(values),
|
||||
open: submitPayload.open,
|
||||
};
|
||||
// Handle the request success.
|
||||
const onSuccess = (response) => {
|
||||
|
||||
@@ -16,6 +16,7 @@ const getSchema = () =>
|
||||
.min(1)
|
||||
.max(DATATYPES_LENGTH.TEXT)
|
||||
.label(intl.get('note')),
|
||||
open: Yup.boolean(),
|
||||
terms_conditions: Yup.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
|
||||
@@ -35,6 +35,7 @@ export const defaultCreditNote = {
|
||||
credit_note_date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
credit_note_number: '',
|
||||
credit_note_no_manually: false,
|
||||
open: '',
|
||||
// reference_no: '',
|
||||
note: '',
|
||||
terms_conditions: '',
|
||||
@@ -82,19 +83,20 @@ export const transformEntriesToSubmit = (entries) => {
|
||||
/**
|
||||
* Filters the givne non-zero entries.
|
||||
*/
|
||||
export const filterNonZeroEntries = (entries) => {
|
||||
export const filterNonZeroEntries = (entries) => {
|
||||
return entries.filter((item) => item.item_id && item.quantity);
|
||||
};
|
||||
|
||||
/**
|
||||
* Transformes form values to request body.
|
||||
*/
|
||||
export const transformFormValuesToRequest = (values) => {
|
||||
export const transformFormValuesToRequest = (values) => {
|
||||
const entries = filterNonZeroEntries(values.entries);
|
||||
|
||||
return {
|
||||
...values,
|
||||
entries: transformEntriesToSubmit(entries),
|
||||
open: false,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -121,7 +123,7 @@ export const entriesFieldShouldUpdate = (newProps, oldProps) => {
|
||||
/**
|
||||
* Syncs invoice no. settings with form.
|
||||
*/
|
||||
export const useObserveCreditNoSettings = (prefix, nextNumber) => {
|
||||
export const useObserveCreditNoSettings = (prefix, nextNumber) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
React.useEffect(() => {
|
||||
|
||||
@@ -8,6 +8,10 @@ const RefundCreditNoteDeleteAlert = React.lazy(() =>
|
||||
import('../../Alerts/CreditNotes/RefundCreditNoteDeleteAlert'),
|
||||
);
|
||||
|
||||
const OpenCreditNoteAlert = React.lazy(() =>
|
||||
import('../../Alerts/CreditNotes/CreditNoteOpenedAlert'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Credit notes alerts.
|
||||
*/
|
||||
@@ -16,6 +20,10 @@ export default [
|
||||
name: 'credit-note-delete',
|
||||
component: CreditNoteDeleteAlert,
|
||||
},
|
||||
{
|
||||
name: 'credit-note-open',
|
||||
component: OpenCreditNoteAlert,
|
||||
},
|
||||
{
|
||||
name: 'refund-credit-delete',
|
||||
component: RefundCreditNoteDeleteAlert,
|
||||
|
||||
@@ -100,6 +100,11 @@ function CreditNotesDataTable({
|
||||
openDialog('refund-credit-note', { creditNoteId: id });
|
||||
};
|
||||
|
||||
// Handle cancel/confirm crdit note open.
|
||||
const handleOpenCreditNote = ({ id }) => {
|
||||
openAlert('credit-note-open', { creditNoteId: id });
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardContentTable>
|
||||
<DataTable
|
||||
@@ -126,6 +131,7 @@ function CreditNotesDataTable({
|
||||
onDelete: handleDeleteCreditNote,
|
||||
onEdit: hanldeEditCreditNote,
|
||||
onRefund: handleRefundCreditNote,
|
||||
onOpen: handleOpenCreditNote,
|
||||
}}
|
||||
/>
|
||||
</DashboardContentTable>
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Intent,
|
||||
Tag,
|
||||
Menu,
|
||||
MenuItem,
|
||||
MenuDivider,
|
||||
ProgressBar,
|
||||
} from '@blueprintjs/core';
|
||||
import { Intent, Tag, Menu, MenuItem, MenuDivider } from '@blueprintjs/core';
|
||||
import intl from 'react-intl-universal';
|
||||
import clsx from 'classnames';
|
||||
|
||||
@@ -14,15 +7,14 @@ import { CLASSES } from '../../../../common/classes';
|
||||
import {
|
||||
FormatDateCell,
|
||||
FormattedMessage as T,
|
||||
AppToaster,
|
||||
Choose,
|
||||
If,
|
||||
Icon,
|
||||
} from 'components';
|
||||
import { formattedAmount, safeCallback, calculateStatus } from 'utils';
|
||||
import { safeCallback } from 'utils';
|
||||
|
||||
export function ActionsMenu({
|
||||
payload: { onEdit, onDelete, onRefund, onViewDetails },
|
||||
payload: { onEdit, onDelete, onRefund, onOpen, onViewDetails },
|
||||
row: { original },
|
||||
}) {
|
||||
return (
|
||||
@@ -38,11 +30,21 @@ export function ActionsMenu({
|
||||
text={intl.get('credit_note.action.edit_credit_note')}
|
||||
onClick={safeCallback(onEdit, original)}
|
||||
/>
|
||||
<MenuItem
|
||||
icon={<Icon icon="quick-payment-16" />}
|
||||
text={intl.get('credit_note.action.refund_credit_note')}
|
||||
onClick={safeCallback(onRefund, original)}
|
||||
/>
|
||||
<If condition={!original.is_closed && !original.is_draft}>
|
||||
<MenuItem
|
||||
icon={<Icon icon="quick-payment-16" />}
|
||||
text={intl.get('credit_note.action.refund_credit_note')}
|
||||
onClick={safeCallback(onRefund, original)}
|
||||
/>
|
||||
</If>
|
||||
<If condition={original.is_draft}>
|
||||
<MenuItem
|
||||
icon={<Icon icon={'check'} iconSize={18} />}
|
||||
text={intl.get('mark_as_opened')}
|
||||
onClick={safeCallback(onOpen, original)}
|
||||
/>
|
||||
</If>
|
||||
|
||||
<MenuItem
|
||||
text={intl.get('credit_note.action.delete_credit_note')}
|
||||
intent={Intent.DANGER}
|
||||
@@ -53,6 +55,35 @@ export function ActionsMenu({
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Status accessor.
|
||||
*/
|
||||
export function StatusAccessor(creditNote) {
|
||||
return (
|
||||
<div>
|
||||
<Choose>
|
||||
<Choose.When condition={creditNote.is_open}>
|
||||
<Tag minimal={true} intent={Intent.WARNING}>
|
||||
<T id={'open'} />
|
||||
</Tag>
|
||||
</Choose.When>
|
||||
|
||||
<Choose.When condition={creditNote.is_closed}>
|
||||
<Tag minimal={true} intent={Intent.SUCCESS}>
|
||||
<T id={'closed'} />
|
||||
</Tag>
|
||||
</Choose.When>
|
||||
|
||||
<Choose.When condition={creditNote.is_draft}>
|
||||
<Tag minimal={true}>
|
||||
<T id={'draft'} />
|
||||
</Tag>
|
||||
</Choose.When>
|
||||
</Choose>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve credit note table columns.
|
||||
*/
|
||||
@@ -100,8 +131,8 @@ export function useCreditNoteTableColumns() {
|
||||
{
|
||||
id: 'status',
|
||||
Header: intl.get('status'),
|
||||
// accessor:
|
||||
width: 120, // 160
|
||||
accessor: StatusAccessor,
|
||||
width: 160, // 160
|
||||
className: 'status',
|
||||
clickable: true,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user