I am trying to execute a function to populate new tree view. I need to execute the function and redirecting to the tree view done by only one button. Please help me with doing it.
My function is
def populate_values(self, cr, uid, ids, context={}):
result = {'value': {}}
today = datetime.datetime.now()
tt=today.date()
emps=self.pool.get('hr.employee').search(cr, uid, [('current_status','=','active')], context=context)
if emps:
#...
#...
#...
return {
'name':_("leave.score.card.tree"),
'view_mode': 'tree',
'view_id': '%(open_leave_score_card_tree)d',
'views': [('tree'),('graph')],
'view_type': 'graph',
'res_id' : '%(open_leave_score_card)d',
'res_model': 'leave.score.card',
'type': 'ir.actions.act_window',
'target': 'new',
}
Form view with the button
<record model="ir.ui.view" id="edit_leave_score_card_form">
<field name="name">leave.score.card.form</field>
<field name="model">leave.score.card</field>
<field name="arch" type="xml">
<form string="Leave Score Card" create="false" edit="false" version="7.0">
<sheet>
<button string="Generate" type="object" name="populate_values" class="oe_highlight"/>
</sheet>
</form>
</field>
</record>
The tree view where I need to get redirected
<record model="ir.ui.view" id="view_leave_score_card_tree">
<field name="name">leave.score.card.tree</field>
<field name="model">leave.score.card</field>
<field name="arch" type="xml">
<tree string="Leave Score Card To the Date" create="false" edit="false" colors="red:available_medical < 0.0; red:available_casual < 0.0">
<field name="employee_id" />
<field name="category_id" />
<field name="taken_medical" />
<field name="taken_casual" />
<field name="taken_annual" />
<field name="taken_spc" />
<field name="available_medical" />
<field name="available_casual" />
<field name="available_annual" />
<field name="available_spc" />
<field name="sec_id" invisible="1" />
</tree>
</field>
</record>
Action windows
<record id="open_leave_score_card" model="ir.actions.act_window">
<field name="name">Leave Score Card Form</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">leave.score.card</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
</record>
<record id="open_leave_score_card_tree" model="ir.actions.act_window">
<field name="name">Leave Score Card Tree</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">leave.score.card</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="view_id" eval="view_leave_score_card_tree"/>
<field name="search_view_id" ref="view_leave_score_card_search"/>
</record>
Please let me know where I did wrong because the button call totally not redirecting
No need to write any function for that. I understand that you want to print score card of the employee while you click on the button.
Update action of score card as follow.
<record id="open_leave_score_card_tree" model="ir.actions.act_window">
<field name="name">Leave Score Card Tree</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">leave.score.card</field>
<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>
<field name="view_id" eval="view_leave_score_card_tree"/>
<field name="search_view_id" ref="view_leave_score_card_search"/>
<field name="context">{
'search_default_employee_id': [active_id],
'default_employee_id': active_id,
'active_test': False,}
</field>
</record>
And then change button code in xml as follow.
<button string="Generate" type="action" name="%(open_leave_score_card_tree)d" class="oe_highlight"/>
Remove function no need it. And if you want to do it with the existing code without changing anything then set domain in dynamic action which you are returning from the function.
In your function you have written wrong view_type, it should be form not graph if you want to return list view then.
def populate_values(self, cr, uid, ids, context={}):
today = datetime.datetime.now()
tt=today.date()
emps=self.pool.get('hr.employee').search(cr, uid, [('current_status','=','active')], context=context)
if emps:
return {
'name':_("leave.score.card.tree"),
'view_mode': 'tree',
'view_id': '%(open_leave_score_card_tree)d',
'views': [('tree'),('graph')],
'view_type': 'form',
'res_id' : '%(open_leave_score_card)d',
'res_model': 'leave.score.card',
'type': 'ir.actions.act_window',
'domain' : [('employee_id','in', ids)],
'target': 'new',
}
return True
Related
so I Have several fields in my Wizard model that the default value is the same from the form but we can change it. I try to send my form field value using context but it has an error like this
odoo.tools.convert.ParseError: ": "name
'arrival_date' is not defined"
while evaluating. The name of the field already right because when I use context in my line or one2many field It works just fine.
And Second when I create the record its not referencing my form record. Do I need to change the default write method?
<record model="ir.ui.view" id="kre_product_reservation_wizard_form_view">
<field name="name">kre.product_reservation.form</field>
<field name="model">kre.product_reservation</field>
<field name="arch" type="xml">
<form string="Add Attendees">
<group>
<group>
<!-- Add your fields here -->
<field name="reservation_number"/>
<field name="arrivals_date"/>
<field name="departure_date"/>
<field name="stay_period"/>
<field name="qty"/>
<field name="price"/>
<field name="tax"/>
<field name="sub_amount"/>
<field name="tax_amount"/>
<field name="amount"/>
<field name="description"/>
</group>
<notebook>
<page string="Guest List">
<field name="guests"/>
</page>
</notebook>
</group>
</form>
</field>
</record>
<act_window id="insert_reservation_wizard" name="Insert Reservation" context="{'reservation_id' : active_id, 'arrival_date' : arrival_date, 'departure_date' : departure_date}" binding_model="kre.reservation" res_model="kre.product_reservation" view_mode="form" target="new"/>
And this is the binding model Field that I want to send in Context.
<field name="name"/>
<field name="billing_name"/>
<field name="arrival_date"/>
<field name="departure_date"/>
<field name="group"/>
<field name="currency"/>
<field name="sub_total"/>
<field name="tax"/>
<field name="total"/>
Hello Theodorus Agum Gumilang,
On your act_window you can set the model id or any selection or boolean from the default context passing. Like this,
<act_window id="insert_reservation_wizard"
name="Insert Reservation"
binding_model="kre.reservation"
res_model="kre.product_reservation"
view_mode="form"
context="{'default_reservation_id' : active_id, 'reservation_id' : active_id}"
target="new"/>
You can check the other reference on odoo for default value set from act_window. As on your default value set from the form itself on wizard view, you can do with by changing the approach this way,
1) Calling your wizard action from the python.
2) On the python, you can pass the default value on context.
On you form view added the button,
<button name="action_wizard" string="Your String" type="object" class="btn-primary" />
On Python Function,
def action_wizard(self):
return {
'name': _("Your String"),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'Object',
'view_id': self.env.ref('module.ref_id').id,
'target': 'new',
'context': {
'default_name': self.default_name,
'default_billing_name': self.default_billing_name,
'default_arrival_date': self.default_arrival_date,
'default_departure_date': self.default_departure_date,
'default_group': self.default_group,
'default_currency': self.default_currency,
'default_sub_total': self.default_sub_total,
'default_tax': self.default_tax,
'default_total': self.default_total
}}
Thanks
In order to show this form view :
<record model="ir.ui.view" id="program_viewform">
<field name="name">My Program</field>
<field name="model">res.partner</field>
<field name="arch" type="xml">
<form>
<separator string="My Program " />
<field name="projects_ids" nolabel="True"/>
<separator string="submitted Tasks" />
<field name="submission_task_ids" nolabel="True"/>
</form>
</field>
</record>
I created this action :
<record model="ir.actions.act_window" id="myprogram_action">
<field name="name">My Program</field>
<field name="res_model">res.partner</field>
<field name="form_view_id" ref="training_program_management.program_viewform"/>
<field name="domain">[('id','=',user.id.partner_id)]</field>
<field name="view_mode">form</field>
</record>
and this Menu :
<menuitem name="My Program" id="program_menu" sequence="5"
parent="training_program_management.menu" action="training_program_management.myprogram_action"/>
What I need is to show the record of res_partner corresponding to the current User, knowing that res.users contains a Many2one Field "Partner_id".
What do I need to do?
This is tested for odoo 8 but it can probably be adapted for odoo 10 or at least help you :
Change <record model="ir.actions.act_window" id="myprogram_action"> to <record model="ir.actions.server" id="myprogram_action">
Then add (yes, old API is on purpose, it doesn't work with the new API, for odoo 8 that is)
<field name='model_id' ref='base.model_res_partner'/>
<field name="code">
action = self._action_open_user_res_partner(cr, uid)
</field>
Create a model extending res.partner in your module, add (more old API ... also I didn't find a way to use ref())
#api.model
def _action_open_user_res_partner(self, cr, uid):
return {
'view_type': 'form',
'view_mode': 'form',
# Since this is a constant, you can use a global to hold the value for 'view_id'
'view_id': int(self.pool['ir.ui.view'].search(cr, uid,
[('name', '=', 'My Program')])[0]),
'res_model': 'res.partner',
'res_id': int(self.pool['res.users'].browse(cr, uid, [uid])[0].partner_id),
'type': 'ir.actions.act_window',
'context': {}
}
Adapting this to odoo 10 probably involves using the new API instead of the old one. This means self.pool should be self.env or env, and that you don't need cr and uid anymore. You can use user variable instead of uid in the function returning (well actually it could be used for odoo 8 too, but since uid is needed anyway...).
On the other hand, the documentation for odoo 10 about actions strongly suggests you'd still need to use the old API for this, except for model replacing self.
So you should first try something like this for odoo 10 :
<field name='model_id' ref='base.model_res_partner'/>
<field name="code">
action = model._action_open_user_res_partner(cr, uid)
</field>
The function in the model is still the same, since we still use the old API.
If it doesn't work, you should try with the new API (get rid of cr, uid)
The code bellow, worked perfectly for me, Thank you alot for your help:
<record model="ir.actions.server" id="myprogram_action">
<field name="name">My Program</field>
<field name='model_id' ref='base.model_res_partner'/>
<field name="state">code</field>
<field name="code">
action = {
'type': 'ir.actions.act_window',
'name': 'My Program',
'view_mode': 'form',
'view_type': 'form',
'res_model': 'res.partner',
'nodestroy': 'true',
'res_id': int(env['res.users'].browse(env.user.partner_id.id)),
'views': [(False, 'form')],
'view_id': 'ref="training_program_management.program_viewform"',
}
</field>
</record>
Still have a small problem thou, i have two FormViews for res.partner, this line doesn't seem to show the desired View:
'view_id': 'ref="training_program_management.program_viewform"',
It shows me The First FormView That i've inherited.
My training_program_management.program_viewform :
<record model="ir.ui.view" id="program_viewform">
<field name="name">My Program</field>
<field name="model">res.partner</field>
<field name="arch" type="xml">
<form>
<separator string="My Program " />
<field name="projects_ids" nolabel="True"/>
<separator string="submitted Tasks" />
<field name="submission_task_ids" nolabel="True"/>
</form>
</field>
</record>
What can i do to show this View Instead Of the inherited one ?
I have defined state actions, buttons, and the workflow. They work just fine, the problem is when I tried to add a clickable statusbar and everytime I click the status bar, it won't actually do anything other than changing the record's state.
How do I link the statusbar to the workflow/actions?
model.py
def action_state_draft(self, cr, uid, ids):
self.write(cr, uid, ids, { 'state' : 'draft' })
return True
def action_state_confirmed(self, cr, uid, ids):
self.write(cr, uid, ids, { 'state' : 'confirmed' })
return True
def action_state_posted(self, cr, uid, ids):
self.write(cr, uid, ids, { 'state' : 'posted' })
return True
def action_state_cancelled(self, cr, uid, ids):
self.write(cr, uid, ids, { 'state' : 'cancelled' })
return True
def hello_world(self):
print "Hello World!"
def hello_world_second(self):
print "Hello World Second!"
model_view.xml
<header>
<button name="action_state_confirmed" string="Confirm" states="draft" />
<button name="action_state_posted" string="Post" states="confirmed" />
<button name="action_state_cancelled" string="Cancel" states="draft,confirmed,posted" />
<field name="state" widget="statusbar" clickable="True" statusbar_visible="draft,confirmed,posted,cancelled"/>
</header>
model_workflow.xml
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="ig_account_voucher_wkf" model="workflow">
<field name="name">ig.account.voucher.wkf</field>
<field name="osv">ig.account.voucher</field>
<field name="on_create">True</field>
</record>
<record id="act_draft" model="workflow.activity">
<field name="wkf_id" ref="ig_account_voucher_wkf"/>
<field name="name">draft</field>
<field name="flow_start">True</field>
</record>
<record id="act_confirmed" model="workflow.activity">
<field name="wkf_id" ref="ig_account_voucher_wkf"/>
<field name="name">confirmed</field>
<field name="action">
write({'state':'confirmed'})
hello_world()
hello_world_second()
</field>
<field name="kind">function</field>
</record>
<record id="act_posted" model="workflow.activity">
<field name="wkf_id" ref="ig_account_voucher_wkf"/>
<field name="name">posted</field>
<field name="action">write({'state':'posted'})</field>
<field name="kind">function</field>
</record>
<record id="act_posted" model="workflow.activity">
<field name="wkf_id" ref="ig_account_voucher_wkf"/>
<field name="name">cancelled</field>
<field name="action">write({'state':'cancelled'})</field>
<field name="kind">function</field>
<field name="flow_stop">True</field>
</record>
<record id="transition_draft_confirmed" model="workflow.transition">
<field name="act_from" ref="act_draft"/>
<field name="act_to" ref="act_confirmed"/>
<field name="condition">True</field>
<field name="signal">action_state_confirmed</field>
</record>
<record id="transition_confirmed_posted" model="workflow.transition">
<field name="act_from" ref="act_confirmed"/>
<field name="act_to" ref="act_posted"/>
<field name="condition">True</field>
<field name="signal">action_state_posted</field>
</record>
<record id="transition_confirmed_cancelled" model="workflow.transition">
<field name="act_from" ref="act_confirmed"/>
<field name="act_to" ref="act_posted"/>
<field name="condition">True</field>
<field name="signal">action_state_cancelled</field>
</record>
</data>
</openerp>
Another relevant little question: Why do we need workflow instead of just using buttons and actions?
In your code you have missing commas on workflow action when u pass the multiple method in workflow action.
please make is correct first
<record id="act_confirmed" model="workflow.activity">
<field name="wkf_id" ref="ig_account_voucher_wkf"/>
<field name="name">confirmed</field>
<field name="action">
write({'state':'confirmed'}),
hello_world(),
hello_world_second()
</field>
<field name="kind">function</field>
</record>
Another Answer of your Question is :
Why Work flow is needed instead of button ??
The Main Goal is that the work flow is define as the business process flow.
Another goals are :
description of document evolution in time
automatic trigger of actions if some conditions are met
management of company roles and validation steps
management of interactions between the different objects/modules
graphical tool for visualization of document flows
I hope this should helpful for you ..:)
There is an input box, labeled "Original", on the popup form, containing typed value '105-0045', picture attached. Button click action code is in the function action_replace(). What is the way to pass the input box value to the button function action_replace() when the "Replace" button is clicked?
Here is my XML code where the input box is defined:
<record id="replace_all_in_BOM_form" model="ir.ui.view">
<field name="name">replace.all.in.BOM.form</field>
<field name="model">product.template</field>
<field name="priority" eval="20"/>
<field name="type">form</field>
<field name="arch" type="xml">
<label class="text-inline" for="original_name" string="Original"
></label>
<input name="original_name" id="original_id" ></input>
<group>
<field name="default_code" string="Replacement" readonly="1"
invisible="0" />
<field name="uom_id" invisible="1" />
<field name="uom_po_id" invisible="1" />
<field name="type" invisible="1" />
<field name="categ_id" invisible="1" />
<field name="name" invisible="1" />
</group>
<button type="object" string="Replace" name="action_replace" />
</field>
</record>
<record id="action5" model="ir.actions.act_window">
<field name="name">Replace all in BOM</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.template</field>
<field name="view_type">form</field>
<field name="target">new</field>
<field name="view_id" ref="replace_all_in_BOM_form"/>
</record>
<record id="ir_BOM_structure5" model="ir.values">
<field eval="'client_action_multi'" name="key2"/>
<field eval="'product.template'" name="model"/>
<field name="name">Replace all in BOM</field>
<field eval="'ir.actions.act_window,'+str(action5)" name="value"/></record>
Here is the part of py code:
def default_get(self, cr, uid, fields, context=None):
product_obj = self.pool.get('product.template')
record_ids = context and context.get('active_ids', []) or []
res = {}
for product in product_obj.browse(cr, uid, record_ids, context=context):
if 'default_code' in fields:
#in 'default_code' is a field name of that pop-up window
res.update({'default_code': product.default_code, 'name': product.name, 'uom_id': product.uom_id.id,
'uom_po_id': product.uom_po_id.id, 'type': product.type, 'categ_id': product.categ_id.id })
return res
def action_replace(self, cr, uid, ids, context=None):
txt_value = ''
for record in self.browse(cr,uid,ids,context=context):
txt_value = record.original_id
return {
'type': 'ir.actions.act_window',
'res_model': 'product.template',
'name': _('Replace all in BOM'),
'res_id': ids[0],
'view_type': 'form',
'view_mode': 'form',
'view_id': 1212,
'target': 'new',
'nodestroy': True,
'context': context
}
Whenever a button is clicked, the default behaviour of the system is to save the data first and then to execute the button click function. So in the button click you will find 'ids' of current record. Following is the way where you will get the value of that textbox.
def action_replace(self,cr,uid,ids,context=None):
for record in self.browse(cr,uid,ids,context=context):
txt_value = record.original
<<your further code>>
return True
I searched and modified the source code of a simple custom module of openerp, I give the code below
init.py
import sim
openerp.py
{
'name': 'Student Information Management',
'version': '0.1',
'category': 'Tools',
'description': """This module is for the Student Information Management.""",
'author': 'Mr Praveen Srinivasan',
'website': 'http://praveenlearner.wordpress.com/',
'depends': ['base'],
'data': ['sim_view.xml'],
'demo': [],
'installable': True,
'auto_install': False,
'application': True,
}
sim_view.xml
<?xml version="1.0"?>
<openerp>
<data>
<!-- ============== student================= -->
<!-- 1st part of the sim_view start-->
<record model="ir.ui.view" id="student_form">
<field name="name">Student</field>
<field name="model">sim.student</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Student" version="7.0">
<group>
<field name="reg_no"/>
<field name="student_name"/>
<field name="father_name"/>
<field name="gender"/>
<field name="contact_no"/>
<field name="address"/>
</group>
</form>
</field>
</record>
<!-- 1st part of the sim_view end-->
<!--2nd part of the sim_view start-->
<record model="ir.ui.view" id="student_tree">
<field name="name">Student</field>
<field name="model">sim.student</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Student">
<field name="reg_no"/>
<field name="student_name"/>
<field name="father_name"/>
<field name="gender"/>
<field name="contact_no"/>
<field name="address"/>
</tree>
</field>
</record>
<!--2nd part of the sim_view end-->
<!-- 3rd part of the sim_view start-->
<record model="ir.actions.act_window" id="action_student">
<field name="name">Student</field>
<field name="res_model">sim.student</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<!--3rd part of the sim_view end-->
<!--4th part of the sim_view start-->
<menuitem name="SIM/Student/StudentInfo" id="menu_sim_student"
action="action_student"/>
<!--4th part of the sim_view end-->
</data>
</openerp>
sim.py
**
from openerp.osv import fields, osv
class student(osv.osv):
_name = "sim.student"
_description = "This table is for keeping personal data of student"
_columns = {
'reg_no': fields.integer('Registration Number',size=7,required=True),
'student_name': fields.char('Student Name',size=25,required=True),
'father_name': fields.char("Father's Name",size=25),
'gender':fields.selection([('male','Male'),('female','Female')],'Gender'),
'contact_no':fields.char('Contact Number',size=10),
'address':fields.char('Address',size=256)
}
_sql_constraints = [
('uniq_name', 'unique(reg_no)', 'This Reg.No is number already registered!')
]
student()
**
All is working good, but I want to add an auto incremented registration Id field. I searched the Internet how to do it, but I can't get a proper solution. Please help me.
After creating sequence file you can add this function to your sim.py
def create(self, cr, uid, vals, context=None):
sequence=self.pool.get('ir.sequence').get(cr, uid, 'reg_code')
vals['reg_no']=sequence
return super(student, self).create(cr, uid, vals, context=context)
This function will work properly
Create a record in ir.sequence. First make your reg_no field to char.
<record id="seq_type_1" model="ir.sequence.type">
<field name="name">REG Type</field>
<field name="code">reg_code</field>
</record>
<record id="seq_1" model="ir.sequence">
<field name="name">reg</field>
<field name="code">reg_code</field>
<field name="prefix">REG</field>
<field name="padding">3</field>
</record>
In your py file you can define when to generate the sequence. Either in defaults to get default reg number or override the create method and call the sequence Or in any other methods:
_defaults = { 'reg_no': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'reg_code'), }