feat: Implement decimal styling for tax totals and refine list view aggregate rendering.

This commit is contained in:
Suherdy Yacob 2026-02-02 16:41:49 +07:00
parent d28cfcaa89
commit 19e19de89a
5 changed files with 51 additions and 19 deletions

View File

@ -15,10 +15,10 @@
'web_decimal_style/static/src/css/decimal_style.css',
'web_decimal_style/static/src/core/utils/numbers_patch.js',
'web_decimal_style/static/src/views/fields/formatters_patch.js',
'web_decimal_style/static/src/views/inventory_decimal_patch.js',
'web_decimal_style/static/src/views/decimal_observer.js',
'web_decimal_style/static/src/views/tax_totals_patch.js',
'web_decimal_style/static/src/views/fields/float_field.xml',
'web_decimal_style/static/src/views/fields/monetary_field.xml',
'web_decimal_style/static/src/views/list_view_patch.xml',
],
'web.assets_backend_lazy': [
'web_decimal_style/static/src/views/pivot_view_patch.xml',

View File

@ -1,7 +1,7 @@
import { localization } from "@web/core/l10n/localization";
import { markup } from "@odoo/owl";
console.log('Web Decimal Style: numbers_patch.js loaded');
/**
* Wraps the decimal part of a formatted number string in a span for styling.
@ -14,15 +14,15 @@ export function wrapDecimal(formattedValue) {
if (!formattedValue || typeof formattedValue !== "string") {
return formattedValue;
}
// If it's already wrapped, don't double wrap
if (formattedValue.includes('class="o_decimal"')) {
return formattedValue;
}
const decimalPoint = localization.decimalPoint || '.';
console.log('wrapDecimal: Processing', formattedValue);
// Handle numbers with decimal points
if (formattedValue.includes(decimalPoint)) {
@ -30,7 +30,7 @@ export function wrapDecimal(formattedValue) {
if (parts.length === 2) {
const integerPart = parts[0];
const decimalPart = parts[1];
// Simple regex to separate digits from symbols
const match = decimalPart.match(/^(\d+)(.*)$/);
if (match) {
@ -38,19 +38,19 @@ export function wrapDecimal(formattedValue) {
const symbols = match[2];
// Use simple class without inline styles
const result = markup(`${integerPart}<span class="o_decimal">${decimalPoint}${digits}</span>${symbols}`);
console.log('wrapDecimal: Wrapped', formattedValue);
return result;
}
}
}
// Handle whole numbers - force decimal formatting for inventory
if (formattedValue.match(/^\d+$/)) {
const result = markup(`${formattedValue}<span class="o_decimal">.000</span>`);
console.log('wrapDecimal: Added decimals to whole number', formattedValue);
return result;
}
console.log('wrapDecimal: No formatting applied to', formattedValue);
return formattedValue;
}

View File

@ -5,7 +5,7 @@ import { MonetaryField } from "@web/views/fields/monetary/monetary_field";
import { FloatField } from "@web/views/fields/float/float_field";
import { formatMonetary, formatFloat } from "@web/views/fields/formatters";
console.log('Loading Web Decimal Style formatters patch...');
// Safe field patching with error handling
try {
@ -92,7 +92,7 @@ try {
}
}, { force: true });
console.log('Web Decimal Style: Safely patched formatter', name);
} catch (error) {
console.warn(`Error patching formatter ${name} (non-critical):`, error);
}
@ -105,4 +105,4 @@ try {
console.warn('Registry patching error (non-critical):', error);
}
console.log('Web Decimal Style formatters patch loaded successfully');

View File

@ -2,15 +2,15 @@
<templates xml:space="preserve">
<!-- Patch List View Footer Aggregates -->
<t t-inherit="web.ListRenderer" t-inherit-mode="extension">
<xpath expr="//tfoot//span[@t-esc='aggregate.value']" position="replace">
<span t-out="aggregate.value" t-att-data-tooltip="aggregate.help"/>
<xpath expr="//tfoot//t[@t-esc='aggregates[column.name].value']" position="replace">
<t t-out="aggregates[column.name].value"/>
</xpath>
</t>
<!-- Patch List View Group Row Aggregates -->
<t t-inherit="web.ListRenderer.GroupRow" t-inherit-mode="extension">
<xpath expr="//t[@t-esc='formatAggregateValue(group, column)']" position="replace">
<t t-if="column.type === 'field'" t-out="formatAggregateValue(group, column)"/>
<xpath expr="//t[@t-esc='groupAggregate.value']" position="replace">
<t t-out="groupAggregate.value"/>
</xpath>
</t>
</templates>

View File

@ -0,0 +1,32 @@
/** @odoo-module **/
import { patch } from "@web/core/utils/patch";
import { wrapDecimal } from "@web_decimal_style/core/utils/numbers_patch";
import { TaxTotalsComponent } from "@account/components/tax_totals/tax_totals";
// Patch TaxTotalsComponent (the main widget)
patch(TaxTotalsComponent.prototype, {
formatMonetary(value) {
const result = super.formatMonetary(value);
return wrapDecimal(result);
}
});
// We also need to patch TaxGroupComponent which is a sub-component defined in the same file
// However, it's not exported directly in Odoo 16/17/18/19 usually, but accessible via TaxTotalsComponent.components
if (TaxTotalsComponent.components && TaxTotalsComponent.components.TaxGroupComponent) {
const TaxGroupComponent = TaxTotalsComponent.components.TaxGroupComponent;
patch(TaxGroupComponent.prototype, {
formatMonetary(value) {
const result = super.formatMonetary(value);
return wrapDecimal(result);
}
});
} else {
console.warn('Web Decimal Style: Could not find TaxGroupComponent to patch');
}