136 lines
5.9 KiB
JavaScript
136 lines
5.9 KiB
JavaScript
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}<span class="o_decimal">.${decimalPart}</span>${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}<span class="o_decimal">.${decimalPart}</span>${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');
|