feat: add discount fields in sale and purchase forms

This commit is contained in:
Ahmed Bouhuolia
2024-11-30 18:02:50 +02:00
parent 73ab92e693
commit ffb06f5194
11 changed files with 352 additions and 36 deletions

View File

@@ -1,28 +1,61 @@
// @ts-nocheck
import React from 'react';
import styled from 'styled-components';
import { Button } from '@blueprintjs/core';
import {
T,
TotalLines,
TotalLine,
TotalLineBorderStyle,
TotalLineTextStyle,
FInputGroup,
FFormGroup,
FSelect,
} from '@/components';
import { useCreditNoteTotals } from './utils';
import {
useCreditNoteSubtotalFormatted,
useCreditNoteTotalFormatted,
} from './utils';
export function CreditNoteFormFooterRight() {
const { formattedSubtotal, formattedTotal } = useCreditNoteTotals();
const subtotalFormatted = useCreditNoteSubtotalFormatted();
const totalFormatted = useCreditNoteTotalFormatted();
return (
<CreditNoteTotalLines labelColWidth={'180px'} amountColWidth={'180px'}>
<TotalLine
title={<T id={'credit_note.label_subtotal'} />}
value={formattedSubtotal}
value={subtotalFormatted}
borderStyle={TotalLineBorderStyle.None}
/>
<FFormGroup name={'discount'} label={'Discount'} inline>
<FInputGroup
name={'discount'}
rightElement={
<FSelect
name={'discount_type'}
items={[
{ text: 'USD', value: 'amount' },
{ text: '%', value: 'percentage' },
]}
input={({ text }) => (
<Button small minimal>
{text}
</Button>
)}
filterable={false}
/>
}
/>
</FFormGroup>
<FFormGroup name={'adjustment'} label={'Adjustment'} inline>
<FInputGroup name={'adjustment'} />
</FFormGroup>
<TotalLine
title={<T id={'credit_note.label_total'} />}
value={formattedTotal}
value={totalFormatted}
textStyle={TotalLineTextStyle.Bold}
/>
</CreditNoteTotalLines>

View File

@@ -4,7 +4,7 @@ import { useFormikContext } from 'formik';
import * as R from 'ramda';
import { ExchangeRateInputGroup } from '@/components';
import { useCurrentOrganization } from '@/hooks/state';
import { useCreditNoteIsForeignCustomer, useCreditNoteTotals } from './utils';
import { useCreditNoteIsForeignCustomer, useCreditNoteSubtotal } from './utils';
import withSettings from '@/containers/Settings/withSettings';
import { transactionNumber } from '@/utils';
import {
@@ -78,13 +78,13 @@ export const CreditNoteSyncIncrementSettingsToForm = R.compose(
*/
export const CreditNoteExchangeRateSync = R.compose(withDialogActions)(
({ openDialog }) => {
const { total } = useCreditNoteTotals();
const subtotal = useCreditNoteSubtotal();
const timeout = useRef();
useSyncExRateToForm({
onSynced: () => {
// If the total bigger then zero show alert to the user after adjusting entries.
if (total > 0) {
if (subtotal > 0) {
clearTimeout(timeout.current);
timeout.current = setTimeout(() => {
openDialog(DialogsName.InvoiceExchangeRateChangeNotice);

View File

@@ -10,6 +10,7 @@ import {
repeatValue,
formattedAmount,
orderingLinesIndexes,
toSafeNumber,
} from '@/utils';
import { useFormikContext } from 'formik';
import { useCreditNoteFormContext } from './CreditNoteFormProvider';
@@ -57,6 +58,9 @@ export const defaultCreditNote = {
entries: [...repeatValue(defaultCreditNoteEntry, MIN_LINES_NUMBER)],
attachments: [],
pdf_template_id: '',
discount: '',
discount_type: 'amount',
adjustment: '',
};
/**
@@ -174,32 +178,74 @@ export const useSetPrimaryWarehouseToForm = () => {
};
/**
* Retreives the credit note totals.
* Retrieves the credit note subtotal.
* @returns {number}
*/
export const useCreditNoteTotals = () => {
export const useCreditNoteSubtotal = () => {
const {
values: { entries, currency_code: currencyCode },
values: { entries },
} = useFormikContext();
// Retrieves the invoice entries total.
const total = React.useMemo(() => getEntriesTotal(entries), [entries]);
// Retrieves the formatted total money.
const formattedTotal = React.useMemo(
() => formattedAmount(total, currencyCode),
[total, currencyCode],
);
// Retrieves the formatted subtotal.
const formattedSubtotal = React.useMemo(
() => formattedAmount(total, currencyCode, { money: false }),
[total, currencyCode],
);
return total;
};
return {
total,
formattedTotal,
formattedSubtotal,
};
/**
* Retrieves the credit note subtotal formatted.
* @returns {string}
*/
export const useCreditNoteSubtotalFormatted = () => {
const subtotal = useCreditNoteSubtotal();
const { currency_code: currencyCode } = useFormikContext();
return formattedAmount(subtotal, currencyCode, { money: false });
};
/**
* Retrieves the credit note discount amount.
* @returns {number}
*/
export const useCreditNoteDiscountAmount = () => {
const { values } = useFormikContext();
const subtotal = useCreditNoteSubtotal();
const discount = toSafeNumber(values.discount);
return values?.discount_type === 'percentage'
? (discount * subtotal) / 100
: discount;
};
/**
* Retrieves the credit note adjustment amount.
* @returns {number}
*/
export const useCreditNoteAdjustmentAmount = () => {
const { values } = useFormikContext();
return toSafeNumber(values.adjustment);
};
/**
* Retrieves the credit note total.
* @returns {number}
*/
export const useCreditNoteTotal = () => {
const subtotal = useCreditNoteSubtotal();
const discountAmount = useCreditNoteDiscountAmount();
const adjustmentAmount = useCreditNoteAdjustmentAmount();
return subtotal - discountAmount - adjustmentAmount;
};
/**
* Retrieves the credit note total formatted.
* @returns {string}
*/
export const useCreditNoteTotalFormatted = () => {
const total = useCreditNoteTotal();
const { currency_code: currencyCode } = useFormikContext();
return formattedAmount(total, currencyCode);
};
/**
@@ -217,7 +263,6 @@ export const useCreditNoteIsForeignCustomer = () => {
return isForeignCustomer;
};
export const useCreditNoteFormBrandingTemplatesOptions = () => {
const { brandingTemplates } = useCreditNoteFormContext();