Merge pull request #361 from ANasouf/BIG-111-add-Convert-to-invoice-button-on-estimate-drawer-toolbar

Big 111 add convert to invoice button on estimate drawer toolbar
This commit is contained in:
Ahmed Bouhuolia
2024-02-26 15:32:19 +02:00
committed by GitHub
5 changed files with 58 additions and 5 deletions

View File

@@ -14,14 +14,18 @@ import { useEstimateDetailDrawerContext } from './EstimateDetailDrawerProvider';
import withDialogActions from '@/containers/Dialog/withDialogActions'; import withDialogActions from '@/containers/Dialog/withDialogActions';
import withAlertsActions from '@/containers/Alert/withAlertActions'; import withAlertsActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions'; import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { SaleEstimateAction, AbilitySubject } from '@/constants/abilityOption'; import {
SaleEstimateAction,
AbilitySubject,
SaleInvoiceAction,
} from '@/constants/abilityOption';
import { EstimateMoreMenuItems } from './components'; import { EstimateMoreMenuItems } from './components';
import { import {
DrawerActionsBar, DrawerActionsBar,
Icon, Icon,
FormattedMessage as T, FormattedMessage as T,
Can, Can,
Choose, If,
} from '@/components'; } from '@/components';
import { compose } from '@/utils'; import { compose } from '@/utils';
@@ -42,7 +46,7 @@ function EstimateDetailActionsBar({
closeDrawer, closeDrawer,
}) { }) {
// Estimate details drawer context. // Estimate details drawer context.
const { estimateId } = useEstimateDetailDrawerContext(); const { estimateId, estimate } = useEstimateDetailDrawerContext();
// History. // History.
const history = useHistory(); const history = useHistory();
@@ -52,6 +56,15 @@ function EstimateDetailActionsBar({
history.push(`/estimates/${estimateId}/edit`); history.push(`/estimates/${estimateId}/edit`);
closeDrawer(DRAWERS.ESTIMATE_DETAILS); closeDrawer(DRAWERS.ESTIMATE_DETAILS);
}; };
// Handle convert to invoice.
const handleConvertEstimate = () => {
history.push(`/invoices/new?from_estimate_id=${estimateId}`, {
action: estimateId,
});
closeDrawer(DRAWERS.ESTIMATE_DETAILS);
};
// Handle delete sale estimate. // Handle delete sale estimate.
const handleDeleteEstimate = () => { const handleDeleteEstimate = () => {
openAlert('estimate-delete', { estimateId }); openAlert('estimate-delete', { estimateId });
@@ -82,7 +95,18 @@ function EstimateDetailActionsBar({
/> />
<NavbarDivider /> <NavbarDivider />
</Can> </Can>
<Can I={SaleInvoiceAction.Create} a={AbilitySubject.Invoice}>
<If condition={!estimate.is_converted_to_invoice}>
<Button
className={Classes.MINIMAL}
intent={Intent.SUCCESS}
icon={<Icon icon="tick" />}
text={<T id={'convert_to_invoice'} />}
onClick={handleConvertEstimate}
/>
<NavbarDivider />
</If>
</Can>
<Can I={SaleEstimateAction.View} a={AbilitySubject.Estimate}> <Can I={SaleEstimateAction.View} a={AbilitySubject.Estimate}>
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -57,6 +57,11 @@ function InvoiceDetailActionsBar({
closeDrawer(DRAWERS.INVOICE_DETAILS); closeDrawer(DRAWERS.INVOICE_DETAILS);
}; };
// Hanlde deliver sale invoice.
const handleDeliverInvoice = ({ id }) => {
openAlert('invoice-deliver', { invoiceId });
};
// Handle convert to invoice. // Handle convert to invoice.
const handleConvertToCreitNote = () => { const handleConvertToCreitNote = () => {
history.push(`/credit-notes/new?from_invoice_id=${invoiceId}`, { history.push(`/credit-notes/new?from_invoice_id=${invoiceId}`, {
@@ -153,6 +158,7 @@ function InvoiceDetailActionsBar({
onCancelBadDebt: handleCancelBadDebtInvoice, onCancelBadDebt: handleCancelBadDebtInvoice,
onNotifyViaSMS: handleNotifyViaSMS, onNotifyViaSMS: handleNotifyViaSMS,
onConvert: handleConvertToCreitNote, onConvert: handleConvertToCreitNote,
onDeliver: handleDeliverInvoice,
}} }}
/> />
</Can> </Can>

View File

@@ -19,6 +19,7 @@ import {
FormattedMessage as T, FormattedMessage as T,
Choose, Choose,
Can, Can,
If,
TextOverviewTooltipCell, TextOverviewTooltipCell,
} from '@/components'; } from '@/components';
import { SaleInvoiceAction, AbilitySubject } from '@/constants/abilityOption'; import { SaleInvoiceAction, AbilitySubject } from '@/constants/abilityOption';
@@ -94,7 +95,7 @@ export const useInvoiceReadonlyEntriesColumns = () => {
* @returns {React.JSX} * @returns {React.JSX}
*/ */
export const BadDebtMenuItem = ({ export const BadDebtMenuItem = ({
payload: { onCancelBadDebt, onBadDebt, onNotifyViaSMS, onConvert }, payload: { onCancelBadDebt, onBadDebt, onNotifyViaSMS, onConvert, onDeliver },
}) => { }) => {
const { invoice } = useInvoiceDetailDrawerContext(); const { invoice } = useInvoiceDetailDrawerContext();
@@ -108,6 +109,12 @@ export const BadDebtMenuItem = ({
}} }}
content={ content={
<Menu> <Menu>
<If condition={!invoice.is_delivered}>
<MenuItem
onClick={onDeliver}
text={<T id={'mark_as_delivered'} />}
/>
</If>
<Choose> <Choose>
<Choose.When condition={!invoice.is_writtenoff}> <Choose.When condition={!invoice.is_writtenoff}>
<MenuItem <MenuItem

View File

@@ -382,6 +382,12 @@ export default {
], ],
viewBox: '0 0 20 20', viewBox: '0 0 20 20',
}, },
tick: {
path: [
'M14,3c-0.28,0-0.53,0.11-0.71,0.29L6,10.59L2.71,7.29C2.53,7.11,2.28,7,2,7C1.45,7,1,7.45,1,8c0,0.28,0.11,0.53,0.29,0.71l4,4C5.47,12.89,5.72,13,6,13s0.53-0.11,0.71-0.29l8-8C14.89,4.53,15,4.28,15,4C15,3.45,14.55,3,14,3z',
],
viewBox: '0 0 16 16',
},
'swap-vert': { 'swap-vert': {
path: [ path: [
'M10.6,10.9V5.4H9v5.5H6.7L9.8,14l3.1-3.1ZM5.1,0,2,3.1H4.3V8.6H5.9V3.1H8.2Z', 'M10.6,10.9V5.4H9v5.5H6.7L9.8,14l3.1-3.1ZM5.1,0,2,3.1H4.3V8.6H5.9V3.1H8.2Z',

View File

@@ -212,6 +212,16 @@ $dashboard-views-bar-height: 44px;
background: rgba(219, 55, 55, 0.1); background: rgba(219, 55, 55, 0.1);
} }
} }
&.#{$ns}-minimal.#{$ns}-intent-success{
color: #1c6e42;
&:hover,
&:focus {
background: rgba(35, 133, 81, 0.1);
color: #1c6e42;
}
}
&.button--blue-highlight { &.button--blue-highlight {
background-color: #ebfaff; background-color: #ebfaff;