Understanding OpenERP Domain Filter? - odoo

I would like to ask you if you could please explain the anatomy of the Openerp domain filters. I have to use it my project.
Please explain the description of the following domain filter.
['|',('order_id.user_id','=',user.id),('order_id.user_id','=',False)]
I want to know the exact meaning of (order_id.user_id','=',user.id), what is order_id, user_id, and user.id. Are they referencing any table. If yes then how am I supposed to know which one...
Basically I want to know decipher the notation from bottom up so that can use it as per my requirement.

This one is pretty simple.
Consider the following fields (only XML i've given here, python you got to manage)
<field name="a"/>
<field name="b"/>
<field name="c"/>
Single Condition
Consider some simple conditions in programming
if a = 5 # where a is the variable and 5 is the value
In Open ERP domain filter it would be written this way
[('a','=',5)] # where a should be a field in the model and 5 will be the value
So the syntax we derive is
('field_name', 'operator', value)
Now let's try to apply another field in place of static value 5
[('a','=',b)] # where a and b should be the fields in the model
In the above you've to note that first variable a is enclosed with single quotes whereas the value b is not. The variable to be compared will be always first and will be enclosed with single quotes and the value will be just the field name. But if you want to compare variable a with the value 'b' you've to do the below
[('a','=','b')] # where only a is the field name and b is the value (field b's value will not be taken for comparison in this case)
Condition AND
In Programming
if a = 5 and b = 10
In Open ERP domain filter
[('a','=',5),('b','=',10)]
Note that if you don't specify any condition at the beginning and condition will be applied. If you want to replace static values you can simply remove the 5 and give the field name (strictly without quotes)
[('a','=',c),('b','=',c)]
Condition OR
In Programming
if a = 5 or b = 10
In Open ERP domain filter
['|',('a','=',5),('b','=',10)]
Note that the , indicates that it's and condition. If you want to replace fields you can simply remove the 5 and give the field name (strictly without quotes)
Multiple Conditions
In Programming
if a = 5 or (b != 10 and c = 12)
In Open ERP domain filter
['|',('a','=',5),('&',('b','!=',10),('c','=',12))]
Also this post from Arya will be greatly helpful to you. Cheers!!

The '|' is an OR that gets applied to the next comparison. The (..., '=', False) gets converted into an IS NULL so the SQL for this would be
WHERE order_id.user_id = x OR order_id.user_id is NULL
The default is AND which is why you don't see ('&', ('field1', '=' ,1), ('field2' ,'=', 2) everywhere.
Note that another useful one is ('field1', '!=', False) which gets converted to WHERE field1 IS NOT NULL
There isn't a lot of great documentation for this and they get quite tricky with multiple operators as you have to work through the tuples in reverse consuming the operators. I find I use complex ones infrequently enough that I just turn on query logging in Postgres and use trial and error observing the generated queries until I get it right.

Related

Regex match first number if it does not appear at the end

I am currently facing a Regex problem which apparently I cannot find an answer to.
My Regex is embedded in a teradata SQL of the form:
REGEXP_SUBSTR(column, 'regex_pattern')
I want to find the first appearance of any number except if it appears at the end of the string.
For Example:
"YEL2X30" -> "2"
"YEL19XYZ05" -> "19"
"YELLOW05" -> ""
I tried it with '[0-9]+(?!$)/' but this returns me a blank String always.
Thanks in Advance!
Shot in the dark here since I'm unfamiliar with teradata and the supported SQL-functionality. However, reading the docs on the REGEXP_SUBSTR() function it seems like you may want to use the 3rd and 4th possible argument along with a slightly different regular expression:
[0-9]+(?![0-9]|$)
Meaning: 1+ Digits that are not followed by either the end of the string or another digit.
I'd believe the following syntax may work now to retrieve the 1st appearance of any number from the matching results:
REGEXP_SUBSTR(column, '[0-9]+(?![0-9]|$)', 1, 1)
The 3rd parameter states from which position in the source-string we need to start searching whereas the 4th will return the 1st match from any possible multiple matches (is how I read the docs). For example: abc123def456ghi789 whould return 123.
Fiddling around in online IDE's gave me that:
CREATE TABLE TBL (TST varchar(100));
INSERT INTO TBL values ('YEL2X30'), ('YEL19XYZ05'), ('YELLOW05'), ('abc123def456ghi789');
SELECT REGEXP_SUBSTR(TST, '[0-9]+(?![0-9]|$)', 1, 1) as 'RESULTS' FROM TBL;
Resulted in:
RESULTS
2
19
NULL
123
NOTE: I also noticed that leaving out the 3rd and 4th parameter made no difference since they will default back to 1 without explicitly mentioning them. I tested this over here.
Possibly the simplest way is to look for digits followed by a non-digit. Then keep all the digits:
regexp_substr(regexp_substr(column, '[0-9]+[^0-9]'), '[0-9]+')

Need to use space separated values in AG-Grid filter to return each match

I'm tasked with moving some UI-Grids to AG-Grid.
I need to allow the user to use a space delimited string for a column filter so "1 4 23 88" would return all rows where column has 1 or 4 or 23 or 88 as a value.
AG-Grid has the drop down OR option but is added clicks and only allows two values.
With UI-Grid the filter parameter in columnDefs can have a condition:
filter:{condition: filterFunction}
FilterFunction simply has the custom logic and returned true or false.
Is there something similar with AG-Grid? Reading through the docs it seems to get overly involved to create a custom filter. The UI-Grid solution is like 6 lines of code.
CentOS 7, VueJS
I ended up using:
filter:'agTextColumnFilter', filterParams: {textCustomComparator: this.filterFunction}
With filterFunction holding the logic.
https://www.ag-grid.com/javascript-grid/filter-text/#text-custom-comparator
Though I'm using a number column there is not a comparator filterParam for numbers, only 'comparator' for dates and 'textCustomComparator' for text.
This seems to work fine for what I need.

SSRS if field value in list

I've looked through a number of tutorials and asks, and haven't found a working solution to my problem.
Suppose my dataset has two columns: sort_order and field_value. sort_order is an integer and field_value is a numerical (10,2).
I want to format some rows as #,#0 and others as #,#0.00.
Normally I would just do
iif( fields!sort_order.value = 1 or fields!sort_order.value = 23 or .....
unfortunately, the list is fairly long.
I'd like to do the equivalent of if fields!sort_order.value in (1,2,21,63,78,...) then...)
As recommended in another post, I tried the following (if sort in list, then just output a 0, else a 1. this is just to test the functionality of the IN operator):
=iif( fields!sort_order.Value IN split("1,2,3,4,5,6,8,10,11,15,16,17,18,19,20,21,26,30,31,33,34,36,37,38,41,42,44,45,46,49,50,52,53,54,57,58,59,62,63,64,67,68,70,71,75,76,77,80,81,82,92,98,99,113,115,116,120,122,123,127,130,134,136,137,143,144,146,147,148,149,154,155,156,157,162,163,164,165,170,171,172,173,183,184,185,186,192,193,194,195,201,202,203,204,210,211,212,213,263",","),0,1)
However, it doesn't look like the SSRS expression editor wants to accept the "IN" operator. Which is strange, because all the examples I've found that solve this problem use the IN operator.
Any advice?
Try using IndexOf function:
=IIF(Array.IndexOf(split("1,2,3,4,...",","),fields!sort_order.Value)>-1,0,1)
Note all values must be inside quotations.
Consider the recommendation of #Jakub, I recommend this solution if
your are feeding your report via SP and you can't touch it.
Let me know if this helps.

Using SQL like for pattern query

I have a PHP function that accepts a parameter called $letter and I want to set the default value of the parameter to a pattern which is "any number or any symbol". How can I do that?
This is my query by the way .
select ID from $wpdb->posts where post_title LIKE '".$letter."%
I tried posting at wordpress stackexchange and they told me to post it here as this is an SQL/general programming question that specific to wordpress.
Thank you! Replies much appreciated :)
In order to match just numbers or letters (I'm not sure exactly what you mean by symbols) you can use the RLIKE operator in MySQL:
SELECT ... WHERE post_title RLIKE '^[A-Za-z0-9]'
That means by default $letter would be [A-Za-z0-9] - this means all letters from a to z (both cases) and numbers from 0-9. If you need specific symbols you can add them to the list (but - has to be first or last, since otherwise it has a special meaning of range). The ^ character tells it to be at the beginning of the string. So you will need something like:
"select ID from $wpdb->posts where post_title RLIKE '^".$letter."%'"
Of course I have to warn you against SQL injection attacks if you build your query like this without sanitizing the input (making sure it doesn't have any ' (apostrophe) in it.
Edit
To match a title that starts with a number just use [0-9] - that means it will match one digit from 0 to 9

Constructing a recursive compare with SQL

This is an ugly one. I wish I wasn't having to ask this question, but the project is already built such that we are handling heavy loads of validations in the database. Essentially, I'm trying to build a function that will take two stacks of data, weave them together with an unknown batch of operations or comparators, and produce a long string.
Yes, that was phrased very poorly, so I'm going to give an example. I have a form that can have multiple iterations of itself. For some reason, the system wants to know if the entered start date on any of these forms is equal to the entered end date on any of these forms. Unfortunately, due to the way the system is designed, everything is stored as a string, so I have to format it as a date first, before I can compare. Below is pseudo code, so please don't correct me on my syntax
Input data:
'logFormValidation("to_date(#) == to_date(^)"
, formname.control1name, formname.control2name)'
Now, as I mentioned, there are multiple iterations of this form, and I need to loop build a fully recursive comparison (note: it may not always be typical boolean comparisons, it could be internally called functions as well, so .In or anything like that won't work.) In the end, I need to get it into a format like below so the validation parser can read it.
OR(to_date(formname.control1name.1) == to_date(formname.control2name.1)
,to_date(formname.control1name.2) == to_date(formname.control2name.1)
,to_date(formname.control1name.3) == to_date(formname.control2name.1)
,to_date(formname.control1name.1) == to_date(formname.control2name.2)
:
:
,to_date(formname.control1name.n) == to_date(formname.control2name.n))
Yeah, it's ugly...but given the way our validation parser works, I don't have much of a choice. Any input on how this might be accomplished? I'm hoping for something more efficient than a double recursive loop, but don't have any ideas beyond that
Okay, seeing as my question is apparently terribly unclear, I'm going to add some more info. I don't know what comparison I will be performing on the items, I'm just trying to reformat the data into something useable for ANY given function. If I were to do this outside the database, it'd look something like this. Note: Pseudocode. '#' is the place marker in a function for vals1, '^' is a place marker for vals2.
function dynamicRecursiveValidation(string functionStr, strArray vals1, strArray vals2){
string finalFunction = "OR("
foreach(i in vals1){
foreach(j in vals2){
finalFunction += functionStr.replace('#', i).replace('^', j) + ",";
}
}
finalFunction.substring(0, finalFunction.length - 1); //to remove last comma
finalFunction += ")";
return finalFunction;
}
That is all I'm trying to accomplish. Take any given comparator and two arrays, and create a string that contains every possible combination. Given the substitution characters I listed above, below is a list of possible added operations
# > ^
to_date(#) == to_date(^)
someFunction(#, ^)
# * 2 - 3 <= ^ / 4
All I'm trying to do is produce the string that I will later execute, and I'm trying to do it without having to kill the server in a recursive loop
I don't have a solution code for this but you can algorithmically do the following
Create a temp table (start_date, end_date, formid) and populate it with every date from any existing form
Get the start_date from the form and simply:
SELECT end_date, form_id FROM temp_table WHERE end_date = <start date to check>
For the reverse
SELECT start_date, form_id FROM temp_table WHERE start_date = <end date to check>
If the database is available why not let it do all the heavy lifting.
I ended up performing a cross product of the data, and looping through the results. It wasn't the sort of solution I really wanted, but it worked.