Complete logic review and fixes: proper case handling, better record management, improved search logic
This commit is contained in:
parent
fa4e0e0090
commit
14d5cdfcea
|
|
@ -70,6 +70,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
|
|
||||||
_performSearch: function (searchValue) {
|
_performSearch: function (searchValue) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
// Keep original value for search, don't lowercase here
|
||||||
var value = (searchValue || '').trim();
|
var value = (searchValue || '').trim();
|
||||||
|
|
||||||
// Prevent concurrent searches
|
// Prevent concurrent searches
|
||||||
|
|
@ -91,8 +92,10 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
this._isSearching = true;
|
this._isSearching = true;
|
||||||
|
|
||||||
// Store original records if not already stored
|
// Store original records if not already stored
|
||||||
if (!this._originalRecords && this.state.data && this.state.data.records) {
|
// Check different possible locations for records
|
||||||
this._originalRecords = this.state.data.records.slice();
|
var currentRecords = this._getCurrentRecords();
|
||||||
|
if (!this._originalRecords && currentRecords) {
|
||||||
|
this._originalRecords = currentRecords.slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get model and fields info
|
// Get model and fields info
|
||||||
|
|
@ -107,7 +110,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build search domain - make it case insensitive
|
// Build search domain
|
||||||
var domain = this._buildSearchDomain(value, fields);
|
var domain = this._buildSearchDomain(value, fields);
|
||||||
|
|
||||||
// Add existing domain if any
|
// Add existing domain if any
|
||||||
|
|
@ -121,19 +124,12 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
var fieldsToRead = this._getFieldsToRead();
|
var fieldsToRead = this._getFieldsToRead();
|
||||||
|
|
||||||
// Build order string safely
|
// Build order string safely
|
||||||
var orderBy = false;
|
var orderBy = this._getOrderBy();
|
||||||
if (this.state.orderedBy && this.state.orderedBy.length > 0 && this.state.orderedBy[0]) {
|
|
||||||
var order = this.state.orderedBy[0];
|
|
||||||
if (order.name) {
|
|
||||||
orderBy = order.name;
|
|
||||||
if (order.asc !== undefined) {
|
|
||||||
orderBy += order.asc ? ' ASC' : ' DESC';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Searching with domain:', domain);
|
console.log('Search query:', value);
|
||||||
|
console.log('Searching with domain:', JSON.stringify(domain));
|
||||||
console.log('Fields to read:', fieldsToRead);
|
console.log('Fields to read:', fieldsToRead);
|
||||||
|
console.log('Model:', model);
|
||||||
|
|
||||||
// Perform RPC search with specific fields only - NO LIMIT
|
// Perform RPC search with specific fields only - NO LIMIT
|
||||||
this._rpc({
|
this._rpc({
|
||||||
|
|
@ -149,6 +145,9 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
}
|
}
|
||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
console.log('Search results:', result.length, 'records found');
|
console.log('Search results:', result.length, 'records found');
|
||||||
|
if (result.length > 0) {
|
||||||
|
console.log('Sample result:', result[0]);
|
||||||
|
}
|
||||||
self._updateListWithSearchResults(result, value);
|
self._updateListWithSearchResults(result, value);
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
console.error('Search error:', error);
|
console.error('Search error:', error);
|
||||||
|
|
@ -161,6 +160,46 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getCurrentRecords: function() {
|
||||||
|
// Try different locations where records might be stored
|
||||||
|
if (this.state.data && this.state.data.records) {
|
||||||
|
return this.state.data.records;
|
||||||
|
}
|
||||||
|
if (this.state.records) {
|
||||||
|
return this.state.records;
|
||||||
|
}
|
||||||
|
if (this.recordsData) {
|
||||||
|
return this.recordsData;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setCurrentRecords: function(records) {
|
||||||
|
// Set records in the appropriate location
|
||||||
|
if (this.state.data) {
|
||||||
|
this.state.data.records = records;
|
||||||
|
} else if (this.state.records !== undefined) {
|
||||||
|
this.state.records = records;
|
||||||
|
} else {
|
||||||
|
// Create data structure if it doesn't exist
|
||||||
|
this.state.data = { records: records };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_getOrderBy: function() {
|
||||||
|
var orderBy = false;
|
||||||
|
if (this.state.orderedBy && this.state.orderedBy.length > 0) {
|
||||||
|
var order = this.state.orderedBy[0];
|
||||||
|
if (order && order.name) {
|
||||||
|
orderBy = order.name;
|
||||||
|
if (order.asc !== undefined) {
|
||||||
|
orderBy += order.asc ? ' ASC' : ' DESC';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return orderBy;
|
||||||
|
},
|
||||||
|
|
||||||
_getFieldsToRead: function() {
|
_getFieldsToRead: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var fields = ['id']; // Always include ID
|
var fields = ['id']; // Always include ID
|
||||||
|
|
@ -175,6 +214,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
if (field) {
|
if (field) {
|
||||||
// Skip computed fields unless they're stored
|
// Skip computed fields unless they're stored
|
||||||
if (field.compute && !field.store) {
|
if (field.compute && !field.store) {
|
||||||
|
console.log('Skipping computed field:', fieldName);
|
||||||
return; // Skip this field
|
return; // Skip this field
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,28 +245,45 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
var normalizedValue = this._normalizeArabic(value);
|
var normalizedValue = this._normalizeArabic(value);
|
||||||
|
|
||||||
_.each(fields, function(field) {
|
_.each(fields, function(field) {
|
||||||
// For char, text, and html fields
|
// For char, text, html, and selection fields
|
||||||
if (['char', 'text', 'html', 'selection'].includes(field.type)) {
|
if (['char', 'text', 'html', 'selection'].includes(field.type)) {
|
||||||
// Use ilike for case-insensitive search
|
// Use ilike for case-insensitive search
|
||||||
orConditions.push([field.name, 'ilike', value]);
|
orConditions.push([field.name, 'ilike', value]);
|
||||||
// Also search with normalized value if different
|
// Also search with normalized value if different (for Arabic)
|
||||||
if (normalizedValue !== value) {
|
if (normalizedValue !== value && normalizedValue) {
|
||||||
orConditions.push([field.name, 'ilike', normalizedValue]);
|
orConditions.push([field.name, 'ilike', normalizedValue]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// For many2one fields - search in the name
|
// For many2one fields - search in the display_name
|
||||||
else if (field.type === 'many2one') {
|
else if (field.type === 'many2one') {
|
||||||
// Use the field name directly with ilike
|
// Many2one search needs special handling
|
||||||
|
// Try searching by ID if value is numeric
|
||||||
|
if (!isNaN(value)) {
|
||||||
|
orConditions.push([field.name, '=', parseInt(value)]);
|
||||||
|
}
|
||||||
|
// Also try text search in the related field's name
|
||||||
orConditions.push([field.name, 'ilike', value]);
|
orConditions.push([field.name, 'ilike', value]);
|
||||||
}
|
}
|
||||||
// For number fields (if value is numeric)
|
// For number fields (if value is numeric)
|
||||||
else if (['integer', 'float', 'monetary'].includes(field.type)) {
|
else if (['integer', 'float', 'monetary'].includes(field.type)) {
|
||||||
if (!isNaN(value) && value !== '') {
|
if (!isNaN(value) && value !== '') {
|
||||||
var numValue = parseFloat(value);
|
var numValue = parseFloat(value);
|
||||||
orConditions.push([field.name, '=', numValue]);
|
// Exact match for integers
|
||||||
// Also search for approximate values
|
if (field.type === 'integer') {
|
||||||
orConditions.push([field.name, '>=', numValue - 0.01]);
|
orConditions.push([field.name, '=', parseInt(value)]);
|
||||||
orConditions.push([field.name, '<=', numValue + 0.01]);
|
} else {
|
||||||
|
// For float/monetary, exact match
|
||||||
|
orConditions.push([field.name, '=', numValue]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// For boolean fields
|
||||||
|
else if (field.type === 'boolean') {
|
||||||
|
var boolValue = value.toLowerCase();
|
||||||
|
if (boolValue === 'true' || boolValue === 'yes' || boolValue === '1' || boolValue === 'نعم') {
|
||||||
|
orConditions.push([field.name, '=', true]);
|
||||||
|
} else if (boolValue === 'false' || boolValue === 'no' || boolValue === '0' || boolValue === 'لا') {
|
||||||
|
orConditions.push([field.name, '=', false]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -314,27 +371,32 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
$countEl.text(message).show();
|
$countEl.text(message).show();
|
||||||
|
|
||||||
// Update the view with new records
|
// Update the view with new records
|
||||||
this.state.data.records = records;
|
this._setCurrentRecords(records);
|
||||||
this._searchMode = true;
|
this._searchMode = true;
|
||||||
|
|
||||||
// Re-render the body with new records
|
// Re-render the body with new records
|
||||||
// Wrap in Promise to ensure consistent behavior
|
// Wrap in try-catch and handle both Promise and non-Promise returns
|
||||||
var renderPromise = this._renderBody();
|
try {
|
||||||
if (renderPromise && typeof renderPromise.then === 'function') {
|
var renderResult = this._renderBody();
|
||||||
renderPromise.then(function() {
|
if (renderResult && typeof renderResult.then === 'function') {
|
||||||
// Restore search input value
|
renderResult.then(function() {
|
||||||
|
// Restore search input value
|
||||||
|
self.$el.find('.oe_search_input').val(self._currentSearchValue);
|
||||||
|
self.$el.find('.oe_clear_search').show();
|
||||||
|
$countEl.show();
|
||||||
|
}).catch(function(error) {
|
||||||
|
console.error('Error rendering search results:', error);
|
||||||
|
self._showError(_t('Error displaying results'));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// If _renderBody doesn't return a promise, just update UI
|
||||||
self.$el.find('.oe_search_input').val(self._currentSearchValue);
|
self.$el.find('.oe_search_input').val(self._currentSearchValue);
|
||||||
self.$el.find('.oe_clear_search').show();
|
self.$el.find('.oe_clear_search').show();
|
||||||
$countEl.show();
|
$countEl.show();
|
||||||
}).catch(function(error) {
|
}
|
||||||
console.error('Error rendering search results:', error);
|
} catch (error) {
|
||||||
self._showError(_t('Error displaying results'));
|
console.error('Error calling _renderBody:', error);
|
||||||
});
|
self._showError(_t('Error displaying results'));
|
||||||
} else {
|
|
||||||
// If _renderBody doesn't return a promise, just update UI
|
|
||||||
self.$el.find('.oe_search_input').val(self._currentSearchValue);
|
|
||||||
self.$el.find('.oe_clear_search').show();
|
|
||||||
$countEl.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -389,21 +451,28 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
|
|
||||||
// If we have original records, restore them
|
// If we have original records, restore them
|
||||||
if (this._originalRecords && this._originalRecords.length > 0) {
|
if (this._originalRecords && this._originalRecords.length > 0) {
|
||||||
this.state.data.records = this._originalRecords;
|
this._setCurrentRecords(this._originalRecords);
|
||||||
|
|
||||||
// Wrap _renderBody in Promise for consistent behavior
|
// Wrap _renderBody in try-catch for safety
|
||||||
var renderPromise = this._renderBody();
|
try {
|
||||||
if (renderPromise && typeof renderPromise.then === 'function') {
|
var renderResult = this._renderBody();
|
||||||
renderPromise.then(function() {
|
if (renderResult && typeof renderResult.then === 'function') {
|
||||||
self._originalRecords = null;
|
renderResult.then(function() {
|
||||||
}).catch(function(error) {
|
self._originalRecords = null;
|
||||||
console.error('Error restoring original records:', error);
|
}).catch(function(error) {
|
||||||
// Just show all rows as fallback
|
console.error('Error restoring original records:', error);
|
||||||
|
// Just show all rows as fallback
|
||||||
|
self.$el.find('.o_data_row').show();
|
||||||
|
self._originalRecords = null;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// If _renderBody doesn't return a promise
|
||||||
self.$el.find('.o_data_row').show();
|
self.$el.find('.o_data_row').show();
|
||||||
self._originalRecords = null;
|
self._originalRecords = null;
|
||||||
});
|
}
|
||||||
} else {
|
} catch (error) {
|
||||||
// If _renderBody doesn't return a promise
|
console.error('Error calling _renderBody:', error);
|
||||||
|
// Just show all rows as fallback
|
||||||
self.$el.find('.o_data_row').show();
|
self.$el.find('.o_data_row').show();
|
||||||
self._originalRecords = null;
|
self._originalRecords = null;
|
||||||
}
|
}
|
||||||
|
|
@ -417,8 +486,8 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
||||||
if (!text) return text;
|
if (!text) return text;
|
||||||
|
|
||||||
// Normalizing Arabic text by removing common variations
|
// Normalizing Arabic text by removing common variations
|
||||||
|
// Don't lowercase here as it's for the search query
|
||||||
return text
|
return text
|
||||||
.toLowerCase() // Make lowercase for better matching
|
|
||||||
.replace(/[\u064B-\u065F]/g, '') // Remove diacritics
|
.replace(/[\u064B-\u065F]/g, '') // Remove diacritics
|
||||||
.replace(/[\u0660-\u0669]/g, (d) => String.fromCharCode(d.charCodeAt(0) - 0x0660 + 0x0030)) // Arabic-Indic digits
|
.replace(/[\u0660-\u0669]/g, (d) => String.fromCharCode(d.charCodeAt(0) - 0x0660 + 0x0030)) // Arabic-Indic digits
|
||||||
.replace(/[\u06F0-\u06F9]/g, (d) => String.fromCharCode(d.charCodeAt(0) - 0x06F0 + 0x0030)) // Extended Arabic-Indic
|
.replace(/[\u06F0-\u06F9]/g, (d) => String.fromCharCode(d.charCodeAt(0) - 0x06F0 + 0x0030)) // Extended Arabic-Indic
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue