Odoo: how to get a specific action view by id in js action? - odoo

I wrote my own action for "mail.message" model, and form for it.
I do this, because i want to open another form view in a specific situation.
Here is view:
<record id="action_view_mail_html_message" model="ir.actions.act_window">
<field name="name">Повідомлення</field>
<field name="res_model">mail.message</field>
<field name="view_mode">form</field>
<field name="view_id" ref="mail_message_view_html_form"/>
</record>
in js module I call action to open message form by this way:
const action = {
name: "Розширене форматування",
type: 'ir.actions.act_window',
res_model: 'mail.message',
views: [[false, 'form']],
res_id: this.message.id,
target: 'new',
context: {
context: {form_view_initial_mode: 'edit'},
},
};
this.env.bus.trigger('do-action', {
action,
});
but Odoo open a default action. How to get my onw action by id?

You can try using rpc.query to call a custom route and in that HTTP route, fetch the action by ID and return it to JS.
Once the RPC call is done, you can get your custom action.
It might be patch work but will work.

Related

Optional Dependencies in Odoo 14 CE

Is there any way to can make optional dependencies in Odoo 14 CE?
I know that there is a dependency attribute in the manifest file that we need to specify, and yes, I have been using it to the best of my abilities.
However, I sometimes need to write some code for only when a module is installed, but even if it isn't then the rest code should function properly without such module.
For example, My custom module will add a field in sale and account, but if this database has purchase installed then it will also add a field in it too. Pretty simple concept, right, but I can't find a way to do it in a single module.
You can use post_init_hook, which is executed right after the module’s installation, to check if the purchase (purchase.order is in registry) module is installed and add the custom field. You can even load an XML file to add the custom field by inheritance using the convert_xml_import function which convert and import XML files.
It is similar to adding the field manually to the corresponding model and view.
When you uninstall the module, the custom field will not be deleted and to do so, you will need to use the uninstall_hook, you will also need to delete the view manually because of the following user error:
User Error
Cannot rename/delete fields that are still present in views
Fields: purchase.order.x_reference
View: purchase.order.form
First set the post_init_hook, uninstall_hook functions inside the __manifest__.py file:
'post_init_hook': '_module_post_init',
'uninstall_hook': '_module_uninstall_hook',
Then define those functions inside the __init__.py file:
import os
from odoo import fields, api, SUPERUSER_ID, tools, modules
from odoo.tools.misc import file_open
def _module_uninstall_hook(cr, registry):
if 'purchase.order' in registry:
env = api.Environment(cr, SUPERUSER_ID, {})
env.ref('stackoverflow_14.purchase_order_form').unlink()
env['ir.model.fields'].search([('name', '=', 'x_reference')]).unlink()
def _module_post_init(cr, registry):
if 'purchase.order' in registry:
env = api.Environment(cr, SUPERUSER_ID, {})
mp = env['ir.model'].search([('model', '=', 'purchase.order')], limit=1)
mp.write({'field_id': [(0, 0, {
'name': 'x_reference',
'field_description': "Reference",
'ttype': 'char',
})]})
pathname = os.path.join(modules.get_module_path('stackoverflow_14'), 'views', 'purchase_order.xml')
with file_open(pathname, 'rb') as fp:
tools.convert.convert_xml_import(cr, 'stackoverflow_14', fp)
The purchase_order.xml file defined inside views use the view inheritance to add the custom field to the purchase_order_form form view:
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<record id="purchase_order_form" model="ir.ui.view">
<field name="name">purchase.order.form</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<field name="partner_ref" position="after">
<field name="x_reference"/>
</field>
</field>
</record>
</data>
</odoo>

Creating a new module in Odoo - Cannot see the module on app list after installation

I setup and installed Odoo. After installation I did scaffolding to create a test module. Within that module I added some code and the module appeared under my module list. However after installation I do not see the module on my app list. Below is my code:
button_action_demo.py
from odoo import models, fields, api
#Non-odoo library
import random
from random import randint
import string
class button_action_demo(models.Model):
_name = 'button.demo'
name = fields.Char(required=True,default='Click on generate name!')
password = fields.Char()
def generate_record_name(self):
self.ensure_one()
#Generates a random name between 9 and 15 characters long and writes it to the record.
self.write({'name': ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(randint(9,15)))})
def generate_record_password(self):
self.ensure_one()
#Generates a random password between 12 and 15 characters long and writes it to the record.
self.write({
'password': ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(randint(12,15)))
})
def clear_record_data(self):
self.ensure_one()
self.write({
'name': '',
'password': ''
})
views.xml
<record model="ir.ui.view" id="view_buttons_form">
<field name="name">Buttons</field>
<field name="model">button.demo</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Button record">
<!--The header tag is built to add buttons within. This puts them at the top -->
<header>
<!--The oe_highlight class gives the button a red color when it is saved.
It is usually used to indicate the expected behaviour. -->
<button string="Generate name" type="object" name="generate_record_name" class="oe_highlight"/>
<button string="Generate password" type="object" name="generate_record_password"/>
<button string="Clear data" type="object" name="clear_record_data"/>
</header>
<group>
<field name="name"/>
<field name="password"/>
</group>
</form>
</field>
</record>
<!--The action -->
<record model="ir.actions.act_window" id="buttons_example_action">
<field name="name">Create new record</field>
<field name="res_model">button.demo</field>
<field name="view_mode">form,tree</field>
<field name='view_id' ref='view_buttons_form'/>
</record>
<!-- top level menu: no parent -->
<menuitem id="main_button_menu" name="Buttons demo"/>
<menuitem id="button_menu" name="Buttons demo"
parent="main_button_menu"/>
<menuitem id="menu_detail_logging"
action="buttons_example_action" parent="button_menu"
sequence="20"/>
</data>
</odoo>
manifest.py
{
'name': "button_action_demo",
'summary': """
Short (1 phrase/line) summary of the module's purpose, used as
subtitle on modules listing or apps.openerp.com""",
'description': """
Long description of module's purpose
""",
'author': "My Company",
'website': "http://www.yourcompany.com",
# Categories can be used to filter modules in modules listing
# Check https://github.com/odoo/odoo/blob/13.0/odoo/addons/base/data/ir_module_category_data.xml
# for the full list
'category': 'Uncategorized',
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['base'],
# always loaded
'data': [
# 'security/ir.model.access.csv',
'views/views.xml',
'views/templates.xml',
],
# only loaded in demonstration mode
'demo': [
'demo/demo.xml',
],
}
security.py
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_button_action_demo_button_action_demo,button_action_demo.button_action_demo,model_button_action_demo_button_action_demo,base.group_user,1,1,1,1
Can someone please guide me what am I missing on my code. I'm more than happy to share more code if required but I think I have provided most of the bits
Add security or open debug mood and then click become super user in odoo 13 admin is not super user but you can make him by doing above
If module is not visible in app list then check few things, listed below.
Restart your Server.
Update App list.
Place module in right addons PATH.
If your security file is not working well or something wrong with your manifest file all these things will happen during installation or after installation.

Reload kanban view after a wizards closes in ODOO 8

I am trying to execute an action after a wizard action is performed, i want to reload a kanban:
Python code:
return {'type': 'ir.actions.act_close_wizard_and_reload_view', }
Javascript code: (taken from the forum, i think for version 7)
openerp.bmwe_crm = function(instance, local) {
instance.web.ActionManager = instance.web.ActionManager.extend({
ir_actions_act_close_wizard_and_reload_view: function (action,options) {
if (!this.dialog) {
options.on_close();
}
this.dialog_stop();
this.inner_widget.views[this.inner_widget.active_view].controller.reload();
return $.when();
}
});
}
All this from a forum about 7.0 version, but i am using 8.0 and it does not seems to work. I've even trying executing a default action:
return { 'type': 'ir.actions.client', 'tag': 'reload'}
Does not reload the page neither
I can solved this right now as follow
static/src/js/your_module_name.js
openerp.yout_module = function (instance) {
instance.web.ActionManager = instance.web.ActionManager.extend({
ir_actions_act_close_wizard_and_reload_view: function (action, options) {
if (!this.dialog) {
options.on_close();
}
this.dialog_stop();
this.inner_widget.active_view.controller.reload();
return $.when();
},
});
}
views/your_module_name.xml
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<template id="assets_backend" name="your_module_name assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/your_module_name/static/src/js/your_js_file_name.js"></script>
</xpath>
</template>
</data>
</openerp>
wizard/your_wizard.py
return { 'type' : 'ir.actions.act_close_wizard_and_reload_view' }
reference1
reference2
above the references, they are using
this.inner_widget.views[this.inner_widget.active_view].controller.reload();
but it is not working in v8. So, I modified it to
this.inner_widget.active_view.controller.reload();
Now, it is working.
To reload a view you can return a view like below. It will return & reload the desired view when wizard closes.
ir_model_data = self.env['ir.model.data']
view_id = ir_model_data.get_object_reference('module_name', 'view_name')[1]
return {
'name': 'view name',
'view_type': 'form',
'view_mode': 'kanban,tree,form',
'res_model': 'your.model.to.reload',
'view_id': view_id,
'context': self._context,
'type': 'ir.actions.act_window',
'target': 'current',
}
DISCALIMER: Not the best FIX, but it's a FIX.
NOTE: In teory odoo 8 web client engine must execute the Action that the Wizards returns in the python code function. This works in all views, except in Kanban views. So this is the workaround:
In the server, create a message in the odoo bus, every time you want to notify something happends:
bus = self.env['bus.bus']
message = {
'subject': '',
'body': 'Appointment Set',
'mode': 'notify',
}
bus.sendone('<CHANNEL-NAME>', message)
Then, in the frontend you must listen for a message on this channel:
First, register the channel (With out this, it wouldn't work)
openerp.bmwe_crm = function(instance, local) {
var bus = instance.bus.bus;
bus.add_channel("<CHANNEL-NAME>");
});
};
Second, reload the kanban when something happend in the channel:
openerp.bmwe_crm = function(instance, local) {
var bus = instance.bus.bus;
bus.add_channel("<CHANNEL-NAME>");
instance.bus.bus.on("notification", instance, function(notification){
instance.client.action_manager.inner_widget.views["kanban"].controller.do_reload();
});
};
DONE!
In my odoo this solution doesn't work...
[ironic mode on] It is one of those things I love about Odoo [ironic mode off]
To other person than the proposal solution doesn't work and need one solution, try this:
return {
'type': 'ir.actions.client',
'tag': 'reload',
}
where you return value, or close the wizard, put this code.
Seriously , good luck.

Importing a New Module (openacademy example) Odoo v8

I installed Odoo v8 on my poste windows 7.
I created a new module "openacademy" , by following the tutorial "Building a Module" on the official website:
https://www.odoo.com/documentation/8.0/howtos/backend.html
then I zip my file "openacademy" ==> "openacademy.zip".
The problem: When I try to import the module, I get this error:
Import Module
WARNING odoo openerp.models: Cannot execute name_search, no _rec_name defined on base.import.module
INFO odoo werkzeug: 127.0.0.1 - - [16/Dec/2014 17:53:03] "POST /web/dataset/call_kw/base.import.module/search_read HTTP/1.1" 200 -
WARNING odoo openerp.modules.module: module openacademy: module not found
INFO odoo openerp.addons.base_import_module.models.ir_module: module openacademy: loading templates.xml
INFO odoo openerp.addons.base_import_module.models.ir_module: module openacademy: loading views/openacademy.xml
INFO odoo werkzeug: 127.0.0.1 - - [16/Dec/2014 17:53:07] "POST /longpolling/poll HTTP/1.1" 200 -
**ERROR odoo openerp.addons.base.ir.ir_ui_view: Model not found: openacademy.course**
Error context:
View 'course.form'
[view_id: 1030, xml_id: n/a, model: openacademy.course, parent_id: n/a]
The model "openacademy.course" is not found, but it already exists in "models.py" !!!
This my code :
models.py :
from openerp import models, fields
class Course(models.Model):
_name = 'openacademy.course'
name = fields.Char(string='Title', required=True)
description = fields.Text()
views/openacademy.xml :
<openerp>
<data>
<record model="ir.ui.view" id="course_form_view">
<field name="name">course.form</field>
<field name="model">openacademy.course</field>
<field name="arch" type="xml">
<form string="Course Form">
<sheet>
<group>
<field name="name"/>
<field name="description"/>
</group>
</sheet>
</form>
</field>
</record>
<!-- window action -->
<!--
The following tag is an action definition for a "window action",
that is an action opening a view or a set of views
-->
<record model="ir.actions.act_window" id="course_list_action">
<field name="name">Courses</field>
<field name="res_model">openacademy.course</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">Create the first course
</p>
</field>
</record>
<!-- top level menu: no parent -->
<menuitem id="main_openacademy_menu" name="Open Academy"/>
<!-- A first level in the left side menu is needed
before using action= attribute -->
<menuitem id="openacademy_menu" name="Open Academy"
parent="main_openacademy_menu"/>
<!-- the following menuitem should appear *after*
its parent openacademy_menu and *after* its
action course_list_action -->
<menuitem id="courses_menu" name="Courses" parent="openacademy_menu"
action="course_list_action"/>
<!-- Full id location:
action="openacademy.course_list_action"
It is not required when it is the same module -->
</data>
</openerp>
__init.py__:
import models
Rename your models.py into course.py
course.py :
from openerp import models, fields
class Course(models.Model):
_name = 'openacademy.course'
name = fields.Char(string='Title', required=True)
description = fields.Text()
And change your __init__.py into this:
import models
I think model file's name should match the class name. You must make different model for each table.
A part from goFrendiAsgard answer, try with this:
Run "Update Apps List" in Odoo interface:
To see this option, you have to turn on the "Technical Feature" going to Settings –> Users, edit your user, and click on "Technical Feature".
Restart Odoo server:
I don't know how to do it in Windows, in Linux is sudo service odoo-server restart
For people facing this issue in a linux environment, can also try:
Check your module files and folder have the right owner and group:
Compare with the rest of modules and change if necesary. For example sudo chown -R odoo:odoo openacademy/
Check your module files and folder permissions:
Usually 755, so you can run sudo chmod -R 755 openacademy/

Openerp act_window popsup a new window, but the main client disappear

I'm building a openerp customer module that in tree view, there is a button for each entry, when pressed, an act_window action will be triggered and open a new pops-up window, but at the same time, the main gtk client disappeared (only the pops-up remains). Also I have set the 'target' to 'new', but still the same. Any ideas?
client: gtk-6.0.3 on windows
server: 6.0.2 on debian 2.6.32
the xml looks like:
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Field Schema">
<field name="field_name" />
<field name="field_type" />
<button name="edit" type="object" string="View and Edit" icon="gtk-go-forward" />
</tree>
</field>
and the edit function to trigger looks like:
def edit(self, cr, uid, ids, context=None):
obj_name = some_fn_dynamic_get_obj_name_from_ids(ids)
obj = self.pool.get(obj_name)
if not obj:
raise osv.except_osv('not supported')
res_id = obj.create(....)
...
return {
'type': 'ir.actions.act_window',
'name': 'View and Edit',
'view_mode': 'form',
'view_type': 'form',
'res_model': obj_name,
'res_id': res_id,
'target': 'new',
'context': context,
}
Updated: after debug into the client's source, i finally found that: i make a typo: nodestory where the correct one should be nodestroy
return {
'type': 'ir.actions.act_window',
...
'context': context,
'nodestroy': True,
}
T_T
I can't see anything obviously wrong. The target attribute is discussed in the developer book. The only thing I can suggest would be to look for examples in the source code that use the target attribute and see how they differ from yours.
To stop the client disappearing you need to add:
'nodestroy': True,