I have to create a selection field based on other column. i mean the data comes from other table but based on current table column value. so i created a selection field as below:
pull_location = fields.Selection(selection='_get_pull_locations',string='Pull Location')
and the function is as below:
#api.multi
def _get_pull_locations(self):
data=[]
** Get the values from other table based on current record **
return [('value1', 'String 1'), ('value2', 'String 2')]
Always when i debug i get self as empty class object ( stock.test()). the scenario is i have a column named zone in stock.test, i have another table called stock.location, so for current record i check the stock.location table where column pull_zone == zone of stock.test and if yes append the selection (pull_location) with that values.
But always the object is empty.
I tried #api.one, #api.multi, #api.model , Nothing happens.
Please help.
Thanks,
Replace your code with following:
#api.multi
def _get_pull_locations(self):
** Get the values from other table based on current record **
return [
('value1', 'String 1'),
('value2', 'String 2')
]
pull_location = fields.Selection('_get_pull_locations', string='Pull Location')
Afterwards, Restart Odoo server and upgrade your module.
Related
Is there any way to add a sublist field via a user event script and define its column position? By default the field is added as the last column. It appears you can move form fields around, but can't change sublist column order.
We can able to edit sublist column postion.
But it can be vary based on your records either transaction or suitlet script or any other things just elaborate your question pls.
// For This Example we create a first Field
var field1 = form.addField({
id : 'textfield1',
type : serverWidget.FieldType.TEXT,
label : 'Text'
});
// For This Example we create a first Field
var field2 = form.addField({
id : 'textfield2',
type : serverWidget.FieldType.TEXT,
label : 'Text'
});
form.insertField({
field : field2,
nextfield : 'textfield1'
});
I'm attempting to write a program that will grab the content from fields from a table both specified by the user on the selection screen.
For example, the user could specify the fields equnr, b_werk, b_lager from the table eqbs.
I've been able to accomplish this like so:
" Determine list of fields provided by user
DATA(lv_fields) = COND string(
WHEN p_key3 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
|{ p_key1 }, { p_key2 }, { p_key3 }, { p_string }|
WHEN p_key2 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
|{ p_key1 }, { p_key2 }, { p_string }|
WHEN p_key2 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
|{ p_key1 }, { p_string }| ).
DATA: lv_field_tab TYPE TABLE OF line.
APPEND lv_fields TO lv_field_tab.
" Determine table specified by user and prepare for Open SQL query
DATA t_ref TYPE REF TO data.
FIELD-SYMBOLS: <t> TYPE any,
<comp> TYPE any.
CREATE DATA t_ref TYPE (p_table).
ASSIGN t_ref->* TO <t>.
ASSIGN COMPONENT lv_fields OF STRUCTURE <t> TO <comp>.
" Prepare result container
DATA: lt_zca_str_to_char TYPE TABLE OF zca_str_to_char,
ls_zca_str_to_char TYPE zca_str_to_char.
SELECT (lv_field_tab) FROM (p_table) INTO (#ls_zca_str_to_char-key1, #ls_zca_str_to_char-key2, #ls_zca_str_to_char-key3, #ls_zca_str_to_char-string).
APPEND ls_zca_str_to_char TO lt_zca_str_to_char.
ENDSELECT.
This will correctly populate lt_zca_str_to_char with data from the table specified by the user.
However, this implies that the user is always providing p_key1, p_key2, and p_key3. I could perform a different selection statement based on how many key fields the user provides, but what's the fun in that?
I set out to solve this like this:
DATA(lv_results) = COND string(
WHEN p_key3 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
|(#ls_zca_str_to_char-key1, #ls_zca_str_to_char-key2, #ls_zca_str_to_char-key3, #ls_zca_str_to_char-string)|
WHEN p_key2 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
|(#ls_zca_str_to_char-key1, #ls_zca_str_to_char-key2, #ls_zca_str_to_char-string)|
WHEN p_key2 IS NOT INITIAL AND p_string IS NOT INITIAL THEN
|(#ls_zca_str_to_char-key1, #ls_zca_str_to_char-string)| ).
SELECT (lv_field_tab) FROM (p_table) INTO (#lv_results).
APPEND ls_zca_str_to_char TO lt_zca_str_to_char.
ENDSELECT.
This will activate, and when I get to my Open SQL query (from a Z table, only filling out the first two of three possible key fields), the values are the following:
lv_field_tab = GUID, TEXT_ID, TEXT_DATA (Good)
p_table = ZCR_TRANS_TEXT (Good)
lv_results = (#ls_zca_str_to_char-key1, #ls_zca_str_to_char-key2, #ls_zca_str_to_char-string) (Good, 3 = 3!)
But, since I'm assuming the compiler is seeing (#lv_results) as one single variable, the program dumps with the following error:
The current ABAP program attempted to execute an Open SQL statement
containing a dynamic entry. The parser returned the following error:
"The field list and the INTO list must have the same number of
elements."
Is it possible for me to use the new Open SQL syntax to accomplish my dynamic INTO clause in harmony with my dynamic field list?
The brackets on the INTO do not do what you expect, from the ABAP help:
... INTO (#dobj1, #dobj2, ... )
Effect
If the results set consists of multiple columns or aggregate expressions specified explicitly in the SELECT list, a list of elementary data objects dobj1, dobj2, ... (in parentheses and separated by commas) can be specified after INTO.
In your case you only have one value in there so you can only select one column and the data will be passed in the variable LV_RESULT. Not what you are looking for. Since you want to fill the fields of an existing structure the INTO CORRESPONDING FIELDS OF construct will work here. And you can use TABLE to make your command more efficient as well. This leads to:
SELECT (lv_field_tab) FROM (p_table)
INTO CORRESPONDING FIELDS OF TABLE #lt_zca_str_to_char.
As said previously, you may use INTO CORRESPONDING FIELDS OF ..., but it's not mandatory, it's only for simplifying the code.
So, instead of using CORRESPONDING FIELDS, you may create a structure dynamically (RTTC) with its components corresponding to the columns in LV_FIELD_TAB, and you may then use:
SELECT (lv_field_tab) FROM (p_table) INTO #<structure> ... ENDSELECT.
But of course, as explained by Gert Beukema, you should better do only one SELECT, by creating an internal table dynamically with the same logic as for the structure above, and you may then use:
SELECT (lv_field_tab) FROM (p_table) INTO TABLE #<internal table> ...
Refer to the many examples in the web how to create data objects dynamically with RTTC.
Do not use a fields list for your INTO clause.
Try with
INTO CORRESPONDING FIELDS OF TABLE
must be a FIELD-SYMBOL type any table, and the rest of the logic is up to you (to put the proper information from your generic and almost-empty to your specific destination one).
Can I select some data fields from different models and display these fields in my tree view, then I modify my selection and persist in other models?
'#api.v8
def get_data(self):
data = self.env['my.models]].browse(id)'
There are 3 ways to provide selection list values that is accepted by OpenERP:
Specifying directly in the field.selection definition: 'field_1':
fields.selection([('value1', 'String 1'), ('value2', 'String 2')],
'Field Label')
Specifying using a name list variable outside of the field.selection
definition: 'field_1': fields.selection(LIST_VARIABLE, 'Field
Label'). Where LIST_VARIABLE is defined beforehand: LIST_VARIABLE =
[('value1', 'String 1'), ('value2', 'String 2')]
Specifying using a method: 'field_1': fields.selection(_method_name,
'Field Label'). Where _method_name is defined beforehand:
def _method_name(self, cr, uid, context=None):
return [('value1', 'String 1'), ('value2', 'String 2')]
Now, you need to check first which one is your current selection field is. If it is using method No. 1, then you need to redefine it to use either method No 2 or method No 3. If it is using method No. 2 or 3, you just need to change either the variable (you can use LIST_VARIABLE.append(('value3', 'String 3'))) to return the new value.
I need to set the value of sequence for a IrSequence model instance inside a Python method.
I would have as input values:
the ID of the IrSequence (and getting the ID of the IrSequenceDateRange if dates are used is also possible).
the value for the next value to be used in the sequence.
Given that ID and that value, how can I set up the next value programmatically -i.e. by python source code- for that sequence?
Thanks,
There are two methods to get the next value in a sequence:
1) Given the id:
next_seq = seq_record.next_by_id(cr, uid, seq_id, context)
2) Given the code:
next_seq = seq_record.next_by_code(cr, uid, seq_code, context=context)
But if you want to change the database value directly you can try to write the record:
seq_rec = self.env[ir_sequence].browse(seq_id)
seq_rec.write({'number_next': your_next_sequence})
I hope this helps
I currently have a .find method in one of my rails controller actions - the relevant part is:
.find(:all, :select => 'last_name as id, last_name as name')
I am getting some odd behaviour trying to alias the last_name column as id - if I alias it as anything else, it works fine (i can do last_name as xyz and it outputs the last name in a column called xyz, but as I am using this to populate a drop-down where I need to have the name in the id column, i need it to be called 'id').
I should point out that it does output an id column, but it is always "id":0.
Could anyone shed any light on what I need to do to get this column aliased as 'id'?
Thanks!
I'm not sure of how you can do this in a Rails query statement. Rails is going to try and take over the id column, casting the value returned by the database as id with the type of column that id is (presumably integer). That's why your id column keeps getting set to 0, because "string".to_i #=> 0
However, there is a way to do it, once you have the results back.
Since you have the question tagged as Rails 3, it is preferable to use the new ActiveRelation syntax. You can do the following:
# First, get the results from the query, then loop through all of them.
Customer.select("last_name as 'ln', last_name as 'name'").all.collect do |c|
# The first step of the loop is to get the attributes into a hash form
h = c.attributes
# The next step is to create an "id" key in the hash.
# The Hash#delete method deletes the key/value pair at the key specified and returns the value.
# We'll take that returned value and assign it to the just created "id" key.
h["id"] = h.delete("ln")
# And we have to call out the hash to ensure that it's the returned value from the collect.
h
end
That will get you a hash with the id value as the text string value last_name and a name value as the same.
Hope that helps!
You shouldn't need to setup aliases in the finder SQL just to populate a drop-down. Instead simply use the last_name value for the value attribute (as well as the display text).
Eg if you're using the collection_select helper:
<%= f.collection_select :attribute_id, #collection, :last_name, :last_name %>