First of all, everything i make is working on my local computer but this error happen when i tried to update this module inside of a server.
I add some fields to res.company
class InheritAccountMove(models.Model):
_inherit = 'res.company'
tax_office = fields.Many2one('tax.office', string='Tax Office')
building_no = fields.Char(string='Building Number')
district_name = fields.Char(string='District/Town')
e_invoice_username = fields.Char(string="E-Invoice API Username")
e_invoice_password = fields.Char(string="E-Invoice API Password")
e_invoice_catalog = fields.Char(string="E-Invoice API Catalog")
e_invoice_isyeri = fields.Char(string="E-Invoice API Isyeri")
e_invoice_wsdl = fields.Char(string="E-Invoice API wsdl")
This is the XML looklike
<record id="view_company_form_inherit" model="ir.ui.view">
<field name="name">company.form</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="arch" type="xml">
<xpath expr="//field[#name='vat']" position="after">
<field name="tax_office"/>
<field name="building_no"/>
<field name="district_name"/>
<field name="e_invoice_username"/>
<field name="e_invoice_password"/>
<field name="e_invoice_catalog"/>
<field name="e_invoice_isyeri"/>
<field name="e_invoice_wsdl"/>
</xpath>
</field>
</record>
Its returning:
***THERE IS NO FIELD "e_invoice_username" inside of res.company.***
this fields starting with e_invoice is new ones. tax_office, building_no and district name was created 1 week ago and only with them it was working good.
Error started when i add this e_invoice fields.
I tried uninstall whole module and upload again but nothing changed.
I didn't understand why this is happening ?
Any idea for this problem ?
Uninstall and Install module will not solve the issue. When you modify python code, you need to restart the Odoo service and then activate developer mode then go to Apps-> click update app list.
Related
I'm trying to add some demo data to a module
one of the models extends res.partner and has a create method (it overrides it from the parent)
The create method does 2 things
it checks that the current user is in some groups
it populates a serial number field with a value (calculated with a sequence)
This is the code
#api.model
def create(self, vals_list):
if not self.env.user.has_group('my-project.group_super') and not self.env.user.has_group(
'my-project.group_some_other_group'):
raise ValidationError(
f"Warning! You have no permission to create a patient. Contact your administrator")
vals_list['patient_number'] = self.env['ir.sequence'].next_by_code('my-project.res.partner')
return super(Patient, self).create(vals_list)
please, note the ValidationError in this method. The message it reports is
Warning! You have no permission to create a patient. Contact your
administrator
in the xml file I'm using to add demo data to this model I have this record
<record id="johnsmith" model="res.partner">
<field name="active" eval="True"></field>
<field name="is_patient" eval="True"></field>
<field name="company_type">person</field>
<field name="firstname">John</field>
<field name="lastname">Smith</field>
<field name="phone">+39 345 345 345</field>
<field name="email">asdfasdfasd</field>
<field name="birthdate">1999-02-17</field>
<field name="place_of_birth">Milan</field>
<field name="fiscalcode">IUCGIUCHEUIOHD38</field>
<field name="city">Milan</field>
<field name="country_id" ref="base.it"></field>
<field name="gender">male</field>
<field name="type">contact</field>
</record>
This record mostly works.
Meaning, it shows up as a demo record when I load demo data.
I say "mostly" because the field patient-number is not populated
But then I copy and paste this record and I only change the id to johnsmith2, like this
<record id="johnsmith2" model="res.partner">
<field name="active" eval="True"></field>
<field name="is_patient" eval="True"></field>
<field name="company_type">person</field>
<field name="firstname">John</field>
<field name="lastname">Smith</field>
<field name="phone">+39 345 345 345</field>
<field name="email">asdfasdfasd</field>
<field name="birthdate">1999-02-17</field>
<field name="place_of_birth">Milan</field>
<field name="fiscalcode">IUCGIUCHEUIOHD38</field>
<field name="city">Milan</field>
<field name="country_id" ref="base.it"></field>
<field name="gender">male</field>
<field name="type">contact</field>
</record>
this second record doesn't work
when installing the module in a database with demo data enabled, I get the error message in the body of the create method override
Warning! You have no permission to create a patient. Contact your
administrator
in the log and the loading of demo data fails
It seems that the first record is not being processed by the create method override, the second one is
what is going on here ?
EDIT
I'm adding the definition of user groups as this came up in the comments
These are the 2 groups mentioned in the create method
<record id="my_project" model="ir.module.category">
<field name="name">My Project</field>
<field name="description">Users groups for My project</field>
</record>
[...]
<record id="group_super" model="res.groups">
<field name="name">Supervisor</field>
<field name="category_id" ref="my-project.my_project"/>
</record>
[...]
<record id="group_some_other_group" model="res.groups">
<field name="name">Some Other Group</field>
<field name="category_id" ref="my-project.my_project"/>
</record>
These are the relevant lines in the ir.model.access.csv file
sc_study_partner_super,res.partner.super,model_res_partner,group_super,1,1,1,1
[...]
sc_study_partner_some_other_role,res.partner.some_other_role,model_res_partner,group_some_other_group,1,1,1,1
The demo/patients.xml file does not contain the no update flag
You can use self.env.is_admin() to check if its runned by administrator environment
Also, it is common to add rights to the super user and the admisstrator:
<record model="res.users" id="base.user_root">
<field eval="[(4,ref('my-project.group_super'))]" name="groups_id"/>
</record>
<record model="res.users" id="base.user_admin">
<field eval="[(4,ref('my-project.group_super'))]" name="groups_id"/>
</record>
I have a module what lock the Sale Order.
I want to do auto-triggering this function when a Field in settings is True.
Because at this moment it's call the function only when i hit a button.
There is how i check if a field value is 'set':
#api.multi
def auto_order_finishing(self):
field_value = self.env['ir.config_parameter'].sudo().get_param('sale.activate_automate_so_locking')
if field_value:
self.confirm_finish_order()
return True
Please check server action, you can achieve your feature with that.
You need to add python code & event on which that code will be applied.
You can create a scheduled action to some function that calls auto_order_finishing on all relevant sale orders at a specific interval.
You can find examples of these by searching for model="ir.cron"
I've pasted an example below
<record forcecreate="True" id="ir_cron_mail_scheduler_action" model="ir.cron">
<field name="name">Mail: Email Queue Manager</field>
<field name="model_id" ref="model_mail_mail"/>
<field name="state">code</field>
<field name="code">model.process_email_queue()</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">hours</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
</record>
I added a new field in account.config.settings model. It displays the new field in settings page and can enter the value. But when i reopen the page the value is not there. I know the Transient model won't store values for long.
But rest of the values still there, how can i achieve this?
Below is my code.
*.py
class AccountSettings(models.TransientModel):
_inherit='account.config.settings'
#api.one
def _get_header(self):
header = fields.Char('Header')
*.xml
<record id="view_account_config_settings_inherit" model="ir.ui.view">
<field name="name">view.account.config.settings.inherit.form</field>
<field name="model">account.config.settings</field>
<field name="inherit_id" ref="account.view_account_config_settings"/>
<field name="arch" type="xml">
<xpath expr="//group[#name='accounting']" position="after">
<group string="Reports" name="reports">
<field name="header" class="oe_inline"/>
</group>
</xpath>
</field>
</record>
In account.config.settings Model you can save your value by using this :
class AccountSettings(models.TransientModel):
_inherit='account.config.settings'
header = fields.Char('Header')
#api.multi
def set_header_defaults(self):
return self.env['ir.values'].sudo().set_default(
'account.config.settings', 'header', self.header)
Try this code:
class AccountSettings(models.TransientModel):
_inherit='account.config.settings'
#api.one
def _get_header(self):
header = fields.Char('Header',config_parameter='header.configuration')
you can name the attribute config_parameter anything you want. And it will be used to get the value of header from other models.
example:
test = self.env['ir.config_parameter'].get_param('**header.configuration**', '').strip()
test will return the temporary stored value in account.config.settings.
I'm trying to create a form view.
<field name="is_positive" attrs="{'readonly':[('state','==','final')]}"/>
However there is many attributes like groups and invisible related to authorization so that certain group of people can see the field.
groups="base.group_hr_user"
But Is there a way for certain group can edit the field and the other group cannot?
add a new field to check whether the user is manager or user.
New Api Method
check_user = fields.Boolean(string='user',compute='_compute_user_check')
#api.multi
def _compute_user_check(self):
if self.user_has_groups('purchase.group_purchase_manager'):
self.check_user =True
In view
<field name="is_positive" attrs="{'readonly':[('check_user','=','True')]}"/>
First of all, you cannot use a domain like this one
<field name="is_positive" attrs="{'readonly':[('state','==','final')]}"/>
There is not a '==' operator, use = instead.
Now, to answer your question, if you want to create a special view for another group in which some elements are readonly for one group, and editable in the other, you have to it this way.
For the default view :
<record id="some_model_view" model="ir.ui.view">
<field name="name">some.model.form</field>
<field name="model">some.model</field>
<field name="arch" type="xml">
<form>
<field name="some_field" readonly="1"/>
</form>
<field/>
</record>
For a certain group :
<record id="some_model_view_for_other_group" model="ir.ui.view">
<field name="name">some.model.form</field>
<field name="model">some.model</field>
<field name="inherit_id" ref="my_module.some_model_view"
<field name="groups_id" eval="[(6, 0, [ref('some.first_group')])]" />
<field name="arch" type="xml">
<field name="some_field" position="attributes">
<attribute name="readonly">0</attribute>
</field>
<field/>
</record>
I will show one example to how this functionality works in sale group.
I make the unit price field in the sale order line makes readonly we select the user group user:own documents only The field is editable for other 2 groups user:All documets and manager
Firstly I create a boolean field for checking the user belongs to which group
is_own_user = fields.Boolean(string="Own user", compute='compute_own_user')
Then assigns the boolean field is True when the user belongs the group user:own documents only otherwise assigns to False
#api.depends('product_id')
def compute_own_user(self):
res_user_id = self.env['res.users'].search([('id', '=', self._uid)])
for rec in self:
if res_user_id.has_group('sales_team.group_sale_salesman') and not res_user_id.has_group('sales_team.group_sale_salesman_all_leads'):
rec.is_own_user = True
else:
rec.is_own_user = False
in xml make is_own_user invisible and replaces the unit price field
<xpath expr="//notebook/page/field[#name='order_line']/tree/field[#name='price_unit']" position="replace">
<field name="price_unit" attrs="{'readonly': [('isown_user', '=', True)]}" />
</xpath>
Like i have one field in product.template with the field name squ_meter which i need to copy this value in custom field of purchase order line with same field name i.e squ_meter and i want to apply onchange on purchase order line field
Any kind of help would be much appreciated. Thanks in advance
Here's my code
class purchase_order_line(osv.osv):
_inherit = 'purchase.order.line'
_columns ={'squ_meter' : fields.float('Square Meter'),
}
purchase_order_line.xml
<field name="name">purchase.order.inherit</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="//page[#string='Products']//field[#name='order_line']//field[#name='product_qty']" position="after">
<field name="squ_meter"/>
</xpath>
</field>
Related Fields
Related field is useful when you want to keep the values of any relational fields except it's reference then it would be easier way to do it.
OLD API
_columns ={
'squ_meter': fields.related('product_id','squ_meter', type='float', relation='product.product', string='Square Meter', readonly=True),
}
Where:
The first set of parameters are the chain of reference fields to
follow, with the desired field at the end.
type is the type of that desired field.
Use relation if the desired field is still some kind of reference. relation is the table to look up that reference in.
NEW API
There is not anymore fields.related fields.
Instead you just set the name argument related to your model:
squ_meter = Fields.Float(string='Square Meter', related='product_id.squ_meter' , readonly=True)
purchase_order_line.xml
<field name="name">purchase.order.inherit</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="//page[#string='Products']//field[#name='order_line']//field[#name='product_qty']" position="after">
<field name="squ_meter" readonly="1" />
</xpath>
</field>