import { registry } from "@web/core/registry"; import { patch } from "@web/core/utils/patch"; import { wrapDecimal } from "@web_decimal_style/core/utils/numbers_patch"; 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 { // Patch Components for Form Views patch(MonetaryField.prototype, { get formattedValue() { if (this.props.inputType === "number" && !this.props.readonly && this.value) { return this.value; } const res = formatMonetary(this.value, { digits: this.currencyDigits, currencyId: this.currencyId, noSymbol: !this.props.readonly || this.props.hideSymbol, }); // For readonly fields, apply decimal styling via safe DOM manipulation if (this.props.readonly) { // Use a longer timeout to avoid Owl lifecycle conflicts setTimeout(() => { try { const element = this.el?.querySelector('.o_field_monetary'); if (element && !element.querySelector('.o_decimal') && document.contains(element)) { const text = element.textContent; const match = text?.match(/^(.*)(\d{1,3}(?:[.,]\d{3})*)[.,](\d+)(.*)$/); if (match && element.textContent === text) { // Double-check content hasn't changed const [, prefix, integerPart, decimalPart, suffix] = match; element.innerHTML = `${prefix}${integerPart}.${decimalPart}${suffix}`; } } } catch (error) { console.warn('Monetary field decimal styling error (non-critical):', error); } }, 150); // Longer delay to avoid Owl conflicts } return res; } }); patch(FloatField.prototype, { get formattedValue() { if ( !this.props.formatNumber || (this.props.inputType === "number" && !this.props.readonly && this.value) ) { return this.value; } const options = { digits: this.props.digits, field: this.props.record.fields[this.props.name], }; let res; if (this.props.humanReadable && !this.state.hasFocus) { res = formatFloat(this.value, { ...options, humanReadable: true, decimals: this.props.decimals, }); } else { res = formatFloat(this.value, { ...options, humanReadable: false }); } // For readonly fields, apply decimal styling via safe DOM manipulation if (this.props.readonly) { setTimeout(() => { try { const element = this.el?.querySelector('.o_field_float'); if (element && !element.querySelector('.o_decimal') && document.contains(element)) { const text = element.textContent; const match = text?.match(/^(.*)(\d+)[.](\d+)(.*)$/); if (match && element.textContent === text) { // Double-check content hasn't changed const [, prefix, integerPart, decimalPart, suffix] = match; element.innerHTML = `${prefix}${integerPart}.${decimalPart}${suffix}`; } } } catch (error) { console.warn('Float field decimal styling error (non-critical):', error); } }, 150); } return res; } }); } catch (error) { console.warn('Field patching error (non-critical):', error); } // Safe Registry Patching for List Views try { const formattersRegistry = registry.category("formatters"); // Store original formatters const originalFormatters = new Map(); function safelyPatchFormatter(name) { if (formattersRegistry.contains(name) && !originalFormatters.has(name)) { try { const original = formattersRegistry.get(name); originalFormatters.set(name, original); formattersRegistry.add(name, (...args) => { try { const res = original(...args); // Return the result as-is, let DOM observer handle styling // This avoids markup escaping issues and Owl conflicts return res; } catch (error) { console.warn(`Formatter ${name} error (non-critical):`, error); return original(...args); // Fallback to original } }, { force: true }); console.log('Web Decimal Style: Safely patched formatter', name); } catch (error) { console.warn(`Error patching formatter ${name} (non-critical):`, error); } } } // Patch all numeric formatters safely ['float', 'monetary', 'percentage', 'float_factor', 'float_time'].forEach(safelyPatchFormatter); } catch (error) { console.warn('Registry patching error (non-critical):', error); } console.log('Web Decimal Style formatters patch loaded successfully');