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/css/decimal_style.css',
'web_decimal_style/static/src/core/utils/numbers_patch.js', '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/fields/formatters_patch.js',
'web_decimal_style/static/src/views/inventory_decimal_patch.js', 'web_decimal_style/static/src/views/tax_totals_patch.js',
'web_decimal_style/static/src/views/decimal_observer.js',
'web_decimal_style/static/src/views/fields/float_field.xml', '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/fields/monetary_field.xml',
'web_decimal_style/static/src/views/list_view_patch.xml',
], ],
'web.assets_backend_lazy': [ 'web.assets_backend_lazy': [
'web_decimal_style/static/src/views/pivot_view_patch.xml', 'web_decimal_style/static/src/views/pivot_view_patch.xml',

View File

@ -1,7 +1,7 @@
import { localization } from "@web/core/l10n/localization"; import { localization } from "@web/core/l10n/localization";
import { markup } from "@odoo/owl"; 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. * Wraps the decimal part of a formatted number string in a span for styling.
@ -22,7 +22,7 @@ export function wrapDecimal(formattedValue) {
const decimalPoint = localization.decimalPoint || '.'; const decimalPoint = localization.decimalPoint || '.';
console.log('wrapDecimal: Processing', formattedValue);
// Handle numbers with decimal points // Handle numbers with decimal points
if (formattedValue.includes(decimalPoint)) { if (formattedValue.includes(decimalPoint)) {
@ -38,7 +38,7 @@ export function wrapDecimal(formattedValue) {
const symbols = match[2]; const symbols = match[2];
// Use simple class without inline styles // Use simple class without inline styles
const result = markup(`${integerPart}<span class="o_decimal">${decimalPoint}${digits}</span>${symbols}`); const result = markup(`${integerPart}<span class="o_decimal">${decimalPoint}${digits}</span>${symbols}`);
console.log('wrapDecimal: Wrapped', formattedValue);
return result; return result;
} }
} }
@ -47,10 +47,10 @@ export function wrapDecimal(formattedValue) {
// Handle whole numbers - force decimal formatting for inventory // Handle whole numbers - force decimal formatting for inventory
if (formattedValue.match(/^\d+$/)) { if (formattedValue.match(/^\d+$/)) {
const result = markup(`${formattedValue}<span class="o_decimal">.000</span>`); const result = markup(`${formattedValue}<span class="o_decimal">.000</span>`);
console.log('wrapDecimal: Added decimals to whole number', formattedValue);
return result; return result;
} }
console.log('wrapDecimal: No formatting applied to', formattedValue);
return 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 { FloatField } from "@web/views/fields/float/float_field";
import { formatMonetary, formatFloat } from "@web/views/fields/formatters"; import { formatMonetary, formatFloat } from "@web/views/fields/formatters";
console.log('Loading Web Decimal Style formatters patch...');
// Safe field patching with error handling // Safe field patching with error handling
try { try {
@ -92,7 +92,7 @@ try {
} }
}, { force: true }); }, { force: true });
console.log('Web Decimal Style: Safely patched formatter', name);
} catch (error) { } catch (error) {
console.warn(`Error patching formatter ${name} (non-critical):`, error); console.warn(`Error patching formatter ${name} (non-critical):`, error);
} }
@ -105,4 +105,4 @@ try {
console.warn('Registry patching error (non-critical):', error); 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"> <templates xml:space="preserve">
<!-- Patch List View Footer Aggregates --> <!-- Patch List View Footer Aggregates -->
<t t-inherit="web.ListRenderer" t-inherit-mode="extension"> <t t-inherit="web.ListRenderer" t-inherit-mode="extension">
<xpath expr="//tfoot//span[@t-esc='aggregate.value']" position="replace"> <xpath expr="//tfoot//t[@t-esc='aggregates[column.name].value']" position="replace">
<span t-out="aggregate.value" t-att-data-tooltip="aggregate.help"/> <t t-out="aggregates[column.name].value"/>
</xpath> </xpath>
</t> </t>
<!-- Patch List View Group Row Aggregates --> <!-- Patch List View Group Row Aggregates -->
<t t-inherit="web.ListRenderer.GroupRow" t-inherit-mode="extension"> <t t-inherit="web.ListRenderer.GroupRow" t-inherit-mode="extension">
<xpath expr="//t[@t-esc='formatAggregateValue(group, column)']" position="replace"> <xpath expr="//t[@t-esc='groupAggregate.value']" position="replace">
<t t-if="column.type === 'field'" t-out="formatAggregateValue(group, column)"/> <t t-out="groupAggregate.value"/>
</xpath> </xpath>
</t> </t>
</templates> </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');
}