feat: enhance discount handling in financial forms

- Implemented discount and adjustment fields in Bill, Credit Note, Estimate, Invoice, and Receipt forms.
- Created new components for displaying discount and adjustment totals, improving clarity in financial documents.
- Updated utility functions to format discount and adjustment amounts consistently across various forms.
- Enhanced user experience by integrating discount functionality into the form context, allowing for better data management and display.

This update improves the overall functionality and user experience related to discounts in financial transactions.
This commit is contained in:
Ahmed Bouhuolia
2024-12-01 17:59:01 +02:00
parent ffb06f5194
commit 000c3e40e1
17 changed files with 644 additions and 194 deletions

View File

@@ -1,23 +1,26 @@
// @ts-nocheck
import styled from 'styled-components';
import { useFormikContext } from 'formik';
import {
TotalLines,
TotalLine,
TotalLineBorderStyle,
TotalLineTextStyle,
FFormGroup,
FInputGroup,
FSelect,
} from '@/components';
import { useBillAggregatedTaxRates, useBillTotals } from './utils';
import { useFormikContext } from 'formik';
import {
useBillAdjustmentAmountFormatted,
useBillAggregatedTaxRates,
useBillDiscountAmountFormatted,
useBillSubtotalFormatted,
useBillTotalFormatted,
useBillTotals,
} from './utils';
import { TaxType } from '@/interfaces/TaxRates';
import { Button } from '@blueprintjs/core';
import { AdjustmentTotalLine } from '@/containers/Sales/Invoices/InvoiceForm/AdjustmentTotalLine';
import { DiscountTotalLine } from '@/containers/Sales/Invoices/InvoiceForm/DiscountTotalLine';
export function BillFormFooterRight() {
const {
formattedSubtotal,
formattedTotal,
formattedDueTotal,
formattedPaymentTotal,
} = useBillTotals();
@@ -26,7 +29,11 @@ export function BillFormFooterRight() {
values: { inclusive_exclusive_tax, currency_code },
} = useFormikContext();
const subtotalFormatted = useBillSubtotalFormatted();
const totalFormatted = useBillTotalFormatted();
const taxEntries = useBillAggregatedTaxRates();
const discountAmount = useBillDiscountAmountFormatted();
const adjustmentAmount = useBillAdjustmentAmountFormatted();
return (
<BillTotalLines labelColWidth={'180px'} amountColWidth={'180px'}>
@@ -38,37 +45,13 @@ export function BillFormFooterRight() {
: 'Subtotal'}
</>
}
value={formattedSubtotal}
borderStyle={TotalLineBorderStyle.None}
value={subtotalFormatted}
/>
{/* ----------- Discount ----------- */}
<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>
{/* ----------- Adjustment ----------- */}
<FFormGroup name={'adjustment'} label={'Adjustment'} inline>
<FInputGroup name={'adjustment'} />
</FFormGroup>
<DiscountTotalLine
currencyCode={currency_code}
discountAmount={discountAmount}
/>
<AdjustmentTotalLine adjustmentAmount={adjustmentAmount} />
{taxEntries.map((tax, index) => (
<TotalLine
key={index}
@@ -78,8 +61,8 @@ export function BillFormFooterRight() {
/>
))}
<TotalLine
title={`Total (${currency_code})`}
value={formattedTotal}
title={`TOTAL (${currency_code})`}
value={totalFormatted}
borderStyle={TotalLineBorderStyle.SingleDark}
textStyle={TotalLineTextStyle.Bold}
/>

View File

@@ -66,6 +66,13 @@ export const defaultBill = {
currency_code: '',
entries: [...repeatValue(defaultBillEntry, MIN_LINES_NUMBER)],
attachments: [],
// Adjustment
adjustment: '',
// Discount
discount: '',
discount_type: 'amount',
};
export const ERRORS = {
@@ -364,6 +371,17 @@ export const useBillSubtotal = () => {
return React.useMemo(() => getEntriesTotal(entries), [entries]);
};
/**
* Retrieves the bill subtotal formatted.
* @returns {string}
*/
export const useBillSubtotalFormatted = () => {
const subtotal = useBillSubtotal();
const { currency_code: currencyCode } = useFormikContext();
return formattedAmount(subtotal, currencyCode);
};
/**
* Retrieves the bill discount amount.
* @returns {number}
@@ -374,6 +392,17 @@ export const useBillDiscountAmount = () => {
return toSafeNumber(values.discount);
};
/**
* Retrieves the bill discount amount formatted.
* @returns {string}
*/
export const useBillDiscountAmountFormatted = () => {
const discountAmount = useBillDiscountAmount();
const { currency_code: currencyCode } = useFormikContext();
return formattedAmount(discountAmount, currencyCode);
};
/**
* Retrieves the bill adjustment amount.
* @returns {number}
@@ -384,6 +413,17 @@ export const useBillAdjustmentAmount = () => {
return toSafeNumber(values.adjustment);
};
/**
* Retrieves the bill adjustment amount formatted.
* @returns {string}
*/
export const useBillAdjustmentAmountFormatted = () => {
const adjustmentAmount = useBillAdjustmentAmount();
const { currency_code: currencyCode } = useFormikContext();
return formattedAmount(adjustmentAmount, currencyCode);
};
/**
* Retrieves the bill total tax amount.
* @returns {number}
@@ -426,3 +466,14 @@ export const useBillTotal = () => {
R.subtract(R.__, adjustmentAmount),
)(subtotal);
};
/**
* Retrieves the bill total formatted.
* @returns {string}
*/
export const useBillTotalFormatted = () => {
const total = useBillTotal();
const { currency_code: currencyCode } = useFormikContext();
return formattedAmount(total, currencyCode);
};

View File

@@ -1,17 +1,26 @@
// @ts-nocheck
import React from 'react';
import styled from 'styled-components';
import { useFormikContext } from 'formik';
import { T, TotalLines, TotalLine, TotalLineTextStyle } from '@/components';
import {
T,
TotalLines,
TotalLine,
TotalLineBorderStyle,
TotalLineTextStyle,
} from '@/components';
import { useVendorCrditNoteTotals } from './utils';
useVendorCreditAdjustmentAmountFormatted,
useVendorCreditDiscountAmount,
useVendorCreditSubtotalFormatted,
useVendorCreditTotalFormatted,
} from './utils';
import { DiscountTotalLine } from '@/containers/Sales/Invoices/InvoiceForm/DiscountTotalLine';
import { AdjustmentTotalLine } from '@/containers/Sales/Invoices/InvoiceForm/AdjustmentTotalLine';
export function VendorCreditNoteFormFooterRight() {
const { formattedSubtotal, formattedTotal } = useVendorCrditNoteTotals();
const {
values: { currency_code },
} = useFormikContext();
const totalFormatted = useVendorCreditTotalFormatted();
const subtotalFormatted = useVendorCreditSubtotalFormatted();
const discountAmount = useVendorCreditDiscountAmount();
const adjustmentAmount = useVendorCreditAdjustmentAmountFormatted();
return (
<VendorCreditNoteTotalLines
@@ -20,12 +29,16 @@ export function VendorCreditNoteFormFooterRight() {
>
<TotalLine
title={<T id={'vendor_credit_form.label.subtotal'} />}
value={formattedSubtotal}
borderStyle={TotalLineBorderStyle.None}
value={subtotalFormatted}
/>
<DiscountTotalLine
currencyCode={currency_code}
discountAmount={discountAmount}
/>
<AdjustmentTotalLine adjustmentAmount={adjustmentAmount} />
<TotalLine
title={<T id={'vendor_credit_form.label.total'} />}
value={formattedTotal}
value={totalFormatted}
textStyle={TotalLineTextStyle.Bold}
/>
</VendorCreditNoteTotalLines>

View File

@@ -11,6 +11,7 @@ import {
transactionNumber,
orderingLinesIndexes,
formattedAmount,
toSafeNumber,
} from '@/utils';
import {
updateItemsEntriesTotal,
@@ -235,6 +236,19 @@ export const useVendorCreditDiscountAmount = () => {
return toSafeNumber(values.discount);
};
/**
* Retrieves the vendor credit discount amount formatted.
* @returns {string}
*/
export const useVendorCreditDiscountAmountFormatted = () => {
const discountAmount = useVendorCreditDiscountAmount();
const {
values: { currency_code: currencyCode },
} = useFormikContext();
return formattedAmount(discountAmount, currencyCode);
};
/**
* Retrieves the vendor credit adjustment amount.
* @returns {number}
@@ -245,6 +259,19 @@ export const useVendorCreditAdjustment = () => {
return toSafeNumber(values.adjustment);
};
/**
* Retrieves the vendor credit adjustment amount formatted.
* @returns {string}
*/
export const useVendorCreditAdjustmentAmountFormatted = () => {
const adjustmentAmount = useVendorCreditAdjustment();
const {
values: { currency_code: currencyCode },
} = useFormikContext();
return formattedAmount(adjustmentAmount, currencyCode);
};
/**
* Retrieves the vendor credit total.
* @returns {number}
@@ -258,12 +285,14 @@ export const useVendorCreditTotal = () => {
};
/**
* Retrieves the vendor credit formatted total.
* Retrieves the vendor credit total formatted.
* @returns {string}
*/
export const useVendorCreditFormattedTotal = () => {
export const useVendorCreditTotalFormatted = () => {
const total = useVendorCreditTotal();
const currencyCode = useCurrentOrganizationCurrencyCode();
const {
values: { currency_code: currencyCode },
} = useFormikContext();
return formattedAmount(total, currencyCode);
};
@@ -279,6 +308,19 @@ export const useVendorCreditFormattedSubtotal = () => {
return formattedAmount(subtotal, currencyCode);
};
/**
* Retrieves the vendor credit formatted subtotal.
* @returns {string}
*/
export const useVendorCreditSubtotalFormatted = () => {
const subtotal = useVendorCreditSubtotal();
const {
values: { currency_code: currencyCode },
} = useFormikContext();
return formattedAmount(subtotal, currencyCode);
};
/**
* Detarmines whether the vendor note has foreign customer.
* @returns {boolean}