Created the cron job for fetching weather information on every 1 minute but it not work. Here, I attach the code (.py function).
#api.model
def weather_cron(self):
weather_location_ids =self.env['weather_location.weather_location'].search([])
for weather_location_id in weather_location_ids:
url_cron = weather_location_id.api_address + weather_location_id.name
json_data = requests.get(url_cron).json()
formatted_data = json_data['weather'][0]['main']
formatted_data1 = json_data['main']['temp']
formatted_data2 = json_data['main']['temp_min']
formatted_data3 = json_data['main']['temp_max']
formatted_data4 = json_data['main']['humidity']
self.env['current_weather.current_weather'].create({
'weather_id':weather_location_id.id,
'main':formatted_data,
'temp':formatted_data1,
'temp_min':formatted_data2,
'temp_max':formatted_data3,
'humidity':formatted_data4,
})
Cron Job (.xml file):
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data noupdate="1">
<record forcecreate="True" id="create_weather_info_cron" model="ir.cron">
<field name="name">Weather Information</field>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="False" />
<field name="interval_number">1</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="model" eval="'weather_location.weather_location'"/>
<field name="function" eval="'weather_cron'"/>
</record>
</data>
</odoo>
You made the cron job inactive. Since it is not active this will not trigger the function you wrote. Please change the value to active as True
<field name="active" eval="True"/>
All your field are correct add this two:
<field name="args" eval="'()'"/>
<!-- delay the call 2 minutes just to make sure but it's optional -->
<field name="nextcall" eval="(DateTime.now() + timedelta(minutes=2)).strftime('%Y-%m-%d 00:00:00')" />
Now if the code sill not working you need to make sure of it.
#1- check that your file is in the __openerp__.py or __manifest__.py
#2- if you don't know how to use debug mode in your IDE just use logging to see if Odoo calls your methodname
Hope this Helps you
One thing if you used noupdate="1" in your xml file odoo will not update the record that it's inserted in first time no matter what you change in the code this will not effect the recrod in database.
just change the id and delete the ir.cron record manually from setting menu
EDITS:
every model with "model.name" have an xml_id like this model_model_name
when you see mode_id remember to prefix the name with _model
<field name="model_id" ref="weather_location.model_weather_location"/>
and they are in the same module just put ref="model_weather_location"
But for ir.cron just give the name of the model because it's a Char field not many2one:
<field name="model" eval="'weathe.location'"/>
Related
I'm trying to set nextcall based on time zone in cronjob in 2nd next day
Here's my code:
<field name="nextcall"
eval="datetime.now() + (datetime.now(pytz.timezone('Asia/Ho_Chi_Minh')).replace(day=26, hour=2, minute=00, second=00) - datetime.now(pytz.timezone('Asia/Ho_Chi_Minh'))) % timedelta(hours=24)"/>
This code is to change the nextcall to the time zone of "Asia/Ho_Chi_Minh".
But when using it, i can't set the days to it, such as 2nd next day.
I've try to set day, but not working.
Please help, thanks.
Edit:
Full code:
<record id="ir_cron_check_qty_and_move_from_internal_customer_to_customer" model="ir.cron">
<field name="name">KiotViet: Check Qty And Move Product From Internal Customer To Customer</field>
<field name="model_id" ref="model_kiotviet_cron"/>
<field name="type">ir.actions.server</field>
<field name="state">code</field>
<field name="code">model.check_qty_and_move_from_internal_customer_to_customer()</field>
<!-- set cron will run after 1 days -->
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<!-- set cron will run at 2am -->
<field name="nextcall"
eval="datetime.now() + (datetime.now(pytz.timezone('Asia/Ho_Chi_Minh')).replace(day=26, hour=2, minute=00, second=00) - datetime.now(pytz.timezone('Asia/Ho_Chi_Minh'))) % timedelta(hours=24)"/>
<field name="numbercall">-1</field>
</record>
I want to view 'working_hours' field only for employee, his manager and 'hr.group_hr_user' group.
how to hide this field automatically without edit form or trigger a button
class InheritHrEmployee(models.Model):
_inherit = 'hr.employee'
def hide_working_hours(self):
if self.env.uid == self.user_id.id or self.env.uid == self.parent_id.user_id.id or self.env.user.has_group(
'hr.group_hr_user'):
self.working_hours_view = True
else:
self.working_hours_view = False
working_hours_view = fields.Boolean(computed=hide_working_hours)
XML:
<record id="hide_working_hours_for_employees" model="ir.ui.view">
<field name="name">Hide Working Hours Employees Form</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='resource_calendar_id']" position="before">
<field name="working_hours_view" invisible="1"/>
</xpath>
<xpath expr="//field[#name='resource_calendar_id']" position="attributes">
<attribute name="attrs">{'invisible': [('working_hours_view' ,'=', False)]}</attribute>
</xpath>
</field>
</record>
Try below code for display working hours field only hr.group_hr_user group users.
XML:
<record id="hide_working_hours_for_employees" model="ir.ui.view">
<field name="name">Hide Working Hours Employees Form</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='resource_calendar_id']" position="before">
<field name="working_hours_view" invisible="1"/>
</xpath>
<xpath expr="//field[#name='resource_calendar_id']" position="attributes">
<attribute name="groups">hr.group_hr_user</attribute>
</xpath>
</field>
</record>
You can add multiple attributes in the XML file like above code.
i added the field before the function and it works now automatically
class InheritHrEmployee(models.Model):
_inherit = 'hr.employee'
inv = fields.Boolean(string="Invisible", compute="c_inv", store=False)
#api.one
def c_inv(self):
if self.env.uid == self.user_id.id or self.env.uid == self.parent_id.user_id.id or self.env.user.has_group(
'hr.group_hr_user'):
self.inv = False
else:
self.inv = True
.. like this example
make fields visible to user and invisible to other
I have a boolean field 'classified' on sale order and my idea was that only users who are in the group that I created 'Classified quotations' can see records on tree view in which classified is true . I created two rules and I have no idea why it doesn't work. Here is the code:
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="sale_order_rule_group_classified_quotations" model="ir.rule">
<field name="name">sale_order_rule_group_classified_quotations</field>
<field name="model_id" search="[('model','=','sale.order')]" model="ir.model"/>
<field name="groups" eval="[(4,ref('group_classified_quotations'))]"/>
<field name="domain_force">['|',('classified','=',True),('classified','=',False)]</field>
</record>
<record id="sale_order_rule_no_group" model="ir.rule">
<field name="name">sale_order_rule_no_group</field>
<field name="model_id" search="[('model','=','sale.order')]" model="ir.model"/>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
<field name="domain_force">[('classified','=',False)]</field>
</record>
</data>
</openerp>
What am I doing wrong?
You didn't tell how it does not work (or how it behaves now). Also If you want to allow to see all records on rule, you should use this instead on domain_force: [(1,'=',1)], this means all records and you don't need to make True or False checking. Try if that works.
I've recently done something similar but done so in the .py file.
You can do something like this:
def write(self, cr, user, ids, vals, context=None):
if vals.get('classified'):
group_id = self.pool.get('ir.model.data').get_object_reference(cr, 1, 'your_model', 'your_group')
user = self.pool.get('res.users').browse(cr, user, user)
if group_id not in user.groups_id:
raise osv.except_osv(_('Error'), _("Only x user can adjust this field"))
return super(your_model, self).write(cr, user, ids, vals, context=context)
I have created a cron which executes a method. Now in that method i want to raise a warning if some value is missing.
Right now my method raise warning(tried Warning and except_orm) but it will log warning to terminal only no warning message appear on GUI.
Am i missing something?
Here is sample code:
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="ir_cron_test_warning" model="ir.cron">
<field name="name">Test Warning</field>
<field name="interval_number">1</field>
<field name="interval_type">minutes</field>
<field name="numbercall">1</field>
<field name="active" eval="True"/>
<field name="model">test.warning</field>
<field name="function">test_warning_exception</field>
<field name="args">()</field>
</record>
</data>
</openerp>
Method:
class test_warning(models.Model):
_name = 'test.warning'
#api.model
def test_warning_exception(self):
aurl = self.env['ir.config_parameter'].get_param('my_path')
if not aurl:
raise Warning(_('Please add mypath to System Parameters1111'))
Regards,
errors and warnings from the cron job will be bypassed by the orm. so you should either make sure only the correct data is taken in the cron function or it should be avoided.
Considering the following objects and a corresponding view:
class first_object(osv.osv):
_name = "first.object"
_columns = {
'id': fields.integer ('First ID'),
'flag': fields.boolean ('Flag'),
'second_object_id': fields.one2many('second.object','first_object_id')
}
class second_object(osv.osv):
_name = "second.object"
_columns = {
'id': fields.integer ('Second ID'),
'first_object_id': fields.many2one('first.object','random field'),
'field_x': fields.float('x',size=128),
'field_y': fields.float('y',size=128),
}
<record model="ir.ui.view" id="first_object_view_id">
<field name="name">Frist Object</field>
<field name="model">first.object</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form>
<notebook>
<page>
<field name="id"></field>
<field name="flag"></field>
<field name="second_object_id">
<tree editable="top">
<field name="field_x" attrs="{'invisible':[('flag','=',True)]}"/>
<field name="field_y"/>
</tree>
<form>
<field name="field_x"/>
<field name="field_y"/>
</form>
</field>
</page>
</notebook>
</form>
</field>
</record>
Notice the attrs I have now for the field of the second object named field_x in the tree which is based on the field of the first object named flag.
First of all, the attribute in this case is ignored completely. I dont know why it wont work. Second, assuming this can't work and the attributes MUST refer to local fields, the invisible attribute does not work for the tree view, just the form view. However, if you set a simple invisible="1" in the tree it would work just fine (I cant rely on that, I need the rule I provide with attributes). Any ideas?
EDIT:
The problem seems to be making fields invisible via attributes (and not invisible="1") in the TREE view. It works fine in the form. If this can be done it would solve my problem.
EDIT 2:
I tried with separated view definitions and local fields instead of many2one and one2many to no avail. However, I managed to somehow achieve this with invisible="context.get('xxx',True/False)". The problem is once the condition is matched, it remains invisible even after creating a new record where the condition is not matched.
please look in stock_move_tree from stock.move
<field name="prodlot_id" groups="base.group_extended"/>
<button name="%(track_line)d" string="Split in production lots" type="action"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('prodlot_id','<>',False)]}"
states="draft,waiting,confirmed,assigned,done"
groups="base.group_extended"/>
<field groups="base.group_extended" name="tracking_id"/>
<button name="setlast_tracking" string="Put in current pack" type="object"
groups="base.group_extended"
icon="terp-stock_effects-object-colorize" attrs="{'invisible': [('tracking_id','<>',False)]}"
states="draft,assigned,confirmed,done"/>
Is the same solution, but for button, not for regular field. And yes, remove field but show empty column.
it seems trying to set an conditional invisible attribute will not affect the true view. only invisible="1". which makes sense since i can't imagine a tree view with some invisible field of which the entire column itself is not invisible.
add a related field to flag in second.oject
class second_object(osv.osv):
_name = "second.object"
_columns = {
'id': fields.integer ('Second ID'),
'flag': fields.related('first_object_id', 'flag', type='boolean', relation='first.object', string='Flag'),
'first_object_id': fields.many2one('first.object','random field'),
'field_x': fields.float('x',size=128),
'field_y': fields.float('y',size=128),
}
an then add field flag in your view as invisible and attrs:
<record model="ir.ui.view" id="first_object_view_id">
<field name="name">Frist Object</field>
<field name="model">first.object</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form>
<notebook>
<page>
<field name="id"></field>
<field name="flag"></field>
<field name="second_object_id">
<tree editable="top">
<field name="flag" invisible="1"/>
<field name="field_x" attrs="{'invisible':[('flag','=',True)]}"/>
<field name="field_y"/>
</tree>
<form>
<field name="field_x"/>
<field name="field_y"/>
</form>
</field>
</page>
</notebook>
</form>
</field>
You have take 1 extra new field (i.e boolean type field) in Object2.
and create onchnage on "flag" field of object1.
in that onchnage you set-reset the value of this new field according to value of Flag field.
and put attrs on this new_field instead of Flag.
Hope This will help you
Please define the view for the model 'second.object' seperately. The same example is in stock_partial_picking.py file inside wizard folder in stock module. please check that. you may need to define a field as user user1888049 told in his answer